From f653cd3811e29c08f373c0f9988cbb8cb32919e1 Mon Sep 17 00:00:00 2001 From: Guti <32563288+TheCaramelion@users.noreply.github.com> Date: Fri, 19 Jun 2026 18:03:51 +0200 Subject: [PATCH] Hats! Hats! Hats! (#19529) --- code/datums/components/unusual_effect.dm | 41 ++++++++++++++++ code/datums/supplypacks/recreation.dm | 7 +++ .../game/objects/effects/particles/unusual.dm | 48 +++++++++++++++++++ .../structures/crates_lockers/largecrate.dm | 4 ++ code/game/objects/structures/mystery_box.dm | 16 +++++++ vorestation.dme | 2 + 6 files changed, 118 insertions(+) create mode 100644 code/datums/components/unusual_effect.dm create mode 100644 code/game/objects/effects/particles/unusual.dm diff --git a/code/datums/components/unusual_effect.dm b/code/datums/components/unusual_effect.dm new file mode 100644 index 00000000000..099408a5a94 --- /dev/null +++ b/code/datums/components/unusual_effect.dm @@ -0,0 +1,41 @@ +/// Creates a cool looking effect on the movable. +/datum/component/unusual_effect + dupe_mode = COMPONENT_DUPE_HIGHLANDER + + var/obj/effect/abstract/particle_holder/special_effects + + var/color + + COOLDOWN_DECLARE(glow_cooldown) + +/datum/component/unusual_effect/Initialize(color, include_particles = FALSE) + var/atom/movable/parent_movable = parent + if(!istype(parent_movable)) + return COMPONENT_INCOMPATIBLE + + src.color = color + parent_movable.add_filter("unusual_effect", 2, list("type" = "outline", "color" = color, "size" = 2)) + if(include_particles) + var/particles = pick(typesof(/particles/unusual_effect)) + special_effects = new(parent_movable, particles) + START_PROCESSING(SSobj, src) + +/datum/component/unusual_effect/Destroy(force) + var/atom/movable/parent_movable = parent + if(istype(parent_movable)) + parent_movable.remove_filter("unusual_effect") + STOP_PROCESSING(SSobj, src) + return ..() + +/datum/component/unusual_effect/process(seconds_per_tick) + var/atom/movable/parent_movable = parent + var/filter = parent_movable.get_filter("unusual_effect") + if(!filter) + parent_movable.add_filter("unusual_effect", 2, list("type" = "outline", "color" = color, "size" = 2)) + return + if(!COOLDOWN_FINISHED(src, glow_cooldown)) + return + + animate(filter, alpha = 110, time = 1.5 SECONDS, loop = -1) + animate(alpha = 40, time = 2.5 SECONDS) + COOLDOWN_START(src, glow_cooldown, 4 SECONDS) diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm index ad02db99b6e..fa1bac9928c 100644 --- a/code/datums/supplypacks/recreation.dm +++ b/code/datums/supplypacks/recreation.dm @@ -380,3 +380,10 @@ ) cost = 30 containertype = /obj/structure/closet/crate + +/datum/supply_pack/recreation/mystery_box/hat + name = "Hat Mystery Box" + desc = "Contains a crate with five random hats." + contains = list() + cost = 50 + containertype = /obj/structure/largecrate/mysteryhats diff --git a/code/game/objects/effects/particles/unusual.dm b/code/game/objects/effects/particles/unusual.dm new file mode 100644 index 00000000000..ff5f4883175 --- /dev/null +++ b/code/game/objects/effects/particles/unusual.dm @@ -0,0 +1,48 @@ +/particles/unusual_effect + icon = 'icons/effects/particles/pollen.dmi' + icon_state = "pollen" + width = 100 + height = 100 + count = 1000 + spawning = 4 + lifespan = 0.7 SECONDS + fade = 1 SECONDS + grow = -0.01 + velocity = list(0, 0) + position = generator(GEN_CIRCLE, 0, 15, NORMAL_RAND) + drift = generator(GEN_VECTOR, list(0, -0.2), list(0, 0.2)) + gravity = list(0, 0.95) + scale = generator(GEN_VECTOR, list(0.3, 0.3), list(1, 1), NORMAL_RAND) + rotation = 30 + spin = generator(GEN_NUM, -20, 20) + +/particles/unusual_effect/cloud + icon = 'icons/effects/particles/smoke.dmi' + icon_state = list("steam_cloud_1" = 1, "steam_cloud_2" = 1, "steam_cloud_3" = 1, "steam_cloud_4" = 1, "steam_cloud_5" = 1) + color = "#FFFFFF8A" + count = 5 + spawning = 0.3 + fade = 1.2 SECONDS + fadein = 0.4 SECONDS + position = generator(GEN_BOX, list(-17,-15,0), list(24,15,0), NORMAL_RAND) + scale = generator(GEN_VECTOR, list(0.9,0.9), list(1.1,1.1), NORMAL_RAND) + drift = generator(GEN_SPHERE, list(-0.01,0), list(0.01,0.01), UNIFORM_RAND) + spin = generator(GEN_NUM, -2, 2, NORMAL_RAND) + gravity = list(0.05, 0.28) + friction = 0.3 + grow = 0.037 + +/particles/unusual_effect/fire + count = 10 + spawning = 5 + width = 64 + height = 96 + gradient = list("#FBAF4D", "#FCE6B6", "#FFFFFF") + lifespan = 1.5 SECONDS + fade = 1 SECONDS + fadein = 0.1 SECONDS + grow = -0.1 + velocity = generator(GEN_CIRCLE, 3, 3, SQUARE_RAND) + position = generator(GEN_SPHERE, 0, 0, LINEAR_RAND) + scale = generator(GEN_VECTOR, list(0.5, 0.5), list(1,1), NORMAL_RAND) + drift = list(0) diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm index a30589720cf..5703474899b 100644 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ b/code/game/objects/structures/crates_lockers/largecrate.dm @@ -152,3 +152,7 @@ /obj/item/assembly/signaler/anomaly/choice/, /obj/item/anomaly_scanner ) + +/obj/structure/largecrate/mysteryhats + name = "mystery hats box" + starts_with = list(/obj/structure/mystery_box/hat) diff --git a/code/game/objects/structures/mystery_box.dm b/code/game/objects/structures/mystery_box.dm index f2e3753adbb..1048ed46201 100644 --- a/code/game/objects/structures/mystery_box.dm +++ b/code/game/objects/structures/mystery_box.dm @@ -139,6 +139,10 @@ if(!isitem(instantiated_weapon)) return + if(istype(instantiated_weapon, /obj/item/clothing/head) && prob(1)) + var/obj/item/clothing/head/hat = instantiated_weapon + hat.AddComponent(/datum/component/unusual_effect, color = "#FFEA0030", include_particles = TRUE) + hat.name = "unusual [hat.name]" user.put_in_hands(instantiated_weapon) /obj/effect/abstract/mystery_box_item @@ -244,6 +248,18 @@ /obj/item/material/fishing_rod/modern ) +/obj/structure/mystery_box/hat + name = "hat box" + desc = "A wooden crate, filled with hats. There's a sticker on the side that says \"May contain an exceedingly rare special hat!\"" + uses_left = 5 + anchored = FALSE + +/obj/structure/mystery_box/hat/generate_valid_types() + valid_types = subtypesof(/obj/item/clothing/head) + for(var/obj/item/hat as anything in valid_types) + if(ispath(hat, /obj/item/clothing/head/helmet) || ispath(hat, /obj/item/clothing/head/hood) || ispath(hat, /obj/item/clothing/head/tesh_hood || ispath(hat, /obj/item/clothing/head/chameleon))) + valid_types -= hat + #undef MYSTERY_BOX_COOLING_DOWN #undef MYSTERY_BOX_STANDBY #undef MYSTERY_BOX_CHOOSING diff --git a/vorestation.dme b/vorestation.dme index 6395c6839af..39c3ebf7365 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -721,6 +721,7 @@ #include "code\datums\components\swarm.dm" #include "code\datums\components\tethered_item.dm" #include "code\datums\components\turfslip.dm" +#include "code\datums\components\unusual_effect.dm" #include "code\datums\components\animations\dizzy.dm" #include "code\datums\components\animations\jittery.dm" #include "code\datums\components\antags\antag.dm" @@ -1650,6 +1651,7 @@ #include "code\game\objects\effects\map_effects\sound_emitter.dm" #include "code\game\objects\effects\particles\fire.dm" #include "code\game\objects\effects\particles\smoke.dm" +#include "code\game\objects\effects\particles\unusual.dm" #include "code\game\objects\effects\particles\water.dm" #include "code\game\objects\effects\prop\columnblast.dm" #include "code\game\objects\effects\prop\snake.dm"