Problems with Selectable Windows

Started by Reygekan, October 26, 2010, 02:31:52 am

Previous topic - Next topic

Reygekan

I decided that, for my game, I wanted a quest system slightly similar to the one from Final Fantasy Tactics, where you selected quests from a menu given a short description. I couldn't find such a system, and I searched for a while (maybe my search terms were bad) so I decided that, despite knowing absolutely no RGSS whatsoever I would learn enough of it to do a simple modification to a quest log script to allow me to accept quests from the log themselves. I do know some Java, so programming isn't totally foreign and I knew I'd really only need to add a few more variables. Ruby can't be THAT hard to figure out right?

Here I am about five-six hours in, and although I've gotten through a lot of debugging, I can't get this new Command Window to be selectable. I edited game_guy's quest log to allow for a third menu which would only show up if you hadn't accepted the job, and would ask if you wanted to accept or ignore it. The command window's frozen however, and no matter how hard I try I simply can't unfreeze it.

Can someone take a look and tell me how to fix it? Any help at all would be appreciated.

Spoiler: ShowHide
##############################################################################
#============================================================================
#:---------------------------------------------------------------------------
#                         Reygekan's Job System
#                        An edit of game_guy's Quest Log script
#                             Version 0.1
#                                10.25.2010
#:---------------------------------------------------------------------------
#=============================================================================
##############################################################################
#:============================================================================
#                            Version History
# Version 0.1-
# Created Script
# Buggy? Yeah, probably
# I don't actually know RGSS
# What the hell am I doing
#
#
#
#
#
#
#
#
## Script Calls:
# Jobs.add(id) ~ Adds the quest(id) to the parties quests.
# Jobs.remove(id) ~ Takes the quest(id) from the party.
# Jobs.complete(id) ~ Makes the quest(id) completed.
# Jobs.completed?(id) ~ Returns true if the quest(id) is completed.
# Jobs.has?(id) ~ Returns true if the party has quest(id).
# Jobs.accepted?(id) ~Returns true if the party has taken a quest(id)
#
#
#
#
#
#
#                                CREDITS
# game_guy as this is basically his quest log. The difference is that
# I've removed a few features for personal use, and allowed you to accept quests
# from the menu.
#:=============================================================================
###############################################################################
#:=============================================================================
#                             BEGIN CONFIGURATION
#:=============================================================================
#:=============================================================================
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#                          CONFIGURATION INSTRUCTIONS
# Configuration is simple, the following methods define a job's name, reward,
# poster, and other information based on the job's id starting from one.
# Add another when statement for every quest and assign a proper return value
#:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#==============================================================================
  module Reygekan #Seriously, I don't know what the hell I'm doing

    JOB_LIMIT = 1 #How many jobs you can take at one time. This is useful for
    #making the player pick between jobs (if they can only take one at a time,
    #and there's a three way gang war for example.) A value of -1 will allow
    #for an infinite number of jobs at once
   
  def self.jobname(id) #a new method jobname, gets the name id, passing in an id
    case id #checking the id
      when 1 then return "Help!" #when it's (id) then the job's name is...
      when 2 then return "Fire!"
      when 3 then return "Two Words"
      when 4 then return "Hello World Hello World Hello World..."
    end
      return "???" #if the id isn't defined, you'll get a "???"
  end
 
  def self.jobreward(id) #Same as above but for rewards
    case id
      when 1 then return "A shoe"
      when 2 then return "Two shoes"
      when 3 then return "Three shoes"
      when 4 then return "Horse shoes"
      end
       return "???"
  end
   
  def self.jobposter(id) #Who put the job up?
    case id
      when 1 then return "Guy"
      when 2 then return "Guy"
      when 3 then return "Guy"
      when 4 then return "Not Guy"
      end
        return "???"
  end
     
  def self.jobdescription(id) #What are the job details?
    case id
      when 1 then return "Get me some gasoline"
      when 2 then return "Help me start a fire"
      when 3 then return "Burn babe"
      when 4 then return "My house burned down. Teach me to be a hobo."
      end
        return "???"
      end
     
end
 
#:=============================================================================
###############################################################################
#                               END CONFIGURATION
###############################################################################
#:=============================================================================

module Jobs #We're defining some call scripts here
  def self.add(id) #The add call script:
    $game_party.add_job(id) #Calls the method "add_job" in Game_Party
  end
 
  def self.remove(id)
    $game_party.remove_job(id) #Opposite of the above
  end
 
  def self.complete(id) #Complete a job
    $game_party.complete(id)
  end
 
  def self.completed?(id) #Checking to see completion
    return $game_party.completed?(id)
  end
 
  def self.has?(id) #Checking to see if the player has a certain job
    return $game_party.has_job?(id)
  end
 
  def self.accepted?(id) #To see if this is in our list of "core jobs"
    return $game_party.accepted?(id)
  end

end


##################################################



class Game_Party #This'll handle the methods we defined above
  attr_accessor :jobs #Some ATTR, one for jobs and the other for completion
  attr_accessor :completed
 
 
  alias rey_jobs_last initialize #See if we've been initialized
  def initialize #Initialize
    @jobs = []
    @accepted = []
    @completed = [] #Creating a job, accepted and completed array
    @uptake = 0 #The number of jobs you've accepted
    rey_jobs_last #Defining rey_jobs_last to make sure we don't reinitialize
  end

  def add_job(id) #The add job function
    unless @jobs.include?(id) #As long as we don't have it
      @jobs.push(id) #Add it
    end
  end
 
  def complete(id) #The completion process
    unless @completed.include?(id) #As long as it's not already completed
      if @jobs.include?(id) #And we have teh job
        @completed.push(id) #Complete the job
      end
    end
  end
 
  def remove_job(id) #Removing a job from the list due to limited availability
    # or the like
    @jobs.delete(id) #delete the idea from the jobs array
  end
 
  def has_job?(id) #Do you ahve the job unlocked?
    return @jobs.include?(id)
  end
 
  def completed?(id) #Did we finish this?
    return @completed.include?(id)
  end
 
  def accepted?(id) #Did you take the job?
    return @accepted.include?(id)
  end
 
  def accept_job(id) #Accepting a job
    unless @accepted.include?(id) #It's not already accepted is it?
      unless @completed.include?(id) #It's not finished is it?
        unless uptake == Reygekan::JOB_LIMIT #We didn't hit the job limit did we?
          accepted.push(id) #No? Let's take the job then
          end
      end
    end
  end
end


################################################


class Scene_Jobs #This is where we handle the visual component
 
 
  def main #Main method
    @jobs = [] #Another jobs array
    for i in $game_party.jobs #Cycling through the other job list
      @jobs.push(Reygekan.jobname(i)) #Getting all the job names
    end
    @map = Spriteset_Map.new #A new scene
    @jobs2 = [] #Another jobs array
    for i in $game_party.jobs #Cycling through the job list
      @jobs2.push(i) #Duplicating it for use here
    end
    @jobs.push("No Jobs") if @jobs.size < 1 #If there are no jobs, say it
    @jobs_window = Window_Command.new(160, @jobs) #Create a "jobs window"
    @jobs_window.height = 480 #How high it is
    @jobs_window.back_opacity = 110 #Transparency
    Graphics.transition #Managing graphics
    loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    @jobs_window.dispose #Disposal
    @jobs_info.dispose if @jobs_info != nil
    @map.dispose
  end
 
   def update #Updating the job information
    @jobs_window.update
    if @jobs_window.active
      update_jobs
      return
    end
    if @jobs_info != nil
      update_info
      return
    end
  end
 
  def update_jobs
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      $scene = Scene_Map.new
      return
    end
    if Input.trigger?(Input::C) #If you select a job
      $game_system.se_play($data_system.decision_se) #Play a sound effect
      @jobs_window.active = false #Making the other window the active one
      x = $game_party.accepted?(@jobs2)
      @jobs_info = Window_JobsInfo.new(@jobs2[@jobs_window.index],x) #Show it's
      #Description in a new window
      if x == false
      s1 = "Take Job"
      s2 = "Leave Job"
      @jobs_taking = Window_Command.new(480, [s1,s2]) #Remember, 200 is the Width
      @jobs_taking.x=160#Set a position for the menu other than 0:0
      @jobs_taking.y=380 #Set a position for the menu other than 0:0
      @jobs_taking.height=100 #Force a new height for the menu window
      @jobs_taking.back_opacity = 110
      @jobs_info.active = false
      @jobs_taking.active = true
      end
      @jobs_info.back_opacity = 110 #Opacity
      return
    end
  end
 
  def update_info
    if Input.trigger?(Input::C)
      x = $game_party.accepted?(@jobs2)
      if x == false
        case jobs_taking.index
          when 0 # Confirm
           if $game_party.accepted?(@jobs) == false
            unless $uptake == Reygekan::JOB_LIMIT
             $game_party.accept_job(@jobs)
            end
          end
        when 1 #Ignore
          Input.trigger(Input::B)
        end
      end
      return
    end
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @jobs_window.active = true
      @jobs_info.dispose
      x = $game_party.accepted?(@jobs2)
      if x == false
      @jobs_taking.dispose
      @jobs_taking = nil
      end
      @jobs_info = nil
      return
    end
  end 
end
############################################################################


class Window_JobsInfo < Window_Base
  def initialize(jobs,x)
    if x == true
    super(160, 0, 480, 480)
  else
    super(160, 0, 480, 380)
    end
    self.contents = Bitmap.new(width - 32, height - 32)
    @jobs = jobs
    refresh
  end
  def refresh
    self.contents.clear
    self.contents.font.color = system_color
    self.contents.draw_text(0, 0, 480, 32, "Job Name:")
    self.contents.font.color = normal_color
    self.contents.draw_text(0, 32, 480, 32, Reygekan.jobname(@jobs))
    self.contents.font.color = system_color
    self.contents.draw_text(0, 64, 480, 32, "Reward:")
    self.contents.font.color = normal_color
    self.contents.draw_text(0, 96, 480, 32, Reygekan.jobreward(@jobs))
    self.contents.font.color = system_color
    self.contents.draw_text(0, 128, 480, 32, "Poster:")
    self.contents.font.color = normal_color
    self.contents.draw_text(0, 160, 480, 32, Reygekan.jobposter(@jobs))
    self.contents.font.color = system_color
    self.contents.draw_text(0, 192, 480, 32, "Status:")
    self.contents.font.color = normal_color
    if $game_party.completed.include?(@jobs)
      self.contents.font.color = crisis_color
      self.contents.draw_text(0, 224, 480, 32, "Completed!")
    else
      if $game_party.accepted?(@jobs)
      self.contents.font.color = normal_color
      self.contents.draw_text(0, 224, 480, 32, "Accepted")
      else
      self.contents.font.color = normal_color
      self.contents.draw_text(0, 224, 480, 32, "Available")
      end
    end
    self.contents.font.color = system_color
    self.contents.draw_text(0, 256, 480, 32, "Description:")
    self.contents.font.color = normal_color
    text = self.contents.slice_text(Reygekan.jobdescription(@jobs), 480)
    text.each_index {|i|
        self.contents.draw_text(0, 288 + i*32, 480, 32, text)}
      end
     
      def setjobs
        return @jobs
      end
end


#############################################################################

class Window_JobsTaking < Window_Base
 
  def initialize()
    @jobs = $Window_JobsInfo.setjobs
    maino
  end
 
  if Input.trigger?(Input::C) #Do the following if ENTER is pressed...
   case @jobs_taking.index
    when 0 # Confirm
         if $game_party.accepted?(@jobs) == false
          unless $uptake == Reygekan::JOB_LIMIT
           $game_party.accept_job(@jobs)
            @command_window.active = false
            @command_window.visible = false
            @selection = false
          end
        end
      when 1 #Ignore
        @command_window.active = false
        @command_window.visible = false
        @selection = false
    end
  end
end
###############################################################

class Bitmap
 
  def slice_text(text, width)
    words = text.split(' ')
    return words if words.size == 1
    result, current_text = [], words.shift
    words.each_index {|i|
        if self.text_size("#{current_text} #{words}").width > width
          result.push(current_text)
          current_text = words
        else
          current_text = "#{current_text} #{words}"
        end
        result.push(current_text) if i >= words.size - 1}
    return result
  end
 
end

ForeverZer0

Probably the order of the update method. It is never being made active. One pointer is instead of a bunch of

if .. return end

Forget the returns, and seperate the different branches with if .. elsif ... elsif .. end. That may even be your problem. Also try changing the order for what is checking for first in that method.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

nathmatt

ok after going through your script i have a few suggestions / fixes

  • when you press on the job list and you have no jobs make a buzzer sound

  • in the spot where you used slice_text you forgot to use
text[i]
    instead of just text[/li]
  • you forgot to update @jobs_taking when it doesn't = nil and you don't have it disposed when id doesn't = nil

  • you can't use Input.trigger?(Input::B) to press the b button i suggest just defining a cancel

  • you don't have to use x == false of x == true you can use just x for true and !x for false

  • the only other thing i noticed was you forgot to add @s to some of you variables

Join Dead Frontier
Sorry, I will no longer be scripting for RMXP. I may or may not give support for my scripts. I don't have the will to script in RGSS anymore.
My script


Reygekan

October 26, 2010, 03:57:14 pm #3 Last Edit: October 26, 2010, 04:13:40 pm by Reygekan
Thanks both of you, I've managed to get it mostly fully working now. :D