object duration query

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.
Post Reply
Spannerbag
Posts: 39
Joined: December 18th, 2016, 6:14 pm

object duration query

Post by Spannerbag » June 6th, 2019, 1:29 pm

Hi,

Could anyone help/clarify what I'm doing wrong with [object] please?

I'm writing/testing the last scenario of my campaign which involves the player recalling units last used several scenarios earlier (this all works).
Let's call this scenario Final.

Some of these recallable units were granted temporary status=unpoisonable in the previous scenario they appeared in (let's call this Earlier) as below:

Code: Select all

      [option]
        message= _ "Drink it!"
        [command]
          [sound]
            name=potion.ogg
          [/sound]
          [heal_unit]		# Full heal (I'm nice like that :-)
            [filter]
              {FILTER}
            [/filter]
            amount=full
            animate=yes
            restore_statuses=yes
          [/heal_unit]
          [object]
            take_only_once=no
            duration=scenario
            [filter]
              {FILTER}
            [/filter]
            [effect]
              apply_to=status
              add=unpoisonable
            [/effect]
          [/object]
          [unit_overlay]
            {FILTER}
            image=items/potion-red-overlay.png
          [/unit_overlay]
          [remove_item]
            image=items/potion-red.png
            x,y=$x1,$y1
          [/remove_item]
        [/command]
        [show_if]
          [have_unit]
            {FILTER}
            [not]
              status=unpoisonable
            [/not]
          [/have_unit]
        [/show_if]
      [/option]
At the end of Earlier the overlay is removed and the units left on-map (i.e. I don't do anything unusual with/to them).
However when at least one of the above units is recalled in Final it is still unpoisonable, despite

Code: Select all

duration=scenario
I have an idea but as re-testing this is going to be somewhat fiddly and time-consuming (there are quite a few scenarios between Earlier and Final) I'd like to get it right first time, hence this post.

The documentation states that an [object] needs an id to be removable. Does this include an object's duration? Will adding an id fix it?
Alternatively I could manually [remove_object] in Earlier - but 'd rather use wml properly.
I suspect that perhaps, without an id, only the first unit to be made unpoisonable has this removed when Earlier ends - but as I have no idea which unit this was I can't easily verify.

So if anyone can explain why the above duration clause doesn't work, I'd be really grateful!

Thanks in advance for your time and trouble.
I suspect the universe is simpler than we think and stranger than we can know.

User avatar
josteph
Developer
Posts: 706
Joined: August 19th, 2017, 6:58 pm

Re: object duration query

Post by josteph » June 6th, 2019, 1:52 pm

Can you look at the unit's WML in the "Final" scenario and check whether it has the [object]? You can open the savefile directly or use :debug and :inspect in-game. I'd like to see whether the object is still there, or whether it was expired/removed but its effects not undone.
Spannerbag wrote:
June 6th, 2019, 1:29 pm
I have an idea but as re-testing this is going to be somewhat fiddly and time-consuming (there are quite a few scenarios between Earlier and Final) I'd like to get it right first time, hence this post.
Why is it a problem that there are many scenarios in between? You could use debug mode to skip them.

Spannerbag wrote:
June 6th, 2019, 1:29 pm
I suspect that perhaps, without an id, only the first unit to be made unpoisonable has this removed when Earlier ends - but as I have no idea which unit this was I can't easily verify.
I checked the source. game_board::heal_all_survivors() calls unit::new_scenario() for each unit, which calls expire_modifications(""), which removes all modifications that have duration set to any value other than "forever". So, no, it shouldn't be a question of which unit got the status first. You can confirm this by letting only one unit drink the potion.

Spannerbag
Posts: 39
Joined: December 18th, 2016, 6:14 pm

Re: object duration query

Post by Spannerbag » June 6th, 2019, 9:05 pm

Hi josteph,

Thanks for taking the trouble to reply, much appreciated.
josteph wrote:
June 6th, 2019, 1:52 pm
Can you look at the unit's WML in the "Final" scenario and check whether it has the [object]? You can open the savefile directly or use :debug and :inspect in-game. I'd like to see whether the object is still there, or whether it was expired/removed but its effects not undone.

I have saved the linger screen from Earlier and remembered a couple of units that were unpoisonable. I can confirm that the [object] is removed when Earlier finishes but that they remain unpoisonable. Out of paranoia, I also checked the unit in Final and that also had no [object] and was unpoisonable.

So it seems that the [object] is correctly and successfully being removed but its [effect] is persisting?
josteph wrote:
June 6th, 2019, 1:52 pm
Spannerbag wrote:
June 6th, 2019, 1:29 pm
I have an idea but as re-testing this is going to be somewhat fiddly and time-consuming (there are quite a few scenarios between Earlier and Final) I'd like to get it right first time, hence this post.
Why is it a problem that there are many scenarios in between? You could use debug mode to skip them.
Not tried that... might work. These scenarios change leaders a lot and I'm not sure skipping through would save everthing correctly. But there are no branches etc. so I could give it a try :)

Any further thoughts? If you want the relevant unit data please let me know.

Again, many thanks for taking the trouble to reply!
I suspect the universe is simpler than we think and stranger than we can know.

User avatar
josteph
Developer
Posts: 706
Joined: August 19th, 2017, 6:58 pm

Re: object duration query

Post by josteph » June 6th, 2019, 9:48 pm

Spannerbag wrote:
June 6th, 2019, 9:05 pm
So it seems that the [object] is correctly and successfully being removed but its [effect] is persisting?
Yeah.

First things first, to get it working as you want, set some flag on the units involved (a custom status on the unit, or a variable listing unit id's) and use that to manually remove unpoisonable at the end of "Earlier" or at the start of one of the subsequent scenarios.

What can the engine do better here? EffectWML is not always reversible (for example, how would we reverse an effect that doubles the hitpoints until end of turn, if the unit's hitpoint changed between getting the effect and end of turn?). Still, even if we can't auto-remove effects in the general case, we should at least improve the wiki documentation, and maybe add some [effect][on_expiry] tag akin to [on_undo] in events.

Spannerbag
Posts: 39
Joined: December 18th, 2016, 6:14 pm

Re: object duration query

Post by Spannerbag » June 6th, 2019, 10:24 pm

josteph wrote:
June 6th, 2019, 9:48 pm
Spannerbag wrote:
June 6th, 2019, 9:05 pm
So it seems that the [object] is correctly and successfully being removed but its [effect] is persisting?
Yeah.

First things first, to get it working as you want, set some flag on the units involved (a custom status on the unit, or a variable listing unit id's) and use that to manually remove unpoisonable at the end of "Earlier" or at the start of one of the subsequent scenarios.

What can the engine do better here? EffectWML is not always reversible (for example, how would we reverse an effect that doubles the hitpoints until end of turn, if the unit's hitpoint changed between getting the effect and end of turn?). Still, even if we can't auto-remove effects in the general case, we should at least improve the wiki documentation, and maybe add some [effect][on_expiry] tag akin to [on_undo] in events.
One last thing, I tested by adding the [object] with and without an id but it made no difference.
Re. manual status change what's the best way? Ideally I'd like to use something that takes a filter such as [modify_unit] but I'm not sure that would work.
A rather laborious but probably reliable way might be to [store_unit] filtered by status=unpoisonable then [for] each set unit.status.unpoisonable=no ?
Would that work?

As ever, thanks for your time and trouble.
I suspect the universe is simpler than we think and stranger than we can know.

Spannerbag
Posts: 39
Joined: December 18th, 2016, 6:14 pm

Re: object duration query : undo status

Post by Spannerbag » June 6th, 2019, 11:15 pm

Hi josteph,

After a bit of experimentation I found a way to reset the status using:

Code: Select all

          [object]
            take_only_once=no
            duration=turn
            [filter]
              {FILTER}
            [/filter]
            [effect]
              apply_to=status
              remove=unpoisonable
            [/effect]
          [/object]
:inspect shows the relevant [status] entry has been removed :)

Thanks for your help, much appreciated.
I suspect the universe is simpler than we think and stranger than we can know.

User avatar
josteph
Developer
Posts: 706
Joined: August 19th, 2017, 6:58 pm

Re: object duration query

Post by josteph » June 7th, 2019, 7:40 pm

Spannerbag wrote:
June 6th, 2019, 10:24 pm
A rather laborious but probably reliable way might be to [store_unit] filtered by status=unpoisonable then [for] each set unit.status.unpoisonable=no ?
Note that would also remove unpoisonable status from units that had it to start with (for example, any undead units on the recall list). Hence I was thinking of having the potion set both unit.status.unpoisonable and a custom status (say, unit.status.Spannerbag_potion) on the drinking unit and then filtering for units that have the custom status to identify which units need to have their unpoisonability removed.
Spannerbag wrote:
June 6th, 2019, 11:15 pm
After a bit of experimentation I found a way to reset the status using:
Hmm. It's a duration=turn effect so you're basically relying again on the "effects are not automatically reverted" behavior that we started with. I'd try [modify_unit] [status] unpoisonable= [/status] [/modify_unit], but note the warning in the last paragraph of https://wiki.wesnoth.org/DirectActionsW ... fy_unit.5D
Spannerbag wrote:
June 6th, 2019, 11:15 pm
Thanks for your help, much appreciated.
You're very welcome :)

gfgtdf
Developer
Posts: 1181
Joined: February 10th, 2013, 2:25 pm

Re: object duration query

Post by gfgtdf » June 7th, 2019, 8:10 pm

I think also had already problems with the same issue, the problem (for the engine) is that we have some statuses, like poisoned/slowed that we clearly don't want to be cleared on 'unit reset' that are properties of single units and other statuses (unpoisonable, etc, that are often properties of unit types) where it would make sense to do so. ( I think the was also a random no mirror add-on in 1.12 where player sometimes got falsey unpoisonable units because they originally got a undead leader but the add-on changed it to another type but the unpoisonable property remained).

Maybe it'd make sense to have dinner global register that lists all 'volatile' statuses.
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.

Spannerbag
Posts: 39
Joined: December 18th, 2016, 6:14 pm

Re: object duration query

Post by Spannerbag » June 13th, 2019, 10:27 pm

josteph wrote:
June 7th, 2019, 7:40 pm
Hmm. It's a duration=turn effect so you're basically relying again on the "effects are not automatically reverted" behavior that we started with. I'd try [modify_unit] [status] unpoisonable= [/status] [/modify_unit], but note the warning in the last paragraph of https://wiki.wesnoth.org/DirectActionsW ... fy_unit.5D
Wow, almost a week's gone by... tempus fugit!
Not had chance to explore the various modify_unit and object permutations, I'm just glad to have something that works, even if it is a bit of a bodge (like about 87% of my wml :D ).

Out of interest, does anyone know of any decent primers on custom terrain? I simply want to alias elven villages (I have created ruined elven villages graphics and am using them as an item + village overlay but if I could make them into custom terrain that'd be preferable).

As ever, thanks for your help and comments!
I suspect the universe is simpler than we think and stranger than we can know.

Spannerbag
Posts: 39
Joined: December 18th, 2016, 6:14 pm

Re: object duration query

Post by Spannerbag » June 14th, 2019, 9:11 pm

Re: my previous post asking for help with custom terrain, there's no need to respond: managed to it working.
Cheerio!
I suspect the universe is simpler than we think and stranger than we can know.

Post Reply