Accessing variables assigned through attack formula

Countyoungblood

Sleeping Dragon
Veteran
Joined
Dec 9, 2017
Messages
622
Reaction score
403
First Language
English
Primarily Uses
RMVXA
thanks to a helpful member of the forums Ive been provided with a nice bit of code to assign variables in an attack formula..

this assigns the id of the target at the variable number equal to the user.
Code:
a.add_state(20);v[(a.index + 1)||(a.enemy_id + 4)]=(b.index+1)||(b.enemy_id+4)
and this is intended to check on that variable.
Code:
  def check_state_from_var
  return if not state?(20)
  id_to_check = self.enemy_id + 4 if enemy?() else self.index
  return if not $game_variables[id_to_check].state?(27)
  remove_state(20)
  add_state(22)
  end
when the attack is used I get an error saying

script game_variables line 19: typeError occurred. no implicit conversion from nil to integer
do i need to convert the id to an integer? im having trouble finding the problem
 

A-Moonless-Night

WINTER IS COMING
Veteran
Joined
Mar 17, 2012
Messages
681
Reaction score
446
First Language
English
Primarily Uses
RMVXA
Code:
v[(a.index + 1)||(a.enemy_id + 4)]=(b.index+1)||(b.enemy_id+4)
What exactly are you trying to do here? If you're trying to do different results depending on whether the target is an actor or enemy, you can do something like the following:
Code:
a.add_state(20); x = a.is_a?(Game_Enemy) ? a.enemy_id + 4 : a.index + 1; y = b.is_a?(Game_Enemy) ? b.enemy_id + 4 : b.index + 1; v[x] = y
Not sure if that will fit in the formula box. If it doesn't, then you could make a new script with something like:
Code:
class Game_Battler < Game_BattlerBase
  def custom_formula(target)
    add_state(20)
    x = target.is_a?(Game_Enemy) ? a.enemy_id + 4 : a.index + 1
    y = self.is_a?(Game_Enemy) ? self.enemy_id + 4 : self.index + 1
    $game_variables[x] = y
  end
end
And then you could use the formula:
Code:
a.custom_formula(b)
Of course, I haven't tested any of this, but it should put you on the right track.
 

Countyoungblood

Sleeping Dragon
Veteran
Joined
Dec 9, 2017
Messages
622
Reaction score
403
First Language
English
Primarily Uses
RMVXA
thanks for the reply, I want to assign a variable with the attack and after the round is over i want to reference that variable and see if a state exists.

is there a way to look at an objects last target and check its states? that'd work just as well i believe.
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,573
Reaction score
6,503
First Language
Indonesian
Primarily Uses
RMVXA
is there a way to look at an objects last target
Here is a simple trick to record target. Put this as a new script
Code:
module Target
  def self.records
    @@records ||= []
  end
end
If you want to record the target, do this in the damage formula.
Code:
Target.records << b
To access the last targetted battler, use
Code:
Target.records[-1]
If you want to do this automatically for all skills, overwrite/make alias make_damage_value, add this somewhere inside the method
Code:
Target.records << self
If you want to record the attacker and the target, use this instead.
Code:
module Target
  def self.records
    @@records ||= {}
  end
end
If you want to record the attacker and the target, do this in the damage formula.
Code:
Target.records[a] << b
If you want to do this automatically for all skills, overwrite/make alias make_damage_value, add this somewhere inside the method
Code:
Target.records[user] = self
To get the information of who is attacking who
Code:
Target.record[battler]
Remember that the "battler" is an instance of either Game_Actor/Game_Enemy. For example:

Code:
Target.records[$game_actors[1]]
Will check what is the last target attacked by actor 1
Code:
Target.records[$game_party.members[0]]
Will check what is the last target attacked by the party member at index 0, the leader
Code:
Target.records[$game_troop.members[0]]
Will check what is the last target attacked by the troop member at the first index

Also, like AMN, I'm having trouble understanding what you're trying to do. The thing is there's probably a simpler way to do what you want to do without making it complex by assigning it into a Game_Variables.
 

Countyoungblood

Sleeping Dragon
Veteran
Joined
Dec 9, 2017
Messages
622
Reaction score
403
First Language
English
Primarily Uses
RMVXA
thanks this all looks great still trying to understand it though. I dont specifically want to use variables i just want to keep an array of objects and their last targets and check it to respond to a change in state.

I want attacker to inflict a state on itself and the enemy like a poison for example.
I have another script that changes an objects state based on current TP. if TP reaches 100 it applies a end_state.

I want to check for this end_state and update the state of the last object who attacked it.

ive put your bit of script into my game but im having trouble intergrating into my bit.

Code:
  def check_state_from_var
  return if not state?(20)
  return if not Target.records[self].state?(27)
  self.remove_state(20)
  self.add_state(22)
If someone has state 20 i want to check for state 27 on their last target.
if their last target has state 27 i want to remove state 20 on the current object
and add state 22.
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,573
Reaction score
6,503
First Language
Indonesian
Primarily Uses
RMVXA
There's still need more clarification
I have another script that changes an objects state based on current TP. if TP reaches 100 it applies a end_state.
What script?
something you made?
someone's else?
is it actually put a state? or it works differently (i.e, it isn't a state)?
I ask this because the "state" might not detectable using a method to check the state. I want to know if it's actually working as intended.

ive put your bit of script into my game but im having trouble intergrating into my bit.
What problem did you run into?
a crash?
not working as intended?
How do you integrate it?
Did you put it in the damage formula? or modify make_damage_value in Game_Battler?
Also when and where that method check_state_from_var is called?

Try to get used to trace your code. Be more suspicious. First, you need to check if the code Target.records[self] actually contains the last targetted battler. Second, try to make sure the state check is actually working, or even the state is actually applied. Break it down into smaller part/modules. Make sure everything work as intended, then integrate it.
 

Countyoungblood

Sleeping Dragon
Veteran
Joined
Dec 9, 2017
Messages
622
Reaction score
403
First Language
English
Primarily Uses
RMVXA
this bit here for the TP

Code:
def tp_state_update
 
 
 if state?(25) or state?(26) or state?(27)
   
   case
     when self.tp.between?(0,30)
     set_state = 25
     when self.tp.between?(31,60)
     set_state = 26
     when self.tp.between?(61,100)
     set_state = 27
   end
   

      if state?(25) && set_state != 25
        self.remove_state(25)
        self.add_state(set_state)
      elsif state?(26) && set_state != 26
        self.remove_state(26)
        self.add_state(set_state)
      elsif state?(27) && set_state != 27
        self.remove_state(27)
        self.add_state(set_state)
end
end
end
this runs at the end of every round to update the state depending on the objects TP value. it works as intended and goes up/down when i add/remove tp. ( i used colored indicators for the state to watch it move..green/yellow/red) Ive been working on my problem in logical little chunks but Im just not that familiar with ruby or rpgmaker.


the problem Im having now is at:

return if not Target.records[self].state?(27)

undefined method state for nil:nilclass

what is being put inside target.records? i dont know how to format it so that i can look at the current objects saved target states.
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,573
Reaction score
6,503
First Language
Indonesian
Primarily Uses
RMVXA
undefined method state for nil:nilclass
It is because the target is not recorded. Which in some cases, it is alright!
To get away from the crash, add an extra exception, like...
Code:
return unless Target.records[self]
return if !Target.records[self].state?(27)
However, you need to make sure that for a feature you need, the last target of the attacker actually gets recorded.
Which that back to my question. How did you put my script? in formula box? or did u modify Game_Battler?

Speaking of which, are you familiar with console and how to debug your script using the console window? (it's located in Game > Show Console)
 

Countyoungblood

Sleeping Dragon
Veteran
Joined
Dec 9, 2017
Messages
622
Reaction score
403
First Language
English
Primarily Uses
RMVXA
i pasted this to a new script by itself. does it need to be in game_battler?
module Target
def self.records
@@records ||= {}
end
end
and this in an attack formula

Target.records[a] << b

ive tried to open the console but havent seen it display anything. how do i get it to report to me?

I need to know how to look at an objects last target states.
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,573
Reaction score
6,503
First Language
Indonesian
Primarily Uses
RMVXA
ive tried to open the console but havent seen it display anything. how do i get it to report to me?
Of course, you need to manually put the command to report it to you.
For example, you can try to put this in your check_state_from_var
Code:
p Target.records[self].class
It will print NilClass if it does not have a target
It will print Game_Enemy if it contains an enemy
It will print RPG::Class if it's an actor iirc.

If you want to know the entire value, you can use this
Code:
Target.records.each {|key, value| p "#{key.class} --> #{value.class}"}
Knowing how to debug and use console may save you a lot of time asking and waiting for the answer.

Also,...
Code:
Target.records[a] << b
I'm not sure if it's a syntax correct, but I use = instead of <<
 

Countyoungblood

Sleeping Dragon
Veteran
Joined
Dec 9, 2017
Messages
622
Reaction score
403
First Language
English
Primarily Uses
RMVXA
thanks theo but I think i may have gone two steps back by reproaching the issue from a different angle just to reach the same wall.

both ways I'm still stuck at not being able to look at the states of one object while focused on another. so maybe this isn't the right approach.

update: just started working with the console.

ive put Target.records.each {|key, value| p "#{key.class} --> #{value.class}"}
it ran 4 times and returned the same value 4 times...

edit2:

managed to get rid of the error but the functionality isn't there.

def check_state_from_var
return if not state?(20)
if $game_party.members[Target.records[self].to_i].state?(27)
self.remove_state(20)
self.add_state(22)
else
return
end
 
Last edited:

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,573
Reaction score
6,503
First Language
Indonesian
Primarily Uses
RMVXA
What are you implying to do by using .to_i method?
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,573
Reaction score
6,503
First Language
Indonesian
Primarily Uses
RMVXA
I keep getting errors saying i cant set to integer so i was wanting to set it to an integer beforehand
Maybe, you need to read the basic ruby, in this case, array. You can't just throw .to_i and it solves everything because it requires an integer.
Are you having trouble understanding what I mean by "using the console to debug your code"?
 

Countyoungblood

Sleeping Dragon
Veteran
Joined
Dec 9, 2017
Messages
622
Reaction score
403
First Language
English
Primarily Uses
RMVXA
Maybe, you need to read the basic ruby, in this case, array. You can't just throw .to_i and it solves everything because it requires an integer.
Are you having trouble understanding what I mean by "using the console to debug your code"?
Ive got quite a bit to read yes but i didnt just add.to_i because it tickled me. Im new to ruby and trying to learn. after trial/error/research i tried to_i at one point which i still dont entirely get. Ive barely started using the console its how i was able to learn that my variables werent getting set. I have been reading about arrays and trying what ive found.

What i still need help with is checking for a state if its there check the objects last target for a state. I couldnt get your solution to work so ive just gone back to using variables. I can confirm the variables are setting properly but i cant check for the last target.
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,573
Reaction score
6,503
First Language
Indonesian
Primarily Uses
RMVXA
One question. When do you want to check the last target state? on turn end? on action end? right after the skill execution?
 

Countyoungblood

Sleeping Dragon
Veteran
Joined
Dec 9, 2017
Messages
622
Reaction score
403
First Language
English
Primarily Uses
RMVXA
One question. When do you want to check the last target state? on turn end? on action end? right after the skill execution?
On turn end which is what its attempting to do ive got a method added to on_turn_end already but the checking line has never worked for me ive tried a handful of combinations.

Assigning a game variable of b.index+1 to the equivelent of a.index+1 worked but i cant look at the states of v[a.index+1] (which contains b.index+1) i dont know how to format that in a way that functions
 

A-Moonless-Night

WINTER IS COMING
Veteran
Joined
Mar 17, 2012
Messages
681
Reaction score
446
First Language
English
Primarily Uses
RMVXA
I don't think you should worry about using variables if you're already doing things in Game_Battler. What about something like the following:
Code:
module Target
  def self.records
    @@records ||= {}
  end
end

class Game_Battler < Game_BattlerBase
 
  alias checkstates_gamebattler_executedmg  execute_damage
  def execute_damage(user)
    checkstates_gamebattler_executedmg(user)
    Target.records[user] = self
  end
 
  alias checkstates_gamebattler_onturnend on_turn_end
  def on_turn_end
    checkstates_gamebattler_onturnend
    if Target.records.key?(self) # if this battler has hit someone
      Target.records[self].check_for_states(self) # the target checks for states in relation to the attacker
    end
  end
 
  def check_for_states(user)
    # state checks go here
    # self.state?(X) for the target
    # user.state?(X) for the attacker
  end
 
end
 

Countyoungblood

Sleeping Dragon
Veteran
Joined
Dec 9, 2017
Messages
622
Reaction score
403
First Language
English
Primarily Uses
RMVXA
It doesn't matter if I use variables or not but if you (or theo) understand how to format the one line I'm struggling with id appreciate help there instead of reworking up to the point I'm already at I've already backtracked to using variables Im not going to toggle again.

the variables are setting properly and my state_update method is working as intended. all i need is the right format to look at states using already properly assigned variables.

my last attempt was this:

if $game_variables[self.index].state?(27)

I've already assigned the variables using this in an attack formula

v[a.index+1] = (b.index + 1)

I want to check these against the current objects index and if any have a value read the value and check that objects states.
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
5,573
Reaction score
6,503
First Language
Indonesian
Primarily Uses
RMVXA
Maybe instead of us guessing what you actually do, give the entire script you're working on? so far you only give us snippets and we're guessing where and when it's called.

if $game_variables[self.index].state?(27)
This is valid, however, the index is really dynamic so that it may use index 1,2,3,4
The method ".state?" may throw an error if the value of the variable is not right.
Do you really need this complicated system?

v[a.index+1] = (b.index + 1)
In this case specifically, if the attacker is an actor first index, then b is the second index, then it's equal as
Code:
$game_variables[1] = 2
if the attacker is an actor third index, then b is the first index, then it's equal as
Code:
$game_variables[3] = 1
Your code check above is not valid because the method ".state?" is not present in integer, it will crash.

What you need to do is to assign the value as Game_Battler, like
Code:
v[a.index+1] = b
 

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

Latest Threads

Latest Posts

Latest Profile Posts

I made some sideview closets for MV!
You can find them in my MV resource thread.
People1.png & SF_People1.png added!!!!

Adventurer:
"Why your body looks like a bird?"

Stranger:
"Because I'm harpy"

Adventurer:
"Clap along if you feel like a room without a roof"

*Both dancing to Pharrell Williams song*
Stream will be live shortly with a make-up session of the Interactive Text Adventure! Feel free to drop by!

Forum statistics

Threads
105,507
Messages
1,014,275
Members
137,177
Latest member
tranphong
Top