Eagle WML Questions: how to filter disabled attacks? +more

The place to post your WML questions and answers.

Moderators: Forum Moderators, Developers

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.
User avatar
Eagle_11
Forum Regular
Posts: 672
Joined: November 20th, 2013, 12:20 pm

Re: Help me to identify this error

Post by Eagle_11 » January 31st, 2018, 8:40 pm

Returning to that question, how to filter out multiple [specials] id= in that same [filter_wml], or can it be not done ? Have to filter out both [berserk] id=berserk and id=rage for an different version.


The unit that has this attack is a ghast that also has feeding abil, when affected unit dies at death event lua spouts some error regarding feeding, possibly due to plague+feeding not playing along ? seems to be functioning as intended otherwise.

Code: Select all

#define SPECIAL_NOTES_EXI_INFECTION
_" 
this unit has an attack that poisons the living in a very special way, infecting them to become zombies upon death."#enddef
#define WEAPON_SPECIAL_EXI_INFECTION
    [poison]
		id=exi_infects
		name=_"infection"
		description= _ "This attack poisons living targets, infecting them in a very special way. Units poisoned by an attack with this special lose 8 HP every turn until they are cured or the plague destroys their mind, turning them into a Zombie.

Also if this attack kills the opponent it will be replaced with an Zombie."
    [/poison]
	[plague]
		id=exi_infects_plague
		name=""
		description=""
		type="Exi Zombie"
	[/plague]
#enddef

#define EVENTS_EXI_INFECTION
    [event]
         name=preload
         first_time_only=no
         id=exi_show_infection
         [lua]
             code=<<
                 local _ = wesnoth.textdomain "wesnoth-Uber_Default"
                 local old_unit_status = wesnoth.theme_items.unit_status
                 function wesnoth.theme_items.unit_status()
                     local u = wesnoth.get_displayed_unit()
                     if not u then return {} end
                     local s = old_unit_status()
                     if u.status.is_infected then
                         table.insert(s, { "element", {
                             image = "misc/zombie_option.png",
                             tooltip = _"This unit is infected. It will lose 8 hp every turn and will be turned into a Zombie after death."
                         } })
                     end
                     return s
                 end
             >>
         [/lua]
    [/event]

#unsure if needed
#    [event]
#		name=attack
#		first_time_only=yes
#		id=exi_fire_infect_preload_event
#		[fire_event]
#			name=preload
#		[/fire_event]
#    [/event]

    [event]
        name=attacker_hits
        first_time_only=no
        [filter_attack]
            special=exi_infects
        [/filter_attack]
        [filter_second]
            [not]
                [filter_wml]
                    [status]
                        not_living=yes
                    [/status]
                [/filter_wml]
            [/not]
        [/filter_second]
        [modify_unit]
            [filter]
                id=$second_unit.id
            [/filter]
            [status]
                is_infected=yes
            [/status]
            [variables]
                infected_by_side=$unit.side
                infected_type="Exi Zombie"
                #canrecruit=no
            [/variables]
        [/modify_unit]
		[object]
			silent=yes
            duration=turn end
			[filter]
				id=$second_unit.id
			[/filter]
			[effect]
				apply_to=image_mod
				add="CS(-50,-30,-50)"
			[/effect]
		[/object]
    [/event]
    [event]
        name=defender_hits
        first_time_only=no
        [filter_second_attack]
            special=exi_infects
        [/filter_second_attack]
        [filter]
            [not]
                [filter_wml]
                    [status]
                        not_living=yes
                    [/status]
                [/filter_wml]
            [/not]
        [/filter]
        [modify_unit]
            [filter]
                id=$unit.id
            [/filter]
            [status]
                is_infected=yes
            [/status]
            [variables]
                infected_by_side=$second_unit.side
                infected_type="Exi Zombie"
                #canrecruit=no
            [/variables]
        [/modify_unit]
		[object]
			silent=yes
            duration=turn end
			[filter]
				id=$unit.id
			[/filter]
			[effect]
				apply_to=image_mod
				add="CS(-50,-30,-50)"
			[/effect]
		[/object]
    [/event]
#apply it
    [event]
        name=turn refresh
        first_time_only=no
        [store_unit]
            [filter]
                [filter_wml]
                    [status]
                        is_infected=yes
                    [/status]
                [/filter_wml]
                [and]
                    [filter_side]
                        side=$side_number
                    [/filter_side]
                [/and]
                [and]
                    [filter_wml]
                        hitpoints=1
                    [/filter_wml]
                [/and]
            [/filter]
            variable=zombie_store
            kill=yes
        [/store_unit]

        {FOREACH zombie_store i}
			[unit]
                side=$zombie_store[$i].variables.infected_by_side
                x=$zombie_store[$i].x
                y=$zombie_store[$i].y
                variation=$zombie_store[$i].undead_variation
                type=$zombie_store[$i].variables.infected_type
                moves=0
                facing=$zombie_store[$i].facing
                attacks_left=0
                animate=no
            [/unit]
            [fire_event]
                name=last_breath
                [primary_unit]
                    x,y=$zombie_store[$i].x,$zombie_store[$i].y
                [/primary_unit]
            [/fire_event]
            [fire_event]
                name=die
                [primary_unit]
                    x,y=$zombie_store[$i].x,$zombie_store[$i].y
                [/primary_unit]
            [/fire_event]
        {NEXT i}

        {CLEAR_VARIABLE zombie_store}

#desinfect adjacent to healer
        [store_unit]
            [filter]
                [filter_wml]
                    [status]
                        is_infected=yes
                    [/status]
                [/filter_wml]
                [and]
                    [filter_side]
                        side=$side_number
                    [/filter_side]
                [/and]
                [and]
                    [filter_adjacent]
                        ability=exi_healing
						[or]
							ability=exi_herbalism
						[/or]
                    [/filter_adjacent]
                [/and]
                [or]
                    [filter_wml]
                        [status]
                            is_infected=yes
                        [/status]
                    [/filter_wml]
                    [and]
                        [filter_side]
                            side=$side_number
                        [/filter_side]
                    [/and]
                    [and]
                        [filter_location]
                            terrain=*^V*
                        [/filter_location]
                    [/and]
                [/or]
            [/filter]
            variable=unzombie_store
            kill=yes
        [/store_unit]

        {FOREACH unzombie_store i}
            {CLEAR_VARIABLE unzombie_store[$i].status.is_infected}
            {CLEAR_VARIABLE unzombie_store[$i].variables.infected_by_side}
            {CLEAR_VARIABLE unzombie_store[$i].variables.infected_type}
            [unstore_unit]
                variable=unzombie_store[$i]
                find_vacant=no
            [/unstore_unit]
        {NEXT i}

        {CLEAR_VARIABLE unzombie_store}
    [/event]
#spawn the zombie on death
    [event]
        name=die
        first_time_only=no
        [filter]
            [filter_wml]
                [status]
                    is_infected=yes
                [/status]
            [/filter_wml]
        [/filter]
        [store_unit]
            [filter]
                id=$unit.id
            [/filter]
            variable=zombie_store
            kill=yes
        [/store_unit]
        [unit]
            side=$zombie_store.variables.infected_by_side
            x=$zombie_store.x
            y=$zombie_store.y
            variation=$zombie_store.undead_variation
            type=$zombie_store.variables.infected_type
            moves=0
            facing=$zombie_store.facing
            attacks_left=0
            animate=no
        [/unit]
        {CLEAR_VARIABLE zombie_store}
    [/event]
#clean at game end
    [event]
	name=victory
	first_time_only=no
        [store_unit]
            [filter]
                [filter_wml]
                    [status]
                        is_infected=yes
                    [/status]
                [/filter_wml]
            [/filter]
            variable=unzombie_store
            kill=yes
        [/store_unit]
        {FOREACH unzombie_store i}
            {CLEAR_VARIABLE unzombie_store[$i].status.is_infected}
            {CLEAR_VARIABLE unzombie_store[$i].variables.infected_by_side}
            {CLEAR_VARIABLE unzombie_store[$i].variables.infected_type}
            [unstore_unit]
                variable=unzombie_store[$i]
                find_vacant=no
            [/unstore_unit]
        {NEXT i}
        {CLEAR_VARIABLE unzombie_store}
    [/event]
#enddef

User avatar
zookeeper
WML Wizard
Posts: 9685
Joined: September 11th, 2004, 10:40 pm
Location: Finland

Re: Help me to identify this error

Post by zookeeper » January 31st, 2018, 9:22 pm

Eagle_11 wrote:Returning to that question, how to filter out multiple [specials] id= in that same [filter_wml], or can it be not done ?
Can't be done. You need multiple [filter_wml] blocks for that.

On that note, you're unnecessarily using [and] everywhere. You can have multiple condition/filter tags side-by-side, you don't have to wrap everything following the first one in an [and].

User avatar
Eagle_11
Forum Regular
Posts: 672
Joined: November 20th, 2013, 12:20 pm

Re: Help me to identify this error

Post by Eagle_11 » February 1st, 2018, 10:04 am

Code: Select all

#define WEAPON_SPECIAL_EXI_RAGE
    [berserk]
        id=exi_rage
        name= _ "rage"
        description= _ "Whether used offensively or defensively, this attack presses the engagement until one of the combatants is slain, or 3 rounds of combat have occurred."
        value=3
    [/berserk]
#enddef
#define SPECIAL_NOTES_EXI_RAGE
_" 
This unit has an attack that prolongs the melee combat for 3 more rounds."#enddef


#define SPECIAL_NOTES_EXI_FURY_OF_AGES
_" 
This unit is capable of instilling rage inside the allied units, causing them to fight with 'rage' weapon-special in melee."#enddef
#define ABILITY_EXI_FURY_OF_AGES
    [dummy]
        id=exi_furyofages
        name= _ "fury of ages"
        description= _ "all adjacent friendly units will gain 'rage' on their melee."
    [/dummy]
[/abilities]
	[event]
		name=side turn
		first_time_only=no
		[store_unit]
			[filter]
				[filter_wml]
				    [variables]
						raged_counter=1
					[/variables]
				[/filter_wml]
			[/filter]
			variable=rage_refresh
		[/store_unit]

		{FOREACH rage_refresh i}
			{CLEAR_VARIABLE rage_refresh[$i].attack.specials.berserk }
			{VARIABLE rage_refresh[$i].variables.raged_counter 0}
			[unstore_unit]
				variable=rage_refresh[$i]
			[/unstore_unit]
		{NEXT i}

		[store_unit]
			[filter]
				side=$side_number
				#as an bandaid can make it drake only since they not have any zerkers, however would prefer not limiting abilities to race...
				#race=exi_drake
				[filter_adjacent]
				    ability=exi_furyofages
					is_enemy=no
				[/filter_adjacent]

				#current: manages to filter out id=berserk but not id=exi_rage, that when second is [filter_wml] left on its own.
				[filter_wml]
					[attack]
						range=melee
						[not]
							[specials]
								[berserk]
									id="berserk"
								[/berserk]
							[/specials]
						[/not]
					[/attack]
				[/filter_wml]
				#doesnt filter anything when used with [or]
				#used with [and] filters out berserk but not rage
				#[or]
				#[and]
					#[filter_wml]
						#[attack]
							#range=melee
							#[not]
								#[specials]
									#[berserk]
										#id="exi_rage"
									#[/berserk]
								#[/specials]
							#[/not]
						#[/attack]
					#[/filter_wml]
				#[/or]
				#[/and]
			[/filter]
			variable=raged
		[/store_unit]

		{FOREACH raged i}
			[if]
				[variable]
					name=raged[$i].attack.specials.berserk.id
					not_equals="rage_drake"
				[/variable]
				[then]
					{VARIABLE raged[$i].variables.raged_counter 1}
					{VARIABLE raged[$i].attack.specials.berserk.id rage_drake}
					{VARIABLE raged[$i].attack.specials.berserk.name "rage (drake)"}
					{VARIABLE raged[$i].attack.specials.berserk.description  "this unit has been affected by an friendly Drake Warmaster, and will fight until either the opponent is slain, or 5 rounds of combat have occured.

This spec will get removed upon attack completion or at begin of next turn."}
					{VARIABLE raged[$i].attack.specials.berserk.value "3"}
					[unstore_unit]
						variable=raged[$i]
					[/unstore_unit]
				[/then]
			[/if]
		{NEXT i}
		
		#seperating second into own store_unit
		#current: Now it doesnt filter out both
		[store_unit]
			[filter]
				side=$side_number
				#race=exi_drake
				[filter_adjacent]
				    ability=exi_furyofages
					is_enemy=no
				[/filter_adjacent]
				[filter_wml]
					[attack]
						range=melee
						[not]
							[specials]
								[berserk]
									id="exi_rage"
								[/berserk]
							[/specials]
						[/not]
					[/attack]
				[/filter_wml]
			[/filter]
			variable=raged_rager
		[/store_unit]

		{FOREACH raged_rager i}
			[if]
				[variable]
					name=raged_rager[$i].attack.specials.berserk.id
					not_equals="rage_drake"
				[/variable]
				[then]
					{VARIABLE raged_rager[$i].variables.raged_counter 1}
					{VARIABLE raged_rager[$i].attack.specials.berserk.id rage_drake}
					{VARIABLE raged_rager[$i].attack.specials.berserk.name "rage (drake)"}
					{VARIABLE raged_rager[$i].attack.specials.berserk.description  "this unit has been affected by an friendly Drake Warmaster, and will fight until either the opponent is slain, or 5 rounds of combat have occured.

This spec will get removed upon attack completion or at begin of next turn."}
					{VARIABLE raged_rager[$i].attack.specials.berserk.value "3"}
					[unstore_unit]
						variable=raged_rager[$i]
					[/unstore_unit]
				[/then]
			[/if]
		{NEXT i}

	[/event]
    [event]
        name=attack_end
        first_time_only=no
		[store_unit]
			[filter]
			    x,y=$x1,$y1
				[filter_wml]
				    [variables]
						raged_counter=1
					[/variables]
					[attack]
						range=melee
					[/attack]					
				[/filter_wml]
			[/filter]
			variable=rage_offense
		[/store_unit]
        {FOREACH rage_offense i}
			{CLEAR_VARIABLE rage_offense[$i].attack.specials.berserk}
			{VARIABLE rage_offense[$i].variables.raged_counter 0}
			[unstore_unit]
				variable=rage_offense[$i]
			[/unstore_unit]
		{NEXT i}
    [/event]
[+abilities]

User avatar
Eagle_11
Forum Regular
Posts: 672
Joined: November 20th, 2013, 12:20 pm

Re: Help me to identify this error

Post by Eagle_11 » February 1st, 2018, 1:37 pm

As an unit gets damaged its hitpoints text at sidebar turns yellow, then orange, then red. What are the %s for this change ?

Is it like unit has 80 till 50% health remaining for yellow,
50% till 20% for orange,
lesser than 20% for red.
?

edit: Ive tried to determine using an 100 hp unit, turned orange when equal to less than 75 and red upon hitting lower than 25.

I have an new question. Im trying to get an functional Transport Boat, keeps functioning at large but then randomly 'fake loading's beginning to occur. The option appears and can use it, but no unit enters and this 'fake' unit has to be unloaded before picking up an actual unit. What is bugging out in the code below, how could it be improved and also i need to filter out flyer and mechanical units to prevent them from entering the transport. If it helps, im trying this on stable 1.12

Code: Select all

	#transport boat mechanic, has bug: first unit recruited by player 1 enters once then no unit else does not ever again. Or in past iterations happens like this too: First unit recruited enters and exits the transport properly, rest after doesnt.
	#discard that line, im unable to pinpoint the exact reason of sometimes unit not entering the transport. Its like every time an unload has occured the transport picks three random directions to accept the next. Also an War Galleon just got loaded into an Transport despite filter, wtf.
	[event]
		name=prestart
        first_time_only=no
		[set_menu_item]
			id=load_command
			description= _ "Load into Boat"
			[show_if]
				[have_unit]
					x,y=$x1,$y1
					side=$side_number
					[filter_wml]
						[modifications]
							[trait]
								id=exi_transportboat
							[/trait]
						[/modifications]
					[/filter_wml]
					[not]
						[filter_wml]
							[variables]
								cargo_loaded=1
							[/variables]
						[/filter_wml]
					[/not]
					[not]
						[filter_wml]
							moves=0
						[/filter_wml]
					[/not]
					[filter_adjacent]
						adjacent=n,ne,se,s,sw,nw
						[not]
							race=mechanical
						[/not]				
						side=$side_number
						[not]
							[filter_wml]
								moves=0
							[/filter_wml]
						[/not]
						[not]
							[filter_wml]
								[movetype]
									flies=true
								[/movetype]
							[/filter_wml]
						[/not]
						[not]
							canrecruit=yes
						[/not]
					[/filter_adjacent]
				[/have_unit]
			[/show_if]
			[command]
				[object]
					silent=yes
					[effect]
						apply_to=new_ability
						[abilities]	
							{ABILITY_EXI_LOADED}
						[/abilities]
					[/effect]
				[/object]
				[store_locations]
					#terrain=*^V*
					[filter]
						[not]
							[filter_wml]
								moves=0
							[/filter_wml]
						[/not]
						[not]
							[filter_wml]
								[movetype]
									flies=true
								[/movetype]
							[/filter_wml]
						[/not]
						[not]
							canrecruit=yes
						[/not]
						side=$side_number
					[/filter]
					[and]
						x,y=$x1,$y1
						radius=1
					[/and]
					variable=boarding_unit_hex
				[/store_locations]
				[store_unit]
					[filter]
						x,y=$x1,$y1
						side=$side_number
					[/filter]
					variable=boat
				[/store_unit]
				[store_unit]
					[filter]
						x,y=$boarding_unit_hex.x,$boarding_unit_hex.y
						[not]
							race=mechanical
						[/not]
						#[not]
							#[filter_wml]
								#[movetype]
									#flies=yes
								#[/movetype]
							#[/filter_wml]
						#[/not]
						[not]
							canrecruit=yes
						[/not]
						side=$side_number
					[/filter]
					variable=boat.variables.unit
					kill=no
				[/store_unit]

				[floating_text]
					x,y=$boarding_unit_hex.x,$boarding_unit_hex.y
					text="<span color='$color_attention' size='small'>boarding transport</span>"
				[/floating_text]
				#{SOUND_X_Y "open-chest.wav" $x1 $y1}
				[kill]
					x,y=$boarding_unit_hex.x,$boarding_unit_hex.y
					animate=no
					fire_event=no
				[/kill]
				[move_unit_fake]
					type=$boat.variables.unit.type
					x=$boarding_unit_hex.x,$x1
					y=$boarding_unit_hex.y,$y1
					side=$side_number
					gender=$boat.variables.unit.gender
				[/move_unit_fake]
				
				#old code below taken from Conquest original, had problem of eating units when multiple enter transport at same time, hence switched to Conquest- version of transport code.
				#[store_unit]
					#[filter]
						#x,y=$x1,$y1
						#side=$side_number
					#[/filter]
					#variable=boat
					#kill=yes
				#[/store_unit]
				#[store_unit]
					#[filter]
						#[filter_location]
							#[and]
								#x,y=$x1,$y1
								#radius=1
							#[/and]
						#[/filter_location]
						#[not]
							#race=mechanical
						#[/not]
						#[not]
							#[filter_wml]
								#[movetype]
									#flies=yes
								#[/movetype]
							#[/filter_wml]
						#[/not]
						#[not]
							#canrecruit=yes
						#[/not]
						#side=$side_number
					#[/filter]
					#variable=boat.variables.unit
					#kill=yes
				#[/store_unit]

				{VARIABLE boat.variables.cargo_loaded 1}
				{VARIABLE boat.variables.unit.moves 0}

				[unstore_unit]
					variable=boat
				[/unstore_unit]
				{CLEAR_VARIABLE boarding_unit_hex}
			[/command]
		[/set_menu_item]
		[set_menu_item]
			id=unload_command
			description=_"Unload from Boat"
			[show_if]
				[have_unit]
					x,y=$x1,$y1
					[filter_wml]
						[modifications]
							[trait]
								id=exi_transportboat
							[/trait]
						[/modifications]
					[/filter_wml]
					[filter_wml]
						[variables]
							cargo_loaded=1
						[/variables]
					[/filter_wml]
					side=$side_number
					#[filter]
					[not]
						[filter_wml]
							moves=0
						[/filter_wml]
					[/not]
					#[/filter]
				[/have_unit]
				[have_location]
					[not]
						terrain=Q*,Mm^Xm,Md^Xm,Ms^Xm,X*,W*,M*
					[/not]
					[not]
						[filter]
						[/filter]
					[/not]
					[and]
						x,y=$x1,$y1
						radius=1
					[/and]
				[/have_location]
			[/show_if]
			[command]	
				[object]
					silent=yes
					[effect]
						apply_to=remove_ability
						[abilities]
							{ABILITY_EXI_LOADED}
						[/abilities]
					[/effect]
				[/object]

				[store_locations]
					#adjacent=n,ne,se,s,sw,nw
					[not]
						terrain=Q*,Mm^Xm,Md^Xm,Ms^Xm,X*,W*,M*
					[/not]
					[not]
						[filter]
						[/filter]
					[/not]
					[and]
						x,y=$x1,$y1
						radius=1
					[/and]
					variable=unboard_spot
				[/store_locations]
				[store_unit]
					[filter]
						x,y=$x1,$y1
						#this was not here
						[filter_wml]
							[variables]
								cargo_loaded=1
							[/variables]
						[/filter_wml]
					[/filter]
					#variable=boat
					variable=unloader_boat
					kill=yes
				[/store_unit]

				[floating_text]
					x,y=$x1,$y1
					text="<span color='$color_normal' size='small'>unboarding</span>"
				[/floating_text]
				#{SOUND_X_Y "gunshot.wav" $x1 $y1}
				[move_unit_fake] # &interface
					type=$boat.variables.unit.type
					x=$x1,$unboard_spot.x
					y=$y1,$unboard_spot.y
					side=$side_number
					gender=$boat.variables.unit.gender
				[/move_unit_fake] 
				[unstore_unit]
					variable=boat.variables.unit
					x,y=$unboard_spot.x,$unboard_spot.y
				[/unstore_unit]
				[capture_village]
					x,y=$unboard_spot.x,$unboard_spot.y
					side=$side_number
				[/capture_village]

				#{CLEAR_VARIABLE boat.variables.cargo_loaded}
				{CLEAR_VARIABLE unloader_boat.variables.cargo_loaded}
				{CLEAR_VARIABLE boat.variables.unit}

				[unstore_unit]
					#variable=boat
					variable=unloader_boat
				[/unstore_unit]
				[redraw]  
					side=$side_number
				[/redraw]
				{CLEAR_VARIABLE unboard_spot}
			[/command]
		[/set_menu_item]
	[/event]

User avatar
Eagle_11
Forum Regular
Posts: 672
Joined: November 20th, 2013, 12:20 pm

Re: Help me to identify this error

Post by Eagle_11 » February 6th, 2018, 8:04 pm

To display ownership on a Healing Tent had to set gives_income=true in its [terrain_type], which then naturaly resulted in it generating income when it shouldnt. Is there any way to display the ownership flag but make it gives 0 income ?

Another question, to build a Shrine an castle hex is required, however i want it to be adjacent to atleast one more castle hex for being available to build, in order to prevent it from being built on those one tile castles out in the wilderness. (because the shrine will be using castle tiles within radius 3 of itself to generate bonuses for units standing on them)

User avatar
Eagle_11
Forum Regular
Posts: 672
Joined: November 20th, 2013, 12:20 pm

Eagle WML Questions: how to filter out disabled attacks?

Post by Eagle_11 » February 9th, 2018, 8:23 am

Is there an way to filter out an currently disabled weapon in this manner:

Code: Select all

		[if]
    		[variable]
        		name=RAunit[$e|].attack[$a|].range
        		equals=ranged
    		[/variable]
Im trying to make it so when enemy unit stands next to a ranged attacks capable unit, it will be forced into close-combat. The 2 disable specials i have given to short and long ranged attacks works for attacking the unit in adjacent hex, the ranged attacker can still use his weapon over long-range even if its disabled, because currently lacks the check for disabled weapon, how should the filtering for an disabled weapon look like in there ?

User avatar
Sapient
Developer
Posts: 4414
Joined: November 26th, 2005, 7:41 am
Contact:

Re: Eagle WML Questions: how to filter out disabled attacks?

Post by Sapient » February 11th, 2018, 2:34 pm

I read your question, but I still don't understand exactly what you are trying to do. In normal Wesnoth, ranged attacks can only be used when standing adjacent to an enemy unit. So if you disable ranged attacks when standing adjacent to an enemy unit, then ranged attacks cannot be used at all.
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."

User avatar
Eagle_11
Forum Regular
Posts: 672
Joined: November 20th, 2013, 12:20 pm

Re: Eagle WML Questions: how to filter out disabled attacks?

Post by Eagle_11 » February 11th, 2018, 8:12 pm

Retrying:
Elf Archer has 3 attacks, their ranges are melee, short ranged and long ranged. Long ranged can be used via the right-click menu.
Now i want to do: When hostile Grunt is adjacent to Elf Archer, its long ranged attack is disabled and the short ranged attack gets enabled. This has been done easily via:

Code: Select all

#disables the long ranged attack
#define WEAPON_SPECIAL_IS_RANGED
    [disable]
        id=is_ranged
        name=""
        description=""
        [filter_self]
            [filter_adjacent]
				adjacent=n,ne,se,s,sw,nw
                is_enemy=yes
                count=1
            [/filter_adjacent]
        [/filter_self]
    [/disable]
#enddef
#disables the short ranged attack when no enemy adjacent
#define WEAPON_SPECIAL_IS_ARCHER
    [disable]
        id=is_archer
        name=""
        description=""
        [filter_self]
            [filter_adjacent]
				adjacent=n,ne,se,s,sw,nw
                is_enemy=yes
                count=0
            [/filter_adjacent]
        [/filter_self]
    [/disable]
#enddef
However, the right-click based ranged attacks component still fetches the disabled long ranged attack, and allows it to be used even if its currently disabled. Therefore, i need to find a way of telling it to not get an disabled long range attack.

Also i have just realized can simply copy-paste the filter_self block somewhere into the component to accomplish this, hmm..


The question about Healing Tent:
Its an custom village overlay tile, need to display its ownership, for that i need to display its flag, for that it needs to give income, however its not supposed to give an income but only the village healing. This problem is also present for the Shrine tile, as that too is not supposed to give income, provide only the healing.

Code: Select all

[binary_path]
		path=data/add-ons/Healing_Tent/
[/binary_path]

{~add-ons/Healing_Tent/images}

[terrain_type]
    symbol_image=tent-fancy-red
    id=deployable_healing_tent
    name= _ "Healing Tent"
	editor_name= _ "Healing Tent"
    string=^Vch
    aliasof=_bas, Vt
	heals=8
	gives_income=true
	income=0
    editor_group=village, flat
[/terrain_type]

#Healing Tent
{NEW:VILLAGE        *^Vch                                                     tent-fancy-red}

[modification]
    id=EXI_Healertent
    name=_"Healing Tent"
    description=_"If this mod is on, then your leader unit may deploy an Healing Tent, to do so the unit should have full moves and be standing on flat terrain(open desert, snow covered and cavernous flats also count), then through the right-click context-menu can order it to deploy the Healing Tent. When the leader deploys the tent its moves are depleted for that turn.

The Healing Tent functions like an portable village that provides the usual village healing benefits but no income. If an enemy unit enters the hex with the Healing Tent it gets instantly destroyed(this also applies to neutral tents without a side), the leader unit can pick up the deployed tent of its own side to carry it elsewhere. Note that whilst you can steal an ally's tent, your leader can carry and deploy only one tent at a time.

The Healing Tent cannot be pitched within 3 radius of any village, castle or keep tile, therefore its of limited use in most maps, except in those that are Randomly generated."
    require_modification=yes

	#building the tent part
	[event]
		name=prestart
		first_time_only=no
		[set_menu_item]
			id=exi_pitch_tent
			description= _ "Deploy Healing Tent!"
			[show_if]
				[have_unit]
					side=$side_number
					x,y=$x1,$y1
					canrecruit=yes
					[not]
						[filter_wml]
							[status]
								deployed_tent=yes
							[/status]
						[/filter_wml]
					[/not]
					[filter_wml]
						moves=$this_unit.max_moves
					[/filter_wml]
				[/have_unit]
				[and]
				[not]
					[have_location]
						terrain=*^V*,C*,K*
						[and]
							x=$x1
							y=$y1
							radius=3
						[/and]
					[/have_location]
				[/not]
				[/and]
			[/show_if]
			[command]
				[store_side]
					side=$side_number
					variable=worker
				[/store_side]

				[store_unit]
					[filter]
						x=$x1
						y=$y1
					[/filter]
					variable=unit
				[/store_unit]

				[set_variable]
					name=finished
					value=no
				[/set_variable]
				[while]
					[variable]
						name=finished
						equals=no
					[/variable]

					[do]
						[message]
							speaker=unit
							message= _ "Are you sure ?"
							[option]
								message= {MENU_IMG_TXT "icons/scroll_red.png" ("<span color='yellow'>" + _ "Cancel" + "</span>")}
								[command]
									[set_variable]
										name=finished
										value=yes
									[/set_variable]
								[/command]
							[/option]

							[option]
								message= {MENU_IMG_TXT "icons/potion_red_medium.png" ("<span color='green'>" + _ "Deploy the Healing Tent" + "</span>") }
								[show_if]
									[have_unit]
										side=$side_number
										x,y=$x1,$y1
										canrecruit=yes
										[filter_location]
											terrain=G*,R*,Aa,Dd,Dt,Ur,Urb,Uu,Uue
										[/filter_location]
									[/have_unit]
									#[and]
										#[not]
											#[have_location]
												#terrain=*^V*,C*,K*
												#[and]
													#x=$x1
													#y=$y1
													#radius=3
												#[/and]
											#[/have_location]
										#[/not]
									#[/and]
								[/show_if]

								[command]
									[set_variable]
										name=finished
										value=yes
									[/set_variable]
									[set_variable]
										name=unit.status.deployed_tent
										value=yes
									[/set_variable]
									[set_variable]
										name=unit.moves
										value=0
									[/set_variable]

									[unstore_unit]
										variable=unit
									[/unstore_unit]

									#{MODIFY_TERRAIN "^Vch" $x1 $y1}

									[terrain]
										x=$x1
										y=$y1
										layer=overlay
										terrain=^Vch
									[/terrain]

									[capture_village]
										x=$x1
										y=$y1
										side=$side_number
									[/capture_village]

									[sound]
										name=miss-1.ogg
									[/sound]
									[delay]
										time=120
									[/delay]
									[sound]
										name=bite.ogg
									[/sound]
									[delay]
										time=220
									[/delay]
									[sound]
										name=dart.wav
									[/sound]
									[delay]
										time=180
									[/delay]
									[sound]
										name=dart.wav
									[/sound]
								[/command]
							[/option]
						[/message]
					[/do]
				[/while]
			[/command]
		[/set_menu_item]
	[/event]

	#tearing down the tent part
    [event]
        name=side_turn
        first_time_only=no
        [store_side]
            side=$side_number
            variable=current_side
        [/store_side]
	
        [set_menu_item]
            [show_if]
                [have_unit]
                    side=$side_number
                    canrecruit=yes
                    x=$x1
                    y=$y1
                    [filter_wml]
                        [status]
                            deployed_tent=yes
                        [/status]
                    [/filter_wml]
                    [filter_location]
                        x=$x1
                        y=$y1
                        terrain=*^Vch
						side=$current_side
                    [/filter_location]
                [/have_unit]
            [/show_if]
            id=exi_teardown_healtent
            description=_ "Teardown Healingtent !"

            [command]
                [store_unit]
                    [filter]
                        x=$x1
                        y=$y1
                    [/filter]
                    variable=unit
                [/store_unit]
                {VARIABLE tentX $x1}
                {VARIABLE tentY $y1}

				[terrain]
					x=$tentX
					y=$tentY
					#x,y={X},{Y}
					layer=overlay
					terrain=^
				[/terrain]

                [set_variable]
                    name=unit.status.deployed_tent
                    value=no
                [/set_variable]

                [set_variable]
                    name=unit.moves
                    value=0
                [/set_variable]

                [unstore_unit]
                    variable=unit
                    {CLEAR_VARIABLE unit}
				    text="<span color='#cccc33'>" + _ "teared down Healing Tent" + "</span>"					
                [/unstore_unit]

				[sound]
					name=staff.wav
				[/sound]
				[delay]
					time=120
				[/delay]
				[sound]
					name=claws.ogg
				[/sound]
				[delay]
					time=220
				[/delay]
				[sound]
					name=wose-die.ogg
				[/sound]
				[delay]
					time=180
				[/delay]
				[sound]
					name=mace.wav
				[/sound]
            [/command]
        [/set_menu_item]
	[/event]

	#delete the tent if hostile enters
	[event]
		name=capture
		first_time_only=no
		[filter]
            [filter_location]
                terrain=*^Vch*
            [/filter_location]
			[filter_side]
				[not]
					[allied_with]
						side=$owner_side
					[/allied_with]
				[/not]
			[/filter_side]
		[/filter]

        [terrain]
            x=$x1
            y=$y1
            layer=overlay
            terrain=^
        [/terrain]
	[/event]

    #[event]
        #first_time_only=no
        #name=moveto
        #[filter]
            #[filter_location]
                #terrain=*^Vch*
            #[/filter_location]
            #side=$side_number
			#[filter_side]
				#[not]
					#[allied_with]
						#side=$owner_side
					#[/allied_with]
				#[/not]
			#[/filter_side]
        #[/filter]

        #[terrain]
            #x=$x1
            #y=$y1
            #layer=overlay
            #terrain=^
        #[/terrain]
    #[/event]
[/modification]

The question about Shrine loc:
Shrine is an custom village overlay, it functions like Orocia's shrine, meaning it generates random upgrade at side turn begin for units in hexes within given radius(used 3) of given terrain type, in my case that is castle terrain. Since it requires atleast one castle tile within radius to generate the upgrade on, otherwise it would be wasted, i have to prevent it from being built on one-tile castle hexes. How should the filter for that looks like ?

Code: Select all

[binary_path]
		path=data/add-ons/Buildable_Shrine/
[/binary_path]

{~add-ons/Buildable_Shrine/images}

[terrain_type]
    symbol_image=temple1
    id=deployable_shrine
    name= _ "Shrine of Upgrades"
	editor_name= _ "Shrine of Upgrades"
    string=^Vks
    aliasof=_bas, Vt
	heals=8
	gives_income=true
	income=0
    editor_group=village, flat
[/terrain_type]

#Shrine
{NEW:VILLAGE        *^Vks                                                    temple1}

#define EXI_INDIVIDUAL_LABEL TEXT COLOR
				[if]
					[have_unit]
						side=$side_number
						x,y=$exi_shrine_array[$i].x,$exi_shrine_array[$i].y
						[not]
							[enemy_of]
								side=$side_number
							[/enemy_of]
						[/not]
						#[filter_side]
							#is_enemy=no
						#[/filter_side]
					[/have_unit]
					[then]
						[label]
							x=$exi_shrine_array[$i].x
							y=$exi_shrine_array[$i].y
							color={COLOR}
							text={TEXT}
						[/label]
					[/then]
					[else]
						[label]
							x=$exi_shrine_array[$i].x
							y=$exi_shrine_array[$i].y
							text=""
						[/label]
					[/else]
				[/if]
#enddef

#define EXI_RESUP_OBJ
				[object]
					silent=yes
					[filter]
						x,y=$exi_shrine_array[$i].x,$exi_shrine_array[$i].y
						side=$side_number
					[/filter]
					[effect]
						apply_to=resistance
						replace=no
						[resistance]
							arcane=-5
							fire=-5
							blade=-5
							pierce=-5
							impact=-5
							cold=-5
						[/resistance]
					[/effect]
				[/object]
#enddef

#define EXI_HPUP_OBJ
				[object]
					silent=yes
					[filter]
						x,y=$exi_shrine_array[$i].x,$exi_shrine_array[$i].y
						side=$side_number
					[/filter]
					[effect]
						apply_to=hitpoints
						increase_total=6
					[/effect]
					[effect]
						apply_to=hitpoints
						increase=6
					[/effect]
				[/object]
#enddef

#define EXI_MPUP_OBJ
				[object]
					silent=yes
					[filter]
						x,y=$exi_shrine_array[$i].x,$exi_shrine_array[$i].y
						side=$side_number
					[/filter]
					[effect]
						apply_to=movement
						increase=1
					[/effect]
				[/object]
#enddef

#define EXI_DMGUP_OBJ
				[object]
					silent=yes
					[filter]
						x,y=$exi_shrine_array[$i].x,$exi_shrine_array[$i].y
						side=$side_number
					[/filter]
					[effect]
						apply_to=attack
						increase_damage=2
					[/effect]
				[/object]
#enddef

#define EXI_STRUP_OBJ
				[object]
					silent=yes
					[filter]
						x,y=$exi_shrine_array[$i].x,$exi_shrine_array[$i].y
						side=$side_number
					[/filter]
					[effect]
						apply_to=attack
						increase_attacks=1
					[/effect]
				[/object]
#enddef

#define EXI_LOYAL_OBJ
				[object]
					silent=yes
					[filter]
						x,y=$exi_shrine_array[$i].x,$exi_shrine_array[$i].y
						side=$side_number
					[/filter]
					[effect]
						apply_to=loyal
					[/effect]
					[unit_overlay]
						x,y=$exi_shrine_array[$i].x,$exi_shrine_array[$i].y
						image="misc/loyal-icon.png"
					[/unit_overlay]
					#overlays="misc/loyal-icon.png"
				[/object]
#enddef

#define EXI_HEAL_OBJ
				[object]
					silent=yes
					[filter]
						x,y=$exi_shrine_array[$i].x,$exi_shrine_array[$i].y
						side=$side_number
					[/filter]
					[effect]
						heal_full=yes
					[/effect]
					[effect]
						apply_to=status
						remove=poisoned
					[/effect]
					[effect]
						apply_to=status
						remove=slowed
					[/effect]
				[/object]
#enddef

#define EXI_DEFUP_OBJ
				[object]
					silent=yes
					[filter]
						x,y=$exi_shrine_array[$i].x,$exi_shrine_array[$i].y
						side=$side_number
					[/filter]
					[effect]
						apply_to=defense
						replace=no
						[defense]
							deep_water=-5
							shallow_water=-5
							swamp_water=-5
							flat=-5
							sand=-5
							forest=-5
							hills=-5
							mountains=-5
							village=-5
							castle=-5
							cave=-5
							frozen=-5
							unwalkable=-5
							#impassable=-5
							fungus=-5
						[/defense]
					[/effect]
				[/object]
#enddef

[modification]
    id=EXI_BonusShrine
    name=_"Shrine Mod"
    description=_"While the brave defenders of Orocia had been busy protecting the realm an cunning group of Pirates snuck in through the forgotten sewers and stole the shrine, now everyone can build an upgrade shrine on any map ! In their hurry they have forgotten to take the labels however...

Each side can build one Shrine(once per game) for 30 gold that generates random bonuses on castle and keep tiles within radius of 3 hexes around itself, to build an shrine your leader unit must be standing on a castle tile and have full moves, then you can build it via right-click context menu. Whilst you can build the Shrine on any one hex castle tile out in the wilderness, common sense dictates it not to be so as normally you want as many castle hexes within the 3 radius as possible to generate the maximum amount of bonuses possible. 

The shrine generates random 8 types of bonuses at the begin of your side's turn. The possible bonuses are +5% more resistant to all damage, +5% defense on all terrains, +6 Hp, +1 Mp, +2 damage to any attack, increase strike of all attacks the unit has by 1, make loyal, gets healed to full and is cured of ailment, and lastly an chance of nothing at all.

The shrine itself functions like an village, meaning units may rest heals when over it. Should any enemy unit enter the hex of the shrine, it instantly dies and the bonuses are no longer provided to the side that has lost the shrine."
    require_modification=yes

	#building the shrine part
	[event]
		name=prestart
		first_time_only=no
		[set_menu_item]
			id=exi_build_shrine
			description= _ "Build the Shrine"
			[show_if]
				[have_unit]
					side=$side_number
					x,y=$x1,$y1
					canrecruit=yes
					[not]
						[filter_wml]
							[status]
								built_shrine=yes
							[/status]
						[/filter_wml]
					[/not]
					[filter_wml]
						moves=$this_unit.max_moves
					[/filter_wml]
					[filter_location]
						terrain=C*
					[/filter_location]
				[/have_unit]
				[and]
					[have_location]
						terrain=C*,K*
						[and]
							x=$x1
							y=$y1
							radius=2
						[/and]
					[/have_location]
				[/and]
			[/show_if]
			[command]
				[store_side]
					side=$side_number
					variable=worker
				[/store_side]

				[store_unit]
					[filter]
						x=$x1
						y=$y1
					[/filter]
					variable=unit
				[/store_unit]

				[set_variable]
					name=finished
					value=no
				[/set_variable]
				[while]
					[variable]
						name=finished
						equals=no
					[/variable]

					[do]
						[message]
							speaker=unit
							message= _ "Are you sure ?"
							[option]
								message= {MENU_IMG_TXT "icons/scroll_red.png" ("<span color='yellow'>" + _ "Cancel" + "</span>")}
								[command]
									[set_variable]
										name=finished
										value=yes
									[/set_variable]
								[/command]
							[/option]

							[option]
								message= {MENU_IMG_TXT2 "icons/key_silver.png" ("<span color='green'>" + _ "Build the Shrine" + "</span>") ("<span size='small'>" + _ "Cost: 30g" + "</span>")}
								#message= {MENU_IMG_TXT "icons/key_silver.png" ("<span color='green'>" + _ "Build the Shrine" + "</span>") }
								[show_if]
									[have_unit]
										side=$side_number
										x,y=$x1,$y1
										canrecruit=yes
										[filter_location]
											terrain=C*
										[/filter_location]
									[/have_unit]
								[/show_if]

								#todo add gold usage to setup shrine
								[command]
									[store_side]
										side=$side_number
										variable=shrinebuilder
									[/store_side]
									[if]
										[variable]
											name=shrinebuilder.gold
											greater_than_equal_to=30
										[/variable]
										[then]
											[gold]
												amount=-30
												side=$side_number
											[/gold]
											[set_variable]
												name=finished
												value=yes
											[/set_variable]
											[set_variable]
												name=unit.status.built_shrine
												value=yes
											[/set_variable]
											[set_variable]
												name=unit.moves
												value=0
											[/set_variable]

											[unstore_unit]
												variable=unit
											[/unstore_unit]

											[terrain]
												x=$x1
												y=$y1
												layer=overlay
												terrain=^Vks
											[/terrain]

											[capture_village]
												x=$x1
												y=$y1
												side=$side_number
											[/capture_village]

											[sound]
												name=miss-1.ogg
											[/sound]
											[delay]
												time=120
											[/delay]
											[sound]
												name=sling-big.ogg
											[/sound]
											[delay]
												time=220
											[/delay]
											[sound]
												name=dart.wav
											[/sound]
											[delay]
												time=180
											[/delay]
											[sound]
												name=fist.ogg
											[/sound]
										[/then]
										[else]
											[message]
												side_for=$side_number
												message=_ "Insufficient Funds"
												speaker=narrator
											[/message]
										[/else]
									[/if]
									{CLEAR_VARIABLE shrinebuilder}
								[/command]
							[/option]
						[/message]
					[/do]
				[/while]
			[/command]
		[/set_menu_item]
	[/event]

	#delete the shrine if hostile enters
	[event]
		name=capture
		first_time_only=no
		[filter]
            [filter_location]
                terrain=*^Vks*
            [/filter_location]
			[filter_side]
				[not]
					[allied_with]
						side=$owner_side
					[/allied_with]
				[/not]
			[/filter_side]
		[/filter]

        [terrain]
            x=$x1
            y=$y1
            layer=overlay
            terrain=^
        [/terrain]
	[/event]

	#store the bonus locations
    [event]
        name=side_turn
        first_time_only=no
		side=$side_number
        [store_locations]
			terrain=*^Vks*
			owner_side=$side_number
            radius=3
            [filter_radius]
                terrain=C*,K*
            [/filter_radius]
            variable=exi_shrine_array
        [/store_locations]
	[/event]

	#determine the bonuses itself
	[event]
		name=side turn
		first_time_only=no
		id=Exi_shrine_upgrades_event

		{VARIABLE_OP Exi_upgrade_id rand 6,0,1,2,3,4,5,6,8,0,1,2,3,4,5,6,7,8,6,8}

		{FOREACH exi_shrine_array i}

		[switch]
			variable=Exi_upgrade_id
			[case]
				value=0
				{EXI_DMGUP_OBJ}
				{EXI_INDIVIDUAL_LABEL (_"damage") (0,127,255)}
			[/case]
			[case]
				value=1
				{EXI_HPUP_OBJ}
				{EXI_INDIVIDUAL_LABEL (_"hitpoints") (0,176,0)}
			[/case]
			[case]
				value=2
				{EXI_MPUP_OBJ}
				{EXI_INDIVIDUAL_LABEL (_"movement") (180,0,180)}
			[/case]
			[case]
				value=3
				{EXI_RESUP_OBJ}
				{EXI_INDIVIDUAL_LABEL (_"resistance") (255,128,0)}
			[/case]
			[case]
				value=4
				{EXI_STRUP_OBJ}
				{EXI_INDIVIDUAL_LABEL (_"strike") (74,247,187)}
			[/case]
			[case]
				value=5
				{EXI_DEFUP_OBJ}
				{EXI_INDIVIDUAL_LABEL (_"defense") (0,90,0)}
			[/case]
			[case]
				value=6
				#nothing
				{EXI_INDIVIDUAL_LABEL (_"nothing") (255,255,0)}
			[/case]
			[case]
				value=7
				#convert to loyal
				{EXI_LOYAL_OBJ}
				{EXI_INDIVIDUAL_LABEL (_"loyal") (255,255,255)}
			[/case]
			[case]
				value=8
				{EXI_HEAL_OBJ}
				{EXI_INDIVIDUAL_LABEL (_"heal and cure") (255,255,255)}
			[/case]
		[/switch]
		{VARIABLE_OP Exi_upgrade_id rand 6,0,1,2,3,4,5,6,8,0,1,2,3,4,5,6,7,8,6,8}

		{NEXT i}
	[/event]
[/modification]

The question about the Transport Boat:
This solved itself when i have adjusted it to check for unit to be loaded into ship its required to not have 0 mp remaining and setting it to 0 when unloading from the ship.

Code: Select all

[modification]
    id=EXI_Shipbuilder_Mod
    name=_"Shipbuilding mod"
    description=_"Forewarning: There may still be an bug present that occasionally causes unit to be not get loaded into the Transport Ship. If that bug ever happens, simply unload the 'fake' unit then try again.

When this mod is on you can recruit two types of ships on shallow or deep water hexes adjacent to an Village that belongs to you. Then through right-click context-menu can order an War Galleon or Transport Galleon to be recruited on the water hex.

The Transport Galleon can ferry one non-mechanical land unit over the sea and is entirely defenseless. Note: Your leader(or any other canrecruit=yes for that matter) may not use the boat. To load an unit into the ship, both the ship and the unit to be loaded must have atleast one movepoint remaining and be adjacent to each other, then you can right-click on the transport and use "Load into Boat". Should there be multiple adjacent friendly units present one will be picked at random.
Units that are already flying, floating or swimming cannot get loaded into an Transport Ship, to filter them out used type=id's, therefore filtering out swimmer and flyers only works for the Default era. Units cannot be unloaded into impassable, water(can into ford or swamp), lava, mountain or volcano terrain when disembarking out of an Transport Ship. Upon disembarking the exiting unit will have 0 moves remaining.

The War Galleon has an Ballista with 10 pierce damage 2 strikes attack and does not transport any units. Both ships have 20% resistance to cold, 10% resistance to pierce, take 20% increased damage from fire and 10% increased damage from impact.
The ships are level 1 mechanical units with 35 hp and 5 moves that cost 15g, have normal upkeep, 50% defense in water(40% in swamps, 30% in reefs), can only travel on wet terrain(those being water and swamps) and absolutely cannot go on land. Also they can self-repair at an rate of 4 hitpoints per turn when overseas.

Building an ship may help with opening up new opportunities in maps that have abundant water, such as Weldyn or Cynsaun."
    require_modification=yes

#define ABILITY_EXI_LOADED
# dummy used by the transporter code for loading units not to be used manually
	[dummy]
		id=exi_loaded
		name= _ "Cargo Full"
		description= _ "Is carrying an unit."
	[/dummy]
#enddef

#define TRAIT_EXI_TRANSPORTER
	[trait]
		id=exi_transportboat
		name= _ "transporter"
		description= _ "This unit can carry one unit across the open sea, excluding flyers and mechanical units."
		availability=must_have
	[/trait]
#enddef

#define ABILITY_EXI_SHIPREPAIR
   [regenerate]
        id=exi_selfrepair_ship
        name= _ "ship repairs"
        description= _ "this unit can self-repair at an rate of 4 hp per turn when overseas."
		value=4
		[filter_self]
			[filter_location]
				[and]
					terrain=S*,W*
				[/and]
			[/filter_location]
		[/filter_self]
    [/regenerate]
#enddef

#define CANNOT_BOAT_TYPES
"Blood Bat, Dread Bat, Vampire Bat, Drake Fighter, Drake Warrior, Drake Blademaster, Drake Burner, Fire Drake, Inferno Drake, Armageddon Drake, Drake Flare, Drake Flameheart, Drake Glider, Hurricane Drake, Sky Drake, Elvish Sylph, Elvish Shyde, Gryphon, Gryphon Rider, Gryphon Master, Falcon, Elder Falcon, Merman Fighter, Merman Warrior, Merman Hoplite, Merman Triton, Ghost, Wraith, Spectre, Shadow, Nightmare, Merman Hunter, Merman Javelineer, Merman Netcaster, Merman Spearman, Merman Entangler, Mermaid Initiate, Mermaid Siren, Mermaid Priestess, Mermaid Enchantress, Mermaid Diviner, Naga Fighter, Naga Warrior, Naga Myrmidon, Cuttlefish, Sea Serpent, Tentacle of the Deep, Water Serpent"#enddef

    [event]
        name=side_turn
        first_time_only=no
        [set_menu_item]

			[filter_location]
				terrain=W*
				[filter_adjacent_location]
						terrain=*^V*
						owner_side=$side_number
				[/filter_adjacent_location]
				[not]
					[filter]
						x=$x1
						y=$y1
					[/filter]
				[/not]
			[/filter_location]
            id=exi_recruit_ships
            description=_ "Build a Ship to sail the waters."
			[command]
				[message]
					side_for=$side_number
					speaker=narrator
					[option]
						message=_ "&"+"units/transport/galleon.png~RC(magenta>red)"+"="+"Transport Galleon - 15 Gold"
						[command]
							[store_side]
								side=$side_number
								variable=shipbuilder
							[/store_side]
							[if]
								[variable]
									name=shipbuilder.gold
									greater_than_equal_to=15
								[/variable]
								[then]
									[gold]
										amount=-15
										side=$side_number
									[/gold]
									[unit]
										type="Exi Transport Galleon"
										side=$side_number
										x,y=$x1,$y1
										moves=0
										animate=yes
									[/unit]
								[/then]
								[else]
									[message]
										side_for=$side_number
										message=_ "Insufficient Funds"
										speaker=narrator
									[/message]
								[/else]
							[/if]
						[/command]
					[/option]
					[option]
						message=_ "&"+"units/transport/transport-galleon.png~RC(magenta>red)"+"="+"War Galleon - 15 Gold"
						[command]
							[store_side]
								side=$side_number
								variable=shipbuilder
							[/store_side]
							[if]
								[variable]
									name=shipbuilder.gold
									greater_than_equal_to=15
								[/variable]
								[then]
									[gold]
										amount=-15
										side=$side_number
									[/gold]
									[unit]
										type="Exi War Galleon"
										side=$side_number
										x,y=$x1,$y1
										moves=0
										animate=yes
									[/unit]
								[/then]
								[else]
									[message]
										side_for=$side_number
										message=_ "Insufficient Funds"
										speaker=narrator
									[/message]
								[/else]
							[/if]
						[/command]
					[/option]
					[option]
						message=_ "Cancel"
						speaker=narrator
					[/option]
				[/message]
				{CLEAR_VARIABLE shipbuilder}
			[/command]
		[/set_menu_item]
	[/event]
	#transport boat mechanic, has bug: first unit recruited by player 1 enters once then no unit else does not ever again. Or in past iterations happens like this too: First unit recruited enters and exits the transport properly, rest after doesnt.
	#discard that line, im unable to pinpoint the exact reason of sometimes unit not entering the transport. Its like every time an unload has occured the transport picks three random directions to accept the next. Also an War Galleon just got loaded into an Transport, wtf.
	[event]
		name=prestart
        first_time_only=no
		[set_menu_item]
			id=load_command
			description= _ "Load into Boat"
			[show_if]
				[have_unit]
					x,y=$x1,$y1
					side=$side_number
					[filter_wml]
						[modifications]
							[trait]
								id=exi_transportboat
							[/trait]
						[/modifications]
					[/filter_wml]
					[not]
						[filter_wml]
							[variables]
								cargo_loaded=1
							[/variables]
						[/filter_wml]
					[/not]
					[not]
						[filter_wml]
							moves=0
						[/filter_wml]
					[/not]
					[filter_adjacent]
						adjacent=n,ne,se,s,sw,nw
						[not]
							race=mechanical
						[/not]
						side=$side_number
						[not]
							[filter_wml]
								moves=0
							[/filter_wml]
						[/not]
						[not]
							type={CANNOT_BOAT_TYPES}
						[/not]
						[not]
							canrecruit=yes
						[/not]
					[/filter_adjacent]
				[/have_unit]
			[/show_if]
			[command]
				[object]
					silent=yes
					[effect]
						apply_to=new_ability
						[abilities]
							{ABILITY_EXI_LOADED}
						[/abilities]
					[/effect]
				[/object]
				[store_locations]
					#terrain=*^V*
					[filter]
						[not]
							[filter_wml]
								moves=0
							[/filter_wml]
						[/not]
						[not]
							race=mechanical
						[/not]
						[not]
							type={CANNOT_BOAT_TYPES}
						[/not]
						[not]
							canrecruit=yes
						[/not]
						side=$side_number
					[/filter]
					[and]
						x,y=$x1,$y1
						radius=1
					[/and]
					variable=boarding_unit_hex
				[/store_locations]
				[store_unit]
					[filter]
						x,y=$x1,$y1
						side=$side_number
					[/filter]
					variable=boat
				[/store_unit]
				[store_unit]
					[filter]
						x,y=$boarding_unit_hex.x,$boarding_unit_hex.y
						[not]
							race=mechanical
						[/not]
						[not]
							type={CANNOT_BOAT_TYPES}
						[/not]
						[not]
							canrecruit=yes
						[/not]
						side=$side_number
					[/filter]
					variable=boat.variables.unit
					kill=no
				[/store_unit]

				[floating_text]
					x,y=$boarding_unit_hex.x,$boarding_unit_hex.y
					text="<span color='white'>" + _ " boarding transport" + "</span>"
					#"<span color='$color_attention'>boarding transport</span>"
				[/floating_text]
				[kill]
					x,y=$boarding_unit_hex.x,$boarding_unit_hex.y
					animate=no
					fire_event=no
				[/kill]
				[move_unit_fake]
					type=$boat.variables.unit.type
					x=$boarding_unit_hex.x,$x1
					y=$boarding_unit_hex.y,$y1
					side=$side_number
					gender=$boat.variables.unit.gender
				[/move_unit_fake]

				{VARIABLE boat.variables.cargo_loaded 1}
				{VARIABLE boat.variables.unit.moves 0}

				[unstore_unit]
					variable=boat
				[/unstore_unit]
				{CLEAR_VARIABLE boarding_unit_hex}
			[/command]
		[/set_menu_item]
		[set_menu_item]
			id=unload_command
			description=_"Unload from Boat"
			[show_if]
				[have_unit]
					x,y=$x1,$y1
					[filter_wml]
						[modifications]
							[trait]
								id=exi_transportboat
							[/trait]
						[/modifications]
					[/filter_wml]
					[filter_wml]
						[variables]
							cargo_loaded=1
						[/variables]
					[/filter_wml]
					side=$side_number
					#[filter]
					#[not]
					[filter_wml]
						[not]
							moves=0
						[/not]
					[/filter_wml]
					#[/not]
					#[/filter]
				[/have_unit]
				[have_location]
					[not]
						terrain=Q*,Mm^Xm,Md^Xm,Ms^Xm,X*,Wwt,Ww,Wwg,Wog,Wo,Wot,M*
					[/not]
					[not]
						[filter]
						[/filter]
					[/not]
					[and]
						x,y=$x1,$y1
						radius=1
					[/and]
				[/have_location]
			[/show_if]

			[command]
				[object]
					silent=yes
					[effect]
						apply_to=remove_ability
						[abilities]
							{ABILITY_EXI_LOADED}
						[/abilities]
					[/effect]
				[/object]

				[store_locations]
					#adjacent=n,ne,se,s,sw,nw
					[not]
						terrain=Q*,Mm^Xm,Md^Xm,Ms^Xm,X*,Wwt,Ww,Wwg,Wog,Wo,Wot,M*
					[/not]
					[not]
						[filter]
						[/filter]
					[/not]
					[and]
						x,y=$x1,$y1
						radius=1
					[/and]
					variable=unboard_spot
				[/store_locations]

				[store_unit]
					[filter]
						x,y=$x1,$y1
						[filter_wml]
							[variables]
								cargo_loaded=1
							[/variables]
						[/filter_wml]
					[/filter]
					variable=unloader_boat
					kill=yes
				[/store_unit]

				[floating_text]
					x,y=$x1,$y1
					text="<span color='white'>" + _ " unboarding transport" + "</span>"
				[/floating_text]

				[move_unit_fake]
					type=$boat.variables.unit.type
					x=$x1,$unboard_spot.x
					y=$y1,$unboard_spot.y
					side=$side_number
					gender=$boat.variables.unit.gender
				[/move_unit_fake]

				[unstore_unit]
					variable=boat.variables.unit
					x,y=$unboard_spot.x,$unboard_spot.y
				[/unstore_unit]
				[capture_village]
					x,y=$unboard_spot.x,$unboard_spot.y
					side=$side_number
				[/capture_village]

				{CLEAR_VARIABLE unloader_boat.variables.cargo_loaded}
				{CLEAR_VARIABLE boat.variables.unit}

				[unstore_unit]
					variable=unloader_boat
				[/unstore_unit]

				[redraw]
					side=$side_number
				[/redraw]
				{CLEAR_VARIABLE unboard_spot,unloader_boat}
			[/command]
		[/set_menu_item]
	[/event]
[/modification]
I have one more question regarding the shrine, those labels that are supposed to indicate what kind of upgrade the unit gets are not being displayed, must have done something wrong, any idea on how to fix.

The question about Hp text coloring:
I was planning to make an weapon-special deal more damage as the opponent gets damaged, and wanted to sync the damage increase with text color change for easy indication, but then realized there is too much between the gaps of color change, so went with per 20% health the opponent is missing instead.

The question about filtering Berserk:
I have noticed something weird happening, its not filtering when given id=anycustomid, only for id=berserk.

Code: Select all

#define WEAPON_SPECIAL_EXI_RAGE
    [berserk]
        id=exi_rage
        name= _ "rage"
        description= _ "Whether used offensively or defensively, this attack presses the engagement until one of the combatants is slain, or 3 rounds of combat have occurred."
        value=3
    [/berserk]
#enddef
#define SPECIAL_NOTES_EXI_RAGE
_" 
This unit has an attack that prolongs the melee combat for 3 more rounds."#enddef


#define SPECIAL_NOTES_EXI_FURY_OF_AGES
_" 
This unit is capable of instilling rage inside the allied units, causing them to fight with 'rage' weapon-special in melee."#enddef
#define ABILITY_EXI_FURY_OF_AGES
    [dummy]
        id=exi_furyofages
        name= _ "fury of ages"
        description= _ "all adjacent friendly units will gain 'rage' on their melee."
    [/dummy]
[/abilities]
	[event]
		name=side turn
		first_time_only=no
		[store_unit]
			[filter]
				[filter_wml]
				    [variables]
						raged_counter=1
					[/variables]
				[/filter_wml]
			[/filter]
			variable=rage_refresh
		[/store_unit]

		{FOREACH rage_refresh i}
			{CLEAR_VARIABLE rage_refresh[$i].attack.specials.berserk }
			{VARIABLE rage_refresh[$i].variables.raged_counter 0}
			[unstore_unit]
				variable=rage_refresh[$i]
			[/unstore_unit]
		{NEXT i}

		[store_unit]
			[filter]
				side=$side_number
				#as an bandaid can make it drake only since they not have any zerkers, however would prefer not limiting abilities to race...
				race=exi_drake
				[filter_adjacent]
				    ability=exi_furyofages
					is_enemy=no
				[/filter_adjacent]
				[filter_wml]
					[attack]
						range=melee
						[not]
							[specials]
								[berserk]
									id=berserk
								[/berserk]
							[/specials]
						[/not]
					[/attack]
				[/filter_wml]
			[/filter]
			variable=raged
		[/store_unit]

		{FOREACH raged i}
			[if]
				[variable]
					name=raged[$i].attack.specials.berserk.id
					not_equals="rage_drake"
				[/variable]
				[then]
					{VARIABLE raged[$i].variables.raged_counter 1}
					{VARIABLE raged[$i].attack.specials.berserk.id rage_drake}
					{VARIABLE raged[$i].attack.specials.berserk.name "rage (drake)"}
					{VARIABLE raged[$i].attack.specials.berserk.description  "this unit has been affected by an friendly Drake Warmaster, and will fight until either the opponent is slain, or 5 rounds of combat have occured.

This spec will get removed upon attack completion or at begin of next turn."}
					{VARIABLE raged[$i].attack.specials.berserk.value "3"}
					[unstore_unit]
						variable=raged[$i]
					[/unstore_unit]
				[/then]
			[/if]
		{NEXT i}

	[/event]
    [event]
        name=attack_end
        first_time_only=no
		[store_unit]
			[filter]
			    x,y=$x1,$y1
				[filter_wml]
				    [variables]
						raged_counter=1
					[/variables]
					[attack]
						range=melee
					[/attack]					
				[/filter_wml]
			[/filter]
			variable=rage_offense
		[/store_unit]
        {FOREACH rage_offense i}
			{CLEAR_VARIABLE rage_offense[$i].attack.specials.berserk}
			{VARIABLE rage_offense[$i].variables.raged_counter 0}
			[unstore_unit]
				variable=rage_offense[$i]
			[/unstore_unit]
		{NEXT i}
    [/event]
[+abilities]
#enddef

User avatar
Sapient
Developer
Posts: 4414
Joined: November 26th, 2005, 7:41 am
Contact:

Re: Eagle WML Questions: how to filter out disabled attacks?

Post by Sapient » February 11th, 2018, 9:00 pm

Ah I see. Regarding the weapon special, you can use this inside a unit filter:

Code: Select all

[set_menu_item]
  [filter_location]
    [filter]
# ... see if there is a range "long" attack without active special "disable"
      [has_attack]
        range=long
          [not]
            special_active=disable
          [/not]
      [/has_attack]
    [/filter]
  [/filter_location]
[/set_menu_item]
However, note that the special_active weapon filter is not available in versions before 1.13.8

For older versions of Wesnoth you’d need to duplicate the adjacent enemy unit filter;

Code: Select all

[set_menu_item]
  [filter_location]
    [filter]
# ...  no adjacent enemy
      [filter_adjacent]
        is_enemy=yes
        count=0
      [/filter_adjacent]
    [/filter]
  [/filter_location]
[/set_menu_item]
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."

User avatar
Sapient
Developer
Posts: 4414
Joined: November 26th, 2005, 7:41 am
Contact:

Re: Eagle WML Questions: how to filter out disabled attacks?

Post by Sapient » February 13th, 2018, 6:31 am

For your second, question about how to make a flag overlay. You can just use a standard animated item halo:

Code: Select all

[event]
  name=moveto
  first_time_only=no

  # Capture logic here:
  # should I check if the side has any leader and/or teammates?

  [remove_item]
    x,y=$x1,$y1
  [/remove_item]
  [item]
    x,y=$x1,$y1
    halo="flags/flag-[1~4].png~TC($side_number,flag_green):150"
    visible_in_fog=no
  [/item]
[/event]
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."

User avatar
Sapient
Developer
Posts: 4414
Joined: November 26th, 2005, 7:41 am
Contact:

Re: Eagle WML Questions: how to filter disabled attacks? +mo

Post by Sapient » February 13th, 2018, 11:25 am

For your third question, about the Shrine, I have a little bad news for you. If you use the item halo then the location will no longer have automatic capture logic and owner_side built-in by the game. So you will have to code that by yourself.

For example, you could add a location (x1,y1) to a "shrine_info" container like this:

Code: Select all

 [store_locations]
   x,y=$x1,$y1
   [or]
      find_in="shrine_info[$side_number].loc"
   [/or]
   variable="shrine_info[$side_number].loc"
Then in your location filter you would add find_in="shrine_info[$side_number].loc"

P.S. I don't really see the need for preventing them from placing it in a non-ideal location. After all a castle hex still has 1 valid position. But you could filter it like so:

Code: Select all

[filter_location]
  terrain=C*
  [filter_adjacent_location]
    terrain=C*
EDIT:

actually, another idea occurred to me that you might want to leave it as a village type terrain and just modify the income using [modify_side] income=
(however, that would have still the disadvantage that the number of villages owned would display an incorrect number.)
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."

User avatar
Eagle_11
Forum Regular
Posts: 672
Joined: November 20th, 2013, 12:20 pm

Re: Eagle WML Questions: how to filter disabled attacks? +mo

Post by Eagle_11 » February 18th, 2018, 12:02 pm

Got some new questions.

inclusion of this event at [era] causes: Unterminated [element] tag error msg. I suppose its related to an 1.13 change regarding x,y=recall,recall ?

Code: Select all

#define EXI_RESURRECT_PIRL_EVENT
	[event]
		name=die
		first_time_only=no
		id=exi_resurrection_other
		[filter]
			[filter_adjacent]
				count=1-6
				is_enemy=no
				ability=exi_resurrects_pirl
			[/filter_adjacent]
			canrecruit=no
		[/filter]
		[animate_unit]
			flag=resurrect
			[filter]
				ability=exi_resurrects_pirl
				[filter_adjacent]
					id=$unit.id
					is_enemy=no
				[/filter_adjacent]
			[/filter]
			text= _ "resurrected!"
			{COLOR_HEAL}
			[facing]
				[filter]
					id=$unit.id
				[/filter]
			[/facing]
		[/animate_unit]
		[store_unit]
			[filter]
				x,y=$x1,$y1
			[/filter]
			variable=killed_unit
			kill=yes
		[/store_unit]
		[if]
			[variable]
				name=killed_unit.experience
				greater_than_equal_to=2
			[/variable]
			[then]
				[set_variable]
					name=killed_unit.experience
					multiply=0.5
				[/set_variable]
			[/then]
		[/if]
		[set_variable]
			name=killed_unit.hitpoints
			to_variable=killed_unit.max_hitpoints
		[/set_variable]
		[set_variable]
			name=killed_unit.moves
			to_variable=killed_unit.max_moves
		[/set_variable]
		[set_variable]
			name=killed_unit.status.poisoned
			value=no
		[/set_variable]
		[set_variable]
			name=killed_unit.status.slowed
			value=no
		[/set_variable]
		[unstore_unit]
			variable=killed_unit
			x,y=recall,recall
		[/unstore_unit]
	[/event]
#enddef
Have an weird issue: When Elf Marksman is ordered to use 7-2 ice arrow, uses the 9-4 longbow instead. The Elf Marksman has those attacks:

Code: Select all

...
    [attack]
        name=longbow
        description=_"longbow"
        icon=attacks/bow-elven.png
        type=pierce
        range=ranged
        [specials]
            {WEAPON_SPECIAL_MARKSMAN}
			{WEAPON_SPECIAL_IS_RANGED}
        [/specials]
        damage=9
        number=4
		movement_used=4
    [/attack]
    [attack]
        name=longbow
        description=_"longbow"
        icon=attacks/bow-elven.png
        type=pierce
        range=short
        [specials]
            {WEAPON_SPECIAL_MARKSMAN}
        [/specials]
        damage=9
        number=4
		movement_used=4
    [/attack]

    [attack]
        name=ice arrow
        description=_"ice arrow"
        icon=attacks/bow-elven-magic.png
        type=cold
        range=ranged
        [specials]
            {WEAPON_SPECIAL_MARKSMAN}
			{WEAPON_SPECIAL_REQUIRE_FROST}
			{WEAPON_SPECIAL_IS_RANGED}
        [/specials]
        damage=7
        number=2
		movement_used=2
    [/attack]
    [attack]
        name=ice arrow
        description=_"ice arrow"
        icon=attacks/bow-elven-magic.png
        type=cold
        range=short
        [specials]
			{WEAPON_SPECIAL_MARKSMAN}
			{WEAPON_SPECIAL_REQUIRE_FROST}
        [/specials]
        damage=7
        number=2
		movement_used=2
    [/attack]
The ice arrow is an extra seperate attack that is activated via having an Elf Enchantress adjacent, when the Elf Marksman is ordered to attack at range via right-click menu its still fetching the 7-2 Ice arrow attack to be used even if there is no Enchantress adjacent to the unit and is thus disabled. Its supposed to fetch only the longbow attack with no Enchantress present. How can i prevent this ?

Code: Select all

#define SPECIAL_NOTES_EXI_AMMO_SUPPLIER_ICE
_" 
this unit can allow Elf Marksmen and Sharpshooters to use arrows with ice damage."#enddef
#define ABILITY_EXI_AMMO_SUPPLIER_ICE
    [dummy]
        id=exi_frostammo
        name= _ "enchant arrows"
        description= _ "this unit is able to supply 'ice arrows' to adjacent friendly Elf Marksmen and Sharpshooters when they fight."
    [/dummy]
#enddef
#define WEAPON_SPECIAL_REQUIRE_FROST
    [disable]
        id=exi_needs_frost
        name=""
        description=""
        [filter_self]
            [filter_adjacent]
				adjacent=n,ne,se,s,sw,nw
                is_enemy=no
                count=0
				ability=exi_frostammo
            [/filter_adjacent]
        [/filter_self]
    [/disable]
#enddef

User avatar
Eagle_11
Forum Regular
Posts: 672
Joined: November 20th, 2013, 12:20 pm

Re: Eagle WML Questions: how to filter disabled attacks? +more

Post by Eagle_11 » March 30th, 2018, 11:16 am

As of 1.13.12, {WEAPON_SPECIAL_IS_RANGED} completely stopped taking effect. Why did this occur and how to fix it. ?

User avatar
zookeeper
WML Wizard
Posts: 9685
Joined: September 11th, 2004, 10:40 pm
Location: Finland

Re: Eagle WML Questions: how to filter disabled attacks? +more

Post by zookeeper » March 30th, 2018, 12:08 pm

Eagle_11 wrote:
March 30th, 2018, 11:16 am
As of 1.13.12, {WEAPON_SPECIAL_IS_RANGED} completely stopped taking effect. Why did this occur and how to fix it. ?
Are you sure you want only people who already know your code to be able to try to answer?

User avatar
Eagle_11
Forum Regular
Posts: 672
Joined: November 20th, 2013, 12:20 pm

Re: Eagle WML Questions: how to filter disabled attacks? +more

Post by Eagle_11 » March 30th, 2018, 3:19 pm

1.13.10 : When 2 Elf Archers with this spec on their ranged attack are attempting to attack each other, correctly disables the attack the spec is given to for both.
1.13.12: Only the opponent's attack with this spec gets disabled. Wanted is behavior of .10

Code: Select all

#define WEAPON_SPECIAL_IS_RANGED
    [disable]
        id=is_ranged
        name=""
        description=""
		#apply_to=self
        [filter_self]
            [filter_adjacent]
				adjacent=n,ne,se,s,sw,nw
                is_enemy=yes
                count=1-6
            [/filter_adjacent]
        [/filter_self]
    [/disable]
#enddef

Post Reply