RPG maker are full of internal bugs. Some have a known solution and others not yet. That's why I decided to make some sort of a compilation of them and I tried also to fix some.
I will post some of them, you can do the same.
Here's a template
[size=18pt][b][u][Maker] Bug's name[/u][/b][/size]
[size=14pt][b]Description[/b][/size]
> Short description of the bug <
[size=14pt][b]Examples[/b][/size]
> Examples about the problem (optional) <
[size=14pt][b]Screenshots[/b][/size]
> Only if it's necessary to understand the bug <
[size=14pt][b]Solution[/b][/size]
> If there is not a solution specify it <
[XP] Interpreter Script Call BugDescriptionOn Script Call from events, when the final eval is 'false' the game crashes.
Examples$game_system.timer_working = false
There are some ways to avoid it but it's not a real solution for the bug
SolutionThere is an official bugfix for this internal bug; Interpreter Script Call Fix (http://forum.chaos-project.com/index.php/topic,938.0.html)
[XP] Float Speed BugDescriptionIf you change the speed of the player to a float, the map and the events do not scroll exactly overlapped.
Screenshots(http://s24.postimg.org/y7yovlwtx/bug.png)
SolutionThere is not a known solution for this bug.
[XP] F12 Stack Level Too DeepDescriptionIf you press F12 in-game the game has to stop and go to the Title Screen. But sometimes the game will crash with a 'stack level too deep' exception.
SolutionIt's an alias problem. What you have to do is simple; look for all the 'alias' in your scripts, for example
and add 'unless $@' on the back.
alias nmode7_setup setup unless $@
[XP] The 'Remove and restore Sprite Battler' problemDescriptionOn battle, if you call a common event to remove an actor and later you call another common event (for example with an item) to get him again to the party (easy way to do an invocation system) its sprite reappears in the same place as before and it should not (I didn't found this bug and I don't understand exactly how it's supposed to work, sorry)
SolutionQuote from: OrochiiI found the problem. That is solved with one line of code in the right place...
Find this on Sprite_Battler:
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
# If battler is nil
if @battler == nil
self.bitmap = nil
loop_animation(nil)
return
end
And replace that with this:
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
super
# If battler is nil
if @battler == nil
@battler_name = nil
self.bitmap = nil
loop_animation(nil)
return
end
This solves the problem. What happens is that the game deletes the image but not the variable that tells which image is loaded. So when you restore the same hero the script does not reload the image because it thinks the image was already loaded. I added @battler_name = nil so the variable is cleared too.
The new bugfix of 'Screen animation to multiple sprites' by LittleDrago fixes this one too.
[XP] The 'Teleport and Collision' weird problemDescriptionYou are in a map (Map1) which has an event that teleports you wherever in the Map2. In the same coordinates than the event but in Map2 there's another event with collision condition which does whatever. That second event should not be activated, but it is.
SolutionPut this above main:
class Game_Event
alias transferring_fix_cet_auto check_event_trigger_auto unless $@
def check_event_trigger_auto
if @trigger == 2 and $game_temp.transition_processing
return
end
transferring_fix_cet_auto
end
end
[XP] Parallel process in the first mapDescriptionWhen you initialize a new game from the title things are loaded is that sequence:
1) Events with Parallel Process start working
2) Transition from Title Screen to the game (20 frames)
3) $game_map and all its things are loaded
4) Auto-start Events, map's music, etc. start working
The problem is, if you start a parallel process which uses something related to the map, $game_map was not loaded yet when it starts so the game crashes, and if you use an Auto-start to solve that, it starts when the transition was done so maybe it will look bad. Also if you use a script call with 'if $scene.is_a?(Scene_Map)' or you use a 'Wait x frames', to try to solve the problem.
SolutionI did an script for an engine of my game and by chance this fixes the problem, but the fix by LittleDrago is much more concise.
Put the script above main:
#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
# This class performs map screen processing.
#==============================================================================
class Scene_Map
#--------------------------------------------------------------------------
# * Constant
#--------------------------------------------------------------------------
Nothing = Struct.new(:update,:dispose)
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:main_parallel_process_fix, :main)
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
init_parallel_process_fix
main_parallel_process_fix
end
#--------------------------------------------------------------------------
# * init_parallel_process_fix
#--------------------------------------------------------------------------
def init_parallel_process_fix
Input.update
@spriteset = Nothing.new
update_systems
transfer_player if $game_temp.player_transferring
return $scene = Scene_Gameover.new if $game_temp.gameover
return $scene = Scene_Title.new if $game_temp.to_title
end
#--------------------------------------------------------------------------
# * update_systems
#--------------------------------------------------------------------------
def update_systems
$game_map.update
$game_system.map_interpreter.update
$game_player.update
$game_system.update
$game_screen.update
end
end
[XP] Screen animation to multiple spritesDescriptionWhen a screen animation (position == 3) is shown to different sprites at the same time, it is displayed overlapping itself and it should be displayed just once.
SolutionEdit: New script by LiTTleDRAgo
Put the script above main:
#==============================================================================
# ** Sprite_Battler
#------------------------------------------------------------------------------
# This sprite is used to display the battler.It observes the Game_Character
# class and automatically changes sprite conditions.
#==============================================================================
class Sprite_Battler
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:update_fix_animation, :update)
$@ || alias_method(:animation_set_sprites_fix, :animation_set_sprites)
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update(*args)
if @battler.nil?
@battler_name = nil
elsif @battler_visible && @battler.animation_id != 0
@disable_animation = @battler.instance_variable_get(:@disable_animation)
end
update_fix_animation(*args)
end
#--------------------------------------------------------------------------
# * Animation Set Sprites
#--------------------------------------------------------------------------
def animation_set_sprites(sp, *args)
return sp[0..15].each {|s| s && s.visible = false } if @disable_animation
animation_set_sprites_fix(sp, *args)
end
end
#==============================================================================
# ** Scene_Battle
#------------------------------------------------------------------------------
# This class performs battle screen processing.
#==============================================================================
class Scene_Battle
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:update_phase4_step4_fix, :update_phase4_step4)
#--------------------------------------------------------------------------
# * Frame Update (main phase step 4 : animation for target)
#--------------------------------------------------------------------------
def update_phase4_step4(*args)
if @animation2_id != 0
@target_battlers.each_with_index do |s,i|
s.instance_variable_set(:@disable_animation,false)
if i > 0 && $data_animations[@animation2_id].position == 3
s.instance_variable_set(:@disable_animation,true)
end
end
end
update_phase4_step4_fix(*args)
end
end
[XP] Disabling skills State bugDescriptionThere's a type of states restriction which disables the usage of skills to the actor (usually used as the "silence" state). But it doesn't work in the menu because the variable restriction when disabling skills equals 1 and the Skills on menu is disabled when it equals >= 2 by default (so it's so easy, if you change that to >= 1 it will work well). But the problem is the next one: You can go to the Skills scene from an actor who has not the state and with Q / W change to another actor who has the state.
SolutionPut this LiTTleDRAgo's script above main:
#==============================================================================
# ** Scene_Menu
#------------------------------------------------------------------------------
# This class performs menu screen processing.
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:update_status_fix, :update_status)
#--------------------------------------------------------------------------
# * Frame Update (when status window is active)
#--------------------------------------------------------------------------
def update_status(*args)
if Input.trigger?(Input::C)
case @command_window.index
when 1 # skill
restrict = $game_party.actors[@status_window.index].restriction >= 1
return $game_system.se_play($data_system.buzzer_se) if restrict
$game_system.se_play($data_system.decision_se)
return $scene = Scene_Skill.new(@status_window.index)
end
end
update_status_fix(*args)
end
end
#==============================================================================
# ** Scene_Skill
#------------------------------------------------------------------------------
# This class performs skill screen processing.
#==============================================================================
class Scene_Skill
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:update_skill_fix, :update_skill)
#--------------------------------------------------------------------------
# * Frame Update (if skill window is active)
#--------------------------------------------------------------------------
def update_skill(*args)
return update_skill_lr(1) if Input.trigger?(Input::R)
return update_skill_lr(-1) if Input.trigger?(Input::L)
update_skill_fix(*args)
end
#--------------------------------------------------------------------------
# * update_skill_lr
#--------------------------------------------------------------------------
def update_skill_lr(type = 1)
return if $game_party.actors.size == 1
actor = @actor_index
loop do
@actor_index = (@actor_index + type) % $game_party.actors.size
break unless $game_party.actors[@actor_index].restriction >= 1
break if @actor_index == actor
end
return $game_system.se_play($data_system.buzzer_se) if @actor_index == actor
$game_system.se_play($data_system.cursor_se)
$scene = Scene_Skill.new(@actor_index)
end
end
[XP] Enemy Action Regarding SkillsDescriptionIf any enemy has the ability to use a skill, it will add it as a potential action it can make regardless if the enemy is even capable of using the skill in the first place (e.g. not enough SP, silenced, etc.).
ExamplesGive an enemy the ability to do a normal attack and use a skill that requires SP. Make it so that the enemy has enough SP to only use the skill once. Make sure both actions have a similar priority. Go into battle and notice that the enemy sometimes skips their turn.
SolutionIn Game_Enemy, find the method
make_action and replace EVERYTHING below it with this:
def make_action
# Clear current action
self.current_action.clear
# If unable to move
unless self.movable?
# End Method
return
end
# Extract current effective actions
available_actions = []
rating_max = 0
for action in self.actions
# Confirm can use skill
if action.kind == 1 && !skill_can_use?(action.skill_id)
next
end
# Confirm turn conditions
n = $game_temp.battle_turn
a = action.condition_turn_a
b = action.condition_turn_b
if (b == 0 and n != a) or
(b > 0 and (n < 1 or n < a or n % b != a % b))
next
end
# Confirm HP conditions
if self.hp * 100.0 / self.maxhp > action.condition_hp
next
end
# Confirm level conditions
if $game_party.max_level < action.condition_level
next
end
# Confirm switch conditions
switch_id = action.condition_switch_id
if switch_id > 0 and $game_switches[switch_id] == false
next
end
# Add this action to applicable conditions
available_actions.push(action)
if action.rating > rating_max
rating_max = action.rating
end
end
# Calculate total with max rating value at 3 (exclude 0 or less)
ratings_total = 0
for action in available_actions
if action.rating > rating_max - 3
ratings_total += action.rating - (rating_max - 3)
end
end
# If ratings total isn't 0
if ratings_total > 0
# Create random numbers
value = rand(ratings_total)
# Set things that correspond to created random numbers as current action
for action in available_actions
if action.rating > rating_max - 3
if value < action.rating - (rating_max - 3)
self.current_action.kind = action.kind
self.current_action.basic = action.basic
self.current_action.skill_id = action.skill_id
self.current_action.decide_random_target_for_enemy
return
else
value -= action.rating - (rating_max - 3)
end
end
end
end
end
end
[XP][VX][VXA] Testing for File Existence in Encrypted GamesDescriptionEncrypted games cannot use methods like [tt]FileTest.exist?[/tt] or [tt]File.open[/tt].
ExamplesIf using RMXP, add
print FileTest.exist?("Data/Scripts.rxdata")
to the top of [tt]Main[/tt]. Encrypt your game. Then run the encrypted game. It should say
false.
SolutionLiTTleDRAgo provided a work-around here: https://pastebin.com/krvZgfPj
Good topic I'm going to stick it.
I didn't know about the float thing, I think it can apply to a script I made where the animations seem to be off center when scrolling. Thanks for this, though I'm not sure I understand the collision one.
Is it something like teleporting from the edge of a mapA to the edge of another mapB, and activating the teleport on the other mapB causing an annoying loop of teleports?
If so, then thanks again because I had no idea that was a bug o.o
You are in coordinates [7, 6] and start a teleportation to another map, on new coordinates [3, 3].
There's a collision event on the second map, on coordinates [7, 6]. That event technically was not touched because your coordinates in the second map were always [3, 3], but the event is activated. That's the bug.
With the script, while the player is teleporting collision events can't be activated.
Quote from: Wecoc on August 15, 2014, 08:29:43 pm
[XP] Screen animation to multiple spritesDescriptionWhen a screen animation (position == 3) is shown to different sprites at the same time, it is displayed overlapping itself and it should be displayed just once.
SolutionIt's a huge script for that little bug, I'm sorry.
Put the script above main:
module RPG
class Sprite < ::Sprite
def animation(animation, hit=true, show=true)
dispose_animation
@_animation = animation
return if @_animation == nil
@_animation_hit = hit
@_animation_duration = @_animation.frame_max
animation_name = @_animation.animation_name
animation_hue = @_animation.animation_hue
bitmap = RPG::Cache.animation(animation_name, animation_hue)
if @@_reference_count.include?(bitmap)
@@_reference_count[bitmap] += 1
else
@@_reference_count[bitmap] = 1
end
@_animation_sprites = []
if @_animation.position != 3 or not @@_animations.include?(animation)
for i in 0..15
sprite = ::Sprite.new(self.viewport)
sprite.bitmap = bitmap
sprite.visible = false
@_animation_sprites.push(sprite)
end
unless @@_animations.include?(animation)
@@_animations.push(animation)
end
end
update_animation(show)
end
def loop_animation(animation, show=true)
return if animation == @_loop_animation
dispose_loop_animation
@_loop_animation = animation
return if @_loop_animation == nil
@_loop_animation_index = 0
animation_name = @_loop_animation.animation_name
animation_hue = @_loop_animation.animation_hue
bitmap = RPG::Cache.animation(animation_name, animation_hue)
if @@_reference_count.include?(bitmap)
@@_reference_count[bitmap] += 1
else
@@_reference_count[bitmap] = 1
end
@_loop_animation_sprites = []
for i in 0..15
sprite = ::Sprite.new(self.viewport)
sprite.bitmap = bitmap
sprite.visible = false
@_loop_animation_sprites.push(sprite)
end
update_loop_animation(show)
end
def update_animation(show=true)
if @_animation_duration > 0
frame_index = @_animation.frame_max - @_animation_duration
cell_data = @_animation.frames[frame_index].cell_data
position = @_animation.position
animation_set_sprites(@_animation_sprites, cell_data, position, show)
for timing in @_animation.timings
if timing.frame == frame_index
animation_process_timing(timing, @_animation_hit)
end
end
else
dispose_animation
end
end
def update_loop_animation(show=true)
frame_index = @_loop_animation_index
cell_data = @_loop_animation.frames[frame_index].cell_data
position = @_loop_animation.position
animation_set_sprites(@_loop_animation_sprites, cell_data, position, show)
for timing in @_loop_animation.timings
if timing.frame == frame_index
animation_process_timing(timing, true)
end
end
end
def animation_set_sprites(sprites, cell_data, position, show=true)
for i in 0..15
sprite = sprites[i]
pattern = cell_data[i, 0]
if sprite == nil or pattern == nil or pattern == -1
sprite.visible = false if sprite != nil
next
end
sprite.visible = show
sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192)
if position == 3
if self.viewport != nil
sprite.x = self.viewport.rect.width / 2
sprite.y = self.viewport.rect.height - 160
else
sprite.x = 320
sprite.y = 240
end
else
sprite.x = self.x - self.ox + self.src_rect.width / 2
sprite.y = self.y - self.oy + self.src_rect.height / 2
sprite.y -= self.src_rect.height / 4 if position == 0
sprite.y += self.src_rect.height / 4 if position == 2
end
sprite.x += cell_data[i, 1]
sprite.y += cell_data[i, 2]
sprite.z = 2000
sprite.ox = 96
sprite.oy = 96
sprite.zoom_x = cell_data[i, 3] / 100.0
sprite.zoom_y = cell_data[i, 3] / 100.0
sprite.angle = cell_data[i, 4]
sprite.mirror = (cell_data[i, 5] == 1)
sprite.opacity = cell_data[i, 6] * self.opacity / 255.0
sprite.blend_type = cell_data[i, 7]
end
end
end
end
class Game_Battler
attr_accessor :show_animation
alias show_animation_ini initialize unless $@
def initialize(*args)
show_animation_ini(*args)
@show_animation = true
end
end
class Scene_Battle
def update_phase4_step4
if @animation2_id != 0 and $data_animations[@animation2_id].position == 3
for target in @target_battlers
target.show_animation = false
end
end
for target in @target_battlers
target.animation_id = @animation2_id
target.animation_hit = (target.damage != "Miss")
end
@wait_count = 8
@phase4_step = 5
end
end
class Sprite_Battler < RPG::Sprite
def update
super
if @battler == nil
@battler_name = nil
self.bitmap = nil
loop_animation(nil)
return
end
if @battler.battler_name != @battler_name or
@battler.battler_hue != @battler_hue
@battler_name = @battler.battler_name
@battler_hue = @battler.battler_hue
self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
@width = bitmap.width
@height = bitmap.height
self.ox = @width / 2
self.oy = @height
if @battler.dead? or @battler.hidden
self.opacity = 0
end
end
if @battler.damage == nil and
@battler.state_animation_id != @state_animation_id
@state_animation_id = @battler.state_animation_id
loop_animation($data_animations[@state_animation_id])
end
if @battler.is_a?(Game_Actor) and @battler_visible
if $game_temp.battle_main_phase
self.opacity += 3 if self.opacity < 255
else
self.opacity -= 3 if self.opacity > 207
end
end
if @battler.blink
blink_on
else
blink_off
end
unless @battler_visible
if not @battler.hidden and not @battler.dead? and
(@battler.damage == nil or @battler.damage_pop)
appear
@battler_visible = true
end
end
if @battler_visible
if @battler.hidden
$game_system.se_play($data_system.escape_se)
escape
@battler_visible = false
end
if @battler.white_flash
whiten
@battler.white_flash = false
end
if @battler.animation_id != 0
animation = $data_animations[@battler.animation_id]
animation(animation, @battler.animation_hit, @battler.show_animation)
@battler.animation_id = 0
end
if @battler.damage_pop
damage(@battler.damage, @battler.critical)
@battler.damage = nil
@battler.critical = false
@battler.damage_pop = false
end
if @battler.damage == nil and @battler.dead?
if @battler.is_a?(Game_Enemy)
$game_system.se_play($data_system.enemy_collapse_se)
else
$game_system.se_play($data_system.actor_collapse_se)
end
collapse
@battler_visible = false
end
end
self.x = @battler.screen_x
self.y = @battler.screen_y
self.z = @battler.screen_z
end
end
これならどうだ?
#==============================================================================
# ** Sprite_Battler
#------------------------------------------------------------------------------
# This sprite is used to display the battler.It observes the Game_Character
# class and automatically changes sprite conditions.
#==============================================================================
class Sprite_Battler
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:update_fix_animation, :update)
$@ || alias_method(:animation_set_sprites_fix, :animation_set_sprites)
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update(*args)
if @battler.nil?
@battler_name = nil
elsif @battler_visible && @battler.animation_id != 0
@disable_animation = @battler.instance_variable_get(:@disable_animation)
end
update_fix_animation(*args)
end
#--------------------------------------------------------------------------
# * Animation Set Sprites
#--------------------------------------------------------------------------
def animation_set_sprites(sp, *args)
return sp[0..15].each {|s| s && s.visible = false } if @disable_animation
animation_set_sprites_fix(sp, *args)
end
end
#==============================================================================
# ** Scene_Battle
#------------------------------------------------------------------------------
# This class performs battle screen processing.
#==============================================================================
class Scene_Battle
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:update_phase4_step4_fix, :update_phase4_step4)
#--------------------------------------------------------------------------
# * Frame Update (main phase step 4 : animation for target)
#--------------------------------------------------------------------------
def update_phase4_step4(*args)
if @animation2_id != 0
@target_battlers.each_with_index do |s,i|
s.instance_variable_set(:@disable_animation,false)
if i > 0 && $data_animations[@animation2_id].position == 3
s.instance_variable_set(:@disable_animation,true)
end
end
end
update_phase4_step4_fix(*args)
end
end
Quote from: Wecoc on August 15, 2014, 08:29:43 pm
[XP] Parallel process in the first mapDescriptionWhen you initialize a new game from the title things are loaded is that sequence:
1) Events with Parallel Process start working
2) Transition from Title Screen to the game (20 frames)
3) $game_map and all its things are loaded
4) Auto-start Events, map's music, etc. start working
The problem is, if you start a parallel process which uses something related to the map, $game_map was not loaded yet when it starts so the game crashes, and if you use an Auto-start to solve that, it starts when the transition was done so maybe it will look bad. Also if you use a script call with 'if $scene.is_a?(Scene_Map)' or you use a 'Wait x frames', to try to solve the problem.
SolutionI did this script for an engine of my game and by chance this fixes the problem.
Put the script above main:
#==============================================================================
# ** Game_Temp
#------------------------------------------------------------------------------
# Esta clase almacena los datos temporales no incluidos en las partidas guardadas.
# Llama a "$game_temp" para acceder a las variables globales incluidas aquí.
#==============================================================================
class Game_Temp
attr_accessor :map_calling
alias map_calling_ini initialize unless $@
def initialize
@map_calling = false
map_calling_ini
end
end
#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
# This class performs map screen processing.
#==============================================================================
class Scene_Map
def main
@spriteset = Spriteset_Map.new
@message_window = Window_Message.new
$game_temp.map_calling = true
$game_temp.transition_processing = true
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
@spriteset.dispose
@message_window.dispose
if $scene.is_a?(Scene_Title)
Graphics.transition
Graphics.freeze
end
end
def update
loop do
$game_map.update
$game_system.map_interpreter.update
$game_player.update
$game_system.update
$game_screen.update
unless $game_temp.player_transferring
break
end
transfer_player
if $game_temp.transition_processing
break
end
end
@spriteset.update
@message_window.update
if $game_temp.gameover
$scene = Scene_Gameover.new
return
end
if $game_temp.to_title
$scene = Scene_Title.new
return
end
if $game_temp.transition_processing
$game_temp.transition_processing = false
if $game_temp.map_calling == true
Graphics.transition
$game_temp.map_calling = false
else
if $game_temp.transition_name == ""
Graphics.transition(20)
else
Graphics.transition(40, "Graphics/Transitions/" +
$game_temp.transition_name)
end
end
end
if $game_temp.message_window_showing
return
end
if $game_player.encounter_count == 0 and $game_map.encounter_list != []
unless $game_system.map_interpreter.running? or
$game_system.encounter_disabled
n = rand($game_map.encounter_list.size)
troop_id = $game_map.encounter_list[n]
if $data_troops[troop_id] != nil
$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 Input.trigger?(Input::B)
unless $game_system.map_interpreter.running? or
$game_system.menu_disabled
$game_temp.menu_calling = true
$game_temp.menu_beep = true
end
end
if $DEBUG and Input.press?(Input::F9)
$game_temp.debug_calling = true
end
unless $game_player.moving?
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
#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
# This class performs map screen processing.
#==============================================================================
class Scene_Map
#--------------------------------------------------------------------------
# * Constant
#--------------------------------------------------------------------------
Nothing = Struct.new(:update,:dispose)
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:main_parallel_process_fix, :main)
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
init_parallel_process_fix
main_parallel_process_fix
end
#--------------------------------------------------------------------------
# * init_parallel_process_fix
#--------------------------------------------------------------------------
def init_parallel_process_fix
@spriteset = Nothing.new
Input.update
update_systems
transfer_player if $game_temp.player_transferring
clear_flag_calling
@spriteset.dispose
return $scene = Scene_Gameover.new if $game_temp.gameover
return $scene = Scene_Title.new if $game_temp.to_title
end
#--------------------------------------------------------------------------
# * update_systems
#--------------------------------------------------------------------------
def update_systems
$game_map.update
$game_system.map_interpreter.update
$game_player.update
$game_system.update
$game_screen.update
end
#--------------------------------------------------------------------------
# * clear_flag_calling
#--------------------------------------------------------------------------
def clear_flag_calling
$game_temp.battle_calling = false
$game_temp.shop_calling = false
$game_temp.name_calling = false
$game_temp.menu_calling = false
$game_temp.save_calling = false
$game_temp.debug_calling = false
end
end
Wow, your fixes are waaay better, I will change my post.
First I thought it would be possible to apply the effect only on the first sprite but it was not, because the flash effects... so I changed all the animation methods to work only with the first sprite (only in that case) but without losing those effects.
I didn't thought about your mecanism. And I see you fixed the @battler_name = nil bug on the same script!
Well, thank you.
------
C'mon, I'm sure there are thousands of bugs and we have eight on the list!
I've fixed the bug before, but I don't have the script anymore. How about this one?
Create a troop. Put three enemies in there, make one Hidden. When you kill the other two, the battle is considered over even though the hidden is still there and fully alive. Even with a battle events, you can't make him re-appear unless enemies still exist. Example: You have a giant slime. Kill him, and two smaller slimes appear. logically, you'd just put a giant slime and two small slimes in a troop and make the small ones hidden.
Quote from: Wecoc on August 15, 2014, 08:29:43 pm[XP] Disabling skills State bugDescriptionThere's a type of states restriction which disables the usage of skills to the actor (usually used as the "silence" state). But it doesn't work in the menu because the variable restriction when disabling skills equals 1 and the Skills on menu is disabled when it equals >= 2 by default (so it's so easy, if you change that to >= 1 it will work well). But the problem is the next one: You can go to the Skills scene from an actor who has not the state and with Q / W change to another actor who has the state.
SolutionPut the script above main:
(I'm sure it can be shortened)
class Scene_Menu
def update_status
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Make command window active
@command_window.active = true
@status_window.active = false
@status_window.index = -1
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# Branch by command window cursor position
case @command_window.index
when 1 # skill
# If this actor's action limit is 2 or more
if $game_party.actors[@status_window.index].restriction >= 1 ## BUGFIX
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to skill screen
$scene = Scene_Skill.new(@status_window.index)
when 2 # equipment
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to equipment screen
$scene = Scene_Equip.new(@status_window.index)
when 3 # status
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to status screen
$scene = Scene_Status.new(@status_window.index)
end
return
end
end
end
class Scene_Skill
#--------------------------------------------------------------------------
# * Frame Update (if skill window is active)
#--------------------------------------------------------------------------
def update_skill
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Switch to menu screen
$scene = Scene_Menu.new(1)
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# Get currently selected data on the skill window
@skill = @skill_window.skill
# If unable to use
if @skill == nil or not @actor.skill_can_use?(@skill.id)
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# If effect scope is ally
if @skill.scope >= 3
# Activate target window
@skill_window.active = false
@target_window.x = (@skill_window.index + 1) % 2 * 304
@target_window.visible = true
@target_window.active = true
# Set cursor position to effect scope (single / all)
if @skill.scope == 4 || @skill.scope == 6
@target_window.index = -1
elsif @skill.scope == 7
@target_window.index = @actor_index - 10
else
@target_window.index = 0
end
# If effect scope is other than ally
else
# If common event ID is valid
if @skill.common_event_id > 0
# Common event call reservation
$game_temp.common_event_id = @skill.common_event_id
# Play use skill SE
$game_system.se_play(@skill.menu_se)
# Use up SP
@actor.sp -= @skill.sp_cost
# Remake each window content
@status_window.refresh
@skill_window.refresh
@target_window.refresh
# Switch to map screen
$scene = Scene_Map.new
return
end
end
return
end
# If R button was pressed
if Input.trigger?(Input::R) ## BUGFIX
if $game_party.actors.size == 1
# $game_system.se_play($data_system.buzzer_se)
return
end
actor_index = @actor_index
loop do
@actor_index += 1
@actor_index %= $game_party.actors.size
unless $game_party.actors[@actor_index].restriction >= 1
break
end
if @actor_index == actor_index
break
end
end
if @actor_index == actor_index
$game_system.se_play($data_system.buzzer_se)
return
end
$game_system.se_play($data_system.cursor_se)
$scene = Scene_Skill.new(@actor_index)
return
end
# If L button was pressed
if Input.trigger?(Input::L) ## BUGFIX
if $game_party.actors.size == 1
# $game_system.se_play($data_system.buzzer_se)
return
end
actor_index = @actor_index
loop do
@actor_index -= 1
@actor_index %= $game_party.actors.size
unless $game_party.actors[@actor_index].restriction >= 1
break
end
if @actor_index == actor_index
break
end
end
if @actor_index == actor_index
$game_system.se_play($data_system.buzzer_se)
return
end
$game_system.se_play($data_system.cursor_se)
$scene = Scene_Skill.new(@actor_index)
return
end
end
end
#==============================================================================
# ** Scene_Menu
#------------------------------------------------------------------------------
# This class performs menu screen processing.
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:update_status_fix, :update_status)
#--------------------------------------------------------------------------
# * Frame Update (when status window is active)
#--------------------------------------------------------------------------
def update_status(*args)
if Input.trigger?(Input::C)
case @command_window.index
when 1 # skill
restrict = $game_party.actors[@status_window.index].restriction >= 1
return $game_system.se_play($data_system.buzzer_se) if restrict
$game_system.se_play($data_system.decision_se)
return $scene = Scene_Skill.new(@status_window.index)
end
end
update_status_fix(*args)
end
end
#==============================================================================
# ** Scene_Skill
#------------------------------------------------------------------------------
# This class performs skill screen processing.
#==============================================================================
class Scene_Skill
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:update_skill_fix, :update_skill)
#--------------------------------------------------------------------------
# * Frame Update (if skill window is active)
#--------------------------------------------------------------------------
def update_skill(*args)
return update_skill_lr(1) if Input.trigger?(Input::R)
return update_skill_lr(-1) if Input.trigger?(Input::L)
update_skill_fix(*args)
end
#--------------------------------------------------------------------------
# * update_skill_lr
#--------------------------------------------------------------------------
def update_skill_lr(type = 1)
return if $game_party.actors.size == 1
actor = @actor_index
loop do
@actor_index = (@actor_index + type) % $game_party.actors.size
break unless $game_party.actors[@actor_index].restriction >= 1
break if @actor_index == actor
end
return $game_system.se_play($data_system.buzzer_se) if @actor_index == actor
$game_system.se_play($data_system.cursor_se)
$scene = Scene_Skill.new(@actor_index)
end
end
game_guy: I wonder if it was really a bug, but this solves the problem:
class Scene_Battle
alias hidden_fix_phase4_step1 update_phase4_step1 unless $@
def update_phase4_step1
troop = $game_troop.enemies
if troop.all? {|enemy| (enemy.hidden == true or enemy.hp0?)}
troop.collect {|enemy| enemy.hidden = false}
end
hidden_fix_phase4_step1
end
end
LiTTleDRAgo: Thank you again, you are contributing a lot.
I don't think it really is a bug, but it does make it more difficult to do as GG described.
As it currently is, it can act as a mechanism for enemies who "escape", therefore allowing the battle to end, but not rewarding experience, etc. It would be more intuitive to have a @hidden flag, and a separate @escaped flag.
It's not a bug I guess, but more of a design flaw.
Quote from: ForeverZer0 on August 17, 2014, 12:31:23 pm
I don't think it really is a bug, but it does make it more difficult to do as GG described.
As it currently is, it can act as a mechanism for enemies who "escape", therefore allowing the battle to end, but not rewarding experience, etc. It would be more intuitive to have a @hidden flag, and a separate @escaped flag.
something like this?
#==============================================================================
# ** Game_Enemy
#------------------------------------------------------------------------------
# This class handles enemies. It's used within the Game_Troop class
# ($game_troop).
#==============================================================================
class Game_Enemy
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :escaped # escaped flag
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:escaped_flag_addition, :escape)
#--------------------------------------------------------------------------
# * Escape
#--------------------------------------------------------------------------
def escape(*args)
@escaped = true
escaped_flag_addition(*args)
end
end
#==============================================================================
# ** Scene_Battle
#------------------------------------------------------------------------------
# This class performs battle screen processing.
#==============================================================================
class Scene_Battle
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:escaped_phase4_step1, :update_phase4_step1)
#--------------------------------------------------------------------------
# * Frame Update (main phase step 1 : action preparation)
#--------------------------------------------------------------------------
def update_phase4_step1(*args)
if (troop = $game_troop.enemies).all? {|e| (e.hidden or e.hp0?)}
troop.each {|enemy| enemy.escaped || enemy.hidden = false }
end
escaped_phase4_step1(*args)
end
end
#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
# This interpreter runs event commands. This class is used within the
# Game_System class and the Game_Event class.
#==============================================================================
class Interpreter
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:escaped_command_335, :command_335)
#--------------------------------------------------------------------------
# * Enemy Appearance
#--------------------------------------------------------------------------
def command_335(*args)
enemy = $game_troop.enemies[@parameters[0]]
enemy && enemy.escaped = false
escaped_command_335(*args)
end
end
it will automatically unhide all unescaped enemies when all visible enemies is defeated
NB : Not properly tested
LiTTleDRAgo: Like a boss! I tested that for you, it works great.
I did the VX Version:
#==============================================================================
# ** Game_Enemy
#------------------------------------------------------------------------------
# This class handles enemies. It's used within the Game_Troop class
# ($game_troop).
#==============================================================================
class Game_Enemy
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :escaped # escaped flag
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:escaped_flag_addition, :escape)
#--------------------------------------------------------------------------
# * Escape
#--------------------------------------------------------------------------
def escape(*args)
@escaped = true
escaped_flag_addition(*args)
end
end
#==============================================================================
# ** Scene_Battle
#------------------------------------------------------------------------------
# This class performs battle screen processing.
#==============================================================================
class Scene_Battle
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:escaped_battle_event, :process_battle_event)
def process_battle_event(*args)
if (troop = $game_troop.members).all? {|e| (e.hidden or e.dead?)}
troop.each {|enemy| enemy.escaped || enemy.hidden = false }
end
escaped_battle_event(*args)
end
end
#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
# This interpreter runs event commands. This class is used within the
# Game_System class and the Game_Event class.
#==============================================================================
class Game_Interpreter
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:escaped_command_335, :command_335)
#--------------------------------------------------------------------------
# * Enemy Appearance
#--------------------------------------------------------------------------
def command_335(*args)
enemy = $game_troop.members[@params[0]]
enemy && enemy.escaped = false
escaped_command_335(*args)
end
end
(I don't know if Ace needs that fix, too)
Quote from: LiTTleDRAgo on August 17, 2014, 01:24:09 pm
Quote from: ForeverZer0 on August 17, 2014, 12:31:23 pm
I don't think it really is a bug, but it does make it more difficult to do as GG described.
As it currently is, it can act as a mechanism for enemies who "escape", therefore allowing the battle to end, but not rewarding experience, etc. It would be more intuitive to have a @hidden flag, and a separate @escaped flag.
something like this?
#==============================================================================
# ** Game_Enemy
#------------------------------------------------------------------------------
# This class handles enemies. It's used within the Game_Troop class
# ($game_troop).
#==============================================================================
class Game_Enemy
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :escaped # escaped flag
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:escaped_flag_addition, :escape)
#--------------------------------------------------------------------------
# * Escape
#--------------------------------------------------------------------------
def escape(*args)
@escaped = true
escaped_flag_addition(*args)
end
end
#==============================================================================
# ** Scene_Battle
#------------------------------------------------------------------------------
# This class performs battle screen processing.
#==============================================================================
class Scene_Battle
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:escaped_phase4_step1, :update_phase4_step1)
#--------------------------------------------------------------------------
# * Frame Update (main phase step 1 : action preparation)
#--------------------------------------------------------------------------
def update_phase4_step1(*args)
if (troop = $game_troop.enemies).all? {|e| (e.hidden or e.hp0?)}
troop.each {|enemy| enemy.escaped || enemy.hidden = false }
end
escaped_phase4_step1(*args)
end
end
#==============================================================================
# ** Interpreter
#------------------------------------------------------------------------------
# This interpreter runs event commands. This class is used within the
# Game_System class and the Game_Event class.
#==============================================================================
class Interpreter
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:escaped_command_335, :command_335)
#--------------------------------------------------------------------------
# * Enemy Appearance
#--------------------------------------------------------------------------
def command_335(*args)
enemy = $game_troop.enemies[@parameters[0]]
enemy && enemy.escaped = false
escaped_command_335(*args)
end
end
it will automatically unhide all unescaped enemies when all visible enemies is defeated
NB : Not properly tested
Yes, that's actually quite perfect. Still would have been nice to been able to do a "When all enemies died" page condition inside the editor, though I suppose no one really thought of that over at Enterbrain.
Quote from: gameus on August 17, 2014, 10:45:17 pm
Yes, that's actually quite perfect. Still would have been nice to been able to do a "When all enemies died" page condition inside the editor, though I suppose no one really thought of that over at Enterbrain.
http://pastebin.com/1WP0KMRM (edited from here (http://forum.chaos-project.com/index.php/topic,13809.0.html))
How to Use
(http://i.imgur.com/oWpPUeNs.png) (http://i.imgur.com/oWpPUeN.png)
xD Thanks Drago! I wasn't actually expecting you to do it. ;p
I'm not sure if it's a bug or not
when player is unarmed (barefisted), atk will became 0 regardless the enemy and player level
Quote from: LiTTleDRAgo on August 18, 2014, 02:19:46 am
I'm not sure if it's a bug or not
when player is unarmed (barefisted), atk will became 0 regardless the enemy and player level
This should work, it's probably the easiest way.
class Game_Actor < Game_Battler
attr_accessor :basic_atk
attr_accessor :basic_animation_id
alias no_weapon_fix_ini initialize unless $@
def initialize(*args)
no_weapon_fix_ini(*args)
@basic_atk = 100
@basic_animation_id = 4
end
def base_atk
weapon = $data_weapons[@weapon_id]
return weapon != nil ? weapon.atk : @basic_atk
end
def animation2_id
weapon = $data_weapons[@weapon_id]
return weapon != nil ? weapon.animation2_id : @basic_animation_id
end
end
Another option I use in my game is not allowing actors to have no weapon.
A friend of mine some time ago did a code called 'ERON module' where each Actor had a specific (not directly used) Enemy which parameters were the actor basics without equip, and also each Enemy had a specific Actor so they were able to have equip, level... That solved this bug by far but I think the project was canceled. Anyway I have not permission to post it here, it was just an anecdote.
XP's Float Bug does have a solution.
It is based on the @real_x and @real_y using whole numbers, not @move_speed. The trouble comes from @move_speed being used to calculate @real_x and @real_y exponentially. 2 ** X in Ruby means "to the power of", or an Exponent. It comes from this line of code in def update_move.
# Convert map coordinates from map move speed into move distance
distance = 2 ** @move_speed
Move Speed 1: 2 ** 1 = 1
Move Speed 2: 2 ** 2 = 4
Move Speed 3: 2 ** 2 = 9
Move Speed 4: 2 ** 2 = 16
Move Speed 5: 2 ** 2 = 25
Move Speed 6: 2 ** 2 = 36
When the resulting value in the right column in the above example is not a whole number, it is still used to adjust @real_x and @real_y values as floats instead of whole numbers. Lets say we wanted a Move Speed of 3.5. It seems to be half way between 3 and 4. But 2 ** 3.5 = 12.25, which is not a whole number. Instead, pick a real value (x or y * 128) between 9 and 16 and get its square root, due to the exponent. Lets say 12. The square root of 12 is 3.46410161513775457705489268 and change. But that is WAY too much for an average person to put in for @move_speed = 3.5. Same problem occurs with a Move Speed of 4.5. The square root of 4.5 would be 2.12132034 and change. Again, too much for Joe Average, and the math has to be 100 accurate.
The code solution for this would be to just round the value to the next whole number.
Change
distance = 2 ** @move_speed
to
distance = (2 ** @move_speed).round
There is only 2 places where this code is used. Game_Map and Game_Character. Just CTRL+SHIFT+F for 2 **.
I discovered this while updating my Downhill Ice Deluxe [XP] script (not released at time of this post).
This was basically my try on this, but rounding the value has an obvious collateral problem; you lose "movement resolution"; 3.1 = 3.2, 3.4 = 3.5 ...
Here an example; these charas are walking (Move up) in frequence 6, and their speed is 3.0, 3.2, 3.4, 3.5, 3.6, 3.8 and 4.0
You can see the difference between rounding the value or not.
(http://s9.postimg.org/sua4my1y7/rounding.png)
One possible fix for that would be to round only the player's distance, but the player would still have that lack of "movement resolution".
Someone said me rounding the distance also has some problems on camera if you are using a "smooth-movement" script, but sincerely I didn't check that.
The other possible way to fix this would be to work always with distances directly controlling it's integer instead of the speed as a float. Anyway, I don't like so much this idea...
The character I used on the first image: http://s9.postimg.org/7i2mp9hzv/character.png
==============================
Anyway, I think I already fixed this on my game some months ago, I didn't post it here because I'm not 100% sure but I'll tell what I found ;D
All this fixes try to fit the charas movement with the current screen movement, but the one which is delayed is the screen.
Once, on my game, I tried to display a bitmap layer or a picture over the map and scroll it via script call on parallel process to fit with the map (changing display_x and display_y). The result was laggy, and because of the
3.6 speed of the player, I had the same problem. It had nothing to do with character speed, so I decided to modificate the Game_Map converting to some sort of a smooth-movement script, but "not so smooth". The result is a map scroll practically identical as the default but the picture is displayed well and lag decreases. The annoying bug also disappears. The only problem is the new script is not perfect. For example, on diagonal movement the map is too slow now...
This is the script. I'm pretty sure correcting its bugs, we would fix the problem definitelly:
#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
# This class handles the map. It includes scrolling and passable determining
# functions. Refer to "$game_map" for the instance of this class.
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :tileset_name # tileset file name
attr_accessor :autotile_names # autotile file name
attr_accessor :panorama_name # panorama file name
attr_accessor :panorama_hue # panorama hue
attr_accessor :fog_name # fog file name
attr_accessor :fog_hue # fog hue
attr_accessor :fog_opacity # fog opacity level
attr_accessor :fog_blend_type # fog blending method
attr_accessor :fog_zoom # fog zoom rate
attr_accessor :fog_sx # fog sx
attr_accessor :fog_sy # fog sy
attr_accessor :battleback_name # battleback file name
attr_accessor :display_x # display x-coordinate * 128
attr_accessor :display_y # display y-coordinate * 128
attr_accessor :need_refresh # refresh request flag
attr_reader :passages # passage table
attr_reader :priorities # prioroty table
attr_reader :terrain_tags # terrain tag table
attr_reader :events # events
attr_reader :fog_ox # fog x-coordinate starting point
attr_reader :fog_oy # fog y-coordinate starting point
attr_reader :fog_tone # fog color tone
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
@map_id = 0
@display_x = 0
@display_y = 0
end
#--------------------------------------------------------------------------
# * Setup
# map_id : map ID
#--------------------------------------------------------------------------
def setup(map_id)
# Put map ID in @map_id memory
@map_id = map_id
# Load map from file and set @map
@map = load_data(sprintf("Data/Map%03d.rxdata", @map_id))
# set tile set information in opening instance variables
tileset = $data_tilesets[@map.tileset_id]
@tileset_name = tileset.tileset_name
@autotile_names = tileset.autotile_names
@panorama_name = tileset.panorama_name
@panorama_hue = tileset.panorama_hue
@fog_name = tileset.fog_name
@fog_hue = tileset.fog_hue
@fog_opacity = tileset.fog_opacity
@fog_blend_type = tileset.fog_blend_type
@fog_zoom = tileset.fog_zoom
@fog_sx = tileset.fog_sx
@fog_sy = tileset.fog_sy
@battleback_name = tileset.battleback_name
@passages = tileset.passages
@priorities = tileset.priorities
@terrain_tags = tileset.terrain_tags
# Initialize displayed coordinates
@display_x = 0
@display_y = 0
@scroll_remain_x = 0
@scroll_remain_y = 0
@scroll_take_x = 0
@scroll_take_y = 0
# Clear refresh request flag
@need_refresh = false
# Set map event data
@events = {}
for i in @map.events.keys
@events[i] = Game_Event.new(@map_id, @map.events[i])
end
# Set common event data
@common_events = {}
for i in 1...$data_common_events.size
@common_events[i] = Game_CommonEvent.new(i)
end
# Initialize all fog information
@fog_ox = 0
@fog_oy = 0
@fog_tone = Tone.new(0, 0, 0, 0)
@fog_tone_target = Tone.new(0, 0, 0, 0)
@fog_tone_duration = 0
@fog_opacity_duration = 0
@fog_opacity_target = 0
# Initialize scroll information
@scroll_direction = 2
@scroll_rest = 0
@scroll_speed = 4
end
#--------------------------------------------------------------------------
# * Get Map ID
#--------------------------------------------------------------------------
def map_id
return @map_id
end
#--------------------------------------------------------------------------
# * Get Width
#--------------------------------------------------------------------------
def width
return @map.width
end
#--------------------------------------------------------------------------
# * Get Height
#--------------------------------------------------------------------------
def height
return @map.height
end
#--------------------------------------------------------------------------
# * Get Encounter List
#--------------------------------------------------------------------------
def encounter_list
return @map.encounter_list
end
#--------------------------------------------------------------------------
# * Get Encounter Steps
#--------------------------------------------------------------------------
def encounter_step
return @map.encounter_step
end
#--------------------------------------------------------------------------
# * Get Map Data
#--------------------------------------------------------------------------
def data
return @map.data
end
#--------------------------------------------------------------------------
# * Automatically Change Background Music and Backround Sound
#--------------------------------------------------------------------------
def autoplay
if @map.autoplay_bgm
$game_system.bgm_play(@map.bgm)
end
if @map.autoplay_bgs
$game_system.bgs_play(@map.bgs)
end
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
# If map ID is effective
if @map_id > 0
# Refresh all map events
for event in @events.values
event.refresh
end
# Refresh all common events
for common_event in @common_events.values
common_event.refresh
end
end
# Clear refresh request flag
@need_refresh = false
end
#--------------------------------------------------------------------------
# * Scroll Down
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_down(distance)
if distance > (self.height - 15) * 128 - @display_y - @scroll_remain_y
distance = (self.height - 15) * 128 - @display_y - @scroll_remain_y
end
if scrolling?
@scroll_take_y = 2 ** @scroll_speed
else
if distance.ceil % 4 == 0
@scroll_take_y = distance.ceil
elsif distance.ceil % 4 <= 2
@scroll_take_y = distance.ceil - distance.ceil % 4
else
@scroll_take_y = distance.ceil + (4 - (distance.ceil % 4))
end
end
@scroll_remain_y += distance
end
#--------------------------------------------------------------------------
# * Scroll Left
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_left(distance)
if distance > @display_x - @scroll_remain_x
distance = @display_x - @scroll_remain_x
end
if scrolling?
@scroll_take_x = 2 ** @scroll_speed
else
if distance.ceil % 4 == 0
@scroll_take_x = distance.ceil
elsif distance.ceil % 4 <= 2
@scroll_take_x = distance.ceil - distance.ceil % 4
else
@scroll_take_x = distance.ceil + (4 - (distance.ceil % 4))
end
end
@scroll_remain_x -= distance
end
#--------------------------------------------------------------------------
# * Scroll Right
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_right(distance)
if distance > (self.width - 15) * 128 - @display_x - @scroll_remain_x
distance = (self.width - 15) * 128 - @display_x - @scroll_remain_x
end
if scrolling?
@scroll_take_x = 2 ** @scroll_speed
else
if distance.ceil % 4 == 0
@scroll_take_x = distance.ceil
elsif distance.ceil % 4 <= 2
@scroll_take_x = distance.ceil - distance.ceil % 4
else
@scroll_take_x = distance.ceil + (4 - (distance.ceil % 4))
end
end
@scroll_remain_x += distance
end
#--------------------------------------------------------------------------
# * Scroll Up
# distance : scroll distance
#--------------------------------------------------------------------------
def scroll_up(distance)
if distance > @display_y - @scroll_remain_y
distance = @display_y - @scroll_remain_y
end
if scrolling?
@scroll_take_y = 2 ** @scroll_speed
else
if distance.ceil % 4 == 0
@scroll_take_y = distance.ceil
elsif distance.ceil % 4 <= 2
@scroll_take_y = distance.ceil - distance.ceil % 4
else
@scroll_take_y = distance.ceil + (4 - (distance.ceil % 4))
end
end
@scroll_remain_y -= distance
end
#--------------------------------------------------------------------------
# * Determine Valid Coordinates
# x : x-coordinate
# y : y-coordinate
#--------------------------------------------------------------------------
def valid?(x, y)
return (x >= 0 and x < width and y >= 0 and y < height)
end
#--------------------------------------------------------------------------
# * Determine if Passable
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# self_event : Self (If event is determined passable)
#--------------------------------------------------------------------------
def passable?(x, y, d, self_event = nil)
# If coordinates given are outside of the map
unless valid?(x, y)
# impassable
return false
end
# Change direction (0,2,4,6,8,10) to obstacle bit (0,1,2,4,8,0)
bit = (1 << (d / 2 - 1)) & 0x0f
# Loop in all events
for event in events.values
# If tiles other than self are consistent with coordinates
if event.tile_id >= 0 and event != self_event and
event.x == x and event.y == y and not event.through
# If obstacle bit is set
if @passages[event.tile_id] & bit != 0
# impassable
return false
# If obstacle bit is set in all directions
elsif @passages[event.tile_id] & 0x0f == 0x0f
# impassable
return false
# If priorities other than that are 0
elsif @priorities[event.tile_id] == 0
# passable
return true
end
end
end
# Loop searches in order from top of layer
for i in [2, 1, 0]
# Get tile ID
tile_id = data[x, y, i]
# Tile ID acquistion failure
if tile_id == nil
# impassable
return false
# If obstacle bit is set
elsif @passages[tile_id] & bit != 0
# impassable
return false
# If obstacle bit is set in all directions
elsif @passages[tile_id] & 0x0f == 0x0f
# impassable
return false
# If priorities other than that are 0
elsif @priorities[tile_id] == 0
# passable
return true
end
end
# passable
return true
end
#--------------------------------------------------------------------------
# * Determine Thicket
# x : x-coordinate
# y : y-coordinate
#--------------------------------------------------------------------------
def bush?(x, y)
if @map_id != 0
for i in [2, 1, 0]
tile_id = data[x, y, i]
if tile_id == nil
return false
elsif @passages[tile_id] & 0x40 == 0x40
return true
end
end
end
return false
end
#--------------------------------------------------------------------------
# * Determine Counter
# x : x-coordinate
# y : y-coordinate
#--------------------------------------------------------------------------
def counter?(x, y)
if @map_id != 0
for i in [2, 1, 0]
tile_id = data[x, y, i]
if tile_id == nil
return false
elsif @passages[tile_id] & 0x80 == 0x80
return true
end
end
end
return false
end
#--------------------------------------------------------------------------
# * Get Terrain Tag
# x : x-coordinate
# y : y-coordinate
#--------------------------------------------------------------------------
def terrain_tag(x, y)
if @map_id != 0
for i in [2, 1, 0]
tile_id = data[x, y, i]
if tile_id == nil
return 0
elsif @terrain_tags[tile_id] > 0
return @terrain_tags[tile_id]
end
end
end
return 0
end
#--------------------------------------------------------------------------
# * Get Designated Position Event ID
# x : x-coordinate
# y : y-coordinate
#--------------------------------------------------------------------------
def check_event(x, y)
for event in $game_map.events.values
if event.x == x and event.y == y
return event.id
end
end
end
#--------------------------------------------------------------------------
# * Start Scroll
# direction : scroll direction
# distance : scroll distance
# speed : scroll speed
#--------------------------------------------------------------------------
def start_scroll(direction, distance, speed)
@scroll_direction = direction
@scroll_speed = speed
@scroll_rest = distance.ceil * 128
case @scroll_direction
when 2 # Down
scroll_down(@scroll_rest)
when 4 # Left
scroll_left(@scroll_rest)
when 6 # Right
scroll_right(@scroll_rest)
when 8 # Up
scroll_up(@scroll_rest)
end
end
#--------------------------------------------------------------------------
# * Determine if Scrolling
#--------------------------------------------------------------------------
def scrolling?
return @scroll_rest > 0
end
#--------------------------------------------------------------------------
# * Start Changing Fog Color Tone
# tone : color tone
# duration : time
#--------------------------------------------------------------------------
def start_fog_tone_change(tone, duration)
@fog_tone_target = tone.clone
@fog_tone_duration = duration
if @fog_tone_duration == 0
@fog_tone = @fog_tone_target.clone
end
end
#--------------------------------------------------------------------------
# * Start Changing Fog Opacity Level
# opacity : opacity level
# duration : time
#--------------------------------------------------------------------------
def start_fog_opacity_change(opacity, duration)
@fog_opacity_target = opacity * 1.0
@fog_opacity_duration = duration
if @fog_opacity_duration == 0
@fog_opacity = @fog_opacity_target
end
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Refresh map if necessary
if $game_map.need_refresh
refresh
end
# If scrolling
if @scroll_rest > 0
@scroll_rest -= 2 ** @scroll_speed
end
if @scroll_remain_x > 0
old_display_x = @display_x
distance = [@scroll_take_x, 4].max
unless @display_x + distance > (self.width - 15) * 128
@display_x += distance
end
@scroll_remain_x += old_display_x - @display_x
if @scroll_remain_x < 0
@scroll_remain_x = 0
end
elsif @scroll_remain_x < 0
old_display_x = @display_x
distance = [@scroll_take_x, 4].max
unless @display_x - distance < 0
@display_x -= distance
end
@scroll_remain_x += old_display_x - @display_x
if @scroll_remain_x > 0
@scroll_remain_x = 0
end
end
if @scroll_remain_y > 0
old_display_y = @display_y
distance = [@scroll_take_y, 4].max
unless @display_y + distance > (self.height - 15) * 128
@display_y += distance
end
@scroll_remain_y += old_display_y - @display_y
if @scroll_remain_y < 0
@scroll_remain_y = 0
end
elsif @scroll_remain_y < 0
old_display_y = @display_y
distance = [@scroll_take_y, 4].max
unless @display_y - distance < 0
@display_y -= distance
end
@scroll_remain_y += old_display_y - @display_y
if @scroll_remain_y > 0
@scroll_remain_y = 0
end
end
# Update map event
for event in @events.values
event.update
end
# Update common event
for common_event in @common_events.values
common_event.update
end
# Manage fog scrolling
@fog_ox -= @fog_sx / 8.0
@fog_oy -= @fog_sy / 8.0
# Manage change in fog color tone
if @fog_tone_duration >= 1
d = @fog_tone_duration
target = @fog_tone_target
@fog_tone.red = (@fog_tone.red * (d - 1) + target.red) / d
@fog_tone.green = (@fog_tone.green * (d - 1) + target.green) / d
@fog_tone.blue = (@fog_tone.blue * (d - 1) + target.blue) / d
@fog_tone.gray = (@fog_tone.gray * (d - 1) + target.gray) / d
@fog_tone_duration -= 1
end
# Manage change in fog opacity level
if @fog_opacity_duration >= 1
d = @fog_opacity_duration
@fog_opacity = (@fog_opacity * (d - 1) + @fog_opacity_target) / d
@fog_opacity_duration -= 1
end
end
end
Rounding just the Player's calculated move speed would be a solution. Or perhaps .floor or .ceil as well? I havent tried it, but have played with adjusting the values after exponential calculations in Downhill Ice. Downhill Ice just adds ice_speed to real_y so it skips all that exponent stuff. I do use floating move speeds all over the place for random movement, just not for the player.
Since no one has posted it, might as well just say that changing a sprite's x/y value by a float won't work. I experienced this occurrence with smooth scrolling scripts while working on a tilemap implementation. It seems to set it as the floor value.
As a result, slowly increasing (+0.1) will do absolutely nothing whereas slowly decreasing (-0.1) will consistently keep moving the sprite left/up 1 pixel. Not sure if this is a workaround, but I think you can add two variables that actually take in the x/y changes first before physically changing the Sprite's built-in x/y attributes, kind of like what @real_ does but with floats instead.
Hi guys, long time no see.
I solved another bug with event interaction. By default the event interaction only depends on the coordinates, and this has some problems.
(http://s12.postimg.org/yac9fs8tp/event_bug.png)
With the script if the player can't go to the event position (without considering the event itself on the passability) there is not interaction.
Also using $game_map.events[ID].passable_touch = true/false you can enable or disable the fix on the event manually.
class Game_Character
attr_accessor :passable_touch
alias passable_touch_ini initialize unless $@
def initialize
passable_touch_ini
@passable_touch = false
end
def no_event_passable?(x, y, d)
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
return true if @passable_touch == true
return false unless $game_map.valid?(new_x, new_y)
return true if @through
return false unless $game_map.passable?(x, y, d, self)
return false unless $game_map.passable?(new_x, new_y, 10 - d)
return true
end
end
class Game_Event < Game_Character
alias collision_passable_fix check_event_trigger_touch unless $@
def check_event_trigger_touch(new_x, new_y)
if @x != new_x
d = (@x < new_x ? 6 : 4)
elsif @y != new_y
d = (@y < new_y ? 2 : 8)
end
if (@x == new_x) and (@y == new_y) or no_event_passable?(@x, @y, d)
collision_passable_fix(new_x, new_y)
end
end
end
class Game_Player < Game_Character
def check_event_trigger_there(triggers)
result = false
if $game_system.map_interpreter.running?
return result
end
new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
for event in $game_map.events.values
if event.x == new_x and event.y == new_y and
triggers.include?(event.trigger)
if not event.jumping? and not event.over_trigger?
passable = no_event_passable?(@x, @y, @direction)
if event.passable_touch == true or passable
event.start
result = true
end
end
end
end
if result == false
if $game_map.counter?(new_x, new_y)
new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
for event in $game_map.events.values
if event.x == new_x and event.y == new_y and
triggers.include?(event.trigger)
if not event.jumping? and not event.over_trigger?
passable = no_event_passable?(@x, @y, @direction)
if event.passable_touch == true or passable
event.start
result = true
end
end
end
end
end
end
return result
end
def check_event_trigger_touch(x, y)
result = false
if $game_system.map_interpreter.running?
return result
end
for event in $game_map.events.values
if event.x == x and event.y == y and [1,2].include?(event.trigger)
if not event.jumping? and not event.over_trigger?
passable = no_event_passable?(@x, @y, @direction)
if event.passable_touch == true or passable
event.start
result = true
end
end
end
end
return result
end
end
-----------------
I found a bug on the LittleDrago's fix called [XP] Parallel process in the first map.
The battle call from event restarts over and over...
KK20: No idea how to do that exactly.
I've done the float sprite movement a while ago. Included is a little test of it. Paste above Main.
=begin
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Allows sprites to have their x and y values changed via float values rather than
automatically converting to int.
Normally, when you change the x/y of a sprite by a Float, it will floor the
value before setting the sprite.
Examples:
sprite.x = 0.5 = floor(0.5) = 0
sprite.y = -0.5 = floor(-0.5) = -1
sprite.x = -1E10 = floor(-1E10) = -1
Also, adding a series of floats will do nothing. Look at the following:
while true
sprite.x += 0.99999
end
This will not move the sprite at all.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
=end
# Takes in a number and an amount. This will add or reduce the number by that
# amount, whatever gets it closer to 0. If it would go beyond 0, it will stop at
# 0 (and if it is already 0, it will do nothing).
# You can make the amount negative to make the number move AWAY from 0 as well.
def to0(num, amt)
# First check if the number is already 0
if num.integer?
return num if num == 0
else
return num if num =~ 0
end
# Now check whether we need to ADD or SUBTRACT to reach (or avoid) 0
if num > 0
num = [num - amt, 0].max
else
num = [num + amt, 0].min
end
end
class Float
# A close float comparison. Because of rounding errors, this comparison will
# help compensate for that. Since 0 and 0.0001 are very close to each other,
# it's best to use this custom comparison.
def =~(num)
return (self + 0.0001 >= num && self - 0.0001 <= num)
end
end
# Contains modified set methods for X/Y that allow the use of Floats
class IntFloat
attr_reader :value
def initialize(n)
@value = n
end
def to_i; @value.to_i; end
def ceil; @value.ceil; end
def floor; @value.floor; end
def to_f; @value; end
def inspect; @value.to_i; end
def +(other)
if other.is_a?(IntFloat)
r = @value + other.value
elsif other.is_a?(Integer)
r = @value.floor + other
elsif other.is_a?(Float)
r = @value + other
else
raise "Cannot perform addition on a non-numeric object!"
end
r
end
def -(other)
if other.is_a?(IntFloat)
r = @value - other.value
elsif other.is_a?(Integer)
r = @value.floor - other
elsif other.is_a?(Float)
r = @value - other
else
raise "Cannot perform subtraction on a non-numeric object!"
end
r
end
def *(other)
if other.is_a?(IntFloat)
r = @value * other.value
elsif other.is_a?(Integer)
r = @value.floor * other
elsif other.is_a?(Float)
r = @value * other
else
raise "Cannot perform multiplication on a non-numeric object!"
end
r
end
def /(other)
if other.is_a?(IntFloat)
r = @value / other.value
elsif other.is_a?(Integer)
r = @value.floor / other
elsif other.is_a?(Float)
r = @value / other
else
raise "Cannot perform division on a non-numeric object!"
end
r
end
def set(other)
if other.is_a?(IntFloat)
@value = other.value
elsif other.is_a?(Integer) || other.is_a?(Float)
@value = other
else
raise "Cannot assign to a non-numeric object!"
end
roundOff
@value
end
def roundOff
if @value.to_f.abs =~ 1
@value = @value.round
end
end
end
class Sprite
alias init_offsets initialize
def initialize(vp = nil)
@intfloat_x = IntFloat.new(0.0)
@intfloat_y = IntFloat.new(0.0)
init_offsets(vp)
end
def x; @intfloat_x; end
def y; @intfloat_y; end
alias set_x x=
def x=(amt)
@intfloat_x.set(amt)
set_x(@intfloat_x.to_i)
end
alias set_y y=
def y=(amt)
@intfloat_y.set(amt)
set_y(@intfloat_y.to_i)
end
def xInt(x)
set_x(x)
end
def yInt(y)
set_y(y)
end
def xInt=(x)
xInt(x)
end
def yInt=(y)
yInt(y)
end
def actualX
return @intfloat_x.to_f
end
def actualY
return @intfloat_y.to_f
end
end
=begin
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Just a test program with the Float sprite movement. Move a red square around the
screen. Has a standard acceleration setup that is added to the sprite's X/Y
coordinates. If using Console debugger, hold SHIFT key to see values.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
=end
begin
#Graphics.resize_screen(1024, 1024)
sprite = Sprite.new
sprite.bitmap = Bitmap.new(32,32)
sprite.bitmap.fill_rect(0,0,32,32, Color.new(255, 0, 0))
accel_x = 0.0
accel_y = 0.0
while true
Graphics.update
Input.update
input = Input.dir8
if Input.press?(Input::SHIFT)
#puts ["Sprite Location: ", sprite.x, sprite.y]
#puts ["Sprite Acutal: ",sprite.actualX, sprite.actualY]
#puts ["accel: ", accel_x, accel_y]
#puts "-------"
end
if Input.trigger?(Input::C)
sprite.y += 10
end
if Input.trigger?(Input::B)
sprite.x += 0.3
elsif Input.trigger?(Input::A)
sprite.x -= 0.3
end
# Get input and set sprite acceleration
if input != 0
if [1,2,3].include?(input)
accel_y += (accel_y >= 0 ? 0.2 : 0.5)
elsif [7,8,9].include?(input)
accel_y -= (accel_y <= 0 ? 0.2 : 0.5)
end
if [1,4,7].include?(input)
accel_x -= (accel_x <= 0 ? 0.2 : 0.5)
elsif [3,6,9].include?(input)
accel_x += (accel_x >= 0 ? 0.2 : 0.5)
end
end
# If not inputting in a desired direction, slow down in that direction
if [0,4,6].include?(input)
accel_y = to0(accel_y, 0.1).to_f
end
if [0,2,8].include?(input)
accel_x = to0(accel_x, 0.1).to_f
end
# Acceleration speed cap
if accel_y.abs > 10
accel_y = (accel_y > 0 ? 10 : -10)
end
if accel_x.abs > 10
accel_x = (accel_x > 0 ? 10 : -10)
end
# Move the sprite
sprite.x += accel_x
sprite.y += accel_y
end
end
Sorry necropost :P
Quote from: KK20 on October 04, 2015, 04:12:29 pm
I've done the float sprite movement a while ago. Included is a little test of it. Paste above Main.
=begin
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Allows sprites to have their x and y values changed via float values rather than
automatically converting to int.
Normally, when you change the x/y of a sprite by a Float, it will floor the
value before setting the sprite.
Examples:
sprite.x = 0.5 = floor(0.5) = 0
sprite.y = -0.5 = floor(-0.5) = -1
sprite.x = -1E10 = floor(-1E10) = -1
Also, adding a series of floats will do nothing. Look at the following:
while true
sprite.x += 0.99999
end
This will not move the sprite at all.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
=end
# Takes in a number and an amount. This will add or reduce the number by that
# amount, whatever gets it closer to 0. If it would go beyond 0, it will stop at
# 0 (and if it is already 0, it will do nothing).
# You can make the amount negative to make the number move AWAY from 0 as well.
def to0(num, amt)
# First check if the number is already 0
if num.integer?
return num if num == 0
else
return num if num =~ 0
end
# Now check whether we need to ADD or SUBTRACT to reach (or avoid) 0
if num > 0
num = [num - amt, 0].max
else
num = [num + amt, 0].min
end
end
class Float
# A close float comparison. Because of rounding errors, this comparison will
# help compensate for that. Since 0 and 0.0001 are very close to each other,
# it's best to use this custom comparison.
def =~(num)
return (self + 0.0001 >= num && self - 0.0001 <= num)
end
end
# Contains modified set methods for X/Y that allow the use of Floats
class IntFloat
attr_reader :value
def initialize(n)
@value = n
end
def to_i; @value.to_i; end
def ceil; @value.ceil; end
def floor; @value.floor; end
def to_f; @value; end
def inspect; @value.to_i; end
def +(other)
if other.is_a?(IntFloat)
r = @value + other.value
elsif other.is_a?(Integer)
r = @value.floor + other
elsif other.is_a?(Float)
r = @value + other
else
raise "Cannot perform addition on a non-numeric object!"
end
r
end
def -(other)
if other.is_a?(IntFloat)
r = @value - other.value
elsif other.is_a?(Integer)
r = @value.floor - other
elsif other.is_a?(Float)
r = @value - other
else
raise "Cannot perform subtraction on a non-numeric object!"
end
r
end
def *(other)
if other.is_a?(IntFloat)
r = @value * other.value
elsif other.is_a?(Integer)
r = @value.floor * other
elsif other.is_a?(Float)
r = @value * other
else
raise "Cannot perform multiplication on a non-numeric object!"
end
r
end
def /(other)
if other.is_a?(IntFloat)
r = @value / other.value
elsif other.is_a?(Integer)
r = @value.floor / other
elsif other.is_a?(Float)
r = @value / other
else
raise "Cannot perform division on a non-numeric object!"
end
r
end
def set(other)
if other.is_a?(IntFloat)
@value = other.value
elsif other.is_a?(Integer) || other.is_a?(Float)
@value = other
else
raise "Cannot assign to a non-numeric object!"
end
roundOff
@value
end
def roundOff
if @value.to_f.abs =~ 1
@value = @value.round
end
end
end
class Sprite
alias init_offsets initialize
def initialize(vp = nil)
@intfloat_x = IntFloat.new(0.0)
@intfloat_y = IntFloat.new(0.0)
init_offsets(vp)
end
def x; @intfloat_x; end
def y; @intfloat_y; end
alias set_x x=
def x=(amt)
@intfloat_x.set(amt)
set_x(@intfloat_x.to_i)
end
alias set_y y=
def y=(amt)
@intfloat_y.set(amt)
set_y(@intfloat_y.to_i)
end
def xInt(x)
set_x(x)
end
def yInt(y)
set_y(y)
end
def xInt=(x)
xInt(x)
end
def yInt=(y)
yInt(y)
end
def actualX
return @intfloat_x.to_f
end
def actualY
return @intfloat_y.to_f
end
end
=begin
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Just a test program with the Float sprite movement. Move a red square around the
screen. Has a standard acceleration setup that is added to the sprite's X/Y
coordinates. If using Console debugger, hold SHIFT key to see values.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
=end
begin
#Graphics.resize_screen(1024, 1024)
sprite = Sprite.new
sprite.bitmap = Bitmap.new(32,32)
sprite.bitmap.fill_rect(0,0,32,32, Color.new(255, 0, 0))
accel_x = 0.0
accel_y = 0.0
while true
Graphics.update
Input.update
input = Input.dir8
if Input.press?(Input::SHIFT)
#puts ["Sprite Location: ", sprite.x, sprite.y]
#puts ["Sprite Acutal: ",sprite.actualX, sprite.actualY]
#puts ["accel: ", accel_x, accel_y]
#puts "-------"
end
if Input.trigger?(Input::C)
sprite.y += 10
end
if Input.trigger?(Input::B)
sprite.x += 0.3
elsif Input.trigger?(Input::A)
sprite.x -= 0.3
end
# Get input and set sprite acceleration
if input != 0
if [1,2,3].include?(input)
accel_y += (accel_y >= 0 ? 0.2 : 0.5)
elsif [7,8,9].include?(input)
accel_y -= (accel_y <= 0 ? 0.2 : 0.5)
end
if [1,4,7].include?(input)
accel_x -= (accel_x <= 0 ? 0.2 : 0.5)
elsif [3,6,9].include?(input)
accel_x += (accel_x >= 0 ? 0.2 : 0.5)
end
end
# If not inputting in a desired direction, slow down in that direction
if [0,4,6].include?(input)
accel_y = to0(accel_y, 0.1).to_f
end
if [0,2,8].include?(input)
accel_x = to0(accel_x, 0.1).to_f
end
# Acceleration speed cap
if accel_y.abs > 10
accel_y = (accel_y > 0 ? 10 : -10)
end
if accel_x.abs > 10
accel_x = (accel_x > 0 ? 10 : -10)
end
# Move the sprite
sprite.x += accel_x
sprite.y += accel_y
end
end
I tested your code and found another issue with it.
Based on your code, of course the sprite x and y values could be changed into floats.
However, that also makes it unusable to other operation as well...
p sprite.x < 0 # throws error
p 10 + sprite.x # throws error
p sprite.x # throws IntFloat class (can't be used in numeric operation)
I think normal float variable is enough to fix float sprite movement.
#==============================================================================
# ** Sprite
#------------------------------------------------------------------------------
# A sprite class for bitmap processing.
#==============================================================================
class Sprite
#---------------------------------------------------------------------------
# * Alias Listing
#---------------------------------------------------------------------------
$@ || alias_method(:set_x_alias, :"x=")
$@ || alias_method(:set_y_alias, :"y=")
$@ || alias_method(:get_x_alias, :"x")
$@ || alias_method(:get_y_alias, :"y")
#---------------------------------------------------------------------------
# * Aliased method: x=, y=
#---------------------------------------------------------------------------
define_method(:x=) {|amt| set_x_alias((@intfloat_x = amt).to_i) }
define_method(:y=) {|amt| set_y_alias((@intfloat_y = amt).to_i) }
define_method(:x) { @intfloat_x ||= get_x_alias }
define_method(:y) { @intfloat_y ||= get_y_alias }
end
Quote from: Wecoc on October 04, 2015, 02:26:59 pm
I found a bug on the LittleDrago's fix called [XP] Parallel process in the first map.
The battle call from event restarts over and over...
Oops... Sorry I didn't look at this thread until now (that's about 2 years :O)
#==============================================================================
# ** Scene_Map
#------------------------------------------------------------------------------
# This class performs map screen processing.
#==============================================================================
class Scene_Map
#--------------------------------------------------------------------------
# * Constant
#--------------------------------------------------------------------------
Nothing = Struct.new(:update,:dispose)
#--------------------------------------------------------------------------
# * Alias Listing
#--------------------------------------------------------------------------
$@ || alias_method(:main_parallel_process_fix, :main)
#--------------------------------------------------------------------------
# * Main Processing
#--------------------------------------------------------------------------
def main
init_parallel_process_fix
main_parallel_process_fix
end
#--------------------------------------------------------------------------
# * init_parallel_process_fix
#--------------------------------------------------------------------------
def init_parallel_process_fix
@spriteset = Nothing.new
Input.update
update_systems
transfer_player if $game_temp.player_transferring
clear_flag_calling
@spriteset.dispose
return $scene = Scene_Gameover.new if $game_temp.gameover
return $scene = Scene_Title.new if $game_temp.to_title
end
#--------------------------------------------------------------------------
# * update_systems
#--------------------------------------------------------------------------
def update_systems
$game_map.update
$game_system.map_interpreter.update
$game_player.update
$game_system.update
$game_screen.update
end
#--------------------------------------------------------------------------
# * clear_flag_calling
#--------------------------------------------------------------------------
def clear_flag_calling
$game_temp.battle_calling = false
$game_temp.shop_calling = false
$game_temp.name_calling = false
$game_temp.menu_calling = false
$game_temp.save_calling = false
$game_temp.debug_calling = false
end
end
untested ~
(Dunno if that would fix the problem or not, since it seems I can't reproduce the bug)
Yeah, that was years ago though. I've refined it more somewhere in one of these many projects.
I see...
I just confirming things since I also got that same problem and found your post while searching in google.
Thank you for that post, I got inspiration because of it. :D
Thanks to Kise for reporting this: http://forum.chaos-project.com/index.php/topic,15768.0.html
Added to first post a way to make enemies disregard the use of a skill if it cannot even use it due to SP costs or disabling states.
Added a fix by LiTTleDRAgo regarding file existence testing in encrypted games.
[XP] Status Window Refreshing During Battle EventsDescriptionWhen in battle, the Window_BattleStatus keeps refreshing while a battle event is running. You can see this under Scene_Battle#update:
# If battle event is running
if $game_system.battle_interpreter.running?
# Update interpreter
$game_system.battle_interpreter.update
# If a battler which is forcing actions doesn't exist
if $game_temp.forcing_battler == nil
# If battle event has finished running
unless $game_system.battle_interpreter.running?
# Rerun battle event set up if battle continues
unless judge
setup_battle_event
end
end
# If not after battle phase
if @phase != 5
# Refresh status window
@status_window.refresh
end
end
end
SolutionA user posted a potential solution on the official RM forums: https://forums.rpgmakerweb.com/index.php?threads/rmxp-battle-text-lag.111312/#post-987292