canrecruit=yes as an AMLA option

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.
Post Reply
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

canrecruit=yes as an AMLA option

Post by vghetto »

Hi,

I want to give the recruiting ability from within the AMLA advancement framework.

Something like this:

Code: Select all

    [advancement]
        strict_amla=yes
        max_times=1
        id=amla_canrecruit
        description= _ "Can recruit, Max XP +20%"
        image="icons/amla-default.png"

        [effect]
            apply_to=canrecruit
        [/effect]
    [/advancement]
Now [effect] doesn't have apply_to=canrecruit, so I'll have to do a custom one with lua.
I'm not sure how to proceed with that, and what is the safest option?
please help...

Code: Select all

function wesnoth.effects.canrecruit(u, cfg)
        -- wiki says this is read only, why?
        u.canrecruit = true

        -- wiki says helper.modify_unit might be removed
        helper.modify_unit({ id=u.id }, { canrecruit=yes })

        -- wml.tag.modify_unit ??
        -- I don't even know how to write this :/

        -- wesnoth.units.modify ??
        -- This isn't even on the wiki! How do I use it?

        -- what goes next? do I need to call wesnoth.add_modification with some object?
end
Thanks
User avatar
WhiteWolf
Forum Moderator
Posts: 769
Joined: September 22nd, 2009, 7:48 pm
Location: Hungary

Re: canrecruit=yes as an AMLA option

Post by WhiteWolf »

You could alternatively just give a dummy placeholder ability with the AMLA, and then use a global "post advance" event to filter for units with this ability, give them actual canrecruit, and remove the dummy ability.
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
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

Re: canrecruit=yes as an AMLA option

Post by vghetto »

I was hoping to avoid doing that.
I tried using helper.modify_unit and wesnoth.units.modify. They gave lua errors for one reason or the other.

Anyway, this is the WhiteWolf approach for anyone interested.
You could bypass apply_to=canrecruit and do apply_to=status directly. Same result.

Code: Select all

function wesnoth.effects.canrecruit(u, cfg)
        wesnoth.add_modification(u, "object", { wml.tag.effect {
                apply_to = "status",
                add = "canrecruit",
        }}, false)
end

Code: Select all

[event]
        name=post advance
        first_time_only=no

        [modify_unit]
                [filter]
                        status=canrecruit
                        canrecruit=no
                [/filter]
                canrecruit=yes
        [/modify_unit]
[/event]
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: canrecruit=yes as an AMLA option

Post by Celtic_Minstrel »

vghetto wrote: February 6th, 2021, 10:28 pm

Code: Select all

        -- wiki says helper.modify_unit might be removed
        helper.modify_unit({ id=u.id }, { canrecruit=yes })
It's not being removed, just moved to wesnoth.units.modify, which should also answer your question on how to use wesnoth.units.modify. I don't think this function will work though, because u.canrecruit is read-only and I think wesnoth.units.modify can only alter things that are writable from Lua; in which case I'd suggest calling the modify_unit tag, like so:

Code: Select all

function wesnoth.effects.canrecruit(u, cfg)
	wesnoth.wml_actions.modify_unit{
		wml.tag.filter{id = u.id},
		canrecruit = true -- or canrecruit = u.canrecruit if you want to also allow removing canrecruit
	}
end
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

Re: canrecruit=yes as an AMLA option

Post by vghetto »

Celtic_Minstrel wrote: February 11th, 2021, 2:30 pm

Code: Select all

function wesnoth.effects.canrecruit(u, cfg)
	wesnoth.wml_actions.modify_unit{
		wml.tag.filter{id = u.id},
		canrecruit = true -- or canrecruit = u.canrecruit if you want to also allow removing canrecruit
	}
end
Thanks Celtic_Minstrel,
This actually did not work and it threw lua errors.
It sort of went into an infinite loop with the AMLA dialog poping up over and over again throwing the same error.
The error happens regardless of which AMLA option was selected.

I think the error is related to #5298

Code: Select all

20210211 15:31:24 error scripting/lua: C stack overflow
stack traceback:
        [C]: in function 'string.format'
        lua/core.lua:454: in function <lua/core.lua:450>
        (...tail calls...)
        lua/wml-utils.lua:170: in field 'start_var_scope'
        lua/wml/modify_unit.lua:187: in upvalue 'simple_modify_unit'
        lua/wml/modify_unit.lua:197: in field 'modify_unit'
        [string ""]:13: in function <[string ""]:4>
        [C]: in method 'advance'
        lua/wml/modify_unit.lua:183: in local 'handle_unit'
        lua/wml/modify_unit.lua:190: in upvalue 'simple_modify_unit'
        lua/wml/modify_unit.lua:197: in field 'modify_unit'
        ...
        [C]: in method 'advance'
        lua/wml/modify_unit.lua:183: in local 'handle_unit'
        lua/wml/modify_unit.lua:190: in upvalue 'simple_modify_unit'
        lua/wml/modify_unit.lua:197: in field 'modify_unit'
        [string ""]:13: in function <[string ""]:4>
        [C]: in method 'advance'
        lua/wml/modify_unit.lua:183: in local 'handle_unit'
        lua/wml/modify_unit.lua:190: in upvalue 'simple_modify_unit'
        lua/wml/modify_unit.lua:197: in local 'cmd'
        lua/wml-utils.lua:144: in field 'handle_event_commands'
        lua/wml-flow.lua:5: in function <lua/wml-flow.lua:4>
I could upload the test case demo if anyone is interested.
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: canrecruit=yes as an AMLA option

Post by Celtic_Minstrel »

Code: Select all

[event]
        name=start
        first_time_only=no

        [modify_unit]
                [filter]
                        id=YourUnitId
                [/filter]
                canrecruit=yes
        [/modify_unit]
[/event]
Does this method work? Does it add the canrecruit ability? If this also gives Lua errors, then there's an actual bug.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

Re: canrecruit=yes as an AMLA option

Post by vghetto »

Celtic_Minstrel wrote: February 11th, 2021, 7:02 pm

Code: Select all

[event]
        name=start
        first_time_only=no

        [modify_unit]
                [filter]
                        id=YourUnitId
                [/filter]
                canrecruit=yes
        [/modify_unit]
[/event]
Does this method work? Does it add the canrecruit ability? If this also gives Lua errors, then there's an actual bug.
It worked with no errors.

But as I said, the error is related to using [modify_unit] in advance or pre-advance.

I think what is happening with the AMLA is that the effects of the amlas are being applied to the unit before the player does the final selection.

For example, if you have a +1 strike AMLA and +1 damage AMLA, and the player just highlights one of them, he'll see the change in the dialog box on the left below the image of the unit. It would look like 6-2 or 7-1 for example. Then you could go on and press Ok.

So, the custom effect of canrecruit is doing [modify_unit] and that is happening in pre-advance.
As the error was happening I could see that the image of the unit has the golden crown over it, (I didn't highlight "Can recruit" AMLA by that time), meaning the effect and modify_unit was being applied.

I hope I'm making sense :augh:
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

Re: canrecruit=yes as an AMLA option

Post by vghetto »

I'm attaching the demo that will throw the error.
Recruit a Javelineer from the keep and move it about the map, with each movement they will gain experience until they level up.

To not get the error, comment out the following on line 180.

Code: Select all

                    [effect]
                        apply_to=canrecruit
                    [/effect]
The demo also shows the Elvish Fighter that got its canrecruit in start.
Attachments
_main.cfg
(15.17 KiB) Downloaded 134 times
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: canrecruit=yes as an AMLA option

Post by Celtic_Minstrel »

So basically [modify_unit] works but not in an advancement event. In that case probably the only solution would be u.canrecruit = true if that worked. I don't know if there's a good reason for that not to work… the wiki even says it does work… although that's for 1.15, so it may not be accurate if you're on 1.14.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
vghetto
Posts: 755
Joined: November 2nd, 2019, 5:12 pm

Re: canrecruit=yes as an AMLA option

Post by vghetto »

*facepalm* u.canrecruit = true does work on 1.14 and 1.15. :doh: :oops:
I had it in the text above but never tried it because this page on the wiki said it is a read only thing.
Post Reply