Kaymon145

Veteran
Veteran
Joined
Apr 22, 2022
Messages
34
Reaction score
17
First Language
English
Primarily Uses
RMMV
At least I think that's the problem anyway.. I'm making a skill that has to read the enemies 'agi' before initializing and it works great when there's only one enemy, things start going wrong with 2 or more though.
After killing one enemy with the skill, I sometimes get a "TypeError: Cannot read property 'agi' of undefined" crash when attempting to use it again. I can't even fully pinpoint when this is happening cause sometimes it happens on the second enemy, sometimes on the third. My theory is that it is still trying to read whatever the previous enemy was, as it sometimes occurs when an ally kills the enemy being targeted, but I just cant seem to get it to run a check at the right time. I am using SRD Timed Attack Core, SRD Timed Attack Action Sequence, and the battle core and 3 action packs from yanfly. This is my whole skill notetag but the line causing the problem is line 2 where I attempt to set the speed of the timed attack.
Code:
<Timed Attack: default>
speed: $gameTroop.aliveMembers()[BattleManager._action._targetIndex].agi
<End Timed Attack>
<Use Timed Attack Action Sequences>
<setup action>
PERFORM START
eval: $gameActors.actor(2).setBattlerImage('AlphonzeLarge2')
display action
motion ABNORMAL: user
wait: 120
CLEAR BATTLE LOG
Timed Attack
immortal: targets, true
</setup action>

<target action>
motion chant: user
move user: targets, center, 15
wait for movement
action animation: target
action effect
jump user: 300, 40
move user: home, 40
motion escape: user
face user: FORWARD
wait for movement
motion ABNORMAL: user
wait: 40
motion guard: user
wait: 40
eval: $gameActors.actor(2).setBattlerImage('AlphonzeLarge')
</target action>

I feel bad asking about this again cause I did post something similar a few days ago, but I've really been struggling to get this to work and I think this is different enough to warrant its own topic..
On a side note though this skill is really fun when it works the way its supposed to and anyone is free to try it out =)
 

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
4,526
Reaction score
2,890
First Language
English
Primarily Uses
RMMV
it sometimes occurs when an ally kills the enemy being targeted
What does this mean? Do you have some system wherein you target this skill, then other actors get turns before this code actually runs? That could make things screwy if you don't do checks to compensate.
 

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
3,672
Reaction score
2,760
First Language
EN
Primarily Uses
RMMZ
Looks like this is the previous thread; linked for reference~

_targetIndex is a tracker for the selected target. It's used as a basis to generate the actual invocation target list. I think that may be the problem.

I had a quick look at the code for Timed Attack Core and it doesn't look like it offers a local target variable for its speed eval. You might need another small plugin to store/fetch action target(s) to/from a global variable, e.g. (untested):
JavaScript:
/*:
 * @target MV
 * @plugindesc Adds a function to fetch the current action target.
 * @help Use $gameTemp.currentTarget() to get a Game_Battler or null.
 *
 * Terms of use: free to use and/or modify for any project.
 */
(function(alias) {
'use strict';
  let targets = [];

  Game_Action.prototype.makeTargets = function() {
    const t = alias.apply(this, arguments);
    targets = t.slice();   // copy by value, not reference
    return t;
  };

  Game_Temp.prototype.currentTarget = function() {
    // targets are shifted out of BattleManager._targets immediately before invoke
    const index = targets.length - BattleManager._targets.length - 1;
    return targets[index] || null;
  };

})(Game_Action.prototype.makeTargets);
Then you could try this kind of thing in your speed eval:

<Timed Attack: default> speed: (function(target) { target ? target.agi : 1 })($gameTemp.currentTarget()) <End Timed Attack>
 

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
4,526
Reaction score
2,890
First Language
English
Primarily Uses
RMMV
_targetIndex is a tracker for the selected target. It's used as a basis to generate the actual invocation target list. I think that may be the problem.
I think that was my bad, I must not grasp the flow correctly. Does the battle manager clear/do something to the _targetIndex variable before the skill starts?

I just don't grok how there can be an instance during an actor's turn where the target of their action can't be directly accessed. I guess I'll have to try to read through it more carefully later.
 

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
3,672
Reaction score
2,760
First Language
EN
Primarily Uses
RMMZ
@ATT_Turan - the battle system is tricky, no worries! :kaohi:

The BattleManager (rpg_managers.js) handles battle flow:
  • Amongst other things, its startAction method generates and stores the action's target list via Game_Action#makeTargets.
  • The updateAction method is then responsible for invoking the action once per target. This method removes the first target (index 0) from the list, then passes that target to invokeAction.
Henceforth, the current target reference is simply passed as a function argument.

Let's trace this back to Game_Action (rpg_objects.js) and its makeTargets method. Ultimately this returns a list of target references, which may or may not correspond exactly to the _targetIndex value, even if there is only one target. For example, the Game_Unit#smoothTarget method gets a living target if the current one is dead. :kaophew:
 

Kaymon145

Veteran
Veteran
Joined
Apr 22, 2022
Messages
34
Reaction score
17
First Language
English
Primarily Uses
RMMV
Looks like this is the previous thread; linked for reference~

_targetIndex is a tracker for the selected target. It's used as a basis to generate the actual invocation target list. I think that may be the problem.

I had a quick look at the code for Timed Attack Core and it doesn't look like it offers a local target variable for its speed eval. You might need another small plugin to store/fetch action target(s) to/from a global variable, e.g. (untested):
JavaScript:
/*:
 * @target MV
 * @plugindesc Adds a function to fetch the current action target.
 * @help Use $gameTemp.currentTarget() to get a Game_Battler or null.
 *
 * Terms of use: free to use and/or modify for any project.
 */
(function(alias) {
'use strict';
  let targets = [];

  Game_Action.prototype.makeTargets = function() {
    const t = alias.apply(this, arguments);
    targets = t.slice();   // copy by value, not reference
    return t;
  };

  Game_Temp.prototype.currentTarget = function() {
    // targets are shifted out of BattleManager._targets immediately before invoke
    const index = targets.length - BattleManager._targets.length - 1;
    return targets[index] || null;
  };

})(Game_Action.prototype.makeTargets);
Then you could try this kind of thing in your speed eval:

<Timed Attack: default> speed: (function(target) { target ? target.agi : 1 })($gameTemp.currentTarget()) <End Timed Attack>

Hey thanks for the replies, sorry for not being more clear, I thought it was when 2 actors were targeting the same enemy and the first one killed it before the second actors turn came up but that doesn't seem to be the case, it will still crash with just one actor as well.
I tried setting up this plugin but using the function in the speed value seems to make the moving part of the action sequence bar disappear, the background is drawn but the slider is just not drawn and I seem to have an unlimited amount of time.. Does the plugin need a specific name to work properly? I really appreciate the help, I have a couple of your other plugins and they are all awesome
 

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
4,526
Reaction score
2,890
First Language
English
Primarily Uses
RMMV
Let's trace this back to Game_Action (rpg_objects.js) and its makeTargets method. Ultimately this returns a list of target references, which may or may not correspond exactly to the _targetIndex value, even if there is only one target. For example, the Game_Unit#smoothTarget method gets a living target if the current one is dead.
Hrm, okay. Then I guess my question is, why use your spontaneous plugin rather than calling
Code:
$gameTroop.smoothTarget(BattleManager._action._targetIndex)
?

Wouldn't that produce a consistent result?
 

caethyril

^_^
Global Mod
Joined
Feb 21, 2018
Messages
3,672
Reaction score
2,760
First Language
EN
Primarily Uses
RMMZ
@Kaymon145 - unlimited time sounds like it returned 0 speed for some reason (an eval error?).

Some ideas:
  1. Did you save your project to apply Plugin Manager changes before testing?
  2. If you press F8 during test to show the console, do you see any red text (errors)?
Otherwise you could try this for testing purposes:

<Timed Attack: default> speed: console.log($gameTemp.currentTarget()), 5 <End Timed Attack>
That should always use speed 5, and also log the $gameTemp.currentTarget() value to the console (F8, as mentioned) like this:
console.jpg
If it shows undefined or such then something's going wrong somewhere. :kaoslp:

Then I guess my question is, why use your spontaneous plugin rather than calling
Code:
$gameTroop.smoothTarget(BattleManager._action._targetIndex)
In this case you might be able to get away with that, not sure. In general smoothTarget is not the only means by which _targetIndex and the current target can differ. Multiple targets cannot be encoded with a single index, invocation may result in reflection (target/subject swap), and plugins could do all kinds of strange things. :kaoback:

[Edit: just realised my mini-plugin doesn't account for reflection either...]
 
Last edited:

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
4,526
Reaction score
2,890
First Language
English
Primarily Uses
RMMV
In this case you might be able to get away with that, not sure. In general smoothTarget is not the only means by which _targetIndex and the current target can differ. Multiple targets cannot be encoded with a single index, invocation may result in reflection (target/subject swap), and plugins could do all kinds of strange things. :kaoback:
Sure, that makes sense, but when you're adding extra stuff to the battle system, there's only so much you can do, right? :wink:

Since the timer plugin is getting called before the skill actually starts, there's not really a way to account for substitution (and you probably wouldn't want to account for reflection, as you're still aiming at that initial target before they reflect it off).

Thanks for the explanations.
 

Kaymon145

Veteran
Veteran
Joined
Apr 22, 2022
Messages
34
Reaction score
17
First Language
English
Primarily Uses
RMMV
Hrm, okay. Then I guess my question is, why use your spontaneous plugin rather than calling
Code:
$gameTroop.smoothTarget(BattleManager._action._targetIndex)
?

Wouldn't that produce a consistent result?
This actually seems to be working perfectly. Tested with multiple actors vs multiple enemies all at different speeds and seems to be reading correctly for each enemy, and no more crashes! Now I'm just not gonna touch it and keep my fingers crossed that nothing else goes wrong with it haha. Thank you both for the support.

@caethyril: I was thinking it was returning 0 too but I tried putting in 0 and it still drew the small bar, it just didn't move, the first code caused it to not be drawn at all strangely. with this:
Code:
console.log($gameTemp.currentTarget()), 5
I don't get any red errors, and it does look to be moving at about a speed of 5, but the console is spammed with a string of nulls during the action sequence?
Either way the code posted by ATT_Turan seems to be working at the moment and not throwing errors, I'll just keep my fingers crossed and try not to change anything else! Again, thank you both so much for the support!
 

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
4,526
Reaction score
2,890
First Language
English
Primarily Uses
RMMV
with this:
Code:
console.log($gameTemp.currentTarget()), 5
I don't get any red errors, and it does look to be moving at about a speed of 5, but the console is spammed with a string of nulls during the action sequence?
That's the whole point - console.log prints the contents of the input to the console. The reason caethyril suggested it was to see what the currentTarget() method was returning as a value.

That's telling you it's giving you null, which is not what you want to end up with if you're trying to get your target and its agility.
 

Kaymon145

Veteran
Veteran
Joined
Apr 22, 2022
Messages
34
Reaction score
17
First Language
English
Primarily Uses
RMMV
That's the whole point - console.log prints the contents of the input to the console. The reason caethyril suggested it was to see what the currentTarget() method was returning as a value.

That's telling you it's giving you null, which is not what you want to end up with if you're trying to get your target and its agility.

That makes sense, I need to start utilizing the console more, could probably save me a lot of headache trying to pinpoint errors on my own lol
 

Latest Threads

Latest Profile Posts

The main game of my trilo/saga 50%OFF on Steam..... its now or never more
I swap between Ace and MZ so I can stay fresh but - what do you mean you can use subfolders in the plugin's folder for easier organization!?
Did some new music again, praise be. To the next song!
Watch Studio Blue play Numina by starlit in our latest RPG Maker Games Critique stream starting NOW!

Forum statistics

Threads
123,140
Messages
1,154,266
Members
161,475
Latest member
guihguih27
Top