Move leader back to keep every turn -- Code not working

The place to post your WML questions and answers.

Moderator: Forum Moderators

Forum rules
  • Please use [code] BBCode tags in your posts for embedding WML snippets.
  • To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
Post Reply
Kharn
Posts: 83
Joined: December 12th, 2005, 7:50 pm
Location: Dallas, Tx

Move leader back to keep every turn -- Code not working

Post by Kharn »

The following code is placed in the unit file for the leader. At the start of game, the code is expected to memorize the X,Y location of each leader. When the turn is about to begin (side turn event) the code is expected to move the leader back to the location that they started the game in. If a unit is on that location, that unit is to be killed and 75% of its value is given as gold to the owner of the unit. It is only expected to work if the player is on side number 1 through 6. The current behavior is that the leader is not moved back to the keep, the unit on the keep is not killed, and no gold is generated. Essentially, it acts as if the code was not even added. Please help find the issue in the code. Thanks!

Code: Select all

	[event]
	name=start
		[store_unit]
			[filter]
				canrecruit=yes
				side=1
			[/filter]
			variable=playerstore[1]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=2
			[/filter]
			variable=playerstore[2]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=3
			[/filter]
			variable=playerstore[3]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=4
			[/filter]
			variable=playerstore[4]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=5
			[/filter]
			variable=playerstore[5]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=6
			[/filter]
			variable=playerstore[6]
		[/store_unit]
	[/event]

	[event]
		name=side turn
		first_time_only=no
		{VARIABLE lastplayer $side_number}
	[/event]

	[event]
		name=turn refresh
		first_time_only=no
		[if]
		[have_unit]
			canrecruit=yes
			side=$lastplayer
			[not]
				[have_location]
					x,y=$playerstore[$lastplayer].x,$playerstore[$lastplayer].y
				[/have_location]
			[/not]
		[/have_unit]
		[then]
			[store_unit]
				[filter]
					x=$playerstore[$lastplayer].x
					y=$playerstore[$lastplayer].y
				[/filter]
				variable=billstore
			[/store_unit]
			{VARIABLE billworth billstore.cost}
			{VARIABLE_OP billworth multiply 0.75}
			#[set_variable]
			#name=billworth
			#multiply=0.75
			#[/set_variable]
			[gold]
				amount=$billworth
				side=$lastplayer
			[/gold]
			[kill]
				animate=no
				fire_event=no
			[/kill]
			[move_unit]
				canrecruit=yes
				side=$lastplayer
				to_x=$playerstore[$lastplayer].x
				to_y=$playerstore[$lastplayer].y
				#force_scroll=yes
			[/move_unit]
		[/then]
		[/if]
	[/event]
	
Creator of 120+ units Lord of the Rings era and campaign now outdated & lost.
Creator of WWII Battleground Europe mod with 120+ units most with custom wml and animations. Every variable is mathematically derived based on WWII stats such as historical cost & mm armour.
User avatar
Ravana
Forum Moderator
Posts: 2934
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: Move leader back to keep every turn -- Code not working

Post by Ravana »

I dont think you are allowed to leave holes in wml arrays. (playerstore[0])

This looks wrong {VARIABLE billworth billstore.cost}
enclave
Posts: 936
Joined: December 15th, 2007, 8:52 am

Re: Move leader back to keep every turn -- Code not working

Post by enclave »

Ravana wrote: October 22nd, 2018, 3:25 pm I dont think you are allowed to leave holes in wml arrays. (playerstore[0])
Y I feel the same, you could try to do [store_unit] variable=playerstore[0].unit but you unlikely can do it your way.. then you would access it with playerstore[0].unit.x etc

you could check what arrays it created using command line ":" , and type there "debug" and once more command line type "inspect", this will show you what arrays you have made with your playerstore[0], if any.. must be either a mess or nothing there..
Ravana wrote: October 22nd, 2018, 3:25 pm This looks wrong {VARIABLE billworth billstore.cost}
maybe i missed something, for me it looks right...
User avatar
Pentarctagon
Project Manager
Posts: 5496
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Move leader back to keep every turn -- Code not working

Post by Pentarctagon »

enclave wrote: October 22nd, 2018, 4:43 pm
Ravana wrote: October 22nd, 2018, 3:25 pm This looks wrong {VARIABLE billworth billstore.cost}
maybe i missed something, for me it looks right...
You're missing a dollar sign.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
enclave
Posts: 936
Joined: December 15th, 2007, 8:52 am

Re: Move leader back to keep every turn -- Code not working

Post by enclave »

indeed...... :D sorry
Kharn
Posts: 83
Joined: December 12th, 2005, 7:50 pm
Location: Dallas, Tx

Re: Move leader back to keep every turn -- Code not working

Post by Kharn »

Ok I fixed the WML hole by starting the array at 0. I added the dollar sign. Leaders are still not teleported back to their starting location every turn.
I copied this code from someone else and it has never worked. If anyone else has a way to move leader back to keep every turn I would really appreciate the help.

Code: Select all

	[event]
	name=start
		[store_unit]
			[filter]
				canrecruit=yes
				side=1
			[/filter]
			variable=playerstore[0]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=2
			[/filter]
			variable=playerstore[1]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=3
			[/filter]
			variable=playerstore[2]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=4
			[/filter]
			variable=playerstore[3]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=5
			[/filter]
			variable=playerstore[4]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=6
			[/filter]
			variable=playerstore[5]
		[/store_unit]
	[/event]

	[event]
		name=side turn
		first_time_only=no
		{VARIABLE lastplayer $side_number}
	[/event]

	[event]
		name=turn refresh
		first_time_only=no
		[if]
		[have_unit]
			canrecruit=yes
			side=$lastplayer
			[not]
				[have_location]
					x,y=$playerstore[$lastplayer].x,$playerstore[$lastplayer].y
				[/have_location]
			[/not]
		[/have_unit]
		[then]
			[store_unit]
				[filter]
					x=$playerstore[$lastplayer].x
					y=$playerstore[$lastplayer].y
				[/filter]
				variable=billstore
			[/store_unit]
			{VARIABLE billworth $billstore.cost}
			{VARIABLE_OP billworth multiply 0.75}
			#[set_variable]
			#name=billworth
			#multiply=0.75
			#[/set_variable]
			[gold]
				amount=$billworth
				side=$lastplayer
			[/gold]
			[kill]
				animate=no
				fire_event=no
			[/kill]
			[move_unit]
				canrecruit=yes
				side=$lastplayer
				to_x=$playerstore[$lastplayer].x
				to_y=$playerstore[$lastplayer].y
				#force_scroll=yes
			[/move_unit]
		[/then]
		[/if]
	[/event]
Creator of 120+ units Lord of the Rings era and campaign now outdated & lost.
Creator of WWII Battleground Europe mod with 120+ units most with custom wml and animations. Every variable is mathematically derived based on WWII stats such as historical cost & mm armour.
User avatar
josteph
Inactive Developer
Posts: 741
Joined: August 19th, 2017, 6:58 pm

Re: Move leader back to keep every turn -- Code not working

Post by josteph »

I don't think [have_location] is valid where you have it. Just [not] x,y=... [/not] should do.

Divide and conquer. Can you show a [message] only at the start of side turns when the leader isn't at his keep?

Do you want to move the leader to the keep or to teleport it to there? It's not the same.
Kharn
Posts: 83
Joined: December 12th, 2005, 7:50 pm
Location: Dallas, Tx

Re: Move leader back to keep every turn -- Code not working

Post by Kharn »

I want to teleport the leader to the keep. It is not clear from https://wiki.wesnoth.org/DirectActionsWML what happens to an existing unit if it is already in the way of the teleport.

I tried adding a message as you can see here:

Code: Select all


		[if]
		[have_unit]
			canrecruit=yes
			side=$lastplayer
			[not]
				[have_location]
					x,y=$playerstore[$lastplayer].x,$playerstore[$lastplayer].y
				[/have_location]
			[/not]
		[/have_unit]
		[then]
		[message]
			message= _ "Leader detected not at keep"
		[/message]	
			[store_unit]
				[filter]
					x=$playerstore[$lastplayer].x
					y=$playerstore[$lastplayer].y
				[/filter]
				variable=billstore
			[/store_unit]


The message does not appear. Thus it likely that either the following is not coming up true when it should

Code: Select all

			[not]
				[have_location]
					x,y=$playerstore[$lastplayer].x,$playerstore[$lastplayer].y
				[/have_location]
			[/not]
or the following is not storing the leaders into $playerstore[$lastplayer].x,$playerstore[$lastplayer].y

Code: Select all

	[event]
	name=start
		[store_unit]
			[filter]
				canrecruit=yes
				side=1
			[/filter]
			variable=playerstore[1]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=2
			[/filter]
			variable=playerstore[2]
		[/store_unit]
Creator of 120+ units Lord of the Rings era and campaign now outdated & lost.
Creator of WWII Battleground Europe mod with 120+ units most with custom wml and animations. Every variable is mathematically derived based on WWII stats such as historical cost & mm armour.
User avatar
beetlenaut
Developer
Posts: 2813
Joined: December 8th, 2007, 3:21 am
Location: Washington State
Contact:

Re: Move leader back to keep every turn -- Code not working

Post by beetlenaut »

Kharn wrote: October 24th, 2018, 12:26 am the following is not coming up true when it should
It's not, and it shouldn't either. As josteph pointed out, you have a [not] inside a unit filter, so that [not] is also a unit filter. You can't stick a location filter is there! It's invalid, so it's ignored. You can use [filter_location] to create a location filter inside the unit filter, but it's not necessary: Unit filters already have an x and a y, so just use those in the [not] directly as josteph suggested.
Kharn wrote: October 24th, 2018, 12:26 am or the following is not storing the leaders
I can't tell for sure if you are once again trying to fill playerstore[1] without defining playerstore[0] first, but it looks like it. As enclave suggested, type :debug then :inspect during the game to see all your variables and check whether this is being stored or not.
Kharn wrote: October 24th, 2018, 12:26 am It is not clear from https://wiki.wesnoth.org/DirectActionsWML what happens to an existing unit if it is already in the way of the teleport.
Nothing happens to that unit. It says the teleporting unit will be stuck in another nearby hex instead of its target hex. (If that's a problem, you just have to move the offending unit out of the way before doing the teleport.)
Campaigns: Dead Water,
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
enclave
Posts: 936
Joined: December 15th, 2007, 8:52 am

Re: Move leader back to keep every turn -- Code not working

Post by enclave »

1) I dont think that you can do it like that:

Code: Select all

[event]
	name=start
		[store_unit]
			[filter]
				canrecruit=yes
				side=1
			[/filter]
			variable=playerstore[1]
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=2
			[/filter]
			variable=playerstore[2]
		[/store_unit]
I think you can only do it like this:

Code: Select all

[event]
	name=start
		[store_unit]
			[filter]
				canrecruit=yes
				side=1
			[/filter]
			variable=playerstore[1].unit
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=2
			[/filter]
			variable=playerstore[2].unit
		[/store_unit]
And then access it with playerstore[2].unit.x etc

2) I don't think you need to use $lastplayer because i think that $side_number on side turn event is the same as $side_number on turn refresh event..

3) before you start troubleshooting your filters, see if your array is stored at all.. if you dont want to use the easiest thing (debug/inspect command) then just make some kind of turn refresh event with just [chat] message="$playerstore[1].x" [/chat] to display what is contained in the x of playerstore[1] if anything at all.
User avatar
josteph
Inactive Developer
Posts: 741
Joined: August 19th, 2017, 6:58 pm

Re: Move leader back to keep every turn -- Code not working

Post by josteph »

I'd forget about arrays for now. Just write it only for one particular side. When you have that working, then start seeing about making it work for N sides without code duplication (using arrays, or macros or whatever else).
Kharn
Posts: 83
Joined: December 12th, 2005, 7:50 pm
Location: Dallas, Tx

Re: Move leader back to keep every turn -- Code not working

Post by Kharn »

Great I finally got the code working, had to fix a few more things like adding a $ for example, setting the billstore back to zero, pointlessly filling array location 0 so there is not an empty array position and so the player numbers match up with array locations, and adding a check to only run code if a unit is blocking, otherwise the kill command kills the leader and ends the game. With all of that fixed....

The following code stores the starting locations of up to 6 leaders into variables. Every turn it stores the side number of the current player to get around limitations in some code that requires a side number to be used instead of defaulting to the current side when no side number is specified. It then looks for all units with canrecruit=1 owned by the current player that are not in the location the leader started in at the beginning of game. If the canrecruit unit is not on the leaders starting location it next checks if the starting location is blocked by a different unit. If so that unit is killed to make room for the canrecruit unit to move back to the keep. The killed unit is refunded at 75% of its value to the controller. Then finally, all canrecruit units are moved as close to the starting location as the leader as possible.

Code: Select all


	[event]
	name=start
		[store_unit]
			[filter]
				canrecruit=yes
				side=1
			[/filter]
			variable=playerstore[0].unit
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=1
			[/filter]
			variable=playerstore[1].unit
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=2
			[/filter]
			variable=playerstore[2].unit
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=3
			[/filter]
			variable=playerstore[3].unit
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=4
			[/filter]
			variable=playerstore[4].unit
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=5
			[/filter]
			variable=playerstore[5].unit
		[/store_unit]
		[store_unit]
			[filter]
				canrecruit=yes
				side=6
			[/filter]
			variable=playerstore[6].unit
		[/store_unit]
	[/event]

	[event]
		name=side turn
		first_time_only=no
		{VARIABLE lastplayer $side_number}
	[/event]

	[event]
		name=turn refresh
		first_time_only=no
		[if]
			[have_unit]
				canrecruit=yes
				side=$lastplayer
				[not]
						x,y=$playerstore[$lastplayer].unit.x,$playerstore[$lastplayer].unit.y
				[/not]
			[/have_unit]
		[then]
			[if]
				[have_unit]
					side=$lastplayer
					x,y=$playerstore[$lastplayer].unit.x,$playerstore[$lastplayer].unit.y
				[/have_unit]			
			[then]
				[store_unit]
					[filter]
						x=$playerstore[$lastplayer].unit.x
						y=$playerstore[$lastplayer].unit.y
					[/filter]
					variable=billstore
				[/store_unit]
				{VARIABLE billworth $billstore.cost}
				{VARIABLE_OP billworth multiply 0.75}
				[gold]
					amount=$billworth
					side=$lastplayer
				[/gold]
				[kill]
					x=$playerstore[$lastplayer].unit.x
					y=$playerstore[$lastplayer].unit.y					
					animate=no
					fire_event=no
				[/kill]
				{VARIABLE billworth 0}
			[/then]
			[/if]
			[move_unit]
				canrecruit=yes
				side=$lastplayer
				to_x=$playerstore[$lastplayer].unit.x
				to_y=$playerstore[$lastplayer].unit.y
				#force_scroll=yes
			[/move_unit]
		[/then]
		[/if]
	[/event]
	


Creator of 120+ units Lord of the Rings era and campaign now outdated & lost.
Creator of WWII Battleground Europe mod with 120+ units most with custom wml and animations. Every variable is mathematically derived based on WWII stats such as historical cost & mm armour.
User avatar
josteph
Inactive Developer
Posts: 741
Joined: August 19th, 2017, 6:58 pm

Re: Move leader back to keep every turn -- Code not working

Post by josteph »

Note that units other than the leader can have canrecruit=yes. Right now your code considers it okay for any canrecruit=yes unit to be at the target x,y, not just the leader. If you don't want that you'd best save the leader's .id and use that in tests (id=$leader[1].id instead of canrecruit=yes).
Kharn
Posts: 83
Joined: December 12th, 2005, 7:50 pm
Location: Dallas, Tx

Re: Move leader back to keep every turn -- Code not working

Post by Kharn »

Canrecruit stopped working back when 1.12 came out. Ever since only able to recruit with my leader. I removed canrecruit=yes from other units to be safe though since it was not being used anyway.
Creator of 120+ units Lord of the Rings era and campaign now outdated & lost.
Creator of WWII Battleground Europe mod with 120+ units most with custom wml and animations. Every variable is mathematically derived based on WWII stats such as historical cost & mm armour.
User avatar
beetlenaut
Developer
Posts: 2813
Joined: December 8th, 2007, 3:21 am
Location: Washington State
Contact:

Re: Move leader back to keep every turn -- Code not working

Post by beetlenaut »

Kharn wrote: October 26th, 2018, 11:30 am Canrecruit stopped working back when 1.12 came out.
Mainline campaigns Secrets of the Ancients and Legend of Wesmere both have multiple units with canrecruit=yes. It must be working pretty well, or everyone would have noticed.
Campaigns: Dead Water,
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
Post Reply