じ☆ve冰风 发表于 2026-8-2 09:12:58

Push, Bridge and Jump Events

Push, Bridge and Jump Events
by AMoonlessNight
14 Apr 2018





This script makes it so that you can push certain events and use them as bridges, or even hop between them. It works best with events with multiple parts, such as pillars.

You must set up regions for where the bridges should go, or else it won't work.

Known issues:
1. At the moment, bridges only work horizontally, not vertically.
2. To hop between events, they must be placed two tiles apart.

Compatibility:
I haven't tested this script with other scripts that modify passability, etc. Let me know if there are any issues.

I may look at improvements for this script upon request.

Script
Spoiler: Script                Code:       
=begin
#============================================================================
#   AMN Push, Bridge and Jump Events
#   Version 1.04
#   Author: AMoonlessNight
#   Date: 14 Apr 2018
#   Latest: 28 Dec 2018
#============================================================================#
#   UPDATE LOG
#----------------------------------------------------------------------------#
# 14 Apr 2018 - created the original script
# 15 Apr 2018 - fixed an issue with being able to push events while upon them
#             - added a wait for the player while pushing events
#             - added passability checks to the pushing script call
# 18 Apr 2018 - fixed an issue with priority types for top events
# 28 Dec 2018 - squashed a few bugs related to passability
#============================================================================#

This script makes it so you can push certain events and use them as bridges.
It works best with events with multiple parts, such as pillars.

You can also set it so that you can jump between events.

You must set up regions for where the bridges should go.


SETTING UP EVENTS:

Name:
* the name must include <move> if you wish for it to be moveable

* if you have an event with multiple parts (e.g. a pillar spanning three
    tiles), they must all include the unique name of the BASE event
   
* the top-most event must include <top> if you wish for it to be used like
    a bridge
   
Priority:

* the top-most event must be set to Through
* any other below or above priority sections should be set to Through
   
Script call:

* the base event must have the script call 'push_event' if you wish for it
    to be pushed
   
* the top-most event must have the script call 'pillar_jump' if you wish for
    the player to jump from one to the other

   
*** IMPORTANT:

* Each separate set of events MUST have a unique name
e.g. a bunch of events just called <move> will all move together.

* For now, bridges only work horizontally, not vertically

* Bridge events will not pass in front of one another


SETTING UP REGIONS:

* Use the first region (Topmost_Region) to designate areas that can be used for
    bridges.

* Use the second region (TopRegion_Bookend) to designate the 'on' and 'off'
    points on either side of the first region. This is so the player can get on
    and off the bridge.
   

#============================================================================#
          SCRIPT CALLS
#============================================================================#

You can use the following script calls:

    * push_event
#----------------------------------------------------------------#
# Pushes the event and any related events. This should go on the
# base event
#----------------------------------------------------------------#

    * pillar_jump
#----------------------------------------------------------------#
# Allows the player to jump from one 'top' event to another
#----------------------------------------------------------------#


=end

module AMNEventMove

#==============================================================================
# ** EDITABLE REGION BELOW
#------------------------------------------------------------------------------
#Change the values in the area below to suit your needs.
#==============================================================================


Topmost_Region =    2   # The region ID for areas that can be used as bridges

TopRegion_Bookend = 3   # The region ID for the areas next to bridges. You
                        # must paint these regions on either side of the
                        # Topmost_Region or else the player can't get off
                        # or jump off


#==============================================================================
# ** END OF EDITABLE REGION
#------------------------------------------------------------------------------
#Please do not edit below this point unless you know what you are doing.
#==============================================================================

end

class Game_Map
def bridge_region
    AMNEventMove::Topmost_Region
end

def bridge_adjacent
    AMNEventMove::TopRegion_Bookend
end

def bridge_region?(x, y)
    region_id(x, y) == bridge_region
end

def bridge_adjacent?(x, y)
    region_id(x, y) == bridge_adjacent
end
end

class Game_CharacterBase

alias amn_eventmove_gamecharabase_passable? passable?
def passable?(x, y, d)
    return false if check_player_bridges?(x, y, d)
    amn_eventmove_gamecharabase_passable?(x, y, d)
end

def check_player_bridges?(x, y, d)
    return false unless self.is_a?(Game_Player)
    return false if debug_through?
    region = 0
    case d
    when 1; reg = $game_map.region_id(x-1, y+1); ev = collide_with_top_event(x-1, y+1)
    when 2; reg = $game_map.region_id(x+0, y+1); ev = collide_with_top_event(x+0, y+1)
    when 3; reg = $game_map.region_id(x+1, y+1); ev = collide_with_top_event(x+1, y+1)
    when 4; reg = $game_map.region_id(x-1, y+0); ev = collide_with_top_event(x-1, y+0)
    when 5; reg = $game_map.region_id(x+0, y+0); ev = collide_with_top_event(x+0, y+0)
    when 6; reg = $game_map.region_id(x+1, y+0); ev = collide_with_top_event(x+1, y+0)
    when 7; reg = $game_map.region_id(x-1, y-1); ev = collide_with_top_event(x-1, y-1)
    when 8; reg = $game_map.region_id(x+0, y-1); ev = collide_with_top_event(x+0, y-1)
    when 9; reg = $game_map.region_id(x+1, y-1); ev = collide_with_top_event(x+1, y-1)
    end
    if not_on_bridge(x, y)
      return true if bridge_adj?(reg)
    elsif on_bridge_region(x, y)
      if $game_player.playerbridge?
      return true unless bridge_region?(reg) && ev || bridge_adj?(reg)
      else
      return true if bridge_adj?(reg)
      end
    elsif next_to_bridge(x, y)
      return true if bridge_region?(reg) && !ev
    end
    return false
end

def bridge_region?(region)
    region == $game_map.bridge_region
end

def bridge_adj?(region)
    region == $game_map.bridge_adjacent
end

def on_bridge_region(x, y)
    $game_map.bridge_region?(x, y) && collide_with_top_event(x, y)
end

def next_to_bridge(x, y)
    $game_map.bridge_adjacent?(x, y)
end

def not_on_bridge(x, y)
    $game_map.bridge_region?(x, y) && !collide_with_top_event(x, y)
end

def collide_with_top_event(x, y)
    $game_map.events_xy(x, y).any? { |event| event.top_event? }
end

end

class Game_Player < Game_Character
   
alias amn_eventmove_gameplayer_movebyinputmove_by_input
def move_by_input
    last_pos = [@x, @y]
    amn_eventmove_gameplayer_movebyinput
    new_pos = [@x, @y]
    @playerbridge = bridge_movement_check(last_pos, new_pos)
end

def bridge_movement_check(last, current)
    last_region = $game_map.region_id(last, last)
    return true if bridge_adj?(last_region) && on_bridge_region(current, current)
    return false if !@playerbridge && on_bridge_region(current, current)
    return true if on_bridge_region(last, last) && on_bridge_region(current, current)
    return false
end

def playerbridge?
    @playerbridge
end

def wait(duration)
    mr = RPG::MoveRoute.new
    mr.repeat = false
    mr.wait = true
    mr.list = []
    mr.list.push( RPG::MoveCommand.new(15, ) )
    mr.list.push( RPG::MoveCommand.new )
    force_move_route(mr)
end

def jumpable_?(x, y)
    evs = $game_map.events_xy(x, y).select{|ev| ev.top_event? }
    @playerbridge = true if bridge_adj?(region_id)
    evs.each { |e| return false if !bridge_region?(e.region_id) }
    return true if !evs.empty? && playerbridge?
    return true if !evs.empty? && bridge_adj?(region_id)
    return true if playerbridge? && $game_map.bridge_adjacent?(x, y)
    return true if bridge_adj?(region_id) && $game_map.bridge_adjacent?(x, y)
end

end

class Game_Event < Game_Character
attr_reader   :name                  # name of event
attr_accessor :priority_type         # priority type (normal, above, below)

alias amn_eventname_initinitialize
def initialize(*args)
    amn_eventname_init(*args)
    @name = @event.name
end

def top_event?
    return true if @name.include?("<top>")
end

def bridge_check
    player = $game_player
    return @priority_type = 2 if !bridge_region?(region_id)
    if distance_x_from($game_player.x) <= 1 && distance_y_from($game_player.y) <= 1
      @priority_type = 0 if player.playerbridge?
    else
      @priority_type = 2
    end
end

alias amn_eventmove_gameevent_updateupdate
def update
    amn_eventmove_gameevent_update
    bridge_check if top_event? && @name.include?("<move>")
end
end

class Game_Interpreter

def push_event(event = $game_map.events[@event_id])
    return unless event.name.include?("<move>")
    return unless event.passable?(event.x, event.y, $game_player.direction)
    evs = $game_map.events.values.select{|ev| ev.name.include?(event.name) }
    x2 = $game_map.round_x_with_direction(event.x, $game_player.direction)
    y2 = $game_map.round_y_with_direction(event.y, $game_player.direction)
    # check if there are any matching events behind the event and check passability
    ev2 = $game_map.events_xy(x2,y2).select{|ev| ev.name.include?(event.name)}
    ev2.each {|ev| return unless ev.passable?(ev.x, ev.y, $game_player.direction)}
    # don't let the events move if there are any other moveable events behind them
    evs.each do |ev|
      evx2 = $game_map.round_x_with_direction(ev.x, $game_player.direction)
      evy2 = $game_map.round_y_with_direction(ev.y, $game_player.direction)
      return unless $game_map.events_xy(evx2,evy2).select{|evv| evv.name.include?("<move>") && !evv.name.include?(event.name)}.empty?
    end
    return unless $game_map.events_xy(x2,y2).select{|ev| ev.name.include?("<move>") && !ev.name.include?(event.name)}.empty?
    #
    $game_player.wait(20)
    # make each event move
    evs.each do |ev|
      mr = RPG::MoveRoute.new
      mr.repeat = false
      mr.wait = true
      mr.list = []
      mr.list.push(RPG::MoveCommand.new($game_player.direction/2, []))
      mr.list.push( RPG::MoveCommand.new )
      ev.force_move_route(mr)
    end
end

def pillar_jump
    tilex = $game_player.x
    tiley = $game_player.y
    case $game_player.direction
    when 2; jumpx = 0; jumpy = 2; tiley += 2
    when 4; jumpx = -2; jumpy = 0; tilex -= 2;
    when 6; jumpx = 2; jumpy = 0; tilex += 2;
    when 8; jumpx = 0; jumpy = -2; tiley -= 2
    end
    if $game_player.jumpable_?(tilex, tiley)
      $game_player.jump(jumpx, jumpy)
    else
      # the player cannot push if they are on the bridge
      return if $game_player.playerbridge?
      x2 = $game_map.round_x_with_direction($game_player.x, $game_player.direction)
      y2 = $game_map.round_y_with_direction($game_player.y, $game_player.direction)
      $game_map.events_xy(x2, y2).select{|ev| ev.priority_type == 1}.each { |ev| ev.start }
    end
end

end


Demo
Version 1.4: https://www.dropbox.com/s/yagqfvvmie5ksxb/Push Bridge Jump script demo.exe?dl=0
updated 28 Dec 2018

Instructions
Spoiler: Instructions


1. Set up your two regions:
a. The first region should designate the 'bridge' area, or topmost area.
b. The second region should designate where the player should get on or off the bridge. It should be on either side of the bridge region.​

2. Set up your events:
Spoiler: Base event



a. The bottom or base of the event should have the script call 'push_event' if you wish for it to be pushed.
b. The name must include <move> if you wish for it to be moveable.
c. The name must be unique to this set of events, or else everything with the same name will move.
d. If you have an event with multiple parts (such as a pillar), they must all include the unique name of the base event.
Spoiler: Top event


a. The top-most event should include the script call 'pillar_jump' if you wish for the player to hop between them.
b. It must include the name of the base event, otherwise it won't move with it.
c. It must include <top> in the name if you wish for it to be used like a bridge.
Screenshots
Spoiler: Screenshots










本贴来自国际rpgmaker官方论坛作者:A-Moonless-Night处,因国际论坛即将永久关站,为了存档多年珍贵资料,署名转载到本论坛存档,由于官方帖子为英文原帖,需要中文翻译请点击论坛顶部切换语言为中文就可以将帖子翻译成中文浏览,方便大家随时查看,原文地址:https://forums.rpgmakerweb.com/threads/push-bridge-and-jump-events.94049/
页: [1]
查看完整版本: Push, Bridge and Jump Events