Way to match a group of units to a dying unit

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
User avatar
Nyanyanyan
Posts: 73
Joined: May 11th, 2018, 10:40 pm

Way to match a group of units to a dying unit

Post by Nyanyanyan »

Hi, I'm trying to match a group of units to a specific leader, to switch them all over to another side once that specific leader dies.

I tried this by giving every unit of that "batch" and their leader a status that's just a running number ($rebellionnumber, starting from 1001).
Now I'm trying to match the death event of the leader to the side switch of the units. However I haven't had much success with what I tried.

Code: Select all

[event]
id=loyalistswin
name=die
first_time_only=no

[filter]
	side=2
	canrecruit=yes
[/filter]

[set_variable]
	name=statuscount
	value=1001
[/set_variable]

#rebellionnumber starts at 1001

{REPEAT "$($rebellionnumber-1000)" (
	[heal_unit]
		side=2
		ammount=100
	[/heal_unit]
	[if]
	[have_unit]
		id=$unit.id
		[and]
		[filter_wml]
			status=$statuscount
		[/filter_wml]
		[/and]
	[/have_unit]
	[then]
		[modify_unit]
			[filter]
				status=$statuscount
			[/filter]
			side=1
		[/modify_unit]
	[/then]
	[/if]
	[set_variable]
		name=statuscount
		add=1
	[/set_variable]

)}
	{CLEAR_VARIABLE statuscount}
	
Basically what this is supposed to do is first of all heal all units of the faction so [have_unit] sees the dying leader.
Then iterate the following once for however many rebellions there have been:
If the dying unit (which is a leader) has a particular status (which are just running numbers for the batches, starting from 1001), then put all units with that same status from side 2 to side 1.
This should go over all possible statuses (the highest being $rebellionnumber) and then stop.

Problem is, that this is not what's happening.
What am I doing wrong?
If there are any easier ways to do this I'm of course also interested, though I'd still like to know where I made a mistake here.
Author of Age of Lords and the Revolution and Civil War and Expendable Leaders 2 multiplayer mods.
User avatar
Ravana
Forum Moderator
Posts: 3002
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: Way to match a group of units to a dying unit

Post by Ravana »

> ammount=100

I would save leaders id, instead of arbitrary index. Then modify units that have variable with value=$unit.id. Then no loop needed.
User avatar
octalot
General Code Maintainer
Posts: 786
Joined: July 17th, 2010, 7:40 pm
Location: Austria

Re: Way to match a group of units to a dying unit

Post by octalot »

What Ravana said :D

Minor comments:
* In one place, you're using [filter], to search for the status, but in another [filter_wml]. One or the other is probably wrong.
* In Wesnoth 1.14, the REPEAT macro can be replaced with the easier-to-read [for] and [foreach].

For debugging, I'd suggest trying to split the problem in to simpler problems:
1. Find out which rebellion this leader was connected to
2. Find other units in that rebellion
3. Modify those other units

The WML functions are making 2. and 3. hard to split, but there's an easy split between 1. and 2. - after the code has worked out which rebellion it is, add a [message] saying something like "Rebellion $counter has surrendered.", and see if the expected identifier is printed.
User avatar
Nyanyanyan
Posts: 73
Joined: May 11th, 2018, 10:40 pm

Re: Way to match a group of units to a dying unit

Post by Nyanyanyan »

Thank you guys, that helped a lot. I wasn't aware of unit variables at all.
I gave the rebel leader a variable corresponding to his previous side, gave the units for that leader a variable with a value that is his id and upon the death of any rebel leader I just filter all units with his id as a value for that variable and put them on the side of the value of the variable the dying leader has.

For anyone who has the same problem, here's the relevant code:

Code: Select all

[event]
id=rebellion
name=die
first_time_only=no
	[filter]
	canrecruit=yes
	[and]
		[not]
			[filter_wml]
				[status]
					warlord=yes
				[/status]
			[/filter_wml]
		[/not]
	[/and]
	[/filter]
  [store_unit]
     [filter]
        x,y=$x1,$y1
		canrecruit=yes
     [/filter]
     variable=leaderdead
  [/store_unit] 
	
	[store_unit]
        [filter]
            side=$leaderdead.side
			[and]
				[not]
				canrecruit=yes
				[/not]
			[/and]
        [/filter]
        variable=leaderdeadwarlordcandidates
	[/store_unit]
   

	[set_variable]
		name=countingvariable
		value=0
	[/set_variable]
	
	{FOREACH leaderdeadwarlordcandidates i}	
	[if]
	[variable]  
        name=countingvariable
        equals="0"  
    [/variable] 
	[then]
		[modify_unit]
			[filter]
				id=$leaderdeadwarlordcandidates[$i].id
			[/filter]
			canrecruit=yes
		[/modify_unit]
		[set_variable]
			name=countingvariable
			value=1
		[/set_variable]
	[/then]
	
	[elseif]
	[variable]  
        name=countingvariable
        equals="1"  
    [/variable] 
	[then]
		[unit_overlay]
			x,y=$x1,$y1
			image=misc/hero-icon.png
		[/unit_overlay]
		[store_unit]
			[filter]
				id=$leaderdeadwarlordcandidates[$i].id
			[/filter]
			variable=rebellionleader
		[/store_unit]
		[store_unit]
			[filter]
				id=$leaderdeadwarlordcandidates[$i].id
			[/filter]
			variable=$leaderdeadwarlordcandidates[$i].id
		[/store_unit]
		[modify_unit]
			[filter]
				id=$leaderdeadwarlordcandidates[$i].id
			[/filter]
			side=$sideslider
			canrecruit=yes
			[effect]
               			 apply_to=status
				add=warlord
			[/effect]
			[variables]
			rebelleaderside=$this_unit.side
			[/variables]
		[/modify_unit]
		[set_variable]
			name=countingvariable
			value=2
		[/set_variable]
	[/then]
	[/elseif]
	
	[else]
		{CLEAR_VARIABLE leaderdeadwarlordcandidates}
	[/else]
	
	[/if]
		{NEXT i}
		{CLEAR_VARIABLE countingvariable}
  
  [store_unit]
        [filter]
            side=$leaderdead.side
			[and]
				[not]
				canrecruit=yes
				[/not]
			[/and]
			[or]
			side=$leaderdead.side
			[and]
				canrecruit=yes
			[/and]
			[and]
				[filter_wml]
					[status]
						general=yes
					[/status]
				[/filter_wml]
			[/and]
			[/or]
        [/filter]
        variable=leaderdeadsideunits
   [/store_unit]
   

	[set_variable]
		name=alternatingvariable
		value=1
	[/set_variable]
	[set_variable]
		name=newrebelleader
		value=$rebellionleader.id
	[/set_variable]
	{FOREACH leaderdeadsideunits i}	
	[if]
	[variable]  
        name=alternatingvariable
        equals="0"  
    [/variable] 
	
	[then]
		[modify_unit]
			[filter]
				id=$leaderdeadsideunits[$i].id
			[/filter]
			side=$sideslider
			[variables]
			rebelleaderid=$newrebelleader
			[/variables]
		[/modify_unit]

		[set_variable]
			name=alternatingvariable
			value=1
		[/set_variable]
	[/then]
	
	
	[else]
		[set_variable]
			name=alternatingvariable
			value=0
		[/set_variable]
	[/else]
	
	[/if]
		{NEXT i}
		{CLEAR_VARIABLE leaderdeadsideunits}
		{CLEAR_VARIABLE rebellionleader}
		{CLEAR_VARIABLE newrebelleader}
		{CLEAR_VARIABLE alternatingvariable}

[/event]
Author of Age of Lords and the Revolution and Civil War and Expendable Leaders 2 multiplayer mods.
User avatar
Celtic_Minstrel
Developer
Posts: 2207
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Way to match a group of units to a dying unit

Post by Celtic_Minstrel »

You should use [filter]status=warlord to match statuses, instead of [filter_wml].
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
Post Reply