diff --git a/_maps/RandomRuins/AnywhereRuins/golem_ship.dmm b/_maps/RandomRuins/AnywhereRuins/golem_ship.dmm index 37a89ba2ff..274c814cf5 100644 --- a/_maps/RandomRuins/AnywhereRuins/golem_ship.dmm +++ b/_maps/RandomRuins/AnywhereRuins/golem_ship.dmm @@ -18,7 +18,7 @@ /obj/item/mining_scanner, /obj/item/flashlight/lantern, /obj/item/card/id/mining, -/obj/item/gps/mining, +/obj/item/gps/mining/off, /turf/open/floor/plating, /area/ruin/powered/golem_ship) "d" = ( @@ -32,7 +32,7 @@ /obj/item/mining_scanner, /obj/item/flashlight/lantern, /obj/item/card/id/mining, -/obj/item/gps/mining, +/obj/item/gps/mining/off, /turf/open/floor/plating, /area/ruin/powered/golem_ship) "e" = ( @@ -71,8 +71,8 @@ /area/ruin/powered/golem_ship) "k" = ( /obj/machinery/computer/arcade/battle{ - icon_state = "arcade"; - dir = 4 + dir = 4; + icon_state = "arcade" }, /turf/open/floor/mineral/titanium/purple, /area/ruin/powered/golem_ship) @@ -112,8 +112,8 @@ /area/ruin/powered/golem_ship) "s" = ( /obj/machinery/computer/arcade/orion_trail{ - icon_state = "arcade"; - dir = 4 + dir = 4; + icon_state = "arcade" }, /turf/open/floor/mineral/titanium/purple, /area/ruin/powered/golem_ship) diff --git a/_maps/map_files/CogStation/CogStation.dmm b/_maps/map_files/CogStation/CogStation.dmm index 6f5bab0498..e41f6c7d89 100644 --- a/_maps/map_files/CogStation/CogStation.dmm +++ b/_maps/map_files/CogStation/CogStation.dmm @@ -6004,12 +6004,12 @@ c_tag = "Security Checkpoint"; pixel_x = 22 }, -/obj/machinery/newscaster/security_unit{ - pixel_y = 32 - }, /obj/structure/cable{ icon_state = "4-8" }, +/obj/machinery/airalarm{ + pixel_y = 23 + }, /turf/open/floor/plasteel, /area/security/checkpoint) "aoz" = ( @@ -32290,10 +32290,6 @@ dir = 8; light_color = "#e8eaff" }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 - }, /turf/open/floor/plasteel, /area/hydroponics) "bsl" = ( @@ -71184,6 +71180,13 @@ /obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) +"pMW" = ( +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/turf/open/floor/plasteel, +/area/hydroponics) "pZq" = ( /obj/structure/disposalpipe/sorting/mail/flip{ dir = 8; @@ -121382,7 +121385,7 @@ amV aqI aqB aGO -auy +pMW aqB aqI amV diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index a776996d91..6ef8eb8d45 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -49544,7 +49544,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/stripes/line{ - dir = 10 + dir = 8 }, /turf/open/floor/plasteel, /area/engine/gravity_generator) @@ -113342,10 +113342,6 @@ /obj/item/clothing/gloves/color/black, /obj/item/storage/box/evidence, /obj/item/taperecorder, -/obj/machinery/airalarm{ - dir = 8; - pixel_x = 24 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index 5140b35d20..698a585688 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -30529,9 +30529,6 @@ dir = 8 }, /obj/structure/closet/bombcloset, -/obj/machinery/airalarm{ - pixel_y = 24 - }, /turf/open/floor/plasteel/dark, /area/science/mixing) "aXC" = ( @@ -43701,10 +43698,6 @@ /obj/structure/window/reinforced{ dir = 1 }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 - }, /mob/living/simple_animal/chicken{ desc = "The arch-nemesis of Kentucky."; name = "Popeye"; @@ -46363,9 +46356,6 @@ "bwK" = ( /obj/structure/flora/grass/jungle/b, /obj/structure/flora/ausbushes/sparsegrass, -/obj/machinery/airalarm{ - pixel_y = 22 - }, /turf/open/floor/grass, /area/chapel/main) "bwL" = ( @@ -48132,16 +48122,6 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/brig) -"bzx" = ( -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/closed/wall, -/area/crew_quarters/locker) "bzy" = ( /obj/machinery/light/small{ dir = 8 @@ -58156,10 +58136,6 @@ icon_state = "plant-02"; pixel_y = 3 }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 - }, /obj/machinery/camera{ c_tag = "Prison Wing Cells"; dir = 4; @@ -61358,7 +61334,7 @@ dir = 10 }, /turf/open/floor/plasteel, -/area/space) +/area/security/warden) "bUs" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/command/glass{ @@ -67208,10 +67184,6 @@ /obj/structure/cable{ icon_state = "1-4" }, -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 - }, /turf/open/floor/plasteel, /area/security/main) "cdU" = ( @@ -71325,9 +71297,9 @@ icon_gib = "magicarp_gib"; icon_living = "magicarp"; icon_state = "magicarp"; + maxHealth = 200; max_co2 = 5; max_tox = 2; - maxHealth = 200; melee_damage_lower = 15; melee_damage_upper = 20; min_oxy = 5; @@ -83279,10 +83251,6 @@ /obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 5 }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -23 - }, /obj/machinery/camera{ c_tag = "Atmospherics Port Tanks"; dir = 4; @@ -108990,7 +108958,7 @@ bss btV aEu bxW -bzx +bIV bKq bKq bKq diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 9013e78daa..cccf44f4af 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -1111,10 +1111,6 @@ /turf/open/floor/plasteel, /area/security/prison) "acx" = ( -/obj/machinery/airalarm{ - dir = 8; - pixel_x = 24 - }, /obj/machinery/cryopod{ dir = 8 }, @@ -40497,10 +40493,9 @@ /area/maintenance/port) "bBr" = ( /obj/machinery/airalarm{ - dir = 4; - pixel_x = -23 + dir = 1; + pixel_y = -22 }, -/obj/structure/displaycase/trophy, /turf/open/floor/wood, /area/library) "bBs" = ( @@ -45866,10 +45861,6 @@ /area/library) "bML" = ( /obj/machinery/light/small, -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 - }, /turf/open/floor/wood, /area/library) "bMM" = ( @@ -59581,6 +59572,10 @@ /obj/structure/chair{ dir = 1 }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -23 + }, /turf/open/floor/plasteel/dark, /area/medical/surgery) "coz" = ( @@ -61596,10 +61591,6 @@ /turf/open/floor/plasteel/white, /area/medical/surgery) "csl" = ( -/obj/machinery/airalarm{ - dir = 1; - pixel_y = -22 - }, /obj/structure/window/reinforced{ dir = 8 }, @@ -102702,7 +102693,7 @@ bue bwa bxU bzD -bBr +dmD bSx bEw bzE @@ -103737,7 +103728,7 @@ bGs bHS bzE bLk -bzE +bBr bue bPS bPR diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 5bf6e58409..75826cf65a 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -4924,11 +4924,11 @@ /obj/effect/turf_decal/stripes/end{ dir = 1 }, -/obj/item/gun/energy/e_gun/hos, /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ dir = 4 }, +/obj/item/gun/energy/e_gun/hos, /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/captain/private) "ahI" = ( @@ -40544,6 +40544,9 @@ name = "Starboard Quater Maintenance APC"; pixel_y = -26 }, +/obj/structure/cable/white{ + icon_state = "0-8" + }, /turf/open/floor/plating{ icon_state = "panelscorched" }, diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 53479d1148..47a934bbec 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -16530,6 +16530,9 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/machinery/airalarm{ + pixel_y = 22 + }, /turf/open/floor/plasteel, /area/quartermaster/warehouse) "aMr" = ( @@ -47631,6 +47634,9 @@ pixel_x = -25; specialfunctions = 4 }, +/obj/machinery/airalarm{ + pixel_y = 22 + }, /turf/open/floor/plasteel/grimy, /area/chapel/main/monastery) "cgM" = ( @@ -47979,6 +47985,9 @@ pixel_x = -25; specialfunctions = 4 }, +/obj/machinery/airalarm{ + pixel_y = 22 + }, /turf/open/floor/plasteel/grimy, /area/chapel/main/monastery) "cip" = ( @@ -51466,6 +51475,10 @@ name = "Coffin Storage"; req_one_access_txt = "22" }, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 + }, /turf/open/floor/plasteel/dark, /area/chapel/main/monastery) "cvu" = ( @@ -59432,6 +59445,10 @@ /obj/effect/turf_decal/tile/yellow{ dir = 8 }, +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 23 + }, /turf/open/floor/plasteel, /area/construction/mining/aux_base) "qXq" = ( diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 68515426c3..e71243994d 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -69,6 +69,9 @@ #define LINGBLOOD_EXPLOSION_THRESHOLD (LINGBLOOD_DETECTION_THRESHOLD * LINGBLOOD_EXPLOSION_MULT) //Hey, important to note here: the explosion threshold is explicitly more than, rather than more than or equal to. This stops a single loud ability from triggering the explosion threshold. ///Heretics -- +GLOBAL_LIST_EMPTY(living_heart_cache) //A list of all living hearts in existance, for us to iterate through. + + #define IS_HERETIC(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic)) #define IS_HERETIC_MONSTER(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic_monster)) diff --git a/code/_onclick/right_click.dm b/code/_onclick/right_click.dm index 9a99bbd20b..4b2480eb8c 100644 --- a/code/_onclick/right_click.dm +++ b/code/_onclick/right_click.dm @@ -51,11 +51,7 @@ //Standard reach turf to turf or reaching inside storage if(CanReach(A,W)) if(W) - if(a_intent == INTENT_HELP && iscarbon(src)) - var/mob/living/carbon/C = src - C.give() - else - return W.rightclick_melee_attack_chain(src, A, params) + return W.rightclick_melee_attack_chain(src, A, params) else if(!AltUnarmedAttack(A, TRUE)) . = UnarmedAttack(A, TRUE, a_intent) diff --git a/code/datums/components/gps.dm b/code/datums/components/gps.dm index c2b3ad1f30..61098c8b66 100644 --- a/code/datums/components/gps.dm +++ b/code/datums/components/gps.dm @@ -21,7 +21,7 @@ GLOBAL_LIST_EMPTY(GPS_list) var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user. var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown -/datum/component/gps/item/Initialize(_gpstag = "COM0", emp_proof = FALSE) +/datum/component/gps/item/Initialize(_gpstag = "COM0", emp_proof = FALSE, starton = TRUE) . = ..() if(. == COMPONENT_INCOMPATIBLE || !isitem(parent)) return COMPONENT_INCOMPATIBLE @@ -33,6 +33,8 @@ GLOBAL_LIST_EMPTY(GPS_list) RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/on_emp_act) RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine) RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/on_AltClick) + if(!starton) + tracking = FALSE ///Called on COMSIG_ITEM_ATTACK_SELF /datum/component/gps/item/proc/interact(datum/source, mob/user) diff --git a/code/datums/elements/ventcrawling.dm b/code/datums/elements/ventcrawling.dm index 4af3a085ef..254345a97f 100644 --- a/code/datums/elements/ventcrawling.dm +++ b/code/datums/elements/ventcrawling.dm @@ -6,6 +6,10 @@ /datum/element/ventcrawling/Attach(datum/target, duration = 0, given_tier = VENTCRAWLER_NUDE) . = ..() + var/mob/living/person = target + if(!istype(person)) + return FALSE + src.tier = given_tier RegisterSignal(target, COMSIG_HANDLE_VENTCRAWL, .proc/handle_ventcrawl) @@ -16,9 +20,10 @@ addtimer(CALLBACK(src, .proc/Detach, target), duration) /datum/element/ventcrawling/Detach(datum/target) - . = ..() - UnregisterSignal(target, list(COMSIG_HANDLE_VENTCRAWL, COMSIG_CHECK_VENTCRAWL)) + to_chat(target, "You can no longer ventcrawl.") + + return ..() /datum/element/ventcrawling/proc/handle_ventcrawl(datum/target,atom/A) var/mob/living/person = target diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index d8617e0b48..0ee07951a9 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -455,7 +455,7 @@ If not set, defaults to check_completion instead. Set it. It's used by cryo. var/target_real_name // Has to be stored because the target's real_name can change over the course of the round var/target_missing_id -/datum/objective/escape/escape_with_identity/find_target() +/datum/objective/escape/escape_with_identity/find_target(dupe_search_range, blacklist) target = ..() update_explanation_text() @@ -553,7 +553,7 @@ GLOBAL_LIST_EMPTY(possible_items) for(var/I in subtypesof(/datum/objective_item/steal)) new I -/datum/objective/steal/find_target() +/datum/objective/steal/find_target(dupe_search_range, blacklist) var/list/datum/mind/owners = get_owners() var/approved_targets = list() check_items: @@ -631,7 +631,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) for(var/I in subtypesof(/datum/objective_item/special) + subtypesof(/datum/objective_item/stack)) new I -/datum/objective/steal/special/find_target() +/datum/objective/steal/special/find_target(dupe_search_range, blacklist) return set_target(pick(GLOB.possible_items_special)) /datum/objective/steal/exchange @@ -844,7 +844,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) name = "destroy AI" martyr_compatible = 1 -/datum/objective/destroy/find_target() +/datum/objective/destroy/find_target(dupe_search_range, blacklist) var/list/possible_targets = active_ais(1) var/mob/living/silicon/ai/target_ai = pick(possible_targets) target = target_ai.mind @@ -1124,7 +1124,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) /datum/objective/hoard/heirloom name = "steal heirloom" -/datum/objective/hoard/heirloom/find_target() +/datum/objective/hoard/heirloom/find_target(dupe_search_range, blacklist) set_target(pick(GLOB.family_heirlooms)) GLOBAL_LIST_EMPTY(traitor_contraband) @@ -1141,7 +1141,7 @@ GLOBAL_LIST_EMPTY(cult_contraband) if(!GLOB.cult_contraband.len) GLOB.cult_contraband = list(/obj/item/clockwork/slab,/obj/item/clockwork/component/belligerent_eye,/obj/item/clockwork/component/belligerent_eye/lens_gem,/obj/item/shuttle_curse,/obj/item/cult_shift) -/datum/objective/hoard/collector/find_target() +/datum/objective/hoard/collector/find_target(dupe_search_range, blacklist) var/obj/item/I var/I_type if(prob(50)) @@ -1172,7 +1172,7 @@ GLOBAL_LIST_EMPTY(possible_sabotages) for(var/I in subtypesof(/datum/sabotage_objective)) new I -/datum/objective/sabotage/find_target() +/datum/objective/sabotage/find_target(dupe_search_range, blacklist) var/list/datum/mind/owners = get_owners() var/approved_targets = list() check_sabotages: diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index efae2dfb5e..6e6e85146d 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -954,6 +954,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb /obj/item/proc/get_part_rating() return 0 +//Can this item be given to people? +/obj/item/proc/can_give() + return TRUE + /obj/item/doMove(atom/destination) if (ismob(loc)) var/mob/M = loc diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index 5b1b86b9e4..7d2b0ed832 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -779,16 +779,40 @@ /obj/item/card/id/departmental_budget/update_label() return +/obj/item/card/id/departmental_budget/civ + department_ID = ACCOUNT_CIV + department_name = ACCOUNT_CIV_NAME + +/obj/item/card/id/departmental_budget/eng + department_ID = ACCOUNT_ENG + department_name = ACCOUNT_ENG_NAME + +/obj/item/card/id/departmental_budget/sci + department_ID = ACCOUNT_SCI + department_name = ACCOUNT_SCI_NAME + +/obj/item/card/id/departmental_budget/med + department_ID = ACCOUNT_MED + department_name = ACCOUNT_MED_NAME + +/obj/item/card/id/departmental_budget/srv + department_ID = ACCOUNT_SRV + department_name = ACCOUNT_SRV_NAME + /obj/item/card/id/departmental_budget/car department_ID = ACCOUNT_CAR department_name = ACCOUNT_CAR_NAME +/obj/item/card/id/departmental_budget/sec + department_ID = ACCOUNT_SEC + department_name = ACCOUNT_SEC_NAME + //Polychromatic Knight Badge /obj/item/card/id/knight name = "knight badge" icon_state = "knight" - desc = "A badge denoting the owner as a knight! It has a strip for swiping like an ID" + desc = "A badge denoting the owner as a knight! It has a strip for swiping like an ID." var/id_color = "#00FF00" //defaults to green var/mutable_appearance/id_overlay diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index bb46577702..a0b695e29f 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -8,10 +8,11 @@ slot_flags = ITEM_SLOT_BELT obj_flags = UNIQUE_RENAME var/gpstag = "COM0" + var/starton = TRUE /obj/item/gps/Initialize() . = ..() - AddComponent(/datum/component/gps/item, gpstag) + AddComponent(/datum/component/gps/item, gpstag, starton) /obj/item/gps/science icon_state = "gps-s" @@ -26,6 +27,9 @@ gpstag = "MINE0" desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life." +/obj/item/gps/mining/off + starton = FALSE + /obj/item/gps/cyborg icon_state = "gps-b" gpstag = "BORG0" diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index d7db5ce908..b52d138385 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -236,6 +236,12 @@ if(!iscyborg(loc)) deductcharge(severity*10, TRUE, FALSE) +/obj/item/melee/baton/can_give() + if(turned_on) + return FALSE + else + ..() + /obj/item/melee/baton/stunsword name = "stunsword" desc = "Not actually sharp, this sword is functionally identical to its baton counterpart." diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 4348ae7661..45d05c70b9 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -174,7 +174,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) //is_bwoink is TRUE if this ticket was started by an admin PM /datum/admin_help/New(msg, client/C, is_bwoink) //clean the input msg - msg = sanitize(copytext_char(msg,1,MAX_MESSAGE_LEN)) + msg = copytext_char(msg,1,MAX_MESSAGE_LEN) if(!msg || !C || !C.mob) qdel(src) return @@ -263,7 +263,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) //message from the initiator without a target, all admins will see this //won't bug irc /datum/admin_help/proc/MessageNoRecipient(msg) - msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN)) + msg = copytext_char(msg, 1, MAX_MESSAGE_LEN) var/ref_src = "[REF(src)]" //Message to be sent to all admins var/admin_msg = "Ticket [TicketHref("#[id]", ref_src)]: [LinkedReplyName(ref_src)] [FullMonty(ref_src)]: [keywords_lookup(msg)]" @@ -523,7 +523,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) if(handle_spam_prevention(msg,MUTE_ADMINHELP)) return - msg = trim(msg) + msg = sanitize(trim(msg)) if(!msg) return diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 2931c52a5c..4856f5af32 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -113,6 +113,11 @@ to_chat(src, "Error: Use the admin IRC/Discord channel, nerd.", confidential = TRUE) return + //clean the message if it's not sent by a high-rank admin + if(!check_rights(R_SERVER|R_DEBUG,0)||external)//no sending html to the poor bots + msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN)) + if(!msg) + return else //get message text, limit it's length.and clean/escape html @@ -141,15 +146,9 @@ to_chat(src, "Error: Admin-PM: You are unable to use admin PM-s (muted).", confidential = TRUE) return - if (src.handle_spam_prevention(msg,MUTE_ADMINHELP)) + if(src.handle_spam_prevention(msg,MUTE_ADMINHELP)) return - //clean the message if it's not sent by a high-rank admin - if(!check_rights(R_SERVER|R_DEBUG,0)||external)//no sending html to the poor bots - msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN)) - if(!msg) - return - var/rawmsg = msg if(holder) diff --git a/code/modules/antagonists/blob/blob/overmind.dm b/code/modules/antagonists/blob/blob/overmind.dm index 02be432045..18f6817ec9 100644 --- a/code/modules/antagonists/blob/blob/overmind.dm +++ b/code/modules/antagonists/blob/blob/overmind.dm @@ -277,3 +277,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) var/datum/antagonist/blob/B = mind.has_antag_datum(/datum/antagonist/blob) if(!B) mind.add_antag_datum(/datum/antagonist/blob) + +//the same but it's forced to be allowed by default as cameras usually don't allow emoting +/mob/camera/blob/emote(act, m_type=1, message = null, intentional = FALSE, forced = TRUE) + . = ..() diff --git a/code/modules/antagonists/eldritch_cult/eldritch_antag.dm b/code/modules/antagonists/eldritch_cult/eldritch_antag.dm index ea226a3cb6..1e43754477 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_antag.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_antag.dm @@ -10,6 +10,8 @@ var/give_equipment = TRUE var/list/researched_knowledge = list() var/total_sacrifices = 0 + var/list/sac_targetted = list() //Which targets did living hearts give them, but they did not sac? + var/list/actually_sacced = list() //Which targets did they actually sac? var/ascended = FALSE /datum/antagonist/heretic/admin_add(datum/mind/new_owner,mob/admin) @@ -175,6 +177,17 @@ knowledge_message += "[EK.name]" parts += knowledge_message.Join(", ") + parts += "Targets assigned by living hearts, but not sacrificed:" + if(!sac_targetted.len) + parts += "None." + else + parts += sac_targetted.Join(",") + parts += "Sacrifices performed:" + if(!actually_sacced.len) + parts += "None!" + else + parts += actually_sacced.Join(",") + return parts.Join("
") //////////////// // Knowledge // @@ -213,6 +226,23 @@ if(ascended) . += 20 +/datum/antagonist/heretic/antag_panel() + var/list/parts = list() + parts += ..() + parts += "Targets currently assigned by living hearts (Can give a false negative if they stole someone elses living heart):" + if(!sac_targetted.len) + parts += "None." + else + parts += sac_targetted.Join(",") + parts += "Targets actually sacrificed:" + if(!actually_sacced.len) + parts += "None." + else + parts += actually_sacced.Join(",") + + return (parts.Join("
") + "
") + + //////////////// // Objectives // //////////////// diff --git a/code/modules/antagonists/eldritch_cult/eldritch_items.dm b/code/modules/antagonists/eldritch_cult/eldritch_items.dm index da2c61ad16..fbf0740e50 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_items.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_items.dm @@ -6,6 +6,17 @@ w_class = WEIGHT_CLASS_SMALL ///Target var/mob/living/carbon/human/target + var/datum/antagonist/heretic/sac_targetter //The heretic who used this to acquire the current target - gets cleared when target gets sacrificed. + +/obj/item/living_heart/Initialize() + . = ..() + GLOB.living_heart_cache.Add(src) //Add is better than +=. + +/obj/item/living_heart/Destroy() + GLOB.living_heart_cache.Remove(src) + if(sac_targetter && target) + sac_targetter.sac_targetted.Remove(target.real_name) + return ..() /obj/item/living_heart/attack_self(mob/user) . = ..() diff --git a/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm b/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm index e0189944e5..481ac08ea5 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm @@ -1,6 +1,6 @@ /** - * #Eldritch Knwoledge + * #Eldritch Knowledge * * Datum that makes eldritch cultist interesting. * @@ -252,6 +252,10 @@ LH.target = null var/datum/antagonist/heretic/EC = carbon_user.mind.has_antag_datum(/datum/antagonist/heretic) + EC.actually_sacced.Add(H.real_name) + if(LH.sac_targetter) + LH.sac_targetter.sac_targetted.Remove(H.real_name) + LH.sac_targetter = null EC.total_sacrifices++ for(var/X in carbon_user.get_all_gear()) if(!istype(X,/obj/item/forbidden_book)) @@ -265,8 +269,14 @@ var/datum/objective/A = new A.owner = user.mind var/list/targets = list() + var/list/target_blacklist = list() + for(var/obj/item/living_heart/CLH in GLOB.living_heart_cache) + if(!CLH || !CLH.target || !CLH.target.mind) + continue + target_blacklist.Add(CLH.target.mind) + for(var/i in 0 to 3) - var/datum/mind/targeted = A.find_target()//easy way, i dont feel like copy pasting that entire block of code + var/datum/mind/targeted = A.find_target(blacklist = target_blacklist)//easy way, i dont feel like copy pasting that entire block of code if(!targeted) break targets[targeted.current.real_name] = targeted.current @@ -274,9 +284,24 @@ if(!LH.target && targets.len) LH.target = pick(targets) //Tsk tsk, you can and will get another target if you want it or not. + + if(LH.target) + target_blacklist = list() + for(var/obj/item/living_heart/CLH in (GLOB.living_heart_cache - LH)) //Recreate blacklist, excluding ourselves. + if(!CLH || !CLH.target || !CLH.target.mind) + continue + target_blacklist.Add(CLH.target.mind) + if(LH.target.mind in target_blacklist) //Someone was faster, or you tried to cheese the system. + to_chat(user, "It seems you were too slow, and your target of choice has already been selected by another living heart!") + LH.target = null + qdel(A) if(LH.target) to_chat(user,"Your new target has been selected, go and sacrifice [LH.target.real_name]!") + var/datum/antagonist/heretic/EC = carbon_user.mind.has_antag_datum(/datum/antagonist/heretic) + LH.sac_targetter = EC + EC.sac_targetted.Add(LH.target.real_name) + else to_chat(user,"target could not be found for living heart.") diff --git a/code/modules/antagonists/traitor/equipment/contractor.dm b/code/modules/antagonists/traitor/equipment/contractor.dm index 28298f4983..525f40d1f7 100644 --- a/code/modules/antagonists/traitor/equipment/contractor.dm +++ b/code/modules/antagonists/traitor/equipment/contractor.dm @@ -43,7 +43,7 @@ var/list/to_generate = list( CONTRACT_PAYOUT_LARGE, CONTRACT_PAYOUT_MEDIUM, - CONTRACT_PAYOUT_SMALL, + CONTRACT_PAYOUT_MEDIUM, CONTRACT_PAYOUT_SMALL, CONTRACT_PAYOUT_SMALL, CONTRACT_PAYOUT_SMALL diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm index f391ceae26..84b299471b 100644 --- a/code/modules/integrated_electronics/core/integrated_circuit.dm +++ b/code/modules/integrated_electronics/core/integrated_circuit.dm @@ -379,7 +379,7 @@ a creative player the means to solve many problems. Circuits are held inside an // Checks if the target object is reachable. Useful for various manipulators and manipulator-like objects. -/obj/item/integrated_circuit/proc/check_target(atom/target, exclude_contents = FALSE, exclude_components = FALSE, exclude_self = FALSE) +/obj/item/integrated_circuit/proc/check_target(atom/target, exclude_contents = FALSE, exclude_components = FALSE, exclude_self = FALSE, exclude_outside = FALSE) if(!target) return FALSE @@ -395,7 +395,7 @@ a creative player the means to solve many problems. Circuits are held inside an if(target == assembly.battery) return FALSE - if(target.Adjacent(acting_object) && isturf(target.loc)) + if(!exclude_outside && target.Adjacent(acting_object) && isturf(target.loc)) return TRUE if(!exclude_contents && (target in acting_object.GetAllContents())) diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index eac16d2950..e32f8daa2d 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -186,6 +186,8 @@ AM.forceMove(src) /obj/item/integrated_circuit/manipulation/grabber/proc/drop(obj/item/AM, turf/T = drop_location()) + if(!check_target(AM, FALSE, TRUE, TRUE, TRUE)) + return var/atom/A = get_object() A.investigate_log("dropped ([AM]) from [src].", INVESTIGATE_CIRCUIT) AM.forceMove(T) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 9ff409a5fb..56c90ba936 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1231,3 +1231,25 @@ */ /mob/living/carbon/proc/get_biological_state() return BIO_FLESH_BONE + +/mob/living/carbon/altattackby(obj/item/W, mob/living/carbon/user, params) + if(user.incapacitated() || !user.Adjacent(src)) + return FALSE + if(W && user.a_intent == INTENT_HELP && W.can_give()) + user.give() + return TRUE + +/mob/living/carbon/verb/give_verb() + set src in oview(1) + set category = "IC" + set name = "Give" + + if(usr.incapacitated() || !usr.Adjacent(src)) + return + + if(!usr.get_active_held_item()) // Let me know if this has any problems -Yota + return + var/obj/item/I = usr.get_active_held_item() + var/mob/living/carbon/C = usr + if(I.can_give()) + C.give() diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index 858e3000fb..75aff774ce 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -805,7 +805,7 @@ /datum/species/golem/plastic/on_species_loss(mob/living/carbon/C) . = ..() - C.RemoveElement(/datum/element/ventcrawling) + C.RemoveElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) /datum/species/golem/bronze name = "Bronze Golem" diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm index 2296b69762..5e07150ce6 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -169,7 +169,7 @@ if(istype(H, /mob/living/simple_animal)) var/mob/living/simple_animal/SA = H if((human_caster.blood_volume <= (BLOOD_VOLUME_BAD*human_caster.blood_ratio)) || (ventcrawl_nude_only && length(human_caster.get_equipped_items(include_pockets = TRUE)))) - SA.RemoveElement(/datum/element/ventcrawling) + SA.RemoveElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) if(transfer_name) H.name = human_caster.name diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index 0ba4023864..ff6941ec70 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -335,6 +335,11 @@ /mob/living/simple_animal/bot/floorbot/proc/repair(turf/target_turf) + if(check_bot_working(target_turf)) + add_to_ignore(target_turf) + target = null + playsound(src, 'sound/effects/whistlereset.ogg', 50, TRUE) + return if(isspaceturf(target_turf)) //Must be a hull breach or in line mode to continue. if(!is_hull_breach(target_turf) && !targetdirection) @@ -418,3 +423,14 @@ repair(A) else ..() + +/** + * Checks a given turf to see if another floorbot is there, working as well. + */ +/mob/living/simple_animal/bot/floorbot/proc/check_bot_working(turf/active_turf) + if(isturf(active_turf)) + for(var/mob/living/simple_animal/bot/floorbot/robot in active_turf) + if(robot.mode == BOT_REPAIRING) + return TRUE + return FALSE + diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm index 0728484cea..11d7884999 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm @@ -110,7 +110,7 @@ to_chat(src, "Your onboard antivirus has initiated lockdown. Motor servos are impaired, ventilation access is denied, and your display reports that you are hacked to all nearby.") hacked = TRUE mind.special_role = "hacked drone" - RemoveElement(/datum/element/ventcrawling) // balance + RemoveElement(/datum/element/ventcrawling, given_tier = VENTCRAWLER_ALWAYS) // balance speed = 1 //gotta go slow message_admins("[src] ([src.key]) became a hacked drone hellbent on [clockwork ? "serving Ratvar" : "destroying the station"]!") else diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index 11ce4f9214..ae0f5ea3ca 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -398,7 +398,6 @@ uniform = /obj/item/clothing/under/color/grey belt = /obj/item/tank/internals/emergency_oxygen mask = /obj/item/clothing/mask/gas - ears = /obj/item/radio/headset gloves = /obj/item/clothing/gloves/color/fyellow id = /obj/item/card/id/silver/reaper //looks cool and has a fancy name but only a 1% chance if(prob(99)) @@ -412,7 +411,7 @@ back = /obj/item/spear else if(prob(80)) //Now they dont always have a backpack back = /obj/item/storage/backpack - backpack_contents = list(/obj/item/stack/cable_coil = 1, /obj/item/assembly/flash = 1, /obj/item/storage/fancy/donut_box = 1, /obj/item/storage/fancy/cigarettes/cigpack_shadyjims = 1, /obj/item/lighter = 1) + backpack_contents = list(/obj/item/stack/cable_coil = 1, /obj/item/storage/fancy/donut_box = 1, /obj/item/storage/fancy/cigarettes/cigpack_shadyjims = 1, /obj/item/lighter = 1) if(prob(90)) r_pocket = /obj/item/kitchen/knife if(prob(60)) @@ -423,7 +422,6 @@ suit = /obj/item/clothing/suit/hooded/bee_costume shoes = /obj/item/clothing/shoes/sneakers/yellow gloves = /obj/item/clothing/gloves/color/yellow - ears = /obj/item/radio/headset belt = /obj/item/storage/belt/fannypack/yellow id_job = "Assisant" id = /obj/item/card/id diff --git a/html/changelogs/AutoChangeLog-pr-14059.yml b/html/changelogs/AutoChangeLog-pr-14059.yml new file mode 100644 index 0000000000..c20e1165ab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14059.yml @@ -0,0 +1,5 @@ +author: "Hatterhat" +delete-after: True +changes: + - rscdel: "Headsets can't be found on most legion corpses now." + - rscdel: "The flash on the assistant corpse is gone, too." diff --git a/html/changelogs/AutoChangeLog-pr-14105.yml b/html/changelogs/AutoChangeLog-pr-14105.yml new file mode 100644 index 0000000000..08c86c9915 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14105.yml @@ -0,0 +1,6 @@ +author: "DeltaFire15" +delete-after: True +changes: + - admin: "The heretic antag panel now shows their sacrifices & current sacrifice targets." + - tweak: "The heretic roundend report now shows their sacrifices and nonsacrificed targets." + - bugfix: "Living hearts can no longer select the same target as another living heart, removing a certain problem." diff --git a/html/changelogs/AutoChangeLog-pr-14114.yml b/html/changelogs/AutoChangeLog-pr-14114.yml new file mode 100644 index 0000000000..5035b47431 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14114.yml @@ -0,0 +1,4 @@ +author: "Hatterhat" +delete-after: True +changes: + - balance: "The free golem ship's GPSes no longer start on. They were never meant to, but they did." diff --git a/html/changelogs/AutoChangeLog-pr-14116.yml b/html/changelogs/AutoChangeLog-pr-14116.yml new file mode 100644 index 0000000000..fdbc7f2a6c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14116.yml @@ -0,0 +1,4 @@ +author: "timothyteakettle" +delete-after: True +changes: + - admin: "adminhelps and pms only sanitize once instead of twice" diff --git a/html/changelogs/AutoChangeLog-pr-14117.yml b/html/changelogs/AutoChangeLog-pr-14117.yml new file mode 100644 index 0000000000..f3fcae5eae --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14117.yml @@ -0,0 +1,4 @@ +author: "timothyteakettle" +delete-after: True +changes: + - rscadd: "blobs can use the 'me' verb" diff --git a/html/changelogs/AutoChangeLog-pr-14127.yml b/html/changelogs/AutoChangeLog-pr-14127.yml new file mode 100644 index 0000000000..2adc32ddd6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14127.yml @@ -0,0 +1,4 @@ +author: "Hatterhat" +delete-after: True +changes: + - balance: "One of the contractor tablet's payouts has been raised from a small payout to a medium payout." diff --git a/html/changelogs/AutoChangeLog-pr-14131.yml b/html/changelogs/AutoChangeLog-pr-14131.yml new file mode 100644 index 0000000000..5838f49bb2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14131.yml @@ -0,0 +1,4 @@ +author: "MrJWhit" +delete-after: True +changes: + - tweak: "Remaps some air alarms for sanity." diff --git a/html/changelogs/AutoChangeLog-pr-14133.yml b/html/changelogs/AutoChangeLog-pr-14133.yml new file mode 100644 index 0000000000..9968f41134 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14133.yml @@ -0,0 +1,5 @@ +author: "Hatterhat" +delete-after: True +changes: + - tweak: "Department budget cards have been readded. TO THE CODE. NOT LOCKERS." + - tweak: "Also budget cards now look more like every other ID - see tgstation#55001." diff --git a/html/changelogs/AutoChangeLog-pr-14134.yml b/html/changelogs/AutoChangeLog-pr-14134.yml new file mode 100644 index 0000000000..c699728c67 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14134.yml @@ -0,0 +1,4 @@ +author: "Arturlang" +delete-after: True +changes: + - rscadd: "Actually adds a right click give option" diff --git a/html/changelogs/AutoChangeLog-pr-14135.yml b/html/changelogs/AutoChangeLog-pr-14135.yml new file mode 100644 index 0000000000..bbbb7170b9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14135.yml @@ -0,0 +1,4 @@ +author: "raspy-on-osu" +delete-after: True +changes: + - bugfix: "bespoke ventcrawling element not detaching due to malformed call" diff --git a/html/changelogs/AutoChangeLog-pr-14136.yml b/html/changelogs/AutoChangeLog-pr-14136.yml new file mode 100644 index 0000000000..8b578f16e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14136.yml @@ -0,0 +1,5 @@ +author: "shellspeed1" +delete-after: True +changes: + - bugfix: "Floorbots had had a software update, preventing them from dogpiling on their target as easily as they did before." + - soundadd: "Floorbots will now play a small chime when stacked on top of each other to indicate that they're moving apart." diff --git a/html/changelogs/AutoChangeLog-pr-14137.yml b/html/changelogs/AutoChangeLog-pr-14137.yml new file mode 100644 index 0000000000..1b7602437b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-14137.yml @@ -0,0 +1,4 @@ +author: "SandPoot" +delete-after: True +changes: + - bugfix: "The drop circuit can no longer drop things that are not inside it." diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi index 13a0725b05..1bd94f2424 100644 Binary files a/icons/obj/card.dmi and b/icons/obj/card.dmi differ diff --git a/sound/effects/whistlereset.ogg b/sound/effects/whistlereset.ogg new file mode 100644 index 0000000000..cf55c06ca8 Binary files /dev/null and b/sound/effects/whistlereset.ogg differ