From b9dabca716d6aff7d33927b225ef7854102edd00 Mon Sep 17 00:00:00 2001 From: Archie Date: Sat, 15 May 2021 17:21:29 -0300 Subject: [PATCH] Ports Vending Machine Tipping --- code/datums/elements/squish.dm | 28 ++++++ code/modules/vending/_vending.dm | 143 ++++++++++++++++++++++++++- code/modules/vending/medical_wall.dm | 1 + tgstation.dme | 1 + 4 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 code/datums/elements/squish.dm diff --git a/code/datums/elements/squish.dm b/code/datums/elements/squish.dm new file mode 100644 index 00000000..823d391e --- /dev/null +++ b/code/datums/elements/squish.dm @@ -0,0 +1,28 @@ +#define SHORT 5/7 +#define TALL 7/5 + +/datum/element/squish + element_flags = ELEMENT_DETACH + +/datum/element/squish/Attach(datum/target, duration) + . = ..() + if(!iscarbon(target)) + return ELEMENT_INCOMPATIBLE + + var/mob/living/carbon/C = target + var/was_lying = (C.lying != 0) + addtimer(CALLBACK(src, .proc/Detach, C, was_lying), duration) + + C.transform = C.transform.Scale(TALL, SHORT) + +/datum/element/squish/Detach(mob/living/carbon/C, was_lying) + . = ..() + if(istype(C)) + var/is_lying = (C.lying != 0) + if(was_lying == is_lying) + C.transform = C.transform.Scale(SHORT, TALL) + else + C.transform = C.transform.Scale(TALL, SHORT) + +#undef SHORT +#undef TALL diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index a49efde2..b256d861 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -74,6 +74,14 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C var/obj/item/vending_refill/refill_canister = null //The type of refill canisters used by this machine + //tilting stuff + var/tilted = FALSE + var/tiltable = TRUE + var/squish_damage = 75 + var/forcecrit = 0 + var/num_shards = 7 + var/list/pinned_mobs = list() + //hyper economy stuff var/credits = 0 var/baseprice = 0 @@ -102,6 +110,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C power_change() /obj/machinery/vending/Destroy() + unbuckle_all_mobs(TRUE) QDEL_NULL(wires) QDEL_NULL(coin) QDEL_NULL(bill) @@ -230,6 +239,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C /obj/machinery/vending/wrench_act(mob/living/user, obj/item/I) if(panel_open) default_unfasten_wrench(user, I, time = 60) + unbuckle_all_mobs(TRUE) return TRUE /obj/machinery/vending/screwdriver_act(mob/living/user, obj/item/I) @@ -307,7 +317,133 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C to_chat(user, "There's nothing to restock!") return else - return ..() + . = ..() + if(tiltable && !tilted && I.force) + switch(rand(1, 100)) + if(1 to 5) + freebie(user, 3) + if(6 to 15) + freebie(user, 2) + if(16 to 25) + freebie(user, 1) + if(76 to 90) + tilt(user) + if(91 to 100) + tilt(user, crit=TRUE) + +/obj/machinery/vending/proc/freebie(mob/fatty, freebies) + visible_message("[src] yields [freebies > 1 ? "several free goodies" : "a free goody"]!") + + for(var/i in 1 to freebies) + playsound(src, 'sound/items/vending.ogg', 50, TRUE, extrarange = -3) + for(var/datum/data/vending_product/R in shuffle(product_records)) + + if(R.amount <= 0) //Try to use a record that actually has something to dump. + continue + var/dump_path = R.product_path + if(!dump_path) + continue + + R.amount-- + new dump_path(get_turf(src)) + break + +/obj/machinery/vending/proc/tilt(mob/fatty, crit=FALSE) + visible_message("[src] tips over!") + tilted = TRUE + layer = ABOVE_MOB_LAYER + + var/crit_case + if(crit) + crit_case = rand(1,5) + + if(forcecrit) + crit_case = forcecrit + + if(in_range(fatty, src)) + for(var/mob/living/L in get_turf(fatty)) + var/mob/living/carbon/C = L + + if(istype(C)) + var/crit_rebate = 0 // lessen the normal damage we deal for some of the crits + + if(crit_case != 5) // the head asplode case has its own description + C.visible_message("[C] is crushed by [src]!", \ + "You are crushed by [src]!") + + switch(crit_case) // only carbons can have the fun crits + if(1) // shatter their legs and bleed 'em + crit_rebate = 60 + C.bleed(150) + var/obj/item/bodypart/l_leg/l = C.get_bodypart(BODY_ZONE_L_LEG) + if(l) + l.receive_damage(brute=200, updating_health=TRUE) + var/obj/item/bodypart/r_leg/r = C.get_bodypart(BODY_ZONE_R_LEG) + if(r) + r.receive_damage(brute=200, updating_health=TRUE) + if(l || r) + C.visible_message("[C]'s legs shatter with a sickening crunch!", \ + "Your legs shatter with a sickening crunch!") + if(2) // pin them beneath the machine until someone untilts it + forceMove(get_turf(C)) + buckle_mob(C, force=TRUE) + C.visible_message("[C] is pinned underneath [src]!", \ + "You are pinned down by [src]!") + if(3) // glass candy + crit_rebate = 50 + for(var/i = 0, i < num_shards, i++) + var/obj/item/shard/shard = new /obj/item/shard(get_turf(C)) + shard.embedding = shard.embedding.setRating(embed_chance = 100) + C.hitby(shard, skipcatch = TRUE, hitpush = FALSE) + shard.embedding = shard.embedding.setRating(embed_chance = EMBED_CHANCE) + if(4) // paralyze this binch + // the new paraplegic gets like 4 lines of losing their legs so skip them + visible_message("[C]'s spinal cord is obliterated with a sickening crunch!", ignored_mobs = list(C)) + C.gain_trauma(/datum/brain_trauma/severe/paralysis/paraplegic) + if(5) // skull squish! + var/obj/item/bodypart/head/O = C.get_bodypart(BODY_ZONE_HEAD) + if(O) + C.visible_message("[O] explodes in a shower of gore beneath [src]!", \ + "Oh f-") + O.dismember() + O.drop_organs() + qdel(O) + new /obj/effect/gibspawner/human/bodypartless(get_turf(C)) + C.apply_damage(max(0, squish_damage - crit_rebate), BRUTE) + C.AddElement(/datum/element/squish, 60 SECONDS) + else + L.visible_message("[L] is crushed by [src]!", \ + "You are crushed by [src]!") + L.apply_damage(squish_damage, BRUTE) + if(crit_case) + L.apply_damage(squish_damage, BRUTE) + + //L.Paralyze(60) We don't have paralyze, too bad. + L.Stun(60, TRUE, TRUE) + L.Knockdown(60) + L.emote("scream") + playsound(L, 'sound/effects/blobattack.ogg', 40, TRUE) + playsound(L, 'sound/effects/splat.ogg', 50, TRUE) + + var/matrix/M = matrix() + M.Turn(pick(90, 270)) + transform = M + + if(get_turf(fatty) != get_turf(src)) + throw_at(get_turf(fatty), 1, 1, spin=FALSE) + +/obj/machinery/vending/proc/untilt(mob/user) + user.visible_message("[user] rights [src].", \ + "You right [src].") + + unbuckle_all_mobs(TRUE) + + tilted = FALSE + layer = initial(layer) + + var/matrix/M = matrix() + M.Turn(0) + transform = M /obj/machinery/vending/exchange_parts(mob/user, obj/item/storage/part_replacer/W) if(!istype(W)) @@ -345,6 +481,11 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C if(seconds_electrified && !(stat & NOPOWER)) if(shock(user, 100)) return + if(tilted && !user.buckled) + to_chat(user, "You begin righting \the [src].") + if(do_after(user, 50, target=src)) + untilt(user) + return return ..() /obj/machinery/vending/ui_interact(mob/user) diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index 514bbd87..cc345016 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -18,6 +18,7 @@ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/wallmed + tiltable = FALSE /obj/item/vending_refill/wallmed machine_name = "NanoMed" diff --git a/tgstation.dme b/tgstation.dme index 2e49929f..3333330f 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -468,6 +468,7 @@ #include "code\datums\elements\flavor_text.dm" #include "code\datums\elements\ghost_role_eligibility.dm" #include "code\datums\elements\mob_holder.dm" +#include "code\datums\elements\squish.dm" #include "code\datums\elements\swimming.dm" #include "code\datums\elements\wuv.dm" #include "code\datums\helper_datums\events.dm"