MV - SRPG Engine MV - Plugins for creating Tactical Battle System

● ARCHIVED · READ-ONLY
Started by RyanBram 3313 posts Page 155 of 166 View original ↗
  1. Shoukang said:
    Hi,
    The key to realizing this functionality is to do stuff in the Scene_Map.prototype.srpgBattlerDeadAfterBattle method.
    I used ChatGPT to draft the code, which has been an interesting process. ChatGPT does not have any knowledge of this plugin, so it took some effort. I think a certain level of coding expertise is essential to use Chat GPT effectively for game development, what a shame!
    I don't have time to test if it works or not. But it seems like it should work:

    JavaScript:
    var _Scene_Map_srpgBattlerDeadAfterBattle = Scene_Map.prototype.srpgBattlerDeadAfterBattle;
    Scene_Map.prototype.srpgBattlerDeadAfterBattle = function() {
        // Erase any summoned events if their summoner is dead
        this.eraseSummonedEventsIfSummonerDead();
    
        // Then call the original method
        _Scene_Map_srpgBattlerDeadAfterBattle.call(this);
    };
    
    Scene_Map.prototype.eraseSummonedEventsIfSummonerDead = function() {
        var allEvents = $gameMap.events();
        allEvents.forEach(function(event) {
            // Check if the event is a Game_SummonEvent and not already erased
            if (event instanceof Game_SummonEvent && !event.isErased()) {
                var summoner = event.summoner();
                // Ensure the summoner exists and is dead before erasing the event
                if (summoner && summoner.isDead()) {
                    // Check if the battler is alive and apply the death state before erasing
                    var battleArray = $gameSystem.EventToUnit(event.eventId());
                    if (battleArray && battleArray[1] && battleArray[1].isAlive()) {
                        battleArray[1].addState(battleArray[1].deathStateId());
                        // Update game variables for actor or enemy count if necessary
                        var valueId = battleArray[1].isActor() ? _existActorVarID : _existEnemyVarID;
                        var oldValue = $gameVariables.value(valueId);
                        $gameVariables.setValue(valueId, oldValue - 1);
                    }
                    // Erase the event after applying the death state
                    event.erase();
                }
            }
        });
    };
    Hello, thank you very much it works perfectly , it has also helped me understand things much better as'well, ill keep practicing coding.
    Also thank you for your awesome plugins
  2. Been trying to create an object event that when activated grants the active unit a state, but it doesn't seem to be working.
    Edit: nevermind, I got it working. Turns out I was just overcomplicating things for myself trying to do multiple lines of code when this works:
    $gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[1].addState(27);


    Edit 2: Is it possible to use Advanced Interactions to have skills activate objects? Was contemplating the ability to, like, break certain barriers with ranged attacks, or like some kind of telekinesis. But idk if it's a thing that can be done.
  3. i've encountered 2 other plugins of this type, does anyone know the pros and cons of each one and how they compare?
  4. shenro said:
    i've encountered 2 other plugins of this type, does anyone know the pros and cons of each one and how they compare?
    I have no experience with the other 2 but from what I have read:

    LeTBS is more like FFT or Tactics Ogre in that battles take place on the map and unit order is based on agility. Original author seems to have abandoned the project and is living off community mods. I tried it ages ago when it was quite new and the notetag syntax seemed very complicated

    Bilal El Moussaoui's Tactics looks more similarly structured to SRPG Engine (Fire-Emblem-esque). Looks a bit simplier and maybe less advanced. Last update was several years ago but the author is still active.
  5. hello does anyone know of plugins that let you stack states that are compatible with Srpg i've tried a few but they dont seem to work the only one that seemed to stack states was
    MrTS_StatesEX.js but the states dont remove after their duration?

    the reason i want to stack states is so that i can add target rate to attack skills when they are used, so that i can have a basic aggro system i have tried writing a plugin but still lack the javascript knowledge to get it working

    couldn't get the plugin working but was a good opportunity to learn a bit more javascript and manged to implement a basic system in the editor using common events on skills, although it isnt great it does the intended job.

    JavaScript:
    /*each state (60,61,62) adds target rate to the user of *110%,with the base target rate being 100%
    the units target rate increases by 1.1= 110% x 1.1 = 121% x 1.1 =133.1%
    you can make other states that apply more target rate and last longer
    so that certain skills increase target rate more*/
    
    var a = $gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[1];
    if (a.isStateAffected(61)){a.addState(62)};
    if (a.isStateAffected(60)){a.addState(61)};
        if (!a.isStateAffected(60)){
            if(!a.isStateAffected(61)){
                if(!a.isStateAffected(62)){
                    a.addState(60)}}};

    my main reason for trying to implement this is so that there is risk to using certain skills and makes combat a bit more unpredictable, hope this helps anyone looking to accomplish the same thing.
  6. Edit: Part of this is almost certainly based on a misunderstanding of how SRPG Engine works. Ignore the third paragraph:hswt:

    Is it possible through events to have an expression that executes when a skill is selected but before its target is selected (for example to show a context specific hud)? Otherwise are there any plugins available that have this capability (I checked but don't think I saw)?

    An implementation of this is an idea I had for how to highlight available targets for a skill in MV3D, which as is doesn't seem to be able to highlight ground tiles themselves:

    I believe when you select a skill, an array of available targets is generated by SRPG Engine. You would then get that array of available targets and run an expression that uses one of MV3D's highlight effects on each event in the array to have them glow/be clearly targetable.

    One issue would be canceling the effect when the target is selected/skill is canceled, but this it might be possible through a similar process just with a different trigger (e.g. pressing the cancel button, observing when the actor target variable is greater than 0).
  7. Is it possible to use Advanced Interactions to have skills activate objects? Was contemplating the ability to, like, break certain barriers with ranged attacks, or like some kind of telekinesis. But idk if it's a thing that can be done.
    In addition to this. Is there a way to get enemies to be able to interact with certain objects when nearby? The item throwing mechanic I made for tank characters is pretty cool imo, and I think it'd be cool if tank style enemies could do the same. But I'm not sure how that would be done aside from using separate mimic objects for lack of a better word that are coded as enemies, but cannot act or move. But then I don't think the main "lift" interaction would work on them for allies.

    Additionally if anyone knows if it's a thing, is there a way to make Yanfly's Extended Damage Over Time work with how turns function in SRPG core? Have the idea for a physical attack that burns the foe over time. Can totally do that using a -HP regen effect, but I was hoping to make it have an elemental effect to tie with certain fire resilient or weak foes.
  8. hello again i've run into a problem while trying to apply progressive states through AoE skills, i'm trying to have the skill apply a state that changes to another state each time a target is hit by the same skill.

    JavaScript:
    var targetEvents = [$gameTemp.targetEvent()].concat($gameTemp.getAreaEvents());
    for (var i = 0; i < targetEvents.length; i++) {
    var b = $gameSystem.EventToUnit(targetEvents[i].eventId())[1];
    if (b.isStateAffected(57)){b.addState(58)
        b.removeState(57)}
    if (b.isStateAffected(56)){b.addState(57)
        b.removeState(56)}
        if (!b.isStateAffected(56)){
            if(!b.isStateAffected(57)){
                if(!b.isStateAffected(58)){
                    b.addState(56)}}}};

    when i use the AoE skill on targets it seems to apply properly if there is 1 target applying state (56) if there is 2 targets it cycles through and applies state (56 then 57) if theres 3 targets it applies state (56 then 57 then 58).
    i'm unsure what it is that i'm missing that is making this happen as i've tried a few different approaches and all seem to have the same out come, does anyone has a solution or tips that may help apply the states appropriately
  9. Though I'm not sure whether it's (easily) possible to have which tiles are moveable/targetable glow with MV3D, I was able to event a basic means of showing which enemies are targetable with MV3D among some other helpful features.

    Place these into a parallel event (to avoid lag, add a wait for 5 to 15 frames at the start):

    Make Targetable Enemies Glow:
    1709510346707.png

    ◆If:Script:($gameSystem.isSubBattlePhase() === 'actor_target')
    ◆Script:var rangeList = $gameTemp.rangeList();
    :Script:for (var i = 0; i < rangeList.length; i++) {
    :Script: var pos = rangeList;
    :Script: if ($gameMap.eventIdXy(pos[0], pos[1]) > 1) {
    :Script: mv3d.command("@e" + $gameMap.eventIdXy(pos[0], pos[1]) + " lamp yellow 1 1 0");
    :Script: }
    :Script:}

    :Else
    ◆Script:var rangeList = $gameTemp.rangeList();
    :Script:for (var i = 0; i < rangeList.length; i++) {
    :Script: var pos = rangeList;
    :Script: if ($gameMap.eventIdXy(pos[0], pos[1]) > 1) {
    :Script: mv3d.command("@e" + $gameMap.eventIdXy(pos[0], pos[1]) + " lamp black 0 0 0");
    :Script: }
    :Script:}

    :End



    Change Cursor image if Outside of Player Character's Range:

    1709510254394.png

    1709510273088.png

    ◆If:Script:($gameSystem.isSubBattlePhase() === 'actor_move') && $gameMap.distance($gamePlayer.x, $gamePlayer.y, $gameMap.event(1).x, $gameMap.event(1).y) > [Insert Actor's Range Here]
    ◆Set Movement Route:Player
    :Set Movement Route:◇Image:srpg_set(1)

    :Else
    ◆Set Movement Route:Player
    :Set Movement Route:◇Image:srpg_set(0)

    :End



    Make Player Glow Red if Targetable by Selected Enemy:

    1709510298379.png

    ◆If:Script:($gameSystem.isSubBattlePhase() === 'status_window')
    ◆Script:var rangeList = $gameTemp.rangeList();
    :Script:
    :Script:for (var i = 0; i < rangeList.length; i++) {
    :Script: var pos = rangeList;
    :Script: if ($gameMap.eventIdXy(pos[0], pos[1]) == 1) {
    :Script: mv3d.command("@e1 lamp red 2 1 0");
    :Script: }
    :Script:}

    :Else
    ◆Script:mv3d.command("@e1 lamp black 0 0 0");

    :End


    **Status Window glow represents the range of the enemy's longest range skill and doesn't seem to account for that skill's shape

    This should help make MV3D integrated SRPG Engine games a bit more user friendly.

    The intuition of it is that the parallel event checks the sub-battle phase of the SRPG battle. Based on $gameSystem.isSubBattlePhase() from SRPG Engine it runs code to change the cursor or make all events within the actor's range table glow. If the sub-battle state changes, the else statement kicks in and deactivates the glowing or changes the cursor back.

    With the intuition in mind, these should be customizable to your games' specific needs. For example, my game has one controllable character so I always have the event with ID 1 be them, but you can change it to work for multiple party members (e.g. actor IDs are always the first 1 to n event IDs).

    The next thing I'm working on is how to make enemies within an AoE (from SRPG_AoE) glow as well, but I haven't been able to figure it out just yet.
  10. Just noticed the team got SRPG_Gear released on steam (Congrats!!)

    What's the difference between the last SRPG_Engine version (1.34 + Q) to SRPG_Gear (1.11 + Q)?
    Is it 1.11 because it's a reverted version? Did the team start from scratch on the numbering? (looking at the github that's my guess).

    And should I still look for support on Gear in this thread or should I head to the MZ "Gear" thread even though I'm on MV?
  11. Greetings i am using an older version of the (Srpg core 1.34+Q) (not Srpg core 1.32 sorry i put the wrong version originally) i was wondering if anyone had a solution for showing counterattacks properly in the prediction window as it doesn't show counterattacks that are ranged ? i tried adding
    if (actor.srpgSkillRange >= target.srpgSkillRange)
    but it does not work?
    i noticed it works in Srpg_Gear but am not able to replicate it at thee moment

    i managed to get it working by assigning a skill to a weapon and using it as a counter skill then checking the skill ranges to see if active skill is equal to or less than target skill and shows counters if within range.

    javascript
    thats the code to check skill range for active event and target event
    JavaScript:
    // Get Active events skill range.
    $gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[1].srpgSkillRange($gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[1].action(0).item());
    
    //Get Target events skiil range (if target has counterattack).
    $gameSystem.EventToUnit($gameTemp.targetEvent().eventId())[1].srpgSkillRange($gameSystem.EventToUnit($gameTemp.targetEvent().eventId())[1].action(0).item());
    i still need to find out how to call the actual skill name and not the weapon name in the prediction window
  12. NoobieMcNoobs said:
    Greetings i am using an older version of the Srpg core 1.32 i was wondering if anyone had a solution for showing counterattacks properly in the prediction window as it doesn't show counterattacks that are ranged ? i tried adding
    if (actor.srpgSkillRange >= target.srpgSkillRange)
    but it does not work?
    i noticed it works in Srpg_Gear but am not able to replicate it at thee moment

    i managed to get it working by assigning a skill to a weapon and using it as a counter skill then checking the skill ranges to see if active skill is equal to or less than target skill and shows counters if within range.

    javascript
    thats the code to check skill range for active event and target event
    JavaScript:
    // Get Active events skill range.
    $gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[1].srpgSkillRange($gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[1].action(0).item());
    
    //Get Target events skiil range (if target has counterattack).
    $gameSystem.EventToUnit($gameTemp.targetEvent().eventId())[1].srpgSkillRange($gameSystem.EventToUnit($gameTemp.targetEvent().eventId())[1].action(0).item());
    i still need to find out how to call the actual skill name and not the weapon name in the prediction window
    I fixed this, but need a lot of edits. I use SRPG_StatBasedCounter created by Dr.Q, not the Dopan version. Also, I deactivated the critical lines in this codes, because I use a personal critical code.

    Edit SrpgPrediction in SRPG_core:

    CODE
    JavaScript:
    Window_SrpgPrediction.prototype.drawContents = function() {
            var windowWidth = this.windowWidth();
            var lineHeight = this.lineHeight();
            var x = 40;
            // action data
            var actor = this._actionArray[1];
            var target = this._targetArray[1];
            var action = actor.currentAction();
            var damage = action.srpgPredictionDamage(target);
            var hit = action.itemHit(target);
            var eva = action.itemEva(target);
           // var cri = action.itemCri(target);
            this.drawSrpgBattleActionName(actor, action, windowWidth / 2 + x, lineHeight * 0, true);
            this.drawSrpgBattleHit(hit, eva, windowWidth / 2 + x, lineHeight * 1);
            //this.drawSrpgBattleCri(cri, windowWidth / 2 + 160 + x, lineHeight * 1);
            this.drawSrpgBattleDistance(actor, action, windowWidth / 2 + 160 + x, lineHeight * 1);
            this.drawSrpgBattleDamage(damage, windowWidth / 2 + x, lineHeight * 2);
            // reaction data
            var actor = this._targetArray[1];
            var target = this._actionArray[1];
            var userActionMeta = target.currentAction().item().meta;
            var counter = this._targetArray[1].cnt * 100;
            // EDITED BY ADRA
            var counterSkill = actor.counterSkillId();
            var action = new Game_Action(actor);
            action.setSkill(counterSkill);
            action.setSubject(actor);
            if (counterSkill > 0) {
                var isCounterInRange = $gameSystem.srpgCntInRange(target.event()._eventId, actor.event()._eventId);
            }  
            if (!this._targetArray[1].canUse(action.item()) && counterSkill === 0) {
                action = null;
            }
            // if no reaction or actingUnit = targetUnit
            if ((!action && counterSkill === 0) || actor == target || counter === 0 || !isCounterInRange) {
                this.drawSrpgBattleActionName(actor, action, x, lineHeight * 0, false);
                return;
            }
           
            // if counter
            if (counter !== 0 && !userActionMeta.srpgUncounterable) {
                this.changeTextColor(this.systemColor());
                this.drawText('Counter', x + 160, lineHeight * 0, 96, 'right');
                this.resetTextColor();
                this.drawText(counter + '%', x + 220, lineHeight * 0, 96, 'right');
                // display target crit
                this.changeTextColor(this.systemColor());
                //this.drawText('Crit', x + 160, lineHeight * 2);
                this.resetTextColor();
                this.drawText(targetCrit + '%', x + 220, lineHeight * 2);
            }
            // EDITED BY ADRA
            var target = $gameSystem.EventToUnit($gameTemp.targetEvent().eventId())[1];
            var counterSkill = target.counterSkillId();
    
            // Check if there's a counter skill and draw its details
            if (counterSkill > 0 && !userActionMeta.srpgUncounterable) {
                var counterAction = $dataSkills[counterSkill]; // Get the skill data
                var actor = this._targetArray[1];
                var target = this._actionArray[1];
                var action = new Game_Action(actor);
                action.setSkill(counterSkill);
                action.setSubject(actor);
                //draw the counter attack name
                this.drawText(counterAction.name, x, lineHeight * 0);
                //calculate the damage , hit, eva and crit
                var counterDamage = action.srpgPredictionDamage(target);
                var counterHit = action.itemHit(target);
                var counterEva = action.itemEva(target);
                var counterCri = action.itemCri(target);
                //draw the damage, hit, eva and crit
                this.drawSrpgBattleHit(counterHit, counterEva, x, lineHeight * 1);
                //this.drawSrpgBattleCri(counterCri, 160 + x, lineHeight * 1);
                this.drawSrpgBattleDamage(counterDamage, x, lineHeight * 2);
                this._targetArray[1].clearActions();          
            } else {
                var action = actor.currentAction();
                var damage = action.srpgPredictionDamage(target);
                var hit = action.itemHit(target);
                var eva = action.itemEva(target);
                var cri = action.itemCri(target);
                this.drawSrpgBattleActionName(actor, action, x, lineHeight * 0, true);
                this.drawSrpgBattleHit(hit, eva, x, lineHeight * 1);
                //this.drawSrpgBattleCri(cri, 160 + x, lineHeight * 1);
                this.drawSrpgBattleDistance(actor, action, 160 + x, lineHeight * 1);
                this.drawSrpgBattleDamage(damage, x, lineHeight * 2);
                this._targetArray[1].clearActions();
            }
        };

    Add this code at the end of SRPG_core:

    CODE
    JavaScript:
    Game_System.prototype.srpgCntInRange = function(userEID, targetEID) {
        var user = $gameSystem.EventToUnit(userEID);
        var target = $gameSystem.EventToUnit(targetEID);
        var skill = 1;
        //if (target[1].attackSkillId() !== 0) skill = target[1].attackSkillId();
        if (target[1].counterSkillId() !== 0) skill = target[1].counterSkillId();
        if ($gameSystem.srpgBattlerDistance(userEID, targetEID) > $gameSystem.srpgUnitSkillRange(target, skill)) {
            return false
        } else {return true};
    };
    Game_System.prototype.srpgBattlerDistance = function(userEID, targetEID) {
        // unit event id
        if (userEID > 0) var user = $gameSystem.EventToUnit(userEID);
        if (targetEID > 0) var target = $gameSystem.EventToUnit(targetEID);
        // active/target event
        if (userEID === 0) var user = $gameSystem.EventToUnit($gameTemp.activeEvent().eventId());
        if (targetEID === 0) var target = $gameSystem.EventToUnit($gameTemp.targetEvent().eventId());
        var xUser = user[1].event().x;
        var xTarget = target[1].event().x;
        var yUser = user[1].event().y;
        var yTarget = target[1].event().y;
        return $gameMap.distance(xUser, yUser, xTarget, yTarget);
    };
    Game_System.prototype.srpgUnitSkillRange = function(userUnit, skillId) {
          var skill = $dataSkills[skillId];
          var range = 1;
          if (userUnit[1].isActor()) {
            if (skill && skill.meta.srpgRange == Number(-1)) {
                if (!userUnit[1].hasNoWeapons()) {
                    var weapon = userUnit[1].weapons()[0];
                    if (weapon.meta.weaponRange) range = Number(weapon.meta.weaponRange);
                    // States
                    userUnit[1].states().forEach(function(state) {
                        if (state && state.meta.srpgWRangePlus) {
                            range += Number(state.meta.srpgWRangePlus);
                        }
                    }, userUnit[1]);
                    // Equip
                    userUnit[1].armors().forEach(function(armor) {
                        if (armor && armor.meta.srpgWRangePlus) {
                            range += Number(armor.meta.srpgWRangePlus);
                        }
                    }, userUnit[1]);
                }
            } else if (skill.meta.srpgRange) {
                range = skill.meta.srpgRange;
            } else {
                range = 1;
            }
          };
          if (userUnit[1].isEnemy()) {
            if (skill && skill.meta.srpgRange == -1) {
                if (!userUnit[1].hasNoWeapons()) {
                    var weapon = userUnit[1].weapons()[0];
                    if (weapon.meta.weaponRange) range = Number(weapon.meta.weaponRange);
                } else {
                    range = Number(userUnit[1].enemy().meta.weaponRange);
                }
                // states
                userUnit[1].states().forEach(function(state) {
                    if (state && state.meta.srpgWRangePlus) {
                        range += Number(state.meta.srpgWRangePlus);
                    }
                }, userUnit[1]);
            } else if (skill.meta.srpgRange) {
                range = skill.meta.srpgRange;
            } else {
                range = 1;
            }
          };
    return Number(range);
    };

    Edit srpgInvokeMapSkill in SRPG_core and search the comment "//apply effects or trigger a counter"

    CODE
    JavaScript:
    // apply effects or trigger a counter
                    if (!data.counter && user != target && Math.random() < action.itemCnt(target)) {
                        if ($gameSystem.srpgCntInRange(user.event()._eventId, target.event()._eventId) == true) {
                            var attackSkill = $dataSkills[target.attackSkillId()];
                            if (target.canUse(attackSkill) == true) {
                                                    target.performCounter();
                                    this.srpgAddCounterAttack(user, target);
                                                 } else {action.apply(target)};      
                            } else {action.apply(target)};
                        } else {action.apply(target)};
  13. adramalesh159753 said:
    I fixed this, but need a lot of edits. I use SRPG_StatBasedCounter created by Dr.Q, not the Dopan version. Also, I deactivated the critical lines in this codes, because I use a personal critical code.

    Edit SrpgPrediction in SRPG_core:

    CODE
    JavaScript:
    Window_SrpgPrediction.prototype.drawContents = function() {
            var windowWidth = this.windowWidth();
            var lineHeight = this.lineHeight();
            var x = 40;
            // action data
            var actor = this._actionArray[1];
            var target = this._targetArray[1];
            var action = actor.currentAction();
            var damage = action.srpgPredictionDamage(target);
            var hit = action.itemHit(target);
            var eva = action.itemEva(target);
           // var cri = action.itemCri(target);
            this.drawSrpgBattleActionName(actor, action, windowWidth / 2 + x, lineHeight * 0, true);
            this.drawSrpgBattleHit(hit, eva, windowWidth / 2 + x, lineHeight * 1);
            //this.drawSrpgBattleCri(cri, windowWidth / 2 + 160 + x, lineHeight * 1);
            this.drawSrpgBattleDistance(actor, action, windowWidth / 2 + 160 + x, lineHeight * 1);
            this.drawSrpgBattleDamage(damage, windowWidth / 2 + x, lineHeight * 2);
            // reaction data
            var actor = this._targetArray[1];
            var target = this._actionArray[1];
            var userActionMeta = target.currentAction().item().meta;
            var counter = this._targetArray[1].cnt * 100;
            // EDITED BY ADRA
            var counterSkill = actor.counterSkillId();
            var action = new Game_Action(actor);
            action.setSkill(counterSkill);
            action.setSubject(actor);
            if (counterSkill > 0) {
                var isCounterInRange = $gameSystem.srpgCntInRange(target.event()._eventId, actor.event()._eventId);
            }
            if (!this._targetArray[1].canUse(action.item()) && counterSkill === 0) {
                action = null;
            }
            // if no reaction or actingUnit = targetUnit
            if ((!action && counterSkill === 0) || actor == target || counter === 0 || !isCounterInRange) {
                this.drawSrpgBattleActionName(actor, action, x, lineHeight * 0, false);
                return;
            }
         
            // if counter
            if (counter !== 0 && !userActionMeta.srpgUncounterable) {
                this.changeTextColor(this.systemColor());
                this.drawText('Counter', x + 160, lineHeight * 0, 96, 'right');
                this.resetTextColor();
                this.drawText(counter + '%', x + 220, lineHeight * 0, 96, 'right');
                // display target crit
                this.changeTextColor(this.systemColor());
                //this.drawText('Crit', x + 160, lineHeight * 2);
                this.resetTextColor();
                this.drawText(targetCrit + '%', x + 220, lineHeight * 2);
            }
            // EDITED BY ADRA
            var target = $gameSystem.EventToUnit($gameTemp.targetEvent().eventId())[1];
            var counterSkill = target.counterSkillId();
    
            // Check if there's a counter skill and draw its details
            if (counterSkill > 0 && !userActionMeta.srpgUncounterable) {
                var counterAction = $dataSkills[counterSkill]; // Get the skill data
                var actor = this._targetArray[1];
                var target = this._actionArray[1];
                var action = new Game_Action(actor);
                action.setSkill(counterSkill);
                action.setSubject(actor);
                //draw the counter attack name
                this.drawText(counterAction.name, x, lineHeight * 0);
                //calculate the damage , hit, eva and crit
                var counterDamage = action.srpgPredictionDamage(target);
                var counterHit = action.itemHit(target);
                var counterEva = action.itemEva(target);
                var counterCri = action.itemCri(target);
                //draw the damage, hit, eva and crit
                this.drawSrpgBattleHit(counterHit, counterEva, x, lineHeight * 1);
                //this.drawSrpgBattleCri(counterCri, 160 + x, lineHeight * 1);
                this.drawSrpgBattleDamage(counterDamage, x, lineHeight * 2);
                this._targetArray[1].clearActions();        
            } else {
                var action = actor.currentAction();
                var damage = action.srpgPredictionDamage(target);
                var hit = action.itemHit(target);
                var eva = action.itemEva(target);
                var cri = action.itemCri(target);
                this.drawSrpgBattleActionName(actor, action, x, lineHeight * 0, true);
                this.drawSrpgBattleHit(hit, eva, x, lineHeight * 1);
                //this.drawSrpgBattleCri(cri, 160 + x, lineHeight * 1);
                this.drawSrpgBattleDistance(actor, action, 160 + x, lineHeight * 1);
                this.drawSrpgBattleDamage(damage, x, lineHeight * 2);
                this._targetArray[1].clearActions();
            }
        };

    Add this code at the end of SRPG_core:

    CODE
    JavaScript:
    Game_System.prototype.srpgCntInRange = function(userEID, targetEID) {
        var user = $gameSystem.EventToUnit(userEID);
        var target = $gameSystem.EventToUnit(targetEID);
        var skill = 1;
        //if (target[1].attackSkillId() !== 0) skill = target[1].attackSkillId();
        if (target[1].counterSkillId() !== 0) skill = target[1].counterSkillId();
        if ($gameSystem.srpgBattlerDistance(userEID, targetEID) > $gameSystem.srpgUnitSkillRange(target, skill)) {
            return false
        } else {return true};
    };
    Game_System.prototype.srpgBattlerDistance = function(userEID, targetEID) {
        // unit event id
        if (userEID > 0) var user = $gameSystem.EventToUnit(userEID);
        if (targetEID > 0) var target = $gameSystem.EventToUnit(targetEID);
        // active/target event
        if (userEID === 0) var user = $gameSystem.EventToUnit($gameTemp.activeEvent().eventId());
        if (targetEID === 0) var target = $gameSystem.EventToUnit($gameTemp.targetEvent().eventId());
        var xUser = user[1].event().x;
        var xTarget = target[1].event().x;
        var yUser = user[1].event().y;
        var yTarget = target[1].event().y;
        return $gameMap.distance(xUser, yUser, xTarget, yTarget);
    };
    Game_System.prototype.srpgUnitSkillRange = function(userUnit, skillId) {
          var skill = $dataSkills[skillId];
          var range = 1;
          if (userUnit[1].isActor()) {
            if (skill && skill.meta.srpgRange == Number(-1)) {
                if (!userUnit[1].hasNoWeapons()) {
                    var weapon = userUnit[1].weapons()[0];
                    if (weapon.meta.weaponRange) range = Number(weapon.meta.weaponRange);
                    // States
                    userUnit[1].states().forEach(function(state) {
                        if (state && state.meta.srpgWRangePlus) {
                            range += Number(state.meta.srpgWRangePlus);
                        }
                    }, userUnit[1]);
                    // Equip
                    userUnit[1].armors().forEach(function(armor) {
                        if (armor && armor.meta.srpgWRangePlus) {
                            range += Number(armor.meta.srpgWRangePlus);
                        }
                    }, userUnit[1]);
                }
            } else if (skill.meta.srpgRange) {
                range = skill.meta.srpgRange;
            } else {
                range = 1;
            }
          };
          if (userUnit[1].isEnemy()) {
            if (skill && skill.meta.srpgRange == -1) {
                if (!userUnit[1].hasNoWeapons()) {
                    var weapon = userUnit[1].weapons()[0];
                    if (weapon.meta.weaponRange) range = Number(weapon.meta.weaponRange);
                } else {
                    range = Number(userUnit[1].enemy().meta.weaponRange);
                }
                // states
                userUnit[1].states().forEach(function(state) {
                    if (state && state.meta.srpgWRangePlus) {
                        range += Number(state.meta.srpgWRangePlus);
                    }
                }, userUnit[1]);
            } else if (skill.meta.srpgRange) {
                range = skill.meta.srpgRange;
            } else {
                range = 1;
            }
          };
    return Number(range);
    };

    Edit srpgInvokeMapSkill in SRPG_core and search the comment "//apply effects or trigger a counter"

    CODE
    JavaScript:
    // apply effects or trigger a counter
                    if (!data.counter && user != target && Math.random() < action.itemCnt(target)) {
                        if ($gameSystem.srpgCntInRange(user.event()._eventId, target.event()._eventId) == true) {
                            var attackSkill = $dataSkills[target.attackSkillId()];
                            if (target.canUse(attackSkill) == true) {
                                                    target.performCounter();
                                    this.srpgAddCounterAttack(user, target);
                                                 } else {action.apply(target)};    
                            } else {action.apply(target)};
                        } else {action.apply(target)};
    thanks it works well, ill need to tweak a few things to better suit my game but it helped a lot I appreciate it

    i just need to find a way to eval the counter attack rate in regards to the direction the target event is facing i've dug through the forum and found how to evaluate the damage and hit
    • #2,326 ill try to use this method as a template for adjusting the counter rate
    got the counter rate prediction to work appropriately isn't the best way to achieve it but it works i just created a function to draw counter text and added 2 parameters to the srpg core to check counter rate

    counter rate
    I copied the parameters from stat based counters plugin and
    renamed them to what ever then wrote their multipliers the same as stat based counters
    JavaScript:
    //replaced counter text
            if (counter !== 0 && !userActionMeta.srpgUncounterable) {
                this.changeTextColor(this.systemColor());
                this.drawText('Counter', x + 160, lineHeight * 0, 96, 'right');
                this.resetTextColor();
                this.drawSrpgBattleCnt(counter, x + 220, lineHeight * 0, 96, 'right');
                // Display target crit
                this.changeTextColor(this.systemColor());
                this.resetTextColor();
            }
    
    //draw counter function
        Window_SrpgPrediction.prototype.drawSrpgBattleCnt = function(counter, x, y) {
            var val = counter;
            this.changeTextColor(this.systemColor());
            this.drawText(TextManager.param(14), x, y, 98);
            this.resetTextColor();
            if ($gameTemp.getAttackDirection) {
                if ($gameTemp.getAttackDirection() === 'side') {
                    this.drawText(Math.floor(val * sideR_cnt) + '%', x + 64, y, 64, 'right');
                }
                else if ($gameTemp.getAttackDirection() === 'back') {
                    this.drawText(Math.floor(val * backR_cnt) + '%', x + 64, y, 64, 'right');
    
                }else this.drawText(Math.floor(val) + '%', x + 64, y, 64, 'right');
            }
        };
    its not really calling the Targets counter rate but just copying the counter rate set in stat based counters
  14. What do you mean "function(userEID, targetEID),, ?? it doesn't exist in SRPG Core 1.32+Q
  15. I tried making a back stab skill using the damage formula
    JavaScript:
    if ($gameTemp.getAttackDirection() === 'back') { a.atk * 8 - b.def * 1 } else {a.atk * 4 - b.def * 2};
    it works but didn't always show the predicted damage as it should be so i added a couple of small changes to the direction mod Game_Action_evalDamageFormula. started off small anyways :blink:
    edit #2,326 Shoukang provided, it just adds note tags to skills to over write the side and back damage modifiers so the predicted damage works properly.

    i made a few errors when changing the code so i redone a few things hopefully it works better now

    Direction mod edits
    the original edits where made by Shoukang i just altered them a bit for more functionality also refer to
    #2,326 to get the decideAttackdirection function used to evaluate the directions to properly show in predictions

    replace Game_Action.prototype.evalDamageFormula with this to have skill and state note tags
    example
    <side_dmg: 1.5>//side damage will be 1.5x (150%) normal damage.
    <back_dmg: 10.2>//back damage will be 10.2x (1020%) normal damage.

    JavaScript:
    var _Game_Action_evalDamageFormula = Game_Action.prototype.evalDamageFormula;
        Game_Action.prototype.evalDamageFormula = function(target) {
            var value = _Game_Action_evalDamageFormula.call(this, target);
            // Check if in SRPG mode and active/target events exist
            if ($gameSystem.isSRPGMode() && $gameTemp.activeEvent() && $gameTemp.targetEvent()) {
                // Get the skill being used
                var skill = this.item();
      
                // Get default modifiers from plugin parameters
                var sideDmg = side_dmg;
                var backDmg = back_dmg;
    
                // Check if the skill has note tags for side and back damage modifiers
                if (skill.meta.side_dmg !== undefined) {
                    sideDmg += parseFloat(skill.meta.side_dmg);
                }
                if (skill.meta.back_dmg !== undefined) {
                    backDmg += parseFloat(skill.meta.back_dmg);
                }
    
                // Check if the attacker has any states with side_dmg or back_dmg modifiers
                var attackerStates = this.subject().states();
                for (var i = 0; i < attackerStates.length; i++) {
                    var state = attackerStates[i];
                    if (state.meta.side_dmg !== undefined) {
                        sideDmg += parseFloat(state.meta.side_dmg);
                    }
                    if (state.meta.back_dmg !== undefined) {
                        backDmg += parseFloat(state.meta.back_dmg);
                    }
                }
      
                // Determine attack direction
                if ($gameSystem.isSubBattlePhase() == 'battle_window') {
                    decideAttackdirection();
                }
      
                // Check if attacker and target are from different groups
                if (this.subject() == $gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[1] &&
                    $gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[0] !=
                    $gameSystem.EventToUnit($gameTemp.targetEvent().eventId())[0]) {
                    // Apply damage modifier based on attack direction
                    if ($gameTemp.getAttackDirection() == 'side') {
                        value *= sideDmg;
                    } else if ($gameTemp.getAttackDirection() == 'back') {
                        value *= backDmg;
                    }
                }
            }
            return value;
        };

    replace Game_Action.prototype.itemHit same as damage eval modified the code to include skill and state note tags, i removed the code to multiply the hit rate if hit rate = 100% or more.
    example
    <side_hit: 0.8>//side hit rate will be 0.8x (80%) normal hit rate.
    <back_hit: 1.3>//back hit rate will be 1.3x (130%) normal hit rate.

    JavaScript:
    var _Game_Action_itemHit = Game_Action.prototype.itemHit;
        Game_Action.prototype.itemHit = function(target) {
            var value = _Game_Action_itemHit.call(this, target);
            // Check if in SRPG mode and active/target events exist
            if ($gameSystem.isSRPGMode() && $gameTemp.activeEvent() && $gameTemp.targetEvent()) {
                // Get the skill being used
                var skill = this.item();
                // Get default hit rate modifiers from plugin parameters
                var sideHit = side_hit;
                var backHit = back_hit;
                // Check if the skill has note tags for hit rate modifiers
                if (skill.meta.side_hit !== undefined) {
                    sideHit += parseFloat(skill.meta.side_hit);
                }
                if (skill.meta.back_hit !== undefined) {
                    backHit += parseFloat(skill.meta.back_hit);
                }
                var attackerStates = this.subject().states();
                for (var i = 0; i < attackerStates.length; i++) {
                    var state = attackerStates[i];
                    if (state.meta.side_hit !== undefined) {
                        sideHit += parseFloat(state.meta.side_hit);
                    }
                    if (state.meta.back_dmg !== undefined) {
                        backHit += parseFloat(state.meta.back_hit);
                    }
                }
                // Check if attacker and target are from different groups
                if (this.subject() == $gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[1] &&
                    $gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[0] !=
                    $gameSystem.EventToUnit($gameTemp.targetEvent().eventId())[0]) {
                    // Apply hit rate modifier based on attack direction
                    if ($gameTemp.getAttackDirection() == 'side') {
                        value *= sideHit;
                    } else if ($gameTemp.getAttackDirection() == 'back') {
                        value *= backHit;
                    }
                }
            }
            return value;
        };

    replace Game_Action.prototype.itemEva i didnt add any other function except added an if hit rate = 100% or more reduce targets evasion rate to 0.

    JavaScript:
        var _Game_Action_itemEva = Game_Action.prototype.itemEva;
        Game_Action.prototype.itemEva = function(target) {
            var value = _Game_Action_itemEva.call(this, target);
            // Check if in SRPG mode and active/target events exist
            if ($gameSystem.isSRPGMode() == true) {
                if ($gameTemp.activeEvent() && $gameTemp.targetEvent()) {
                    // Check if attacker and target are from different groups
                    if (this.subject() == $gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[1] &&
                        $gameSystem.EventToUnit($gameTemp.activeEvent().eventId())[0] !=
                        $gameSystem.EventToUnit($gameTemp.targetEvent().eventId())[0]) {
                        // Apply evasion rate modifier based on attack direction
                        if ($gameTemp.getAttackDirection() == 'side') {
                            value *= side_eva;
                        } else if ($gameTemp.getAttackDirection() == 'back') {
                            value *= back_eva;
                        }
                        // If the hit rate is 100% or more, set the target's evasion rate to 0
                        var hitRate = this.itemHit();
                        if (hitRate >= 1.0) {
                            value = 0;
                            console.log("Eva rate adjusted for guaranteed hit:", value);
                        }
                      
                    }
                }
            }
            console.log("Eva rate for hit:", value);
            return value;
        };

    I am trying to make a target event face the the direction of an attacking unit when its counter rate is successful and is able to perform a counter attack (I am using stat based counters from Dr Q) how would i call weather the counter rate of the target event is successful and is
    Scene_Map.prototype.preBattleSetDirection the appropriate function to address when setting targets direction (i set _srpgDamageDirectionChange to false)?
    (seriously so much easier doing it in game then trying to code it into the srpg core)
    counter face target
    i set this up in a common event and call it on the counter attack set for units ((i used unique counter attack skills that i only set up for counter attacks)) if you use a common event attached to skill there is a delay and unit will turn to face the attacker after they use the counter attack.

    if you use Yep Skill core you can call the common event with.
    <Custom Execution>
    $gameTemp.reserveCommonEvent(X);
    </Custom Execution>
    so that the unit will turn and face the attacker when it counters.

    its just copied from Scene_Map.prototype.preBattleSetDirection and compressed it
    JavaScript:
    var differenceX = $gameTemp.activeEvent().posX() - $gameTemp.targetEvent().posX();
    var differenceY = $gameTemp.activeEvent().posY() - $gameTemp.targetEvent().posY();
    if (Math.abs(differenceX) > Math.abs(differenceY)) {
        if (differenceX > 0) { $gameTemp.activeEvent().setDirection(4); $gameTemp.targetEvent().setDirection(6);
        } else { $gameTemp.activeEvent().setDirection(6); $gameTemp.targetEvent().setDirection(4);}
    } else {if (differenceY >= 0) {$gameTemp.activeEvent().setDirection(8);$gameTemp.targetEvent().setDirection(2);
        } else {$gameTemp.activeEvent().setDirection(2);$gameTemp.targetEvent().setDirection(8);}
    };

    you can also perform a pop up when facing attacker using balloons or other methods.
    place this above the provided code $gameTemp.targetEvent().requestBalloon(11);

    CounterBalloon.png
    use this if you like just add it to your balloons

    @Adisas88 I am using srpg core 1.34+Q sorry i wrote the wrong version origianlly
  16. Hello, thank you very much for this amazing plugin!
    Just asking is there any other alternatives to srpg_mapviewbattler plugin?
    Because its bugged and wont show animations correctly even in demo
    (sorry for my bad english)
  17. @NoobieMcNoobs wow, balloon popups? that's a great addition!
  18. It is possible to make a forced move system for it? For example: I would like to create a skill that when it hits the enemy, the player can move it X spaces in Y direction, and the same thing for the enemies.
  19. magoale1 said:
    It is possible to make a forced move system for it? For example: I would like to create a skill that when it hits the enemy, the player can move it X spaces in Y direction, and the same thing for the enemies.
    you could try the position effects plugin it lets you push and pull units with skills as well as set up teleportation skills
  20. Hello guys, I don't know if it has been answered yet, if so I apologize. Does anyone know how to solve the error that appears when after selecting an actor and moving the cursor to the edge of the window it gives an error, It happens when the game is in full screen and cursor follow mose is true, there must be some error there, thanks for the help.

    Console Log
    DevTools failed to load SourceMap: Could not load content for chrome-extension://njgcanhfjdabfmnlmpmdedalocpafnhl/js/libs/pixi.js.map: System error: net::ERR_FILE_NOT_FOUND
    rmmz_managers.js:2032 TypeError: Cannot read property '11' of undefined
    at Game_Temp.MoveTable (SRPG_core_MZ.js:3145)
    at Game_Temp.showRoute (SRPG_ShowPath_MZ.js:161)
    at Game_Player.moveByInput (SRPG_MouseOperation_MZ.js:685)
    at Game_Player.update (rmmz_objects.js:8366)
    at Scene_Map.updateMain (rmmz_scenes.js:734)
    at Scene_Map.updateMainMultiply (rmmz_scenes.js:729)
    at Scene_Map.update (rmmz_scenes.js:716)
    at Scene_Map.update (SRPG_core_MZ.js:9324)
    at Scene_Map.update (SRPG_core_MZ.js:11033)
    at Scene_Map.update (SRPG_BattlePrepare_MZ.js:764)
    SceneManager.catchNormalError @ rmmz_managers.js:2032
    SceneManager.catchException @ rmmz_managers.js:2020
    SceneManager.update @ rmmz_managers.js:1941
    Graphics._onTick @ rmmz_core.js:811
    TickerListener.emit @ pixi.js:9474
    Ticker.update @ pixi.js:9928
    Ticker._tick @ pixi.js:9679
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682
    requestAnimationFrame (async)
    Ticker._tick @ pixi.js:9682

    crash srpg.jpg