diff --git a/monkestation/code/modules/trading/icons/particles.dmi b/monkestation/code/modules/trading/icons/particles.dmi index 7cfb8511c722..12083a1b5f4e 100644 Binary files a/monkestation/code/modules/trading/icons/particles.dmi and b/monkestation/code/modules/trading/icons/particles.dmi differ diff --git a/monkestation/code/modules/trading/unusual_effects/_unusual_component.dm b/monkestation/code/modules/trading/unusual_effects/_unusual_component.dm new file mode 100644 index 000000000000..03501d116b2f --- /dev/null +++ b/monkestation/code/modules/trading/unusual_effects/_unusual_component.dm @@ -0,0 +1,37 @@ +/datum/component/unusual_handler + var/atom/source_object + ///the description added to the unusual. + var/unusual_description = "" + ///the round the unusual was created at + var/round_id = 0 + ///the particle spewer component path + var/particle_path = /datum/component/particle_spewer/confetti + /// The original owners name + var/original_owner_ckey = "dwasint" + /// the slot this item goes in used when creating the particle itself + var/unusual_equip_slot = ITEM_SLOT_HEAD + +//this init is handled far differently than others. it parses data from the DB for information about the unusual itself +//it than loads this info into the component itself, the particle_path is purely for spawning temporary ones in round +/datum/component/unusual_handler/Initialize(list/parsed_variables = list(), particle_path = /datum/component/particle_spewer/confetti) + . = ..() + if(!length(parsed_variables)) + src.particle_path = particle_path + else + setup_from_list(parsed_variables) + + source_object = parent + + source_object.AddComponent(particle_path) + +/datum/component/unusual_handler/proc/setup_from_list(list/parsed_results) + return + +/obj/item/clothing/head/costume/chicken/confetti_unusual/Initialize(mapload) + . = ..() + AddComponent(/datum/component/unusual_handler) + +/obj/item/clothing/head/costume/chicken/snow_unusual/Initialize(mapload) + . = ..() + AddComponent(/datum/component/unusual_handler) + diff --git a/monkestation/code/modules/trading/unusual_effects/animation_housing/_spawning_component.dm b/monkestation/code/modules/trading/unusual_effects/animation_housing/_spawning_component.dm index adac718fcd0d..46a3250b6273 100644 --- a/monkestation/code/modules/trading/unusual_effects/animation_housing/_spawning_component.dm +++ b/monkestation/code/modules/trading/unusual_effects/animation_housing/_spawning_component.dm @@ -8,6 +8,8 @@ /datum/component/particle_spewer var/atom/source_object + //the worn mob + var/mob/worn_mob ///the duration we last var/duration = 0 ///the spawn intervals in game ticks @@ -27,33 +29,51 @@ ///current process count var/count = 0 ///equipped offset ie hats go to 32 if set to 32 will also reset to height changes - var/equipped_offset = 32 + var/equipped_offset = 0 ///per burst spawn amount var/burst_amount = 1 ///the actual lifetime of this component before we die [ 0 = infinite] var/lifetime = 0 + ///kept track of for removal sake + var/added_x = 0 + var/added_y = 0 - -/datum/component/particle_spewer/Initialize(duration = 0, spawn_interval = 1, offset_x = 0, offset_y = 0, icon_file = 'monkestation/code/modules/trading/icons/particles.dmi', particle_state = "none", equipped_offset = 32, burst_amount = 1, lifetime = 0) +/datum/component/particle_spewer/Initialize(duration = 0, spawn_interval = 0, offset_x = 0, offset_y = 0, icon_file, particle_state, equipped_offset = 0, burst_amount = 0, lifetime = 0) . = ..() - src.icon_file = icon_file - src.particle_state = particle_state - src.offset_x = offset_x + rand(-8, 8) - src.offset_y = offset_y + rand(-4, 4) - src.spawn_interval = spawn_interval - src.duration = duration - src.equipped_offset = equipped_offset - src.burst_amount = burst_amount - src.lifetime = lifetime + if(icon_file) + src.icon_file = icon_file + if(particle_state) + src.particle_state = particle_state + if(offset_x) + src.offset_x = offset_x + rand(-8, 8) + if(offset_y) + src.offset_y = offset_y + rand(-4, 4) + if(spawn_interval) + src.spawn_interval = spawn_interval + if(duration) + src.duration = duration + if(equipped_offset) + src.equipped_offset = equipped_offset + if(burst_amount) + src.burst_amount = burst_amount + if(lifetime) + src.lifetime = lifetime source_object = parent START_PROCESSING(SSactualfastprocess, src) - + RegisterSignal(source_object, COMSIG_ITEM_EQUIPPED, PROC_REF(handle_equip_offsets)) + RegisterSignal(source_object, COMSIG_ITEM_POST_UNEQUIP, PROC_REF(reset_offsets)) + if(lifetime) addtimer(CALLBACK(src, PROC_REF(kill_it_with_fire)), lifetime) /datum/component/particle_spewer/Destroy(force, silent) . = ..() + UnregisterSignal(source_object, list( + COMSIG_ITEM_EQUIPPED, + COMSIG_ITEM_POST_UNEQUIP, + )) + STOP_PROCESSING(SSactualfastprocess, src) for(var/atom/listed_atom as anything in living_particles + dead_particles) qdel(listed_atom) @@ -93,6 +113,32 @@ /datum/component/particle_spewer/proc/kill_it_with_fire() qdel(src) +/datum/component/particle_spewer/proc/handle_equip_offsets(datum/source, mob/equipper, slot) + SIGNAL_HANDLER + offset_x -= added_x + offset_y -= added_y + added_x = 0 + added_y = 0 + worn_mob = equipper + + switch(slot) + if(ITEM_SLOT_HEAD) + added_y = 16 + else + added_y = 0 + added_x = 0 + + offset_y += added_y + offset_x += added_x + +/datum/component/particle_spewer/proc/reset_offsets() + SIGNAL_HANDLER + offset_x -= added_x + offset_y -= added_y + added_x = 0 + added_y = 0 + worn_mob = null + /obj/item/debug_particle_holder/Initialize(mapload) . = ..() AddComponent(/datum/component/particle_spewer, 2 SECONDS) diff --git a/monkestation/code/modules/trading/unusual_effects/animation_housing/confetti.dm b/monkestation/code/modules/trading/unusual_effects/animation_housing/confetti.dm index a311082d1f5c..ecddda9529d0 100644 --- a/monkestation/code/modules/trading/unusual_effects/animation_housing/confetti.dm +++ b/monkestation/code/modules/trading/unusual_effects/animation_housing/confetti.dm @@ -1,3 +1,7 @@ +/datum/component/particle_spewer/confetti + duration = 2 SECONDS + burst_amount = 5 + /datum/component/particle_spewer/confetti/animate_particle(obj/effect/abstract/particle/spawned) var/matrix/first = matrix() var/matrix/second = matrix() @@ -14,7 +18,8 @@ animate(spawned, transform = first, time = 0.4 SECONDS, pixel_y = rand(-32, 32) + spawned.pixel_y, pixel_x = rand(-32, 32) + spawned.pixel_x, easing = LINEAR_EASING) animate(transform = second, time = 0.5 SECONDS, alpha = 0, pixel_y = spawned.pixel_y - 5, easing = LINEAR_EASING|EASE_OUT) + addtimer(CALLBACK(src, PROC_REF(delete_particle), spawned), duration) /obj/item/debug_confetti/Initialize(mapload) . = ..() - AddComponent(/datum/component/particle_spewer/confetti, 10 SECONDS, burst_amount = 5) + AddComponent(/datum/component/particle_spewer/confetti) diff --git a/monkestation/code/modules/trading/unusual_effects/animation_housing/snow.dm b/monkestation/code/modules/trading/unusual_effects/animation_housing/snow.dm new file mode 100644 index 000000000000..566988f0e0b7 --- /dev/null +++ b/monkestation/code/modules/trading/unusual_effects/animation_housing/snow.dm @@ -0,0 +1,24 @@ +/datum/component/particle_spewer/snow + icon_file = 'monkestation/code/modules/outdoors/icons/effects/particles/particle.dmi' + particle_state = "cross" + burst_amount = 4 + duration = 2 SECONDS + +/datum/component/particle_spewer/snow/animate_particle(obj/effect/abstract/particle/spawned) + var/chance = rand(1, 10) + switch(chance) + if(1 to 2) + spawned.icon_state = "cross" + if(3 to 4) + spawned.icon_state = "snow_2" + if(5 to 6) + spawned.icon_state = "snow_3" + else + spawned.icon_state = "snow_1" + + spawned.pixel_x += rand(-3, 3) + spawned.pixel_y += rand(-3, 3) + + animate(spawned, pixel_y = spawned.pixel_y - 32, time = 2 SECONDS) + animate(spawned, alpha = 25, time = 1.5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(delete_particle), spawned), duration) diff --git a/tgstation.dme b/tgstation.dme index d99b10d51c04..d508cdc6dae4 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6341,8 +6341,10 @@ #include "monkestation\code\modules\surgery\organs\internal\lungs.dm" #include "monkestation\code\modules\surgery\organs\internal\stomach.dm" #include "monkestation\code\modules\surgery\organs\internal\tongue.dm" +#include "monkestation\code\modules\trading\unusual_effects\_unusual_component.dm" #include "monkestation\code\modules\trading\unusual_effects\animation_housing\_spawning_component.dm" #include "monkestation\code\modules\trading\unusual_effects\animation_housing\confetti.dm" +#include "monkestation\code\modules\trading\unusual_effects\animation_housing\snow.dm" #include "monkestation\code\modules\twitch_bits\admin_command.dm" #include "monkestation\code\modules\twitch_bits\twitch_system.dm" #include "monkestation\code\modules\twitch_bits\events\amongus.dm"