Chciałbym w dowolnym momencie w grze być w stanie zmienić obrażenia wybranej broni bez robienia 100 egzemplarzy w Bazie Danych.
# ==============================================================================
# richter_h's Smithing -- Simply Upgrade Your Weapon
# v1.0 - June 5, 2013
# Type: Actor Customization, Equipments
# Level: Medium
# ==============================================================================
# Ever played Suikoden? That game has some blacksmithes that provide weapon
# upgrades and some enchantments, making your fights would be easier than
# using a simple stick to the brawl.
# And based on that reason, I made this script.
#
# Here in this rather-simple-to-use script, you can add a simple upgrade
# path for every assigned weapon below. Also, you can:
# -> Add parameter in every weapon's level. So you can add some ATKs in
# first levels, then add it more PLUS some SPI. Just for your pleasure.
# -> Change your favorite weapon's name from simple "Longsword" into
# "Longersword", "Cloudcleaver", or "Titan's Toothpick" or even
# "Sword of the Dark Flame Master"? No problem.
# You can set weapon's name in every level as you want.
# -> Changing only the name won't impress you? You can change the icon
# of the weapon as you desire. Just put the certain number and you'll
# have a totally-epic-looking sword's icon once you upgrade them.
# And for you Enu SBS a.k.a. Tankentai user, you'll be rejoiced by this,
# if you know what I mean.
# -> Not only the name, the description of assigned weapon can be changed
# and whatever the "Longsword"'s description when upgraded is at your
# hand.
# -> The blacksmith can has lines to speak! It's highly customizable
# as you want, however, only one kind of quote lines could be added;
# A generic quote would work.
#
# There is another feature that I leave it behind for now. The 'Socket'ing
# feature is in development. In different of your daily 'socket'ing and
# all things 'socket'ery, I planned to just implying the feature brought
# from the first Suikoden series; single-slot socketable in every weapon
# that every Fragment socketed into it could be removed. For now, let's
# don't talk about that 'socket'ery, kay? :D
#
# How to use this script?
# Simply put this below Material and above Main in Script Editor. Don't ask me
# how to put scripts on. Ask other for assistance.
# (implying whoever has a use of this knows how to put scripts in Script Editor)
#
# Credits if you wanna. Don't claim as your own.
# Also credit maximusPrime, since I worked this script based on his.
#
# Oh, don't forget to say a mention to Konami, since they'd made the
# well-made traditional RPG back in 90s. (Not to mention that I only regard
# those first two series, though.)
# ==============================================================================
# New Scene:
# - Scene_Smith
# New Windows:
# - Window_SmithList
# - Window_SmithList_Detail
# Aliased:
# - Scene_Title: load_database
# Altered:
# - RPG::Weapon
# new methods: add_levels, get_next_cost, get_next_weapon, clone_data
# new attributes: level, cost, upgrade_balance, next_weapon_id
# ==============================================================================
# ==============================================================================
# This is just to make sure the script is recognized in system.
# A "scripter"'s stuff.
# ==============================================================================
$imported = {} if $imported == nil
$imported["richter_h's Smithing"] = true
module Smithery
# ============================================================================
# So if you planned to set base price and inflation costs in every upgrades,
# change those numbers below. Their name are self-explanatory.
# ============================================================================
module Pricing
Base_Upgrade_Price = 10
Inflation_Price = 2
end
# ============================================================================
# These variables are for some SEs when the upgrading is in progress.
# A simple cosmetic, based on what the Suikoden's blacksmithes ever do.
# ============================================================================
SMITH_SE = RPG::SE.new("Sword1", 80, 100)
SMITH_DONE_SE = RPG::SE.new("Sword2", 80, 100)
# ============================================================================
# Here's the main course of this script.
# You can see what's happened below. Those lines are what I called the
# 'upgrade tree.'
# You must follow the rules of adding the tree to make sure the script will
# work. Ready to follow the instruction? Here we go.
# ============================================================================
Upgrade_Table = { # Don't touch this, in the name of King Stout.
# ========================================================================
# The rule is simple; just add the weapon ID based on the Weapon tab in
# database, add some lines, add certain numbers, set the name and
# description for certain weapon's level, and you're on.
# Here's the quick guide:
#
# ID => [ { parameters }, icon_index, name, description ],
#
# where:
# ID = ID of the weapon.
# Look at the Database > Weapons and see the number
# that followed by weapon's name.
# { parameters } = What parameter will be up (or down) once you
# upgrade your weapon.
# You can use these symbols to represent the stats:
# ----------------------------------------------------
# | :atk or :str <--- this one for weapon's ATK |
# | :spi or :int <--- this one for weapon's SPI |
# | :agi <--- this one for weapon's AGI |
# | :def <--- this one for weapon's DEF |
# ----------------------------------------------------
# And to assign the growth of assigned stats, follow
# this rule:
# ----------------------------------------------------
# | :atk => 5, :spi => 2 |
# ----------------------------------------------------
# It means when upgraded, it'll has ATK+5 and SPI+2
# up.
# You can add multiple stats, of course.
# icon_index = The icon's index in Graphics/Iconset.png
# It starts from 0, and it's limitless.
# Use -1 if you don't want to change weapon's icon
# once upgraded.
# name = The new name for upgraded weapon. Once it reaches
# that level, the name changes by it.
# description = The new description for upgraded weapon.
# Once it reaches that level, the description
# changes by it.
# (Am I heard an echo?)
# ========================================================================
1 => [ # The Weapon ID #1. Don't forget to add '=>' and '[' as example.
# These line below is for the weapon level 2.
# Let me explain this once again.
[ # It's started from this bracket... Don't touch this!
{:atk => 8, :agi => 2, :spi => 1}, # The parameter growth once
# it's upgraded to this level.
-1, # The icon index of weapon if upgraded to this level.
"Heavy Club", # The name of weapon if upgraded to this level.
"Upgraded version of your daily clubs." # And the description of
# weapon if upgraded to
# this level.
], # It's started from this bracket and coma... Don't touch this!
# And in short, your upgrade tree will be like these below.
# This line below is for the weapon level 3.
[{:atk => 2, :agi => 1, :spi => 4}, -1, "", ""],
# This line below is for the weapon level 4.
[{:atk => 10, :agi => 2, :spi => 0}, 15,
"Flail", "Your everyday clubs won't be as cool as this!"],
# And so on...
], # End of Weapon ID #1's upgrade tree. Don't forget to add '],'
# ========================================================================
# For the joyment of Pilsner Lord, I added some examples of the upgrade
# paths. Feel free to alter or delete as you want.
# ========================================================================
2 => [ # The beginning of upgrade tree
[{:atk => 3 }, -1, "", ""],
[{:atk => 3 }, 2, "Longsword",
"As described on the sword's label..."],
[{:atk => 5 }, 2, "Bastard Sword",
"Not to mention whoever wield this sword is bastard..."],
[{:atk => 3, :agi => 5 }, -1, "", ""],
[{:atk => 10, :agi => 10, :def => 10, :spi => 10 }, 26,
"Sword of Dark Flame Master",
"Once wielded by a boy who claims himself as the sword says."],
], # The ending of upgrade tree
3 => [ # The beginning of upgrade tree
[{:atk => 3 }, -1, "", ""],
[{:atk => 3 }, -1, "", ""],
[{:atk => 3 }, -1, "", ""],
], # The ending of upgrade tree
} # End of Upgrade Table. Don't touch this, in the name of King Stout.
# ============================================================================
# And here, for the joyment of smithing.
# These lines are quotes for some of choice that would be made when accessing
# a blacksmith.
# Figure it out once if you want to change it.
# ========================================================================
module Smith_Quote
Decide_service = "What can I do for you?"
Select_weapon = "Whose weapon will be upgraded?"
Decide_weapon = "Upgrade this weapon?"
Upgrade_complete = "It's done."
Refuse_upgrade = "Not enough money to upgrade."
end
# ==============================================================================
# Touching anything below is not good for our Dark Flame Master himself and
# even for our drunken brawler Vent McGraves.
# For whatever reason, don't change everything below unless you know what
# you're doing below there.
# ==============================================================================
module Weapon_Table
def self.set_class_weaponset(ori, adder)
for data in $data_classes
if(data != nil && data.weapon_set.include?(ori))
data.weapon_set.push(adder)
end
end
end
def self.initialize_weapons
ori_weapon_table = []
$data_weapons.each do |i|
if i.nil?
ori_weapon_table.push(i)
else
ori_weapon_table.push(i.clone_data)
end
end
temp_table2 = {}
for item in Upgrade_Table
next_weapon = nil
temp_table = []
for wep_lv in 0..item[1].size - 1
prop = item[1][wep_lv]
if(next_weapon == nil)
next_weapon = ori_weapon_table[item[0]].clone_data
next_weapon.next_weapon_id = item[1].size
next_weapon.level = 1
end
if prop[0] != {}
prop[0].each do |stat|
case stat[0]
when :atk, :str
next_weapon.atk += stat[1]
when :agi
next_weapon.agi += stat[1]
when :spi, :int
next_weapon.spi += stat[1]
when :def
next_weapon.def += stat[1]
end
end
end
if prop[1] != -1
next_weapon.icon_index = prop[1]
end
if prop[2] != ""
next_weapon.name = prop[2]
end
if prop[3] != ""
next_weapon.description = prop[3]
end
next_weapon.cost = next_weapon.get_next_cost(next_weapon)
next_weapon.next_weapon_id -= 1
next_weapon.level += 1
temp_table.push(next_weapon.clone_data)
end
temp_table2[item[0]] = []
for i in 0..temp_table.size - 1
temp_table2[item[0]].push(temp_table[i])
end
end
preprocess = []
reprocess = []
ori_weapon_table.each do |i|
if i != nil
i.add_levels
end
if temp_table2.has_key?(i.id)
preprocess.push(nil)
reprocess.push(i)
else
preprocess.push(i)
end
end
reprocess.each do |i|
maxUpgrade = temp_table2[i.id].size
currentSize = preprocess.size
oriNextUpgrade = 0
temp_table2[i.id].each do |z|
actualCurrentID = preprocess.size
if(z.next_weapon_id > 0)
z.next_weapon_id = currentSize + (maxUpgrade - z.next_weapon_id)
end
z.id = actualCurrentID
if(oriNextUpgrade == 0)
oriNextUpgrade = z.id
end
preprocess.push(z.clone_data)
set_class_weaponset(i.id, z.id)
end
i.next_weapon_id = oriNextUpgrade
preprocess[i.id] = i.clone_data
end
reprocess.clear
reprocess = nil
$data_weapons = preprocess
preprocess = nil
temp_table2 = nil
temp_table = nil
end
end
end
module RPG
class Weapon < BaseItem
include Smithery::Pricing
attr_accessor :level
attr_accessor :cost
attr_accessor :upgrade_balance
attr_accessor :next_weapon_id
attr_accessor :socket
def add_levels
@level = 1
@cost = Base_Upgrade_Price
@upgrade_balance = Inflation_Price
@next_weapon_id = 0
@socket = []
end
def get_next_cost(weapon)
if(weapon.level == nil)
@level = 2
end
@cost = ((Base_Upgrade_Price+Inflation_Price)*@level)
return @cost
end
def get_next_weapon
return $data_weapons[@next_weapon_id]
end
def upgrade_cost
return Base_Upgrade_Price if @cost.nil?
return @cost + ((Base_Upgrade_Price+Inflation_Price)*@level)
end
def clone_data
originalData = self
if(originalData.is_a?(RPG::Weapon))
clonedData = RPG::Weapon.new
clonedData.id = originalData.id
clonedData.name = originalData.name
clonedData.icon_index = originalData.icon_index
clonedData.description = originalData.description
clonedData.note = originalData.note
clonedData.animation_id = originalData.animation_id
clonedData.price = originalData.price
clonedData.hit = originalData.hit
clonedData.atk = originalData.atk
clonedData.def = originalData.def
clonedData.spi = originalData.spi
clonedData.agi = originalData.agi
clonedData.two_handed = originalData.two_handed
clonedData.fast_attack = originalData.fast_attack
clonedData.dual_attack = originalData.dual_attack
clonedData.critical_bonus = originalData.critical_bonus
clonedData.element_set = originalData.element_set.clone
clonedData.state_set = originalData.state_set.clone
clonedData.level = originalData.level
clonedData.cost = originalData.cost
clonedData.upgrade_balance = originalData.upgrade_balance
clonedData.next_weapon_id = originalData.next_weapon_id
clonedData.socket = originalData.socket
return clonedData
end
return nil
end
end
end
class Scene_Title < Scene_Base
alias load_database_smithery load_database
def load_database
load_database_smithery
Smithery::Weapon_Table.initialize_weapons
end
end
class Window_SmithList < Window_Selectable
def initialize(x,y,w,h)
super(x,y,w,h)
@column_max = 1
self.index = 0
self.back_opacity = 192
refresh
end
def item
return @data[self.index]
end
def include?(item)
return false if item == nil
return true
end
def enable?(item)
if(item.next_weapon_id > 0 &&
$game_party.gold >= item.upgrade_cost)
return true
end
return false
end
def refresh
@data = []
for member in $game_party.members
@data.push(member)
end
@data.push(nil) if include?(nil)
@item_max = @data.size
create_contents
for i in 0...@item_max
draw_item(i)
end
end
def draw_item(index)
rect = item_rect(index)
self.contents.clear_rect(rect)
item = @data[index]
if item != nil
enabled = enable?(item.equips[0])
rect.width -= 4
self.contents.font.color.alpha = enabled ? 255 : 128
self.contents.draw_text(rect, item.name)
end
end
end
class Window_SmithList_Detail < Window_Base
def initialize(x,y,w,h,member)
super(x,y,w,h)
refresh(member)
end
def refresh(actor)
create_contents
weapon = actor.equips[0]
self.contents.font.color = normal_color
self.contents.font.size = 22
dY = 0
dWidth = self.width - 20
pad = 40
draw_item_name(weapon, 0, 0, true)
dY += 30
self.contents.font.size = 18
self.contents.font.bold = false
self.contents.fill_rect(0, dY, dWidth, 2, normal_color)
if(weapon.next_weapon_id > 0)
dY += 4
self.contents.draw_text(0, dY, dWidth-16, self.contents.font.size,
"Cost: " + weapon.upgrade_cost.to_s, 0)
self.contents.font.color = crisis_color
self.contents.draw_text(0, dY, dWidth-16, self.contents.font.size,
"Upgradeable", 2)
self.contents.font.bold = true
self.contents.draw_text(0, dY + self.contents.font.size + 4, dWidth-16, self.contents.font.size,
"Lv." + weapon.level.to_s, 2)
self.contents.font.bold = false
self.contents.font.color = normal_color
if weapon.get_next_weapon.atk - weapon.atk > 0 and (weapon.next_weapon_id > 0)
dY += self.contents.font.size + 4
self.contents.font.size = 20
self.contents.font.color = system_color
self.contents.draw_text(0, dY, pad, self.contents.font.size,
Vocab.atk)
self.contents.font.color = normal_color
self.contents.draw_text(pad, dY, dWidth - pad, self.contents.font.size,
": " + weapon.atk.to_s + " > " + weapon.get_next_weapon.atk.to_s)
end
if weapon.get_next_weapon.agi - weapon.agi > 0 and (weapon.next_weapon_id > 0)
dY += self.contents.font.size + 4
self.contents.font.size = 20
self.contents.font.color = system_color
self.contents.draw_text(0, dY, pad, self.contents.font.size,
Vocab.agi)
self.contents.font.color = normal_color
self.contents.draw_text(pad, dY, dWidth - pad, self.contents.font.size,
": " + weapon.agi.to_s + " > " + weapon.get_next_weapon.agi.to_s)
end
if weapon.get_next_weapon.spi - weapon.spi > 0 and (weapon.next_weapon_id > 0)
dY += self.contents.font.size + 4
self.contents.font.size = 20
self.contents.font.color = system_color
self.contents.draw_text(0, dY, pad, self.contents.font.size,
Vocab.spi)
self.contents.font.color = normal_color
self.contents.draw_text(pad, dY, dWidth - pad, self.contents.font.size,
": " + weapon.spi.to_s + " > " + weapon.get_next_weapon.spi.to_s)
end
if weapon.get_next_weapon.def - weapon.def > 0 and (weapon.next_weapon_id > 0)
dY += self.contents.font.size + 4
self.contents.font.size = 20
self.contents.font.color = system_color
self.contents.draw_text(0, dY, pad, self.contents.font.size,
Vocab.def)
self.contents.font.color = normal_color
self.contents.draw_text(pad, dY, dWidth - pad, self.contents.font.size,
": " + weapon.def.to_s + " > " + weapon.get_next_weapon.def.to_s)
end
else
dY += 4
self.contents.font.color = crisis_color
self.contents.font.bold = true
self.contents.draw_text(0, dY, dWidth-16, self.contents.font.size,
"Lv." + weapon.level.to_s, 2)
self.contents.font.color = normal_color
self.contents.font.bold = false
self.contents.draw_text(0, dY, dWidth-16, self.contents.font.size,
"Maxed Out", 0)
end
end
end
class Window_Notification < Window_Base
def initialize
super(0, 0, 400, WLH*2 + 32)
self.back_opacity = 255
end
def set_text(text, weapon=nil, align = 0)
text2 = ""
if weapon != nil
weapon2 = weapon.get_next_weapon
text = "The weapon turned into " + weapon2.name if weapon.name != weapon2.name
text2 += Vocab.atk + " +" + (weapon2.atk - weapon.atk).to_s + " " if weapon2.atk > weapon.atk
text2 += Vocab.spi + " +" + (weapon2.spi - weapon.spi).to_s + " " if weapon2.spi > weapon.spi
text2 += Vocab.agi + " +" + (weapon2.agi - weapon.agi).to_s + " " if weapon2.agi > weapon.agi
text2 += Vocab.def + " +" + (weapon2.def - weapon.def).to_s + " " if weapon2.def > weapon.def
end
if text != @text or align != @align
self.contents.clear
self.contents.font.color = normal_color
self.contents.draw_text(4, 0, self.width - 40, WLH, text, align)
if text2 != ""
self.contents.font.color = text_color(4)
self.contents.draw_text(4, WLH, self.width - 40, WLH, text2, align)
end
@text = text
@align = align
end
end
end
class Scene_Smith < Scene_Base
#--------------------------------------------------------------------------
# * Start processing
#--------------------------------------------------------------------------
def start
super
create_menu_background
@viewport = Viewport.new(0, 0, 544, 416)
@gold_window = Window_Gold.new(384, 56)
@help_window = Window_Help.new
@help_window.viewport = @viewport
create_notification_window
create_party_list_window
create_detail_window
create_choice_box
create_confirmation_box
@choice_box.active = true
arrange_windows
smith_quote_list("Decide service")
end
def create_notification_window
@notification_window = Window_Notification.new
@notification_window.x = Graphics.width/2 - @notification_window.width/2
@notification_window.y = Graphics.height/2 - @notification_window.height/2
@notification_window.visible = false
@notification_window.z = 200
end
def create_choice_box
#~ s1 = "Sharpen"
#~ s2 = "Fragment Socket"
#~ s3 = "Exit"
#~ @choice_box = Window_Command.new(160, [s1, s2, s3])
menu = []
menu.push("Sharpen")
menu.push("Socket")
menu.push("Exit")
@choice_box = Window_Command.new(384, menu, menu.length, 1)
@choice_box.index = 0
@choice_box.viewport = @viewport
end
def create_party_list_window
@list_window = Window_SmithList.new(0, 56, 128,
($game_party.members.size*24)+32)
@list_window.viewport = @viewport
@list_window.visible = false
end
def create_detail_window
@smith_detail_window = Window_SmithList_Detail.new(0,0,256,180,
$game_party.members[@list_window.index])
@smith_detail_window.viewport = @viewport
@smith_detail_window.visible = false
end
def create_confirmation_box
s1 = "Yes"
s2 = "No"
@confirmation_box = Window_Command.new(80, [s1, s2])
@confirmation_box.visible = false
end
def arrange_windows
@choice_box.y = @help_window.height
@list_window.y = @choice_box.y + @choice_box.height
@smith_detail_window.x = @list_window.width
@smith_detail_window.y = @gold_window.y + @gold_window.height
@confirmation_box.x = @smith_detail_window.x + @smith_detail_window.width - @confirmation_box.width
@confirmation_box.y = @smith_detail_window.y + @smith_detail_window.height - @confirmation_box.height
end
def terminate
super
dispose_menu_background
@viewport.dispose
@gold_window.dispose
@help_window.dispose
@list_window.dispose
@smith_detail_window.dispose
@choice_box.dispose
@confirmation_box.dispose
end
def refresh
@choice_box.refresh
@list_window.refresh
if(@current_item != nil)
@smith_detail_window.refresh(@current_item)
end
end
def return_scene
$scene = Scene_Map.new
end
def update
super
update_menu_background
@gold_window.update
@help_window.update
if @choice_box.active
update_choice_box
elsif @list_window.active
update_smithing_window
elsif @confirmation_box.active
@confirmation_box.update
update_confirmation_box
end
end
def update_choice_box
@choice_box.update
if Input.trigger?(Input::C)
case @choice_box.index
when 0
Sound.play_decision
smith_quote_list("Choose weapon")
select_party
when 1
Sound.play_buzzer
@notification_window.visible = true
@notification_window.set_text("Socketing isn't available for now.")
smith_quote_list("Socketing weapon")
for i in 0...150
Graphics.update
end
@notification_window.visible = false
smith_quote_list("Decide service")
when 2
Sound.play_cancel
return_scene
end
elsif Input.trigger?(Input::B)
Sound.play_cancel
return_scene
end
end
def update_confirmation_box
if Input.trigger?(Input::C)
case @confirmation_box.index
when 0
Sound.play_decision
itema = @list_window.item
weapon = itema.equips[0]
wait_for_smithing(weapon)
$game_party.lose_gold(weapon.upgrade_cost)
$game_party.gain_item(weapon.get_next_weapon.clone_data, 1)
$game_party.members[@list_window.index].change_equip(0, weapon.get_next_weapon.clone_data)
$game_party.lose_item(weapon, 1)
@gold_window.refresh
confirm
when 1
Sound.play_cancel
confirm
smith_quote_list("Choose weapon")
end
elsif Input.trigger?(Input::B)
Sound.play_cancel
confirm
smith_quote_list("Choose weapon")
end
end
def update_smithing_window
@list_window.update
@smith_detail_window.update
item = @list_window.item
weapon = item.equips[0]
if(@current_item != item)
@current_item = item
@smith_detail_window.refresh(@current_item)
end
if Input.trigger?(Input::B)
Sound.play_cancel
hide_party
smith_quote_list("Decide service")
elsif Input.trigger?(Input::C)
if(weapon != nil &&
weapon.next_weapon_id > 0 && weapon.get_next_weapon != nil &&
$game_party.gold >= weapon.upgrade_cost)
Sound.play_decision
smith_quote_list("Decide weapon")
confirmation
end
end
end
def wait_for_smithing(weapon)
for i in 0...300
Graphics.update
Smithery::SMITH_SE.play if i%60 == 0 and i < 150
if i == 180
Smithery::SMITH_DONE_SE.play
@notification_window.visible = true
@notification_window.set_text("Weapon improved.", weapon)
smith_quote_list("Upgrade complete")
end
end
@notification_window.visible = false
smith_quote_list("Choose weapon")
end
def confirmation
@confirmation_box.active = true
@confirmation_box.visible = true
@list_window.active = false
end
def confirm
@confirmation_box.active = false
@confirmation_box.visible = false
@list_window.active = true
refresh
end
def select_party
refresh
@choice_box.active = false
@list_window.active = true
@list_window.visible = true
@smith_detail_window.active = true
@smith_detail_window.visible = true
end
def hide_party
@choice_box.active = true
@list_window.active = false
@list_window.visible = false
@smith_detail_window.active = false
@smith_detail_window.visible = false
refresh
end
def smith_quote_list(response = "")
case response
when "Decide service"
@help_window.set_text(Smithery::Smith_Quote::Decide_service)
when "Choose weapon"
@help_window.set_text(Smithery::Smith_Quote::Select_weapon)
when "Decide weapon"
@help_window.set_text(Smithery::Smith_Quote::Decide_weapon)
when "Upgrade complete"
@help_window.set_text(Smithery::Smith_Quote::Upgrade_complete)
when "Not enough money"
@help_window.set_text(Smithery::Smith_Quote::Refuse_upgrade)
when "Socketing weapon"
@help_window.set_text("Maybe not now, mate.")
end
end
end
Tylko że wolałbym pominąć te wszystkie okienka i wybór broni i po prostu zwiększyć obrażenia w wybranym momencie.
Da się to może jakoś wywołać podczas gry? Albo czy jest jakiś lepszy skrypt/rozwiązanie?