diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index 1880fcdf14d..244ef15c3f1 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -39,8 +39,12 @@ ///from mind/transfer_to. Sent to the receiving mob. #define COMSIG_MOB_MIND_TRANSFERRED_INTO "mob_mind_transferred_into" -///from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj -#define COMSIG_MOB_ALLOWED "mob_allowed" +///from base of obj/allowed(mob/M): (/obj) returns ACCESS_ALLOWED if mob has id access to the obj +#define COMSIG_MOB_TRIED_ACCESS "tried_access" + #define ACCESS_ALLOWED (1<<0) + #define ACCESS_DISALLOWED (1<<1) + #define LOCKED_ATOM_INCOMPATIBLE (1<<2) + ///from base of mob/anti_magic_check(): (mob/user, magic, holy, tinfoil, chargecost, self, protection_sources) #define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" #define COMPONENT_BLOCK_MAGIC (1<<0) diff --git a/code/datums/components/simple_access.dm b/code/datums/components/simple_access.dm new file mode 100644 index 00000000000..fd82d723327 --- /dev/null +++ b/code/datums/components/simple_access.dm @@ -0,0 +1,33 @@ +///This component allows us to give a mob access without giving them an ID card. +/datum/component/simple_access + dupe_mode = COMPONENT_DUPE_ALLOWED + ///list of accesses we are allowed to access via this component + var/list/access + +/datum/component/simple_access/Initialize(list/new_access, atom/donor_atom) + . = ..() + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + access = new_access + RegisterSignal(parent, COMSIG_MOB_TRIED_ACCESS, .proc/on_tried_access) + if(!donor_atom) + return + if(istype(donor_atom, /obj/item/organ)) + RegisterSignal(donor_atom, COMSIG_ORGAN_REMOVED, .proc/on_donor_removed) + else if(istype(donor_atom, /obj/item/implant)) + RegisterSignal(donor_atom, COMSIG_IMPLANT_REMOVED, .proc/on_donor_removed) + RegisterSignal(donor_atom, COMSIG_PARENT_QDELETING, .proc/on_donor_removed) + +/datum/component/simple_access/proc/on_tried_access(datum/source, atom/locked_thing) + SIGNAL_HANDLER + if(!isobj(locked_thing)) + return LOCKED_ATOM_INCOMPATIBLE + var/obj/locked_object = locked_thing + if(locked_object.check_access_list(access)) + return ACCESS_ALLOWED + else + return ACCESS_DISALLOWED + +/datum/component/simple_access/proc/on_donor_removed(datum/source) + SIGNAL_HANDLER + qdel(src) diff --git a/code/modules/antagonists/abductor/equipment/glands/access.dm b/code/modules/antagonists/abductor/equipment/glands/access.dm index bddea3ad159..420d8ed4121 100644 --- a/code/modules/antagonists/abductor/equipment/glands/access.dm +++ b/code/modules/antagonists/abductor/equipment/glands/access.dm @@ -9,12 +9,4 @@ /obj/item/organ/heart/gland/access/activate() to_chat(owner, span_notice("You feel like a VIP for some reason.")) - RegisterSignal(owner, COMSIG_MOB_ALLOWED, .proc/free_access) - -/obj/item/organ/heart/gland/access/proc/free_access(datum/source, obj/O) - SIGNAL_HANDLER - return TRUE - -/obj/item/organ/heart/gland/access/Remove(mob/living/carbon/M, special = 0) - UnregisterSignal(owner, COMSIG_MOB_ALLOWED) - ..() + owner.AddComponent(/datum/component/simple_access, SSid_access.get_region_access_list(list(REGION_ALL_GLOBAL)), src) diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm index b5fa6c51860..1bf9516c4b5 100644 --- a/code/modules/jobs/access.dm +++ b/code/modules/jobs/access.dm @@ -13,21 +13,21 @@ if(isAdminGhostAI(accessor)) //Access can't stop the abuse return TRUE - else if(istype(accessor) && SEND_SIGNAL(accessor, COMSIG_MOB_ALLOWED, src)) + //If the mob has the simple_access component with the requried access, we let them in. + else if(SEND_SIGNAL(accessor, COMSIG_MOB_TRIED_ACCESS, src) & ACCESS_ALLOWED) return TRUE + //If the mob is holding a valid ID, we let them in. get_active_held_item() is on the mob level, so no need to copypasta everywhere. + else if(check_access(accessor.get_active_held_item())) + return TRUE + //if they are wearing a card that has access, that works else if(ishuman(accessor)) var/mob/living/carbon/human/human_accessor = accessor - //if they are holding or wearing a card that has access, that works - if(check_access(human_accessor.get_active_held_item()) || src.check_access(human_accessor.wear_id)) - return TRUE - else if(isalienadult(accessor)) - var/mob/living/carbon/george = accessor - //they can only hold things :( - if(check_access(george.get_active_held_item())) + if(check_access(human_accessor.wear_id)) return TRUE + //if they have a hacky abstract animal ID with the required access, let them in i guess... else if(isanimal(accessor)) var/mob/living/simple_animal/animal = accessor - if(check_access(animal.get_active_held_item()) || check_access(animal.access_card)) + if(check_access(animal.access_card)) return TRUE return FALSE diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index c2080886ad7..fe43c08692f 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -686,58 +686,62 @@ var/being_used = FALSE var/sentience_type = SENTIENCE_ORGANIC -/obj/item/slimepotion/slime/sentience/attack(mob/living/M, mob/user) - if(being_used || !ismob(M)) +/obj/item/slimepotion/slime/sentience/attack(mob/living/dumb_mob, mob/user) + if(being_used || !ismob(dumb_mob)) return - if(!isanimal(M) || M.ckey) //only works on animals that aren't player controlled - to_chat(user, span_warning("[M] is already too intelligent for this to work!")) + if((!isanimal(dumb_mob) && !isbasicmob(dumb_mob)) || dumb_mob.ckey) //only works on animals that aren't player controlled + to_chat(user, span_warning("[dumb_mob] is already too intelligent for this to work!")) return - if(M.stat) - to_chat(user, span_warning("[M] is dead!")) - return - var/mob/living/simple_animal/SM = M - if(SM.sentience_type != sentience_type) - to_chat(user, span_warning("[src] won't work on [SM].")) + if(dumb_mob.stat) + to_chat(user, span_warning("[dumb_mob] is dead!")) return + if(isanimal(dumb_mob)) + var/mob/living/simple_animal/dumb_animal = dumb_mob + if(dumb_animal.sentience_type != sentience_type) + to_chat(user, span_warning("[src] won't work on [dumb_animal].")) + return + else if(isbasicmob(dumb_mob)) //duplicate shit code until all simple animasls are made into basic mobs. sentience_type is not on living, but it duplicated on basic and animal + var/mob/living/basic/basic_dumb_bitch = dumb_mob + if(basic_dumb_bitch.sentience_type != sentience_type) + to_chat(user, span_warning("[src] won't work on [basic_dumb_bitch].")) + return - to_chat(user, span_notice("You offer [src] to [SM]...")) + to_chat(user, span_notice("You offer [src] to [dumb_mob]...")) being_used = TRUE - var/list/candidates = poll_candidates_for_mob("Do you want to play as [SM.name]?", ROLE_SENTIENCE, ROLE_SENTIENCE, 5 SECONDS, SM, POLL_IGNORE_SENTIENCE_POTION) // see poll_ignore.dm + var/list/candidates = poll_candidates_for_mob("Do you want to play as [dumb_mob.name]?", ROLE_SENTIENCE, ROLE_SENTIENCE, 5 SECONDS, dumb_mob, POLL_IGNORE_SENTIENCE_POTION) // see poll_ignore.dm if(LAZYLEN(candidates)) var/mob/dead/observer/C = pick(candidates) - SM.key = C.key - SM.mind.enslave_mind_to_creator(user) - SEND_SIGNAL(SM, COMSIG_SIMPLEMOB_SENTIENCEPOTION, user) - SM.sentience_act() - to_chat(SM, span_warning("All at once it makes sense: you know what you are and who you are! Self awareness is yours!")) - to_chat(SM, span_userdanger("You are grateful to be self aware and owe [user.real_name] a great debt. Serve [user.real_name], and assist [user.p_them()] in completing [user.p_their()] goals at any cost.")) - if(SM.flags_1 & HOLOGRAM_1) //Check to see if it's a holodeck creature - to_chat(SM, span_userdanger("You also become depressingly aware that you are not a real creature, but instead a holoform. Your existence is limited to the parameters of the holodeck.")) - to_chat(user, span_notice("[SM] accepts [src] and suddenly becomes attentive and aware. It worked!")) - SM.copy_languages(user) - after_success(user, SM) + dumb_mob.key = C.key + dumb_mob.mind.enslave_mind_to_creator(user) + SEND_SIGNAL(dumb_mob, COMSIG_SIMPLEMOB_SENTIENCEPOTION, user) + if(isanimal(dumb_mob)) + var/mob/living/simple_animal/smart_animal = dumb_mob + smart_animal.sentience_act() + to_chat(dumb_mob, span_warning("All at once it makes sense: you know what you are and who you are! Self awareness is yours!")) + to_chat(dumb_mob, span_userdanger("You are grateful to be self aware and owe [user.real_name] a great debt. Serve [user.real_name], and assist [user.p_them()] in completing [user.p_their()] goals at any cost.")) + if(dumb_mob.flags_1 & HOLOGRAM_1) //Check to see if it's a holodeck creature + to_chat(dumb_mob, span_userdanger("You also become depressingly aware that you are not a real creature, but instead a holoform. Your existence is limited to the parameters of the holodeck.")) + to_chat(user, span_notice("[dumb_mob] accepts [src] and suddenly becomes attentive and aware. It worked!")) + dumb_mob.copy_languages(user) + after_success(user, dumb_mob) qdel(src) else - to_chat(user, span_notice("[SM] looks interested for a moment, but then looks back down. Maybe you should try again later.")) + to_chat(user, span_notice("[dumb_mob] looks interested for a moment, but then looks back down. Maybe you should try again later.")) being_used = FALSE ..() -/obj/item/slimepotion/slime/sentience/proc/after_success(mob/living/user, mob/living/simple_animal/SM) +/obj/item/slimepotion/slime/sentience/proc/after_success(mob/living/user, mob/living/smart_mob) return /obj/item/slimepotion/slime/sentience/nuclear name = "syndicate intelligence potion" desc = "A miraculous chemical mix that grants human like intelligence to living beings. It has been modified with Syndicate technology to also grant an internal radio implant to the target and authenticate with identification systems." -/obj/item/slimepotion/slime/sentience/nuclear/after_success(mob/living/user, mob/living/simple_animal/SM) +/obj/item/slimepotion/slime/sentience/nuclear/after_success(mob/living/user, mob/living/smart_mob) var/obj/item/implant/radio/syndicate/imp = new(src) - imp.implant(SM, user) - - // Ugly as sin. Simble mob accesses are for another time. - SM.access_card = new /obj/item/card/id/advanced/chameleon(SM) - SSid_access.apply_trim_to_card(SM, /datum/id_trim/chameleon) - ADD_TRAIT(SM.access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + imp.implant(smart_mob, user) + smart_mob.AddComponent(/datum/component/simple_access, list(ACCESS_SYNDICATE, ACCESS_MAINT_TUNNELS)) /obj/item/slimepotion/transference name = "consciousness transference potion" @@ -747,45 +751,53 @@ var/prompted = 0 var/animal_type = SENTIENCE_ORGANIC -/obj/item/slimepotion/transference/afterattack(mob/living/M, mob/living/user, proximity) +/obj/item/slimepotion/transference/afterattack(mob/living/switchy_mob, mob/living/user, proximity) if(!proximity) return - if(prompted || !ismob(M)) + if(prompted || !ismob(switchy_mob)) return - if(!isanimal(M) || M.ckey) //much like sentience, these will not work on something that is already player controlled - to_chat(user, span_warning("[M] already has a higher consciousness!")) + if(!(isanimal(switchy_mob) || isbasicmob(switchy_mob))|| switchy_mob.ckey) //much like sentience, these will not work on something that is already player controlled + to_chat(user, span_warning("[switchy_mob] already has a higher consciousness!")) return ..() - if(M.stat) - to_chat(user, span_warning("[M] is dead!")) + if(switchy_mob.stat) + to_chat(user, span_warning("[switchy_mob] is dead!")) return ..() - var/mob/living/simple_animal/SM = M - if(SM.sentience_type != animal_type) - to_chat(user, span_warning("You cannot transfer your consciousness to [SM].") ) - return ..() - var/jb = is_banned_from(user.ckey, ROLE_MIND_TRANSFER) - if(QDELETED(src) || QDELETED(M) || QDELETED(user)) + if(isanimal(switchy_mob)) + var/mob/living/simple_animal/switchy_animal= switchy_mob + if(switchy_animal.sentience_type != animal_type) + to_chat(user, span_warning("You cannot transfer your consciousness to [switchy_animal].") ) + return ..() + else //ugly code duplication, but necccesary as sentience_type is implemented twice. + var/mob/living/basic/basic_mob = switchy_mob + if(basic_mob.sentience_type != animal_type) + to_chat(user, span_warning("You cannot transfer your consciousness to [basic_mob].") ) + return ..() + + var/job_banned = is_banned_from(user.ckey, ROLE_MIND_TRANSFER) + if(QDELETED(src) || QDELETED(switchy_mob) || QDELETED(user)) return - if(jb) + if(job_banned) to_chat(user, span_warning("Your mind goes blank as you attempt to use the potion.")) return prompted = 1 - if(tgui_alert(usr,"This will permanently transfer your consciousness to [SM]. Are you sure you want to do this?",,list("Yes","No"))=="No") + if(tgui_alert(usr,"This will permanently transfer your consciousness to [switchy_mob]. Are you sure you want to do this?",,list("Yes","No"))=="No") prompted = 0 return - to_chat(user, span_notice("You drink the potion then place your hands on [SM]...")) + to_chat(user, span_notice("You drink the potion then place your hands on [switchy_mob]...")) - - user.mind.transfer_to(SM) - SM.faction = user.faction.Copy() - SM.sentience_act() //Same deal here as with sentience + user.mind.transfer_to(switchy_mob) + switchy_mob.faction = user.faction.Copy() user.death() - to_chat(SM, span_notice("In a quick flash, you feel your consciousness flow into [SM]!")) - to_chat(SM, span_warning("You are now [SM]. Your allegiances, alliances, and role is still the same as it was prior to consciousness transfer!")) - SM.name = "[user.real_name]" + to_chat(switchy_mob, span_notice("In a quick flash, you feel your consciousness flow into [switchy_mob]!")) + to_chat(switchy_mob, span_warning("You are now [switchy_mob]. Your allegiances, alliances, and role is still the same as it was prior to consciousness transfer!")) + switchy_mob.name = "[user.real_name]" qdel(src) + if(isanimal(switchy_mob)) + var/mob/living/simple_animal/switchy_animal= switchy_mob + switchy_animal.sentience_act() /obj/item/slimepotion/slime/steroid name = "slime steroid" diff --git a/tgstation.dme b/tgstation.dme index 6ff390ad30b..8c34dda1472 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -702,6 +702,7 @@ #include "code\datums\components\shrink.dm" #include "code\datums\components\shy.dm" #include "code\datums\components\shy_in_room.dm" +#include "code\datums\components\simple_access.dm" #include "code\datums\components\singularity.dm" #include "code\datums\components\sitcomlaughter.dm" #include "code\datums\components\sizzle.dm"