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
> Stealth Detection System, Translated from VX (something people been waiting for since Janurary)
Bigace
post Jul 13 2010, 05:11 PM
Post #1


The King of Spades
Group Icon

Group: Revolutionary
Posts: 400
Type: Developer
RM Skill: Intermediate




Stealth Detection System (SDS)
Multi-style stealth system (v1.1 since June 17 2008)



Version: 1.1
Creator: Cmpsr2000
VX Release Date: June 17 2008
Exclusive VX Version: Stealth Detection System for VX
Edited by: Night_Runner
XP Release Date: July 13 2010


Introduction
SDS allows the developer to build games that include "Stealth" features similar to certain Final Fantasy games or even Metal Gear Solid.
.
Features
Make any event "aware" of its surroundings, effectively turning it into a "guard"
Execute 4 different actions on detection:
Mode 0: Send to Jail (transfer player)
Mode 1: Game Over
Mode 2: Common Event

Mode 3: MGS Mode
Create a "jail" event anywhere on the map!
MGS Mode allows guards to be alerted before trying to capture the player
Guard intercept speed in MGS mode can be customized
Final capture action in MGS mode can be customized
Guard search time in MGS mode can be customized
Guards can have custom sight ranges
Guards can have tunnel vision or a "cone" field of view
Tunnel width for tunnel vision can be customized
Guards' sight is blocked by objects by default, but this can be disabled by granting "truesight"
Mode 2 can execute any custom event you specify
Guards have a circle of awareness around themselves that can be disabled if desired

Script
Redefinitions
CODE
#-------------------------------------------------------------------------------
# This is a surprise ^^
#-------------------------------------------------------------------------------
module Sound
  def self.play_found
    Audio.se_play("Audio/SE/found.wav", 100, 100)
  end
end



#-------------------------------------------------------------------------------
# This contains command for object movement and can be reused and included in
# any game_character or it's descendants.
#-------------------------------------------------------------------------------
module Movement
  #-----------------------------------------------------------------------------
  # Checks to see whether this object has moved since the last check.
  # RETURNS: Boolean
  #-----------------------------------------------------------------------------
  def moved?
    if self.x != @oldX or self.y != @oldY
      setPosition
      return true
    else
      return false
    end
  end
  #-----------------------------------------------------------------------------
  # Checks to see whether this object has turned.
  # RETURNS: Boolean
  #-----------------------------------------------------------------------------
  def turned?
    if self.direction != @oldDirection
      setDirection
      return true
    else
      return false
    end
  end
  #-----------------------------------------------------------------------------
  # Saves the current direction so that it can be checked against after a turn
  #-----------------------------------------------------------------------------
  def setDirection
    @oldDirection = self.direction
  end
  #-----------------------------------------------------------------------------
  # Saves the current position so that it can be checked against after a move
  #-----------------------------------------------------------------------------
  def setPosition
    @oldX = self.x
    @oldY = self.y
  end
  #-----------------------------------------------------------------------------
  # Changes the object's route to perform an in-place spin while waiting after
  # each turn. It is recommended to call object.lock before using this, and
  # call object.unlock when it has complete.
  #-----------------------------------------------------------------------------
  def spinInPlace(waitTime)
    spinRoute = RPG::MoveRoute.new
    spinRoute.repeat = false
    #spinRoute.wait = true
    for x in 0..3
      spinRoute.list.push(RPG::MoveCommand.new(15, [waitTime]))
      spinRoute.list.push(RPG::MoveCommand.new(16 + x))
    end
    spinRoute.list.push(RPG::MoveCommand.new(15, [waitTime]))
    spinRoute.list.push(RPG::MoveCommand.new(0))
    spinRoute.list.delete_at(0) #weird RGSS Anomoly, must delete empty position
    
    self.move_route = spinRoute
    self.move_route_index = 0
  end
  #-----------------------------------------------------------------------------
  # This is an advanced pathfinding algorithm that returns a boolean indicating
  # whether or not it was able to find a path from the start point (the object's
  # current location) to the endpoint, then changes the object's move values
  # to initiate movement. RETURNS: Boolean
  #   finalX:   x coordinate of the destination
  #   finalY:   y coordinate of the destination
  #-----------------------------------------------------------------------------
  def goto(finalX, finalY)
    return true if self.x == finalX and self.y == finalY
    startX = self.x
    startY = self.y
    
    #figure out the route: A* algorithm
    @activeList = []
    @activeParents = []
    @activeScores = []
    @closedList = []
    @closedParents = []
    @closedScores = []
    @activeList.push([startX, startY])
    @activeParents.push([startX, startY])
    @activeScores.push([0,0,0])
    noPath = false
    finalNode = [finalX, finalY]
    
    #main logic
    while @closedList.index(finalNode) == nil
      nodeToCheck = @activeList[0]  #lowest F is always in position 0!
      if nodeToCheck == nil
        noPath = true
        break
      end
      moveToClosed(nodeToCheck)
      for node in adjacentNodes(nodeToCheck) #a "node" is an array: [x, y] !!!
        if ($game_map.passable?(node[0], node[1], 0) and
           @closedList.index(node) == nil) or node == finalNode
          index = @activeList.index(node)
          if index == nil
            scores = calcScores(node, nodeToCheck, finalNode)
            insertionPoint = findInsertionPoint(scores[0])
            @activeList.insert(insertionPoint, node)
            @activeParents.insert(insertionPoint, nodeToCheck)
            @activeScores.insert(insertionPoint, scores)
          else
            g = calcG(nodeToCheck)
            if g < @activeScores[index][1]
              @activeParents[index] = nodeToCheck
              h = @activeScores[index][2]
              f = g + h
              @activeScores[index] = [f, g, h]
              insertionPoint = findInsertionPoint(@activeScores[index][0])
              
              #we don't need to reinsert if we already exist in the right place
              if insertionPoint != index
                tempNode   = @activeList[index]
                tempParent = @activeParents[index]
                tempScores = @activeScores[index]
                
                #delete existing
                @activeList.delete(tempNode)
                @activeParents.delete(tempParent)
                @activeScores.delete(tempScores)
                
                #reinsert
                @activeList.insert(insertionPoint, tempNode)
                @activeParents.insert(insertionPoint, tempParent)
                @activeScores.insert(insertionPoint, tempScores)
              end
            end
          end
        end
      end
    end
    
    #return if there is no path, otherwise build the path
    return false if noPath
    path = [finalNode]
    parent = @closedParents[@closedList.index(finalNode)]
    while parent != [startX, startY]
      path.push(parent)
      parent = @closedParents[@closedList.index(parent)]
    end
    path.reverse! #put the path in order of execution
    
    #make a new route object that doesn't repeat (one time use only!)
    gotoRoute = RPG::MoveRoute.new
    gotoRoute.repeat = false
    
    #itterate through the path and add the appropriate commands to the route
    #we can't move diagonal, so only one x or one y should change between steps
    lastNode = [startX, startY]
    for node in path
      if node[0] > lastNode[0]
        commandCode = 3 # move right
      elsif node[0] < lastNode[0]
        commandCode = 2 # move left
      else
        if node[1] > lastNode[1]
          commandCode = 1 # move down
        elsif node[1] < lastNode[1]
          commandCode = 4 # move up
        end
      end
      lastNode = node
      gotoRoute.list.push(RPG::MoveCommand.new(commandCode))
    end
    gotoRoute.list.push(RPG::MoveCommand.new(0))
    gotoRoute.list.delete_at(0) #weird RGSS Anomoly, must delete empty position
    
    #set the object's route and return!
    self.move_route = gotoRoute
    self.move_route_index = 0
    return true
  end
  #-----------------------------------------------------------------------------
  # moves the active node to the closed list so it's not checked twice!
  #-----------------------------------------------------------------------------
  def moveToClosed(activeNode)
    index = @activeList.index(activeNode)
    
    #add to closed
    @closedList.push(@activeList[index])
    @closedParents.push(@activeParents[index])
    @closedScores.push(@activeScores[index])
    
    #delete from active
    @activeList.delete_at(index)
    @activeParents.delete_at(index)
    @activeScores.delete_at(index)
  end
  #-----------------------------------------------------------------------------
  # finds the array insertion point based on the f score
  #-----------------------------------------------------------------------------
  def findInsertionPoint(f)
    insertionPoint = 0
    if @activeList.length != 0
      while insertionPoint < @activeList.length
        if f <= @activeScores[insertionPoint][0]
          break
        else
          insertionPoint += 1
        end
      end  
    end
    
    return insertionPoint
  end
  #-----------------------------------------------------------------------------
  # calculates all the scores for a node
  #-----------------------------------------------------------------------------
  def calcScores(node, parentNode, finalNode)
    h = calcH(node, finalNode)
    g = calcG(parentNode)
    f = g + h
    
    return [f, g, h]
  end
  #-----------------------------------------------------------------------------
  # calculates the G value (route distance)
  #-----------------------------------------------------------------------------
  def calcG(parentNode)
    #can't move diagonly: just add 1 to parent score
    index = @closedList.index(parentNode)
    score = @closedScores[index][1] + 1
    return score
  end
  #-----------------------------------------------------------------------------
  # claculates the H value (distance from start to finish)
  #-----------------------------------------------------------------------------
  def calcH(node, finalNode)
    #Manhattan method is admissible in this context
    score = (node[0] - finalNode[0]).abs + (node[1] - finalNode[1]).abs
    
    return score
  end
  #-----------------------------------------------------------------------------
  # Finds the adjacent nodes of the active node
  #-----------------------------------------------------------------------------
  def adjacentNodes(sourceNode)
    node1 = [sourceNode[0] + 1, sourceNode[1]]
    node2 = [sourceNode[0], sourceNode[1] + 1]
    node3 = [sourceNode[0] - 1, sourceNode[1]]
    node4 = [sourceNode[0], sourceNode[1] - 1]
    return [node1, node2, node3, node4]
  end
end



#-------------------------------------------------------------------------------
# the instance of $game_stealth needs to be created
#-------------------------------------------------------------------------------
class Scene_Title
  alias oldCommandNewGameStealth command_new_game
  def command_new_game
    $game_stealth = Game_Stealth.new
    oldCommandNewGameStealth
  end
end



#-------------------------------------------------------------------------------
# saveing and loading $game_stealth
#-------------------------------------------------------------------------------
class Scene_Save
  #--------------------------------------------------------------------------
  # * Write Save Data
  #     file : write file object (opened)
  #--------------------------------------------------------------------------
  alias old_WriteSaveDataStealth write_save_data
  def write_save_data(file)
    old_WriteSaveDataStealth(file)
    Marshal.dump($game_stealth, file)
  end
end
class Scene_Load
  #--------------------------------------------------------------------------
  # * Read Save Data
  #     file : write file object (opened)
  #--------------------------------------------------------------------------
  alias old_ReadSaveDataStealth read_save_data
  def read_save_data(file)
    old_ReadSaveDataStealth(file)
    $game_stealth = Marshal.load(file)
  end
end




#-------------------------------------------------------------------------------
# The stealth system needs to be updated every frame along with the map scene
#-------------------------------------------------------------------------------
class Scene_Map
  alias oldUpdateStealth update
  def update
    oldUpdateStealth
    unless $game_temp.message_window_showing      # Unless displaying a message
      $game_stealth.update
    end
  end
end



class Game_Character
  alias nr_sds_initialize initialize
  def initialize(*args)
    nr_sds_initialize(*args)
    @move_failed = false
  end
  #--------------------------------------------------------------------------
  # * Determine if Stopping
  #--------------------------------------------------------------------------
  def stopping?
    return (not (moving? or jumping?))
  end
  #--------------------------------------------------------------------------
  # * Move Down
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_down(turn_enabled = true)
    # Turn down
    if turn_enabled
      turn_down
    end
    # If passable
    if passable?(@x, @y, 2)
      # Turn down
      turn_down
      # Update coordinates
      @y += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x, @y+1)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Left
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_left(turn_enabled = true)
    # Turn left
    if turn_enabled
      turn_left
    end
    # If passable
    if passable?(@x, @y, 4)
      # Turn left
      turn_left
      # Update coordinates
      @x -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x-1, @y)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Right
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_right(turn_enabled = true)
    # Turn right
    if turn_enabled
      turn_right
    end
    # If passable
    if passable?(@x, @y, 6)
      # Turn right
      turn_right
      # Update coordinates
      @x += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x+1, @y)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move up
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_up(turn_enabled = true)
    # Turn up
    if turn_enabled
      turn_up
    end
    # If passable
    if passable?(@x, @y, 8)
      # Turn up
      turn_up
      # Update coordinates
      @y -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x, @y-1)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Lower Left
  #--------------------------------------------------------------------------
  def move_lower_left
    # If no direction fix
    unless @direction_fix
      # Face down is facing right or up
      @direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction)
    end
    # When a down to left or a left to down course is passable
    if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 4)) or
       (passable?(@x, @y, 4) and passable?(@x - 1, @y, 2))
      # Update coordinates
      @x -= 1
      @y += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Lower Right
  #--------------------------------------------------------------------------
  def move_lower_right
    # If no direction fix
    unless @direction_fix
      # Face right if facing left, and face down if facing up
      @direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction)
    end
    # When a down to right or a right to down course is passable
    if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 6)) or
       (passable?(@x, @y, 6) and passable?(@x + 1, @y, 2))
      # Update coordinates
      @x += 1
      @y += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Upper Left
  #--------------------------------------------------------------------------
  def move_upper_left
    # If no direction fix
    unless @direction_fix
      # Face left if facing right, and face up if facing down
      @direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction)
    end
    # When an up to left or a left to up course is passable
    if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 4)) or
       (passable?(@x, @y, 4) and passable?(@x - 1, @y, 8))
      # Update coordinates
      @x -= 1
      @y -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Upper Right
  #--------------------------------------------------------------------------
  def move_upper_right
    # If no direction fix
    unless @direction_fix
      # Face right if facing left, and face up if facing down
      @direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction)
    end
    # When an up to right or a right to up course is passable
    if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 6)) or
       (passable?(@x, @y, 6) and passable?(@x + 1, @y, 8))
      # Update coordinates
      @x += 1
      @y -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
end



class Game_Player < Game_Character
  include Movement
  attr_accessor :detected
  def transfer(new_map, new_x, new_y, new_dir)
    # Set transferring player flag
    $game_temp.player_transferring = true
    # Set player move destination
    $game_temp.player_new_map_id = new_map
    $game_temp.player_new_x = new_x
    $game_temp.player_new_y = new_y
    $game_temp.player_new_direction = new_dir
    Graphics.freeze
    # Set transition processing flag
    $game_temp.transition_processing = true
    $game_temp.transition_name = ""
  end
end



#-------------------------------------------------------------------------------
# Events have tons of new attributes with the stealth system. Plus, we need to
# include the movement module and initialize awareness to false.
#-------------------------------------------------------------------------------
class Game_Event < Game_Character
  include Movement
  
  #for all stealth
  attr_accessor :isAware
  attr_accessor :detectRange
  attr_accessor :tunnelVision
  attr_accessor :trueSight
  attr_accessor :detectAction
  attr_accessor :originalAction
  
  #For MGS-style stealth
  attr_accessor :move_speed
  attr_accessor :move_frequency
  attr_accessor :detectState
  attr_accessor :move_route_index
  attr_accessor :move_route
  attr_accessor :returnX
  attr_accessor :returnY
  attr_accessor :returnRoute
  attr_accessor :returnRouteIndex
  attr_accessor :returnSpeed
  attr_accessor :returnFrequency
  attr_reader   :move_failed
  
  alias oldInitStealth initialize
  def initialize(map_id, event)
    oldInitStealth(map_id, event)
    @isAware = false
  end
end

Game_Stealth
CODE
#-------------------------------------------------------------------------------

#

#                           Stealth Detection System v 1.0

#                    code by cmpsr2000 @ rpgrevolution.com/forums

#                               Released June 11, 2008

#

#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------

#

# SDS is an advanced stealth detection system for use in RPG Maker VX games.

# To use the system, you need to build an event that begins with a script call:

#

#   $game_stealth.detector(eventID, detectRange, detectAction,

#                          tunnelVision, trueSight)

#

#   eventID:        The ID of the event. Use @event_id as it's the easiest way

#   detectRange:    How far the "guard" is able to see. Higher numbers require

#                   more CPU time to proccess! Lag increases exponentially if

#                   you are NOT using tunnel vision.

#   detectAction:   The action to perform when the guard detects the player

#                   DEFAULT = 1

#                   0: Goto jail event

#                   1: Game Over

#                   2: Execute common event

#                   3: MGS Mode

#   tunnelVision:   determines whether the guard's field of view cones out or

#                   goes in a straight line.

#                   DEFAULT = false

#   trueSight:      determines whether the guard can see through obstacles

#                   DEFAULT = false

#

#   NOTE: You do NOT have to set parameters that have a default.

#

#                         MGS MODE EXPLAINATION:

#

#       When using detectAction 3 (MGS Mode) guards will be "alerted" if

#       they spot the player. The guard will run to the position they spotted

#       the player at, then begin to look around for the player again. If the

#       guard sees the player a second time, the captureAction is performed.

#

#-------------------------------------------------------------------------------

class Game_Stealth

  

  attr_accessor :common_event_id

  

  def initialize

    @checkedTiles   = []

    @fovPassability = {}

    @detectingEvent = nil

    @tempInterpreter = nil

    @alertedGuards = []

    

    #---------------------------------------------------------------------------

    # If you use tunnel vision, set the tunnel width here. It MUST be an ODD

    # number or the game will round up to the next odd number! Widths over 3

    # are not recomended.

    #---------------------------------------------------------------------------

    @tunnelWidth = 3

    

    #---------------------------------------------------------------------------

    # The common event ID to execute when using the common event detect action

    #---------------------------------------------------------------------------

    @common_event_id = 1

    

    #---------------------------------------------------------------------------

    # The speed and frequency the guards move when they detect the player in

    # MGS mode.

    #   speed:      1: x8 slower,

    #               2: x4 slower

    #               3: x2 slower

    #               4: normal

    #               5: x2 faster

    #               6: x4 faster

    #

    #   frequency:  1: lowest

    #               2: lower

    #               3: normal

    #               4: higher

    #               5: highest

    #---------------------------------------------------------------------------

    @guardInterceptSpeed = 4

    @guardInterceptFrequency = 6

    

    #---------------------------------------------------------------------------

    # When in MGS mode, the action to be performed if the guard detects the

    # player a second time. This is set by default to game_over since all other

    # options require some configuration. Valid values are:

    #   captureAction:  0: Goto jail event

    #                   1: Game Over

    #                   2: Execute common event

    #---------------------------------------------------------------------------

    @captureAction = 1

    

    #---------------------------------------------------------------------------

    # How many frames a guard will wait before executing each turn when

    # searching for the player after detecting them in MGS mode.

    #---------------------------------------------------------------------------

    @waitTime = Graphics.frame_rate / 2 # 40

    

    #---------------------------------------------------------------------------

    # Change this to false to disable the detection radius around guards.

    # This means the player can safely stand next to a guard as long as he's

    # not in the guard's line of sight.

    #---------------------------------------------------------------------------

    @allowDetectRadius= true</FONT></P> <P><FONT size=6><FONT size=2>    @tunnelWidth += 1 if (@tunnelWidth % 2) == 1

  end

  

  #-----------------------------------------------------------------------------

  # Standard update method; checks for player detection then handles MGS

  # state changes for guards then checks for player detection again

  #-----------------------------------------------------------------------------

  def update

    if $game_player.detected and not $game_player.moving?

      doDetectAction

    end

    for guard in @alertedGuards

      case guard.detectState

      when nil, 0 #alerted

        guard.lock

        guard.returnX           = guard.x

        guard.returnY           = guard.y

        guard.returnRoute       = guard.move_route

        guard.returnRouteIndex  = guard.move_route_index

        guard.returnSpeed       = guard.move_speed

        guard.returnFrequency   = guard.move_frequency

        guard.move_speed        = @guardInterceptSpeed

        guard.move_frequency    = @guardInterceptFrequency

        guard.isAware = false

        guard.detectState = guard.goto($game_player.x, $game_player.y) ? 1 : 3

        guard.unlock

      when 1 #intercepting

        if (guard.move_route_index == guard.move_route.list.length - 1 and

           guard.stopping?) or guard.move_failed

          guard.lock

          guard.isAware = true

          guard.spinInPlace(@waitTime)

          guard.detectState = 2

          guard.unlock

        end

      when 2 #checking

        if guard.move_route_index == guard.move_route.list.length - 1 and

           guard.stopping?

          guard.lock

          guard.isAware = false

          go = guard.goto(guard.returnX, guard.returnY)

          guard.detectState = 3

          guard.unlock

        end

      when 3 #returning

        if guard.move_route_index == guard.move_route.list.length - 1 and not

           guard.moving?

          guard.lock

          guard.isAware = true

          guard.move_route        = guard.returnRoute

          guard.move_route_index  = guard.returnRouteIndex

          guard.move_speed        = guard.returnSpeed

          guard.move_frequency    = guard.returnFrequency

          guard.detectState       = 0

          @captured = false

          @alertedGuards.delete(guard)

          guard.unlock

        end

      end

    end

    observe

  end

  #-----------------------------------------------------------------------------

  # Runs through the aware events(guards) on the map and tells them to check

  # for the player.

  #-----------------------------------------------------------------------------

  def observe

    for event in $game_map.events.values #events is a hash!

      if event.isAware

        if event.moved? or event.turned? or $game_player.moved?

          if checkForDetection(event)

            $game_player.detected = true

            @detectingEvent = event

            return

          end

        end

      end

      @checkedTiles   = []

      @fovPassability = {}

    end

  end

  #-----------------------------------------------------------------------------

  # Runs through each tile in the event(guard)'s field of view and checks

  # it for the player. RETURNS: Boolean

  #   event:    The guard that is currently checking for the player.

  #-----------------------------------------------------------------------------

  def checkForDetection(event)

    return true if playerInDetectionRadius(event)

    return false if playerOutOfRange(event)

    fieldOfView = event.tunnelVision ? @tunnelWidth : 1

    for distance in 1..event.detectRange

      for width in 1..fieldOfView

        return true if checkTile(event, width, distance)

      end

      fieldOfView += 2 unless event.tunnelVision

    end

    return false

  end

  #-----------------------------------------------------------------------------

  # Checks a tile for the player. RETURNS: Boolean

  #   event:    The guard that is currently checking for the player.

  #   width:    The width-index of the tile being checked

  #   distance: The depth-index of the tile being checked

  #-----------------------------------------------------------------------------

  def checkTile(event, width, distance)

    if event.tunnelVision

      if @tunnelWidth > 1

        width = width - ((@tunnelWidth - 1)/2)

      else

        width = 0

      end

    else

      width -= distance

    end

    x = event.x

    y = event.y

    direction = event.direction

    case direction

    when 2

      y += distance

      x += width

    when 4

      y += width

      x -= distance

    when 6

      y += width

      x += distance

    when 8

      y -= distance

      x += width

    end

    return false if @checkedTiles.index([x,y]) != nil

    return false if tileHidden?(event, x, y)

    return true if $game_player.x == x and $game_player.y == y

    return false

  end

  #-----------------------------------------------------------------------------

  # Determines the visibility of a tile to a guard. RETURNS: Boolean

  #   event:    The guard that is currently checking for the player.

  #   x:        The x coordinate of the tile to be checked

  #   y:        The y coordinate of the tile to be checked

  #-----------------------------------------------------------------------------

  def tileHidden?(event, x, y)

    return false if event.trueSight

    #check the current tile first

    @checkedTiles.push([x,y])

    originalX = x

    originalY = y

    if not $game_map.passable?(x, y, 0)

      @fovPassability[[x,y]] = false

      return true

    end

    

    #now check all adjacent tiles one step closer to the detector

    direction = event.direction

    case direction

    when 2 #down

      y -= 1

      for i in (x-1)..(x+1)

        #if we've checked the tile, then it exists in the FoV

        if @checkedTiles.index([i,y]) != nil

          if not @fovPassability[[i,y]]

            @fovPassability[[originalX,originalY]] = false

            return true

          end

        end

      end

    when 4 #left

      x += 1

      for i in (y-1)..(y+1)

        #if we've checked the tile, then it exists in the FoV

        if @checkedTiles.index([x,i]) != nil

          if not @fovPassability[[x,i]]

            @fovPassability[[originalX,originalY]] = false

            return true

          end

        end

      end

    when 6 #right

      x -= 1

      for i in (y-1)..(y+1)

        #if we've checked the tile, then it exists in the FoV

        if @checkedTiles.index([x,i]) != nil

          if not @fovPassability[[x,i]]

            @fovPassability[[originalX,originalY]] = false

            return true

          end

        end

      end

    when 8 #up

      y += 1

      for i in (x-1)..(x+1)

        #if we've checked the tile, then it exists in the FoV

        if @checkedTiles.index([i,y]) != nil

          if not @fovPassability[[i,y]]

            @fovPassability[[originalX,originalY]] = false

            return true

          end

        end

      end

    end

    

    #this tile and the blocking tiles must be passable

    @fovPassability[[originalX,originalY]] = true

    return false

  end

  #-----------------------------------------------------------------------------

  # Guards and other "detector" events have an awareness of their immediate

  # surroundings. If the player is adjacent to the event, they will be

  # discovered if @allowDetectRadius is true. RETURNS: Boolean

  #   event:    The guard that is currently checking for the player.

  #-----------------------------------------------------------------------------

  def playerInDetectionRadius(event)

    return false unless @allowDetectRadius

    adjacentTiles = [ [event.x, event.y - 1],

                      [event.x + 1, event.y - 1],

                      [event.x + 1, event.y],

                      [event.x + 1, event.y + 1],

                      [event.x, event.y + 1],

                      [event.x - 1, event.y + 1],

                      [event.x - 1, event.y],

                      [event.x - 1, event.y - 1] ]

    for tile in adjacentTiles

      if $game_player.x == tile[0] and $game_player.y == tile[1]

        return true

      end

    end

    return false

  end

  

  def playerOutOfRange(event)

    direction = event.direction

    case direction

    when 2 #down

      yDifference = event.y - $game_player.y

      xDifference = event.x - $game_player.x

      coneWidth = event.tunnelVision ? (@tunnelWidth / 2).floor : event.detectRange - 1

      if yDifference > event.detectRange or $game_player.y < event.y - 1 or

         (xDifference.abs > coneWidth)

        return true

      end

    when 4 #left

      yDifference = event.y - $game_player.y

      xDifference = event.x - $game_player.x

      coneWidth = event.tunnelVision ? (@tunnelWidth / 2).floor : event.detectRange - 1

      if xDifference > event.detectRange or $game_player.x > event.x + 1 or

         (yDifference.abs > coneWidth)

        return true

      end

    when 6 #right

      yDifference = $game_player.y - event.y

      xDifference = $game_player.x - event.x

      coneWidth = event.tunnelVision ? (@tunnelWidth / 2).floor : event.detectRange - 1

      if xDifference > event.detectRange or $game_player.x < event.x - 1 or

         (yDifference.abs > coneWidth)

        return true

      end

    when 8 #up

      yDifference = event.y - $game_player.y

      xDifference = event.x - $game_player.x

      coneWidth = event.tunnelVision ? (@tunnelWidth / 2).floor : event.detectRange - 1

      if yDifference > event.detectRange or $game_player.y > event.y + 1 or

         (xDifference.abs > coneWidth)

        return true

      end

    end

    return false

  end

  #-----------------------------------------------------------------------------

  # Called in an event to enable detection for the event (guard).

  #   eventID:      The id of the event. use @event_id in your event call!

  #   detectRange:  How far away the guard can see

  #   detectAction: What happens when caught. defaults to game_over

  #   tunnelVision: Whether the guard has field of view or tunnel vision

  #   trueSight:    Whether the guard can see through objects

  #-----------------------------------------------------------------------------

  def detector(eventID, detectRange, detectAction = 1,

               tunnelVision = false, trueSight = false)

    event               = $game_map.events[eventID]

    event.isAware       = true

    event.detectAction  = detectAction

    event.detectRange   = detectRange

    event.tunnelVision  = tunnelVision

    event.trueSight     = trueSight

    event.setPosition

  end

  #-----------------------------------------------------------------------------

  # Called in an event to set the location tile of the "jail"

  #   eventID:   The ID of the event that is at the jail location.

  #              Again, use @event_id

  #-----------------------------------------------------------------------------

  def jail(eventID)

    event = $game_map.events[eventID]

    @jailX      = event.x

    @jailY      = event.y

  end

  #-----------------------------------------------------------------------------

  # Executes the desired action upon detecting the player

  #-----------------------------------------------------------------------------

  def doDetectAction

    case @detectingEvent.detectAction

    when 0 # goto jail

      sendToJail

    when 1 # game over

      $scene = Scene_Gameover.new

    when 2 # execute common event

      doCommonEvent

    when 3 # MGS - enemy moves towards player position

      if @detectingEvent.detectState == 2

        if not @captured

          case @captureAction

          when 0

            sendToJail

          when 1, 3

            gameOver

          when 2

            doCommonEvent

          end

          @captured = true

        end

      else

        Sound.play_found

        @detectingEvent.animation_id = 98

        unless @alertedGuards.include?(@detectingEvent)

          @alertedGuards.push(@detectingEvent)

        end

      end

    end

    $game_player.detected = false

    @detectingEvent = nil

  end

  #-----------------------------------------------------------------------------

  # MODE 0: Send player to the "jail" tile

  #-----------------------------------------------------------------------------

  def sendToJail

      $game_player.transfer($game_map.map_id, @jailX, @jailY,

                                    @detectingEvent.direction)

  end

  #-----------------------------------------------------------------------------

  # MODE 1: Game Over

  #-----------------------------------------------------------------------------

  def gameOver

    $scene = Scene_Gameover.new

  end

  #-----------------------------------------------------------------------------

  # MODE 2: Execute Common Event

  #-----------------------------------------------------------------------------

  def doCommonEvent

      $game_temp.common_event_id = @common_event_id

  end

end

Demo: SDS DEMO for XP
You'll also need this sound if you didn't download the demo: Attached File  found.wav ( 83.52K ) Number of downloads: 61

Customization
For customization, go to the original thread - Stealth Detection System for VX. As customizing the script is the same for both systems.
Compatibility
QUOTE (Night_Runner @ Jan 3 2010, 02:37 AM) *
Give this a shot, I haven't tested it extensively, so there's almost guaranteed to be at least 999 bugs, but I tried re-enacting all the default maps, and I didn't notice anything odd, oh well, give it a shot, and let me know

As you can see it's still kind of in the beta stage for XP, so if obviously it might run into some areas with some other scripts that Redefines Scene_Title, Scene_Map and Game_Event.

Screenshot
Not yet!
FAQ
Not yet!
Terms and Conditions
QUOTE (cmpsr2000 @ Jun 12 2008, 03:16 AM) *
Feel free to use this in your game, but please give me a shout in the credits! Also, feel free to edit this for your own personal purposes but please do not repost an edited version without my consent first.

Thanks ^^/

Special Thanks
Cmrp2000 - for creating this script
Night_Runner - for converting it to XP



This post has been edited by Bigace: Mar 10 2011, 02:27 PM


__________________________



Use Dropbox to upload your files. Much simpler than other upload sites, you can simply place a folder on your desktop that will sync with your DropBox account.

QUOTE ('Exiled One')
"If you are one of the very few teenagers that know what real rap is and don't blindly listen to the hate statements (rap is crap), then put this in your sig. I say this in the name of Common, Mos Def, Lupe Fiasco, 2Pac, Nas, Talib Kweli, Eminem, and many others."
Go to the top of the page
 
+Quote Post
   
Loneknight07
post Mar 5 2011, 11:19 AM
Post #2



Group Icon

Group: Member
Posts: 4
Type: Event Designer
RM Skill: Skilled




This script is awesome and everything worked except when I try to load save files after exiting the game and re-opening it, I get an error message that involves the "$game_stealth.update" part of the Redefinitions script under "The stealth system needs to be updated every frame along with the map scene" (It's line 285). I noticed that the same thing happened in the demo and I don't know what to do or how to fix it. Any help would be greatly appreciated. smile.gif

This post has been edited by Loneknight07: Mar 5 2011, 11:37 AM
Go to the top of the page
 
+Quote Post
   
Night_Runner
post Mar 5 2011, 03:35 PM
Post #3


Level 50
Group Icon

Group: +Gold Member
Posts: 1,529
Type: Scripter
RM Skill: Undisclosed




That's a bit of a problem.......... Let me fix that for you!

[Show/Hide] Updated Redefinitions, replace the original with this
CODE
#-------------------------------------------------------------------------------
# This is a surprise ^^
#-------------------------------------------------------------------------------
module Sound
  def self.play_found
    Audio.se_play("Audio/SE/found.wav", 100, 100)
  end
end



#-------------------------------------------------------------------------------
# This contains command for object movement and can be reused and included in
# any game_character or it's descendants.
#-------------------------------------------------------------------------------
module Movement
  #-----------------------------------------------------------------------------
  # Checks to see whether this object has moved since the last check.
  # RETURNS: Boolean
  #-----------------------------------------------------------------------------
  def moved?
    if self.x != @oldX or self.y != @oldY
      setPosition
      return true
    else
      return false
    end
  end
  #-----------------------------------------------------------------------------
  # Checks to see whether this object has turned.
  # RETURNS: Boolean
  #-----------------------------------------------------------------------------
  def turned?
    if self.direction != @oldDirection
      setDirection
      return true
    else
      return false
    end
  end
  #-----------------------------------------------------------------------------
  # Saves the current direction so that it can be checked against after a turn
  #-----------------------------------------------------------------------------
  def setDirection
    @oldDirection = self.direction
  end
  #-----------------------------------------------------------------------------
  # Saves the current position so that it can be checked against after a move
  #-----------------------------------------------------------------------------
  def setPosition
    @oldX = self.x
    @oldY = self.y
  end
  #-----------------------------------------------------------------------------
  # Changes the object's route to perform an in-place spin while waiting after
  # each turn. It is recommended to call object.lock before using this, and
  # call object.unlock when it has complete.
  #-----------------------------------------------------------------------------
  def spinInPlace(waitTime)
    spinRoute = RPG::MoveRoute.new
    spinRoute.repeat = false
    #spinRoute.wait = true
    for x in 0..3
      spinRoute.list.push(RPG::MoveCommand.new(15, [waitTime]))
      spinRoute.list.push(RPG::MoveCommand.new(16 + x))
    end
    spinRoute.list.push(RPG::MoveCommand.new(15, [waitTime]))
    spinRoute.list.push(RPG::MoveCommand.new(0))
    spinRoute.list.delete_at(0) #weird RGSS Anomoly, must delete empty position
    
    self.move_route = spinRoute
    self.move_route_index = 0
  end
  #-----------------------------------------------------------------------------
  # This is an advanced pathfinding algorithm that returns a boolean indicating
  # whether or not it was able to find a path from the start point (the object's
  # current location) to the endpoint, then changes the object's move values
  # to initiate movement. RETURNS: Boolean
  #   finalX:   x coordinate of the destination
  #   finalY:   y coordinate of the destination
  #-----------------------------------------------------------------------------
  def goto(finalX, finalY)
    return true if self.x == finalX and self.y == finalY
    startX = self.x
    startY = self.y
    
    #figure out the route: A* algorithm
    @activeList = []
    @activeParents = []
    @activeScores = []
    @closedList = []
    @closedParents = []
    @closedScores = []
    @activeList.push([startX, startY])
    @activeParents.push([startX, startY])
    @activeScores.push([0,0,0])
    noPath = false
    finalNode = [finalX, finalY]
    
    #main logic
    while @closedList.index(finalNode) == nil
      nodeToCheck = @activeList[0]  #lowest F is always in position 0!
      if nodeToCheck == nil
        noPath = true
        break
      end
      moveToClosed(nodeToCheck)
      for node in adjacentNodes(nodeToCheck) #a "node" is an array: [x, y] !!!
        if ($game_map.passable?(node[0], node[1], 0) and
           @closedList.index(node) == nil) or node == finalNode
          index = @activeList.index(node)
          if index == nil
            scores = calcScores(node, nodeToCheck, finalNode)
            insertionPoint = findInsertionPoint(scores[0])
            @activeList.insert(insertionPoint, node)
            @activeParents.insert(insertionPoint, nodeToCheck)
            @activeScores.insert(insertionPoint, scores)
          else
            g = calcG(nodeToCheck)
            if g < @activeScores[index][1]
              @activeParents[index] = nodeToCheck
              h = @activeScores[index][2]
              f = g + h
              @activeScores[index] = [f, g, h]
              insertionPoint = findInsertionPoint(@activeScores[index][0])
              
              #we don't need to reinsert if we already exist in the right place
              if insertionPoint != index
                tempNode   = @activeList[index]
                tempParent = @activeParents[index]
                tempScores = @activeScores[index]
                
                #delete existing
                @activeList.delete(tempNode)
                @activeParents.delete(tempParent)
                @activeScores.delete(tempScores)
                
                #reinsert
                @activeList.insert(insertionPoint, tempNode)
                @activeParents.insert(insertionPoint, tempParent)
                @activeScores.insert(insertionPoint, tempScores)
              end
            end
          end
        end
      end
    end
    
    #return if there is no path, otherwise build the path
    return false if noPath
    path = [finalNode]
    parent = @closedParents[@closedList.index(finalNode)]
    while parent != [startX, startY]
      path.push(parent)
      parent = @closedParents[@closedList.index(parent)]
    end
    path.reverse! #put the path in order of execution
    
    #make a new route object that doesn't repeat (one time use only!)
    gotoRoute = RPG::MoveRoute.new
    gotoRoute.repeat = false
    
    #itterate through the path and add the appropriate commands to the route
    #we can't move diagonal, so only one x or one y should change between steps
    lastNode = [startX, startY]
    for node in path
      if node[0] > lastNode[0]
        commandCode = 3 # move right
      elsif node[0] < lastNode[0]
        commandCode = 2 # move left
      else
        if node[1] > lastNode[1]
          commandCode = 1 # move down
        elsif node[1] < lastNode[1]
          commandCode = 4 # move up
        end
      end
      lastNode = node
      gotoRoute.list.push(RPG::MoveCommand.new(commandCode))
    end
    gotoRoute.list.push(RPG::MoveCommand.new(0))
    gotoRoute.list.delete_at(0) #weird RGSS Anomoly, must delete empty position
    
    #set the object's route and return!
    self.move_route = gotoRoute
    self.move_route_index = 0
    return true
  end
  #-----------------------------------------------------------------------------
  # moves the active node to the closed list so it's not checked twice!
  #-----------------------------------------------------------------------------
  def moveToClosed(activeNode)
    index = @activeList.index(activeNode)
    
    #add to closed
    @closedList.push(@activeList[index])
    @closedParents.push(@activeParents[index])
    @closedScores.push(@activeScores[index])
    
    #delete from active
    @activeList.delete_at(index)
    @activeParents.delete_at(index)
    @activeScores.delete_at(index)
  end
  #-----------------------------------------------------------------------------
  # finds the array insertion point based on the f score
  #-----------------------------------------------------------------------------
  def findInsertionPoint(f)
    insertionPoint = 0
    if @activeList.length != 0
      while insertionPoint < @activeList.length
        if f <= @activeScores[insertionPoint][0]
          break
        else
          insertionPoint += 1
        end
      end  
    end
    
    return insertionPoint
  end
  #-----------------------------------------------------------------------------
  # calculates all the scores for a node
  #-----------------------------------------------------------------------------
  def calcScores(node, parentNode, finalNode)
    h = calcH(node, finalNode)
    g = calcG(parentNode)
    f = g + h
    
    return [f, g, h]
  end
  #-----------------------------------------------------------------------------
  # calculates the G value (route distance)
  #-----------------------------------------------------------------------------
  def calcG(parentNode)
    #can't move diagonly: just add 1 to parent score
    index = @closedList.index(parentNode)
    score = @closedScores[index][1] + 1
    return score
  end
  #-----------------------------------------------------------------------------
  # claculates the H value (distance from start to finish)
  #-----------------------------------------------------------------------------
  def calcH(node, finalNode)
    #Manhattan method is admissible in this context
    score = (node[0] - finalNode[0]).abs + (node[1] - finalNode[1]).abs
    
    return score
  end
  #-----------------------------------------------------------------------------
  # Finds the adjacent nodes of the active node
  #-----------------------------------------------------------------------------
  def adjacentNodes(sourceNode)
    node1 = [sourceNode[0] + 1, sourceNode[1]]
    node2 = [sourceNode[0], sourceNode[1] + 1]
    node3 = [sourceNode[0] - 1, sourceNode[1]]
    node4 = [sourceNode[0], sourceNode[1] - 1]
    return [node1, node2, node3, node4]
  end
end



#-------------------------------------------------------------------------------
# the instance of $game_stealth needs to be created
#-------------------------------------------------------------------------------
class Scene_Title
  alias oldCommandNewGameStealth command_new_game
  def command_new_game
    $game_stealth = Game_Stealth.new
    oldCommandNewGameStealth
  end
end



#-------------------------------------------------------------------------------
# saveing and loading $game_stealth
#-------------------------------------------------------------------------------
class Scene_Save
  #--------------------------------------------------------------------------
  # * Write Save Data
  #     file : write file object (opened)
  #--------------------------------------------------------------------------
  alias old_WriteSaveDataStealth write_save_data
  def write_save_data(file)
    old_WriteSaveDataStealth(file)
    Marshal.dump($game_stealth, file)
  end
end
class Scene_Load
  #--------------------------------------------------------------------------
  # * Read Save Data
  #     file : write file object (opened)
  #--------------------------------------------------------------------------
  alias old_ReadSaveDataStealth read_save_data
  def read_save_data(file)
    old_ReadSaveDataStealth(file)
    $game_stealth = Marshal.load(file)
  end
end




#-------------------------------------------------------------------------------
# The stealth system needs to be updated every frame along with the map scene
#-------------------------------------------------------------------------------
class Scene_Map
  alias oldUpdateStealth update
  def update
    oldUpdateStealth
    unless $game_temp.message_window_showing      # Unless displaying a message
      $game_stealth.update
    end
  end
end



class Game_Character
  alias nr_sds_initialize initialize
  def initialize(*args)
    nr_sds_initialize(*args)
    @move_failed = false
  end
  #--------------------------------------------------------------------------
  # * Determine if Stopping
  #--------------------------------------------------------------------------
  def stopping?
    return (not (moving? or jumping?))
  end
  #--------------------------------------------------------------------------
  # * Move Down
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_down(turn_enabled = true)
    # Turn down
    if turn_enabled
      turn_down
    end
    # If passable
    if passable?(@x, @y, 2)
      # Turn down
      turn_down
      # Update coordinates
      @y += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x, @y+1)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Left
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_left(turn_enabled = true)
    # Turn left
    if turn_enabled
      turn_left
    end
    # If passable
    if passable?(@x, @y, 4)
      # Turn left
      turn_left
      # Update coordinates
      @x -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x-1, @y)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Right
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_right(turn_enabled = true)
    # Turn right
    if turn_enabled
      turn_right
    end
    # If passable
    if passable?(@x, @y, 6)
      # Turn right
      turn_right
      # Update coordinates
      @x += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x+1, @y)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move up
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_up(turn_enabled = true)
    # Turn up
    if turn_enabled
      turn_up
    end
    # If passable
    if passable?(@x, @y, 8)
      # Turn up
      turn_up
      # Update coordinates
      @y -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x, @y-1)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Lower Left
  #--------------------------------------------------------------------------
  def move_lower_left
    # If no direction fix
    unless @direction_fix
      # Face down is facing right or up
      @direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction)
    end
    # When a down to left or a left to down course is passable
    if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 4)) or
       (passable?(@x, @y, 4) and passable?(@x - 1, @y, 2))
      # Update coordinates
      @x -= 1
      @y += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Lower Right
  #--------------------------------------------------------------------------
  def move_lower_right
    # If no direction fix
    unless @direction_fix
      # Face right if facing left, and face down if facing up
      @direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction)
    end
    # When a down to right or a right to down course is passable
    if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 6)) or
       (passable?(@x, @y, 6) and passable?(@x + 1, @y, 2))
      # Update coordinates
      @x += 1
      @y += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Upper Left
  #--------------------------------------------------------------------------
  def move_upper_left
    # If no direction fix
    unless @direction_fix
      # Face left if facing right, and face up if facing down
      @direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction)
    end
    # When an up to left or a left to up course is passable
    if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 4)) or
       (passable?(@x, @y, 4) and passable?(@x - 1, @y, 8))
      # Update coordinates
      @x -= 1
      @y -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Upper Right
  #--------------------------------------------------------------------------
  def move_upper_right
    # If no direction fix
    unless @direction_fix
      # Face right if facing left, and face up if facing down
      @direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction)
    end
    # When an up to right or a right to up course is passable
    if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 6)) or
       (passable?(@x, @y, 6) and passable?(@x + 1, @y, 8))
      # Update coordinates
      @x += 1
      @y -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
end



class Game_Player < Game_Character
  include Movement
  attr_accessor :detected
  def transfer(new_map, new_x, new_y, new_dir)
    # Set transferring player flag
    $game_temp.player_transferring = true
    # Set player move destination
    $game_temp.player_new_map_id = new_map
    $game_temp.player_new_x = new_x
    $game_temp.player_new_y = new_y
    $game_temp.player_new_direction = new_dir
    Graphics.freeze
    # Set transition processing flag
    $game_temp.transition_processing = true
    $game_temp.transition_name = ""
  end
end



#-------------------------------------------------------------------------------
# Events have tons of new attributes with the stealth system. Plus, we need to
# include the movement module and initialize awareness to false.
#-------------------------------------------------------------------------------
class Game_Event < Game_Character
  include Movement
  
  #for all stealth
  attr_accessor :isAware
  attr_accessor :detectRange
  attr_accessor :tunnelVision
  attr_accessor :trueSight
  attr_accessor :detectAction
  attr_accessor :originalAction
  
  #For MGS-style stealth
  attr_accessor :move_speed
  attr_accessor :move_frequency
  attr_accessor :detectState
  attr_accessor :move_route_index
  attr_accessor :move_route
  attr_accessor :returnX
  attr_accessor :returnY
  attr_accessor :returnRoute
  attr_accessor :returnRouteIndex
  attr_accessor :returnSpeed
  attr_accessor :returnFrequency
  attr_reader   :move_failed
  
  alias oldInitStealth initialize
  def initialize(map_id, event)
    oldInitStealth(map_id, event)
    @isAware = false
  end
end


I'll try and get Bigace to update the original post & demo so it includes the new code.

I know Google offer $20,000 if you find a bug in their code, but all that I can offer is a dancing bunny bunny.gif


Just as a footnote, don't try and open any save files from before you apply this patch. I've had to restructure the save file data, and it'll just error if you load a save from an old game....


__________________________
K.I.S.S.
Want help with your scripting problems? Upload a demo! Or at the very least; provide links to the scripts in question.

Most important guide ever: Newbie's Guide to Switches
Go to the top of the page
 
+Quote Post
   
Bigace
post Mar 10 2011, 02:24 PM
Post #4


The King of Spades
Group Icon

Group: Revolutionary
Posts: 400
Type: Developer
RM Skill: Intermediate




QUOTE (Loneknight07 @ Mar 5 2011, 02:19 PM) *
This script is awesome and everything worked except when I try to load save files after exiting the game and re-opening it, I get an error message that involves the "$game_stealth.update" part of the Redefinitions script under "The stealth system needs to be updated every frame along with the map scene" (It's line 285). I noticed that the same thing happened in the demo and I don't know what to do or how to fix it. Any help would be greatly appreciated. smile.gif


lol some actually posted 1 year after people were asking for the script. Either they werent serious are they know how to solve problems with out much help.

QUOTE (Night_Runner @ Mar 5 2011, 06:35 PM) *
That's a bit of a problem.......... Let me fix that for you!

[Show/Hide] Updated Redefinitions, replace the original with this
CODE
#-------------------------------------------------------------------------------
# This is a surprise ^^
#-------------------------------------------------------------------------------
module Sound
  def self.play_found
    Audio.se_play("Audio/SE/found.wav", 100, 100)
  end
end



#-------------------------------------------------------------------------------
# This contains command for object movement and can be reused and included in
# any game_character or it's descendants.
#-------------------------------------------------------------------------------
module Movement
  #-----------------------------------------------------------------------------
  # Checks to see whether this object has moved since the last check.
  # RETURNS: Boolean
  #-----------------------------------------------------------------------------
  def moved?
    if self.x != @oldX or self.y != @oldY
      setPosition
      return true
    else
      return false
    end
  end
  #-----------------------------------------------------------------------------
  # Checks to see whether this object has turned.
  # RETURNS: Boolean
  #-----------------------------------------------------------------------------
  def turned?
    if self.direction != @oldDirection
      setDirection
      return true
    else
      return false
    end
  end
  #-----------------------------------------------------------------------------
  # Saves the current direction so that it can be checked against after a turn
  #-----------------------------------------------------------------------------
  def setDirection
    @oldDirection = self.direction
  end
  #-----------------------------------------------------------------------------
  # Saves the current position so that it can be checked against after a move
  #-----------------------------------------------------------------------------
  def setPosition
    @oldX = self.x
    @oldY = self.y
  end
  #-----------------------------------------------------------------------------
  # Changes the object's route to perform an in-place spin while waiting after
  # each turn. It is recommended to call object.lock before using this, and
  # call object.unlock when it has complete.
  #-----------------------------------------------------------------------------
  def spinInPlace(waitTime)
    spinRoute = RPG::MoveRoute.new
    spinRoute.repeat = false
    #spinRoute.wait = true
    for x in 0..3
      spinRoute.list.push(RPG::MoveCommand.new(15, [waitTime]))
      spinRoute.list.push(RPG::MoveCommand.new(16 + x))
    end
    spinRoute.list.push(RPG::MoveCommand.new(15, [waitTime]))
    spinRoute.list.push(RPG::MoveCommand.new(0))
    spinRoute.list.delete_at(0) #weird RGSS Anomoly, must delete empty position
    
    self.move_route = spinRoute
    self.move_route_index = 0
  end
  #-----------------------------------------------------------------------------
  # This is an advanced pathfinding algorithm that returns a boolean indicating
  # whether or not it was able to find a path from the start point (the object's
  # current location) to the endpoint, then changes the object's move values
  # to initiate movement. RETURNS: Boolean
  #   finalX:   x coordinate of the destination
  #   finalY:   y coordinate of the destination
  #-----------------------------------------------------------------------------
  def goto(finalX, finalY)
    return true if self.x == finalX and self.y == finalY
    startX = self.x
    startY = self.y
    
    #figure out the route: A* algorithm
    @activeList = []
    @activeParents = []
    @activeScores = []
    @closedList = []
    @closedParents = []
    @closedScores = []
    @activeList.push([startX, startY])
    @activeParents.push([startX, startY])
    @activeScores.push([0,0,0])
    noPath = false
    finalNode = [finalX, finalY]
    
    #main logic
    while @closedList.index(finalNode) == nil
      nodeToCheck = @activeList[0]  #lowest F is always in position 0!
      if nodeToCheck == nil
        noPath = true
        break
      end
      moveToClosed(nodeToCheck)
      for node in adjacentNodes(nodeToCheck) #a "node" is an array: [x, y] !!!
        if ($game_map.passable?(node[0], node[1], 0) and
           @closedList.index(node) == nil) or node == finalNode
          index = @activeList.index(node)
          if index == nil
            scores = calcScores(node, nodeToCheck, finalNode)
            insertionPoint = findInsertionPoint(scores[0])
            @activeList.insert(insertionPoint, node)
            @activeParents.insert(insertionPoint, nodeToCheck)
            @activeScores.insert(insertionPoint, scores)
          else
            g = calcG(nodeToCheck)
            if g < @activeScores[index][1]
              @activeParents[index] = nodeToCheck
              h = @activeScores[index][2]
              f = g + h
              @activeScores[index] = [f, g, h]
              insertionPoint = findInsertionPoint(@activeScores[index][0])
              
              #we don't need to reinsert if we already exist in the right place
              if insertionPoint != index
                tempNode   = @activeList[index]
                tempParent = @activeParents[index]
                tempScores = @activeScores[index]
                
                #delete existing
                @activeList.delete(tempNode)
                @activeParents.delete(tempParent)
                @activeScores.delete(tempScores)
                
                #reinsert
                @activeList.insert(insertionPoint, tempNode)
                @activeParents.insert(insertionPoint, tempParent)
                @activeScores.insert(insertionPoint, tempScores)
              end
            end
          end
        end
      end
    end
    
    #return if there is no path, otherwise build the path
    return false if noPath
    path = [finalNode]
    parent = @closedParents[@closedList.index(finalNode)]
    while parent != [startX, startY]
      path.push(parent)
      parent = @closedParents[@closedList.index(parent)]
    end
    path.reverse! #put the path in order of execution
    
    #make a new route object that doesn't repeat (one time use only!)
    gotoRoute = RPG::MoveRoute.new
    gotoRoute.repeat = false
    
    #itterate through the path and add the appropriate commands to the route
    #we can't move diagonal, so only one x or one y should change between steps
    lastNode = [startX, startY]
    for node in path
      if node[0] > lastNode[0]
        commandCode = 3 # move right
      elsif node[0] < lastNode[0]
        commandCode = 2 # move left
      else
        if node[1] > lastNode[1]
          commandCode = 1 # move down
        elsif node[1] < lastNode[1]
          commandCode = 4 # move up
        end
      end
      lastNode = node
      gotoRoute.list.push(RPG::MoveCommand.new(commandCode))
    end
    gotoRoute.list.push(RPG::MoveCommand.new(0))
    gotoRoute.list.delete_at(0) #weird RGSS Anomoly, must delete empty position
    
    #set the object's route and return!
    self.move_route = gotoRoute
    self.move_route_index = 0
    return true
  end
  #-----------------------------------------------------------------------------
  # moves the active node to the closed list so it's not checked twice!
  #-----------------------------------------------------------------------------
  def moveToClosed(activeNode)
    index = @activeList.index(activeNode)
    
    #add to closed
    @closedList.push(@activeList[index])
    @closedParents.push(@activeParents[index])
    @closedScores.push(@activeScores[index])
    
    #delete from active
    @activeList.delete_at(index)
    @activeParents.delete_at(index)
    @activeScores.delete_at(index)
  end
  #-----------------------------------------------------------------------------
  # finds the array insertion point based on the f score
  #-----------------------------------------------------------------------------
  def findInsertionPoint(f)
    insertionPoint = 0
    if @activeList.length != 0
      while insertionPoint < @activeList.length
        if f <= @activeScores[insertionPoint][0]
          break
        else
          insertionPoint += 1
        end
      end  
    end
    
    return insertionPoint
  end
  #-----------------------------------------------------------------------------
  # calculates all the scores for a node
  #-----------------------------------------------------------------------------
  def calcScores(node, parentNode, finalNode)
    h = calcH(node, finalNode)
    g = calcG(parentNode)
    f = g + h
    
    return [f, g, h]
  end
  #-----------------------------------------------------------------------------
  # calculates the G value (route distance)
  #-----------------------------------------------------------------------------
  def calcG(parentNode)
    #can't move diagonly: just add 1 to parent score
    index = @closedList.index(parentNode)
    score = @closedScores[index][1] + 1
    return score
  end
  #-----------------------------------------------------------------------------
  # claculates the H value (distance from start to finish)
  #-----------------------------------------------------------------------------
  def calcH(node, finalNode)
    #Manhattan method is admissible in this context
    score = (node[0] - finalNode[0]).abs + (node[1] - finalNode[1]).abs
    
    return score
  end
  #-----------------------------------------------------------------------------
  # Finds the adjacent nodes of the active node
  #-----------------------------------------------------------------------------
  def adjacentNodes(sourceNode)
    node1 = [sourceNode[0] + 1, sourceNode[1]]
    node2 = [sourceNode[0], sourceNode[1] + 1]
    node3 = [sourceNode[0] - 1, sourceNode[1]]
    node4 = [sourceNode[0], sourceNode[1] - 1]
    return [node1, node2, node3, node4]
  end
end



#-------------------------------------------------------------------------------
# the instance of $game_stealth needs to be created
#-------------------------------------------------------------------------------
class Scene_Title
  alias oldCommandNewGameStealth command_new_game
  def command_new_game
    $game_stealth = Game_Stealth.new
    oldCommandNewGameStealth
  end
end



#-------------------------------------------------------------------------------
# saveing and loading $game_stealth
#-------------------------------------------------------------------------------
class Scene_Save
  #--------------------------------------------------------------------------
  # * Write Save Data
  #     file : write file object (opened)
  #--------------------------------------------------------------------------
  alias old_WriteSaveDataStealth write_save_data
  def write_save_data(file)
    old_WriteSaveDataStealth(file)
    Marshal.dump($game_stealth, file)
  end
end
class Scene_Load
  #--------------------------------------------------------------------------
  # * Read Save Data
  #     file : write file object (opened)
  #--------------------------------------------------------------------------
  alias old_ReadSaveDataStealth read_save_data
  def read_save_data(file)
    old_ReadSaveDataStealth(file)
    $game_stealth = Marshal.load(file)
  end
end




#-------------------------------------------------------------------------------
# The stealth system needs to be updated every frame along with the map scene
#-------------------------------------------------------------------------------
class Scene_Map
  alias oldUpdateStealth update
  def update
    oldUpdateStealth
    unless $game_temp.message_window_showing      # Unless displaying a message
      $game_stealth.update
    end
  end
end



class Game_Character
  alias nr_sds_initialize initialize
  def initialize(*args)
    nr_sds_initialize(*args)
    @move_failed = false
  end
  #--------------------------------------------------------------------------
  # * Determine if Stopping
  #--------------------------------------------------------------------------
  def stopping?
    return (not (moving? or jumping?))
  end
  #--------------------------------------------------------------------------
  # * Move Down
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_down(turn_enabled = true)
    # Turn down
    if turn_enabled
      turn_down
    end
    # If passable
    if passable?(@x, @y, 2)
      # Turn down
      turn_down
      # Update coordinates
      @y += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x, @y+1)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Left
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_left(turn_enabled = true)
    # Turn left
    if turn_enabled
      turn_left
    end
    # If passable
    if passable?(@x, @y, 4)
      # Turn left
      turn_left
      # Update coordinates
      @x -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x-1, @y)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Right
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_right(turn_enabled = true)
    # Turn right
    if turn_enabled
      turn_right
    end
    # If passable
    if passable?(@x, @y, 6)
      # Turn right
      turn_right
      # Update coordinates
      @x += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x+1, @y)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move up
  #     turn_enabled : a flag permits direction change on that spot
  #--------------------------------------------------------------------------
  def move_up(turn_enabled = true)
    # Turn up
    if turn_enabled
      turn_up
    end
    # If passable
    if passable?(@x, @y, 8)
      # Turn up
      turn_up
      # Update coordinates
      @y -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    # If impassable
    else
      # Determine if touch event is triggered
      check_event_trigger_touch(@x, @y-1)
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Lower Left
  #--------------------------------------------------------------------------
  def move_lower_left
    # If no direction fix
    unless @direction_fix
      # Face down is facing right or up
      @direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction)
    end
    # When a down to left or a left to down course is passable
    if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 4)) or
       (passable?(@x, @y, 4) and passable?(@x - 1, @y, 2))
      # Update coordinates
      @x -= 1
      @y += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Lower Right
  #--------------------------------------------------------------------------
  def move_lower_right
    # If no direction fix
    unless @direction_fix
      # Face right if facing left, and face down if facing up
      @direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction)
    end
    # When a down to right or a right to down course is passable
    if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 6)) or
       (passable?(@x, @y, 6) and passable?(@x + 1, @y, 2))
      # Update coordinates
      @x += 1
      @y += 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Upper Left
  #--------------------------------------------------------------------------
  def move_upper_left
    # If no direction fix
    unless @direction_fix
      # Face left if facing right, and face up if facing down
      @direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction)
    end
    # When an up to left or a left to up course is passable
    if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 4)) or
       (passable?(@x, @y, 4) and passable?(@x - 1, @y, 8))
      # Update coordinates
      @x -= 1
      @y -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
  #--------------------------------------------------------------------------
  # * Move Upper Right
  #--------------------------------------------------------------------------
  def move_upper_right
    # If no direction fix
    unless @direction_fix
      # Face right if facing left, and face up if facing down
      @direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction)
    end
    # When an up to right or a right to up course is passable
    if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 6)) or
       (passable?(@x, @y, 6) and passable?(@x + 1, @y, 8))
      # Update coordinates
      @x += 1
      @y -= 1
      # Increase steps
      increase_steps
      # Set move failed flag
      @move_failed = false
    else
      # Set move failed flag
      @move_failed = true
    end
  end
end



class Game_Player < Game_Character
  include Movement
  attr_accessor :detected
  def transfer(new_map, new_x, new_y, new_dir)
    # Set transferring player flag
    $game_temp.player_transferring = true
    # Set player move destination
    $game_temp.player_new_map_id = new_map
    $game_temp.player_new_x = new_x
    $game_temp.player_new_y = new_y
    $game_temp.player_new_direction = new_dir
    Graphics.freeze
    # Set transition processing flag
    $game_temp.transition_processing = true
    $game_temp.transition_name = ""
  end
end



#-------------------------------------------------------------------------------
# Events have tons of new attributes with the stealth system. Plus, we need to
# include the movement module and initialize awareness to false.
#-------------------------------------------------------------------------------
class Game_Event < Game_Character
  include Movement
  
  #for all stealth
  attr_accessor :isAware
  attr_accessor :detectRange
  attr_accessor :tunnelVision
  attr_accessor :trueSight
  attr_accessor :detectAction
  attr_accessor :originalAction
  
  #For MGS-style stealth
  attr_accessor :move_speed
  attr_accessor :move_frequency
  attr_accessor :detectState
  attr_accessor :move_route_index
  attr_accessor :move_route
  attr_accessor :returnX
  attr_accessor :returnY
  attr_accessor :returnRoute
  attr_accessor :returnRouteIndex
  attr_accessor :returnSpeed
  attr_accessor :returnFrequency
  attr_reader   :move_failed
  
  alias oldInitStealth initialize
  def initialize(map_id, event)
    oldInitStealth(map_id, event)
    @isAware = false
  end
end


I'll try and get Bigace to update the original post & demo so it includes the new code.

I know Google offer $20,000 if you find a bug in their code, but all that I can offer is a dancing bunny bunny.gif


Just as a footnote, don't try and open any save files from before you apply this patch. I've had to restructure the save file data, and it'll just error if you load a save from an old game....


I'll update in a few like i said in the post i sent you eariler, however the demo well take awhile though since i'm doing stuff at the moment.

-----------------------------------------------------
-----------------------------------------------------
Edit: Script is updated, but the demo will be updated on saturday. Sorry dry.gif

This post has been edited by Bigace: Mar 10 2011, 02:29 PM


__________________________



Use Dropbox to upload your files. Much simpler than other upload sites, you can simply place a folder on your desktop that will sync with your DropBox account.

QUOTE ('Exiled One')
"If you are one of the very few teenagers that know what real rap is and don't blindly listen to the hate statements (rap is crap), then put this in your sig. I say this in the name of Common, Mos Def, Lupe Fiasco, 2Pac, Nas, Talib Kweli, Eminem, and many others."
Go to the top of the page
 
+Quote Post
   
MagitekElite
post Apr 14 2011, 08:21 PM
Post #5


Level 42
Group Icon

Group: Revolutionary
Posts: 1,138
Type: None
RM Skill: Skilled




So there is no way to save the old files?

Every time I make an edit to my maps, events or the like, replay the savefile it gives me an error about the Update.nil (or something like that). It seems like it was make it difficult to update games/demos for the players. If the game is released, an error is find and then the game creator re-uploaded a fixed game only to have the player lose their file....

Is there no way to stop this? Some sort of trick...?
Go to the top of the page
 
+Quote Post
   
Night_Runner
post Apr 20 2011, 05:21 AM
Post #6


Level 50
Group Icon

Group: +Gold Member
Posts: 1,529
Type: Scripter
RM Skill: Undisclosed




For my wide audience, I present an update!

http://www.4shared.com/file/Ht9Dp8s7/SDS_Script_for_XP.html

The main points of the update is that it will now have backward compatibility to games saved without this script, and I spent the last few hours getting a system setup that stores all events that have been set as a guard, and keeps them upon re-entering the map (there was a way of doing this with events, but this snippet I've added means a bit less work for you guys smile.gif)

It also sports a shiny new script I've made for a request, it lets you have a guard start a battle when you're detected, and automatically erases the guard when you defeat him (well, not in that order, but the effect is the same).


__________________________
K.I.S.S.
Want help with your scripting problems? Upload a demo! Or at the very least; provide links to the scripts in question.

Most important guide ever: Newbie's Guide to Switches
Go to the top of the page
 
+Quote Post
   
lowcku
post Apr 21 2011, 03:12 PM
Post #7


Level 3
Group Icon

Group: Member
Posts: 31
Type: None
RM Skill: Undisclosed




wrong window to post in, sorry

This post has been edited by lowcku: Apr 25 2011, 05:44 PM
Go to the top of the page
 
+Quote Post
   
supercow
post Sep 13 2011, 01:00 AM
Post #8


Level 15
Group Icon

Group: Revolutionary
Posts: 285
Type: Artist
RM Skill: Undisclosed




ive been using this awesome script wanted to make like mgs style but then got problem with loading cuz it clash with other script, thankfully @nightrunner updated definition solved it thx very much thumbsup.gif
is SDS gonna have an update? cuz sometimes the distance is not very accurate happy.gif
Go to the top of the page
 
+Quote Post
   
vvalkingman
post Sep 14 2011, 05:23 PM
Post #9


The Traveling Bard ;)
Group Icon

Group: Revolutionary
Posts: 210
Type: Developer
RM Skill: Intermediate




I know this script was thrown out back in april and this borderlines necro posting...but what I'm trying to do is use the mgs mode with the battle instigator. According to the comments all I need to do to activate a battle is set @captureAction = 3 however when I go down into the code(line 431) there is a case stating that when 1 or 3 gameover will come up lol how would I alter this part to call the battle feature? Thanks in advance! biggrin.gif

This post has been edited by vvalkingman: Sep 14 2011, 05:23 PM


__________________________

Thank you X-M-O for my sexy new banner! ;)

Project I'm currently racking my brain on:
"Modern Witch" Project(tentative name): 5% done
Goshiki: The Five Paths: 40% done

Projects on the backburner:
The Great Thief of Mango City: 5% done
Knights of the Black Gate: 10% done
The Venting: 74% done
Go to the top of the page
 
+Quote Post
   
supercow
post Sep 17 2011, 04:02 AM
Post #10


Level 15
Group Icon

Group: Revolutionary
Posts: 285
Type: Artist
RM Skill: Undisclosed




make the guard autorun have
$game_stealth.detector(@event_id, 4, 4) ##(@event_id, 4, [4] <- this one had to be 4)

and remember each guard/event had to be specify in the script (its in the NR - StealthBattle section)

Go to the top of the page
 
+Quote Post
   
vvalkingman
post Sep 17 2011, 04:16 PM
Post #11


The Traveling Bard ;)
Group Icon

Group: Revolutionary
Posts: 210
Type: Developer
RM Skill: Intermediate




That doesn't use the mgs mode though. That makes the detection reaction become a battle. In the original script there is a place(line 91) where is says that mgs mode can be in use and that a battle will come up if the player is detected a second time(instead of the default game over).

Basically I want the guard to react like the MGS mode where they see you and run to your location. You have a few seconds to run away but if they see you then a battle starts. Can this script do that? Or is the comments in the code just misleading?



__________________________

Thank you X-M-O for my sexy new banner! ;)

Project I'm currently racking my brain on:
"Modern Witch" Project(tentative name): 5% done
Goshiki: The Five Paths: 40% done

Projects on the backburner:
The Great Thief of Mango City: 5% done
Knights of the Black Gate: 10% done
The Venting: 74% done
Go to the top of the page
 
+Quote Post
   
supercow
post Sep 17 2011, 06:32 PM
Post #12


Level 15
Group Icon

Group: Revolutionary
Posts: 285
Type: Artist
RM Skill: Undisclosed




owww i get it , its not hard i think , ok bear with me

make the guard detect on 3(mgs) not 4
in line 432 (of game stealth) its the one below when 1, 3 , put
title

enemyTroopID = 1
case @detectingEvent.event.name
when 'EV005'
enemyTroopID = 1 # Three Ghosts, by default
when 'EV006'
enemyTroopID = 3 # Two Basilisks, by default
else # If none of the above options were selected.
enemyTroopID = 1 # Two Ghosts, by default
end
# End of Customization
# Set battle abort flag
$game_temp.battle_abort = true
# Set battle calling flag
$game_temp.battle_calling = true
$game_temp.battle_troop_id = enemyTroopID
$game_temp.battle_can_escape = false
$game_temp.battle_can_lose = false
# Pre-emptivly erase the guard
Graphics.freeze
@detectingEvent.erase

i just cut some part of NR - StealthBattle ( maybe theres easier way like calling that script but i dunno how )
i tried it and it works smile.gif
dont forget to erase the gameover or itll ....gameover biggrin.gif
Go to the top of the page
 
+Quote Post
   
vvalkingman
post Sep 17 2011, 07:52 PM
Post #13


The Traveling Bard ;)
Group Icon

Group: Revolutionary
Posts: 210
Type: Developer
RM Skill: Intermediate




Instead of that I did the following at line 428 in the game stealth script to that case there:

CODE
case @captureAction
          when 0
            sendToJail
          when 1
            gameOver
          when 2
            doCommonEvent
          when 3
            @mgsBattle = 1
          end
          @captured = true


And in the NR - Stealth Battle script, line 47 I replaced the if @detectAction ==4 with if @msgBattle == 1
and line 72 above the return line, I put @msgBattle = 0

Of course this makes it so that it'll only work in mgs mode, but that's what I wanted haha thanks for the awesome script guys biggrin.gif

edit: Btw, I think I see why the detection is alittle off. Basically it's not constantly checking to see if the player is in front of them. Example, if I walk up to the guard after he has already moved/turned...nothing happens. But if I walk up to him AS he moves or turns, then the detection runs. I'll see if I can figure out how to remedy this...my skills are rusty at best though, so feel free to take the bug report as you want biggrin.gif

edit2: Upon further investigation, I've found that there is some serious bugs with the actual detection of where the player is in mgs mode as well as the reset when they've returned to their posts. I was about five tiles down from one of the guards and their back was turned when BAM i got thrown into a battle lol idk...i'll see if I can figure this out, maybe we'll get lucky and the scripting gods will hear our cries..

This post has been edited by vvalkingman: Sep 17 2011, 08:28 PM


__________________________

Thank you X-M-O for my sexy new banner! ;)

Project I'm currently racking my brain on:
"Modern Witch" Project(tentative name): 5% done
Goshiki: The Five Paths: 40% done

Projects on the backburner:
The Great Thief of Mango City: 5% done
Knights of the Black Gate: 10% done
The Venting: 74% done
Go to the top of the page
 
+Quote Post
   
sotd
post Jan 1 2012, 10:40 AM
Post #14



Group Icon

Group: Member
Posts: 2
Type: Developer
RM Skill: Skilled




QUOTE (Night_Runner @ Apr 20 2011, 05:21 AM) *
For my wide audience, I present an update!

http://www.4shared.com/file/Ht9Dp8s7/SDS_Script_for_XP.html

The main points of the update is that it will now have backward compatibility to games saved without this script, and I spent the last few hours getting a system setup that stores all events that have been set as a guard, and keeps them upon re-entering the map (there was a way of doing this with events, but this snippet I've added means a bit less work for you guys smile.gif)

It also sports a shiny new script I've made for a request, it lets you have a guard start a battle when you're detected, and automatically erases the guard when you defeat him (well, not in that order, but the effect is the same).


Hey is there any way you can re present this update as I can not find it and would like to use the script.

Thanks!
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: 19th June 2013 - 06:13 AM
RPG RPG Revolution is an Privacy Policy and Legal
eXTReMe Tracker