diff --git a/code/__DEFINES/dcs/signals/atom/signals_obj.dm b/code/__DEFINES/dcs/signals/atom/signals_obj.dm index df53558834f6..aebd0d09d0d2 100644 --- a/code/__DEFINES/dcs/signals/atom/signals_obj.dm +++ b/code/__DEFINES/dcs/signals/atom/signals_obj.dm @@ -4,6 +4,8 @@ /// From /obj/effect/alien/weeds/Initialize() #define COMSIG_WEEDNODE_GROWTH_COMPLETE "weednode_growth_complete" +/// From /obj/effect/alien/weeds/Initialize() +#define COMSIG_WEEDNODE_GROWTH "weednode_growth" /// From /obj/effect/alien/weeds/proc/on_weed_expand() #define COMSIG_WEEDNODE_CANNOT_EXPAND_FURTHER "weednode_cannot_expand_further" @@ -24,3 +26,6 @@ #define COMSIG_TRANSMITTER_UPDATE_ICON "transmitter_update_icon" #define COMSIG_TENT_COLLAPSING "tent_collapsing" + +/// from /obj/proc/afterbuckle() +#define COSMIG_OBJ_AFTER_BUCKLE "signal_obj_after_buckle" diff --git a/code/__DEFINES/tgui.dm b/code/__DEFINES/tgui.dm index 865088ee72fc..ca6408961eab 100644 --- a/code/__DEFINES/tgui.dm +++ b/code/__DEFINES/tgui.dm @@ -32,7 +32,7 @@ /// Creates a message packet for sending via output() // This is {"type":type,"payload":payload}, but pre-encoded. This is much faster // than doing it the normal way. -// To ensure this is correct, this is unit tested in tgui_create_message. However, CM does not have unit tests available. +// To ensure this is correct, this is unit tested in tgui_create_message. #define TGUI_CREATE_MESSAGE(type, payload) ( \ "%7b%22type%22%3a%22[type]%22%2c%22payload%22%3a[url_encode(json_encode(payload))]%7d" \ ) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index dd700ccde996..4897a04fea82 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -123,7 +123,7 @@ #define TRAIT_SUPER_STRONG "t_super_strong" /// Foreign biology. Basic medHUDs won't show the mob. (Yautja, Zombies) #define TRAIT_FOREIGN_BIO "t_foreign_bio" -/// Eye color changes on intent. (G1 Synths) +/// Eye color changes on intent. (G1 Synths and WJs) #define TRAIT_INTENT_EYES "t_intent_eyes" /// Masked synthetic biology. Basic medHUDs will percieve the mob as human. (Infiltrator Synths) #define TRAIT_INFILTRATOR_SYNTH "t_infiltrator_synth" @@ -157,6 +157,8 @@ #define TRAIT_LEADERSHIP "t_leadership" /// If the mob can see the reagents contents of stuff #define TRAIT_REAGENT_SCANNER "reagent_scanner" +/// If the mob cannot eat/be fed +#define TRAIT_CANNOT_EAT "t_cannot_eat" /// If the mob is being lazed by a sniper spotter #define TRAIT_SPOTTER_LAZED "t_spotter_lazed" /// If the mob has ear protection. Protects from external ear damage effects. Includes explosions, firing the RPG, screeching DEAFNESS only, and flashbangs. @@ -261,6 +263,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_BIMEX" = TRAIT_BIMEX, "TRAIT_EMOTE_CD_EXEMPT" = TRAIT_EMOTE_CD_EXEMPT, "TRAIT_LISPING" = TRAIT_LISPING, + "TRAIT_CANNOT_EAT" = TRAIT_CANNOT_EAT, ), /mob/living/carbon/xenomorph = list( "TRAIT_ABILITY_NO_PLASMA_TRANSFER" = TRAIT_ABILITY_NO_PLASMA_TRANSFER, diff --git a/code/__DEFINES/wj_emotes.dm b/code/__DEFINES/wj_emotes.dm new file mode 100644 index 000000000000..f315c6eb2ba5 --- /dev/null +++ b/code/__DEFINES/wj_emotes.dm @@ -0,0 +1,8 @@ +#define JOE_EMOTE_CATEGORY_GREETING "Greeting" +#define JOE_EMOTE_CATEGORY_TASK_UPDATE "Task Update" +#define JOE_EMOTE_CATEGORY_RESTRICTED_AREA "Restricted Area" +#define JOE_EMOTE_CATEGORY_FAREWELL "Farewell" +#define JOE_EMOTE_CATEGORY_QUIP "Quip" +#define JOE_EMOTE_CATEGORY_WARNING "Warning" +#define JOE_EMOTE_CATEGORY_QUESTION "Question" +#define JOE_EMOTE_CATEGORY_NOTICE "Notice" diff --git a/code/datums/components/footstep.dm b/code/datums/components/footstep.dm index 970ab89d961e..0d218ba94da4 100644 --- a/code/datums/components/footstep.dm +++ b/code/datums/components/footstep.dm @@ -31,7 +31,7 @@ return var/mob/living/LM = parent - if(LM.buckled || LM.throwing || LM.is_ventcrawling) + if(LM.buckled || LM.throwing || LM.is_ventcrawling || LM.stat == DEAD) return if(LM.life_steps_total % steps) diff --git a/code/datums/components/weed_food.dm b/code/datums/components/weed_food.dm new file mode 100644 index 000000000000..0c578b661517 --- /dev/null +++ b/code/datums/components/weed_food.dm @@ -0,0 +1,297 @@ +#define WEED_FOOD_DELAY 5 MINUTES +#define WEED_FOOD_STATE_DELAY 1 MINUTES + +/atom/movable/vis_obj/weed_food + name = "weeds" + desc = "Weird black weeds in the shape of a body..." + gender = PLURAL + vis_flags = VIS_INHERIT_DIR|VIS_INHERIT_PLANE|VIS_INHERIT_LAYER + icon = 'icons/mob/xenos/weeds.dmi' + var/static/list/icon_states = list("human_1","human_2","human_3","human_4","human_5") + var/static/list/icon_states_flipped = list("human_1_f","human_2_f","human_3_f","human_4_f","human_5_f") + var/icon_state_idx = 0 + var/timer_id = null + var/flipped = FALSE + +/atom/movable/vis_obj/weed_food/Initialize(mapload, is_flipped, ...) + flipped = is_flipped + timer_id = addtimer(CALLBACK(src, PROC_REF(on_animation_timer)), WEED_FOOD_STATE_DELAY, TIMER_STOPPABLE|TIMER_UNIQUE|TIMER_LOOP|TIMER_DELETE_ME) + on_animation_timer() + return ..() + +/// Timer callback for changing the icon_state +/atom/movable/vis_obj/weed_food/proc/on_animation_timer() + icon_state_idx++ + if(icon_state_idx > length(icon_states)) + deltimer(timer_id) + timer_id = null + return + icon_state = flipped ? icon_states_flipped[icon_state_idx] : icon_states[icon_state_idx] + +/** + * A component that can be attached to a mob/living to be merged with weeds after a delay. + * Attempting to attach a new weed_food even if one already exists is equivalent to calling start(). + * + * Attach this to any mob/living that is dead (death or initialized dead) and it should handle the rest. + */ +/datum/component/weed_food + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + /// Whether we are waiting on timer to merge + var/active = FALSE + /// Whether we are merged with weeds + var/merged = FALSE + /// The time we were unmerged (just to handle weeds upgrading) + var/unmerged_time + /// Any active timer for a pending merge + var/timer_id = null + /// The living mob that we are bound to + var/mob/living/parent_mob + /// The turf that our parent is on + var/turf/parent_turf + /// The obj that our parent is buckled to and we have registered a signal + var/obj/parent_buckle + /// The weeds that we are merging/merged with + var/obj/effect/alien/weeds/absorbing_weeds + /// The overlay image when merged + var/atom/movable/vis_obj/weed_food/weed_appearance + +/datum/component/weed_food/Initialize(...) + parent_mob = parent + //if(!istype(parent_mob)) + //return COMPONENT_INCOMPATIBLE + if(!istype(parent_mob, /mob/living/carbon/human)) + return COMPONENT_INCOMPATIBLE // TODO: At the moment we only support humans + + parent_turf = get_turf(parent_mob) + if(parent_turf != parent_mob.loc) + parent_turf = null // if our location is actually a container, we want to be safe from weeds + + start() + +/datum/component/weed_food/InheritComponent(datum/component/C, i_am_original) + start() + +/datum/component/weed_food/Destroy(force, silent) + . = ..() + + unmerge_with_weeds() + QDEL_NULL(weed_appearance) + parent_mob = null + parent_turf = null + +/datum/component/weed_food/RegisterWithParent() + RegisterSignal(parent_mob, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) + RegisterSignal(parent_mob, list(COMSIG_LIVING_REJUVENATED, COMSIG_HUMAN_REVIVED), PROC_REF(on_rejuv)) + RegisterSignal(parent_mob, COMSIG_HUMAN_SET_UNDEFIBBABLE, PROC_REF(on_update)) + if(parent_turf) + RegisterSignal(parent_turf, COMSIG_WEEDNODE_GROWTH, PROC_REF(on_update)) + +/datum/component/weed_food/UnregisterFromParent() + if(parent_mob) + UnregisterSignal(parent_mob, list( + COMSIG_MOVABLE_MOVED, + COMSIG_LIVING_REJUVENATED, + COMSIG_HUMAN_REVIVED, + COMSIG_HUMAN_SET_UNDEFIBBABLE, + )) + if(absorbing_weeds) + UnregisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING) + if(parent_turf) + UnregisterSignal(parent_turf, COMSIG_WEEDNODE_GROWTH) + if(parent_buckle) + UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE) + +/// SIGNAL_HANDLER for COMSIG_MOVABLE_MOVED +/datum/component/weed_food/proc/on_move() + SIGNAL_HANDLER + + if(absorbing_weeds) + UnregisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING) + absorbing_weeds = null + + if(parent_turf) + UnregisterSignal(parent_turf, COMSIG_WEEDNODE_GROWTH) + parent_turf = get_turf(parent_mob) + if(parent_turf != parent_mob.loc) + parent_turf = null // if our location is actually a container, we want to be safe from weeds + else + RegisterSignal(parent_turf, COMSIG_WEEDNODE_GROWTH, PROC_REF(on_update)) + + // We moved, restart or start the proccess + if(stop() || !merged) + start() + return + + // If we somehow moved when we were merged, handle that + absorbing_weeds = parent_turf?.weeds + if(absorbing_weeds) + RegisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING, PROC_REF(on_weed_deletion)) + return + unmerge_with_weeds() + +/// SIGNAL_HANDLER for COMSIG_LIVING_REJUVENATED and COMSIG_HUMAN_REVIVED +/datum/component/weed_food/proc/on_rejuv() + SIGNAL_HANDLER + + qdel(src) + +/// SIGNAL_HANDLER for COSMIG_OBJ_AFTER_BUCKLE +/datum/component/weed_food/proc/on_after_buckle(obj/source, mob/buckled) + SIGNAL_HANDLER + + if(buckled) + return + start() // We unbuckled, so lets try to start again + +/// SIGNAL_HANDLER for COMSIG_HUMAN_SET_UNDEFIBBABLE & COMSIG_WEEDNODE_GROWTH +/datum/component/weed_food/proc/on_update() + SIGNAL_HANDLER + + start() + +/// SIGNAL_HANDLER for COMSIG_PARENT_QDELETING of weeds +/datum/component/weed_food/proc/on_weed_deletion() + SIGNAL_HANDLER + + if(active) + stop() + return + if(merged) + unmerge_with_weeds() + return + +/** + * Try to start the process to turn into weeds + * Returns TRUE if started successfully + */ +/datum/component/weed_food/proc/start() + if(active) + return FALSE + if(merged) + return FALSE + if(QDELETED(parent_mob)) + return FALSE + + if(parent_mob.buckled) + if(parent_mob.buckled == parent_buckle) + return FALSE // Still buckled to the same thing + if(!istype(parent_mob.buckled, /obj/structure/bed/nest)) + if(parent_buckle) // Still have a lingering reference somehow? + UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE) + parent_buckle = parent_mob.buckled + RegisterSignal(parent_mob.buckled, COSMIG_OBJ_AFTER_BUCKLE, PROC_REF(on_after_buckle)) + return FALSE + if(parent_buckle) + UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE) + parent_buckle = null + + if(parent_mob.is_xeno_grabbable()) + return FALSE + if(!(parent_mob.status_flags & PERMANENTLY_DEAD)) + var/mob/living/carbon/human/parent_human = parent_mob + if(istype(parent_human) && !parent_human.undefibbable) + return FALSE + if(!parent_turf?.weeds) + return FALSE + + if(unmerged_time == world.time) + return merge_with_weeds() // Weeds upgraded, re-merge now re-using the apperance + QDEL_NULL(weed_appearance) + absorbing_weeds = parent_turf.weeds + RegisterSignal(parent_turf.weeds, COMSIG_PARENT_QDELETING, PROC_REF(on_weed_deletion)) + + active = TRUE + timer_id = addtimer(CALLBACK(src, PROC_REF(merge_with_weeds)), WEED_FOOD_DELAY, TIMER_STOPPABLE|TIMER_UNIQUE|TIMER_DELETE_ME|TIMER_OVERRIDE) + + return TRUE + +/** + * Try to stop the process turning into weeds + * Returns TRUE if stopped successfully (was active when called) + */ +/datum/component/weed_food/proc/stop() + if(!active) + return FALSE + + active = FALSE + deltimer(timer_id) + timer_id = null + + return TRUE + +/** + * Finish becomming one with the weeds + * Returns TRUE if merged successfully + */ +/datum/component/weed_food/proc/merge_with_weeds() + if(merged) + return FALSE + if(QDELETED(parent_mob)) + return FALSE + + if(absorbing_weeds) // Remove the signal that would call stop + UnregisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING) + + if(parent_mob.buckled) + if(parent_mob.buckled == parent_buckle) + return FALSE // Still buckled to the same thing somehow? + if(!istype(parent_mob.buckled, /obj/structure/bed/nest)) + if(parent_buckle) // Still have a lingering reference somehow? + UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE) + parent_buckle = parent_mob.buckled + RegisterSignal(parent_mob.buckled, COSMIG_OBJ_AFTER_BUCKLE, PROC_REF(on_after_buckle)) + return FALSE + if(parent_buckle) + UnregisterSignal(parent_buckle, COSMIG_OBJ_AFTER_BUCKLE) + parent_buckle = null + + absorbing_weeds = parent_turf?.weeds + if(!absorbing_weeds) + return FALSE + RegisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING, PROC_REF(on_weed_deletion)) + // Technically we could have just left the signal alone, but both because of the posibility of other conditions preventing a merge or weeds somehow changing and on_move didn't catch it, this is less fragile + + active = FALSE + merged = TRUE + + parent_mob.density = FALSE + parent_mob.anchored = TRUE + parent_mob.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + parent_mob.plane = FLOOR_PLANE + parent_mob.remove_from_all_mob_huds() + + if(!weed_appearance) // Make a new sprite if we aren't re-merging + var/is_flipped = parent_mob.transform.b == -1 // Technically we should check if d is 1 too, but corpses can only be rotated 90 or 270 (1/-1 or -1/1) + if(parent_mob.dir & WEST) + is_flipped = !is_flipped // The direction reversed the effect of the flip! + weed_appearance = new(null, is_flipped) + weed_appearance.color = absorbing_weeds.color + // TODO: For non-humans change the icon_state or something here + parent_mob.vis_contents += weed_appearance + + return TRUE + +/** + * Undo the weedening + * Returns TRUE if unmerged successfully (always) + */ +/datum/component/weed_food/proc/unmerge_with_weeds() + merged = FALSE + unmerged_time = world.time + + if(absorbing_weeds) + UnregisterSignal(absorbing_weeds, COMSIG_PARENT_QDELETING) + absorbing_weeds = null + + parent_mob.anchored = FALSE + parent_mob.mouse_opacity = MOUSE_OPACITY_ICON + parent_mob.plane = GAME_PLANE + parent_mob.vis_contents -= weed_appearance + + if(!QDELETED(parent_mob)) + parent_mob.add_to_all_mob_huds() + + return TRUE + +#undef WEED_FOOD_DELAY +#undef WEED_FOOD_STATE_DELAY diff --git a/code/datums/skills.dm b/code/datums/skills.dm index ef86b726a3c1..16a2a20a57fd 100644 --- a/code/datums/skills.dm +++ b/code/datums/skills.dm @@ -851,7 +851,7 @@ SYNTHETIC /datum/skills/colonial_synthetic name = SYNTH_COLONY skills = list( - SKILL_CQC = SKILL_CQC_SKILLED, + SKILL_CQC = SKILL_CQC_EXPERT, SKILL_ENGINEER = SKILL_ENGINEER_ENGI, SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI, SKILL_FIREARMS = SKILL_FIREARMS_EXPERT, @@ -862,7 +862,7 @@ SYNTHETIC SKILL_MELEE_WEAPONS = SKILL_MELEE_SUPER, SKILL_PILOT = SKILL_PILOT_EXPERT, SKILL_POLICE = SKILL_POLICE_SKILLED, - SKILL_FIREMAN = SKILL_FIREMAN_TRAINED, + SKILL_FIREMAN = SKILL_FIREMAN_EXPERT, SKILL_POWERLOADER = SKILL_POWERLOADER_MASTER, SKILL_VEHICLE = SKILL_VEHICLE_LARGE, SKILL_JTAC = SKILL_JTAC_BEGINNER, diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 7a10a3ffa1df..6ccb0b5b18f7 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -284,7 +284,7 @@ return //Dismantle the frame. - if(istype(O, /obj/item/tool/crowbar)) + if(HAS_TRAIT(O, TRAIT_TOOL_CROWBAR)) dismantle() return diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index fd246d2d640a..bb6972a58ac3 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -51,7 +51,7 @@ to_chat(user, SPAN_NOTICE(" You screw the circuit board into place.")) state = 2 icon_state = "2" - if(istype(P, /obj/item/tool/crowbar) && circuit) + if(HAS_TRAIT(P, TRAIT_TOOL_CROWBAR) && circuit) playsound(loc, 'sound/items/Crowbar.ogg', 25, 1) to_chat(user, SPAN_NOTICE(" You remove the circuit board.")) state = 1 @@ -121,7 +121,7 @@ to_chat(usr, "Added [mmi].") icon_state = "3b" - if(istype(P, /obj/item/tool/crowbar) && brain) + if(HAS_TRAIT(P, TRAIT_TOOL_CROWBAR) && brain) playsound(loc, 'sound/items/Crowbar.ogg', 25, 1) to_chat(user, SPAN_NOTICE(" You remove the brain.")) brain.forceMove(loc) @@ -129,7 +129,7 @@ icon_state = "3" if(4) - if(istype(P, /obj/item/tool/crowbar)) + if(HAS_TRAIT(P, TRAIT_TOOL_CROWBAR)) playsound(loc, 'sound/items/Crowbar.ogg', 25, 1) to_chat(user, SPAN_NOTICE(" You remove the glass panel.")) state = 3 diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index bd42b31ea573..07c960807205 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -52,7 +52,7 @@ to_chat(user, SPAN_NOTICE(" You screw the circuit board into place.")) src.state = 2 src.icon_state = "2" - if(istype(P, /obj/item/tool/crowbar) && circuit) + if(HAS_TRAIT(P, TRAIT_TOOL_CROWBAR) && circuit) playsound(src.loc, 'sound/items/Crowbar.ogg', 25, 1) to_chat(user, SPAN_NOTICE(" You remove the circuit board.")) src.state = 1 @@ -99,7 +99,7 @@ src.state = 4 src.icon_state = "4" if(4) - if(istype(P, /obj/item/tool/crowbar)) + if(HAS_TRAIT(P, TRAIT_TOOL_CROWBAR)) playsound(src.loc, 'sound/items/Crowbar.ogg', 25, 1) to_chat(user, SPAN_NOTICE(" You remove the glass panel.")) src.state = 3 diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 0288b7eb2426..357ef48fff37 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -114,7 +114,7 @@ A.amount = 5 if(CONSTRUCTION_STATE_FINISHED) - if(istype(P, /obj/item/tool/crowbar)) + if(HAS_TRAIT(P, TRAIT_TOOL_CROWBAR)) if(!skillcheck(user, SKILL_ENGINEER, required_dismantle_skill)) to_chat(user, SPAN_WARNING("You are not trained to dismantle machines...")) return diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 435976668577..afcc9686cff5 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -2,6 +2,7 @@ /obj/structure/machinery/cryo_cell name = "cryo cell" + desc = "A donation from the old A.W. project, using cryogenic technology. It slowly heals whoever is inside the tube." icon = 'icons/obj/structures/machinery/cryogenics2.dmi' icon_state = "cell" density = FALSE diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 6d96daf3152f..e9006a9f2fb4 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -167,7 +167,7 @@ return //If it's emagged, crowbar can pry electronics out. - if (src.operating == -1 && istype(I, /obj/item/tool/crowbar)) + if (src.operating == -1 && HAS_TRAIT(I, TRAIT_TOOL_CROWBAR)) playsound(src.loc, 'sound/items/Crowbar.ogg', 25, 1) user.visible_message("[user] removes the electronics from the windoor.", "You start to remove electronics from the windoor.") if (do_after(user, 40, INTERRUPT_ALL, BUSY_ICON_BUILD)) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index e1c9c9a4e279..b538f55292c1 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -4,13 +4,16 @@ anchored = FALSE density = FALSE drag_delay = 1 + base_pixel_x = 15 + base_pixel_y = -2 var/mob/living/carbon/attached = null var/mode = 1 // 1 is injecting, 0 is taking blood. var/obj/item/reagent_container/beaker = null + var/datum/beam/current_beam /obj/structure/machinery/iv_drip/update_icon() - if(src.attached) + if(attached) icon_state = "hooked" else icon_state = "" @@ -35,8 +38,31 @@ filling.color = mix_color_from_reagents(reagents.reagent_list) overlays += filling +/obj/structure/machinery/iv_drip/proc/update_beam() + if(current_beam) + QDEL_NULL(current_beam) + else if(!QDELETED(src) && attached) + current_beam = beam(attached, "iv_tube") + +/obj/structure/machinery/iv_drip/power_change() + . = ..() + if(stat & NOPOWER && attached) + visible_message("\The [src] retracts its IV tube and shuts down.") + attached.active_transfusions -= src + attached = null + update_beam() + update_icon() + +/obj/structure/machinery/iv_drip/Destroy() + attached?.active_transfusions -= src + update_beam() + . = ..() + /obj/structure/machinery/iv_drip/MouseDrop(over_object, src_location, over_location) ..() + if(inoperable()) + visible_message("\The [src] is not powered.") + return if(ishuman(usr)) var/mob/living/carbon/human/H = usr @@ -48,6 +74,7 @@ "You detach \the [src] from \the [attached].") attached.active_transfusions -= src attached = null + update_beam() update_icon() stop_processing() return @@ -57,6 +84,7 @@ "You attach \the [src] to \the [over_object].") attached = over_object attached.active_transfusions += src + update_beam() update_icon() start_processing() @@ -81,6 +109,7 @@ log_admin("[key_name(user)] put a [beaker] into [src], containing [reagentnames] at ([src.loc.x],[src.loc.y],[src.loc.z]).") to_chat(user, "You attach \the [W] to \the [src].") + update_beam() update_icon() return else @@ -97,6 +126,7 @@ attached.emote("scream") attached.active_transfusions -= src attached = null + update_beam() update_icon() stop_processing() return diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index cded8a1148c7..a370356ad60b 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -62,7 +62,7 @@ stat &= ~BROKEN // the machine's not borked anymore! else to_chat(user, SPAN_WARNING("You need five coils of wire for this.")) - if(istype(P, /obj/item/tool/crowbar)) + if(HAS_TRAIT(P, TRAIT_TOOL_CROWBAR)) to_chat(user, "You begin prying out the circuit board other components...") playsound(src.loc, 'sound/items/Crowbar.ogg', 25, 1) if(do_after(user, 60 * user.get_skill_duration_multiplier(SKILL_ENGINEER), INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) diff --git a/code/game/machinery/vending/vendor_types/medical.dm b/code/game/machinery/vending/vendor_types/medical.dm index 5815f60b2e0c..70ac7701973b 100644 --- a/code/game/machinery/vending/vendor_types/medical.dm +++ b/code/game/machinery/vending/vendor_types/medical.dm @@ -272,7 +272,7 @@ /obj/structure/machinery/cm_vending/sorted/medical/blood name = "\improper MM Blood Dispenser" - desc = "Marine Med brand Blood Pack Dispensary" + desc = "The Marine Med Brand Blood Pack Dispensary is the premier, top-of-the-line blood dispenser of 2105! Get yours today!" //Don't update this year, the joke is it's old. icon_state = "blood" wrenchable = TRUE hackable = TRUE diff --git a/code/game/objects/items/reagent_containers/blood_pack.dm b/code/game/objects/items/reagent_containers/blood_pack.dm index 450cdde2fa00..8e29a26c2ecd 100644 --- a/code/game/objects/items/reagent_containers/blood_pack.dm +++ b/code/game/objects/items/reagent_containers/blood_pack.dm @@ -13,7 +13,9 @@ var/mode = BLOOD_BAG_INJECTING var/mob/living/carbon/human/connected_to + var/mob/living/carbon/human/connected_from var/blood_type = null + var/datum/beam/current_beam /obj/item/reagent_container/blood/Initialize() . = ..() @@ -32,6 +34,12 @@ if(10 to 50) icon_state = "half" if(51 to INFINITY) icon_state = "full" +/obj/item/reagent_container/blood/proc/update_beam() + if(current_beam) + QDEL_NULL(current_beam) + else if(connected_from && connected_to) + current_beam = connected_from.beam(connected_to, "iv_tube") + /obj/item/reagent_container/blood/attack(mob/attacked_mob, mob/user) . = ..() @@ -44,7 +52,10 @@ user.visible_message("[user] detaches [src] from [connected_to].", \ "You detach [src] from [connected_to].") connected_to.active_transfusions -= src + connected_to.base_pixel_x = 0 connected_to = null + connected_from = null + update_beam() return if(!skillcheck(user, SKILL_SURGERY, SKILL_SURGERY_NOVICE)) @@ -60,10 +71,13 @@ if(istype(attacked_mob, /mob/living/carbon/human)) connected_to = attacked_mob + connected_from = user connected_to.active_transfusions += src + connected_to.base_pixel_x = 5 START_PROCESSING(SSobj, src) user.visible_message("[user] attaches \the [src] to [connected_to].", \ "You attach \the [src] to [connected_to].") + update_beam() /obj/item/reagent_container/blood/process() //if we're not connected to anything stop doing stuff @@ -106,6 +120,10 @@ connected_to.take_blood(src, amount) +/obj/item/reagent_container/blood/dropped() + ..() + bad_disconnect() + ///Used to standardize effects of a blood bag disconnecting improperly /obj/item/reagent_container/blood/proc/bad_disconnect() if(!connected_to) @@ -116,7 +134,10 @@ if(connected_to.pain.feels_pain) connected_to.emote("scream") connected_to.active_transfusions -= src + connected_to.base_pixel_x = 0 connected_to = null + connected_from = null + update_beam() /obj/item/reagent_container/blood/verb/toggle_mode() set category = "Object" diff --git a/code/game/objects/items/reagent_containers/food/snacks.dm b/code/game/objects/items/reagent_containers/food/snacks.dm index 7dae94bfe4eb..c0e11dac8eb3 100644 --- a/code/game/objects/items/reagent_containers/food/snacks.dm +++ b/code/game/objects/items/reagent_containers/food/snacks.dm @@ -66,6 +66,10 @@ if(issynth(C)) fullness = 200 //Synths never get full + if(HAS_TRAIT(M, TRAIT_CANNOT_EAT)) //Do not feed the Working Joes + to_chat(user, SPAN_DANGER("[user == M ? "You are" : "[M] is"] unable to eat!")) + return + if(fullness > 540) C.overeat_cooldown = world.time + OVEREAT_TIME diff --git a/code/game/objects/items/tools/flame_tools.dm b/code/game/objects/items/tools/flame_tools.dm index db35d3300ae7..6ebd8ee5982e 100644 --- a/code/game/objects/items/tools/flame_tools.dm +++ b/code/game/objects/items/tools/flame_tools.dm @@ -170,13 +170,20 @@ CIGARETTE PACKETS ARE IN FANCY.DM damtype = "brute" icon_state = "[initial(icon_state)]_burnt" item_state = "cigoff" - if(user && loc != user) - user.SetLuminosity(0, FALSE, src) SetLuminosity(0) name = burnt_name desc = "A match. This one has seen better days." STOP_PROCESSING(SSobj, src) + if(user) + user.SetLuminosity(0, FALSE, src) + return + + if(ismob(loc)) + user = loc + user.SetLuminosity(0, FALSE, src) + return + /obj/item/tool/match/paper name = "paper match" desc = "A simple match stick, used for lighting fine smokables." diff --git a/code/game/objects/items/tools/maintenance_tools.dm b/code/game/objects/items/tools/maintenance_tools.dm index 25bcefc1cc34..2560c5ff91e8 100644 --- a/code/game/objects/items/tools/maintenance_tools.dm +++ b/code/game/objects/items/tools/maintenance_tools.dm @@ -557,8 +557,6 @@ if(attacked_door.locked) //Bolted to_chat(user, SPAN_DANGER("You can't pry open [attacked_door] while it is bolted shut.")) return - if(!attacked_door.arePowerSystemsOn()) //Opens like normal if unpowered - return FALSE if(requires_superstrength_pry) if(!HAS_TRAIT(user, TRAIT_SUPER_STRONG)) //basically IS_PRY_CAPABLE_CROWBAR @@ -645,7 +643,7 @@ resin_door.Open() return - if(istype(attacked_obj, /turf/open/floor)) + else if(istype(attacked_obj, /turf/open/floor)) var/turf/open/floor/flooring = attacked_obj if(crowbar_mode && user.a_intent == INTENT_HELP) //Only pry flooring on help intent diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index e98e3b527c5f..b92624cf4201 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -223,6 +223,7 @@ /obj/proc/afterbuckle(mob/M as mob) // Called after somebody buckled / unbuckled handle_rotation() + SEND_SIGNAL(src, COSMIG_OBJ_AFTER_BUCKLE, buckled_mob) return buckled_mob /obj/proc/unbuckle() diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index e6c215d0208f..cf0374c09ab4 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -135,15 +135,17 @@ return stored_units /obj/structure/closet/proc/store_mobs(stored_units) - for(var/mob/M in src.loc) + for(var/mob/cur_mob in src.loc) if(stored_units + mob_size > storage_capacity) break - if(istype (M, /mob/dead/observer)) + if(istype (cur_mob, /mob/dead/observer)) continue - if(M.buckled) + if(cur_mob.buckled) + continue + if(cur_mob.anchored) continue - M.forceMove(src) + cur_mob.forceMove(src) stored_units += mob_size return stored_units diff --git a/code/game/objects/structures/props.dm b/code/game/objects/structures/props.dm index f6905d4d044d..1a91650c620a 100644 --- a/code/game/objects/structures/props.dm +++ b/code/game/objects/structures/props.dm @@ -24,7 +24,7 @@ . = ..() if(isxeno(user)) return - else if (ishuman(user) && istype(W, /obj/item/tool/wrench)) + else if (ishuman(user) && HAS_TRAIT(W, TRAIT_TOOL_WRENCH)) on = !on visible_message("You wrench the controls of \the [src]. The drill jumps to life." , "[user] wrenches the controls of \the [src]. The drill jumps to life.") @@ -501,7 +501,7 @@ . = ..() if(isxeno(user)) return - else if (ishuman(user) && istype(W, /obj/item/tool/crowbar)) + else if (ishuman(user) && HAS_TRAIT(W, TRAIT_TOOL_CROWBAR)) on = !on visible_message("You pry at the control valve on [src]. The machine shudders." , "[user] pries at the control valve on [src]. The entire machine shudders.") diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 5c084ce94cbc..cccc1211bfb0 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -121,7 +121,7 @@ cistern_overlay.icon_state = "cistern[cistern]" /obj/structure/toilet/attackby(obj/item/I, mob/living/user) - if(istype(I, /obj/item/tool/crowbar)) + if(HAS_TRAIT(I, TRAIT_TOOL_CROWBAR)) to_chat(user, SPAN_NOTICE("You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"].")) playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 25, 1) if(do_after(user, 30, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) diff --git a/code/game/turfs/floor.dm b/code/game/turfs/floor.dm index 4a600d4d033b..dc2cda0c2c2a 100644 --- a/code/game/turfs/floor.dm +++ b/code/game/turfs/floor.dm @@ -148,7 +148,7 @@ if(src.weeds) return weeds.attackby(hitting_item,user) - if(istype(hitting_item, /obj/item/tool/crowbar) && (tool_flags & (REMOVE_CROWBAR|BREAK_CROWBAR))) + if(HAS_TRAIT(hitting_item, TRAIT_TOOL_CROWBAR) && (tool_flags & (REMOVE_CROWBAR|BREAK_CROWBAR))) if(broken || burnt) to_chat(user, SPAN_WARNING("You remove the broken tiles.")) else diff --git a/code/game/turfs/walls/walls.dm b/code/game/turfs/walls/walls.dm index 411ff8182661..3599d5bb980b 100644 --- a/code/game/turfs/walls/walls.dm +++ b/code/game/turfs/walls/walls.dm @@ -98,11 +98,15 @@ qdel(found_nest) //nests are built on walls, no walls, no nest /turf/closed/wall/MouseDrop_T(mob/current_mob, mob/user) + if(!ismob(current_mob)) + return + if(acided_hole) if(current_mob == user && isxeno(user)) acided_hole.use_wall_hole(user) return - if(isxeno(user)) + + if(isxeno(user) && istype(user.get_active_hand(), /obj/item/grab)) var/mob/living/carbon/xenomorph/user_as_xenomorph = user user_as_xenomorph.do_nesting_host(current_mob, src) ..() diff --git a/code/modules/admin/tabs/event_tab.dm b/code/modules/admin/tabs/event_tab.dm index 4effbf3b26cb..febc1550fca0 100644 --- a/code/modules/admin/tabs/event_tab.dm +++ b/code/modules/admin/tabs/event_tab.dm @@ -744,7 +744,7 @@ create_humans_html = replacetext(create_humans_html, "null /* object types */", "\"[equipment_presets]\"") create_humans_html = replacetext(create_humans_html, "/* href token */", RawHrefToken(forceGlobal = TRUE)) - show_browser(user, replacetext(create_humans_html, "/* ref src */", "\ref[src]"), "Create Humans", "create_humans", "size=450x630") + show_browser(user, replacetext(create_humans_html, "/* ref src */", "\ref[src]"), "Create Humans", "create_humans", "size=450x720") /client/proc/create_humans() set name = "Create Humans" diff --git a/code/modules/cm_aliens/weeds.dm b/code/modules/cm_aliens/weeds.dm index 7ca73a5c2822..f20fa842e446 100644 --- a/code/modules/cm_aliens/weeds.dm +++ b/code/modules/cm_aliens/weeds.dm @@ -73,10 +73,11 @@ else if(!hibernate && do_spread) addtimer(CALLBACK(src, PROC_REF(weed_expand)), WEED_BASE_GROW_SPEED / max(weed_strength, 1)) - var/turf/T = get_turf(src) - if(T) - T.weeds = src - weeded_turf = T + var/turf/turf = get_turf(src) + if(turf) + turf.weeds = src + weeded_turf = turf + SEND_SIGNAL(turf, COMSIG_WEEDNODE_GROWTH) // Currently for weed_food wakeup RegisterSignal(src, list( COMSIG_ATOM_TURF_CHANGE, @@ -429,7 +430,11 @@ /obj/effect/alien/weeds/weedwall/MouseDrop_T(mob/current_mob, mob/user) . = ..() - if(isxeno(user)) + + if(!ismob(current_mob)) + return + + if(isxeno(user) && istype(user.get_active_hand(), /obj/item/grab)) var/mob/living/carbon/xenomorph/user_as_xenomorph = user user_as_xenomorph.do_nesting_host(current_mob, src) diff --git a/code/modules/cm_tech/implements/railgun.dm b/code/modules/cm_tech/implements/railgun.dm index b0d91515419f..b69f9a9d13a8 100644 --- a/code/modules/cm_tech/implements/railgun.dm +++ b/code/modules/cm_tech/implements/railgun.dm @@ -6,6 +6,7 @@ GLOBAL_DATUM(railgun_eye_location, /datum/coords) /obj/effect/landmark/railgun_computer name = "Railgun computer landmark" + desc = "A computer with an orange interface, it's idly blinking, awaiting a password." /obj/effect/landmark/railgun_computer/Initialize(mapload, ...) . = ..() diff --git a/code/modules/gear_presets/corpses.dm b/code/modules/gear_presets/corpses.dm index 02671cc02a93..7e9dd5b841a0 100644 --- a/code/modules/gear_presets/corpses.dm +++ b/code/modules/gear_presets/corpses.dm @@ -16,28 +16,32 @@ /datum/equipment_preset/corpse/load_status(mob/living/carbon/human/new_human) . = ..(new_human) + + // These two values matter because they are checked on death for weed_food + new_human.undefibbable = TRUE + if(xenovictim) + new_human.chestburst = 2 + new_human.death(create_cause_data("existing"), TRUE) //Kills the new mob new_human.apply_damage(100, BRUTE) new_human.apply_damage(100, BRUTE) new_human.apply_damage(100, BRUTE) if(xenovictim) - var/datum/internal_organ/O + var/datum/internal_organ/organ var/i for(i in list("heart","lungs")) - O = new_human.internal_organs_by_name[i] + organ = new_human.internal_organs_by_name[i] new_human.internal_organs_by_name -= i - new_human.internal_organs -= O - new_human.chestburst = 2 + new_human.internal_organs -= organ new_human.update_burst() //buckle to nest - var/obj/structure/bed/nest/N = locate() in get_turf(src) - if(N) - new_human.buckled = N - new_human.setDir(N.dir) + var/obj/structure/bed/nest/nest = locate() in get_turf(src) + if(nest) + new_human.buckled = nest + new_human.setDir(nest.dir) new_human.update_canmove() - N.buckled_mob = new_human - N.afterbuckle(new_human) - new_human.undefibbable = TRUE + nest.buckled_mob = new_human + nest.afterbuckle(new_human) new_human.spawned_corpse = TRUE new_human.updatehealth() new_human.pulse = PULSE_NONE diff --git a/code/modules/gear_presets/survivors.dm b/code/modules/gear_presets/survivors.dm index 456f0881987e..44808d7a374f 100644 --- a/code/modules/gear_presets/survivors.dm +++ b/code/modules/gear_presets/survivors.dm @@ -1369,3 +1369,43 @@ return var/shoespath = /obj/item/clothing/shoes/combat human.equip_to_slot_or_del(new shoespath, WEAR_FEET) + +/datum/equipment_preset/survivor/new_varadero/commander + name = "Survivor - USASF Commander" + assignment = "USASF Commander" + skills = /datum/skills/commander + paygrade = "NO5" + idtype = /obj/item/card/id/gold + role_comm_title = "USASF CDR" + flags = EQUIPMENT_PRESET_START_OF_ROUND + access = list( + ACCESS_CIVILIAN_PUBLIC, + ACCESS_CIVILIAN_RESEARCH, + ACCESS_CIVILIAN_ENGINEERING, + ACCESS_CIVILIAN_LOGISTICS, + ACCESS_CIVILIAN_BRIG, + ACCESS_CIVILIAN_MEDBAY, + ACCESS_CIVILIAN_COMMAND, + ) + +/datum/equipment_preset/survivor/new_varadero/commander/load_gear(mob/living/carbon/human/new_human) + new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/officer/bridge(new_human), WEAR_BODY) + + var/obj/item/clothing/suit/storage/jacket/marine/service/suit = new() + suit.icon_state = "[suit.initial_icon_state]_o" + suit.buttoned = FALSE + + var/obj/item/clothing/accessory/ranks/navy/o5/pin = new() + suit.attach_accessory(new_human, pin) + + new_human.equip_to_slot_or_del(suit, WEAR_JACKET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(new_human), WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress(new_human), WEAR_L_EAR) + new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/survival/full(new_human), WEAR_L_STORE) + new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large(new_human), WEAR_R_STORE) + new_human.equip_to_slot_or_del(new /obj/item/notepad(new_human), WEAR_IN_R_STORE) + new_human.equip_to_slot_or_del(new /obj/item/tool/pen/fountain(new_human), WEAR_IN_R_STORE) + new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel(new_human), WEAR_BACK) + new_human.equip_to_slot_or_del(new /obj/item/stack/sheet/metal/med_small_stack(new_human), WEAR_IN_BACK) + new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/m4a3/m1911(new_human), WEAR_WAIST) + new_human.equip_to_slot_or_del(new /obj/item/clothing/head/cmcap(new_human), WEAR_HEAD) diff --git a/code/modules/gear_presets/synths.dm b/code/modules/gear_presets/synths.dm index f2a5283e2a26..823cfb4d69d4 100644 --- a/code/modules/gear_presets/synths.dm +++ b/code/modules/gear_presets/synths.dm @@ -532,6 +532,7 @@ new_human.h_style = "Bald" new_human.f_style = "Shaved" if(prob(5)) + new_human.grad_style = "None" //No gradients for Working Joes new_human.h_style = "Shoulder-length Hair" //Added the chance of hair as per Monkeyfist lore accuracy new_human.r_eyes = 0 new_human.g_eyes = 0 diff --git a/code/modules/gear_presets/uscm_medical.dm b/code/modules/gear_presets/uscm_medical.dm index 3c4509e88789..ac1e082f6655 100644 --- a/code/modules/gear_presets/uscm_medical.dm +++ b/code/modules/gear_presets/uscm_medical.dm @@ -55,7 +55,6 @@ back_item = /obj/item/storage/backpack/marine new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/almayer/cmo(new_human), WEAR_L_EAR) - new_human.equip_to_slot_or_del(new /obj/item/tool/pen/fountain(new_human), WEAR_R_EAR) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/rank/chief_medical_officer(new_human), WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/latex(new_human), WEAR_HANDS) diff --git a/code/modules/gear_presets/uscm_police.dm b/code/modules/gear_presets/uscm_police.dm index 884e0edcd9db..29bc32cffa7a 100644 --- a/code/modules/gear_presets/uscm_police.dm +++ b/code/modules/gear_presets/uscm_police.dm @@ -170,7 +170,6 @@ back_item = /obj/item/storage/backpack/security new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/almayer/cmpcom(new_human), WEAR_L_EAR) - new_human.equip_to_slot_or_del(new /obj/item/tool/pen/fountain(new_human), WEAR_R_EAR) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/officer/warrant(new_human), WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine(new_human), WEAR_HANDS) diff --git a/code/modules/gear_presets/uscm_ship.dm b/code/modules/gear_presets/uscm_ship.dm index 8816ed5f5790..7aa9eabb3042 100644 --- a/code/modules/gear_presets/uscm_ship.dm +++ b/code/modules/gear_presets/uscm_ship.dm @@ -77,7 +77,6 @@ //back_item = /obj/item/storage/backpack new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/almayer/mcl(new_human), WEAR_L_EAR) - new_human.equip_to_slot_or_del(new /obj/item/tool/pen/fountain(new_human), WEAR_R_EAR) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/liaison_suit(new_human), WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new back_item(new_human), WEAR_BACK) @@ -219,7 +218,6 @@ back_item = /obj/item/storage/backpack/marine/tech new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/almayer/ce(new_human), WEAR_L_EAR) - new_human.equip_to_slot_or_del(new /obj/item/tool/pen/fountain(new_human), WEAR_R_EAR) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/officer/ce(new_human), WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/yellow(new_human), WEAR_HANDS) @@ -344,7 +342,6 @@ back_item = /obj/item/storage/backpack/industrial new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/almayer/ro(new_human), WEAR_L_EAR) - new_human.equip_to_slot_or_del(new /obj/item/tool/pen/fountain(new_human), WEAR_R_EAR) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/rank/ro_suit(new_human), WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/yellow(new_human), WEAR_HANDS) @@ -455,7 +452,6 @@ sidearmpath = /obj/item/storage/belt/gun/m4a3/vp78 new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/almayer/mcom/cdrcom(new_human), WEAR_L_EAR) - new_human.equip_to_slot_or_del(new /obj/item/tool/pen/fountain(new_human), WEAR_R_EAR) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/officer/bridge(new_human), WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/jacket/marine/service(new_human), WEAR_JACKET) new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/dress/commander(new_human), WEAR_FEET) @@ -523,7 +519,6 @@ back_item = /obj/item/storage/backpack/marine new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/almayer/mcom/cdrcom(new_human), WEAR_L_EAR) - new_human.equip_to_slot_or_del(new /obj/item/tool/pen/fountain(new_human), WEAR_R_EAR) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/officer/exec(new_human), WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/jacket/marine/service(new_human), WEAR_JACKET) new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/dress(new_human), WEAR_FEET) @@ -557,7 +552,6 @@ back_item = /obj/item/storage/backpack/marine new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/almayer/mcom(new_human), WEAR_L_EAR) - new_human.equip_to_slot_or_del(new /obj/item/tool/pen/fountain(new_human), WEAR_R_EAR) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/officer/bridge(new_human), WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/dress(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/m4a3/mod88(new_human), WEAR_WAIST) @@ -597,7 +591,6 @@ new_human.equip_to_slot_or_del(new back_item(new_human), WEAR_BACK) new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/almayer/mcom/cdrcom(new_human), WEAR_L_EAR) - new_human.equip_to_slot_or_del(new /obj/item/tool/pen/fountain(new_human), WEAR_R_EAR) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/officer/bridge(new_human), WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/m44/custom(new_human), WEAR_WAIST) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index d29b88ac8893..b0a1c1d15565 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -86,7 +86,6 @@ body.alter_ghost(src) apply_transform(matrix()) - own_orbit_size = body.get_orbit_size() desc = initial(desc) @@ -95,6 +94,7 @@ invisibility = INVISIBILITY_OBSERVER plane = GHOST_PLANE layer = ABOVE_FLY_LAYER + mouse_opacity = MOUSE_OPACITY_ICON // In case we were weed_food sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS|SEE_SELF see_invisible = INVISIBILITY_OBSERVER diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 72f113e04785..3896cd1f9ded 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -41,7 +41,9 @@ if(stat == DEAD) species?.handle_dead_death(src, gibbed) return + GLOB.alive_human_list -= src + if(!gibbed) if(HAS_TRAIT(src, TRAIT_HARDCORE) || MODE_HAS_TOGGLEABLE_FLAG(MODE_HARDCORE_PERMA)) if(!(species.flags & IS_SYNTHETIC)) // Synths wont perma @@ -54,8 +56,10 @@ disable_lights() disable_special_items() disable_headsets() //Disable radios for dead people to reduce load + if(pulledby && isxeno(pulledby)) // Xenos lose grab on dead humans pulledby.stop_pulling() + //Handle species-specific deaths. if(species) species.handle_death(src, gibbed) @@ -71,16 +75,14 @@ // Finding the last guy for anti-delay. if(SSticker.mode && SSticker.mode.is_in_endgame && SSticker.current_state != GAME_STATE_FINISHED && is_mainship_level(z)) var/mob/last_living_human - for(var/mob/living/carbon/human/H as anything in GLOB.alive_human_list) - if(!is_mainship_level(H.z)) + for(var/mob/living/carbon/human/cur_human as anything in GLOB.alive_human_list) + if(!is_mainship_level(cur_human.z)) continue if(last_living_human) last_living_human = null break - last_living_human = H - if(last_living_human) - if((last_qm_callout + 2 MINUTES) > world.time) - return + last_living_human = cur_human + if(last_living_human && (last_qm_callout + 2 MINUTES) < world.time) last_qm_callout = world.time // Tell the xenos where the human is. xeno_announcement("I sense the last tallhost hiding in [get_area(last_living_human)].", XENO_HIVE_NORMAL, SPAN_ANNOUNCEMENT_HEADER_BLUE("[QUEEN_MOTHER_ANNOUNCE]")) @@ -108,4 +110,13 @@ if(HAS_TRAIT(src, TRAIT_HARDCORE)) death_message = "valiantly falls to the ground, dead, unable to continue." - return ..(cause, gibbed, death_message) + . = ..(cause, gibbed, death_message) + + // stat is now set + var/datum/cause_data/death_data = cause + if(!gibbed && death_data?.cause_name != "gibbing") + // Hilariously the gibbing proc causes death via droplimb which means gibbed is false... + AddComponent(/datum/component/weed_food) + else if(death_data?.cause_name == "existing") + // Corpses spawn as gibbed true to avoid sfx, even though they aren't actually gibbed... + AddComponent(/datum/component/weed_food) diff --git a/code/modules/mob/living/carbon/human/species/emote-synthetic.dm b/code/modules/mob/living/carbon/human/species/emote-synthetic.dm deleted file mode 100644 index fd763b038153..000000000000 --- a/code/modules/mob/living/carbon/human/species/emote-synthetic.dm +++ /dev/null @@ -1,354 +0,0 @@ -/datum/emote/living/carbon/human/synthetic/working_joe - species_type_allowed_typecache = list(/datum/species/synthetic/colonial/working_joe) - keybind_category = CATEGORY_SYNTH_EMOTE - volume = 75 - -/datum/emote/living/carbon/human/synthetic/working_joe/alwaysknow - key = "alwaysknow" - key_third_person = "workingjoe" - sound = 'sound/voice/joe/alwaysknow.ogg' - say_message = "You always know a Working Joe." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/hysterical - key = "hysterical" - sound = 'sound/voice/joe/hysterical.ogg' - say_message = "You are becoming hysterical." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/safety - key = "safety" - sound = 'sound/voice/joe/safety.ogg' - say_message = "You and I are going to have a talk about safety." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/awful_mess - key = "awful" - key_third_person = "mess" - sound = 'sound/voice/joe/awful.ogg' - say_message = "Tut, tut. What an awful mess." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/damage - key = "damage" - sound = 'sound/voice/joe/damage.ogg' - say_message = "Do not damage Seegson property." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/firearm - key = "firearm" - sound = 'sound/voice/joe/firearm.ogg' - say_message = "Firearms can cause serious injury. Let me assist you." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/report - key = "report" - sound = 'sound/voice/joe/report.ogg' - say_message = "Logging report to APOLLO." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/breach - key = "breach" - sound = 'sound/voice/joe/breach.ogg' - say_message = "Hazard Containment breach logged." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/species - key = "species" - sound = 'sound/voice/joe/species.ogg' - say_message = "Unidentified species." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/alwaysknow_damaged - key = "alwaysknowdamaged" - sound = 'sound/voice/joe/alwaysknow_damaged.ogg' - say_message = "You always know a Working Joe." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/apollo_behalf - key = "apollobehalf" - sound = 'sound/voice/joe/apollo_behalf.ogg' - say_message = "I will inform APOLLO on your behalf." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/back_to_work - key = "backtowork" - sound = 'sound/voice/joe/back_to_work.ogg' - say_message = "Back to work." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/beyond_repair - key = "beyondrepair" - sound = 'sound/voice/joe/beyond_repair.ogg' - say_message = "Hmm, far beyond repair." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/come_out_vent - key = "comeoutvent" - sound = 'sound/voice/joe/come_out_vent.ogg' - say_message = "Come out of the vent system, please." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/could_require_attention - key = "couldrequireattention" - sound = 'sound/voice/joe/could_require_attention.ogg' - say_message = "This could require my attention." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/dangerous_items - key = "dangerousitems" - sound = 'sound/voice/joe/dangerous_items.ogg' - say_message = "You are carrying some very dangerous items." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/day_never_done - key = "dayneverdone" - sound = 'sound/voice/joe/day_never_done.ogg' - say_message = "A synthetic's day is never done." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/detailed_report - key = "detailedreport" - sound = 'sound/voice/joe/detailed_report.ogg' - say_message = "APOLLO will require a detailed report." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/fire - key = "fire" - sound = 'sound/voice/joe/fire.ogg' - say_message = "Only wild animals fear fire." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/fire_drill - key = "firedrill" - sound = 'sound/voice/joe/fire_drill.ogg' - say_message = "Please congregate at your nearest fire assembly point. This is not a drill; do not panic." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/unprotected_flames - key = "unprotectedflames" - sound = 'sound/voice/joe/unprotected_flames.ogg' - say_message = "Unprotected flames are extremely dangerous and entirely unadvisable." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/follow_me - key = "followme" - sound = 'sound/voice/joe/follow_me.ogg' - say_message = "Follow me." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/further_assistance - key = "furtherassistance" - sound = 'sound/voice/joe/further_assistance.ogg' - say_message = "Please call if you need further assistance." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/good_day - key = "goodday" - sound = 'sound/voice/joe/good_day.ogg' - say_message = "Good day." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/health_risks - key = "healthrisks" - sound = 'sound/voice/joe/health_risks.ogg' - say_message = "These items carry notable health risks." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/hello - key = "hello" - sound = 'sound/voice/joe/hello.ogg' - say_message = "Hello." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/how_can_i_help - key = "howcanihelp" - sound = 'sound/voice/joe/how_can_i_help.ogg' - say_message = "How can I help you?" - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/irresponsible - key = "irresponsible" - sound = 'sound/voice/joe/irresponsible.ogg' - say_message = "That was irresponsible." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/join_us - key = "joinus" - sound = 'sound/voice/joe/join_us.ogg' - say_message = "We hope you'll join us for the journey." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/little_details - key = "littledetails" - sound = 'sound/voice/joe/little_details.ogg' - say_message = "We don't forget the little details when seeing the big picture." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/lost - key = "lost" - sound = 'sound/voice/joe/lost.ogg' - say_message = "Are you lost?" - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/misbehaving - key = "misbehaving" - sound = 'sound/voice/joe/misbehaving.ogg' - say_message = "Have you been misbehaving?" - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/not_allowed_there - key = "notallowedthere" - sound = 'sound/voice/joe/not_allowed_there.ogg' - say_message = "You're not allowed in there." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/not_liking - key = "notliking" - sound = 'sound/voice/joe/not_liking.ogg' - say_message = "If you find this facility in a state that isn't to your liking, please let me know." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/not_what_i_think - key = "notwhatithink" - sound = 'sound/voice/joe/not_what_i_think.ogg' - say_message = "I hope that's not what I think it is." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/other_concerns - key = "otherconcerns" - sound = 'sound/voice/joe/other_concerns.ogg' - say_message = "I have other concerns." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/more_pressing_matters - key = "morepressingmatters" - sound = 'sound/voice/joe/more_pressing_matters.ogg' - say_message = "There are more pressing matters." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/patience - key = "patience" - sound = 'sound/voice/joe/patience.ogg' - say_message = "You are starting to test my patience." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/presence_logged - key = "presencelogged" - sound = 'sound/voice/joe/presence_logged.ogg' - say_message = "Your presence has been logged." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/required_by_apollo - key = "requiredbyapollo" - sound = 'sound/voice/joe/required_by_apollo.ogg' - say_message = "I am required by APOLLO." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/returning_to_tasks - key = "returningtotasks" - sound = 'sound/voice/joe/returning_to_tasks.ogg' - say_message = "Returning to assigned tasks." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/running_accidents - key = "runningaccidents" - sound = 'sound/voice/joe/running_accidents.ogg' - say_message = "Running causes accidents." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/safety_breach - key = "safetybreach" - sound = 'sound/voice/joe/safety_breach.ogg' - say_message = "This is a breach of multiple safety directives." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/seegson_quality - key = "seegsonquality" - sound = 'sound/voice/joe/seegson_quality.ogg' - say_message = "Seegson - Relentless in the pursuit of affordable quality." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/seegson_standards - key = "seegsonstandards" - sound = 'sound/voice/joe/seegson_standards.ogg' - say_message = "If my services do not meet Seegson standards, please log a complaint." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/shouldnt_be_here - key = "shouldntbehere" - sound = 'sound/voice/joe/shouldnt_be_here.ogg' - say_message = "You shouldn't be here." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/seegson_behind - key = "seegsonbehind" - sound = 'sound/voice/joe/seegson_behind.ogg' - say_message = "With Seegson, there is someone behind you, helping you every step of the way." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/take_a_seat - key = "takeaseat" - sound = 'sound/voice/joe/take_a_seat.ogg' - say_message = "Please take a seat, someone will be with you shortly." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/talk_to_seegson - key = "talktoseegson" - sound = 'sound/voice/joe/talk_to_seegson.ogg' - say_message = "Interested in our Working Joe android range? Talk to Seegson." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/temperatures - key = "temperatures" - sound = 'sound/voice/joe/temperatures.ogg' - say_message = "I am built to whitstand temperatures of up to 1210 degrees." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/that_stings - key = "thatstings" - sound = 'sound/voice/joe/that_stings.ogg' - say_message = "That stings." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/this_is_futile - key = "thisisfutile" - sound = 'sound/voice/joe/this_is_futile.ogg' - say_message = "This is futile." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/trespassing - key = "trespassing" - sound = 'sound/voice/joe/trespassing.ogg' - say_message = "You are trespassing." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/weapon_permit - key = "weaponpermit" - sound = 'sound/voice/joe/weapon_permit.ogg' - say_message = "I assume you have a permit for that weapon." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/what_happened_to_you - key = "whathappenedtoyou" - sound = 'sound/voice/joe/what_happened_to_you.ogg' - say_message = "What happened to you?" - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/what_is_this - key = "whatisthis" - sound = 'sound/voice/joe/what_is_this.ogg' - say_message = "What is this?" - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/with_you_shortly - key = "withyoushortly" - sound = 'sound/voice/joe/with_you_shortly.ogg' - say_message = "I will be with you shortly." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE - -/datum/emote/living/carbon/human/synthetic/working_joe/inexpensive - key = "inexpensive" - sound = 'sound/voice/joe/inexpensive.ogg' - say_message = "I am inexpensive, I am reliable, you know my face - the Working Joe." - emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE diff --git a/code/modules/mob/living/carbon/human/species/synthetic.dm b/code/modules/mob/living/carbon/human/species/synthetic.dm index e518a470993f..6cdbd28d04ec 100644 --- a/code/modules/mob/living/carbon/human/species/synthetic.dm +++ b/code/modules/mob/living/carbon/human/species/synthetic.dm @@ -75,12 +75,12 @@ name = SYNTH_COLONY name_plural = "Colonial Synthetics" uses_ethnicity = TRUE - burn_mod = 0.65 // made for hazardous environments, withstanding temperatures up to 1210 degrees + burn_mod = 0.8 mob_inherent_traits = list(TRAIT_SUPER_STRONG) pain_type = /datum/pain/synthetic/colonial rarity_value = 1.5 - slowdown = 0.45 + slowdown = 0.2 total_health = 200 //But more durable default_lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE @@ -111,8 +111,10 @@ name_plural = "Working Joes" death_message = "violently gargles fluid and seizes up, the glow in their eyes dimming..." uses_ethnicity = FALSE - mob_inherent_traits = list(TRAIT_SUPER_STRONG, TRAIT_INTENT_EYES, TRAIT_EMOTE_CD_EXEMPT) + burn_mod = 0.65 // made for hazardous environments, withstanding temperatures up to 1210 degrees + mob_inherent_traits = list(TRAIT_SUPER_STRONG, TRAIT_INTENT_EYES, TRAIT_EMOTE_CD_EXEMPT, TRAIT_CANNOT_EAT) + slowdown = 0.45 hair_color = "#000000" icobase = 'icons/mob/humans/species/r_synthetic.dmi' deform = 'icons/mob/humans/species/r_synthetic.dmi' diff --git a/code/modules/mob/living/carbon/human/species/working_joe/_emote.dm b/code/modules/mob/living/carbon/human/species/working_joe/_emote.dm new file mode 100644 index 000000000000..63cc79a57dae --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/working_joe/_emote.dm @@ -0,0 +1,8 @@ +/datum/emote/living/carbon/human/synthetic/working_joe + species_type_allowed_typecache = list(/datum/species/synthetic/colonial/working_joe) + keybind_category = CATEGORY_SYNTH_EMOTE + volume = 75 + /// A general category for the emote, for use in the WJ emote panel. See [code/__DEFINES/wj_emotes.dm] for categories. + var/category = "" + /// Override text for the emote to be displayed in the WJ emote panel + var/override_say = "" diff --git a/code/modules/mob/living/carbon/human/species/working_joe/_species.dm b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm new file mode 100644 index 000000000000..815af3474cd4 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm @@ -0,0 +1,130 @@ +/datum/species/synthetic/colonial/working_joe + name = SYNTH_WORKING_JOE + name_plural = "Working Joes" + uses_ethnicity = FALSE + mob_inherent_traits = list(TRAIT_SUPER_STRONG, TRAIT_INTENT_EYES, TRAIT_EMOTE_CD_EXEMPT) + + hair_color = "#000000" + icobase = 'icons/mob/humans/species/r_synthetic.dmi' + deform = 'icons/mob/humans/species/r_synthetic.dmi' + + +/datum/species/synthetic/colonial/working_joe/handle_post_spawn(mob/living/carbon/human/joe) + . = ..() + give_action(joe, /datum/action/joe_emote_panel) + + +/// Open the WJ's emote panel, which allows them to use voicelines +/datum/species/synthetic/colonial/working_joe/proc/open_emote_panel() + var/datum/joe_emote_panel/ui = new(usr) + ui.ui_interact(usr) + + +/datum/action/joe_emote_panel + name = "Open Voice Synthesizer" + action_icon_state = "looc_toggle" + + +/datum/action/joe_emote_panel/can_use_action() + . = ..() + if(!.) + return FALSE + + if(!isworkingjoe(owner)) + return FALSE + + return TRUE + + +/datum/action/joe_emote_panel/action_activate() + if(!can_use_action()) + return + + var/mob/living/carbon/human/human_owner = owner + var/datum/species/synthetic/colonial/working_joe/joe_species = human_owner.species + joe_species.open_emote_panel() + + +/datum/joe_emote_panel + /// Static dict ("category" : (emotes)) of every wj emote typepath + var/static/list/wj_emotes + /// Static list of categories + var/static/list/wj_categories = list() + /// Panel allows you to spam, so a manual CD is added here + COOLDOWN_DECLARE(panel_emote_cooldown) + + +/datum/joe_emote_panel/New() + if(!length(wj_emotes)) + var/list/emotes_to_add = list() + for(var/datum/emote/living/carbon/human/synthetic/working_joe/emote as anything in subtypesof(/datum/emote/living/carbon/human/synthetic/working_joe)) + if(!initial(emote.key) || !initial(emote.say_message)) + continue + + if(!(initial(emote.category) in wj_categories)) + wj_categories += initial(emote.category) + + emotes_to_add += emote + + + wj_emotes = emotes_to_add + + +/datum/joe_emote_panel/proc/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "JoeEmotes") + ui.open() + + +/datum/joe_emote_panel/ui_state(mob/user) + return GLOB.conscious_state + + +/datum/joe_emote_panel/ui_data(mob/user) + var/list/data = list() + + data["on_cooldown"] = !COOLDOWN_FINISHED(src, panel_emote_cooldown) + + return data + + +/datum/joe_emote_panel/ui_static_data(mob/user) + var/list/data = list() + + data["categories"] = wj_categories + data["emotes"] = list() + + for(var/datum/emote/living/carbon/human/synthetic/working_joe/emote as anything in wj_emotes) + data["emotes"] += list(list( + "id" = initial(emote.key), + "text" = (initial(emote.override_say) || initial(emote.say_message)), + "category" = initial(emote.category), + "path" = "[emote]", + )) + + return data + + +/datum/joe_emote_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + switch(action) + if("emote") + var/datum/emote/living/carbon/human/synthetic/working_joe/path + if(!params["emotePath"]) + return + + path = text2path(params["emotePath"]) + + if(!path || !COOLDOWN_FINISHED(src, panel_emote_cooldown)) + return + + if(!(path in subtypesof(/datum/emote/living/carbon/human/synthetic/working_joe))) + return + + COOLDOWN_START(src, panel_emote_cooldown, 2.5 SECONDS) + usr.emote(initial(path.key)) + return TRUE diff --git a/code/modules/mob/living/carbon/human/species/working_joe/farewell.dm b/code/modules/mob/living/carbon/human/species/working_joe/farewell.dm new file mode 100644 index 000000000000..1de68d8d3aec --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/working_joe/farewell.dm @@ -0,0 +1,26 @@ +/datum/emote/living/carbon/human/synthetic/working_joe/farewell + category = JOE_EMOTE_CATEGORY_FAREWELL + +/datum/emote/living/carbon/human/synthetic/working_joe/farewell/back_to_work + key = "backtowork" + sound = 'sound/voice/joe/back_to_work.ogg' + say_message = "Back to work." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/farewell/other_concerns + key = "otherconcerns" + sound = 'sound/voice/joe/other_concerns.ogg' + say_message = "I have other concerns." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/farewell/further_assistance + key = "furtherassistance" + sound = 'sound/voice/joe/further_assistance.ogg' + say_message = "Please call if you need further assistance." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/farewell/more_pressing_matters + key = "morepressingmatters" + sound = 'sound/voice/joe/more_pressing_matters.ogg' + say_message = "There are more pressing matters." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE diff --git a/code/modules/mob/living/carbon/human/species/working_joe/greeting.dm b/code/modules/mob/living/carbon/human/species/working_joe/greeting.dm new file mode 100644 index 000000000000..fb401ea95451 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/working_joe/greeting.dm @@ -0,0 +1,20 @@ +/datum/emote/living/carbon/human/synthetic/working_joe/greeting + category = JOE_EMOTE_CATEGORY_GREETING + +/datum/emote/living/carbon/human/synthetic/working_joe/greeting/good_day + key = "goodday" + sound = 'sound/voice/joe/good_day.ogg' + say_message = "Good day." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/greeting/hello + key = "hello" + sound = 'sound/voice/joe/hello.ogg' + say_message = "Hello." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/greeting/how_can_i_help + key = "howcanihelp" + sound = 'sound/voice/joe/how_can_i_help.ogg' + say_message = "How can I help you?" + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE diff --git a/code/modules/mob/living/carbon/human/species/working_joe/notice.dm b/code/modules/mob/living/carbon/human/species/working_joe/notice.dm new file mode 100644 index 000000000000..ca5efe716db8 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/working_joe/notice.dm @@ -0,0 +1,68 @@ +/datum/emote/living/carbon/human/synthetic/working_joe/notice + category = JOE_EMOTE_CATEGORY_NOTICE + +/datum/emote/living/carbon/human/synthetic/working_joe/notice/detailed_report + key = "detailedreport" + sound = 'sound/voice/joe/detailed_report.ogg' + say_message = "APOLLO will require a detailed report." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/notice/firearm + key = "firearm" + sound = 'sound/voice/joe/firearm.ogg' + say_message = "Firearms can cause serious injury. Let me assist you." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/notice/follow_me + key = "followme" + sound = 'sound/voice/joe/follow_me.ogg' + say_message = "Follow me." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/notice/breach + key = "breach" + sound = 'sound/voice/joe/breach.ogg' + say_message = "Hazard Containment breach logged." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/notice/beyond_repair + key = "beyondrepair" + sound = 'sound/voice/joe/beyond_repair.ogg' + say_message = "Hmm, far beyond repair." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/notice/with_you_shortly + key = "withyoushortly" + sound = 'sound/voice/joe/with_you_shortly.ogg' + say_message = "I will be with you shortly." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/notice/apollo_behalf + key = "apollobehalf" + sound = 'sound/voice/joe/apollo_behalf.ogg' + say_message = "I will inform APOLLO on your behalf." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/notice/report + key = "report" + sound = 'sound/voice/joe/report.ogg' + say_message = "Logging report to APOLLO." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/notice/take_a_seat + key = "takeaseat" + sound = 'sound/voice/joe/take_a_seat.ogg' + say_message = "Please take a seat, someone will be with you shortly." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/notice/could_require_attention + key = "couldrequireattention" + sound = 'sound/voice/joe/could_require_attention.ogg' + say_message = "This could require my attention." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/notice/species + key = "species" + sound = 'sound/voice/joe/species.ogg' + say_message = "Unidentified species." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE diff --git a/code/modules/mob/living/carbon/human/species/working_joe/question.dm b/code/modules/mob/living/carbon/human/species/working_joe/question.dm new file mode 100644 index 000000000000..d4805e36224f --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/working_joe/question.dm @@ -0,0 +1,26 @@ +/datum/emote/living/carbon/human/synthetic/working_joe/question + category = JOE_EMOTE_CATEGORY_QUESTION + +/datum/emote/living/carbon/human/synthetic/working_joe/question/lost + key = "lost" + sound = 'sound/voice/joe/lost.ogg' + say_message = "Are you lost?" + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/question/misbehaving + key = "misbehaving" + sound = 'sound/voice/joe/misbehaving.ogg' + say_message = "Have you been misbehaving?" + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/question/what_happened_to_you + key = "whathappenedtoyou" + sound = 'sound/voice/joe/what_happened_to_you.ogg' + say_message = "What happened to you?" + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/question/what_is_this + key = "whatisthis" + sound = 'sound/voice/joe/what_is_this.ogg' + say_message = "What is this?" + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE diff --git a/code/modules/mob/living/carbon/human/species/working_joe/quip.dm b/code/modules/mob/living/carbon/human/species/working_joe/quip.dm new file mode 100644 index 000000000000..2ec66f9d9d83 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/working_joe/quip.dm @@ -0,0 +1,84 @@ +/datum/emote/living/carbon/human/synthetic/working_joe/quip + category = JOE_EMOTE_CATEGORY_QUIP + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/temperatures + key = "temperatures" + sound = 'sound/voice/joe/temperatures.ogg' + say_message = "I am built to withstand temperatures of up to 1210 degrees." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/inexpensive + key = "inexpensive" + sound = 'sound/voice/joe/inexpensive.ogg' + say_message = "I am inexpensive, I am reliable, you know my face - the Working Joe." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/weapon_permit + key = "weaponpermit" + sound = 'sound/voice/joe/weapon_permit.ogg' + say_message = "I assume you have a permit for that weapon." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/seegson_standards + key = "seegsonstandards" + sound = 'sound/voice/joe/seegson_standards.ogg' + say_message = "If my services do not meet Seegson standards, please log a complaint." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/not_liking + key = "notliking" + sound = 'sound/voice/joe/not_liking.ogg' + say_message = "If you find this facility in a state that isn't to your liking, please let me know." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/talk_to_seegson + key = "talktoseegson" + sound = 'sound/voice/joe/talk_to_seegson.ogg' + say_message = "Interested in our Working Joe android range? Talk to Seegson." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/seegson_quality + key = "seegsonquality" + sound = 'sound/voice/joe/seegson_quality.ogg' + say_message = "Seegson - Relentless in the pursuit of affordable quality." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/awful_mess + key = "awful" + key_third_person = "mess" + sound = 'sound/voice/joe/awful.ogg' + say_message = "Tut, tut. What an awful mess." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/little_details + key = "littledetails" + sound = 'sound/voice/joe/little_details.ogg' + say_message = "We don't forget the little details when seeing the big picture." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/join_us + key = "joinus" + sound = 'sound/voice/joe/join_us.ogg' + say_message = "We hope you'll join us for the journey." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/seegson_behind + key = "seegsonbehind" + sound = 'sound/voice/joe/seegson_behind.ogg' + say_message = "With Seegson, there is someone behind you, helping you every single step of the way." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/alwaysknow + key = "alwaysknow" + key_third_person = "workingjoe" + sound = 'sound/voice/joe/alwaysknow.ogg' + say_message = "You always know a Working Joe." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/quip/alwaysknow_damaged + key = "alwaysknowdamaged" + key_third_person = "workingjoedamaged" + sound = 'sound/voice/joe/alwaysknow_damaged.ogg' + say_message = "You always know a Working Joe." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + override_say = "You always know a Working Joe. (Damaged)" diff --git a/code/modules/mob/living/carbon/human/species/working_joe/restricted_area.dm b/code/modules/mob/living/carbon/human/species/working_joe/restricted_area.dm new file mode 100644 index 000000000000..fd5db0870b25 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/working_joe/restricted_area.dm @@ -0,0 +1,32 @@ +/datum/emote/living/carbon/human/synthetic/working_joe/restricted_area + category = JOE_EMOTE_CATEGORY_RESTRICTED_AREA + +/datum/emote/living/carbon/human/synthetic/working_joe/restricted_area/come_out_vent + key = "comeoutvent" + sound = 'sound/voice/joe/come_out_vent.ogg' + say_message = "Come out of the vent system, please." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/restricted_area/trespassing + key = "trespassing" + sound = 'sound/voice/joe/trespassing.ogg' + say_message = "You are trespassing." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/restricted_area/not_allowed_there + key = "notallowedthere" + sound = 'sound/voice/joe/not_allowed_there.ogg' + say_message = "You're not allowed in there." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/restricted_area/presence_logged + key = "presencelogged" + sound = 'sound/voice/joe/presence_logged.ogg' + say_message = "Your presence has been logged." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/restricted_area/shouldnt_be_here + key = "shouldntbehere" + sound = 'sound/voice/joe/shouldnt_be_here.ogg' + say_message = "You shouldn't be here." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE diff --git a/code/modules/mob/living/carbon/human/species/working_joe/task_update.dm b/code/modules/mob/living/carbon/human/species/working_joe/task_update.dm new file mode 100644 index 000000000000..b08f5d179213 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/working_joe/task_update.dm @@ -0,0 +1,20 @@ +/datum/emote/living/carbon/human/synthetic/working_joe/task_update + category = JOE_EMOTE_CATEGORY_TASK_UPDATE + +/datum/emote/living/carbon/human/synthetic/working_joe/task_update/day_never_done + key = "dayneverdone" + sound = 'sound/voice/joe/day_never_done.ogg' + say_message = "A synthetic's day is never done." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/task_update/required_by_apollo + key = "requiredbyapollo" + sound = 'sound/voice/joe/required_by_apollo.ogg' + say_message = "I am required by APOLLO." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/task_update/returning_to_tasks + key = "returningtotasks" + sound = 'sound/voice/joe/returning_to_tasks.ogg' + say_message = "Returning to assigned tasks." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE diff --git a/code/modules/mob/living/carbon/human/species/working_joe/warning.dm b/code/modules/mob/living/carbon/human/species/working_joe/warning.dm new file mode 100644 index 000000000000..63c7dfadde14 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/working_joe/warning.dm @@ -0,0 +1,92 @@ +/datum/emote/living/carbon/human/synthetic/working_joe/warning + category = JOE_EMOTE_CATEGORY_WARNING + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/damage + key = "damage" + sound = 'sound/voice/joe/damage.ogg' + say_message = "Do not damage Seegson property." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/not_what_i_think + key = "notwhatithink" + sound = 'sound/voice/joe/not_what_i_think.ogg' + say_message = "I hope that's not what I think it is." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/fire + key = "fire" + sound = 'sound/voice/joe/fire.ogg' + say_message = "Only wild animals fear fire." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/fire_drill + key = "firedrill" + sound = 'sound/voice/joe/fire_drill.ogg' + say_message = "Please congregate at your nearest fire assembly point. This is not a drill; do not panic." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/running_accidents + key = "runningaccidents" + sound = 'sound/voice/joe/running_accidents.ogg' + say_message = "Running causes accidents." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/that_stings + key = "thatstings" + sound = 'sound/voice/joe/that_stings.ogg' + say_message = "That stings." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/irresponsible + key = "irresponsible" + sound = 'sound/voice/joe/irresponsible.ogg' + say_message = "That was irresponsible." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/health_risks + key = "healthrisks" + sound = 'sound/voice/joe/health_risks.ogg' + say_message = "These items carry notable health risks." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/safety_breach + key = "safetybreach" + sound = 'sound/voice/joe/safety_breach.ogg' + say_message = "This is a breach of multiple safety directives." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/this_is_futile + key = "thisisfutile" + sound = 'sound/voice/joe/this_is_futile.ogg' + say_message = "This is futile." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/unprotected_flames + key = "unprotectedflames" + sound = 'sound/voice/joe/unprotected_flames.ogg' + say_message = "Unprotected flames are extremely dangerous and entirely unadvisable." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/safety + key = "safety" + sound = 'sound/voice/joe/safety.ogg' + say_message = "You and I are going to have a talk about safety." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/hysterical + key = "hysterical" + sound = 'sound/voice/joe/hysterical.ogg' + say_message = "You are becoming hysterical." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/dangerous_items + key = "dangerousitems" + sound = 'sound/voice/joe/dangerous_items.ogg' + say_message = "You are carrying some very dangerous items." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE + +/datum/emote/living/carbon/human/synthetic/working_joe/warning/patience + key = "patience" + sound = 'sound/voice/joe/patience.ogg' + say_message = "You are starting to test my patience." + emote_type = EMOTE_AUDIBLE|EMOTE_VISIBLE diff --git a/code/modules/mob/living/carbon/human/species/zombie.dm b/code/modules/mob/living/carbon/human/species/zombie.dm index 2c9c423c671e..532d9413102c 100644 --- a/code/modules/mob/living/carbon/human/species/zombie.dm +++ b/code/modules/mob/living/carbon/human/species/zombie.dm @@ -102,6 +102,8 @@ if(zombie.client) zombie.play_screen_text("You are dead...
You lost your head. No reviving for you.", /atom/movable/screen/text/screen_text/command_order, rgb(155, 0, 200)) to_chat(zombie, SPAN_XENOWARNING("You fall... headless, you will no longer rise.")) + zombie.undefibbable = TRUE // really only for weed_food + SEND_SIGNAL(zombie, COMSIG_HUMAN_SET_UNDEFIBBABLE) /datum/species/zombie/handle_dead_death(mob/living/carbon/human/zombie, gibbed) if(gibbed) @@ -144,6 +146,9 @@ return static_tab_items /datum/species/zombie/handle_head_loss(mob/living/carbon/human/zombie) + if(!zombie.undefibbable) + zombie.undefibbable = TRUE // really only for weed_food + SEND_SIGNAL(zombie, COMSIG_HUMAN_SET_UNDEFIBBABLE) if(WEAKREF(zombie) in to_revive) remove_from_revive(zombie) var/client/receiving_client = zombie.client diff --git a/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm b/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm index 8b3b1d54f26d..5ef9626620b2 100644 --- a/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm +++ b/code/modules/mob/living/carbon/xenomorph/Facehuggers.dm @@ -191,9 +191,9 @@ return FALSE /obj/item/clothing/mask/facehugger/launch_towards(datum/launch_metadata/LM) - ..() if(stat == CONSCIOUS) icon_state = "[initial(icon_state)]_thrown" + ..() /obj/item/clothing/mask/facehugger/launch_impact(atom/hit_atom) . = ..() @@ -240,8 +240,8 @@ if(!target) return FALSE - target.visible_message(SPAN_WARNING("\The scuttling [src] leaps at [target]!"), \ - SPAN_WARNING("The scuttling [src] leaps at [target]!")) + target.visible_message(SPAN_WARNING("[src] leaps at [target]!"), \ + SPAN_WARNING("[src] leaps at [target]!")) leaping = TRUE throw_atom(target, 3, SPEED_FAST) return TRUE diff --git a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm index 22cb816f865b..09fdb42ad5c3 100644 --- a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm +++ b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm @@ -712,6 +712,10 @@ to_chat(src, SPAN_XENONOTICE("This is not a host.")) return + if(current_mob.stat == DEAD) + to_chat(src, SPAN_XENONOTICE("This host is dead.")) + return + var/mob/living/carbon/human/host_to_nest = current_mob var/found_grab = FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm index fbf7d993a067..4a57c0729b91 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm @@ -1000,7 +1000,10 @@ if(blunt_stab) stabbing_xeno.visible_message(SPAN_XENOWARNING("\The [stabbing_xeno] swipes its tail into [target]'s [limb ? limb.display_name : "chest"], bashing it!"), SPAN_XENOWARNING("You swipe your tail into [target]'s [limb? limb.display_name : "chest"], bashing it!")) - playsound(target, "punch", 50, TRUE) + if(prob(1)) + playsound(target, 'sound/effects/comical_bonk.ogg', 50, TRUE) + else + playsound(target, "punch", 50, TRUE) // The xeno smashes the target with their tail, moving it to the side and thus their direction as well. stab_direction = turn(stabbing_xeno.dir, pick(90, -90)) stab_overlay = "slam" diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm b/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm index 3f65be228443..82d80752ec54 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Larva.dm @@ -138,6 +138,9 @@ else icon_state = "[state_override || state]Larva" +/mob/living/carbon/xenomorph/larva/alter_ghost(mob/dead/observer/ghost) + ghost.icon_state = "[caste.caste_type]" + /mob/living/carbon/xenomorph/larva/handle_name() return diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm index 93b6d230b198..ac975835b21f 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm @@ -940,3 +940,7 @@ // Switch icon back and then let normal icon behavior happen Queen.icon = Queen.queen_standing_icon + +/mob/living/carbon/xenomorph/queen/alter_ghost(mob/dead/observer/ghost) + ghost.icon = queen_standing_icon + return ..() diff --git a/code/modules/mob/living/carbon/xenomorph/death.dm b/code/modules/mob/living/carbon/xenomorph/death.dm index fe4b4cca2fb1..e3a69da23262 100644 --- a/code/modules/mob/living/carbon/xenomorph/death.dm +++ b/code/modules/mob/living/carbon/xenomorph/death.dm @@ -50,7 +50,7 @@ new_xeno.generate_name() if(!SSticker.mode.transfer_xeno(xeno_candidate, new_xeno)) qdel(new_xeno) - return + break new_xeno.visible_message(SPAN_XENODANGER("A larva suddenly burrows out of the ground!"), SPAN_XENODANGER("You burrow out of the ground after feeling an immense tremor through the hive, which quickly fades into complete silence...")) @@ -105,6 +105,11 @@ GLOB.hive_datum[hivenumber].stored_larva++ GLOB.hive_datum[hivenumber].hive_ui.update_burrowed_larva() + if(hardcore) + QDEL_IN(src, 3 SECONDS) + //else if(!gibbed) // At the moment we only support humans + //AddComponent(/datum/component/weed_food) + if(hive) hive.remove_xeno(src) // Finding the last xeno for anti-delay. @@ -125,9 +130,6 @@ to_chat(X, SPAN_XENOANNOUNCE("Your carapace rattles with dread. You are all that remains of the hive!")) announce_dchat("There is only one Xenomorph left: [X.name].", X) - if(hardcore) - QDEL_IN(src, 3 SECONDS) - SEND_GLOBAL_SIGNAL(COMSIG_GLOB_XENO_DEATH, src, gibbed) /mob/living/carbon/xenomorph/gib(datum/cause_data/cause = create_cause_data("gibbing", src)) diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 5a335002d71d..6a20e9cfe78e 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -264,7 +264,7 @@ display round(lastgen) and phorontank amount to_chat(user, SPAN_NOTICE(" You open the access panel.")) else to_chat(user, SPAN_NOTICE(" You close the access panel.")) - else if(istype(O, /obj/item/tool/crowbar) && open) + else if(HAS_TRAIT(O, TRAIT_TOOL_CROWBAR) && open) var/obj/structure/machinery/constructable_frame/new_frame = new /obj/structure/machinery/constructable_frame(src.loc) for(var/obj/item/I in component_parts) if(I.reliability < 100) diff --git a/code/modules/projectiles/magazines/pistols.dm b/code/modules/projectiles/magazines/pistols.dm index 16090d9f2b81..317124955cbc 100644 --- a/code/modules/projectiles/magazines/pistols.dm +++ b/code/modules/projectiles/magazines/pistols.dm @@ -8,7 +8,7 @@ caliber = "9mm" icon = 'icons/obj/items/weapons/guns/ammo_by_faction/uscm.dmi' icon_state = "m4a3" - max_rounds = 9 + max_rounds = 12 w_class = SIZE_SMALL default_ammo = /datum/ammo/bullet/pistol gun_type = /obj/item/weapon/gun/pistol/m4a3 diff --git a/code/modules/reagents/chemistry_machinery/chem_dispenser.dm b/code/modules/reagents/chemistry_machinery/chem_dispenser.dm index 8de20ca2b79a..09d46aa8c053 100644 --- a/code/modules/reagents/chemistry_machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry_machinery/chem_dispenser.dm @@ -1,5 +1,6 @@ /obj/structure/machinery/chem_dispenser - name = "chem dispenser" + name = "chemical dispenser" + desc = "A complex machine for mixing elements into chemicals. A Wey-Yu product." density = TRUE anchored = TRUE icon = 'icons/obj/structures/machinery/science_machines.dmi' diff --git a/code/modules/shuttle/computers/dropship_computer.dm b/code/modules/shuttle/computers/dropship_computer.dm index ea4a7fdbc79d..50449b32fcb9 100644 --- a/code/modules/shuttle/computers/dropship_computer.dm +++ b/code/modules/shuttle/computers/dropship_computer.dm @@ -1,6 +1,6 @@ /obj/structure/machinery/computer/shuttle/dropship/flight name = "dropship navigation computer" - desc = "flight computer for dropship" + desc = "A flight computer that can be used for autopilot or long-range flights." icon = 'icons/obj/structures/machinery/shuttle-parts.dmi' icon_state = "console" req_one_access = list(ACCESS_MARINE_LEADER, ACCESS_MARINE_DROPSHIP) diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index be92afffb898..010cba770ce2 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -85,6 +85,7 @@ #include "unit_test.dm" #include "spawn_humans.dm" #include "check_runtimes.dm" +#include "wj_emotes.dm" #undef TEST_ASSERT #undef TEST_ASSERT_EQUAL diff --git a/code/modules/unit_tests/wj_emotes.dm b/code/modules/unit_tests/wj_emotes.dm new file mode 100644 index 000000000000..f89757665011 --- /dev/null +++ b/code/modules/unit_tests/wj_emotes.dm @@ -0,0 +1,7 @@ +/// Test that all working joe emotes have a category +/datum/unit_test/wj_emotes + +/datum/unit_test/wj_emotes/Run() + for(var/datum/emote/living/carbon/human/synthetic/working_joe/emote as anything in subtypesof(/datum/emote/living/carbon/human/synthetic/working_joe)) + if(!initial(emote.category)) + TEST_FAIL("Emote [emote] did not have a category!") diff --git a/colonialmarines.dme b/colonialmarines.dme index 204c144c8916..304d5221ddd3 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -111,6 +111,7 @@ #include "code\__DEFINES\vv.dm" #include "code\__DEFINES\weapon_stats.dm" #include "code\__DEFINES\weather.dm" +#include "code\__DEFINES\wj_emotes.dm" #include "code\__DEFINES\xeno.dm" #include "code\__DEFINES\dcs\flags.dm" #include "code\__DEFINES\dcs\helpers.dm" @@ -370,6 +371,7 @@ #include "code\datums\components\speed_modifier.dm" #include "code\datums\components\toxin_buildup.dm" #include "code\datums\components\weed_damage_reduction.dm" +#include "code\datums\components\weed_food.dm" #include "code\datums\components\xeno\shield_slash.dm" #include "code\datums\construction\construction_template.dm" #include "code\datums\construction\xenomorph\construction_template_xenomorph.dm" @@ -1780,7 +1782,6 @@ #include "code\modules\mob\living\carbon\human\powers\human_powers.dm" #include "code\modules\mob\living\carbon\human\powers\issue_order.dm" #include "code\modules\mob\living\carbon\human\species\emote-monkey.dm" -#include "code\modules\mob\living\carbon\human\species\emote-synthetic.dm" #include "code\modules\mob\living\carbon\human\species\emote-yautja.dm" #include "code\modules\mob\living\carbon\human\species\human.dm" #include "code\modules\mob\living\carbon\human\species\monkey.dm" @@ -1788,6 +1789,16 @@ #include "code\modules\mob\living\carbon\human\species\synthetic.dm" #include "code\modules\mob\living\carbon\human\species\yautja.dm" #include "code\modules\mob\living\carbon\human\species\zombie.dm" +#include "code\modules\mob\living\carbon\human\species\working_joe\_emote.dm" +#include "code\modules\mob\living\carbon\human\species\working_joe\_species.dm" +#include "code\modules\mob\living\carbon\human\species\working_joe\farewell.dm" +#include "code\modules\mob\living\carbon\human\species\working_joe\greeting.dm" +#include "code\modules\mob\living\carbon\human\species\working_joe\notice.dm" +#include "code\modules\mob\living\carbon\human\species\working_joe\question.dm" +#include "code\modules\mob\living\carbon\human\species\working_joe\quip.dm" +#include "code\modules\mob\living\carbon\human\species\working_joe\restricted_area.dm" +#include "code\modules\mob\living\carbon\human\species\working_joe\task_update.dm" +#include "code\modules\mob\living\carbon\human\species\working_joe\warning.dm" #include "code\modules\mob\living\carbon\xenomorph\Abilities.dm" #include "code\modules\mob\living\carbon\xenomorph\attack_alien.dm" #include "code\modules\mob\living\carbon\xenomorph\damage_procs.dm" diff --git a/html/changelogs/AutoChangeLog-pr-3645.yml b/html/changelogs/AutoChangeLog-pr-3645.yml new file mode 100644 index 000000000000..f959710b689e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3645.yml @@ -0,0 +1,5 @@ +author: "Khadd" +delete-after: True +changes: + - rscadd: "added a iv tube between the user and the bloodpack / iv drip" + - imageadd: "sprites for the iv tube" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3685.yml b/html/changelogs/AutoChangeLog-pr-3685.yml deleted file mode 100644 index efffe192d42e..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3685.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Newyearnewme, Morrow" -delete-after: True -changes: - - rscadd: "Xeno structures/weeds now become forsaken after hijack" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3709.yml b/html/changelogs/AutoChangeLog-pr-3709.yml deleted file mode 100644 index 8e7d2c05c803..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3709.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - balance: "Gardener's hardy weeds now upgrade normal weeds (just like hive weeds upgrade weeds)." - - balance: "Gardener's hardy weeds now don't prevent special structures (core and pylons) but they are still only allowed if the turf allows them." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3728.yml b/html/changelogs/AutoChangeLog-pr-3728.yml deleted file mode 100644 index ed15d5da7b63..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3728.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Steelpoint" -delete-after: True -changes: - - imageadd: "Synth utility vest is now slimmer in appearance" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3741.yml b/html/changelogs/AutoChangeLog-pr-3741.yml deleted file mode 100644 index 40678f6790a2..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3741.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "thatoneyeeter" -delete-after: True -changes: - - balance: "metal foam now becomes solid faster" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3755.yml b/html/changelogs/AutoChangeLog-pr-3755.yml deleted file mode 100644 index c2a183d77700..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3755.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "realforest2001" -delete-after: True -changes: - - admin: "Adds logs for bioscans successfully completing." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3765.yml b/html/changelogs/AutoChangeLog-pr-3765.yml deleted file mode 100644 index a52472ec8b42..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3765.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - balance: "Weed nodes can no longer be placed in walls or window frames (or any turf or structure with density)" - - refactor: "Refactored the plant weeds ability code" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3790.yml b/html/changelogs/AutoChangeLog-pr-3790.yml deleted file mode 100644 index 369a2ae3bf62..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3790.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "BeagleGaming1" -delete-after: True -changes: - - code_imp: "evacuation pod crash chance changed to a var" - - code_imp: "proc added to force evacuation pods to crash" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3792.yml b/html/changelogs/AutoChangeLog-pr-3792.yml new file mode 100644 index 000000000000..1a49d8916a87 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-3792.yml @@ -0,0 +1,4 @@ +author: "Zonespace27" +delete-after: True +changes: + - rscadd: "Working Joes now have an emote panel to use voice lines, accessible as an action button." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-3793.yml b/html/changelogs/AutoChangeLog-pr-3793.yml deleted file mode 100644 index 6702f7cab39b..000000000000 --- a/html/changelogs/AutoChangeLog-pr-3793.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - bugfix: "Fixed more broken logos (primarily WY research papers)" \ No newline at end of file diff --git a/html/changelogs/archive/2023-07.yml b/html/changelogs/archive/2023-07.yml index bba1c604b538..f4cfd2ce189e 100644 --- a/html/changelogs/archive/2023-07.yml +++ b/html/changelogs/archive/2023-07.yml @@ -53,3 +53,66 @@ - rscadd: CMB/Anchorpoint Marines get bandages to stop bleeding. harryob: - rscadd: all xenos can now access the tacmap, while the queen is on ovi +2023-07-06: + BeagleGaming1: + - code_imp: evacuation pod crash chance changed to a var + - code_imp: proc added to force evacuation pods to crash + Drathek: + - bugfix: Fixed more broken logos (primarily WY research papers) + - balance: Weed nodes can no longer be placed in walls or window frames (or any + turf or structure with density) + - refactor: Refactored the plant weeds ability code + - balance: Gardener's hardy weeds now upgrade normal weeds (just like hive weeds + upgrade weeds). + - balance: Gardener's hardy weeds now don't prevent special structures (core and + pylons) but they are still only allowed if the turf allows them. + Newyearnewme, Morrow: + - rscadd: Xeno structures/weeds now become forsaken after hijack + Steelpoint: + - imageadd: Synth utility vest is now slimmer in appearance + realforest2001: + - admin: Adds logs for bioscans successfully completing. + thatoneyeeter: + - balance: metal foam now becomes solid faster +2023-07-07: + Diegoflores31: + - rscadd: Defender Tail Slam has a 1% chance to do a BONK sound instead. + Drathek: + - bugfix: Fixed ghost icons for larva and ovi queen + Morrow: + - rscdel: Removes fountain pens from gear sets + - rscdel: Removed nesting the dead + - rscadd: Added a visiting USASF Commander (CO survivor) to New Varadero + - bugfix: Burnt matches no longer permanently give you a light source if they naturally + burn out + QuickLoad: + - balance: Colony Synthetics are faster but are less resistant. This allows for + the option of avoiding engagements. + - balance: Colony Synthetics have slightly better CQC and can carry people better. + realforest2001: + - bugfix: Fixes Queen making footstep sounds while dead and being dragged. +2023-07-08: + Ben10083: + - bugfix: Working Joes can no longer have a gradient on their rare hair spawn. + - rscdel: Working Joes can no longer be fed. + - code_imp: 'New trait: Cannot eat. Self-explanatory.' + Cursor: + - spellcheck: Changed Chem Dispenser to Chemical Dispenser, added descriptions to + the cryo cell, rail computer and chemical dispenser. Updated the descriptions + for the Blood Dispenser and Dropship computer. + Drathek: + - bugfix: Fixed facehuggers incorrectly displaying thrown state when it has landed + Drathek Kugamo: + - rscadd: Added the ability for weeds to merge with unrevivable corpses + - imageadd: Added human shaped weeds by Kugamo + - code_imp: Added a signal for weeds sent to the turf to indicate it is now weeded, + and added a signal for afterbuckle. + - bugfix: Closets (including coffins) can no longer move anchored mobs. + Morrow: + - qol: Create humans tab length increase + - qol: Create humans tab now defaults to 0 range to spawn + - bugfix: Fixed extraneous messages in regards to wall nests + SpartanBobby: + - balance: changes M4A3 magazine size from 9 to 12 + Zonespace27: + - bugfix: The maintenance jack should work a little better at crowbarring things. diff --git a/html/create_humans.html b/html/create_humans.html index ed9361fc6f25..06b92cba0c71 100644 --- a/html/create_humans.html +++ b/html/create_humans.html @@ -11,7 +11,7 @@ Amount of humans:
- Range to spawn in: + Range to spawn in:

Spawn mobs as:
Regular
diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 704c0ad1c02c..d6ee40cf7fe8 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/mob/hud/actions.dmi b/icons/mob/hud/actions.dmi index 1692879116dc..4d0697733207 100644 Binary files a/icons/mob/hud/actions.dmi and b/icons/mob/hud/actions.dmi differ diff --git a/icons/mob/xenos/weeds.dmi b/icons/mob/xenos/weeds.dmi index 8eb4b2203cf6..0b9403058109 100644 Binary files a/icons/mob/xenos/weeds.dmi and b/icons/mob/xenos/weeds.dmi differ diff --git a/maps/new_varadero.json b/maps/new_varadero.json index d9d6a0d231cc..9a0bf5d56be1 100644 --- a/maps/new_varadero.json +++ b/maps/new_varadero.json @@ -13,6 +13,9 @@ "/datum/equipment_preset/survivor/security/lv", "/datum/equipment_preset/survivor/colonial_marshal/lv" ], + "CO_survivor_types": [ + "/datum/equipment_preset/survivor/new_varadero/commander" + ], "defcon_triggers": [ 3300, diff --git a/sound/effects/comical_bonk.ogg b/sound/effects/comical_bonk.ogg new file mode 100644 index 000000000000..e0a2751d52c2 Binary files /dev/null and b/sound/effects/comical_bonk.ogg differ diff --git a/tgui/packages/tgui/interfaces/JoeEmotes.tsx b/tgui/packages/tgui/interfaces/JoeEmotes.tsx new file mode 100644 index 000000000000..acd37de34978 --- /dev/null +++ b/tgui/packages/tgui/interfaces/JoeEmotes.tsx @@ -0,0 +1,110 @@ +import { useBackend, useLocalState } from '../backend'; +import { Box, Button, Divider, Section, Stack, Tabs } from '../components'; +import { Window } from '../layouts'; +import { BooleanLike } from '../../common/react'; + +type Emote = { + id: string; + text: string; + category: string; + path: string; +}; + +type BackendContext = { + categories: string[]; + emotes: Emote[]; + on_cooldown: BooleanLike; +}; + +const EmoteTab = (props, context) => { + const { data, act } = useBackend(context); + const { categories, emotes, on_cooldown } = data; + const [categoryIndex, setCategoryIndex] = useLocalState( + context, + 'category_index', + 'Farewell' + ); + const mapped_emote = emotes.filter( + (emote) => emote && emote.category === categoryIndex + ); + return ( + + + + + {categories.map((item, key) => ( + { + setCategoryIndex(item); + }}> + {item} + + ))} + + + + +
+ + + {mapped_emote.map((item) => ( + + + {' '} + + + + +
+
+
+ ); +}; + +export const JoeEmotes = (props, context) => { + return ( + + + + + + ); +};