[XP] Super Event Sensor (Event NPC Advanced AI)

Started by Heretic86, November 27, 2013, 08:56:03 pm

Previous topic - Next topic

Heretic86

November 27, 2013, 08:56:03 pm Last Edit: January 29, 2019, 07:10:04 am by Heretic86
Super Event Sensor - Event NPC AI [XP]
Authors: Heretic
Version: 1.12
Type: Event NPC AI
Key Term: Misc Add-on



Introduction

This Script is highly useful as an Artifical Intelligence by allowing you to create different "behaviors" through Event Pages.  When a Sensor is "Triggered", Self Switches change automatically!  Since a Sensor can detect a Target both through "Sight" and "Sound", TWO Self Switches can be specified.  Due to using up half of your Self Switches, it is HIGHLY RECOMMENDED that you also grab More Self-Switches by Game_Guy / gameus as it allows for More Page Conditions


Features


  • Total Overkill of Options (yeah, I think that is kind of a feature)

  • Highly Useful for Enemy AI

  • Line of Sight to Target

  • Different Types of Views (think Metal Gear)

  • Obstruction of Line of Sight - WALL

  • Can "See" Over Specified Tiles like Water for "Smarter Enemies"

  • Triggered Settings can be Different than Non Triggered Settings

  • Sensors can be set to Ignore Walls once triggered

  • Uses Terrain Tags to Fix Problem Tiles like Water or Fences

  • Should be compatible with Terrain Tag Scripts

  • Can use Bush Tags to obstruct the View of Small Enemies

  • Allows Terrain Tags to specify Trees that obstruct Flying Enemies View

  • Sound - Movement makes Sound, and Movement can be Detected

  • Sound Detection doesnt need additional scripts, just DONT MOVE!

  • Compatible with Pathfinding Scripts

  • Supports Suprise Attack Supported Battle Systems - XRXS Rewrite 1.03

  • Suprise Attack Script Calls can prevent Event from turning toward Player

  • Can Target ANY Game_Character, not just Player

  • Move Route Index Reset on Detrigger - Trust me, you want this.

  • Every Event can have Different Settings

  • The Constants in Config are used for Defaults, you can change Per Event

  • Expandable "View" Definitions by Easy Aliasing

  • Added Triggers for Enemy Contact with Heretic's Caterpillar

  • Stores XY Coordinates of First Seen and First Heard for other uses.

  • Stores XY Coordinates of Location of Sensor Event for returning to path

  • Stealth abilities enabled by Game Switches (not Self Switches)

  • Stealth Switches can also alter View and Range

  • Documentation - Intended for better understanding of specific parts

  • Demo - Extremely complex script is given Demos for each feature




Screenshots

Spoiler: ShowHide


Image Borrowed from Little Drago's Simple Event Sensor
Concept is exactly the same with way way more features!




Demo

This Demo contains MANY different Scripts.  A high number of the Scripts contained in this Collection Demo are designed to enhance Super Event Sensor!  However, you should know that this Script can work just fine as a Standalone Script and is NOT DEPENDANT on any other Scripts!

http://downloads.chaos-project.com/heretic86/CollectionVer2.4.zip


Script

http://downloads.chaos-project.com/heretic86/SuperEventSensor1.12.txt



History

  Version 1.0  : Saturday, November 23rd, 2013
  Version 1.01 : Saturday, October 18th, 2014
  - Fixed a Bug with Caterpillar where Touch Events would Trigger even
    if the Caterpillar was paused.
  Version 1.02 : Saturday, April 4th, 2015
  - Due to the creation of a Modular Passable Script which supports
    a whole ton of features, another script called Looping Maps
    needed to be made compatible
  - Fixed a bug where Save Games had wrong pointer for $game_player
    Bug caused loaded games to not recognize new instance of $game_player
    as the Target for the Sensor.



Instructions

Put above Main and below Scene_Debug (and SDK if installed)

Create a Sensor by putting a COMMENT on Page 1 of an Event.  It does NOT have to be at the Top of the Page, but needs to be fairly close.  Also optional in the Scrit Configuration of how many lines to read while looking for Sensor_Configs

In the Comment, put the following:

Sensor_Config
range=4
listen=4
listen_switch=C

* The Keyword "Sensor_Config" needs to be on its OWN LINE.  Do NOT put any Config Options on the same line as the Keyword of Sensor_Config!

Sensor_Config range=4 WILL NOT WORK!!!

* Do NOT use Spaces between your Option Name and Option Value

range = 4 WILL NOT WORK!!!
range=4 WILL WORK because there are No Spaces!!!

**  See Documentation and Demo for explanation of the list of Sensor Config Options.  There are a LOT of them!

**  There are so many Options, that you can easily fill up an entire COMMENT BOX.  Due to this, you can have MORE THAN ONE Sensor_Config!  Each Sensor_Config needs to have Sensor_Config as the FIRST LINE.



Compatibility

Not compatible with SIMPLE Event Sensor due to the nature of the Script.

Should be compatible with everything else, including both major Pathfinder Scripts and the SDK.

NOTE:  The only supported Battle System at this time for the "Suprise Attack" feature is Heretic's Overhaul of the XRXS Battle System - Version 1.03 and above (included in that massive Demo).


Credits and Thanks


  • Little Drago for the Original Concept

  • Blizzard for modifying his Lagless Pathfinder to expand the functionality of this Script




Author's Notes

This script is designed to Change Pages, which is where the Events Behaviors are created.  Really, it is only about HALF of a true NPC AI as the other half would allow for movements toward the Sensor's Target.

I have no intention of making this Script work with VX or VX Ace.

Sensors can only detect ONE TARGET at this time.  I will probably change this later so expect Updates!

Creating any form of Artifical Intelligence is not easy, considering the semi-limited functionality of the nature of RMXP.  Because this script is so complex, expect to be confused by a good number of the Options!

Please ASK if you have any difficulty in getting your Sensors to work exactly as you expect them to, but do expect that they can behave exactly the way you want them to!

---

Updated to Version 1.12!

New features include full integration with Dynamic Lighting so you can use Darkness to hide from Sensors!
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

ThallionDarkshine

November 27, 2013, 09:37:29 pm #1 Last Edit: November 27, 2013, 09:39:16 pm by ThallionDarkshine
This looks pretty awesome! I love all the different options you build into it. Just one quick tip though after reading through your instructions. I really think that allowing users to have whitespace in their comments would be nice. It would be really annoying debugging a game just because you added an extra space. To do this just use
Code: ruby
/\s*/
where you want to allow whitespace. Another way to do this would be just to use a regexp with
Code: ruby
/YOUR_REGEXP_HERE/x
, which would ignore whitespace.

Heretic86

November 27, 2013, 09:51:24 pm #2 Last Edit: November 27, 2013, 11:23:24 pm by Heretic86
Not gonna add whitespaces, sorry.  Once you really get into this script, you'll find that space in the Comment Boxes is really needed.  I know I could put it in as optional, but decided not to because of the high number of space consuming options.

---

Off topic, I used your Event Transitions script in the Demo, if that's alright...
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

G_G

If a script is too large, there's always http://pastebin.com Not many people are willing to download a 70mb demo of a shit load of scripts just to figure out one script.

Heretic86

Quote from: gameus on November 28, 2013, 01:22:03 am
If a script is too large, there's always http://pastebin.com Not many people are willing to download a 70mb demo of a shit load of scripts just to figure out one script.


Agreed.  I just put it up on an old server I still have access too.  Not much space available on it, but for a text file, it works.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Diamond Star

Please check Script page, It seems the file was removed.
this script is very useful but I don't want to download the demo for it.
I have many dreams and look for who understand me and help me to achieve them

Heretic86

That old server died, company went out of business.  I just made a text file and put it up here without the rest of the very large and cumbersome demo.  Its on the Script link in the original post.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

cdaz

Maybe too late to ask but... can I set some Event as Wall.
just like hinding behind the door or carriage.

Heretic86

Unfortunately no, cant use an Event as a Wall.  Its a good idea and I wanted to do it, but the performance hit would have been way too much.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Helios

April 09, 2016, 05:53:08 am #9 Last Edit: April 09, 2016, 09:07:24 am by Helios
Is there a way to check if the player is currently been "seen"?

I tried doing it with switch (seen->on, defeat the guard->off), but if the player is been seen by two or more enemies at the same time, defeating the first one would set the switch off despite the fact player is still been seen.

(I'm using my own common-event-based battle system, so there is no scene transition between battles, and the sensors can not reset.)


Also, if you set something like listen=5, you get an error "Undefined method "move_speed" for Game_Player" on line 2044

G_G

You might need individual switches for each guard then.

Heretic86

Quote from: Helios on April 09, 2016, 05:53:08 am
Is there a way to check if the player is currently been "seen"?

I tried doing it with switch (seen->on, defeat the guard->off), but if the player is been seen by two or more enemies at the same time, defeating the first one would set the switch off despite the fact player is still been seen.

(I'm using my own common-event-based battle system, so there is no scene transition between battles, and the sensors can not reset.)


Also, if you set something like listen=5, you get an error "Undefined method "move_speed" for Game_Player" on line 2044


Sensors typically change Self Switches, but in your case, you could try directly accessing the @sensor object and do something like this:

On a Parallel event, run a Conditional Branch -> Script "$game_map.events[@event_id].sensor.can_see?" without the quotes.  Then you can event to your hearts content, but, you cant interact with a Parallel Event.

Another thing you could try is doing the stuff in a Move Route.

@step_anime = (sensor.can_see?) ? true : false

You CAN interact with an Event like this, but, youre fairly limited to the Events you can do.  Thats why they were set up to use Event Pages.

If you REALLY wanna get fancy, you can use Event Pages (Default is Self Switch D) so have a Page for Self Switch D and in a Move Route, use a script and put in the word "start" to start running event commands.

NOTE: Put the "start" move route on the Page that checks for Self Switch D
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Helios

April 11, 2016, 06:36:11 pm #12 Last Edit: April 11, 2016, 06:37:17 pm by Helios
Quote from: Heretic86 on April 11, 2016, 06:37:10 amSensors typically change Self Switches, but in your case, you could try directly accessing the @sensor object and do something like this:

On a Parallel event, run a Conditional Branch -> Script "$game_map.events[@event_id].sensor.can_see?" without the quotes.  Then you can event to your hearts content, but, you cant interact with a Parallel Event.

Another thing you could try is doing the stuff in a Move Route.

@step_anime = (sensor.can_see?) ? true : false

You CAN interact with an Event like this, but, youre fairly limited to the Events you can do.  Thats why they were set up to use Event Pages.

If you REALLY wanna get fancy, you can use Event Pages (Default is Self Switch D) so have a Page for Self Switch D and in a Move Route, use a script and put in the word "start" to start running event commands.

NOTE: Put the "start" move route on the Page that checks for Self Switch D


Thanks for your reply, if my understanding is correct this Parallel Event serves as a "controller" instead of actual "guard" right? Anyway I got an error "undefined method 'can_see?' for nilclass".

P.S. What I'm trying to achieve here is something like "if any guard is seeing the player then lock that door/rise the alarm/etc etc until the guards are no longer alerted one way or the other"

And any luck with the "listen=" crash? This should be the easiest and most straightforward way to set up a listening guard, but it seems to be broken. Or it's caused by conflicting scripts? I can't really tell.

Heretic86

April 11, 2016, 10:16:38 pm #13 Last Edit: April 12, 2016, 03:05:41 am by Heretic86
Ok, take a look at these two things:

Spoiler: ShowHide
#==============================================================================
#
#      SUPER EVENT SENSOR ADDON[XP]
#
#  - Run "guards_can_see?( [1,2,3] ) from Conditional Branch - Script in a
#    Parallel Event.  The numbers 1, 2, 3 need to be the EVENT IDs of your
#    events you are using as Guards.
#
#  ** REQUIRES "CONTROL SELF SWTICHES ANYWHERE" and SUPER EVENT SENSOR
#
#==============================================================================

#==============================================================================
# ** Interpreter
#==============================================================================
class Interpreter
  #--------------------------------------------------------------------------
  # * Guards Can See? - Interpreter
  #  - Run this in Event Commands -> Conditional Branch -> Script
  #      guard_ids : Array - Use Event IDs
  #  Example:  guards_can_see?( [4,5,12,21,32,44,63] )
  #--------------------------------------------------------------------------
  def guards_can_see?(guard_ids)
    return if not guard_ids.is_a?(Array)
    # Default
    result = false
    # Iterate the Guards
    for guard_id in guard_ids
      # Get the Guard Event
      guard = $game_map.events[guard_id]
      # If the Guuard exists and Guard is a Sensor
      if guard and guard.sensor
        # Get the Guards "See" Switch
        see_switch = guard.sensor.switch
        # Check if that Self Switch is set to True
        if guard.get_self_switch(see_switch) == true
          # Set the Result Flag to True
          result = true
          # Quit iterating (performance)
          break
        end
      end
    end
    # Return the Result
    return result
  end
end


#==============================================================================
#
#      HERETIC'S CONTROL SELF SWITCHES ANYWHERE
#      Version 1.1
#      Saturday, November 15th, 2014
#
#==============================================================================
#
#  - Version 1.1 added an Optional Argument for Map ID which allows for
#    getting and setting Self Switches across different maps!
#
#  The Default Game Engine allows you to change Game Switches from a Move Route
#  but does NOT have anything to allow you to change Self Switches.  This
#  script will allow you to Check and Change ANY Self Switches for Any Event
#  on your Current Map.
#
#    * get_self_switch( Letter, event_id, (Optional) Map ID)
#      - Letter is 'A', 'B', 'C', or 'D', WITH Quotes, Upper case doesnt matter
#      - Returns True if Switch is ON
#      - Returns False if Switch is OFF
#      - Example : get_self_switch('A', 24)
#      - Example : get_self_switch('D', id = 18, map_id = 5)
#    * set_self_switch( Letter, On or Off, event_id, (Optional) Map ID)
#      - Letter is 'A', 'B', 'C', or 'D', WITH Quotes, Upper case doesnt matter
#      - Sets Switch Letter to Value (true or false, 'On' and 'Off' okay too)
#      - Example : set_self_switch('B', true, id = 48)
#      - Example : set_self_switch('C', 'On', id = 27, map_id = 12)
#
#  The intent of this script is to save you from always having to use
#  Game Switches by allowing you more access to Self Switches.  Too
#  many Game Switches can make your game excessively complex for things
#  that will most likely only relate to Events on One Map.  If you need
#  to check Switches across Game Maps or during Battle, then the use of
#  Game Switches is a better idea.
#
#  NOTE:  The script calls in Event -> Script and Move Route -> Script are
#  quite similar, but not exactly the same.  It may be easiest for you to
#  use this script by calling ALL of the arguments.
#
#  get_self_switch can use THREE Arguments
#  set_self_switch can use FOUR Arguments
#
#  If you have any difficulty with the Script Calls, just use all arguments
#  and that will usually solve your problems.  I tried to set up this script
#  to provide lots of error messages that clearly explain what went wrong
#  should something go wrong in your script call.
#
#  NOTE: I allowed for the usage of get_self_switch inside of Set Move Route
#  because you can use a Ternary Operator for Conditional Move Routes.  It is
#  very unlikely that you'll ever need to use get_self_switch inside of
#  Set Move Route -> Script.
#
#  NOTE: You can set a Self Switch for ANY Event on your Game Map, even from
#  setting a Player Move Route -> Script.  When using Player, you MUST call
#  for an Event ID as the Game Player has no Self Switches.  This may be
#  much easier than jumping in and out of Set Move Route when trying to
#  synchronize movements.
#
#  Installation
#
#  Put anywhere between the Default Scripts and Main.  These are all unique
#  definitions so this script should be perfectly compatible with ALL other
#  scripts in existence.
#
#  ---  Limitations  ---
#
#  You cant use during either Battle or Different Maps.
#
#  ---  Usage  ---
#
#  You can use anywhere you can make a Script Call, except in Battle.
#
#  For Conditional Branching, in Events Page 1, click on Conditional Branch.
#  Then in Page 4 of the Conditional Branch, go to Script.
#  In Script, enter "get_self_switch(Letter, event_id) == true / false"
#  -  Dont use Quotes on the whole statement
#  -  Dont use the word IF
#  -  (Letter is 'A', 'B', 'C', or 'D') WITH Quotes in the Script Call.
#  -  Event ID does NOT have Quotes.
#
#  Dont forget you CAN PRINT anywhere you can enter a Script Call also.
#  print get_self_switch(Letter, event_id)
#
# ---  Version History  ---
#
#  Version 1.1 - Saturday, November 15th, 2014
#    * Added Optional Argument for Map ID to change Self Switches for Events
#      from different Maps entirely.
#    NOTE: When specifying a Map ID, the Event is NOT checked for existence
#
#  Version 1.0 - Monday, September 9th, 2013
#    * Initial Release
#
#==============================================================================

class Game_Character
  #--------------------------------------------------------------------------
  # * Set Self Switch(ch, value, id, map_id) - Game_Character
  #       ch     : A, B, C, or D
  #       value  : true, false, 'On', 'Off', 1, or 0
  #       id     : Event ID
  #       map_id : (Optional) Current or Specified Map ID
  #
  #   - Change a Self Switch from a Move Route Event
  #-------------------------------------------------------------------------- 
  def set_self_switch(ch, value, id = @id, map_id = $game_map.map_id)
    # if Player Move Route and id is not Specified
    if id == 0 and $DEBUG
      # Print Error
      print "When using set_self_switch from Player Move Route, you need to\n",
            "specify an Event ID because the Game Player does not\n",
            "have any Self Switches"
    end
    # Valid Values
    value_valid = [true, false, 0, 1, 'on','off']
    if value.is_a?(String)
      value = true if value.to_s.downcase == 'on'
      value = false if value.to_s.downcase == 'off'
    elsif value.is_a?(Integer)
      value = true if value == 1
      value = false if value == 0
    end
   # If we have A, B, C, or D, and the Event exists   
    if ch.is_a?(String) and "ABCD".include?(ch.upcase) and
       (value == true or value == false) and 
       (map_id != $game_map.map_id or $game_map.events[id])
      # If event ID is valid
      if @id > 0 and
        # Make Upper Case for Key
        ch = ch.to_s.upcase
        # Make a self switch key
        key = [map_id, id, ch]
        # Change self switches
        $game_self_switches[key] = value
      end
      # Refresh map
      $game_map.need_refresh = true
      # Continue
      return true
    else
      if $DEBUG
        print "Warning: set_self_switch expects Two Arguments\n",
              "The First Argument should be the letter A, B, C, or D\n",
              "The Second Argument should be either True or False.\n",
              "(On or Off is acceptable too.  Just need you",
              "to say what you want to set it to.)\n\n",
              "Example: set_self_switch('A',true)\n\n",
              "Example 2: set_self_switch('A','On')\n\n",
              "There is an Optional 3rd Argument for",
              "specifying an Event ID\n\n",
              "Example 2: set_self_switch('B',false, 32)\n\n",
              "This Script call to get_self_switch was made\n",
              "from MOVE ROUTE => SCRIPT\n\n",
              "set_self_switch in MOVE ROUTES => SCRIPT expect TWO Arguments,",
              "THIRD Optional\n",
              "set_self_switch in EVENT => SCRIPT expects THREE Arguments\n\n",
              "Your Script: Move Route -> Script set_self_switch",
              "('",ch,"','",value,"','",id,"')"
        # If on the Same Map and Event doesn't exist, explain the Problem
        if map_id == $game_map.map_id and not $game_map.events[id]
          print "The Event ID: ", id, " you specified\n",
                "doesn't exist on this map"
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Get Self Switch(ch, id) - Game_Character
  #       ch     : A, B, C, or D
  #       id     : Event ID
  #       map_id : (Optional) Current or Specified Map ID 
  #
  #   - Returns True if a Switch is ON, False if Switch is OFF
  #   - This is usually only good with Ternary Operator but I included it anyway
  #     Example:  @direction = (get_self_switch('A',15) ? 8 : 2
  #-------------------------------------------------------------------------- 
  def get_self_switch(ch, id = @id, map_id = $game_map.map_id)
    # if Player Move Route and id is not Specified
    if id == 0 and $DEBUG
      # Print Error
      print "When using get_self_switch for Player Set Move Route,",
            "you need to\n",
            "specify an Event ID because the Game Player does not\n",
            "have any Self Switches\n\n",
            "Calling in Player with no ID argument causes\n",
            "the ID to be set to 0"
    end   
    # If we have A, B, C, or D, and the Event exists if same Map
    if ch.is_a?(String) and "ABCD".include?(ch.upcase) and
       id and (map_id != $game_map.map_id or $game_map.events[id])
      # Make a Key
      key = [map_id, id, ch.upcase]
      return $game_self_switches[key]
    else
      if $DEBUG
        print "Warning: get_self_switch expects Two Arguments\n",
              "The First Argument should be the Letter of\n",
              " the Self Switch you are Checking, A, B, C, or D\n",       
              "The Second Argument should be the Event's ID\n",
              "Example: get_self_switch('B', 23)\n\n",
              "This Script call to get_self_switch was made\n",
              "from MOVE ROUTE => SCRIPT\n\n",
              "Your Script: Move Route -> Script get_self_switch",
              "('",ch,"','",id,"')"
        if map_id == $game_map.map_id and not $game_map.events[id]
          print "The Event ID: ", id, " you specified\n",
                "doesn't exist on this map"
        end
      end
    end
  end
end

class Interpreter
  #--------------------------------------------------------------------------
  # * Get Self Switch(ch, id) - Interpreter
  #       ch     : A, B, C, or D
  #       id     : Event ID (Default to self.id)
  #       map_id : (Optional) Current or Specified Map ID 
  #
  #   - Returns True if a Switch is ON, False if Switch is OFF
  #   - This is NOT called from Move Route - Script
  #-------------------------------------------------------------------------- 
  def get_self_switch(ch, id = nil, map_id = $game_map.map_id)
    # If we have A, B, C, or D, and the Event exists on same Map
    if ch.is_a?(String) and "ABCD".include?(ch.upcase) and
       id and (map_id != $game_map.map_id or $game_map.events[id])
      # Make a Key for the Hash in a Key / Value Pair
      key = [map_id, id, ch.upcase]
      # Return the boolean value of the Self Switch
      return $game_self_switches[key]
    else
      if $DEBUG
        print "Warning: get_self_switch expects Two Arguments\n",
              "The First Argument should be the Letter of\n",
              " the Self Switch you are Checking, A, B, C, or D\n",       
              "The Second Argument should be the Event's ID\n",
              "Example: get_self_switch('B', 23)\n\n",
              "Note: The call that generated this error",
              "was NOT called from a Move Route\n ",
              "just an Event Script\n\n",
              "Your Script: Event -> Script get_self_switch('",ch,"','",id,"')"
        # Explain the Problem of No ID
        if id.nil?
          print "The Event ID: ", id, " isn't set in your script call"
        # If on the Same Map and Event doesn't exist, explain the Problem
        elsif map_id == $game_map.map_id and not $game_map.events[id]
          print "The Event ID: ", id, " doesn't exist on this map"
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Set Self Switch(ch, value, id) - Interpreter
  #     ch     : A, B, C, or D
  #     value  : true, false, 'On', 'Off', 1, or 0
  #     id     : Event ID (default self.id)
  #     map_id : (Optional) Current Map ID or Specified Map ID
  #
  #   - Change a Self Switch for any Event from another Event -> Script
  #   - Use this ONLY to change a Self Switch for another Event.  The
  #     game engine already has a button for changing Self Switches. 
  #   - This is NOT called from Move Route - Script
  #-------------------------------------------------------------------------- 
  def set_self_switch(ch, value, id = nil, map_id = $game_map.map_id)
    # Valid Values
    value_valid = [true, false, 0, 1, 'on','off']
    if value.is_a?(String)
      value = true if value.to_s.downcase == 'on'
      value = false if value.to_s.downcase == 'off'
    elsif value.is_a?(Integer)
      value = true if value == 1
      value = false if value == 0
    end
    if ch.is_a?(String) and "ABCD".include?(ch.upcase) and
       (value == true or value == false) and id and
       (map_id != $game_map.map_id or $game_map.events[id])
      # If event ID is valid
      if id > 0 and
        # Make Upper Case for Key
        ch = ch.to_s.upcase
        # Make a Key for the Hash in a Key / Value Pair
        key = [map_id, id, ch]
        # Set the boolean value of the Self Switch (true / false)
        $game_self_switches[key] = value
      end
      # Refresh map
      $game_map.need_refresh = true
      # Continue
      return true
    else
      if $DEBUG
        print "Warning: set_self_switch expects THREE Arguments\n",
              "The First Argument should be the letter A, B, C, or D\n",
              "The Second Argument should be either True or False\n",
              "The 3rd Argument is used to specify an Event ID\n\n",
              "Example: set_self_switch('B','Off', 32)\n\n",
              "Note: The call that generated this error ",
              "was NOT called from a Move Route\n",
              "just an Event Script\n\n",
              "set_self_switch in MOVE ROUTES => SCRIPT expect TWO Arguments,",
              "THIRD Optional\n",
              "set_self_switch in EVENT => SCRIPT expects THREE Arguments\n\n",
              "Your Script: Event -> Script set_self_switch('",ch,"','",value,
              "','",id,"')"             
        # Explain the Error to the User
        if id.nil?
          print "The Event ID: ", id, " isn't set in your script call"
        # If on the Same Map and Event doesn't exist, explain the Problem
        elsif map_id == $game_map.map_id and not $game_map.events[id]
          print "The Event ID: ", id, " doesn't exist current Map"
        end             
      end
    end
  end   
end


That should allow you to do what you are seeking.  Just run "guards_can_see?( [1, 2, 5, 16] )" in a Conditional Branch -> Script.  Im pretty sure I already did this, but theres only a thousand lines of documentation, literally...

---

Edit:  Quick thought, if you use a Self Switch to detect "Defeated", change "        if guard.get_self_switch(see_switch) == true" add to it " and not guard.get_self_switch('A')" to make sure dead guards dont trigger changes, assuming switch A is a self switch for defeat.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Helios

Quote from: Heretic86 on April 11, 2016, 10:16:38 pm
SUPER EVENT SENSOR ADDON[XP]


Just what I need, many thanks! Works perfectly.

Now about that "listen=X" cause "undefined method move_speed in Game_Player" bug...
After a lot of trial-and-errors, I figured out the problem. It was caused by the absent of "HERETIC's CATERPILLAR SCRIPT".
Tested by deleting the Caterpillar script in "CollectionOfArtAndScripts", got the same error.
In other words, if you use "Super Event Sensor" but not "HERETIC's CATERPILLAR SCRIPT", you'll get this error when you walk into a guard with "listen=X".

Could you please make a fix for that? Shouldn't be too hard I guess.

Heretic86

class Game_Character
  attr_accessor :move_speed
end


I probably forgot to put that in as it was made available by another script somewhere...
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Helios


Heretic86

Thanks for letting me know. 

Theres usually two things I find myself messing up constantly.  Forgetting to put in attr_accessors and messing with Save Games.  Im glad the fix worked.  I'm working on putting together some Demo Maps for a couple of new scripts to put in my Collection.  New version with this teeny weeny bugfix will be up pretty soon!
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

Helios

April 22, 2016, 07:19:45 am #18 Last Edit: April 22, 2016, 07:22:40 am by Helios
Another question:

Is there a way to have more than one set of "Sensor_Config" for the same event? It seems the "Sensor_Config" settings are fixed to page 1 even if there is another set of "Sensor_Config" on later pages.

Or if there is a way to disable its "Sensor_Config" state completely? So the "guard" would still move along its patrol route but ignore the player, and act like a normal NPC if talked to. Currently if a NPC is made a guard by putting "Sensor_Config" on page 1, they retain their guard status no matter what page they are on.

What I'm trying to achieve here is a "disguised" state. Think Hitman series, when the player is in a public area guards have no reason to be hostile to the player (the second method, guard act like normal NPC). When the player put on some disguise like enemy uniform, they could enter restricted zones but enemy would notice the player up close (the first method, by changing the view range to 1 or 2).

I try to do it with multiple copies of map, but it would mean at least 3 different version of the same map (safe, disguised, hostile), and the change won't take effect until you leave the current map.

Heretic86

For your situation, take your view page, and immediately to the right of that, put another page that checks for the view condition Self Switch.  This is where certain types of equipment and a script called "Auto State Switches" comes in to play.  Create a Ring or some sort of item the Player equips as a "Disguise".  Create a "state" called "disguise" in your Database.  Set up the config in Auto State Switches for the Item ID of the "Disguise Ring", and the Game Switch you want to turn on and off.  Thus, when your players equip that item on any of the characters in the party, the Game Switch is turned on.  When they unequip it, that Game Switch is automatically turned off.  Use that Switch ID as an additional page condition for your Guard character, and a standard condition the See Self Switch, typically D.  Then you can just Event out what you want to happen from there on that page.  Since this page is to the right of your "See Trigger Page" and to the left of the "Defeated" page, this page will be used when youre in disguise, but not if the guard event is already defeated. 

Do NOT use your Stealth Gear switches, if you are incorporating that as well.  This is a normal Game Switch that youre customizing your guards in this area for.  Just tie that Game Switch and Equipment ID together in the script config of Auto State Switches.  That is all that needs to be done.  Its just Changing Pages.  Pages to the right will be executed before a Page to the left.  Your "Disguised" page can just be text like "guard duty is so boring" or something like that.  No battles, just dialogue.  How ever you want to event it.

Heres the point.  Super Event Sensor at its core is just a very fancy way of changing event pages.  And each of those Pages can be overridden with just more Pages and Conditions.  Although Super Event Sensor is complex, the nature of simply changing Pages and checking Page Conditions allows customization without scripting!
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)