tekelili advanced WML questions

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
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: tekelili advanced WML questions

Post by 8680 »

tekelili wrote:A very simple doubt about pango: I want convert "Resistances" into "resistances" using pango, it is possible?
I tried

Code: Select all

"<span variant='smallcaps'>"+_ "Resistances"+"</span>"
but doesnt look do anything.
If text is in “small-caps”, at least as the term is used in CSS [1] and (I believe) many word processors, it means that the lower-case letters are made to look like small capital letters, not that the capital letters are made small.
tekelili wrote:Edit: if no possible with pango, anyway to convert a string to lower case would help me.
I don’t believe that changing a string’s case is possible in WML, other than by writing the case-changing logic oneself (e.g., iterating over each character in the string and having a [switch] block with a [case] for every character with multiple cases).

In Lua, however, a string’s case can be easily changed:

Code: Select all

local lower_case_string = original_string:lower()
An ActionWML tag to make a string lower-case could be implemented thus:

Code: Select all

function wesnoth.wml_actions.lower_case(cfg)
    local s = cfg.string or helper.wml_error
        "[lower_case] missing required string= attribute"
    wesnoth.set_variable(
        cfg.variable or 'lower_case_string', tostring(s):lower())
end

Code: Select all

[lower_case]
    string= _ "Resistances"
    #variable= ## Defaults to "lower_case_string".
[/lower_case]
[message]
    speaker=narrator
    message="$lower_case_string|: " + _"blade 20%, pierce -10%, impact 10%, fire 0%, cold 00%, arcane 20%"
[/message]
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili advanced WML questions

Post by tekelili »

Thanks a lot 8680, it worked for me after fix 2 issues, add " [lua] code= <<" and declare #text-domain after lua function (declare it before caused errors when trying to see a unit description)

Code: Select all

[event]
    name=prestart
    [lua]
        code=<<
        function wesnoth.wml_actions.lower_case(cfg)
            local s = cfg.string or helper.wml_error
                "[lower_case] missing required string= attribute"
            wesnoth.set_variable(
                cfg.variable or 'lower_case_string', tostring(s):lower())
        end
        >>
    [/lua]

#################################
#textdomain wesnoth-help
#################################

    [lower_case]
        string= _ "Resistances"
        variable=str_lc_resistances 
    [/lower_case]
[/event]
I have other issue (sorry for bother so often): I have an event name=recruit to store player gold, but it stores the gold the player had before the recruit was done...
Is there a simple way to fix this? (Other than tedious store_unit_type, and substract unit_type.cost from gold) Edit: bah... forget I asked aboout it, I had to store unit_types for other issue anyway :doh:
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: tekelili advanced WML questions

Post by 8680 »

tekelili wrote:I have other issue (sorry for bother so often): I have an event name=recruit to store player gold, but it stores the gold the player had before the recruit was done...
Is there a simple way to fix this? (Other than tedious store_unit_type, and substract unit_type.cost from gold) Edit: bah... forget I asked aboout it, I had to store unit_types for other issue anyway :doh:
The unit’s cost should be available in the unit itself, so you could use:

Code: Select all

[event]
    name=recruit
    ...
    [gold]
        side=1
        amount=-$unit.cost
    [/gold]
[/event]
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili advanced WML questions

Post by tekelili »

8680 wrote:The unit’s cost should be available in the unit itself
Thanks a lot for that hint, after read [unit] in wml-wiki I supossed unit didnt have that variable stored and I was doing lot of dumb things to get it :augh:
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
User avatar
Dugi
Posts: 4961
Joined: July 22nd, 2010, 10:29 am
Location: Carpathian Mountains
Contact:

Re: tekelili advanced WML questions

Post by Dugi »

I supossed unit didnt have that variable stored
You may want to use the [inspect] tag to see the contents of variables to avoid further issues of this kind.
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: tekelili advanced WML questions

Post by 8680 »

tekelili wrote:Thanks a lot for that hint, after read [unit] in wml-wiki I supossed unit didnt have that variable stored […]
Also see InternalActionsWMLUnitTags and the :inspect command.
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili advanced WML questions

Post by tekelili »

wiki says in [abilities] extra keys:
"poison: can be one of slowed,cured."

If really there is no value for "no effect", would be nice have it added. As example, I want use [heals] to harm enemies, but dont want stop their poison damage ot that poison stops me from harming them.

As side question, I am using [harm_unit] iside an [event] name= side turn, to walk around my problem, but I found a new one as I am unable to find out how display a floating text of damaged inflicted, as it can vary (I have kill=no as key in harm_unit). Damages inflicted with harm_unit are stored... but I dont know how use them without some other key as coordenates being stored :? (it would be also nice that key animate could take values of different animation tags, like heal)

It is store/unstoe units the best way to do this?

Edit: My bad that I didnt notice [harm_unit] already displays a floating text :oops:
I have the ability working in acceptable way right now via event -> harm_unit
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili advanced WML questions

Post by tekelili »

I have a complex problem: I have a macro that writes an [event] name=post advance inside a unit. Until here all works correct for me, event fires when unit advances... but in one particular case:I have an [event] name=recruit that uses macro to write inside unit, and then store unit, modify xp and ustore_unit with fire_event=yes.

After some test, it looks that my post advance event would be fired if was writed before (per example in other unit), but fails at being fired if it is writed inside recruited unit for 1st time in scenario. As I said, this post advance event will works well if future, just looks like it wasnt written in scenario until end of recruit event :hmm:
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: tekelili advanced WML questions

Post by Anonymissimus »

There are two ways "events in units" can be used: [unit_type][event] and [scenario][event][unit][event] (or [scenario][side][unit][event]). Writing the wml of an event into an existing unit (what seems to be what you're doing) doesn't work. The above methods work by simply inserting the event into the scenario wml just as if that event had been written into the scenario directly. So, you can check that the wml of your event appears (or does not appear) in your scenario's savegame.
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
User avatar
Dugi
Posts: 4961
Joined: July 22nd, 2010, 10:29 am
Location: Carpathian Mountains
Contact:

Re: tekelili advanced WML questions

Post by Dugi »

You mean that the event was inside the unit it advanced to? If you say it doesn't work like that (I haven't experimented here, maybe you have just made a mistake with event id or first_time_only=no), maybe you could include the event in the unit that advances to that unit on which the event should be fired. In that case, you can be sure that the event will be there at the time it advances, the unit it advances to doesn't need it otherwise.

Anyway, if you want to efficiently use events that appear across many scenarios repeatedly, put them all into a dummy unit, create that unit in prestart and kill it right after creating it (on coordinates 1,1, side 1, in that case it will work in all scenarios and won't clear shroud). In that case, they will be loaded only once no matter what and you'll have them reliably everywhere (except prestart events or if you remove them if you find it suitable).
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: tekelili advanced WML questions

Post by Anonymissimus »

Dugi wrote:Anyway, if you want to efficiently use events that appear across many scenarios repeatedly, put them all into a dummy unit, create that unit in prestart and kill it right after creating it
Isn't it much cleaner to put those events into macros which are included as needed then ? The point of "events in units" is that such events should be in some way related to the unit and only needed in case that that unit also exists in the scenario.
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
User avatar
Dugi
Posts: 4961
Joined: July 22nd, 2010, 10:29 am
Location: Carpathian Mountains
Contact:

Re: tekelili advanced WML questions

Post by Dugi »

Anonymissimus wrote:Isn't it much cleaner to put those events into macros which are included as needed then ? The point of "events in units" is that such events should be in some way related to the unit and only needed in case that that unit also exists in the scenario.
I don't think so. If the event is used in twenty scenarios, you have to put that macro into twenty scenarios, and the event is loaded into RAM twenty times (once for each scenario). This can have unpleasant impacts on RAM usage and loading speed if the events are large. A large number of events does not increase the size of save files significantly if they don't contain macro bloat (Walking Corpses with their [variation]s on a recall list are far worse), the size of the currently played scenario uses little room in RAM and a large number of events doesn't seem to decrease performance (unless their filters contain filter_location with radius or other performance eaters). You also never forget or fail to add them.

This trick comes especially useful when it is used to hold events that are used in event-based abilities and weapon specials, you don't have to use the hard-to-understand [+abilities] trick and can add the weapon specials through [object]s or AMLA.
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili advanced WML questions

Post by tekelili »

Anonymissimus wrote:There are two ways "events in units" can be used: [unit_type][event] and [scenario][event][unit][event] (or [scenario][side][unit][event]). Writing the wml of an event into an existing unit (what seems to be what you're doing) doesn't work. The above methods work by simply inserting the event into the scenario wml just as if that event had been written into the scenario directly. So, you can check that the wml of your event appears (or does not appear) in your scenario's savegame.
By writting event into unit I mean this:

Code: Select all

[set_variables]
    mode=append
    name=unit.event
    [insert_tag]
        name=value
        variable={ARTIFACT}.event
    [/insert_tag]
[/set_variables]
If this is suposed to not work then I am conffused because it works for me but in that particular case. I am adding different event to units like feeding or store/change halo/unstore that works perfectly during game or debug... but in the particular case I described.
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
User avatar
Dugi
Posts: 4961
Joined: July 22nd, 2010, 10:29 am
Location: Carpathian Mountains
Contact:

Re: tekelili advanced WML questions

Post by Dugi »

You're doing that in an overcomplicated way that will never work.

This does exactly the same than your chunk of code:

Code: Select all

[set_variables]
    mode=append
    name=unit.event
    to_variable={ARTIFACT}.event
[/set_variables]
Anyway, that's not the problem. The events are added from unit_type, not from a single modified unit. An event can be added within an event, the only problem is sometimes variable substitution. A structure like this will work without any problems (set a variable to a certain value when a unit attacks, clear it at the end of scenario).

Code: Select all

[event]
  name=attack
  {VARIABLE attacked yes}
  [event]
    name=victory
    {CLEAR_VARIABLE attacked}
  [/event]
[/event]
If the event is contained in a variable array (let's say that it's {ARTIFACT}.event), you can add this easily like this (maybe it must be done within an event).

Code: Select all

[insert_tag]
  name=event
  variable={ARTIFACT}.event
[/insert_tag]
By the way, you can also remove events if they had an id, like this (the id was 'horrible event'):

Code: Select all

[event]
  id=horrible event
  remove=yes
[/event]
User avatar
tekelili
Posts: 1039
Joined: August 19th, 2009, 9:28 pm

Re: tekelili advanced WML questions

Post by tekelili »

I divided my recruit event into a prerecuit one where I append into unit.event and the recruit one where I was storing/adding xp/unstoring... and now all works for me. Maybe this is suposed to not work, but I feel it like the more elegant way to per example add feeding via a magic item :o

Code: Select all

#define WCT_FEEDING
[effect]
    apply_to=new_ability
    [abilities]
        [dummy]
            id=feeding
            name= _ "feeding"
            female_name= _ "female^feeding"
            description= _ "Feeding:
This unit gains 1 hitpoint added to its maximum whenever it kills a living unit."
        [/dummy]
    [/abilities]
[/effect]
[event]
    id=ability_feeding_die
    name=die
    first_time_only=no
    [filter]
        [not]
            [filter_wml]
                [status]
                    not_living="yes"
                [/status]
            [/filter_wml]
        [/not]
    [/filter]
    [filter_second]
        ability=feeding
    [/filter_second]
    [unstore_unit]
        variable=second_unit
        {COLOR_HEAL}
        text= _ "+1 max HP"
        find_vacant=no
    [/unstore_unit]
    [object]
        silent=yes
        duration=forever
        [filter]
            x,y=$|x2,$|y2
        [/filter]
        [effect]
            apply_to=hitpoints
            increase_total=1
            increase=1
        [/effect]
    [/object]
[/event]
#enddef
I use macro inside my artifact variable and then in macro to attach items:

Code: Select all

....
...
[object]
    silent=yes
    duration=forever
    [filter]
        x,y=$unit.x,$unit.y
    [/filter]
    [insert_tag]
        name=effect
        variable={ARTIFACT}.effect
    [/insert_tag]
[/object]
[store_unit]
    variable=unit
    [filter]
        x,y=$unit.x,$unit.y
    [/filter]
[/store_unit]
[set_variables]
    mode=append
    name=unit.event
    [insert_tag]
        name=value
        variable={ARTIFACT}.event
    [/insert_tag]
[/set_variables]
[unstore_unit]
    variable=unit
    fire_event=yes
[/unstore_unit]
I will try Dugi advise to not use my weird way to append ;)
Edit: For some reason I dont care investigate, in order to work, my code needs I use insert tag instead a simple to_variable=
Edit2: Changed feeding event code, as need $| in order to work (maybe not using insert_tag wouldnt need use delayed variable substitution, but I am lazy to check it once my scenario works finally well...)
Be aware English is not my first language and I could have explained bad myself using wrong or just invented words.
World Conquest II
Post Reply