Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design New Thread Event Handler #11

Closed
6 tasks done
Pychnight opened this issue Jan 6, 2018 · 9 comments
Closed
6 tasks done

Design New Thread Event Handler #11

Pychnight opened this issue Jan 6, 2018 · 9 comments
Assignees
Labels
Blocker enhancement Part 1 First part of the write

Comments

@Pychnight
Copy link
Owner

Pychnight commented Jan 6, 2018

  • Multi Event Execution Tasks
  • Multi Trigger Execution
  • able to execute multi-able triggers at different times per thread
  • able to start a new thread to execute side objectives inside the quest. (such collect item)
  • ensure triggers and tasks can be looped (see below)
  • Provide a way to do loops and have them actually execute the events inside the loop
  • Triggers and tasks need to work on all threads.
  • allow triggers to be easily looped to prevent code duplication in scripts.
  • Fix issue with triggers breaking when having the same monster name / item names
  • see examples below
  • Fix quest crashes when aborting during looped code.
  • Ensure Thread Safety (/reload, looped code, etc)

#1
#10 #8 #9 #3 #5 #4 #6 #7

@Pychnight Pychnight created this issue from a note in Custom Quests Redesign (To Do) Jan 6, 2018
@Pychnight Pychnight added the Part 1 First part of the write label Feb 23, 2018
@Pychnight Pychnight mentioned this issue Apr 9, 2018
22 tasks
@tbarela
Copy link
Collaborator

tbarela commented Apr 25, 2018

Undergoing continued testing and refinement.

@tbarela
Copy link
Collaborator

tbarela commented Apr 27, 2018

Everything seems to be working as intended. However, you'll still need to be vigilant about situations involving race conditions or unintended dead locking. Theres no autopilot that magically solves these types of problems.

@tbarela tbarela closed this as completed Apr 27, 2018
Custom Quests Redesign automation moved this from To Do to Done Apr 27, 2018
@Pychnight Pychnight reopened this Apr 28, 2018
Custom Quests Redesign automation moved this from Done to In progress Apr 28, 2018
@Pychnight
Copy link
Owner Author

Pychnight commented Apr 28, 2018

Reopened and unchecked Multi Event Execution.

Can't execute Triggers on different threads, they will always wait for the first task on the main thread to complete thus ending in the same situation as custom quests v1.0

mainResult = false
count = 5

countTask = CreateTask:
	for i in range(count):
		killcount = TriggerWaitAny( 120000, KillNpcs(party,1,"Green Slime"))
		if killcount:
			for member in party:
				member["killedslimes"] = 0
			for member in party:
				kills = member["killedslimes"]
				member.SendMessage("You Killed $kills Green Slimes")
				Delay 300
				SpawnMob("Green Slime", member.TileX+5,member.TileY+5, 1, 1)


taskMain = CreateTask:
	party.SendMessage("Welcome to the tutorial quest", Color.Yellow)
	party.SendMessage("This Quest will be going over how to play this server.", Color.Yellow)
	Delay 5000
	party.SendMessage("Would you like to hear how to play Please answer with yes or no", Color.Yellow)
	TriggerYes = TriggerWaitAll( 120000, ChatResponse(party, "yes"))
	if TriggerYes == true:
		tut_spawner = GetRegion("tut_spawner").Area
		party.SendMessage("First deal kill 5 green slimes.", Color.Yellow)
		countTask.Start()
		for member in party:
			SpawnMob("Green Slime", member.TileX+5,member.TileY+5, 1, 1)
		triggerKill = TriggerWaitAny( 120000, KillNpcs(party,count,"Green Slime"))
		if triggerKill:
			party.SendMessage("You Have succesfully killed all slimes", Color.Yellow)
			//ExecuteCommand('/bankadmin give EXP ' .. party .. ' 100')
			Delay 5000
			party.SendMessage("Looks good your probally wondering why you can't mine?", Color.Yellow)
			Delay 5000
			party.SendMessage("You will unlock the ability to mine and access the full server at level 5", Color.Yellow)
			Delay 5000
			party.SendMessage("for now you can only access Quests and Warp zones.", Color.Yellow)
			Delay 5000
			party.SendMessage("To complete quests, you must complete all objectives before time runs out", Color.Yellow)
			Delay 5000
			party.SendMessage("to access custom shops please use the warp points and go inside the houses at the points", Color.Yellow)
			Delay 5000
			party.SendMessage("Alright. If you have any other questions please refer to the website at raindreamdev.com", Color.Yellow)
			party.UnlockQuest("new lands")
		else:
			Complete(false)
			mainResult = true
	else:
			party.SendMessage("Alright, it looks like you already know how to play.", Color.Yellow)
			party.SendMessage("Unlocking next Quest.", Color.Yellow)
			//ExecuteCommand('/bankadmin give EXP ' .. party .. ' 100')
			party.UnlockQuest("new lands")
			Complete(false)
			mainResult = true
taskMain.Start()

@Pychnight
Copy link
Owner Author

tried working around this issue by using goto loops

	:repeat
	for i in range(exec):
		triggerKill = TriggerWaitAll( 120000, KillNpcs(party,1,"Green Slime"))
		if triggerKill:
			party.SendMessage(exec + " amount executed", Color.Yellow)
			exec = exec + 1
			countTask.Start()
			goto repeat if exec < 5

the trigger will not execute at all.

@Pychnight
Copy link
Owner Author

Pychnight commented Apr 28, 2018

alright --- i broke something in the script -_-; i will try to see what's causing the triggers to fail... in the code.
Had to undo everything i had written to find why the triggers there not executing anymore

seems like triggerKill = TriggerWaitAll( 120000, KillNpcs(party,1,"Green Slime"), KillNpcs(party,1,"Green Slime") ) doing the same triggers back to back also ends up breaking the triggers.

@Pychnight
Copy link
Owner Author

I greatly simplified the script to try to prove the issue exists

mainResult = false
count = 5

for member in party:
	member["killedslimes"] = 0
	kills = member["killedslimes"]

secondthread = CreateTask:
	party.SendMessage("Second thread active", Color.Yellow)
	secondthread = TriggerWaitAll( 120000, KillNpcs(party,1,"Green Slime"))
	if secondthread:
		party.SendMessage("You Have succesfully killed all slimes second thread", Color.Yellow)
		mainResult = true
		for i in range(count):
			for member in party:
				member.SendMessage("You Killed $kills Green Slimes")
				Delay 600
				SpawnMob("Green Slime", member.TileX+5,member.TileY+5, 1, 1)
	else:
		party.SendMessage("Second thread test failure", Color.Yellow)
		Complete(false)
		mainResult = true


mainthread = CreateTask:
	party.SendMessage("Welcome to the thread test", Color.Yellow)
	Delay 5000
	secondthread.Start()
	triggerKill = TriggerWaitAll( 120000, KillNpcs(party,count,"Green Slime"))
	if triggerKill:
		party.SendMessage("You Have succesfully killed all slimes for the main thread", Color.Yellow)
	else:
		party.SendMessage("thread test failure", Color.Yellow)
		Complete(false)
		mainResult = true
mainthread.Start()

in this script both events fail, it looks like they start successfully however, you can't complete ether one for what ever reason.

@Pychnight
Copy link
Owner Author

Pychnight commented Apr 28, 2018

No comment, found the reason why both events are failing.

TriggerWaitAll( 120000, KillNpcs(party,1,"Green Slime")

seems like if you reuse the enemy name for a different trigger such as green slime. it will cause the trigger to fail, however it only fails on different threads, reusing the enemy on the same thread works fine.

even doing this

triggerKill = TriggerWaitAll( 120000, KillNpcs(party,count,"Green Slime"), KillNpcs(party,count,"Green Slime") ) causes failure.

I have also tried doing clever TPL cancellation methods to work around the issue but it's the same.
Overall, starting a trigger on anther thread with the same enemy objective seems to break.

With this starting anther thread to run code in side by side of the main thread seems to not work at all currently, it seems like when you start the new code sequence it stops executing the main thread into it's done waiting for a trigger on a different thread. -_-

@tbarela
Copy link
Collaborator

tbarela commented May 1, 2018

Okay a couple of points to touch on here...

  1. Completion

You may have already picked up on it, but theres no call to Complete(true) anywhere, so your quest never succeeds. If you want the quest to succeed, you must issue a Complete(true) somewhere.

  1. KillNpcs

I've tested multiple duplicate KillNpcs triggers, in both a single task, and dual task form. They both work, with the caveat that something like:

result = TriggerWaitAll(KillNpcs(party,1,"Green Slime"), KillNpcs(party,1,"Green Slime"))

Results in them being handled sequentially. I presume this could cause issues elsewhere as well.( though the only reason your original example is having issues is because of the lack of Complete(s), as stated above ).

Now this is actually an issue with the KillNpc's trigger itself, and not the Tasks. This could have caused issues with the old quest callback system as well. KillNpcs internally keeps a single global dictionary of player npc strikes, removing the strikes on death. Hence why multiple duplicate triggers are operating sequentially. The first one is removing the strikes before the second one sees them, and thus the kill never gets associated with the player when the second trigger runs its code...

I'm not sure the best way to fix the trigger is just yet, but I'll work something out.

@tbarela
Copy link
Collaborator

tbarela commented May 1, 2018

Okay think that was an easy enough fix for KillNpcs. Just made it so its a dictionary per trigger. Closing this again.

@tbarela tbarela closed this as completed May 1, 2018
Custom Quests Redesign automation moved this from In progress to Done May 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Blocker enhancement Part 1 First part of the write
Projects
Development

No branches or pull requests

2 participants