Problems with [object] and [remove_object]

The place to post your WML questions and answers.

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.
User avatar
Bob_The_Mighty
Posts: 870
Joined: July 13th, 2006, 1:15 pm

Problems with [object] and [remove_object]

Post by Bob_The_Mighty »

[remove_object] is a new tag in 1.13.7 which allows you to remove previously applied objects. It's really useful, but either I'm not sure how it works or it has problems.

It seems fine in simple cases (adding and subtracting moves, resistances, etc), but there's a potential bug when it is used multiple times - as I've discovered in Bob's RPG Era. I can't quite work out what is going on, and the results sometimes seem inconsistent.

Imagine a unit picks up a holy sword that uses [object] to changes its melee damage type from blade to arcane. Later the unit picks up a fancy ring that uses [object] to change its melee damage type to fire. What happens if the unit drops the holy sword? What is the result of using [remove_object] in this case? Will the damage type stay as fire or revert to blade? If the unit drops the ring would it switch to arcane or blade?

I've also found that weapon specials applied via [object] can be lost when another [object] is used to affect the same attack. In addition, an [object] applied to a unit can be lost when another [object] causes it to change variation (whether or not inherit=yes is present).

I've also discovered a problem with using [object] to apply unit halos, as posted here.

Lastly, and this is more of a feature request, could we expand the uses of the 'duration' key? Currently an object can last until the end of the scenario; until the end of the turn; or forever. Could we have something that made it last for x turns? This would be very useful for controlling temporary custom bonuses and status without the faff of creating a sort of internal variable clock.
My current projects:
MP pirate campaign: The Altaz Mariners
RPG sequel: Return to Trent
MP stealth campaign: Den of Thieves
gfgtdf
Developer
Posts: 1432
Joined: February 10th, 2013, 2:25 pm

Re: Problems with [object] and [remove_object]

Post by gfgtdf »

Bob_The_Mighty wrote:[remove_object] is a new tag in 1.13.7 which allows you to remove previously applied objects. It's really useful, but either I'm not sure how it works or it has problems.

It seems fine in simple cases (adding and subtracting moves, resistances, etc), but there's a potential bug when it is used multiple times - as I've discovered in Bob's RPG Era. I can't quite work out what is going on, and the results sometimes seem inconsistent.

Imagine a unit picks up a holy sword that uses [object] to changes its melee damage type from blade to arcane. Later the unit picks up a fancy ring that uses [object] to change its melee damage type to fire. What happens if the unit drops the holy sword? What is the result of using [remove_object] in this case? Will the damage type stay as fire or revert to blade? If the unit drops the ring would it switch to arcane or blade?
it should still be fire, unless ofcourse the ring only changes melee arcance attacks to type fire.
Bob_The_Mighty wrote: I've also found that weapon specials applied via [object] can be lost when another [object] is used to affect the same attack. In addition, an [object] applied to a unit can be lost when another [object] causes it to change variation (whether or not inherit=yes is present).

I've also discovered a problem with using [object] to apply unit halos, as posted here.

Lastly, and this is more of a feature request, could we expand the uses of the 'duration' key? Currently an object can last until the end of the scenario; until the end of the turn; or forever. Could we have something that made it last for x turns? This would be very useful for controlling temporary custom bonuses and status without the faff of creating a sort of internal variable clock.
the underlying lua function wesnoth.remove_modifications is actuall even mor powerful than [remove_object] you can use to implement arbitary 'durations', for example you cna have a wml event

Code: Select all

[event]
name=new_turn
[lua]
code = <<

for i, unit in ipairs(wesnoth.get_units({})) do
		wesnoth.remove_modifications(unit, {duration = "turn_" .. wesnoth.current.turn})
end

>>
[lua]
[/event]

to create a 'turn x' duration which expires at tunr x
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.
User avatar
Bob_The_Mighty
Posts: 870
Joined: July 13th, 2006, 1:15 pm

Re: Problems with [object] and [remove_object]

Post by Bob_The_Mighty »

gfgtdf wrote:it should still be fire, unless ofcourse the ring only changes melee arcance attacks to type fire.
What if you use [remove_object] to take away the ring while the unit still has the sword? Does the attack revert to blade, i.e. the unit's original damage type? Or does it still track the previous holy sword [object] and change to arcane? Do you see what I mean?

Am I better off using [modify_unit] for multiple overlapping items? What's the difference between using [modify_unit] containing modification/object and using object directly?
My current projects:
MP pirate campaign: The Altaz Mariners
RPG sequel: Return to Trent
MP stealth campaign: Den of Thieves
gfgtdf
Developer
Posts: 1432
Joined: February 10th, 2013, 2:25 pm

Re: Problems with [object] and [remove_object]

Post by gfgtdf »

Bob_The_Mighty wrote:
gfgtdf wrote:it should still be fire, unless ofcourse the ring only changes melee arcance attacks to type fire.
What if you use [remove_object] to take away the ring while the unit still has the sword? Does the attack revert to blade, i.e. the unit's original damage type? Or does it still track the previous holy sword [object] and change to arcane? Do you see what I mean?
well, since it still has the sword it will still be arcance.
Bob_The_Mighty wrote: Am I better off using [modify_unit] for multiple overlapping items? What's the difference between using [modify_unit] containing modification/object and using object directly?
there is no real diference between using [object] diectly and [modify_unit][object] except that the later will apply ot all units mathing the filter while the first will only apply to the first unit found. Also [modify_unit]might also be able to effect units on te recall list, not sure though.
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.
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Problems with [object] and [remove_object]

Post by Celtic_Minstrel »

When you use [remove_object] to remove an object, the effect is the same as if that object had never been applied. After removing objects, the unit is reverted to the base unit and all remaining objects are re-applied in order. (This is called "rebuilding the unit", and also happens when the unit levels up.)
Bob_The_Mighty wrote:Imagine a unit picks up a holy sword that uses [object] to changes its melee damage type from blade to arcane. Later the unit picks up a fancy ring that uses [object] to change its melee damage type to fire. What happens if the unit drops the holy sword? What is the result of using [remove_object] in this case? Will the damage type stay as fire or revert to blade? If the unit drops the ring would it switch to arcane or blade?
This depends on how the [object] is defined.

Suppose both objects use just range=melee as the weapon filter to determine which weapon to affect. In that case, dropping the ring would change the melee damage to arcane, and dropping the holy sword would change the melee damage to fire.

However, if the ring used range,type=melee,arcane as the weapon filter to determine which weapon to affect, then dropping the holy sword would change the melee damage to blade, because the filter in the ring's object no longer matches the weapon. Dropping the ring would still change the melee damage to arcane in this case.
Bob_The_Mighty wrote:I've also found that weapon specials applied via [object] can be lost when another [object] is used to affect the same attack.
Can you give a specific example of this? I'm pretty sure objects are always applied in the same order, which would suggest this sort of thing shouldn't happen, but I might be misunderstanding what you said.
Bob_The_Mighty wrote:In addition, an [object] applied to a unit can be lost when another [object] causes it to change variation (whether or not inherit=yes is present).
This is definitely possible if the [object] has a filter that no longer matches the new variation, because changing the variation triggers a rebuild. It's not a bug; this is intended behaviour. I rely on this (though in reverse) in my campaign, where a single [object] defines abilities that the unit will gain as they level up.
Bob_The_Mighty wrote:Am I better off using [modify_unit] for multiple overlapping items? What's the difference between using [modify_unit] containing modification/object and using object directly?
Basic [modify_unit] is pretty terrible when you have multiple overlapping items, because it basically means you have to decide yourself exactly how everything interacts. This does not apply to [object] nested in [modify_unit] though, which works exactly the same as a normal [object] nested in [unit] (ie, lacking the action-specific features such as a popup message, failure command, filter, etc).
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Bob_The_Mighty
Posts: 870
Joined: July 13th, 2006, 1:15 pm

Re: Problems with [object] and [remove_object]

Post by Bob_The_Mighty »

Thanks for explaining how it works. The stuff about 'rebuilding the unit' was very helpful, and lead me to fix my problem. A filter wasn't working because I was manipulating unit.attack[0].name when I should have been using set_name= in the [object][effect].
My current projects:
MP pirate campaign: The Altaz Mariners
RPG sequel: Return to Trent
MP stealth campaign: Den of Thieves
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Problems with [object] and [remove_object]

Post by Celtic_Minstrel »

Note: Everywhere I was talking about `[object]` having a filter above, it should have been `[effect]` having a filter. The generic `[object]` tag does not support a filter (only the ActionWML version does).
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Bob_The_Mighty
Posts: 870
Joined: July 13th, 2006, 1:15 pm

Re: Problems with [object] and [remove_object]

Post by Bob_The_Mighty »

Hey chaps. I'm still getting problems with [remove_object], this time on 1.13.10. It seems to me that using this tag to remove an object from a unit inadvertently also removes poison and slow.
Celtic_Minstrel wrote:After removing objects, the unit is reverted to the base unit and all remaining objects are re-applied in order. (This is called "rebuilding the unit", and also happens when the unit levels up.)
Does this mean that when the unit is rebuilt the game forgets to reapply the status conditions? I've tested this in two ways. 1) poisoning a unit by manipulating the variable, e.g. unit.status.poisoned. 2) by attacking an orcish assassin. In both cases the poison can be cleared afterwards by triggering a menu item with a [remove_object] tag.
My current projects:
MP pirate campaign: The Altaz Mariners
RPG sequel: Return to Trent
MP stealth campaign: Den of Thieves
gfgtdf
Developer
Posts: 1432
Joined: February 10th, 2013, 2:25 pm

Re: Problems with [object] and [remove_object]

Post by gfgtdf »

Does this mean that when the unit is rebuilt the game forgets to reapply the status conditions? I've tested this in two ways. 1) poisoning a unit by manipulating the variable, e.g. unit.status.poisoned. 2) by attacking an orcish assassin. In both cases the poison can be cleared afterwards by triggering a menu item with a [remove_object] tag.
Well thee are two problems involved here:
1) you seem to assume that clearing status on rebuild unit is unwanted behaviour, while this is indeeed true for temporary statusses like poinned, this it's not true for things like unpoisonable which is usulually added via [effect] (it doesnt matter whether the effect comes from a trait or an object)
2) rebuilding the unit reaplies all effects, in particular it reapplies the 'heal_full' effect of standard amlas that why there are always some problem with using [remove_object] on a unit that has taken a standard amla.
3) The game engine has some workarounds to partly fix the issues i meantioned above (hp resetting, special treament of poisoned status), but they are rather fragile, and i wouldn't be suprised if they sometimes do more harm than good.
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.
User avatar
Bob_The_Mighty
Posts: 870
Joined: July 13th, 2006, 1:15 pm

Re: Problems with [object] and [remove_object]

Post by Bob_The_Mighty »

1. I assumed that the fact temporary statuses are lost is a bug. Are you saying it's intended behaviour or just explaining how it currently works?
2. This sounds like a bug too, no?
3. What are these workarounds? Do I have to implement them in my WML or do they happen automatically?
My current projects:
MP pirate campaign: The Altaz Mariners
RPG sequel: Return to Trent
MP stealth campaign: Den of Thieves
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Problems with [object] and [remove_object]

Post by Celtic_Minstrel »

If you have a temporary status that needs to not be lost when rebuilding the unit, you could apply the status with an [object], which would cause it to not be lost. You can then make that object expire however and whenever you want.

I think there was a fix for the HP resetting. Not sure whether or not it made it to 1.13.10, but it not it'll certainly be in 1.13.11.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Bob_The_Mighty
Posts: 870
Joined: July 13th, 2006, 1:15 pm

Re: Problems with [object] and [remove_object]

Post by Bob_The_Mighty »

Celtic_Minstrel wrote:If you have a temporary status that needs to not be lost when rebuilding the unit, you could apply the status with an [object], which would cause it to not be lost. You can then make that object expire however and whenever you want.
Okay, that's good to know. I guess I can rewrite all my code to accommodate that. However, what about 'naturally' occurring poison from Ghouls/Assassins? These statuses are also lost when using the tag.
Celtic_Minstrel wrote:I think there was a fix for the HP resetting. Not sure whether or not it made it to 1.13.10, but it not it'll certainly be in 1.13.11.
Cool, I'll keep an eye out and give it a test.
My current projects:
MP pirate campaign: The Altaz Mariners
RPG sequel: Return to Trent
MP stealth campaign: Den of Thieves
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Problems with [object] and [remove_object]

Post by Celtic_Minstrel »

Really? I thought there was a special case to preserve poison through unit rebuilds...
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Re: Problems with [object] and [remove_object]

Post by Sapient »

Here's what TRANSFORM_UNIT does. It's not perfect but it is pretty reasonable. I think it would be appropriate for [remove_object] to do likewise:

Code: Select all

#define TRANSFORM_UNIT FILTER TYPE
    # Transforms all units matching the filter into TYPE or if missing, their normal advancement
    # Keeps the unit's hitpoints, experience and status intact.
    #
    # Example to turn all spearmen into cavalrymen:
    #! {TRANSFORM_UNIT type=Spearman Cavalryman}
    [store_unit]
        [filter]
            {FILTER}
        [/filter]
        variable=TU_store
        kill=no
    [/store_unit]
    {ADVANCE_UNIT ({FILTER}) ({TYPE}) }
    {FOREACH TU_store TRANSFORM_UNIT_i}
        [store_unit]
            [filter]
                id=$TU_store[$TRANSFORM_UNIT_i].id
            [/filter]
            variable=TUrestore_store
            kill=yes
        [/store_unit]
        [set_variables]
            name=TUrestore_store
            mode=merge
            [value]
                hitpoints=$TU_store[$TRANSFORM_UNIT_i].hitpoints
                experience=$TU_store[$TRANSFORM_UNIT_i].experience
                [insert_tag]
                    name=status
                    variable=TU_store[$TRANSFORM_UNIT_i].status
                [/insert_tag]
            [/value]
        [/set_variables]
        [if]
            [variable]
                name=TUrestore_store.status.unpoisonable
                boolean_equals=true
            [/variable]
            [then]
                [clear_variable]
                    name=TUrestore_store.status.poisoned
                [/clear_variable]
            [/then]
        [/if]
        [unstore_unit]
            variable=TUrestore_store
            find_vacant=no
            advance=false
        [/unstore_unit]
        {CLEAR_VARIABLE TUrestore_store}
    {NEXT TRANSFORM_UNIT_i}
    {CLEAR_VARIABLE TU_store}
#enddef
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
gfgtdf
Developer
Posts: 1432
Joined: February 10th, 2013, 2:25 pm

Re: Problems with [object] and [remove_object]

Post by gfgtdf »

Bob_The_Mighty wrote:1. I assumed that the fact temporary statuses are lost is a bug. Are you saying it's intended behaviour or just explaining how it currently works?
My point was that there are temporary statuses (poisoned) and nontemporary statuses (unpoisonable) and that the game (at least the [remove_object] code) doesn't know the difference, so both ways ('preserve all statuses' and 'reset all statuses') would be wrong. Whihc makes this rather hard to fix, specially since umc may define custom stuses which which the engine cannot know ehther they are temporary or not.
Bob_The_Mighty wrote: 3. What are these workarounds? Do I have to implement them in my WML or do they happen automatically?
Iirc the c++ game engine does some workarounds that tries to fix the problems above, but they are rather 'hacky' to it's hard to see from looking at the code how it would behave in a certain case, which makes i questionable whetehr they really improve things.
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.
Post Reply