Changing up counter-attack functionality

jkweath

Goes Fast
Veteran
Joined
Sep 21, 2016
Messages
304
Reaction score
455
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,348
Reaction score
596
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
304
Reaction score
455
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,348
Reaction score
596
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
304
Reaction score
455
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,348
Reaction score
596
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
304
Reaction score
455
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,348
Reaction score
596
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 Profile Posts

I need to remember that if i want to learn to map like a pro, I need to spend hours doing it like a noob again and again… also, a cool map sometimes has hours/even days of work behind. I need to remember that too.
Yo there how's it going rpg community.
It's raining non stop since yesterday. The sound of the rain is so soothing.
I really miss the old style disney animated movies. I guess the last one was The Princess and the Frog from 2009. Now I am trying to collect every single one I can get on BD or DVD.
What I've seen from the MZ tiles looks pretty inconsistent, bleh. Every plant seems to be drawn in a different style.

Forum statistics

Threads
99,291
Messages
963,916
Members
130,903
Latest member
ReaperERAZE
Top