RMRK is retiring.
Registration is disabled. The site will remain online, but eventually become a read-only archive. More information.

RMRK.net has nothing to do with Blockchains, Cryptocurrency or NFTs. We have been around since the early 2000s, but there is a new group using the RMRK name that deals with those things. We have nothing to do with them.
NFTs are a scam, and if somebody is trying to persuade you to buy or invest in crypto/blockchain/NFT content, please turn them down and save your money. See this video for more information.
[VX To VXA Conversion Request] Trace Stealth System

0 Members and 1 Guest are viewing this topic.

*
A-pow 2015
Rep:
Level 81
2014 Best RPG Maker User - GraphicsFor frequently finding and reporting spam and spam bots2013 Most Unsung MemberSecret Santa 2013 ParticipantFor taking arms in the name of your breakfast.How can I help you? :Da^2 + b^2 = c^2Secret Santa 2012 ParticipantSilver - GIAW 10Silver - GIAW 9Bronze - GIAW HalloweenGold - Game In A Week VII
<Prof. Meow Meow's Trace Stealth System Conversion>
<8/3/2013>



Summary
Description from the original topic found here.
Quote
The Trace Stealth System is now two systems: Sight & Sound. The sight system traces an imaginary line from each guard to the player. It follows each line, checking for impassable tiles. If no impassable tiles are detected, and if the player is within range, then the guard sees the player! The sound system lets event make "noise" of varying loudness. The louder a noise is, the further it travels, potentially attracting more guards!


Original Script

Code: [Select]
module Trace # <= don't touch this
#==============================================================================
# ? ??-VX ? Trace Stealth System ? version 2.2 ? P???. ???? ????
#------------------------------------------------------------------------------
# 1.0
# ? Initial release
# 1.1
# ? Alert no longer counts down while a message is displayed
# ? Revised the trace method, slimming it down and fixing the following bugs:
# ? Fixed a bug where tracers' vision would sometimes be blocked by itself
# ? Fixed a bug where tracers would see through Same As Characters events
# 2.0
# ? Added the sound stealth system
# ? Changed the way the trace range is handled
# ? Added ability to disable a tracer's senses
# 2.1
# ? Patched minors bugs
# 2.2
# ? Rewrote trace method using Bresenham's Line Algorithm
#==============================================================================
# ? Tracing With Style - please read everything!
#------------------------------------------------------------------------------
#   Tracer (n): Anything that is searching for the player, e.g., a guard.
#   Designate which events are a tracer by including "tracer" in its name.
#   When a tracer event sees the player, the Alert Switch it turned ON.
#   When the Alert Switch is turned on, a countdown begins. If the player
#   remains out of site for 1800 frames, the Alert Switch is turned OFF.
ALERT_SWITCH = 1        # any game switch
ALERT_COUNTDOWN = 1800  # frames (60 frames is 1 second; 1800 frames is 30 sec)
#==============================================================================
# ? Change How Far Your Guards Can See
#------------------------------------------------------------------------------
#   By default, tracers have an average range of vision: 5 tiles.
#   A tracer's range should be odd: 3, 5, 7, 9, etc.
#   An even value will be the next odd number, e.g., 4 will be a range of 5.
TRACE_RANGE_DEFAULT = 5 # any odd value
#   You can change the range at any time by calling this line:
#    ? $game_system.trace_range = n   where n is the new sight range
#   You may want to change the trace range when the lighting changes:
#    ? For a dark room, or during the night, use 3 or 5.
#    ? For a lit room, or during the day, use 5 or higher.
#==============================================================================
# ? Three Ways To Hide The Player From Sight
#------------------------------------------------------------------------------
#   There are three methods that can be used to hide the player:
#    ? Make the player transparent
#    ? Make the player's opacity to HIDE_OPACITY or lower
#    ? Change the Hide Switch to ON
HIDE_OPACITY = 100      # 0~255 (for realism, keep it low)
HIDE_SWITCH = 2         # any game switch
#==============================================================================
# ? 2.0 Feature ? Making a Ruckus: a guide to sound stealth ?
#------------------------------------------------------------------------------
#   All noises have a loudness value which is it's range. For example, a
#   noise with a loudness of 4 will be heard by all guards within 4 tiles.
#   To make a noise, call the following line from within a Move Route command:
#    ? tss_noise(n)   where n is the range of the noise
#   When a tracer hears a noise, its Caution Self Swith is set ON.
#   To have the tracer move toward the source the sound, call the following
#   line from within it's custom autonomous movement:
#    ? tss_investigate
#   Once the tracer reaches the source, its Caution Self Switch is set OFF.
CAUTION_SELF_SWITCH = "C"         # "A", "B", "C", or "D"
#   When the player sprints, he or she makes some noise!
#   You can change how much noise is made at any time by calling this line:
#    ? $game_player.sprint_noise = n   where n is the range of the noise
DEFAULT_SPRINT_NOISE = 3          # any value (set this to 0 to disable)
#   Here are some example of noises and their estimated range:
#    ? Creaking Floor............ 1~2
#    ? Carefully Closing a Door.. 2~3
#    ? Sneezing or Coughing...... 4~5
#    ? Bumping Into Something.... 4~5
#    ? Tripping Over Furniture... 6~7
#    ? Breaking Glass............ 8~9
#    Sprinting:
#    ? Thief Sprinting........... 2~3
#    ? Civilian Sprinting........ 4~6
#    ? Soldier Sprinting......... 7~9
#    Dialogue:
#    ? Whispering................ 2~3
#    ? Talking................... 4~6
#    ? Shouting.................. 7~9
#==============================================================================
# ? 2.0 Feature ? Two Ways To Disable a Tracer's Senses
#------------------------------------------------------------------------------
#   There are two methods that can be used to disable a tracer's "senses":
#    ? Erase the tracer event
#    ? Change it's Disabling Self Switch to ON
#   Prof tip: "D" is for many things- dead, disabled.... When you knock out a
#   guard, erase or turn it's "D" self switch ON so he can't see or hear you!
ALLOW_SELF_SWITCH_DISABLING = true  # true~false
DISABLING_SELF_SWITCH = "D"         # "A", "B", "C", or "D"
#==============================================================================
# ? Special Effects
#------------------------------------------------------------------------------
#   When a guard sees you, an ! appears above all heads and an ME plays.
SHOW_ALERT = true               # Do you want the ! to display? true~false
PLAY_ALERT = true               # Do you want an ME to play?    true~false
ALERT_ME = "Audio/ME/Shock"     # Which ME do you want to play? any ME
ALERT_VOLUME = 100              # At what volume?               0~100
ALERT_PITCH = 100               # At what pitch?                50~150
#   When the guards call off the search, a ? appears above all heads.
SHOW_QUIT = true                # Do you want the ? to display? true~false
#   2.0 Feature ? When a guards hears a noise, a ? appears above it's head
#   and an ME plays.
SHOW_CAUTION = true             # Do you want the ? to display? true~false
PLAY_CAUTION = true             # Do you want an ME to play?    true~false
CAUTION_ME = "Audio/ME/Mystery" # Which ME do you want to play? any ME
CAUTION_VOLUME = 100            # At what volume?               0~100
CAUTION_PITCH = 100             # At what pitch?                50~150
#==============================================================================
# ? 2.0 Feature ? Something For Fun
#------------------------------------------------------------------------------
#   You can call huh? or hey! through an event script to display '?' or '!'
#   above all active tracer heads!
#==============================================================================
# ? DO NOT TOUCH ANYTHING BELOW THIS POINT - this is for your own safety!   
#==============================================================================
CHECK_INTERVAL = 16  # 16
end
#==============================================================================
# Game System
#==============================================================================
class Game_System
  #----------------------------------------------------------------------------
  # Local Variables
  #----------------------------------------------------------------------------
  attr_accessor :trace_range
  attr_accessor :alert_countdown
  #----------------------------------------------------------------------------
  # Initialize
  #----------------------------------------------------------------------------
  alias trace_system_initialize initialize unless $@
  def initialize
    trace_system_initialize
    @trace_range = Trace::TRACE_RANGE_DEFAULT
    @alert_countdown = 0
  end
  #----------------------------------------------------------------------------
  # Update
  #----------------------------------------------------------------------------
  alias trace_system_update update unless $@
  def update
    trace_system_update
    if @alert_countdown > 0 and !$game_message.visible
      @alert_countdown -= 1
    elsif @alert_countdown <= 0 and $game_switches[Trace::ALERT_SWITCH]
      if Trace::SHOW_QUIT
        for i in $game_map.events.keys
          event = $game_map.events[i]
          if event.name.include?("tracer") and !event.erased
            next if Trace::ALLOW_SELF_SWITCH_DISABLING and
                    event.get_self_switch(Trace::DISABLING_SELF_SWITCH)
            event.balloon_id = 2
          end
        end
      end
      $game_switches[Trace::ALERT_SWITCH] = false
      $game_map.need_refresh = true
    end
  end
end
#==============================================================================
# Game Character
#==============================================================================
class Game_Character
  #----------------------------------------------------------------------------
  # Local Variables
  #----------------------------------------------------------------------------
  attr_accessor :old_x
  attr_accessor :old_y
  attr_accessor :old_player_x
  attr_accessor :old_player_y
  attr_accessor :attention_x
  attr_accessor :attention_y
  #----------------------------------------------------------------------------
  # Initialize
  #----------------------------------------------------------------------------
  alias trace_initialize initialize unless $@
  def initialize
    trace_initialize
    @old_x = @x
    @old_y = @y
    @old_player_x = 0
    @old_player_y = 0
    @attention_x = @x
    @attention_y = @y
  end
  #----------------------------------------------------------------------------
  # Update
  #----------------------------------------------------------------------------
  alias trace_update update unless $@
  def update
    trace_update
    if @id > 0 # if an event
      if name.include?("tracer") and not @erased
        if @old_x != @x or @old_y != @y or
           @old_player_x != $game_player.x or @old_player_y != $game_player.y
          if !$game_switches[Trace::ALERT_SWITCH]
            if tss_trace
              if Trace::PLAY_ALERT
                name = Trace::ALERT_ME
                volume = Trace::ALERT_VOLUME
                pitch = Trace::ALERT_PITCH
                Audio.me_play(name, volume, pitch)
              end
              if Trace::SHOW_ALERT                     
                for event in $game_map.events.values
                  if event.name.include?("tracer") and !event.erased
                    next if Trace::ALLOW_SELF_SWITCH_DISABLING and
                            event.get_self_switch(Trace::DISABLING_SELF_SWITCH)
                    event.balloon_id = 1
                  end
                end
              end
              $game_switches[Trace::ALERT_SWITCH] = true
              $game_system.alert_countdown = Trace::ALERT_COUNTDOWN
              $game_map.need_refresh = true
            end
          end
          @old_x = @x
          @old_y = @y
          @old_player_x = $game_player.x
          @old_player_y = $game_player.y
        end
        if [(@x - @attention_x).abs, (@y - @attention_y).abs].max < 2 and
        get_self_switch(Trace::CAUTION_SELF_SWITCH)
          @balloon_id = 2 if Trace::SHOW_QUIT
          set_self_switch(Trace::CAUTION_SELF_SWITCH, false)
        end
      end
    end
  end 
  #----------------------------------------------------------------------------
  # Trace
  #----------------------------------------------------------------------------
  def tss_trace(range = $game_system.trace_range)
    return false if Trace::ALLOW_SELF_SWITCH_DISABLING and
                    get_self_switch(Trace::DISABLING_SELF_SWITCH)
    return false if $game_player.transparent
    return false if $game_switches[Trace::HIDE_SWITCH]
    return false if $game_player.opacity <= Trace::HIDE_OPACITY
    return false if range > 0 and !player_in_sight_field?
    x0, y0 = @x * 32 + 16, @y * 32 + 16
    x1, y1 = $game_player.x * 32 + 16, $game_player.y * 32 + 16
    line_points = get_line(x0, y0, x1, y1)
    check_countdown = Trace::CHECK_INTERVAL
    line_points.each do |point|
      if check_countdown > 0
        check_countdown -= 1
      else
        check_countdown = Trace::CHECK_INTERVAL
        x, y = point[:x]/32, point[:y]/32
        return true if $game_player.pos?(x, y)
        break if !$game_player.passable?(x, y) and !pos?(x, y)
      end
    end
    return false
  end
  #----------------------------------------------------------------------------
  # Player In Sight Field?
  #----------------------------------------------------------------------------
  def player_in_sight_field?   
    # Find the center of the range because the range is radial
    range = 1 + $game_system.trace_range / 2
    # Find the center of the field of vision
    center_vision_x = @x
    center_vision_y = @y
    center_vision_y += range if @direction == 2
    center_vision_x -= range if @direction == 4
    center_vision_x += range if @direction == 6
    center_vision_y -= range if @direction == 8
    # Calculate the X & Y distances between the center of vision and player
    sx = center_vision_x - $game_player.x
    sy = center_vision_y - $game_player.y
    # Return true if the player is within the field of vision
    return true if [sx.abs,sy.abs].max < range
    # Otherwise, return false
    return false
  end
  #----------------------------------------------------------------------------
  # Noise
  #----------------------------------------------------------------------------
  def tss_noise(range = 0)
    if $game_switches[Trace::ALERT_SWITCH] == false
      for event in $game_map.events.values
        if event.name.include?("tracer") and !event.erased
          next if Trace::ALLOW_SELF_SWITCH_DISABLING and
          event.get_self_switch(Trace::DISABLING_SELF_SWITCH)
          sx = event.x - @x
          sy = event.y - @y
          if [sx.abs, sy.abs].max <= range
            if Trace::PLAY_CAUTION
              name = Trace::CAUTION_ME
              volume = Trace::CAUTION_VOLUME
              pitch = Trace::CAUTION_PITCH
              Audio.me_play(name, volume, pitch)
            end
            event.attention_x = @x
            event.attention_y = @y
            event.balloon_id = 2 if Trace::SHOW_CAUTION
            event.set_self_switch(Trace::CAUTION_SELF_SWITCH, true)
          end
        end
      end
    end 
  end
  #--------------------------------------------------------------------------
  # * Investigate
  #--------------------------------------------------------------------------
  def tss_investigate
    sx = @x - @attention_x
    sy = @y - @attention_y
    if sx.abs + sy.abs >= 20
      move_random
    else
      case rand(6)
      when 0..3;  move_toward_position(@attention_x,@attention_y)
      when 4;     move_random
      when 5;     move_forward
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Move Toward Position
  #--------------------------------------------------------------------------
  def move_toward_position(x,y)
    sx = @x - x
    sy = @y - y
    if sx != 0 or sy != 0
      if sx.abs > sy.abs                  # Horizontal distance is longer
        sx > 0 ? move_left : move_right   # Prioritize left-right
        if @move_failed and sy != 0
          sy > 0 ? move_up : move_down
        end
      else                                # Vertical distance is longer
        sy > 0 ? move_up : move_down      # Prioritize up-down
        if @move_failed and sx != 0
          sx > 0 ? move_left : move_right
        end
      end
    end
  end
  #----------------------------------------------------------------------------
  # Get Self Switch
  #----------------------------------------------------------------------------
  def get_self_switch(switch)
    key = [@map_id, @id, switch]
    return $game_self_switches[key]
  end
  #----------------------------------------------------------------------------
  # Set Self Switch
  #----------------------------------------------------------------------------
  def set_self_switch(switch,true_false)
    key = [@map_id, @id, switch]
    $game_self_switches[key] = true_false
    $game_map.need_refresh = true
  end
  #----------------------------------------------------------------------------
  # Get Line
  #----------------------------------------------------------------------------
  # Algorithm by.. Bresenham
  # Written by.... RogueBasin
  #----------------------------------------------------------------------------
  def get_line(x0,y0,x1,y1)
    original_x0, original_y0 = x0, y0
    points = []
    steep = ((y1-y0).abs) > ((x1-x0).abs)
    if steep
      x0,y0 = y0,x0
      x1,y1 = y1,x1
    end
    if x0 > x1
      x0,x1 = x1,x0
      y0,y1 = y1,y0
    end
    deltax = x1-x0
    deltay = (y1-y0).abs
    error = (deltax / 2).to_i
    y = y0
    ystep = nil
    if y0 < y1
      ystep = 1
    else
      ystep = -1
    end
    for x in x0..x1
      if steep
        points << {:x => y, :y => x}
      else
        points << {:x => x, :y => y}
      end
      error -= deltay
      if error < 0
        y += ystep
        error += deltax
      end
    end
    if original_x0 != points[0][:x] or original_y0 != points[0][:y]
      points.reverse!
    end
    return points
  end
end
#==============================================================================
# Game Event
#==============================================================================
class Game_Event < Game_Character
  #----------------------------------------------------------------------------
  # Name (get name)
  #----------------------------------------------------------------------------
  def name
    return @event.name
  end
  #----------------------------------------------------------------------------
  # Erased (get erased)
  #----------------------------------------------------------------------------
  def erased
    return @erased
  end
end
#==============================================================================
# Game Player
#==============================================================================
class Game_Player < Game_Character
  #----------------------------------------------------------------------------
  # Local Variables
  #----------------------------------------------------------------------------
  attr_accessor :old_steps
  attr_accessor :sprint_noise
  #----------------------------------------------------------------------------
  # Initialize
  #----------------------------------------------------------------------------
  alias trace_player_initialize initialize unless $@
  def initialize
    trace_player_initialize
    @old_steps = 0
    @sprint_noise = Trace::DEFAULT_SPRINT_NOISE
  end
  #----------------------------------------------------------------------------
  # Update
  #----------------------------------------------------------------------------
  alias trace_player_update update unless $@
  def update
    trace_player_update
    if $game_party.steps > @old_steps + 5 and moving? and dash?
      tss_noise(@sprint_noise)
      @old_steps = $game_party.steps
    end
  end
end
#==============================================================================
# Game Interpreter
#==============================================================================
class Game_Interpreter
  #----------------------------------------------------------------------------
  # Huh?
  #----------------------------------------------------------------------------
  def huh?
    for event in $game_map.events.values
      if event.name.include?("tracer") and !event.erased
        next if Trace::ALLOW_SELF_SWITCH_DISABLING and
        event.get_self_switch(Trace::DISABLING_SELF_SWITCH)
        event.balloon_id = 2 # display ?
      end
    end
  end
  #----------------------------------------------------------------------------
  # Hey!
  #----------------------------------------------------------------------------
  def hey!
    for event in $game_map.events.values
      if event.name.include?("tracer") and !event.erased
        next if Trace::ALLOW_SELF_SWITCH_DISABLING and
        event.get_self_switch(Trace::DISABLING_SELF_SWITCH)
        event.balloon_id = 1 # display !
      end
    end
  end
end

Features Desired
Honestly just having the script converted as is would be great, but if it's not too much work, having the guards go back to where they originated after getting out of the alert or caution phase would be great.

Games its been in
  • Metal Gear
  • Splinter Cell?
  • Pretty much any other stealthy game.



Did you search?
I searched everywhere. At one point I even tried eventing it. It wasn't pretty.

The only script that I've been able to find that even comes close to this is Jet's Stealth System, and it doesn't really have the features necessary for what I want to do.

Where did you search?
  • Pretty much any RPG maker community you could think of.

What did you search for?
  • Stealth System
  • Line of Sight
  • Metal Gear guard system, ect.

**
Rep:
Level 73
RMRK Junior

*
A-pow 2015
Rep:
Level 81
2014 Best RPG Maker User - GraphicsFor frequently finding and reporting spam and spam bots2013 Most Unsung MemberSecret Santa 2013 ParticipantFor taking arms in the name of your breakfast.How can I help you? :Da^2 + b^2 = c^2Secret Santa 2012 ParticipantSilver - GIAW 10Silver - GIAW 9Bronze - GIAW HalloweenGold - Game In A Week VII
Wow, that was quick. Thanks!

Edit: It looks like they can see through walls though. Is there any way to fix that?
« Last Edit: August 04, 2013, 05:56:39 AM by Acolyte »

**
Rep:
Level 73
RMRK Junior

*
A-pow 2015
Rep:
Level 81
2014 Best RPG Maker User - GraphicsFor frequently finding and reporting spam and spam bots2013 Most Unsung MemberSecret Santa 2013 ParticipantFor taking arms in the name of your breakfast.How can I help you? :Da^2 + b^2 = c^2Secret Santa 2012 ParticipantSilver - GIAW 10Silver - GIAW 9Bronze - GIAW HalloweenGold - Game In A Week VII
Thanks again. Everything seems to work fine now.