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.

[SOLVED] [RMXP] Animated Battlers Scripting Issue

Status
Not open for further replies.
Hey all, so I suddenly got inspired to sprite today and I was making an enemy sprite and implemented into my animated battle system, when suddenly, out of nowhere I got this error:

https://www.dropbox.com/s/tv259crtsggu74m/error.png

I have never gotten anything like this and I've had my animated battler script for well . . . ever now, so I am baffled that this is now consistently happening. The weird thing is depending on the battleback background I choose or the character battler I have in the test battle, sometimes I won't encounter this error. I know next to nothing about scripting so any help here would be so appreciated! Here's the script that the error is referencing:

Code:
#==============================================================================

# ** Sprite_Battler

#------------------------------------------------------------------------------

#  Animated Battlers by Minkoff

#==============================================================================

 

class Sprite_Battler < RPG::Sprite

  #--------------------------------------------------------------------------

  # * Initialize

  #--------------------------------------------------------------------------

  alias cbs_initialize initialize

  def initialize(viewport, battler = nil)

    @speed = 5#7

    @frames = 4

    @poses = 11

    @stationary_enemies = true

    @stationary_actors = false

    @calculate_speed = true

    @phasing = true

    @frame = 0

    @pose = 0

    @last_time = 0

    @last_move_time = 0

    cbs_initialize(viewport, battler)

    viewport.z = 99

  end

  #--------------------------------------------------------------------------

  # * Update

  #--------------------------------------------------------------------------

  alias cbs_update update

  def update

    return unless @battler

 

    # Regular Update

    cbs_update

 

    # Start Routine

    unless @started

      @width = @width / @frames

      @height = @height / @poses

      @display_x = @battler.screen_x

      @display_y = @battler.screen_y

      @destination_x = @display_x

      @destination_y = @display_y

    end

 

    # Setup Sprite

    self.src_rect.set(@width * @frame, @height * @pose, @width, @height)

    self.mirror = @battler.is_a?(Game_Enemy) unless @started

    if @battler.is_a?(Game_Actor)

   @stationary_actors = [5, 7, 9].include?(@battler.class_id)

    end

    # Position Sprite

    self.x = @display_x

    self.y = @display_y

    self.z = @display_y

    self.ox = @width / 2

    self.oy = @height

 

    # Setup Animation

    time = Graphics.frame_count / (Graphics.frame_rate / @speed)

    if @last_time < time

      @frame = (@frame + 1) % @frames

      if @frame == 0 or @reload

        if @freeze

          @frame = @frames - 1

          return

        end

        @pose = state

      end

    end

    @last_time = time

 

    # Move It

    move if moving

 

    # Finish Up

    @started = true

  end

  #--------------------------------------------------------------------------

  # * Current State

  #--------------------------------------------------------------------------

  def state

    # Damage State

    if [nil,{}].include?(@battler.damage)

      # Battler Fine

      @state = 0

      # Battler Wounded

      @state = 0 if @battler.hp < @battler.maxhp / 4

      # Battler Dead

      @state = 2 if @battler.dead?

    end

    # Guarding State

    @state = 3 if @battler.guarding?

    # Moving State

    if moving

      # Battler Moving Left

      @state = 4 if moving.eql?(0)

      # Battler Moving Right

      @state = 5 if moving.eql?(1)

    end

    # Return State

    return @state

  end

  #--------------------------------------------------------------------------

  # * Move

  #--------------------------------------------------------------------------

  def move

    time = Graphics.frame_count / (Graphics.frame_rate.to_f / (@speed * 5))

    if @last_move_time < time

 

      # Pause for Animation

      return if @pose != state

 

      # Phasing

      if @phasing

        d1 = (@display_x - @original_x).abs

        d2 = (@display_y - @original_y).abs

        d3 = (@display_x - @destination_x).abs

        d4 = (@display_y - @destination_y).abs

        self.opacity = [255 - ([d1 + d2, d3 + d4].min * 1.75).to_i, 0].max

      end

 

      # Calculate Difference

      difference_x = (@display_x - @destination_x).abs

      difference_y = (@display_y - @destination_y).abs

 

      # Done? Reset, Stop

      if [difference_x, difference_y].max.between?(0, 8)

        @display_x = @destination_x

        @display_y = @destination_y

        @pose = state

        return

      end

 

      # Calculate Movement Increments

      increment_x = increment_y = 1

      if difference_x < difference_y

        increment_x = 1.0 / (difference_y.to_f / difference_x)

      elsif difference_y < difference_x

        increment_y = 1.0 / (difference_x.to_f / difference_y)

      end

      

      # Calculate Movement Speed

      if @calculate_speed

        total = 0; $game_party.actors.each{ |actor| total += actor.agi }

        speed = @battler.agi.to_f / (total / $game_party.actors.size)

        increment_x *= speed

        increment_y *= speed

      end

      

      # Multiply and Move

      multiplier_x = (@destination_x - @display_x > 0 ? 8 : -8)

      multiplier_y = (@destination_y - @display_y > 0 ? 8 : -8)

      @display_x += (increment_x * multiplier_x).to_i

      @display_y += (increment_y * multiplier_y).to_i

    end

    @last_move_time = time

  end

  #--------------------------------------------------------------------------

  # * Set Movement

  #--------------------------------------------------------------------------

  def setmove(destination_x, destination_y)

    unless (@battler.is_a?(Game_Enemy) and @stationary_enemies) or

           (@battler.is_a?(Game_Actor) and @stationary_actors)

      @original_x = @display_x

      @original_y = @display_y

      @destination_x = destination_x

      @destination_y = destination_y

    end

  end

  #--------------------------------------------------------------------------

  # * Movement Check

  #--------------------------------------------------------------------------

  def moving

    if (@display_x != @destination_x and @display_y != @destination_y)

      return (@display_x > @destination_x ? 0 : 1)

    end

  end

  #--------------------------------------------------------------------------

  # * Set Pose

  #--------------------------------------------------------------------------

  def pose=(pose)

    @pose = pose

    @frame = 0

  end

  #--------------------------------------------------------------------------

  # * Freeze

  #--------------------------------------------------------------------------

  def freeze

    @freeze = true

  end

  #--------------------------------------------------------------------------

  # * Fallen Pose

  #--------------------------------------------------------------------------

  def collapse

    return

  end

end

 

#==============================================================================

# ** Game_Actor

#==============================================================================

 

class Game_Actor

  #--------------------------------------------------------------------------

  # * Actor X Coordinate

  #--------------------------------------------------------------------------

  def screen_x

    if self.index != nil

      return self.index * 45 + 450

    else

      return 0

    end

  end

  #--------------------------------------------------------------------------

  # * Actor Y Coordinate

  #--------------------------------------------------------------------------

  def screen_y

    return self.index * 35 + 200

  end

  #--------------------------------------------------------------------------

  # * Actor Z Coordinate

  #--------------------------------------------------------------------------

  def screen_z

    return screen_y

  end

end

 

#==============================================================================

# ** Scene_Battle

#==============================================================================

 

class Scene_Battle

  #--------------------------------------------------------------------------

  # * Action Animation, Movement

  #--------------------------------------------------------------------------

  alias cbs_update_phase4_step3 update_phase4_step3

  def update_phase4_step3(battler = @active_battler)

    @rtab = !@target_battlers

    target = (@rtab ? battler.target : @target_battlers)[0]

    @moved = {} unless @moved

    return if @spriteset.battler(battler).moving

    case battler.current_action.kind

    when 0 # Attack

      if not (@moved[battler] or battler.guarding?)

        offset = (battler.is_a?(Game_Actor) ? 40 : -40)

        @spriteset.battler(battler).setmove(target.screen_x + offset, target.screen_y)

        @moved[battler] = true

        return

      elsif not battler.guarding?

        @spriteset.battler(battler).pose = 6 + rand(2)

        @spriteset.battler(battler).setmove(battler.screen_x, battler.screen_y)

      end

    when 1 # Skill

      @spriteset.battler(battler).pose = 10

    when 2 # Item

      @spriteset.battler(battler).pose = 8

    end

    @moved[battler] = false

    @rtab ? cbs_update_phase4_step3(battler) : cbs_update_phase4_step3

  end

  #--------------------------------------------------------------------------

  # * Hit Animation

  #--------------------------------------------------------------------------

  alias cbs_update_phase4_step4 update_phase4_step4

  def update_phase4_step4(battler = @active_battler)

    for target in (@rtab ? battler.target : @target_battlers)

      damage = (@rtab ? target.damage[battler] : target.damage)

      if damage.is_a?(Numeric) and damage > 0

        @spriteset.battler(target).pose = 1

      end

    end

    @rtab ? cbs_update_phase4_step4(battler) : cbs_update_phase4_step4

  end

  #--------------------------------------------------------------------------

  # * Victory Animation

  #--------------------------------------------------------------------------

  alias cbs_start_phase5 start_phase5

  def start_phase5

    for actor in $game_party.actors

      return if @spriteset.battler(actor).moving

    end

    for actor in $game_party.actors

      unless actor.dead?

        @spriteset.battler(actor).pose = 9

        @spriteset.battler(actor).freeze

      end

    end

    cbs_start_phase5

  end

  #--------------------------------------------------------------------------

  # * Change Arrow Viewport

  #--------------------------------------------------------------------------

  alias cbs_start_enemy_select start_enemy_select

  def start_enemy_select

    cbs_start_enemy_select

    @enemy_arrow.dispose

    @enemy_arrow = Arrow_Enemy.new(@spriteset.viewport2)

    @enemy_arrow.help_window = @help_window

  end

end

 

#==============================================================================

# ** Spriteset_Battle

#==============================================================================

 

class Spriteset_Battle

  #--------------------------------------------------------------------------

  # * Find Sprite From Battler Handle

  #--------------------------------------------------------------------------

  def battler(handle)

    for sprite in @actor_sprites + @enemy_sprites

      return sprite if sprite.battler == handle

    end

    return false

  end

end

 

#==============================================================================

# ** Arrow_Base

#==============================================================================

 

class Arrow_Base < Sprite

  #--------------------------------------------------------------------------

  # * Reposition Arrows

  #--------------------------------------------------------------------------

  alias cbs_initialize initialize

  def initialize(viewport)

    cbs_initialize(viewport)

    self.ox = 14 # 32

    self.oy = 10 # 40

  end

end

class Spriteset_Battle

attr_accessor :actor_sprites

end

 

#==============================================================================

# ** Scene_Battle

#==============================================================================

class Scene_Battle

#--------------------------------------------------------------------------

# * Constants

#--------------------------------------------------------------------------

# Loads Data System

data_system = load_data("Data/System.rxdata")

# Gets Element Array

element_array = data_system.elements

# Here's the Constants

REMOVE_NO_REPLACE = element_array.index('Remove - No Replace')

REMOVE_REPLACE_SAME = element_array.index('Remove - Replace Same')

REMOVE_REPLACE_DEAD = element_array.index('Remove - Replace Dead')

TEMP_REMOVE_SAME = element_array.index('Temp Remove - Same')

TEMP_REMOVE_KO = element_array.index('Temp Remove - KO') 

#--------------------------------------------------------------------------

# * Alias Listings

#--------------------------------------------------------------------------

alias sephraziel_actorreplacing_scenebattle_main main

alias sephraziel_actorreplacing_scenebattle_msar make_skill_action_result

alias sephraziel_actorreplacing_scenebattle_ups6 update_phase4_step6

#--------------------------------------------------------------------------

# * Main Processing

#--------------------------------------------------------------------------

def main

# This Part Executes Before our original Main Method

# Creates Replacing Array

@sephraziel_replacing_array = []

# Calls our old Main Method

sephraziel_actorreplacing_scenebattle_main

# Once our loop in the main method is broke, and it 

# does the rest of the stuff at the end of our 

# default main method, these lines will execute

# This code block goes through each idea in the actor replacing array

for id in @sephraziel_replacing_array

# Adds the actor back in with the actor id

$game_party.add_actor(id)

end

end

#--------------------------------------------------------------------------

# * Make Skill Action Results

#--------------------------------------------------------------------------

def make_skill_action_result

# Get skill

skill = $data_skills[@active_battler.current_action.skill_id] 

# Checks for Temp Remove

if skill.element_set.include?(TEMP_REMOVE_SAME) ||

skill.element_set.include?(TEMP_REMOVE_KO)

# Gets Active Battler Index

index = $game_party.actors.index(@active_battler)

# Turns off visiblilty

@spriteset.actor_sprites[index].visible = false

end

# Original Method

sephraziel_actorreplacing_scenebattle_msar

end

#--------------------------------------------------------------------------

# * Frame Update (main phase step 6 : refresh)

#--------------------------------------------------------------------------

def update_phase4_step6

# Execute our original method

sephraziel_actorreplacing_scenebattle_ups6

# New Part

if @phase4_step == 1

# If Casing Skill

if @active_battler.current_action.kind == 1

# Gets skill

skill = $data_skills[@active_battler.current_action.skill_id]

# First, we check for Remove - No Replace Skills

if skill.element_set.include?(REMOVE_NO_REPLACE)

# Removes the Actor from the party

$game_party.remove_actor(@active_battler.id)

# Now, we check for Remove - Replace Same

elsif skill.element_set.include?(REMOVE_REPLACE_SAME)

# Stores Actor Id Into Array

@sephraziel_replacing_array << @active_battler.id

# Removes the Actor from the party

$game_party.remove_actor(@active_battler.id)

# Finally, we check for Remove - Replace Dead

elsif @skill.element_set.include?(REMOVE_REPLACE_DEAD)

# Stores Actor Id Into Array

@sephraziel_replacing_array << @active_battler.id

# Kills Actor

@active_battler.hp = 0

# Removes the Actor from the party

$game_party.remove_actor(@active_battler.id)

end

# Checks for Temp Remove

if skill.element_set.include?(TEMP_REMOVE_SAME) ||

skill.element_set.include?(TEMP_REMOVE_KO)

# Gets Active Battler Index

index = $game_party.actors.index(@active_battler)

# KO's actor, if Temo Remove - KO

if skill.element_set.include?(TEMP_REMOVE_KO)

@active_battler.hp = 0

end

# Turns off visiblilty

@spriteset.actor_sprites[index].visible = true

end

end

# Refreshes Status Window

@status_window.refresh

end

end

end

 
 
The error is basically saying that you have something that doesn't exist (nil) trying to be computed as a number (or Fixnum). Essentially, something in the parenthesis of the "self.src_rect.set" is for some reason non existant. The most probable thing is that either your width or your height or even both are nil (non existant) because the bitmap or sprite it's referring to (this new enemy sprite) may not be there. Try changing the "@width" and "@height" words on that line to random numbers, like so:

Code:
self.src_rect.set(100 * @frame, 100 * @pose, 100, 100)

If this doesn't draw an error, we can move from there. Hope this was helpful :)
 
Thanks for the quick reply! ALright so I entered your code to replace that line and still got errors, however upon tinkering with it and replacing a few things, I noticed that if I change "@pose" to a number I don't get errors anymore. Some new weird things began happening, however:

If I change "@pose" to a number, my battlers cease to animate and remain on whichever pose correlates to the number I change it to (my animated battlers have 11 different poses ranging from fighting pose, defending, using an item, defeated, etc.) This also applies to the enemy battlers. Taking out your code, and just using the normal code I had to begin with I've also noticed some weird observations.

My game will only generate the error under this circumstance:

I only have ONE character fighting more than ONE enemy.

Basically, I've noticed that if I have more than two player characters in the party fight any number of enemies, I don't get any error. If I only have one character in the party fight any more than 1 enemy, however, I generate the error. I can have one character vs. one enemy and not generate the error, but if I place any more enemies, I get the error.

Hopefully some of my observations can help? I really appreciate you already trying to help me out. This is sort of a weird bug that kinda' places everything on halt until I get it fixed. Let me know if you need any screenshots. Thanks again!
 
Alright this narrows down things. First of all, setting @pose to one value should do what you described, the battler should only be set to one pose. But, since you don’t get any errors when you set this to a constant value, that means @pose is what’s causing the errors, and apparently @pose only becomes nil when you have one character versus two or more enemies. I did some bug testing and I was actually able to create your error by putting above the line in question this line:

Code:
 @pose = nil

And this gave me the exact same error you got, however the script by itself in its normal state does not give me any errors even in the way you told me it would (1 character vs 2+ enemies). So that means another script is causing this error and is setting your @pose value to nil somehow or it’s simply a compatibility issue. So here’s what you do, cut out one script at a time and paste it in a notepad file, then playtest your game. If the error is still there that means that’s not the script causing the issue, keep doing this until you find the script that when pulled out, the error is gone (when I say error I’m talking about the situation where it’s one actor vs. two or more enemies).

Hope this helps, man :)
 
So I started removing scripts and tinkering around with my game and I've found two more equally weird factors that seem to be playing into this error I keep getting. When I remove the following script:

Code:
#ENEMY HP WINDOW

class Window_EnemyHP < Window_Base

def initialize

super(0, 0, 160, 140)

self.contents = Bitmap.new(width - 32, height - 32)#32

self.contents.font.name = $defaultfontface

self.contents.font.size = $defaultfontsize

self.opacity = 0

refresh

end

#DISPOSE

def dispose

super

end

 

#REFRESH

def refresh

self.contents.clear

for i in 0...$game_troop.enemies.size

enemy = $game_troop.enemies[i]

x = 0

y = i * 35

draw_enemy_name(enemy, x, y)

draw_enemy_hp_meter(enemy, x, y)

end

end

end

and I delete the traces of this script within my "Scene_Battle" scripts, the error seemingly goes away.

However, when I was messing around with enemy stats and now see that if the enemy's agility is greater than my character, the error will occur. If it is not, however, the error won't occur. So now I'm guessing it has something to do with the speed of the enemies vs. the speed of my character's. Interestingly, I was able to fight 3 enemies with one player character so as long as their agility was lower than my player character. A temporary solution I suppose, but it's still bugging me as to what is causing this. Thanks again for the help!
 
Alright two questions to make sure I got this:

1. If you remove that script you posted (the enemy hud script), regardless of what you do (like if you have the enemy agility higher) it still won't cause any errors right? If so, then I think it would be very easy to find your error.

2. Regardless of if a script is removed, if the enemy agility is lower, everything will run properly, right? (If so then it will be harder to find your error lol)

Finally, I think you're gonna have to send me a test game with all your scripts in it, I'm more of a "hands on" guy so I think if I can see all your scripts and how they relate, I'm pretty positive I can find the problem :)

EDIT: Also, I put that enemy hp script in my script editor with the original script and I even made the enemies have 999 agility and still no error. If you're sure that if no other scripts that you cut out didn't stop the error (meaning there was no compatibility issues), then I'm nearly 100% sure this error is caused by those "traces of this script within my "Scene_Battle" scripts".
 
1) So I re-took the enemy HP script out and I actually still get the error if the enemies are faster than any player character so I guess that wasn't the conflicting script.

2) As far as I know, as long as the enemy's agility is lower than any player character, all scripts work and everything runs properly.

In hindsight, I hadn't completely removed all possible scripts, so perhaps another script is truly the issue.

Just to be sure, here's a test game link. Again, I appreciate your help on the matter.

http://dl.dropbox.com/u/43636206/JDSLAS ... 20Game.rar
 
No matter what I do for some reason I keep getting "RGSS Player is not running" even if I copy the scripts out. Could you finish doing the cut-out/test method first to see which script could be causing the error and then I can zone in that script?
 
EDIT: Forget everything I wrote below, actually I found a solution. Just delete RGSS102E.dll and keep RGSS104E.dll in the same folder as the demo. It should work fine after that. It did for me lol.






Oh yeah, that's a weird issue I've been getting ever since I switched to Windows 7. To bypass that "RGSS player has stopped working" error, open up the config file called "Game" (Not the one that opens up the project in RMXP) and it should open up a notepad file. Within the text of that notepad file you'll see that it says:


[Game]
Library=RGSS102E.dll
Scripts=Data\Scripts.rxdata
Title=Samurai Burst
RTP1=Standard
RTP2=
RTP3=


Change the library from RGSS102E.dll to RGSS104E.dll and save. Keep this notepad file open. If you ever save in RMXP, you'll get the RGSS player isn't working error so you'll have to go back to the notepad file and save again. It's a really weird error.
 
Nope I used Batra . . . lemme tinker with the game and do what you did. One sec.

EDIT: I know what it is. I removed all of the attacks that Batra could do. If you go back to the enemy tab and make him do any type of attack. THAT's when the errors begin to occur
 
Alright I tried that out too, I gave Batra any skill or basic attack and still no error. Could you give me the exact skills and...actually is it possible you could just give a screenshot of that enemy page of Batra?
 
Here is the screenshot for the enemy screen for Batra. You're doing just one character vs. more than one Batra right? The error always occur whenever I do Batra x3 vs. just Hayato (or any character) alone so as long as their speed is lower than Batra.

image.png
 
Alright, I did it exactly as so and I'm still not getting any errors...so I'm gonna have to ask a couple questions first because this might actually lead me to the error (sorry I haven't been able to pinpoint it yet :( )

1. The demo you sent me, was that exactly what you have?

2. So if the battle is 1 actor versus 2 or more enemies, there will be an error even if the agility of the enemy is lower?

3. (Opposite of question two) if the agility of the enemy is higher, there will be an error even if the battle is 1 actor versus 1 enemy?
 
1) I made a new game demo (to avoid sending excess graphic and unneeded files) but when I run the game demo I get the very same error. Strange that you're not getting it.

2) No, if I have 1 actor vs. 2 or more enemies but their agility is LOWER than the player character, I get no errors.

3) Even if I do 1 vs. 1, if I set the enemy's agility higher than the player character's it errors. I noticed that the error occurs if the enemy gets the first attack in the battle.

I can send you my exact game file if that would help.
 
Status
Not open for further replies.

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