Submit Your Article


 
RPG Maker

Welcome Guest ( Log In | Register )


  Games Resources RPG Maker VX RPG Maker XP Scripts Tutorials Downloads

 
Closed TopicStart new topic
> Tactical Espionage Engine, Create your own MGS style games/minigames
maximusmaxy
post Oct 6 2011, 08:24 PM
Post #1


PZE whore
Group Icon

Group: Revolutionary
Posts: 131
Type: Scripter
RM Skill: Skilled




Tactical Espionage Engine

Version: 1.0
Author: Maximusmaxy
Release Date: 7/10/2011

Introduction
This is a fully revamped version of the first script I ever wrote. It's a compilation of smaller scripts I've written to make up an MGS styled tactical espionage engine. You can do a range of things with this script from avoiding guards, to your own ice slide mini game.

Features
  • Fields of view, with many different types (pyramid, diamond, cone, linear...)
  • Walk, Run, Sneak with configurable keys and speeds.
  • Modified Terrains (fast, slow, loud, slippery)
  • Cancel/Menu button split
  • MGS styled wall locking and wall knocking.
  • Planned Features (Path finding)

Script
CODE
#===============================================================================
# Tactical Espionage Engine
# Author: Maximusmaxy
# Version: 1.0
# Thanks to:
# Night Runner - Creating the coordinate highlighter and general tips.
#===============================================================================
# Version 0.1: 24/8/2011
# Version 0.5: 5/9/2011
# Version 0.5.1: 5/9/2011 fixed WRS
# Version 0.5.2: 6/9/2011 fixed FoV
# Version 0.6: 7/9/2011 rewrote FoV
# Version 1.0: 7/10/2011
# -rewrote every method/function
# -added slip terrains, wall locking, cone view.
#===============================================================================
#
#                              Introduction:
#
# This is a compilation of small scripts ive written, compiled together to make
# a tactical espionage engine, much like a metal gear solid game (it's where i
# got the idea from).
#
# Features:
# - Fields of view, with many different types
# - Walk, Run, Sneak with configurable keys/speeds.
# - Modified Terrains
# - Cancel/Menu button split
# - Wall locking, like in MGS
#
#                              Field of View:
#
# To add a field of view to an event you place the field of view comment in
# the event. If you enter the events field of view it will activate the self
# switch specified which could than trigger a chase event system or an autorun
# event, however you want that event to react.
# The comment you place in the event follows this format:
#
# Fov(TYPE,DISTANCE,SELF_SWITCH)
#
# TYPE is the field of view type.
# If type is 0 no field of view is used. But the event is activated by noises.
#
# Type 1: Diamond      Type 2: Pyramid      Type 3: Linear     Type 4: Circle
#
#                              N                          
#      3                      3N                                     3
#     234                    23N                                    234
#   E1234N                 E123N               E1234N              12E4N
#     234                    23N                                    234
#      3                      3N                                     3
#                              N                  
#                                      
# where Distance = 5  where Distance = 4  where distance = 5  where Distance = 5
#
#                    Type 5: Cone
#
#                          oo          The cone is not affected by distance
#                        oooo          but events using it cannot see through
#                       Eoooo          walls.
#                        oooo
#                          oo
#
# DISTANCE is how many tiles they look in that direction.
#
# SELF_SWICH is the switch that is changed when you enter the field of view
#
# You can omit putting in the distance/type/switch and use the defaults
# eg. Fov(3,5,A) or Fov(4,1) or Fov(2) or Fov
#
# You can change the field of view manually using a the call scripts. You can
# change either all attributes or one at a time.
#
# TEE.fov(TYPE,DISTANCE,SWITCH)
# TEE.fow_type(TYPE)
# TEE.fov_distance(DISTANCE)
# TEE.fov_switch(SWITCH)
#
#
#                          Walk/Run/Sneak:
#
# Running and sneaking can be enabled and disabled during the game using script
# calls. It is highly recommended to disable them manually during cutscenes.
# The script calls are as follows:

# TEE.run_enable         (enables running)
# TEE.sneak_enable       (enables sneaking
# TEE.wrs_enable         (enables both running and sneaking)
# TEE.run_disable        (disables running)
# TEE.sneak_disable      (disables sneaking)
# TEE.wrs_disable        (disables both running and sneaking)
#
#                          Modified Terrains:
#
# Using different terrain tags you can make different things happen. The terrain
# tags can be changed in the configuration.

# Wall terrain - Denotes that the terrain is a wall.
# Loud Terrain - Creates a sound depending on how fast you are moving.
# Slow Terrain - Slows the player down.
# Fast Terrain - Speeds the player up.
# Slip Terrain - Makes the player move forward until hitting a different terrain
#                or hitting an impassable tile.
#
# Loud terrains automatically activate the self switch of surrounding events
# with a field of view. It draws a circle of a size relative to your move speed.
# The size of the circle can be changed in the config. The size doubles if you
# are running but is non existant if you are sneaking.
#
#                             Wall Locking:
#
# This function gives you the MGS style wall locking feature, to use it walk up
# against a wall and then press against the wall again. You may only wall lock
# on terrains specified as walls in the modified terrains. Whilst in this mode
# you will strafe along the wall, and if you hit Input C (decision key) you will
# knock on the wall, causing a noise and triggering events with a field of view
# within a circle. The loudness of your knock depends on which running/sneaking
# keys are pressed down. You may enable/disable wall locking with the call
# script as follows:
#
# TEE.wall_lock_enable   (enables wall locking)
# TEE.wall_lock_disable  (disables wall locking)
#
#                           Event Resetting:
#
# It is recommended to reset your events after triggering them with either a
# field of view or a noise. Resetting your events returns them to there
# initial position, resets there move path and sets there self switch to off.
# You can reset all the events on the map using the call script:
#
# TEE.reset              (resets the events with a fov on the map)
#
#                              Menu Split:
#
# This feature simply splits the menu and cancel button into 2 seperate buttons.
# Its not an important feature but like most RPG's the cancel button is usually
# also the run button and i have tried to emulate this. It can be enabled or
# disabled in the configuration and the key can be changed.
#
#                            Compatabillity:
#
# This script is very likely to have compatabillity issues with other running
# and sneaking scripts,possibly 8 directional/pixel based movement scripts and
# other scripts which change or use certain controls. If the menu split
# conflicts with other scripts just disable it in the configuration.
#
#===============================================================================

module TEE
  
#===============================================================================
# Configuration
#===============================================================================

  #set the defaults for the field of view here
  TYPE = 1                     #can be 1,2,3 or 4
  DISTANCE = 5                 #only use odd distances for types 0,3,4
  SELF_SWITCH = 'A'            #can be 'A','B','C' or 'D'
  #set walk/run/sneak speed here
  WALK_S = 4                   #a good number is around 4
  RUN_S = 4.8                  #a good number is around 5  
  SNEAK_S = 3                  #a good number is around 3
  #set the input keys for run and sneak here
  RUN_K = Input::B             #Defaults as X on the keyboard
  SNEAK_K = Input::A           #Defaults as Z on the keyboard
  #state here whether walking or sneaking is enabled/disabled initially
  #it can be changed using the call script
  RUN_ENABLED = true
  SNEAK_ENABLED = true  
  #set if you want to split the menu/cancel keys and the new menu input
  MENU_SPLIT = true
  MENU_K = Input::Y            #Input::Y defaults as S
  #set the terrain tags for the specified terrains
  WALL_T = 1                   #If you do not want to use a specific terrain
  LOUD_T = 2                   #set its value to -1.
  SLOW_T = 3                  
  FAST_T = 4
  SLIP_T = 5
  #The sound that plays for noisy terrains and the default distance of the
  #circle and self switch of noise checks can be chosen here.
  NOISE_SOUND = '042-Knock03'  #Check the Sound Test for other sound effects
  NOISE_D = 5                  #a good number is around 5 (USE ODD NUMBERS)
  NOISE_S = 'A'                #can be 'A','B','C' or 'D'
  #This sets wether wall locking is enabled or disabled initially
  #it can be changed using the call script
  WALL_LOCK = false
  KNOCK_SOUND = '042-Knock03'  #sound for knocking while wall locked
  KNOCK_D = 11                 #distance of wall knock sound
  KNOCK_S = 'B'                #switch activated by knocking
  #The coordinate highlighter highlights the field of views and noise circles.
  #It is only available in debug mode and is a little laggy when too many field
  #of views are active.
  HIGHLIGHT = true             #Allow highlighter use?
  HIGHLIGHT_K = Input::X       #Input::X defaults as A
  
#===============================================================================
# End Configuration
#===============================================================================
  
  def self.fov(type = TEE::TYPE,distance = TEE::DISTANCE,
               switch = TEE::SELF_SWITCH) #establishes a new field of view
    event = $game_temp.last_event_interpreted
    $game_map.events[event].fov = true
    $game_map.events[event].fov_type = type
    $game_map.events[event].fov_distance = distance
    $game_map.events[event].fov_switch = [$game_map.map_id,event,switch]
  end
  
  def self.fov_type(type) #changes the fov type
    $game_map.events[$game_temp.last_event_interpreted].fov_type = type
  end
  
  def self.fov_distance(distance) #changes the fov distance
    $game_map.events[$game_temp.last_event_interpreted].fov_distance = distance
  end
  
  def self.fov_switch(switch) #changes the fov switch
    event = $game_temp.last_event_interpreted
    $game_map.events[event].fov_switch = [$game_map.map_id,event,switch]
  end
  
  def self.fov_disable #disables the events field of view
    $game_map.events[$game_temp.last_event_interpreted].fov = false
  end  
  
  def self.reset #resets the events on the map
    $game_map.reset_fov_events
  end
  
  def self.run_disable #disable running
    $game_system.wrs_run_enabled = false
    $game_player.wrs_speed = 2
  end
  
  def self.sneak_disable #disable sneaking
    $game_system.wrs_sneak_enabled = false
    $game_player.wrs_speed = 2
  end
  
  def self.wrs_disable #disable both running and sneaking
    $game_system.wrs_run_enabled = false
    $game_system.wrs_sneak_enabled = false
    $game_player.wrs_speed = 2
  end
  
  def self.run_enable #enable running
    $game_system.wrs_run_enabled = true
  end
  
  def self.sneak_enable #enable sneaking
    $game_system.wrs_sneak_enabled = true
  end
  
  def self.wrs_enable #enable both running and sneaking
    $game_system.wrs_run_enabled = true
    $game_system.wrs_sneak_enabled = true
  end
  
  def self.wall_lock_enable #enables wall locking
    $game_system.wall_lock_enabled = true
    $game_map.need_refresh = true
  end
  
  def self.wall_lock_disable #disables wall locking
    $game_system.wall_lock_enabled = false
    $game_map.need_refresh = true
  end
end

#===============================================================================
# Game_Temp
#===============================================================================

class Game_Temp
  attr_accessor :highlight_new_coords
  attr_accessor :last_event_interpreted
  alias nr_FOV_initialize  initialize
  def initialize( *args )
    #holds the id of the last event interpreted.
    @last_event_interpreted
    # Create a temporary holding, that keeps all the new coordinates that
    # need to be shaded
    @highlight_new_coords = []
    # Run the original Game_Temp
    return nr_FOV_initialize( *args )
  end
end

#===============================================================================
# Game_System
#===============================================================================

class Game_System
  attr_accessor :wrs_run_enabled
  attr_accessor :wrs_sneak_enabled
  attr_accessor :wall_lock_enabled
  alias max_wrs_initialize_later initialize
  def initialize
    max_wrs_initialize_later
    #variables for enabling/disabling, running/sneaking/wall locking
    @wrs_run_enabled = TEE::RUN_ENABLED
    @wrs_sneak_enabled = TEE::SNEAK_ENABLED
    @wall_lock_enabled = TEE::WALL_LOCK
  end
end

#===============================================================================
# Game_Map
#===============================================================================

class Game_Map
  #this method resets the events with a field of view
  def reset_fov_events
    @events.each_value do |event|
      if event.fov
        event.moveto(event.original_x, event.original_y)
        event.move_route_index = 0
        event.direction = event.original_direction
        event.fov_activated = false
        key = [$game_map.map_id,event.id,'A']
        $game_self_switches[key] = false
        key = [$game_map.map_id,event.id,'B']
        $game_self_switches[key] = false
        key = [$game_map.map_id,event.id,'C']
        $game_self_switches[key] = false
        key = [$game_map.map_id,event.id,'D']
        $game_self_switches[key] = false
        event.refresh
      end
    end
  end
end

#===============================================================================
# Game_Character
#===============================================================================

class Game_Character
  attr_accessor :direction_9
  attr_accessor :direction
  attr_accessor :original_direction
  attr_accessor :move_speed
  alias max_direction_initialize_later initialize
  alias max_turn_left_later turn_left
  alias max_turn_right_later turn_right
  alias max_turn_up_later turn_up
  alias max_turn_down_later turn_down
  def initialize
    #variable for 9 direction facing
    @direction_9 = 0
    max_direction_initialize_later
  end
  
  def turn_left
    case @direction
    #when facing down, right or up and turning to the left
    when 2,6,8
      #face 1,3,7
      @direction_9 = @direction - 1
    end
    max_turn_left_later
  end
  
  def turn_right
    case @direction
    #when facing down, left or up and turning to the right
    when 2,4,8
      #face 3,5,9
      @direction_9 = @direction + 1
    end
    max_turn_right_later
  end
  
  def turn_up
    case @direction
    #when facing down, left or right and turning up
    when 2,4,6
      #face 5,7,9
      @direction_9 = @direction + 3
    end
    max_turn_up_later
  end
  
  def turn_down
    case @direction
    #when facing left,right or up and turning down
    when 4,6,8
      #face 1,3,5
      @direction_9 = @direction - 3
    end
    max_turn_down_later
  end
end

#===============================================================================
# Game_Event
#===============================================================================

class Game_Event < Game_Character
  attr_accessor :fov
  attr_accessor :fov_type
  attr_accessor :fov_distance
  attr_accessor :fov_switch
  attr_accessor :fov_activated
  attr_accessor :original_x
  attr_accessor :original_y
  attr_accessor :move_route_index
  alias max_tee_initialize_later initialize
  alias max_tee_refresh_later refresh
  alias max_tee_update_later update
  def initialize(*args)
    #field of view variables
    @fov = false
    @fov_type = 0
    @fov_distance = 0
    @fov_switch = [@map_id,@id,'A']
    @fov_activated = false
    max_tee_initialize_later(*args)
    #patrol path reset variables
    @original_x = @event.x
    @original_y = @event.y
  end
  
  def refresh
    max_tee_refresh_later
    #if the event isn't erased or a fov hasn't already been established
    unless @erased || @fov || @list.nil?
      #search the events list
      for i in 0...@list.size
        #if there is a comment
        if @list[i].code == 108
          #with the format fov(type,distance,switch)
          if /[Ff]ov\(?(\d*),?(\d*),?'?(\w?)'?\)?/ =~ @list[i].parameters[0]
            #activate the fov
            @fov = true
            #set the type
            @fov_type = $1 == '' ? TEE::TYPE : $1.to_i
            #set the distance
            @fov_distance = $2 == '' ? TEE::DISTANCE : $2.to_i
            #set the switch
            @fov_switch = [@map_id,@id,$3 == '' ? TEE::SELF_SWITCH : $3]
          end
        end
      end
    end
  end
  
  def update
    max_tee_update_later
    #update the field of view if the event has a field of view
    if @fov
      #variables to change the direction
      xi = (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
      yi = (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
      xj = (@direction == 4 || @direction == 6 ? 0 : 1)
      yj = (@direction == 2 || @direction == 8 ? 0 : 1)
      case @fov_type
      #Diamond(Top left origin x, y, distance)
      when 1
        case @direction
        when 2 #down
          diamond(@x - (@fov_distance - 1) / 2, @y + 1, @fov_distance)
        when 4 #left
          diamond(@x - @fov_distance, @y - (@fov_distance - 1) / 2, @fov_distance)
        when 6 #right
          diamond(@x + 1,@y - (@fov_distance - 1) / 2, @fov_distance)
        when 8 #up
          diamond(@x - (@fov_distance - 1) / 2, @y - @fov_distance, @fov_distance)
        end
        case @direction_9
        #Triangle(x, y, left right?, LR inc, up down?, UD inc, distance)
        when 1 #bottom left
          triangle(@x, @y + @fov_distance, -1, 0, -1, -1, @fov_distance + 1)
        when 3 #bottom right
          triangle(@x + @fov_distance, @y, -1, -1, 1, 0, @fov_distance + 1)
        when 7 #top left
          triangle(@x - @fov_distance, @y, 1, 1, -1, 0, @fov_distance + 1)
        when 9 #top right
          triangle(@x, @y - @fov_distance, 1, 0, 1, 1, @fov_distance + 1)
        end
      #Pyramid(x, y, left right?, LR inc, up down?, UD inc, distance)
      when 2
        case @direction
        when 2 #down
          pyramid(@x, @y + 1, -1, 1, 1, 0, @fov_distance)
        when 4 #left
          pyramid(@x - 1, @y, -1, 0, -1, 1, @fov_distance)
        when 6 #right
          pyramid(@x + 1, @y, 1, 0, 1, -1, @fov_distance)
        when 8 #up
          pyramid(@x, @y - 1, 1, -1, -1, 0, @fov_distance)
        end
        case @direction_9
        #Triangle(x, y, left right?, LR inc, up down?, UD inc, distance)
        when 1 #bottom left
          triangle(@x, @y + @fov_distance, -1, 0, -1, -1, @fov_distance + 1)
        when 3 #bottom right
          triangle(@x + @fov_distance, @y, -1, -1, 1, 0, @fov_distance + 1)
        when 7 #top left
          triangle(@x - @fov_distance, @y, 1, 1, -1, 0, @fov_distance + 1)
        when 9 #top right
          triangle(@x, @y - @fov_distance, 1, 0, 1, 1, @fov_distance + 1)
        end
      #Linear(x increment, y increment, distance)
      when 3
        linear(xi,yi,@fov_distance)
      #Circle(distance)
      when 4
        circle(@fov_distance)
      #Cone
      when 5
        return if cone_front(xi,yi)
        linear(xi,yi,4)
        cone1(xi,yi,xj,yj)
        cone2(xi,yi,xj,yj)
        cone3(xi,yi,xj,yj)
        cone4(xi,yi,xj,yj)
      end
    end
  end
  
  def cone1(xi,yi,xj,yj)
    #draw the left of the cone
    for i in 0...4
      new_x = @x + (i + 1) * xi - 1 * xj
      new_y = @y + (i + 1) * yi - 1 * yj
      #return if there is a wall
      if $game_map.terrain_tag(new_x, new_y) == TEE::WALL_T &&
         !$game_map.passable?(new_x, new_y, @direction)
        return
      end
      #check the coordinates
      check_seen(new_x, new_y)
    end  
  end
  
  def cone2(xi,yi,xj,yj)
    #draw the right of the cone
    for i in 0...4
      new_x = @x + (i + 1) * xi + 1 * xj
      new_y = @y + (i + 1) * yi + 1 * yj
      #return if there is a wall
      if $game_map.terrain_tag(new_x, new_y) == TEE::WALL_T &&
         !$game_map.passable?(new_x, new_y, @direction)
        return
      end
      #check the coordinates
      check_seen(new_x, new_y)
    end
  end
  
  def cone3(xi,yi,xj,yj)
    #draw the far left of the cone
    for i in 0...4
      new_x = @x + (i + 1) * xi - (i / 2 + 1) * xj
      new_y = @y + (i + 1) * yi - (i / 2 + 1) * yj
      #return if there is a wall
      if $game_map.terrain_tag(new_x, new_y) == TEE::WALL_T &&
         !$game_map.passable?(new_x, new_y, @direction)
        return
      end
      #check the coordinates
      check_seen(new_x, new_y)
    end  
  end
  
  def cone4(xi,yi,xj,yj)
    #draw the far right of the cone
    for i in 0...4
      new_x = @x + (i + 1) * xi + (i / 2 + 1) * xj
      new_y = @y + (i + 1) * yi + (i / 2 + 1) * yj
      #return if there is a wall
      if $game_map.terrain_tag(new_x, new_y) == TEE::WALL_T &&
         !$game_map.passable?(new_x, new_y, @direction)
        return
      end
      #check the coordinates
      check_seen(new_x, new_y)
    end
  end
  
  def cone_front(xi,yi)
    #returns true if there is a wall in front, false if there isn't
    if $game_map.terrain_tag(@x + xi, @y + yi) == TEE::WALL_T &&
         !$game_map.passable?(@x + xi, @y + yi, @direction)
      return true
    end
    return false
  end
  
  #draws the diamond shape and checks
  def diamond(x,y,n)
    #even number fix
    if n % 2 == 0
      n += 1
    end
    #loop for x
    for i in 0...n
      #loop for the amount of y iterations for each x
      for j in 0...(n - (2 * ((i-n/2).abs)))
        #increment the x value for each loop
        a = x + i
        #increment the y value for each j iteration
        b = y + (n/2-i).abs + j
        #check the new values
        check_seen(a,b)
        #If switch is activated stop checking
        return if @fov_activated
      end
    end
  end
  
  #draws the pyramid shape and checks
  def pyramid(x,y,lr,lri,ud,udi,n)
    #loop for the increment direction (negative lri is left while
    #positive lri is right. negative udi is down while positive udi is up).
    for i in 0...n
      #loop for the amount of iterations for each directional increment.
      for j in 0..(2*(i+1)-2)
        #increment x to the left/right, j times
        a = x + (i*lr) + (j*lri)
        #increment y up/down, j times
        b = y + (i*ud) + (j*udi)
        #check new values
        check_seen(a,b)
        #If switch is activated stop checking
        return if @fov_activated
      end
    end
  end
  
  #draws a straight line and checks
  def linear(xi,yi,n)
    for i in 0...n
      new_x = @x + (i + 1) * xi
      new_y = @y + (i + 1) * yi
      #return if there is a wall tile
      if $game_map.terrain_tag(new_x, new_y) == TEE::WALL_T &&
         !$game_map.passable?(new_x, new_y, @direction)
        return
      end
      #check the coordinates
      check_seen(new_x, new_y)
    end  
  end
  
  #draws a right angled triangle and checks
  def triangle(x, y, lr, lri, ud, udi, n)
    #loop for the distance
    for i in 0...n
      #loop for the iterations per distance
      for j in 0...(n-i)
        #increment x to the left/right, j times
        a = x + (i*lr) + (j*lri)
        #increment y up/down, j times
        b = y + (i*ud) + (j*udi)
        #check new values
        check_seen(a,b)
        #If switch is activated stop checking
        return if @fov_activated
      end
    end
    #reset the diagonal direction after the check
    @direction_9 = 0
  end
  
  #draws a circle(actually its a diamond) around the event and checks
  def circle(n)
    #even number fix
    if n % 2 == 0
      n += 1
    end
    #loop for distance
    for i in 0...n
      #loop for the iterations per increment
      for j in 0...(n - (2 * ((i-n/2).abs)))
        #increment the x value for each loop
        a = @x - n/2 + i
        #increment the y value for each j iteration
        b = @y - n/2 + (n/2-i).abs + j
        #perform check of new values
        check_seen(a,b)
        #If switch is activated stop checking
        return if @fov_activated
      end
    end
    #reset the diagonal direction after the check if doing diagonal checks
    @direction_9 = 0
  end

  def check_seen(x,y)
    #highlight the coords if L is pressed and allowed
    if Input.press?(TEE::HIGHLIGHT_K) && TEE::HIGHLIGHT && $DEBUG
      $game_temp.highlight_new_coords << [x, y]
    end
    #if the player is in the checked co-ordinates
    if x == $game_player.x && y == $game_player.y
      @fov_activated = true
      #set self switch to true
      $game_self_switches[@fov_switch] = true
      #update self switches
      $game_map.need_refresh = true
    else
      @fov_activated = false
      #reset switch if doing circle
      if @fov_type == 4
        #set self switch to false
        $game_self_switches[@fov_switch] = false
        #update self switches
        $game_map.need_refresh = true
      end
    end
  end
end

#===============================================================================
# Game_Player
#===============================================================================

class Game_Player < Game_Character
  attr_accessor :wrs_speed
  attr_accessor :wrs_speed_increment
  alias max_tee_initialize_later initialize
  alias max_tee_update_later update
  def initialize
    max_tee_initialize_later
    #added move speed variables
    @wrs_speed = 2 #sneaking = 1, walking = 2, running = 3
    @wrs_speed_increment = 0
    #terrain variables
    @sound_activated = false
    @wall_lock = false
  end

  def update
    max_tee_update_later
    #location of the coords in front
    x = (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
    y = (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
    #if there is a wall ahead, not wall locked, not passable, locking is enabled
    #and there is no event in front of you
    if terrain_ahead == TEE::WALL_T && !@wall_lock &&
       !passable?(@x, @y, @direction) && $game_system.wall_lock_enabled &&
        $game_map.check_event(@x + x, @y + y).is_a?(Array)
      #down triggered and facing down
      if Input.trigger?(Input::DOWN) && @direction == 2
        #wall lock
        @direction = 8
        wall_lock
      #left is triggered and facing left
      elsif Input.trigger?(Input::LEFT) && @direction == 4
        #wall lock
        @direction = 6
        wall_lock
      #right is triggered and facing right
      elsif Input.trigger?(Input::RIGHT) && @direction == 6
        #wall lock
        @direction = 4
        wall_lock
      #up is triggered and facing up
      elsif Input.trigger?(Input::UP) && @direction == 8
        #wall lock
        @direction = 2
        wall_lock
      end
    #if wall locked
    elsif @wall_lock
      #if moving forward or no wall behind or an event is behind
      if (@direction == 2 && (Input.trigger?(Input::DOWN) || passable?(@x,@y,8))) ||
         (@direction == 4 && (Input.trigger?(Input::LEFT) || passable?(@x,@y,6))) ||
         (@direction == 6 && (Input.trigger?(Input::RIGHT) || passable?(@x,@y,4))) ||
         (@direction == 8 && (Input.trigger?(Input::UP) || passable?(@x,@y,2))) ||
         !$game_map.check_event(@x + x * - 1, @y + y * -1).is_a?(Array)
        #unlock
        @direction_fix = false
        @wall_lock = false
      elsif Input.trigger?(Input::C)
        #noise check
        tee_make_noise(false)
      end
    end
    case terrain_tag
    when TEE::LOUD_T
      #reset speed increment
      @wrs_speed_increment = 0
      #if not moving
      unless moving?
        #if the sound hasn't been activated
        unless @sound_activated
          @sound_activated = true
          #noise check
          tee_make_noise(true)
        end
      else
        #reset sound if moving
        @sound_activated = false
      end
    when TEE::SLOW_T
      #decrease speed increment
      @wrs_speed_increment = -1
    when TEE::FAST_T
      #increase speed increment
      @wrs_speed_increment = 1
    when TEE::SLIP_T
      #reset speed increment
      @wrs_speed_increment = 0
      #if not moving
      unless moving?
        #move forward
        move_forward
        #disable walk animation
        @walk_anime = true
      else
        #enable walk animation
        @walk_anime = false
      end
    else
      #reset speed increment
      @wrs_speed_increment = 0
    end
    #if both sneak and run buttons are pressed and both
    #sneaking and running is allowed
    if Input.press?(TEE::RUN_K) && Input.press?(TEE::SNEAK_K) &&
       $game_system.wrs_run_enabled && $game_system.wrs_sneak_enabled
      #walk
      @wrs_speed = 2 + @wrs_speed_increment
    #if run button is pressed and running is allowed
    elsif Input.press?(TEE::RUN_K) && $game_system.wrs_run_enabled
      #run
      @wrs_speed = 3 + @wrs_speed_increment
    #if sneak button is pressed and sneaking is allowed
    elsif Input.press?(TEE::SNEAK_K) && $game_system.wrs_sneak_enabled
      #sneak
      @wrs_speed = 1 + @wrs_speed_increment
    #if nothing is pressed and either sneaking or running is allowed
    elsif $game_system.wrs_run_enabled || $game_system.wrs_sneak_enabled
      #walk
      @wrs_speed = 2 + @wrs_speed_increment
    end
    #Change actual speed
    case @wrs_speed
    when 0,1 #sneak
      @move_speed = TEE::SNEAK_S
    when 2 #walk
      @move_speed = TEE::WALK_S
    when 3 #run
      @move_speed = TEE::RUN_S
    when 4 #super run
      @move_speed = TEE::RUN_S + 1
    end
  end
  
  def tee_make_noise(noise)
    #volume for noise
    volume = 50
    #if noise terrain
    if noise
      dist = TEE::NOISE_D
      #adjust volume to move speed
      volume += 30 * ($game_player.wrs_speed - 2)
      #don't check if sneaking
      return if $game_player.wrs_speed == 1 if noise
      #if running double circle size
      dist = (dist * 2) - 1 if $game_player.wrs_speed == 3
      #play sound effect
      Audio.se_play('Audio/SE/' + TEE::NOISE_SOUND, volume)
    else #if knocking
      dist = TEE::KNOCK_D
      #play sound effect
      Audio.se_play('Audio/SE/' + TEE::KNOCK_SOUND, volume)
    end
    #even number fix
    if dist % 2 == 0
      dist += 1
    end
    #loop for distance
    for i in 0...dist
      #loop for the iterations per increment
      for j in 0...(dist - (2 * ((i-dist/2).abs)))
        #increment the x value for each loop
        x = $game_player.x - dist/2 + i
        #increment the y value for each j iteration
        y = $game_player.y - dist/2 + (dist/2-i).abs + j
        tee_noise_check(x,y,noise)
      end
    end
  end
  
  def tee_noise_check(x,y,noise)
    #highlight the coords if L is pressed and allowed
    if Input.press?(TEE::HIGHLIGHT_K) && TEE::HIGHLIGHT && $DEBUG
      $game_temp.highlight_new_coords << [x, y]
    end
    #variable for id
    id = $game_map.check_event(x,y)
    #return if there is no event in that location
    return if id.instance_of?(Array)
    #if the event has a field of view
    if $game_map.events[id].fov
      #switch activated
      switch = noise ? TEE::NOISE_S : TEE::KNOCK_S
      #variable for the events selfswitch A
      key = [$game_map.map_id,$game_map.check_event(x,y),switch]
      #set self switch to true
      $game_self_switches[key] = true
      #update self switches
      $game_map.need_refresh = true
    end
  end
  
  def wall_lock
    #lock to wall
    @direction_fix = true
    @wall_lock = true
    #make wall lock noise
    $game_system.se_play($data_system.cursor_se)
  end
  
  def terrain_ahead
    #returns the terrain tag of the position ahead of you
    x = (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
    y = (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
    return $game_map.terrain_tag(@x + x, @y + y)
  end
  
  def terrain_behind
    #returns the terrain tag of the position behind you
    x = (@direction == 6 ? -1 : @direction == 4 ? 1 : 0)
    y = (@direction == 2 ? -1 : @direction == 8 ? 1 : 0)
    return $game_map.terrain_tag(@x + x, @y + y)
  end
end

#===============================================================================
# Spriteset_Map
#===============================================================================

class Spriteset_Map
  alias nr_FOV_initialize initialize
  alias nr_FOV_update update
  def initialize( *args )
    @highlighted_squares = {}
    return nr_FOV_initialize( *args )
  end
  
  def update( *args )
    # Load the new coords
    for x, y in $game_temp.highlight_new_coords
      o_data = @highlighted_squares[ [ x, y ] ]
      if not o_data.nil?
        o_sprite = o_data[:sprite]
        o_sprite.bitmap.dispose unless o_sprite.bitmap.disposed?
        o_sprite.dispose unless o_sprite.disposed?
      end
      o_sprite = Sprite.new(@viewport1)
      o_sprite.bitmap = Bitmap.new(32, 32)
      o_sprite.bitmap.fill_rect(0, 0, 32, 32, Color.new(255, 0, 0, 100))
      o_data = { :sprite => o_sprite, :time_left => 3 }
      @highlighted_squares[ [ x, y ] ] = o_data
    end
    $game_temp.highlight_new_coords = []
    # Move the sprites to their coordinates
    @highlighted_squares.each do |key, data|
      data[:time_left] -= 1
      if data[:time_left] == 0
        data[:sprite].bitmap.dispose
        data[:sprite].dispose
        @highlighted_squares.delete(key)
      else
        x, y = key
        screen_x = (x * 128 - $game_map.display_x + 3) / 4
        screen_y = (y * 128 - $game_map.display_y + 3) / 4
        data[:sprite].x = screen_x
        data[:sprite].y = screen_y
        data[:sprite].update
      end
    end
    # Run the original update
    return nr_FOV_update( *args )
  end
end

#===============================================================================
# Interpreter
#===============================================================================

class Interpreter
  alias max_tee_command_201_later command_201
  alias max_tee_command_335_later command_355
  def command_201
    #resets the events if transferring maps
    $game_map.reset_fov_events
    max_tee_command_201_later
  end
  
  def command_355
    #stores the id of the last event interpreted
    $game_temp.last_event_interpreted = @event_id
    max_tee_command_335_later
  end
end

#===============================================================================
# Scene_Map
#===============================================================================

class Scene_Map
  alias max_tee_update_later update
  def update
    # Cancel old menu input
    if Input.trigger?(Input::B) && TEE::MENU_SPLIT
      return
    end
    max_tee_update_later
    # If new input button for menu is pressed
    if Input.trigger?(TEE::MENU_K) && TEE::MENU_SPLIT
      # If event is running, or menu is not forbidden
      unless $game_system.map_interpreter.running? or
             $game_system.menu_disabled
        # Set menu calling flag or beep flag
        $game_temp.menu_calling = true
        $game_temp.menu_beep = true
      end
    end
  end
end

#===============================================================================
# Scene_Menu
#===============================================================================

class Scene_Menu
  alias max_tee_update_command_later update_command
  def update_command
    max_tee_update_command_later
    #if new input button is pushed
    if Input.trigger?(TEE::MENU_K) && TEE::MENU_SPLIT
      # Play cancel SE
      $game_system.se_play($data_system.cancel_se)
      # Switch to map screen
      $scene = Scene_Map.new
      return
    end
  end
end


Screenshot




DEMO
http://www.mediafire.com/?0hcbnvbjjnmvgsb

Installation
Paste script above the main, and below the other default scripts

Terms and Conditions
Be sure to credit me if using this script. Contact me if there is any incompatibilities with other scripts or you would like any other features implemented.

Credits
Maximusmaxy - for writing the script
Night Runner - for writing the coordinate highlighter, helped a ton with debugging


__________________________
Check out the new PZE Forums! http://zeldaengine.net/index.php
Go to the top of the page
 
+Quote Post
   
SilentResident
post Oct 10 2011, 01:02 AM
Post #2


PZE Team Member
Group Icon

Group: Revolutionary
Posts: 669
Type: Developer
RM Skill: Skilled




QUOTE (maximusmaxy @ Oct 7 2011, 07:24 AM) *
Features
  • Modified Terrains (fast, slow, loud, slippery)


Wooot woot.gif Terrain-based movement speed... I will have this in my mind. Very useful for simulating stairs / sand / shallow water in a game. This is exactly what I was looking for, but never though it has to be a script instead of an event. Good work! thumbsup.gif


__________________________
Create, Share and Play your own Zelda 2D games with the Updated Project Zelda Engine!
The official website here: zeldaengine.net
Download it here: www.rpgrevolution.com
Download it here: www.rmrk.net
Download it here: www.rmxpunlimited.net
Download it here: www.creationasylum.net
Download it here: www.zfgc.com
Go to the top of the page
 
+Quote Post
   
Green Biker Dude...
post Oct 21 2011, 05:00 AM
Post #3


Level 3
Group Icon

Group: Member
Posts: 33
Type: Artist
RM Skill: Intermediate




Well, this is extremely cool! Nice work!

I was wondering if there are ways to change which sounds are used for noisy terrain, wall sticking, and wall knocking? Like if I wanted to change the sounds used in different rooms? Or even in the same room? Like the grates and normal floor in the same room both make sound, but it's a different sound? Even if they are right next to each other?

Is there a way to make wall sticking make the character move a little? Like, just a few pixels up? How about changing the character sheet? And how about doing that with the wall knocking too? When you do a wall knock, a way to make the character actually tap the wall?

Sorry to ask so many questions.

(Thumbs up for using a Snake sprite! And not yet another demo of Aluxes, ugh)
Go to the top of the page
 
+Quote Post
   

Closed TopicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 24th May 2013 - 07:43 AM
RPG RPG Revolution is an Privacy Policy and Legal
eXTReMe Tracker