From 3554c78e6bea03638f58ab16c90b39496a5388d5 Mon Sep 17 00:00:00 2001 From: Coul Date: Thu, 17 Oct 2019 20:48:25 -0400 Subject: [PATCH 01/59] make 513 compile --- code/__DEFINES/misc.dm | 2 +- code/__HELPERS/lists.dm | 5 ----- code/__HELPERS/unsorted.dm | 13 ++++++++++++- code/_onclick/hud/plane_master.dm | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 7dd5fc5a609..169a5129eee 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -384,7 +384,7 @@ #define EXPLOSIVE_WALL_GROUP_SYNDICATE_BASE "syndicate_base" // Filters -#define FILTER_AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, border=4, color="#04080FAA") +#define FILTER_AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, color="#04080FAA") //Fullscreen overlay resolution in tiles. #define FULLSCREEN_OVERLAY_RESOLUTION_X 15 diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index 49983658d48..5ffe891d95b 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -69,11 +69,6 @@ return list[index] return -/proc/islist(list/list) - if(istype(list)) - return 1 - return 0 - //Return either pick(list) or null if list is not of type /list or is empty /proc/safepick(list/list) if(!islist(list) || !list.len) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 82295bc9d80..f1611b38fd9 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -540,9 +540,20 @@ Returns 1 if the chain up to the area contains the given typepath /proc/between(var/low, var/middle, var/high) return max(min(middle, high), low) -proc/arctan(x) + + +#if DM_VERSION > 513 +#warn 513 is definitely stable now, remove this +#endif +#if DM_VERSION < 513 +/proc/arctan(x) var/y=arcsin(x/sqrt(1+x*x)) return y +/proc/islist(list/list) + if(istype(list)) + return 1 + return 0 +#endif //returns random gauss number proc/GaussRand(var/sigma) diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index a5586578b3f..9c0f498cd83 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -16,7 +16,7 @@ filters += filter(type = "outline", size = _size, color = _color) /obj/screen/plane_master/proc/shadow(_size, _border, _offset = 0, _x = 0, _y = 0, _color = "#04080FAA") - filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset, border = _border) + filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset) /obj/screen/plane_master/proc/clear_filters() filters = list() From 5c959d8548a5a56a51268c345f4b8fb91fd245fa Mon Sep 17 00:00:00 2001 From: moxian Date: Tue, 5 Nov 2019 06:41:41 +0000 Subject: [PATCH 02/59] Fix odysseus syringes breaking when flying beyond max range. --- .../mecha/equipment/tools/medical_tools.dm | 58 +++++++++---------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index 5b5f483b94f..aacd605b730 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -316,40 +316,38 @@ var/mob/originaloccupant = chassis.occupant spawn(0) src = null //if src is deleted, still process the syringe - for(var/i=0, i<6, i++) + var/max_range = 6 + for(var/i=0, i [M] was hit by the syringe!") - if(M.can_inject(null, TRUE)) - if(mechsyringe.reagents) - for(var/datum/reagent/A in mechsyringe.reagents.reagent_list) - R += A.id + " (" - R += num2text(A.volume) + ")," - add_attack_logs(originaloccupant, M, "Shot with [src] containing [R], transferred [mechsyringe.reagents.total_volume] units") - mechsyringe.icon_state = initial(mechsyringe.icon_state) - mechsyringe.icon = initial(mechsyringe.icon) - mechsyringe.reagents.reaction(M, INGEST) - mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume) - M.take_organ_damage(2) - break - else if(mechsyringe.loc == trg) - mechsyringe.icon_state = initial(mechsyringe.icon_state) - mechsyringe.icon = initial(mechsyringe.icon) - mechsyringe.update_icon() - break - else - mechsyringe.icon_state = initial(mechsyringe.icon_state) - mechsyringe.icon = initial(mechsyringe.icon) - mechsyringe.update_icon() + if(!step_towards(mechsyringe,trg)) + break + + var/list/mobs = new + for(var/mob/living/carbon/M in mechsyringe.loc) + mobs += M + var/mob/living/carbon/M = safepick(mobs) + if(M) + var/R + mechsyringe.visible_message(" [M] was hit by the syringe!") + if(M.can_inject(null, TRUE)) + if(mechsyringe.reagents) + for(var/datum/reagent/A in mechsyringe.reagents.reagent_list) + R += A.id + " (" + R += num2text(A.volume) + ")," + add_attack_logs(originaloccupant, M, "Shot with [src] containing [R], transferred [mechsyringe.reagents.total_volume] units") + mechsyringe.reagents.reaction(M, INGEST) + mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume) + M.take_organ_damage(2) + break + else if(mechsyringe.loc == trg) break sleep(1) + if(mechsyringe) + // Revert the syringe icon to normal one once it stops flying. + mechsyringe.icon_state = initial(mechsyringe.icon_state) + mechsyringe.icon = initial(mechsyringe.icon) + mechsyringe.update_icon() return 1 From 736b7129c069a84792d11ad0374cd9530ab93234 Mon Sep 17 00:00:00 2001 From: TDSSS <32099540+TDSSS@users.noreply.github.com> Date: Wed, 6 Nov 2019 02:12:36 +0100 Subject: [PATCH 03/59] Initial commit --- code/game/gamemodes/miniantags/abduction/abduction.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index 908eaa5360f..a8ae824dc92 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -184,6 +184,7 @@ var/obj/machinery/abductor/console/con = get_team_console(team_number) var/datum/objective/objective = team_objectives[team_number] if(con.experiment.points >= objective.target_amount) + priority_announcement.Announce("Regular crew brainwave monitoring has detected large amount of abnormal thought patterns, heavy abductor presence suspected. All crew are recalled for mandatory physical and mental evaluation and reconditioning.") SSshuttle.emergency.request(null, 0.5) SSshuttle.emergency.canRecall = FALSE finished = 1 From 711eeecd0131176529eb3ca7ca0691aa9b8a6ad4 Mon Sep 17 00:00:00 2001 From: TDSSS <32099540+TDSSS@users.noreply.github.com> Date: Wed, 6 Nov 2019 13:24:18 +0100 Subject: [PATCH 04/59] incorporated message into shuttle call, changed wording --- code/game/gamemodes/miniantags/abduction/abduction.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index a8ae824dc92..9fce3cc6e24 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -184,8 +184,7 @@ var/obj/machinery/abductor/console/con = get_team_console(team_number) var/datum/objective/objective = team_objectives[team_number] if(con.experiment.points >= objective.target_amount) - priority_announcement.Announce("Regular crew brainwave monitoring has detected large amount of abnormal thought patterns, heavy abductor presence suspected. All crew are recalled for mandatory physical and mental evaluation and reconditioning.") - SSshuttle.emergency.request(null, 0.5) + SSshuttle.emergency.request(null, 0.5, reason = "Large amount of abnormal thought patterns detected. All crew are recalled for mandatory evaluation and reconditioning.") SSshuttle.emergency.canRecall = FALSE finished = 1 return ..() From 091a53c4d817eb70515c577dd833e8a392b82c27 Mon Sep 17 00:00:00 2001 From: moxian Date: Thu, 7 Nov 2019 06:28:14 +0000 Subject: [PATCH 05/59] Fix hijack objective check. Corpses no longer count against it. Slaughter demons and other special roles don't count against it either. Instead of having a long list of roles that are allowed on the shuttle, it's easier to list *dis*allowed ones instead. --- code/modules/shuttle/emergency.dm | 57 ++++++++++++++----------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 953c0e6682c..7e758bb86c4 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -175,42 +175,35 @@ /obj/docking_port/mobile/emergency/proc/is_hijacked() for(var/mob/living/player in GLOB.player_list) if(player.mind) - if(player.stat != DEAD || !iszombie(player)) - if(issilicon(player)) //Borgs are technically dead anyways + if(player.stat == DEAD) // Corpses + continue + if(iszombie(player)) // Walking corpses + continue + if(issilicon(player)) //Borgs are technically dead anyways + continue + if(isanimal(player)) //Poly does not own the shuttle + continue + if(ishuman(player)) //hostages allowed on the shuttle, check for restraints + var/mob/living/carbon/human/H = player + if(!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD) //new crit users who are in hard crit are considered dead continue - if(isanimal(player)) //Poly does not own the shuttle + if(H.handcuffed) //cuffs continue - if(ishuman(player)) //hostages allowed on the shuttle, check for restraints - var/mob/living/carbon/human/H = player - if(!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD) //new crit users who are in hard crit are considered dead - continue - if(H.handcuffed) //cuffs - continue - if(H.wear_suit && H.wear_suit.breakouttime) //straight jacket - continue - if(istype(H.loc, /obj/structure/closet)) //locked/welded locker, all aboard the clown train honk honk - var/obj/structure/closet/C = H.loc - if(C.welded || C.locked) - continue - var/special_role = player.mind.special_role - if(special_role) - if(special_role == SPECIAL_ROLE_TRAITOR) // traitors can hijack the shuttle + if(H.wear_suit && H.wear_suit.breakouttime) //straight jacket + continue + if(istype(H.loc, /obj/structure/closet)) //locked/welded locker, all aboard the clown train honk honk + var/obj/structure/closet/C = H.loc + if(C.welded || C.locked) continue + var/special_role = player.mind.special_role + if(special_role) + // There's a long list of special roles, but almost all of them are antags anyway. + // If you manage to escape with a pet slaughter demon - go for it! Greentext well earned! + if(special_role != SPECIAL_ROLE_ERT && special_role != SPECIAL_ROLE_EVENTMISC) + continue - if(special_role == SPECIAL_ROLE_CHANGELING) // changelings as well - continue - - if(special_role == SPECIAL_ROLE_VAMPIRE || special_role == SPECIAL_ROLE_VAMPIRE_THRALL) // for traitorvamp - continue - - if(special_role == SPECIAL_ROLE_NUKEOPS) // so can nukeops, for the hell of it - continue - - if(special_role == SPECIAL_ROLE_SYNDICATE_DEATHSQUAD) // and the syndie deathsquad i guess - continue - - if(get_area(player) == areaInstance) - return FALSE + if(get_area(player) == areaInstance) + return FALSE return TRUE From 30139af05aaed126a64ba703f7e3aaa30f40c821 Mon Sep 17 00:00:00 2001 From: moxian Date: Thu, 7 Nov 2019 06:49:07 +0000 Subject: [PATCH 06/59] Death Squad are not syndies despite "Death" in the name. Derp. --- code/modules/shuttle/emergency.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 7e758bb86c4..c79fa4d2607 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -199,7 +199,7 @@ if(special_role) // There's a long list of special roles, but almost all of them are antags anyway. // If you manage to escape with a pet slaughter demon - go for it! Greentext well earned! - if(special_role != SPECIAL_ROLE_ERT && special_role != SPECIAL_ROLE_EVENTMISC) + if(special_role != SPECIAL_ROLE_EVENTMISC && special_role != SPECIAL_ROLE_ERT && special_role != SPECIAL_ROLE_DEATHSQUAD) continue if(get_area(player) == areaInstance) From 07e5740cefa7ffaf30e97d70c2232307e845d4d8 Mon Sep 17 00:00:00 2001 From: moxian Date: Thu, 7 Nov 2019 06:52:40 +0000 Subject: [PATCH 07/59] Remove one more level of indentation while at it. Uniformity, yay! --- code/modules/shuttle/emergency.dm | 51 ++++++++++++++++--------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index c79fa4d2607..5af2d472416 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -174,36 +174,37 @@ /obj/docking_port/mobile/emergency/proc/is_hijacked() for(var/mob/living/player in GLOB.player_list) - if(player.mind) - if(player.stat == DEAD) // Corpses + if(!player.mind) + continue + if(player.stat == DEAD) // Corpses + continue + if(iszombie(player)) // Walking corpses + continue + if(issilicon(player)) //Borgs are technically dead anyways + continue + if(isanimal(player)) //Poly does not own the shuttle + continue + if(ishuman(player)) //hostages allowed on the shuttle, check for restraints + var/mob/living/carbon/human/H = player + if(!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD) //new crit users who are in hard crit are considered dead continue - if(iszombie(player)) // Walking corpses + if(H.handcuffed) //cuffs continue - if(issilicon(player)) //Borgs are technically dead anyways + if(H.wear_suit && H.wear_suit.breakouttime) //straight jacket continue - if(isanimal(player)) //Poly does not own the shuttle + if(istype(H.loc, /obj/structure/closet)) //locked/welded locker, all aboard the clown train honk honk + var/obj/structure/closet/C = H.loc + if(C.welded || C.locked) + continue + var/special_role = player.mind.special_role + if(special_role) + // There's a long list of special roles, but almost all of them are antags anyway. + // If you manage to escape with a pet slaughter demon - go for it! Greentext well earned! + if(special_role != SPECIAL_ROLE_EVENTMISC && special_role != SPECIAL_ROLE_ERT && special_role != SPECIAL_ROLE_DEATHSQUAD) continue - if(ishuman(player)) //hostages allowed on the shuttle, check for restraints - var/mob/living/carbon/human/H = player - if(!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD) //new crit users who are in hard crit are considered dead - continue - if(H.handcuffed) //cuffs - continue - if(H.wear_suit && H.wear_suit.breakouttime) //straight jacket - continue - if(istype(H.loc, /obj/structure/closet)) //locked/welded locker, all aboard the clown train honk honk - var/obj/structure/closet/C = H.loc - if(C.welded || C.locked) - continue - var/special_role = player.mind.special_role - if(special_role) - // There's a long list of special roles, but almost all of them are antags anyway. - // If you manage to escape with a pet slaughter demon - go for it! Greentext well earned! - if(special_role != SPECIAL_ROLE_EVENTMISC && special_role != SPECIAL_ROLE_ERT && special_role != SPECIAL_ROLE_DEATHSQUAD) - continue - if(get_area(player) == areaInstance) - return FALSE + if(get_area(player) == areaInstance) + return FALSE return TRUE From 79af914dc1019dcf985c821c2b6ab0f34c864043 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Thu, 7 Nov 2019 17:53:38 -0600 Subject: [PATCH 08/59] Chemistry bag QoL improvement --- code/modules/reagents/chemistry/machinery/reagentgrinder.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 41a0a747118..c28eaf39fa1 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -176,7 +176,7 @@ //Fill machine with a bag! if(istype(I, /obj/item/storage/bag)) var/obj/item/storage/bag/B = I - for (var/obj/item/reagent_containers/food/snacks/grown/G in B.contents) + for (var/obj/item/reagent_containers/food/G in B.contents) B.remove_from_storage(G, src) holdingitems += G if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill From 7b15c9e301661e61150a49ec93ea4f3c80de872f Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Thu, 7 Nov 2019 19:19:47 -0600 Subject: [PATCH 09/59] Forgot to include this --- code/modules/reagents/chemistry/machinery/reagentgrinder.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index c28eaf39fa1..9203f095d85 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -184,7 +184,7 @@ break if(!I.contents.len) - to_chat(user, "You empty the plant bag into the All-In-One grinder.") + to_chat(user, "You empty [I] into the All-In-One grinder.") src.updateUsrDialog() return 1 From 7a04e5ee9b41e4ce0a23271eef6202f9e113fce0 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Fri, 8 Nov 2019 10:42:59 -0600 Subject: [PATCH 10/59] indention and logic cleanup --- .../chemistry/machinery/reagentgrinder.dm | 130 ++++++++++-------- 1 file changed, 71 insertions(+), 59 deletions(-) diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 9203f095d85..e1371466dc2 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -134,76 +134,88 @@ icon_state = "juicer0" /obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params) - if(default_unfasten_wrench(user, I)) - return + if(default_unfasten_wrench(user, I)) + return - if(exchange_parts(user, I)) - return + if(exchange_parts(user, I)) + return - if(anchored && !beaker) - if(default_deconstruction_screwdriver(user, "juicer_open", "juicer0", I)) - return + if(anchored && !beaker) + if(default_deconstruction_screwdriver(user, "juicer_open", "juicer0", I)) + return - if(panel_open && istype(I, /obj/item/crowbar)) - default_deconstruction_crowbar(I) - return + if(panel_open && istype(I, /obj/item/crowbar)) + default_deconstruction_crowbar(I) + return - if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER) ) - if(beaker) - to_chat(user, "There's already a container inside.") - else if(panel_open) - to_chat(user, "Close the maintenance panel first.") - else - if(!user.drop_item()) - return 1 - beaker = I - beaker.loc = src - update_icon() - src.updateUsrDialog() - return 1 //no afterattack + if(istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER) ) + if(beaker) + to_chat(user, "There's already a container inside.") + else if(panel_open) + to_chat(user, "Close the maintenance panel first.") + else + if(!user.drop_item()) + return TRUE + beaker = I + beaker.loc = src + update_icon() + updateUsrDialog() + return TRUE //no afterattack - if(is_type_in_list(I, dried_items)) - if(istype(I, /obj/item/reagent_containers/food/snacks/grown)) - var/obj/item/reagent_containers/food/snacks/grown/G = I - if(!G.dry) - to_chat(user, "You must dry that first!") - return 1 + if(is_type_in_list(I, dried_items)) + if(istype(I, /obj/item/reagent_containers/food/snacks/grown)) + var/obj/item/reagent_containers/food/snacks/grown/G = I + if(!G.dry) + to_chat(user, "You must dry that first!") + return TRUE - if(holdingitems && holdingitems.len >= limit) - to_chat(usr, "The machine cannot hold anymore items.") - return 1 + if(holdingitems && holdingitems.len >= limit) + to_chat(usr, "The machine cannot hold anymore items.") + return TRUE - //Fill machine with a bag! - if(istype(I, /obj/item/storage/bag)) - var/obj/item/storage/bag/B = I - for (var/obj/item/reagent_containers/food/G in B.contents) - B.remove_from_storage(G, src) - holdingitems += G - if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill - to_chat(user, "You fill the All-In-One grinder to the brim.") - break + //Fill machine with a bag! + if(istype(I, /obj/item/storage/bag)) + var/obj/item/storage/bag/B = I + if(!B.contents.len) + to_chat(user, "[B] is empty.") + return FALSE - if(!I.contents.len) - to_chat(user, "You empty [I] into the All-In-One grinder.") + var/original_contents_len = B.contents.len - src.updateUsrDialog() - return 1 + for(var/obj/item/G in B.contents) + if(is_type_in_list(G, blend_items) || is_type_in_list(G, juice_items)) + B.remove_from_storage(G, src) + holdingitems += G + if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill + to_chat(user, "You fill the All-In-One grinder to the brim.") + break - if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) - if(user.a_intent == INTENT_HARM) - return ..() - else - to_chat(user, "Cannot refine into a reagent!") - return 1 + if(B.contents.len == original_contents_len) + to_chat(user, "Nothing in [B] can be put into the All-In-One grinder.") + return FALSE + else if(!B.contents.len) + to_chat(user, "You empty all of [B]'s contents into the All-In-One grinder.") + else + to_chat(user, "You empty some of [B]'s contents into the All-In-One grinder.") - if(user.drop_item()) - I.loc = src - holdingitems += I - src.updateUsrDialog() - return 0 + updateUsrDialog() + return TRUE + + if(!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) + if(user.a_intent == INTENT_HARM) + return ..() + else + to_chat(user, "Cannot refine into a reagent!") + return TRUE + + if(user.drop_item()) + I.loc = src + holdingitems += I + src.updateUsrDialog() + return FALSE /obj/machinery/reagentgrinder/attack_ai(mob/user) - return 0 + return FALSE /obj/machinery/reagentgrinder/attack_hand(mob/user) user.set_machine(src) @@ -301,8 +313,8 @@ /obj/machinery/reagentgrinder/proc/is_allowed(obj/item/reagent_containers/O) for (var/i in blend_items) if(istype(O, i)) - return 1 - return 0 + return TRUE + return FALSE /obj/machinery/reagentgrinder/proc/get_allowed_by_id(obj/item/O) for (var/i in blend_items) From 4876cbf7eab044fc3472062cfcf65fb3c7608247 Mon Sep 17 00:00:00 2001 From: Leanfrog <52841396+Leanfrog@users.noreply.github.com> Date: Sat, 9 Nov 2019 11:44:09 -0500 Subject: [PATCH 11/59] Waterbreath Trait --- .../modules/mob/living/carbon/human/species/monkey.dm | 7 +++++++ .../modules/mob/living/carbon/human/species/skrell.dm | 11 ++++++++++- code/modules/mob/living/carbon/human/species/slime.dm | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/species/monkey.dm b/code/modules/mob/living/carbon/human/species/monkey.dm index a0980256718..b357d2c5345 100644 --- a/code/modules/mob/living/carbon/human/species/monkey.dm +++ b/code/modules/mob/living/carbon/human/species/monkey.dm @@ -131,6 +131,13 @@ "appendix" = /obj/item/organ/internal/appendix, "eyes" = /obj/item/organ/internal/eyes/skrell //Tajara monkey-forms are uniquely colourblind and have excellent darksight, which is why they need a subtype of their greater-form's organ.. ) +/datum/species/monkey/skrell/on_species_gain(mob/living/carbon/human/H) + ..() + ADD_TRAIT(H, TRAIT_WATERBREATH, "species") + +/datum/species/monkey/skrell/on_species_loss(mob/living/carbon/human/H) + ..() + REMOVE_TRAIT(H, TRAIT_WATERBREATH, "species") /datum/species/monkey/unathi name = "Stok" diff --git a/code/modules/mob/living/carbon/human/species/skrell.dm b/code/modules/mob/living/carbon/human/species/skrell.dm index 009514f4902..9e21c0bf390 100644 --- a/code/modules/mob/living/carbon/human/species/skrell.dm +++ b/code/modules/mob/living/carbon/human/species/skrell.dm @@ -12,6 +12,7 @@ herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \ the secrets of their empire to their allies." + species_traits = list(LIPS) clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS bodyflags = HAS_SKIN_COLOR | HAS_BODY_MARKINGS @@ -43,4 +44,12 @@ "is jamming their thumbs into their eye sockets!", "is twisting their own neck!", "makes like a fish and suffocates!", - "is strangling themselves with their own tendrils!") \ No newline at end of file + "is strangling themselves with their own tendrils!") + +/datum/species/skrell/on_species_gain(mob/living/carbon/human/H) + ..() + ADD_TRAIT(H, TRAIT_WATERBREATH, "species") + +/datum/species/skrell/on_species_loss(mob/living/carbon/human/H) + ..() + REMOVE_TRAIT(H, TRAIT_WATERBREATH, "species") \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/slime.dm b/code/modules/mob/living/carbon/human/species/slime.dm index 42a566e450c..e7501486b72 100644 --- a/code/modules/mob/living/carbon/human/species/slime.dm +++ b/code/modules/mob/living/carbon/human/species/slime.dm @@ -72,6 +72,7 @@ grow.Grant(H) recolor = new() recolor.Grant(H) + ADD_TRAIT(H, TRAIT_WATERBREATH, "species") /datum/species/slime/on_species_loss(mob/living/carbon/human/H) ..() @@ -79,6 +80,7 @@ grow.Remove(H) if(recolor) recolor.Remove(H) + REMOVE_TRAIT(H, TRAIT_WATERBREATH, "species") /datum/species/slime/handle_life(mob/living/carbon/human/H) // Slowly shifting to the color of the reagents From 156299d3ac984d28bdeb7a87e5b54b629148940e Mon Sep 17 00:00:00 2001 From: Leanfrog <52841396+Leanfrog@users.noreply.github.com> Date: Sat, 9 Nov 2019 11:45:11 -0500 Subject: [PATCH 12/59] Waterbreath Trait --- code/__HELPERS/traits.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/__HELPERS/traits.dm b/code/__HELPERS/traits.dm index 472caea4490..7c1d2257e27 100644 --- a/code/__HELPERS/traits.dm +++ b/code/__HELPERS/traits.dm @@ -62,6 +62,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai //mob traits #define TRAIT_PACIFISM "pacifism" +#define TRAIT_WATERBREATH "waterbreathing" // common trait sources #define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention \ No newline at end of file From 2cc6931334ba6524ad2f2e6dbe26cfa9d0b24e1c Mon Sep 17 00:00:00 2001 From: Leanfrog <52841396+Leanfrog@users.noreply.github.com> Date: Sat, 9 Nov 2019 11:46:17 -0500 Subject: [PATCH 13/59] Waterbreath Trait --- code/game/machinery/poolcontroller.dm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm index 4b512297ffd..12804cfcc88 100644 --- a/code/game/machinery/poolcontroller.dm +++ b/code/game/machinery/poolcontroller.dm @@ -28,21 +28,21 @@ /obj/machinery/poolcontroller/invisible/sea name = "Sea Controller" desc = "A controller for the underwater portion of the sea. Players shouldn't see this." - deep_water = TRUE + deep_water = TRUE -/obj/machinery/poolcontroller/Initialize(mapload) - var/contents_loop = linked_area +/obj/machinery/poolcontroller/Initialize(mapload) + var/contents_loop = linked_area if(!linked_area) contents_loop = range(srange, src) for(var/turf/T in contents_loop) if(istype(T, /turf/simulated/floor/beach/water)) var/turf/simulated/floor/beach/water/W = T - W.linkedcontroller = src + W.linkedcontroller = src linkedturfs += T else if(istype(T, /turf/unsimulated/beach/water)) var/turf/unsimulated/beach/water/W = T - W.linkedcontroller = src + W.linkedcontroller = src linkedturfs += T . = ..() @@ -121,7 +121,7 @@ return //Has internals, no drowning if((NO_BREATHE in drownee.dna.species.species_traits) || (BREATHLESS in drownee.mutations)) return //doesn't breathe, no drowning - if(isskrell(drownee) || isneara(drownee)) + if(HAS_TRAIT(drownee,TRAIT_WATERBREATH)) return //fish things don't drown if(drownee.stat == DEAD) //Dead spacemen don't drown more From 6dbfd469a20a6c1ac2c3770b8a85047c83cd6c03 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sun, 10 Nov 2019 11:31:02 -0600 Subject: [PATCH 14/59] Adds a cancel button to the wizard teleport spell --- code/datums/spells/area_teleport.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/datums/spells/area_teleport.dm b/code/datums/spells/area_teleport.dm index 2f07f106d2a..4aa7eafbed6 100644 --- a/code/datums/spells/area_teleport.dm +++ b/code/datums/spells/area_teleport.dm @@ -25,10 +25,13 @@ var/A = null if(!randomise_selection) - A = input("Area to teleport to", "Teleport", A) in teleportlocs + A = input("Area to teleport to", "Teleport", A) as null|anything in teleportlocs else A = pick(teleportlocs) + if(!A) + return + var/area/thearea = teleportlocs[A] if(thearea.tele_proof && !istype(thearea, /area/wizard_station)) From 21960b87228811252dde85f2a039e3dd05a23699 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 11 Nov 2019 16:36:27 -0600 Subject: [PATCH 15/59] fixes some backwards return logic --- code/modules/reagents/chemistry/machinery/reagentgrinder.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index e1371466dc2..9601746443a 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -155,7 +155,7 @@ to_chat(user, "Close the maintenance panel first.") else if(!user.drop_item()) - return TRUE + return FALSE beaker = I beaker.loc = src update_icon() @@ -167,11 +167,11 @@ var/obj/item/reagent_containers/food/snacks/grown/G = I if(!G.dry) to_chat(user, "You must dry that first!") - return TRUE + return FALSE if(holdingitems && holdingitems.len >= limit) to_chat(usr, "The machine cannot hold anymore items.") - return TRUE + return FALSE //Fill machine with a bag! if(istype(I, /obj/item/storage/bag)) From 55bf2fe756bd9cbef005b344b8daba9a1daaf85c Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Tue, 12 Nov 2019 05:03:43 -0600 Subject: [PATCH 16/59] Spray bottle admin attack log tweaks --- code/modules/reagents/reagent_containers.dm | 8 ++++++++ .../reagents/reagent_containers/spray.dm | 17 ++++++++--------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 41f9524874b..82d430bfcd7 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -72,3 +72,11 @@ obj/item/reagent_containers/proc/add_initial_reagents() to_chat(user, "You fill [src] from [source].") return ..() + +// Returns a string that contains a list of reagents seperated with commas +/obj/item/reagent_containers/proc/get_formatted_contents_string() + var/contents_string + for(var/R in reagents.reagent_list) + contents_string += "[R], " + contents_string = copytext(contents_string, 1, lentext(contents_string)-1) + return contents_string diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 482b8b20ccd..a778a4fd56f 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -43,21 +43,20 @@ to_chat(user, "[src] is empty!") return + var/contents_log = get_formatted_contents_string() spray(A) playsound(loc, 'sound/effects/spray2.ogg', 50, 1, -6) user.changeNext_move(CLICK_CD_RANGE*2) user.newtonian_move(get_dir(A, user)) - if(reagents.has_reagent("sacid")) - msg_admin_attack("[key_name_admin(user)] fired sulphuric acid from \a [src] at [COORD(user)].", ATKLOG_FEW) - log_game("[key_name(user)] fired sulphuric acid from \a [src] at [COORD(user)].") - if(reagents.has_reagent("facid")) - msg_admin_attack("[key_name_admin(user)] fired fluorosulfuric acid from \a [src] at [COORD(user)].", ATKLOG_FEW) - log_game("[key_name(user)] fired fluorosulfuric Acid from \a [src] at [COORD(user)].") - if(reagents.has_reagent("lube")) - msg_admin_attack("[key_name_admin(user)] fired space lube from \a [src] at [COORD(user)].") - log_game("[key_name(user)] fired space lube from \a [src] at [COORD(user)].") + if(reagents.reagent_list.len == 1 && reagents.has_reagent("cleaner")) // Don't show logs for bottles spraying only space cleaner + return + + var/attack_log_type = ATKLOG_MOST + if(reagents.has_reagent("sacid") || reagents.has_reagent("facid") || reagents.has_reagent("lube")) + attack_log_type = ATKLOG_FEW + msg_admin_attack("[key_name_admin(user)] used a spray bottle at [COORD(user)] - Contents: [contents_log] - Temperature: [reagents.chem_temp]K", attack_log_type) return From 468ebe87e0aa21ac952815f6e6eca49a9228a5fc Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Tue, 12 Nov 2019 10:17:54 -0600 Subject: [PATCH 17/59] temp based cleaner logs, uses Join() --- code/modules/reagents/reagent_containers.dm | 8 -------- code/modules/reagents/reagent_containers/spray.dm | 8 +++++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 82d430bfcd7..41f9524874b 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -72,11 +72,3 @@ obj/item/reagent_containers/proc/add_initial_reagents() to_chat(user, "You fill [src] from [source].") return ..() - -// Returns a string that contains a list of reagents seperated with commas -/obj/item/reagent_containers/proc/get_formatted_contents_string() - var/contents_string - for(var/R in reagents.reagent_list) - contents_string += "[R], " - contents_string = copytext(contents_string, 1, lentext(contents_string)-1) - return contents_string diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index a778a4fd56f..7433c227e45 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -43,20 +43,22 @@ to_chat(user, "[src] is empty!") return - var/contents_log = get_formatted_contents_string() + var/contents_log = reagents.reagent_list.Join(", ") spray(A) playsound(loc, 'sound/effects/spray2.ogg', 50, 1, -6) user.changeNext_move(CLICK_CD_RANGE*2) user.newtonian_move(get_dir(A, user)) - if(reagents.reagent_list.len == 1 && reagents.has_reagent("cleaner")) // Don't show logs for bottles spraying only space cleaner - return + if(reagents.reagent_list.len == 1 && reagents.has_reagent("cleaner")) // Only show space cleaner logs if it's burning people from being too hot or cold + if((reagents.chem_temp < 300) && (reagents.chem_temp > 280)) // 280 is the cold threshold for slimes, 300 the hot threshold for drask + return var/attack_log_type = ATKLOG_MOST if(reagents.has_reagent("sacid") || reagents.has_reagent("facid") || reagents.has_reagent("lube")) attack_log_type = ATKLOG_FEW msg_admin_attack("[key_name_admin(user)] used a spray bottle at [COORD(user)] - Contents: [contents_log] - Temperature: [reagents.chem_temp]K", attack_log_type) + log_game("[key_name(user)] used a spray bottle at [COORD(user)] - Contents: [contents_log] - Temperature: [reagents.chem_temp]K") return From 87a8a933e8d109e0a9c546de27f3ddcb73bef8b6 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Thu, 14 Nov 2019 10:53:22 -0600 Subject: [PATCH 18/59] remove useless parentheses --- code/modules/reagents/reagent_containers/spray.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 7433c227e45..a4320639f39 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -51,7 +51,7 @@ user.newtonian_move(get_dir(A, user)) if(reagents.reagent_list.len == 1 && reagents.has_reagent("cleaner")) // Only show space cleaner logs if it's burning people from being too hot or cold - if((reagents.chem_temp < 300) && (reagents.chem_temp > 280)) // 280 is the cold threshold for slimes, 300 the hot threshold for drask + if(reagents.chem_temp < 300 && reagents.chem_temp > 280) // 280 is the cold threshold for slimes, 300 the hot threshold for drask return var/attack_log_type = ATKLOG_MOST From a071b23ff905424ffa6661825ed8de3b273300a0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Nov 2019 20:30:23 -0500 Subject: [PATCH 19/59] Made gauze and ointment heal for 10 brute or burn respectively. --- code/game/objects/items/stacks/medical.dm | 26 +++++++++-------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 7dc1a97a735..9f8c877aa24 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -12,7 +12,7 @@ var/heal_brute = 0 var/heal_burn = 0 var/self_delay = 20 - var/unique_handling = 0 //some things give a special prompt, do we want to bypass some checks in parent? + var/unique_handling = FALSE //some things give a special prompt, do we want to bypass some checks in parent? var/stop_bleeding = 0 var/healverb = "bandage" @@ -31,28 +31,20 @@ var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) if(!H.can_inject(user, TRUE)) - return 1 + return TRUE if(!affecting) to_chat(user, "That limb is missing!") - return 1 + return TRUE if(affecting.is_robotic()) to_chat(user, "This can't be used on a robotic limb.") - return 1 - - if(stop_bleeding) - if(H.bleedsuppress) - to_chat(user, "[H]'s bleeding is already bandaged!") - return 1 - else if(!H.bleed_rate) - to_chat(user, "[H] isn't bleeding!") - return 1 + return TRUE if(M == user && !unique_handling) user.visible_message("[user] starts to apply [src] on [H]...") if(!do_mob(user, H, self_delay)) - return 1 + return TRUE return if(isanimal(M)) @@ -123,6 +115,7 @@ desc = "Some sterile gauze to wrap around bloody stumps." icon_state = "gauze" origin_tech = "biotech=2" + heal_brute = 10 stop_bleeding = 1800 /obj/item/stack/medical/bruise_pack/attackby(obj/item/I, mob/user, params) @@ -140,13 +133,13 @@ /obj/item/stack/medical/bruise_pack/attack(mob/living/M, mob/user) if(..()) - return 1 + return TRUE if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) - if(affecting.open == 0) + if(affecting.open == FALSE) affecting.germ_level = 0 if(stop_bleeding) @@ -187,6 +180,7 @@ icon_state = "ointment" origin_tech = "biotech=2" healverb = "salve" + heal_burn = 10 /obj/item/stack/medical/ointment/attack(mob/living/M, mob/user) if(..()) @@ -196,7 +190,7 @@ var/mob/living/carbon/human/H = M var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected) - if(affecting.open == 0) + if(affecting.open == FALSE) affecting.germ_level = 0 heal(H, user) From 28a4e6a343d9384f77fe30df0f044cfcecb7caea Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Nov 2019 11:21:07 -0500 Subject: [PATCH 20/59] constructs have wiz-hud --- code/game/gamemodes/wizard/soulstone.dm | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 520e6939b60..b3643d3d38a 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -265,12 +265,15 @@ var/mob/living/simple_animal/hostile/construct/armoured/Z = new /mob/living/simple_animal/hostile/construct/armoured (get_turf(T.loc)) Z.key = A.key Z.faction |= "\ref[U]" + Z.mind.store_memory(A.mind.memory) if(iscultist(U)) if(SSticker.mode.name == "cult") SSticker.mode:add_cultist(Z.mind) else SSticker.mode.cult+=Z.mind SSticker.mode.update_cult_icons_added(Z.mind) + if(iswizard(U)) + SSticker.mode.update_wiz_icons_added(Z.mind) qdel(T) to_chat(Z, "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, create shield walls and even deflect energy weapons, and rip apart enemies and walls alike.") to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.") @@ -281,12 +284,15 @@ var/mob/living/simple_animal/hostile/construct/wraith/Z = new /mob/living/simple_animal/hostile/construct/wraith (get_turf(T.loc)) Z.key = A.key Z.faction |= "\ref[U]" + Z.mind.store_memory(A.mind.memory) if(iscultist(U)) if(SSticker.mode.name == "cult") SSticker.mode:add_cultist(Z.mind) else SSticker.mode.cult+=Z.mind - SSticker.mode.update_cult_icons_added(Z.mind) + if(iswizard(U)) + SSticker.mode.update_wiz_icons_added(Z.mind) + qdel(T) to_chat(Z, "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.") to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.") @@ -297,12 +303,15 @@ var/mob/living/simple_animal/hostile/construct/builder/Z = new /mob/living/simple_animal/hostile/construct/builder (get_turf(T.loc)) Z.key = A.key Z.faction |= "\ref[U]" + Z.mind.store_memory(A.mind.memory) if(iscultist(U)) if(SSticker.mode.name == "cult") SSticker.mode:add_cultist(Z.mind) else SSticker.mode.cult+=Z.mind SSticker.mode.update_cult_icons_added(Z.mind) + if(iswizard(U)) + SSticker.mode.update_wiz_icons_added(Z.mind) qdel(T) to_chat(Z, "You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, use magic missile, repair allied constructs (by clicking on them), and most important of all create new constructs (Use your Artificer spell to summon a new construct shell and Summon Soulstone to create a new soulstone).") to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.") @@ -350,8 +359,12 @@ S.key = T.key if(U) S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation + if(!iscultist(U)) + S.mind.store_memory("Serve [U.real_name], your creator.") if(U && iscultist(U)) SSticker.mode.add_cultist(S.mind, 0) + if(U && iswizard(U)) + SSticker.mode.update_wiz_icons_added(S.mind) S.cancel_camera() name = "soulstone: Shade of [T.real_name]" icon_state = "soulstone2" From a69d9afd392f112d0f5b78d11eb32fc65e0ab40d Mon Sep 17 00:00:00 2001 From: Patrick Meade Date: Sat, 16 Nov 2019 11:26:15 -0600 Subject: [PATCH 21/59] Clean up for changes in PR #10861 --- code/modules/events/sentience.dm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm index 52e8918a16c..0430b7a2ee8 100644 --- a/code/modules/events/sentience.dm +++ b/code/modules/events/sentience.dm @@ -36,9 +36,9 @@ SA.universal_speak = 1 SA.sentience_act() SA.can_collar = 1 - SA.maxHealth = max(SA.maxHealth + 200) - SA.melee_damage_lower = max(SA.melee_damage_lower + 15) - SA.melee_damage_upper = max(SA.melee_damage_upper + 15) + SA.maxHealth = SA.maxHealth + 200 + SA.melee_damage_lower = SA.melee_damage_lower + 15 + SA.melee_damage_upper = SA.melee_damage_upper + 15 SA.health = SA.maxHealth SA.del_on_death = FALSE greet_sentient(SA) @@ -50,4 +50,3 @@ to_chat(M, "Due to freak radiation, you have gained \ human level intelligence and the ability to speak and understand \ human language!") - From 1881051171f9ca746672af8a0807757cd9190117 Mon Sep 17 00:00:00 2001 From: Patrick Meade Date: Sat, 16 Nov 2019 11:58:30 -0600 Subject: [PATCH 22/59] Better to fix it all the way --- code/modules/events/sentience.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm index 0430b7a2ee8..fb896e9e2a6 100644 --- a/code/modules/events/sentience.dm +++ b/code/modules/events/sentience.dm @@ -36,9 +36,9 @@ SA.universal_speak = 1 SA.sentience_act() SA.can_collar = 1 - SA.maxHealth = SA.maxHealth + 200 - SA.melee_damage_lower = SA.melee_damage_lower + 15 - SA.melee_damage_upper = SA.melee_damage_upper + 15 + SA.maxHealth += 200 + SA.melee_damage_lower += 15 + SA.melee_damage_upper += 15 SA.health = SA.maxHealth SA.del_on_death = FALSE greet_sentient(SA) From fa55b253b01f784389030e4b03ff81852d54f8f7 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Nov 2019 13:49:06 -0500 Subject: [PATCH 23/59] Constructs/Shades removed from cult on death, and logged as antags if made by wizard/cultist. Shades now properly deleted when construct is created. --- code/game/gamemodes/wizard/soulstone.dm | 70 +++++-------------- .../mob/living/simple_animal/constructs.dm | 4 ++ .../modules/mob/living/simple_animal/shade.dm | 3 + 3 files changed, 26 insertions(+), 51 deletions(-) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index b3643d3d38a..09a8643802d 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -172,7 +172,7 @@ was_used() attack_self(U) -///////////////////////////Transferring to constructs///////////////////////////////////////////////////// +///////////////////////////Transferring to fs///////////////////////////////////////////////////// /obj/structure/constructshell name = "empty shell" icon = 'icons/obj/wizard.dmi' @@ -263,64 +263,30 @@ switch(construct_class) if("Juggernaut") var/mob/living/simple_animal/hostile/construct/armoured/Z = new /mob/living/simple_animal/hostile/construct/armoured (get_turf(T.loc)) - Z.key = A.key - Z.faction |= "\ref[U]" - Z.mind.store_memory(A.mind.memory) - if(iscultist(U)) - if(SSticker.mode.name == "cult") - SSticker.mode:add_cultist(Z.mind) - else - SSticker.mode.cult+=Z.mind - SSticker.mode.update_cult_icons_added(Z.mind) - if(iswizard(U)) - SSticker.mode.update_wiz_icons_added(Z.mind) - qdel(T) to_chat(Z, "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, create shield walls and even deflect energy weapons, and rip apart enemies and walls alike.") - to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.") - Z.cancel_camera() - qdel(C) + init_construct(Z,A,C,T) if("Wraith") var/mob/living/simple_animal/hostile/construct/wraith/Z = new /mob/living/simple_animal/hostile/construct/wraith (get_turf(T.loc)) - Z.key = A.key - Z.faction |= "\ref[U]" - Z.mind.store_memory(A.mind.memory) - if(iscultist(U)) - if(SSticker.mode.name == "cult") - SSticker.mode:add_cultist(Z.mind) - else - SSticker.mode.cult+=Z.mind - if(iswizard(U)) - SSticker.mode.update_wiz_icons_added(Z.mind) - - qdel(T) to_chat(Z, "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.") - to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.") - Z.cancel_camera() - qdel(C) + init_construct(Z,A,C,T) if("Artificer") var/mob/living/simple_animal/hostile/construct/builder/Z = new /mob/living/simple_animal/hostile/construct/builder (get_turf(T.loc)) - Z.key = A.key - Z.faction |= "\ref[U]" - Z.mind.store_memory(A.mind.memory) - if(iscultist(U)) - if(SSticker.mode.name == "cult") - SSticker.mode:add_cultist(Z.mind) - else - SSticker.mode.cult+=Z.mind - SSticker.mode.update_cult_icons_added(Z.mind) - if(iswizard(U)) - SSticker.mode.update_wiz_icons_added(Z.mind) - qdel(T) to_chat(Z, "You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, use magic missile, repair allied constructs (by clicking on them), and most important of all create new constructs (Use your Artificer spell to summon a new construct shell and Summon Soulstone to create a new soulstone).") - to_chat(Z, "You are still bound to serve your creator, follow [U.p_their()] orders and help [U.p_them()] complete [U.p_their()] goals at all costs.") - Z.cancel_camera() - qdel(C) + init_construct(Z,A,C,T) else to_chat(U, "Creation failed!: The soul stone is empty! Go kill someone!") return +/proc/init_construct(var/mob/living/simple_animal/hostile/construct/wraith/Z, var/mob/living/simple_animal/shade/A, var/obj/item/soulstone/C, var/obj/structure/constructshell/T) + A.mind.transfer_to(Z) + qdel(T) + qdel(A) + to_chat(Z, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") + Z.cancel_camera() + qdel(C) + /proc/makeNewConstruct(var/mob/living/simple_animal/hostile/construct/ctype, var/mob/target, var/mob/stoner = null, cultoverride = 0) if(jobban_isbanned(target, "cultist") || jobban_isbanned(target, "Syndicate")) return @@ -334,11 +300,11 @@ SSticker.mode.cult+=newstruct.mind SSticker.mode.update_cult_icons_added(newstruct.mind) if(stoner && iswizard(stoner)) - to_chat(newstruct, "You are still bound to serve your creator, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.") + to_chat(newstruct, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") else if(stoner && iscultist(stoner)) - to_chat(newstruct, "You are still bound to serve the cult, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.") + to_chat(newstruct, "You are still bound to serve the cult, follow their orders and help them complete their goals at all costs.") else - to_chat(newstruct, "You are still bound to serve your creator, follow [stoner.p_their()] orders and help [stoner.p_them()] complete [stoner.p_their()] goals at all costs.") + to_chat(newstruct, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") newstruct.cancel_camera() /obj/item/soulstone/proc/init_shade(mob/living/T, mob/U, vic = 0) @@ -363,15 +329,17 @@ S.mind.store_memory("Serve [U.real_name], your creator.") if(U && iscultist(U)) SSticker.mode.add_cultist(S.mind, 0) + S.mind.special_role = SPECIAL_ROLE_CULTIST if(U && iswizard(U)) SSticker.mode.update_wiz_icons_added(S.mind) + S.mind.special_role = SPECIAL_ROLE_WIZARD_APPRENTICE S.cancel_camera() name = "soulstone: Shade of [T.real_name]" icon_state = "soulstone2" if(U && iswizard(U)) - to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help [U.p_them()] succeed in their goals at all costs.") + to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help them succeed in their goals at all costs.") else if(U && iscultist(U)) - to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help [U.p_them()] succeed in their goals at all costs.") + to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs.") if(vic && U) to_chat(U, "Capture successful!: [T.real_name]'s soul has been ripped from [U.p_their()] body and stored within the soul stone.") if(isrobot(T))//Robots have to dust or else they spill out an empty robot brain, and unequiping them spills robot components that shouldn't spawn. diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 0c003b9e3b8..a51d2dcefc1 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -47,6 +47,10 @@ if(SSticker.cultdat?.theme == "blood") updateglow() +/mob/living/simple_animal/hostile/construct/death(gibbed) + . = ..() + SSticker.mode.remove_cultist(src.mind, FALSE) + /mob/living/simple_animal/hostile/construct/examine(mob/user) . = ..() diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index 3f7b76c5af0..948c16314c9 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -28,6 +28,9 @@ del_on_death = 1 deathmessage = "lets out a contented sigh as their form unwinds." +/mob/living/simple_animal/shade/death(gibbed) + . = ..() + SSticker.mode.remove_cultist(src.mind, FALSE) /mob/living/simple_animal/shade/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri if(istype(O, /obj/item/soulstone)) From 71ba80cfda74a4ac29fbb35a32c8a7182ab1bed6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Nov 2019 14:27:29 -0500 Subject: [PATCH 24/59] Cleaned up unintended dirty change --- code/game/gamemodes/wizard/soulstone.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 09a8643802d..19e0dd678c1 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -172,7 +172,7 @@ was_used() attack_self(U) -///////////////////////////Transferring to fs///////////////////////////////////////////////////// +///////////////////////////Transferring to constructs///////////////////////////////////////////////////// /obj/structure/constructshell name = "empty shell" icon = 'icons/obj/wizard.dmi' From 68668226406acb816df2e48d56fee139b0d002b6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Nov 2019 15:32:42 -0500 Subject: [PATCH 25/59] byond black magic, casing fixed --- code/game/gamemodes/wizard/soulstone.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 19e0dd678c1..b859eec6b97 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -279,7 +279,7 @@ to_chat(U, "Creation failed!: The soul stone is empty! Go kill someone!") return -/proc/init_construct(var/mob/living/simple_animal/hostile/construct/wraith/Z, var/mob/living/simple_animal/shade/A, var/obj/item/soulstone/C, var/obj/structure/constructshell/T) +/proc/init_construct(var/mob/living/simple_animal/hostile/construct/Z, var/mob/living/simple_animal/shade/A, var/obj/item/soulstone/C, var/obj/structure/constructshell/T) A.mind.transfer_to(Z) qdel(T) qdel(A) From 01fb3f2c46b57a400ce3d9b33ad39c17aebdf65c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Nov 2019 20:10:32 -0500 Subject: [PATCH 26/59] review changes --- code/game/gamemodes/wizard/soulstone.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index b859eec6b97..d720b62792e 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -279,7 +279,7 @@ to_chat(U, "Creation failed!: The soul stone is empty! Go kill someone!") return -/proc/init_construct(var/mob/living/simple_animal/hostile/construct/Z, var/mob/living/simple_animal/shade/A, var/obj/item/soulstone/C, var/obj/structure/constructshell/T) +/proc/init_construct(mob/living/simple_animal/hostile/construct/Z, mob/living/simple_animal/shade/A, obj/item/soulstone/C, obj/structure/constructshell/T) A.mind.transfer_to(Z) qdel(T) qdel(A) @@ -327,10 +327,10 @@ S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation if(!iscultist(U)) S.mind.store_memory("Serve [U.real_name], your creator.") - if(U && iscultist(U)) + if(iscultist(U)) SSticker.mode.add_cultist(S.mind, 0) S.mind.special_role = SPECIAL_ROLE_CULTIST - if(U && iswizard(U)) + if(iswizard(U)) SSticker.mode.update_wiz_icons_added(S.mind) S.mind.special_role = SPECIAL_ROLE_WIZARD_APPRENTICE S.cancel_camera() From e1afee0e784c68d132bffc072f5dbba6803b074a Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 17 Nov 2019 01:20:59 -0500 Subject: [PATCH 27/59] review changes --- code/game/gamemodes/wizard/soulstone.dm | 87 ++++++++++++------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index d720b62792e..2edbb41cb95 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -205,19 +205,19 @@ /obj/item/proc/transfer_soul(var/choice as text, var/target, var/mob/U as mob) switch(choice) if("FORCE") - var/obj/item/soulstone/C = src + var/obj/item/soulstone/SS = src var/mob/living/T = target if(T.client != null) - C.init_shade(T, U) + SS.init_shade(T, U) else to_chat(U, "Capture failed!: The soul has already fled its mortal frame. You attempt to bring it back...") T.Paralyse(20) - if(!C.getCultGhost(T,U)) + if(!SS.getCultGhost(T,U)) T.dust() //If we can't get a ghost, kill the sacrifice anyway. if("VICTIM") var/mob/living/carbon/human/T = target - var/obj/item/soulstone/C = src + var/obj/item/soulstone/SS = src if(T.stat == 0) to_chat(U, "Capture failed!: Kill or maim the victim first!") else @@ -226,66 +226,66 @@ else if(T.client == null) to_chat(U, "Capture failed!: The soul has already fled its mortal frame. You attempt to bring it back...") - C.getCultGhost(T,U) + SS.getCultGhost(T,U) else - if(C.contents.len) + if(SS.contents.len) to_chat(U, "Capture failed!: The soul stone is full! Use or free an existing soul to make room.") else - C.init_shade(T, U, vic = 1) + SS.init_shade(T, U, vic = 1) if("SHADE") var/mob/living/simple_animal/shade/T = target - var/obj/item/soulstone/C = src - if(!C.can_use(U)) + var/obj/item/soulstone/SS = src + if(!SS.can_use(U)) U.Paralyse(5) to_chat(U, "Your body is wracked with debilitating pain!") return if(T.stat == DEAD) to_chat(U, "Capture failed!: The shade has already been banished!") else - if(C.contents.len) + if(SS.contents.len) to_chat(U, "Capture failed!: The soul stone is full! Use or free an existing soul to make room.") else - T.loc = C //put shade in stone + T.loc = SS //put shade in stone T.status_flags |= GODMODE T.canmove = 0 T.health = T.maxHealth T.faction |= "\ref[U]" - C.icon_state = "soulstone2" + SS.icon_state = "soulstone2" to_chat(T, "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form") to_chat(U, "Capture successful!: [T.name]'s has been recaptured and stored within the soul stone.") if("CONSTRUCT") var/obj/structure/constructshell/T = target - var/obj/item/soulstone/C = src - var/mob/living/simple_animal/shade/A = locate() in C - if(A) + var/obj/item/soulstone/SS = src + var/mob/living/simple_animal/shade/SH = locate() in SS + if(SH) var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer") switch(construct_class) if("Juggernaut") - var/mob/living/simple_animal/hostile/construct/armoured/Z = new /mob/living/simple_animal/hostile/construct/armoured (get_turf(T.loc)) - to_chat(Z, "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, create shield walls and even deflect energy weapons, and rip apart enemies and walls alike.") - init_construct(Z,A,C,T) + var/mob/living/simple_animal/hostile/construct/armoured/C = new /mob/living/simple_animal/hostile/construct/armoured (get_turf(T.loc)) + to_chat(C, "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, create shield walls and even deflect energy weapons, and rip apart enemies and walls alike.") + init_construct(C,SH,SS,T) if("Wraith") - var/mob/living/simple_animal/hostile/construct/wraith/Z = new /mob/living/simple_animal/hostile/construct/wraith (get_turf(T.loc)) - to_chat(Z, "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.") - init_construct(Z,A,C,T) + var/mob/living/simple_animal/hostile/construct/wraith/C = new /mob/living/simple_animal/hostile/construct/wraith (get_turf(T.loc)) + to_chat(C, "You are a Wraith. Though relatively fragile, you are fast, deadly, and even able to phase through walls.") + init_construct(C,SH,SS,T) if("Artificer") - var/mob/living/simple_animal/hostile/construct/builder/Z = new /mob/living/simple_animal/hostile/construct/builder (get_turf(T.loc)) - to_chat(Z, "You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, use magic missile, repair allied constructs (by clicking on them), and most important of all create new constructs (Use your Artificer spell to summon a new construct shell and Summon Soulstone to create a new soulstone).") - init_construct(Z,A,C,T) + var/mob/living/simple_animal/hostile/construct/builder/C = new /mob/living/simple_animal/hostile/construct/builder (get_turf(T.loc)) + to_chat(C, "You are an Artificer. You are incredibly weak and fragile, but you are able to construct fortifications, use magic missile, repair allied constructs (by clicking on them), and most important of all create new constructs (Use your Artificer spell to summon a new construct shell and Summon Soulstone to create a new soulstone).") + init_construct(C,SH,SS,T) else to_chat(U, "Creation failed!: The soul stone is empty! Go kill someone!") return -/proc/init_construct(mob/living/simple_animal/hostile/construct/Z, mob/living/simple_animal/shade/A, obj/item/soulstone/C, obj/structure/constructshell/T) - A.mind.transfer_to(Z) +/proc/init_construct(mob/living/simple_animal/hostile/construct/C, mob/living/simple_animal/shade/SH, obj/item/soulstone/SS, obj/structure/constructshell/T) + SH.mind.transfer_to(C) qdel(T) - qdel(A) - to_chat(Z, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") - Z.cancel_camera() - qdel(C) + qdel(SH) + to_chat(C, "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.") + C.cancel_camera() + qdel(SS) /proc/makeNewConstruct(var/mob/living/simple_animal/hostile/construct/ctype, var/mob/target, var/mob/stoner = null, cultoverride = 0) if(jobban_isbanned(target, "cultist") || jobban_isbanned(target, "Syndicate")) @@ -323,23 +323,22 @@ S.name = "Shade of [T.real_name]" S.real_name = "Shade of [T.real_name]" S.key = T.key - if(U) - S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation - if(!iscultist(U)) - S.mind.store_memory("Serve [U.real_name], your creator.") - if(iscultist(U)) - SSticker.mode.add_cultist(S.mind, 0) - S.mind.special_role = SPECIAL_ROLE_CULTIST - if(iswizard(U)) - SSticker.mode.update_wiz_icons_added(S.mind) - S.mind.special_role = SPECIAL_ROLE_WIZARD_APPRENTICE S.cancel_camera() name = "soulstone: Shade of [T.real_name]" icon_state = "soulstone2" - if(U && iswizard(U)) - to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help them succeed in their goals at all costs.") - else if(U && iscultist(U)) - to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs.") + if(U) + S.faction |= "\ref[U]" //Add the master as a faction, allowing inter-mob cooperation + if(iswizard(U)) + SSticker.mode.update_wiz_icons_added(S.mind) + S.mind.special_role = SPECIAL_ROLE_WIZARD_APPRENTICE + if(iscultist(U)) + SSticker.mode.add_cultist(S.mind, 0) + S.mind.special_role = SPECIAL_ROLE_CULTIST + S.mind.store_memory("Serve the cult's will.") + to_chat(S, "Your soul has been captured! You are now bound to the cult's will. Help them succeed in their goals at all costs.") + else + S.mind.store_memory("Serve [U.real_name], your creator.") + to_chat(S, "Your soul has been captured! You are now bound to [U.real_name]'s will. Help them succeed in their goals at all costs.") if(vic && U) to_chat(U, "Capture successful!: [T.real_name]'s soul has been ripped from [U.p_their()] body and stored within the soul stone.") if(isrobot(T))//Robots have to dust or else they spill out an empty robot brain, and unequiping them spills robot components that shouldn't spawn. From 4705a89676fb73a1e38c2cb922b550ad12e373f8 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Mon, 18 Nov 2019 15:22:15 -0600 Subject: [PATCH 28/59] Makes cluwning ignore brain damage modifiers Update organ_internal.dm --- code/datums/spells/cluwne.dm | 2 +- code/modules/mob/living/carbon/human/human_damage.dm | 5 +++-- code/modules/surgery/organs/organ_internal.dm | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/code/datums/spells/cluwne.dm b/code/datums/spells/cluwne.dm index 6a87419886c..620b64812ee 100644 --- a/code/datums/spells/cluwne.dm +++ b/code/datums/spells/cluwne.dm @@ -17,7 +17,7 @@ var/obj/item/organ/internal/brain/cluwne/idiot_brain = new idiot_brain.insert(src, make_cluwne = 0) idiot_brain.dna = dna.Clone() - setBrainLoss(80) + setBrainLoss(80, ignore_brain_mod = TRUE) set_nutrition(9000) overeatduration = 9000 Confused(30) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 71a3ae3e87c..c844e7a593a 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -39,7 +39,7 @@ update_stat("adjustBrainLoss") return STATUS_UPDATE_STAT -/mob/living/carbon/human/setBrainLoss(amount, updating = TRUE) +/mob/living/carbon/human/setBrainLoss(amount, updating = TRUE, ignore_brain_mod = FALSE) if(status_flags & GODMODE) return STATUS_UPDATE_NONE //godmode @@ -47,7 +47,8 @@ var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) if(dna.species && amount > 0) - amount = amount * dna.species.brain_mod + if(!ignore_brain_mod) + amount = amount * dna.species.brain_mod sponge.damage = Clamp(amount, 0, 120) if(sponge.damage >= 120) visible_message("[src] goes limp, [p_their()] facial expression utterly blank.") diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 98ed11672fb..333fa485e91 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -283,7 +283,7 @@ /obj/item/organ/internal/honktumor/cursed/on_life() //No matter what you do, no matter who you are, no matter where you go, you're always going to be a fat, stuttering dimwit. ..() - owner.setBrainLoss(80) + owner.setBrainLoss(80, ignore_brain_mod = TRUE) owner.set_nutrition(9000) owner.overeatduration = 9000 From 2a54c79256306dbab6fc7a9f1665a7c9ea01dfc0 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Thu, 21 Nov 2019 03:02:53 -0600 Subject: [PATCH 29/59] Adds examine text for people who have open incisions Update examine.dm --- .../mob/living/carbon/human/examine.dm | 32 +++++++++++++++++++ code/modules/surgery/organs/organ_external.dm | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 7a18e881eb6..b859041d02f 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -215,6 +215,12 @@ else if(E.status & ORGAN_SPLINTED) wound_flavor_text["[E.limb_name]"] = "[p_they(TRUE)] [p_have()] a splint on [p_their()] [E.name]!\n" + if(E.open) + if(E.is_robotic()) + msg += "The maintenance hatch on [p_their()] [ignore_limb_branding(E.limb_name)] is open!\n" + else + msg += "[p_their(TRUE)] [ignore_limb_branding(E.limb_name)] has an open incision!\n" + for(var/obj/item/I in E.embedded_objects) msg += "[p_they(TRUE)] [p_have()] \a [bicon(I)] [I] embedded in [p_their()] [E.name]!\n" @@ -403,3 +409,29 @@ return 0 else return 0 + +// Ignores robotic limb branding prefixes like "Morpheus Cybernetics" +/proc/ignore_limb_branding(limb_name) + switch(limb_name) + if("chest") + . = "upper body" + if("groin") + . = "lower body" + if("head") + . = "head" + if("l_arm") + . = "left arm" + if("r_arm") + . = "right arm" + if("l_leg") + . = "left leg" + if("r_leg") + . = "right leg" + if("l_foot") + . = "left foot" + if("r_foot") + . = "right foot" + if("l_hand") + . = "left hand" + if("r_hand") + . = "right hand" diff --git a/code/modules/surgery/organs/organ_external.dm b/code/modules/surgery/organs/organ_external.dm index 2c891632770..1fde13e246e 100644 --- a/code/modules/surgery/organs/organ_external.dm +++ b/code/modules/surgery/organs/organ_external.dm @@ -47,7 +47,7 @@ var/damage_msg = "You feel an intense pain" var/broken_description - var/open = 0 + var/open = 0 // If the body part has an open incision from surgery var/sabotaged = 0 //If a prosthetic limb is emagged, it will detonate when it fails. var/encased // Needs to be opened with a saw to access the organs. From 01f20745b786b5e99e5fd543cc2e55a956900ca4 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 30 Nov 2019 11:52:50 -0500 Subject: [PATCH 30/59] made unbuckle time, the break restraints time --- code/modules/mob/living/carbon/carbon.dm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index fd60d5d49bd..6464031a5d7 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -771,14 +771,19 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) /mob/living/carbon/resist_buckle() + var/breakouttime = 600 + spawn(0) resist_muzzle() if(restrained()) + var/obj/item/I = handcuffed + breakouttime = I.breakouttime + var/displaytime = breakouttime / 600 changeNext_move(CLICK_CD_BREAKOUT) last_special = world.time + CLICK_CD_BREAKOUT visible_message("[src] attempts to unbuckle [p_them()]self!", \ - "You attempt to unbuckle yourself... (This will take around one minute and you need to stay still.)") - if(do_after(src, 600, 0, target = src)) + "You attempt to unbuckle yourself... (This will take around [displaytime] minute and you need to stay still.)") + if(do_after(src, breakouttime, 0, target = src)) if(!buckled) return buckled.user_unbuckle_mob(src,src) From bacbd01cf6c1aa38af8bc08b356960e8d0e091aa Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sun, 1 Dec 2019 18:47:03 -0600 Subject: [PATCH 31/59] Traitor clown fixes --- code/modules/antagonists/traitor/datum_traitor.dm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index 9c06c94bb5b..9e6f1b79bfa 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -28,6 +28,7 @@ forge_traitor_objectives() if(!silent) greet() + apply_innate_effects() update_traitor_icons_added() finalize_traitor() @@ -54,6 +55,7 @@ assigned_targets.Cut() SSticker.mode.traitors -= owner owner.special_role = null + remove_innate_effects() update_traitor_icons_removed() if(!silent && owner.current) @@ -67,8 +69,10 @@ if(owner.assigned_role == "Clown") var/mob/living/carbon/human/traitor_mob = owner.current if(traitor_mob && istype(traitor_mob)) - to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") + to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") traitor_mob.mutations.Remove(CLUMSY) + var/datum/action/innate/toggle_clumsy/A = new + A.Grant(traitor_mob) /datum/antagonist/traitor/remove_innate_effects() @@ -76,7 +80,11 @@ if(owner.assigned_role == "Clown") var/mob/living/carbon/human/traitor_mob = owner.current if(traitor_mob && istype(traitor_mob)) + to_chat(traitor_mob, "You lose your syndicate training and return to your own clumsy, clownish self.") traitor_mob.mutations.Add(CLUMSY) + for(var/datum/action/innate/A in traitor_mob.actions) + if(istype(A, /datum/action/innate/toggle_clumsy)) + A.Remove(traitor_mob) // Adding/removing objectives in the owner's mind until we can datumize all antags. Then we can use the /datum/antagonist/objectives var to handle them // Change "owner.objectives" to "objectives" once objectives are handled in antag datums instead of the mind From 2b88361749cb16e2d1dd556d41886862990ecf53 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Tue, 3 Dec 2019 17:26:39 +0100 Subject: [PATCH 32/59] Fixes the null pointer --- code/modules/power/apc.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 8847b6fdeed..fa7acea6a6d 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -749,7 +749,7 @@ /obj/machinery/power/apc/proc/get_malf_status(mob/living/silicon/ai/malf) - if(istype(malf) && malf.mind.has_antag_datum(/datum/antagonist/traitor) || malf.malf_picker) // If they're a traitor OR they have the malf picker from the combat module + if(istype(malf) && (malf.mind.has_antag_datum(/datum/antagonist/traitor) || malf.malf_picker)) // If they're a traitor OR they have the malf picker from the combat module if(malfai == (malf.parent || malf)) if(occupier == malf) return 3 // 3 = User is shunted in this APC From 1361305bf937ca7a7939626e053705fcc0d3f100 Mon Sep 17 00:00:00 2001 From: Kyep Date: Wed, 4 Dec 2019 21:37:10 -0800 Subject: [PATCH 33/59] Updates links for new domain --- config/example/motd.txt | 2 +- config/example/rules.html | 2 +- goon/browserassets/js/browserOutput.js | 2 +- html/templates/header.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/example/motd.txt b/config/example/motd.txt index 106be771704..f39e579a6f7 100644 --- a/config/example/motd.txt +++ b/config/example/motd.txt @@ -1,5 +1,5 @@

Welcome to Space Station 13!

--This server is running Paradise's modification of the Baystation 12 and /tg/station13 SS13 code. +-This server is running Paradise's modification of the Baystation 12 and /tg/station13 SS13 code.

GitHub: https://github.com/ParadiseSS13/Paradise diff --git a/config/example/rules.html b/config/example/rules.html index c7a717aca63..ef37effcea4 100644 --- a/config/example/rules.html +++ b/config/example/rules.html @@ -4,7 +4,7 @@ diff --git a/goon/browserassets/js/browserOutput.js b/goon/browserassets/js/browserOutput.js index 094e8258562..317fc02b9cb 100644 --- a/goon/browserassets/js/browserOutput.js +++ b/goon/browserassets/js/browserOutput.js @@ -1005,7 +1005,7 @@ $(function() { '
' + '
Choose up to '+opts.highlightLimit+' strings that will highlight the line when they appear in chat.
'+ 'Enable Regex'+ - '
See here for details
' + + '
See here for details
' + '
' + termInputs + '
Paradise Station
-

+

Visit our Discord channel:-Click Here- From 03b9dafae4c28eada6460a853082c213b7080149 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sun, 8 Dec 2019 02:45:18 -0600 Subject: [PATCH 34/59] Sleep clearning effects don't work on mobs who are admin frozen --- code/modules/admin/verbs/freeze.dm | 13 +++++++------ code/modules/mob/living/status_procs.dm | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/code/modules/admin/verbs/freeze.dm b/code/modules/admin/verbs/freeze.dm index 4d60fb72bee..7b53ed26570 100644 --- a/code/modules/admin/verbs/freeze.dm +++ b/code/modules/admin/verbs/freeze.dm @@ -26,7 +26,7 @@ var/global/list/frozen_mob_list = list() /mob/living/var/frozen = null //used for preventing attacks on admin-frozen mobs /mob/living/var/admin_prev_sleeping = 0 //used for keeping track of previous sleeping value with admin freeze -/mob/living/proc/admin_Freeze(var/client/admin, skip_overlays = FALSE) +/mob/living/proc/admin_Freeze(client/admin, skip_overlays = FALSE) if(istype(admin)) to_chat(src, "You have been frozen by [admin]") message_admins("[key_name_admin(admin)] froze [key_name_admin(src)]") @@ -34,24 +34,25 @@ var/global/list/frozen_mob_list = list() var/obj/effect/overlay/adminoverlay/AO = new if(skip_overlays) - src.overlays += AO + overlays += AO - anchored = 1 - frozen = AO + canmove = FALSE admin_prev_sleeping = sleeping AdjustSleeping(20000) + frozen = AO if(!(src in frozen_mob_list)) frozen_mob_list += src -/mob/living/proc/admin_unFreeze(var/client/admin, skip_overlays = FALSE) +/mob/living/proc/admin_unFreeze(client/admin, skip_overlays = FALSE) if(istype(admin)) to_chat(src, "You have been unfrozen by [admin]") message_admins("[key_name_admin(admin)] unfroze [key_name_admin(src)]") log_admin("[key_name(admin)] unfroze [key_name(src)]") - anchored = 0 if(skip_overlays) overlays -= frozen + + canmove = TRUE frozen = null SetSleeping(admin_prev_sleeping) admin_prev_sleeping = null diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 0e1a19da662..28cdc17afeb 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -344,6 +344,8 @@ return SetSleeping(max(sleeping, amount), updating, no_alert) /mob/living/SetSleeping(amount, updating = 1, no_alert = FALSE) + if(frozen) // If the mob has been admin frozen, sleeping should not be changable + return FALSE . = STATUS_UPDATE_STAT if((!!amount) == (!!sleeping)) // We're not changing from + to 0 or vice versa updating = FALSE From 42e2aa7dcebd6c71e7abfd532b2288875f457cc2 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sun, 8 Dec 2019 02:54:30 -0600 Subject: [PATCH 35/59] typo --- code/modules/mob/living/status_procs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 28cdc17afeb..7beb722ae2e 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -344,7 +344,7 @@ return SetSleeping(max(sleeping, amount), updating, no_alert) /mob/living/SetSleeping(amount, updating = 1, no_alert = FALSE) - if(frozen) // If the mob has been admin frozen, sleeping should not be changable + if(frozen) // If the mob has been admin frozen, sleeping should not be changeable return FALSE . = STATUS_UPDATE_STAT if((!!amount) == (!!sleeping)) // We're not changing from + to 0 or vice versa From 254c2daedf184a64dcb56be3ca8bf55bf8095a83 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sun, 8 Dec 2019 10:45:15 -0600 Subject: [PATCH 36/59] re add anchored --- code/modules/admin/verbs/freeze.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/admin/verbs/freeze.dm b/code/modules/admin/verbs/freeze.dm index 7b53ed26570..9b01e94846c 100644 --- a/code/modules/admin/verbs/freeze.dm +++ b/code/modules/admin/verbs/freeze.dm @@ -36,6 +36,7 @@ var/global/list/frozen_mob_list = list() if(skip_overlays) overlays += AO + anchored = TRUE canmove = FALSE admin_prev_sleeping = sleeping AdjustSleeping(20000) @@ -52,6 +53,7 @@ var/global/list/frozen_mob_list = list() if(skip_overlays) overlays -= frozen + anchored = FALSE canmove = TRUE frozen = null SetSleeping(admin_prev_sleeping) From f2f09f1edf3cd7b3b5f0972120436342824e8324 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sun, 8 Dec 2019 10:52:04 -0600 Subject: [PATCH 37/59] mirrors ignore brain mod functionality onto adjustBrainLoss --- code/modules/mob/living/carbon/human/human_damage.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index c844e7a593a..4ace483a1f9 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -22,7 +22,7 @@ med_hud_set_status() handle_hud_icons_health() -/mob/living/carbon/human/adjustBrainLoss(amount, updating = TRUE) +/mob/living/carbon/human/adjustBrainLoss(amount, updating = TRUE, ignore_brain_mod = FALSE) if(status_flags & GODMODE) return STATUS_UPDATE_NONE //godmode @@ -30,7 +30,8 @@ var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) if(dna.species && amount > 0) - amount = amount * dna.species.brain_mod + if(!ignore_brain_mod) + amount = amount * dna.species.brain_mod sponge.damage = Clamp(sponge.damage + amount, 0, 120) if(sponge.damage >= 120) visible_message("[src] goes limp, [p_their()] facial expression utterly blank.") From 8cf4c7c66ab7e3671360ba396e94f0e58cad5146 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Dec 2019 18:11:05 -0500 Subject: [PATCH 38/59] cleaned my poor quality code --- code/modules/mob/living/carbon/carbon.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 6464031a5d7..c5bf235befd 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -771,13 +771,11 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle)) /mob/living/carbon/resist_buckle() - var/breakouttime = 600 - spawn(0) resist_muzzle() if(restrained()) var/obj/item/I = handcuffed - breakouttime = I.breakouttime + var/breakouttime = I.breakouttime var/displaytime = breakouttime / 600 changeNext_move(CLICK_CD_BREAKOUT) last_special = world.time + CLICK_CD_BREAKOUT From 53fa06aff60f966dd0f3e0aee98114e436e8e322 Mon Sep 17 00:00:00 2001 From: Kyep Date: Tue, 10 Dec 2019 13:54:36 -0800 Subject: [PATCH 39/59] Fixes headcrab bugs --- .../mob/living/simple_animal/hostile/headcrab.dm | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index e48d980c2a4..ece990c7743 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -19,7 +19,7 @@ attack_sound = 'sound/creatures/headcrab_attack.ogg' speak_emote = list("hisses") var/is_zombie = 0 - stat_attack = DEAD //so they continue to attack when they are on the ground. + stat_attack = DEAD // Necessary for them to attack (zombify) dead humans robust_searching = 1 var/host_species = "" var/list/human_overlays = list() @@ -37,7 +37,7 @@ visible_message("[src] consumes [target] whole!") if(health < maxHealth) health += 10 - qdel(K) + qdel(K) break cycles = 0 cycles++ @@ -71,6 +71,7 @@ melee_damage_lower = 10 melee_damage_upper = 15 ranged = 0 + stat_attack = CONSCIOUS // Disables their targeting of dead mobs once they're already a zombie icon = H.icon speak = list('sound/creatures/zombie_idle1.ogg','sound/creatures/zombie_idle2.ogg','sound/creatures/zombie_idle3.ogg') speak_chance = 50 @@ -118,7 +119,13 @@ I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod_gray") overlays += I - +/mob/living/simple_animal/hostile/headcrab/CanAttack(atom/the_target) + if(stat_attack == DEAD && isliving(the_target) && !ishuman(the_target)) + var/mob/living/L = the_target + if(L.stat == DEAD) + // Override default behavior of stat_attack, to stop headcrabs targeting dead mobs they cannot infect, such as silicons. + return FALSE + return ..() /mob/living/simple_animal/hostile/headcrab/fast name = "fast headcrab" From f6c1a388a3a8d93a04e90a3db19f0042b94235d8 Mon Sep 17 00:00:00 2001 From: Arvenius169 <56715097+Arvenius169@users.noreply.github.com> Date: Wed, 11 Dec 2019 15:29:07 -0500 Subject: [PATCH 40/59] Racial Loadout Items Placement Fix --- code/modules/client/preference/loadout/loadout_racial.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/client/preference/loadout/loadout_racial.dm b/code/modules/client/preference/loadout/loadout_racial.dm index 38d216ae156..1c7cf132cfc 100644 --- a/code/modules/client/preference/loadout/loadout_racial.dm +++ b/code/modules/client/preference/loadout/loadout_racial.dm @@ -1,6 +1,7 @@ /datum/gear/racial sort_category = "Racial" subtype_path = /datum/gear/racial + slot = slot_glasses cost = 2 @@ -40,4 +41,5 @@ /datum/gear/racial/footwraps display_name = "cloth footwraps" path = /obj/item/clothing/shoes/footwraps - cost = 1 \ No newline at end of file + slot = slot_shoes + cost = 1 From efb2d3cd5c324df8b6f33c8a8e0fe9b6e3c72243 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Dec 2019 18:46:42 -0500 Subject: [PATCH 41/59] fixed 3 UOD bugs --- code/game/machinery/recycler.dm | 1 + .../objects/structures/crates_lockers/closets/utility_closets.dm | 1 + code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm | 1 + 3 files changed, 3 insertions(+) diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index eb3052dd909..eecdc0e4f4a 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -8,6 +8,7 @@ var/const/SAFETY_COOLDOWN = 100 layer = MOB_LAYER+1 // Overhead anchored = 1 density = 1 + damage_deflection = 10 var/safety_mode = 0 // Temporarily stops machine if it detects a mob var/icon_name = "grinder-o" var/blood = 0 diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm index a89bce34396..504d2b29644 100644 --- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm @@ -104,6 +104,7 @@ icon_opened = "toolclosetopen" /obj/structure/closet/toolcloset/New() + ..() if(prob(40)) new /obj/item/clothing/suit/storage/hazardvest(src) if(prob(70)) diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index f8c65089324..6a2180efcac 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -8,6 +8,7 @@ max_integrity = 120 var/image/nest_overlay comfort = 0 + flags = NODECONSTRUCT /obj/structure/bed/nest/New() nest_overlay = image('icons/mob/alien.dmi', "nestoverlay", layer=MOB_LAYER - 0.2) From 4af6e8a24302974c6e28f21d63da2f67b557a831 Mon Sep 17 00:00:00 2001 From: Nokko Date: Wed, 11 Dec 2019 21:41:45 -0800 Subject: [PATCH 42/59] Fix minor spelling error in surgery ```diff -- KOM-RAD's hand slips, tearing blood vessals and causing massive bleeding in Vampy The Vampiric Clown's lower body with the hemostat! ++ KOM-RAD's hand slips, tearing blood vessels and causing massive bleeding in Vampy The Vampiric Clown's lower body with the hemostat! ``` --- code/modules/surgery/generic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index c66d95df899..54a9c4c88be 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -83,7 +83,7 @@ /datum/surgery_step/generic/clamp_bleeders/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool,datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) - user.visible_message(" [user]'s hand slips, tearing blood vessals and causing massive bleeding in [target]'s [affected.name] with \the [tool]!", \ + user.visible_message(" [user]'s hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.name] with \the [tool]!", \ " Your hand slips, tearing blood vessels and causing massive bleeding in [target]'s [affected.name] with \the [tool]!",) affected.receive_damage(10) return 0 From dcfcd31c866406b90548191ae3612ffcdea43e55 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Thu, 12 Dec 2019 15:59:33 +0100 Subject: [PATCH 43/59] Change the nested if to a early return check. Refactor to use enums --- code/modules/power/apc.dm | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index fa7acea6a6d..4d7dafa69bf 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -30,6 +30,11 @@ #define APC_UPDATE_ICON_COOLDOWN 200 // 20 seconds +// APC malf status +#define APC_MALF_NOT_HACKED 1 +#define APC_MALF_HACKED 2 // APC hacked by user, and user is in its core. +#define APC_MALF_SHUNTED_HERE 3 // User is shunted in this APC +#define APC_MALF_SHUNTED_OTHER 4 // User is shunted in another APC // the Area Power Controller (APC), formerly Power Distribution Unit (PDU) // one per area, needs wire conection to power network through a terminal @@ -749,18 +754,22 @@ /obj/machinery/power/apc/proc/get_malf_status(mob/living/silicon/ai/malf) - if(istype(malf) && (malf.mind.has_antag_datum(/datum/antagonist/traitor) || malf.malf_picker)) // If they're a traitor OR they have the malf picker from the combat module - if(malfai == (malf.parent || malf)) - if(occupier == malf) - return 3 // 3 = User is shunted in this APC - else if(istype(malf.loc, /obj/machinery/power/apc)) - return 4 // 4 = User is shunted in another APC - else - return 2 // 2 = APC hacked by user, and user is in its core. + if(!istype(malf)) + return FALSE + + // Only if they're a traitor OR they have the malf picker from the combat module + if(!malf.mind.has_antag_datum(/datum/antagonist/traitor) && !malf.malf_picker) + return FALSE + + if(malfai == (malf.parent || malf)) + if(occupier == malf) + return APC_MALF_SHUNTED_HERE + else if(istype(malf.loc, /obj/machinery/power/apc)) + return APC_MALF_SHUNTED_OTHER else - return 1 // 1 = APC not hacked. + return APC_MALF_HACKED else - return 0 // 0 = User is not a Malf AI + return APC_MALF_NOT_HACKED /obj/machinery/power/apc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) if(!user) @@ -1008,7 +1017,7 @@ /obj/machinery/power/apc/proc/malfhack(mob/living/silicon/ai/malf) if(!istype(malf)) return - if(get_malf_status(malf) != 1) + if(get_malf_status(malf) != APC_MALF_NOT_HACKED) return if(malf.malfhacking) to_chat(malf, "You are already hacking an APC.") From 08bceebcb18a987a44e877eb32574feb248f3aad Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Thu, 12 Dec 2019 16:20:38 +0100 Subject: [PATCH 44/59] Move the handle_changeling proc to a signal --- code/__DEFINES/components.dm | 1 + code/game/gamemodes/changeling/evolution_menu.dm | 5 +++++ code/modules/mob/living/carbon/life.dm | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index df957eaa11e..f9fba3ff4a4 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -155,6 +155,7 @@ // /mob/living/carbon signals #define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) +#define COMSIG_CARBON_LIFE "carbon_life" //from base of mob/living/carbon/Life() () // /mob/living/simple_animal/hostile signals #define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget" diff --git a/code/game/gamemodes/changeling/evolution_menu.dm b/code/game/gamemodes/changeling/evolution_menu.dm index b6a0213f82f..a9d1c3bb480 100644 --- a/code/game/gamemodes/changeling/evolution_menu.dm +++ b/code/game/gamemodes/changeling/evolution_menu.dm @@ -383,6 +383,9 @@ var/list/sting_paths var/mob/living/carbon/C = src //only carbons have dna now, so we have to typecaste mind.changeling.absorbed_dna |= C.dna.Clone() mind.changeling.trim_dna() + + RegisterSignal(C, COMSIG_CARBON_LIFE, CALLBACK(C, /mob/living/carbon/.proc/handle_changeling)) + return 1 //Used to dump the languages from the changeling datum into the actual mob. @@ -421,6 +424,8 @@ var/list/sting_paths if(hud_used) hud_used.lingstingdisplay.icon_state = null hud_used.lingstingdisplay.invisibility = 101 + hud_used.lingchemdisplay.invisibility = 101 + UnregisterSignal(src, COMSIG_CARBON_LIFE) /datum/changeling/proc/has_sting(datum/action/power) for(var/datum/action/P in purchasedpowers) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 5352ba525f1..6898b75b485 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -13,13 +13,13 @@ for(var/obj/item/organ/internal/O in internal_organs) O.on_life() - handle_changeling() handle_wetness(times_fired) // Increase germ_level regularly if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level germ_level++ + SEND_SIGNAL(src, COMSIG_CARBON_LIFE, seconds, times_fired) /////////////// // BREATHING // From f005908970c35a09701347b74986a025cfcf4993 Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Thu, 12 Dec 2019 17:25:15 +0100 Subject: [PATCH 45/59] Fixes the juggernaut reflect and refactors the reflect to be a proc instead of copy pasta --- .../mob/living/carbon/human/human_defense.dm | 16 ++-------------- .../mob/living/carbon/human/species/golem.dm | 14 ++------------ .../mob/living/simple_animal/constructs.dm | 14 +------------- code/modules/projectiles/projectile.dm | 15 +++++++++++++++ 4 files changed, 20 insertions(+), 39 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 6c1cfeb7714..037b9fb7d87 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -16,20 +16,8 @@ emp_act if(check_reflect(def_zone)) // Checks if you've passed a reflection% check visible_message("The [P.name] gets reflected by [src]!", \ "The [P.name] gets reflected by [src]!") - // Find a turf near or on the original location to bounce to - if(P.starting) - var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) - var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) - var/turf/curloc = get_turf(src) - - // redirect the projectile - P.firer = src - P.original = locate(new_x, new_y, P.z) - P.starting = curloc - P.current = curloc - P.yo = new_y - curloc.y - P.xo = new_x - curloc.x - P.Angle = null + + P.reflect_back(src) return -1 // complete projectile permutation diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index 7c92d8748bd..f88670fc0c1 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -474,19 +474,9 @@ if(P.is_reflectable) H.visible_message("The [P.name] gets reflected by [H]'s glass skin!", \ "The [P.name] gets reflected by [H]'s glass skin!") - if(P.starting) - var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) - var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) - var/turf/curloc = get_turf(H) + + P.reflect_back(H) - // redirect the projectile - P.firer = src - P.original = locate(new_x, new_y, P.z) - P.starting = curloc - P.current = curloc - P.yo = new_y - curloc.y - P.xo = new_x - curloc.x - P.Angle = null return FALSE return TRUE diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 0c003b9e3b8..b41f7f3837a 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -132,19 +132,7 @@ visible_message("The [P.name] gets reflected by [src]'s shell!", \ "The [P.name] gets reflected by [src]'s shell!") - // Find a turf near or on the original location to bounce to - if(P.starting) - var/new_x = P.starting.x + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) - var/new_y = P.starting.y + pick(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3) - var/turf/curloc = get_turf(src) - - // redirect the projectile - P.original = locate(new_x, new_y, P.z) - P.starting = curloc - P.current = curloc - P.firer = src - P.yo = new_y - curloc.y - P.xo = new_x - curloc.x + P.reflect_back(src, list(0, 0, -1, 1, -2, 2, -2, 2, -2, 2, -3, 3, -3, 3)) return -1 // complete projectile permutation diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index dc798e10830..a02c301ec01 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -302,6 +302,21 @@ Range() sleep(1) +obj/item/projectile/proc/reflect_back(atom/source, list/position_modifiers = list(0, 0, 0, 0, 0, -1, 1, -2, 2)) + if(starting) + var/new_x = starting.x + pick(position_modifiers) + var/new_y = starting.y + pick(position_modifiers) + var/turf/curloc = get_turf(source) + + // redirect the projectile + firer = source + original = locate(new_x, new_y, z) + starting = curloc + current = curloc + yo = new_y - curloc.y + xo = new_x - curloc.x + Angle = null // Will be calculated in fire() + obj/item/projectile/Crossed(atom/movable/AM, oldloc) //A mob moving on a tile with a projectile is hit by it. ..() if(isliving(AM) && AM.density && !checkpass(PASSMOB)) From f3ad67bd73cc5942e7e8ff2fad95d8423ed05fff Mon Sep 17 00:00:00 2001 From: Darkmight9 <45213755+Darkmight9@users.noreply.github.com> Date: Thu, 12 Dec 2019 17:27:52 -0500 Subject: [PATCH 46/59] Changes the spray bottle in the full janitor belt to one with space cleaner in it --- code/game/objects/items/weapons/storage/belt.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 5560f3b4306..0ebd553fc3b 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -396,7 +396,7 @@ ..() new /obj/item/lightreplacer(src) new /obj/item/holosign_creator(src) - new /obj/item/reagent_containers/spray(src) + new /obj/item/reagent_containers/spray/cleaner(src) new /obj/item/soap(src) new /obj/item/grenade/chem_grenade/cleaner(src) new /obj/item/grenade/chem_grenade/cleaner(src) From 46ea323cf3b7a9f61b8088aef3110aa34491bdea Mon Sep 17 00:00:00 2001 From: Arvenius169 <56715097+Arvenius169@users.noreply.github.com> Date: Fri, 13 Dec 2019 18:40:26 -0500 Subject: [PATCH 47/59] Update loadout_racial.dm --- .../client/preference/loadout/loadout_racial.dm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/modules/client/preference/loadout/loadout_racial.dm b/code/modules/client/preference/loadout/loadout_racial.dm index 1c7cf132cfc..1c693db9d2e 100644 --- a/code/modules/client/preference/loadout/loadout_racial.dm +++ b/code/modules/client/preference/loadout/loadout_racial.dm @@ -1,39 +1,39 @@ /datum/gear/racial sort_category = "Racial" subtype_path = /datum/gear/racial - slot = slot_glasses + +/datum/gear/racial/taj cost = 2 - -/datum/gear/racial/tajciv +/datum/gear/racial/taj/civ display_name = "embroidered veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." path = /obj/item/clothing/glasses/tajblind cost = 1 -/datum/gear/racial/tajsec +/datum/gear/racial/taj/sec display_name = "sleek veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built security HUD." path = /obj/item/clothing/glasses/hud/security/tajblind allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot", "Internal Affairs Agent", "Magistrate") -/datum/gear/racial/tajmed +/datum/gear/racial/taj/med display_name = "lightweight veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built medical HUD." path = /obj/item/clothing/glasses/hud/health/tajblind allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Psychiatrist", "Paramedic", "Virologist", "Brig Physician" , "Coroner") -/datum/gear/racial/tajsci +/datum/gear/racial/taj/sci display_name = "hi-tech veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." path = /obj/item/clothing/glasses/tajblind/sci -/datum/gear/racial/tajeng +/datum/gear/racial/taj/eng display_name = "industrial veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." path = /obj/item/clothing/glasses/tajblind/eng -/datum/gear/racial/tajcargo +/datum/gear/racial/taj/cargo display_name = "khaki veil" description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. It is light and comfy!" path = /obj/item/clothing/glasses/tajblind/cargo From a94916d5f31438649918b8b7bb5cd7888e61248c Mon Sep 17 00:00:00 2001 From: Arvenius169 <56715097+Arvenius169@users.noreply.github.com> Date: Fri, 13 Dec 2019 18:44:34 -0500 Subject: [PATCH 48/59] Update loadout_racial.dm --- code/modules/client/preference/loadout/loadout_racial.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/client/preference/loadout/loadout_racial.dm b/code/modules/client/preference/loadout/loadout_racial.dm index 1c693db9d2e..2acec90e7b7 100644 --- a/code/modules/client/preference/loadout/loadout_racial.dm +++ b/code/modules/client/preference/loadout/loadout_racial.dm @@ -3,6 +3,7 @@ subtype_path = /datum/gear/racial /datum/gear/racial/taj + slot = slot_glasses cost = 2 /datum/gear/racial/taj/civ From df2de1931e9bebcc649b56face01b1e4588b5f47 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sat, 14 Dec 2019 00:13:28 -0600 Subject: [PATCH 49/59] use_brain_mod --- code/datums/spells/cluwne.dm | 2 +- code/modules/mob/living/carbon/human/human_damage.dm | 8 ++++---- code/modules/surgery/organs/organ_internal.dm | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/datums/spells/cluwne.dm b/code/datums/spells/cluwne.dm index 620b64812ee..58a33e31a44 100644 --- a/code/datums/spells/cluwne.dm +++ b/code/datums/spells/cluwne.dm @@ -17,7 +17,7 @@ var/obj/item/organ/internal/brain/cluwne/idiot_brain = new idiot_brain.insert(src, make_cluwne = 0) idiot_brain.dna = dna.Clone() - setBrainLoss(80, ignore_brain_mod = TRUE) + setBrainLoss(80, use_brain_mod = FALSE) set_nutrition(9000) overeatduration = 9000 Confused(30) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 4ace483a1f9..65a75f80e8c 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -22,7 +22,7 @@ med_hud_set_status() handle_hud_icons_health() -/mob/living/carbon/human/adjustBrainLoss(amount, updating = TRUE, ignore_brain_mod = FALSE) +/mob/living/carbon/human/adjustBrainLoss(amount, updating = TRUE, use_brain_mod = TRUE) if(status_flags & GODMODE) return STATUS_UPDATE_NONE //godmode @@ -30,7 +30,7 @@ var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) if(dna.species && amount > 0) - if(!ignore_brain_mod) + if(use_brain_mod) amount = amount * dna.species.brain_mod sponge.damage = Clamp(sponge.damage + amount, 0, 120) if(sponge.damage >= 120) @@ -40,7 +40,7 @@ update_stat("adjustBrainLoss") return STATUS_UPDATE_STAT -/mob/living/carbon/human/setBrainLoss(amount, updating = TRUE, ignore_brain_mod = FALSE) +/mob/living/carbon/human/setBrainLoss(amount, updating = TRUE, use_brain_mod = TRUE) if(status_flags & GODMODE) return STATUS_UPDATE_NONE //godmode @@ -48,7 +48,7 @@ var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain) if(sponge) if(dna.species && amount > 0) - if(!ignore_brain_mod) + if(use_brain_mod) amount = amount * dna.species.brain_mod sponge.damage = Clamp(amount, 0, 120) if(sponge.damage >= 120) diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 333fa485e91..25f87d71104 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -283,7 +283,7 @@ /obj/item/organ/internal/honktumor/cursed/on_life() //No matter what you do, no matter who you are, no matter where you go, you're always going to be a fat, stuttering dimwit. ..() - owner.setBrainLoss(80, ignore_brain_mod = TRUE) + owner.setBrainLoss(80, use_brain_mod = FALSE) owner.set_nutrition(9000) owner.overeatduration = 9000 From d13100676f257198fb37fb4cb40ce8f0b768734c Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sat, 14 Dec 2019 00:14:46 -0600 Subject: [PATCH 50/59] remove false --- code/modules/mob/living/status_procs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 7beb722ae2e..72f136304d7 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -345,7 +345,7 @@ /mob/living/SetSleeping(amount, updating = 1, no_alert = FALSE) if(frozen) // If the mob has been admin frozen, sleeping should not be changeable - return FALSE + return . = STATUS_UPDATE_STAT if((!!amount) == (!!sleeping)) // We're not changing from + to 0 or vice versa updating = FALSE From febda8b6ec581973f890fe9c332c8e5129d1b6fe Mon Sep 17 00:00:00 2001 From: Kyep Date: Sat, 14 Dec 2019 13:07:58 -0800 Subject: [PATCH 51/59] Disables floor cluwne event --- code/modules/events/event_container.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 1c99d2d1bc0..ece0b5c607e 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -197,8 +197,8 @@ var/list/event_last_fired = list() new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 15), 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Traders", /datum/event/traders, 180, is_one_shot = 1), new /datum/event_meta(EVENT_LEVEL_MAJOR, "Terror Spiders", /datum/event/spider_terror, 0, list(ASSIGNMENT_SECURITY = 15), is_one_shot = 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Slaughter Demon", /datum/event/spawn_slaughter, 15, is_one_shot = 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Floor Cluwne", /datum/event/spawn_floor_cluwne, 15, is_one_shot = 1) + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Slaughter Demon", /datum/event/spawn_slaughter, 15, is_one_shot = 1) + //new /datum/event_meta(EVENT_LEVEL_MAJOR, "Floor Cluwne", /datum/event/spawn_floor_cluwne, 15, is_one_shot = 1) ) From d911954920005cf2a18c1dd7cf7c28aed134db61 Mon Sep 17 00:00:00 2001 From: FreeStylaLT Date: Sun, 15 Dec 2019 12:04:29 +0200 Subject: [PATCH 52/59] Fixes reflectors and a Projectile angle bug --- code/game/objects/structures/reflector.dm | 6 +++++- code/modules/power/singularity/emitter.dm | 1 + code/modules/projectiles/projectile.dm | 3 +-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm index e3ebb0579a4..51738446750 100644 --- a/code/game/objects/structures/reflector.dm +++ b/code/game/objects/structures/reflector.dm @@ -12,9 +12,9 @@ /obj/structure/reflector/bullet_act(obj/item/projectile/P) var/turf/reflector_turf = get_turf(src) var/turf/reflect_turf - var/new_dir = get_reflection(dir, P.dir) if(!istype(P, /obj/item/projectile/beam)) return ..() + var/new_dir = get_reflection(dir, P.dir) if(new_dir) reflect_turf = get_step(reflect_turf, new_dir) else @@ -30,6 +30,10 @@ P.current = reflector_turf P.yo = reflect_turf.y - reflector_turf.y P.xo = reflect_turf.x - reflector_turf.x + P.ignore_source_check = TRUE //If shot by a laser, will now hit the mob that fired it + var/reflect_angle = dir2angle(new_dir) + P.setAngle(reflect_angle) + new_dir = 0 return -1 diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 8977062c947..82d78e99e53 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -254,6 +254,7 @@ shot_number = 0 P.setDir(dir) P.starting = loc + P.Angle = null P.fire() return P diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index dc798e10830..a2575634d98 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -240,8 +240,7 @@ if(!paused) if((!( current ) || loc == current)) current = locate(Clamp(x+xo,1,world.maxx),Clamp(y+yo,1,world.maxy),z) - - if(!Angle) + if(isnull(Angle)) Angle=round(Get_Angle(src,current)) if(spread) Angle += (rand() - 0.5) * spread From 4003be153dcbab90025b0a5e79392508b13a159a Mon Sep 17 00:00:00 2001 From: joep van der velden Date: Mon, 16 Dec 2019 22:28:47 +0100 Subject: [PATCH 53/59] firer can't be a non mob --- code/modules/projectiles/projectile.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index a02c301ec01..4c62a1dce1d 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -308,8 +308,12 @@ obj/item/projectile/proc/reflect_back(atom/source, list/position_modifiers = lis var/new_y = starting.y + pick(position_modifiers) var/turf/curloc = get_turf(source) + if(ismob(source)) + firer = source // The reflecting mob will be the new firer + else + firer = null // Reflected by something other than a mob so firer will be null + // redirect the projectile - firer = source original = locate(new_x, new_y, z) starting = curloc current = curloc From fc650c273a1c15f00a75b407b56f7273fa4ddb58 Mon Sep 17 00:00:00 2001 From: Kyep Date: Mon, 16 Dec 2019 18:55:51 -0800 Subject: [PATCH 54/59] domain links update 2 --- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- README.md | 4 ++-- code/controllers/subsystem/jobs.dm | 18 +++++++++--------- .../gamemodes/miniantags/revenant/revenant.dm | 2 +- code/game/gamemodes/shadowling/shadowling.dm | 2 +- code/game/objects/items/weapons/manuals.dm | 8 ++++---- .../living/simple_animal/hostile/hellhound.dm | 2 +- .../hostile/terror_spiders/black.dm | 2 +- .../hostile/terror_spiders/empress.dm | 2 +- .../hostile/terror_spiders/gray.dm | 2 +- .../hostile/terror_spiders/green.dm | 2 +- .../hostile/terror_spiders/mother.dm | 2 +- .../hostile/terror_spiders/prince.dm | 2 +- .../hostile/terror_spiders/princess.dm | 2 +- .../hostile/terror_spiders/purple.dm | 2 +- .../hostile/terror_spiders/red.dm | 2 +- .../hostile/terror_spiders/white.dm | 2 +- html/changelog.html | 3 +-- 18 files changed, 30 insertions(+), 31 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 2f58d4e9ebb..a8a0459bcb1 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,4 +7,4 @@ assignees: '' --- -Please place all features requests here: https://nanotrasen.se/forum/60-suggestions/ +Please place all features requests here: https://www.paradisestation.org/forum/60-suggestions/ diff --git a/README.md b/README.md index d60fe8006c8..eafdb5ffe91 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![forthebadge](http://forthebadge.com/images/badges/contains-technical-debt.svg)](http://forthebadge.com) [![forthebadge](http://forthebadge.com/images/badges/fuck-it-ship-it.svg)](http://forthebadge.com) -[Website](https://nanotrasen.se/) - [Code](https://github.com/ParadiseSS13/Paradise) - [Discord](https://discordapp.com/invite/YJDsXFE) +[Website](https://www.paradisestation.org/) - [Code](https://github.com/ParadiseSS13/Paradise) - [Discord](https://discordapp.com/invite/YJDsXFE) --- @@ -104,7 +104,7 @@ Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/paradise_schema.sql or /SQL/paradise_schema_prefix.sql, depending on if you want table prefixes. More detailed setup instructions are located on our wiki: -https://nanotrasen.se/wiki/index.php/Setting_up_the_Database +https://www.paradisestation.org/wiki/index.php/Setting_up_the_Database --- diff --git a/code/controllers/subsystem/jobs.dm b/code/controllers/subsystem/jobs.dm index 166083b36ff..504a2d74a2c 100644 --- a/code/controllers/subsystem/jobs.dm +++ b/code/controllers/subsystem/jobs.dm @@ -421,23 +421,23 @@ SUBSYSTEM_DEF(jobs) to_chat(H, "You are the [alt_title ? alt_title : rank].") to_chat(H, "As the [alt_title ? alt_title : rank] you answer directly to [job.supervisors]. Special circumstances may change this.") - to_chat(H, "For more information on how the station works, see Standard Operating Procedure (SOP)") + to_chat(H, "For more information on how the station works, see Standard Operating Procedure (SOP)") if(job.is_service) - to_chat(H, "As a member of Service, make sure to read up on your Department SOP") + to_chat(H, "As a member of Service, make sure to read up on your Department SOP") if(job.is_supply) - to_chat(H, "As a member of Supply, make sure to read up on your Department SOP") + to_chat(H, "As a member of Supply, make sure to read up on your Department SOP") if(job.is_command) - to_chat(H, "As an important member of Command, read up on your Department SOP") + to_chat(H, "As an important member of Command, read up on your Department SOP") if(job.is_legal) - to_chat(H, "Your job requires complete knowledge of Space Law and Legal Standard Operating Procedure") + to_chat(H, "Your job requires complete knowledge of Space Law and Legal Standard Operating Procedure") if(job.is_engineering) - to_chat(H, "As a member of Engineering, make sure to read up on your Department SOP") + to_chat(H, "As a member of Engineering, make sure to read up on your Department SOP") if(job.is_medical) - to_chat(H, "As a member of Medbay, make sure to read up on your Department SOP") + to_chat(H, "As a member of Medbay, make sure to read up on your Department SOP") if(job.is_science) - to_chat(H, "As a member of Science, make sure to read up on your Department SOP") + to_chat(H, "As a member of Science, make sure to read up on your Department SOP") if(job.is_security) - to_chat(H, "As a member of Security, you are to know Space Law, Legal Standard Operating Procedure, as well as your Department SOP") + to_chat(H, "As a member of Security, you are to know Space Law, Legal Standard Operating Procedure, as well as your Department SOP") if(job.req_admin_notify) to_chat(H, "You are playing a job that is important for the game progression. If you have to disconnect, please notify the admins via adminhelp.") diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index b761af6db92..f86f018757e 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -162,7 +162,7 @@ to_chat(src, "You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.") to_chat(src, "To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.") to_chat(src, "You do not remember anything of your past lives, nor will you remember anything about this one after your death.") - to_chat(src, "Be sure to read the wiki page at http://nanotrasen.se/wiki/index.php/Revenant to learn more.") + to_chat(src, "Be sure to read the wiki page at http://www.paradisestation.org/wiki/index.php/Revenant to learn more.") var/datum/objective/revenant/objective = new objective.owner = mind mind.objectives += objective diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index b580f88c0b7..b4b4b265711 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -126,7 +126,7 @@ Made by Xhuis to_chat(shadow.current, "Currently, you are disguised as an employee aboard [world.name].") to_chat(shadow.current, "In your limited state, you have two abilities: Hatch and Shadowling Hivemind (:8).") to_chat(shadow.current, "Any other shadowlings are your allies. You must assist them as they shall assist you.") - to_chat(shadow.current, "If you are new to shadowling, or want to read about abilities, check the wiki page at http://nanotrasen.se/wiki/index.php/Shadowling
") + to_chat(shadow.current, "If you are new to shadowling, or want to read about abilities, check the wiki page at https://www.paradisestation.org/wiki/index.php/Shadowling
") diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index 4d36c640784..4cc4cb948ce 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -18,7 +18,7 @@ - + @@ -164,7 +164,7 @@ - + @@ -805,7 +805,7 @@ - + @@ -828,7 +828,7 @@ - + diff --git a/code/modules/mob/living/simple_animal/hostile/hellhound.dm b/code/modules/mob/living/simple_animal/hostile/hellhound.dm index 201c4c07992..9107aa03457 100644 --- a/code/modules/mob/living/simple_animal/hostile/hellhound.dm +++ b/code/modules/mob/living/simple_animal/hostile/hellhound.dm @@ -1,6 +1,6 @@ // Hellhound /mob/living/simple_animal/hostile/hellhound - // Sprites by FoS: http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 + // Sprites by FoS: https://www.paradisestation.org/forum/profile/335-fos name = "Lesser Hellhound" desc = "A demonic-looking black canine monster with glowing red eyes and sharp teeth. A firey, lava-like substance drips from it." icon_state = "hellhound" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm index c9dc370648a..eae926b88e1 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/black.dm @@ -6,7 +6,7 @@ // -------------: AI: attacks to inject its venom, then retreats. Will inject its enemies multiple times then hang back to ensure they die. // -------------: SPECIAL: venom that does more damage the more of it is in you // -------------: TO FIGHT IT: if bitten once, retreat, get charcoal/etc treatment, and come back with a gun. -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/black name = "Black Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm index 1c6fcdb6e5d..fd30532a7bc 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/empress.dm @@ -5,7 +5,7 @@ // -------------: AI: none - this is strictly adminspawn-only and intended for RP events, coder testing, and teaching people 'how to queen' // -------------: SPECIAL: Lay Eggs ability that allows laying queen-level eggs. // -------------: TO FIGHT IT: run away screaming? -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/queen/empress name = "Empress of Terror" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm index 14aa2b9299a..c06a7c2fee6 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/gray.dm @@ -6,7 +6,7 @@ // -------------: AI: hides in vents, emerges when prey is near to kill it, then hides again. Intended to scare normal crew. // -------------: SPECIAL: invisible when on top of a vent, emerges when prey approaches or gets trapped in webs. // -------------: TO FIGHT IT: shoot it through a window, or make it regret ambushing you -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/gray name = "Gray Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm index 43d21286f8f..e7daced65ff 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/green.dm @@ -6,7 +6,7 @@ // -------------: AI: after it kills you, it webs you and lays new terror eggs on your body // -------------: SPECIAL: can also create webs, web normal objects, etc // -------------: TO FIGHT IT: kill it however you like - just don't die to it! -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/green name = "Green Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm index d1e171d2f55..65a3ff3db47 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/mother.dm @@ -6,7 +6,7 @@ // -------------: AI: no special ai // -------------: SPECIAL: spawns an ungodly number of spiderlings when killed // -------------: TO FIGHT IT: don't! Just leave it alone! It is harmless by itself... but god help you if you aggro it. -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/mother name = "Mother of Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm index 646e9e50660..e486872abbb 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/prince.dm @@ -6,7 +6,7 @@ // -------------: AI: no special ai // -------------: SPECIAL: massive health // -------------: TO FIGHT IT: a squad of at least 4 people with laser rifles. -// -------------: SPRITES FROM: Travelling Merchant, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=2766 +// -------------: SPRITES FROM: Travelling Merchant, https://www.paradisestation.org/forum/profile/2715-travelling-merchant/ /mob/living/simple_animal/hostile/poison/terror_spider/prince name = "Prince of Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm index 419f2a617f6..828e0e5f8f6 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/princess.dm @@ -6,7 +6,7 @@ // -------------: AI: as green, but will evolve to queen when it can // -------------: SPECIAL: can evolve into a queen, if fed enough // -------------: TO FIGHT IT: kill it before it evolves -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/princess name = "Princess of Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm index 62832527293..92c7688e1e1 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/purple.dm @@ -6,7 +6,7 @@ // -------------: AI: dies if too far from queen // -------------: SPECIAL: chance to stun on hit // -------------: TO FIGHT IT: shoot it from range, bring friends! -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/purple name = "Purple Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm index 3f16eb44837..a96486e473e 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/red.dm @@ -7,7 +7,7 @@ // -------------: AI: uses very powerful fangs to wreck people in melee // -------------: SPECIAL: the more you hurt it, the harder it bites you // -------------: TO FIGHT IT: shoot it from range. Kite it. -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/red name = "Red Terror spider" diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm index 8b5010c9d25..f62167792a3 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/white.dm @@ -5,7 +5,7 @@ // -------------: AI: injects a venom that makes you grow spiders in your body, then retreats // -------------: SPECIAL: stuns you on first attack - vulnerable to groups while it does this // -------------: TO FIGHT IT: blast it before it can get away -// -------------: SPRITES FROM: FoS, http://nanotrasen.se/phpBB3/memberlist.php?mode=viewprofile&u=386 +// -------------: SPRITES FROM: FoS, https://www.paradisestation.org/forum/profile/335-fos /mob/living/simple_animal/hostile/poison/terror_spider/white name = "White Terror spider" diff --git a/html/changelog.html b/html/changelog.html index e16a576f43d..3ffad2b6c96 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -25,8 +25,7 @@
Paradise Station
-

- Visit our Discord channel:-Click Here- +

From 0ea89b98d18b36ccf3059c43b0950743354a9673 Mon Sep 17 00:00:00 2001 From: FreeStylaLT Date: Tue, 17 Dec 2019 15:19:39 +0200 Subject: [PATCH 55/59] Oopsie woopsie nully wubby (#12812) --- code/modules/projectiles/projectile.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index daa8a48eb0b..d31231823f8 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -24,7 +24,7 @@ var/p_x = 16 var/p_y = 16 // the pixel location of the tile that the player clicked. Default is the center var/speed = 1 //Amount of deciseconds it takes for projectile to travel - var/Angle = 0 + var/Angle = null var/spread = 0 //amount (in degrees) of projectile spread var/legacy = FALSE //legacy projectile system animate_movement = 0 From e6090ea530967aad2ac41fca9cbac775ab12960a Mon Sep 17 00:00:00 2001 From: Lumi Date: Wed, 18 Dec 2019 14:32:24 +1100 Subject: [PATCH 56/59] Adds vox-themed plushie. (#12745) --- code/game/objects/items/toys.dm | 16 ++++++++++++++++ icons/obj/toy.dmi | Bin 76851 -> 77735 bytes 2 files changed, 16 insertions(+) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 71d5e36badf..0ad64e24f23 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1069,6 +1069,22 @@ obj/item/toy/cards/deck/syndicate/black name = "tuxedo cat plushie" icon_state = "tuxedocat" +/obj/item/toy/plushie/voxplushie + name = "vox plushie" + desc = "A stitched-together vox, fresh from the skipjack. Press its belly to hear it skree!" + icon_state = "plushie_vox" + item_state = "plushie_vox" + var/cooldown = 0 + +/obj/item/toy/plushie/voxplushie/attack_self(mob/user) + if(!cooldown) + playsound(user, 'sound/voice/shriek1.ogg', 10, 0) + visible_message("Skreee!") + cooldown = 1 + spawn(30) cooldown = 0 + return + ..() + //New generation TG plushies /obj/item/toy/plushie/lizardplushie diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi index 17ebf4c9219dc8d107b5f5735ac1112a38a9a71e..511b578ad4a29b89a1ae13de6c8aeda120ee1540 100644 GIT binary patch delta 18117 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 Rj5yB#1fH&bF6*2UngFm+(Xapj delta 17232 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 z%0ADIo<3w2J8b@?djDSKi=3Q_rI!Ep?(VB!_8S7y($Wl!j2T|DJ2iBjrP>Yf?Yrr~ z&vEl^bMA>2FE>1i0(|W31?cVww=5klU33UYj4TkrWV+C2^E|eO^JVjpAb9hz*pI18 zP^-al8x??Bpg@=AQohg+vvh?U6vLT>b;d^u(Jc(8l~gASX*t9r7mYmX*%BDHym2r7 z@>T1x;>pz6dOQ@RhNe@R>wu%W->BC0@~L-kB9j_sol~LDo^7U=>d|zyH%1Mn{I#|n z{#rDhaixm|EIM`H&c`en8kuShgRTfG#2(O6B>~DIwRP}jVCYl|XZ%7$LHOs^G4x8QA3vF(w znkR~lt^q%g%B~A+ygs=emX1Z4r9-rx4=sl~ET(HQ8NZ0UQczM74RXc4+F$mIjB5dC zmuS0pMpBtGv$Eib1YB82KUjm>VehimMr)zQs`uggFn}b^G3XiiS^X0_54YZYek{@6 z$X=gbhKcD<*tFcr4@q~$T_1|~ef$e}FT;=9PFd$H=g$wEyP$P1H8}O;jKtqfGP=8} zQrlT6M!l@M4!UPRxVP*F81Pa?8UMz5 z=vP!!bn3IuiN`xFE(`Km#qG_sG|4&h)h$QF$H(Vu)s_BtAvZRoCXv;eWt};A8*SDz z)-dYyR4`s+2uz%PH#9%p5robLA+#H1y$*v*rFOTx$cM=U%ce5^%!$ul?N3SsVUStM z`A3lQ$a9;IwbL~MDT{SU7L&Ol|Bet``p~^Sb8IrQ3^I!erE8-)V`?qkV${@9V$xp)23o#*v|gtBtXFq#s!+p-H`Yin!0Cc<#4fSRnu zD#$d}H(#>HwqiAVvQLw=jj46&#tf+n*x!3*&Kh}SUvn=wu8-90Op;(X z&2{O1zsshc;Eiq=0|El z{-^3z|HIaEgc;9mW|S0jChBQM`mG)jtQm6+iJSkm*W+bfv#h7h&#c%W`dd8ByRb-} zs@HFT{2Gz=0}9n2W%REW0?S|eOfYhHCR;KHBc*t#x)?qWvr*e#vh_@F$mC7(RZrWb z%I~^j-)t3YbYfwxjj7h5!@=1S8tCfkik8g^z}j1MPhGKh9{a00^Ca9tojB*xY`Xs` zs^TupJxFqm^iMDBYS|K)Xn7@}UQQtl2r54V3%Vg&$Wp}1l}|LRQp=Mks|zcK1tt`jX9m?a9&c~E$VenGHHU_VGB7c1!0f%& z=LF9%)}!<2F{QF3?FoyemyyvkvKif z)YYiiCCnRktex&UKFaY&IPdY0>!HX|)Xz9flkOCr7i|o_ygWLS^zRUqdk_uHxkUNX zq4=tJ4?o@Dl%@G$CTqE00ET4ok!^IRZO31VARfK72P1Vo`=G0ndf~O2yh-QbF(MSlX2ER(5PjgIgBCnoE5O!V zSSn5w@%NxrJObu?0@&Et7??>5*|y7#caM*Yjxv^EzpKS79dFOJ+9kJkyC;u+?iiCl zkc9Qu80?@b>g%7nB0Hh9{?&#TL|Bjbfh9Ut=|Nq4eBbjtYajcagCm?mB+YHrhcLQd z*~(RggxlP=L;oGX!&5h7Banp(UTa(pf;nG>*R5@QaJmqp7oN!50F~L&F(=QjH^+;x z9S)(nIy(xaxR_a=lPg~#m`*`NT!mp`fawmOs2H{R+xh#(T`B+B?PEl6$iWP1GKWzh zh=|iTSPTktZ1crhR@l>TT}JIDvQY-(SaGLIRB{%8^zo_yF=*nJb;n>PJ7T!s{@isLahtwNJ%zrzd{;|rW8|2wc6N2OHEm?~3lFg* z^ntVa*zkS0cYnbDJa3WGgc7;VDM0Yg4$_{8r-wWql{4#=pqm5B9{UWTl-P0-2i*c*E-wfC0niSwT>UK z4UUt>L$*cNu0V9FVTeioM$w^Wfy#a$mexqU2`me299NI;OC7Q-PCzvWMC-wVLNIufZ^7{m#j+8^&H2q&lGEd zFoQW^hj`f~F#iQw9#;cDj143`@>D**J^Wcz2N*x{sY|cg7d;mOtYk>fCqcerGC4`eT8c zMJR@yzH0s|s2znsDp#R3uvu#(zd7sVxH?*`0cC`^U3FMvJ9FGkC}c?(RbcrC((NJ7 zdSYjfpAYyFHJ#5EL*^Fhp^Rjj?{W7n3cPEN$ew>SH8%Fz_dI!p zU-8H6v^S;-PAwq#=J)v&m@bR6v+PiC?IdM5H!}TYp{1`s*X?wq7_wbvxa4$Nztoy^=yDWq^dXrb ztfw|L9f-F>6JyhDp4+~e)&}R_J!7JxQZX}!!Pc0N=_0jRP1XE^=So7oo6Nz6V`;Fu z#9SEo8gS#Z@Oyu3Ft7!Of5JncerfCduQJ@o!^7j6LM>i2J)THECT;B39?e(eV)=Uug5)Ud`|os|pu6p?HK)7~BusS}Mmd&Aj*9BIuPVsYSruR>j0GG! zofB0XKW0`_a;v~IfVdgBXApl|4w#zt^O2)hLq6dQaP~ze?ytqaNNhRm{yZcUcdAYI zylLKBsUypgFy)k`N1m*q`baAAX95ow(R>W6&`LI!G4>m+05SO;18Cm_r5PvsR3938 z7f|Q6q(S?*JDP@n{BYBut=x_BjRPpD=FjBzOk(mxtwtsJQz8GguplOtR+1dO*v;jM zcB}V|14&z=fSdBL81KgS^Kc4|UuXHQLu8AoEnnuh2(lo*VXE&X4GrG|r5b(cZK)^tB zm1&6L?ds@J!zIW)bf0~;5eh>STRU58u{4G;4s>fSgM}aL_|;*$YeT^Vp`qwxZtacuG_m_MnQYJ~(+u2uBKD zAU8BL;1LpjOWrv2r-pC$ zqrEc8!0$riRmf8l#_rq=EVAOi$J_USy!z|eb>`r?T=)~Jx(c{0w4Er4fBEvo5QfR# zA!y*L>I=K(c5c?<(T)vJhyQK-2vU-pc}rVUg5&0~h%TWnaTDN+j$8RzK=oX9s7pf2 zd}};ZLB|NhDOUihtsMv)bl|}=z@M-C2{7#dM!n2}wla#sC4zz$#Z`26c}c~(O#g=B zE0Lx;Dsr*v(Xs;@cN7O{w78OKNSJ2Azc=S5Ik?;7xI5@)W5~(R4&Q8xdk3;>`AH^1 zzCDMTe0S507>M4KHvk~0d`*aqye=~0CShb@DdxuPo%WNx_LmSB2dS>dCM0~el?UVl zdYd$V6{N8Pz#+K*>B-yC(UF0*WbSd#^3y*Yoq4j{g?w}k3YCbH`1w~0e_?(K7229ZPq?h=&{{K ze_k3D6%{@BMhuMrr-> z+nPj%f?R7HV1V@=&nz#$Kd5 zC`T>=9UckIx$43K+*Kt4l45Sjbf*#XOB_HX)M14>&a@dlSeK$Qc!9UpSM{BzQ5bV5*FDw-X5 zBRn(vbT7+BD{9U8{S#FY7`{MX+I z(#z$#)p6LyFv$n&KFn1u=-BSgZsQVj?nt0AAOXwn<6(l~;rWvkA_YfAx)mYADwKRs zyGQ}iU$eLdHz9YbWg6FtJ@Jjj3I?C z^rcR3c8z*=;8lh%&Rbt78i#^*Ff`JMZ|T_1SH-zt{j)Cxn*10O`_N3;1mhplt+(|n zcW^|+m-TaQoIjsBwTI~D_@MAup@3bv=q=$B2SHal1&0irGAr8{_EDkI8M5uSiSKDD#k@ktKOUnRX1?d$0H0g1Ob)7B z4RUt)E7_CZ#ttmUacNb8wc_gR`K-&dlkz>m{R!(0+ zU>Gl)ROF{za`C;O$GyiJVt#)ZuIKW+GIzN4`8d2;RKTERb;}1NbDE&)4`W6|M%G=E zzIhFs$d2u(x()p*Vf9khTv+)JB!lxTk#Uy_qc5RJYb>p*W%JgHJl^UakunmUR=eay zXBYJk&P{gRAo;X`{J1+NfqR_7sgV+atfg~&A@}D?<#hwOFNwSkRE&&_(>Qt*qis9a zWE{^w9edSinl}KRv`SlXjnn=oFHJ{w;VR9I!{O0k-|KrJ3w;kt^{6xc#@>f#WYo&q zB7TV1qf8u2#c>n#<#CVr)r<%L+jCwbUc}5eYrZ z?K9V#7vZ6kOZIa!9GhL1(UmXYwpt7-D~}s_(1awSg8D=?8sTXj_&0aP%8eXAv7w&&^}IwR7RBFM>|Tm}`MY+s-$K z+wUqr7=z8GM~Daf;Z8%>zekfD1s#w~_VIkDM>@eDS?}Y^>J4$apRcwV`}G=~^z8QK z_F^k(dr1T^$7&HfFg&|8c1_pqPH!Lx)k%A1Zh3+y6Q8*_(o3vxYPvY_CE~cZ)Sat2 zKm2lru7BG8X+v_o4_{`r$FPFE1>hy{o`Y;~=9mU(TtekWzjyI*LJ;~zyu&0F`GjxyYuQ_yY63m!kYBG_7>CQQ&O~#ji39Pnl{O> zBsCP_!d4;i9E$u0bynh^8buz~^tt=btI@}?`HkriL%zHTnVM|0z{+@jaHO+E5j(L0 zx_1(9Lk>dAm)mHJh6G1r%qR>e1G~Z#rU=VDoBTT8V34!>HU(;Q3FTID)|TD{o&`6` zl5)wiXjD~b!Yb}ggs{|Ny{N2pqsgv~no7`b#qHX3GFPtJW-+eQPxRnU%WRwcahr&P zgQNDCQmmvZMlzC|)eCy22uHx-->}j*8Qmk8*7_wP9?5^GLfRv1khGE+cLyQ=m%uJmA zB?3RkX_nHfEbgxwm<(Y~vDV&U#Dk|d5|ip3;(KDJeK;r5OV_DcV<{mj>IZcFaMO;b z`I#n&rYoGS$LZKhrrHtn`*-Kba+BTNncL3hz1H61-a_P`GD4^|u0csM5{#L!`L6jO z9q(`B{-Rxipd!G)x}tAhx;vI&$XD*F`Vq2Ub+Yz%Iy@Y{UUe z_oeHh;Gv(r8UvVz zm#MIZK;^2gh7j2l}CZ3E2)IK6?d9meAh8%uB>?4S##K%37US*MtmbRu7v znTTf?X0M2KRh#ARo7^66Civ#Vbu-lR|3>=fM_poXyMCp%AVupEsf|FSKVk4!b$)l+ zz4Lr@Z8{GMQ)-DTR^qbrsg4QijjSYvx(Y`S(;Rp_V(D`(cF#`x46J0hErkT(i3JCX5N6H&K{#>>eNb64> z{!y<)(>KIy2snP=FL^DiqSx~A+IYH5uTA?IT%!|ZR$N{_X7De;hm{o6H2e$FieU+r zUg=8ILTMjYTtdQL`Es*|ljJf0#7ZP+n%8JlnQjB71Nq0Hf<}C<_ZF53m9W252n;N* zAJ?5Ef5p3^rq)p`qkH~|Ic^#?92g&OmBAwU^P+-Xy)F`VjxC%`M~Fq@=@&~MnyAp* z*G19%X&^`?nS*b)Vw~zy>4T0~wQ;QaT+KB*l6>|bACcs&Jh0(aVHb7Rz^n$p$Jj$w zc0DlEUEtl3^Nnzy2o$-(^Vz%lW#^K7wnT^7nV$?(ym9*>azlTKA;o#tOet)Gp z>LD(UVCk-aE|wmIT zR+B4hmD#8(FPNEm&_IBJAsE)7$@_113xM3DqD&eVNV|3}-<`fXK$ZmNNx%e3n!=VT{kn0t=!+y#pJM$@oNv-)F5jSO`l-KB;r~QSH`$HZ%lJKXH{avVw*CEoamwaBOJQlM=|zY&e08ODvhSDbAv}| z+15QWZQ-aB`*DH^v@mA5f%MxxYO0UB0sUw!p@GjK{RwiWt<6kBG5LuQgmMxyd#EtELIF_~LFr;sErZ|4N-|UURm7}6QA5RKC8!}s7`Bv-W^SCOP zj6ufddG}5V;FCYh#b&tQJy#92__i7!O^C|p$%YATiIcg{Q5k{zX7&*t!$9)UulT0_ z?f~qg;>}0Dzt}c29L(MD2K{a`(JDZ!E#j8w*L2o<5 zZxA((qt8{!;+a}gqOXqi4o$_?Q;iNKE)}`@o;)ZWz$Kkxho62?#yr>v<`Ww3Jn>N% z^doLb>Sn}+Zx|Aj2`fB&9ss!j>U4Kr)#@=V zy~oeBh*k4`Sbl$BNJLwzx03M1Q$daqCNVKFoPT5xT;9B7>wZwu))pm`2vb$$Ra5Bh zk2c#UIQTAE^lKe=Xb?@LA>+AhbEEqQrVv6qAo7ftHQooSk=|c!Mov~+d{Zsc9bRei zg5?FGr|X}7yhi^bBLj$?7SJDSlhEeS&IM7zs&lCAxpK+2Om7QDd=dUHlOM#VvR zUK;-UN)fjcZ7naDhsY*>D4BQ!V6;xqLaoiA{m8L?n-UxWDVMl9o>c+x4V+Pd0*+n( z@fz*XZkcDXHiqk;6PUkYecKs*(_kp&h@s5X9@yQDDp3(9pyD4d=U(uJj9XiqIRG`e z*5})ai*86i;V?Q$&{?)m>D*U7DJFdV3J#7=M-_b!6a!q{*}o!v7Ejy2_HOSRY!b0x zG4}~!wWH7Sl6-I5ZIbB`ymj$JRy<%GW z-<-uFB1NR0)uY==hPXWOL@z8^Rt?EOh5U=1&GtY(%4 z!jH>SK-5wBeRUj9@_%lc*5m&eu+6CaNiCM4)BdP;a)a`IJCN1^0(J9#Vee206==K5sB11lmMobmih zNO7O!qCIwMP=-UCVfSMypL&Uj!CQO@9r%{-H!}U@;YJh|z3W8XRs5O$YEyQ;ytjM9 ztftjN=)3aj;^IP`u#VJs&MOP9*Z(OA8SJGDVCRN{V+Z5GRhH9CAUfFu5HFqa>{iFA zHJ~w-`r$n1cWUf#SaPuluO7K&1i~Es)~vWY-y+4+23_)1)%gfnT9biMWwOn-3(O4EZ|Jsz(q=8}P0 zoBER%K5Dfva)VoJW5*#C#U6D}4N-}_`QSy!vqmT>6PET(F}X)uJ-8SyB87=3-;gDv zc!TDCbav_PQ-$aC?!evoCL*#dtt1=%cGiqb>3-v{LWNKmlj25~eb*;8RqdN{#?`-y z@e0~bb6Mr3Whhe&EWG)*5Dr1~07u748Qha&i>Cpp0sOUgr^ry#aWZ7vfrCw#=^A&mdMsyjo5M=%$wf3^m?wZ7E zrdaWBI59P>lxBITRS(!34l#gI*nSKHPdwKdeLu!R<7>q ze9jw5k5(TZPi-G(S;Z7pIz`2L1V#nFZbU`xe|8 zFVyCMdin%7FN+r4gxs5+Gj?w%sYCK7i%~o09pI*7&r|zmZ7*Of}O>Q)!o4kSST;OJ&5xQn&OQu#P z@-~stmS+sKw)u~}P~|NC(m9ol|; zb5^W38?ij zjt=?E&Oq#!kpCr1HHggjo?QeBZU>vHkN=D%S3cF!YBcG67%a}byxg``S>Fg- zIQ!a5Eac8q2Dw34g~ZCntuySlU>Fd^42(8L!g?2aKS_p`8aq7Yr6-VZCD02$hHsU9 zu%BA%p#-BB{CK#C8o3I>(mT;@%;$swoRgd|CNcc~U0$uS0{Aw%_c4CmH2mClJGHPj zBN&kfb7`Y7+i>$)XS=h3D-Q>>AdBIxlOmSR)@PzVf~ z|LqRJ1sXPg3f$fArZ4aKIMhNy><*1kc_K-FWujS486YSO*fq->*M(c^LY~q*8LS#E769g7NcE)(yev3)K)9Juu*jbX_pIvbIOfXc7^7A_H9TsHRxWRyrdV zX}QtzI>3ie=I$<;ti}==_TH+SI-35Qw)PO0Q`*k-tfkvi;T`-OZ0DbnlCo{_)YAsY zDn;k>T*8ATH|EoY_<>y^D>d|<|qFL}H^{Qq7+*#hRD zA??5A8p9RtF`PapV$Q@w5_J{m!~kbQ-r#Y%v^357RYB1vCe1sBV9w~oovO4yQ(}W+ zPP;hxT)zU1{!Tb;Y^~PZRqm<=kgM3L>?v-;PT&Nu(x&V<{44wNNhyvDxk(UN?5PI* zN5s4~akaxox?WKtI5;>spRTW*bzdvw<;rLWF;&|J-1%8~2-j__gO8!Yz;P1`iU=cz z;vZh!Ff7Y>QCN*s%T8Iz@OL|mE3DQOvrrCL^+L5eA#qzJ(yeNBb}APwjXuo3PqmON z0wfQ=pU)~QRU6dULcda<5`f6b`GxaMX`hnVPq*VGK7Itj!NJL$Q5%-@M3R zCLAgX8PqVg9w`b@*4&=~@i##FjSfGW(m!S~j8W`pWQpe&^Z$~ImC61Oqc~BTd0mF4 z=99DYRY@zte@tXcvVFMd|8*@e$p-!3PK_}VvL*eWSGj`%UO08Ns1C_t?0nc$UctI6 zhe+4}1Sr00QYkET;5%vIj&J06Ao}=cHB^rO#%KBz_>Pt*f~j>TptR~5QLn%5xhij1 zh4LRc9VaAPu&xC3C~+C_x#9>X@l(+Dk5&SO9<|=FpEOsNh->c}bB~V=9@Vg`D12mF zzy3#-*50mt^C?%|6$Jplg1|vQcmV(f;flqvCF|C8;;IaOXvjGt`1z#E*2v4}bqt}N zKE4_Ff(o1tNo=cDmriEH42>RqDH?)YabPd-ZpCSr{l~{{ldu(li!+?3JsV%&-84I7 zW?;!;II2e;uun%0`}vaq^!12L-FEf2ZBq#pmleiud~Sl(|F*qVx(Ay9?NV^H1M+C| z-NNZb>woW3i3~Pe;MbmbYc^);K{=`+UGG@;B(j@=4YZHQ-!mCte7C`PGZf!oNja4B z$zLh9Gz<(0AJeJ$Zw4G2jwNgeLez>JR@kdBKcB|`C*O8`iDNrt+?yJNbUNFUa#>^8 zM0LI$o>@QJUj=x3#HqIm$`Cz~jOD1{HSqP&aZza}QY-AZZj_Eu4-- zskPblf24Igd9`M~qX>GLFf6c1zk>XyPNlTPfmb_r7l_X_wM?z3;fQzlcLr?CP9DN@ z{E_#WndL?{Mwgv(P!!)mM1r7asO}Q33!plK|MLYPqS4+*_ezW>_DX#&ME>D3%P0Mx zC88{ulC$qFfqgOJykegww6&V@r(AYsJcjB#eluM{_`X6~RkuZ%M(reV&iDsMQeH=9BCSJ%Pd&Ej zOs&RuivPs?eX;a`yc}nGDqgZ|B19vi$?$cuvZNz5T<;gN?)YOi<2UWPF;rrA!_d*~Ms2oe16!$K=hB(Bjr5#pR;!$WsNjhFaRx9y<(a3CK%Hj<*?LVLT zQsSWH-p*9`yd8dk&dg2#`bF%lp6%{K&-nu*ti18M%TXRSor06>#7%12QbJfx zvbN%P7Q_=;_E3ipw5c(t)9x?vef1V?@yVVSvtFzYChUpY*p8-WE??Zlkh&O)(_>3N+TyOKxg_I$KE35AT(3=u-`xTE?Qqo$bCZ-Yfb4&&oLlV7tOL5qVjJAu=f$Y;qnxZrfa|OdI=q5{5ngpQ?4Q zd4-5nwlA4QQ=jV$SD9g6z|q(hjZAsRWWX`YTwgeYb~#H5Dq=6%uYvI}@2z|Wf$QC5 zwEOky_jtEfrf@f%htSTrnZDYjSEgrH`iE9CeZ8vCLsO#njrE$d`r!8F{&pz@y<7Jz z#{jBMkh!w5;UW0N&?M&u<_Sek7XJmgrI|TF{lYuV3a_Y(hm*ts>T#~3qZad)0|)iW z7@y)S{#`Zy%c0g}M%RT7N1$w?!?6rUV@b*(;7)UwLr)pcuzJ_olO%6)(!OTa>SF61 z;=8&vzml>_jbHeRI_HR3m5zz<`rK(XAz;AHE(nNCjfSO9kM#e=jE$ZPoBZ&zpB1n!UJ}&n(xP|ru>?sK zW>0cHNtvD<7sCN59BGss0x0Eylwb4m;MTt3_2J6BY*!vur=!p3s7%Ruv|CcO9${mC zt@XrX#?l7eOGx-mzuIZKutF^L7*+nHN<8uE-$LpU=sEwBqTbmDGv1u zYpy;vj}K9g17YIgPId`4_CZLcl}w|&9d#R&rnw^3l^ztVxtLbgJ}p@x}wpPHx8 zo7EA7=lxG`_B1?`bnPiE`Zp_O_Lw4-FPE!K5qh5gK28$9klM;cAks$TljOcN)s1X= z+cT?@k%P(+Cm%p7v(I6}rSObJ^RW%aXzfKGe60UH&^><~KD!svnfJ4Qrk2oPB!5FD zhY6sPMP>iD*gj!5>=!29keAOq*QnaXGu7wH(Ly>O^_$~@SB(}-^+7G6(5xAkX3iE(fJRQez0y_Sj+~_LN~)9mWagytdhXj-y=>9H?m6G&1kdh` z4Qq2Mdady$?AgaocgI;6s>bi7o1LAK2 Date: Wed, 18 Dec 2019 14:32:44 +1100 Subject: [PATCH 57/59] Added_Pylon_healing_to_Wizards (#12743) --- code/game/gamemodes/cult/cult_structures.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index d30ac4f8a68..3489a087ec0 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -198,7 +198,7 @@ var/list/blacklisted_pylon_turfs = typecacheof(list( if(last_heal <= world.time) last_heal = world.time + heal_delay for(var/mob/living/L in range(5, src)) - if(iscultist(L) || istype(L, /mob/living/simple_animal/shade) || istype(L, /mob/living/simple_animal/hostile/construct)) + if(iscultist(L) || iswizard(L) || istype(L, /mob/living/simple_animal/shade) || istype(L, /mob/living/simple_animal/hostile/construct)) if(L.health != L.maxHealth) new /obj/effect/temp_visual/heal(get_turf(src), "#960000") if(ishuman(L)) From 2d9961f425467d6197353b4af3a316b3f2502154 Mon Sep 17 00:00:00 2001 From: SteelSlayer <42044220+SteelSlayer@users.noreply.github.com> Date: Tue, 17 Dec 2019 21:34:15 -0600 Subject: [PATCH 58/59] Improves AI voice announcement logging; adds an admin message in-game for it (#12692) --- code/modules/mob/living/silicon/ai/say.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index 36f248cd2c2..b4db13f5452 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -129,7 +129,8 @@ var/const/VOX_PATH = "sound/vox_fem/" announcing_vox = world.time + VOX_DELAY - log_game("[key_name_admin(src)] made a vocal announcement with the following message: [message].") + log_game("[key_name(src)] made a vocal announcement: [message].") + message_admins("[key_name_admin(src)] made a vocal announcement: [message].") for(var/word in words) play_vox_word(word, src.z, null) From 727397463ea1cdcace3ee05e763af5af96f37f41 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Dec 2019 23:07:14 -0500 Subject: [PATCH 59/59] display time in Seconds now --- code/modules/mob/living/carbon/carbon.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index c5bf235befd..af6bdb26af5 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -776,11 +776,11 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, if(restrained()) var/obj/item/I = handcuffed var/breakouttime = I.breakouttime - var/displaytime = breakouttime / 600 + var/displaytime = breakouttime / 10 changeNext_move(CLICK_CD_BREAKOUT) last_special = world.time + CLICK_CD_BREAKOUT visible_message("[src] attempts to unbuckle [p_them()]self!", \ - "You attempt to unbuckle yourself... (This will take around [displaytime] minute and you need to stay still.)") + "You attempt to unbuckle yourself... (This will take around [displaytime] seconds and you need to stay still.)") if(do_after(src, breakouttime, 0, target = src)) if(!buckled) return @@ -839,10 +839,10 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump, /mob/living/carbon/proc/cuff_resist(obj/item/I, breakouttime = 600, cuff_break = 0) breakouttime = I.breakouttime - var/displaytime = breakouttime / 600 + var/displaytime = breakouttime / 10 if(!cuff_break) visible_message("[src] attempts to remove [I]!") - to_chat(src, "You attempt to remove [I]... (This will take around [displaytime] minutes and you need to stand still.)") + to_chat(src, "You attempt to remove [I]... (This will take around [displaytime] seconds and you need to stand still.)") if(do_after(src, breakouttime, 0, target = src)) if(I.loc != src || buckled) return