Ring Choice Window

Started by Vexus, January 18, 2015, 12:06:02 pm

Previous topic - Next topic

Vexus

This is not much a request but I've seen it on youtube and was wondering if anyone know if there is the script?

I can't seem to remember which video it was or when I seen it, but I liked the idea.

In short, it's like this: http://forum.chaos-project.com/index.php?topic=12055.0 but instead of showing only text, you have a ring menu around your character with icons and a window with the description of each choice.

Anyone know what I am talking about? I already tried searching on google.

Thanks
Current Project/s:

Zexion

I think that ring menu was made by G_G specially for Tuggernuts. I can probably make one for you though, but it'll probs be more complicated than G_G's cuz I suk

Vexus

January 18, 2015, 01:18:21 pm #2 Last Edit: January 18, 2015, 01:19:34 pm by Vexus
Google searching tuggernuts showed nothing relevant. You seem to get what I meant from my OP, so I guess you are right and it's an exclusive script.

As for making one, up to you really, man.  I don't NEED it, but I wanted to experiment with one instead of using the bland choice window.
Current Project/s:

Blizzard

Just a sidenote: Tuggernuts is a member here and G_G is now called gameus (also a member here).
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Vexus

Had no idea.

Oh well, guess I'll see what to do.
Current Project/s:

G_G

January 19, 2015, 08:15:26 pm #5 Last Edit: January 19, 2015, 08:16:54 pm by gameus
Let me talk to Branden about it. I doubt he'll mind if I release it to people. It's actually a very handy script. What's cool is it still uses the 'Show Choices' command and you can create nested rings and toggle between ring choices and normal show choices.

Vexus

That would be great!

If however, you want to keep it exclusive there's no need really :)
Current Project/s:

G_G

Nyah, not at all. I just need to tweak and clean it up a bit and we should be good to go.

Vexus

Then, thank you for sharing it :)

That ring choice menu makes investigation games and such look better.
Current Project/s:

G_G

January 20, 2015, 07:42:21 pm #9 Last Edit: January 20, 2015, 08:01:48 pm by gameus
Sorry for the delay. It's lost somewhere in my pool of backup files, gimme another day and it'll be here. xD

EDIT: Nevermind, found it on my trusty FTP.

http://jugglingcode.com/scripts/Branden/Ring%20Choices.exe

The demo is very short but should explain it really well. You can use a placeholder icon for testing purposes, branch out ring choices since the 'Show Choices' command only allows for four choices. Toggle between ring/normal choices. I'll eventually post this in the public script database as well but feeling lazy at the moment. Also, I was having issues with the script call so I put Zeriab's interpreter fix in the script as well. If you already have it in your project by chance, it shouldn't effect it whatsoever.

Spoiler: ShowHide

Spoiler: ShowHide



Vexus

It's fine.

Take as much time as you need, I'm in no rush :)
Current Project/s:

G_G

LOL! Posted edit as you replied, check again. :3

Spaceman McConaughey

January 20, 2015, 10:29:55 pm #12 Last Edit: January 20, 2015, 10:31:01 pm by Sgt. Tuggernuts
Not even gonna lie, I was very reluctant to give this out, seeing as it'd be one less unique asthetic for ESTA. :p

gameus is tweaking it up for me to set it apart from the now released version, so at least there's that. Hope you enjoy the script. :)

Vexus

First of all thank you :)

Secondly, if you still want it exclusive it's not a problem for me.
Current Project/s:

Spaceman McConaughey

No no, it's fine.

Use it. Have fun. :)

Vexus

January 23, 2015, 11:43:29 am #15 Last Edit: January 23, 2015, 11:52:35 am by Vexus
Very well, thanks :)

I might try and tweak it a little tough. Was thinking on adding a bottom window with the description of the choice being selected instead of showing in mid air.

It might be better visually to read.
Current Project/s:

Vexus

February 07, 2015, 11:10:23 am #16 Last Edit: February 07, 2015, 11:13:00 am by Vexus
Haven't touched the script yet, but as I previously said, I wanted to see how to make the choice text be in a separate window instead of being in between the choices. There are some comments written in another language in the script and I don't understand those, but reading the code itself I can't seem to find which area I should be looking at to modify.

I'd like to try and make the text in a separate windows because I was thinking on making this project as a point and click with the mouse (If that works with this script heh) instead of the ordinary WASD movement.

Any insight?

Thanks
Current Project/s:

G_G

I added the separate window option. But I'm not going to implement mouse controls.
Spoiler: ShowHide



Added two new options, DISPLAY_TYPE and DISPLAY_POSITION.
Code: ruby
#===============================================================================
# Ring Menu Show Choices
# Version 1.1
# Author gameus
#-------------------------------------------------------------------------------
# Intro:
# Displays a ring of options when using the 'Show Choices' command. The ring
# can be toggled allowing use for both the ring menu and the regular command.
#
# Instructions:
# Do the little amount of configuration below. Ignore the DISABLED_ICON option.
# It's useless but is needed to be there.
#
# To use the ring menu, use this script call before using 'Show Choices'
#  $game_system.ring = true
# To go back to the regular show choices, use this
#  $game_system.ring = false
# That's pretty much it.
#
# Oh, and you need to have your icons titled as such and placed in the icons
# folder.
#   choice_icon
# Example, your choices are Talk, Barter, Nevermind
#   Talk_icon
#   Barter_icon
#   Nevermind_icon
#
# If the icon isn't found, it'll use the placeholder configured below.
#
# Credits
# gameus ~ For making it
# Unknown Author ~ For base Ring Menu
# Colonel Blinx ~ For requesting it
# Zeriab ~ For interpreter fix (included in this script)
#===============================================================================

module Gameus
  # You can either display the option in the ring menu, or a separate window
  # 0 = ring, 1 = separate menu
  DISPLAY_TYPE     = 1
  # X and Y for the window in display type 1
  DISPLAY_POSITION = [64, 64]
  # Radius for the ring menu, 64 is a pretty good value
  RING_MENU_RADIUS = 64
  # Ignore this
  DISABLED_ICON    = ''
  # This is the sound effect that plays when the ring opens up
  # blank = no sound
  SE_STARTUP       = ''
  # This is the placeholder icon for icons not found
  PLACEHOLDER      = '001-Weapon01'
end

class Game_System
 
  attr_accessor :ring
 
  alias gg_init_ring_event_lat initialize
  def initialize
    @ring = false
    gg_init_ring_event_lat
  end

end

class Game_Temp
 
  attr_accessor :setup_ring
  attr_accessor :parameters
  attr_accessor :event_id
 
  alias gg_init_ring_temp_lat initialize
  def initialize
    @setup_ring = false
    @parameters = nil
    gg_init_ring_temp_lat
  end

end

class Window_Message < Window_Selectable
 
  alias gg_upd_ring_event_lat update
  def update
    if $game_temp.setup_ring
      $game_temp.setup_ring = false
      event = $game_map.events[$game_temp.event_id]
      px = calc_pos_x(event)
      py = calc_pos_y(event)
      @ring = Sprite_Ring.new($game_temp.parameters[0], px, py)
      if Gameus::DISPLAY_TYPE == 1
        @help = Window_RingHelp.new
      end
    end
    if @ring != nil
      @ring.update
      if @help != nil
        @help.set_text(@ring.commands[@ring.index], 1)
      end
      if Input.trigger?(Input::B)
        if $game_temp.choice_max > 0 and $game_temp.choice_cancel_type > 0
          $game_system.se_play($data_system.cancel_se)
          $game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
          dispose_ring
          terminate_message
        end
        return
      elsif Input.trigger?(Input::C)
        if $game_temp.choice_max > 0
          $game_system.se_play($data_system.decision_se)
          $game_temp.choice_proc.call(@ring.index)
        end
        dispose_ring
        terminate_message
        return
      end
    else
      gg_upd_ring_event_lat
    end
  end
 
  def dispose_ring
    if @help != nil
      @help.dispose
      @help = nil
    end
    @ring.dispose
    @ring = nil
  end
 
  def calc_pos_x(char)
    if char.screen_x >= 640 - Gameus::RING_MENU_RADIUS
      px = char.screen_x - 15 - Gameus::RING_MENU_RADIUS
    elsif char.screen_x <= Gameus::RING_MENU_RADIUS
      px = char.screen_x - 15 + Gameus::RING_MENU_RADIUS
    else
      px = char.screen_x - 15
    end
    return px
  end
 
  def calc_pos_y(char)
    if char.screen_y >= 480 - Gameus::RING_MENU_RADIUS
      py = char.screen_y - 24 - Gameus::RING_MENU_RADIUS
    elsif char.screen_y <= Gameus::RING_MENU_RADIUS
      py = char.screen_y - 24 + Gameus::RING_MENU_RADIUS
    else
      py = char.screen_y - 24
    end
    return py
  end
 
end

class Interpreter
 
  alias gg_setup_ring_choices_lat setup_choices
  def setup_choices(parameters)
    if !$game_system.ring
      gg_setup_ring_choices_lat(parameters)
      return
    end
    $game_temp.choice_max = parameters[0].size
    $game_temp.setup_ring = true
    $game_temp.parameters = parameters
    $game_temp.event_id = @event_id
    $game_temp.choice_cancel_type = parameters[1]
    current_indent = @list[@index].indent
    $game_temp.choice_proc = Proc.new { |n| @branch[current_indent] = n }
  end
 
end

class Window_RingHelp < Window_Base
  def initialize
    super(Gameus::DISPLAY_POSITION[0], Gameus::DISPLAY_POSITION[1], 160, 64)
    self.contents = Bitmap.new(width - 32, height - 32)
    @text =''
    self.back_opacity = 128
  end
  def set_text(text, align = 0)
    if text != @text
      self.contents.clear
      self.contents.font.color = normal_color
      self.contents.draw_text(4, 0, self.width - 40, 32, text, align)
      @text = text
    end
  end
end

class Sprite_Ring < Sprite
 
  #--------------------------------------------------------------------------
  # › ƒNƒ‰ƒX'è"
  #--------------------------------------------------------------------------
  STARTUP_FRAMES = 20
  MOVING_FRAMES = 5   
  MODE_START = 1
  MODE_WAIT  = 2
  MODE_MOVEL = 3
  MODE_MOVER = 4
  SIZE = Gameus::RING_MENU_RADIUS * 2
  #--------------------------------------------------------------------------
  # › ƒAƒNƒZƒT
  #--------------------------------------------------------------------------
  attr_accessor :index
  attr_accessor :active
  attr_reader   :commands
  #--------------------------------------------------------------------------
  # The stuff in the section below can be accomodated for new menu entries
  #--------------------------------------------------------------------------
  def initialize( commands, center_x, center_y, r = Gameus::RING_MENU_RADIUS )
    super(Viewport.new(0, 0, 640, 480))
    self.viewport.z = 10000
    self.bitmap = Bitmap.new(SIZE * 2, SIZE * 2)
    @active = true
    @data = commands
    @commands = []
    @items = []
    @data.each { |i|
      @commands.push(i)
      begin
        icon = RPG::Cache.icon(i + "_icon")
      rescue
        icon = RPG::Cache.icon(Gameus::PLACEHOLDER)
      end
      @items.push(icon)
    }
    # I changed this to prevent glitches when modifying the number of menu items
    @item_max = @commands.size
    @index = 0
    @disabled = Array.new(@commands.size, false)
    self.x = center_x - SIZE / 2
    self.y = center_y - SIZE / 2
    @center_x = center_x
    @center_y = center_y
    @cx = SIZE / 2
    @cy = SIZE / 2
    @radius = r
    setup_move_start
    refresh
  end
  def dispose
    self.viewport.dispose
    super
  end
  def item
    return @data[@index]
  end
  #--------------------------------------------------------------------------
  # œ ƒtƒŒ[ƒ€XV
  #--------------------------------------------------------------------------
  def update
    super
    refresh
    return if animation? || !@active
    if Input.repeat?(Input::UP) || Input.repeat?(Input::LEFT)
      $game_system.se_play($data_system.cursor_se)
      setup_move_move(MODE_MOVEL)
      return
    end
    if Input.repeat?(Input::DOWN) || Input.repeat?(Input::RIGHT)
      $game_system.se_play($data_system.cursor_se)
      setup_move_move(MODE_MOVER)
      return
    end
  end
  #--------------------------------------------------------------------------
  # œ ‰æ-ʍĕ`‰æ
  #--------------------------------------------------------------------------
  def refresh
    self.bitmap.clear
    # ƒAƒCƒRƒ",ð•`‰æ
    case @mode
    when MODE_START
      refresh_start
    when MODE_WAIT
      refresh_wait
    when MODE_MOVER
      refresh_move(1)
    when MODE_MOVEL
      refresh_move(0)
    end
    # ƒAƒNƒeƒBƒu,ȃRƒ}ƒ"ƒh-¼•\Ž¦
    rect = Rect.new(-@cx + 16, @cy + 24, self.bitmap.width, 32)
    if Gameus::DISPLAY_TYPE == 0
      self.bitmap.draw_text(rect, @commands[@index],1)
    end
  end
  #--------------------------------------------------------------------------
  # › ‰æ-ʍĕ`‰æ(‰Šú‰»Žž)
  #--------------------------------------------------------------------------
  def refresh_start
    d1 = 2.0 * Math::PI / @item_max
    d2 = 1.0 * Math::PI / STARTUP_FRAMES
    r = @radius - 1.0 * @radius * @steps / STARTUP_FRAMES
    for i in 0...@item_max
      j = i - @index
      d = d1 * j + d2 * @steps
      x = @cx + ( r * Math.sin( d ) ).to_i
      y = @cy - ( r * Math.cos( d ) ).to_i
      draw_menu_item(x, y, i)
    end
    @steps -= 1
    if @steps < 1
      @mode = MODE_WAIT
    end
  end
  #--------------------------------------------------------------------------
  # › ‰æ-ʍĕ`‰æ('Ò‹@Žž)
  #--------------------------------------------------------------------------
  def refresh_wait
    d = 2.0 * Math::PI / @item_max
    for i in 0...@item_max
      j = i - @index
      x = @cx + ( @radius * Math.sin( d * j ) ).to_i
      y = @cy - ( @radius * Math.cos( d * j ) ).to_i
      draw_menu_item(x, y, i)
    end
  end
  #--------------------------------------------------------------------------
  # › ‰æ-ʍĕ`‰æ(‰ñ"]Žž)
  #  mode : 0="½ŽžŒv‰ñ,è 1=ŽžŒv‰ñ,è
  #--------------------------------------------------------------------------
  def refresh_move( mode )
    d1 = 2.0 * Math::PI / @item_max
    d2 = d1 / MOVING_FRAMES
    d2 *= -1 if mode != 0
    for i in 0...@item_max
      j = i - @index
      d = d1 * j + d2 * @steps
      x = @cx + ( @radius * Math.sin( d ) ).to_i
      y = @cy - ( @radius * Math.cos( d ) ).to_i
      draw_menu_item(x, y, i)
    end
    @steps -= 1
    if @steps < 1
      @mode = MODE_WAIT
    end
  end
  #--------------------------------------------------------------------------
  # œ €-Ú,Ì•`‰æ
  #     x :
  #     y :
  #     i : €-Ú"ԍ†
  #--------------------------------------------------------------------------
  def draw_menu_item(x, y, i)
    #p "x=" + x.to_s + " y=" + y.to_s + " i=" + @items[i].to_s
    rect = Rect.new(0, 0, @items[i].width, @items[i].height)
    if @index == i
      if @disabled[i]
        self.bitmap.blt( x, y, Gameus::DISABLED_ICON, rect )
      else
        self.bitmap.blt( x, y, @items[i], rect )
      end
    else
      if @disabled[i]
        self.bitmap.blt( x, y, Gameus::DISABLED_ICON, rect, 128 )
      else
        self.bitmap.blt( x, y, @items[i], rect, 128 )
      end
    end
  end
  #--------------------------------------------------------------------------
  # œ €-Ú,ð-³Œø,É,·,é
  #     index : €-Ú"ԍ†
  #--------------------------------------------------------------------------
  def disable_item(index)
    @disabled[index] = true
  end
  #--------------------------------------------------------------------------
  # › ‰Šú‰»ƒAƒjƒ[ƒVƒ‡ƒ",̏€"õ
  #--------------------------------------------------------------------------
  def setup_move_start
    @mode = MODE_START
    @steps = STARTUP_FRAMES
    if Gameus::SE_STARTUP != ""
      Audio.se_play("Audio/SE/" + Gameus::SE_STARTUP, 80, 100)
    end
  end
  #--------------------------------------------------------------------------
  # › ‰ñ"]ƒAƒjƒ[ƒVƒ‡ƒ",̏€"õ
  #--------------------------------------------------------------------------
  def setup_move_move(mode)
    if mode == MODE_MOVER
      @index -= 1
      @index = @items.size - 1 if @index < 0
    elsif mode == MODE_MOVEL
      @index += 1
      @index = 0 if @index >= @items.size
    else
      return
    end
    @mode = mode
    @steps = MOVING_FRAMES
  end
  #--------------------------------------------------------------------------
  # › ƒAƒjƒ[ƒVƒ‡ƒ"'†,©,Ç,¤,©
  #--------------------------------------------------------------------------
  def animation?
    return @mode != MODE_WAIT
  end
end

class Interpreter
  SCRIPT_WAIT_RESULTS = [:wait, FalseClass]
  #-------------------------------------------------------------------
  # * Script
  #-------------------------------------------------------------------
  def command_355
    # Set first line to script
    script = @list[@index].parameters[0] + "\n"
    # Store index in case we need to wait.
    current_index = @index
    # Loop
    loop do
      # If next event command is second line of script or after
      if @list[@index+1].code == 655
        # Add second line or after to script
        script += @list[@index+1].parameters[0] + "\n"
      # If event command is not second line or after
      else
        # Abort loop
        break
      end
      # Advance index
      @index += 1
    end
    # Evaluation
    result = eval(script)
    # If return value is false
    if SCRIPT_WAIT_RESULTS.include?(result)
      # Set index back (If multi-line script call)
      @index = current_index
      # End and wait
      return false
    end
    # Continue
    return true
  end
end


Vexus

February 07, 2015, 11:52:34 am #18 Last Edit: February 07, 2015, 12:13:42 pm by Vexus
Sweet, thanks!

It's ok for the mouse I'm still experimenting :)


I managed to move the text just now but I noticed something when I did it, the choice windows are not centred around the player but around the event that has the selection. Was this intentional?

I'm trying to make it so it's always on the player.
Current Project/s:

G_G

Yes that was intentional, that was what Branden had originally requested. These methods in Window_Message are what calculate the X and Y.

  def calc_pos_x(char)
    if char.screen_x >= 640 - Gameus::RING_MENU_RADIUS
      px = char.screen_x - 15 - Gameus::RING_MENU_RADIUS
    elsif char.screen_x <= Gameus::RING_MENU_RADIUS
      px = char.screen_x - 15 + Gameus::RING_MENU_RADIUS
    else
      px = char.screen_x - 15
    end
    return px
  end
 
  def calc_pos_y(char)
    if char.screen_y >= 480 - Gameus::RING_MENU_RADIUS
      py = char.screen_y - 24 - Gameus::RING_MENU_RADIUS
    elsif char.screen_y <= Gameus::RING_MENU_RADIUS
      py = char.screen_y - 24 + Gameus::RING_MENU_RADIUS
    else
      py = char.screen_y - 24
    end
    return py
  end


Just add 'char = $game_player' at the beginning of each method.