Two weapon specials with nearly identical codes - one works, one doesn't

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
DopeKiwiWarrior
Posts: 30
Joined: January 27th, 2013, 4:04 pm
Location: Inside your mom, she ate me, send help before I dissolve.

Two weapon specials with nearly identical codes - one works, one doesn't

Post by DopeKiwiWarrior »

Hello,

I am creating two weapon specials that move units after they attack - recoil and leap. Recoil moves the unit backwards, leap moves it behind its opponent. It works alright until two units with the same special attack each other. I fixed it by adding another version of the special event. The one for leap works flawlessly but the one for recoil produces around 50 lines of "error engine: failed to auto-store $second_unit at (x,y)" in the error log without producing the right result despite the codes being identical only with different variables. Can you help me fix this?
Leap code (works)

Code: Select all

#define WEAPON_SPECIAL_LEAP
	[dummy]
		id=leap
		name=_ "leap"
		description=_ "At the end of the attack, this unit is moved behind the unit it was attacking."
	[/dummy]
	[/specials]
	[/attack]
	[event]
		name=attack end
		first_time_only=no
		id=leap second_unit event
		[filter_second_attack]
			special=leap
		[/filter_second_attack]
		[filter_attack]
			[not]
				special=leap
			[/not]
		[/filter_attack]
		[store_locations]
            [filter_adjacent_location]
                x,y=$x1,$y1
                adjacent=-$second_unit.facing
            [/filter_adjacent_location]
            variable=leap_hex
   		[/store_locations]
		[store_unit]
	        [filter]
                x,y=$x2,$y2
            [/filter]
    	    kill=yes
 	       variable=leaper
        [/store_unit]
        {MOVE_XP_GIVER unit leaper}
    	[if]
    	[and]
    	[not]
	        [have_unit]
	        	x,y=$leap_hex.x,$leap_hex.y
	        [/have_unit]
        [/not]
        [not]
        	[have_location]
        		x,y=$leap_hex.x,$leap_hex.y
        		terrain=Q*,Mv,*^Xm,X*,*^P*,*^Xo,*^Qov
        	[/have_location]
        [/not]
        [/and]
        [then]        
	        [unstore_unit]
	            variable=leaper
	            x,y=$leap_hex.x,$leap_hex.y
	        [/unstore_unit]
	        [capture_village]
	            x,y=$leap_hex.x,$leap_hex.y
	            side=$leaper.side
	        [/capture_village]
	    [/then]
	    [else]
	        	[unstore_unit]
	        		variable=leaper
				[/unstore_unit]	        
	    [/else]
	    [/if]
		{CLEAR_VARIABLE leap_hex}			
	[/event]
	[event]
		name=attack end
		first_time_only=no
		id=leap unit event
		[filter_attack]
			special=leap
		[/filter_attack]
		[filter_second_attack]
			[not]
				special=leap
			[/not]
		[/filter_second_attack]
		[store_locations]
            [filter_adjacent_location]
                x,y=$x2,$y2
                adjacent=-$unit.facing
            [/filter_adjacent_location]
            variable=leap_hex
        [/store_locations]
		[store_unit]
            [filter]
                x,y=$x1,$y1
            [/filter]
            kill=yes
            variable=leaper
        [/store_unit]
        {MOVE_XP_GIVER second_unit leaper}
        [if]
        	[and]
        	[not]
		        [have_unit]
		        	x,y=$leap_hex.x,$leap_hex.y
		        [/have_unit]
		    [/not]
	        [not]
	        	[have_location]
	        		x,y=$leap_hex.x,$leap_hex.y
	        		terrain=Q*,Mv,*^Xm,X*,*^P*,*^Xo,*^Qov
	        	[/have_location]
	        [/not]
	        [/and]
	        [then]
		        [unstore_unit]
		            variable=leaper
		            x,y=$leap_hex.x,$leap_hex.y
		        [/unstore_unit]
		        [capture_village]
		            x,y=$leap_hex.x,$leap_hex.y
		            side=$leaper.side
		        [/capture_village]
	        [/then]
	        [else]
	        	[unstore_unit]
	        		variable=leaper
				[/unstore_unit]	        
	        [/else]
        [/if]
		{CLEAR_VARIABLE leap_hex}
	[/event]
	[event]
		name=attack end
		first_time_only=no
		id=double leap event
		[filter_attack]
			special=leap
		[/filter_attack]
		[filter_second_attack]
			special=leap
		[/filter_second_attack]
		[store_locations]
            [filter_adjacent_location]
                x,y=$x2,$y2
                adjacent=-$unit.facing
            [/filter_adjacent_location]
            variable=leap_hex1
        [/store_locations]
		[store_unit]
            [filter]
                x,y=$x1,$y1
            [/filter]
            kill=yes
            variable=leaper1
        [/store_unit]
        {MOVE_XP_GIVER second_unit leaper1}
        [if]
        	[and]
        	[not]
		        [have_unit]
		        	x,y=$leap_hex1.x,$leap_hex1.y
		        [/have_unit]
		    [/not]
	        [not]
	        	[have_location]
	        		x,y=$leap_hex1.x,$leap_hex1.y
	        		terrain=Q*,Mv,*^Xm,X*,*^P*,*^Xo,*^Qov
	        	[/have_location]
	        [/not]
	        [/and]
	        [then]
		        [unstore_unit]
		            variable=leaper1
		            x,y=$leap_hex1.x,$leap_hex1.y
		        [/unstore_unit]
		        [capture_village]
		            x,y=$leap_hex1.x,$leap_hex1.y
		            side=$leaper1.side
		        [/capture_village]
	        [/then]
	        [else]
	        	[unstore_unit]
	        		variable=leaper1
				[/unstore_unit]	        
	        [/else]
        [/if]
        [store_locations]
            [filter_adjacent_location]
                x,y=$x1,$y1
                adjacent=-$second_unit.facing
            [/filter_adjacent_location]
            variable=leap_hex2
   		[/store_locations]
		[store_unit]
	        [filter]
                x,y=$x2,$y2
            [/filter]
    	    kill=yes
 	       variable=leaper2
        [/store_unit]
        {MOVE_XP_GIVER unit leaper2}
    	[if]
    	[and]
    	[not]
	        [have_unit]
	        	x,y=$leap_hex2.x,$leap_hex2.y
	        [/have_unit]
        [/not]
        [not]
        	[have_location]
        		x,y=$leap_hex2.x,$leap_hex2.y
        		terrain=Q*,Mv,*^Xm,X*,*^P*,*^Xo,*^Qov
        	[/have_location]
        [/not]
        [/and]
        [then]        
	        [unstore_unit]
	            variable=leaper2
	            x,y=$leap_hex2.x,$leap_hex2.y
	        [/unstore_unit]
	        [capture_village]
	            x,y=$leap_hex2.x,$leap_hex2.y
	            side=$leaper2.side
	        [/capture_village]
	    [/then]
	    [else]
	        	[unstore_unit]
	        		variable=leaper2
				[/unstore_unit]	        
	    [/else]
	    [/if]
		{CLEAR_VARIABLE leap_hex1,leap_hex2}
	[/event]
	[+attack]
	[+specials]
#enddef
Recoil code (bugs out)

Code: Select all

#define WEAPON_SPECIAL_RECOIL
	[dummy]
		id=recoil
		name=_ "recoil"
		description=_ "At the end of the attack, this unit is moved backwards."
	[/dummy]
	[/specials]
	[/attack]
	[event]
		name=attack end
		first_time_only=no
		id=recoil second_unit event
		[filter_second_attack]
			special=recoil
		[/filter_second_attack]
		[filter_attack]
			[not]
				special=recoil
			[/not]
		[/filter_attack]
		[store_locations]
            [filter_adjacent_location]
                x,y=$x2,$y2
                adjacent=-$unit.facing
            [/filter_adjacent_location]
            variable=recoil_hex
        [/store_locations]
		[store_unit]
        	[filter]
                x,y=$x2,$y2
            [/filter]
           kill=yes
           variable=recoiled
        [/store_unit]
        {MOVE_XP_GIVER unit recoiled}
        [if]
        	[and]
        	[not]
		        [have_unit]
		        	x,y=$recoil_hex.x,$recoil_hex.y
		        [/have_unit]
	        [/not]
	        [not]
	        	[have_location]
	        		x,y=$recoil_hex.x,$recoil_hex.y
	        		terrain=Q*,Mv,*^Xm,X*,*^P*,*^Xo,*^Qov
	        	[/have_location]
	        [/not]
	        [/and]
	        [then]
			    [unstore_unit]
			        variable=recoiled
			        x,y=$recoil_hex.x,$recoil_hex.y
			   	[/unstore_unit]
			    [capture_village]
			        x,y=$recoil_hex.x,$recoil_hex.y
			        side=$recoiled.side
			    [/capture_village]
		    [/then]
	        [else]
	        	[unstore_unit]
	        		variable=recoiled
				[/unstore_unit]	        
	        [/else]
        [/if]
		{CLEAR_VARIABLE recoil_hex}
	[/event]
	[event]
		name=attack end
		first_time_only=no
		id=recoil unit event
		[filter_attack]
			special=recoil
		[/filter_attack]
		[filter_second_attack]
			[not]
				special=recoil
			[/not]
		[/filter_second_attack]
		[store_locations]
            [filter_adjacent_location]
                x,y=$x1,$y1
                adjacent=-$second_unit.facing
            [/filter_adjacent_location]
            variable=recoil_hex
        [/store_locations]
			[store_unit]
                [filter]
                    x,y=$x1,$y1
                [/filter]
           	kill=yes
           	variable=recoiled
        [/store_unit]
        {MOVE_XP_GIVER second_unit recoiled}
        [if]
        	[and]
        	[not]
		        [have_unit]
		        	x,y=$recoil_hex.x,$recoil_hex.y
		        [/have_unit]
	        [/not]
	        [not]
	        	[have_location]
	        		x,y=$recoil_hex.x,$recoil_hex.y
	        		terrain=Q*,Mv,*^Xm,X*,*^P*,*^Xo,*^Qov
	        	[/have_location]
	        [/not]
	        [/and]
	        [then]
		        [unstore_unit]
		            variable=recoiled
		            x,y=$recoil_hex.x,$recoil_hex.y
		        [/unstore_unit]
		        [capture_village]
		            x,y=$recoil_hex.x,$recoil_hex.y
		            side=$recoiled.side
		        [/capture_village]
	        [/then]
	        [else]
	        	[unstore_unit]
	        		variable=recoiled
				[/unstore_unit]	        
	        [/else]	        
        [/if]
		{CLEAR_VARIABLE recoil_hex}
	[/event]
	[event]
		name=attack end
		first_time_only=no
		id=double recoil event
		[filter_attack]
			special=recoil
		[/filter_attack]
		[filter_second_attack]
			special=recoil
		[/filter_second_attack]
		[store_locations]
            [filter_adjacent_location]
                x,y=$x2,$y2
                adjacent=-$unit.facing
            [/filter_adjacent_location]
            variable=recoil_hex1
        [/store_locations]
		[store_unit]
        	[filter]
                x,y=$x2,$y2
            [/filter]
           kill=yes
           variable=recoiled1
        [/store_unit]
        {MOVE_XP_GIVER unit recoiled1}
        [if]
        	[and]
        	[not]
		        [have_unit]
		        	x,y=$recoil_hex1.x,$recoil_hex1.y
		        [/have_unit]
	        [/not]
	        [not]
	        	[have_location]
	        		x,y=$recoil_hex1.x,$recoil_hex1.y
	        		terrain=Q*,Mv,*^Xm,X*,*^P*,*^Xo,*^Qov
	        	[/have_location]
	        [/not]
	        [/and]
	        [then] 
			    [unstore_unit]
			        variable=recoiled1
			        x,y=$recoil_hex1.x,$recoil_hex1.y
			   	[/unstore_unit]
			    [capture_village]
			        x,y=$recoil_hex1.x,$recoil_hex1.y
			        side=$recoiled1.side
			    [/capture_village]
		    [/then]
	        [else]
	        	[unstore_unit]
	        		variable=recoiled1
				[/unstore_unit]	        
	        [/else]
        [/if]
        [store_locations]
            [filter_adjacent_location]
                x,y=$x1,$y1
                adjacent=-$second_unit.facing
            [/filter_adjacent_location]
            variable=recoil_hex2
        [/store_locations]
		[store_unit]
        	[filter]
                x,y=$x1,$y1
            [/filter]
           kill=yes
           variable=recoiled2
        [/store_unit]
        {MOVE_XP_GIVER second_unit recoiled2}
        [if]
        	[and]
        	[not]
		        [have_unit]
		        	x,y=$recoil_hex2.x,$recoil_hex2.y
		        [/have_unit]
	        [/not]
	        [not]
	        	[have_location]
	        		x,y=$recoil_hex2.x,$recoil_hex2.y
	        		terrain=Q*,Mv,*^Xm,X*,*^P*,*^Xo,*^Qov
	        	[/have_location]
	        [/not]
	        [/and]
	        [then] 
			    [unstore_unit]
			        variable=recoiled2
			        x,y=$recoil_hex2.x,$recoil_hex2.y
			   	[/unstore_unit]
			    [capture_village]
			        x,y=$recoil_hex2.x,$recoil_hex2.y
			        side=$recoiled2.side
			    [/capture_village]  
		    [/then]
	        [else]
	        	[unstore_unit]
	        		variable=recoiled2
				[/unstore_unit]	        
	        [/else]
        [/if]
	    {CLEAR_VARIABLE recoil_hex1,recoil_hex2}
	[/event]
	[+attack]
	[+specials]
#enddef
MOVE_XP_GIVER macro just in case

Code: Select all

#define MOVE_XP_GIVER UNITVAR ADDVAR
		{VARIABLE killxp ${UNITVAR}.level}
		[store_unit]
			[filter]
				id=${UNITVAR}.id
			[/filter]
			variable=unitvar
		[/store_unit]
		[if]
			[variable]
				name=unitvar.hitpoints
				less_than_equal_to=0
			[/variable]
			[then]
				[if]
		        	[variable]
		        		name=killxp
		        		equals=0
		        	[/variable]
		        	[then]
		        		{VARIABLE killxp 4}
		        	[/then]
		        	[else]
						{VARIABLE_OP killxp multiply 8}
		        	[/else]
		        [/if]					      
		    [/then]
	    [/if]
	    [unstore_unit]
	    	variable=unitvar
	    [/unstore_unit]
	    {VARIABLE_OP {ADDVAR}.experience add $killxp}
        {CLEAR_VARIABLE killxp}
#enddef
Creator of Moonday Era, go check it out! (And critique the hell out of it, because it needs it.)
User avatar
Ravana
Forum Moderator
Posts: 2482
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: Two weapon specials with nearly identical codes - one works, one doesn't

Post by Ravana »

Sounds like race condition, one event tries to store unit that has already been moved away.
User avatar
DopeKiwiWarrior
Posts: 30
Joined: January 27th, 2013, 4:04 pm
Location: Inside your mom, she ate me, send help before I dissolve.

Re: Two weapon specials with nearly identical codes - one works, one doesn't

Post by DopeKiwiWarrior »

Ravana wrote: May 20th, 2018, 12:31 pm Sounds like race condition, one event tries to store unit that has already been moved away.
It's really a problem of the succession? My god why haven't I tried that.
Creator of Moonday Era, go check it out! (And critique the hell out of it, because it needs it.)
Post Reply