Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Kain Nobel's Game_Enemy+ [Development Thread]

Thanks for helping with script, I've finished the first version of it. You can find it in submitted scripts section, or just copy it from here, they both work !

Code:
#===============================================================================
# ~* Enemy Auto-Leveling Script *~
#-------------------------------------------------------------------------------
# Written by  : Kain Nobel
# Version     : 1.0
# Last Update : 5/9/2008
# Created     : 5/8/2008
#-------------------------------------------------------------------------------
# Special Thanks: Arbiter & khmp
#===============================================================================
################################################################################
#===============================================================================
# * Game_Enemy (Aliased)
#===============================================================================
class Game_Enemy < Game_Battler
  # Alias Method for Base Stats
  alias_method :kn_game_enemy_base_maxhp, :base_maxhp
  alias_method :kn_game_enemy_base_maxsp, :base_maxsp
  alias_method :kn_game_enemy_base_str, :base_str
  alias_method :kn_game_enemy_base_dex, :base_dex
  alias_method :kn_game_enemy_base_agi, :base_agi
  alias_method :kn_game_enemy_base_int, :base_int
  alias_method :kn_game_enemy_base_atk, :base_atk
  alias_method :kn_game_enemy_base_pdef, :base_pdef
  alias_method :kn_game_enemy_base_mdef, :base_mdef
  alias_method :kn_game_enemy_base_eva, :base_eva
  # Alias Method for Gold, Exp and Drops
  alias_method :kn_game_enemy_exp, :exp
  alias_method :kn_game_enemy_gold, :gold
  #NOTE: alias overwrites origional initialize, pops up error
  #   when alias_method, so this is temporarily commented out.
  #------------------------
  # * Initialization Method
  #------------------------
  #def initialize(troop_id, member_index) #<--Included in origional method.
    #kn_game_enemy_initialize
    #
  #end
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     troop_id     : troop ID
  #     member_index : troop member index
  #--------------------------------------------------------------------------
  def initialize(troop_id, member_index)
    super()
    # Super's variables
    @troop_id = troop_id
    @member_index = member_index
    # Troop Data
    troop = $data_troops[@troop_id]
    @enemy_id = troop.members[@member_index].enemy_id
    enemy = $data_enemies[@enemy_id]
    # KN: Added average_level to initialize
    @avg_level = average_level
    @battler_name = enemy.battler_name
    @battler_hue = enemy.battler_hue
    @hp = maxhp
    @sp = maxsp
    @hidden = troop.members[@member_index].hidden
    @immortal = troop.members[@member_index].immortal
  end
  #---------------------------------
  # * Get Game_Party's Average Level
  #---------------------------------
  def average_level
    avg = 0
    $game_party.actors.each {|actor| avg += actor.level }
    return avg / $game_party.actors.size 
  end
  #-----------------------
  # * Define Average MaxHP
  #-----------------------
  def base_maxhp
    return kn_game_enemy_base_maxhp + (100 * @avg_level).to_i
  end
  #-----------------------
  # * Define Average MaxSP
  #-----------------------
  def base_maxsp
    return kn_game_enemy_base_maxsp + (10 * @avg_level).to_i
  end
  #-----------------------
  # * Define Average Str
  #-----------------------
  def base_str
    return kn_game_enemy_base_str + (1 * @avg_level).to_i
  end
  #---------------------
  # * Define Average Dex
  #---------------------
  def base_dex
    return kn_game_enemy_base_dex + (1 * @avg_level).to_i
  end
  #---------------------
  # * Define Average Agi
  #---------------------
  def base_agi
    return kn_game_enemy_base_agi + (1 * @avg_level).to_i
  end
  #---------------------
  # * Define Average Int
  #---------------------
  def base_int
    return kn_game_enemy_base_int + (1 * @avg_level).to_i
  end
  #---------------------
  # * Define Average Atk
  #---------------------
  def base_atk
    return kn_game_enemy_base_atk + (1 * @avg_level).to_i
  end
  #---------------------
  # * Define Average PDef
  #---------------------
  def base_pdef
    return kn_game_enemy_base_pdef + (1 * @avg_level).to_i
  end
  #---------------------
  # * Define Average MDef
  #---------------------
  def base_mdef
    return kn_game_enemy_base_mdef + (1 * @avg_level).to_i
  end
  #---------------------
  # * Define Average Eva
  #---------------------
  def base_eva
    return kn_game_enemy_base_eva + (1 * @avg_level).to_i
  end
  #------------------
  # * Def Average Exp
  #------------------
  def exp
    return kn_game_enemy_exp + (1 * @avg_level).to_i
  end
  #-------------------
  # * Def Average Gold
  #-------------------
  def gold
    return kn_game_enemy_gold + (1 * @avg_level).to_i
  end
end
 

khmp

Sponsor

Like Mr. SephirothSpawn's dynamic enemies where the enemies increase with difficulty as the party's average level increases? Alright for starters. The RPG data classes are never initialized. "RPG::Enemy.new" never occurs in the code. They are only ever saved and loaded through a file stream. That means that if you make an initialize for RPG::Enemy it doesn't get called unless you yourself were to create a new enemy while in game. So you are going to have to think of a separate approach to the problem.

Now for Game_Enemy. You alias initialize but never call the alias in the new initialize. You effectively override initialize instead of preserving the old code. Also you are doing this kind of thing in your average methods.
Code:
def method1
  @a = 1
  return @a
end
@a = method1 # This is redundant.

Speaking of average methods. First whats the average based on? As far as I can tell you base it off an enemy that doesn't exist unless you have some method you're not showing. I'll use your Average Level method as an example.
Code:
  #--------------------------------------------------------------------------
  # * Get Average Level
  #--------------------------------------------------------------------------
  def average_level

    # If "level_size" not to be confused with "@level_size" isn't a method 
    # you are assigning a nil local variable to an instance variable.
    @level_size = level_size 

    # Determining troop size? You would want to use: $game_troop.enemies.size
    if @level_size != 0
      # Average variable is added, to be averaged later.
      @avg_level += $data_enemies[@level_size].level
      # Troop Size Index for LVL is reduced by 1.
      @level_size -= 1
    end
    
    # Then you save the level size to a local variable which will be lost as soon as
    # this method hits return.
    level_size = @level_size

    # Return avg level which is based off of one enemy's level.
    return @avg_level
  end
   
You'll most likely want to override or clever aliasing handle the base attribute methods inside Game_Enemy. The average if you do want to base it on the party's average level would be:
Code:
  def average_level
    avg = 0
    $game_party.actors.each {|actor| avg += actor.level }
    return avg / $game_party.actors.size 
  end

Once you have the average you will need to intercept the base values that define an enemy.

Code:
class Game_Enemy
  #--------------------------------------------------------------------------
  # * Alias Methods
  #--------------------------------------------------------------------------
  alias_method :kain_dynamic_enemies_game_enemy_base_eva, :base_eva
  alias_method :kain_dynamic_enemies_game_enemy_initialize, :initalize
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    kain_dynamic_enemies_game_enemy_initialize
    @avg_level = average_level
  end
  #--------------------------------------------------------------------------
  # * Average Part Level
  #--------------------------------------------------------------------------
  def average_level
    avg = 0
    $game_party.actors.each {|actor| avg += actor.level }
    return avg / $game_party.actors.size 
  end
  #--------------------------------------------------------------------------
  # * Get Basic Evasion
  #--------------------------------------------------------------------------
  def base_eva
    return kain_dynamic_enemies_game_enemy_base_eva + 
      (0.75 * @avg_level).to_i
  end
  #... other methods involving stats, gold, exp, loot, etc.
end

That's where I think you want to go with this. The 0.75 thing is just a 3/4 slope line applied to average level. You might want to create an array ahead of time if you want anything more than a linear interpolation.

Good luck with the scripting Kain Nobel! :thumb:
 
Alright for starters. The RPG data classes are never initialized. "RPG::Enemy.new" never occurs in the code. They are only ever saved and loaded through a file stream. That means that if you make an initialize for RPG::Enemy it doesn't get called unless you yourself were to create a new enemy while in game.

What exactly do you mean by 'create a new enemy'? Like, if a new enemy spawns when you kill a certain enemy, then am I going to have to do anything to the module, or will it be fine if I just leave it alone? (Although, I'm guessing you mean, like 'write' a new enemy with a script, which I didn't origionally plan on doing.)

On that note, will I have to do anything to the module if I assign enemy levels just like they were actor levels, or can I just write that into the Game_Enemy class? Same thing if I give the option to assign additonal drops to enemies, and a gold variance, will I have to define that in the module at all too?

I noticed I get a script error when I wrote it like

Code:
alias_method :kn_game_enemy_initialize, :initialize

But when I wrote it like

Code:
alias kn_game_enemy_initialize initialize

It came out fine... the rest of my 'alias' stuff is written like

Code:
alias_method :kn_game_enemy_base_maxhp, :base_maxhp

But it didn't pop any errors, just errors in the initialize. Thats cool but is 'alias' just overwritting the rest of the origional method, or does it still recall its origional properties?

Script re-written and updated in top post.
 
Still, whats the difference between...

alias
alias_method

?

Re-updated script! No errors, works like a charm ;)

However, I set everything to (5 * @avg_level).

I also want to set up some sort of array or whatever, so I can make min/max growth for each enemies stat, so some enemies will level up Str at a normal rate meanwhile others will become increasingly stronger than average. That way when its called, it'll be like...

([@this stat] * @avg_level)

And... I'm going to try to set up an 'additional enemy drops' thing, I'll try what I've learned so far and see if I can do it myself, I might be coming back with more questions though.
 

khmp

Sponsor

alias_method is used to achieve the same ends as alias. alias_method is used primarily because it gets automatically logged with the SDK. That makes it a ton easier to find a bug where multiple scripts alias the same methods while using the SDK. In most cases though the person isn't using the SDK, so why use it? Well for me its a coding habit I guess. Blame Mr. SephirothSpawn for that and hashes.

The below code works perfectly fine I have no idea why it would error out on you.
Code:
class Game_Enemy
  alias_method :kn_game_enemy_initialize, :initialize
  def initialize(troop_id, member_index)
    # new code here and it works fine.
    kn_game_enemy_initialize(troop_id, member_index)
    # new code here and it works fine.
  end
end

Also Enemy creation. There is a difference between RPG::Enemy and Game_Enemy. Game_Enemy's are created while the game runs whenever you get into a fight. RPG::Enemy is just an Array of the database entries of enemies. These are never created in code like this:
Code:
$data_enemies << RPG::Enemy.new
They are read directly from the file and dumped into an Array. Initialize is never called for them. That's why if you create an initialize for RPG::Enemy it will only ever be called if you were to physically use the above line of code somewhere in the scripts. I hope that makes a little more sense.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top