battle error "String can't be coerced into fixnum" crash. Would this fix it?

Discussion in 'RGSSx Script Support' started by Qeo, May 21, 2019.

  1. Qeo

    Qeo Veteran Veteran

    Messages:
    98
    Likes Received:
    19
    I've been getting random crashes in battle saying "String can't be coerced into fixnum" on line 61 of my Timed Hits script.

    "self.damage = Integer((@timed_hit_hit_percent * self.damage) / 100)"

    There was a .0 after the 100 before someone suggest I remove it when I had this error. This may have fixed the problem, but since saved games don't save script changes and I have to restart my playthrough again, I'd hate to run into it again after a half hour of playtime and being forced to restart again so I'm just making sure that edit would fix the error. Would it?

    Code:
    #==============================================================================
    # ** Game_Battler
    #------------------------------------------------------------------------------
    #  This class deals with battlers. It's used as a superclass for the Game_Actor
    #  and Game_Enemy classes.
    #==============================================================================
    
    class Game_Battler
      #--------------------------------------------------------------------------
      # * Alias Listings
      #--------------------------------------------------------------------------
      alias timed_hit_attack_effect attack_effect
      alias timed_hit_skill_effect skill_effect
      #--------------------------------------------------------------------------
      # * Public Instance Variables
      #--------------------------------------------------------------------------
      attr_accessor :timed_hit_hit_percent
      attr_accessor :timed_hit_use_percent
      attr_accessor :timed_hit_state_to_add
      #--------------------------------------------------------------------------
      # * Applying Normal Attack Effects
      #     attacker : battler
      #--------------------------------------------------------------------------
      def attack_effect(attacker)   
        effective = false
        # If part of Timed Hits
        if @timed_hit_use_percent
          hp = self.hp
          # Perform the original call and get effective
          effective = timed_hit_attack_effect(attacker)
          if self.damage != "Miss"
            self.hp = hp
            self.damage = Integer((@timed_hit_hit_percent * self.damage) / 100.0)
            if @timed_hit_state_to_add != nil
              self.add_state(@timed_hit_state_to_add)
            end
          end
        # If not part of Timed Hits
        else
          # Perform the original call and get effective
          effective = timed_hit_attack_effect(attacker)
        end
        @timed_hit_use_percent  = false
        @timed_hit_state_to_add = nil
        return effective
      end
      #--------------------------------------------------------------------------
      # * Apply Skill Effects
      #     user  : the one using skills (battler)
      #     skill : skill
      #--------------------------------------------------------------------------
      def skill_effect(user, skill)
        effective = false
        # If part of Timed Hits
        if @timed_hit_use_percent
          hp = self.hp
          # Perform the original call and get effective
          effective = timed_hit_skill_effect(user, skill)
          if self.damage != "Miss"
            self.hp = hp
            self.damage = Integer((@timed_hit_hit_percent * self.damage) / 100)
          end
        # If not part of Timed Hits
        else
          # Perform the original call and get effective
          effective = timed_hit_skill_effect(user, skill)
        end
        @timed_hit_use_percent = false
        return effective
      end
    end
    
    
    
    #==============================================================================
    # ** Game_Actor
    #------------------------------------------------------------------------------
    #  This class handles the actor. It's used within the Game_Actors class
    #  ($game_actors) and refers to the Game_Party class ($game_party).
    #==============================================================================
    
    class Game_Actor < Game_Battler
      #--------------------------------------------------------------------------
      # * Public Instance Variables
      #--------------------------------------------------------------------------
      attr_reader   :actor_id
    end
     
    Last edited: May 22, 2019
    #1
  2. Shaz

    Shaz Veteran Veteran

    Messages:
    37,331
    Likes Received:
    11,135
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    If this is a continuation of a problem you posted about in another thread, you really should have just asked the question there. Then we could have seen the discussion that had taken place instead of having to go searching for it.

    Where are you initializing @timed_hit_hit_percent? Where is the rest of the script? My guess is that's been set incorrectly. self.damage could also be a string. Perhaps you should insert a couple of lines before that one, to just
    Code:
    p self.damage
    p @time_hit_hit_percent
    just so you can be sure which part it's objecting to.

    I also don't believe there's any difference between 100 and 100.0 especially since you're doing the conversion to integer. I'd question whether that was the real issue you were having before. Where were you told to change this and what was the error you were having then? I found one other thread of yours and it wasn't mentioned there.

    For future reference, use code tags when pasting a script into your post, rather than quote tags. You'll notice the quote has removed all the formatting/indentation, which makes it harder to read your script. In some cases, it'll also convert certain character strings to emoji, so we won't even be able to see what the script says.
     
    #2
    Qeo likes this.
  3. gstv87

    gstv87 Veteran Veteran

    Messages:
    1,711
    Likes Received:
    725
    First Language:
    Spanish
    Primarily Uses:
    RMVXA
    Code:
    if self.damage != "Miss"
     self.hp = hp
     self.damage = Integer((@timed_hit_hit_percent * self.damage) / 100.0)
    
    Code:
    self.damage = (@timed_hit_hit_percent * self.damage.to_i) / 100.0).to_i
    
    you're validating through not-"Miss", and not-"Miss" can be anything that is not "Miss" including "nil" and "whatever string that is not 'Miss' specifically"
    if "Miss" is "whatever string that is not 'Miss' specifically", then self.damage is String, and you can't multiply variable * string unless you make that string into a number.
    if that string is " ", then that defaults to 0.

    putting Integer(this), doesn't prevent the multiplication from taking place.

    weird variable structure tho.... self.identifier is used for methods.
    if you're working with variables (especially local variables) you should use variables, not methods.

    saved games don't *need* to save script changes.
    saved games save *data* not *raw code*
     
    #3
    Qeo and Shaz like this.
  4. Qeo

    Qeo Veteran Veteran

    Messages:
    98
    Likes Received:
    19
    The issue regarding the enemies having half their health has been resolved. Though now the enemies sometimes have slightly more health than they do in the database, only someone who knows the HP of the enemies would know the difference so it's not a game breaking error like the other one. Sometimes enemies do die on a miss though, but only when they were going to die in one last hit anyway. Still, iffy to kill something with a miss.

    But anyway my real issue is the awful random crashing. I was told to change it on that line of code, 61. The error I was having then is the same one I'm having now, crashing in battle because of that error. That error was discussed in PM's so that's why there was no discussion of it in threads.

    I honestly don't know how to answer that question about where it's initialized so I'll just post the script above and below that one.

    Code:
    class Timed_Hit
      def add_to_actor(actor_id, attack_data_id)
        if @actor_data[actor_id] == nil
          @actor_data[actor_id] = []
        end
       
        @actor_data[actor_id].push(attack_data_id)
      end
     
      def remove_from_actor(actor_id, attack_data_id)
        if @actor_data[actor_id] == nil
          return
        end
       
        @actor_data[actor_id].delete(attack_data_id)
       
        if @actor_data[actor_id].size == 0
          @actor_data[actor_id] = nil
        end
      end
     
      def bar_x
        return @bar_x
      end
     
      def bar_y
        return @bar_y
      end
     
      def key_list
        return @key_list
      end
     
      def hit_sound
        return @hit_sound
      end
     
      def miss_sound
        return @miss_sound
      end
     
      def weapon_states(index)
        return @weapon_states[index]
      end
     
      def actor_attack_data(index)
        return @attack_data[index]
      end
    
      def actor_data(index)
        return @actor_data[index]
      end
     
      def skill_data(index)
        return @skill_data[index]
      end
    end
    
    Code:
    class Scene_Battle
      alias timed_hit_start_phase4 start_phase4
      def start_phase4
        if $game_party.timed_hit == nil
          $game_party.timed_hit= Timed_Hit.new
          $game_party.timed_hit.setup
        end
       
        @timed_hit = $game_party.timed_hit
       
        timed_hit_start_phase4
      end
     
      alias timed_hit_update_phase4_step3 update_phase4_step3
      def update_phase4_step3
        if @active_battler.is_a?(Game_Actor) &&     
           @active_battler.current_action.kind != 2 &&
           @active_battler.current_action.basic != 1
    #Get the active battlers id
          id = @active_battler.actor_id
    #If the bar exists and wait > 0
          if @timed_hit_bar != nil && @timed_hit_wait > 0   
           
    #Update the bar
            @timed_hit_bar.update
           
            key = -1
           
    #Test for a pressed button
            for button in @timed_hit.key_list
              if Input.trigger?(button)
                key = button
                break
              end
            end
           
    #Test for a hit
            if key > 0  
              if @timed_hit_bar.hit?(key)
                @timed_hit_bar.update
                $game_system.se_play(@timed_hit.hit_sound)
              else
                $game_system.se_play(@timed_hit.miss_sound)
              end
            end
           
            @timed_hit_bar.percent = ((@max_wait - @timed_hit_wait) * 100) / @max_wait
           
            @timed_hit_wait -= @timed_hit_wait_increment
           
            return
    #If there is no bar       
          elsif @timed_hit_bar == nil
            if @active_battler.current_action.kind == 0
              if @timed_hit.actor_attack_data(id) != nil && @timed_hit.actor_data(id) != nil
                r_id = rand(@timed_hit.actor_data(id).size)
                data = @timed_hit.actor_attack_data(@timed_hit.actor_data(id)[r_id])
                timed_hit_make_bar(data)
                return
              end
            elsif @active_battler.current_action.kind == 1
              if @timed_hit.skill_data(@active_battler.current_action.skill_id) != nil
                timed_hit_make_bar(@timed_hit.skill_data(@active_battler.current_action.skill_id))
                return
              end
            end
          end
        end
       
        if @active_battler.is_a?(Game_Actor)
          if @timed_hit_bar != nil
            damage_percent = @timed_hit_bar.damage_percent
          end
           
          if @active_battler.current_action.kind == 0 &&
             @active_battler.current_action.basic != 1
           
            for target in @target_battlers
              if @timed_hit_bar != nil
                target.timed_hit_hit_percent = damage_percent + 1
                if @timed_hit.weapon_states(@active_battler.weapon_id) != nil
                  if damage_percent > @timed_hit.weapon_states(@active_battler.weapon_id)[1]
                    target.timed_hit_state_to_add = @timed_hit.weapon_states(@active_battler.weapon_id)[0]
                  end
                end
                target.timed_hit_use_percent = true
                target.attack_effect(@active_battler)
              else
                target.timed_hit_hit_percent = 100
                target.timed_hit_use_percent = true
                target.attack_effect(@active_battler)
              end
            end
          elsif @active_battler.current_action.kind == 1
            for target in @target_battlers
              if @timed_hit_bar != nil
                target.timed_hit_hit_percent = damage_percent + 1
                target.timed_hit_use_percent = true
                target.skill_effect(@active_battler, @skill)
              else
                target.timed_hit_hit_percent = 100             
                target.timed_hit_use_percent = true
                target.skill_effect(@active_battler, @skill)
              end
            end
          end
        end
       
        if @active_battler.is_a?(Game_Actor)
          if @timed_hit_bar != nil
            @timed_hit_bar.dispose
            @timed_hit_bar = nil
          end
        end
       
        timed_hit_update_phase4_step3
      end
     
      def timed_hit_make_bar(data)
        @max_wait = data[0]
        @timed_hit_wait_increment = data[1]
        damage_mod = data[2]
        key = data[3]
        target = data[4]
        marker = data[5]
        bar_mode = data[6]
        @timed_hit_wait = @max_wait
        @timed_hit_bar = Spriteset_timerbar.new(@timed_hit.bar_x, @timed_hit.bar_y, damage_mod, key, target, marker, bar_mode)
        @timed_hit_bar.update
      end
    end
    
    As for the suggestion -

    Code:
    p self.damage
    p @time_hit_hit_percent
    p self.damage"
    p @time_hit_hit_percent
    I put that directly in the lines before this?

    Code:
    self.damage = Integer((@timed_hit_hit_percent * self.damage) / 100)
    When I do this I get these errors in battle "254 nil" "299 nil" and "347 nil" . Don't know what it means.
     
    #4
  5. Qeo

    Qeo Veteran Veteran

    Messages:
    98
    Likes Received:
    19

    Alright thank you I'll put that in see how it goes.

    Do I need to do the edit on the previous part involving self damage also or just this part? And did you want me to delete the "
    if self.damage != "Miss"
    self.hp = hp" lines above your edit? Because I'm getting syntax errors when I do that at line 69, which is just "end" and another end at the bottom.

    Edit: I changed that line without deleting the parts above it and the problem is apparently fixed - thank you! :)
     
    Last edited: May 23, 2019
    #5
  6. Qeo

    Qeo Veteran Veteran

    Messages:
    98
    Likes Received:
    19
    Well the script crash was fixed but now the "enemies having more HP than normal" has come back.

    This timed hit script is an edit of one I was previously using. I was unable to use skills in menu so someone wrote a rewrite so I could use them, yet that's where the enemy HP issues and crashes began. So here's the original script which only has the "Can't use skills in menu" error and none of the others. How would I fix this so that I can use skills but not have those other issues?

    Code:
    class Game_Battler
    attr_accessor :timed_hit_hit_percent
    attr_accessor :timed_hit_use_percent
    attr_accessor :timed_hit_state_to_add
    
    alias timed_hit_attack_effect attack_effect
    def attack_effect(attacker)
    if @timed_hit_use_percent
    hp = self.hp
    
    timed_hit_attack_effect(attacker)
    
    if self.damage.is_a?(Numeric)
    self.hp = hp
    self.damage = Integer((@timed_hit_hit_percent * self.damage) / 100.0)
    self.hp -= Integer(self.damage)
    if @timed_hit_state_to_add != nil
    self.add_state(@timed_hit_state_to_add)
    end
    end
    elsif attacker.is_a?(Game_Enemy)
    timed_hit_attack_effect(attacker)
    end
    
    @timed_hit_use_percent = false
    @timed_hit_state_to_add = nil
    end
    
    alias timed_hit_skill_effect skill_effect
    def skill_effect(user, skill)
    if @timed_hit_use_percent
    hp = self.hp
    
    timed_hit_skill_effect(user, skill)
    
    if self.damage.is_a?(Numeric)
    self.hp = hp
    self.damage = Integer((@timed_hit_hit_percent * self.damage) / 100.0)
    self.hp -= Integer(self.damage)
    end
    elsif user.is_a?(Game_Enemy)
    timed_hit_skill_effect(user, skill)
    end
    
    @timed_hit_use_percent = false
    end
    end
    
    #--------------------------------------------------------------------------
    # Game_Actor
    #--------------------------------------------------------------------------
    class Game_Actor < Game_Battler
    attr_reader :actor_id
    end
     
    #6
  7. Qeo

    Qeo Veteran Veteran

    Messages:
    98
    Likes Received:
    19
    Nevermind.
     
    Last edited: May 28, 2019
    #7

Share This Page