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.

Best way to handle items that are also weapons?

Apologies if this has been done to death - it's hard finding effective search terms since "Item" and "weapon" are used so frequently

Anyway. The situation is that I have a security flashlight as an item in my game. It's one of these police issue ones that are essentially nightsticks with a handy built-in flashlight.

My problem then, is that I want the flashlight to appear on the item menu, and also on the weapons menu.

The first thing that occurs is to create two objects - a weapon and an item - with the same icon and description. I could modify the lose_item method to ensure that dropping or selling one resulted in the other vanishing as well. But I can't escape the feeling that this is  going to be a right pain to debug.

Does anyone know any other ways to approach the problem?

[Edit] I suppose I had better mention that I'm running RMXP

[edit2] :s/always/also/
 

Jason

Awesome Bro

Well what I'd do in a situation like this is a conditional branch

IF [ACTOR] has [WEAPON] equipped:
Add item [ITEM]
Else
Remove item [ITEM]

I haven't tried it out yet, but basicaly what this SHOULD do is:
You only have the weapon, but once you equip it, it will appear in the inventory as an item, and when it's unequipped it will go out of the inventory.

I hope I've helped and if it's what you need.
 
jbrist":2luxwng3 said:
I haven't tried it out yet, but basicaly what this SHOULD do is:
You only have the weapon, but once you equip it, it will appear in the inventory as an item, and when it's unequipped it will go out of the inventory.

mmm...  that works until the player gets a better weapon. Then he equips the taser, and his flashlight vanishes.
 
Sorry, that was more by way of thinking out loud than an actual bug report. What do you think of this:

Code:
class Game_Party
#
#       define a couple of hashes to map weapons onto items
#       and vice versa
#
        @@weapon_item_map = {
                 4      => 38,
                 5      => 39
        }
        @@item_weapon_map = {
                38      => 4,
                39      => 5
        }
#
#       we need a lock varaible to stop recursion loops
#
        @@dcx_lock = false
#
#       and alias the original methods
#

        alias dcx_gain_item gain_item
        alias dcx_gain_weapon gain_weapon
#
#       now we can override the gain_item method
#       lose_item just calls gain_item with negative "n"
#       so this hacks the lose case as well
#
        def gain_item(item_id, n)
#
#               call the original
#
                dcx_gain_item(item_id, n)
#
#               look up the corresponding weapon
#               if it isn't there, we have nothing to do
#
                weapon_id = @@item_weapon_map[item_id] 
                return if weapon_id == nil
#
#               if the lockfile is set, it means this is being
#               called from gain_weapon - so we don't need to call 
#               gain_weapon from here
#
                return if @@dcx_lock
#
#               set the lock, call gain weapon 
#               and then release the lock
#
                @@dcx_lock = true
                gain_weapon(weapon_id, n)
                @@dcx_lock = false
        end

        def gain_weapon(id, n)
#
#               call the original
#
                dcx_gain_weapon(id, n)
#
#               look up the corresponding item
#               if it isn't there, we have nothing to do
#
                item_id = @@item_item_map[id] 
                return if item_id == nil
#
#               check the lock. return if set
#               set if unset
#
                return if @@dcx_lock
                @@dcx_lock = true
#
#               update the items and release the lock
#
                gain_item(item_id, n)
                @@dcx_lock = false
        end

end

add to this a price of zero for the weapon (so it doesn't appear when selling things) and I think this ought to do the job
 

Jason

Awesome Bro

So that means weapon 4 = item 38 ? So an item can have properties of a weapon too ? Alot like a pickaxe or hatchet, it can be used to attack, but mine/cut as well.

Yeah in theory that should work, lol.
 
Whoop, wrong button.

Yeah, that's what I want to do - I'll let you know how it works out. There is one bug in the posted code: item_item_map should be weapon_item_map

[edit]

Ah. I hadn't realised weapons got removed from the lists when equiped. That's what you were getting at with the conditional code. So I need to surpress mapped weapons from display in the inventory list, and lock the item map when equiping or un-equiping a weapon.
 
no problem :) I have the equip problem sorted out - all I need now is to filter the inventory list

[edit]

Try this. It works for me - feel free to use it yourself


Code:
class Game_Party
#
#       define a couple of hashes to map weapons onto items
#       and vice versa
#
        @@weapon_item_map = {
                 4      => 38,
                 5      => 39
        }
        @@item_weapon_map = {
                38      => 4,
                39      => 5
        }
#
#       we need a lock variable to stop recursion loops
#
        @@dcx_lock = false
#
#       We need to get at these from outside the 
#       class - so we can filter inventory lists,
#       for instance
#
        def self.weapon_to_item(id)
                @@weapon_item_map[id]
        end
        def self.item_to_weapon(id)
                @@item_weapon_map[id]
        end
#
#       and the same for the lock
#
        def self.test_dcx_lock
                #print "checking lock (#{@@dcx_lock})"
                @@dcx_lock
        end
        def self.set_dcx_lock(bval)
                #print "setting lock to (#{bval})"
                @@dcx_lock = bval
        end
#
#       and alias the original methods
#

        alias dcx_gain_item gain_item
        alias dcx_gain_weapon gain_weapon
#
#       now we can override the gain_item method
#       lose_item just calls gain_item with negative "n"
#       so this hacks the lose case as well
#
        def gain_item(item_id, n)
                #print "extended gain item (map = #{@@item_weapon_map[item_id]}, lock = #{@@dcx_lock})"
#
#               call the original
#
                dcx_gain_item(item_id, n)
#
#               look up the corresponding weapon
#               if it isn't there, we have nothing to do
#
                weapon_id = @@item_weapon_map[item_id] 
                return if weapon_id == nil
#
#               if the lockfile is set, it means this is being
#               called from gain_weapon - so we don't need to call 
#               gain_weapon from here
#
                return if @@dcx_lock == true
#
#               set the lock, call gain weapon 
#               and then release the lock
#
                @@dcx_lock = true
                gain_weapon(weapon_id, n)
                @@dcx_lock = false
        end

        def gain_weapon(id, n)
                #print "extended gain weapon (id = #{id}, n = #{n}, map = #{@@weapon_item_map[id]}, lock = #{@@dcx_lock})"
#
#               call the original
#
                dcx_gain_weapon(id, n)
#
#               look up the corresponding item
#               if it isn't there, we have nothing to do
#
                item_id = @@weapon_item_map[id] 
                if item_id == nil
                        #print "not updating item: no map for #{id}"
                        return 
                end
#
#               check the lock. return if set
#               set if unset
#
                if @@dcx_lock == true
                        #print "not updating item: lock set to #{@@dcx_lock}"
                        return
                end
                @@dcx_lock = true
#
#               update the items and release the lock
#
                gain_item(item_id, n)
                @@dcx_lock = false
                return true
        end
end

class Game_Actor < Game_Battler
        alias dcx_equip equip
        def equip(equip_type, id)
                Game_Party.set_dcx_lock(true)
                rval = dcx_equip(equip_type, id)
                Game_Party.set_dcx_lock(false)
                return rval
        end
end

class Window_Item < Window_Selectable
        #--------------------------------------------------------------------
        # * Refresh
        #--------------------------------------------------------------------
        def refresh
                if self.contents != nil
                        self.contents.dispose
                        self.contents = nil
                end
                @data = []
                # Add item
                for i in 1...$data_items.size
                        if $game_party.item_number(i) > 0
                                @data.push($data_items[i])
                        end
                end
                # Also add weapons and items if outside of battle
                unless $game_temp.in_battle
                        for i in 1...$data_weapons.size
                                next if Game_Party.weapon_to_item(i) != nil
                                if $game_party.weapon_number(i) > 0
                                        @data.push($data_weapons[i])
                                end
                        end
                        for i in 1...$data_armors.size
                                if $game_party.armor_number(i) > 0
                                        @data.push($data_armors[i])
                                end
                        end
                end
                # If item count is not 0, make a bit map and draw all items
                @item_max = @data.size
                if @item_max > 0
                        self.contents = Bitmap.new(width - 32, row_max * 32)
                        for i in 0...@item_max
                                draw_item(i)
                        end
                end
        end
end
 

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