Field of Vision component. (#12075)

* Hopeless WIP for vision cones.

* Core component and hooks done

* Removing clutter.

* linter bashing me for using statements as args.

* Ok.

* continue

* bring back the macro

* Configs and openspace filter.

* Chat plane, reset perspective signal, mechs/vehicles cases, machineries.

* view, viewers and spoopy ghosts.

* Renamed component, admin fun button and snowflakes robots.

* Whoopsie.

* Yikes

* test merge tweak.

* radial yaketi sax.

* Fixed tgui UIs, some messages not displayed to the target.

* Documentation and a little bugfix.

* Pulling QoL, seventh plane made in this PR.

* Fix.

* Tweaks and improvements.

* Update randomverbs.dm
This commit is contained in:
Ghom
2020-05-16 00:25:04 +02:00
committed by GitHub
parent b21fb97bda
commit 7c7147cb3e
122 changed files with 947 additions and 347 deletions
+4 -4
View File
@@ -927,14 +927,14 @@ Proc for attack log creation, because really why not
target.log_message(reverse_message, LOG_ATTACK, color="orange", log_globally=FALSE)
// Filter stuff
/atom/movable/proc/add_filter(name,priority,list/params)
/atom/proc/add_filter(name,priority,list/params)
LAZYINITLIST(filter_data)
var/list/p = params.Copy()
p["priority"] = priority
filter_data[name] = p
update_filters()
/atom/movable/proc/update_filters()
/atom/proc/update_filters()
filters = null
filter_data = sortTim(filter_data, /proc/cmp_filter_data_priority, TRUE)
for(var/f in filter_data)
@@ -943,11 +943,11 @@ Proc for attack log creation, because really why not
arguments -= "priority"
filters += filter(arglist(arguments))
/atom/movable/proc/get_filter(name)
/atom/proc/get_filter(name)
if(filter_data && filter_data[name])
return filters[filter_data.Find(name)]
/atom/movable/proc/remove_filter(name)
/atom/proc/remove_filter(name)
if(filter_data && filter_data[name])
filter_data -= name
update_filters()
+9 -8
View File
@@ -179,14 +179,15 @@
return TRUE
/atom/movable/proc/stop_pulling()
if(pulling)
pulling.pulledby = null
var/mob/living/ex_pulled = pulling
pulling = null
setGrabState(0)
if(isliving(ex_pulled))
var/mob/living/L = ex_pulled
L.update_mobility()// mob gets up if it was lyng down in a chokehold
if(!pulling)
return
pulling.pulledby = null
var/mob/living/ex_pulled = pulling
pulling = null
setGrabState(0)
if(isliving(ex_pulled))
var/mob/living/L = ex_pulled
L.update_mobility()// mob gets up if it was lyng down in a chokehold
/atom/movable/proc/Move_Pulled(atom/A)
if(!pulling)
+5
View File
@@ -37,6 +37,11 @@
reset_chem_buttons()
RefreshParts()
add_inital_chems()
new_occupant_dir = dir
/obj/machinery/sleeper/setDir(newdir)
. = ..()
new_occupant_dir = dir
/obj/machinery/sleeper/on_deconstruction()
var/obj/item/reagent_containers/sleeper_buffer/buffer = new (loc)
+3 -1
View File
@@ -110,7 +110,8 @@ Class Procs:
var/state_open = FALSE
var/critical_machine = FALSE //If this machine is critical to station operation and should have the area be excempted from power failures.
var/list/occupant_typecache //if set, turned into typecache in Initialize, other wise, defaults to mob/living typecache
var/atom/movable/occupant = null
var/atom/movable/occupant
var/new_occupant_dir = SOUTH //The direction the occupant will be set to look at when entering the machine.
var/speed_process = FALSE // Process as fast as possible?
var/obj/item/circuitboard/circuit // Circuit to be created and inserted when the machinery is created
// For storing and overriding ui id and dimensions
@@ -217,6 +218,7 @@ Class Procs:
if(target && !target.has_buckled_mobs() && (!isliving(target) || !mobtarget.buckled))
occupant = target
target.forceMove(src)
target.setDir(new_occupant_dir)
updateUsrDialog()
update_icon()
+1
View File
@@ -3,6 +3,7 @@
desc = "A remote control switch."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "doorctrl"
plane = ABOVE_WALL_PLANE
var/skin = "doorctrl"
power_channel = ENVIRON
var/obj/item/assembly/device
+1
View File
@@ -169,6 +169,7 @@
desc = "Used for watching an empty arena."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "telescreen"
plane = ABOVE_WALL_PLANE
network = list("thunder")
density = FALSE
circuit = null
+13 -13
View File
@@ -470,15 +470,15 @@
if(welded)
weld_overlay = get_airlock_overlay("welded", overlays_file)
if(obj_integrity < integrity_failure * max_integrity)
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
else if(obj_integrity < (0.75 * max_integrity))
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
if(lights && hasPower())
if(locked)
lights_overlay = get_airlock_overlay("lights_bolts", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
lights_overlay = get_airlock_overlay("lights_bolts", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
else if(emergency)
lights_overlay = get_airlock_overlay("lights_emergency", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
lights_overlay = get_airlock_overlay("lights_emergency", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
if(note)
note_overlay = get_airlock_overlay(notetype, note_overlay_file)
@@ -496,18 +496,18 @@
else
panel_overlay = get_airlock_overlay("panel_closed", overlays_file)
if(obj_integrity < integrity_failure * max_integrity)
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
else if(obj_integrity < (0.75 * max_integrity))
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
if(welded)
weld_overlay = get_airlock_overlay("welded", overlays_file)
lights_overlay = get_airlock_overlay("lights_denied", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
lights_overlay = get_airlock_overlay("lights_denied", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
if(note)
note_overlay = get_airlock_overlay(notetype, note_overlay_file)
if(AIRLOCK_EMAG)
frame_overlay = get_airlock_overlay("closed", icon)
sparks_overlay = get_airlock_overlay("sparks", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
sparks_overlay = get_airlock_overlay("sparks", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
if(airlock_material)
filling_overlay = get_airlock_overlay("[airlock_material]_closed", overlays_file)
else
@@ -518,9 +518,9 @@
else
panel_overlay = get_airlock_overlay("panel_closed", overlays_file)
if(obj_integrity < integrity_failure * max_integrity)
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
damag_overlay = get_airlock_overlay("sparks_broken", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
else if(obj_integrity < (0.75 * max_integrity))
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
if(welded)
weld_overlay = get_airlock_overlay("welded", overlays_file)
if(note)
@@ -533,7 +533,7 @@
else
filling_overlay = get_airlock_overlay("fill_closing", icon)
if(lights && hasPower())
lights_overlay = get_airlock_overlay("lights_closing", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
lights_overlay = get_airlock_overlay("lights_closing", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
if(panel_open)
if(security_level)
panel_overlay = get_airlock_overlay("panel_closing_protected", overlays_file)
@@ -554,7 +554,7 @@
else
panel_overlay = get_airlock_overlay("panel_open", overlays_file)
if(obj_integrity < (0.75 * max_integrity))
damag_overlay = get_airlock_overlay("sparks_open", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
damag_overlay = get_airlock_overlay("sparks_open", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
if(note)
note_overlay = get_airlock_overlay("[notetype]_open", note_overlay_file)
@@ -565,7 +565,7 @@
else
filling_overlay = get_airlock_overlay("fill_opening", icon)
if(lights && hasPower())
lights_overlay = get_airlock_overlay("lights_opening", overlays_file, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE)
lights_overlay = get_airlock_overlay("lights_opening", overlays_file, EMISSIVE_UNBLOCKABLE_LAYER, EMISSIVE_UNBLOCKABLE_PLANE)
if(panel_open)
if(security_level)
panel_overlay = get_airlock_overlay("panel_opening_protected", overlays_file)
+1
View File
@@ -21,6 +21,7 @@
icon = 'icons/obj/status_display.dmi'
icon_state = "frame"
desc = "A remote control for a door."
plane = ABOVE_WALL_PLANE
req_access = list(ACCESS_SECURITY)
density = FALSE
var/id // id of linked machinery/lockers
@@ -34,7 +34,7 @@
/obj/machinery/embedded_controller/radio/simple_vent_controller
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "airlock_control_standby"
plane = ABOVE_WALL_PLANE
name = "vent controller"
density = FALSE
+1
View File
@@ -17,6 +17,7 @@
desc = "<i>\"Pull this in case of emergency\"</i>. Thus, keep pulling it forever."
icon = 'icons/obj/monitors.dmi'
icon_state = "fire0"
plane = ABOVE_WALL_PLANE
max_integrity = 250
integrity_failure = 0.4
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30)
+2
View File
@@ -5,6 +5,7 @@
desc = "A wall-mounted flashbulb device."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "mflash1"
plane = ABOVE_WALL_PLANE
max_integrity = 250
integrity_failure = 0.4
light_color = LIGHT_COLOR_WHITE
@@ -20,6 +21,7 @@
name = "portable flasher"
desc = "A portable flashing device. Wrench to activate and deactivate. Cannot detect slow movements."
icon_state = "pflash1-p"
plane = GAME_PLANE
strength = 80
anchored = FALSE
base_state = "pflash"
+5
View File
@@ -20,6 +20,11 @@
. = ..()
if(prob(1))
name = "auto-autopsy"
new_occupant_dir = dir
/obj/machinery/harvester/setDir(newdir)
. = ..()
new_occupant_dir = dir
/obj/machinery/harvester/RefreshParts()
interval = 0
+1
View File
@@ -5,6 +5,7 @@
name = "light switch"
icon = 'icons/obj/power.dmi'
icon_state = "light1"
plane = ABOVE_WALL_PLANE
desc = "Make dark."
var/on = TRUE
var/area/area = null
+1
View File
@@ -16,6 +16,7 @@ GLOBAL_LIST_EMPTY(allConsoles)
desc = "A console intended to send requests to different departments on the station."
icon = 'icons/obj/terminals.dmi'
icon_state = "req_comp0"
plane = ABOVE_WALL_PLANE
var/department = "Unknown" //The list of all departments on the station (Determined from this variable on each unit) Set this to the same thing if you want several consoles in one department
var/list/messages = list() //List of all messages
var/departmentType = 0
+1
View File
@@ -21,6 +21,7 @@
desc = null
icon = 'icons/obj/status_display.dmi'
icon_state = "frame"
plane = ABOVE_WALL_PLANE
density = FALSE
use_power = IDLE_POWER_USE
idle_power_usage = 10
+7 -3
View File
@@ -23,11 +23,11 @@
layer = BELOW_MOB_LAYER//icon draw layer
infra_luminosity = 15 //byond implementation is bugged.
force = 5
flags_1 = HEAR_1
flags_1 = HEAR_1|BLOCK_FACE_ATOM_1
var/can_move = 0 //time of next allowed movement
var/mob/living/carbon/occupant = null
var/mob/living/occupant = null
var/step_in = 10 //make a step in step_in/10 sec.
var/dir_in = 2//What direction will the mech face when entered/powered on? Defaults to South.
var/dir_in = SOUTH //What direction will the mech face when entered/powered on? Defaults to South.
var/normal_step_energy_drain = 10 //How much energy the mech will consume each time it moves. This variable is a backup for when leg actuators affect the energy drain.
var/step_energy_drain = 10
var/melee_energy_drain = 15
@@ -495,6 +495,10 @@
occupant_message("<span class='warning'>Air port connection teared off!</span>")
mecha_log_message("Lost connection to gas port.")
/obj/mecha/setDir(newdir)
. = ..()
occupant?.setDir(newdir)
/obj/mecha/Process_Spacemove(var/movement_dir = 0)
. = ..()
if(.)
+6 -3
View File
@@ -333,10 +333,13 @@
send_byjax(occupant,"exosuit.browser","t_port_connection","[internal_tank.connected_port?"Disconnect from":"Connect to"] gas port")
if(href_list["dna_lock"])
if(occupant && !iscarbon(occupant))
to_chat(occupant, "<span class='danger'> You do not have any DNA!</span>")
if(!occupant)
return
dna_lock = occupant.dna.unique_enzymes
var/mob/living/carbon/C = occupant
if(!istype(C) || !C.dna)
to_chat(C, "<span class='danger'> You do not have any DNA!</span>")
return
dna_lock = C.dna.unique_enzymes
occupant_message("You feel a prick as the needle takes your DNA sample.")
if(href_list["reset_dna"])
+1
View File
@@ -49,6 +49,7 @@
var/original_name
desc = "A large piece of space-resistant printed paper."
icon = 'icons/obj/contraband.dmi'
plane = ABOVE_WALL_PLANE
anchored = TRUE
var/ruined = FALSE
var/random_basetype
+2 -2
View File
@@ -143,8 +143,8 @@ RLD
//if user can't be seen from A (only checks surroundings' opaqueness) and can't see A.
//jarring, but it should stop people from targetting atoms they can't see...
//excluding darkness, to allow RLD to be used to light pitch black dark areas.
if(!((user in view(view_range, A)) || (user in viewers(view_range, A))))
to_chat(user, "<span class='warning'>You focus, pointing \the [src] at whatever outside your field of vision in the given direction... to no avail.</span>")
if(!((user in view(view_range, A)) || (user in get_actual_viewers(view_range, A))))
to_chat(user, "<span class='warning'>You focus, pointing \the [src] at whatever outside your field of vision in that direction... to no avail.</span>")
return FALSE
return TRUE
@@ -135,7 +135,8 @@
outmsg = "<span class='warning'>You miss the lens of [C] with [src]!</span>"
//catpeople
for(var/mob/living/carbon/human/H in view(1,targloc))
var/list/viewers = get_actual_viewers(1,targloc)
for(var/mob/living/carbon/human/H in viewers)
if(!iscatperson(H) || H.incapacitated() || H.eye_blind )
continue
if(!H.lying)
@@ -150,7 +151,7 @@
H.visible_message("<span class='notice'>[H] stares at the light</span>","<span class = 'warning'> You stare at the light... </span>")
//cats!
for(var/mob/living/simple_animal/pet/cat/C in view(1,targloc))
for(var/mob/living/simple_animal/pet/cat/C in viewers)
if(prob(50))
C.visible_message("<span class='notice'>[C] pounces on the light!</span>","<span class='warning'>LIGHT!</span>")
C.Move(targloc)
@@ -2,6 +2,7 @@
name = "station intercom"
desc = "Talk through this."
icon_state = "intercom"
plane = ABOVE_WALL_PLANE
anchored = TRUE
w_class = WEIGHT_CLASS_BULKY
canhear_range = 2
+2 -3
View File
@@ -196,9 +196,8 @@
sleep(1)
previousturf = T
operating = FALSE
for(var/mob/M in viewers(1, loc))
if((M.client && M.machine == src))
attack_self(M)
if(usr.machine == src)
attack_self(usr)
/obj/item/flamethrower/proc/default_ignite(turf/target, release_amount = 0.05)
@@ -66,7 +66,7 @@
if(ismob(loc))
attack_self(loc)
else
for(var/mob/M in viewers(1, src))
for(var/mob/M in get_actual_viewers(1, src))
if(M.client)
attack_self(M)
add_fingerprint(usr)
+2 -4
View File
@@ -105,10 +105,7 @@
if (length(code) > 5)
code = "ERROR"
add_fingerprint(usr)
for(var/mob/M in viewers(1, loc))
if ((M.client && M.machine == src))
attack_self(M)
return
attack_self(usr)
return
@@ -158,6 +155,7 @@
/obj/item/storage/secure/safe
name = "secure safe"
icon = 'icons/obj/storage.dmi'
plane = ABOVE_WALL_PLANE
icon_state = "safe"
icon_opened = "safe0"
icon_locking = "safeb"
+1 -1
View File
@@ -104,7 +104,7 @@
if (ismob(src.loc))
attack_self(src.loc)
else
for(var/mob/M in viewers(1, src))
for(var/mob/M in get_actual_viewers(1, src))
if (M.client)
src.attack_self(M)
return
+2 -2
View File
@@ -123,7 +123,7 @@
/obj/proc/updateUsrDialog()
if((obj_flags & IN_USE) && !(obj_flags & USES_TGUI))
var/is_in_use = FALSE
var/list/nearby = viewers(1, src)
var/list/nearby = get_actual_viewers(1, src)
for(var/mob/M in nearby)
if ((M.client && M.machine == src))
is_in_use = TRUE
@@ -152,7 +152,7 @@
if(obj_flags & IN_USE)
var/is_in_use = FALSE
if(update_viewers)
for(var/mob/M in viewers(1, src))
for(var/mob/M in get_actual_viewers(1, src))
if ((M.client && M.machine == src))
is_in_use = TRUE
src.interact(M)
@@ -24,6 +24,7 @@
move_delay = TRUE
var/oldloc = loc
step(src, direction)
user.setDir(direction)
if(oldloc != loc)
addtimer(CALLBACK(src, .proc/ResetMoveDelay), (use_mob_movespeed ? user.movement_delay() : CONFIG_GET(number/movedelay/walk_delay)) * move_speed_multiplier)
else
@@ -42,7 +43,7 @@
Snake = L
break
if(Snake)
alerted = viewers(7,src)
alerted = get_actual_viewers(world.view,src)
..()
if(LAZYLEN(alerted))
egged = world.time + SNAKE_SPAM_TICKS
@@ -3,6 +3,7 @@
desc = "A small wall mounted cabinet designed to hold a fire extinguisher."
icon = 'icons/obj/wallmounts.dmi'
icon_state = "extinguisher_closed"
plane = ABOVE_WALL_PLANE
anchored = TRUE
density = FALSE
max_integrity = 200
@@ -7,6 +7,7 @@
anchored = TRUE
icon = 'icons/turf/walls/wall.dmi'
icon_state = "wall"
plane = WALL_PLANE
layer = LOW_OBJ_LAYER
density = TRUE
opacity = 1
+1
View File
@@ -3,6 +3,7 @@
desc = "There is a small label that reads \"For Emergency use only\" along with details for safe use of the axe. As if."
icon = 'icons/obj/wallmounts.dmi'
icon_state = "fireaxe"
plane = ABOVE_WALL_PLANE
anchored = TRUE
density = FALSE
armor = list("melee" = 50, "bullet" = 20, "laser" = 0, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50)
+1 -1
View File
@@ -130,7 +130,7 @@
// The crowd is pleased
// The delay is to making large crowds have a longer laster applause
var/delay_offset = 0
for(var/mob/M in viewers(src, 7))
for(var/mob/M in get_actual_viewers(world.view, src))
var/mob/living/carbon/human/C = M
if (ishuman(M))
addtimer(CALLBACK(C, /mob/.proc/emote, "clap"), delay_offset * 0.3)
+1
View File
@@ -4,6 +4,7 @@
desc = "Mirror mirror on the wall, who's the most robust of them all?"
icon = 'icons/obj/watercloset.dmi'
icon_state = "mirror"
plane = ABOVE_WALL_PLANE
density = FALSE
anchored = TRUE
max_integrity = 200
@@ -3,6 +3,7 @@
desc = "A board for pinning important notices upon."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "nboard00"
plane = ABOVE_WALL_PLANE
density = FALSE
anchored = TRUE
max_integrity = 150
@@ -3,6 +3,7 @@
anchored = TRUE
opacity = 0
density = FALSE
plane = ABOVE_WALL_PLANE
layer = SIGN_LAYER
max_integrity = 100
armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
+1
View File
@@ -1,5 +1,6 @@
/turf/closed
layer = CLOSED_TURF_LAYER
plane = WALL_PLANE
opacity = 1
density = TRUE
blocks_air = 1