Spreading Poison
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.
Spreading Poison
Hey,
for a very specific scenario I want to have poison spreading.
I tried to do this by using wml:
https://forums.wesnoth.org/viewtopic.php?t=48985
https://wiki.wesnoth.org/FilterWML
https://wiki.wesnoth.org/FilterWML/Exam ... use_Filter
Any ideas (yea it would be better to define a custom status, but that looks very unhandy so I take a cheap solution and then just limit the scenario to only few poisoning units)
for a very specific scenario I want to have poison spreading.
Code: Select all
Forall units.status_poisoned
poison_nearby_friendly_units
https://forums.wesnoth.org/viewtopic.php?t=48985
https://wiki.wesnoth.org/FilterWML
https://wiki.wesnoth.org/FilterWML/Exam ... use_Filter
Code: Select all
[event]
name="side turn"
first_time_only=no
#this filter works; I've tested it with other commands
[filter]
side=$side_number
[filter_wml]
[status]
poisoned=yes
[/status]
[/filter_wml]
[/filter]
#doesnt work properly; I think because of the filter
[modify_unit]
[filter]
# Finds teammates with with the advancing unit next to them.
side=$unit.side
[filter_adjacent]
id=$unit.id
[/filter_adjacent]
[/filter]
hitpoints=1
[/modify_unit]
[/event]
Re: Spreading Poison
I've not done anything similar to what you're trying to do, but it looks to me like your code is trying to poison a side, instead of units. You may need to store, poison, and unstore all the adjacent units in the targeted side. You might investigate that idea while waiting for an experienced coder to pipe in.
Author of:
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
Re: Spreading Poison
Hey @Helmet I am not really sure about this since in the topic above someone describes the part I use up there as "working" (first link in initial post). The grabbing of all poisoned units works fine, but I think what doesnt work is that "all poisoned units" is a set/sum/aggregate or however wesnoth may call it of units instead of a single unit and instead of automatically applying the effect to all units it fails to do anything meaningful (since unit.id is unclear).
If I would write this in another language I would try something like:
This is of course very simple pseudo-code but I think one can understand what I mean
If you don't know how to do it, don't worry thanks for your help anyway!
If I would write this in another language I would try something like:
Code: Select all
adjacentUnits = []
foreach unit in AllUnits
if unit.isPoisoned
adjacentUnits.add(unit)
foreach unit in adjacentUnits
unit.setPoisoned = true
If you don't know how to do it, don't worry thanks for your help anyway!
Re: Spreading Poison
Hi,
I don't think side turn events take filters.
This might be what you're after, or close to it.
I didn't test this, let us know if it works.
Edit:
The filter_side tag can be further simplified with
I don't think side turn events take filters.
This might be what you're after, or close to it.
Code: Select all
[event]
name="side turn"
first_time_only=no
[modify_unit]
[filter]
side=$side_number
[not]
status=poisoned
[/not]
[filter_adjacent]
status=poisoned
[filter_side]
[allied_with]
side=$side_number
[/allied_with]
[/filter_side]
[/filter_adjacent]
[/filter]
# Apply poisoned effect
[effect]
apply_to=status
add=poisoned
[/effect]
[/modify_unit]
[/event]
Edit:
The filter_side tag can be further simplified with
is_enemy=no
instead filter_side and allied_with
Last edited by vghetto on December 9th, 2020, 10:03 pm, edited 1 time in total.
Re: Spreading Poison
Just because you specifically said "this filter works" in your first post, I must comment: that filter doesn't do anything. It's a side turn event, that doesn't take a unit filter. Btw, even the
Actually, I think your pseude-code is also wrong. You search for poisoned units, then add them to a list of some kind, and then just poison the poisoned ones again. (Works in Gwent probably )
The trick is to search for the adjacent units, and that's the trick here too, but it's not very difficult thanks to the [filter_adjacent] tag. Do this in your event:
You should probably use the more robust [foreach] tag instead of the old {FOREACH} macro (I'm just someone who refuses to go on and always uses the old syntax). If might also be a better idea to use a [modify_unit][effect] to apply the poison instead of directly editing the status with {MODIFY_UNIT}.
EDIT: vghetto's code in the earlier post is better than mine, it works on the same principle, but it's more concise.
side=$side_number
doesn't really make sense. Stored event variables are not available at filter level, because they are created at the time when they are first accessed in the event. (For that, the event must start executing).Actually, I think your pseude-code is also wrong. You search for poisoned units, then add them to a list of some kind, and then just poison the poisoned ones again. (Works in Gwent probably )
The trick is to search for the adjacent units, and that's the trick here too, but it's not very difficult thanks to the [filter_adjacent] tag. Do this in your event:
Code: Select all
[store_unit]
[filter]
[filter_adjacent]
status=poisoned # yes, the [filter_wml] way works too but it's slower.
[/filter_adjacent]
[/filter]
variable=spread_poison
[/store_unit]
{FOREACH spread_poison i}
{MODIFY_UNIT id=$spread_poison[$i] status.poisoned yes}
{NEXT i}
{CLEAR_VARIABLE spread_poison}
EDIT: vghetto's code in the earlier post is better than mine, it works on the same principle, but it's more concise.
Main UMC campaigns: The Ravagers - now for 1.16, with new bugs!
Old UMC works: The Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny
Old UMC works: The Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny
Re: Spreading Poison
First thank you @vghetto! Your solution works like a charm (with and without edit; even though the edit is nicer of course)
I would like to explain your code back to you, so I can make sure that I understand it right in order to enable me to do similar stuff on my own in the future...
is that right more or less? Is there a major advantage of filtering by going through not poisoned units? Is it just simpler in WML?
@WhiteWolf
Ye, you right ^^ that pseudo-code was garbage! Tbh I didn't gave it much thought, because I think my problem wasn't a structural one, but just me being new to WML. (I could argue though that I never defined add, but let's be honest )
You claim that my filter up there doesn't do much which is right in it's context, but the context is given by the first link in the initial post. I just tested the filter in a different structure:
This one where it works.
I could've been more precise saying that I only know that the filter works; not if it is in the right place.
I am still very new to WML so I mostly work with what I find online tinkering around, seeing what works and what doesn't.
Thanks for all your help (to all of you)!
I would like to explain your code back to you, so I can make sure that I understand it right in order to enable me to do similar stuff on my own in the future...
Code: Select all
On every side turn
modify all units where side=currentSide
unit is not poisoned
and there is an adjacent unit
and that unit is poisoned and not_enemy
and modify it with the effect: add poison to status
@WhiteWolf
Ye, you right ^^ that pseudo-code was garbage! Tbh I didn't gave it much thought, because I think my problem wasn't a structural one, but just me being new to WML. (I could argue though that I never defined add, but let's be honest )
You claim that my filter up there doesn't do much which is right in it's context, but the context is given by the first link in the initial post. I just tested the filter in a different structure:
Code: Select all
[event]
name="side turn"
first_time_only=no
[modify_unit]
[filter]
side=$side_number
[filter_wml]
[status]
poisoned=yes
[/status]
[/filter_wml]
[/filter]
side=$unit.side
[/modify_unit]
[/event]
I could've been more precise saying that I only know that the filter works; not if it is in the right place.
I am still very new to WML so I mostly work with what I find online tinkering around, seeing what works and what doesn't.
Thanks for all your help (to all of you)!
Re: Spreading Poison
Yes, you got it. I excluded the already poisoned to reduce the iteration size. It might not matter much in terms of performance.
Re: Spreading Poison
If you are familiar with that kind of languages, it might be suitable to implement some logic with Lua. https://wiki.wesnoth.org/LuaWMLJustNatan wrote: ↑December 9th, 2020, 8:04 pm If I would write this in another language I would try something like:
Code: Select all
adjacentUnits = [] foreach unit in AllUnits if unit.isPoisoned adjacentUnits.add(unit) foreach unit in adjacentUnits unit.setPoisoned = true
Re: Spreading Poison
Hey,
@Ravana
maybe this is an option. I haven't done much with lua yet, but I might give it a go
I feel more and more like wesnoth is either very badly documented or I am very stupid...
I tried to switch 'name="side turn"' to 'name="turn end"'. Both set the variable side_number to the current side (turn end before switching) so I thought this would move my poison spreading effect to end of turn. But now nothing happens.
I feel like Wesnoth doesn't give a lot of feedback; or do I have to activate a debug_mode or something like that?
Full code:
@Ravana
maybe this is an option. I haven't done much with lua yet, but I might give it a go
I feel more and more like wesnoth is either very badly documented or I am very stupid...
I tried to switch 'name="side turn"' to 'name="turn end"'. Both set the variable side_number to the current side (turn end before switching) so I thought this would move my poison spreading effect to end of turn. But now nothing happens.
I feel like Wesnoth doesn't give a lot of feedback; or do I have to activate a debug_mode or something like that?
Full code:
Code: Select all
[event]
name="turn end"
first_time_only=no
[modify_unit]
[filter]
side=$side_number
[not]
status=poisoned
[/not]
[filter_adjacent]
status=poisoned
is_enemy=no
[/filter_adjacent]
[/filter]
# Apply poisoned effect
[effect]
apply_to=status
add=poisoned
[/effect]
[/modify_unit]
[/event]
- lhybrideur
- Posts: 369
- Joined: July 9th, 2019, 1:46 pm
Re: Spreading Poison
Maybe $side_number is initialized in side turn and not in turn end
Re: Spreading Poison
turn end
fires once at the end of the whole turn, when the last side passes. You probably didn't get to that point in your test, that's why you didn't see anything at all. You want side turn end
for this application $side_turn, (and all prestored event variables as far as I know), are initialized when they are first accessed in the respective event. So that's not a problem.
Wesnoth's documentation is here: https://wiki.wesnoth.org/Referencewml
There's a list of all the tags in the right pane, whenever in doubt of how something works, just check it - it's got all keys and their behaviour explained. (The number and quality of examples could indeed be improved though.)
To be honest, the easiest way to debug stuff is the equivalent of printf("does it get to this pont?"):
Code: Select all
[message]
speaker=narrator
message= _ "Game, tell me if we got to this point in the code or not."
[/message]
Main UMC campaigns: The Ravagers - now for 1.16, with new bugs!
Old UMC works: The Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny
Old UMC works: The Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny
Re: Spreading Poison
It took me a while to learn how to use the WML Wiki. The information presented is concise, literal, deficient in examples, and presupposes that you understand a lot about about WML and have memorized the acronyms and definitions for terms. However, once you get to a certain point in your self-education with WML, the Wiki becomes very helpful. It is almost never wrong about anything. I can't count the number of times I went back to the Wiki after solving a problem, thinking the Wiki misled me, only to discover that I had not read a passage carefully enough.
I think a lot of people collect their own code examples in a file, as a supplement to the Wiki.
Author of:
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
DIY Campaign, Confederacy of Swamp Creatures: Big Battle 1, Confederacy of Swamp Creatures: Big Battle 2, Frogfolk Delivery Service, The Pool of Ek.
Re: Spreading Poison
I've had this thought for a while in mind … I think what is missing is a new landing page in the wiki for people who are new here, which tells where to start. Maybe you guys want to write one? You're new enough to know what is missing.Helmet wrote: […]
What I feel what is missing:
- telling people how to use their computer: Installing an editor, getting syntax highlighting, installing python, opening a terminal, how to start wesnoth with the `-d` flag.
- A hint about how to debug: the existence of `:ínspect` for example.
- Explaining the difference between the preprocessor and WML. It's not a big deal, but unless one know this, a lot of things remain unclear later on. It's not the first thing one needs to know though …
- The difference between code which is just data and code which is code … or in other words, explaining events. (Someone did that pretty good in one of the threads here recently)
Personally, I made some notes over the last year to come up with a how to get into Lua page.
Try out the dark board theme.
Re: Spreading Poison
I just tried again (the old version), because I was really sure that I got to the point where the last side passes and again it didn't work. I assume that "last side passes" means: The last side passes and the turn counter is incremented.
Your version on the other hand works; but I don't know why the "turn end" doesn't. It doesn't make a lot of a difference to me tbh I am fine with both solutions; and probably "side turn end" is fairer.
This actually helped a little, not because I've never seen the wml pages of wesnoth, but because it shows some kind of structure I haven't seen before.WhiteWolf wrote: ↑December 11th, 2020, 11:53 am Wesnoth's documentation is here: https://wiki.wesnoth.org/Referencewml
There's a list of all the tags in the right pane, whenever in doubt of how something works, just check it - it's got all keys and their behaviour explained. (The number and quality of examples could indeed be improved though.)
But this is not enough to constitute a good documentation. But I guess I have to lower my expectations since it's a non-commercial project after all (examples for good documentation: Documentation of supercollider (the linking system in the supercollider IDE is great), bootstrap https://getbootstrap.com/docs/4.1/getti ... roduction/ documentation or spring boot probably as well https://docs.spring.io/spring-boot/docs ... tmlsingle/. You can also name stuff like hoogle https://hoogle.haskell.org/ there are a lot of examples)
For me it'sShiki wrote: ↑December 11th, 2020, 4:27 pm What I feel what is missing:
- telling people how to use their computer: Installing an editor, getting syntax highlighting, installing python, opening a terminal, how to start wesnoth with the `-d` flag.
- A hint about how to debug: the existence of `:ínspect` for example.
- Explaining the difference between the preprocessor and WML. It's not a big deal, but unless one know this, a lot of things remain unclear later on. It's not the first thing one needs to know though …
- The difference between code which is just data and code which is code … or in other words, explaining events. (Someone did that pretty good in one of the threads here recently)
-One example for every piece of code. (by having one page/tag(I am not sure how it's called in wesnoth))
-More explicit explanations and better structure (by having one page/tag(I am not sure how it's called in wesnoth))
-A Guide for everything
-Common mistake list
-Best practice routines
-Q&A of most common questions
But also: If a filter cannot be interpreted by wesnoth, just throw an error!
Tbh my syntax highlighting is prob. not the best I use Visual Studio Code with WML 1.07 by Aaron Winter.
What do you need python for when coding for wesnoth (I don't know much about wesnoth's internal structure)?
--
Anyway, probably it's just me feeling bad about having to ask you guys so many questions cause I can't figure it out on my own for some reason
Re: Spreading Poison
That's correct,
turn end
fires just before the turn counter is incremented. Maybe it didn't work because the last side didn't have any poisoned units? Keep in mind that the code still has $side_number in it, which at "turn end" equals to the last side, and the code only runs for that one.If you run wesnoth in a terminal on linux, there's logs in it. It's also outputted to some log.txt on windows (I don't know where, someone will need to clarify the exact location). Those logs do contain these types of warnings. But there is no way for Wesnoth to tell you problems with stuff that is not syntactically wrong. No programming language compiler can do that.But also: If a filter cannot be interpreted by wesnoth, just throw an error!
There's a collection of syntax highlighters that people use for various editors in this topic.Tbh my syntax highlighting is prob. not the best I use Visual Studio Code with WML 1.07 by Aaron Winter.
What do you need python for when coding for wesnoth (I don't know much about wesnoth's internal structure)?
Main UMC campaigns: The Ravagers - now for 1.16, with new bugs!
Old UMC works: The Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny
Old UMC works: The Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny