Asagi's Gun License
Version: 1.07x
Author: Kread-EX, modified by Trihan
Date: April 11, 2012
Update History
- 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, removed equipped ammo from the list of equippable items, and edited the item list so it shows the correct quantity of ammo if a party member has that ammo equipped.
Description
Kread-EX's original Asagi's Gun Licence script allows you to specify ammunition options for classes and skills.
At the request of Eternallight on IRC (and already requested, as I found later, by SirCumferance on Kread's Wordpress) I've modified the script so that you can set ammo types for individual weapons rather than the class. I've also modified skill assignment so that a skill can be used with more than one ammo type (say you wanted a skill that could be used with either arrows or bullets equipped)
I've also fixed some bugs; most of my own making and a couple from the original. One thing with the original script is that if you have multiple party members whose class can equip ammo type X, they'll both be able to equip it and both will draw from the same pool of items. I've fixed this by preventing ammo from being equipped if someone else is already equipping it.
I've also made a small fix to the items list where normally it would show less ammo than you actually have (because obviously one or more of the weapons is equipped). It now shows the full amount regardless of whether it's equipped on anyone.
And finally, I modified the skill notetags so you can assign an ammo cost in case you want the skill to use up more than a single arrow/bullet/dwarf.
Features
- You can make a class an "ammo user" by setting some notetags that determine which equipment slot will take ammo and what the slot will be called.
- Weapons can be assigned with an ammo type they can equip. Ammo can only be equipped if the actor has a weapon that can take it.
- Skills can be given ammo requirements and costs using notetags. The skill will only be useable if ammo of that type is equipped and you possess the correct amount of it.
- As ammo is treated like equipment, ordinarily the same ammo item would be equippable by multiple actors. I've edited it to disallow this.
- When viewing your item list in the menu ammo count will be correctly shown even if a party member is equipping it.
- Weapons can be assigned with their own ammo slot name, which will take priority over the class setting.
ScreenshotsWithout the proper weapon equipped, you can't equip ammo.
Equip the proper weapon and as if by magic ammo appears!
Once equipped, ammo no longer shows up in the list (like it usually would for weapons you have more than 1 of)
Now that it's equipped, the ammo can't be used by anyone else.
And if we look at our items menu, it'll display the correct amount even though it's equipped by someone.
Instructions
Paste this script into its own slot in the Script Editor, above Main and below Materials.
Configuration is pretty much done through notetags; the syntax and instructions are included in the script comments.
If you have any questions, please feel free to post them here.
Script
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# ? Asagi's Gun License
# Author: Kread-EX
# Modified by: Trihan
# Version 1.07x
# Release date: 10/04/2012
#
# For Seiryuki.
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#-------------------------------------------------------------------------------------------------
# ? 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
else
return @actor.class.ammo_slot_name
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
Credit
- Kread-EX
- Trihan
- Angius (bug report)
Modifier's Notes
This modification was created to fulfil a specific need, but I tried to make it as flexible as possible to uses other people might have for it. If there's anything else you want to see the script do, let me know and I'll see if I can accommodate the request.