Jump to content
New account registrations are disabed. This website is now an archive. Read more here.
Sign in to follow this  
kerkidas

Fable III style Choices

Recommended Posts

Hi everyone,

 

I want to make the dialog choices behave as in games like fable. Specifically:

 

-You have to hold down the button.

-An animation appears

-After a specific time interval, the animation changes and releasing the button makes the choice.

-Releasing the button earlier cancels the action.

 

I tried messing with Window_Selectable and failed. I am using SDK 2.3 and AMS R4. It was like I didn't change anything.

When tried to do the same in a vanilla project, it crashed. I know in theory how to do this, I don't understand why it's not working.

 

I know this is very easy to do. Someone please help.

Edited by kerkidas

Share this post


Link to post
Share on other sites

i have been messing around with window_message, at the moment it checks if the input is repeated then it counts down the timer, when the timer equals 0 it continues as normal, the problem is getting it to cancel if you let go of the button, heres the code at the moment:

 

 

#==============================================================================
# ** Window_Message
#------------------------------------------------------------------------------
#  This message window is used to display text.
#==============================================================================
class Window_Message < Window_Selectable
 attr_reader :timer
 #--------------------------------------------------------------------------
 # * Object Initialization
 #--------------------------------------------------------------------------
 alias init_init initialize
 def initialize
   init_init
   @timer = 0
 end
 #--------------------------------------------------------------------------
 # * Frame Update
 #--------------------------------------------------------------------------
 def update
   super
   # If fade in
   if @fade_in
  self.contents_opacity += 24
  if @input_number_window != nil
    @input_number_window.contents_opacity += 24
  end
  if self.contents_opacity == 255
    @fade_in = false
  end
  return
   end
   # If inputting number
   if @input_number_window != nil
  @input_number_window.update
  # Confirm
  if Input.trigger?(Input::C)
    $game_system.se_play($data_system.decision_se)
    $game_variables[$game_temp.num_input_variable_id] =
	  @input_number_window.number
    $game_map.need_refresh = true
    # Dispose of number input window
    @input_number_window.dispose
    @input_number_window = nil
    terminate_message
  end
  return
   end
   # If message is being displayed
   if @contents_showing
  # If choice isn't being displayed, show pause sign
  if $game_temp.choice_max == 0
    self.pause = true
  end
  # Cancel
  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)
	  terminate_message
    end
  end






  # Confirm
  if Input.trigger?(Input::C)# && @timer == 0
    if $game_temp.choice_max > 0
	  $game_system.se_play($data_system.decision_se)
	  @timer = 100
    else
	  terminate_message
    end
  end

  if @timer > 0
    if Input.repeat?(Input::C)
	  $game_system.se_play($data_system.decision_se)
	  @timer -= 1
	  if @timer == 0
	    $game_temp.choice_proc.call(self.index)
	    terminate_message
	  end
    end
  end
  return
   end






   # If display wait message or choice exists when not fading out
   if @fade_out == false and $game_temp.message_text != nil
  @contents_showing = true
  $game_temp.message_window_showing = true
  reset_window
  refresh
  Graphics.frame_reset
  self.visible = true
  self.contents_opacity = 0
  if @input_number_window != nil
    @input_number_window.contents_opacity = 0
  end
  @fade_in = true
  return
   end
   # If message which should be displayed is not shown, but window is visible
   if self.visible
  @fade_out = true
  self.opacity -= 48
  if self.opacity == 0
    self.visible = false
    @fade_out = false
    $game_temp.message_window_showing = false
  end
  return
   end
 end
end

 

 

the problem is that if i put an else branch for the button repeat it runs it no matter what as the repeat process calls the input method rather than checking a value, anyways just letting you know how im going with this :)

Share this post


Link to post
Share on other sites

Thank you so much for taking the time to help me man.

 

I think I fixed that problem, I added this:

if Input.press?(Input::C) == false
		@timer = 100
end

I found out in documentation that input.press checks the value needed.

 

I have another issue though. The script is incompatible with AMS for some reason. It does nothing if put before AMS and it crashes if put after AMS. Works perfect without AMS. I could not figure out why.

 

If it will make things easier, I don't necessarily have to replace the original choice dialog, I don't mind calling it with the script command seperately.

Edited by kerkidas

Share this post


Link to post
Share on other sites

when you say AMS i guess you mean this one :http://www.rmxpunlimited.net/forums/topic/30-advanced-message-script-release-4/ ?

if that's the case i can very easily see the problem, we are both completely overriding the update method, so if you put my edit before his, my edit is cancelled, if you put it after it, it overrides theirs breaking the rest of their script, I could apply the edits directly to the AMS for compatibility if you like, as for the animation that you want to be played when prompting the player to Input the button, do you want it to be shown inside the selection box? also for accessibilty i could make a trigger so it can easily be turned on and off, and i could set a randomizer for the button input

Share this post


Link to post
Share on other sites

Yes, that's the one. I hadn't noticed it overrides the whole method. It's okay, I think I can apply the edits on ams myself (besides I have to because I already have changed other things on it).

 

Normally I'd need the animation outside the box, but just in case let me know how to switch it.

((My plan with animations is basically to display them in mid-screen(like in fable) and then try to make a seperate window for the text of each choice to be displayed below. I'm not sure I'll be able to do that (and I know it's too much to ask another to do it) ))

 

The trigger thing sounds good.

What would the randomizer for the button input do?

Share this post


Link to post
Share on other sites

well the way i would probably do it is create a seperate window that contains your animations, turn the opacity to 0, and show/hide it depending whever you need it, the way i would probably do the randomizer is when you initially press C you see it sets the wait count to 100(or however long the animation will last) before you set the wait count i would randomize the Input, ill show u an example of how i would do this in the already existing code:

if Input.trigger?(Input::C)
    if $game_temp.choice_max > 0
	  if self.index != $game_temp.choice_cancel_type - 1
	    $game_system.se_play($data_system.decision_se)
	    @randomizer = rand(5)
	    case @randomizer
	    when 0
		  @input = Input::C
	    when 1
		  @input = Input::B
	    #ect
	    end
	    @timer = 100
	  else
	    $game_system.se_play($data_system.decision_se)
	    $game_temp.choice_proc.call(self.index)
	    terminate_message
	  end
    else
	  terminate_message
    end
  end

  if @timer > 0
    if Input.press?(@randomizer)
	  $game_system.se_play($data_system.decision_se)
	  @timer -= 1
	  if @timer == 0
	    $game_temp.choice_proc.call(self.index)
	    terminate_message
	  end
    else
	  @timer = 0
	  terminate_message
    end
  end
  return
   end

so you can see rand(5) sets a random number between 0 and 4 then i set the case branch to change @input to whatever the random value returns, then when checking for the Input down below it checks @input therefore checking a randomly generated Input :)

you will also notice i added this case: if self.index != $game_temp.choice_cancel_type - 1

that is basicly saying if the index is other than the cancel command then procceed, if not cancel like normal rather than running the timers.

if you have any troubles i dont mind helping, i like the practice in scripting :)

Share this post


Link to post
Share on other sites

if you dont want random Inputs scratch what i said, i have never played fable 3 so i dont understand how the system works, i just guessed that when prompting for an input to be held it would randomly generate it, like most games that suddenly prompt for a button to be bashed/held

Share this post


Link to post
Share on other sites

Look at 5:26 or 10:27 to see what I wanted to mimic. http://www.youtube.com/watch?v=j1EnL52NwpY

 

So it would randomize WHICH button to press when asked? While this is probably useless for dialog choices, it would be pretty amazing in an action sequence. I don't need this for that script(to answer your question), but you've definitely given me ideas. I think I will try that.

 

Long story short, I don't need the randomizer, but thank you for letting me know of the ability.

 

Actually you've already given me what I need. Just a couple of questions: Is there command for displaying an animation outside any window? Is there a command to stop displaying it? Or do I have to make everything inside skinless windows and make the windows disappear when I want to get rid of the animation?

Edited by kerkidas

Share this post


Link to post
Share on other sites

well a window would have to be created to display the animation in, then you would have to edit Scene_Map to enable/disable viewing the animation, the tricky part is creating the animation, heres an example of how i would do it, its not perfect to fit your scenario but it works within context and you can work of it:

first the new window for the animation:

 

#============================================================================
# * Window Button Animation
#============================================================================
class Window_Button_Animation < Window_Base
 #--------------------------------------------------------------------------
 # * Initialize
 #--------------------------------------------------------------------------
 def initialize
@bitmap = RPG::Cache.picture("your image name") #from the pictures directory
@frame_count = Graphics.frame_count
#Gets the number of frames from the image
@frames = @bitmap.width / @bitmap.height
#Get's the frame height
@frame_height = @bitmap.height
#Get's the frame width;
@frame_width = @bitmap.width / @frames
super(0, 0, @frame_width + 32, @frame_height + 32)
self.contents = Bitmap.new(width - 32, height - 32)
#self.opacity = 0
self.visible = false
self.active = false
refresh
 end
 #--------------------------------------------------------------------------
 # * frame Update
 #--------------------------------------------------------------------------
 def update
super
refresh
 end
 #--------------------------------------------------------------------------
 # * Refresh
 #--------------------------------------------------------------------------
 def refresh
#Gets the bitmap frames and settings
self.contents.clear
time = Graphics.frame_count - @frame_count
if time >= 10
  #Save the current frame count
  @frame_count = Graphics.frame_count
  #Get the next frame
  rect = Rect.new(@frame * @frame_width, 0, @frame_width, @frame_height)
  #Displays the image
  self.contents.blt(0, 0, @bitmap, rect, 255)
  #Increase the current frame
  @frame += 1
  # if its the end of the frame
  if @frame == @frames
	@frame = 0
  end
else #if its the same frame;
  #Get the next frame
  rect = Rect.new(@frame * @frame_width, 0, @frame_width, @frame_height)
  #Displays the image
  self.contents.blt(0, 0, @bitmap, rect, 255)
end
 end
end

 

then the edited scene map:

 

class Scene_Map
 #--------------------------------------------------------------------------
 # * Main Processing
 #--------------------------------------------------------------------------
 def main
# Make sprite set
@spriteset = Spriteset_Map.new
# Make message window
@message_window = Window_Message.new



@button_animation = Window_Button_Animation.new
@button_animation.x = (640 - @button_animation.width) / 2
@button_animation.y = @message_window.y - @button_animation.height



# Transition run
Graphics.transition
# Main loop
loop do
  # Update game screen
  Graphics.update
  # Update input information
  Input.update
  # Frame update
  update
  # Abort loop if screen is changed
  if $scene != self
	break
  end
end
# Prepare for transition
Graphics.freeze
# Dispose of sprite set
@spriteset.dispose
# Dispose of message window
@message_window.dispose



@button_animation.dispose



# If switching to title screen
if $scene.is_a?(Scene_Title)
  # Fade out screen
  Graphics.transition
  Graphics.freeze
end
 end
 #--------------------------------------------------------------------------
 # * Frame Update
 #--------------------------------------------------------------------------
 def update
# Loop
loop do
  # Update map, interpreter, and player order
  # (this update order is important for when conditions are fulfilled
  # to run any event, and the player isn't provided the opportunity to
  # move in an instant)
  $game_map.update
  $game_system.map_interpreter.update
  $game_player.update
  # Update system (timer), screen
  $game_system.update
  $game_screen.update
  # Abort loop if player isn't place moving
  unless $game_temp.player_transferring
	break
  end
  # Run place move
  transfer_player
  # Abort loop if transition processing
  if $game_temp.transition_processing
	break
  end
end
# Update sprite set
@spriteset.update
# Update message window
@message_window.update
# If game over
if $game_temp.gameover
  # Switch to game over screen
  $scene = Scene_Gameover.new
  return
end
# If returning to title screen
if $game_temp.to_title
  # Change to title screen
  $scene = Scene_Title.new
  return
end
# If transition processing
if $game_temp.transition_processing
  # Clear transition processing flag
  $game_temp.transition_processing = false
  # Execute transition
  if $game_temp.transition_name == ""
	Graphics.transition(20)
  else
	Graphics.transition(40, "Graphics/Transitions/" +
	  $game_temp.transition_name)
  end
end
# If showing message window
if $game_temp.message_window_showing



  if @message_window.timer > 0
	@button_animation.update
	@button_animation.active = true
	@button_animation.visible = true
  else
	@button_animation.active = false
	@button_animation.visible = false
  end



  return
end
# If encounter list isn't empty, and encounter count is 0
if $game_player.encounter_count == 0 and $game_map.encounter_list != []
  # If event is running or encounter is not forbidden
  unless $game_system.map_interpreter.running? or
		 $game_system.encounter_disabled
	# Confirm troop
	n = rand($game_map.encounter_list.size)
	troop_id = $game_map.encounter_list[n]
	# If troop is valid
	if $data_troops[troop_id] != nil
	  # Set battle calling flag
	  $game_temp.battle_calling = true
	  $game_temp.battle_troop_id = troop_id
	  $game_temp.battle_can_escape = true
	  $game_temp.battle_can_lose = false
	  $game_temp.battle_proc = nil
	end
  end
end
# If B button was pressed
if Input.trigger?(Input::B)
  # If event is running, or menu is not forbidden
  unless $game_system.map_interpreter.running? or
		 $game_system.menu_disabled
	# Set menu calling flag or beep flag
	$game_temp.menu_calling = true
	$game_temp.menu_beep = true
  end
end
# If debug mode is ON and F9 key was pressed
if $DEBUG and Input.press?(Input::F9)
  # Set debug calling flag
  $game_temp.debug_calling = true
end
# If player is not moving
unless $game_player.moving?
  # Run calling of each screen
  if $game_temp.battle_calling
	call_battle
  elsif $game_temp.shop_calling
	call_shop
  elsif $game_temp.name_calling
	call_name
  elsif $game_temp.menu_calling
	call_menu
  elsif $game_temp.save_calling
	call_save
  elsif $game_temp.debug_calling
	call_debug
  end
end
 end
end

 

have a look what i did there and you should be able to use those to get what you need, just remember your going to have to make sure that the window message has a reading method for the timer variable so the other classes can read it like so:

class Window_Message < Window_Selectable
 attr_reader: timer
 #then everything else
end

the way the animation works is it divides the width by the height, and thats what the frames are divided into

Edited by diagostimo

Share this post


Link to post
Share on other sites

i dont think showing an animation from the animation system is as simple as a quick script call, looking at the battle scenes, all the data is obtained from RPG:Sprite, and it is all designed to target the Sprites, i think it would be more bother than worth trying to use the default animation system, and would require a new window to contain it in anyway, the method i gave you makes it so you can completely and easily customize your animation

Edited by diagostimo

Share this post


Link to post
Share on other sites

I see. Well, I merged the script on AMS and it's working perfectly, doing exactly what I needed.

 

Thanks a lot diagostimo! You've been a great help, and I really appreciate you taking the time to help me.

For what it's worth, I'll credit you in my game.smile.png

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...