From 6e57a237a9e9c77ec6255a2a6f83eb6542a1fd37 Mon Sep 17 00:00:00 2001 From: Sim Date: Mon, 7 Oct 2024 23:27:22 -0300 Subject: [PATCH 01/14] [MIRROR] Popup Notice tgstation/tgstation#61010 Ports the admin popup notice from tgstation. --- code/__DEFINES/dcs/signals.dm | 8 ++ code/__DEFINES/layers_planes.dm | 3 + .../configuration/entries/general.dm | 3 + code/datums/components/admin_popup.dm | 125 ++++++++++++++++++ code/modules/admin/topic.dm | 16 +++ code/modules/admin/verbs/adminhelp.dm | 5 + code/modules/admin/verbs/adminpm.dm | 15 +-- config/entries/admin.txt | 6 +- tgstation.dme | 1 + 9 files changed, 165 insertions(+), 17 deletions(-) create mode 100644 code/datums/components/admin_popup.dm diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index 41c164b667..28e0d9d159 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -712,3 +712,11 @@ #define COMSIG_ALARM_TRIGGERED "comsig_alarm_triggered" ///Send when an alarm source is cleared (alarm_type, area/source_area) #define COMSIG_ALARM_CLEARED "comsig_alarm_clear" + +/// Admin helps +/// From /datum/admin_help/RemoveActive(). +/// Fired when an adminhelp is made inactive either due to closing or resolving. +#define COMSIG_ADMIN_HELP_MADE_INACTIVE "admin_help_made_inactive" + +/// Called when the player replies. From /client/proc/cmd_admin_pm(). +#define COMSIG_ADMIN_HELP_REPLIED "admin_help_replied" diff --git a/code/__DEFINES/layers_planes.dm b/code/__DEFINES/layers_planes.dm index 578dfe87e5..64d8b5f02c 100644 --- a/code/__DEFINES/layers_planes.dm +++ b/code/__DEFINES/layers_planes.dm @@ -200,5 +200,8 @@ #define SPLASHSCREEN_PLANE 90 #define SPLASHSCREEN_RENDER_TARGET "SPLASHSCREEN_PLANE" +// Admin popup layer +#define ADMIN_POPUP_LAYER 1 + ///Layer for screentips #define SCREENTIP_LAYER 40 diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index f7c864a89f..148d0be3d7 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -347,3 +347,6 @@ /datum/config_entry/str_list/randomizing_station_name_message default = list() + +/// Gives the ability to send players a maptext popup. +/datum/config_entry/flag/popup_admin_pm diff --git a/code/datums/components/admin_popup.dm b/code/datums/components/admin_popup.dm new file mode 100644 index 0000000000..ae7855e850 --- /dev/null +++ b/code/datums/components/admin_popup.dm @@ -0,0 +1,125 @@ +/// Applied to clients when they receive an admin popup, alerting them to +/// their ticket. +/datum/component/admin_popup + /// The user's most active ticket. If this is resolved, closed, or replied to, + /// then the component will delete itself. + var/datum/admin_help/ticket + + var/atom/movable/screen/admin_popup/admin_popup + +/datum/component/admin_popup/Initialize(datum/admin_help/ticket) + if (!istype(parent, /client)) + return COMPONENT_INCOMPATIBLE + + if (!istype(ticket)) + return COMPONENT_INCOMPATIBLE + + create_notice() + + RegisterSignal( + ticket, + list( + COMSIG_ADMIN_HELP_MADE_INACTIVE, + COMSIG_ADMIN_HELP_REPLIED, + COMSIG_PARENT_QDELETING, + ), + PROC_REF(delete_self), + ) + +/datum/component/admin_popup/Destroy(force) + var/client/parent_client = parent + + parent_client?.screen -= admin_popup + QDEL_NULL(admin_popup) + + if (!QDELETED(ticket)) + UnregisterSignal(ticket, list( + COMSIG_ADMIN_HELP_MADE_INACTIVE, + COMSIG_ADMIN_HELP_REPLIED, + COMSIG_PARENT_QDELETING, + )) + + ticket = null + + return ..() + +/datum/component/admin_popup/proc/create_notice() + if(admin_popup) + qdel(admin_popup) + admin_popup = new + + var/client/parent_client = parent + admin_popup.maptext_width = view_to_pixels(parent_client.view_size.getView())[1] + parent_client.screen += admin_popup + +/datum/component/admin_popup/proc/delete_self() + SIGNAL_HANDLER + qdel(src) + +/// The UI element for admin popups +/atom/movable/screen/admin_popup + icon = null + icon_state = null + plane = ABOVE_HUD_PLANE + layer = ADMIN_POPUP_LAYER + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + screen_loc = "TOP-5,LEFT" + maptext_height = 720 + maptext_width = 720 + maptext = "" + + var/static/list/colors = list( + COLOR_RED, + COLOR_ORANGE, + COLOR_YELLOW, + COLOR_LIME, + COLOR_CYAN, + COLOR_PURPLE, + ) + + /// The last color chosen in the animation, sourced from the static list colors. + var/last_color_index = 0 + + /// The `world.time` when the last color update occurred. + var/last_update_time = 0 + +/atom/movable/screen/admin_popup/Initialize(mapload, datum/hud/hud_owner, ...) + . = ..() + + START_PROCESSING(SSobj, src) + update_text() + +/atom/movable/screen/admin_popup/Destroy() + STOP_PROCESSING(SSobj, src) + return ..() + +/atom/movable/screen/admin_popup/process(seconds_per_tick) + update_text() + +/atom/movable/screen/admin_popup/proc/update_text() + // Even if processing time changes, we want this to remain slow. + // We want to pester them into reading their ticket, not give them a seizure! + if (world.time - last_update_time < 2 SECONDS) + return + + last_color_index = (last_color_index % colors.len) + 1 + + var/message = "" + message += "HEY!
An admin is trying to talk to you!
Check your chat window,
and click their name to respond!" + message += "
" + + maptext = MAPTEXT(message) + last_update_time = world.time + +/// Tries to give the target an admin popup. +/// If it fails, will send the error to the passed admin. +/proc/give_admin_popup(client/target, client/admin, message) + log_admin("[key_name(admin)] sent an admin popup to [key_name(target)].") + + var/datum/admin_help/current_ticket = target.current_ticket + if (!current_ticket) + to_chat(admin, span_warning("[key_name(target)] had no active ahelp, aborting.")) + return + + admin.cmd_admin_pm(target, message) + target.AddComponent(/datum/component/admin_popup, current_ticket) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index ffe284aa71..eb42828744 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1997,6 +1997,22 @@ to_chat(H, "Your prayers have been answered!! You received the best cookie!") SEND_SOUND(H, sound('sound/effects/pray_chaplain.ogg')) + else if (href_list["adminpopup"]) + if (!check_rights(R_ADMIN)) + return + + var/message = input(owner, "As well as a popup, they'll also be sent a message to reply to. What do you want that to be?", "Message") as text|null + if (!message) + to_chat(owner, span_notice("Popup cancelled.")) + return + + var/client/target = locate(href_list["adminpopup"]) + if (!istype(target)) + to_chat(owner, span_notice("The mob doesn't exist anymore!")) + return + + give_admin_popup(target, owner, message) + else if(href_list["adminsmite"]) if(!check_rights(R_ADMIN|R_FUN)) return diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index a3f6548112..284cdcf5b3 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -249,6 +249,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) if(state == AHELP_ACTIVE) . += ClosureLinks(ref_src) + if (CONFIG_GET(flag/popup_admin_pm)) + . += " (POPUP)" + //private /datum/admin_help/proc/ClosureLinks(ref_src) if(!ref_src) @@ -332,6 +335,8 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) if(initiator && initiator.current_ticket == src) initiator.current_ticket = null + SEND_SIGNAL(src, COMSIG_ADMIN_HELP_MADE_INACTIVE) + //Mark open ticket as closed/meme /datum/admin_help/proc/Close(key_name = key_name_admin(usr), silent = FALSE) if(state != AHELP_ACTIVE) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 950a06b2b9..4969962e4c 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -172,6 +172,7 @@ if(holder && recipient.holder && !current_ticket) //Both are admins, and this is not a reply to our own ticket. badmin = TRUE if(recipient.holder && !badmin) + SEND_SIGNAL(current_ticket, COMSIG_ADMIN_HELP_REPLIED) if(holder) to_chat(recipient, "Admin PM from-[key_name(src, recipient, 1)]: [keywordparsedmsg]", confidential = TRUE) to_chat(src, "Admin PM to-[key_name(recipient, src, 1)]: [keywordparsedmsg]", confidential = TRUE) @@ -215,9 +216,6 @@ //always play non-admin recipients the adminhelp sound SEND_SOUND(recipient, sound('sound/effects/adminhelp.ogg')) - //AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn - if(CONFIG_GET(flag/popup_admin_pm)) - INVOKE_ASYNC(src, PROC_REF(popup_admin_pm), recipient, msg) else //neither are admins to_chat(src, "Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.", confidential = TRUE) @@ -235,17 +233,6 @@ if(X.key!=key && X.key!=recipient.key) //check client/X is an admin and isn't the sender or recipient to_chat(X, "PM: [key_name(src, X, 0)]->[key_name(recipient, X, 0)]: [keywordparsedmsg]" , confidential = TRUE) -/client/proc/popup_admin_pm(client/recipient, msg) - var/sender = src - var/sendername = key - var/reply = input(recipient, msg,"Admin PM from-[sendername]", "") as message|null //show message and await a reply - if(recipient && reply) - if(sender) - recipient.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them - else - adminhelp(reply) //sender has left, adminhelp instead - - /proc/IrcPm(target,msg,sender) return TgsPm(target,msg,sender) //compatability moment. diff --git a/config/entries/admin.txt b/config/entries/admin.txt index d7932bbe13..75fc08f99e 100644 --- a/config/entries/admin.txt +++ b/config/entries/admin.txt @@ -30,9 +30,9 @@ MENTOR_LEGACY_SYSTEM ## Uncomment this to forbid admins from possessing the singularity. #FORBID_SINGULO_POSSESSION -## Uncomment to show a popup 'reply to' window to every non-admin that receives an adminPM. -## The intention is to make adminPMs more visible. (although I fnd popups annoying so this defaults to off) -#POPUP_ADMIN_PM +## Uncomment to give admins the ability to send a maptext popup to players. +## Only fires when an admin requests it, not every ahelp. +POPUP_ADMIN_PM ## Uncomment this to let players see their own notes (they can still be set by admins only) #SEE_OWN_NOTES diff --git a/tgstation.dme b/tgstation.dme index e932719dba..9d2a19e884 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -597,6 +597,7 @@ #include "code\datums\components\_component.dm" #include "code\datums\components\acid.dm" #include "code\datums\components\activity.dm" +#include "code\datums\components\admin_popup.dm" #include "code\datums\components\anti_magic.dm" #include "code\datums\components\area_sound_manager.dm" #include "code\datums\components\armor_plate.dm" From c8983e1b0383efef75f29f2dfb929cd6813da8e5 Mon Sep 17 00:00:00 2001 From: Sim Date: Tue, 8 Oct 2024 01:50:15 -0300 Subject: [PATCH 02/14] Did you know Mosley pulls from downstreams without knowing what he pulls? AKA [PORT] Refactors smiting, adds smite build mode tgstation/tgstation#55327 !! NOT!! A!! RUNNING!! BUILD!! LIGHTNING IS BROKEN IMMERSE IS COMMENTED OUT HALF OF THIS SHIT IS BROKEN DO NOT BASE YOURSELF ON THIS BUILD!! --- code/__DEFINES/admin.dm | 21 -- code/_globalvars/lists/admin.dm | 8 + code/datums/brain_damage/phobia.dm | 4 + code/datums/components/admin_popup.dm | 4 +- code/modules/admin/smites/berforate.dm | 46 +++ code/modules/admin/smites/bloodless.dm | 17 ++ code/modules/admin/smites/boneless.dm | 13 + code/modules/admin/smites/bonk.dm | 9 + code/modules/admin/smites/bookify.dm | 13 + code/modules/admin/smites/brain_damage.dm | 6 + code/modules/admin/smites/bread.dm | 14 + code/modules/admin/smites/bsa.dm | 32 +++ code/modules/admin/smites/cluwne.dm | 10 + code/modules/admin/smites/custompie.dm | 18 ++ code/modules/admin/smites/dock_pay.dm | 31 ++ code/modules/admin/smites/fake_bwoink.dm | 7 + code/modules/admin/smites/finalmessage.dm | 12 + code/modules/admin/smites/fireball.dm | 7 + code/modules/admin/smites/fry.dm | 7 + code/modules/admin/smites/gib.dm | 7 + code/modules/admin/smites/immerse.dm | 10 + code/modules/admin/smites/knot_shoes.dm | 15 + code/modules/admin/smites/lightning.dm | 17 ++ code/modules/admin/smites/nugget.dm | 21 ++ code/modules/admin/smites/pickle.dm | 7 + code/modules/admin/smites/pie.dm | 8 + code/modules/admin/smites/puzzle.dm | 8 + code/modules/admin/smites/rod.dm | 17 ++ code/modules/admin/smites/scarify.dm | 12 + code/modules/admin/smites/shoes.dm | 15 + code/modules/admin/smites/smite.dm | 17 ++ code/modules/admin/smites/supply_pod.dm | 21 ++ code/modules/admin/smites/supply_pod_quick.dm | 49 ++++ code/modules/admin/smites/tabletide.dm | 16 ++ code/modules/admin/verbs/bluespacearty.dm | 26 -- code/modules/admin/verbs/randomverbs.dm | 266 ++---------------- code/modules/buildmode/submodes/smite.dm | 40 +++ icons/misc/buildmode.dmi | Bin 1711 -> 2783 bytes .../code/modules/admin/verbs/randomverbs.dm | 9 - tgstation.dme | 33 ++- 40 files changed, 585 insertions(+), 308 deletions(-) create mode 100644 code/_globalvars/lists/admin.dm create mode 100644 code/modules/admin/smites/berforate.dm create mode 100644 code/modules/admin/smites/bloodless.dm create mode 100644 code/modules/admin/smites/boneless.dm create mode 100644 code/modules/admin/smites/bonk.dm create mode 100644 code/modules/admin/smites/bookify.dm create mode 100644 code/modules/admin/smites/brain_damage.dm create mode 100644 code/modules/admin/smites/bread.dm create mode 100644 code/modules/admin/smites/bsa.dm create mode 100644 code/modules/admin/smites/cluwne.dm create mode 100644 code/modules/admin/smites/custompie.dm create mode 100644 code/modules/admin/smites/dock_pay.dm create mode 100644 code/modules/admin/smites/fake_bwoink.dm create mode 100644 code/modules/admin/smites/finalmessage.dm create mode 100644 code/modules/admin/smites/fireball.dm create mode 100644 code/modules/admin/smites/fry.dm create mode 100644 code/modules/admin/smites/gib.dm create mode 100644 code/modules/admin/smites/immerse.dm create mode 100644 code/modules/admin/smites/knot_shoes.dm create mode 100644 code/modules/admin/smites/lightning.dm create mode 100644 code/modules/admin/smites/nugget.dm create mode 100644 code/modules/admin/smites/pickle.dm create mode 100644 code/modules/admin/smites/pie.dm create mode 100644 code/modules/admin/smites/puzzle.dm create mode 100644 code/modules/admin/smites/rod.dm create mode 100644 code/modules/admin/smites/scarify.dm create mode 100644 code/modules/admin/smites/shoes.dm create mode 100644 code/modules/admin/smites/smite.dm create mode 100644 code/modules/admin/smites/supply_pod.dm create mode 100644 code/modules/admin/smites/supply_pod_quick.dm create mode 100644 code/modules/admin/smites/tabletide.dm delete mode 100644 code/modules/admin/verbs/bluespacearty.dm create mode 100644 code/modules/buildmode/submodes/smite.dm diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index d54a9baf36..13830b20c8 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -69,27 +69,6 @@ #define ADMIN_VERBOSEJMP(src) "[src ? "[AREACOORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]" #define ADMIN_INDIVIDUALLOG(user) "(LOGS)" -#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt" -#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage" -#define ADMIN_PUNISHMENT_GIB "Gib" -#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device" -#define ADMIN_PUNISHMENT_FIREBALL "Fireball" -#define ADMIN_PUNISHMENT_ROD "Immovable Rod" -#define ADMIN_PUNISHMENT_SUPPLYPOD_QUICK "Supply Pod (Quick)" -#define ADMIN_PUNISHMENT_SUPPLYPOD "Supply Pod" -#define ADMIN_PUNISHMENT_MAZING "Puzzle" -#define ADMIN_PUNISHMENT_PIE "Cream Pie" -#define ADMIN_PUNISHMENT_CUSTOM_PIE "Custom Cream Pie" -#define ADMIN_PUNISHMENT_SHOES "Knot Shoes" -#define ADMIN_PUNISHMENT_CRACK ":B:oneless" -#define ADMIN_PUNISHMENT_BLEED ":B:loodless" -#define ADMIN_PUNISHMENT_SCARIFY "Scarify" -#define ADMIN_PUNISHMENT_PICKLE "Pickle-ify" -#define ADMIN_PUNISHMENT_FRY "Fry" -#define ADMIN_PUNISHMENT_PERFORATE ":B:erforate" -#define ADMIN_PUNISHMENT_CLUWNE "Cluwne" -#define ADMIN_PUNISHMENT_GOODBYE "Their final message" //sandstorm - #define AHELP_ACTIVE 1 #define AHELP_CLOSED 2 #define AHELP_RESOLVED 3 diff --git a/code/_globalvars/lists/admin.dm b/code/_globalvars/lists/admin.dm new file mode 100644 index 0000000000..9ee6ab6208 --- /dev/null +++ b/code/_globalvars/lists/admin.dm @@ -0,0 +1,8 @@ +/proc/init_smites() + var/list/smites = list() + for (var/_smite_path in subtypesof(/datum/smite)) + var/datum/smite/smite_path = _smite_path + smites[initial(smite_path.name)] = smite_path + return smites + +GLOBAL_LIST_INIT_TYPED(smites, /datum/smite, init_smites()) diff --git a/code/datums/brain_damage/phobia.dm b/code/datums/brain_damage/phobia.dm index 10c217c6a9..4dbe2d507a 100644 --- a/code/datums/brain_damage/phobia.dm +++ b/code/datums/brain_damage/phobia.dm @@ -213,3 +213,7 @@ /datum/brain_trauma/mild/phobia/conspiracies phobia_type = "conspiracies" random_gain = FALSE + +/datum/brain_trauma/mild/phobia/ocky_icky + phobia_type = "ocky icky" + random_gain = FALSE diff --git a/code/datums/components/admin_popup.dm b/code/datums/components/admin_popup.dm index ae7855e850..0542dd1a0c 100644 --- a/code/datums/components/admin_popup.dm +++ b/code/datums/components/admin_popup.dm @@ -64,8 +64,8 @@ layer = ADMIN_POPUP_LAYER mouse_opacity = MOUSE_OPACITY_TRANSPARENT screen_loc = "TOP-5,LEFT" - maptext_height = 720 - maptext_width = 720 + maptext_height = 480 + maptext_width = 480 maptext = "" var/static/list/colors = list( diff --git a/code/modules/admin/smites/berforate.dm b/code/modules/admin/smites/berforate.dm new file mode 100644 index 0000000000..b8b4e2f8c7 --- /dev/null +++ b/code/modules/admin/smites/berforate.dm @@ -0,0 +1,46 @@ +/// Fires an absurd amount of bullets at the target +/datum/smite/berforate + name = ":B:erforate" + /// Determines how fucked the target is + var/hatred +/datum/smite/berforate/configure(client/user) + var/static/list/how_fucked_is_this_dude = list("A little", "A lot", "So fucking much", "FUCK THIS DUDE") + hatred = input(user, "How much do you hate this guy?") in how_fucked_is_this_dude +/datum/smite/berforate/effect(client/user, mob/living/target) + . = ..() + if (!iscarbon(target)) + to_chat(user, "This must be used on a carbon mob.", confidential = TRUE) + return + var/repetitions + var/shots_per_limb_per_rep = 2 + var/damage + switch (hatred) + if ("A little") + repetitions = 1 + damage = 5 + if ("A lot") + repetitions = 2 + damage = 8 + if ("So fucking much") + repetitions = 3 + damage = 10 + if ("FUCK THIS DUDE") + repetitions = 4 + damage = 10 + var/mob/living/carbon/dude = target + var/list/open_adj_turfs = get_adjacent_open_turfs(dude) + var/list/wound_bonuses = list(15, 70, 110, 250) + var/delay_per_shot = 1 + var/delay_counter = 1 + dude.Immobilize(5 SECONDS) + for (var/wound_bonus_rep in 1 to repetitions) + for (var/_limb in dude.bodyparts) + var/obj/item/bodypart/limb = _limb + var/shots_this_limb = 0 + for (var/_iter_turf in shuffle(open_adj_turfs)) + var/turf/iter_turf = _iter_turf + addtimer(CALLBACK(GLOBAL_PROC, .proc/firing_squad, dude, iter_turf, limb.body_zone, wound_bonuses[wound_bonus_rep], damage), delay_counter) + delay_counter += delay_per_shot + shots_this_limb += 1 + if (shots_this_limb > shots_per_limb_per_rep) + break diff --git a/code/modules/admin/smites/bloodless.dm b/code/modules/admin/smites/bloodless.dm new file mode 100644 index 0000000000..68b67e7c13 --- /dev/null +++ b/code/modules/admin/smites/bloodless.dm @@ -0,0 +1,17 @@ +/// Slashes up the target +/datum/smite/bloodless + name = ":B:loodless" +/datum/smite/bloodless/effect(client/user, mob/living/target) + . = ..() + if(!iscarbon(target)) + to_chat(usr,"This must be used on a carbon mob.", confidential = TRUE) + return + var/mob/living/carbon/carbon_target = target + for(var/_limb in carbon_target.bodyparts) + var/obj/item/bodypart/limb = _limb + var/type_wound = pick(list(/datum/wound/slash/severe, /datum/wound/slash/moderate)) + limb.force_wound_upwards(type_wound, smited = TRUE) + type_wound = pick(list(/datum/wound/slash/critical, /datum/wound/slash/severe, /datum/wound/slash/moderate)) + limb.force_wound_upwards(type_wound, smited = TRUE) + type_wound = pick(list(/datum/wound/slash/critical, /datum/wound/slash/severe)) + limb.force_wound_upwards(type_wound, smited = TRUE) diff --git a/code/modules/admin/smites/boneless.dm b/code/modules/admin/smites/boneless.dm new file mode 100644 index 0000000000..6d35508f39 --- /dev/null +++ b/code/modules/admin/smites/boneless.dm @@ -0,0 +1,13 @@ +/// Gives the target critically bad wounds +/datum/smite/boneless + name = ":B:oneless" +/datum/smite/boneless/effect(client/user, mob/living/target) + . = ..() + if (!iscarbon(target)) + to_chat(user, "This must be used on a carbon mob.", confidential = TRUE) + return + var/mob/living/carbon/carbon_target = target + for(var/_limb in carbon_target.bodyparts) + var/obj/item/bodypart/limb = _limb + var/type_wound = pick(list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate)) + limb.force_wound_upwards(type_wound, smited = TRUE) diff --git a/code/modules/admin/smites/bonk.dm b/code/modules/admin/smites/bonk.dm new file mode 100644 index 0000000000..9921f21a7f --- /dev/null +++ b/code/modules/admin/smites/bonk.dm @@ -0,0 +1,9 @@ +/// Bonks the target +/datum/smite/bonk + name = "Bonk" + +/datum/smite/bonk/effect(client/user, mob/living/target) + . = ..() + playsound(target, 'modular_splurt/sound/misc/bonk.ogg', 100, 1) + target.AddElement(/datum/element/squish, 60 SECONDS) + to_chat(target, "Bonk.") diff --git a/code/modules/admin/smites/bookify.dm b/code/modules/admin/smites/bookify.dm new file mode 100644 index 0000000000..eba95af538 --- /dev/null +++ b/code/modules/admin/smites/bookify.dm @@ -0,0 +1,13 @@ +#define BOOKIFY_TIME (2 SECONDS) +/// Turns the target into a book +/datum/smite/bookify + name = "Bookify" + +/datum/smite/bookify/effect(client/user, mob/living/carbon/human/target as mob) + . = ..() + var/mutable_appearance/book_appearance = mutable_appearance('icons/obj/library.dmi', "book") + var/mutable_appearance/transform_scanline = mutable_appearance('modular_splurt/icons/effects/effects.dmi', "transform_effect") + target.transformation_animation(book_appearance, time = BOOKIFY_TIME, transform_overlay=transform_scanline, reset_after=TRUE) + addtimer(CALLBACK(GLOBAL_PROC, .proc/bookify, target), BOOKIFY_TIME) + playsound(target, 'modular_splurt/sound/misc/bookify.ogg', 60, 1) +#undef BOOKIFY_TIME diff --git a/code/modules/admin/smites/brain_damage.dm b/code/modules/admin/smites/brain_damage.dm new file mode 100644 index 0000000000..ce7d6ae478 --- /dev/null +++ b/code/modules/admin/smites/brain_damage.dm @@ -0,0 +1,6 @@ +/// Inflicts crippling brain damage on the target +/datum/smite/brain_damage + name = "Brain damage" +/datum/smite/brain_damage/effect(client/user, mob/living/target) + . = ..() + target.adjustOrganLoss(ORGAN_SLOT_BRAIN, BRAIN_DAMAGE_DEATH - 1, BRAIN_DAMAGE_DEATH - 1) diff --git a/code/modules/admin/smites/bread.dm b/code/modules/admin/smites/bread.dm new file mode 100644 index 0000000000..2bdd34155e --- /dev/null +++ b/code/modules/admin/smites/bread.dm @@ -0,0 +1,14 @@ +#define BREADIFY_TIME (5 SECONDS) + +/// Turns the target into bread +/datum/smite/bread + name = "Bread" + +/datum/smite/bread/effect(client/user, mob/living/target) + . = ..() + var/mutable_appearance/bread_appearance = mutable_appearance('icons/obj/food/burgerbread.dmi', "bread") + var/mutable_appearance/transform_scanline = mutable_appearance('icons/effects/effects.dmi', "transform_effect") + target.transformation_animation(bread_appearance,time = BREADIFY_TIME, transform_overlay=transform_scanline, reset_after=TRUE) + addtimer(CALLBACK(GLOBAL_PROC, .proc/breadify, target), BREADIFY_TIME) + +#undef BREADIFY_TIME diff --git a/code/modules/admin/smites/bsa.dm b/code/modules/admin/smites/bsa.dm new file mode 100644 index 0000000000..fa89af32e7 --- /dev/null +++ b/code/modules/admin/smites/bsa.dm @@ -0,0 +1,32 @@ +#define BSA_CHANCE_TO_BREAK_TILE_TO_PLATING 80 +#define BSA_MAX_DAMAGE 99 +#define BSA_PARALYZE_TIME (40 SECONDS) +#define BSA_STUTTER_TIME (40 SECONDS) + +/// Fires the BSA at the target +/datum/smite/bsa + name = "Bluespace Artillery Device" + +/datum/smite/bsa/effect(client/user, mob/living/target) + . = ..() + + explosion(target.loc, 0, 0, 0, 0) + + var/turf/open/floor/target_turf = get_turf(target) + if (istype(target_turf)) + if (prob(BSA_CHANCE_TO_BREAK_TILE_TO_PLATING)) + target_turf.break_tile_to_plating() + else + target_turf.break_tile() + + if (target.health <= 1) + target.gib(1, 1) + else + target.adjustBruteLoss(min(BSA_MAX_DAMAGE, target.health - 1)) + target.DefaultCombatKnockdown(BSA_PARALYZE_TIME) + target.stuttering = 20 + +#undef BSA_CHANCE_TO_BREAK_TILE_TO_PLATING +#undef BSA_MAX_DAMAGE +#undef BSA_PARALYZE_TIME +#undef BSA_STUTTER_TIME diff --git a/code/modules/admin/smites/cluwne.dm b/code/modules/admin/smites/cluwne.dm new file mode 100644 index 0000000000..a097a0f16a --- /dev/null +++ b/code/modules/admin/smites/cluwne.dm @@ -0,0 +1,10 @@ +/// Cluwneifies the target +/datum/smite/cluwne + name = "Cluwne" + +/datum/smite/cluwne/effect(client/user, mob/living/carbon/human/target as mob) + . = ..() + if(!iscarbon(target)) + to_chat(usr,"This must be used on a carbon mob.") + return + target.cluwneify() diff --git a/code/modules/admin/smites/custompie.dm b/code/modules/admin/smites/custompie.dm new file mode 100644 index 0000000000..890907ecfc --- /dev/null +++ b/code/modules/admin/smites/custompie.dm @@ -0,0 +1,18 @@ +/// Throws a custom pie at the target +/datum/smite/custompie + name = "Custom Pie" + +/datum/smite/custompie/effect(client/user, mob/living/target) + . = ..() + var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/A = new() + if(!A.reagents) + var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num|null + if(amount) + A.create_reagents(amount) + if(A.reagents) + var/chosen_id = choose_reagent_id(usr) + if(chosen_id) + var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num|null + if(amount) + A.reagents.add_reagent(chosen_id, amount) + A.splat(target) diff --git a/code/modules/admin/smites/dock_pay.dm b/code/modules/admin/smites/dock_pay.dm new file mode 100644 index 0000000000..0ce91bbd4b --- /dev/null +++ b/code/modules/admin/smites/dock_pay.dm @@ -0,0 +1,31 @@ +/// Docks the target's pay +/datum/smite/dock_pay + name = "Dock Pay" + +/datum/smite/dock_pay/effect(client/user, mob/living/target) + . = ..() + if (!iscarbon(target)) + to_chat(user, span_warning("This must be used on a carbon mob."), confidential = TRUE) + return + var/mob/living/carbon/dude = target + var/obj/item/card/id/card = dude.get_idcard(TRUE) + if (!card) + to_chat(user, span_warning("[dude] does not have an ID card on!"), confidential = TRUE) + return + if (!card.registered_account) + to_chat(user, span_warning("[dude] does not have an ID card with an account!"), confidential = TRUE) + return + if (card.registered_account.account_balance == 0) + to_chat(user, span_warning("ID Card lacks any funds. No pay to dock.")) + return + var/new_cost = input("How much pay are we docking? Current balance: [card.registered_account.account_balance] credits.", "BUDGET CUTS") as num|null + if (!new_cost) + return + if (!(card.registered_account.has_money(new_cost))) + to_chat(user, span_warning("ID Card lacked funds. Emptying account.")) + card.registered_account.bank_card_talk("[new_cost] credits deducted from your account based on performance review.") + card.registered_account.account_balance = 0 + else + card.registered_account.account_balance = card.registered_account.account_balance - new_cost + card.registered_account.bank_card_talk("[new_cost] credits deducted from your account based on performance review.") + SEND_SOUND(target, 'sound/machines/buzz-sigh.ogg') diff --git a/code/modules/admin/smites/fake_bwoink.dm b/code/modules/admin/smites/fake_bwoink.dm new file mode 100644 index 0000000000..a4179ff5ce --- /dev/null +++ b/code/modules/admin/smites/fake_bwoink.dm @@ -0,0 +1,7 @@ +/// Sends the target a fake adminhelp sound +/datum/smite/fake_bwoink + name = "Fake bwoink" + +/datum/smite/fake_bwoink/effect(client/user, mob/living/target) + . = ..() + SEND_SOUND(target, 'sound/effects/adminhelp.ogg') diff --git a/code/modules/admin/smites/finalmessage.dm b/code/modules/admin/smites/finalmessage.dm new file mode 100644 index 0000000000..b5fdbfeb0b --- /dev/null +++ b/code/modules/admin/smites/finalmessage.dm @@ -0,0 +1,12 @@ +/// Their Final Message +/datum/smite/finalmessage + name = "Final Message" + +/datum/smite/finalmessage/effect(client/user, mob/living/target) + . = ..() + var/mob/living/C = target + if(C.stat == DEAD) + to_chat(usr, "[C] is dead!") + return + else + C.goodbye() diff --git a/code/modules/admin/smites/fireball.dm b/code/modules/admin/smites/fireball.dm new file mode 100644 index 0000000000..98dad65d82 --- /dev/null +++ b/code/modules/admin/smites/fireball.dm @@ -0,0 +1,7 @@ +/// Throws a fireball down at the target +/datum/smite/fireball + name = "Fireball" + +/datum/smite/fireball/effect(client/user, mob/living/target) + . = ..() + new /obj/effect/temp_visual/target(get_turf(target)) diff --git a/code/modules/admin/smites/fry.dm b/code/modules/admin/smites/fry.dm new file mode 100644 index 0000000000..66a4100f10 --- /dev/null +++ b/code/modules/admin/smites/fry.dm @@ -0,0 +1,7 @@ +/// Fry the target +/datum/smite/fry + name = "Fry" + +/datum/smite/fry/effect(client/user, mob/living/target) + . = ..() + target.fry() diff --git a/code/modules/admin/smites/gib.dm b/code/modules/admin/smites/gib.dm new file mode 100644 index 0000000000..37f1e1c8b4 --- /dev/null +++ b/code/modules/admin/smites/gib.dm @@ -0,0 +1,7 @@ +/// Gibs the target +/datum/smite/gib + name = "Gib" + +/datum/smite/gib/effect(client/user, mob/living/target) + . = ..() + target.gib(FALSE) diff --git a/code/modules/admin/smites/immerse.dm b/code/modules/admin/smites/immerse.dm new file mode 100644 index 0000000000..5d6ca24455 --- /dev/null +++ b/code/modules/admin/smites/immerse.dm @@ -0,0 +1,10 @@ +/// "Fully immerses" the player, making them manually breathe and blink +/*/datum/smite/immerse + name = "Fully Immerse" + +/datum/smite/immerse/effect(client/user, mob/living/target) + . = ..() + immerse_player(target) + SEND_SOUND(target, sound('sound/misc/roleplay.ogg')) + to_chat(target, span_boldnotice("Please roleplay appropriately, okay?")) +*/ diff --git a/code/modules/admin/smites/knot_shoes.dm b/code/modules/admin/smites/knot_shoes.dm new file mode 100644 index 0000000000..057dbd7436 --- /dev/null +++ b/code/modules/admin/smites/knot_shoes.dm @@ -0,0 +1,15 @@ +/// Ties the target's shoes +/datum/smite/knot_shoes + name = "Knot Shoes" + +/datum/smite/knot_shoes/effect(client/user, mob/living/target) + . = ..() + if (!iscarbon(target)) + to_chat(user, span_warning("This must be used on a carbon mob."), confidential = TRUE) + return + var/mob/living/carbon/dude = target + var/obj/item/clothing/shoes/sick_kicks = dude.shoes + if (!sick_kicks?.can_be_tied) + to_chat(user, span_warning("[dude] does not have knottable shoes!"), confidential = TRUE) + return + sick_kicks.adjust_laces(SHOES_KNOTTED) diff --git a/code/modules/admin/smites/lightning.dm b/code/modules/admin/smites/lightning.dm new file mode 100644 index 0000000000..d7e3ce5627 --- /dev/null +++ b/code/modules/admin/smites/lightning.dm @@ -0,0 +1,17 @@ +/// Strikes the target with a lightning bolt +/*/datum/smite/lightning + name = "Lightning bolt" + +/datum/smite/lightning/effect(client/user, mob/living/carbon/human/target as mob) + . = ..() + if(prob(75)) + playsound(target, 'modular_splurt/sound/misc/NOW.ogg', 75, FALSE) + sleep(4 SECONDS) + var/turf/T = get_step(get_step(user, NORTH), NORTH) + T.Beam(target, icon_state="lightning[rand(1,12)]", time = 5) + target.adjustFireLoss(75) + target.electrocution_animation(40) + to_chat(target, "The gods have punished you for your sins!") +*/ + +//BROKEN!!! FIX LATER!! diff --git a/code/modules/admin/smites/nugget.dm b/code/modules/admin/smites/nugget.dm new file mode 100644 index 0000000000..86fd9af9cf --- /dev/null +++ b/code/modules/admin/smites/nugget.dm @@ -0,0 +1,21 @@ +/// Rips off all the limbs of the target +/datum/smite/nugget + name = "Nugget" + +/datum/smite/nugget/effect(client/user, mob/living/target) + . = ..() + + if (!iscarbon(target)) + to_chat(user, span_warning("This must be used on a carbon mob."), confidential = TRUE) + return + + var/mob/living/carbon/carbon_target = target + var/timer = 2 SECONDS + for (var/_limb in carbon_target.bodyparts) + var/obj/item/bodypart/limb = _limb + if (limb.body_part == HEAD || limb.body_part == CHEST) + continue + addtimer(CALLBACK(limb, TYPE_PROC_REF(/obj/item/bodypart/, dismember)), timer) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), carbon_target, 'modular_splurt/sound/effects/cartoon_pop.ogg', 70), timer) + addtimer(CALLBACK(carbon_target, TYPE_PROC_REF(/mob/living/, spin), 4, 1), timer - 0.4 SECONDS) + timer += 2 SECONDS diff --git a/code/modules/admin/smites/pickle.dm b/code/modules/admin/smites/pickle.dm new file mode 100644 index 0000000000..18e370e535 --- /dev/null +++ b/code/modules/admin/smites/pickle.dm @@ -0,0 +1,7 @@ +/// Turns the target into a pickle +/datum/smite/pickle + name = "Pickle" + +/datum/smite/pickle/effect(client/user, mob/living/target) + . = ..() + target.turn_into_pickle() diff --git a/code/modules/admin/smites/pie.dm b/code/modules/admin/smites/pie.dm new file mode 100644 index 0000000000..d21a891dde --- /dev/null +++ b/code/modules/admin/smites/pie.dm @@ -0,0 +1,8 @@ +/// Throws a pie at the target +/datum/smite/pie + name = "Pie" + +/datum/smite/pie/effect(client/user, mob/living/target) + . = ..() + var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/creamy = new(get_turf(target)) + creamy.splat(target) diff --git a/code/modules/admin/smites/puzzle.dm b/code/modules/admin/smites/puzzle.dm new file mode 100644 index 0000000000..ffaee14412 --- /dev/null +++ b/code/modules/admin/smites/puzzle.dm @@ -0,0 +1,8 @@ +/// Turns the user into a sliding puzzle +/datum/smite/puzzle + name = "Puzzle" + +/datum/smite/puzzle/effect(client/user, mob/living/target) + . = ..() + if(!puzzle_imprison(target)) + to_chat(user, "Imprisonment failed!", confidential = TRUE) diff --git a/code/modules/admin/smites/rod.dm b/code/modules/admin/smites/rod.dm new file mode 100644 index 0000000000..8598258e36 --- /dev/null +++ b/code/modules/admin/smites/rod.dm @@ -0,0 +1,17 @@ +/// Throw an immovable rod at the target +/datum/smite/rod + name = "Immovable Rod" + var/force_looping = FALSE + +/datum/smite/rod/configure(client/user) + var/loop_input = tgui_alert(usr,"Would you like this rod to force-loop across space z-levels?", "Loopy McLoopface", list("Yes", "No")) + + force_looping = (loop_input == "Yes") + +/datum/smite/rod/effect(client/user, mob/living/target) + . = ..() + var/turf/target_turf = get_turf(target) + var/startside = pick(GLOB.cardinals) + var/turf/start_turf = spaceDebrisStartLoc(startside, target_turf.z) + var/turf/end_turf = spaceDebrisFinishLoc(startside, target_turf.z) + new /obj/effect/immovablerod(start_turf, end_turf, target, force_looping) diff --git a/code/modules/admin/smites/scarify.dm b/code/modules/admin/smites/scarify.dm new file mode 100644 index 0000000000..fcbe2062e8 --- /dev/null +++ b/code/modules/admin/smites/scarify.dm @@ -0,0 +1,12 @@ +/// Gives the target fake scars +/datum/smite/scarify + name = "Scarify" + +/datum/smite/scarify/effect(client/user, mob/living/target) + . = ..() + if(!iscarbon(target)) + to_chat(user, span_warning("This must be used on a carbon mob."), confidential = TRUE) + return + var/mob/living/carbon/dude = target + dude.generate_fake_scars(rand(1, 4)) + to_chat(dude, span_warning("You feel your body grow jaded and torn...")) diff --git a/code/modules/admin/smites/shoes.dm b/code/modules/admin/smites/shoes.dm new file mode 100644 index 0000000000..ff74e50943 --- /dev/null +++ b/code/modules/admin/smites/shoes.dm @@ -0,0 +1,15 @@ +/// Ties the target's shoes +/datum/smite/shoes + name = "Knot Shoes" + +/datum/smite/shoes/effect(client/user, mob/living/target) + . = ..() + if(!iscarbon(target)) + to_chat(usr,"This must be used on a carbon mob.") + return + var/mob/living/carbon/C = target + var/obj/item/clothing/shoes/sick_kicks = C.shoes + if(!sick_kicks?.can_be_tied) + to_chat(usr,"[C] does not have knottable shoes!") + return + sick_kicks.adjust_laces(SHOES_KNOTTED) diff --git a/code/modules/admin/smites/smite.dm b/code/modules/admin/smites/smite.dm new file mode 100644 index 0000000000..b767f47f8f --- /dev/null +++ b/code/modules/admin/smites/smite.dm @@ -0,0 +1,17 @@ +/// A smite, used by admins to punish players, or for their own amusement +/datum/smite + /// The name of the smite, shown in the menu + var/name + + /// Should this smite write to logs? + var/should_log = TRUE + +/// Called once after either choosing the option to smite a player, or when selected in smite build mode. +/// Use this to prompt the user configuration options. +/// Return FALSE if the smite should not be used. +/datum/smite/proc/configure(client/user) + +/// The effect of the smite, make sure to call this in your own smites +/datum/smite/proc/effect(client/user, mob/living/target) + if (should_log) + user.punish_log(target, name) diff --git a/code/modules/admin/smites/supply_pod.dm b/code/modules/admin/smites/supply_pod.dm new file mode 100644 index 0000000000..187507e9bb --- /dev/null +++ b/code/modules/admin/smites/supply_pod.dm @@ -0,0 +1,21 @@ +#define SUPPLY_POD_FIRE_RANGE + +/// Throws a supply pod at the target, with no item inside +/datum/smite/supply_pod + name = "Supply Pod" + + // punish_log() is handled by the centcom_podlauncher datum + should_log = FALSE + +/datum/smite/supply_pod/effect(client/user, mob/living/target) + . = ..() + var/datum/centcom_podlauncher/plaunch = new(user) + plaunch.specificTarget = target + plaunch.launchChoice = 0 + plaunch.damageChoice = 1 + plaunch.explosionChoice = 1 + plaunch.temp_pod.damage = 40 // bring the mother fuckin ruckus + plaunch.temp_pod.explosionSize = list(0, 0, 0, SUPPLY_POD_FIRE_RANGE) + plaunch.temp_pod.effectStun = TRUE + +#undef SUPPLY_POD_FIRE_RANGE diff --git a/code/modules/admin/smites/supply_pod_quick.dm b/code/modules/admin/smites/supply_pod_quick.dm new file mode 100644 index 0000000000..ccb04d47ce --- /dev/null +++ b/code/modules/admin/smites/supply_pod_quick.dm @@ -0,0 +1,49 @@ +#define SUPPLY_POD_QUICK_DAMAGE 40 +#define SUPPLY_POD_QUICK_FIRE_RANGE 2 + +/// Quickly throws a supply pod at the target, optionally with an item +/datum/smite/supply_pod_quick + name = "Supply Pod (Quick)" + + /// What is sent down with the pod + var/target_path + +/datum/smite/supply_pod_quick/configure(client/user) + var/attempted_target_path = input( + user, + "Enter typepath of an atom you'd like to send with the pod (type \"empty\" to send an empty pod):", + "Typepath", + "/obj/item/reagent_containers/food/snacks/grown/harebell", + ) as null|text + if (isnull(attempted_target_path)) //The user pressed "Cancel" + return FALSE + + if (attempted_target_path == "empty") + target_path = null + return + + // if you didn't type empty, we want to load the pod with a delivery + var/delivery = text2path(attempted_target_path) + if(!ispath(delivery)) + delivery = pick_closest_path(attempted_target_path) + if(!delivery) + alert(user, "ERROR: Incorrect / improper path given.") + return FALSE + target_path = delivery + +/datum/smite/supply_pod_quick/effect(client/user, mob/living/target) + . = ..() + + var/area/pod_storage_area = locate(/area/centcom/supplypod/podStorage) in GLOB.sortedAreas + var/obj/structure/closet/supplypod/centcompod/pod = new(pick(get_area_turfs(pod_storage_area))) + pod.damage = SUPPLY_POD_QUICK_DAMAGE + pod.explosionSize = list(0, 0, 0, SUPPLY_POD_QUICK_FIRE_RANGE) + pod.effectStun = TRUE + + if (!isnull(target_path)) + new target_path(pod) + + new /obj/effect/pod_landingzone(get_turf(target), pod) + +#undef SUPPLY_POD_QUICK_DAMAGE +#undef SUPPLY_POD_QUICK_FIRE_RANGE diff --git a/code/modules/admin/smites/tabletide.dm b/code/modules/admin/smites/tabletide.dm new file mode 100644 index 0000000000..a2c3425840 --- /dev/null +++ b/code/modules/admin/smites/tabletide.dm @@ -0,0 +1,16 @@ +/// Tableslam the target +/datum/smite/tabletide + name = "Table Tideslam" + +/datum/smite/tabletide/effect(client/user, mob/living/target) + . = ..() + priority_announce(html_decode("[target] has brought the wrath of the gods upon themselves and is now being tableslammed across the station. Please stand by."), null, 'sound/misc/announce.ogg', "CentCom") + var/list/areas = list() + for(var/area/A in world) + if(A.z == SSmapping.station_start) + areas += A + SEND_SOUND(target, sound('modular_splurt/sound/misc/slamofthenorthstar.ogg',volume=60)) + for(var/area/A in areas) + for(var/obj/structure/table/T in A) + T.tablepush(target, target) + sleep(1) diff --git a/code/modules/admin/verbs/bluespacearty.dm b/code/modules/admin/verbs/bluespacearty.dm deleted file mode 100644 index 23fff5ece9..0000000000 --- a/code/modules/admin/verbs/bluespacearty.dm +++ /dev/null @@ -1,26 +0,0 @@ -/client/proc/bluespace_artillery(mob/M in GLOB.mob_list) - if(!holder || !check_rights(R_FUN)) - return - - var/mob/living/target = M - - if(!isliving(target)) - to_chat(usr, "This can only be used on instances of type /mob/living", confidential = TRUE) - return - - explosion(target.loc, 0, 0, 0, 0) - - var/turf/open/floor/T = get_turf(target) - if(istype(T)) - if(prob(80)) - T.break_tile_to_plating() - else - T.break_tile() - - if(target.health <= 1) - target.gib(1, 1) - else - target.adjustBruteLoss(min(99,(target.health - 1))) - target.DefaultCombatKnockdown(400) - target.stuttering = 20 - diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 519154c597..021129bdd9 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1283,266 +1283,34 @@ Traitors and the like can also be revived with the previous role mostly intact. busy_toggling_fov = FALSE -/client/proc/smite(mob/living/carbon/human/target as mob) +/client/proc/smite(mob/living/target as mob) set name = "Smite" set category = "Admin.Fun" if(!check_rights(R_ADMIN) || !check_rights(R_FUN)) return - var/list/punishment_list = list( - ADMIN_PUNISHMENT_PIE, - ADMIN_PUNISHMENT_CUSTOM_PIE, - ADMIN_PUNISHMENT_FIREBALL, - ADMIN_PUNISHMENT_LIGHTNING, - ADMIN_PUNISHMENT_BRAINDAMAGE, - ADMIN_PUNISHMENT_BSA, - ADMIN_PUNISHMENT_GIB, - ADMIN_PUNISHMENT_SUPPLYPOD_QUICK, - ADMIN_PUNISHMENT_SUPPLYPOD, - ADMIN_PUNISHMENT_MAZING, - ADMIN_PUNISHMENT_ROD, - ADMIN_PUNISHMENT_SHOES, - ADMIN_PUNISHMENT_PICKLE, - ADMIN_PUNISHMENT_FRY, - ADMIN_PUNISHMENT_CRACK, - ADMIN_PUNISHMENT_BLEED, - ADMIN_PUNISHMENT_SCARIFY, - ADMIN_PUNISHMENT_CLUWNE, - ADMIN_PUNISHMENT_GOODBYE, - ADMIN_PUNISHMENT_TABLETIDESTATIONWIDE, - ADMIN_PUNISHMENT_FAKEBWOINK, - ADMIN_PUNISHMENT_NUGGET, - ADMIN_PUNISHMENT_BREADIFY, - ADMIN_PUNISHMENT_BOOKIFY, - ADMIN_PUNISHMENT_BONK) - var/punishment = tgui_input_list(usr, "Choose a punishment", "Divine Smiting", punishment_list) + var/punishment = tgui_input_list(usr, "Choose a punishment", "DIVINE SMITING", GLOB.smites) if(QDELETED(target) || !punishment) return - switch(punishment) - if(ADMIN_PUNISHMENT_LIGHTNING) - if(prob(75)) - playsound(target, 'modular_splurt/sound/misc/NOW.ogg', 75, FALSE) - sleep(4 SECONDS) - var/turf/T = get_step(get_step(target, NORTH), NORTH) - T.Beam(target, icon_state="lightning[rand(1,12)]", time = 5) - target.adjustFireLoss(75) - target.electrocution_animation(40) - to_chat(target, "The gods have punished you for your sins!") - if(ADMIN_PUNISHMENT_BRAINDAMAGE) - target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 199, 199) - if(ADMIN_PUNISHMENT_GIB) - target.gib(FALSE) - if(ADMIN_PUNISHMENT_BSA) - bluespace_artillery(target) - if(ADMIN_PUNISHMENT_FIREBALL) - new /obj/effect/temp_visual/target(get_turf(target)) - if(ADMIN_PUNISHMENT_ROD) - var/turf/T = get_turf(target) - var/startside = pick(GLOB.cardinals) - var/turf/startT = spaceDebrisStartLoc(startside, T.z) - var/turf/endT = spaceDebrisFinishLoc(startside, T.z) - new /obj/effect/immovablerod(startT, endT,target) - if(ADMIN_PUNISHMENT_SUPPLYPOD_QUICK) - var/target_path = input(usr,"Enter typepath of an atom you'd like to send with the pod (type \"empty\" to send an empty pod):" ,"Typepath","/obj/item/reagent_containers/food/snacks/grown/harebell") as null|text - var/area/pod_storage_area = locate(/area/centcom/supplypod/podStorage) in GLOB.sortedAreas - var/obj/structure/closet/supplypod/centcompod/pod = new(pick(get_area_turfs(pod_storage_area))) //Lets not runtime - pod.damage = 40 - pod.explosionSize = list(0,0,0,2) - pod.effectStun = TRUE - if (isnull(target_path)) //The user pressed "Cancel" - return - if (target_path != "empty")//if you didn't type empty, we want to load the pod with a delivery - var/delivery = text2path(target_path) - if(!ispath(delivery)) - delivery = pick_closest_path(target_path) - if(!delivery) - alert("ERROR: Incorrect / improper path given.") - new delivery(pod) - new /obj/effect/pod_landingzone(get_turf(target), pod) - if(ADMIN_PUNISHMENT_SUPPLYPOD) - var/datum/centcom_podlauncher/plaunch = new(usr) - if(!holder) - return - plaunch.specificTarget = target - plaunch.launchChoice = 0 - plaunch.damageChoice = 1 - plaunch.explosionChoice = 1 - plaunch.temp_pod.damage = 40//bring the mother fuckin ruckus - plaunch.temp_pod.explosionSize = list(0,0,0,2) - plaunch.temp_pod.effectStun = TRUE - return //We return here because punish_log() is handled by the centcom_podlauncher datum + var/smite_path = GLOB.smites[punishment] + var/datum/smite/smite = new smite_path + var/configuration_success = smite.configure(usr) + if (configuration_success == FALSE) + return + smite.effect(src, target) - if(ADMIN_PUNISHMENT_MAZING) - if(!puzzle_imprison(target)) - to_chat(usr,"Imprisonment failed!") - return - if(ADMIN_PUNISHMENT_PIE) - var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/creamy = new(get_turf(target)) - creamy.splat(target) - if(ADMIN_PUNISHMENT_CUSTOM_PIE) - var/obj/item/reagent_containers/food/snacks/pie/cream/nostun/A = new() - if(!A.reagents) - var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num|null - if(amount) - A.create_reagents(amount) - if(A.reagents) - var/chosen_id = choose_reagent_id(usr) - if(chosen_id) - var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num|null - if(amount) - A.reagents.add_reagent(chosen_id, amount) - A.splat(target) - if(ADMIN_PUNISHMENT_CRACK) - if(!iscarbon(target)) - to_chat(usr,"This must be used on a carbon mob.", confidential = TRUE) - return - var/mob/living/carbon/C = target - for(var/i in C.bodyparts) - var/obj/item/bodypart/squish_part = i - var/type_wound = pick(list(/datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/critical, /datum/wound/blunt/severe, /datum/wound/blunt/moderate)) - squish_part.force_wound_upwards(type_wound, smited=TRUE) - if(ADMIN_PUNISHMENT_BLEED) - if(!iscarbon(target)) - to_chat(usr,"This must be used on a carbon mob.", confidential = TRUE) - return - var/mob/living/carbon/C = target - for(var/i in C.bodyparts) - var/obj/item/bodypart/slice_part = i - var/type_wound = pick(list(/datum/wound/slash/severe, /datum/wound/slash/moderate)) - slice_part.force_wound_upwards(type_wound, smited=TRUE) - type_wound = pick(list(/datum/wound/slash/critical, /datum/wound/slash/severe, /datum/wound/slash/moderate)) - slice_part.force_wound_upwards(type_wound, smited=TRUE) - type_wound = pick(list(/datum/wound/slash/critical, /datum/wound/slash/severe)) - slice_part.force_wound_upwards(type_wound, smited=TRUE) - if(ADMIN_PUNISHMENT_SCARIFY) - if(!iscarbon(target)) - to_chat(usr,"This must be used on a carbon mob.", confidential = TRUE) - return - var/mob/living/carbon/dude = target - dude.generate_fake_scars(rand(1, 4)) - to_chat(dude, "You feel your body grow jaded and torn...") - if(ADMIN_PUNISHMENT_PERFORATE) - if(!iscarbon(target)) - to_chat(usr,"This must be used on a carbon mob.", confidential = TRUE) - return - var/list/how_fucked_is_this_dude = list("A little", "A lot", "So fucking much", "FUCK THIS DUDE") - var/hatred = input("How much do you hate this guy?") in how_fucked_is_this_dude - var/repetitions - var/shots_per_limb_per_rep = 2 - var/damage - switch(hatred) - if("A little") - repetitions = 1 - damage = 5 - if("A lot") - repetitions = 2 - - damage = 8 - if("So fucking much") - repetitions = 3 - damage = 10 - if("FUCK THIS DUDE") - repetitions = 4 - damage = 10 - - var/mob/living/carbon/dude = target - var/list/open_adj_turfs = get_adjacent_open_turfs(dude) - var/list/wound_bonuses = list(15, 70, 110, 250) - - var/delay_per_shot = 1 - var/delay_counter = 1 - - dude.Immobilize(5 SECONDS) - for(var/wound_bonus_rep in 1 to repetitions) - for(var/i in dude.bodyparts) - var/obj/item/bodypart/slice_part = i - var/shots_this_limb = 0 - for(var/t in shuffle(open_adj_turfs)) - var/turf/iter_turf = t - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(firing_squad), dude, iter_turf, slice_part.body_zone, wound_bonuses[wound_bonus_rep], damage), delay_counter) - delay_counter += delay_per_shot - shots_this_limb++ - if(shots_this_limb > shots_per_limb_per_rep) - break - if(ADMIN_PUNISHMENT_PICKLE) - target.turn_into_pickle() - if(ADMIN_PUNISHMENT_FRY) - target.fry() - - if(ADMIN_PUNISHMENT_SHOES) - if(!iscarbon(target)) - to_chat(usr,"This must be used on a carbon mob.") - return - var/mob/living/carbon/C = target - var/obj/item/clothing/shoes/sick_kicks = C.shoes - if(!sick_kicks?.can_be_tied) - to_chat(usr,"[C] does not have knottable shoes!") - return - sick_kicks.adjust_laces(SHOES_KNOTTED) - if(ADMIN_PUNISHMENT_CLUWNE) - if(!iscarbon(target)) - to_chat(usr,"This must be used on a carbon mob.") - return - target.cluwneify() - if(ADMIN_PUNISHMENT_GOODBYE) //sandstorm punish :) it starts here - var/mob/living/C = target - if(C.stat == DEAD) - to_chat(usr, "[C] is dead!") - return - else - C.goodbye() //sandstorm punish and ends here. - if(ADMIN_PUNISHMENT_TABLETIDESTATIONWIDE) //SPLURT punishments start here - priority_announce(html_decode("[target] has brought the wrath of the gods upon themselves and is now being tableslammed across the station. Please stand by."), null, 'sound/misc/announce.ogg', "CentCom") - var/list/areas = list() - for(var/area/A in world) - if(A.z == SSmapping.station_start) - areas += A - SEND_SOUND(target, sound('modular_splurt/sound/misc/slamofthenorthstar.ogg',volume=60)) - for(var/area/A in areas) - for(var/obj/structure/table/T in A) - T.tablepush(target, target) - sleep(1) - if(ADMIN_PUNISHMENT_FAKEBWOINK) - SEND_SOUND(target, 'sound/effects/adminhelp.ogg') - if(ADMIN_PUNISHMENT_NUGGET) - if (!iscarbon(target)) - return - var/mob/living/carbon/carbon_target = target - var/timer = 2 SECONDS - for (var/_limb in carbon_target.bodyparts) - var/obj/item/bodypart/limb = _limb - if (limb.body_part == HEAD || limb.body_part == CHEST) - continue - addtimer(CALLBACK(limb, TYPE_PROC_REF(/obj/item/bodypart, dismember)), timer) - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), carbon_target, 'modular_splurt/sound/effects/cartoon_pop.ogg', 70), timer) - addtimer(CALLBACK(carbon_target, TYPE_PROC_REF(/mob/living, spin), 4, 1), timer - 0.4 SECONDS) - timer += 2 SECONDS - if(ADMIN_PUNISHMENT_BREADIFY) - #define BREADIFY_TIME (5 SECONDS) - var/mutable_appearance/bread_appearance = mutable_appearance('icons/obj/food/burgerbread.dmi', "bread") - var/mutable_appearance/transform_scanline = mutable_appearance('modular_splurt/icons/effects/effects.dmi', "transform_effect") - target.transformation_animation(bread_appearance, time = BREADIFY_TIME, transform_overlay=transform_scanline, reset_after=TRUE) - addtimer(CALLBACK(src, PROC_REF(breadify), target), BREADIFY_TIME) - #undef BREADIFY_TIME - if(ADMIN_PUNISHMENT_BOOKIFY) - #define BOOKIFY_TIME (2 SECONDS) - var/mutable_appearance/book_appearance = mutable_appearance('icons/obj/library.dmi', "book") - var/mutable_appearance/transform_scanline = mutable_appearance('modular_splurt/icons/effects/effects.dmi', "transform_effect") - target.transformation_animation(book_appearance, time = BOOKIFY_TIME, transform_overlay=transform_scanline, reset_after=TRUE) - addtimer(CALLBACK(src, PROC_REF(bookify), target), BOOKIFY_TIME) - playsound(target, 'modular_splurt/sound/misc/bookify.ogg', 60, 1) - #undef BOOKIFY_TIME - if(ADMIN_PUNISHMENT_BONK) - playsound(target, 'modular_splurt/sound/misc/bonk.ogg', 100, 1) - target.AddElement(/datum/element/squish, 60 SECONDS) - to_chat(target, "Bonk.") - - punish_log(target, punishment) +/proc/breadify(atom/movable/target) + var/obj/item/reagent_containers/food/snacks/store/bread/plain/funnyBread = new(get_turf(target)) + target.forceMove(funnyBread) +/proc/bookify(atom/movable/target) + var/obj/item/reagent_containers/food/snacks/store/book/funnyBook = new(get_turf(target)) + target.forceMove(funnyBook) + funnyBook.name = "Book of " + target.name /** * firing_squad is a proc for the :B:erforate smite to shoot each individual bullet at them, so that we can add actual delays without sleep() nonsense * @@ -1569,10 +1337,10 @@ Traitors and the like can also be revived with the previous role mostly intact. divine_wrath.fire() /client/proc/punish_log(var/whom, var/punishment) - var/msg = "[key_name_admin(usr)] punished [key_name_admin(whom)] with [punishment]." + var/msg = "[key_name_admin(src)] punished [key_name_admin(whom)] with [punishment]." message_admins(msg) admin_ticket_log(whom, msg) - log_admin("[key_name(usr)] punished [key_name(whom)] with [punishment].") + log_admin("[key_name(src)] punished [key_name(whom)] with [punishment].") /client/proc/trigger_centcom_recall() if(!check_rights(R_ADMIN)) diff --git a/code/modules/buildmode/submodes/smite.dm b/code/modules/buildmode/submodes/smite.dm new file mode 100644 index 0000000000..5f5050b41f --- /dev/null +++ b/code/modules/buildmode/submodes/smite.dm @@ -0,0 +1,40 @@ +/datum/buildmode_mode/smite + key = "smite" + var/datum/smite/selected_smite + +/datum/buildmode_mode/smite/Destroy() + selected_smite = null + return ..() + +/datum/buildmode_mode/smite/show_help(client/user) + to_chat(user, "***********************************************************\n\ + Right Mouse Button on buildmode button = Select smite to use.\n\ + Left Mouse Button on mob/living = Smite the mob.\n\ + ***********************************************************") + +/datum/buildmode_mode/smite/change_settings(client/user) + var/punishment = input(user, "Choose a punishment", "DIVINE SMITING") as null|anything in GLOB.smites + var/smite_path = GLOB.smites[punishment] + var/datum/smite/picking_smite = new smite_path + var/configuration_success = picking_smite.configure(user) + if (configuration_success == FALSE) + return + selected_smite = picking_smite + +/datum/buildmode_mode/smite/handle_click(client/user, params_string, object) + var/list/params = params2list(params_string) + + if (!check_rights(R_ADMIN | R_FUN)) + return + + if (!params.Find("left")) + return + + if (!isliving(object)) + return + + if (selected_smite == null) + to_chat(user, "No smite selected.") + return + + selected_smite.effect(user, object) diff --git a/icons/misc/buildmode.dmi b/icons/misc/buildmode.dmi index f0de428b6c55b37d8ad59cac0e9e5064e2d64ad7..45ff81ba2de91875943a1288ba391844ea92a73d 100644 GIT binary patch delta 2746 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 T?+b1H00000NkvXXu0mjfA2T@6 diff --git a/modular_splurt/code/modules/admin/verbs/randomverbs.dm b/modular_splurt/code/modules/admin/verbs/randomverbs.dm index a0c81e3f19..157cb66883 100644 --- a/modular_splurt/code/modules/admin/verbs/randomverbs.dm +++ b/modular_splurt/code/modules/admin/verbs/randomverbs.dm @@ -1,12 +1,3 @@ -/client/proc/breadify(atom/movable/target) - var/obj/item/reagent_containers/food/snacks/store/bread/plain/funnyBread = new(get_turf(target)) - target.forceMove(funnyBread) - -/client/proc/bookify(atom/movable/target) - var/obj/item/reagent_containers/food/snacks/store/book/funnyBook = new(get_turf(target)) - target.forceMove(funnyBook) - funnyBook.name = "Book of " + target.name - /client/proc/cmd_admin_subtle_headset_message(mob/M, sender = null) if(!ismob(M)) return diff --git a/tgstation.dme b/tgstation.dme index 9d2a19e884..4a670f0e7c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -318,6 +318,7 @@ #include "code\_globalvars\tgui.dm" #include "code\_globalvars\traits.dm" #include "code\_globalvars\lists\achievements.dm" +#include "code\_globalvars\lists\admin.dm" #include "code\_globalvars\lists\client.dm" #include "code\_globalvars\lists\flavor_misc.dm" #include "code\_globalvars\lists\keybindings.dm" @@ -1580,13 +1581,42 @@ #include "code\modules\admin\whitelist.dm" #include "code\modules\admin\callproc\callproc.dm" #include "code\modules\admin\DB_ban\functions.dm" +#include "code\modules\admin\smites\berforate.dm" +#include "code\modules\admin\smites\bloodless.dm" +#include "code\modules\admin\smites\boneless.dm" +#include "code\modules\admin\smites\bonk.dm" +#include "code\modules\admin\smites\bookify.dm" +#include "code\modules\admin\smites\brain_damage.dm" +#include "code\modules\admin\smites\bread.dm" +#include "code\modules\admin\smites\bsa.dm" +#include "code\modules\admin\smites\cluwne.dm" +#include "code\modules\admin\smites\custompie.dm" +#include "code\modules\admin\smites\dock_pay.dm" +#include "code\modules\admin\smites\fake_bwoink.dm" +#include "code\modules\admin\smites\finalmessage.dm" +#include "code\modules\admin\smites\fireball.dm" +#include "code\modules\admin\smites\fry.dm" +#include "code\modules\admin\smites\gib.dm" +#include "code\modules\admin\smites\immerse.dm" +#include "code\modules\admin\smites\knot_shoes.dm" +#include "code\modules\admin\smites\lightning.dm" +#include "code\modules\admin\smites\nugget.dm" +#include "code\modules\admin\smites\pickle.dm" +#include "code\modules\admin\smites\pie.dm" +#include "code\modules\admin\smites\puzzle.dm" +#include "code\modules\admin\smites\rod.dm" +#include "code\modules\admin\smites\scarify.dm" +#include "code\modules\admin\smites\shoes.dm" +#include "code\modules\admin\smites\smite.dm" +#include "code\modules\admin\smites\supply_pod.dm" +#include "code\modules\admin\smites\supply_pod_quick.dm" +#include "code\modules\admin\smites\tabletide.dm" #include "code\modules\admin\verbs\adminhelp.dm" #include "code\modules\admin\verbs\adminjump.dm" #include "code\modules\admin\verbs\adminpm.dm" #include "code\modules\admin\verbs\adminsay.dm" #include "code\modules\admin\verbs\ak47s.dm" #include "code\modules\admin\verbs\atmosdebug.dm" -#include "code\modules\admin\verbs\bluespacearty.dm" #include "code\modules\admin\verbs\borgpanel.dm" #include "code\modules\admin\verbs\BrokenInhands.dm" #include "code\modules\admin\verbs\cinematic.dm" @@ -2073,6 +2103,7 @@ #include "code\modules\buildmode\submodes\fill.dm" #include "code\modules\buildmode\submodes\mapgen.dm" #include "code\modules\buildmode\submodes\save_area.dm" +#include "code\modules\buildmode\submodes\smite.dm" #include "code\modules\buildmode\submodes\throwing.dm" #include "code\modules\buildmode\submodes\variable_edit.dm" #include "code\modules\cargo\bounty.dm" From df41f4cb068d51aa5115217d0ec9c3164a3a47ad Mon Sep 17 00:00:00 2001 From: Cyfause Date: Tue, 8 Oct 2024 13:06:35 -0400 Subject: [PATCH 03/14] anthro facial hair fix --- .../mob/living/carbon/human/species_types/anthropomorph.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm b/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm index c9af50de9d..d63f4e8af7 100644 --- a/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm +++ b/code/modules/mob/living/carbon/human/species_types/anthropomorph.dm @@ -2,7 +2,7 @@ name = "Anthropomorph" id = SPECIES_MAMMAL default_color = "4B4B4B" - species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR,HAS_FLESH,HAS_BONE) + species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,FACEHAIR,HORNCOLOR,WINGCOLOR,HAS_FLESH,HAS_BONE) inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BEAST mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None", "mam_body_markings" = list(), "taur" = "None", "horns" = "None", "legs" = "Plantigrade", "meat_type" = "Mammalian") From 3e4f8da97c2a48339477b4179ea2c92f7839b77b Mon Sep 17 00:00:00 2001 From: Sim Date: Tue, 8 Oct 2024 15:06:28 -0300 Subject: [PATCH 04/14] [Port] The Ocky Icky Phobia from tgstation/tgstation#57450 & tgstation/tgstation#80247 --- code/controllers/subsystem/traumas.dm | 3 +- code/modules/admin/smites/bread.dm | 2 +- code/modules/admin/smites/phobia_ocky_icky.dm | 8 +++ strings/phobia.json | 60 ++++++++++++++++++- tgstation.dme | 1 + 5 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 code/modules/admin/smites/phobia_ocky_icky.dm diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm index 529f9dee5c..2725a71eeb 100644 --- a/code/controllers/subsystem/traumas.dm +++ b/code/controllers/subsystem/traumas.dm @@ -39,7 +39,8 @@ SUBSYSTEM_DEF(traumas) "mimes" = strings(PHOBIA_FILE, "mimes"), "cats" = strings(PHOBIA_FILE, "cats"), "syndicate"= strings(PHOBIA_FILE, "syndicate"), - "eye" = strings(PHOBIA_FILE, "eye") + "eye" = strings(PHOBIA_FILE, "eye"), + "ocky icky" = strings(PHOBIA_FILE, "ocky icky") ) phobia_mobs = list("spiders" = typecacheof(list(/mob/living/simple_animal/hostile/poison/giant_spider)), diff --git a/code/modules/admin/smites/bread.dm b/code/modules/admin/smites/bread.dm index 2bdd34155e..a92c5c8e27 100644 --- a/code/modules/admin/smites/bread.dm +++ b/code/modules/admin/smites/bread.dm @@ -7,7 +7,7 @@ /datum/smite/bread/effect(client/user, mob/living/target) . = ..() var/mutable_appearance/bread_appearance = mutable_appearance('icons/obj/food/burgerbread.dmi', "bread") - var/mutable_appearance/transform_scanline = mutable_appearance('icons/effects/effects.dmi', "transform_effect") + var/mutable_appearance/transform_scanline = mutable_appearance('modular_splurt/icons/effects/effects.dmi', "transform_effect") target.transformation_animation(bread_appearance,time = BREADIFY_TIME, transform_overlay=transform_scanline, reset_after=TRUE) addtimer(CALLBACK(GLOBAL_PROC, .proc/breadify, target), BREADIFY_TIME) diff --git a/code/modules/admin/smites/phobia_ocky_icky.dm b/code/modules/admin/smites/phobia_ocky_icky.dm new file mode 100644 index 0000000000..8295b062cf --- /dev/null +++ b/code/modules/admin/smites/phobia_ocky_icky.dm @@ -0,0 +1,8 @@ +/// "Immerses" the player, making them unable to use some OOC terms IC +/datum/smite/ocky_icky + name = "Ocky icky phobia" + +/datum/smite/ocky_icky/effect(client/user, mob/living/target) + . = ..() + var/mob/living/carbon/ocker = target + ocker.gain_trauma(/datum/brain_trauma/mild/phobia/ocky_icky, TRAUMA_RESILIENCE_LOBOTOMY) diff --git a/strings/phobia.json b/strings/phobia.json index ee25cc62fa..d442e9f979 100644 --- a/strings/phobia.json +++ b/strings/phobia.json @@ -38,7 +38,7 @@ "brig", "gulag" ], - + "conspiracies": [ "central command", "command", @@ -296,7 +296,7 @@ "i'll catch you", "slip" ], - + "syndicate": [ "syndicate", "changeling", @@ -315,7 +315,7 @@ "enemy corporation", "agent" ], - + "anime": [ "anime", "manga", @@ -342,5 +342,59 @@ "neet", "ora", "~" + ], + "ocky icky": [ + "admeme", + "admin", + "ahelp", + "amogus", + "antag", + "antagonist", + "ban", + "banned", + "chat", + "click", + "c*der", + "coder", + "coders", + "discord", + "erp", + "forum", + "ick ock", + "joever", + "k", + "kek", + "kys", + "leddit", + "lmao", + "lol", + "mapper", + "moderator", + "mods", + "muderbone", + "murderboning", + "ocky", + "ooc", + "owo", + "pwn", + "powergame", + "reddit", + "round", + "rule", + "rp", + "self antag", + "selfantag", + "sprite", + "spriter", + "splurt", + "sus", + "tide", + "u", + "ur", + "uwa", + "uwu", + "valid", + "y", + "5head" ] } diff --git a/tgstation.dme b/tgstation.dme index 4a670f0e7c..8b66a7fed8 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1601,6 +1601,7 @@ #include "code\modules\admin\smites\knot_shoes.dm" #include "code\modules\admin\smites\lightning.dm" #include "code\modules\admin\smites\nugget.dm" +#include "code\modules\admin\smites\phobia_ocky_icky.dm" #include "code\modules\admin\smites\pickle.dm" #include "code\modules\admin\smites\pie.dm" #include "code\modules\admin\smites\puzzle.dm" From 6cbc3a79300a33c49afd1e4d17e7cfb46dd387f4 Mon Sep 17 00:00:00 2001 From: Sim Date: Tue, 8 Oct 2024 16:45:05 -0300 Subject: [PATCH 05/14] Adds Rejuvenate to the Context Menu faster aheals faster tickets this one's coded by me Context Menu is ordered by category so switching it to Debug bumps it up a few spaces. --- code/modules/admin/admin_verbs.dm | 2 ++ code/modules/admin/verbs/debug.dm | 20 ++++++++++++++++++++ code/modules/admin/verbs/randomverbs.dm | 20 -------------------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 7a8ea640c9..969a4ceee9 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -30,6 +30,7 @@ GLOBAL_PROTECT(admin_verbs_admin) // /datum/admins/proc/show_traitor_panel, /*interface which shows a mob's mind*/ -Removed due to rare practical use. Moved to debug verbs ~Errorage /datum/admins/proc/show_player_panel, /*shows an interface for individual players, with various links (links require additional flags*/ /datum/verbs/menu/Admin/verb/playerpanel, + /client/proc/cmd_admin_rejuvenate, // VENUS CODE, MOSLEY CREDIT THE PROPER PEOPLE PLEASE /client/proc/game_panel, /*game panel, allows to change game-mode etc*/ /client/proc/check_ai_laws, /*shows AI and borg laws*/ // /client/proc/ghost_pool_protection, /*opens a menu for toggling ghost roles*/ @@ -238,6 +239,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( /client/proc/toggle_view_range, /client/proc/cmd_admin_check_contents, /datum/admins/proc/access_news_network, + /client/proc/cmd_admin_rejuvenate, // VENUS CODE, MOSLEY CREDIT THE PROPER PEOPLE PLEASE /client/proc/admin_end_shift, /client/proc/admin_call_shuttle, /client/proc/admin_cancel_shuttle, diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index cd8c849c45..c7dcac83df 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -539,6 +539,26 @@ return dresscode +/client/proc/cmd_admin_rejuvenate(mob/living/M in GLOB.mob_list) + set category = "Debug" + set name = "Rejuvenate" + + if(!check_rights(R_ADMIN)) + return + + if(!mob) + return + if(!istype(M)) + alert("Cannot revive a ghost") + return + M.revive(full_heal = 1, admin_revive = 1) + + log_admin("[key_name(usr)] healed / revived [key_name(M)]") + var/msg = "Admin [key_name_admin(usr)] healed / revived [ADMIN_LOOKUPFLW(M)]!" + message_admins(msg) + admin_ticket_log(M, msg) + SSblackbox.record_feedback("tally", "admin_verb", 1, "Rejuvinate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + /client/proc/startSinglo() set category = "Debug" diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 021129bdd9..a8af0f8f64 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -474,26 +474,6 @@ Traitors and the like can also be revived with the previous role mostly intact. SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_admin_rejuvenate(mob/living/M in GLOB.mob_list) - set category = "Special Verbs" - set name = "Rejuvenate" - - if(!check_rights(R_ADMIN)) - return - - if(!mob) - return - if(!istype(M)) - alert("Cannot revive a ghost") - return - M.revive(full_heal = 1, admin_revive = 1) - - log_admin("[key_name(usr)] healed / revived [key_name(M)]") - var/msg = "Admin [key_name_admin(usr)] healed / revived [ADMIN_LOOKUPFLW(M)]!" - message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Rejuvinate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - /client/proc/cmd_admin_create_centcom_report() set category = "Admin.Events" set name = "Create Command Report" From 50c16ccfadcca2e1aae5889fe52fe1601f9288ec Mon Sep 17 00:00:00 2001 From: Sim Date: Tue, 8 Oct 2024 18:29:20 -0300 Subject: [PATCH 06/14] [PORT] Adds Immersion from tgstation/tgstation/47704 Please roleplay appropriately, okay? Commit can also be called "How I Lost My Entire Playerbase" --- code/datums/components/manual_blinking.dm | 83 ++++++++++++++++++ code/datums/components/manual_breathing.dm | 93 +++++++++++++++++++++ code/modules/admin/smites/immerse.dm | 3 +- code/modules/admin/verbs/randomverbs.dm | 16 ++++ code/modules/admin/verbs/secrets.dm | 29 +++---- code/modules/mob/emote.dm | 4 +- code/modules/mob/living/emote.dm | 9 ++ sound/misc/roleplay.ogg | Bin 0 -> 50598 bytes tgstation.dme | 2 + 9 files changed, 222 insertions(+), 17 deletions(-) create mode 100644 code/datums/components/manual_blinking.dm create mode 100644 code/datums/components/manual_breathing.dm create mode 100644 sound/misc/roleplay.ogg diff --git a/code/datums/components/manual_blinking.dm b/code/datums/components/manual_blinking.dm new file mode 100644 index 0000000000..d5afbcabdc --- /dev/null +++ b/code/datums/components/manual_blinking.dm @@ -0,0 +1,83 @@ +/datum/component/manual_blinking + dupe_mode = COMPONENT_DUPE_UNIQUE + + var/obj/item/organ/eyes/E + var/warn_grace = FALSE + var/warn_dying = FALSE + var/last_blink + var/check_every = 20 SECONDS + var/grace_period = 6 SECONDS + var/damage_rate = 1 // organ damage taken per tick + var/list/valid_emotes = list(/datum/emote/living/carbon/blink, /datum/emote/living/carbon/blink_r) + +/datum/component/manual_blinking/Initialize() + if(!iscarbon(parent)) + return COMPONENT_INCOMPATIBLE + + var/mob/living/carbon/C = parent + E = C.getorganslot(ORGAN_SLOT_EYES) + + if(E) + START_PROCESSING(SSdcs, src) + last_blink = world.time + to_chat(C, "You suddenly realize you're blinking manually.") + +/datum/component/manual_blinking/Destroy(force, silent) + E = null + STOP_PROCESSING(SSdcs, src) + to_chat(parent, "You revert back to automatic blinking.") + return ..() + +/datum/component/manual_blinking/RegisterWithParent() + RegisterSignal(parent, COMSIG_MOB_EMOTE, .proc/check_emote) + RegisterSignal(parent, COMSIG_ORGAN_INSERTED, .proc/check_added_organ) + RegisterSignal(parent, COMSIG_ORGAN_REMOVED, .proc/check_removed_organ) + RegisterSignal(parent, COMSIG_LIVING_REVIVE, .proc/restart) + RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/pause) + +/datum/component/manual_blinking/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_MOB_EMOTE) + UnregisterSignal(parent, COMSIG_ORGAN_INSERTED) + UnregisterSignal(parent, COMSIG_ORGAN_REMOVED) + UnregisterSignal(parent, COMSIG_LIVING_REVIVE) + UnregisterSignal(parent, COMSIG_MOB_DEATH) + +/datum/component/manual_blinking/proc/restart() + START_PROCESSING(SSdcs, src) + +/datum/component/manual_blinking/proc/pause() + STOP_PROCESSING(SSdcs, src) + +/datum/component/manual_blinking/process() + var/mob/living/carbon/C = parent + + if(world.time > (last_blink + check_every + grace_period)) + if(!warn_dying) + to_chat(C, "Your eyes begin to wither, you need to blink!") + warn_dying = TRUE + + E.applyOrganDamage(damage_rate) + else if(world.time > (last_blink + check_every)) + if(!warn_grace) + to_chat(C, "You feel a need to blink!") + warn_grace = TRUE + +/datum/component/manual_blinking/proc/check_added_organ(mob/who_cares, obj/item/organ/O) + var/obj/item/organ/eyes/new_eyes = O + + if(istype(new_eyes,/obj/item/organ/eyes)) + E = new_eyes + START_PROCESSING(SSdcs, src) + +/datum/component/manual_blinking/proc/check_removed_organ(mob/who_cares, obj/item/organ/O) + var/obj/item/organ/eyes/bye_beyes = O // oh come on, that's pretty good + + if(istype(bye_beyes, /obj/item/organ/eyes)) + E = null + STOP_PROCESSING(SSdcs, src) + +/datum/component/manual_blinking/proc/check_emote(mob/living/carbon/user, datum/emote/emote) + if(emote.type in valid_emotes) + warn_grace = FALSE + warn_dying = FALSE + last_blink = world.time diff --git a/code/datums/components/manual_breathing.dm b/code/datums/components/manual_breathing.dm new file mode 100644 index 0000000000..45155285bf --- /dev/null +++ b/code/datums/components/manual_breathing.dm @@ -0,0 +1,93 @@ +/datum/component/manual_breathing + dupe_mode = COMPONENT_DUPE_UNIQUE + + var/obj/item/organ/lungs/L + var/warn_grace = FALSE + var/warn_dying = FALSE + var/last_breath + var/check_every = 12 SECONDS + var/grace_period = 6 SECONDS + var/damage_rate = 1 // organ damage taken per tick + var/datum/emote/next_breath_type = /datum/emote/inhale + +/datum/component/manual_breathing/Initialize() + if(!iscarbon(parent)) + return COMPONENT_INCOMPATIBLE + + var/mob/living/carbon/C = parent + L = C.getorganslot(ORGAN_SLOT_LUNGS) + + if(L) + START_PROCESSING(SSdcs, src) + last_breath = world.time + to_chat(C, "You suddenly realize you're breathing manually.") + +/datum/component/manual_breathing/Destroy(force, silent) + L = null + STOP_PROCESSING(SSdcs, src) + to_chat(parent, "You revert back to automatic breathing.") + return ..() + +/datum/component/manual_breathing/RegisterWithParent() + RegisterSignal(parent, COMSIG_MOB_EMOTE, .proc/check_emote) + RegisterSignal(parent, COMSIG_ORGAN_INSERTED, .proc/check_added_organ) + RegisterSignal(parent, COMSIG_ORGAN_REMOVED, .proc/check_removed_organ) + RegisterSignal(parent, COMSIG_LIVING_REVIVE, .proc/restart) + RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/pause) + +/datum/component/manual_breathing/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_MOB_EMOTE) + UnregisterSignal(parent, COMSIG_ORGAN_INSERTED) + UnregisterSignal(parent, COMSIG_ORGAN_REMOVED) + UnregisterSignal(parent, COMSIG_LIVING_REVIVE) + UnregisterSignal(parent, COMSIG_MOB_DEATH) + +/datum/component/manual_breathing/proc/restart() + START_PROCESSING(SSdcs, src) + +/datum/component/manual_breathing/proc/pause() + STOP_PROCESSING(SSdcs, src) + +/datum/component/manual_breathing/process() + var/mob/living/carbon/C = parent + + var/next_text = initial(next_breath_type.key) + if(world.time > (last_breath + check_every + grace_period)) + if(!warn_dying) + to_chat(C, "You begin to suffocate, you need to [next_text]!") + warn_dying = TRUE + + L.applyOrganDamage(damage_rate) + C.losebreath += 0.8 + else if(world.time > (last_breath + check_every)) + if(!warn_grace) + to_chat(C, "You feel a need to [next_text]!") + warn_grace = TRUE + +/datum/component/manual_breathing/proc/check_added_organ(mob/who_cares, obj/item/organ/O) + var/obj/item/organ/eyes/new_lungs = O + + if(istype(new_lungs,/obj/item/organ/lungs)) + L = new_lungs + START_PROCESSING(SSdcs, src) + +/datum/component/manual_breathing/proc/check_removed_organ(mob/who_cares, obj/item/organ/O) + var/obj/item/organ/lungs/old_lungs = O + + if(istype(old_lungs, /obj/item/organ/lungs)) + L = null + STOP_PROCESSING(SSdcs, src) + +/datum/component/manual_breathing/proc/check_emote(mob/living/carbon/user, datum/emote/emote) + if(emote.type == next_breath_type) + if(next_breath_type == /datum/emote/inhale) + next_breath_type = /datum/emote/exhale + else + next_breath_type = /datum/emote/inhale + + warn_grace = FALSE + warn_dying = FALSE + last_breath = world.time + + var/mob/living/carbon/C = parent + C.losebreath = max(0, C.losebreath - 0.4) diff --git a/code/modules/admin/smites/immerse.dm b/code/modules/admin/smites/immerse.dm index 5d6ca24455..9cdd8aca95 100644 --- a/code/modules/admin/smites/immerse.dm +++ b/code/modules/admin/smites/immerse.dm @@ -1,5 +1,5 @@ /// "Fully immerses" the player, making them manually breathe and blink -/*/datum/smite/immerse +/datum/smite/immerse name = "Fully Immerse" /datum/smite/immerse/effect(client/user, mob/living/target) @@ -7,4 +7,3 @@ immerse_player(target) SEND_SOUND(target, sound('sound/misc/roleplay.ogg')) to_chat(target, span_boldnotice("Please roleplay appropriately, okay?")) -*/ diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index a8af0f8f64..3f70ab295f 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1495,3 +1495,19 @@ Traitors and the like can also be revived with the previous role mostly intact. log_admin("[key_name(usr)] spawned floor cluwne.") message_admins("[key_name(usr)] spawned floor cluwne.") */ + +/// "Immerse", or how I made the entire playerbase quit the game. +/proc/immerse_player(mob/living/carbon/target, toggle=TRUE, remove=FALSE) + var/list/immersion_components = list(/datum/component/manual_breathing, /datum/component/manual_blinking) + + for(var/immersies in immersion_components) + var/has_component = target.GetComponent(immersies) + + if(has_component && (toggle || remove)) + qdel(has_component) + else if(toggle || !remove) + target.AddComponent(immersies) + +/proc/mass_immerse(remove=FALSE) + for(var/mob/living/carbon/M in GLOB.mob_list) + immerse_player(M, toggle=FALSE, remove=remove) diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index c7b3523906..84a91113bc 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -567,20 +567,21 @@ message_admins("[key_name_admin(holder)] has removed everyone from \ purrbation.") log_admin("[key_name(holder)] has removed everyone from purrbation.") - // if("massimmerse") // my immursion is ruinned :( - // if(!is_funmin) - // return - // mass_immerse() - // message_admins("[key_name_admin(holder)] has Fully Immersed - // everyone!") - // log_admin("[key_name(holder)] has Fully Immersed everyone.") - // if("unmassimmerse") - // if(!is_funmin) - // return - // mass_immerse(remove=TRUE) - // message_admins("[key_name_admin(holder)] has Un-Fully Immersed - // everyone!") - // log_admin("[key_name(holder)] has Un-Fully Immersed everyone.") + // Shh!! Don't let badmins know this isn't actually a button! + if("massimmerse") + if(!is_funmin) + return + mass_immerse() + message_admins("[key_name_admin(holder)] has Fully Immersed \ + everyone!") + log_admin("[key_name(holder)] has Fully Immersed everyone.") + if("unmassimmerse") + if(!is_funmin) + return + mass_immerse(remove=TRUE) + message_admins("[key_name_admin(holder)] has Un-Fully Immersed \ + everyone!") + log_admin("[key_name(holder)] has Un-Fully Immersed everyone.") if(E) E.processing = FALSE if(E.announce_when>0) diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm index 1652997149..bfee6b87c0 100644 --- a/code/modules/mob/emote.dm +++ b/code/modules/mob/emote.dm @@ -11,7 +11,9 @@ for(var/datum/emote/emote in key_emotes) if(!emote.can_run_emote(src, TRUE, intentional, param)) continue - emote.run_emote(src, param, m_type, intentional) + if(emote.run_emote(src, param, m_type, intentional)) + SEND_SIGNAL(src, COMSIG_MOB_EMOTE, emote, act, m_type, message, intentional) + return TRUE if(!key_emotes) to_chat(src, span_notice("Unusable emote '[act]'. Say *help for a list.")) return diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 45adeaee7d..efdc92654b 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -587,3 +587,12 @@ var/mob/living/carbon/C = user if(isjellyperson(C)) pick(playsound(C, 'sound/effects/meatslap.ogg', 50, 1),playsound(C, 'sound/effects/gib_step.ogg', 50, 1)) + +/datum/emote/inhale + key = "inhale" + key_third_person = "inhales" + message = "breathes in." +/datum/emote/exhale + key = "exhale" + key_third_person = "exhales" + message = "breathes out." diff --git a/sound/misc/roleplay.ogg b/sound/misc/roleplay.ogg new file mode 100644 index 0000000000000000000000000000000000000000..e9ec54550091de2e55b1754d844a668dc858c484 GIT binary patch literal 50598 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 z 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 MiCyBrf-&%a06qxq{r~^~ literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index 8b66a7fed8..b1871816ad 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -633,6 +633,8 @@ #include "code\datums\components\lifesteal.dm" #include "code\datums\components\lockon_aiming.dm" #include "code\datums\components\magnetic_catch.dm" +#include "code\datums\components\manual_blinking.dm" +#include "code\datums\components\manual_breathing.dm" #include "code\datums\components\material_container.dm" #include "code\datums\components\mirage_border.dm" #include "code\datums\components\mirv.dm" From 99b901e8487914edd4bedfa53ba22c1164afbcb0 Mon Sep 17 00:00:00 2001 From: VENUS Bot <97993072+VENUS-Station-Bot@users.noreply.github.com> Date: Tue, 8 Oct 2024 21:44:01 +0000 Subject: [PATCH 07/14] Automatic changelog generation for PR #16 [ci skip] --- html/changelogs/AutoChangeLog-pr-16.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-16.yml diff --git a/html/changelogs/AutoChangeLog-pr-16.yml b/html/changelogs/AutoChangeLog-pr-16.yml new file mode 100644 index 0000000000..68a16f9a27 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-16.yml @@ -0,0 +1,4 @@ +author: cyfause +delete-after: true +changes: + - bugfix: allow facial hair on anthromorph species From 9027e749245f041a20d2d35fe522c714a875062b Mon Sep 17 00:00:00 2001 From: Changelogs Date: Tue, 8 Oct 2024 21:44:38 +0000 Subject: [PATCH 08/14] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-16.yml | 4 ---- html/changelogs/archive/2024-10.yml | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-16.yml diff --git a/html/changelogs/AutoChangeLog-pr-16.yml b/html/changelogs/AutoChangeLog-pr-16.yml deleted file mode 100644 index 68a16f9a27..0000000000 --- a/html/changelogs/AutoChangeLog-pr-16.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: cyfause -delete-after: true -changes: - - bugfix: allow facial hair on anthromorph species diff --git a/html/changelogs/archive/2024-10.yml b/html/changelogs/archive/2024-10.yml index 1990d91292..cde703a5a4 100644 --- a/html/changelogs/archive/2024-10.yml +++ b/html/changelogs/archive/2024-10.yml @@ -6,3 +6,6 @@ 2024-10-05: Just-Sim: - bugfix: fixes bugs brought about by the emote panel +2024-10-08: + cyfause: + - bugfix: allow facial hair on anthromorph species From 2ed0e2069e50b20baf1ec101c92f29c7c9509ce3 Mon Sep 17 00:00:00 2001 From: Sim Date: Tue, 8 Oct 2024 18:45:56 -0300 Subject: [PATCH 09/14] Fixes Lightning Smite --- code/modules/admin/smites/lightning.dm | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/code/modules/admin/smites/lightning.dm b/code/modules/admin/smites/lightning.dm index d7e3ce5627..93527fad8b 100644 --- a/code/modules/admin/smites/lightning.dm +++ b/code/modules/admin/smites/lightning.dm @@ -1,17 +1,20 @@ /// Strikes the target with a lightning bolt -/*/datum/smite/lightning +/datum/smite/lightning name = "Lightning bolt" -/datum/smite/lightning/effect(client/user, mob/living/carbon/human/target as mob) +/datum/smite/lightning/effect(client/user, mob/living/target) . = ..() - if(prob(75)) - playsound(target, 'modular_splurt/sound/misc/NOW.ogg', 75, FALSE) - sleep(4 SECONDS) - var/turf/T = get_step(get_step(user, NORTH), NORTH) - T.Beam(target, icon_state="lightning[rand(1,12)]", time = 5) - target.adjustFireLoss(75) - target.electrocution_animation(40) + lightningbolt(target) to_chat(target, "The gods have punished you for your sins!") -*/ -//BROKEN!!! FIX LATER!! +///this is the actual bolt effect and damage, made into its own proc because it is used elsewhere +/proc/lightningbolt(mob/living/user) + playsound(get_turf(user), 'modular_splurt/sound/misc/NOW.ogg', 75, FALSE) + sleep(4 SECONDS) + var/turf/T = get_step(get_step(user, NORTH), NORTH) + T.Beam(user, icon_state="lightning[rand(1,12)]", time = 5) + user.adjustFireLoss(75) + if(ishuman(user)) + var/mob/living/carbon/human/human_target = user + human_target.electrocution_animation(40) + From a60a88e43c4af399810ecd91e445f2cdb0027948 Mon Sep 17 00:00:00 2001 From: VENUS Bot <97993072+VENUS-Station-Bot@users.noreply.github.com> Date: Tue, 8 Oct 2024 22:07:33 +0000 Subject: [PATCH 10/14] Automatic changelog generation for PR #17 [ci skip] --- html/changelogs/AutoChangeLog-pr-17.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-17.yml diff --git a/html/changelogs/AutoChangeLog-pr-17.yml b/html/changelogs/AutoChangeLog-pr-17.yml new file mode 100644 index 0000000000..a9346c597f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-17.yml @@ -0,0 +1,7 @@ +author: Just-Sim +delete-after: true +changes: + - rscadd: popup notices + - rscadd: the ocky icky + - code_imp: added rejuvenation to the admin context menu + - refactor: refactored smites From 3885d210a7c4fb68ebd012eab9876ede982c2d07 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Tue, 8 Oct 2024 22:08:31 +0000 Subject: [PATCH 11/14] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-17.yml | 7 ------- html/changelogs/archive/2024-10.yml | 5 +++++ 2 files changed, 5 insertions(+), 7 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-17.yml diff --git a/html/changelogs/AutoChangeLog-pr-17.yml b/html/changelogs/AutoChangeLog-pr-17.yml deleted file mode 100644 index a9346c597f..0000000000 --- a/html/changelogs/AutoChangeLog-pr-17.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: Just-Sim -delete-after: true -changes: - - rscadd: popup notices - - rscadd: the ocky icky - - code_imp: added rejuvenation to the admin context menu - - refactor: refactored smites diff --git a/html/changelogs/archive/2024-10.yml b/html/changelogs/archive/2024-10.yml index cde703a5a4..2b86ffacf6 100644 --- a/html/changelogs/archive/2024-10.yml +++ b/html/changelogs/archive/2024-10.yml @@ -7,5 +7,10 @@ Just-Sim: - bugfix: fixes bugs brought about by the emote panel 2024-10-08: + Just-Sim: + - rscadd: popup notices + - rscadd: the ocky icky + - code_imp: added rejuvenation to the admin context menu + - refactor: refactored smites cyfause: - bugfix: allow facial hair on anthromorph species From 7f4d26fe06774f84b31f0f3eca6f80755dbfdd42 Mon Sep 17 00:00:00 2001 From: ariaworld <143797359+ariaworld@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:22:37 +0200 Subject: [PATCH 12/14] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 05415a5494..5c4def5762 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,4 +1,4 @@ # These are supported funding model platforms -patreon: test +patreon: venus_station ko_fi: test From 587299b32e66a98e6b71ad487e44b479b7ac7f49 Mon Sep 17 00:00:00 2001 From: ariaworld <143797359+ariaworld@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:26:26 +0200 Subject: [PATCH 13/14] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 5c4def5762..bb49d38176 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,4 +1,4 @@ # These are supported funding model platforms -patreon: venus_station +patreon: Venus_Station ko_fi: test From 4cda05e817e81710041dee3c029604084c7fbe5c Mon Sep 17 00:00:00 2001 From: ariaworld <143797359+ariaworld@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:27:52 +0200 Subject: [PATCH 14/14] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 71d6e5aca4..31fa3af798 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,8 @@ Based and maintained from VENUS Station. **VENUS Station Information** * **Code:** https://github.com/VENUS-Station/VENUS-Station-13 * **Discord:** https://discord.gg/kCuWJRdzb7 - +* **Patreon:** https://www.patreon.com/Venus_Station + ## DOWNLOADING