Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Stopping players from jumping over NPCs

I'd really love to know how I could do this, via script or eventing :)

I'm currently using this event system:
Code:
if Y is being pressed: 
> if player is facing left
>> jump 2 spaces left 
> if player is facing up
>> jump 2 spaces up
> if player is facing down
>> jump 2 spaces down
> if player is facing right
>> jump 2 spaces right

I have them ignoring if the move is impossible, waiting till the movement is over, and waiting 4 frames between each jump, but I thought I'd just give you the basic pseudocode.

Would there happen to be a script around for RMXP that can make more realistic jumps? If I recall correctly, there was one for VX.

Thanks for any help,
Megalomania
 
How about a mix of event & script?

Store the current position in 2 variables

Control Variables [0001] = Player's MAP X
Control Variables [0002] = Player's MAP Y

> if player is facing left
>> Conditional Branch: Script: $game_player.passable?($game_variables[1] - 1, $game_variables[2], 0)
>>> jump 2 spaces left
> if player is facing up
>> Conditional Branch: Script: $game_player.passable?($game_variables[1], $game_variables[2] - 1, 0)
>>> jump 2 spaces up

We could modify the passable? method, but we'd have to take into account the fact that the Jump statement parameters allow angled jumps, and different length jumps. Which would be a bit overkill for what you are trying to do.
 
Eep - sadly this doesn't allow me to jump over small narrows of water and such >.<
Sorry about neglecting to tell you that :3

But thanks for the help :D

I was thinking that with scripting, on each map I could make a parallel 'Jump allower', which basically takes the player's X, Y and Facing - and compares them to a list of tuples? Such as...

if (playerx, playery, playerfacing) in (1,3,4),(5,8,1):
> allowjump = True
else:
> allowjump = False

So playerx = variable1
playery = var2
playeracing = var3

allowjump is switch1, which controls a jump Common Event.

Could that work? :)
 
This sounds completely different than your original request of "not jumping over events".

Now it sounds like you want to make regions of the map where jumping is allowed. This could probably be more easily achieved with Terrain tags.

For the events problem, since some tiles & events are both unpassable, we would need to modify the passable? method (or the jump method) to check for events only between the starting & ending position. That way you could still jump over unpassable tiles.

<scratches beard & ponders this one>
 
No need to throw events and conditions in there ever. Just jump event commands and scripts doing the rest (of course I would say that).

I suggest making a jumpable_tile?(x, y) method in Game_Map, that can read if an event is there or a desired terrain is there that is not jumpable.

Code:
module Jump
  # Array with [tileset_id, terrain_tag] of non-jumpable terrains
  Non_Jumpable_Terrains = []
  # As default, can jump over player or events
  # We could overwrite this, if event has a special comment
  Can_Jump_Player = true
  Can_Jump_Events = false
  # Event comment that makes events inverse of what our default is
  # IE, Can_Jump_Events = false, events with comment can be jumped over
  # and vise versa
  Event_Comment = 'jump?'
  def self.jumpable_tile?(x, y)
    key = [$game_map.map.tileset_id, $game_map.terrain_tag(x, y)]
    return false if Non_Jumpable_Terrains.include?(key)
    return false if $game_player.x == x && $game_player.y == y && Can_Jump_Player == false
    events = $game_map.events_at(x, y)
    events.each do |event|
      next if event.erased
      next if event.character_name == '' && event.tile_id == 0
      return false if event.can_jump_over == false
    end
    return true
  end
end

class Game_Map
  attr_reader :map
  def events_at(x, y)
    a = []
    @events.values.each {|e| a << e if e.x == x && e.y == y}
    return a
  end
  def can_jump?(x, y)
    return Jump.jumpable_tile?(x, y)
  end
end

class Game_Event
  attr_reader :can_jump_over
  alias_method :seph_cj_gmevt_refresh, :refresh
  def refresh
    seph_cj_gmevt_refresh
    @seph_cj_gmevt_refresh = Jump::Can_Jump_Events
    return if @erased || @list == nil
    for ec in @list
      next if ec.code != 108 || ec.code != 408
      if ec.parameters[0].downcase.include?(Jump::Event_Comment.downcase)
        @seph_cj_gmevt_refresh = !@seph_cj_gmevt_refresh
        break
      end
    end
  end
end

From here, its just a matter of aliasing our jump method, finding tiles in direct path to the destination tile, and checking each tile.
Code:
class Game_Character
  alias_method :seph_cj_gmchr_jump, :jump
  def jump(x_plus, y_plus)
    if x_plus.abs < 2 && y_plus.abs < 2
      seph_cj_gmchr_jump(x_plus, y_plus)
      return
    end
    x1, x2, y1, y2 = @x, @x + x_plus, @y, @y + y_plus
    x1, x2, y1, y2 = x2, x1, y2, y1 if x2 < x1    
    length = x2 - x1 < (y2 - y1).abs ? (y2 - y1).abs : x2 - x1
    x_increment, y_increment = (x2 - x1) / length.to_f, (y2 - y1) / length.to_f
    x, y = x1, y1
    tested_coordinates = []
    while x < x2
      key = [Integer(x), Integer(y)]
      unless tested_coordinates.include?(key)
        return unless $game_map.can_jump?(*key)
        tested_coordinates << key
      end
      x += x_increment
      y += y_increment
    end
    seph_cj_gmchr_jump?(x_plus, y_plus)
  end
end


Let me know if that works out for you, since I haven't tested it.
 
Brewmeister":1j8l9lsn said:
This sounds completely different than your original request of "not jumping over events".
This was kind of my backup plan, I thought that if I couldn't automate it, I'd just control where the player can and can't jump. =)

SephSpawn":1j8l9lsn said:
No need to throw events and conditions in there ever. Just jump event commands and scripts doing the rest (of course I would say that).

I suggest making a jumpable_tile?(x, y) method in Game_Map, that can read if an event is there or a desired terrain is there that is not jumpable.

Hmm, I just them under Debug and Above main, is this correct? (I'm not great with placement, sorry)
If it is, I'm getting an error in line 80.

Other scripts I am using: Anti-Lag, SDK, Hermes, and an on screen HP/SP Bar, :)
 
Just once second and I'll test it all out. I have rmxp open now, so I'll check it out.

Silly spelling errors. Try this (above scene_debug, above main)
Code:
module Jump
  # Array with [tileset_id, terrain_tag] of non-jumpable terrains
  Non_Jumpable_Terrains = [[1, 1]]
  # As default, can jump over player or events
  # We could overwrite this, if event has a special comment
  Can_Jump_Player = true
  Can_Jump_Events = false
  # Event comment that makes events inverse of what our default is
  # IE, Can_Jump_Events = false, events with comment can be jumped over
  # and vise versa
  Event_Comment = 'jump?'
  def self.jumpable_tile?(x, y)
    key = [$game_map.map.tileset_id, $game_map.terrain_tag(x, y)]
    return false if Non_Jumpable_Terrains.include?(key)
    return false if $game_player.x == x && $game_player.y == y && Can_Jump_Player == false
    events = $game_map.events_at(x, y)
    events.each do |event|
      next if event.erased
      next if event.character_name == '' && event.tile_id == 0
      return false if event.can_jump_over == false
    end
    return true
  end
end

class Game_Map
  attr_reader :map
  def events_at(x, y)
    a = []
    @events.values.each {|e| a << e if e.x == x && e.y == y}
    return a
  end
  def can_jump?(x, y)
    return Jump.jumpable_tile?(x, y)
  end
end

class Game_Event
  attr_reader :can_jump_over
  attr_reader :erased
  alias_method :seph_cj_gmevt_refresh, :refresh
  def refresh
    seph_cj_gmevt_refresh
    @can_jump_over = Jump::Can_Jump_Events
    return if @erased || @list == nil
    for ec in @list
      next if ec.code != 108 || ec.code != 408
      if ec.parameters[0].downcase.include?(Jump::Event_Comment.downcase)
        @can_jump_over = !@can_jump_over
        break
      end
    end
  end
end

class Game_Character
  alias_method :seph_cj_gmchr_jump?, :jump
  def jump(x_plus, y_plus)
    if x_plus.abs < 2 && y_plus.abs < 2
      seph_cj_gmchr_jump(x_plus, y_plus)
      return
    end
    tx, ty = @x + x_plus, @y + y_plus
    length = [(@x - tx).abs, (@y - ty).abs].max
    x_inc = (@x - tx).abs / length.to_f
    y_inc = (@y - ty).abs / length.to_f
    x_inc *= -1 if tx < @x
    y_inc *= -1 if ty < @y
    sx, sy = @x, @y
    tested_coordinates = []
    while sx != tx || sy != ty
      key = [Integer(sx), Integer(sy)]
      unless tested_coordinates.include?(key)
        return true unless $game_map.can_jump?(*key)
        tested_coordinates << key
      end
      sx += x_inc
      sy += y_inc
    end
    seph_cj_gmchr_jump?(x_plus, y_plus)
  end
end

If you are using the set move route command, make sure you have ignore if cant move on, because otherwise it will keep trying to preform the command.
 
Ah, sorry >.< I really should have gone over the comments - my mistake :)

I'll test it all out (with the new menu system and all) and report back soon :)

Thanks for the help and guidance.

EDIT: Okay, I decided that in general, I'll have more NPCs than jumpable events, so I set Can_Jump_Events to False, then I made an event which I wanted to jump over - adding in the 'jump?' comment.
Sadly, the player could jump over every event - even if they had no event comment.
 
It seems to work fine for me.

I have Can_Jump_Events = false, and event with the comment jump?, and an event in front of the event that has the set move route with the jump command that makes the player jump over the event with the jump comment.

It you are using the set move route, make sure you have the ignore if can't move box checked.

If you have a script that you press a button and it makes the player jump, it should work, but just in case, if you are using a script, please post it.
 
Strange :S
For some strange reason, unless I turn jumping off totally (with can_jump_player), the player jumps over anything, even with can_jump_events = False and no event comments.

Ignore is on, and I'm using a Common Event with move routes to make the player jump :)
 
Okay, I got the player to be unable to jump over NPCs, as I changed the position to under Scene_Dialogue (I realised that I read one of your posts wrong)

However, now, even if I put the jump? comment in, the player cannot jump over events.

I worked out that the multiple jumps was a problem with the Common Event, so I sorted that out myself.

So, I just need the 'jump?' comments working, and we're all set, thanks for all the help :)
Is there anything I need to do in addition to the comment?
 

Jason

Awesome Bro

Since this thread is about jumping, I have a question

So say you're stood two squares away from a nonpassable tile, it doesn't let you jump, yeah, thats how I want it, however, is there a way that, if a nonpassable tile is two squares away, it just makes you jump ONE square infront ?

Cause at the moment, if I stand two squares away from a wall and jump towards it, it doesn't do anything, I'd want it to jump one square.

Another, and last thing, if you're stood at the side of TWO nonpassable tiles (A wall two squares thick), I'd want it to make you jump on the spot.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top