How does one filter units based on traits
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.
- Col Lightbeam
- Posts: 46
- Joined: November 18th, 2008, 1:01 am
How does one filter units based on traits
Where would I find help in making an event filter that works for all units only in one type of terrain (I already know mostly how to do this) at the beginning of each turn (I think I could do this without help) and NOT (I think I could do this without help) if they have "X" trait (this is the part that seems the biggest issue)?
Mix Era Of Magic, Era of Myths, and Extended Era and you get all my favorite teams on one group! and ULTIMATE POWER!!!!!!!!!!!!
Also in the programming industry... later.
Also in the programming industry... later.
Re: How does one filter units based on traits
A StandardUnitFilter for filtering for a trait:
Code: Select all
[filter_wml]
[modifications]
[trait]
id=strong
[/trait]
[/modifications]
[/filter_wml]
Re: How does one filter units based on traits
We really should add this to the SUF so it is easier to check traits and weapon specials by id. Although for weapon specials it may be better to add a full blown [filter_weapon] rather than a top-level special= check.
Unfortunately I don't have my computer set up for building the code right now, but it should be an Easy Coding Task.
Unfortunately I don't have my computer set up for building the code right now, but it should be an Easy Coding Task.
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
- Col Lightbeam
- Posts: 46
- Joined: November 18th, 2008, 1:01 am
Re: How does one filter units based on traits
What did I do wrong with this bit of code?
What the apparent result is that the turns accelerate, and both leaders die on turn 1.
Nevermind...
I forgot one set of it seems.
Now, it is this and it appears not to work anymore...
What did I do wrong?
Code: Select all
###voiddeath###
[event]
name=new turn
first_time_only=no
[have_unit]
side=$side_number
x,y=$x1,$y1
[/have_unit]
[filter_location]
terrain="Xv"
[/filter_location]
[not]
[filter_wml]
[modifications]
[trait]
id=spacewalker
[/trait]
[/modifications]
[/filter_wml]
[/not]
[kill]
x=$x1
y=$y1
animate=no
[/kill]
[/event]
Nevermind...
I forgot one set of
Code: Select all
[filter][/filter]
Now, it is this and it appears not to work anymore...
Code: Select all
###voiddeath###
[event]
name=new turn
first_time_only=no
[filter]
[have_unit]
side=$side_number
x,y=$x1,$y1
[/have_unit]
[filter_location]
terrain="Xv"
[/filter_location]
[/filter]
[not]
[filter_wml]
[modifications]
[trait]
id=spacewalker
[/trait]
[/modifications]
[/filter_wml]
[/not]
[kill]
x=$x1
y=$y1
animate=no
[/kill]
[/event]
Last edited by Col Lightbeam on August 30th, 2010, 9:31 pm, edited 1 time in total.
Mix Era Of Magic, Era of Myths, and Extended Era and you get all my favorite teams on one group! and ULTIMATE POWER!!!!!!!!!!!!
Also in the programming industry... later.
Also in the programming industry... later.
Re: How does one filter units based on traits
First off, [have_unit] makes no sense by itself, it needs to be in a [if], and it will eventually be followed by a [then]. Look a some exemples from mainline, there are plenty.
Second, [filter_location] and [filter_wml] should be inside your [have_unit]
Third, I really doubt there is a x1 and y1 in a new turn event, since this event doesn't necessarily concern a unit in particular (contrarily to attacker hits, for instance). You will need to store the concerned unit, and then use that stored version to kill it. In fact, you can probably skip the whole [if] and [have_unit] part if you just go with an efficient [store_unit].
Second, [filter_location] and [filter_wml] should be inside your [have_unit]
Third, I really doubt there is a x1 and y1 in a new turn event, since this event doesn't necessarily concern a unit in particular (contrarily to attacker hits, for instance). You will need to store the concerned unit, and then use that stored version to kill it. In fact, you can probably skip the whole [if] and [have_unit] part if you just go with an efficient [store_unit].
Jazz is not dead, it just smells funny - Frank Zappa
Current projects: Internet meme Era, The Settlers of Wesnoth
Current projects: Internet meme Era, The Settlers of Wesnoth
- Col Lightbeam
- Posts: 46
- Joined: November 18th, 2008, 1:01 am
Re: How does one filter units based on traits
I tried what you said and it just caused the effect of the first set of code in my last post
this is the code I tried:
I got it to delay accl turns and loss of units until after there was a unit that fulfilled the conditions by
Now how do you get it to only destroy units that fill that condition?
And thanks for that tip about
this is the code I tried:
Code: Select all
###voiddeath###
[event]
name=new turn
first_time_only=no
[store_unit]
[filter]
x=$x1
y=$y1
[/filter]
[filter_location]
terrain="Xv"
[/filter_location]
[filter_wml]
[not]
[modifications]
[trait]
id=spacewalker
[/trait]
[/modifications]
[/not]
[/filter_wml]
kill=yes
mode=replace
variable=worker
[/store_unit]
[/event]
Code: Select all
###voiddeath###
[event]
name=new turn
first_time_only=no
[if]
[have_unit]
[filter]
x=$x1
y=$y1
[/filter]
[filter_location]
terrain="Xv"
[/filter_location]
[filter_wml]
[not]
[modifications]
[trait]
id=spacewalker
[/trait]
[/modifications]
[/not]
[/filter_wml]
[/have_unit]
[then]
[store_unit]
kill=yes
[/store_unit]
[/then]
[/if]
[/event]
And thanks for that tip about
Code: Select all
mode=replace
Last edited by Col Lightbeam on August 30th, 2010, 11:20 pm, edited 2 times in total.
Mix Era Of Magic, Era of Myths, and Extended Era and you get all my favorite teams on one group! and ULTIMATE POWER!!!!!!!!!!!!
Also in the programming industry... later.
Also in the programming industry... later.
- Pentarctagon
- Project Manager
- Posts: 5564
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: How does one filter units based on traits
fyi, the mode=replace line is redundant since replace is the default value anyway. also, it seems that x1 and y1 do exist in a new turn event, however their values are both -999, which could explain why nothing is happening.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
- Col Lightbeam
- Posts: 46
- Joined: November 18th, 2008, 1:01 am
Re: How does one filter units based on traits
I got it to work except it seems to ignore the filter of
Code: Select all
[not]
[modifications]
[trait]
id=spacewalker
[/trait]
[/modifications]
[/not]
Mix Era Of Magic, Era of Myths, and Extended Era and you get all my favorite teams on one group! and ULTIMATE POWER!!!!!!!!!!!!
Also in the programming industry... later.
Also in the programming industry... later.
Re: How does one filter units based on traits
Your code is so, so wrong. I suggest you give this a good read. Also, follow the link to standard unit filter, because it has great wisdom to share with you, and you could use it. And get rid of x1 and y1, they make no sense used there. If you really must, you can use "$this_unit.x,$this_unit.y", but it is pointless.
Ideally, you would also clear the variable the units are stored into.
Ideally, you would also clear the variable the units are stored into.
Jazz is not dead, it just smells funny - Frank Zappa
Current projects: Internet meme Era, The Settlers of Wesnoth
Current projects: Internet meme Era, The Settlers of Wesnoth
- Col Lightbeam
- Posts: 46
- Joined: November 18th, 2008, 1:01 am
Re: How does one filter units based on traits
I guess this is one reason why some people aren't good at advice...Dixie wrote:Your code is so, so wrong. I suggest you give this a good read. Also, follow the link to standard unit filter, because it has great wisdom to share with you, and you could use it. And get rid of x1 and y1, they make no sense used there. If you really must, you can use "$this_unit.x,$this_unit.y", but it is pointless.
Ideally, you would also clear the variable the units are stored into.
You say "Your code is so, so wrong" and yet give little thought to explaining it. I WAS and still AM at the suggested places and you seem to imply that
would help me somehow without directing me to any specific place. This is kind of like saying as a person's lawyer in response to a question concerning problems with court logic "It is in here" and handing him or her a law book. Please, if you are to give suggestions, at least help by saying how your logic is superior (in other words why you are right and I am wrong) and how to correct that. You may think that you ARE being helpful, but it seems to me you are just handing me a law book (extreme example but sufficient I think) and say "It is in here". Certainly a computer could in theory read through the law book and mix and match looking for the problem, but that takes a very smart computer and I am nowhere near at putting different combinations together and seeing results quickly."StandardUnitFilter
From Wesnoth
From FilterWML, this is the standard way of filtering units.
When a unit filter is applied to a map, first it applies to all units on the field, based on their coordinates. Next it applies to units in the recall list. This is important to remember as it means, for example, that the tag [kill] can be used to kill units in the recall list.
You can access the filtered unit within the filter as the $this_unit variable, see SingleUnitWML for the possible content of these variables
The term StandardUnitFilter means that the set of such keys and tags (see below) can appear at that point. Often a StandardUnitFilter needs to be included in a [filter] tag. But many tags take the StandardUnitFilter directly as an argument, like [kill] and [have_unit].
The following attributes and sub-tags are allowed:
* id: unit matches the given description. This is the same as id in the [unit] tag. Note that it is independent of a unit's user-visible name, which can be internationalized independent of this. See SingleUnitWML.
* speaker: alias for description
* type: matches the unit's type name (can be a list of types)
* race: the race of the unit type.
Mainline races are listed in data/core/units.cfg
* ability: unit has an ability with the given id; see AbilitiesWML
* side: the unit is on the given side (can be a list)
* has_weapon: the unit has a weapon with the given name
* canrecruit: yes if the unit can recruit (i.e. is a leader)
* gender: female if the unit is female rather than the default of male
* role: the unit has been assigned the given role; see [role], InternalActionsWML
* level: the level of the unit
* defense: current defense of the unit on current tile (chance to hit %, like in movement type definitions)
* movement_cost: current movement cost of the unit on current tile
* x,y: the position of the unit. Note: there is a special case for units on the recall list such that x,y="recall,recall"
* find_in: name of an array or container variable; if present, the unit will not match unless it is also found stored in the variable
* [filter_vision]: this tests whether or not the unit is currently visible
o visible: yes or no, default yes. In Wesnoth 1.6.4 "yes" filters for units (visible or invisible) in visible locations. Filtering for unit (in)visibility requires "no".
o viewing_side: the side(s) which you are checking if they are able to see (or not see) the unit. All sides listed here must pass the test. If no side is listed, it will check the visibility all enemy sides.
* [filter_wml]: this is WML level filter for the unit. In it, you can filter on anything that is in the WML description of a unit. This description can be found in any savegame also in SingleUnitWML.
* [and]: an extra unit filter. Unless the unit also matches the [and] filter, then it will not count as a match. Note: [and],[or], and [not] filters are considered after the containing filter; they are then processed in the order encountered.
* [or]: an extra unit filter. If a unit matches the [or] filter, then it will count as a match regardless of conditions in previous filters or the containing filter.
* [not]: an extra unit filter. If a unit matches the [not] filter, then that unit will not be considered a match by the containing filter.
* [filter_adjacent]: standard unit filter; if present the correct number of adjacent units must match this filter
o count: a number, range, or comma separated range; default "1-6"
o adjacent: a comma separated list of directions; default "n,ne,se,s,sw,nw"
o is_enemy: a boolean specifying whether the adjacent unit must be an enemy or an ally (optional)
* [filter_location]: StandardLocationFilter - the tile that the unit is standing on matches the location filter.
* formula: FormulaAI like formula returning a boolean. The unit filtered is an implicit variable in the call.
* lua_function: the name of a Lua function in the global environment that takes a unit as an argument and returns true if the given unit matches the filter. StandardUnitFilter
From Wesnoth
From FilterWML, this is the standard way of filtering units.
When a unit filter is applied to a map, first it applies to all units on the field, based on their coordinates. Next it applies to units in the recall list. This is important to remember as it means, for example, that the tag [kill] can be used to kill units in the recall list.
You can access the filtered unit within the filter as the $this_unit variable, see SingleUnitWML for the possible content of these variables
The term StandardUnitFilter means that the set of such keys and tags (see below) can appear at that point. Often a StandardUnitFilter needs to be included in a [filter] tag. But many tags take the StandardUnitFilter directly as an argument, like [kill] and [have_unit].
The following attributes and sub-tags are allowed:
* id: unit matches the given description. This is the same as id in the [unit] tag. Note that it is independent of a unit's user-visible name, which can be internationalized independent of this. See SingleUnitWML.
* speaker: alias for description
* type: matches the unit's type name (can be a list of types)
* race: the race of the unit type.
Mainline races are listed in data/core/units.cfg
* ability: unit has an ability with the given id; see AbilitiesWML
* side: the unit is on the given side (can be a list)
* has_weapon: the unit has a weapon with the given name
* canrecruit: yes if the unit can recruit (i.e. is a leader)
* gender: female if the unit is female rather than the default of male
* role: the unit has been assigned the given role; see [role], InternalActionsWML
* level: the level of the unit
* defense: current defense of the unit on current tile (chance to hit %, like in movement type definitions)
* movement_cost: current movement cost of the unit on current tile
* x,y: the position of the unit. Note: there is a special case for units on the recall list such that x,y="recall,recall"
* find_in: name of an array or container variable; if present, the unit will not match unless it is also found stored in the variable
* [filter_vision]: this tests whether or not the unit is currently visible
o visible: yes or no, default yes. In Wesnoth 1.6.4 "yes" filters for units (visible or invisible) in visible locations. Filtering for unit (in)visibility requires "no".
o viewing_side: the side(s) which you are checking if they are able to see (or not see) the unit. All sides listed here must pass the test. If no side is listed, it will check the visibility all enemy sides.
* [filter_wml]: this is WML level filter for the unit. In it, you can filter on anything that is in the WML description of a unit. This description can be found in any savegame also in SingleUnitWML.
* [and]: an extra unit filter. Unless the unit also matches the [and] filter, then it will not count as a match. Note: [and],[or], and [not] filters are considered after the containing filter; they are then processed in the order encountered.
* [or]: an extra unit filter. If a unit matches the [or] filter, then it will count as a match regardless of conditions in previous filters or the containing filter.
* [not]: an extra unit filter. If a unit matches the [not] filter, then that unit will not be considered a match by the containing filter.
* [filter_adjacent]: standard unit filter; if present the correct number of adjacent units must match this filter
o count: a number, range, or comma separated range; default "1-6"
o adjacent: a comma separated list of directions; default "n,ne,se,s,sw,nw"
o is_enemy: a boolean specifying whether the adjacent unit must be an enemy or an ally (optional)
* [filter_location]: StandardLocationFilter - the tile that the unit is standing on matches the location filter.
* formula: FormulaAI like formula returning a boolean. The unit filtered is an implicit variable in the call.
* lua_function: the name of a Lua function in the global environment that takes a unit as an argument and returns true if the given unit matches the filter. "
Now to give Dixie some credit, He did help me reduce lines of code for an older problem I had with his suggestion.
(By the way I was looking for [switch] which works almost like the Select Case for Visual basic for praychance)
Soo, if one is to act and talk superior, please act and talk superior in a helpful way... Like including answers to "How" and "Why"
Mix Era Of Magic, Era of Myths, and Extended Era and you get all my favorite teams on one group! and ULTIMATE POWER!!!!!!!!!!!!
Also in the programming industry... later.
Also in the programming industry... later.
Re: How does one filter units based on traits
but perfect description cannot be found there. this seems to be a problem of the page.* [filter_wml]: this is WML level filter for the unit. In it, you can filter on anything that is in the WML description of a unit. This description can be found in any savegame also in SingleUnitWML.
(sorry if this post of mine is not to the point)
Re: How does one filter units based on traits
Don't put the [not] inside the [filter_wml] since it just does blind WML matching... put it outside wrapping it instead. The [and] [or] [not] tags are not allowed anywhere you might want them, but only where explicitly stated in the Reference.
Also, I agree it would be nice if people refrained from posting unhelpful or discouraging comments. I think what they were trying to say is that you are placing tags in places where they make sense to you (based on other situations) but not where the reference explicitly states they are allowed.
Also, I agree it would be nice if people refrained from posting unhelpful or discouraging comments. I think what they were trying to say is that you are placing tags in places where they make sense to you (based on other situations) but not where the reference explicitly states they are allowed.
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
Re: How does one filter units based on traits
[not] works fine inside [filter_wml]. [and] and [or] don't.Sapient wrote:Don't put the [not] inside the [filter_wml] since it just does blind WML matching... put it outside wrapping it instead. The [and] [or] [not] tags are not allowed anywhere you might want them, but only where explicitly stated in the Reference.
- Ken_Oh
- Moderator Emeritus
- Posts: 2178
- Joined: February 6th, 2006, 4:03 am
- Location: Baltimore, Maryland, USA
Re: How does one filter units based on traits
Heh, yeah, I was about to get confused here for a minute.
Re: How does one filter units based on traits
Hmmm... well that's rather counter-intuitive and undocumented.
Anyways I wouldn't rely on such a behavior because if it is undocumented and counter-intuitive then it is likely be removed in a future version.
Back to your problem, this looks bad:
[store_unit]
kill=yes
[/store_unit]
It should warn you that [store_unit] requires a [filter], if it ever tried to execute that line.
There may be other bugs as well.
Anyways I wouldn't rely on such a behavior because if it is undocumented and counter-intuitive then it is likely be removed in a future version.
Back to your problem, this looks bad:
[store_unit]
kill=yes
[/store_unit]
It should warn you that [store_unit] requires a [filter], if it ever tried to execute that line.
There may be other bugs as well.
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."