Jump to content

Trying to make a new type of counter, having trouble


Recommended Posts

To not bore you with details, I had an idea for a new counter that applies burn to the target instead of directly dealing damage. The problem is, the way counter works is by playing a card for the counter attack, and the condition modifies the min/max damage equal to stacks of counter. I have a card made for the condition, but it's not actually applying burn to the attacker.
 

Spoiler

PC_WUMPUS_hotshot_att =
    {
        name = "Too Hot To Handle",
        anim = "riposte",

        hit_tags = {"riposte"},
        quip = "counter_attack",
        cost = 0,

        flags = CARD_FLAGS.SPECIAL | CARD_FLAGS.MELEE,
        --no_modifiers = true,
        OnPostResolve = function( self, battle, attack )
            attack:AddCondition("BURN", 5, self)
        end,     
    },

Even with a value directly added (the 5), the game still doesn't apply burn to the enemies. the features function worked for this, but the problem with features was it didn't let me change how much burn was applied based on stacks of my condition. I either need to figure out how to change the value that features applies to stacks or figure out how to use some other method to make it apply burn to the enemies.

Link to comment
Share on other sites

  • Developer

Sorry for the late reply.  Did you have any luck with this?

If I play this card *directly* it does indeed apply the Burn, so I imagine the problem is in how it's being played during the counter.  Do you have that code available?

 

Link to comment
Share on other sites

On 8/12/2021 at 10:47 AM, rooks said:

Sorry for the late reply.  Did you have any luck with this?

If I play this card *directly* it does indeed apply the Burn, so I imagine the problem is in how it's being played during the counter.  Do you have that code available?

 

That's what I got too. The card played normally (after the necessary adjustments to make it playable) applies the burn, but the card used as a counter move doesn't work. Strangely, it works when I use the seemingly long forgotten features function...except I don't know if I can use a variable like burn_amt to apply the burn in features, so it's caught between a rock and a hard place.

I hadn't made too many modifications to the original riposte condition to make the new condition, except replace the damage and add a "take damage at the end of your turn"...the code's right here. I also annotated it to try and figure out what did what. Don't know if it's all correct or not.
 

Spoiler

PC_WUMPUS_hot_shot =
    {
        name = "Hot Shot",
        desc = "At the end of your turn, take damage equal to stacks of {PC_WUMPUS_hot_shot}. When attacked, apply {BURN} to the attacker, equal to stacks of {PC_WUMPUS_hot_shot}.",
        ctype = CTYPE.DEBUFF,
        event_handlers =
        {
            --remove the condition at the start of your turn, not the end of it.
            [ BATTLE_EVENT.BEGIN_TURN ] = function( self, fighter )
                if fighter == self.owner then
                    self.owner:RemoveCondition( self.id )
                end
            end,

            [ BATTLE_EVENT.ON_HIT] = function( self, battle, attack, hit )
                --this is the card the ai plays.
                local resolve_card = attack.card
                --if the card player is active and doesn't have stun or isn't surrendering...
                if self.owner:IsActive() and not self.owner:HasCondition( "STUN" ) and not self.owner:HasCondition("SURRENDER") then
                    --if the card owner is them self and the owner wasn't "called in" by certain cards (I.E. Oolo type shenanigans) and it's an attack card and it deals damage and it isn't...a counter? what?
                    --Okay I think the is_counter is just so the game doesn't loop counters. Makes sense.
                    if resolve_card.owner and resolve_card.owner ~= self.owner and not resolve_card.owner.call_in and resolve_card:IsAttackCard() and hit.damage and (hit.damage > 0 or (attack.card.max_damage and attack.card.max_damage > 0)) and not attack.is_counter then
                        --if the counter owner is the target
                        if hit.target == self.owner then
                            self.counter_attack_counter = (self.counter_attack_counter or 0) + 1
                            attack.riposted = true
                        end
                    end
                end
            end,

            [ BATTLE_EVENT.END_RESOLVE ] = function( self, battle, resolve_card )
                --if the counter counter is above 0
                if self.counter_attack_counter and self.counter_attack_counter > 0 then
                    self.owner:CheckForSurrender()
                    --If the person with counter is active, and not stunned, and isn't surrendering, and the attacker is also active.
                    if self.owner:IsActive() and not self.owner:HasCondition( "STUN" ) and not self.owner:HasCondition("SURRENDER") and resolve_card.owner:IsActive() then
                        --This is the actual card, I believe
                        local card = Battle.Card( "PC_WUMPUS_hotshot_att", self.owner )
                        card.engine = battle -- HAX
                        card.burn_amt = self.stacks
                        --Get the owner's fight data, and check if they have ranged_riposte
                        local fight_data = self.owner.agent.fight_data
                        if fight_data.riposte_tags then
                            card.hit_tags = self.owner.riposte_tags
                        end
                        --Flavour, just updates the card flags so it can be ranged or melee
                        if fight_data.ranged_riposte then
                            card.flags = CARD_FLAGS.SPECIAL | CARD_FLAGS.RANGED
                        end
                        --Play the card against the attacker
                        card:AssignTarget( resolve_card.owner, { { resolve_card.owner } } )
                        --For every point in the counter counter
                        for i=1, self.counter_attack_counter do
                            --If the fu-ah, uh..."nice person" hasn't keeeeeee I am really bad at being family friendly in my code annotations, apparently. over yet then
                            if resolve_card.owner:IsAlive() then
                                --Get the card again, then attack 
                                local counter_attack = Battle.Attack( card )
                                counter_attack:GenerateHits()
                                --set it to true so the game doesn't endlessly run the attack...that's a good trick, actually.
                                counter_attack.is_counter = true
                                --Do the visual coolness, like the actual attacks.
                                battle:BroadcastEvent( BATTLE_EVENT.ON_RIPOSTE, counter_attack, i == 1, resolve_card, i == self.counter_attack_counter )
                                counter_attack:RunAttack()
                            end
                        end
                        --did the guy who just got brutalized decide this ain't worth dying for?
                        resolve_card.owner:CheckForSurrender()
                    end
                end
                --The counter is perpetually at 0 in the background, at least until the counter owner gets hit.
                self.counter_attack_counter = 0
            end,
            
            [ BATTLE_EVENT.CONDITION_ADDED ] = function( self, fighter, condition, stacks, source )
                if fighter == self.owner and condition:GetID() == "STUN" then
                    self.owner:RemoveCondition(self.id)
                end
            end,
            --My own snippet. Hotshot is a risk, but one you can manage for Big Damage.
            [ BATTLE_EVENT.END_PLAYER_TURN ] = function( self, fighter, stacks )
                self.owner:SelfDamage( self.stacks, self )
            end
        },
    },

 

Link to comment
Share on other sites

  • Developer

Ah ok.  So because the counter attack is actually just an attack being issued directly via counter_attack:RunAttack(), there is no post resolve step and so the burn condition won't be added.  Post resolve only happens when a card is played via BattleEngine:PlayCard.  What you can do is simply add the burn condition to the attack directly in the PC_WUMPUS_hot_shot condition -- in fact if you do this, you can use the regular counter_attack card and don't even need to define PC_WUMPUS_hotshot_att.

Below I pasted a copy of your code with the relevant 2 changes:

Spoiler


    PC_WUMPUS_hot_shot =
    {
        name = "Hot Shot",
        desc = "At the end of your turn, take damage equal to stacks of {WUMPUS}. When attacked, apply {BURN} to the attacker, equal to stacks of {WUMPUS}.",
        ctype = CTYPE.DEBUFF,
        event_handlers =
        {
            --remove the condition at the start of your turn, not the end of it.
            [ BATTLE_EVENT.BEGIN_TURN ] = function( self, fighter )
                if fighter == self.owner then
                    self.owner:RemoveCondition( self.id )
                end
            end,

            [ BATTLE_EVENT.ON_HIT] = function( self, battle, attack, hit )
                --this is the card the ai plays.
                local resolve_card = attack.card
                --if the card player is active and doesn't have stun or isn't surrendering...
                if self.owner:IsActive() and not self.owner:HasCondition( "STUN" ) and not self.owner:HasCondition("SURRENDER") then
                    --if the card owner is them self and the owner wasn't "called in" by certain cards (I.E. Oolo type shenanigans) and it's an attack card and it deals damage and it isn't...a counter? what?
                    --Okay I think the is_counter is just so the game doesn't loop counters. Makes sense.
                    if resolve_card.owner and resolve_card.owner ~= self.owner and not resolve_card.owner.call_in and resolve_card:IsAttackCard() and hit.damage and (hit.damage > 0 or (attack.card.max_damage and attack.card.max_damage > 0)) and not attack.is_counter then
                        --if the counter owner is the target
                        if hit.target == self.owner then
                            self.counter_attack_counter = (self.counter_attack_counter or 0) + 1
                            attack.riposted = true
                        end
                    end
                end
            end,

            [ BATTLE_EVENT.END_RESOLVE ] = function( self, battle, resolve_card )
                --if the counter counter is above 0
                if self.counter_attack_counter and self.counter_attack_counter > 0 then
                    self.owner:CheckForSurrender()
                    --If the person with counter is active, and not stunned, and isn't surrendering, and the attacker is also active.
                    if self.owner:IsActive() and not self.owner:HasCondition( "STUN" ) and not self.owner:HasCondition("SURRENDER") and resolve_card.owner:IsActive() then
                        --This is the actual card, I believe
                        local card = Battle.Card( "counter_attack", self.owner )
                        card.engine = battle -- HAX
                        card.burn_amt = self.stacks
                        --Get the owner's fight data, and check if they have ranged_riposte
                        local fight_data = self.owner.agent.fight_data
                        if fight_data.riposte_tags then
                            card.hit_tags = self.owner.riposte_tags
                        end
                        --Flavour, just updates the card flags so it can be ranged or melee
                        if fight_data.ranged_riposte then
                            card.flags = CARD_FLAGS.SPECIAL | CARD_FLAGS.RANGED
                        end
                        --Play the card against the attacker
                        card:AssignTarget( resolve_card.owner, { { resolve_card.owner } } )
                        --For every point in the counter counter
                        for i=1, self.counter_attack_counter do
                            --If the fu-ah, uh..."nice person" hasn't keeeeeee I am really bad at being family friendly in my code annotations, apparently. over yet then
                            if resolve_card.owner:IsAlive() then
                                --Get the card again, then attack 
                                local counter_attack = Battle.Attack( card )
                                counter_attack:GenerateHits()
                                --set it to true so the game doesn't endlessly run the attack...that's a good trick, actually.
                                counter_attack.is_counter = true
                                counter_attack:AddCondition( "BURN", self.stacks ) -- Apply BURN directly.
                                --Do the visual coolness, like the actual attacks.
                                battle:BroadcastEvent( BATTLE_EVENT.ON_RIPOSTE, counter_attack, i == 1, resolve_card, i == self.counter_attack_counter )
                                counter_attack:RunAttack()
                            end
                        end
                        --did the guy who just got brutalized decide this ain't worth dying for?
                        resolve_card.owner:CheckForSurrender()
                    end
                end
                --The counter is perpetually at 0 in the background, at least until the counter owner gets hit.
                self.counter_attack_counter = 0
            end,
            
            [ BATTLE_EVENT.CONDITION_ADDED ] = function( self, fighter, condition, stacks, source )
                if fighter == self.owner and condition:GetID() == "STUN" then
                    self.owner:RemoveCondition(self.id)
                end
            end,
            --My own snippet. Hotshot is a risk, but one you can manage for Big Damage.
            [ BATTLE_EVENT.END_PLAYER_TURN ] = function( self, fighter, stacks )
                self.owner:SelfDamage( self.stacks, self )
            end
        },
    },

 

Link to comment
Share on other sites

Alright, that makes sense. I changed it to apply the Burn through the condition and it worked fine. I still kept the card mostly because it looked cool, but it's basically interchangeable with the counter attack card, the only difference I can tell is the name that flashes up. 
I had tried other cards as the played card and they played but didn't do their specific effects, I.E. Uppercut didn't give me power. I just didn't know how to get past the problem of the OnPostResolve not playing, and didn't think of just applying it through the condition itself. 

Anyways, Thank you Sir. This helped keep an idea that I made out of desperation and inspiration alive.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...