Need a fix for (???nOBodY???'s Weapon Cycler) [VX]

Discussion in 'RGSSx Script Support' started by Revival, Mar 6, 2016.

  1. Revival

    Revival Veteran Veteran

    Messages:
    61
    Likes Received:
    23
    Location:
    Canada
    First Language:
    English
    Hello everybody, this is a script I requseted a friend named ???nOBodY??? make for me a long time ago.  
    I thought the script worked fine until recently when I finally caught on to a bug I'd been having that I didn't understand - now I've isolated the issue.

    The script works by adding +1 to an index every time a weapon is added to your inventory.  This allows the Cycler to know how many weapons the player holds, so it can cycle through them all, so if you have 13 weapons, it will go through 1 at a time over 13 presses of a button.

    The issue seems to be that the script doesn't properly interact with shops, it does not remove -1 from the index when a weapon is sold.  It's an invisible value due to being within the script.  But I'm beyond positive this is what is happening.   If you have 13 weapons, you can sell 3 of those 13 weapons and only have 10 left, but the weapon cycler still registers the index as 13, and therefore it fills up those extra 3 in the index by repeating weapons - meaning sometimes you press the button and it cycles to the same weapon 3 times in a row. 

    I have tested this in a vanilla project with only the weapon cycle and it's HUD script counterpart.  I'm 100% positive this is a bug where the script just does not comprehend how to handle removing items via shops.  It seems to have absolutely no problem adding the index value when buying weapons - the issue comes from selling.  If anybody can help I'm requesting a fix that will allow it to work.  I have created a small demo where you can test the issue and the scripts are in it.  I will also post the script I think is the issue right here in case anybody can fix it without needing the demo.  It is not a compatibility issue with other scripts, nor is it user error - just some sort of index issue - I understand, very basically, how scripts work - but not enough to fix this :/  

    (for those of you wondering this script is mostly for an ABS, not a traditional RPG - it is the equivalent of the feature in Shooter games where pressing a button switches your weapon on the fly - no menu needed.)

    Small Demo of Bug


     

    Weapon Cycler Script (Likely Culprit)

    Spoiler


    Code:
    
    # Weapon Cycle
    # by ???nOBodY???
    # Requested By: Revival
    
    #    *fix 1: fix index when changing equip manually via event or menu
    #    *fix 2: se on cycle
    
    #Set to false if equipping from the menu is disabled
    WEAPON_CYCLE_ADJUST_INDEX_ON_MANUAL_EQUIP = true
    
    #Set mapped key/button
    WEAPON_CYCLE_BUTTON = Input::L
    
    #Switch to disable/enable weapon cycler
    WEAPON_CYCLE_SWITCH = 1 #switch id
    
    #Set to nil to disable
    WEAPON_CYCLE_SE = "Audio/SE/Equip.ogg"
    
    
    class Game_System
      attr_accessor :wpnC_wpns
      attr_accessor :wpnC_index
      
      alias weapon_cycle_initializer initialize
      def initialize
        weapon_cycle_initializer
        @wpnC_wpns = []
        @wpnC_index = 0
      end
    end
    
    #==============================================================================
    # ** Game_Player
    #------------------------------------------------------------------------------
    #  This class handles maps. It includes event starting determinants and map
    # scrolling functions. The instance of this class is referenced by $game_map.
    #==============================================================================
    
    class Game_Player < Game_Character
      def play_weapon_cycle_se
        if WEAPON_CYCLE_SE != nil
          Audio.se_play(WEAPON_CYCLE_SE, 100, 100)
        end
      end
      def weapon_cycle
        #Get actor object
        char = $game_party.members[0]
        #Cycle Wpns update
        for item in $game_party.items
          if item.is_a?(RPG::Weapon)
            next if $game_system.wpnC_wpns.include?(item)
            next if !char.equippable?(item)
            $game_system.wpnC_wpns.push(item) unless $game_system.wpnC_wpns.include?(item)
          end
        end
        #Cycle Index update
        if $game_system.wpnC_index < $game_system.wpnC_wpns.size-1
          $game_system.wpnC_index += 1
        else
          $game_system.wpnC_index = 0
        end
        #Equip Change
        play_weapon_cycle_se
        char.change_equip(0, $game_system.wpnC_wpns[$game_system.wpnC_index]) unless $game_system.wpnC_wpns[$game_system.wpnC_index].nil?
         $scene = Scene_Map.new 
      end
      #--------------------------------------------------------------------------
      # * Processing of Movement via input from the Directional Buttons
      #--------------------------------------------------------------------------
      alias weapon_cycle_move_by_input move_by_input
      def move_by_input
        weapon_cycle_move_by_input
        if Input.trigger?(WEAPON_CYCLE_BUTTON) && $game_switches[WEAPON_CYCLE_SWITCH]
          weapon_cycle
        end
      end
    end
    if WEAPON_CYCLE_ADJUST_INDEX_ON_MANUAL_EQUIP
    #==============================================================================
    # ** Game_Actor
    #------------------------------------------------------------------------------
    #  This class handles actors. It's used within the Game_Actors class
    # ($game_actors) and referenced by the Game_Party class ($game_party).
    #==============================================================================
    
    class Game_Actor < Game_Battler
      #--------------------------------------------------------------------------
      # * Change Equipment (designate object)
      #     equip_type : Equip region (0..4)
      #     item       : Weapon or armor (nil is used to unequip)
      #     test       : Test flag (for battle test or temporary equipment)
      #--------------------------------------------------------------------------
      alias weapon_cycle_change_equip change_equip
      def change_equip(equip_type, item, test = false)
        weapon_cycle_change_equip(equip_type, item, test)
        $game_system.wpnC_index = $game_system.wpnC_wpns.index(item) if $game_system.wpnC_wpns.include?(item)
      end
    end
    end #if WEAPON_CYCLE_ADJUST_INDEX_ON_MANUAL_EQUIP
     
    Last edited by a moderator: Jun 21, 2016
    #1
  2. Shaz

    Shaz Veteran Veteran

    Messages:
    37,714
    Likes Received:
    11,421
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    I've moved this thread to RGSSx Script Support. Please be sure to post your threads in the correct forum next time. Thank you.
     
    #2
  3. Revival

    Revival Veteran Veteran

    Messages:
    61
    Likes Received:
    23
    Location:
    Canada
    First Language:
    English
    My bad, never realized.  It's been long time but I'm still used to rpgmakervx.net's setup... each iteration of Ruby had it's own subforums for had it's own support... I didn't realize this site had them all in one play so when I clicked in RGSS2 and didn't see a Support Subforum I figured requests was right.  I'll make note of it in the future.  
     
    Last edited by a moderator: Mar 15, 2016
    #3
  4. Revival

    Revival Veteran Veteran

    Messages:
    61
    Likes Received:
    23
    Location:
    Canada
    First Language:
    English
    Bump, I would really appreciate any help I can get.
     
    #4
  5. Revival

    Revival Veteran Veteran

    Messages:
    61
    Likes Received:
    23
    Location:
    Canada
    First Language:
    English
    Bump - after looking at the script more I think it has something to do with the "Index +1" and "Index -1" parts of the script.  
     
    #5
  6. Revival

    Revival Veteran Veteran

    Messages:
    61
    Likes Received:
    23
    Location:
    Canada
    First Language:
    English
    Ancient bump... I'm still hoping... 

    If somebody can get this done for me, you are essentially finalizing the scripting of my 3 year project, allowing me to no longer worry about it, and focus primarily on everything else.  I just have a hard time working with bugs like this hanging over my head, and I'm certainly not confident putting my demo out with such an annoying bug to my basic game mechanics. 
     
    Last edited by a moderator: Jun 21, 2016
    #6
  7. Sixth

    Sixth Veteran Veteran

    Messages:
    2,130
    Likes Received:
    798
    First Language:
    Hungarian
    Primarily Uses:
    RMVXA
    The issue happens because that array which stores the weapons of the party never gets cleared.


    So, yeah, if you sell your weapons, for example, it still thinks that those sold weapons are in the inventory.


    Try to do this:


    Replace the entire weapon_cycle method with this one:

    def weapon_cycle
    #Get actor object
    char = $game_party.members[0]
    #Cycle Wpns update
    $game_system.wpnC_wpns = []
    for item in $game_party.items
    if item.is_a?(RPG::Weapon)
    next if $game_system.wpnC_wpns.include?(item)
    next if !char.equippable?(item)
    $game_system.wpnC_wpns.push(item) unless $game_system.wpnC_wpns.include?(item)
    end
    end
    $game_system.wpnC_wpns << char.equips[0] if char.equips[0] && !$game_system.wpnC_wpns.include?(char.equips[0])
    $game_system.wpnC_wpns.sort_by! {|item| item.id }
    $game_system.wpnC_index = $game_system.wpnC_wpns.index(char.equips[0]) if char.equips[0]
    #Cycle Index update
    if $game_system.wpnC_index < $game_system.wpnC_wpns.size-1
    $game_system.wpnC_index += 1
    else
    $game_system.wpnC_index = 0
    end
    #Equip Change
    play_weapon_cycle_se
    char.change_equip(0, $game_system.wpnC_wpns[$game_system.wpnC_index]) unless $game_system.wpnC_wpns[$game_system.wpnC_index].nil?
    $scene = Scene_Map.new
    end



    You can also remove the last part of the script starting with this line:


    if WEAPON_CYCLE_ADJUST_INDEX_ON_MANUAL_EQUIP


    Everything below that line can be deleted (including the mentioned line itself).


    I did not test this, I don't even own VX, but I made a few script based on this exact logic (changing equips with a button), and unless VX uses a different method to get the actor's equipped items (the actor_object.equips(equip_index) method), it should work on VX too.


    And wow, this topic is really ancient. o.o
     
    #7
  8. Revival

    Revival Veteran Veteran

    Messages:
    61
    Likes Received:
    23
    Location:
    Canada
    First Language:
    English
    Hey Sixth, I appreciate the reply, the script encounters a NoMethodError on the line "$game_system.wpnC_wpns.sort_by! {|item| item.id }"

    undefined method "sort_by"

     Thank you again for taking the time to reply.
     
    #8
  9. Sixth

    Sixth Veteran Veteran

    Messages:
    2,130
    Likes Received:
    798
    First Language:
    Hungarian
    Primarily Uses:
    RMVXA
    It seems that the Ruby version in RGSS2 doesn't have that method (sort_by), so it might need a different method for correctly sorting the array. 


    I will try to think of something, maybe there is something that can be done without that method.


    Edit:


    Okay, try to replace that line with the error with this one:


    $game_system.wpnC_wpns.sort! {|i1,i2| i1.id - i2.id }


    This, in theory, should do the same like the sort_by method I used.
     
    Last edited by a moderator: Jun 23, 2016
    #9
    Dymdez likes this.
  10. Revival

    Revival Veteran Veteran

    Messages:
    61
    Likes Received:
    23
    Location:
    Canada
    First Language:
    English
    Wooooo!  You did it!  Thank you so much Sixth, It's working perfectly in all cases, I can remove weapons freely now :)  I'll make sure to add you to the scripting credits of my game! 

    This topic can be closed now, and I don't have to worry about scripting anymore (party time!!!!)
     
    #10

Share This Page