mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-11 08:06:33 +01:00
14d2514aa9
## About The Pull Request /area/station/ai_monitored's behaviour was isolated into a component, `/datum/component/monitored_area`, which itself uses `/datum/motion_group`s to query cameras. Functionally, it (should) work identically to the old implementation. I'm sure that behaviour could have been further cleaned up, camera code is quite dreadful, but it's better to focus on isolating the behaviour first. Baby steps. Areas that want to opt into monitoring can set `var/motion_monitored` to TRUE (this approach was taken to make subtyping easier). The following non-AI areas were changed: - /area/station/ai_monitored/security/armory -> /area/station/security/armory - /area/station/ai_monitored/command/nuke_storage -> /area/station/command/vault - /area/station/ai_monitored/command/storage/eva -> /area/station/command/eva All other `/area/station/ai_monitored` subtypes were repathed into `/area/station/ai` and cleaned up in a way that I thought made logical sense. It is **much** more readable now. For example: - /area/station/ai_monitored/turret_protected/aisat -> /area/station/ai/satellite - /area/station/ai_monitored/command/storage/satellite -> /area/station/ai/satellite/maintenance/storage - /area/station/ai_monitored/turret_protected/ai -> /area/station/ai/satellite/chamber
273 lines
9.5 KiB
Plaintext
273 lines
9.5 KiB
Plaintext
#define WAND_OPEN "open"
|
|
#define WAND_BOLT "bolt"
|
|
#define WAND_EMERGENCY "emergency"
|
|
#define WAND_SHOCK "shock"
|
|
#define WAND_DEPOWER "depower"
|
|
|
|
/obj/item/door_remote
|
|
icon_state = "remote"
|
|
base_icon_state = "remote"
|
|
inhand_icon_state = "electronic"
|
|
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
|
|
icon = 'icons/obj/devices/remote.dmi'
|
|
name = "control wand"
|
|
desc = "A remote for controlling a set of airlocks."
|
|
w_class = WEIGHT_CLASS_TINY
|
|
drop_sound = 'sound/items/door_remote/door_remote_drop1.ogg'
|
|
pickup_sound = 'sound/items/door_remote/door_remote_pick_up1.ogg'
|
|
|
|
var/department = "civilian"
|
|
var/mode = WAND_OPEN
|
|
var/region_access = REGION_GENERAL
|
|
var/list/access_list = list()
|
|
// the trim of the owner of this remote, if applied
|
|
var/datum/id_trim/job/owner_trim = null
|
|
// areas that this remote is the exclusive owner of
|
|
var/list/area/our_domain = null
|
|
// areas specifically considered as restricted from a remote
|
|
// accessing them unless specifically allowed (vault, security, etc)
|
|
var/static/list/area/restricted_areas = list(
|
|
/area/station/command/bridge, /*so Captain's remote isn't totally useless*/
|
|
/area/station/security, /*so antag RD/HoP/QM/CMO can't easily screw up the brig doors*/
|
|
/area/station/command/vault, /*aka Vault since it's QM's special thing*/
|
|
/area/station/ai/satellite/chamber, // these are areas exclusive to RD
|
|
/area/station/ai/upload, // but sometimes mappers might misconfig their doors with our several dozen access helpers
|
|
)
|
|
COOLDOWN_DECLARE(shock_cooldown)
|
|
/// sound played when mode is switched
|
|
var/mode_switch_sound = SFX_REMOTE_MODE_SWITCH
|
|
/// sound played when an action is done
|
|
var/action_sound = SFX_REMOTE_ACTION
|
|
|
|
/obj/item/door_remote/Initialize(mapload)
|
|
. = ..()
|
|
update_icon_state()
|
|
// initialize late to make sure job accesses are fully configured
|
|
return INITIALIZE_HINT_LATELOAD
|
|
|
|
/obj/item/door_remote/LateInitialize()
|
|
access_list = SSid_access.get_region_access_list(list(region_access))
|
|
if(!isnull(owner_trim))
|
|
var/datum/id_trim/job/trim_singlet = SSid_access.trim_singletons_by_path[owner_trim]
|
|
access_list |= trim_singlet.access
|
|
|
|
/obj/item/door_remote/proc/is_my_domain(area/restricted_area)
|
|
for(var/area/dominion as anything in our_domain)
|
|
if(istype(restricted_area, dominion))
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/obj/item/door_remote/emag_act(mob/user, obj/item/card/emag/emag_card)
|
|
. = ..()
|
|
if(obj_flags & EMAGGED)
|
|
return FALSE
|
|
balloon_alert(user, "restricted functions unlocked")
|
|
obj_flags |= EMAGGED
|
|
update_icon_state()
|
|
return TRUE
|
|
|
|
/obj/item/door_remote/attack_self(mob/user)
|
|
var/static/list/ops = list(WAND_OPEN = "Open Door", WAND_BOLT = "Toggle Bolts", WAND_EMERGENCY = "Toggle Emergency Access", WAND_SHOCK = "Shock Door", WAND_DEPOWER = "Depower Door")
|
|
switch(mode)
|
|
if(WAND_OPEN)
|
|
mode = WAND_BOLT
|
|
if(WAND_BOLT)
|
|
mode = WAND_EMERGENCY
|
|
if(WAND_EMERGENCY)
|
|
if(!(obj_flags & EMAGGED))
|
|
mode = WAND_OPEN
|
|
else
|
|
mode = WAND_SHOCK
|
|
if(WAND_SHOCK)
|
|
mode = WAND_DEPOWER
|
|
if(WAND_DEPOWER)
|
|
mode = WAND_OPEN
|
|
update_icon_state()
|
|
balloon_alert(user, "mode: [ops[mode]]")
|
|
if(mode_switch_sound)
|
|
playsound(src, mode_switch_sound, 50, TRUE)
|
|
|
|
/obj/item/door_remote/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
|
|
if(!istype(interacting_with, /obj/machinery/door) && !isturf(interacting_with))
|
|
return NONE
|
|
return ranged_interact_with_atom(interacting_with, user, modifiers)
|
|
|
|
/obj/item/door_remote/omni
|
|
name = "omni door remote"
|
|
desc = "This control wand can access any door on the station."
|
|
department = "omni"
|
|
region_access = REGION_ALL_STATION
|
|
our_domain = list( /area/station )
|
|
|
|
/obj/item/door_remote/captain
|
|
name = "command door remote"
|
|
desc = "A remote for controlling a set of airlocks. Despite its gaudy insignia denoting the Captain as its owner, some fine print\
|
|
indicates that its access is exclusively relegated to the Bridge and high-security command areas -- an additional byline\
|
|
specifically excludes Security from the high-security areas. Ironic."
|
|
department = "command"
|
|
region_access = REGION_COMMAND
|
|
our_domain = list(
|
|
/area/station, // still restricted by limited accesses in REGION_COMMAND
|
|
)
|
|
|
|
/obj/item/door_remote/chief_engineer
|
|
name = "engineering door remote"
|
|
desc = "A remote for controlling a set of airlocks. This one smells like burnt flesh and ozone."
|
|
department = "engi"
|
|
region_access = REGION_ENGINEERING
|
|
owner_trim = /datum/id_trim/job/chief_engineer
|
|
// doesn't need a domain because their specific high-security areas aren't on anyone else's trim but cap
|
|
|
|
/obj/item/door_remote/research_director
|
|
name = "research door remote"
|
|
desc = "A remote for controlling a set of airlocks. This one is slightly misshapen, as if squeezed by a person possessing ludicrous strength."
|
|
department = "sci"
|
|
region_access = REGION_RESEARCH
|
|
owner_trim = /datum/id_trim/job/research_director
|
|
our_domain = list(
|
|
/area/station/ai/satellite/chamber,
|
|
/area/station/ai/upload,
|
|
)
|
|
|
|
/obj/item/door_remote/head_of_security
|
|
name = "security door remote"
|
|
desc = "A remote for controlling a set of airlocks. This one smells like sweat, blood, resentment, and coffee.\
|
|
Someone appears to have tampered with the identifier."
|
|
department = "security"
|
|
region_access = REGION_SECURITY
|
|
owner_trim = /datum/id_trim/job/head_of_security
|
|
our_domain = list( /area/station/security )
|
|
|
|
/obj/item/door_remote/quartermaster
|
|
name = "cargo door remote"
|
|
desc = "Remotely controls airlocks. This remote has additional Vault access. Despite that, holding it makes you feel insecure for some reason."
|
|
department = "cargo"
|
|
region_access = REGION_SUPPLY
|
|
owner_trim = /datum/id_trim/job/quartermaster
|
|
our_domain = list( /area/station/command/vault )
|
|
|
|
/obj/item/door_remote/chief_medical_officer
|
|
name = "medical door remote"
|
|
desc = "A remote for controlling a set of airlocks. It has the overpowering odor of blood and, despite its medical insignia,\
|
|
has absolutely no accompanying odor of disinfectant."
|
|
department = "med"
|
|
region_access = REGION_MEDBAY
|
|
owner_trim = /datum/id_trim/job/chief_medical_officer
|
|
|
|
/obj/item/door_remote/head_of_personnel
|
|
name = "service door remote"
|
|
desc = "A remote for controlling a set of airlocks. This one smells like printer ink, and fills its holder with the urge\
|
|
to mysteriously vanish."
|
|
department = "civilian"
|
|
region_access = REGION_GENERAL
|
|
owner_trim = /datum/id_trim/job/head_of_personnel
|
|
|
|
/obj/item/door_remote/ranged_interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
|
|
var/obj/machinery/door/door
|
|
if(action_sound)
|
|
playsound(src, action_sound, 50, TRUE)
|
|
|
|
if (istype(interacting_with, /obj/machinery/door))
|
|
door = interacting_with
|
|
if (!door.opens_with_door_remote)
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
else
|
|
for (var/obj/machinery/door/door_on_turf in get_turf(interacting_with))
|
|
if (door_on_turf.opens_with_door_remote)
|
|
door = door_on_turf
|
|
break
|
|
|
|
if (isnull(door))
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
if (!door.check_access_list(access_list) || !door.requiresID())
|
|
interacting_with.balloon_alert(user, "can't access!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
var/area/door_area = get_area(door)
|
|
if(is_type_in_list(door_area, restricted_areas) && !is_my_domain(get_area(door)))
|
|
interacting_with.balloon_alert(user, "can't access!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
var/obj/machinery/door/airlock/airlock = door
|
|
|
|
if (!door.hasPower() || (istype(airlock) && !airlock.canAIControl()))
|
|
interacting_with.balloon_alert(user, mode == WAND_OPEN ? "it won't budge!" : "nothing happens!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
switch (mode)
|
|
if (WAND_OPEN)
|
|
if (door.density)
|
|
door.open()
|
|
else
|
|
door.close()
|
|
|
|
if (WAND_BOLT)
|
|
if (!istype(airlock))
|
|
interacting_with.balloon_alert(user, "only airlocks!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
if (airlock.locked)
|
|
airlock.unbolt()
|
|
log_combat(user, airlock, "unbolted", src)
|
|
else
|
|
airlock.bolt()
|
|
log_combat(user, airlock, "bolted", src)
|
|
|
|
if (WAND_EMERGENCY)
|
|
if (!istype(airlock))
|
|
interacting_with.balloon_alert(user, "only airlocks!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
|
|
airlock.emergency = !airlock.emergency
|
|
airlock.update_appearance(UPDATE_ICON)
|
|
|
|
if (WAND_SHOCK)
|
|
if (!istype(airlock))
|
|
interacting_with.balloon_alert(user, "only airlocks!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
if (!COOLDOWN_FINISHED(src, shock_cooldown))
|
|
interacting_with.balloon_alert(user, "shock pulse resetting!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
if (airlock.isElectrified())
|
|
interacting_with.balloon_alert(user, "already electrified!")
|
|
else
|
|
airlock.set_electrified(MACHINE_DEFAULT_ELECTRIFY_TIME, user)
|
|
COOLDOWN_START(src, shock_cooldown, 10 SECONDS)
|
|
|
|
if (WAND_DEPOWER)
|
|
if (!istype(airlock))
|
|
interacting_with.balloon_alert(user, "only airlocks!")
|
|
return ITEM_INTERACT_BLOCKING
|
|
// First hit disrupts main power, backup comes back in ten seconds, if you stick around you can hit backup for 60 more seconds of downtime.
|
|
if (!airlock.main_power_timer)
|
|
airlock.loseMainPower()
|
|
else if (!airlock.backup_power_time)
|
|
airlock.loseBackupPower()
|
|
|
|
return ITEM_INTERACT_SUCCESS
|
|
|
|
/obj/item/door_remote/update_icon_state()
|
|
var/icon_state_mode
|
|
if(!(obj_flags & EMAGGED))
|
|
switch(mode)
|
|
if(WAND_OPEN)
|
|
icon_state_mode = "open"
|
|
if(WAND_BOLT)
|
|
icon_state_mode = "bolt"
|
|
if(WAND_EMERGENCY)
|
|
icon_state_mode = "emergency"
|
|
else
|
|
icon_state_mode = "emergency"
|
|
|
|
icon_state = "[base_icon_state]_[department]_[icon_state_mode]"
|
|
return ..()
|
|
|
|
#undef WAND_OPEN
|
|
#undef WAND_BOLT
|
|
#undef WAND_EMERGENCY
|
|
#undef WAND_SHOCK
|
|
#undef WAND_DEPOWER
|