Closed Pychnight closed 5 years ago
Theres really only 2 ways to go about this, the easy way and the painful way, which is to reengineer the trigger system from the ground up to support stuff like this. Thats wildly out of scope, so we're not going to entertain that one right now.
The easy way involves adding another parameter, that lets you pass in optional method to be executed each time the tally changes. The downside is, these methods are NOT the place to do long running code, or start spawning new triggers, etc. These should do whatever their job is quickly, and nothing else. As a quick example:
The second one has potential to deadlock things. Same with trying to start new triggers there.
I would prefer a proper solution to this problem, however as you said it would require refactoring the entire trigger system.
errors already happen during trigger loops if you abort the quest during a loop.
I could deal with the quick solution for now, but I'm also adding this issue to Milestone 4 into the proper solution can be developed.
GatherItems and KillNpcs triggers now feature have overloads that accept an action( Action<PartyMember,int>, in c# ). The second parameter is the count of whatever was gained( or lost, but the current triggers don't currently use or record losses of any sort, this is for future expansion )
GatherItems Example
def OnTallyChange(member as PartyMember,count as int):
Broadcast "$(member.Name) gained $count items."
Broadcast "This quest tests the GatherItems trigger."
itemType = "Torch"
itemCount = 5
timeout = 60 * 1000
Delay 3000
Broadcast "Please gather $itemCount $itemType(s)."
result = TriggerWaitAll(timeout,GatherItems(party,OnTallyChange,itemType,itemCount))
if result==true:
Broadcast "Test is complete!"
Complete(true)
else:
Broadcast "Time ran out. Try again."
Complete(false)
KillNpcs Example
def OnSlimeKilled(member as PartyMember,count as int):
Broadcast "$(member.Name) killed $count Green Slime(s)!"
party.SendInfoMessage("This quest tests the KillNpcs trigger.")
count = 10
taskSpawner = CreateTask:
Delay 4000
party.SendInfoMessage("Generating $count slimes now...")
#hardcoded to my world...
tx as Single = 2403
ty as Single = 263
for i in range(count):
Delay 750
SpawnMob("Green Slime",tx, ty, 5, 1)
taskKill = CreateTask:
Delay 4000
party.SendInfoMessage("Kill all the slimes!")
result = TriggerWaitAll(KillNpcs(party,OnSlimeKilled,count,"Green Slime"))
if result:
party.SendInfoMessage("Test is complete!")
Complete(true)
else:
party.SendInfoMessage("You ran out of time. Please try again.")
Complete(false)
taskSpawner.Start()
taskKill.Start()
taskKill.Wait()
Note that only a single overload exists on each trigger, and it requires you specify all the parameters explicitly. None of the shorter overloads accept the action!
And again -- DO NOT delay or wait on anything in these tally callbacks. Going through a loop is probably fine and spawning things, or running commands is probably okay-- but anything that waits will probably deadlock the quest.
Currently there is a limitation within all triggers that require to be completed within specific amount such as KILL = 10 or Collect 10 of specific types of items.
That issue is you can't send events before the trigger is completed.