Gem Roulette XP VX & ACE

Discussion in 'RGSS Scripts (RMXP)' started by kyonides, Nov 17, 2019.

  1. kyonides

    kyonides Villager Member

    Messages:
    26
    Likes Received:
    4
    First Language:
    English
    Primarily Uses:
    RMXP
    Gem Roulette XP
    v 1.0.7



    by Kyonides-Arkanthes


    Introduction

    This is my own version of a roulette mini game. The gems you can see on the screenshot below will rotate as expected after you hit the OK button. Later on it will show you your prize. After you collect it, it will show up on the window on the right hand side of the screen as an icon. You may collect more prizes the more attempts you get.

    Just remember I didn't provide the gems you see below. Use your own icons if possible, you just need 10 of them.

    You may also find ports to VX and VX Ace.

    Screenshots

    [​IMG]

    Instructions

    There is a TXT file you need to edit so you can configure the prizes the player might earn after spinning the wheel. Later on you may check the instructions included in my script. You also need to place all required (gem) graphics in Graphics/Icons directory, you may need to create it first.

    All 3 Scripts

    DOWNLOAD DEMOS HERE


    XP Version 1.0.7

    Code:
    # * Gem Roulette XP - Stand Alone Version
    #   Scripter : Kyonides-Arkanthos
    #   v 1.0.7 - 2017-11-14
    
    #   Script Calls
    
    #   To open Gem Roulette :           $scene = Gem_Roulette.new
    
    #   To increase Spinning Attempts :  $game_party.roulette_attempts += Number
    
    #   This script will let you spin some gems as if they were part of a Wheel of
    #   Fortune. Later on you will collect your prize. Previous prizes will be
    #   displayed on the window on the right hand side.
    
    #   Prizes are picked up randomly but you can configure what prizes they might
    #   get if you edit the file named as shown on the PRIZE_FILENAME Constant below
    
    #   There is the possibility of not letting the player get a prize depending on
    #   then gem or slot selected by the script.
    
    #   Don't forget to include the sprites needed for the 10 Gem-Slots.
    
    module GemRouletteSetup
     # Gem Icon Sprite Name Prefix - will be used as Slots
     ICON_NAME_PREFIX = 'gem'
     # SE for Startup and Prize is ready to be collected
     SE_STARTUP = "056-Right02"
     # Prizes TXT Filename
     PRIZE_FILENAME = 'prizes.txt'
     # Label for Position or Slot
     POSITION_LABEL = 'Slot'
     # Label for No Prize for you
     NO_PRIZE = 'Nothng'
     # Label for Item as Prize
     ITEM_PRIZE   = 'Item'
     # Label for Weapon as Prize
     WEAPON_PRIZE = 'Weapon'
     # Label for Armor as Prize
     ARMOR_PRIZE  = 'Armor'
     # Label for Skill as Prize
     SKILL_PRIZE  = 'Skill'
     # Label for HP as Prize or Punishment
     HP_LOSS = 'HP'
     # Label for SP as Prize or Punishment
     SP_LOSS = 'SP'
     # Icon filename for Losing HP or SP
     STATS_LOSS_ICON = ''
     # Points Earned Label
     STATS_LOSS_LABEL = ' Earned: '
     # Attempts Left Label
     ATTEMPTS_LEFT = 'Attempts Left: '
     # Spin the Wheel String
     SPIN_WHEEL = 'Spin Wheel'
     # Collect Prize String
     COLLECT = 'Collect'
     # No More Spins Left String
     RUNOUT = 'No More Spins'
     # Better Luck Next Time String
     NEXT_TIME = 'Better Luck Next Time!'
     # Points Label
     POINTS = 'Points'
     # DO NOT EDIT ANYTHING BELOW THIS LINE
     PRIZE_RXDATA = 'Data/GemRoulette.rxdata'
     PRIZES = {}
     @prizes = []
     @prize_points = []
     def self.prizes() @prizes end
     def self.prize_points() @prize_points end
     def self.get_prize_data
       if $DEBUG and File.exist?(PRIZE_FILENAME)
         lines = File.readlines(PRIZE_FILENAME)
         10.times{|n| pts = lines[0].scan(/\d+ #{POINTS}/)[0].sub!(/ #{POINTS}/,'')
           @prize_points << pts.to_i
           lines.shift
           PRIZES[n] = []
           regex = /[a-zA-Z]+/
           kinds = lines[0].scan(regex).map {|ln| self.prize_kind(ln) }
           indexes = lines[0].scan(/[0-9\-]+/).map {|ln| self.prize_kind(ln) }
           kinds.size.times {|m| PRIZES[n] << [kinds[m], indexes[m]] }
           lines.shift  }
         File.open(PRIZE_RXDATA, 'wb') {|file|
           Marshal.dump(@prize_points, file)
           Marshal.dump(PRIZES, file)  }
         return
       end
       File.open(PRIZE_RXDATA, 'rb') {|file|
         @prize_points = Marshal.load(file)
         PRIZES.merge!(Marshal.load(file))  }
     end
    
     def self.prize_kind(kind)
       regexp = /\d+/
       prize = case kind
       when ITEM_PRIZE then :item
       when WEAPON_PRIZE then :weapon
       when ARMOR_PRIZE then :armor
       when SKILL_PRIZE then :skill
       when HP_LOSS then :hp
       when SP_LOSS then :sp
       when regexp then kind.to_i
       end
       return prize
     end
     self.get_prize_data
    end
    
    class StatsItem
     attr_reader :name, :points, :icon_name
     def initialize(new_name, new_points)
       @name = new_name.to_s.upcase + ' ' + GemRouletteSetup::STATS_LOSS_LABEL
       @name += new_points.to_s
       @points = new_points
       @icon_name = GemRouletteSetup::STATS_LOSS_ICON
     end
    end
    
    class Game_Party
     attr_accessor :roulette_attempts, :roulette_points
     alias kyon_gem_roulette_gm_party_init initialize
     def initialize
       @roulette_attempts = 0
       @roulette_points = 0
       @skills = {}
       kyon_gem_roulette_gm_party_init
     end
    
     def gain_skill(sid, n)
       return unless sid > 0
       @skills[sid] = [[skill_number(sid) + n, 0].max, 99].min
     end
     def lose_skill(sid, n) gain_skill(sid, -n) end
     def skill_number(sid) @skills.include?(sid)? @skills[sid] : 0 end
    end
    
    class Sprite_Blink < Sprite
     def update
       super
       if @_blink
         @_blink_count = (@_blink_count + 1) % 32
         alpha = 6 * (@_blink_count < 16 ? 16 - @_blink_count : @_blink_count - 16)
         self.color.set(255, 255, 255, alpha)
       end
       @@_animations.clear rescue nil
     end
    
     def blink_on
       return if @_blink
       @_blink = true
       @_blink_count = 0
     end
    
     def blink_off
       return unless @_blink
       @_blink = false
       self.color.set(0, 0, 0, 0)
     end
    end
    
    class Window_Roulette_Prizes < Window_Base
     def initialize
       super(552, 80, 88, 340)
       @column_max = 2
       refresh
     end
    
     def refresh
       if self.contents != nil
         self.contents.dispose
         self.contents = nil
       end
       @data = GemRouletteSetup.prizes
       @item_max = @data.size
       return if @item_max == 0
       self.contents = Bitmap.new(width - 32, @item_max * 32)
       @item_max.times {|n| draw_item(n) }
     end
    
     def draw_item(index)
       x = index % 2 * 32
       y = index / 2 * 32
       bitmap = RPG::Cache.icon(@data[index])
       self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
     end
    end
    
    class Window_Command
     def replace_command(index, command)
       @commands[index] = command
       refresh
     end
    end
    
    class Window_GRPLabel < Window_Base
     def initialize(w)
       super(0, 0, w, 64)
       self.contents = Bitmap.new(width - 32, height - 32)
       refresh
     end
    
     def refresh
       self.contents.clear
       self.contents.font.color = system_color
       points = GemRouletteSetup::POINTS
       self.contents.draw_text(0, 0, self.width - 32, 32, points)
       self.contents.font.color = normal_color
       points = $game_party.roulette_points.to_s
       self.contents.draw_text(0, 0, self.width - 32, 32, points, 2)
     end
    end
    
    class Gem_Roulette
     def initialize
       path = 'Graphics/Icons/'
       items = Dir[path + GemRouletteSetup::ICON_NAME_PREFIX+'*'].sort
       @items = items.map{|item| item.sub!(path, '') }
       @moving_frames = 15
       @steps = 60
       Audio.se_play("Audio/SE/" + GemRouletteSetup::SE_STARTUP, 80, 100)
       @item_sprites = []
       @cx = 320
       @cy = 240
       if @items.size < 10
         @items += items[0,(10 - @items.size)].dup
       elsif @items.size > 10
         @items = @items[0,10]
       end
       @item_max = @items.size
       @radius = 120
       @d = 2.0 * Math::PI / @item_max
       @item_max.times {|n| @item_sprites << Sprite_Blink.new
         @item_sprites[n].x = @cx - 20 - (@radius * Math.sin(@d * n)).round
         @item_sprites[n].y = @cy - 60 + (@radius * Math.cos(@d * n)).round
         @item_sprites[n].bitmap = RPG::Cache.icon(items[n % items.size]) }
       @blink_index = 0
       @item_sprites[@blink_index].blink_on
       @xy = [@item_sprites[0].x, @item_sprites[0].y]
       @prize_sprites = []
       3.times { @prize_sprites << Sprite.new(@viewport3)
         @prize_sprites[-1].z = 5000 }
       @prize_sprites[0].x = @cx - 12
       @prize_sprites[0].y = @cy - 36
       @prize_sprites[1].x = @prize_sprites[0].x - 78
       @prize_sprites[1].y = @prize_sprites[0].y + 36
       @prize_sprites[2].x = 210
       @prize_sprites[2].y = 344
       make_attempts_left_label
       @option_window = Window_Command.new(160, [GemRouletteSetup::SPIN_WHEEL])
       @option_window.x = 240
       @option_window.y = @prize_sprites[2].y + 36
     end
    
     def make_attempts_left_label
       @prize_sprites[2].bitmap.clear rescue nil
       @prize_sprites[2].bitmap = bitmap = Bitmap.new(220, 32)
       color = Color.new(25, 25, 25, 180)
       @prize_sprites[2].bitmap.fill_rect(0, 0, 220, 32, color)
       left = GemRouletteSetup::ATTEMPTS_LEFT
       attempts = left + $game_party.roulette_attempts.to_s
       bitmap.draw_text(0, 0, 220, 32, attempts, 1)
     end
    
     def main
       @spriteset = Spriteset_Map.new
       @points_window = Window_GRPLabel.new(172)
       @points_window.x = 640 - @points_window.width
       3.times {|n| @prize_sprites[n].z = 5000 }
       @item_max.times {|n| @item_sprites[n].z = 5000 }
       @prizes_window = Window_Roulette_Prizes.new
       Graphics.transition
       loop do
         Graphics.update
         Input.update
         update
         break if $scene != self
       end
       Graphics.freeze
       @prizes_window.dispose
       @option_window.dispose
       @xy.clear
       @prize_sprites.each {|sprite| sprite.dispose }
       @prize_sprites.clear
       @item_sprites.each {|sprite| sprite.dispose }
       @item_sprites.clear
       @prize_sprites = @item_sprites = @xy = nil
       @points_window.dispose
       @spriteset.dispose
     end
    
     def update
       @option_window.update
       @prizes_window.update
       @item_sprites.each {|sprite| sprite.update }
       if @move
         refresh_sprites
         return
       end
       if Input.trigger?(Input::B)
         exit_scene
         return
       elsif Input.trigger?(Input::C)
         if $game_party.roulette_attempts == 0
           if @result
             retrieve_new_prize
             exit_scene
           else
             $game_system.se_play($data_system.buzzer_se)
           end
           return
         end
         $game_system.se_play($data_system.decision_se)
         retrieve_new_prize
       end
     end
    
     def exit_scene
       $game_system.se_play($data_system.buzzer_se)
       GemRouletteSetup.prizes.clear
       $scene = Scene_Map.new
     end
    
     def retrieve_new_prize
       if !@move and !@result
         @item_sprites[@blink_index].blink_off
         @option_window.index = -1
         $game_party.roulette_attempts -= 1
         make_attempts_left_label
         @index = rand(@item_max)
         @move = true
         return
       end
       return unless @result
       GemRouletteSetup.prizes << @new_prize.icon_name if @new_prize
       @prizes_window.refresh
       @option_window.index = 0
       case @kind
       when :item then $game_party.gain_item(@new_prize.id, 1)
       when :weapon then $game_party.gain_weapon(@new_prize.id, 1)
       when :armor then $game_party.gain_armor(@new_prize.id, 1)
       when :skill then $game_party.gain_skill(@new_prize.id, 1)
       when :hp then $game_party.actors[0].hp += @new_prize.points
       when :sp then $game_party.actors[0].sp += @new_prize.points
       end
       @prize_sprites[0].bitmap.clear rescue nil
       @prize_sprites[1].bitmap.clear rescue nil
       @result = nil
       spin = $game_party.roulette_attempts > 0
       comm = spin ? GemRouletteSetup::SPIN_WHEEL : GemRouletteSetup::RUNOUT
       @option_window.replace_command(0,comm)
     end
    
     def refresh_sprites
       d1 = -@d / @moving_frames * 2
       @item_max.times {|n| m = n - @index
         d = @d * m + d1 * @steps
         @item_sprites[n].x = @cx - 20 - (@radius * Math.sin(d)).round
         @item_sprites[n].y = @cy - 60 + (@radius * Math.cos(d)).round }
       @steps -= 1
       if @steps == -1
         if rand(5) == 0
           @steps += 5
           return
         end
         Audio.se_play("Audio/SE/" + GemRouletteSetup::SE_STARTUP, 80, 100)
         @move = nil
         @steps = 1 + @moving_frames * (3 + rand(5))
         results = @item_sprites.map {|sprite| @xy == [sprite.x,sprite.y] }
         @blink_index = @result = results.index(true)
         @item_sprites[@blink_index].blink_on
         check_prize
       end
     end
    
     def check_prize
       $game_party.roulette_points += GemRouletteSetup.prize_points[@blink_index]
       @points_window.refresh
       prizes = GemRouletteSetup::PRIZES[@result]
       unless prizes[0]
         no_prize
         return
       end
       @new_prize = case prizes.size
       when 1 then prizes[0][0] ? prize_kind(prizes[0][0], prizes[0][1]) : nil
       else
         index = prizes.size > 2 ? rand(prizes.size) : rand(4) % 2
         prize_kind(prizes[index][0], prizes[index][1])
       end
       unless @new_prize
         no_prize
         return
       end
       @prize_sprites[0].bitmap = RPG::Cache.icon(@new_prize.icon_name).dup
       @prize_sprites[1].bitmap = bitmap = Bitmap.new(180, 24)
       bitmap.font.bold = true
       bitmap.font.size = 19
       bitmap.draw_text(0, 0, 180, 24, @new_prize.name, 1)
       @option_window.replace_command(0, GemRouletteSetup::COLLECT)
     end
    
     def prize_kind(kind, index)
       @kind = kind
       case kind
       when :item then $data_items[index]
       when :weapon then $data_weapons[index]
       when :armor then $data_armors[index]
       when :skill then $data_skills[index]
       when :hp, :sp then StatsItem.new(kind, index)
       end
     end
    
     def no_prize
       @kind = nil
       @prize_sprites[1].bitmap = bitmap = Bitmap.new(200, 24)
       label = GemRouletteSetup::NEXT_TIME
       bitmap.font.bold = true
       bitmap.font.size = 19
       bitmap.draw_text(0, 0, 200, 24, label, 1)
     end
    end

    TXT Config File
    Valid for All Versions
    Code:
    Slot 1
     Weapon 1, Item 1, Armor 1, Skill 1
    Slot 2
     Weapon 2, Item 2, Skill 2
    Slot 3
     Weapon 5, Item 3, Armor 4, Skill 3
    Slot 4
     Weapon 1, Item 1, Armor 1, Skill 1
    Slot 5
     Weapon 1, Item 5, Item 8, Skill 1
    Slot 6
     Weapon 1, Item 1, Armor 8, Skill 1
    Slot 7
     Weapon 1, Item 1, Armor 1, Skill 1
    Slot 8
     Nothing
    Slot 9
     Weapon 1, Item 1, Armor 1, Skill 5
    Slot 10
     Weapon 4, Item 1, Armor 4, Skill 20
    
    FAQ

    Nothing to say, yet.


    Compatibility

    Designed for RPG Maker XP & VX & VX ACE. You may need to check out the other subfora to find them.


    Terms and Conditions

    Free for use in non commercial projects, but you may contact me in case you want to go commercial. Due credit is a must.

    By the way, I will only support the latest version available because it usually includes bug fixes and improvements.

    You are not allowed to repost my scripts on any other boards.
     
    Last edited: Nov 18, 2019
    #1

Share This Page