Connection ErrorBad RequestSession ExpiredSign in requiredForbiddenNot FoundToo Many RequestsServer ErrorBad GatewayService UnavailableGateway TimeoutHTTP Version Not Supported
Session Expired
Your session has expired. Please log in to continue.
Sign in required
You need an account to do that. Sign in or create one — it only takes a minute.
Request Failed
We encountered an issue while processing your request.
Please check your internet connection and try again.
question for experienced scripters:
what is the best way (with the minimum amount of code) to create a handler for building visits, such as a Necropolis, for example? My ideas are limited to a method – by enabling/disabling a check constant in the trigger for a new day with the conditions I need. But maybe there is a more efficient way?
KioM, please provide a more detailed description of what you need, because as I understand it, the "building visit handler" is a function that triggers when a building is visited. In that case, it's unclear what the problem is if there's already a trigger for touching an object.
KioM, please describe in more detail what you need, because as I understand it, the "building visitation handler" is a function that triggers when a building is visited. In that case, it's unclear what the problem is if there's a trigger for touching the object.
almost) I need: there's a Temple (a unique one). When activated, a script runs, a battle takes place, etc. Then, I want to make it so that when it's visited, say, in the following few days, until the start of a new week, it displays a message and denies access (this is also clear). But how can I best check whether it has already been visited by a player or multiple players? The idea was to use a state indicator in the new day function through a trigger, but maybe there's a simpler and more universal feature for such things? For similar buildings, that would transmit information that it has already been looted.
It's slightly easier during activation to save the current date in a variable and, when the object is touched, compare the date with that variable. If the behavior is the same for all players, there is one variable; if it's different for each player, there is a table of variables. If you need to visually indicate on the object whether it has been looted or has already been refreshed, then you can only do this through a trigger for the new day; there are no other ways.
It might be slightly easier to save the current date in a variable during activation, and then compare the date with this variable when the object is touched.
local NHF_Trigger_env = {trig = {}} print("T1:"); NHF_Trigger_env.Trigger = Trigger function NHF_Trigger_env.tostring(a) return a and (a.."" ~= a and a or '"'..a..'"') or "nil" end; function NHF_Trigger_env.emptytable(t) print("T2:"); for k,v in t do if v then return nil end end return 1 end; function NHF_Trigger_env.hasparam(i) print("T3:"); return i ~= 0 and i ~= 10 and i ~= 11 end; function __HANDLER(trigtype, param) print("T4:"); print("T5:"); local h = %NHF_Trigger_env.trig[trigtype] if not h then return end local NHF_Trigger_env = %NHF_Trigger_env return function(a, b, c, d) a = %NHF_Trigger_env.tostring(a) b = %NHF_Trigger_env.tostring(b) c = %NHF_Trigger_env.tostring(c) d = %NHF_Trigger_env.tostring(d) local args = "(" .. a .. "," .. b .. "," .. c .. "," .. d .. ")" print("T6:"); for sender, tab in %h do if sender ~= 0 then local handler = %NHF_Trigger_env.hasparam(%trigtype) and tab and tab[%param] or tab if handler then startThread(parse(handler .. args)) end end end local tab = %h[0] print("T7:"); if tab then local handler = %NHF_Trigger_env.hasparam(%trigtype) and tab and tab[%param] or tab if handler then print("T8:"); startThread(parse(handler .. args)) end end end end; function Trigger(sender, trig, par, handler) print("T9:"); if sender .. "" ~= sender then print("T10:"); sender, trig, par, handler = 0, sender, trig, par end if not %NHF_Trigger_env.hasparam(trig) then print("T11:"); par, handler = nil, par end local need_disable = handler ~= nil if handler then print("T12:"); %NHF_Trigger_env.trig[trig] = %NHF_Trigger_env.trig[trig] or {} if par then print("T13:"); %NHF_Trigger_env.trig[trig][sender] = %NHF_Trigger_env.trig[trig][sender] or {} %NHF_Trigger_env.trig[trig][sender][par] = handler else print("T14:"); %NHF_Trigger_env.trig[trig][sender] = handler end else print("T15:"); if %NHF_Trigger_env.trig[trig] then if %NHF_Trigger_env.trig[trig][sender] then if par then print("T16:"); %NHF_Trigger_env.trig[trig][sender][par] = nil need_disable = %NHF_Trigger_env.emptytable(%NHF_Trigger_env.trig[trig][sender]) if need_disable then %NHF_Trigger_env.trig[trig][sender] = nil end else %NHF_Trigger_env.trig[trig][sender] = nil end need_disable = %NHF_Trigger_env.emptytable(%NHF_Trigger_env.trig[trig]) if need_disable then %NHF_Trigger_env.trig[trig] = nil end end end end if not need_disable then return end if par then print("T17:"); %NHF_Trigger_env.Trigger(trig, par, handler and "__HANDLER(" .. trig .. "," .. %NHF_Trigger_env.tostring(par) .. ")") else %NHF_Trigger_env.Trigger(trig, handler and "__HANDLER(" .. trig .. ")") end print("T18:end"); end;
It produces an error:
Do you have any guesses as to what might be wrong here?
local NHF_Trigger_env = {trig = {}} print("T1:"); NHF_Trigger_env.Trigger = Trigger function NHF_Trigger_env.tostring(a) return a and (a.."" ~= a and a or '"'..a..'"') or "nil" end; function NHF_Trigger_env.emptytable(t) print("T2:"); for k,v in t do if v then return nil end end return 1 end; function NHF_Trigger_env.hasparam(i) print("T3:"); return i ~= 0 and i ~= 10 and i ~= 11 end; function __HANDLER(trigtype, param) print("T4:"); print("T5:"); local h = %NHF_Trigger_env.trig[trigtype] if not h then return end local NHF_Trigger_env = %NHF_Trigger_env return function(a, b, c, d) a = %NHF_Trigger_env.tostring(a) b = %NHF_Trigger_env.tostring(b) c = %NHF_Trigger_env.tostring(c) d = %NHF_Trigger_env.tostring(d) local args = "(" .. a .. "," .. b .. "," .. c .. "," .. d .. ")" print("T6:"); for sender, tab in %h do if sender ~= 0 then local handler = %NHF_Trigger_env.hasparam(%trigtype) and tab and tab[%param] or tab if handler then startThread(parse(handler .. args)) end end end local tab = %h[0] print("T7:"); if tab then local handler = %NHF_Trigger_env.hasparam(%trigtype) and tab and tab[%param] or tab if handler then print("T8:"); startThread(parse(handler .. args)) end end end end; function Trigger(sender, trig, par, handler) print("T9:"); if sender .. "" ~= sender then print("T10:"); sender, trig, par, handler = 0, sender, trig, par end if not %NHF_Trigger_env.hasparam(trig) then print("T11:"); par, handler = nil, par end local need_disable = handler ~= nil if handler then print("T12:"); %NHF_Trigger_env.trig[trig] = %NHF_Trigger_env.trig[trig] or {} if par then print("T13:"); %NHF_Trigger_env.trig[trig][sender] = %NHF_Trigger_env.trig[trig][sender] or {} %NHF_Trigger_env.trig[trig][sender][par] = handler else print("T14:"); %NHF_Trigger_env.trig[trig][sender] = handler end else print("T15:"); if %NHF_Trigger_env.trig[trig] then if %NHF_Trigger_env.trig[trig][sender] then if par then print("T16:"); %NHF_Trigger_env.trig[trig][sender][par] = nil need_disable = %NHF_Trigger_env.emptytable(%NHF_Trigger_env.trig[trig][sender]) if need_disable then %NHF_Trigger_env.trig[trig][sender] = nil end else %NHF_Trigger_env.trig[trig][sender] = nil end need_disable = %NHF_Trigger_env.emptytable(%NHF_Trigger_env.trig[trig]) if need_disable then %NHF_Trigger_env.trig[trig] = nil end end end end if not need_disable then return end if par then print("T17:"); %NHF_Trigger_env.Trigger(trig, par, handler and "__HANDLER(" .. trig .. "," .. %NHF_Trigger_env.tostring(par) .. ")") else %NHF_Trigger_env.Trigger(trig, handler and "__HANDLER(" .. trig .. ")") end print("T18:end"); end;
It produces an error:
Do you have any idea what might be wrong here?
With what parameters was the overridden Trigger called?
What parameters were used when the overridden Trigger was called?
Type: OBJECT_TOUCH_TRIGGER There is a check for the existence of a hero and a monster.
function __HANDLER(trigtype, param) print("T4:"..trigtype); print("T5:"..param);
By calling each trigger in a separate thread and using the necessary delays depending on whether it's a multiplayer map or not, it can be made to work in multiplayer. At least, some of the triggers will work somehow.
Type: OBJECT_TOUCH_TRIGGER The check for the existence of a hero and a monster is in place.
function __HANDLER(trigtype, param) print("T4:"..trigtype); print("T5:"..param);
With each trigger being called in a separate thread and with the necessary delays depending on whether it's a multiplayer map or not, it can be made to work in multiplayer. At least, some of the triggers will work somehow.
I can't check it right now, but at first glance, you can try replacing
local handler = %NHF_Trigger_env.hasparam(%trigtype) and tab and tab[%param] or tab
with
local handler if %NHF_Trigger_env.hasparam(%trigtype) then handler = tab and tab[%param] else handler = tab end
Is the trigger sender specified as another object? That is, in the mod, all triggers should have an additional first parameter – the sender. For example, Trigger("NHF", OBJECT_TOUCH_TRIGGER, "mob", "handler_function")
Added 2 minutes later Each unique sender can have its own trigger for this type of event and parameter (object, player, ...).
Is the trigger's sender specified as something else? In other words, should all triggers in the mod have an additional first parameter – the sender? For example, Trigger("NHF", OBJECT_TOUCH_TRIGGER, "mob", "handler_function")
Added 2 minutes later Each unique sender can have its own trigger for a given event type and parameter (object, player, etc.).
Yes, I've tried both ways. The result is the same. If you override the trigger directly in the map, it works. With a different sender parameter. But you wouldn't rewrite the scripts of existing maps, would you?
Another question is about resetting the trigger, so that only the necessary one is reset. Would this be correct: Trigger("NHF", OBJECT_TOUCH_TRIGGER, mob, nil);? But if the trigger is reset in the map itself with Trigger(OBJECT_TOUCH_TRIGGER, mob, nil), wouldn't it affect all of them?
As I understand it, if the first parameter = nil, this is also a unique sender parameter.
I'm investigating delays and threads; they might be influencing things because the code itself seems correct.
Yes, I tried both ways. The result is the same. If you redefine the Trigger in the map itself, it works. With a different sender parameter. But you won't be rewriting the scripts of ready-made maps...
It is important that the Trigger override occurs before the map script and the mod script are executed. It is also desirable to add the standard alias for the Trigger function:
SetTrigger = Trigger
to the end of that large piece of code that performs the override. It is probably used rarely or not at all, but it should still be taken into account.
Another question is about resetting the trigger, so that only the necessary one is reset. Would this be correct: Trigger("NHF", OBJECT_TOUCH_TRIGGER, mob, nil);?
Yes, that is correct.
And if the Trigger(OBJECT_TOUCH_TRIGGER, mob, nil); is reset in the map itself, will it affect all of them?
No, by default, calling the trigger with standard parameters (from the Manuals) will be interpreted as a call from sender 0 (as a number, not a string). That is, in this case, only the trigger set in the usual way will be reset, and all the "special" ones will remain. However, emulation via Trigger(0, ...) is not possible, as this is equivalent to Trigger(NEW_DAY_TRIGGER, ...).
As I understand it, if the first parameter = nil, this is also a unique sender parameter.
No, the first parameter must be either a number (standard call), in which case it will be taken as the event type, or a string, in which case it will be taken as the sender. Passing nil as the first parameter will cause an error: attempt to concat a nil value. If desired, the sender parameter can be placed at the end as an optional parameter, then any value can be sent as the sender, except nil (which will be equivalent to not specifying the parameter) and NaN (which is not indexed in tables because it is not equal to itself). This will require a small code modification.