diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 8d05c06977..dd498017d3 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -122,6 +122,9 @@ #define TRAIT_STRONG_GRABBER "strong_grabber" #define TRAIT_CALCIUM_HEALER "calcium_healer" #define TRAIT_CAPTAIN_METABOLISM "captain-metabolism" +#define TRAIT_ABDUCTOR_TRAINING "abductor-training" +#define TRAIT_ABDUCTOR_SCIENTIST_TRAINING "abductor-scientist-training" +#define TRAIT_SURGEON "surgeon" //non-mob traits #define TRAIT_PARALYSIS "paralysis" //Used for limb-based paralysis, where replacing the limb will fix it @@ -187,6 +190,7 @@ #define STASIS_MUTE "stasis" #define GENETICS_SPELL "genetics_spell" #define EYES_COVERED "eyes_covered" +<<<<<<< HEAD #define CULT_TRAIT "cult" #define CLOWN_NUKE_TRAIT "clown-nuke" #define STICKY_MOUSTACHE_TRAIT "sticky-moustache" @@ -208,3 +212,4 @@ #define LOCKED_HELMET_TRAIT "locked-helmet" #define NINJA_SUIT_TRAIT "ninja-suit" #define ANTI_DROP_IMPLANT_TRAIT "anti-drop-implant" +#define ABDUCTOR_ANTAGONIST "abductor-antagonist" \ No newline at end of file diff --git a/code/datums/traits.dm b/code/datums/traits.dm new file mode 100644 index 0000000000..15715c3c88 --- /dev/null +++ b/code/datums/traits.dm @@ -0,0 +1,75 @@ +/datum/proc/add_trait(trait, source) + LAZYINITLIST(status_traits) + + if(!status_traits[trait]) + status_traits[trait] = list(source) + else + status_traits[trait] |= list(source) + + +/datum/proc/remove_trait(trait, list/sources, force) + if(!status_traits) + return //nothing to remove + + if(!status_traits[trait]) + return + + if(locate(ROUNDSTART_TRAIT) in status_traits[trait] && !force) //mob traits applied through roundstart cannot normally be removed + return + + if(!sources) // No defined source cures the trait entirely. + status_traits -= trait + return + + if(!islist(sources)) + sources = list(sources) + + if(LAZYLEN(sources)) + for(var/S in sources) + if(S in status_traits[trait]) + status_traits[trait] -= S + else + status_traits[trait] = list() + + if(!LAZYLEN(status_traits[trait])) + status_traits -= trait + +/datum/proc/has_trait(trait, list/sources) + if(!status_traits) + return FALSE //well of course it doesn't have the trait + + if(!status_traits[trait]) + return FALSE + + . = FALSE + + if(sources && !islist(sources)) + sources = list(sources) + if(LAZYLEN(sources)) + for(var/S in sources) + if(S in status_traits[trait]) + return TRUE + else if(LAZYLEN(status_traits[trait])) + return TRUE + +/datum/proc/remove_all_traits(remove_species_traits = FALSE, remove_organ_traits = FALSE, remove_quirks = FALSE) + if(!status_traits) + return //nothing to remove + + var/list/blacklisted_sources = list() + if(!remove_species_traits) + blacklisted_sources += SPECIES_TRAIT + if(!remove_organ_traits) + blacklisted_sources += ORGAN_TRAIT + if(!remove_quirks) + blacklisted_sources += ROUNDSTART_TRAIT + + for(var/kebab in status_traits) + var/skip + for(var/S in blacklisted_sources) + if(S in status_traits[kebab]) + skip = TRUE + break + if(!skip) + remove_trait(kebab, null, TRUE) + CHECK_TICK diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm index 0fca957ffe..c13106ce02 100644 --- a/code/modules/antagonists/abductor/abductor.dm +++ b/code/modules/antagonists/abductor/abductor.dm @@ -44,6 +44,7 @@ owner.assigned_role = "[name] [sub_role]" owner.objectives += team.objectives finalize_abductor() + owner.add_trait(TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST) return ..() /datum/antagonist/abductor/on_removal() @@ -51,6 +52,7 @@ if(owner.current) to_chat(owner.current,"You are no longer the [owner.special_role]!") owner.special_role = null + owner.remove_trait(TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST) return ..() /datum/antagonist/abductor/greet() @@ -75,11 +77,15 @@ update_abductor_icons_added(owner,"abductor") -/datum/antagonist/abductor/scientist/finalize_abductor() - ..() - var/mob/living/carbon/human/H = owner.current - var/datum/species/abductor/A = H.dna.species - A.scientist = TRUE +/datum/antagonist/abductor/scientist/on_gain() + owner.add_trait(TRAIT_ABDUCTOR_SCIENTIST_TRAINING, ABDUCTOR_ANTAGONIST) + owner.add_trait(TRAIT_SURGEON, ABDUCTOR_ANTAGONIST) + . = ..() + +/datum/antagonist/abductor/scientist/on_removal() + owner.remove_trait(TRAIT_ABDUCTOR_SCIENTIST_TRAINING, ABDUCTOR_ANTAGONIST) + owner.remove_trait(TRAIT_SURGEON, ABDUCTOR_ANTAGONIST) + . = ..() /datum/antagonist/abductor/admin_add(datum/mind/new_owner,mob/admin) var/list/current_teams = list() @@ -214,4 +220,4 @@ /datum/antagonist/proc/update_abductor_icons_removed(datum/mind/alien_mind) var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_ABDUCTOR] hud.leave_hud(alien_mind.current) - set_antag_hud(alien_mind.current, null) \ No newline at end of file + set_antag_hud(alien_mind.current, null) diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm index 1573204d88..9072e1b263 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm @@ -132,22 +132,24 @@ /obj/item/abductor icon = 'icons/obj/abductor.dmi' -/obj/item/abductor/proc/AbductorCheck(user) - if(isabductor(user)) +/obj/item/abductor/proc/AbductorCheck(mob/user) + if(user.has_trait(TRAIT_ABDUCTOR_TRAINING)) return TRUE to_chat(user, "You can't figure how this works!") return FALSE -/obj/item/abductor/proc/ScientistCheck(user) - if(!AbductorCheck(user)) - return FALSE +/obj/item/abductor/proc/ScientistCheck(mob/user) + var/training = user.has_trait(TRAIT_ABDUCTOR_TRAINING) + var/sci_training = user.has_trait(TRAIT_ABDUCTOR_SCIENTIST_TRAINING) - var/mob/living/carbon/human/H = user - var/datum/species/abductor/S = H.dna.species - if(S.scientist) - return TRUE - to_chat(user, "You're not trained to use this!") - return FALSE + if(training && !sci_training) + to_chat(user, "You're not trained to use this!") + . = FALSE + else if(!training && !sci_training) + to_chat(user, "You can't figure how this works!") + . = FALSE + else + . = TRUE /obj/item/abductor/gizmo name = "science tool" @@ -683,7 +685,7 @@ Congratulations! You are now trained for invasive xenobiology research!"} desc = "Abduct with style - spiky style. Prevents digital tracking." icon_state = "alienhelmet" item_state = "alienhelmet" - blockTracking = 1 + blockTracking = TRUE flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR // Operating Table / Beds / Lockers diff --git a/code/modules/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm index 72edb18020..0b3f3ed595 100644 --- a/code/modules/antagonists/abductor/equipment/gland.dm +++ b/code/modules/antagonists/abductor/equipment/gland.dm @@ -5,6 +5,7 @@ icon_state = "gland" status = ORGAN_ROBOTIC beating = TRUE + var/true_name = "baseline placebo referencer" var/cooldown_low = 300 var/cooldown_high = 300 var/next_activation = 0 @@ -16,6 +17,11 @@ var/mind_control_duration = 1800 var/active_mind_control = FALSE +/obj/item/organ/heart/gland/examine(mob/user) + . = ..() + if(user.has_trait(TRAIT_ABDUCTOR_SCIENTIST_TRAINING) || isobserver(user)) + to_chat(user, "It is \a [true_name].") + /obj/item/organ/heart/gland/proc/ownerCheck() if(ishuman(owner)) return TRUE @@ -95,6 +101,7 @@ return /obj/item/organ/heart/gland/heals + true_name = "coherency harmonizer" cooldown_low = 200 cooldown_high = 400 uses = -1 @@ -109,6 +116,7 @@ owner.adjustOxyLoss(-20) /obj/item/organ/heart/gland/slime + true_name = "gastric animation galvanizer" cooldown_low = 600 cooldown_high = 1200 uses = -1 @@ -130,6 +138,7 @@ Slime.Leader = owner /obj/item/organ/heart/gland/mindshock + true_name = "neural crosstalk uninhibitor" cooldown_low = 400 cooldown_high = 700 uses = -1 @@ -156,6 +165,7 @@ H.hallucination += 60 /obj/item/organ/heart/gland/pop + true_name = "anthropmorphic translocator" cooldown_low = 900 cooldown_high = 1800 uses = -1 @@ -171,6 +181,7 @@ owner.set_species(species) /obj/item/organ/heart/gland/ventcrawling + true_name = "pliant cartilage enabler" cooldown_low = 1800 cooldown_high = 2400 uses = 1 @@ -183,6 +194,7 @@ owner.ventcrawler = VENTCRAWLER_ALWAYS /obj/item/organ/heart/gland/viral + true_name = "contamination incubator" cooldown_low = 1800 cooldown_high = 2400 uses = 1 @@ -217,6 +229,7 @@ return A /obj/item/organ/heart/gland/trauma + true_name = "white matter randomiser" cooldown_low = 800 cooldown_high = 1200 uses = 5 @@ -235,6 +248,7 @@ owner.gain_trauma_type(BRAIN_TRAUMA_MILD, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY)) /obj/item/organ/heart/gland/spiderman + true_name = "araneae cloister accelerator" cooldown_low = 450 cooldown_high = 900 uses = -1 @@ -249,6 +263,7 @@ S.directive = "Protect your nest inside [owner.real_name]." /obj/item/organ/heart/gland/egg + true_name = "roe/enzymatic synthesizer" cooldown_low = 300 cooldown_high = 400 uses = -1 @@ -264,6 +279,7 @@ new /obj/item/reagent_containers/food/snacks/egg/gland(T) /obj/item/organ/heart/gland/electric + true_name = "electron accumulator/discharger" cooldown_low = 800 cooldown_high = 1200 uses = -1 @@ -289,6 +305,7 @@ playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, 1) /obj/item/organ/heart/gland/chem + true_name = "intrinsic pharma-provider" cooldown_low = 50 cooldown_high = 50 uses = -1 @@ -315,6 +332,7 @@ ..() /obj/item/organ/heart/gland/plasma + true_name = "effluvium sanguine-synonym emitter" cooldown_low = 1200 cooldown_high = 1800 uses = -1 diff --git a/code/modules/antagonists/abductor/machinery/camera.dm b/code/modules/antagonists/abductor/machinery/camera.dm index 41cfa6a954..3c2ce5f840 100644 --- a/code/modules/antagonists/abductor/machinery/camera.dm +++ b/code/modules/antagonists/abductor/machinery/camera.dm @@ -55,8 +55,7 @@ actions += set_droppoint_action /obj/machinery/computer/camera_advanced/abductor/proc/IsScientist(mob/living/carbon/human/H) - var/datum/species/abductor/S = H.dna.species - return S.scientist + return H.has_trait(TRAIT_ABDUCTOR_SCIENTIST_TRAINING) /datum/action/innate/teleport_in name = "Send To" diff --git a/code/modules/antagonists/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm index 46d69ba9bb..0c74686a8f 100644 --- a/code/modules/antagonists/abductor/machinery/console.dm +++ b/code/modules/antagonists/abductor/machinery/console.dm @@ -28,7 +28,7 @@ . = ..() if(.) return - if(!isabductor(user)) + if(!user.has_trait(TRAIT_ABDUCTOR_TRAINING)) to_chat(user, "You start mashing alien buttons at random!") if(do_after(user,100, target = src)) TeleporterSend() diff --git a/code/modules/antagonists/abductor/machinery/pad.dm b/code/modules/antagonists/abductor/machinery/pad.dm index 1cb95fbf05..ab636f7d0e 100644 --- a/code/modules/antagonists/abductor/machinery/pad.dm +++ b/code/modules/antagonists/abductor/machinery/pad.dm @@ -53,4 +53,4 @@ . = ..() var/datum/effect_system/spark_spread/S = new S.set_up(10,0,loc) - S.start() \ No newline at end of file + S.start() diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm index ad1f5c9190..ffd129ebf7 100644 --- a/code/modules/mob/living/carbon/human/species_types/abductors.dm +++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm @@ -6,10 +6,6 @@ species_traits = list(NOBLOOD,NOEYES,NOGENITALS,NOAROUSAL) inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NOGUNS,TRAIT_NOHUNGER,TRAIT_NOBREATH) mutanttongue = /obj/item/organ/tongue/abductor - var/scientist = FALSE // vars to not pollute spieces list with castes - -/datum/species/abductor/copy_properties_from(datum/species/abductor/old_species) - scientist = old_species.scientist /datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..()