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.

[XP]In-game Weapon Creator - ver 2.0

Haki

Member

In-game Weapon Creator ver. 2.0
by Haki

Introduction:
This script allows to create weapons inside the game. Weapon parts must be given inside the script.


Script:

Please follow the instructions inside the script. If there's anything you don't get please download the demo.

Code:
#=================================================================================
#In-game Weapon Creator ver 2.0 by Haki
#=================================================================================
#
# Version 2.0 updates:
# -each part can now be used only once
# -added gold display
# -fixed the problem when using two same parts
#
# How to use:
# -Inside the game, call "$scene = Scene_Weapon_Select.new" to open
#  the weapon creator window.
# -All weapon parts must be edited and created inside this script inside
#  the "Weapons" module. Instructions on how to do that are in the module.
# -To enable parts call "Weapons::AVAILABLE_PARTS.push(part_id)".
#  To disable them call "Weapons::AVAILABLE_PARTS.delete(part_id)"
#
# Compatibility:
# -The script hasn't been tested with other scripts but it should be
#  compatible.
#
# Bug report:
# -If you find any bugs, e-mail me at ivica.hakstok@du.t-com.hr
#
#=================================================================================




module Weapons
  
  WEAPON_TYPE = {1 => "Sword", 2 => "Spear"} #types used when creating a new weapon
  CLASS_WEAPON = {1 => 1, 2 =>2} #set which class can hold which type of weapon - class_id => type 
  WEAPON_PARTS = {1 => [1,"Simple Handle",30,0,100], 2 =>[1,"Simple Blade",120,0,100], 3 => [2,"Simple Stick",20,1,100], 4 =>[2,"Simple Spike",100,3,100], 5 =>[2,"Mega Attack Booster!!!",200,12,200]} #part => [type, name, atk, dex_plus,cost]
  AVAILABLE_PARTS = [1,2,5] #parts of WEAPON_PARTS that are available. Add new ones using event's "Script..." command "Weapons::AVAILABLE_PARTS.push(part_id)"
  NEW_WEAPON = {[1,2] => ["Simple Sword","A simple sword.",7], [3,4] => ["Simple Spear","A simple spear.",8], [3,4,5] => ["Super Duper Spear","A super duper spear!!!",8]} #weapon_parts => new weapon name, weapon description, animation_id
  DEFAULT_ICON = {1=>"001-Weapon01",2=>"002-Weapon02"} #type => id of the icon which represents the type
  

end

class Window_Command < Window_Selectable
  attr_accessor :commands
end

class Game_Party
  attr_accessor :gold
end

class Scene_Weapon_Select
  attr_accessor :type
  def main
    @spriteset = Spriteset_Map.new
    @weapon_type_window = Window_Command.new(160, Weapons::WEAPON_TYPE.values)
    @weapon_type_window.index = 0
    @weapon_type_window.x = 320 - @weapon_type_window.width / 2
    @weapon_type_window.y = 240 - @weapon_type_window.height / 2
    @weapon_type_window.opacity = 155
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    @weapon_type_window.dispose
    @spriteset.dispose
  end
  
  def update
    @weapon_type_window.update
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      Graphics.update
      $scene = Scene_Map.new
      return
    end
    if Input.trigger?(Input::C)
      self.type = @weapon_type_window.index + 1
      $game_system.se_play($data_system.decision_se)
      $scene = Scene_Weapon_Main.new(self.type)
    end
  end
end

class Scene_Weapon_Main
  attr_accessor :type
  
  def initialize(type)
    self.type = type
  end
  
  
  def main
    @spriteset = Spriteset_Map.new
    @parts = []
    @parts_selected = []
    @leftover_parts = []
    @leftover_check = []
    @cost = 0
    @str = 0
    @dex = 0
    clean(Weapons::AVAILABLE_PARTS)
    for i in Weapons::AVAILABLE_PARTS
      if Weapons::WEAPON_PARTS[i] != nil
        case Weapons::WEAPON_PARTS[i][0]
          when type
          @parts.push(Weapons::WEAPON_PARTS[i][1] + "     " + Weapons::WEAPON_PARTS[i][4].to_s)
        end
      end
    end
    @parts.push("Done")
    @weapon_part1_window = Window_Command.new(480, @parts)
    @weapon_part1_window.index = 0
    @weapon_part1_window.x = 0
    @weapon_part1_window.y = 240 - @weapon_part1_window.height / 2
    @result_window = Window_Base.new(0,416,640,64)
    @result_window.contents = Bitmap.new(608,32)
    @info_window = Window_Base.new(0,0,640,64)
    @info_window.contents = Bitmap.new(608,32)
    @info_window.opacity = 155
    @weapon_part1_window.opacity = 155
    @result_window.opacity = 155
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    @weapon_part1_window.dispose
    @result_window.dispose
    @spriteset.dispose
    @info_window.dispose
  end
  
  def clean(array) #this method will remove double parts
    a = []
    for i in 0...array.size
      for j in i+1...array.size
        if array[i] == array[j]
          a.push(array[i])
        end
      end
    end
    for i in a
      array.delete(i)
      array.push(i)
    end
  end
  
  def update
    @weapon_part1_window.update
    @result_window.update
    @info_window.update
    @info_window.contents.clear
    @info_window.contents.draw_text(0,0,368,32,"Select the parts you want to use.")
    @info_window.contents.draw_text(400,0,208,32,"You have " + $game_party.gold.to_s + " " + $data_system.words.gold)
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      Graphics.update
      $scene = Scene_Map.new
      return
    end
    if Input.trigger?(Input::C)
      i = @parts[@weapon_part1_window.index]
      for j in Weapons::WEAPON_PARTS.keys
        if i.sub(/\s+\S+\Z/){""} == Weapons::WEAPON_PARTS[j][1]
          id = j
        end
      end
      if @weapon_part1_window.index == @weapon_part1_window.commands.size - 1
        $scene = Scene_Map.new if @parts_selected == []
        for i in @parts_selected
          @cost += Weapons::WEAPON_PARTS[i][4].to_i
        end
        if @cost <= $game_party.gold
          for i in 0...Weapons::NEW_WEAPON.keys.size
            @leftover_parts = @parts_selected - Weapons::NEW_WEAPON.keys[i]
            @leftover_check = Weapons::NEW_WEAPON.keys[i] - @parts_selected
            if @leftover_parts == @leftover_check and @leftover_check == [] and @leftover_parts == []
              @result_window.contents.clear
              @result_window.contents.draw_text(0,0,608,32,"Created " + Weapons::NEW_WEAPON[Weapons::NEW_WEAPON.keys[i]][0])
              @result_window.update
              $game_party.gold -= @cost
              for part in Weapons::NEW_WEAPON.keys[i]
                @str += Weapons::WEAPON_PARTS[part][2]
                @dex += Weapons::WEAPON_PARTS[part][3]
              end
              weapon = RPG::Weapon.new
              weapon.name = Weapons::NEW_WEAPON[Weapons::NEW_WEAPON.keys[i]][0]
              weapon.icon_name = Weapons::DEFAULT_ICON[type]
              weapon.atk = @str
              weapon.dex_plus = @dex
              weapon.animation2_id = Weapons::NEW_WEAPON[Weapons::NEW_WEAPON.keys[i]][2]
              weapon.description = Weapons::NEW_WEAPON[Weapons::NEW_WEAPON.keys[i]][1]
              for j in 1...$data_weapons.size
                if $data_weapons[j].name == weapon.name
                  $game_system.se_play($data_system.equip_se) 
                  $game_party.gain_weapon($data_weapons[j].id,1)
                  return
                end
                if $data_weapons[j].name == ""
                  $game_system.se_play($data_system.equip_se) 
                  weapon.id = $data_weapons[j].id
                  $data_weapons[j] = weapon
                  $data_classes[type].weapon_set.push(weapon.id)
                  $game_party.gain_weapon(weapon.id,1)
                  break
                end
              end
              for x in @parts_selected
                Weapons::AVAILABLE_PARTS.delete(x)
              end
              @parts_selected = []
              Graphics.freeze
              $scene = Scene_Weapon_Select.new                 
              Graphics.transition(40)
            else
              @result_window.contents.clear
              @result_window.contents.draw_text(0,0,608,32,"Nothing created")
              @result_window.update
            end
          end
        else
          @result_window.contents.clear
          @result_window.contents.draw_text(0,0,608,32,"Not enough money to do this.")
          @result_window.update
          $game_system.se_play($data_system.buzzer_se)        
        end
      elsif @parts_selected.include?(id) == true
        $game_system.se_play($data_system.cancel_se)
        @weapon_part1_window.draw_item(@weapon_part1_window.index,Color.new(255,255,255,255))
        @parts_selected.delete(id)
      elsif @parts_selected.include?(id) == false
        $game_system.se_play($data_system.decision_se)
        @weapon_part1_window.draw_item(@weapon_part1_window.index,Color.new(255,255,255,127))
        @parts_selected.push(id)
      end
    end
  end
end

Download:
http://www.megaupload.com/?d=HJL6LR46


Other Notes:
If you use this script credit me (Haki). The script hasn't been tested with any other scripts so if you find any compatibility issues post them in this topic or e-mail me at ivica.hakstok@du.t-com.hr
 

OS

Sponsor

It's pretty cool. I only had four problems with it:

1. I didn't like the emptiness, so I added a @spriteset object to show the Map in the background.

2. I didn't like exiting the menu when pressing B. I think it should have stepped to the Swords/Spear menu instead.

3. I didn't like the fact that a Message Window opened when I made an item. It allowed me to see that if you keep pressing Done the values just add up, though. It's more for debugging. I don't know if you missed it, or if it was intentional, but it cuts away from the player's game play experience.

Those were just my opinions. The real problem is that, regardless of the code creating and storing the weapon in the data_weapons object, it doesn't appear in my inventory. I can't figure out why.

Other than that, great work. It could use some comments, but it is easy to tell for the most part what you are doing. The menus all display correctly. Keep up the good work.

EDIT:

OMG. Sorry. I fixed my little problem where the weapon wouldn't drop in my inventory. It turns out that you have to have empty Weapons in your database. Did not know that. :|

So, it's mostly just the aesthetics of the script I don't like. Usability is 100% perfect so far.

EDIT2:

Okay, one real error: if you create the same weapon twice, you get two different weapons that are identical. To prevent this, replace line 159 with:

Code:
if $data_weapons[j].name == weapon.name
   $game_party.gain_weapon($data_weapons[j].id,1)
elsif $data_weapons[j].name == ""
 

Haki

Member

@OS: Those message windows were just used for testing. I forgot to delete them after completing the script. I uploaded a version without them. I wasn't aware of the problem if you create the same weapon twice. This will be fixed.

EDIT: I fixed everything and made some features even better. New demo is available for download.
 
Is this like Dark Chronicles or more like Final Fantasy VIII? Both had a weapon maker, though DC needed you to level the weaposn up, whereas FFVIII needed you to have specific rare items to upgrade your current weapons.
 

Haki

Member

@New2Ya: The weapon maker is not like in any of those games. In this maker you have parts, which are unique for any weapon type. You can make it so that different parts are available at different stores, or that a certain part is available after defeating a boss or a regular enemy. The parts themselves need not to be created inside the database but in the script. Each part has it's cost. If you have enough money and if parts you selected inside the maker create a specific weapon, you will gain that weapon. The weapon is also created entirely inside the script by using specifications for each part. If you still don't understand how it works, download the demo and find out.
 
i found a error. when i go to spears and select them all, a error message comes up.
it is an error message as in there is a error in script blah blah blah line whatever it is.

sorry for my little discriptive piece there, I went and deleted the game folder.

i was going to keep it, but when i test demos, when im done i delete them
 
This looks good, but there's a problem... In the Spear menu, if you select more than 2 things (one spike, one stick), the game crashes. It's because when you talk to the girl who adds them, if you talk more than once, she'll add them multiple times... So...

Oh, and rocknroll93, I have the same system. I delete all demos when I'm done with them unless they're really good so that I want to keep it. :wink:
 
You can make it so that the event checks if those parts are already available.

Code:
@>Script: x =Weapons::AVAILABLE_PARTS
          if !x.include?(3)
          Weapons::AVAILABLE_PARTS.push(3)
          end
          if !x.include?(4)
          Weapons::AVAILABLE_PARTS.push(4)
          end
 
I could make an inlimited (99) amount of swords with only two items? Also the lay-out needs some work (show you're current amount of gold for example). But the idea behind it is very good :)
 
pretty good but a few little things that have a problem. kinda like what  gRaViJa said; you can click done infinite times when you only select the two weapon parts. kinda cheapo.
 
I tried adding a new part called the Long blade then created a new weapon to be created called the SImple longsword, I edited everything of those like the ID of the part, so it should word. 1,5 create that, but it won't say: Simple Longsword Created and won't add the sword to my inventory. WHAT THE HECK!
 
@haki: I love this script and am almost definitely going to use it in the small, personal project I'm currently working on. The only complaint that I really have is that you can use the the weapon parts an unlimited number of times, which seems to be a popular issue. I think you should only be able to use the each part once. For example, if you use the Simple  Handle and Simple Blade you were originally given, you should have to acquire new instances of those items in order to make another Simple Sword. Personally, I think it makes the weapon creator system a bit more realistic.

edit: Funny thing. I noticed that the weapon creator script does not actually deduct gold from your party. The weapon creator system will tell you you've run out of gold, but if you immediately exit and check the menu, you will see that you still have the same amount of gold you started with. If you open the system back up, you will be able to use the same gold you just used again, and again, and again.

Update: I solved the problem by moving $game_party.gold -= @cost into this if statement in the def update method of the Scene_Weapon_Main class.

Code:
if Input.trigger?(Input::C)
      id = @weapon_part1_window.index + 1 + (type-1) * 2
      if @weapon_part1_window.index == @weapon_part1_window.commands.size - 1
        for i in @parts_selected
          @cost += Weapons::WEAPON_PARTS[i][4].to_i
        end
        if @cost <= $game_party.gold
          for i in 0..Weapons::NEW_WEAPON.keys.size - 1
            @leftover_parts = @parts_selected - Weapons::NEW_WEAPON.keys[i]
            @leftover_check = Weapons::NEW_WEAPON.keys[i] - @parts_selected 
            if @leftover_parts == @leftover_check and @leftover_check == [] and @leftover_parts == []
              @result_window.contents.clear
              @result_window.contents.draw_text(0,0,608,32,"Created " + Weapons::NEW_WEAPON[Weapons::NEW_WEAPON.keys[i]][0])
              @result_window.update
              $game_party.gold -= @cost  #<-----------HERE IT IS!         
              for part in Weapons::NEW_WEAPON.keys[i]
                @str += Weapons::WEAPON_PARTS[part][2]
                @dex += Weapons::WEAPON_PARTS[part][3]
              end
              weapon = RPG::Weapon.new
              weapon.name = Weapons::NEW_WEAPON[Weapons::NEW_WEAPON.keys[i]][0]
              weapon.icon_name = Weapons::DEFAULT_ICON[type]
              weapon.atk = @str
              weapon.dex_plus = @dex
              weapon.animation2_id = Weapons::NEW_WEAPON[Weapons::NEW_WEAPON.keys[i]][2]
              weapon.description = Weapons::NEW_WEAPON[Weapons::NEW_WEAPON.keys[i]][1]
              for j in 1...$data_weapons.size
                if $data_weapons[j].name == weapon.name
                  $game_system.se_play($data_system.equip_se) 
                  $game_party.gain_weapon($data_weapons[j].id,1)
                  return
                end
                if $data_weapons[j].name == ""
                  $game_system.se_play($data_system.equip_se) 
                  weapon.id = $data_weapons[j].id
                  $data_weapons[j] = weapon
                  $data_classes[type].weapon_set.push(weapon.id)
                  $game_party.gain_weapon(weapon.id,1)
                  return
                end
              end
            end
          end
        else
          @result_window.contents.clear
          @result_window.contents.draw_text(0,0,608,32,"Not enough funds to do this.")
          @result_window.update
          $game_system.se_play($data_system.buzzer_se)        
        end
      elsif @parts_selected.include?(id) == true
        $game_system.se_play($data_system.cancel_se)
        @weapon_part1_window.draw_item(@weapon_part1_window.index,Color.new(255,255,255,255))
        @parts_selected.delete(id)
      elsif @parts_selected.include?(id) == false
        $game_system.se_play($data_system.decision_se)
        @weapon_part1_window.draw_item(@weapon_part1_window.index,Color.new(255,255,255,127))
        @parts_selected.push(id)
      end
    end
  end

I also changed if @cost < $game_party.gold  to  if @cost <= $game_party.gold I got annoyed when I had enough money but wasn't able to craft my weapon.

@gRaViJa  and anyone else interested in adding a window to show the amount of gold your party has:

It's really pretty simple to add a window that shows the amount of gold you have to any layout, but I thought that this particular script needed it in order to suit my needs and I thought I'd share it to help out anyone else who wants it.

Bear in mind I took the code straight from the Scene_Window script in the Script Editor and tweaked it a bit to change it's locale.
Code:
@gold_window = Window_Gold.new
    @gold_window.x = 540 - @gold_window.width / 2
    @gold_window.y = 400 - @gold_window.height / 2

Obviously, you would change the @gold_window.x and @gold_window.y to whatever location you want your window to be. This one ends up in the lower right hand corner of the screen and honestly, I think that's the best place for it, but to each his own.

edit: I originally forgot to mention that this should be added into the both Scene_Weapon_Select class and the Scene_Weapon_Main class. It should be added to the main methods of each class.

Here is the new Scene_Weapon_Select class main method:

Code:
class Scene_Weapon_Select
  attr_accessor :type
  def main
    @spriteset = Spriteset_Map.new
    @gold_window = Window_Gold.new
    @gold_window.x = 540 - @gold_window.width / 2
    @gold_window.y = 400 - @gold_window.height / 2
    @weapon_type_window = Window_Command.new(160, Weapons::WEAPON_TYPE.values)
    @weapon_type_window.index = 0
    @weapon_type_window.x = 320 - @weapon_type_window.width / 2
    @weapon_type_window.y = 240 - @weapon_type_window.height / 2
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    @weapon_type_window.dispose
    @spriteset.dispose
    @gold_window.dispose
  end

Here is the new main method for the Scene_Weapon_Main class:

Code:
def main
    @spriteset = Spriteset_Map.new
    @parts = []
    @parts_selected = []
    @leftover_parts = []
    @leftover_check = []
    @cost = 0
    @str = 0
    @dex = 0
    for i in Weapons::AVAILABLE_PARTS
      if Weapons::WEAPON_PARTS[i] != nil
        case Weapons::WEAPON_PARTS[i][0]
          when type
          @parts.push(Weapons::WEAPON_PARTS[i][1] + "     " + Weapons::WEAPON_PARTS[i][4].to_s)
        end
      end
    end
    @parts.push("Done")
    @gold_window = Window_Gold.new
    @gold_window.x = 540 - @gold_window.width / 2
    @gold_window.y = 400 - @gold_window.height / 2
    @weapon_part1_window = Window_Command.new(480, @parts)
    @weapon_part1_window.index = 0
    @weapon_part1_window.x = 0
    @weapon_part1_window.y = 240 - @weapon_part1_window.height / 2
    @result_window = Window_Base.new(0,416,640,64)
    @result_window.contents = Bitmap.new(608,32)
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    @weapon_part1_window.dispose
    @result_window.dispose
    @gold_window.dispose
    @spriteset.dispose
  end

Take special notice near the end of each of the main methods. Notice the code I added:

Code:
@gold_window.dispose

If you forget that, the gold window will still be on the screen after you get out of the weapon creator menu. Believe me, that's never any fun. XP
 
There's a major error again. When i create one simple sword and then i go look to my items, the itemlist is full of simple swords :O
 

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