Need suggestions for implementing custom weapon special

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
Tedder
Posts: 11
Joined: May 5th, 2018, 12:18 am

Need suggestions for implementing custom weapon special

Post by Tedder »

Hey guys!

I've started working on an awesome (it's really awesome) campaign about 2 months ago - I won't spoiler anything here, it will take a long time, but I'll come up with it when it's ready to be played (and with wishes for suggested adjustments to balancing and more)...

Yesterday I started working on some weapon special. I'll summarize it...
Let's assume your attack hits 10 - 4.

It's an attacker-only attack, it can't be used as defense.
The special is intended to work like a "hail" or a "bombardment" or some "burst fire", currently it's called hail. When you attack, you won't do your first strike, defend the opponents first strike, then you strike second, and so on. You will bombard the enemy down with all attacks you have, and after that, the enemy does all attacks he has.
For every hit you do while bombarding, the damage will be calculated between (currently) 60% and 120%. With my current logic, the hits have a 100% chance to actually hit. I'd like to have normal hit chances here.
So it can happen that you hit (with the assumed 10 - 4 attack) 60%, 110%, 80%, 100%, which results in 6+11+8+10 = 35.
Of course it will need to be balanced.

Some suggestions:

- Make the attack e.g. 32-1 instead of 8-4, and split its damage when attacking. This will give the player a better understanding of how hail special works.

Current issues:

- If the unit dies being harmed, the attacker doesn't receive any experience - But he definitely must receive XP!
- The units aligment (chaotic, neutral, lawful) is not included in the current damage calculation
- Neither HP nor EP bars are displayed when harming
- The dying animation looks ugly and not smooth when the enemy is killed with hail special

As I said, I started working on this yesterday.... But, unfortunately, I won't have time this weekend to work anything on Wesnoth (where i spent about ** (too much....) hours every day the past 2 months, lol) so I just wanted to share my first approach here.

Code: Select all

#textdomain wesnoth-xx

#define WEAPON_SPECIAL_HAIL
  # This weapon special can be used on offense and ranged attacks only.
  [damage]
    id = hail
    name = _ "Hail"
    description = _ "This attack is fired inaccurate but affects a comparatively large area that makes its shots always hit. The salves are fired one by one, giving the enemy no opportunity to strike back the bombardment in time. On the downside, caused by the looseness of taking aim, this offense will vary from 60% up to 120% of the base damage every time it hits.

Active on offense only.
Chance to hit 100%, but damage varying."
    active_on = offense
    [filter_self]
      [filter_weapon]
        range = ranged
      [/filter_weapon]
    [/filter_self]
  [/damage]
  [chance_to_hit]
    value = 100
  [/chance_to_hit]
#enddef

#define EVENT_HAIL
  # This provides the effects intended for the weapon special 'hail'
  [event]
    id = hail_combat
    name = attack
    first_time_only = no
    [filter_attack]
      special = hail
    [/filter_attack]

    # Divide weapon damage by 4, equally with the number of iterations
    # todo Make the attack e.g. 32-1 instead of 8-4, and split its damage here. This will give the player a better understanding of how hail special works.
    {VARIABLE damage_to_deal "$($($weapon.damage*$second_unit.resistance.$weapon.type)/100)"}

    # Variables used in nested events
    {VARIABLE attacker_id $unit.id}
    {VARIABLE defender_id $second_unit.id}
    {VARIABLE weapon_name $weapon.name}
    {VARIABLE weapon_number $weapon.number}

    # Because the entire combat is managed in this event itself, modify the units hail attack hitting 0 times by default
    # This is reverted in the event hail_combat_end
    [modify_unit]
      [filter]
        id = $unit.id
      [/filter]
      [effect]
        apply_to = attack
        name = $weapon.name
        set_attacks = 0
      [/effect]
    [/modify_unit]

    # Iterate the range of weapon attack number
    [for]
      start = 1
      end = $weapon.number
      [do]
        # Break the hail iterations - Otherwise the unit would continue attacking an empty hex after its target died
        # todo If the unit dies being harmed, the attacker doesn't receive any experience - But he definitely must receive XP!
        [event]
          id = hail_killed
          name = die
          [filter]
            id = $defender_id
          [/filter]
          {CLEAR_VARIABLE defender_id}
          [break]
          [/break]
        [/event]

        # Reset the units hail attack number
        [event]
          id = hail_combat_end
          name = attack end
          [modify_unit]
            [filter]
              id = $attacker_id
            [/filter]
            [effect]
              apply_to = attack
              name = $weapon_name
              set_attacks = $weapon_number
            [/effect]
          [/modify_unit]
          {CLEAR_VARIABLE attacker_id,weapon_name,weapon_number}
        [/event]

        # todo Include the units alignment (chaotic, neutral, lawful) in damage calculation!
        # $weapon.type deals the defenders resistance % of $weapon.damage, which is calculated as $damage_to_deal
        [set_variable]
          name = random_multiplier
          # Order of defined multipliers is important - Change for balancing only!
          rand = "110,80,120,60,130,50,100"
        [/set_variable]
        {VARIABLE_OP damage_to_deal multiply $random_multiplier}
        {VARIABLE_OP damage_to_deal divide 100}

        # Animate the unit attacking
        [animate_unit]
          flag = attack
          [filter]
            id = $unit.id
          [/filter]
          [filter_second]
            id = $second_unit.id
          [/filter_second]
          [primary_attack]
            name = $weapon.name
          [/primary_attack]
          [secondary_attack]
            range = $weapon.range
          [/secondary_attack]
          hits = yes
          [animate]
            flag = defend
            [filter]
              id = $second_unit.id
            [/filter]
            [primary_attack]
              range = $weapon.range
            [/primary_attack]
          [/animate]
        [/animate_unit]

        # Actually hit the enemy by the calculated amount
        # todo Neither HP nor EP bars are displayed when harming and the dying animation looks ugly and not smooth
        [harm_unit]
          [filter]
            x,y = $x2,$y2
          [/filter]
          [filter_second]
            x,y = $x1,$y1
          [/filter_second]
          amount = $damage_to_deal
          damage_type = $weapon.type
          experience = no
          fire_event = yes
          [primary_attack]
            range = $weapon.range
          [/primary_attack]
          [secondary_attack]
            name = $weapon.name
          [/secondary_attack]
        [/harm_unit]
        {CLEAR_VARIABLE random_multiplier}
      [/do]
    [/for]

    # Clear up. Do not remove the 'hail_combat_end' event!
    [remove_event]
      id = hail_killed
    [/remove_event]
    {CLEAR_VARIABLE defender_id,damage_to_deal,random_multiplier}
  [/event]
#enddef

#define SPECIAL_NOTES_HAIL
  # Special notes for the weapon special 'hail'
  _ " Using a hailing attack offensively will give the enemy no opportunity to strike back the bombardment in time. On the downside, caused by the looseness of taking aim, this offenses damage will vary every time it hits."
#enddef
Any suggestions or other contribution is highly appreciated!!

Thank you in advance!
User avatar
Ravana
Forum Moderator
Posts: 2949
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: Need suggestions for implementing custom weapon special

Post by Ravana »

You say no experience is given: experience = no. If time of day is not used, most likely resistance and weapon specials are not either, there should be $damage or similar variable available in attack related events.
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Need suggestions for implementing custom weapon special

Post by Celtic_Minstrel »

This is actually quite an interesting idea, I might steal it for that new campaign I've been slowly working on... not necessarily with the same implementation, though.

(I'm vaguely thinking of something where, upon initiating the attack, you do something to the opponent that prevents them from attacking at all, basically disabling all their attacks with the same range; then after the attack, you undo that, apply it to the attacker, and manually make the opponent strike back.)
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
Tedder
Posts: 11
Joined: May 5th, 2018, 12:18 am

Re: Need suggestions for implementing custom weapon special

Post by Tedder »

Thanks for the replies guys!

@Ravana, The experience = no key in [harm_unit] was set in order to prevent receiving damage for each iteration.
If I simply set the experience = yes, the unit will receive for a level 1 enemy 4x 1 XP, in addition to that, when the enemy is killed, there occur somewhat even more crazy results about the experience gained. I havn't taken a look at this since friday, going to spend more time in it until next weekend.

@Celtig_Minstrel, it is an interesting idea, yeah XD
Go on and steal it :D , I will post here when I made it working entirely properly.
Beside that, as far as I understood your idea, your special does only need the following steps (I think?)...

Set an attack event with an nested attack end event, in the attack event, set enemies attack number to 0, in the attack end event, set the enemies attack number back to its original value - Which you need to store in a seperate variable, just like I have done here in my nested events already.
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Need suggestions for implementing custom weapon special

Post by Celtic_Minstrel »

Does setting the attack number actually work? If so, that's even easier than I was imagining, which was to temporarily remove the weapons altogether.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
Tedder
Posts: 11
Joined: May 5th, 2018, 12:18 am

Re: Need suggestions for implementing custom weapon special

Post by Tedder »

Hey Celtic Minstrel, this is pretty much the parth that does the job for you...
"attack" event...

Code: Select all

 
   # Store the attack number of the attack you want to prevent in $stored_attacks
   [modify_unit]
      [filter]
        # Apply your SUF, weapon should be filtered in the event filter itself
      [/filter]
      [effect]
        apply_to = attack
        name = $weapon.name
        set_attacks = 0
      [/effect]
    [/modify_unit]
In the "attack end" event...
Just the same, but

Code: Select all

  set_attacks = $stored_attacks
I can't promise this works, i am not at home, just checked Forums from work, hehe. Anyway, this was the way i used it already, and yes, it prevents attacks properly. I hope it helps!
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Need suggestions for implementing custom weapon special

Post by Celtic_Minstrel »

Ah, I see, it's setting the number of strikes to zero. That makes sense. I thought you were talking about something completely different (which would've implied a way for the WML to force the unit to use a different weapon!).
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
Post Reply