How to change strikes count during attack? (or fake it)

The place to post your WML questions and answers.

Moderators: Forum Moderators, Developers

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.
lea
Posts: 167
Joined: October 1st, 2016, 7:25 pm

How to change strikes count during attack? (or fake it)

Post by lea »

I want to make a weapon special that can prevent last few swings from taking place depending on results of previous swings. But number of strikes seems to be "carved in stone" while attack is in progress.

Is it possible to change/reduce number of strikes?
Or change attack's animation while attack is in progress? Or attack animation's length?

It is possible to prevent the strike(s) from hitting by setting its chance_to_hit to zero but I also want to prevent it's animation.
author of: Altered Era/Ruleset (on add-ons servers for BfW 1.14, 1.12 and 1.10 )

User avatar
Ravana
Forum Moderator
Posts: 2440
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: How to change strikes count during attack? (or fake it)

Post by Ravana »

You can stop combat entirely like https://github.com/ProditorMagnus/Agele ... errupt.cfg

Attack animation does allow specifying on which strikes it should happen, but I dont know if you can modify it in event.

lea
Posts: 167
Joined: October 1st, 2016, 7:25 pm

Re: How to change strikes count during attack? (or fake it)

Post by lea »

Ravana wrote:You can stop combat entirely like https://github.com/ProditorMagnus/Agele ... errupt.cfg
I want second unit to be able to go on with its remaining strikes when the first one stops attacking because of my weapon special so this script will not help me... Thanks for your effort anyway )
Ravana wrote:Attack animation does allow specifying on which strikes it should happen, but I dont know if you can modify it in event.
is it possible to specify animation choice based on value of variable that can be set in event?
author of: Altered Era/Ruleset (on add-ons servers for BfW 1.14, 1.12 and 1.10 )

User avatar
The_Gnat
Posts: 2129
Joined: October 10th, 2016, 3:06 am
Contact:

Re: How to change strikes count during attack? (or fake it)

Post by The_Gnat »

I'm no expert on this stuff but you could try using a event inside the unit.

For example:

Code: Select all

[event]
      name = attacker hits

      [filter]
          type=YOURUNIT
      [/filter]

      [filter_attack]
         name=YOURWEAPONWITHTHESPECIAL
      [/filter_attack]

[/event]
I dont know exactly what your doing but I always use events like this in attacks and what you could always do if nothing else works is say if proper events happen then decrease the weapon damage to 0 so it no longer matters if he hits
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon
Co-designer of the (not-wesnoth) space combat video game Planet Bounce.

lea
Posts: 167
Joined: October 1st, 2016, 7:25 pm

Re: How to change strikes count during attack? (or fake it)

Post by lea »

The_Gnat wrote:- if proper events happen then decrease the weapon damage to 0 so it no longer matters if he hits
that's what I did so far. it works but extra animated strikes that never hit are misleading - I want them to not happen visually in addition to giving them 0% hit chance
author of: Altered Era/Ruleset (on add-ons servers for BfW 1.14, 1.12 and 1.10 )

User avatar
The_Gnat
Posts: 2129
Joined: October 10th, 2016, 3:06 am
Contact:

Re: How to change strikes count during attack? (or fake it)

Post by The_Gnat »

Yeah thats a complicated one... I remember someone has created a weapon special that added a strike for every hit but I would have to look into that. Alternatively you could have a message that comes up above the units head that says "blocked" to clarify that that strike never had a chance of hitting.

For example:

Code: Select all

[unstore_unit]
         x, y=$x1, $y1
         text="blocked"
         {COLOR_HEAL}
[/unstore_unit]
Or something like that (thats not tested code sorry)

Hopefully this helps
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon
Co-designer of the (not-wesnoth) space combat video game Planet Bounce.

lea
Posts: 167
Joined: October 1st, 2016, 7:25 pm

Re: How to change strikes count during attack? (or fake it)

Post by lea »

The_Gnat wrote:Yeah thats a complicated one... I remember someone has created a weapon special that added a strike for every hit but I would have to look into that.
do you remember where did you find that? it is exactly what I am looking for except I add extra strike on different event.
IMHO message does not make sense because these extra strikes are not blocked, they do not happen in the first place unless condition was met.
author of: Altered Era/Ruleset (on add-ons servers for BfW 1.14, 1.12 and 1.10 )

User avatar
The_Gnat
Posts: 2129
Joined: October 10th, 2016, 3:06 am
Contact:

Re: How to change strikes count during attack? (or fake it)

Post by The_Gnat »

lea wrote:do you remember where did you find that? it is exactly what I am looking for except I add extra strike on different event.
IMHO message does not make sense because these extra strikes are not blocked, they do not happen in the first place unless condition was met.
:? Unfortunately i have looked into the attack i had seen before and the person who wrote it was not able to get it working either...

If you post what you have created so far i will look at it and may be able to help you complete it though! :D
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon
Co-designer of the (not-wesnoth) space combat video game Planet Bounce.

lea
Posts: 167
Joined: October 1st, 2016, 7:25 pm

Re: How to change strikes count during attack? (or fake it)

Post by lea »

I settled for setting 0% to hit for now and it works but in case you think attack count can be changed during combat encounter (as I initially wanted) here it is:

Code: Select all

#define ATTACK_SPECIAL_CIRCULAR_SINGLE
    # definition to be included in a [specials] clause.
    [chance_to_hit]
        id=circular(single)
        name= _ ""
        name_inactive= _ ""
        value=0
        [filter_self]
            [filter_wml]
                [variables]
                    no_strikes_left=yes
                [/variables]
            [/filter_wml]
        [/filter_self]
    [/chance_to_hit]
    [attacks]
        id=circular(single)
        name= _ "circular(single)"
        name_inactive= _ "circular(single)"
        description= _ "This attack has one extra chance to hit per combat encounter. (Extra chance to hit is animated as separate strike but number of hits per combat enounter cannot exceed attack's base number of strikes)"
        add=1
    [/attacks]
#enddef

#define SET_NO_STRIKES_LEFT_FLAG_FOR_UNIT UNIT VALUE
        [set_variable]
            name={UNIT}.variables.no_strikes_left
            value={VALUE}
        [/set_variable]
        [unstore_unit]
            variable={UNIT}
        [/unstore_unit]
#enddef

#define RESET_HITS_COUNTER_FOR_UNIT UNIT
        [set_variable]
            name={UNIT}.variables.hits
            value=0
        [/set_variable]
        [unstore_unit]
            variable={UNIT}
        [/unstore_unit]
#enddef

#define INCREMENT_HITS_COUNTER_FOR_UNIT_AND_SET_NO_STRIKES_LEFT_FLAG_IF_APPROPRIATE UNIT WEAPON_OF_UNIT
        [set_variable]
            name={UNIT}.variables.hits
            add=1
        [/set_variable]
        [if]
            [variable]
                name={UNIT}.variables.hits
                greater_than_equal_to=${WEAPON_OF_UNIT}.number
            [/variable]
            [then]
                {SET_NO_STRIKES_LEFT_FLAG_FOR_UNIT {UNIT} yes}
            [/then]
            [else]
                [unstore_unit]
                    variable={UNIT}
                [/unstore_unit]
            [/else]
        [/if]
#enddef

#define EVENTS_FOR_ATTACK_SPECIAL_CIRCULAR
    # definition to be included in an [era] clause for ATTACK_SPECIAL_CIRCULAR to work.
    [event]
        name=attack
        first_time_only=no
        [filter_attack]
            special=circular(single)
            [or]
                special=circular(double)
            [/or]
            [or]
                special=circular(triple)
            [/or]
        [/filter_attack]
        {RESET_HITS_COUNTER_FOR_UNIT unit}
        {RESET_HITS_COUNTER_FOR_UNIT second_unit}
        {SET_NO_STRIKES_LEFT_FLAG_FOR_UNIT unit no}
        {SET_NO_STRIKES_LEFT_FLAG_FOR_UNIT second_unit no}
    [/event]
    [event]
        name=attack end
        first_time_only=no
        [filter_attack]
            special=circular(single)
            [or]
                special=circular(double)
            [/or]
            [or]
                special=circular(triple)
            [/or]
        [/filter_attack]
        {RESET_HITS_COUNTER_FOR_UNIT unit}
        {RESET_HITS_COUNTER_FOR_UNIT second_unit}
        {SET_NO_STRIKES_LEFT_FLAG_FOR_UNIT unit no}
        {SET_NO_STRIKES_LEFT_FLAG_FOR_UNIT second_unit no}
    [/event]
    [event]
        name=attacker hits
        first_time_only=no
        [filter_attack]
            special=circular(single)
            [or]
                special=circular(double)
            [/or]
            [or]
                special=circular(triple)
            [/or]
        [/filter_attack]
        {INCREMENT_HITS_COUNTER_FOR_UNIT_AND_SET_NO_STRIKES_LEFT_FLAG_IF_APPROPRIATE unit weapon}
    [/event]
    [event]
        name=defender hits
        first_time_only=no
        [filter_attack]
            special=circular(single)
            [or]
                special=circular(double)
            [/or]
            [or]
                special=circular(triple)
            [/or]
        [/filter_attack]
        {INCREMENT_HITS_COUNTER_FOR_UNIT_AND_SET_NO_STRIKES_LEFT_FLAG_IF_APPROPRIATE second_unit weapon}
    [/event]
#enddef
it adds 1 extra strike to attack and sets to hit chance to 0% until combat encounter ends if all strikes except last did connect. If at least one strike misses then last strike has its usual to hit chance (as defined by defender's stats and terrain)
author of: Altered Era/Ruleset (on add-ons servers for BfW 1.14, 1.12 and 1.10 )

User avatar
Ravana
Forum Moderator
Posts: 2440
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: How to change strikes count during attack? (or fake it)

Post by Ravana »

Did you test this against berserk?

User avatar
The_Gnat
Posts: 2129
Joined: October 10th, 2016, 3:06 am
Contact:

Re: How to change strikes count during attack? (or fake it)

Post by The_Gnat »

Hmm... this is a fairly complicated problem (btw nice code its very well written!)

As i see it you have 3 options which could work:
1. Create a filter in your animation
This could be done with a [if] [variable] in your animation that checks for the no_strikes_left variable or it might be able to be put into the [filter] of your animation.
You could then put a alternative animation that if there are no_strikes_left then the animation for the unit is nothing.

Unfortunately i don't know enough about animations to answer which of these options (if either) will work.
Ravana wrote:Attack animation does allow specifying on which strikes it should happen, but I dont know if you can modify it in event.
Ravana does say its possible to specify things on certain strikes, maybe its possible to also check for variables on certain strikes?

2. Animate a fake attack
Alternatively you could make it so the unit has the normal amount of attacks, but if at the end of the attack some variable indicates that all the strikes were successful then store the 2 units fighting and animate a fake attack. Run a randomizer 1-100 and if that number correlates with the stored defense of the unit your attacking then [unstore_unit] and show a damage number above him equivilent to the stored damage of the attacker and then [modify_unit] to lose that many hitpoints.

This is a more complex (and convoluted :P ) way of doing it but i can probably make this work because i'm familiar with this sort of thing.

3. Not really a solution
If the other two aren't satisfactory then we always can continue to mess around with the [attacks] method and see if either:

-a second attack could be launched after the first but on this second attack the enemy has 0 strikes and you only have 1
-if their is a way to on-the-fly modify the attacks number like you changed the resistance
-or check if there's a way to dynamically change the attack_anim of a unit to not show a attack
-also if solution 1. doesn't work normally then we might be able to implement it using [lua] variables
Thats what i've thought up for now, tell me if you like any of the solutions :D

Hopefully one of these works ;)
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon
Co-designer of the (not-wesnoth) space combat video game Planet Bounce.

lea
Posts: 167
Joined: October 1st, 2016, 7:25 pm

Re: How to change strikes count during attack? (or fake it)

Post by lea »

Ravana wrote:Did you test this against berserk?
my mod does not have berserk yet but it may be added so I should test it. thanks for the hint!
The_Gnat wrote:
1. Create a filter in your animation
This could be done with a [if] [variable] in your animation that checks for the no_strikes_left variable or it might be able to be put into the [filter] of your animation.
You could then put a alternative animation that if there are no_strikes_left then the animation for the unit is nothing.
this looks like exactly what I want to do - replace animation with empty or super short one.
The_Gnat wrote:Ravana does say its possible to specify things on certain strikes, maybe its possible to also check for variables on certain strikes?
that's the question - and also how if possible
The_Gnat wrote:2. Animate a fake attack
seems far too complicated to me, I'd prefer my current solution for now
The_Gnat wrote:-a second attack could be launched after the first but on this second attack the enemy has 0 strikes and you only have 1
this should trigger "attack" and "attack end" events twice per what is intended to be a single combat encounter so I do not like it...
The_Gnat wrote:-if their is a way to on-the-fly modify the attacks number like you changed the resistance
number of strikes seems to be fixed when combat encounter starts - otherwise I would not have this problem
The_Gnat wrote:-or check if there's a way to dynamically change the attack_anim of a unit to not show a attack
that's what I want to do but could not find out how (and if it is possible) so far
author of: Altered Era/Ruleset (on add-ons servers for BfW 1.14, 1.12 and 1.10 )

User avatar
The_Gnat
Posts: 2129
Joined: October 10th, 2016, 3:06 am
Contact:

Re: How to change strikes count during attack? (or fake it)

Post by The_Gnat »

lea wrote:this looks like exactly what I want to do - replace animation with empty or super short one.
Cool i'll also have a look into this. Then i guess if either of us has any luck we can post our results 8)

Btw, i think that if a animation has nothing in it, it just defaults to the base unit picture moving into the enemy's hex (i.e. this would not solve our problem)

EDIT: Btw, just making sure, from reading your code i get that:
if you hit everytime you don't get an additional strike... otherwise the unit with this special gets an extra strike.
Is that correct?
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon
Co-designer of the (not-wesnoth) space combat video game Planet Bounce.

User avatar
The_Gnat
Posts: 2129
Joined: October 10th, 2016, 3:06 am
Contact:

Re: How to change strikes count during attack? (or fake it)

Post by The_Gnat »

SOLUTION: hopefully

Ok well i've looked into some animation manipulating and i think i've solved the problem:
1. Modify the normal animation of the unit with this power by adding this line

Code: Select all

        {FILTER_FOR_REMAINING_STRIKES}
2. Then modify your #define EVENTS_FOR_ATTACK_SPECIAL_CIRCULAR
- Change the definition to say #define EVENTS_FOR_ATTACK_SPECIAL_CIRCULAR UNIT_DEFUALT_IMAGE
- Then at the end of the definition add {NO_ATTACK_ANIMATION {UNIT_DEFUALT_IMAGE}}

- Then also add these defines to your file:

Code: Select all

#define FILTER_FOR_REMAINING_STRIKES
        [filter]
            [filter_wml]
                  [not]
                    [variables]
                        no_strikes_left=yes
                   [/variables]
                 [/not]
            [/filter_wml]
        [/filter]
#enddef

#define NO_ATTACK_ANIMATION UNIT_IMAGE
    [attack_anim]
        [filter]
            [filter_wml]
                [variables]
                    no_strikes_left=yes
                [/variables]
            [/filter_wml]
        [/filter]

        missile_start_time=0
        start_time=0

        [missile_frame]
            image="misc/blank-hex.png:1"
        [/missile_frame]

        [frame]
            image="{UNIT_IMAGE}:0"
        [/frame]

    [/attack_anim]
#enddef
Basically what this does is add a filter for the original attack animation of the unit with the weapon special: only if the variable no_strikes_left is not yes.

Then it adds a new attack animation that checks if no_strikes_left is yes: if it is then the attack animation changes to a anim that looks like nothing.

I've tested this on 1.12, and it works well, but i have noticed some problems if any are significant i can try to fix them also:

- The unit on the attack that never happens (because of the blank anim) come to the front and their is a larger than normal delay before the enemies next attack
- Some units have defense animations that still run even though this guy has no attack animation which looks somewhat odd.
- Like ravana said this attack fails (massively) against berserk! After the first blank attack the no_strikes_left variable is never cleared so it doesn't get anymore strikes.
Creator of: The Reign of The Lords Era,The Gnats Franken Dungeon
Co-designer of the (not-wesnoth) space combat video game Planet Bounce.

lea
Posts: 167
Joined: October 1st, 2016, 7:25 pm

Re: How to change strikes count during attack? (or fake it)

Post by lea »

The_Gnat wrote:EDIT: Btw, just making sure, from reading your code i get that:
if you hit everytime you don't get an additional strike... otherwise the unit with this special gets an extra strike.
Is that correct?
yes, that's what I want with this special. It is essentially to hit % bonus which is kind of complicated and requires the unit to survive counterattacks to make use of it.
The_Gnat wrote:- The unit on the attack that never happens (because of the blank anim) come to the front and their is a larger than normal delay before the enemies next attack
unit's advancing movement for melee attacks is merely default, it can be overridden by setting respective parameter explicitly. in this case required parameter should be "offset" and it should be set to 0 for all frames. Also I'll try to set animation's duration to 0 or something like 1 (millisecond) - when I will get back to it, that is )
The_Gnat wrote:- Some units have defense animations that still run even though this guy has no attack animation which looks somewhat odd.
I hope it can be fixed by setting "empty" animation's duration to 0 or 1. with such a small duration opponent's defense animation should fit between frames and as such become effectively invisible unless it has its own duration.
The_Gnat wrote:- Like ravana said this attack fails (massively) against berserk! After the first blank attack the no_strikes_left variable is never cleared so it doesn't get anymore strikes.
I hoped that repeating sets of strikes from berserk tip off "attack" animation for each round of berserk - apparently it doesn't. I'll have to count total amount of strikes to reset "no_strikes_left" variable for berserk.

Thanks for your effort )
author of: Altered Era/Ruleset (on add-ons servers for BfW 1.14, 1.12 and 1.10 )

Post Reply