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.

Dynamic Enemies Script help

I've fiddled with this thing for a while now, and searched around these forums, but this script just isn't doing what I want it to do.  Perhaps I have misunderstood it's intended function.

In another thread, I saw Seph suggest inputting the following:

Stats[5] = {}
  Stats[5]['hp'] = [0, 1, 99, 500, 150]
  Stats[5]['sp'] = [0, 1, 99, 200, 75]
  Stats[5]['str'] = [0, 1, 99, 50, 10]
  Stats[5]['dex'] = [0, 1, 99, 50, 10]
  Stats[5]['agi'] = [0, 1, 99, 50, 10]
  Stats[5]['int'] = [0, 1, 99, 50, 10]

To test it out, I've set my character's initial level at 60 and put him in a map where he randomly encounters basilisks, a default enemy in RXMP.  I want the basilisks to match up with my character, but my character is killing them all in one hit while the enemies do a measly 64 damage each time.

Is this script supposed to make enemies scale, or does it only randomize it's base stats within a small range?  Perhaps I've modified Seph's code incorrectly for the basilisks, but even then shouldn't that be covered by default level ranges?

Sorry if this question seems stupid, or posted in the wrong place, or formatted incorrectly.  I'm new to scripting and these boards.
 

khmp

Sponsor

Well that code standing by itself won't do anything in fact it won't even compile I don't think. Could you provide the link where you found this if possible? I might be able to better help you then.
 

khmp

Sponsor

Ah ok. So going from that part of code you have at the top the basilisk is enemy number 5 I take it.

Code:
Stats = {
  5 => { 
    'hp' => [0, 1, 99, 500, 150], 'sp' => [0, 1, 99, 200, 75], 'str' => [0, 1, 99, 50, 10],
    'dex' => [0, 1, 99, 50, 10], 'agi' => [0, 1, 99, 50, 10], 'int' => [0, 1, 99, 50, 10]
  }
}

That's the pattern he's looking for I believe. Oh don't forget to put code in code tags.

Good luck with it grnydrowave! :thumb:
 
Actually, they're enemy 002 by default in RMXP.  I tried formatting it the way you suggested but I'm not seeing any difference.  My character still deals over 1,000 damage while the reptiles deal 64.
 

khmp

Sponsor

Hmm... Then change that five to a two. If you haven't already done that. You also have to have MACL 2.1 installed above this script correct? I guess you would have got an error if you didn't. I'm looking at the curve generation and it looks like the numbers you are using might be your problem.

Code:
Stats = {
  2 => { 
    'hp' => [0, 1, 99, 50, 1500], 'sp' => [0, 1, 99, 200, 750], 'str' => [0, 1, 99, 50, 100],
    'dex' => [0, 1, 99, 50, 100], 'agi' => [0, 1, 99, 50, 100], 'int' => [0, 1, 99, 50, 100],
    'atk' => [0, 1, 99, 300, 1000]
  }
}

I made it so at level 1 the monster in slot 2 will have 300 attack. At level 99 its attack will be 1000. Try that out. If that does work you'll just need to change some numbers.

Number Explanation:
Code:
'hp' => [0, # Two point slope. (Leave this at 0)
         1, # Min level.
         99, # Max level.
         500, # HP value at Min level.
         150] # HP value at Max level. This is actually weakening your monster as it levels up.


Good luck with it grnydrowave! :thumb:
 
Yes, I did change the 5 to 2.  I also tried changing it to 002, and I also tried changing it to the troop number instead of the enemy number.  And yes, I have installed MALC 2.1 above this script as well.

I've implemented your revised code, and the only difference I've noticed is that the monsters miss more frequently.  I don't know if that is just a coincidence, but when they do land hits, they are in the 64-69 damage range.  :(
 

khmp

Sponsor

I think I know the problem if that is your project's Scripts.rxdata. There is no MACL or Dynamic Enemy Script in there. Or did you upload the wrong project's Scripts.rxdata file?
 

khmp

Sponsor

Yeah I found that one part SephirothSpawn's script had a misnamed method that was called over and over. And once I got past that it goes and crashes when generating a curve.

But anyway what I've done so far. There's a method called "is_dynamic?" that when you handed it to me checked to see if the id was contained inside "Unaffected_Enemies" array. It now as I assumed it should have checks to see if it's listed inside the "Stats" hash. Next the misnomered method "get_base_stat". There is a closely worded method inside module Dynamic_Enemies called "get_stat_base". I renamed the method to match the calls made inside Game_Enemy's "setup_dynamic_enemy" method.

Code:
#==============================================================================
# ** Dynamic Enemies
#------------------------------------------------------------------------------
# SephirothSpawn
# Version 3.01
# 2007-05-11
# SDK : Version 2.0+, Part 1
#------------------------------------------------------------------------------
# * Version History :
#
#   Version 1 ---------------------------------------------------- (2006-08-06)
#   Version 2 ---------------------------------------------------- (2006-10-07)
#    - Update : Updated to work with Trickster's Curve Generator Module
#   Version 3 ---------------------------------------------------- (2007-02-28)
#    - Update : Rescripted entire system
#    Version 3.01 ------------------------------------------------ (2007-05-11)
#     - Bug Fix : Fixed Extremely Minor Base Stat Level Error
#------------------------------------------------------------------------------
# * Requirements :
#
#   Method & Class Library 2.1+
#------------------------------------------------------------------------------
# * Description
#
#   This script was designed to allow your game to have enemies that develope
#   as your actors do. No longer will you encounter the same old boring enemy
#   each time. As the developer, you can control the development of each stat
#   for each enemy. The script assigns the enemy a semi-random and controled
#   level depending on the party's average level. The stats are then pulled
#   from a generated curve based of your definitions.
#------------------------------------------------------------------------------
# * Instructions
#
#   Place The Script Below the SDK and Above Main.
#   To Customize your enemy stats, refer to the customization instructions.
#------------------------------------------------------------------------------
# * Customization
#
#   Setting unaffected enemies
#    - Unaffected_Enemies = [enemy_id, enemy_id, ...]
#
#   Setting enemy stats
#    - Stats = { 
#        enemy_id => { <stat_name> => [ generator_type, *args ], ... }
#        , ...
#      }
#
#   Stat Names : 'maxhp', 'maxsp', 'str', 'dex', 'agi', 'int', 'atk', 
#                'pdef',  'mdef',  'eva', 'hit', 'exp', 'gold'
#
#   ** Refer to Curve Generator System for type and args specification.
#
#   Enemy Min & Max Level
#    - Min_Levels = { enemy_id => min_level, ... }
#    - Max_Levels = { enemy_id => max_level, ... }
#
#   Default Min & Max Level (For all non-defined enemies)
#    - Min_Levels.default = min_level
#    - Max_Levels.default = max_level
#
#   Range For Enemy Levels Off Party Level
#    - Level_Ranges = { enemy_id => (min_v..max_v), ... }
#
#   Range For Enemy Levels Off Party Level (For all non-defined enemies)
#    - Level_Ranges.default = (min_v..max_v)
#--------------------------------------------------------------------------
# * Syntax :
#
#   Enemy Level
#    - <game_enemy>.level
#
#   Dynamic Enemies
#    - <game_enemy>.is_dynamic?
#==============================================================================

#------------------------------------------------------------------------------
# * SDK Log Script
#------------------------------------------------------------------------------
SDK.log('Dynamic Enemies', 'SephirothSpawn', 3.01, '2007-05-11')
SDK.check_requirements(2.0, [], {'Method & Class Library' => 2.1}) 

#------------------------------------------------------------------------------
# * Begin SDK Enable Test
#------------------------------------------------------------------------------
if SDK.enabled?('Dynamic Enemies')
  
#==============================================================================
# ** Dynamic_Enemies
#==============================================================================

module Dynamic_Enemies
  #--------------------------------------------------------------------------
  # * Saves Curves
  #
  #  ~ @cache = { <generator_setup> => <curve>, ... }
  #--------------------------------------------------------------------------
  @cache = {}
  #--------------------------------------------------------------------------
  # * Unaffected Enemies
  #
  #  ~ Unaffected_Enemies = [enemy_id, enemy_id, ...]
  #--------------------------------------------------------------------------
  Unaffected_Enemies = []
  #--------------------------------------------------------------------------
  # * Stats
  #
  #  ~ enemy_id => { <stat_name> => [ generator_type, *args ], ... }
  #
  #  Stat Names : 'maxhp', 'maxsp', 'str', 'dex', 'agi', 'int', 'atk', 
  #               'pdef',  'mdef',  'eva', 'hit', 'exp', 'gold'
  #
  #  ** Refer to Curve Generator System for type and args specification.
  #--------------------------------------------------------------------------
  Stats = {
    2 => {
      'maxhp' => [0, 1, 99, 500, 150], 'maxsp' => [0, 1, 99, 200, 75], 'str' => [0, 1, 99, 50, 10],
      'dex' => [0, 1, 99, 50, 10], 'agi' => [0, 1, 99, 50, 10], 'int' => [0, 1, 99, 50, 10]
    }
  }
  #--------------------------------------------------------------------------
  # * Defaults : BE CAREFUL WITH ALTERATION
  #--------------------------------------------------------------------------
  Stats.default = {}
  # Default For All Non-Defined Stats
  Stats.default.default = [0, 1, 99, 500, 220]
  Stats.values.each do |stat_settings|
    # Default For All Non-Defined Stats For Defined Enemies
    stat_settings.default = [0, 1, 99, 500, 220]
  end
  #--------------------------------------------------------------------------
  # * Level Specifications
  #
  #   Enemy Min & Max Level
  #    - Min_Levels = { enemy_id => min_level, ... }
  #    - Max_Levels = { enemy_id => max_level, ... }
  #
  #   Default Min & Max Level (For all non-defined enemies)
  #    - Min_Levels.default = min_level
  #    - Max_Levels.default = max_level
  #
  #   Range For Enemy Levels Off Party Level
  #    - Level_Ranges = { enemy_id => (min_v..max_v), ... }
  #
  #   Range For Enemy Levels Off Party Level (For all non-defined enemies)
  #    - Level_Ranges.default = (min_v..max_v)
  #--------------------------------------------------------------------------
  Min_Levels           = {}
  Max_Levels           = {}
  Level_Ranges         = {}
  Min_Levels.default   = 1
  Max_Levels.default   = 99
  Level_Ranges.default = (-3..3)
  #--------------------------------------------------------------------------
  # * Get Base Stat
  #--------------------------------------------------------------------------
  def self.get_base_stat(enemy_id, stat_name, level)
    # Gets Curve Data
    curve_data = Stats[enemy_id][stat_name]
    # Checks For Pre-defined Curve
    if @cache.has_key?(curve_data)
      return @cache[curve_data][level]
    end
    # Creates Curve Data
    curve = Curve_Generator.generate_curve(*curve_data)
    # Save Curve
    @cache[curve_data] = curve
    # Return Stat
    return curve[level]
  end
  #--------------------------------------------------------------------------
  # * Generate Level
  #--------------------------------------------------------------------------
  def self.generate_level(enemy_id)
    # Collect Average Party Level
    level = 0
    $game_party.actors.each {|a| level += a.level}
    level /= $game_party.actors.size
    # Cap Level
    level = [[level, Min_Levels[enemy_id]].max, Max_Levels[enemy_id]].min
    # Modifies Level
    level += Level_Ranges[enemy_id].random
    # Return Level Data
    return level
  end
end

#==============================================================================
# ** Game_Enemy
#==============================================================================

class Game_Enemy < Game_Battler
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_reader :level
  #--------------------------------------------------------------------------
  # * Alias Listings
  #--------------------------------------------------------------------------
  alias_method :seph_dynenemies_gmenmy_init,  :initialize
  alias_method :seph_dynenemies_gmenmy_maxhp, :base_maxhp
  alias_method :seph_dynenemies_gmenmy_maxsp, :base_maxhp
  alias_method :seph_dynenemies_gmenmy_str,   :base_str
  alias_method :seph_dynenemies_gmenmy_dex,   :base_dex
  alias_method :seph_dynenemies_gmenmy_agi,   :base_agi
  alias_method :seph_dynenemies_gmenmy_int,   :base_int
  alias_method :seph_dynenemies_gmenmy_atk,   :base_atk
  alias_method :seph_dynenemies_gmenmy_eva,   :base_eva
  alias_method :seph_dynenemies_gmenmy_pdef,  :base_pdef
  alias_method :seph_dynenemies_gmenmy_mdef,  :base_mdef
  alias_method :seph_dynenemies_gmenmy_exp,   :exp
  alias_method :seph_dynenemies_gmenmy_gold,  :gold
  #--------------------------------------------------------------------------
  # * Is Dynamic
  #--------------------------------------------------------------------------
  def is_dynamic?(enemy_id = @enemy_id)
    return Dynamic_Enemies::Stats.has_key?(enemy_id)
  end
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(troop_id, member_index)
    # Gets Enemy ID
    enemy_id = $data_troops[troop_id].members[member_index].enemy_id
    # Set Level
    @level = Dynamic_Enemies.generate_level(enemy_id)
    # Setup Dynamic Enemy
    setup_dynamic_enemy(enemy_id) if is_dynamic?(enemy_id)
    # Original Initialization
    seph_dynenemies_gmenmy_init(troop_id, member_index)
  end
  #--------------------------------------------------------------------------
  # * Setup Dynamic Enemy
  #--------------------------------------------------------------------------
  def setup_dynamic_enemy(enemy_id)
    # Set Dynamic Stats
    @dyn_base_maxhp = Dynamic_Enemies.get_base_stat(enemy_id, 'hp',   @level)
    @dyn_base_maxsp = Dynamic_Enemies.get_base_stat(enemy_id, 'sp',   @level)
    @dyn_base_str   = Dynamic_Enemies.get_base_stat(enemy_id, 'str',  @level)
    @dyn_base_dex   = Dynamic_Enemies.get_base_stat(enemy_id, 'dex',  @level)
    @dyn_base_agi   = Dynamic_Enemies.get_base_stat(enemy_id, 'agi',  @level)
    @dyn_base_int   = Dynamic_Enemies.get_base_stat(enemy_id, 'int',  @level)
    @dyn_base_atk   = Dynamic_Enemies.get_base_stat(enemy_id, 'atk',  @level)
    @dyn_base_eva   = Dynamic_Enemies.get_base_stat(enemy_id, 'eva',  @level)
    @dyn_base_pdef  = Dynamic_Enemies.get_base_stat(enemy_id, 'pdef', @level)
    @dyn_base_mdef  = Dynamic_Enemies.get_base_stat(enemy_id, 'mdef', @level)
    @dyn_gold       = Dynamic_Enemies.get_base_stat(enemy_id, 'gold', @level)
    @dyn_exp        = Dynamic_Enemies.get_base_stat(enemy_id, 'exp',  @level)
  end
  #--------------------------------------------------------------------------
  # * Get Basic Maximum HP
  #--------------------------------------------------------------------------
  def base_maxhp
    return is_dynamic? ? @dyn_base_maxhp : seph_dynenemies_gmenmy_maxhp
  end
  #--------------------------------------------------------------------------
  # * Get Basic Maximum SP
  #--------------------------------------------------------------------------
  def base_maxsp
    return is_dynamic? ? @dyn_base_maxsp : seph_dynenemies_gmenmy_maxsp
  end
  #--------------------------------------------------------------------------
  # * Get Basic Strength
  #--------------------------------------------------------------------------
  def base_str
    return is_dynamic? ? @dyn_base_str : seph_dynenemies_gmenmy_str
  end
  #--------------------------------------------------------------------------
  # * Get Basic Dexterity
  #--------------------------------------------------------------------------
  def base_dex
    return is_dynamic? ? @dyn_base_dex : seph_dynenemies_gmenmy_dex
  end
  #--------------------------------------------------------------------------
  # * Get Basic Agility
  #--------------------------------------------------------------------------
  def base_agi
    return is_dynamic? ? @dyn_base_agi : seph_dynenemies_gmenmy_agi
  end
  #--------------------------------------------------------------------------
  # * Get Basic Intelligence
  #--------------------------------------------------------------------------
  def base_int
    return is_dynamic? ? @dyn_base_int : seph_dynenemies_gmenmy_int
  end
  #--------------------------------------------------------------------------
  # * Get Basic Attack Power
  #--------------------------------------------------------------------------
  def base_atk
    return is_dynamic? ? @dyn_base_atk : seph_dynenemies_gmenmy_atk
  end
  #--------------------------------------------------------------------------
  # * Get Basic Physical Defense
  #--------------------------------------------------------------------------
  def base_pdef
    return is_dynamic? ? @dyn_base_pdef : seph_dynenemies_gmenmy_pdef
  end
  #--------------------------------------------------------------------------
  # * Get Basic Magic Defense
  #--------------------------------------------------------------------------
  def base_mdef
    return is_dynamic? ? @dyn_base_mdef : seph_dynenemies_gmenmy_mdef
  end
  #--------------------------------------------------------------------------
  # * Get Basic Evasion
  #--------------------------------------------------------------------------
  def base_eva
    return is_dynamic? ? @dyn_base_eva : seph_dynenemies_gmenmy_eva
  end
  #--------------------------------------------------------------------------
  # * Exp
  #--------------------------------------------------------------------------
  def exp
    return is_dynamic? ? @dyn_exp : seph_dynenemies_gmenmy_exp
  end
  #--------------------------------------------------------------------------
  # * Gold
  #--------------------------------------------------------------------------
  def gold
    return is_dynamic? ? @dyn_gold : seph_dynenemies_gmenmy_gold
  end
end

#--------------------------------------------------------------------------
# * End SDK Enable Test
#--------------------------------------------------------------------------
end

Alright there's actually some little bugs in the MACL version you and I downloaded. These are little buggers you'll need to fix before the script will work.

Ctrl-H this line:
Code:
tables[type][args] = curve
Replace with this line:
Code:
tables[type][args] = table

Ctrl-H this line:
Code:
def self.generate_curve(min_l, max_level, start_value, inflation)
Replace with this line:
Code:
def self.generate_curve(min_l, max_l, start_value, inflation)

As always and hopefully finally good luck with it grnydrowave! :thumb:
 
I've replaced the Dynamic Enemies script I had with the one you provided, and now I'm getting this error as soon as battles initialize:

Script 'MACL Complete' line 7793: NameError occured

undefined local variable or method 'max_l' for Curve_Generator::Point_Slope:Module

Of course I have no idea what that means.

Edit: Sorry, I see that you've made some edits.  Disregard this post for the moment.
 

khmp

Sponsor

You didn't wait until I edited my previous post. :lol: I think its solved. At least it seems to work on mine. By the way in any case if that was the MACL that everyone grabs you might have helped resolve a few bugs in it so I'm glad you asked for help on this subject.
 
Success!  Those pesky basilisks are tough as nails now!  Perhaps a little too though.. haha.  But I'm sure I can fix that myself.

Thank you so very much!!!  You've been extremely prompt, helpful and polite.  You must be a great asset to this community.
 

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