diff --git a/code/__DEFINES/cleaning.dm b/code/__DEFINES/cleaning.dm index 7c954602215e3..79708cd152b62 100644 --- a/code/__DEFINES/cleaning.dm +++ b/code/__DEFINES/cleaning.dm @@ -29,3 +29,8 @@ #define CLEAN_SCRUB (CLEAN_WASH | CLEAN_TYPE_FINGERPRINTS | CLEAN_TYPE_FIBERS | CLEAN_TYPE_HARD_DECAL) #define CLEAN_RAD CLEAN_TYPE_RADIATION #define CLEAN_ALL ALL + +// Footprint sprites to use when making footprints in blood, oil, etc. +#define FOOTPRINT_SPRITE_SHOES "shoes" +#define FOOTPRINT_SPRITE_PAWS "paws" +#define FOOTPRINT_SPRITE_CLAWS "claws" diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index 467b405f715e8..1d69d48e9d59f 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -84,6 +84,7 @@ #define JOB_BARTENDER "Bartender" #define JOB_BOTANIST "Botanist" #define JOB_COOK "Cook" +#define JOB_CHEF "Chef" // Alternate cook title. #define JOB_JANITOR "Janitor" #define JOB_CLOWN "Clown" #define JOB_MIME "Mime" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 2e1eac6672d2a..d9514d735d0f1 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -120,7 +120,6 @@ #define SPECIES_NIGHTMARE "nightmare" #define SPECIES_MONKEY "monkey" #define SPECIES_MONKEY_FREAK "monkey_freak" -#define SPECIES_MONKEY_HOLODECK "monkey_holodeck" #define SPECIES_MONKEY_HUMAN_LEGGED "monkey_human_legged" #define SPECIES_MOTH "moth" #define SPECIES_MUSHROOM "mush" diff --git a/code/datums/components/bloodysoles.dm b/code/datums/components/bloodysoles.dm index a79d4b385c20b..e1a60112c901f 100644 --- a/code/datums/components/bloodysoles.dm +++ b/code/datums/components/bloodysoles.dm @@ -21,6 +21,8 @@ /// The world.time when we last picked up blood var/last_pickup + var/footprint_sprite = FOOTPRINT_SPRITE_SHOES + /datum/component/bloodysoles/Initialize() if(!isclothing(parent)) return COMPONENT_INCOMPATIBLE @@ -113,9 +115,9 @@ /** * Find a blood decal on a turf that matches our last_blood_state */ -/datum/component/bloodysoles/proc/find_pool_by_blood_state(turf/turfLoc, typeFilter = null) +/datum/component/bloodysoles/proc/find_pool_by_blood_state(turf/turfLoc, typeFilter = null, footprint_sprite) for(var/obj/effect/decal/cleanable/blood/pool in turfLoc) - if(pool.blood_state == last_blood_state && (!typeFilter || istype(pool, typeFilter))) + if(pool.blood_state == last_blood_state && pool.footprint_sprite == footprint_sprite && (!typeFilter || istype(pool, typeFilter))) return pool /** @@ -171,23 +173,23 @@ return var/half_our_blood = bloody_shoes[last_blood_state] / 2 - + var/footprint_sprite = wielder.get_footprint_sprite() // Add footprints in old loc if we have enough cream if(half_our_blood >= BLOOD_FOOTPRINTS_MIN) var/turf/oldLocTurf = get_turf(OldLoc) - var/obj/effect/decal/cleanable/blood/footprints/oldLocFP = find_pool_by_blood_state(oldLocTurf, /obj/effect/decal/cleanable/blood/footprints) + var/obj/effect/decal/cleanable/blood/footprints/oldLocFP = find_pool_by_blood_state(oldLocTurf, /obj/effect/decal/cleanable/blood/footprints, footprint_sprite) if(oldLocFP) // Footprints found in the tile we left, add us to it add_parent_to_footprint(oldLocFP) if (!(oldLocFP.exited_dirs & wielder.dir)) oldLocFP.exited_dirs |= wielder.dir oldLocFP.update_appearance() - else if(find_pool_by_blood_state(oldLocTurf)) + else if(find_pool_by_blood_state(oldLocTurf, footprint_sprite = footprint_sprite)) // No footprints in the tile we left, but there was some other blood pool there. Add exit footprints on it adjust_bloody_shoes(last_blood_state, half_our_blood) update_icon() - oldLocFP = new(oldLocTurf) + oldLocFP = new(oldLocTurf, footprint_sprite) if(!QDELETED(oldLocFP)) ///prints merged oldLocFP.blood_state = last_blood_state oldLocFP.exited_dirs |= wielder.dir @@ -207,7 +209,7 @@ adjust_bloody_shoes(last_blood_state, half_our_blood) update_icon() - var/obj/effect/decal/cleanable/blood/footprints/FP = new(get_turf(parent_atom)) + var/obj/effect/decal/cleanable/blood/footprints/FP = new(get_turf(parent_atom), footprint_sprite) if(!QDELETED(FP)) ///prints merged FP.blood_state = last_blood_state FP.entered_dirs |= wielder.dir @@ -266,7 +268,8 @@ return COMPONENT_INCOMPATIBLE parent_atom = parent wielder = parent - + if(footprint_sprite) + src.footprint_sprite = footprint_sprite if(!bloody_feet) bloody_feet = mutable_appearance('icons/effects/blood.dmi', "shoeblood", SHOES_LAYER) diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm index 0cf6631f8074b..1f432efc73455 100644 --- a/code/datums/components/butchering.dm +++ b/code/datums/components/butchering.dm @@ -107,6 +107,12 @@ var/final_effectiveness = effectiveness - target.butcher_difficulty var/bonus_chance = max(0, (final_effectiveness - 100) + bonus_modifier) //so 125 total effectiveness = 25% extra chance + if(target.flags_1 & HOLOGRAM_1) + butcher.visible_message(span_notice("[butcher] tries to butcher [target], but it vanishes."), \ + span_notice("You try to butcher [target], but it vanishes.")) + qdel(target) + return + for(var/result_typepath in target.butcher_results) var/obj/remains = result_typepath var/amount = target.butcher_results[remains] diff --git a/code/datums/elements/decals/blood.dm b/code/datums/elements/decals/blood.dm index 889ebb12904bd..ec09caed73d59 100644 --- a/code/datums/elements/decals/blood.dm +++ b/code/datums/elements/decals/blood.dm @@ -13,29 +13,20 @@ /datum/element/decal/blood/generate_appearance(_icon, _icon_state, _dir, _plane, _layer, _color, _alpha, _smoothing, source) var/obj/item/I = source - if(!_icon) - _icon = 'icons/effects/blood.dmi' - if(!_icon_state) - _icon_state = "itemblood" var/icon = I.icon var/icon_state = I.icon_state if(!icon || !icon_state) // It's something which takes on the look of other items, probably icon = I.icon icon_state = I.icon_state - var/static/list/blood_splatter_appearances = list() - //try to find a pre-processed blood-splatter. otherwise, make a new one - var/index = "[REF(icon)]-[icon_state]" - pic = blood_splatter_appearances[index] - - if(!pic) - var/icon/blood_splatter_icon = icon(I.icon, I.icon_state, , 1) //icon of the item that will become splattered - var/icon/blood_icon = icon(_icon, _icon_state) //icon of the blood that we apply - blood_icon.Scale(blood_splatter_icon.Width(), blood_splatter_icon.Height()) - blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent) - blood_splatter_icon.Blend(blood_icon, ICON_MULTIPLY) //adds blood and the remaining white areas become transparant - pic = mutable_appearance(blood_splatter_icon, I.icon_state) - blood_splatter_appearances[index] = pic + var/icon/icon_for_size = icon(icon, icon_state) + var/scale_factor_x = icon_for_size.Width()/world.icon_size + var/scale_factor_y = icon_for_size.Height()/world.icon_size + var/mutable_appearance/blood_splatter = mutable_appearance('icons/effects/blood.dmi', "itemblood", appearance_flags = RESET_COLOR) //MA of the blood that we apply + blood_splatter.transform = blood_splatter.transform.Scale(scale_factor_x, scale_factor_y) + blood_splatter.blend_mode = BLEND_INSET_OVERLAY + blood_splatter.color = _color + pic = blood_splatter return TRUE /datum/element/decal/blood/proc/get_examine_name(datum/source, mob/user, list/override) diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index d286f8ee6043d..a6e9936b1d9cf 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -129,15 +129,16 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) // 60+: Service JOB_HEAD_OF_PERSONNEL = 60, JOB_BARTENDER = 61, - JOB_COOK = 62, - JOB_BOTANIST = 63, - JOB_CURATOR = 64, - JOB_CHAPLAIN = 65, - JOB_CLOWN = 66, - JOB_MIME = 67, - JOB_JANITOR = 68, - JOB_LAWYER = 69, - JOB_PSYCHOLOGIST = 71, + JOB_CHEF = 62, + JOB_COOK = 63, + JOB_BOTANIST = 64, + JOB_CURATOR = 65, + JOB_CHAPLAIN = 66, + JOB_CLOWN = 67, + JOB_MIME = 68, + JOB_JANITOR = 69, + JOB_LAWYER = 71, + JOB_PSYCHOLOGIST = 72, // 200-229: Centcom JOB_CENTCOM_ADMIRAL = 200, JOB_CENTCOM = 201, diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index f789da69cb52e..4a275199f3f55 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -12,6 +12,7 @@ var/dryname = "dried blood" //when the blood lasts long enough, it becomes dry and gets a new name var/drydesc = "Looks like it's been here a while. Eew." //as above var/drytime = 0 + var/footprint_sprite = null /obj/effect/decal/cleanable/blood/Initialize(mapload) . = ..() @@ -230,7 +231,7 @@ name = "footprints" desc = "WHOSE FOOTPRINTS ARE THESE?" icon = 'icons/effects/footprints.dmi' - icon_state = "blood1" + icon_state = "blood_shoes_enter" random_icon_states = null blood_state = BLOOD_STATE_HUMAN //the icon state to load images from var/entered_dirs = 0 @@ -245,12 +246,13 @@ dryname = "dried footprints" drydesc = "HMM... SOMEONE WAS HERE!" -/obj/effect/decal/cleanable/blood/footprints/Initialize(mapload) +/obj/effect/decal/cleanable/blood/footprints/Initialize(mapload, footprint_sprite) + src.footprint_sprite = footprint_sprite . = ..() icon_state = "" //All of the footprint visuals come from overlays if(mapload) entered_dirs |= dir //Keep the same appearance as in the map editor - update_appearance() + update_appearance(mapload ? (ALL) : (UPDATE_NAME | UPDATE_DESC)) //Rotate all of the footprint directions too /obj/effect/decal/cleanable/blood/footprints/setDir(newdir) @@ -272,6 +274,21 @@ update_appearance() return ..() +/obj/effect/decal/cleanable/blood/footprints/update_name(updates) + switch(footprint_sprite) + if(FOOTPRINT_SPRITE_CLAWS) + name = "clawprints" + if(FOOTPRINT_SPRITE_SHOES) + name = "footprints" + if(FOOTPRINT_SPRITE_PAWS) + name = "pawprints" + dryname = "dried [name]" + return ..() + +/obj/effect/decal/cleanable/blood/footprints/update_desc(updates) + desc = "WHOSE [uppertext(name)] ARE THESE?" + return ..() + /obj/effect/decal/cleanable/blood/footprints/update_icon() . = ..() alpha = min(BLOODY_FOOTPRINT_BASE_ALPHA + (255 - BLOODY_FOOTPRINT_BASE_ALPHA) * bloodiness / (BLOOD_ITEM_MAX / 2), 255) @@ -286,22 +303,22 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache) . = ..() for(var/Ddir in GLOB.cardinals) if(entered_dirs & Ddir) - var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"] + var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[footprint_sprite]-[blood_state]-[Ddir]"] if(!bloodstep_overlay) - GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]1", dir = Ddir) + GLOB.bloody_footprints_cache["entered-[footprint_sprite]-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]_[footprint_sprite]_enter", dir = Ddir) . += bloodstep_overlay if(exited_dirs & Ddir) - var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] + var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["exited-[footprint_sprite]-[blood_state]-[Ddir]"] if(!bloodstep_overlay) - GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]2", dir = Ddir) + GLOB.bloody_footprints_cache["exited-[footprint_sprite]-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]_[footprint_sprite]_exit", dir = Ddir) . += bloodstep_overlay /obj/effect/decal/cleanable/blood/footprints/examine(mob/user) . = ..() if((shoe_types.len + species_types.len) > 0) - . += "You recognise the footprints as belonging to:" + . += "You recognise the [name] as belonging to:" for(var/sole in shoe_types) var/obj/item/clothing/item = sole var/article = initial(item.gender) == PLURAL ? "Some" : "A" @@ -311,14 +328,14 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache) if(species == "unknown") . += "Some feet." else if(species == SPECIES_MONKEY) - . += "[icon2html('icons/mob/human/human.dmi', user, "monkey")] Some monkey feet." + . += "[icon2html('icons/mob/human/human.dmi', user, "monkey")] Some monkey paws." else if(species == SPECIES_HUMAN) . += "[icon2html('icons/mob/human/bodyparts.dmi', user, "default_human_l_leg")] Some human feet." else . += "[icon2html('icons/mob/human/bodyparts.dmi', user, "[species]_l_leg")] Some [species] feet." -/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/C) - if(blood_state != C.blood_state) //We only replace footprints of the same type as us +/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/blood/blood_decal) + if(blood_state != blood_decal.blood_state || footprint_sprite != blood_decal.footprint_sprite) //We only replace footprints of the same type as us return FALSE return ..() diff --git a/code/game/objects/effects/spawners/random/entertainment.dm b/code/game/objects/effects/spawners/random/entertainment.dm index 0a61cd1ab1fbb..3ad477b0294f3 100644 --- a/code/game/objects/effects/spawners/random/entertainment.dm +++ b/code/game/objects/effects/spawners/random/entertainment.dm @@ -51,14 +51,13 @@ loot = list( /obj/item/coin/iron = 5, /obj/item/coin/plastic = 5, - /obj/item/coin/silver = 3, - /obj/item/coin/plasma = 3, + /obj/item/coin/silver = 4, + /obj/item/coin/plasma = 4, /obj/item/coin/uranium = 3, /obj/item/coin/titanium = 3, /obj/item/coin/diamond = 2, /obj/item/coin/bananium = 2, /obj/item/coin/adamantine = 2, - /obj/item/coin/mythril = 2, /obj/item/coin/runite = 2, /obj/item/food/chococoin = 2, /obj/item/coin/twoheaded = 1, diff --git a/code/game/objects/items/devices/scanners/health_analyzer.dm b/code/game/objects/items/devices/scanners/health_analyzer.dm index a27faee2094bc..ef922ed3a7d3c 100644 --- a/code/game/objects/items/devices/scanners/health_analyzer.dm +++ b/code/game/objects/items/devices/scanners/health_analyzer.dm @@ -219,7 +219,7 @@ if(ears.damage) render_list += "Subject has [ears.damage > ears.maxHealth ? "permanent ": "temporary "]hearing damage.\n" if(ears.deaf) - render_list += "Subject is [ears.damage > ears.maxHealth ? "permanently ": "temporarily "] deaf.\n" + render_list += "Subject is [ears.damage > ears.maxHealth ? "permanently": "temporarily"] deaf.\n" // Eye status var/obj/item/organ/internal/eyes/eyes = carbontarget.get_organ_slot(ORGAN_SLOT_EYES) diff --git a/code/game/objects/structures/maintenance.dm b/code/game/objects/structures/maintenance.dm index 78a67198fefdc..f9ed6d93c1e9f 100644 --- a/code/game/objects/structures/maintenance.dm +++ b/code/game/objects/structures/maintenance.dm @@ -24,9 +24,8 @@ at the cost of risking a vicious bite.**/ /obj/item/restraints/handcuffs/cable/green = 1, /obj/item/restraints/handcuffs/cable/pink = 1, /obj/item/restraints/handcuffs/alien = 2, - /obj/item/coin/bananium = 9, + /obj/item/coin/bananium = 10, /obj/item/knife/butcher = 5, - /obj/item/coin/mythril = 1, ) diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index d74bbbe56553b..fcf0de64a5e47 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -22,6 +22,7 @@ var/lace_time = 5 SECONDS ///An active alert var/datum/weakref/our_alert_ref + var/footprint_sprite = FOOTPRINT_SPRITE_SHOES /datum/armor/clothing_shoes bio = 50 diff --git a/code/modules/fishing/sources/source_types.dm b/code/modules/fishing/sources/source_types.dm index 5cdc2d2b8416f..c21579626fe28 100644 --- a/code/modules/fishing/sources/source_types.dm +++ b/code/modules/fishing/sources/source_types.dm @@ -233,12 +233,12 @@ /obj/item/stack/ore/plasma = 3, /mob/living/basic/mining/lobstrosity = 1, /obj/effect/decal/remains/plasma = 1, - /obj/item/stack/sheet/mineral/mythril = 1, + /obj/item/stack/sheet/mineral/runite = 1, /obj/item/stack/sheet/mineral/adamantine = 1, ) fish_counts = list( /obj/item/stack/sheet/mineral/adamantine = 3, - /obj/item/stack/sheet/mineral/mythril = 2, + /obj/item/stack/sheet/mineral/runite = 2, ) /datum/fish_source/moisture_trap diff --git a/code/modules/food_and_drinks/machinery/gibber.dm b/code/modules/food_and_drinks/machinery/gibber.dm index a774d0126a2ea..62157177bdcaf 100644 --- a/code/modules/food_and_drinks/machinery/gibber.dm +++ b/code/modules/food_and_drinks/machinery/gibber.dm @@ -147,6 +147,12 @@ if(!occupant) audible_message(span_hear("You hear a loud metallic grinding sound.")) return + if(occupant.flags_1 & HOLOGRAM_1) + audible_message(span_hear("You hear a very short metallic grinding sound.")) + playsound(loc, 'sound/machines/hiss.ogg', 20, TRUE) + qdel(occupant) + set_occupant(null) + return use_power(active_power_usage) audible_message(span_hear("You hear a loud squelchy grinding sound.")) diff --git a/code/modules/forensics/_forensics.dm b/code/modules/forensics/_forensics.dm index 6a06e549d2635..40b480182537e 100644 --- a/code/modules/forensics/_forensics.dm +++ b/code/modules/forensics/_forensics.dm @@ -70,6 +70,7 @@ var/atom/parent_atom = parent.resolve() if (!isnull(parent_atom)) UnregisterSignal(parent_atom, list(COMSIG_COMPONENT_CLEAN_ACT)) + parent = null return ..() /// Empties the fingerprints list @@ -147,7 +148,9 @@ /// Adds a single fiber /datum/forensics/proc/add_fibers(mob/living/carbon/human/suspect) var/fibertext - var/atom/actual_parent = parent.resolve() + var/atom/actual_parent = parent?.resolve() + if(isnull(actual_parent)) + parent = null var/item_multiplier = isitem(actual_parent) ? ITEM_FIBER_MULTIPLIER : NON_ITEM_FIBER_MULTIPLIER if(suspect.wear_suit) fibertext = "Material from \a [suspect.wear_suit]." @@ -214,8 +217,11 @@ if(last_stamp_pos) LAZYSET(hiddenprints, suspect.key, copytext(hiddenprints[suspect.key], 1, last_stamp_pos)) hiddenprints[suspect.key] += "\nLast: \[[current_time]\] \"[suspect.real_name]\"[has_gloves]. Ckey: [suspect.ckey]" //made sure to be existing by if(!LAZYACCESS);else - var/atom/parent_atom = parent.resolve() - parent_atom.fingerprintslast = suspect.ckey + var/atom/parent_atom = parent?.resolve() + if(!isnull(parent_atom)) + parent_atom.fingerprintslast = suspect.ckey + else + parent = null return TRUE /// Adds the given list into blood_DNA @@ -230,7 +236,10 @@ /// Updates the blood displayed on parent /datum/forensics/proc/check_blood() - var/obj/item/the_thing = parent.resolve() + var/obj/item/the_thing = parent?.resolve() + if(isnull(the_thing)) + parent = null + return if(!istype(the_thing) || isorgan(the_thing)) // organs don't spawn with blood decals by default return if(!length(blood_DNA)) diff --git a/code/modules/holodeck/holo_effect.dm b/code/modules/holodeck/holo_effect.dm index 1bbedefb2e0ef..afd4c2270388f 100644 --- a/code/modules/holodeck/holo_effect.dm +++ b/code/modules/holodeck/holo_effect.dm @@ -62,11 +62,9 @@ mobtype = pick(mobtype) our_mob = new mobtype(loc) our_mob.flags_1 |= HOLOGRAM_1 - ADD_TRAIT(our_mob, TRAIT_PERMANENTLY_MORTAL, INNATE_TRAIT) // these vars are not really standardized but all would theoretically create stuff on death - for(var/v in list("butcher_results","corpse","weapon1","weapon2","blood_volume") & our_mob.vars) - our_mob.vars[v] = null + our_mob.add_traits(list(TRAIT_PERMANENTLY_MORTAL, TRAIT_NO_BLOOD_OVERLAY, TRAIT_NOBLOOD, TRAIT_NOHUNGER), INNATE_TRAIT) RegisterSignal(our_mob, COMSIG_QDELETING, PROC_REF(handle_mob_delete)) return our_mob @@ -103,7 +101,7 @@ mobtype = /mob/living/basic/bee/toxin /obj/effect/holodeck_effect/mobspawner/monkey - mobtype = /mob/living/carbon/human/species/monkey/holodeck + mobtype = /mob/living/carbon/human/species/monkey /obj/effect/holodeck_effect/mobspawner/monkey/activate(obj/machinery/computer/holodeck/computer) var/mob/living/carbon/human/monkey = ..() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 729ef541adeba..7c036fe22390d 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1064,6 +1064,9 @@ /proc/cmp_organ_slot_asc(slot_a, slot_b) return GLOB.organ_process_order.Find(slot_a) - GLOB.organ_process_order.Find(slot_b) +/mob/living/carbon/proc/get_footprint_sprite() + return FOOTPRINT_SPRITE_PAWS + /mob/living/carbon/vv_get_dropdown() . = ..() VV_DROPDOWN_OPTION("", "---------") @@ -1344,7 +1347,6 @@ else set_lying_angle(new_lying_angle) - /mob/living/carbon/vv_edit_var(var_name, var_value) switch(var_name) if(NAMEOF(src, disgust)) @@ -1360,17 +1362,18 @@ return ..() - /mob/living/carbon/get_attack_type() if(has_active_hand()) var/obj/item/bodypart/arm/active_arm = get_active_hand() return active_arm.attack_type return ..() - /mob/living/carbon/proc/attach_rot() - if(mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD)) - AddComponent(/datum/component/rot, 6 MINUTES, 10 MINUTES, 1) + if(flags_1 & HOLOGRAM_1) + return + if(!(mob_biotypes & (MOB_ORGANIC|MOB_UNDEAD))) + return + AddComponent(/datum/component/rot, 6 MINUTES, 10 MINUTES, 1) /** * This proc is used to determine whether or not the mob can handle touching an acid affected object. diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 7d31dd5ff90de..6d15f696bed57 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -6,6 +6,8 @@ GLOBAL_LIST_EMPTY(dead_players_during_shift) new /obj/effect/temp_visual/dust_animation(loc, dna.species.dust_anim) /mob/living/carbon/human/spawn_gibs(drop_bitflags=NONE) + if(flags_1 & HOLOGRAM_1) + return if(drop_bitflags & DROP_BODYPARTS) new /obj/effect/gibspawner/human(drop_location(), src, get_static_viruses()) else diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 4791c818e1aff..1860fd0dd0917 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -24,7 +24,7 @@ RegisterSignal(src, COMSIG_COMPONENT_CLEAN_FACE_ACT, PROC_REF(clean_face)) AddComponent(/datum/component/personal_crafting) AddElement(/datum/element/footstep, FOOTSTEP_MOB_HUMAN, 1, -6) - AddComponent(/datum/component/bloodysoles/feet) + AddComponent(/datum/component/bloodysoles/feet, FOOTPRINT_SPRITE_SHOES) AddElement(/datum/element/ridable, /datum/component/riding/creature/human) AddElement(/datum/element/strippable, GLOB.strippable_human_items, TYPE_PROC_REF(/mob/living/carbon/human/, should_strip)) var/static/list/loc_connections = list( @@ -347,6 +347,10 @@ var/obj/item/bodypart/the_part = isbodypart(target_zone) ? target_zone : get_bodypart(check_zone(target_zone)) //keep these synced to_chat(user, span_alert("There is no exposed flesh or thin material on [p_their()] [the_part.name].")) +/mob/living/carbon/human/get_footprint_sprite() + var/obj/item/bodypart/leg/L = get_bodypart(BODY_ZONE_R_LEG) || get_bodypart(BODY_ZONE_L_LEG) + return shoes?.footprint_sprite || L?.footprint_sprite + #define CHECK_PERMIT(item) (item && item.item_flags & NEEDS_PERMIT) /mob/living/carbon/human/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) diff --git a/code/modules/mob/living/carbon/human/monkey.dm b/code/modules/mob/living/carbon/human/monkey.dm index 88d46855a5e3d..d11e4f5208bc7 100644 --- a/code/modules/mob/living/carbon/human/monkey.dm +++ b/code/modules/mob/living/carbon/human/monkey.dm @@ -32,12 +32,6 @@ equip_to_slot_or_del(helmet, ITEM_SLOT_HEAD) helmet.attack_self(src) // todo encapsulate toggle -/mob/living/carbon/human/species/monkey/holodeck - race = /datum/species/monkey/holodeck - -/mob/living/carbon/human/species/monkey/holodeck/spawn_gibs() // no blood and no gibs - return - GLOBAL_DATUM(the_one_and_only_punpun, /mob/living/carbon/human/species/monkey/punpun) /mob/living/carbon/human/species/monkey/punpun diff --git a/code/modules/mob/living/carbon/human/species_types/monkeys.dm b/code/modules/mob/living/carbon/human/species_types/monkeys.dm index 3c176ff4388c8..b67f3efb3ef17 100644 --- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm +++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm @@ -191,23 +191,4 @@ /obj/item/organ/internal/brain/primate/get_attacking_limb(mob/living/carbon/human/target) return owner.get_bodypart(BODY_ZONE_HEAD) -/// Virtual monkeys that crave virtual bananas. Everything about them is ephemeral (except that bite). -/datum/species/monkey/holodeck - id = SPECIES_MONKEY_HOLODECK - knife_butcher_results = list() - meat = null - skinned_type = null - inherent_traits = list( - TRAIT_GENELESS, - TRAIT_GUN_NATURAL, - TRAIT_NO_AUGMENTS, - TRAIT_NO_BLOOD_OVERLAY, - TRAIT_NO_DNA_COPY, - TRAIT_NO_UNDERWEAR, - TRAIT_NO_ZOMBIFY, - TRAIT_NOBLOOD, - TRAIT_NOHUNGER, - TRAIT_VENTCRAWLER_NUDE, - ) - #undef MONKEY_SPEC_ATTACK_BITE_MISS_CHANCE diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 4da845c11df43..0c228775662d8 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -37,6 +37,8 @@ * * DROP_BODYPARTS - Gibs will spawn with bodypart limbs present **/ /mob/living/proc/spawn_gibs(drop_bitflags=NONE) + if(flags_1 & HOLOGRAM_1) + return new /obj/effect/gibspawner/generic(drop_location(), src, get_static_viruses()) /** diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm index 2031ea4c72309..be1a7828c2e99 100644 --- a/code/modules/surgery/bodyparts/parts.dm +++ b/code/modules/surgery/bodyparts/parts.dm @@ -383,7 +383,8 @@ unarmed_effectiveness = 15 /// Datum describing how to offset things worn on the foot of this leg, note that an x offset won't do anything here var/datum/worn_feature_offset/worn_foot_offset - + /// Used by the bloodysoles component to make footprints + var/footprint_sprite = FOOTPRINT_SPRITE_SHOES biological_state = BIO_STANDARD_JOINTED /obj/item/bodypart/leg/Destroy() @@ -463,6 +464,7 @@ unarmed_damage_low = 2 unarmed_damage_high = 3 unarmed_effectiveness = 0 + footprint_sprite = FOOTPRINT_SPRITE_PAWS /obj/item/bodypart/leg/left/alien icon = 'icons/mob/human/species/alien/bodyparts.dmi' @@ -552,6 +554,7 @@ unarmed_damage_low = 2 unarmed_damage_high = 3 unarmed_effectiveness = 0 + footprint_sprite = FOOTPRINT_SPRITE_PAWS /obj/item/bodypart/leg/right/alien icon = 'icons/mob/human/species/alien/bodyparts.dmi' diff --git a/code/modules/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm index 1d2e6b6838167..031534b0723e3 100644 --- a/code/modules/surgery/lipoplasty.dm +++ b/code/modules/surgery/lipoplasty.dm @@ -87,14 +87,17 @@ var/mob/living/carbon/human/human = target var/typeofmeat = /obj/item/food/meat/slab/human - if(human.dna && human.dna.species) + if(target.flags_1 & HOLOGRAM_1) + typeofmeat = null + else if(human.dna && human.dna.species) typeofmeat = human.dna.species.meat - var/obj/item/food/meat/slab/human/newmeat = new typeofmeat - newmeat.name = "fatty meat" - newmeat.desc = "Extremely fatty tissue taken from a patient." - newmeat.subjectname = human.real_name - newmeat.subjectjob = human.job - newmeat.reagents.add_reagent (/datum/reagent/consumable/nutriment, (removednutriment / 15)) //To balance with nutriment_factor of nutriment - newmeat.forceMove(target.loc) + if(typeofmeat) + var/obj/item/food/meat/slab/human/newmeat = new typeofmeat + newmeat.name = "fatty meat" + newmeat.desc = "Extremely fatty tissue taken from a patient." + newmeat.subjectname = human.real_name + newmeat.subjectjob = human.job + newmeat.reagents.add_reagent (/datum/reagent/consumable/nutriment, (removednutriment / 15)) //To balance with nutriment_factor of nutriment + newmeat.forceMove(target.loc) return ..() diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_holodeck.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_holodeck.png deleted file mode 100644 index e0d02f4302f43..0000000000000 Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_holodeck.png and /dev/null differ diff --git a/html/changelogs/AutoChangeLog-pr-81477.yml b/html/changelogs/AutoChangeLog-pr-81477.yml deleted file mode 100644 index afcfee6c41cb7..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-81477.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - refactor: "Frames have been refactored, you know the things you use to build computers and machines, report any oddities" - - bugfix: "You can now smack (de)constructed computer and machine frames to break them, rather than doing nothing." - - rscadd: "Machine frames can now be deconstructed with screwdrivers, and computer frames can now be deconstructed with welding torches. Welders are faster." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-81541.yml b/html/changelogs/AutoChangeLog-pr-81541.yml new file mode 100644 index 0000000000000..b152c6498dbdb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-81541.yml @@ -0,0 +1,4 @@ +author: "nevimer" +delete-after: True +changes: + - bugfix: "ForceEvent tgui panel search is more reliable." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-81569.yml b/html/changelogs/AutoChangeLog-pr-81569.yml deleted file mode 100644 index e0b2b2367dcd2..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-81569.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ghommie" -delete-after: True -changes: - - bugfix: "sec-hailers no longer apply filters on TTS when pushed out of the way." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-81577.yml b/html/changelogs/AutoChangeLog-pr-81577.yml new file mode 100644 index 0000000000000..16702f1297aa8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-81577.yml @@ -0,0 +1,4 @@ +author: "13spacemen" +delete-after: True +changes: + - refactor: "Bloody item overlays no longer use icon procs to generate the overlay" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-81584.yml b/html/changelogs/AutoChangeLog-pr-81584.yml deleted file mode 100644 index 68115f1eef452..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-81584.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - bugfix: "Organs have the blood DNA of their owns on them again" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-81585.yml b/html/changelogs/AutoChangeLog-pr-81585.yml deleted file mode 100644 index ac9af0845bd41..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-81585.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Melbert" -delete-after: True -changes: - - bugfix: "Chasms no longer break your verbs" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-81587.yml b/html/changelogs/AutoChangeLog-pr-81587.yml deleted file mode 100644 index 58ded0611baf5..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-81587.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Derpguy3" -delete-after: True -changes: - - bugfix: "Adds a missing servo component into the MK1 Ripley Crate ordered from cargo." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-81588.yml b/html/changelogs/AutoChangeLog-pr-81588.yml new file mode 100644 index 0000000000000..fc9163ce3efcd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-81588.yml @@ -0,0 +1,5 @@ +author: "13spacemen, Kapu1178" +delete-after: True +changes: + - refactor: "Footprint sprites are now based on your shoes and legs, shoes have priority" + - image: "Monkey legs now produce pawprints instead of footprints" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-81589.yml b/html/changelogs/AutoChangeLog-pr-81589.yml new file mode 100644 index 0000000000000..4cdcda2320ac0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-81589.yml @@ -0,0 +1,4 @@ +author: "JohnFulpWillard" +delete-after: True +changes: + - spellcheck: "Removed a double space in health analyzer's message telling you someone is deaf." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-81595.yml b/html/changelogs/AutoChangeLog-pr-81595.yml new file mode 100644 index 0000000000000..9a9db0f69a221 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-81595.yml @@ -0,0 +1,5 @@ +author: "Melbert" +delete-after: True +changes: + - rscdel: "Deletes Mythril Coins from random coin spawners" + - rscdel: "Replaces Mythril sheets in icebox vent fishing with Runite sheets" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-81597.yml b/html/changelogs/AutoChangeLog-pr-81597.yml new file mode 100644 index 0000000000000..87369c39be1f8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-81597.yml @@ -0,0 +1,4 @@ +author: "00-Steven" +delete-after: True +changes: + - bugfix: "Chefs (not to be confused with cooks) actually display as being a part of service on the crew monitor." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-81606.yml b/html/changelogs/AutoChangeLog-pr-81606.yml new file mode 100644 index 0000000000000..02bee239288bd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-81606.yml @@ -0,0 +1,4 @@ +author: "JohnFulpWillard" +delete-after: True +changes: + - refactor: "Holographic mobs now gives better feedback to players and should more consistently not give any drops." \ No newline at end of file diff --git a/html/changelogs/archive/2024-02.yml b/html/changelogs/archive/2024-02.yml index b949bfb3e41d1..de87de3d7f2b0 100644 --- a/html/changelogs/archive/2024-02.yml +++ b/html/changelogs/archive/2024-02.yml @@ -628,3 +628,18 @@ - bugfix: you may not teleport in or out of deathmatch arenas - bugfix: if you died as a changeling/anyone that has cool mind spells you do not get them in deathmatch +2024-02-22: + Derpguy3: + - bugfix: Adds a missing servo component into the MK1 Ripley Crate ordered from + cargo. + Ghommie: + - bugfix: sec-hailers no longer apply filters on TTS when pushed out of the way. + Melbert: + - bugfix: Chasms no longer break your verbs + - refactor: Frames have been refactored, you know the things you use to build computers + and machines, report any oddities + - bugfix: You can now smack (de)constructed computer and machine frames to break + them, rather than doing nothing. + - rscadd: Machine frames can now be deconstructed with screwdrivers, and computer + frames can now be deconstructed with welding torches. Welders are faster. + - bugfix: Organs have the blood DNA of their owns on them again diff --git a/icons/effects/footprints.dmi b/icons/effects/footprints.dmi index a98344abe41ee..a00c6a0f780db 100644 Binary files a/icons/effects/footprints.dmi and b/icons/effects/footprints.dmi differ diff --git a/tgui/packages/tgui/interfaces/ForceEvent.tsx b/tgui/packages/tgui/interfaces/ForceEvent.tsx index a93ea6a5f430f..4811e2fc20f2c 100644 --- a/tgui/packages/tgui/interfaces/ForceEvent.tsx +++ b/tgui/packages/tgui/interfaces/ForceEvent.tsx @@ -21,13 +21,15 @@ const paginateEvents = (events: Event[], maxPerPage: number): Event[][] => { let maxChars = EVENT_PAGE_MAXCHARS; for (const event of events) { - maxChars -= event.name.length; - if (maxChars <= 0) { - // would overflow the next line over - itemsToAdd = maxPerPage; - maxChars = EVENT_PAGE_MAXCHARS - event.name.length; - pages.push(page); - page = []; + if (event.name && typeof event.name === 'string') { + maxChars -= event.name.length; + if (maxChars <= 0) { + // would overflow the next line over + itemsToAdd = maxPerPage; + maxChars = EVENT_PAGE_MAXCHARS - event.name.length; + pages.push(page); + page = []; + } } page.push(event); itemsToAdd--; @@ -127,7 +129,14 @@ export const EventSection = (props) => { return false; } // remove events not being searched for, if a search is active - if (searchQuery && !event.name.toLowerCase().includes(searchQuery)) { + if ( + searchQuery && + event.name && + typeof event.name === 'string' && + searchQuery && + typeof searchQuery === 'string' && + !event.name.toLowerCase().includes(searchQuery.toLowerCase()) + ) { return false; } return true;