diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 8ecaa7c3645..9bb64c21703 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -84,30 +84,6 @@ /turf/Safe_COORD_Location() return src - -#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_IMMERSE "Fully Immerse" -#define ADMIN_PUNISHMENT_FAT "Fatten up" -#define ADMIN_PUNISHMENT_FAKEBWOINK "Fake bwoink" -#define ADMIN_PUNISHMENT_NUGGET "Nugget" -#define ADMIN_PUNISHMENT_CRACK ":B:oneless" -#define ADMIN_PUNISHMENT_BLEED ":B:loodless" -#define ADMIN_PUNISHMENT_PERFORATE ":B:erforate" -#define ADMIN_PUNISHMENT_SCARIFY "Scarify" -#define ADMIN_PUNISHMENT_SHOES "Knot Shoes" -#define ADMIN_PUNISHMENT_DOCK "Dock Pay" -#define ADMIN_PUNISHMENT_BREAD "Bread" -/// Applies [/datum/component/omen] to the target, optionally permanently. -#define ADMIN_PUNISHMENT_BADLUCK "Bad Luck" - #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 index be9f1ff7292..22e4f293468 100644 --- a/code/_globalvars/lists/admin.dm +++ b/code/_globalvars/lists/admin.dm @@ -1,3 +1,12 @@ GLOBAL_LIST_EMPTY(stickybanadminexemptions) //stores a list of ckeys exempted from a stickyban (workaround for a bug) GLOBAL_LIST_EMPTY(stickybanadmintexts) //stores the entire stickyban list temporarily GLOBAL_VAR(stickbanadminexemptiontimerid) //stores the timerid of the callback that restores all stickybans after an admin joins + +/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/modules/admin/smites/bad_luck.dm b/code/modules/admin/smites/bad_luck.dm new file mode 100644 index 00000000000..b8bac94b1ca --- /dev/null +++ b/code/modules/admin/smites/bad_luck.dm @@ -0,0 +1,17 @@ +/// Gives the target bad luck, optionally permanently +/datum/smite/bad_luck + name = "Bad Luck" + + /// Should the target know they've received bad luck? + var/silent + + /// Is this permanent? + var/permanent + +/datum/smite/bad_luck/configure(client/user) + silent = alert(user, "Do you want to apply the omen with a player notification?", "Notify Player?", "Notify", "Silent") == "Silent" + permanent = alert(user, "Would you like this to be permanent or removed automatically after the first accident?", "Permanent?", "Permanent", "Temporary") == "Permanent" + +/datum/smite/bad_luck/effect(client/user, mob/living/target) + . = ..() + target.AddComponent(/datum/component/omen, silent, null, permanent) diff --git a/code/modules/admin/smites/berforate.dm b/code/modules/admin/smites/berforate.dm new file mode 100644 index 00000000000..ce573237565 --- /dev/null +++ b/code/modules/admin/smites/berforate.dm @@ -0,0 +1,53 @@ +/// 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 00000000000..cc6e0c7d920 --- /dev/null +++ b/code/modules/admin/smites/bloodless.dm @@ -0,0 +1,18 @@ +/// Slashes up the target +/datum/smite/bloodless + name = ":B:loodless" + +/datum/smite/bloodless/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/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 00000000000..e622f2c4f1e --- /dev/null +++ b/code/modules/admin/smites/boneless.dm @@ -0,0 +1,16 @@ +/// 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/brain_damage.dm b/code/modules/admin/smites/brain_damage.dm new file mode 100644 index 00000000000..ceafc49df24 --- /dev/null +++ b/code/modules/admin/smites/brain_damage.dm @@ -0,0 +1,7 @@ +/// 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 00000000000..2bdd34155e1 --- /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 00000000000..7df6bc8ad42 --- /dev/null +++ b/code/modules/admin/smites/bsa.dm @@ -0,0 +1,35 @@ +#define BSA_CHANCE_TO_BREAK_TILE_TO_PLATING 80 +#define BSA_MAX_DAMAGE 99 +#define BSA_PARALYZE_TIME (40 SECONDS) +#define BSA_STUTTER_TIME 20 + +/// 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( + /* no_brain = */ TRUE, + /* no_organs = */ TRUE, + ) + else + target.adjustBruteLoss(min(BSA_MAX_DAMAGE, target.health - 1)) + target.Paralyze(BSA_PARALYZE_TIME) + target.stuttering = BSA_STUTTER_TIME + +#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/dock_pay.dm b/code/modules/admin/smites/dock_pay.dm new file mode 100644 index 00000000000..8c220e25c9f --- /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, "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, "[dude] does not have an ID card on!", confidential = TRUE) + return + if (!card.registered_account) + to_chat(user, "[dude] does not have an ID card with an account!", confidential = TRUE) + return + if (card.registered_account.account_balance == 0) + to_chat(user, "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, "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 00000000000..a4179ff5ce8 --- /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/fat.dm b/code/modules/admin/smites/fat.dm new file mode 100644 index 00000000000..4eba39f466e --- /dev/null +++ b/code/modules/admin/smites/fat.dm @@ -0,0 +1,7 @@ +/// Fattens the target +/datum/smite/fat + name = "Fatten up" + +/datum/smite/fat/effect(client/user, mob/living/target) + . = ..() + target.set_nutrition(NUTRITION_LEVEL_FAT * 2) diff --git a/code/modules/admin/smites/fireball.dm b/code/modules/admin/smites/fireball.dm new file mode 100644 index 00000000000..98dad65d825 --- /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/gib.dm b/code/modules/admin/smites/gib.dm new file mode 100644 index 00000000000..471479e7645 --- /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(/* no_brain = */ FALSE) diff --git a/code/modules/admin/smites/immerse.dm b/code/modules/admin/smites/immerse.dm new file mode 100644 index 00000000000..84f5aeb6b9b --- /dev/null +++ b/code/modules/admin/smites/immerse.dm @@ -0,0 +1,7 @@ +/// "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) diff --git a/code/modules/admin/smites/knot_shoes.dm b/code/modules/admin/smites/knot_shoes.dm new file mode 100644 index 00000000000..42d41e238e9 --- /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, "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, "[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 00000000000..3148ae7d4f5 --- /dev/null +++ b/code/modules/admin/smites/lightning.dm @@ -0,0 +1,19 @@ +#define LIGHTNING_BOLT_DAMAGE 75 +#define LIGHTNING_BOLT_ELECTROCUTION_ANIMATION_LENGTH 40 + +/// Strikes the target with a lightning bolt +/datum/smite/lightning + name = "Lightning bolt" + +/datum/smite/lightning/effect(client/user, mob/living/target) + . = ..() + var/turf/lightning_source = get_step(get_step(target, NORTH), NORTH) + lightning_source.Beam(target, icon_state="lightning[rand(1,12)]", time = 5) + target.adjustFireLoss(LIGHTNING_BOLT_DAMAGE) + if(ishuman(target)) + var/mob/living/carbon/human/human_target = target + human_target.electrocution_animation(LIGHTNING_BOLT_ELECTROCUTION_ANIMATION_LENGTH) + to_chat(target, "The gods have punished you for your sins!", confidential = TRUE) + +#undef LIGHTNING_BOLT_DAMAGE +#undef LIGHTNING_BOLT_ELECTROCUTION_ANIMATION_LENGTH diff --git a/code/modules/admin/smites/nugget.dm b/code/modules/admin/smites/nugget.dm new file mode 100644 index 00000000000..77f92536ff5 --- /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, "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, /obj/item/bodypart/.proc/dismember), timer) + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, carbon_target, 'sound/effects/cartoon_pop.ogg', 70), timer) + addtimer(CALLBACK(carbon_target, /mob/living/.proc/spin, 4, 1), timer - 0.4 SECONDS) + timer += 2 SECONDS diff --git a/code/modules/admin/smites/puzzle.dm b/code/modules/admin/smites/puzzle.dm new file mode 100644 index 00000000000..ffaee144120 --- /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 00000000000..6c4b50b2688 --- /dev/null +++ b/code/modules/admin/smites/rod.dm @@ -0,0 +1,11 @@ +/// Throw an immovable rod at the target +/datum/smite/rod + name = "Immovable Rod" + +/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) diff --git a/code/modules/admin/smites/scarify.dm b/code/modules/admin/smites/scarify.dm new file mode 100644 index 00000000000..d2d445f23e3 --- /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, "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...") diff --git a/code/modules/admin/smites/smite.dm b/code/modules/admin/smites/smite.dm new file mode 100644 index 00000000000..b767f47f8fe --- /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 00000000000..187507e9bb4 --- /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 00000000000..0af70e715f9 --- /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/food/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/obj/structure/closet/supplypod/centcompod/pod = new + 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/verbs/bluespacearty.dm b/code/modules/admin/verbs/bluespacearty.dm deleted file mode 100644 index b257581e796..00000000000 --- 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.Paralyze(400) - target.stuttering = 20 - diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 2a89c6c2342..1df904a4064 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1117,232 +1117,18 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!check_rights(R_ADMIN) || !check_rights(R_FUN)) return - var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, - ADMIN_PUNISHMENT_BRAINDAMAGE, - ADMIN_PUNISHMENT_GIB, - ADMIN_PUNISHMENT_BSA, - ADMIN_PUNISHMENT_FIREBALL, - ADMIN_PUNISHMENT_ROD, - ADMIN_PUNISHMENT_SUPPLYPOD_QUICK, - ADMIN_PUNISHMENT_SUPPLYPOD, - ADMIN_PUNISHMENT_MAZING, - ADMIN_PUNISHMENT_IMMERSE, - ADMIN_PUNISHMENT_FAT, - ADMIN_PUNISHMENT_FAKEBWOINK, - ADMIN_PUNISHMENT_NUGGET, - ADMIN_PUNISHMENT_CRACK, - ADMIN_PUNISHMENT_BLEED, - ADMIN_PUNISHMENT_PERFORATE, - ADMIN_PUNISHMENT_SCARIFY, - ADMIN_PUNISHMENT_SHOES, - ADMIN_PUNISHMENT_DOCK, - ADMIN_PUNISHMENT_BREAD, - ADMIN_PUNISHMENT_BADLUCK - ) - var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in sortList(punishment_list) + var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in GLOB.smites if(QDELETED(target) || !punishment) return - switch(punishment) - if(ADMIN_PUNISHMENT_LIGHTNING) - var/turf/T = get_step(get_step(target, NORTH), NORTH) - T.Beam(target, icon_state="lightning[rand(1,12)]", time = 5) - target.adjustFireLoss(75) - if(ishuman(target)) - var/mob/living/carbon/human/H = target - H.electrocution_animation(40) - to_chat(target, "The gods have punished you for your sins!", confidential = TRUE) - 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/food/grown/harebell") as null|text - var/obj/structure/closet/supplypod/centcompod/pod = new() - 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.") - return - 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 - if(ADMIN_PUNISHMENT_MAZING) - if(!puzzle_imprison(target)) - to_chat(usr,"Imprisonment failed!", confidential = TRUE) - return - if(ADMIN_PUNISHMENT_IMMERSE) - immerse_player(target) - if(ADMIN_PUNISHMENT_FAT) - target.set_nutrition(NUTRITION_LEVEL_FAT*2) - if(ADMIN_PUNISHMENT_FAKEBWOINK) - SEND_SOUND(target, 'sound/effects/adminhelp.ogg') - if(ADMIN_PUNISHMENT_NUGGET) - if(!iscarbon(target)) - to_chat(usr,"This must be used on a carbon mob.", confidential = TRUE) - return - var/mob/living/carbon/C = target - var/timer = 2 SECONDS - for(var/obj/item/bodypart/thing in C.bodyparts) - if(thing.body_part == HEAD || thing.body_part == CHEST) - continue - addtimer(CALLBACK(thing, /obj/item/bodypart/.proc/dismember), timer) - addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, C, 'sound/effects/cartoon_pop.ogg', 70), timer) - addtimer(CALLBACK(C, /mob/living/.proc/spin, 4, 1), timer - 0.4 SECONDS) - timer += 2 SECONDS - 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_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, .proc/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_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_SHOES) - if(!iscarbon(target)) - to_chat(usr,"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(usr,"[dude] does not have knottable shoes!", confidential = TRUE) - return - sick_kicks.adjust_laces(SHOES_KNOTTED) - if(ADMIN_PUNISHMENT_DOCK) - if(!iscarbon(target)) - to_chat(usr,"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(usr,"[dude] does not have an ID card on!", confidential = TRUE) - return - if(!card.registered_account) - to_chat(usr,"[dude] does not have an ID card with an account!", confidential = TRUE) - return - if(card.registered_account.account_balance == 0) - to_chat(usr, "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(usr, "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') - if(ADMIN_PUNISHMENT_BREAD) - 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= 5 SECONDS,transform_overlay=transform_scanline,reset_after=TRUE) - addtimer(CALLBACK(GLOBAL_PROC, .proc/breadify, target), 5 SECONDS) - if(ADMIN_PUNISHMENT_BADLUCK) - if(!isliving(target)) - to_chat(usr, "This must be used on a /mob/living type of mob.", confidential = TRUE) - return - var/silent = alert("Do you want to apply the omen with a player notification?", "Notify Player?", "Notify", "Silent") == "Silent" - var/permanent = alert("Would you like this to be permanent or removed automatically after the first accident?", "Permanent?", "Permanent", "Temporary") == "Permanent" - target.AddComponent(/datum/component/omen, silent, null, permanent) - - punish_log(target, punishment) + 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) /proc/breadify(atom/movable/target) var/obj/item/food/bread/plain/bread = new(get_turf(target)) @@ -1374,10 +1160,10 @@ Traitors and the like can also be revived with the previous role mostly intact. divine_wrath.fire() /client/proc/punish_log(whom, 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 00000000000..5f5050b41f3 --- /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 fb51ad68116..edb635e7f2e 100644 Binary files a/icons/misc/buildmode.dmi and b/icons/misc/buildmode.dmi differ diff --git a/tgstation.dme b/tgstation.dme index c2fb1ff264c..4d46155d6f4 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1396,6 +1396,28 @@ #include "code\modules\admin\topic.dm" #include "code\modules\admin\whitelist.dm" #include "code\modules\admin\callproc\callproc.dm" +#include "code\modules\admin\smites\bad_luck.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\brain_damage.dm" +#include "code\modules\admin\smites\bread.dm" +#include "code\modules\admin\smites\bsa.dm" +#include "code\modules\admin\smites\dock_pay.dm" +#include "code\modules\admin\smites\fake_bwoink.dm" +#include "code\modules\admin\smites\fat.dm" +#include "code\modules\admin\smites\fireball.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\puzzle.dm" +#include "code\modules\admin\smites\rod.dm" +#include "code\modules\admin\smites\scarify.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\verbs\adminhelp.dm" #include "code\modules\admin\verbs\adminjump.dm" #include "code\modules\admin\verbs\adminpm.dm" @@ -1403,7 +1425,6 @@ #include "code\modules\admin\verbs\anonymousnames.dm" #include "code\modules\admin\verbs\atmosdebug.dm" #include "code\modules\admin\verbs\beakerpanel.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" @@ -1722,6 +1743,7 @@ #include "code\modules\buildmode\submodes\fill.dm" #include "code\modules\buildmode\submodes\mapgen.dm" #include "code\modules\buildmode\submodes\outfit.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"