#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= # ▼ Asagi's Gun License # Author: Kread-EX # Modified by: Trihan # Version 1.08x # Release date: 13/04/2012 # # For Seiryuki. # # Thanks to Angius for finding a bug. #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:= #------------------------------------------------------------------------------------------------- # ▼ UPDATES #------------------------------------------------------------------------------------------------- # # 13/04/2012. Bugfix: Gaining a non-ranged weapon caused the script to crash # # when moving the cursor over the ammo slot in the equipment menu. # # 10/04/2012. Bugfix: unequipping non-weapon items caused a crash. # # 10/04/2012. Modifications: Added slot names on a per-weapon basis. # # 09/04/2012. Modifications: allowed ammo to be assigned on a per-weapon basis # # rather than classes, and allowed skills to use multiple ammo types/IDs. # # Implemented ammo costs for skills. # # Prevented multiple ammo users from equipping the same ammo. # # Equipped ammo is now removed from the equippable items list. # # The item list now shows the correct quantity of ammo if a party member has # # that ammo equipped. # # 09/03/2012. Bugfix: skills without ammo could crash. # # 08/03/2012. Bugfix: ammo stopped consuming because of my previous bugfixes. # # 22/02/2012. Bugfix: some REGEXP didn't work with european characters. # # 20/02/2012. Bugfix: all skills used to consume ammo. #------------------------------------------------------------------------------------------------- # ▼ TERMS OF USAGE #------------------------------------------------------------------------------------------------- # # You are free to adapt this work to suit your needs. # # You can use this work for commercial purposes if you like it. # # Credit is appreciated. # # # # For support: # # grimoirecastle.wordpress.com # # rpgmakervxace.net # # rpgrevolution.com #------------------------------------------------------------------------------------------------- # ▼ INTRODUCTION #------------------------------------------------------------------------------------------------- # # Enables the use of ammunition for skills. #------------------------------------------------------------------------------------------------- # ▼ INSTRUCTIONS #------------------------------------------------------------------------------------------------- # # Three levels of configuration: Class, Weapon and Skill. # # Class notetags: # # <ammo_slot_id: x> # # This determines the slot in the equip screen which will be replaced by the # # ammo slot. # # <ammo_slot_name: string> Just the name of the slot. # # # # Weapon notetags: # # <ammo_type_id: x, y, z> # # Replace x with the weapon types of the kind of ammo you want the # # weapon to use. # # # # Skill notetags # # <linked_ammo_types: x> # # Will require and consume ammo of a specific type. # # <linked_ammo_ids: x> # # Will require and consume unique arrows. In this case, x isn't the weapon # # type but the weapon ID. # # <ammo_cost: x> # # Determines how much ammo is required to use the skill, and will be expended # # on use. #------------------------------------------------------------------------------------------------- # ▼ COMPATIBILITY #------------------------------------------------------------------------------------------------- # # List of aliases and overwrites: # # # # DataManager # # load_database (alias) # # load_ammo_notetags (new method) # # # # RPG::Class # # ammo_slot_id (new attr method) # # ammo_slot_name (new attr method) # # load_ammo_notetags (new method) # # ammo_user? (new method) # # # # RPG::Skill # # ammo_type_id (new attr method) # # ammo_absolute_id (new attr method) # # ammo_cost (new attr method) # # load_ammo_notetags (new method) # # # # RPG::Weapon # # ammo_type_ids (new attr method) # # already_equipped (new attr method) # # load_ammo_notetags (new method) # # ammo_user? (new method) # # # # Game_Actor # # change_equip (alias) # # equip_slots (alias) # # equippable? (alias) # # release_unequippable_items (overload) # # skill_cost_payable? (alias) # # skill_ammo_reqs_ok? (new method) # # pay_skill_cost (alias) # # consume_ammo (new method) # # # # Game_Party # # discard_members_equip (overload) # # # # Window_EquipSlot # # draw_item (alias) # # slot_name (alias) # # # # Window_EquipItem # # include? (alias) # # enable? (alias) #------------------------------------------------------------------------------------------------- $imported = {} if $imported.nil? $imported['KRX-AsagisGunLicense'] = true puts 'Load: Asagi\'s Gun License v1.03 by Kread-EX' module KRX module REGEXP AMMO_SLOT_ID = /<ammo_slot_id:[ ]*(\d+)>/i AMMO_SLOT_NAME = /<ammo_slot_name:[ ]*(.+)>/ AMMO_TYPE_ID = /<ammo_type_id:[ ]*(\d+)>/i AMMO_CONSUMPTION_TYPES = /<linked_ammo_types:[ ]*(.+?)>/i AMMO_CONSUMPTION_IDS = /<linked_ammo_ids:[ ]*(.+?)>/i AMMO_COST = /<ammo_cost:[ ]*(\d+)>/i end end #=========================================================================== # ■ DataManager #=========================================================================== module DataManager #-------------------------------------------------------------------------- # ● Loads the database #-------------------------------------------------------------------------- class << self alias_method(:krx_ammo_dm_load_database, :load_database) end def self.load_database krx_ammo_dm_load_database load_ammo_notetags end #-------------------------------------------------------------------------- # ● Loads the note tags #-------------------------------------------------------------------------- def self.load_ammo_notetags groups = [$data_classes, $data_skills, $data_weapons] for group in groups for obj in group next if obj.nil? obj.load_ammo_notetags end end puts "Read: Ammo Requirements Notetags" end end #=========================================================================== # ■ RPG::Class #=========================================================================== class RPG::Class < RPG::BaseItem #-------------------------------------------------------------------------- # ● Public instance variables #-------------------------------------------------------------------------- attr_reader :weapon_slot_id attr_reader :ammo_slot_id attr_reader :ammo_slot_name #-------------------------------------------------------------------------- # ● Loads the note tags #-------------------------------------------------------------------------- def load_ammo_notetags @note.split(/[\r\n]+/).each do |line| case line when KRX::REGEXP::AMMO_SLOT_ID @ammo_slot_id = $1.to_i if @ammo_slot_id == 0 @weapon_slot_id = 1 else @weapon_slot_id = 0 end when KRX::REGEXP::AMMO_SLOT_NAME @ammo_slot_name = $1 end end end #-------------------------------------------------------------------------- # ● Determine if this class uses ammo #-------------------------------------------------------------------------- def ammo_user? return @ammo_slot_id != nil end end #=========================================================================== # ■ RPG::Skill #=========================================================================== class RPG::Skill < RPG::UsableItem #-------------------------------------------------------------------------- # ● Public instance variables #-------------------------------------------------------------------------- attr_reader :ammo_type_ids attr_reader :ammo_absolute_ids attr_reader :ammo_cost #-------------------------------------------------------------------------- # ● Loads the note tags #-------------------------------------------------------------------------- def load_ammo_notetags @note.split(/[\r\n]+/).each do |line| case line when KRX::REGEXP::AMMO_CONSUMPTION_TYPES @ammo_type_ids = [] @ammo_type_ids |= $1.scan(/\d+/).collect { |id| id.to_i } when KRX::REGEXP::AMMO_CONSUMPTION_IDS @ammo_absolute_ids = [] @ammo_absolute_ids |= $1.scan(/\d+/).collect { |id| id.to_i } when KRX::REGEXP::AMMO_COST @ammo_cost = $1.to_i end end end end class RPG::Weapon < RPG::EquipItem #-------------------------------------------------------------------------- # ● Public instance variables #-------------------------------------------------------------------------- attr_reader :ammo_type_id attr_reader :ammo_slot_name attr_accessor :already_equipped #-------------------------------------------------------------------------- # ● Constructor #-------------------------------------------------------------------------- alias_method(:krx_ammo_rw_init, :initialize) def initialize @already_equipped = false krx_ammo_rw_init end #-------------------------------------------------------------------------- # ● Loads the note tags #-------------------------------------------------------------------------- def load_ammo_notetags @note.split(/[\r\n]+/).each do |line| case line when KRX::REGEXP::AMMO_SLOT_NAME @ammo_slot_name = $1 when KRX::REGEXP::AMMO_TYPE_ID @ammo_type_id = $1.to_i end end end #-------------------------------------------------------------------------- # ● Determine if this weapon uses ammo #-------------------------------------------------------------------------- def ammo_user? return @ammo_type_id != nil end end #=========================================================================== # ■ Game_Actor #=========================================================================== class Game_Actor < Game_Battler #-------------------------------------------------------------------------- # ● Gets the available equipment slots #-------------------------------------------------------------------------- alias_method(:krx_ammo_ga_es, :equip_slots) def equip_slots base = krx_ammo_ga_es return base unless self.class.ammo_user? ammo_slot = self.class.ammo_slot_id result = [] done = false base.each do |x| if x == ammo_slot && !done result.push(0) done = true else result.push(x) end end result end #-------------------------------------------------------------------------- # ● Determines if an item can be equipped #-------------------------------------------------------------------------- alias_method(:krx_ammo_ga_equippable?, :equippable?) def equippable?(item) if self.class.ammo_user? && item.is_a?(RPG::Weapon) weapon_slot = self.class.weapon_slot_id if self.equips[weapon_slot] return true if item.wtype_id == self.equips[weapon_slot].ammo_type_id end end return krx_ammo_ga_equippable?(item) end #-------------------------------------------------------------------------- # ● Performs equipment change #-------------------------------------------------------------------------- alias_method(:krx_ammo_ga_ce, :change_equip) def change_equip(slot_id, item) if item == nil && equips[slot_id] && equips[slot_id].is_a?(RPG::Weapon) equips[slot_id].already_equipped = false elsif self.class.ammo_slot_id == slot_id && item.is_a?(RPG::Weapon) weapon_slot = self.class.weapon_slot_id return unless item.is_a?(RPG::Weapon) && item.wtype_id == self.equips[weapon_slot].ammo_type_id return unless trade_item_with_party(item, equips[slot_id]) if equips[slot_id] != nil && equips[slot_id].is_a?(RPG::Weapon) equips[slot_id].already_equipped = false end item.already_equipped = true @equips[slot_id].object = item return end krx_ammo_ga_ce(slot_id, item) end #-------------------------------------------------------------------------- # * Remove Equipment that Cannot Be Equipped # item_gain: Return removed equipment to party. #-------------------------------------------------------------------------- def release_unequippable_items(item_gain = true) loop do last_equips = equips.dup @equips.each_with_index do |item, i| if !equippable?(item.object) || item.object.etype_id != equip_slots[i] if item.object.is_a?(RPG::Weapon) item.object.already_equipped = false if item.object.already_equipped == true end trade_item_with_party(nil, item.object) if item_gain item.object = nil end end return if equips == last_equips end end #-------------------------------------------------------------------------- # ● Determine if a skill can be used #-------------------------------------------------------------------------- alias_method(:krx_ammo_ga_scp?, :skill_cost_payable?) def skill_cost_payable?(skill) return false unless skill_ammo_reqs_ok?(skill) return krx_ammo_ga_scp?(skill) end #-------------------------------------------------------------------------- # ● Check the ammo requirements for the skill #-------------------------------------------------------------------------- def skill_ammo_reqs_ok?(skill) return true if skill.ammo_type_ids.nil? && skill.ammo_absolute_ids.nil? result = false weapon_id = self.class.weapon_slot_id slot_id = self.class.ammo_slot_id if skill.ammo_type_ids != nil return false unless self.class.ammo_user? item = @equips[slot_id].object return false if item.nil? if skill.ammo_cost return false if $game_party.item_number(item) < skill.ammo_cost - 1 end result = true if skill.ammo_type_ids.include?(item.wtype_id) end if skill.ammo_absolute_ids != nil return false unless self.class.ammo_user? item = @equips[slot_id].object return false if item.nil? if skill.ammo_cost return false if $game_party.item_number(item) < skill.ammo_cost - 1 end result = true if skill.ammo_type_ids.include?(item.id) end result end #-------------------------------------------------------------------------- # ● Pay the required cost for a skill #-------------------------------------------------------------------------- alias_method(:krx_ammo_ga_psc, :pay_skill_cost) def pay_skill_cost(skill) krx_ammo_ga_psc(skill) consume_ammo(skill) if self.class.ammo_user? end #-------------------------------------------------------------------------- # ● Consume the required ammo for a skill #-------------------------------------------------------------------------- def consume_ammo(skill) return if skill.ammo_type_ids.nil? && skill.ammo_absolute_ids.nil? slot_id = self.class.ammo_slot_id item = @equips[slot_id].object if skill.ammo_cost $game_party.lose_item(item, skill.ammo_cost, true) else $game_party.lose_item(item, 1, true) end end end #=========================================================================== # ■ Game_Party #=========================================================================== class Game_Party < Game_Unit #-------------------------------------------------------------------------- # * Discard Members' Equipment #-------------------------------------------------------------------------- def discard_members_equip(item, amount) n = amount members.each do |actor| while n > 0 && actor.equips.include?(item) if item.is_a?(RPG::Weapon) item.already_equipped = false if item.already_equipped == true end actor.discard_equip(item) n -= 1 end end end end #=========================================================================== # ■ Window_ItemList #=========================================================================== class Window_ItemList < Window_Selectable #-------------------------------------------------------------------------- # * Draw Number of Items #-------------------------------------------------------------------------- def draw_item_number(rect, item) quantity = 0 for member in $game_party.all_members if member.class.ammo_user? if member.equips[member.class.ammo_slot_id] if member.equips[member.class.ammo_slot_id].id == item.id quantity += 1 end end end end draw_text(rect, sprintf(":%2d", ($game_party.item_number(item) + quantity)), 2) end end #=========================================================================== # ■ Window_EquipSlot #=========================================================================== class Window_EquipSlot < Window_Selectable #-------------------------------------------------------------------------- # ● Displays the equipped item #-------------------------------------------------------------------------- alias_method(:krx_ammo_wes_di, :draw_item) def draw_item(index) krx_ammo_wes_di(index) rect = item_rect_for_text(index) item = @actor.equips[index] name = slot_name(index) if @actor.class.ammo_user? && name == @actor.class.ammo_slot_name unless item.nil? draw_text(rect, sprintf(":%2d", $game_party.item_number(item) + 1), 2) end end end #-------------------------------------------------------------------------- # ● Determine the name of the slot #-------------------------------------------------------------------------- alias_method(:krx_ammo_wes_sn, :slot_name) def slot_name(index) if @actor && @actor.class.ammo_slot_id == index if @actor.equips[@actor.class.weapon_slot_id] if @actor.equips[@actor.class.weapon_slot_id].ammo_slot_name != nil return @actor.equips[@actor.class.weapon_slot_id].ammo_slot_name else return @actor.class.ammo_slot_name end end end krx_ammo_wes_sn(index) end end #=========================================================================== # ■ Window_Item #=========================================================================== class Window_EquipItem < Window_ItemList #-------------------------------------------------------------------------- # ● Determine if an item goes in the list #-------------------------------------------------------------------------- alias_method(:krx_ammo_wei_include?, :include?) def include?(item) if @actor.class.ammo_user? weapon_slot = @actor.class.weapon_slot_id if @slot_id == @actor.class.ammo_slot_id return true if item.nil? return false unless item.is_a?(RPG::Weapon) && @actor.equips[weapon_slot] return false if item.already_equipped == true if @actor.equips[@slot_id] return false if @actor.equips[@slot_id].id == item.id end return @actor.equips[weapon_slot].ammo_type_id == item.wtype_id else if item.is_a?(RPG::Weapon) && @actor.equips[weapon_slot] return false if @actor.equips[weapon_slot].ammo_type_id == item.wtype_id end end end krx_ammo_wei_include?(item) end #-------------------------------------------------------------------------- # ● Determine if an item can be equipped #-------------------------------------------------------------------------- alias_method(:krx_ammo_wei_enable?, :enable?) def enable?(item) if @actor.class.ammo_user? weapon_slot = @actor.class.weapon_slot_id if @slot_id == @actor.class.ammo_slot_id && @actor.equips[weapon_slot] return true if item.nil? return @actor.equips[weapon_slot].ammo_type_id == item.wtype_id end end krx_ammo_wei_enable?(item) end end