Author Topic: About RPG maker's internal bugs  (Read 5217 times)

Offline Heretic86

  • Astral Trancist
  • *****
  • Posts: 724
  • LV: 29
    • View Profile
Re: About RPG maker's internal bugs
« Reply #20 on: October 28, 2014, 09:36:33 AM »
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.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Offline KK20

  • Master Scripter Fixer
  • Global Moderator
  • Lexima Warrior
  • ****
  • Posts: 2900
  • LV: 365
  • Gender: Male
  • Bringer of Salt
    • View Profile
Re: About RPG maker's internal bugs
« Reply #21 on: October 28, 2014, 11:16:42 AM »
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.



(click to show/hide)
NNID: KK20-CP

Offline Wecoc

  • Transcended Spirit
  • ***
  • Posts: 108
  • LV: 44
  • Gender: Male
    • View Profile
    • Mundo Maker
Re: About RPG maker's internal bugs
« Reply #22 on: October 04, 2015, 08:26:59 PM »
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.

(click to show/hide)

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.

Code: [Select]
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.

Offline KK20

  • Master Scripter Fixer
  • Global Moderator
  • Lexima Warrior
  • ****
  • Posts: 2900
  • LV: 365
  • Gender: Male
  • Bringer of Salt
    • View Profile
Re: About RPG maker's internal bugs
« Reply #23 on: October 04, 2015, 10:12:29 PM »
I've done the float sprite movement a while ago. Included is a little test of it. Paste above Main.
Code: (ruby) [Select]
=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

« Last Edit: October 06, 2016, 08:45:42 PM by KK20 »



(click to show/hide)
NNID: KK20-CP

Offline LiTTleDRAgo

  • Astral Trancist
  • *****
  • Posts: 811
  • LV: 510
  • Gender: Male
    • View Profile
    • ~
Re: About RPG maker's internal bugs
« Reply #24 on: March 18, 2017, 11:24:09 AM »
Sorry necropost :P

I've done the float sprite movement a while ago. Included is a little test of it. Paste above Main.
(click to show/hide)

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...

Code: [Select]
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.

Code: [Select]
#==============================================================================
# ** 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

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)

(click to show/hide)

untested ~
(Dunno if that would fix the problem or not, since it seems I can't reproduce the bug)

Offline KK20

  • Master Scripter Fixer
  • Global Moderator
  • Lexima Warrior
  • ****
  • Posts: 2900
  • LV: 365
  • Gender: Male
  • Bringer of Salt
    • View Profile
Re: About RPG maker's internal bugs
« Reply #25 on: March 18, 2017, 01:07:07 PM »
Yeah, that was years ago though. I've refined it more somewhere in one of these many projects.



(click to show/hide)
NNID: KK20-CP

Offline LiTTleDRAgo

  • Astral Trancist
  • *****
  • Posts: 811
  • LV: 510
  • Gender: Male
    • View Profile
    • ~
Re: About RPG maker's internal bugs
« Reply #26 on: March 18, 2017, 01:45:57 PM »
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