Replace Maint. Drone machinery whitelist with last touched check & other tweaks (#58802)

Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
This commit is contained in:
Jonathan Rubenstein
2021-05-08 16:12:31 -07:00
committed by GitHub
co-authored by Mothblocks
parent 56e6f9e768
commit 770148de06
36 changed files with 344 additions and 122 deletions
+7 -1
View File
@@ -523,6 +523,9 @@
#define COMPONENT_BLOCK_SWAP (1<<0)
///from base of /mob/verb/pointed: (atom/A)
#define COMSIG_MOB_POINTED "mob_pointed"
///Mob is trying to open the wires of a target [/atom], from /datum/wires/interactable(): (atom/target)
#define COMSIG_TRY_WIRES_INTERACT "try_wires_interact"
#define COMPONENT_CANT_INTERACT_WIRES (1<<0)
///from /obj/structure/door/crush(): (mob/living/crushed, /obj/machinery/door/crushing_door)
#define COMSIG_LIVING_DOORCRUSHED "living_doorcrush"
@@ -702,7 +705,10 @@
///from /obj/machinery/can_interact(mob/user): Called on user when attempting to interact with a machine (obj/machinery/machine)
#define COMSIG_TRY_USE_MACHINE "try_use_machine"
#define COMPONENT_CANT_USE_MACHINE (1<<0)
/// Can't interact with the machine
#define COMPONENT_CANT_USE_MACHINE_INTERACT (1<<0)
/// Can't use tools on the machine
#define COMPONENT_CANT_USE_MACHINE_TOOLS (1<<1)
///from obj/machinery/iv_drip/IV_attach(target, usr) : (attachee)
#define COMSIG_IV_ATTACH "iv_attach"
+20
View File
@@ -0,0 +1,20 @@
// PDA defines //
#define CART_SECURITY (1<<0)
#define CART_ENGINE (1<<1)
#define CART_ATMOS (1<<2)
#define CART_MEDICAL (1<<3)
#define CART_MANIFEST (1<<4)
#define CART_CLOWN (1<<5)
#define CART_MIME (1<<6)
#define CART_JANITOR (1<<7)
#define CART_REAGENT_SCANNER (1<<8)
#define CART_NEWSCASTER (1<<9)
#define CART_REMOTE_DOOR (1<<10)
#define CART_STATUS_DISPLAY (1<<11)
#define CART_QUARTERMASTER (1<<12)
#define CART_HYDROPONICS (1<<13)
#define CART_DRONEPHONE (1<<14)
#define CART_DRONEACCESS (1<<15)
// Used by PDA and cartridge code to reduce repetitiveness of spritesheets
#define PDAIMG(what) {"<span class="pda16x16 [#what]"></span>"}
+8
View File
@@ -190,3 +190,11 @@
#define ORION_GAMER_PAMPHLET -1
//game begins to have a chance to warn sec and med
#define ORION_GAMER_REPORT_THRESHOLD 2
// Air alarm [/obj/machinery/airalarm/buildstage]
/// Air alarm missing circuit
#define AIRALARM_BUILD_NO_CIRCUIT 0
/// Air alarm has circuit but is missing wires
#define AIRALARM_BUILD_NO_WIRES 1
/// Air alarm has all components but isn't completed
#define AIRALARM_BUILD_COMPLETE 2
-3
View File
@@ -454,9 +454,6 @@ GLOBAL_LIST_INIT(pda_styles, sortList(list(MONO, VT, ORBITRON, SHARE)))
#define EGG_LAYING_MESSAGES list("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.")
// Used by PDA and cartridge code to reduce repetitiveness of spritesheets
#define PDAIMG(what) {"<span class="pda16x16 [#what]"></span>"}
/// Prepares a text to be used for maptext. Use this so it doesn't look hideous.
#define MAPTEXT(text) {"<span class='maptext'>[##text]</span>"}
+10
View File
@@ -22,3 +22,13 @@
// If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY,
// tool sound is only played when op is started. If not, it's played twice.
#define MIN_TOOL_SOUND_DELAY 20
// tool_act chain flags
/// When a tooltype_act proc is successful
#define TOOL_ACT_TOOLTYPE_SUCCESS (1<<0)
/// When [COMSIG_ATOM_TOOL_ACT] blocks the act
#define TOOL_ACT_SIGNAL_BLOCKING (1<<1)
/// When [TOOL_ACT_TOOLTYPE_SUCCESS] or [TOOL_ACT_SIGNAL_BLOCKING] are set
#define TOOL_ACT_MELEE_CHAIN_BLOCKING (TOOL_ACT_TOOLTYPE_SUCCESS | TOOL_ACT_SIGNAL_BLOCKING)
+3
View File
@@ -31,3 +31,6 @@ GLOBAL_PROTECT(poll_options)
GLOBAL_VAR_INIT(internal_tick_usage, 0.2 * world.tick_lag)
GLOBAL_VAR_INIT(glowshrooms, 0)
/// If drones are blacklisted from certain sensitive machines
GLOBAL_VAR_INIT(drone_machine_blacklist_enabled, TRUE)
+2 -2
View File
@@ -2,7 +2,7 @@
* This is the proc that handles the order of an item_attack.
*
* The order of procs called is:
* * [/atom/proc/tool_act] on the target. If it returns TRUE, the chain will be stopped.
* * [/atom/proc/tool_act] on the target. If it returns TOOL_ACT_TOOLTYPE_SUCCESS or TOOL_ACT_SIGNAL_BLOCKING, the chain will be stopped.
* * [/obj/item/proc/pre_attack] on src. If this returns TRUE, the chain will be stopped.
* * [/atom/proc/attackby] on the target. If it returns TRUE, the chain will be stopped.
* * [/obj/item/proc/afterattack]. The return value does not matter.
@@ -11,7 +11,7 @@
var/is_right_clicking = LAZYACCESS(params2list(params), RIGHT_CLICK)
if(tool_behaviour && target.tool_act(user, src, tool_behaviour, is_right_clicking))
if(tool_behaviour && (target.tool_act(user, src, tool_behaviour, is_right_clicking) & TOOL_ACT_MELEE_CHAIN_BLOCKING))
return TRUE
var/pre_attack_result
+14 -4
View File
@@ -14,10 +14,11 @@
src.message = message
/datum/component/technointrovert/RegisterWithParent()
RegisterSignal(parent, COMSIG_TRY_USE_MACHINE, .proc/is_in_whitelist)
RegisterSignal(parent, COMSIG_TRY_USE_MACHINE, .proc/on_try_use_machine)
RegisterSignal(parent, COMSIG_TRY_WIRES_INTERACT, .proc/on_try_wires_interact)
/datum/component/technointrovert/UnregisterFromParent()
UnregisterSignal(parent, COMSIG_TRY_USE_MACHINE)
UnregisterSignal(parent, list(COMSIG_TRY_USE_MACHINE, COMSIG_TRY_WIRES_INTERACT))
/datum/component/technointrovert/PostTransfer()
if(!ismob(parent))
@@ -29,8 +30,17 @@
message = friend.message
/datum/component/technointrovert/proc/is_in_whitelist(datum/source, obj/machinery/machine)
SIGNAL_HANDLER
if(!is_type_in_typecache(machine, whitelist))
to_chat(source, "<span class='warning'>[replacetext(message, "%TARGET", machine)]</span>")
return COMPONENT_CANT_USE_MACHINE
return FALSE
return TRUE
/datum/component/technointrovert/proc/on_try_use_machine(datum/source, obj/machinery/machine)
SIGNAL_HANDLER
if(!is_in_whitelist(source, machine))
return COMPONENT_CANT_USE_MACHINE_INTERACT | COMPONENT_CANT_USE_MACHINE_TOOLS
/datum/component/technointrovert/proc/on_try_wires_interact(datum/source, atom/machine)
SIGNAL_HANDLER
if(ismachinery(machine) && !is_in_whitelist(source, machine))
return COMPONENT_CANT_INTERACT_WIRES
+55
View File
@@ -0,0 +1,55 @@
/// You can't use machines when they've been touched within the last [unused_duration], unless it was by a mob in [whitelist]
/datum/component/technoshy
can_transfer = TRUE
/// How long in deciseconds the machine can be untouched for
var/unused_duration = (2 MINUTES)
/// Typecache of allowed last_users
var/list/whitelist
/// Message presented if the machine was used too recently
var/message = "The %TARGET is way too fresh dude. Since we're like, <b>super</b> retro, we gotta wait for it to exit the mainstream."
/datum/component/technoshy/Initialize(unused_duration, message, whitelist)
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE
if(unused_duration)
src.unused_duration = unused_duration
if(message)
src.message = message
if(!whitelist)
whitelist = typecacheof(parent.type)
src.whitelist = whitelist
/datum/component/technoshy/RegisterWithParent()
RegisterSignal(parent, COMSIG_TRY_USE_MACHINE, .proc/on_try_use_machine)
RegisterSignal(parent, COMSIG_TRY_WIRES_INTERACT, .proc/on_try_wires_interact)
/datum/component/technoshy/UnregisterFromParent()
UnregisterSignal(parent, list(COMSIG_TRY_USE_MACHINE, COMSIG_TRY_WIRES_INTERACT))
/datum/component/technoshy/PostTransfer()
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE
/datum/component/technoshy/InheritComponent(datum/component/technoshy/friend, i_am_original, list/arguments)
if(i_am_original)
whitelist = friend.whitelist
message = friend.message
/datum/component/technoshy/proc/is_not_touched(datum/source, obj/machinery/machine)
var/time_since = world.time - machine.last_used_time
if(time_since < unused_duration && !isnull(machine.last_user_mobtype) && !is_type_in_typecache(machine.last_user_mobtype, whitelist))
to_chat(source, "<span class='warning'>[replacetext(message, "%TARGET", machine)]</span>")
return TRUE
/datum/component/technoshy/proc/on_try_use_machine(datum/source, obj/machinery/machine)
SIGNAL_HANDLER
if(is_not_touched(source, machine))
return COMPONENT_CANT_USE_MACHINE_INTERACT | COMPONENT_CANT_USE_MACHINE_TOOLS
/datum/component/technoshy/proc/on_try_wires_interact(datum/source, atom/machine)
SIGNAL_HANDLER
if(!ismachinery(machine))
return
else if(is_not_touched(source, machine))
return COMPONENT_CANT_INTERACT_WIRES
+3
View File
@@ -207,6 +207,9 @@
// Overridable Procs
/datum/wires/proc/interactable(mob/user)
SHOULD_CALL_PARENT(TRUE)
if((SEND_SIGNAL(user, COMSIG_TRY_WIRES_INTERACT, holder) & COMPONENT_CANT_INTERACT_WIRES))
return FALSE
return TRUE
/datum/wires/proc/get_status()
+2
View File
@@ -12,6 +12,8 @@
..()
/datum/wires/airalarm/interactable(mob/user)
if(!..())
return FALSE
var/obj/machinery/airalarm/A = holder
if(A.panel_open && A.buildstage == 2)
return TRUE
+2
View File
@@ -62,6 +62,8 @@
return ..()
/datum/wires/airlock/interactable(mob/user)
if(!..())
return FALSE
var/obj/machinery/door/airlock/A = holder
if(!issilicon(user) && A.isElectrified())
var/mob/living/carbon/carbon_user = user
+2
View File
@@ -11,6 +11,8 @@
..()
/datum/wires/apc/interactable(mob/user)
if(!..())
return FALSE
var/obj/machinery/power/apc/A = holder
if(A.panel_open && !A.opened)
return TRUE
+2
View File
@@ -11,6 +11,8 @@
..()
/datum/wires/autolathe/interactable(mob/user)
if(!..())
return FALSE
var/obj/machinery/autolathe/A = holder
if(A.panel_open)
return TRUE
+2
View File
@@ -13,5 +13,7 @@
C.interact(fingerman)
/datum/wires/conveyor/interactable(mob/user)
if(!..())
return FALSE
fingerman = user
return TRUE
+4 -3
View File
@@ -22,6 +22,8 @@
var/fingerprint
/datum/wires/explosive/chem_grenade/interactable(mob/user)
if(!..())
return FALSE
var/obj/item/grenade/chem_grenade/G = holder
if(G.stage == GRENADE_WIRED)
return TRUE
@@ -77,9 +79,6 @@
/datum/wires/explosive/c4 // Also includes X4
holder_type = /obj/item/grenade/c4
/datum/wires/explosive/c4/interactable(mob/user) // No need to unscrew wire panels on plastic explosives
return TRUE
/datum/wires/explosive/c4/explode()
var/obj/item/grenade/c4/P = holder
P.detonate()
@@ -95,6 +94,8 @@
..()
/datum/wires/explosive/pizza/interactable(mob/user)
if(!..())
return FALSE
var/obj/item/pizzabox/P = holder
if(P.open && P.bomb)
return TRUE
+2
View File
@@ -9,6 +9,8 @@
..()
/datum/wires/microwave/interactable(mob/user)
if(!..())
return FALSE
. = FALSE
var/obj/machinery/microwave/M = holder
if(M.panel_open)
+2
View File
@@ -13,6 +13,8 @@
..()
/datum/wires/mulebot/interactable(mob/user)
if(!..())
return FALSE
var/mob/living/simple_animal/bot/mulebot/M = holder
if(M.open)
return TRUE
+2
View File
@@ -12,6 +12,8 @@
..()
/datum/wires/rnd/interactable(mob/user)
if(!..())
return FALSE
var/obj/machinery/rnd/R = holder
if(R.panel_open)
return TRUE
+2
View File
@@ -10,6 +10,8 @@
..()
/datum/wires/radio/interactable(mob/user)
if(!..())
return FALSE
var/obj/item/radio/R = holder
return R.unscrewed
+2
View File
@@ -13,6 +13,8 @@
..()
/datum/wires/robot/interactable(mob/user)
if(!..())
return FALSE
var/mob/living/silicon/robot/R = holder
if(R.wiresexposed)
return TRUE
+2
View File
@@ -13,6 +13,8 @@
..()
/datum/wires/roulette/interactable(mob/user)
if(!..())
return FALSE
. = FALSE
var/obj/machinery/roulette/R = holder
if(R.machine_stat & MAINT)
+2
View File
@@ -11,6 +11,8 @@
..()
/datum/wires/suit_storage_unit/interactable(mob/user)
if(!..())
return FALSE
var/obj/machinery/suit_storage_unit/SSU = holder
if(SSU.panel_open)
return TRUE
+2
View File
@@ -11,6 +11,8 @@
..()
/datum/wires/syndicatebomb/interactable(mob/user)
if(!..())
return FALSE
var/obj/machinery/syndicatebomb/P = holder
if(P.open_panel)
return TRUE
+2
View File
@@ -11,6 +11,8 @@
..()
/datum/wires/vending/interactable(mob/user)
if(!..())
return FALSE
var/obj/machinery/vending/V = holder
if(!issilicon(user) && V.seconds_electrified && V.shock(user, 100))
return FALSE
+21 -16
View File
@@ -1354,48 +1354,53 @@
* Must return parent proc ..() in the end if overridden
*/
/atom/proc/tool_act(mob/living/user, obj/item/I, tool_type, is_right_clicking)
var/act_result
var/signal_result
if(!is_right_clicking) // Left click first for sensibility
var/list/processing_recipes = list() //List of recipes that can be mutated by sending the signal
signal_result = SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(tool_type), user, I, processing_recipes)
if(signal_result & COMPONENT_BLOCK_TOOL_ATTACK) // The COMSIG_ATOM_TOOL_ACT signal is blocking the act
return TOOL_ACT_SIGNAL_BLOCKING
if(processing_recipes.len)
process_recipes(user, I, processing_recipes)
if(QDELETED(I))
return TRUE
switch(tool_type)
if(TOOL_CROWBAR)
. = crowbar_act(user, I,)
act_result = crowbar_act(user, I,)
if(TOOL_MULTITOOL)
. = multitool_act(user, I)
act_result = multitool_act(user, I)
if(TOOL_SCREWDRIVER)
. = screwdriver_act(user, I)
act_result = screwdriver_act(user, I)
if(TOOL_WRENCH)
. = wrench_act(user, I)
act_result = wrench_act(user, I)
if(TOOL_WIRECUTTER)
. = wirecutter_act(user, I)
act_result = wirecutter_act(user, I)
if(TOOL_WELDER)
. = welder_act(user, I)
act_result = welder_act(user, I)
if(TOOL_ANALYZER)
. = analyzer_act(user, I)
act_result = analyzer_act(user, I)
else
signal_result = SEND_SIGNAL(src, COMSIG_ATOM_SECONDARY_TOOL_ACT(tool_type), user, I)
if(signal_result & COMPONENT_BLOCK_TOOL_ATTACK) // The COMSIG_ATOM_TOOL_ACT signal is blocking the act
return TOOL_ACT_SIGNAL_BLOCKING
switch(tool_type)
if(TOOL_CROWBAR)
. = crowbar_act_secondary(user, I,)
act_result = crowbar_act_secondary(user, I,)
if(TOOL_MULTITOOL)
. = multitool_act_secondary(user, I)
act_result = multitool_act_secondary(user, I)
if(TOOL_SCREWDRIVER)
. = screwdriver_act_secondary(user, I)
act_result = screwdriver_act_secondary(user, I)
if(TOOL_WRENCH)
. = wrench_act_secondary(user, I)
act_result = wrench_act_secondary(user, I)
if(TOOL_WIRECUTTER)
. = wirecutter_act_secondary(user, I)
act_result = wirecutter_act_secondary(user, I)
if(TOOL_WELDER)
. = welder_act_secondary(user, I)
act_result = welder_act_secondary(user, I)
if(TOOL_ANALYZER)
. = analyzer_act_secondary(user, I)
if(. || signal_result & COMPONENT_BLOCK_TOOL_ATTACK) //Either the proc or the signal handled the tool's events in some way.
return TRUE
act_result = analyzer_act_secondary(user, I)
if(act_result) // A tooltype_act has completed successfully
return TOOL_ACT_TOOLTYPE_SUCCESS
/atom/proc/process_recipes(mob/living/user, obj/item/I, list/processing_recipes)
+34 -2
View File
@@ -130,6 +130,10 @@
var/tgui_id // ID of TGUI interface
///Is this machine currently in the atmos machinery queue?
var/atmos_processing = FALSE
/// world.time of last use by [/mob/living]
var/last_used_time = 0
/// Mobtype of last user. Typecast to [/mob/living] for initial() usage
var/mob/living/last_user_mobtype
/obj/machinery/Initialize()
if(!armor)
@@ -344,7 +348,7 @@
if(!isliving(user))
return FALSE //no ghosts in the machine allowed, sorry
if(SEND_SIGNAL(user, COMSIG_TRY_USE_MACHINE, src) & COMPONENT_CANT_USE_MACHINE)
if(SEND_SIGNAL(user, COMSIG_TRY_USE_MACHINE, src) & COMPONENT_CANT_USE_MACHINE_INTERACT)
return FALSE
var/mob/living/living_user = user
@@ -422,10 +426,12 @@
/obj/machinery/interact(mob/user, special_state)
if(interaction_flags_machine & INTERACT_MACHINE_SET_MACHINE)
user.set_machine(src)
update_last_used(user)
. = ..()
/obj/machinery/ui_act(action, list/params)
add_fingerprint(usr)
update_last_used(usr)
return ..()
/obj/machinery/Topic(href, href_list)
@@ -435,6 +441,7 @@
if(!usr.canUseTopic(src))
return TRUE
add_fingerprint(usr)
update_last_used(usr)
return FALSE
////////////////////////////////////////////////////////////////////////////////////////////
@@ -479,10 +486,30 @@
else
return _try_interact(user)
/obj/machinery/attackby(obj/item/weapon, mob/user, params)
. = ..()
if(.)
return
update_last_used(user)
/obj/machinery/attackby_secondary(obj/item/weapon, mob/user, params)
. = ..()
if(.)
return
update_last_used(user)
/obj/machinery/tool_act(mob/living/user, obj/item/tool, tool_type)
if(SEND_SIGNAL(user, COMSIG_TRY_USE_MACHINE, src) & COMPONENT_CANT_USE_MACHINE_TOOLS)
return TOOL_ACT_MELEE_CHAIN_BLOCKING
. = ..()
if(. & TOOL_ACT_SIGNAL_BLOCKING)
return
update_last_used(user)
/obj/machinery/_try_interact(mob/user)
if((interaction_flags_machine & INTERACT_MACHINE_WIRES_IF_OPEN) && panel_open && (attempt_wire_interaction(user) == WIRE_INTERACTION_BLOCK))
return TRUE
if(SEND_SIGNAL(user, COMSIG_TRY_USE_MACHINE, src) & COMPONENT_CANT_USE_MACHINE)
if(SEND_SIGNAL(user, COMSIG_TRY_USE_MACHINE, src) & COMPONENT_CANT_USE_MACHINE_INTERACT)
return TRUE
return ..()
@@ -779,3 +806,8 @@
var/alertstr = "<span class='userdanger'>Network Alert: Hacking attempt detected[get_area(src)?" in [get_area_name(src, TRUE)]":". Unable to pinpoint location"].</span>"
for(var/mob/living/silicon/ai/AI in GLOB.player_list)
to_chat(AI, alertstr)
/obj/machinery/proc/update_last_used(mob/user)
if(isliving(user))
last_used_time = world.time
last_user_mobtype = user.type
@@ -325,6 +325,9 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "<li><a href='byond://?src=[REF(src)];choice=Toggle Door'>[PDAIMG(rdoor)]Toggle Remote Door</a></li>"
if (cartridge.access & CART_DRONEPHONE)
dat += "<li><a href='byond://?src=[REF(src)];choice=Drone Phone'>[PDAIMG(dronephone)]Drone Phone</a></li>"
if (cartridge.access & CART_DRONEACCESS)
var/blacklist_state = GLOB.drone_machine_blacklist_enabled
dat += "<li><a href='byond://?src=[REF(src)];drone_blacklist=[!blacklist_state];choice=Drone Access'>[PDAIMG(droneblacklist)][blacklist_state ? "Disable" : "Enable"] Drone Blacklist</a></li>"
dat += "<li><a href='byond://?src=[REF(src)];choice=3'>[PDAIMG(atmos)]Atmospheric Scan</a></li>"
dat += "<li><a href='byond://?src=[REF(src)];choice=Light'>[PDAIMG(flashlight)][light_on ? "Disable" : "Enable"] Flashlight</a></li>"
if (pai)
@@ -589,6 +592,15 @@ GLOBAL_LIST_EMPTY(PDAs)
to_chat(U, msg)
if(!silent)
playsound(src, 'sound/machines/terminal_success.ogg', 15, TRUE)
if("Drone Access")
var/mob/living/simple_animal/drone/drone_user = U
if(isdrone(U) && drone_user.shy)
to_chat(U, "<span class='warning'>Your laws prevent this action.</span>")
return
var/new_state = text2num(href_list["drone_blacklist"])
GLOB.drone_machine_blacklist_enabled = new_state
if(!silent)
playsound(src, 'sound/machines/terminal_select.ogg', 15, TRUE)
//NOTEKEEPER FUNCTIONS===================================
+1 -19
View File
@@ -1,21 +1,3 @@
#define CART_SECURITY (1<<0)
#define CART_ENGINE (1<<1)
#define CART_ATMOS (1<<2)
#define CART_MEDICAL (1<<3)
#define CART_MANIFEST (1<<4)
#define CART_CLOWN (1<<5)
#define CART_MIME (1<<6)
#define CART_JANITOR (1<<7)
#define CART_REAGENT_SCANNER (1<<8)
#define CART_NEWSCASTER (1<<9)
#define CART_REMOTE_DOOR (1<<10)
#define CART_STATUS_DISPLAY (1<<11)
#define CART_QUARTERMASTER (1<<12)
#define CART_HYDROPONICS (1<<13)
#define CART_DRONEPHONE (1<<14)
/obj/item/cartridge
name = "generic cartridge"
desc = "A data cartridge for portable microcomputers."
@@ -160,7 +142,7 @@
/obj/item/cartridge/ce
name = "\improper Power-On DELUXE cartridge"
icon_state = "cart-ce"
access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_ENGINE | CART_ATMOS | CART_DRONEPHONE
access = CART_MANIFEST | CART_STATUS_DISPLAY | CART_ENGINE | CART_ATMOS | CART_DRONEPHONE | CART_DRONEACCESS
bot_access_flags = FLOOR_BOT | FIRE_BOT
/obj/item/cartridge/cmo
+2 -1
View File
@@ -90,7 +90,8 @@
"skills" = 'icons/pda_icons/pda_skills.png',
"status" = 'icons/pda_icons/pda_status.png',
"dronephone" = 'icons/pda_icons/pda_dronephone.png',
"emoji" = 'icons/pda_icons/pda_emoji.png'
"emoji" = 'icons/pda_icons/pda_emoji.png',
"droneblacklist" = 'icons/pda_icons/pda_droneblacklist.png',
)
/datum/asset/spritesheet/simple/paper
+65 -52
View File
@@ -77,7 +77,7 @@
var/locked = TRUE
var/aidisabled = 0
var/shorted = 0
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
var/buildstage = AIRALARM_BUILD_COMPLETE // 2 = complete, 1 = no wires, 0 = circuit gone
var/frequency = FREQ_ATMOS_CONTROL
var/alarm_frequency = FREQ_ATMOS_ALARMS
@@ -219,7 +219,7 @@
setDir(ndir)
if(nbuild)
buildstage = 0
buildstage = AIRALARM_BUILD_NO_CIRCUIT
panel_open = TRUE
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
pixel_y = (dir & 3)? (dir == 1 ? -24 : 24) : 0
@@ -244,11 +244,11 @@
/obj/machinery/airalarm/examine(mob/user)
. = ..()
switch(buildstage)
if(0)
if(AIRALARM_BUILD_NO_CIRCUIT)
. += "<span class='notice'>It is missing air alarm electronics.</span>"
if(1)
if(AIRALARM_BUILD_NO_WIRES)
. += "<span class='notice'>It is missing wiring.</span>"
if(2)
if(AIRALARM_BUILD_COMPLETE)
. += "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"] the interface.</span>"
/obj/machinery/airalarm/ui_status(mob/user)
@@ -391,7 +391,7 @@
/obj/machinery/airalarm/ui_act(action, params)
. = ..()
if(. || buildstage != 2)
if(. || buildstage != AIRALARM_BUILD_COMPLETE)
return
if((locked && !usr.has_unlimited_silicon_privilege) || (usr.has_unlimited_silicon_privilege && aidisabled))
return
@@ -644,11 +644,11 @@
/obj/machinery/airalarm/update_icon_state()
if(panel_open)
switch(buildstage)
if(2)
if(AIRALARM_BUILD_COMPLETE)
icon_state = "alarmx"
if(1)
if(AIRALARM_BUILD_NO_WIRES)
icon_state = "alarm_b2"
if(0)
if(AIRALARM_BUILD_NO_CIRCUIT)
icon_state = "alarm_b1"
return ..()
@@ -737,42 +737,62 @@
update_appearance()
/obj/machinery/airalarm/crowbar_act(mob/living/user, obj/item/tool)
if(buildstage != AIRALARM_BUILD_NO_WIRES)
return
user.visible_message("<span class='notice'>[user.name] removes the electronics from [name].</span>", \
"<span class='notice'>You start prying out the circuit...</span>")
tool.play_tool_sound(src)
if (tool.use_tool(src, user, 20))
if (buildstage == AIRALARM_BUILD_NO_WIRES)
to_chat(user, "<span class='notice'>You remove the air alarm electronics.</span>")
new /obj/item/electronics/airalarm(drop_location())
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
buildstage = AIRALARM_BUILD_NO_CIRCUIT
update_appearance()
return TRUE
/obj/machinery/airalarm/screwdriver_act(mob/living/user, obj/item/tool)
if(buildstage != AIRALARM_BUILD_COMPLETE)
return
tool.play_tool_sound(src)
panel_open = !panel_open
to_chat(user, "<span class='notice'>The wires have been [panel_open ? "exposed" : "unexposed"].</span>")
update_appearance()
return TRUE
/obj/machinery/airalarm/wirecutter_act(mob/living/user, obj/item/tool)
if(!(buildstage == AIRALARM_BUILD_COMPLETE && panel_open && wires.is_all_cut()))
return
tool.play_tool_sound(src)
to_chat(user, "<span class='notice'>You cut the final wires.</span>")
var/obj/item/stack/cable_coil/cables = new(drop_location(), 5)
user.put_in_hands(cables)
buildstage = AIRALARM_BUILD_NO_WIRES
update_appearance()
return TRUE
/obj/machinery/airalarm/wrench_act(mob/living/user, obj/item/tool)
if(buildstage != AIRALARM_BUILD_NO_CIRCUIT)
return
to_chat(user, "<span class='notice'>You detach \the [src] from the wall.</span>")
tool.play_tool_sound(src)
var/obj/item/wallframe/airalarm/alarm_frame = new(drop_location())
user.put_in_hands(alarm_frame)
qdel(src)
return TRUE
/obj/machinery/airalarm/attackby(obj/item/W, mob/user, params)
update_last_used(user)
switch(buildstage)
if(2)
if(W.tool_behaviour == TOOL_WIRECUTTER && panel_open && wires.is_all_cut())
W.play_tool_sound(src)
to_chat(user, "<span class='notice'>You cut the final wires.</span>")
new /obj/item/stack/cable_coil(loc, 5)
buildstage = 1
update_appearance()
return
else if(W.tool_behaviour == TOOL_SCREWDRIVER) // Opening that Air Alarm up.
W.play_tool_sound(src)
panel_open = !panel_open
to_chat(user, "<span class='notice'>The wires have been [panel_open ? "exposed" : "unexposed"].</span>")
update_appearance()
return
else if(W.GetID())// trying to unlock the interface with an ID card
if(AIRALARM_BUILD_COMPLETE)
if(W.GetID())// trying to unlock the interface with an ID card
togglelock(user)
return
else if(panel_open && is_wire_tool(W))
wires.interact(user)
return
if(1)
if(W.tool_behaviour == TOOL_CROWBAR)
user.visible_message("<span class='notice'>[user.name] removes the electronics from [src.name].</span>", \
"<span class='notice'>You start prying out the circuit...</span>")
W.play_tool_sound(src)
if (W.use_tool(src, user, 20))
if (buildstage == 1)
to_chat(user, "<span class='notice'>You remove the air alarm electronics.</span>")
new /obj/item/electronics/airalarm( src.loc )
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, TRUE)
buildstage = 0
update_appearance()
return
if(AIRALARM_BUILD_NO_WIRES)
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/cable = W
if(cable.get_amount() < 5)
@@ -781,7 +801,7 @@
user.visible_message("<span class='notice'>[user.name] wires the air alarm.</span>", \
"<span class='notice'>You start wiring the air alarm...</span>")
if (do_after(user, 20, target = src))
if (cable.get_amount() >= 5 && buildstage == 1)
if (cable.get_amount() >= 5 && buildstage == AIRALARM_BUILD_NO_WIRES)
cable.use(5)
to_chat(user, "<span class='notice'>You wire the air alarm.</span>")
wires.repair()
@@ -790,14 +810,14 @@
mode = 1
shorted = 0
post_alert(0)
buildstage = 2
buildstage = AIRALARM_BUILD_COMPLETE
update_appearance()
return
if(0)
if(AIRALARM_BUILD_NO_CIRCUIT)
if(istype(W, /obj/item/electronics/airalarm))
if(user.temporarilyRemoveItemFromInventory(W))
to_chat(user, "<span class='notice'>You insert the circuit.</span>")
buildstage = 1
buildstage = AIRALARM_BUILD_NO_WIRES
update_appearance()
qdel(W)
return
@@ -808,21 +828,14 @@
return
user.visible_message("<span class='notice'>[user] fabricates a circuit and places it into [src].</span>", \
"<span class='notice'>You adapt an air alarm circuit and slot it into the assembly.</span>")
buildstage = 1
buildstage = AIRALARM_BUILD_NO_WIRES
update_appearance()
return
if(W.tool_behaviour == TOOL_WRENCH)
to_chat(user, "<span class='notice'>You detach \the [src] from the wall.</span>")
W.play_tool_sound(src)
new /obj/item/wallframe/airalarm( user.loc )
qdel(src)
return
return ..()
/obj/machinery/airalarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
if((buildstage == 0) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS))
if((buildstage == AIRALARM_BUILD_NO_CIRCUIT) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS))
return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1)
return FALSE
@@ -831,7 +844,7 @@
if(RCD_UPGRADE_SIMPLE_CIRCUITS)
user.visible_message("<span class='notice'>[user] fabricates a circuit and places it into [src].</span>", \
"<span class='notice'>You adapt an air alarm circuit and slot it into the assembly.</span>")
buildstage = 1
buildstage = AIRALARM_BUILD_NO_WIRES
update_appearance()
return TRUE
return FALSE
+1 -1
View File
@@ -88,7 +88,7 @@
if(!random || newname)
if(newname)
M.real_name = newname
else
else if(!M.unique_name)
M.real_name = mob_name ? mob_name : M.name
if(!mob_gender)
mob_gender = pick(MALE, FEMALE)
@@ -122,27 +122,35 @@
"<span class='notice'> - Interacting with living beings (communication, attacking, healing, etc.)</span>\n"+\
"<span class='notice'> - Interacting with non-living beings (dragging bodies, looting bodies, etc.)</span>\n"+\
"<span class='warning'>These rules are at admin discretion and will be heavily enforced.</span>\n"+\
"<span class='warning'><u>If you do not have the regular drone laws, follow your laws to the best of your ability.</u></span>"
"<span class='warning'><u>If you do not have the regular drone laws, follow your laws to the best of your ability.</u></span>\n"+\
"<span class='notice'>Prefix your message with :b to speak in Drone Chat.</span>\n"
/// blacklisted drone areas, direct
var/list/drone_area_blacklist_flat = list(/area/engineering/atmos, /area/engineering/atmospherics_engine)
/// blacklisted drone areas, recursive/includes descendants
var/list/drone_area_blacklist_recursive = list(/area/engineering/supermatter)
/// whitelisted drone machines, direct
var/list/drone_machinery_whitelist_flat
/// whitelisted drone machines, recursive/includes descendants
var/list/drone_machinery_whitelist_recursive = list(
/obj/machinery/atmospherics,
/obj/machinery/autolathe,
/obj/machinery/cell_charger,
/obj/machinery/disposal,
/obj/machinery/drone_dispenser,
/obj/machinery/light,
/obj/machinery/pipedispenser,
/obj/machinery/recharger,
/obj/machinery/rnd/production,
/// blacklisted drone machines, direct
var/list/drone_machinery_blacklist_flat
/// blacklisted drone machines, recursive/includes descendants
var/list/drone_machinery_blacklist_recursive = list(
/obj/machinery/airalarm,
/obj/machinery/computer,
/obj/machinery/modular_computer,
)
/// cancels out blacklisted machines, direct
var/list/drone_machinery_whitelist_flat
/// cancels out blacklisted machines, recursive/includes descendants
var/list/drone_machinery_whitelist_recursive = list(
/obj/machinery/computer/arcade,
/obj/machinery/computer/monitor,
/obj/machinery/computer/pod,
/obj/machinery/computer/station_alert,
/obj/machinery/computer/teleporter,
)
/// blacklisted drone machine typecache, compiled from [var/drone_machinery_blacklist_flat], [var/list/drone_machinery_blacklist_recursive], negated by their whitelist counterparts
var/list/drone_machinery_blacklist_compiled
/// whitelisted drone items, direct
var/list/drone_item_whitelist_flat = list(
/obj/item/chisel,
/obj/item/crowbar/drone,
/obj/item/screwdriver/drone,
/obj/item/wrench/drone,
@@ -166,6 +174,7 @@
/obj/item/stack/tile,
/obj/item/stock_parts,
/obj/item/toner,
/obj/item/wallframe,
/obj/item/clothing/head,
/obj/item/clothing/mask,
)
@@ -360,26 +369,47 @@
if(cleared)
to_chat(src, "--- [class] alarm in [A.name] has been cleared.")
/mob/living/simple_animal/drone/proc/blacklist_on_try_use_machine(datum/source, obj/machinery/machine)
SIGNAL_HANDLER
if(GLOB.drone_machine_blacklist_enabled && is_type_in_typecache(machine, drone_machinery_blacklist_compiled))
to_chat(src, "<span class='warning'>Using [machine] could break your laws.</span>")
return COMPONENT_CANT_USE_MACHINE_INTERACT | COMPONENT_CANT_USE_MACHINE_TOOLS
/mob/living/simple_animal/drone/proc/blacklist_on_try_wires_interact(datum/source, atom/machine)
SIGNAL_HANDLER
if(GLOB.drone_machine_blacklist_enabled && is_type_in_typecache(machine, drone_machinery_blacklist_compiled))
to_chat(src, "<span class='warning'>Using [machine] could break your laws.</span>")
return COMPONENT_CANT_INTERACT_WIRES
/mob/living/simple_animal/drone/proc/set_shy(new_shy)
shy = new_shy
shy_update()
/mob/living/simple_animal/drone/proc/shy_update()
var/list/drone_bad_areas = make_associative(drone_area_blacklist_flat) + typecacheof(drone_area_blacklist_recursive)
var/list/drone_good_machines = make_associative(drone_machinery_whitelist_flat) + typecacheof(drone_machinery_whitelist_recursive)
var/list/drone_good_items = make_associative(drone_item_whitelist_flat) + typecacheof(drone_item_whitelist_recursive)
var/list/drone_bad_machinery = make_associative(drone_machinery_blacklist_flat) + typecacheof(drone_machinery_blacklist_recursive)
var/list/drone_good_machinery = LAZYCOPY(drone_machinery_whitelist_flat) + typecacheof(drone_machinery_whitelist_recursive) // not a valid typecache, only intended for negation against drone_bad_machinery
drone_machinery_blacklist_compiled = drone_bad_machinery - drone_good_machinery
var/static/list/not_shy_of = typecacheof(list(/mob/living/simple_animal/drone, /mob/living/simple_animal/bot))
if(shy)
ADD_TRAIT(src, TRAIT_PACIFISM, DRONE_SHY_TRAIT)
LoadComponent(/datum/component/shy, typecacheof(/mob/living/simple_animal/drone), 4, "Your laws prevent this action near %TARGET.", TRUE)
LoadComponent(/datum/component/shy, not_shy_of, 4, "Your laws prevent this action near %TARGET.", TRUE)
LoadComponent(/datum/component/shy_in_room, drone_bad_areas, "Touching anything in %ROOM could break your laws.")
LoadComponent(/datum/component/technointrovert, drone_good_machines, "Using %TARGET could break your laws.")
LoadComponent(/datum/component/technoshy, 5 MINUTES, "%TARGET was touched by a being recently, using it could break your laws.")
LoadComponent(/datum/component/itempicky, drone_good_items, "Using %TARGET could break your laws.")
RegisterSignal(src, COMSIG_TRY_USE_MACHINE, .proc/blacklist_on_try_use_machine)
RegisterSignal(src, COMSIG_TRY_WIRES_INTERACT, .proc/blacklist_on_try_wires_interact)
else
REMOVE_TRAIT(src, TRAIT_PACIFISM, DRONE_SHY_TRAIT)
qdel(GetComponent(/datum/component/shy))
qdel(GetComponent(/datum/component/shy_in_room))
qdel(GetComponent(/datum/component/technointrovert))
qdel(GetComponent(/datum/component/technoshy))
qdel(GetComponent(/datum/component/itempicky))
UnregisterSignal(src, list(COMSIG_TRY_USE_MACHINE, COMSIG_TRY_WIRES_INTERACT))
/mob/living/simple_animal/drone/handle_temperature_damage()
return
@@ -42,6 +42,10 @@
return ..()
var/required_role = CONFIG_GET(string/drone_required_role)
var/required_playtime = CONFIG_GET(number/drone_role_playtime) * 60
if(CONFIG_GET(flag/use_exp_restrictions_admin_bypass) && check_rights_for(user.client, R_ADMIN))
return ..()
if(user?.client?.prefs.db_flags & DB_FLAG_EXEMPT)
return ..()
if(required_playtime <= 0)
return ..()
var/current_playtime = user_client?.calc_exp_type(required_role)
Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

+2
View File
@@ -48,6 +48,7 @@
#include "code\__DEFINES\construction.dm"
#include "code\__DEFINES\cooldowns.dm"
#include "code\__DEFINES\cult.dm"
#include "code\__DEFINES\devices.dm"
#include "code\__DEFINES\diseases.dm"
#include "code\__DEFINES\DNA.dm"
#include "code\__DEFINES\do_afters.dm"
@@ -556,6 +557,7 @@
#include "code\datums\components\tackle.dm"
#include "code\datums\components\tactical.dm"
#include "code\datums\components\technointrovert.dm"
#include "code\datums\components\technoshy.dm"
#include "code\datums\components\tether.dm"
#include "code\datums\components\thermite.dm"
#include "code\datums\components\twohanded.dm"