New weapon specials

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
WhiteWolf
Forum Moderator
Posts: 769
Joined: September 22nd, 2009, 7:48 pm
Location: Hungary

New weapon specials

Post by WhiteWolf »

Hi,

I'd like to make a few new weapon specials.
One of them is supposed to be "bleeding", when the weapon causes severe damage and the wounds bleed over time, cause the damaged unit to lose 4 HP every turn until cured or moved to village.

Basically, I'm talking about a poison attack, but with only 4HP loss, not 8 HP.
However, the [poison] tag doesn't take any value key, and the poison amount is defined inside game_config.cfg, I'm not sure if an add-on campaign can modify that.

Any ideas for a workaround?

Best regards,
WhiteWolf
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
User avatar
Ravana
Forum Moderator
Posts: 2949
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: New weapon specials

Post by Ravana »

https://github.com/ProditorMagnus/Agele ... eeding.cfg

Addon CAN modify that game config value, however that would break all 8hp poisons, so do that only if normal poison is not used in that scenario.
User avatar
WhiteWolf
Forum Moderator
Posts: 769
Joined: September 22nd, 2009, 7:48 pm
Location: Hungary

Re: New weapon specials

Post by WhiteWolf »

No, regular poison is also ingame.

So the code on this github link will work fine, or it's not compatible with ingame poison? Or did you just comment that for trying to modify game_config? :)
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
User avatar
Ravana
Forum Moderator
Posts: 2949
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: New weapon specials

Post by Ravana »

As description says, I did not extensively test interaction with other poisons.

game_config changes value of [poison], and my code uses [dummy].
User avatar
Heindal
Posts: 1344
Joined: August 11th, 2011, 9:25 pm
Location: Germany, Karlsruhe
Contact:

Re: New weapon specials

Post by Heindal »

An alternative approach to realize any kind of status that is draining hp or changing a unit is to make a dummy ability, check for the dummy ability at the start of the units turn and apply the change (e.g. hploss). You can than make weapons specials that apply this new kind of status, when the weapon hits.

Drawback - the status will stay, as long as the ability exists, so you might need to check if the units enters a village, or if the level is won.


Example venom from Trader / Strange Legacy

# this defines the dummy ability

#define ABILITY_AFFECTEDBYVENOM
[dummy]
id=affectedbyvenom
name= _ "affected by venom"
name_inactive= _ "affected by venom"
description= _ "This unit is affected by deadly venom and looses 16 hp each round!"
affect_self=yes
[/dummy]
#enddef

# this event has to be placed anywhere, where the status should occur

[event]
name=new turn
first_time_only=no
[if]
[have_unit]
ability=affectedbyvenom
[/have_unit]
[then]
[store_unit]
[filter]
ability=affectedbyvenom
[/filter]
variable=unit
[/store_unit]

{VARIABLE_OP unit.hitpoints add -16}

[if]
[variable]
name=unit.hitpoints
less_than=1
[/variable]
[then]
[set_variable]
name=unit.hitpoints
value=1
[/set_variable]
[/then]
[/if]

[unstore_unit]
variable=unit
find_vacant=no
text= _ "-16"
red,green,blue=150,0,0
[/unstore_unit]

{CLEAR_VARIABLE unit}

[/then]
[/if]

[/event]


# this event should also be called in all of your adventures, it can be called together with the above event

[event]
name=attacker_hits
first_time_only=no

[filter_attack]
special=venom
[/filter_attack]
[filter_second]
[not]
[filter_wml]
[status]
not_living="yes"
[/status]
[/filter_wml]
[/not]
[/filter_second]

[object]
silent=yes
[filter]
x,y=$x2,$y2
[/filter]
[effect]
apply_to=new_ability
[abilities]
{ABILITY_AFFECTEDBYVENOM}
[/abilities]
[/effect]
[/object]
[/event]



# this defines the weapon special

#define WEAPON_SPECIAL_VENOM

[dummy]
id=venom
name= _ "venom"
name_inactive= _ "venom"
description= _ "When hit by a weapon with this special the victim is affected by a deadly venom that causes 16 damage each turn."
apply_to=opponent
[/dummy]

#enddef
The future belongs to those, who believe in the beauty of their dreams.
Developer of: Trapped, Five Fates, Strange Legacy, Epical, UR Epic Era
Dungeonmasters of Wesnoth, Wild Peasants vs Devouring Corpses, Dwarf Dwarfson Dwarvenminer
User avatar
Ravana
Forum Moderator
Posts: 2949
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: New weapon specials

Post by Ravana »

The venom code you posted is quite close to the bleeding I included, but also including it as dummy ability is nice touch.
User avatar
Heindal
Posts: 1344
Joined: August 11th, 2011, 9:25 pm
Location: Germany, Karlsruhe
Contact:

Re: New weapon specials

Post by Heindal »

Yeah I've made a lot of effects that way. Weakening effects, which reduce the damage output of a unit for example are easy to realize by applying a leadership with a negative damage effect for the unit with that ability.
The future belongs to those, who believe in the beauty of their dreams.
Developer of: Trapped, Five Fates, Strange Legacy, Epical, UR Epic Era
Dungeonmasters of Wesnoth, Wild Peasants vs Devouring Corpses, Dwarf Dwarfson Dwarvenminer
GbDorn
Posts: 60
Joined: March 26th, 2014, 5:07 pm

Re: New weapon specials

Post by GbDorn »

Heindal wrote: {VARIABLE_OP unit.hitpoints add -16}

[if]
[variable]
name=unit.hitpoints
less_than=1
[/variable]
[then]
[set_variable]
name=unit.hitpoints
value=1
[/set_variable]
[/then]
[/if]

[unstore_unit]
variable=unit
find_vacant=no
text= _ "-16"
red,green,blue=150,0,0
[/unstore_unit]
This should be placed inside a {FOREACH} loop.


Using a dummy ability instead of unit.status/unit.variables only gives you shorter WML when filtering.

Adding/removing an ability can be done with different [object] but [object] itself cannot be removed (without custom Lua) so they would fill up the unit's WML.

Also it is much better to use wesnoth.theme_items.unit_status rather than an ability for displaying custom "status".

Alternatively you could use a dummy ability with only the id key so it doesn't show up in the sidebar, and still use wesnoth.theme_items.unit_status. The latter is generally used with unit.status (as in the link above) for good reason: wesnoth.get_displayed_unit has access to 'status' and 'variables' but not 'abilities' so you would need to use something like this:

Code: Select all

local old_unit_status = wesnoth.theme_items.unit_status
function wesnoth.theme_items.unit_status()
  local u = wesnoth.get_displayed_unit()
  if not u then return {} end
  local s = old_unit_status()
  local u_full = wesnoth.get_units({ x=u.x, y=u.y})[1].__cfg
  local u_abilities = helper.get_child(u_full, "abilities")
  local u_status = helper.get_child(u_abilities, "dummy_tag_you_have_renamed_to_your_unique_custom_status_tag")
  if u_status ~= nil then
    table.insert(s, { "element", {
      image = "your_custom_image.png",
      tooltip = tostring(_"your_custom_text")
    } })
  end
  return s
end
User avatar
James_The_Invisible
Posts: 534
Joined: October 28th, 2012, 1:58 pm
Location: Somewhere in the Northlands, fighting dark forces
Contact:

Re: New weapon specials

Post by James_The_Invisible »

GbDorn wrote:[object] itself cannot be removed (without custom Lua) so they would fill up the unit's WML.
This is not true, you can remove object from a unit with just wml. No there is no tag for this but objects are stored as variables within the unit so you clear it and rebuild the unit. An example (from my campaign):

Code: Select all

[store_unit]
    [filter]
        id=Clare
    [/filter]
    variable=clare_store
    kill=yes
[/store_unit]
{FOREACH clare_store.modifications.object i}
[if]
    [variable]
        name=clare_store.modifications.object[$i].id
        equals=staff_of_ethalir
    [/variable]
    [then]
        {CLEAR_VARIABLE clare_store.modifications.object[$i]}
        {VARIABLE_OP i sub 1}
    [/then]
[/if]
{NEXT i}
{CLEAR_VARIABLE i}
[unstore_unit]
    variable=clare_store
    find_vacant=no
[/unstore_unit]
{TRANSFORM_UNIT id=Clare $clare_store.type}
{CLEAR_VARIABLE clare_store}
GbDorn
Posts: 60
Joined: March 26th, 2014, 5:07 pm

Re: New weapon specials

Post by GbDorn »

Edit: removed previous post

Fair enough.
One can use custom WML, Lua, or 'no_write=yes' in 1.13.1+ to remove [object].
And one should use one of these to avoid filling up the unit's WML when dealing with on/off effects, so you have to use:
- some code to add the ability
- some code to remove the ability
- some code to remove [object](s) if you use that method
The code would be much simpler and shorter using unit.status/unit.variables.

Also an [object] with 'id' can be applied only once. One should use 'item_id' for on/off [object]/[effect].
User avatar
Heindal
Posts: 1344
Joined: August 11th, 2011, 9:25 pm
Location: Germany, Karlsruhe
Contact:

Re: New weapon specials

Post by Heindal »

Lua is obviously complicated. If you are a new to wml it would be better to realize things with wml first. Imho I believe that forcing new coders to learn lua makes things more complicated and increases frustration. And last is bad if its a freetime project. Keep it lean and simple.
The future belongs to those, who believe in the beauty of their dreams.
Developer of: Trapped, Five Fates, Strange Legacy, Epical, UR Epic Era
Dungeonmasters of Wesnoth, Wild Peasants vs Devouring Corpses, Dwarf Dwarfson Dwarvenminer
Post Reply