Jet

Stealth System

35 posts in this topic

Stealth System

by Jet

Introduction

We all know about those cool stealth games. Hiding in trees, ducking in the shadows, stealth forcefields. Stealth is just a fun element to add to a game in certain areas. This script will allow you to do just that, with somewhat accurate, real formulas.

This will give you the ability to check for the sighting of another event, or the player, with an event. This system is PURELY EVENT DRIVEN.

This script does nothing on it's own other than give you the ability to check sight. You must event what happens from there.

Features

- Uses real distance formulas and measurements

- Purely event driven

- Extreme amount of customization

- Potentially includes a simulated height variable for additional sight measuring

- And more...

Script

http://pastebin.com/raw.php?i=ZVzfhk7k

Credit

Jet

Made because Touchfuzzy wanted it but then he was too lazy to ever use and I'm Touchfuzzy's scriptslave.

Note

I have a license, it's in my signature.

Edited by Jet

Share this post


Link to post
Share on other sites

You forgot:

Credits:

Made cause Touchfuzzy wanted it but then he was too lazy to ever use and I'm Touchfuzzy's scriptslave.

Added.

Puppet of Fate likes this

Share this post


Link to post
Share on other sites

This is cool. It is so much more in-depth than just doing it through eventing. Thank you for this script.

Share this post


Link to post
Share on other sites

I am getting the same thing as stated above.

Share this post


Link to post
Share on other sites

That was odd. I could've sworn I tested the link and everything.

Well, either way I fixed the link.

Share this post


Link to post
Share on other sites

What if I don't know how to event that?

Share this post


Link to post
Share on other sites

Any way you would make a demo with a few example events?

Would begging help?

ultimagicka likes this

Share this post


Link to post
Share on other sites

Any way you would make a demo with a few example events?

Would begging help?

No.

IceDragon, Des and Helladen like this

Share this post


Link to post
Share on other sites

Well nice script but I guess I will wait to use it then. I appreciate the quick (and witty) replies also.

Share this post


Link to post
Share on other sites

He wrote this system, you should be obligated to learn how to use it by yourself if no demo is provided. My two cents about the begging for help. :)

Edited by Helladen

Share this post


Link to post
Share on other sites
He wrote this system, you should be obligated to learn how to use it by yourself if no demo is provided. My two cents about the begging for help. :)

With all due respect, if it's a simple task to learn this, then saying, "this isn't that hard to learn" may be an effective deterrent. As it is, I see nothing wrong with a new user asking for help. Responding with "learn how" seems a bit harsh. I recognize Jet's name as one of the more adept scripters I've read on this site, so I understand the respect he has earned in the community. As such, I can only imagine the backlash a newer poster may encounter answering a request for help with a script they had posted, and replying in kind.

Aside from the above opinion (ymmv) it would seem that a lot of the information people may require is embedded in the liberal use of comment tags within the script. In my limited experience, this is where I would start in an attempt to better understand the script. (Which, after reading it, looks like I might need to investigate further, as it looks awesome and very translatable to my current game!)

Snacktaveous, tesaigo and joeyhugg like this

Share this post


Link to post
Share on other sites
HEyy is there any other link??????

Hey, the link works fine for me. Do you not link to the pastebin? Are you firewalled?

Share this post


Link to post
Share on other sites

No i am not firewalled it just says

" google chrome could not connect to pastebin" :(

Share this post


Link to post
Share on other sites

This is the latest version of the link, as per the time of posting. (No, I will not be following the thread and updating as necessary.)

#===============================================================================

# Stealth System

# By Jet10985 (Jet)

# Inspired By: Touchfuzzy

#===============================================================================

# This script will implement a realistic stealth detection system for use

# with events. All measurements are interpreted as metres.

# This script has: 20 customization options.

#===============================================================================

# Overwritten Methods:

# None

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

# Aliased methods:

# Game_System: initialize

#===============================================================================

=begin

To set an event's height, use this Comment in their event page:

HEIGHT = number

--------------------------------------------------------------------------------

To set the player's default camo rating, use this in an event "Script...":

change_player_camo(number)

--------------------------------------------------------------------------------

To give an equipment a bonus to camo rating, use this in the armor's notebox:

<camo = number>

--------------------------------------------------------------------------------

To change the player's height, use this in an event "Script...":

change_player_height(number)

--------------------------------------------------------------------------------

To manually set a region or terrain tag's camo or height for a map, use these in

an event's "Script..." command:

set_region_height(region_id, number)

set_terrain_height(terrain_id, number)

set_region_camo(region_id, number)

set_terrain_camo(terrain_id, number)

--------------------------------------------------------------------------------

You can check for sighting of any event or the player using this

in an event's Conditional Branch "Script...":

can_see?(char_id)

char_id by default is -1, which means the Player

0 is the calling event

anything above 0 is the id of an event on the map

=end

module Jet

module Stealth

# This is the button used for the player to enter a "ducking" position.

DUCK_BUTTON = :ALT

# This is the suffix of the sprite that the player's will be changed to when

# ducking. If the player's sprite name is "Jimmy" and the suffix is "_duck"

# then the game will look for "Jimmy_duck"

DUCK_SUFFIX = ""

# This is how many metres a single tile represents.

TILE_METRE_DIST = 75

# this is how tall events are by default.

DEFAULT_EVENT_HEIGHT = 1.7

# This is how tall the player is by default.

PLAYER_HEIGHT = 1.7

# this is how much "camo" rating is gained from ducking.

DUCKING_CAMO_GAINED = 20

# This is how much "camo" rating is lost when moving while dashing.

DASHING_CAMO_LOST = 15

# This is how much "camo" is lost when just moving without dashing.

MOVEMENT_CAMO_LOST = 10

# This is how much movement speed is lost when ducking.

DUCKING_SPEED_LOST = 2

# This is how many metres away a character has to be to have the

# detector begin to lose some vision per metre.

POINT_OF_VISION_LOSS = TILE_METRE_DIST * 5

# This is how much "camo" is gained per metre once distance has passed the

# POINT_OF_VISION_LOSS mark.

VISION_LOSS_PER_METRE = 0.00271

# How tall are unpassable tiles by default? This only applies if there are

# no events on the tile.

UNPASSABLE_HEIGHT = (1.0 / 0.0)

# These are the default heights of Region IDs for every map.

# A map's specific region height can be changed by using a script command

# found in the instructions above.

# This follows the format: region_id => height

REGION_HEIGHTS = {

#1 => 0,

#2 => 2,

#3 => 0.2

}

# This is the default height of any undefined region above.

REGION_HEIGHTS.default = 0

# These are the default heights of Terrains for every map.

# A map's specific terrain height can be changed by using a script command

# found in the instructions above.

# This follows the format: terrain_id => height

TERRAIN_HEIGHTS = {

#1 => 0,

#2 => 2,

#3 => 0.2

}

# This is the default height of any undefined terrain above.

TERRAIN_HEIGHTS.default = 0

# These are the default camo of Region IDs for every map.

# A map's specific region camo can be changed by using a script command

# found in the instructions above.

# This follows the format: region_id => camo

REGION_CAMOS = {}

# This is the default camo of any undefined region above.

REGION_CAMOS.default = 0

# These are the default camo of Terrains for every map.

# A map's specific terrain camo can be changed by using a script command

# found in the instructions above.

# This follows the format: terrain_id => camo

TERRAIN_CAMOS = {}

# This is the default camo of any undefined terrain above.

TERRAIN_CAMOS.default = 0

end

end

#===============================================================================

# DON'T EDIT FURTHER UNLESS YOU KNOW WHAT TO DO.

#===============================================================================

module Math

module_function

def dist_form(x, y, x2, y2)

sqrt((x2 - x).abs ** 2 + (y2 - y).abs ** 2)

end

def horizon(metres)

3.856 * sqrt(metres) * 1000

end

def rad_to_deg(rads)

rads * 180 / PI

end

end

class RPG::Armor

def camo

@camoflague ||= (

f = self.note.match(/<CAMO[ ]*(\:|=)[ ]*(\d+)>/i)

f.nil? ? 0 : f[2].to_f

)

end

end

class Game_Actor

def character_name

@character_name + ($game_player.ducking? ? Jet::Stealth::DUCK_SUFFIX : "")

end

end

class Game_Event

def check_for_comment(regexp)

return false if empty?

@list.select {|a|

[108, 408].include?(a.code)

}.collect {|a|

a.parameters[0]

}.each {|a|

if !a[regexp].nil?

return a.match(regexp)

end

}

return false

end

def height

f = check_for_comment(/HEIGHT[ ]*(\:|=)[ ]*(\d+)/i)

f == false ? Jet::Stealth::DEFAULT_EVENT_HEIGHT : f[2].to_f

end

def movable?

return false if moving?

return false if @move_route_forcing

return false if $game_message.busy? || $game_message.visible

return true

end

end

class Game_Player

def height

if ducking?

if moving?

f = (2.0 / 3.0)

else

f = (1.0 / 3.0)

end

else

f = 1.0

end

$game_system.player_height * f

end

def ducking?

Input.press?(Jet::Stealth::DUCK_BUTTON)

end

def camoflague

camo = 0

camo += $game_system.player_camo

camo += $game_map.xy_camo(self.x, self.y)

camo += $game_party.members[0].armors.inject {|a, b| a.camo + b.camo }

if moving?

if dash?

camo -= Jet::Stealth::DASHING_CAMO_LOST

else

camo -= Jet::Stealth::MOVEMENT_CAMO_LOST

end

end

camo += Jet::Stealth::DUCKING_CAMO_GAINED if ducking?

[camo, 0].max

end

def real_move_speed

super - (ducking? ? Jet::Stealth::DUCKING_SPEED_LOST : 0)

end

end

class Game_Character

attr_writer :sighted

def camoflague

camo = 0

camo += $game_map.xy_camo(self.x, self.y)

camo -= Jet::Stealth::MOVEMENT_CAMO_LOST if moving?

[camo, 0].max

end

def sight_range

map_height = $game_map.xy_height(self.x, self.y)

Math.horizon(self.height + map_height)

end

def true_height

self.height + $game_map.xy_height(self.x, self.y)

end

def horizontal_angle_from(char)

x_dist = self.x - char.x

y_dist = self.y - char.y

hypo = Math.hypot(x_dist, y_dist)

(Math.rad_to_deg(Math.atan2(y_dist, x_dist)) - 180).abs

end

def viewing_angle_horizontal

case self.direction

when 2

[210, 330]

when 4

[120, 240]

when 6

10

when 8

[30, 150]

end

end

def vertical_angle_from(char)

height = (self.true_height - $game_map.xy_height(char.x, char.y)).abs

distance = Math.dist_form(self.x, self.y, char.x, char.y)

distance *= Jet::Stealth::TILE_METRE_DIST

hypo = Math.hypot(height, distance)

Math.rad_to_deg(Math.asin(height / hypo.to_f))

end

def tiles_seen(x, y, x1, y1, char = nil)

tiles = {}

sx = x - x1

sy = y - y1

if sx.abs > sy.abs

direction = sx > 0 ? 4 : 6

elsif sy != 0

direction = sy > 0 ? 8 : 2

end

x_distance = x1 - x

y_distance = y1 - y

total_distance = Math.dist_form(x, y, x1, y1)

x_per_tile = x_distance / total_distance

y_per_tile = y_distance / total_distance

x_dist_t = 0.0

y_dist_t = 0.0

if !char.nil?

vert_angle = vertical_angle_from(char)

end

self_height = self.true_height

until x_dist_t.abs >= x_distance.abs && y_dist_t.abs >= y_distance.abs

x_dist_t += x_per_tile

y_dist_t += y_per_tile

x_tile = (x + x_dist_t).to_i

y_tile = (y + y_dist_t).to_i

height = $game_map.total_height(x_tile, y_tile, direction)

tiles[[x_tile, y_tile]] = [height]

if !char.nil?

dist = (x_dist_t.abs + y_dist_t.abs) - total_distance

dist = dist.abs

viewing_height = self.height * dist - height

tiles[[x_tile, y_tile]].push(viewing_height)

end

end

tiles

end

def sighted?(char)

distance = Math.dist_form(self.x, self.y, char.x, char.y)

distance *= Jet::Stealth::TILE_METRE_DIST

return false if distance > sight_range

h_angle = horizontal_angle_from(char)

case viewing_angle_horizontal

when Array

h_viewing_angle = viewing_angle_horizontal

return false if !h_angle.between?(*h_viewing_angle)

when 10

return false unless h_angle.between?(0, 60) || h_angle.between?(320, 360)

end

v_angle = vertical_angle_from(char)

if self.true_height >= $game_map.xy_height(char.x, char.y)

return false unless v_angle <= 75

v_viewing_angle = 75

else

return false unless v_angle <= 60

v_viewing_angle = 60

end

camo = char.camoflague

distance += (self.true_height - $game_map.xy_height(char.x, char.y)).abs

if distance.between?(Jet::Stealth::POINT_OF_VISION_LOSS, sight_range)

add = (distance - Jet::Stealth::POINT_OF_VISION_LOSS)

add *= Jet::Stealth::VISION_LOSS_PER_METRE

camo += add

elsif distance > sight_range

return false

elsif distance < Jet::Stealth::POINT_OF_VISION_LOSS

camo /= 4

end

camo = [camo, 0].max

return false if rand(100) + 1 <= camo

tiles = tiles_seen(self.x, self.y, char.x, char.y, char)

tiles.each {|coords, heights|

next if coords == [self.x, self.y]

if heights[1] <= 0

return false

end

}

return true

end

end

class Game_System

attr_accessor :player_height, :player_camo

alias jet3745_initialize initialize

def initialize(*args, &block)

jet3745_initialize(*args, &block)

@player_height = Jet::Stealth::PLAYER_HEIGHT

@player_camo = 0

end

end

class Game_Map

def xy_height(x, y, dir = 0)

reg = region_id(x, y)

reg_h = region_heights(reg)

ter = terrain_tag(x, y)

ter_h = terrain_heights(ter)

pas_h = $game_map.passable?(x, y, dir) ? 0 : Jet::Stealth::UNPASSABLE_HEIGHT

reg_h + ter_h + pas_h

end

def xy_camo(x, y)

reg = region_id(x, y)

reg_c = region_camos(reg)

ter = terrain_tag(x, y)

ter_c = terrain_camos(ter)

reg_c + ter_c

end

def total_height(x, y, dir = 0)

xy = xy_height(x, y, dir)

evs = $game_map.events_xy(x, y)

ev_height = evs.sort {|a, b| a.height <=> b.height }

ev_height = (ev_height[-1].true_height rescue 0)

xy + (ev_height || 0)

end

def region_heights(reg)

(@map_region_heights ||= {})[@map_id] ||= Jet::Stealth::REGION_HEIGHTS

@map_region_heights[@map_id][reg]

end

def set_region_height(reg, height)

(@map_region_heights ||= {})[@map_id] ||= Jet::Stealth::REGION_HEIGHTS

@map_region_heights[@map_id][reg] = height

end

def terrain_heights(ter)

(@map_terrain_heights ||= {})[@map_id] ||= Jet::Stealth::TERRAIN_HEIGHTS

@map_terrain_heights[@map_id][ter]

end

def set_region_height(ter, height)

(@map_terrain_heights ||= {})[@map_id] ||= Jet::Stealth::TERRAIN_HEIGHTS

@map_terrain_heights[@map_id][ter] = height

end

def region_camos(reg)

(@map_region_camos ||= {})[@map_id] ||= Jet::Stealth::REGION_CAMOS

@map_region_camos[@map_id][reg]

end

def set_region_camo(reg, camo)

(@map_region_camos ||= {})[@map_id] ||= Jet::Stealth::REGION_CAMOS

@map_region_camos[@map_id][reg] = camo

end

def terrain_camos(ter)

(@map_terrain_camos ||= {})[@map_id] ||= Jet::Stealth::TERRAIN_CAMOS

@map_terrain_camos[@map_id][ter]

end

def set_region_camo(ter, camo)

(@map_terrain_camos ||= {})[@map_id] ||= Jet::Stealth::TERRAIN_CAMOS

@map_terrain_camos[@map_id][ter] = camo

end

end

class Game_Interpreter

def set_region_height(reg, height)

$game_map.set_right_height(reg, height)

end

def set_terrain_height(ter, height)

$game_map.set_terrain_height(ter, height)

end

def set_region_camo(reg, camo)

$game_map.set_right_height(reg, camo)

end

def set_terrain_camo(ter, camo)

$game_map.set_terrain_height(ter, camo)

end

def change_player_height(height)

$game_system.player_height = height

end

def change_player_camo(camo)

$game_system.player_camo = camo

end

def can_see?(ev = -1)

get_character(0).sighted?(get_character(ev))

end

end

Share this post


Link to post
Share on other sites

Idk if I'm doing this wrong but the character sprite doesn't appear to change when I duck?

I used the suffix "_duck" in the script and I made a translucent version of the evil sprite sheet.

So to be clear my normal character sprite sheet is Evil.png my translucent sprite sheet is Evil_duck.png

Edit:

Also when I use a conditional branch with "can_see?(0)"

I get This error.

"Script 'Game_Interpreter' line 450: Math::DomainError occurred

Numerical argument is out of domain - "atan2"

Do I misunderstand how to use this?

Edited by Lord Valdyr

Share this post


Link to post
Share on other sites

I don't think the stealth detection in this script works, because I've increased my camouflage by 1,000 and setup a parallel process event, but it still detects me over 50 tiles away. It could be my fault, but I've spent almost thirty minutes testing this and nothing appears to get it working correctly.

I am using can_see?(0) as the conditional branch check and making sure it sets my camouflage before the parallel process event will even check it. I would look around the script and fix this, but I'm doing this for the summer contest, and would much rather just write a common event system to save time.

Let me know if you have a solution, thanks. :)

Edited by Helladen

Share this post


Link to post
Share on other sites

It's can_see?(-1) to detect the player I did the same thing lol

Share this post


Link to post
Share on other sites

It is? I thought the instructions said it was 0.

Oh wow, thanks. The way it was written appeared like it was leading up to 0, but it was actually not. No problem with the script, just a misinterpretation.

Edited by Helladen

Share this post


Link to post
Share on other sites

Yea I was confused too

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.