how to filter for unknown weapon specials (of any kind)
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.
how to filter for unknown weapon specials (of any kind)
hello i want to check if a weapon has unknown weapon special.
(via weapon filter)
the task is to filter weapons that have CUSTOM specials, which can have any tag name.
so i just check if there are NO ALREADY KNOWN specials,
but this check would also be true if the weapon has NO SPECIAL AT ALL
so i need to ensure that there is no "empty" weapon special field.
so it checks that the field is not empty, but also contains no known specials, so the conclusion is that there is unknown special.
so the main question is how to check if a weapon has no special at all
something like:
special_type=notexistant/empty
this check below wont work, so also weapons with NO special will return positive
(via weapon filter)
the task is to filter weapons that have CUSTOM specials, which can have any tag name.
so i just check if there are NO ALREADY KNOWN specials,
but this check would also be true if the weapon has NO SPECIAL AT ALL
so i need to ensure that there is no "empty" weapon special field.
so it checks that the field is not empty, but also contains no known specials, so the conclusion is that there is unknown special.
so the main question is how to check if a weapon has no special at all
something like:
special_type=notexistant/empty
this check below wont work, so also weapons with NO special will return positive
Code: Select all
[effect]
apply_to=attack
[not]
special_type=notexistant #or empty <----------------- how to check this ?
[or]
special_type=swarm
[/or]
[or]
special_type=slow
[/or]
[or]
special_type=poison
[/or]
[or]
special_type=plague
[/or]
[or]
special_type=petrifies
[/or]
[or]
special_type=heal_on_hit
[/or]
[or]
special_type=drains
[/or]
[or]
special_type=poison
[/or]
[or]
special_type=firststrike
[/or]
[or]
special_type=disable
[/or]
[or]
special_type=damage
[/or]
[or]
special_type=chance_to_hit
[/or]
[or]
special_type=berserk
[/or]
[or]
special_type=attacks
[/or]
[/not]
.......
The best bet is your own, good Taste.
- Spannerbag
- Posts: 552
- Joined: December 18th, 2016, 6:14 pm
- Location: Yes
Re: how to filter for unknown weapon specials (of any kind)
Hmm... first off don't know why you start your code withMabuse wrote: ↑August 5th, 2023, 11:53 pm hello i want to check if a weapon has unknown weapon special.
(via weapon filter)
the task is to filter weapons that have CUSTOM specials, which can have any tag name.
so i just check if there are NO ALREADY KNOWN specials,
but this check would also be true if the weapon has NO SPECIAL AT ALL
so i need to ensure that there is no "empty" weapon special field.
so it checks that the field is not empty, but also contains no known specials, so the conclusion is that there is unknown special.
so the main question is how to check if a weapon has no special at all
something like:
special_type=notexistant/empty
this check below wont work, so also weapons with NO special will return positive
Code: Select all
[effect] apply_to=attack [not] special_type=notexistant #or empty <----------------- how to check this ? [or] special_type=swarm [/or] [or] special_type=slow [/or] [or] special_type=poison [/or] [or] special_type=plague [/or] [or] special_type=petrifies [/or] [or] special_type=heal_on_hit [/or] [or] special_type=drains [/or] [or] special_type=poison [/or] [or] special_type=firststrike [/or] [or] special_type=disable [/or] [or] special_type=damage [/or] [or] special_type=chance_to_hit [/or] [or] special_type=berserk [/or] [or] special_type=attacks [/or] [/not] .......
[effect]
?In the code below (which is a first hack so may need experimentation to get it exactly right) the weapon filter (
[has_attack]
) does the work but I also wrapped it in a unit [filter]
in case you want to limit the unit(s) to be processed in some other (non-weapon) way. If not you'll need to remove the [filter]
and replace [has_attack]
with [filter_attack]
.Cleverer people than me might have more elegant/efficient solutions by using lua and/or a more intricate formula but I've stuck with WML.
Note that within
[filter]
where I've typed "..." just means "other unit identifiers" such as "x,y=23,9" and/or "side=1" etc.I think within the weapon filter the comma separated list of specials should work but if not your code above with lots of individual
[not]
clauses should work.Also the wiki lists the full range of specials as:
[attacks]: modifies the number of attacks of a weapon
[berserk]: pushes the attack for more than one combat round
[chance_to_hit]: modifies the chance to hit of a weapon
[damage]: modifies the damage of a weapon
[disable]: disables the weapon
[drains]: heals the attacker half of the damage dealt
[firststrike]: forces the weapon to always strike first
[heal_on_hit]: heals the attacker when an attack connects
[petrifies]: turns the target to stone
[plague]: when used to kill an enemy, a friendly unit takes its place
[poison]: poisons the target
[slow]: slows the target
[swarm]: number of strikes decreases as the unit loses hitpoints
[berserk]: pushes the attack for more than one combat round
[chance_to_hit]: modifies the chance to hit of a weapon
[damage]: modifies the damage of a weapon
[disable]: disables the weapon
[drains]: heals the attacker half of the damage dealt
[firststrike]: forces the weapon to always strike first
[heal_on_hit]: heals the attacker when an attack connects
[petrifies]: turns the target to stone
[plague]: when used to kill an enemy, a friendly unit takes its place
[poison]: poisons the target
[slow]: slows the target
[swarm]: number of strikes decreases as the unit loses hitpoints
So the filter below will (hopefully) exclude them all.
Note: this logic filters by [
tag_name
] not the special id
so will also exclude customised versions of existing specials such as a modified form of [berserk]
that only lasts for 3 rounds.So if you do not want to exclude these customised versions of existing specials you'll need to filter by
special_id
rather than special_type
.This will make
[plague]
messy because it has multiple ids as shown below.
Code: Select all
#define WEAPON_SPECIAL_PLAGUE_TYPE TYPE
# Canned definition of the Plague ability to be included in a
# [specials] clause (with type specifier).
[plague]
id=plague({TYPE})
name= _ "plague"
description= _ "When a unit is killed by a Plague attack, that unit is replaced with a unit on the same side as the unit with the Plague attack. This doesn’t work on Undead or units in villages."
type={TYPE}
[/plague]
#enddef
[specials]
clause that also does not include the regular specials so if a weapon has a "standard" special and a custom one then I think this logic will miss it.You'll need to sort out the detail, I can only provide starting points
As I say this has been coded on the spot so might need some tweaking (or major surgery ).
Code: Select all
[filter]
...
[has_attack]
range=melee # Or =ranged or omit if you want both
[not]
special_type=attacks,berserk,chance_to_hit,damage,disable,drains,firststrike,heal_on_hit,petrifies,plague,poison,slow,swarm
[/not]
formula="length(specials) > 0" # Weapon has a special
[/has_attack]
[/filter]
You could fix the formula or, alternatively, you could remove it then after
[has_attack]
add this instead:
Code: Select all
[/has_attack] # After has_attack
[filter_wml]
[specials] # Inside [attack] tag
[/filter_wml]
[filter_wml]
will accept an unclosed tag like [specials]
but it's worth a try.Also this means not everything is done inside a weapon filter
Note that I used:
Code: Select all
[not]
special_type=attacks,berserk,chance_to_hit,damage,disable,drains,firststrike,heal_on_hit,petrifies,plague,poison,slow,swarm
[/not]
special_type=null
because this would, I imagine, possibly exclude the custom specials you want depending on how they were implemented... maybe.
It's also possible that certain specials that were implemented as, say, events might be missed (because they would not be recognised as such by the game's filters). You'll know better than me if this is a problem or not.
Not had chance to test this myself but it might get you part way there?
Good luck,
Cheers!
-- Spannerbag
Re: how to filter for unknown weapon specials (of any kind)
special_type represents weapon special tag name, and empty tag name is not allowed in wml. So you can be sure it is never empty. And all valid tags are allowed in abilities, so notexistant is also allowed, but wont do anything without events.
Maintainer of Ageless Era. Ravana's Multiplayer Works
Re: how to filter for unknown weapon specials (of any kind)
Hello
the identification is simply used to remove them
(by now i copy over every weapon that has no KNOWN special (also weapons without a special) a useless-special (this process will remove all existing specials) and then remove that useless-special again, so weapons with unknown specials and weapon without specials end up with no specials.)
but in case your solution work, i will use that since then (for the sake of compensation) its possible to replace any unknown custom specials with a basic special like "magical" e.g., and give them a small damage boost or something
because its just a part of a trait (its inside a trait that is applied to the leader of a side at start of the game)Spannerbag wrote: ↑August 6th, 2023, 2:37 pm Hmm... first off don't know why you start your code with[effect]
?
hey, that looks interesting, i will try thatSpannerbag wrote: ↑August 6th, 2023, 2:37 pmCode: Select all
[filter] ... formula="length(specials) > 0" # Weapon has a special [/filter]
if the above wont work i might take look at thatSpannerbag wrote: ↑August 6th, 2023, 2:37 pm If the formula doesn't work I've probably done something wrong.
You could fix the formula or, alternatively, you could remove it then after[has_attack]
add this instead:Though I'm not sure ifCode: Select all
[/has_attack] # After has_attack [filter_wml] [specials] # Inside [attack] tag [/filter_wml]
[filter_wml]
will accept an unclosed tag like[specials]
but it's worth a try.
Also this means not everything is done inside a weapon filter
custom specials that use the "standardized" tags are by now no problem, a damage tag will influence the damage in one way or another, sure it can be OP, but a units can be itself OP, so it doesnt matter - but non-standardized custom tags may do completely crazy thingsSpannerbag wrote: ↑August 6th, 2023, 2:37 pm Note that I used:rather than (assuming it works):Code: Select all
[not] special_type=attacks,berserk,chance_to_hit,damage,disable,drains,firststrike,heal_on_hit,petrifies,plague,poison,slow,swarm [/not]
special_type=null
because this would, I imagine, possibly exclude the custom specials you want depending on how they were implemented... maybe.
It's also possible that certain specials that were implemented as, say, events might be missed (because they would not be recognised as such by the game's filters). You'll know better than me if this is a problem or not.
Not had chance to test this myself but it might get you part way there?
the identification is simply used to remove them
(by now i copy over every weapon that has no KNOWN special (also weapons without a special) a useless-special (this process will remove all existing specials) and then remove that useless-special again, so weapons with unknown specials and weapon without specials end up with no specials.)
but in case your solution work, i will use that since then (for the sake of compensation) its possible to replace any unknown custom specials with a basic special like "magical" e.g., and give them a small damage boost or something
thank you, help is very appreciated
The best bet is your own, good Taste.
- Spannerbag
- Posts: 552
- Joined: December 18th, 2016, 6:14 pm
- Location: Yes
Re: how to filter for unknown weapon specials (of any kind)
Ah, OK... I see you like making life easy for yourselfMabuse wrote: ↑August 6th, 2023, 6:07 pm Hello
because its just a part of a trait (its inside a trait that is applied to the leader of a side at start of the game)Spannerbag wrote: ↑August 6th, 2023, 2:37 pm Hmm... first off don't know why you start your code with[effect]
?
Hope it (or something like it) works...Mabuse wrote: ↑August 6th, 2023, 6:07 pmhey, that looks interesting, i will try thatSpannerbag wrote: ↑August 6th, 2023, 2:37 pmCode: Select all
[filter] ... formula="length(specials) > 0" # Weapon has a special [/filter]
So if I understand you correctly, you assign a dummy (useless) special to all weapons without a known special (including weapons with no special) then remove it. What happens if a weapon has both one or more known special(s) and one or more custom special(s)? Can this even happen in your campaign/project?Mabuse wrote: ↑August 6th, 2023, 6:07 pm custom specials that use the "standardized" tags are by now no problem, a damage tag will influence the damage in one way or another, sure it can be OP, but a units can be itself OP, so it doesnt matter - but non-standardized custom tags may do completely crazy things
the identification is simply used to remove them
(by now i copy over every weapon that has no KNOWN special (also weapons without a special) a useless-special (this process will remove all existing specials) and then remove that useless-special again, so weapons with unknown specials and weapon without specials end up with no specials.)
but in case your solution work, i will use that since then (for the sake of compensation) its possible to replace any unknown custom specials with a basic special like "magical" e.g., and give them a small damage boost or something
Just curious.
Glad to help
Hope you get your logic working the way you want!
Cheers!
-- Spannerbag
- Spannerbag
- Posts: 552
- Joined: December 18th, 2016, 6:14 pm
- Location: Yes
Re: how to filter for unknown weapon specials (of any kind)
Ah, I didn't think that through... really shouldn't type stuff without taking a second or two to check it makes sense!
Cheers!
-- Spannerbag
Re: how to filter for unknown weapon specials (of any kind)
yes, it can happen since you might use whatever era you want in the scenario.Spannerbag wrote: ↑August 6th, 2023, 8:29 pm So if I understand you correctly, you assign a dummy (useless) special to all weapons without a known special (including weapons with no special) then remove it. What happens if a weapon has both one or more known special(s) and one or more custom special(s)? Can this even happen in your campaign/project?
Just curious.
and you are right, this is a big disadvantage of the approach currently.
i guess i cant work around storing a unit, and iterate over every weapon, and compare every special on that weapon with a valid-list, and if it doesnt match, store the id of that non-valid-special and then delete it.
The best bet is your own, good Taste.
- Celtic_Minstrel
- Developer
- Posts: 2263
- Joined: August 3rd, 2012, 11:26 pm
- Location: Canada
- Contact:
Re: how to filter for unknown weapon specials (of any kind)
Your formula approach is probably better, but this line of reasoning isn't completely off track. All you have to do is add a closingSpannerbag wrote: ↑August 6th, 2023, 2:37 pm If the formula doesn't work I've probably done something wrong.
You could fix the formula or, alternatively, you could remove it then after[has_attack]
add this instead:Though I'm not sure ifCode: Select all
[/has_attack] # After has_attack [filter_wml] [specials] # Inside [attack] tag [/filter_wml]
[filter_wml]
will accept an unclosed tag like[specials]
but it's worth a try.
Also this means not everything is done inside a weapon filter
[specials
tag and also wrap that in an [attack]
tag, and it'll match only units that have [specials]
in an [attack]
. The only caveat is… that might be all units. I haven't checked, but it's possible the game automatically inserts an empty [specials]
tag on attacks that don't have any specials.Now, moving on to the more important part… your formula has an error in it. I realize this might be a little confusing, but the
length()
function in WFL measures the length of a string. If you try to use it on a list, you'll only get null()
and an error message. The function to get the number of elements in a list is size()
.And to make things even more confusing, I don't actually recommend using either of those functions. This is how I would write the formula:
Code: Select all
formula="specials.size > 0"
.size
over size()
is simply that it also works on strings, so it's less confusing. There might actually be an argument for deprecating the functions and making this the sole supported way of getting the size of a list, string, or map in WFL.There is also one other option:
Code: Select all
formula="not specials.empty"
- Spannerbag
- Posts: 552
- Joined: December 18th, 2016, 6:14 pm
- Location: Yes
Re: how to filter for unknown weapon specials (of any kind)
OK... so could I summarise what you want to do as follows?Mabuse wrote: ↑August 7th, 2023, 1:39 amyes, it can happen since you might use whatever era you want in the scenario.Spannerbag wrote: ↑August 6th, 2023, 8:29 pm So if I understand you correctly, you assign a dummy (useless) special to all weapons without a known special (including weapons with no special) then remove it. What happens if a weapon has both one or more known special(s) and one or more custom special(s)? Can this even happen in your campaign/project?
Just curious.
and you are right, this is a big disadvantage of the approach currently.
In my campaign if a player decides to use an era/mod/resource/whatever that adds custom weapon specials (via custom tags) then these should be discarded.
That is, variants of specials that use standard tags (such as a berserk attack with a duration different to regular berserk) would be allowed but a special with a non-standard tag, like
[vorpal_strike]
(or, I guess [berserk_3]
?) would not.Have I understood correctly?
Had a bit of a think about the best way to do that and yeah, it's a bit gnarly.
I can see ways to do it (maybe) but they ain't pretty
And they all seem to involve iterating through all the units one way or another.
There doesn't seem to be any way in WML to store_weapon (unless I missed it).
Heh, I started mulling over how I'd do this in detail and ended up, I suspect, pretty much where you'd already gotten to, so I gave up
I found extracting the actual specials quite laborious, so hopefully I missed something and you've found a more elegant method...
Anyway, good luck!
Cheers!
-- Spannerbag