[XP] How to Make an Actor to Enemy Stat Conversion Script?

Started by nazra7, November 09, 2016, 05:32:00 pm

Previous topic - Next topic

nazra7

Hello everyone, I am making a commercial Tactical RPG similar to Final Fantasy Tactics with RPG Maker XP and I would like some help creating a script which takes the values of a specified Actor's stats, after adding stats from equipment, and applies the same values of stats to a specified Enemy's stats using the Event Script Command. This way, I can simulate Enemys having levels and wearing equipment. For example, using the event's script command to convert Actor #5's stats to the stats of Enemy #10 in the Database, I think it would look something like this:

enemy[10].maxhp = actor[5].maxhp
enemy[10].maxsp = actor[5].maxsp
enemy[10].hp = actor[5].sp
enemy[10].sp = actor[5].sp
enemy[10].str = actor[5].str
enemy[10].dex = actor[5].dex
enemy[10].agi = actor[5].agi
enemy[10].int = actor[5].int
enemy[10].atk = actor[5].atk
enemy[10].pdef = actor[5].pdef
enemy[10].mdef = actor[5].mdef
enemy[10].eva = actor[5].eva

But I know that's not going to work because it doesn't use the correct script codes. However, I'm hoping it will be about as simple in structure. I just need to know what the right script codes are for this... Does anyone here, who's much better at scripting, know what script codes I need to use in order to pull this off? Please let me know, I'd GREATLY appreciate it! And thanks a ton in advance!

KK20

Need to rewrite some of Game_Enemy first, so add this somewhere below the default scripts:

class Game_Enemy < Game_Battler
  #--------------------------------------------------------------------------
  # * Sets the base stats of the enemy to that of an Actor
  #--------------------------------------------------------------------------
  def set_actor_stats(actor_id)
    actor = $game_actors[actor_id]
    @hp = @maxhp = actor.maxhp
    @sp = @maxsp = actor.maxsp
    @str = actor.str
    @dex = actor.dex
    @int = actor.int
    @atk = actor.atk
    @pdef = actor.pdef
    @mdef = actor.mdef
    @eva = actor.eva
  end
  #--------------------------------------------------------------------------
  # * Get Basic Maximum HP
  #--------------------------------------------------------------------------
  def base_maxhp
    return @maxhp || $data_enemies[@enemy_id].maxhp
  end
  #--------------------------------------------------------------------------
  # * Get Basic Maximum SP
  #--------------------------------------------------------------------------
  def base_maxsp
    return @maxsp || $data_enemies[@enemy_id].maxsp
  end
  #--------------------------------------------------------------------------
  # * Get Basic Strength
  #--------------------------------------------------------------------------
  def base_str
    return @str || $data_enemies[@enemy_id].str
  end
  #--------------------------------------------------------------------------
  # * Get Basic Dexterity
  #--------------------------------------------------------------------------
  def base_dex
    return @dex || $data_enemies[@enemy_id].dex
  end
  #--------------------------------------------------------------------------
  # * Get Basic Agility
  #--------------------------------------------------------------------------
  def base_agi
    return @agi || $data_enemies[@enemy_id].agi
  end
  #--------------------------------------------------------------------------
  # * Get Basic Intelligence
  #--------------------------------------------------------------------------
  def base_int
    return @int || $data_enemies[@enemy_id].int
  end
  #--------------------------------------------------------------------------
  # * Get Basic Attack Power
  #--------------------------------------------------------------------------
  def base_atk
    return @atk || $data_enemies[@enemy_id].atk
  end
  #--------------------------------------------------------------------------
  # * Get Basic Physical Defense
  #--------------------------------------------------------------------------
  def base_pdef
    return @pdef || $data_enemies[@enemy_id].pdef
  end
  #--------------------------------------------------------------------------
  # * Get Basic Magic Defense
  #--------------------------------------------------------------------------
  def base_mdef
    return @mdef || $data_enemies[@enemy_id].mdef
  end
  #--------------------------------------------------------------------------
  # * Get Basic Evasion
  #--------------------------------------------------------------------------
  def base_eva
    return @eva || $data_enemies[@enemy_id].eva
  end
 
end

If you have access to the Game_Enemy object e, you can then use the command
e.set_actor_stats(5)


This is a very basic implementation though. If you're going to be more creative like "can destroy pieces of armor so PDEF should go down as well" you will need to make some modifications to the existing scripts to allow that (since it doesn't exist in the default RMXP scripts).

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

nazra7

Thanks very much for the reply! But I'm kind of confused as to how to use this script you suggested here. For example:

1. For the class Game_Enemy script, for these two lines of code:

  def set_actor_stats(actor_id)
    actor = $game_actors[actor_id]

  Do I replace "actor_id" with the id number of  the actor I want to use? So if I'm wanting to change Enemy 3's stats to that of Actor 5's stats, do I put "5" in place of "actor_id" on those two lines of code?
  Also, where/how do I specify which enemy (in this case enemy 3) I want to change its stats to that of Actor 5?

And...

2. When using "e.set_actor_stats(5)", is "5" the actor ID I want to use to change to base the enemy's stats on? And if so, how do I specify which enemy exactly will have Actor 5's stats?

Please let me know as soon as you can. Thanks very much!

KK20

actor_id is the database ID of the actor. So 1 would be Aluxes, 2 is Basil, etc.

That depends on how your system works. Are you using the default RMXP way of using enemy troops? In that case,

$game_troop.setup(A)
$game_troop.enemies[B].set_actor_stats(C)

A = troop ID in database
B = enemy index in the troop above
C = actor ID in database

I don't know how your battle system script works, so I can't really tell you the answer.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

nazra7

Hey, sorry for the late reply, and thanks again for your reply. My battle system does use the default troops in the RMXP database. I understand what the value actor_ID represents, I'm just having a hard time understanding how to use this method you're suggesting to change a specific enemy's stats to equal that of a specific actor's stats. So far, this is what I understand:

1. Place this script above the "Main" script and below the default scripts:

class Game_Enemy < Game_Battler
  #--------------------------------------------------------------------------
  # * Sets the base stats of the enemy to that of an Actor
  #--------------------------------------------------------------------------
  def set_actor_stats(actor_id)
    actor = $game_actors[actor_id]
    @hp = @maxhp = actor.maxhp
    @sp = @maxsp = actor.maxsp
    @str = actor.str
    @dex = actor.dex
    @int = actor.int
    @atk = actor.atk
    @pdef = actor.pdef
    @mdef = actor.mdef
    @eva = actor.eva
  end
  #--------------------------------------------------------------------------
  # * Get Basic Maximum HP
  #--------------------------------------------------------------------------
  def base_maxhp
    return @maxhp || $data_enemies[@enemy_id].maxhp
  end
  #--------------------------------------------------------------------------
  # * Get Basic Maximum SP
  #--------------------------------------------------------------------------
  def base_maxsp
    return @maxsp || $data_enemies[@enemy_id].maxsp
  end
  #--------------------------------------------------------------------------
  # * Get Basic Strength
  #--------------------------------------------------------------------------
  def base_str
    return @str || $data_enemies[@enemy_id].str
  end
  #--------------------------------------------------------------------------
  # * Get Basic Dexterity
  #--------------------------------------------------------------------------
  def base_dex
    return @dex || $data_enemies[@enemy_id].dex
  end
  #--------------------------------------------------------------------------
  # * Get Basic Agility
  #--------------------------------------------------------------------------
  def base_agi
    return @agi || $data_enemies[@enemy_id].agi
  end
  #--------------------------------------------------------------------------
  # * Get Basic Intelligence
  #--------------------------------------------------------------------------
  def base_int
    return @int || $data_enemies[@enemy_id].int
  end
  #--------------------------------------------------------------------------
  # * Get Basic Attack Power
  #--------------------------------------------------------------------------
  def base_atk
    return @atk || $data_enemies[@enemy_id].atk
  end
  #--------------------------------------------------------------------------
  # * Get Basic Physical Defense
  #--------------------------------------------------------------------------
  def base_pdef
    return @pdef || $data_enemies[@enemy_id].pdef
  end
  #--------------------------------------------------------------------------
  # * Get Basic Magic Defense
  #--------------------------------------------------------------------------
  def base_mdef
    return @mdef || $data_enemies[@enemy_id].mdef
  end
  #--------------------------------------------------------------------------
  # * Get Basic Evasion
  #--------------------------------------------------------------------------
  def base_eva
    return @eva || $data_enemies[@enemy_id].eva
  end
 
end


2. Use this command: e.set_actor_stats(5)

But this is where I am lost. What does the command "e.set_actor_stats(5)" do exactly? Does it change a single enemy's stats to equal the stats of actor number 5? If so, which enemy's stat is it changing? Or does it instead change the stats of every enemy in the entire current troop of enemies? After reading your last post, it does indeed sound like the above script only changes the stats of every enemy in the troop to equal the stats of actor 5 rather than changing just a single and specific enemy's stats. If that's true, then how do I change just one specific enemy's stats instead of the entire troop? Please let me know as soon as possible. And thanks again!

KK20

Please look at the script call again:

$game_troop.setup(A)
$game_troop.enemies[B].set_actor_stats(C)

Say that in your game your player is going into battle with the monster troop ID 1. In this troop are two ghosts. To create the enemy objects, you initialize the troop by calling Game_Troop#setup and passing the parameter 1 (the first line in the script call) like so:

$game_troop.setup(1)


But say that you want the first ghost to have the same stats as actor ID 5 while the second ghost has the same stats as actor ID 3. You would use:

$game_troop.enemies[0].set_actor_stats(5)
$game_troop.enemies[1].set_actor_stats(3)

If you wanted all enemies in the troop to have the same stats as actor ID 4:

$game_troop.enemies.each{|e|
e.set_actor_stats(4) }


I really can't explain it any clearer.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

nazra7

That explains it perfectly! Thanks so much and again really sorry for the late reply. I  really want to try this but there's just one more problem. I can't figure out how to call this line of code using the script command for events: $game_troop.enemies[0].set_actor_stats(5) because its too long to fit inside the tiny box, half of it is put on the second line like this:

$game_troop.enemies
[0].set_actor_stats(5)




and this will of course cause a crash error. I know you can store certain codes in variables to shorten the code length to fit inside this tiny script box, but I don't know if that can be one with this specific line of code. Could you tell me how to get this code to fit inside the tiny event script box? Or how I can use the game's script editor to set up battles with specified enemies in specified troops to have the same stats as a specified actor? Please let me know, and thanks very much again in advance! I really appreciate all the help you've given me so far :D

KK20

You should try experimenting more. You already provided yourself the answer

e = $game_troop.enemies
e[0].set_actor_stats(5)
e[1].set_actor_stats(3)

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

nazra7

Ah, thank you SO much! I didn't know what part of that line of code could be stored in a variable. I'm going to try it out here pretty soon and I'll get back with you if there's anymore issues.

nazra7

Hello again KK20, I just tried to test this script, and when I tried to call this script with an event:

e = $game_troop.enemies
$game_troop.setup(4)
e[1].set_actor_stats(41)


I got this error: No Method error occurred while running script. Undefined method 'set_actor_stats' for nil:NilClass. I don't know why its giving me this error since the script you gave me clearly defines set_actor_stats. I've tried placing it in multiple places around my custom scripts above the main script and below the default scripts, and I've tried rewriting the Game_Enemy script to include this code instead of using a new script to rewrite it to no avail. If you can find out what's going on here, please let me know how to fix this. I can't thank you enough for all the help you've given me so far!  :haha:

KK20

It's either one of these two things

You need to setup the troop first before getting the troop enemies. Currently there is no troop loaded so enemies returns nil.

Your troop has only one enemy in it. Arrays are zero indexed so the first enemy is actually at 0, not 1.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

nazra7

Yes! That worked! And I also had to call the script during a battle, not before one. Thank you so much!!! :D :haha: I have another question I hope you could help me with if its not too much trouble. Along with the actor's stats, I'd also like to set the enemy's normal attack animation to the same animation as the actor's weapon attack animation. I tried adding this to the script:

  #--------------------------------------------------------------------------
  # * Get Offensive Animation ID for Normal Attack
  #--------------------------------------------------------------------------
  def animation1_id
    return @animation1_id || $data_enemies[@enemy_id].animation1_id
  end
  #--------------------------------------------------------------------------
  # * Get Target Animation ID for Normal Attack
  #--------------------------------------------------------------------------
  def animation2_id
    return @animation2_id || $data_enemies[@enemy_id].animation2_id
  end


But that didn't seem to do anything at all. I think its because the actor's attack animation is stored in a variable with a different name, unlike the names of the stat variables because when I search for actor.animation1_id or actor.animation2_id I get no result. There's only actor.animation_id which I think is the id of the animation that plays on the actor when its a target of a skill as I've learned from fiddling around with it. So, if you know know how I could make it to where the enemy's attack animation is set to the actor's attack animation/weapon animation, if you could show me how I would greatly appreciate it so much!

KK20

Revising the script:

class Game_Enemy < Game_Battler
  #--------------------------------------------------------------------------
  # * Sets the base stats of the enemy to that of an Actor
  #--------------------------------------------------------------------------
  def set_actor_stats(actor_id)
    @actor = $game_actors[actor_id]
    @hp = @maxhp = @actor.maxhp
    @sp = @maxsp = @actor.maxsp
    @str = @actor.str
    @dex = @actor.dex
    @int = @actor.int
    @atk = @actor.atk
    @pdef = @actor.pdef
    @mdef = @actor.mdef
    @eva = @actor.eva
  end
  #--------------------------------------------------------------------------
  # * Get Basic Maximum HP
  #--------------------------------------------------------------------------
  def base_maxhp
    return @maxhp || $data_enemies[@enemy_id].maxhp
  end
  #--------------------------------------------------------------------------
  # * Get Basic Maximum SP
  #--------------------------------------------------------------------------
  def base_maxsp
    return @maxsp || $data_enemies[@enemy_id].maxsp
  end
  #--------------------------------------------------------------------------
  # * Get Basic Strength
  #--------------------------------------------------------------------------
  def base_str
    return @str || $data_enemies[@enemy_id].str
  end
  #--------------------------------------------------------------------------
  # * Get Basic Dexterity
  #--------------------------------------------------------------------------
  def base_dex
    return @dex || $data_enemies[@enemy_id].dex
  end
  #--------------------------------------------------------------------------
  # * Get Basic Agility
  #--------------------------------------------------------------------------
  def base_agi
    return @agi || $data_enemies[@enemy_id].agi
  end
  #--------------------------------------------------------------------------
  # * Get Basic Intelligence
  #--------------------------------------------------------------------------
  def base_int
    return @int || $data_enemies[@enemy_id].int
  end
  #--------------------------------------------------------------------------
  # * Get Basic Attack Power
  #--------------------------------------------------------------------------
  def base_atk
    return @atk || $data_enemies[@enemy_id].atk
  end
  #--------------------------------------------------------------------------
  # * Get Basic Physical Defense
  #--------------------------------------------------------------------------
  def base_pdef
    return @pdef || $data_enemies[@enemy_id].pdef
  end
  #--------------------------------------------------------------------------
  # * Get Basic Magic Defense
  #--------------------------------------------------------------------------
  def base_mdef
    return @mdef || $data_enemies[@enemy_id].mdef
  end
  #--------------------------------------------------------------------------
  # * Get Basic Evasion
  #--------------------------------------------------------------------------
  def base_eva
    return @eva || $data_enemies[@enemy_id].eva
  end
  #--------------------------------------------------------------------------
  # * Get Offensive Animation ID for Normal Attack
  #--------------------------------------------------------------------------
  def animation1_id
    return !@actor.nil? ? @actor.animation1_id : $data_enemies[@enemy_id].animation1_id
  end
  #--------------------------------------------------------------------------
  # * Get Target Animation ID for Normal Attack
  #--------------------------------------------------------------------------
  def animation2_id
    return !@actor.nil? ? @actor.animation2_id : $data_enemies[@enemy_id].animation2_id
  end
end

We're going to store the actor the enemy references now as an instance variable (i.e. begins with @). This way we can just reference the actor's animation methods directly. If no actor is referenced, we fail-safe on the enemy database configuration.

The Game_Actor's animation1/2_id methods are these:

  #--------------------------------------------------------------------------
  # * Get Offensive Animation ID for Normal Attacks
  #--------------------------------------------------------------------------
  def animation1_id
    weapon = $data_weapons[@weapon_id]
    return weapon != nil ? weapon.animation1_id : 0
  end
  #--------------------------------------------------------------------------
  # * Get Target Animation ID for Normal Attacks
  #--------------------------------------------------------------------------
  def animation2_id
    weapon = $data_weapons[@weapon_id]
    return weapon != nil ? weapon.animation2_id : 0
  end

Just like with Game_Enemy, there is no such thing as @animation1_id or @animation2_id instance variables, only class methods. They're referenced in Scene_Battle 4

  #--------------------------------------------------------------------------
  # * Make Basic Action Results
  #--------------------------------------------------------------------------
  def make_basic_action_result
    # If attack
    if @active_battler.current_action.basic == 0
      # Set anaimation ID
      @animation1_id = @active_battler.animation1_id
      @animation2_id = @active_battler.animation2_id


The purpose of @animation_id is exactly as you discovered. This is for the Game_Battler class however, not Game_Actor nor Game_Enemy.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

nazra7

I just tried this new script out and it seems to work the same as the last version of it but for some reason its not changing the attack animation of the enemy. No errors or anything either, its just not changing.

KK20

Oh lol I work too fast. For the animation methods I forgot to put a ! in front of @actor.nil?

Fixed in previous post.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

nazra7

Thank you so much! IT works perfectly! Would it also be possible to change the enemy's battler graphic, skills, auto states from armor, and Elemental/State efficiency/weaknesses to equal that of the actor's as well? And if not all of these, just as many as possible?

KK20

Probably all can be done except for skills to an extent. Since enemy actions can be defined requiring certain conditions for its use, you can't really achieve this if you were to just grab the actor's skills and assign it to the enemy. Unless you're totally okay with all actions having an equal chance of being used (like healing when at full health).

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!