Changing up counter-attack functionality

jkweath

Goes Fast
Veteran
Joined
Sep 21, 2016
Messages
306
Reaction score
468
First Language
English
Primarily Uses
N/A
So I have a small counter-attack system in my upcoming game. I already have a plugin that sets it up so enemies counter-attack after being struck rather than completely evading the initial hit, but I'm wanting to make two other changes to how counter-attacks work to balance it out a bit. I'm not experienced with JS myself, so I hope these edits are simple enough for someone who's more familiar with how the engine works.

For one, I want enemies to only be able to counter-attack once per turn. I had a balancing issue in my previous game where an actor using a multi-hit attack could get completely decimated by being counter-attacked multiple times at once, so this is important.

For the other change, I want counter-attacks to be slightly weaker than a basic attack. I imagine this could be accomplished by simply applying a state before the enemy counters and removing it after the counter.
 

Eliaquim

Raze: The Rakuen Zero's Guardian!
Veteran
Joined
May 22, 2018
Messages
1,369
Reaction score
621
First Language
Portuguese - Br
Primarily Uses
RMMV
I think we have to take a look at this plugin first, that enemies can counter-attack, for us to see how it does.
Otherwise, we just have to see the proper code part in the core files and see what to change.
I'm not a huge fan of the battle scene, so I don't know very well the battle code. But, I believe that the second thing of a weaker attack is easy to apply.
 

jkweath

Goes Fast
Veteran
Joined
Sep 21, 2016
Messages
306
Reaction score
468
First Language
English
Primarily Uses
N/A
I think we have to take a look at this plugin first, that enemies can counter-attack, for us to see how it does.
It can likely be done without messing with the plugin. If any problems arise I'm sure I can solve them myself. I'm not a JS expert, but I've made some edits to the base code. I'm just not experienced enough to know how to make the changes here that I need.

EDIT: Thought it might be worth mentioning I am *NOT* using Yanfly's counter-attack plugin. I'm using the game's base counter-attack system with a simple plugin that makes it so the original attack being countered will connect rather than being ignored.
 
Last edited:

Eliaquim

Raze: The Rakuen Zero's Guardian!
Veteran
Joined
May 22, 2018
Messages
1,369
Reaction score
621
First Language
Portuguese - Br
Primarily Uses
RMMV
Ok!
So I give you some hints, but as I said, I'm not used to the battle codes. And I did not test it.
But I believe that your case is a simple case of setting a variable for control the counter-attack limit. Or with numbers or with a boolean(true/false). To allow or not the player or enemies be able to perform the counter.
And for reducing the damage, it will also a matter of math, like take the total calculation of the damage and reduce it by the amount you want.
The thing is where you can do this.

So based on the core files, you have these 3 functions on game object:
I believe Game_Battler will work for both players and enemies.
So you can try to add an if condition here to check the counter times. Maybe you have to set a flag variable to allow counter and disallow it. Or, as you said, apply a state.
Also, you can reduce the attack in the peformAttack, maybe?
JavaScript:
Game_Battler.prototype.performCounter = function() {
    SoundManager.playEvasion();
};

Game_Actor.prototype.performCounter = function() {
    Game_Battler.prototype.performCounter.call(this);
    this.performAttack();
};

Game_Actor.prototype.performAttack = function() {
    var weapons = this.weapons();
    var wtypeId = weapons[0] ? weapons[0].wtypeId : 0;
    var attackMotion = $dataSystem.attackMotions[wtypeId];
    if (attackMotion) {
        if (attackMotion.type === 0) {
            this.requestMotion('thrust');
        } else if (attackMotion.type === 1) {
            this.requestMotion('swing');
        } else if (attackMotion.type === 2) {
            this.requestMotion('missile');
        }
        this.startWeaponAnimation(attackMotion.weaponImageId);
    }
};

But you also have these ones on managers:
Maybe in "process turn" you can made the checks and apply the behaviours you want for the "counter attack limit"?
JavaScript:
BattleManager.updateTurn = function() {
    $gameParty.requestMotionRefresh();
    if (!this._subject) {
        this._subject = this.getNextSubject();
    }
    if (this._subject) {
        this.processTurn();
    } else {
        this.endTurn();
    }
};

BattleManager.processTurn = function() {
    var subject = this._subject;
    var action = subject.currentAction();
    if (action) {
        action.prepare();
        if (action.isValid()) {
            this.startAction();
        }
        subject.removeCurrentAction();
    } else {
        subject.onAllActionsEnd();
        this.refreshStatus();
        this._logWindow.displayAutoAffectedStatus(subject);
        this._logWindow.displayCurrentState(subject);
        this._logWindow.displayRegeneration(subject);
        this._subject = this.getNextSubject();
    }
};

BattleManager.endTurn = function() {
    this._phase = 'turnEnd';
    this._preemptive = false;
    this._surprise = false;
    this.allBattleMembers().forEach(function(battler) {
        battler.onTurnEnd();
        this.refreshStatus();
        this._logWindow.displayAutoAffectedStatus(battler);
        this._logWindow.displayRegeneration(battler);
    }, this);
    if (this.isForcedTurn()) {
        this._turnForced = false;
    }
};
 

jkweath

Goes Fast
Veteran
Joined
Sep 21, 2016
Messages
306
Reaction score
468
First Language
English
Primarily Uses
N/A
@Eliaquim Thanks for showing me that code. I took a look through the code myself and wonder if something could be done with these two blocks:

BattleManager.invokeAction = function(subject, target) {
this._logWindow.push('pushBaseLine');
if (Math.random() < this._action.itemCnt(target)) {
this.invokeCounterAttack(subject, target);
} else if (Math.random() < this._action.itemMrf(target)) {
this.invokeMagicReflection(subject, target);
} else {
this.invokeNormalAction(subject, target);
}
subject.setLastTarget(target);
this._logWindow.push('popBaseLine');
this.refreshStatus();
};

BattleManager.invokeCounterAttack = function(subject, target) {
var action = new Game_Action(target);
action.setAttack();
action.apply(subject);
this._logWindow.displayCounter(target);
this._logWindow.displayActionResults(target, subject);
};

I'm just not sure what syntax to use. I think for invokeCounterAttack, you could just set it to add a state before the action and remove the state afterward.
 

Eliaquim

Raze: The Rakuen Zero's Guardian!
Veteran
Joined
May 22, 2018
Messages
1,369
Reaction score
621
First Language
Portuguese - Br
Primarily Uses
RMMV
Nice one! I think this will be a better approach than mine.
But, instead of applying a state, why don't you use just a flag?
If it is true, then allow counter-attack. If it is false then not allow the counter.

Dig this function action.setAttack(); I think you can weak the damage here.

I wish I could help you more, but the battle code part of mv is not my strong point. I still have to read and understand it =/
And since I did not like it, I have delayed this for a long time xD
 

jkweath

Goes Fast
Veteran
Joined
Sep 21, 2016
Messages
306
Reaction score
468
First Language
English
Primarily Uses
N/A
Wanted to update this thread to say I've figured this out. The problem was much simpler than I was making it out to be.

But, instead of applying a state, why don't you use just a flag?
If it is true, then allow counter-attack. If it is false then not allow the counter.
Applying a state that wears off in 1 turn and reduces the enemy's chance to counter-attack to 0 was a much simpler approach. I basically took the invokeCounterAttack() function above and had it add 2 states before applying the attack.

The first state does as I described above: it reduces the enemy's chance to counter-attack for that turn. The second state reduces the enemy's Attack by 15% before the counter-attack. This state is immediately removed after the counter.

I tested it out and everything seems to work, so I suppose this thread is solved and a mod can close it if they'd like.
 

Eliaquim

Raze: The Rakuen Zero's Guardian!
Veteran
Joined
May 22, 2018
Messages
1,369
Reaction score
621
First Language
Portuguese - Br
Primarily Uses
RMMV
Nice!
Your knowing of battle codes make everything more simple ^^
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Well, It is 4:23 here! Time to sleep!
Good night y'all! <3 :rock-right:
Anybody else ready for MZ Ace?
For scrolling of large maps... Minimap, or very small zoom?
Sometimes you think you know people, then the next thing you know it's below freezing outside, and they're falling from the sky. And no two are exactly alike.

Forum statistics

Threads
99,579
Messages
966,898
Members
131,238
Latest member
Ordnael
Top