#sandngrit onObjectEnterScriptingZone delay
1 messages · Page 1 of 1 (latest)
just posting this again:
run a script when each card enters a zone that modifies their description
after 1 second has passed with no cards being added
run a script that check the outcome on those cards that were added
Awesome, I’ll make a brew
so now we need to add a delay timer, now there's many ways of doing this, and it'll require a bit of a leap from you, but this is how i'd do it
I’m ready.. brew made, glasses on 😂
delayIDs = {}
function setDelay(delayName, functionToCall, delaySeconds)
if delayIDs[delayName] then -- if a delay timer with this name (key in table delayIDs) is already running then
Wait.stop(onObjectEnterScriptingZoneDelayID) -- stop the delay timer
end
delayIDs[delayName] = Wait.time( -- get a new wait ID for the following Wait.time function
functionToCall, -- function to call when the timer runs out. note i have left out the (), as it wants a function _NOT_ a function call
delaySeconds, -- how many seconds to wait for
)
end
alright so this is a function I just wrote to make the whole process easier for you
it uses Wait.time() and Wait.stop() to start and stop a timer
after that timer runs out, it then calls a function
so put this somewhere in your script in the global scope
(that means not inside of another function)
to use it in your script you'd do something like this:
setDelay("My Timer Name", myTimerFinished, 1)
So it runs like a callback function ?
that's a good analogy, even if it is not quite the same thing
the important part about the function is you can call it three times, and as long as the delayName is the same, it'll reset the timer each time, and then only call the end function once.
so
function myTimerFinished()
print("my timer is finished!")
end
setDelay("My Timer Name", myTimerFinished, 1)
setDelay("My Timer Name", myTimerFinished, 5)
setDelay("My Timer Name", myTimerFinished, 2)
-- after 2 seconds prints "my timer is finished!" only once
now you'll be using this in your script to call a function after I dunno, 0.5 seconds.
That’s all I’ll need I think
now you dont actually want the myTimerFinished() function but we'll be writing that in a bit
just get it to print something out once and then we can go from there
if you get stuck, post your entire code
Will do!
I wrote this in the scripting zone under the new onObjectEnter ..
I think from what you said I should have written it in global?
Also I think from what you’ve said it’s not complete yet, but was hesitant to add more as you said we’d be writing more after this, didn’t want to make a mess
function onObjectEnterScriptingZone(zone, enter_object)
if zone == self then
name = tonumber(enter_object.getName())
description = tonumber(enter_object.getDescription())
if 0 == name - description then
enter_object.setDescription(description + 4)
end
end
end
delayIDs = {"cardsEntering", "cardsEntered"}
function setDelay(delayName, functionToCall, delaySeconds)
if delayIDs[cardsEntering] then
wait.stop("cardsEntered")
end
delayIDs[cardsEntered] = Wait.time(function functionToCall, 20)
I did add the names “cardsEntering” and “cardsEntered” as I thought it showed my understanding of that part of the code
that wasn't what I expected, but I can see why you've interpreted it as that
the code I posted above is standalone, copy it completely into your code #951122976147906611 message
this was an example of how you'd use it: #951122976147906611 message you'll be adapting just this line into your existing code
ending up with this:
function onObjectEnterScriptingZone(zone, enter_object)
if zone == self then
name = tonumber(enter_object.getName())
description = tonumber(enter_object.getDescription())
if 0 == name - description then
enter_object.setDescription(description + 4)
end
-- we've done the description part, now we need to set the timer
-- this is where you'll adapt my example to start a timer
-- this was my example:
setDelay("My Timer Name", myTimerFinished, 1)
end
end
-- below just copy pasted from my above
delayIDs = {} -- yes, this should be empty
function setDelay(delayName, functionToCall, delaySeconds)
if delayIDs[delayName] then -- if a delay timer with this name (key in table delayIDs) is already running then
Wait.stop(delayIDs[delayName]) -- stop the delay timer
end
delayIDs[delayName] = Wait.time( -- get a new wait ID for the following Wait.time function
functionToCall, -- function to call when the timer runs out. note i have left out the (), as it wants a function _NOT_ a function call
delaySeconds -- how many seconds to wait for
)
end
-- also from my example above:
function myTimerFinished()
print("my timer is finished!")
end
I added a few extra comments to make it clearer
bear in mind that all these functions are defined in the "global" scope, the order they are defined in does not matter, except for your ease of reading
Ok I’ve copied and pasted, I get the error “<expression> expected near ‘)’”
this is why I should test my code before posting
ah I bet its the last comma
yup, just remove it, after delaySeconds
there was another error in there too so copy the code again
Ok done 👍
so you should get "my timer is finished" printing just once, even if you throw more than one card into the zone
which means we've now done step 2 of my three step breakdown:
run a script when each card enters a zone that modifies their description
after 1 second has passed with no cards being added
run a script that check the outcome on those cards that were added
now we need to backtrack a little for the third part - at the moment we don't know wihch cards have been added
so we need to add them to a table, then clear that table after the script has run so...
in an example outside of your function:
objectsEnteringScriptingZone = {} -- make an empty table
-- sometime later, inside onObjectEnterScriptingZone:
table.insert(objectsEnteringScriptingZone, enter_object) -- insert this enter_object to the end of the table
-- sometime later _after_ using the table
objectsEnteringScriptingZone = {} -- set the table to empty again
these are the three lines you need, but they all go in different places - any idea where?
note we're not actually doing anything with the objects yet.
objectsEnteringScriptingZone = {} this one definitely going before the function onObjectEnterScriptingZone to create the table
The next would be used to insert the enter object into the table, so in the onObjectEnter function
The third would be used (guess) in the myTimerFinished function?
Although I suspect that last one would cause the table to clear before the info is used ..
Unless I wrote the table clear last
Ok this is where I got to ..
objectsEnteringScriptingZone = {}
function onObjectEnterScriptingZone(zone, enter_object)
if zone == self then
table.insert(objectsEnteringScriptingZone, enter_object)
log(table.insert(objectsEnteringScriptingZone, enter_object))
name = tonumber(enter_object.getName())
description = tonumber(enter_object.getDescription())
if 0 == name - description then
enter_object.setDescription(description + 4)
enter_object.addTag("sent")
end
-- we've done the description part, now we need to set the timer
-- this is where you'll adapt my example to start a timer
-- this was my example:
setDelay("My Timer Name", myTimerFinished, 1)
end
end
-- below just copy pasted from my above
delayIDs = {} -- yes, this should be empty
function setDelay(delayName, functionToCall, delaySeconds)
if delayIDs[delayName] then -- if a delay timer with this name (key in table delayIDs) is already running then
Wait.stop(delayIDs[delayName]) -- stop the delay timer
end
delayIDs[delayName] = Wait.time( -- get a new wait ID for the following Wait.time function
functionToCall, -- function to call when the timer runs out. note i have left out the (), as it wants a function _NOT_ a function call
delaySeconds -- how many seconds to wait for
)
end
-- also from my example above:
function myTimerFinished()
objectsEntered = objectsEnteringScriptingZone
log(objectsEntered, "ObjectsEntered")
log(description, "description")
if objectEntered.hasTag("freestyle") and objectEntered.hasTag("sent") then
local success = tonumber(objectEntered.getDescription())
if success <= 5 then
log("Success")
else
log("Fail")
end
end
end
Using the log, it‘s saying that within the table “objectsEnteringScriptingZone” there’s 6 entries, where there should only be three.
Then I get an error after the delay that reads “attempt to index a nil value”
I assume that’s because I’ve not inserted the tag information in the table I’m referencing, but that’s because I can’t figure out how to ..
Getting somewhere though 😅
you don't need the tag information in the table because you're keeping the object itself in the table
you're missing a few things so let me clean that up
including one part we haven't covered yet, and that's looping through the objectsEnteringScriptingZone which I'll cover another time (I'm going out in a few minutes)
objectsEnteringScriptingZone = {}
function onObjectEnterScriptingZone(zone, enter_object)
if zone == self then
name = tonumber(enter_object.getName())
description = tonumber(enter_object.getDescription())
if 0 == name - description then
enter_object.setDescription(description + 4)
enter_object.addTag("sent")
end
-- we've done the description part, now we need to set the timer
-- this is where you'll adapt my example to start a timer
-- this was my example:
setDelay("My Timer Name", myTimerFinished, 1)
-- insert as the last thing we do
table.insert(objectsEnteringScriptingZone, enter_object)
end
end
-- below just copy pasted from my above
delayIDs = {} -- yes, this should be empty
function setDelay(delayName, functionToCall, delaySeconds)
if delayIDs[delayName] then -- if a delay timer with this name (key in table delayIDs) is already running then
Wait.stop(delayIDs[delayName]) -- stop the delay timer
end
delayIDs[delayName] = Wait.time( -- get a new wait ID for the following Wait.time function
functionToCall, -- function to call when the timer runs out. note i have left out the (), as it wants a function _NOT_ a function call
delaySeconds -- how many seconds to wait for
)
end
-- also from my example above:
function myTimerFinished()
for _,obj in ipairs (objectsEnteringScriptingZone) do -- for each object in our table do
log(obj, "obj:")
log(obj.getDescription(), "description")
if obj.hasTag("freestyle") and obj.hasTag("sent") then
local success = tonumber(obj.getDescription())
if success <= 5 then
log("Success")
else
log("Fail")
end
end
end
-- now we've finished looping, reset the table
objectsEnteringScriptingZone = {}
end
I did add the loop here
the part
for _,obj in ipairs(objectsEnteringScriptingZone) do
end
just loops through our table in order where each loop obj is each individual object
I then renamed the objectEntered var to simply obj for all the code inside it
the _ is a throwaway var name, its used when we don't need to know whats stored there. you could put a var there e.g. i and it'd tell you which number you are on, so it'd go 1 then 2 then 3 for three cards
Right, was just thinking should I do I loop
Ok, the script runs for the overall now, but is registering a fail when it should be a success
Agh no that was me getting > wrong way round ..
However it’s now not registering when there’s no freestyle tag that it’s a fail .. probably needs to be written in but I’m just telling you that’s what I’m getting. I’ll have a fiddle just need to pop out too.
Ok just getting myself into a mess now ..
Still getting the same problem = script keeps running for the individual card entered …
objectsEnteringScriptingZone = {}
function onObjectEnterScriptingZone(zone, enter_object)
if zone == self then
name = tonumber(enter_object.getName())
description = tonumber(enter_object.getDescription())
if 0 == name - description then
enter_object.setDescription(description + 4)
enter_object.addTag("sent")
end
-- we've done the description part, now we need to set the timer
-- this is where you'll adapt my example to start a timer
-- this was my example:
setDelay("My Timer Name", myTimerFinished, 1)
-- insert as the last thing we do
table.insert(objectsEnteringScriptingZone, enter_object)
end
end
-- below just copy pasted from my above
delayIDs = {} -- yes, this should be empty
function setDelay(delayName, functionToCall, delaySeconds)
if delayIDs[delayName] then -- if a delay timer with this name (key in table delayIDs) is already running then
Wait.stop(delayIDs[delayName]) -- stop the delay timer
end
delayIDs[delayName] = Wait.time( -- get a new wait ID for the following Wait.time function
functionToCall, -- function to call when the timer runs out. note i have left out the (), as it wants a function _NOT_ a function call
delaySeconds -- how many seconds to wait for
)
end
-- also from my example above:
function myTimerFinished()
sentCard = false
sentCard2 = false
log(sentCard, "sentCard:")
log(sentCard2,"sentCard2:")
for _,obj in ipairs (objectsEnteringScriptingZone) do -- for each object in our table do
sentCard = true
log(sentCard, "sentCard")
log(obj, "obj:")
log(obj.getDescription(), "description:")
log(obj.getTags(), "Tags:")
if obj.hasTag("freestyle") and obj.hasTag("sent") then
sentCard2 = true
log(sentCard2, "sentCard2")
elseif not obj.hasTag("freestyle") and obj.hasTag("sent") then
sentCard = false
log(sentCard, "sentCard")
if sentCard == false and sentCard2 == false then
log("fail")
print("fail")
elseif sentCard == false and sentCard2 == true then
log("success")
print("success")
end
end
end
objectsEnteringScriptingZone = {}
end
Still getting the same problem = script keeps running for the individual card entered …
how are you entering the cards?
Entering them by manually grabbing 3, and dragging them to the zone
does your save have local assets? if so this won't work but if it doesn't then email me your save file
I’m currently now trying the following ..
Set a variable to true if a freestyle tag is detected
On a button click from elsewhere, detect whether that variable is true or false, then do accordingly
But the variable isn’t being passed or changed by objects, even if I originate it in Global
So I’m doing
In global
“success = false”
Then in the zone,
For objects …… do
If freestyle tag found then
Success = true
Then on the button
If success = true then
Do the thing
Else do something else
i can't read that because it's too pseudo :)
i tested the script in my TTS so it was working on my end, but I guess it depends how fast you're putting the cards in
I’ve found a solution .. you’re probably going to laugh ….
I’ve ended up giving the zone itself a tag “successful” if the correct card and value is found.
Then a button to check if the zone has the tag or not …….
that sounds a practical solution, but (again) that wasn't your brief :P