Activate trigger only every nth time

Aus EnigmaWiki

Wechseln zu: Navigation, Suche
Available languages: Deutsch, English, Русский

Inhaltsverzeichnis

Problem definition

The problem arises with all it-trigger: the function, which calls a callback, is called both when entering and when leaving. That can be extremely annoying. Now, how can you prevent that? The function is called only every 2. (n.) times.

Solution

The function is provided with an if-statement, which examines whether a certain variable has a certain value.

Example solution

set_item("it-trigger",4,2,{action="callback", target="right_switch"})
set_stone("st-laser",4,4,{name="right_laser", dir=SOUTH, on=FALSE})
 
local second = 0
function right_switch()
    if second == 0 then
        SendMessage("right_laser","onoff")
    end
    second = 1-second
end
 

Analysis

The variable second is initialized with 0 and changes its value between 0 and 1. This is mathematically very easy to manage: second = 1-second.

Now if the function right_switch() is called by the trigger, it first examines the value of second. If it is 0, it implements its actual task. if it is 1, it does nothing. In either way, it changes the value of second to the other state.


Extended example

The above solution can be extended in such a way that the function implements its task only each nth time.

Example solution

set_stone("st-switch",4,2,{action="callback", target="right_switch"})
set_stone("st-laser",4,4,{name="right_laser", dir=SOUTH, on=FALSE})
 
local second = 0
local ntesmal = 5
function right_switch()
    if second == 0 then
        SendMessage("right_laser","onoff")
    end
    second = second+1
    if second == ntesmal then
        second = 0
    end
end

Analysis

With the variable ntesmal you determine how often the function called by the switch performs its task. In the example the laser switches itself on when first operated (second is at first 0 - ntesmal could be e.g. 3, then the laser would only switch itself on with the 3rd time). In order to switch it off again you must operate the switch exactly 5 times.


A very elegant example

Here we use the implicit values that we get from the callback function. The variable value contains further information about the trigger. sender is as usual the object, that triggered the callback.

-- The positions {triggerx, triggery, targetx, targety}
positions = {{5,5,2,3},{6,6,9,10},{7,7,4,6}}
local num_objects = table.getn(positions)
 
for i=1, num_objects  do
    set_item("it-trigger", positions[i][1], positions[i][2], {action="callback", target="toggle", _targetx=positions[i][3], _targety=positions[i][4]})
    set_stone("st-metal", positions[i][3], positions[i][4])
end
 
 
function toggle(value, sender)
    if value==1 then
        set_stone("st-grate1", enigma.GetAttrib(sender, "_targetx"),enigma.GetAttrib(sender, "_targety"))
    else
        set_stone("st-metal", enigma.GetAttrib(sender, "_targetx"),enigma.GetAttrib(sender, "_targety"))
    end
end

A further example

Here we can specify the initial condition of the targets over the array status .

-- Positions of the triggers:
trigger_positions = {{1,1},{2,3},{3,1},{4,4},{5,2},{6,3}}
-- Initial target states:
status = {1,0,1,0,0,1}
-- Positions of the targets:
target_positions = {{1,6},{2,8},{3,7},{4,9},{5,5},{6,8}}
 
function initialise_triggers(source_positions, states)
    local num_objects = table.getn(source_positions)
    for i=1, num_objects do
        set_item("it-trigger", source_positions[i][1], source_positions[i][2], {action="callback", target="replace", _id=i})
        if states[i] == 0 then
            set_stone("st-metal", target_positions[i][1], target_positions[i][2])
        else
            set_stone("st-grate1", target_positions[i][1], target_positions[i][2])
        end
    end
end
 
function replace(onoff, sender)
    local _id = enigma.GetAttrib(sender, "_id")
    if status[_id] == 0 then
        set_stone("st-grate1", target_positions[_id][1], target_positions[_id][2])
    else
        set_stone("st-metal", target_positions[_id][1], target_positions[_id][2])
    end
    status[_id] = 1 - status[_id]
end
 
initialise_triggers(trigger_positions, status)
Persönliche Werkzeuge