diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 613489323a..343b96c283 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -144,6 +144,7 @@ #define TRAIT_NOMARROW "nomarrow" // You don't make blood, with chemicals or nanites. #define TRAIT_NOPULSE "nopulse" // Your heart doesn't beat. #define TRAIT_EXEMPT_HEALTH_EVENTS "exempt-health-events" +#define TRAIT_NO_MIDROUND_ANTAG "no-midround-antag" //can't be turned into an antag by random events // mobility flag traits // IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it) @@ -227,6 +228,7 @@ // unique trait sources, still defines #define STATUE_MUTE "statue" #define CLONING_POD_TRAIT "cloning-pod" +#define VIRTUAL_REALITY_TRAIT "vr_trait" #define CHANGELING_DRAIN "drain" #define CHANGELING_HIVEMIND_MUTE "ling_mute" #define ABYSSAL_GAZE_BLIND "abyssal_gaze" diff --git a/code/datums/components/virtual_reality.dm b/code/datums/components/virtual_reality.dm index 63e4f4f092..9239d4c565 100644 --- a/code/datums/components/virtual_reality.dm +++ b/code/datums/components/virtual_reality.dm @@ -58,6 +58,7 @@ RegisterSignal(current_mind, COMSIG_PRE_MIND_TRANSFER, .proc/pre_player_transfer) if(mastermind?.current) mastermind.current.audiovisual_redirect = M + ADD_TRAIT(M, TRAIT_NO_MIDROUND_ANTAG, VIRTUAL_REALITY_TRAIT) /datum/component/virtual_reality/UnregisterFromParent() . = ..() @@ -69,6 +70,7 @@ current_mind = null if(mastermind?.current) mastermind.current.audiovisual_redirect = null + REMOVE_TRAIT(parent, TRAIT_NO_MIDROUND_ANTAG, VIRTUAL_REALITY_TRAIT) /** * Called when attempting to connect a mob to a virtual reality mob. @@ -235,7 +237,7 @@ qdel(src) /** - * Used for recursive virtual realities shenanigeans and should be called only through the above proc. + * Used for recursive virtual realities shenanigeans and should be called by the above proc. */ /datum/component/virtual_reality/proc/vr_in_a_vr(mob/player, deathcheck = FALSE, lethal_cleanup = FALSE) var/mob/M = parent diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 039fc102e8..638d8b53b6 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -43,7 +43,7 @@ if (!istype(M, required_type)) trimmed_list.Remove(M) continue - if (M.GetComponent(/datum/component/virtual_reality)) + if (HAS_TRAIT(M, TRAIT_NO_MIDROUND_ANTAG)) trimmed_list.Remove(M) continue if (!M.client) // Are they connected? diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 77416c45e5..711bc09069 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -195,9 +195,7 @@ return if(isgolem(user) && can_transfer) var/transfer_choice = alert("Transfer your soul to [src]? (Warning, your old body will die!)",,"Yes","No") - if(transfer_choice != "Yes") - return - if(QDELETED(src) || uses <= 0) + if(transfer_choice != "Yes" || QDELETED(src) || uses <= 0 || !user.canUseTopic(src, BE_CLOSE, NO_DEXTERY, NO_TK)) return log_game("[key_name(user)] golem-swapped into [src]") user.visible_message("A faint light leaves [user], moving to [src] and animating it!","You leave your old body behind, and transfer into [src]!") @@ -680,8 +678,9 @@ new_spawn.AddElement(/datum/element/dusts_on_catatonia) new_spawn.AddElement(/datum/element/dusts_on_leaving_area,list(A.type,/area/hilbertshotel)) ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT) - ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT) - ADD_TRAIT(new_spawn,TRAIT_PACIFISM,GHOSTROLE_TRAIT) + ADD_TRAIT(new_spawn, TRAIT_EXEMPT_HEALTH_EVENTS, GHOSTROLE_TRAIT) + ADD_TRAIT(new_spawn, TRAIT_NO_MIDROUND_ANTAG, GHOSTROLE_TRAIT) //The mob can't be made into a random antag, they are still elegible for ghost roles popups. + ADD_TRAIT(new_spawn, TRAIT_PACIFISM, GHOSTROLE_TRAIT) to_chat(new_spawn,"You may be sharing your cafe with some ninja-captured individuals, so make sure to only interact with the ghosts you hear as a ghost!") to_chat(new_spawn,"You can turn yourself into a ghost and freely reenter your body with the ghost action.") var/datum/action/ghost/G = new(new_spawn) diff --git a/code/modules/antagonists/blood_contract/blood_contract.dm b/code/modules/antagonists/blood_contract/blood_contract.dm index 4e7238647e..5d2fda08fc 100644 --- a/code/modules/antagonists/blood_contract/blood_contract.dm +++ b/code/modules/antagonists/blood_contract/blood_contract.dm @@ -27,7 +27,7 @@ INVOKE_ASYNC(B, /obj/effect/mine/pickup/bloodbath/.proc/mineEffect, H) //could use moving out from the mine for(var/mob/living/carbon/human/P in GLOB.player_list) - if(P == H) + if(P == H || HAS_TRAIT(P, TRAIT_NO_MIDROUND_ANTAG)) continue to_chat(P, "You have an overwhelming desire to kill [H]. [H.p_theyve(TRUE)] been marked red! Whoever [H.p_they()] [H.p_were()], friend or foe, go kill [H.p_them()]!") P.put_in_hands(new /obj/item/kitchen/knife/butcher(P), TRUE) diff --git a/code/modules/events/holiday/vday.dm b/code/modules/events/holiday/vday.dm index d3cbf03581..cb742ca27f 100644 --- a/code/modules/events/holiday/vday.dm +++ b/code/modules/events/holiday/vday.dm @@ -16,13 +16,14 @@ ..() for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) H.put_in_hands(new /obj/item/valentine) - var/obj/item/storage/backpack/b = locate() in H.contents - new /obj/item/reagent_containers/food/snacks/candyheart(b) - new /obj/item/storage/fancy/heart_box(b) + var/obj/item/storage/backpack/B = locate() in H.contents + if(B) + new /obj/item/reagent_containers/food/snacks/candyheart(B) + new /obj/item/storage/fancy/heart_box(B) var/list/valentines = list() for(var/mob/living/M in GLOB.player_list) - if(!M.stat && M.client && M.mind) + if(!M.stat && M.client && M.mind && !HAS_TRAIT(M, TRAIT_NO_MIDROUND_ANTAG)) valentines |= M diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index bf25bb9da8..a95c0e24ed 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -136,7 +136,7 @@ desc = "A device which causes kinetic accelerators to permanently gain damage against creature types killed with it." id = "bountymod" materials = list(/datum/material/iron = 4000, /datum/material/silver = 4000, /datum/material/gold = 4000, /datum/material/bluespace = 4000) - reagents_list = list("blood" = 40) + reagents_list = list(/datum/reagent/blood = 40) build_path = /obj/item/borg/upgrade/modkit/bounty //Spooky special loot diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index c569a2c59a..41f2c7142f 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -237,7 +237,7 @@ return /datum/reagent/blood/jellyblood if(dna?.species?.exotic_blood) return dna.species.exotic_blood - else if((NOBLOOD in dna.species.species_traits) || (HAS_TRAIT(src, TRAIT_NOCLONE))) + else if((dna && (NOBLOOD in dna.species.species_traits)) || HAS_TRAIT(src, TRAIT_NOCLONE)) return else return /datum/reagent/blood diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index 410ad05d93..8257238e9c 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -24,7 +24,7 @@ id = "spaceskeleton" limbs_id = "skeleton" blacklisted = 1 - inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER) + inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT, TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER) /datum/species/skeleton/space/check_roundstart_eligible() return FALSE \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/dueling.dm b/code/modules/projectiles/guns/energy/dueling.dm index 2f0aa00027..7fa81f513f 100644 --- a/code/modules/projectiles/guns/energy/dueling.dm +++ b/code/modules/projectiles/guns/energy/dueling.dm @@ -28,6 +28,16 @@ /datum/duel/New() id = next_id++ +/datum/duel/Destroy() + if(gun_A) + gun_A.duel = null + gun_A = null + if(gun_B) + gun_B.duel = null + gun_B = null + STOP_PROCESSING(SSobj, src) + . = ..() + /datum/duel/proc/try_begin() //Check if both guns are held and if so begin. var/mob/living/A = get_duelist(gun_A) @@ -45,13 +55,13 @@ message_duelists("Set your gun setting and move [required_distance] steps away from your opponent.") - START_PROCESSING(SSobj,src) + START_PROCESSING(SSobj, src) -/datum/duel/proc/get_duelist(obj/gun) - var/mob/living/G = gun.loc - if(!istype(G) || !G.is_holding(gun)) - return null - return G +/datum/duel/proc/get_duelist(obj/item/gun/energy/dueling/G) + var/mob/living/L = G.loc + if(!istype(L) || !L.is_holding(G)) + return + return L /datum/duel/proc/message_duelists(message) var/mob/living/LA = get_duelist(gun_A) @@ -66,7 +76,7 @@ /datum/duel/proc/end() message_duelists("Duel finished. Re-engaging safety.") - STOP_PROCESSING(SSobj,src) + STOP_PROCESSING(SSobj, src) state = DUEL_IDLE /datum/duel/process() @@ -129,10 +139,11 @@ return FALSE if(!isturf(A.loc) || !isturf(B.loc)) return FALSE - if(get_dist(A,B) != required_distance) + if(get_dist(A, B) != required_distance) return FALSE - for(var/turf/T in getline(get_turf(A),get_turf(B))) - if(is_blocked_turf(T,TRUE)) + for(var/i in getline(A.loc, B.loc)) + var/turf/T = i + if(is_blocked_turf(T, TRUE)) return FALSE return TRUE @@ -180,7 +191,6 @@ return "duel_red" /obj/item/gun/energy/dueling/attack_self(mob/living/user) - . = ..() if(duel.state == DUEL_IDLE) duel.try_begin() else @@ -205,12 +215,9 @@ add_overlay(setting_overlay) /obj/item/gun/energy/dueling/Destroy() - . = ..() - if(duel.gun_A == src) - duel.gun_A = null - if(duel.gun_B == src) - duel.gun_B = null - duel = null + if(duel) + qdel(duel) + return ..() /obj/item/gun/energy/dueling/can_trigger_gun(mob/living/user) . = ..() @@ -234,10 +241,8 @@ if(duel.state == DUEL_READY) duel.confirmations[src] = TRUE to_chat(user,"You confirm your readiness.") - return else if(!is_duelist(target)) //I kinda want to leave this out just to see someone shoot a bystander or missing. to_chat(user,"[src] safety system prevents shooting anyone but your designated opponent.") - return else duel.fired[src] = TRUE . = ..() diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 2d177318aa..2974df29a6 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -356,7 +356,6 @@ replace_beaker(user, B) to_chat(user, "You add [B] to [src].") updateUsrDialog() - update_icon() else if(user.a_intent != INTENT_HARM && !istype(I, /obj/item/card/emag)) to_chat(user, "You can't load [I] into [src]!") return ..() diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 0104bfba7b..be1b9460b0 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -55,6 +55,10 @@ Nothing else in the console has ID requirements. if (istype(ID, /datum/material)) var/datum/material/material = ID return material.name + + else if(GLOB.chemical_reagents_list[ID]) + var/datum/reagent/reagent = GLOB.chemical_reagents_list[ID] + return reagent.name return ID /obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any). diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index af825eb5ee..967f874a02 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -705,8 +705,9 @@ 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) - var/obj/item/implant/radio/syndicate/imp = new - imp.implant(SM, user) + if(SM.can_be_implanted()) + var/obj/item/implant/radio/syndicate/imp = new + imp.implant(SM, user) SM.access_card = new /obj/item/card/id/syndicate(SM) ADD_TRAIT(SM.access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) @@ -961,11 +962,12 @@ icon_state = "potgrey" /obj/item/slimepotion/slime/slimeradio/attack(mob/living/M, mob/user) - if(!ismob(M)) - return if(!isanimal(M)) to_chat(user, "[M] is too complex for the potion!") return + if(!M.can_be_implanted()) + to_chat(user, "[M] is incompatible with the potion!") + return if(M.stat) to_chat(user, "[M] is dead!") return diff --git a/code/modules/spells/spell_types/rightandwrong.dm b/code/modules/spells/spell_types/rightandwrong.dm index ea131fb996..2beaa97b3d 100644 --- a/code/modules/spells/spell_types/rightandwrong.dm +++ b/code/modules/spells/spell_types/rightandwrong.dm @@ -163,7 +163,7 @@ GLOBAL_VAR_INIT(summon_magic_triggered, FALSE) for(var/mob/living/carbon/human/H in GLOB.player_list) var/turf/T = get_turf(H) - if(T && is_away_level(T.z)) + if((T && is_away_level(T.z)) || HAS_TRAIT(H, TRAIT_NO_MIDROUND_ANTAG)) continue if(summon_type == SUMMON_MAGIC) give_magic(H)