mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-16 12:07:48 +00:00
## About The Pull Request Fixes #79764 I was going to tackle this issue by slamming `TRAIT_NO_SLIP_ALL` on Atrocinator users and calling it a day, but like, that didn't feel proper. So I thought hey, we could just give them the flying movetype, even though they technically aren't flying it means they're unaffected by things that flying would make you unaffected by. Nope, this means the mob technically "negates gravity", so no falling and no feetsteps. Let's try floating - this give us feetsteps but no falling upwards. So instead of going back to square one, with `TRAIT_NO_SLIP_ALL`, I decided to go for the more complex route of just adding a movetype. Hence, move type `UPSIDE_DOWN`. This covers situations where a mob would be "floating" above the ground, but still walking. ...Negative gravity. This means overall the Atrociator acts more as you'd expect - you don't slip on ice, you don't trigger bear traps or mouse traps, you can walk over railings, unaffected by conveyor belts, etc. ## Why It's Good For The Game Makes the Atrocinator a lot more consistent with how you'd expect for it to work. Admittedly it is a bit niche use of movetypes, but it can possibly be expanded to more things in the future, who knows? I applied it to mobs on meat spikes (even though they don't move), just for proof of concept. ## Changelog 🆑 Melbert fix: Atrocinating mobs will now behave more as you'd expect. Meaning they don't slip on wet patches, can't trigger bear traps / landmines / mouse traps, ignore conveyors, and can walk over tables and railings. fix: Floating mobs are unaffected by conveyor belts, acid (on the ground), glass tables fix: Floating mobs won't squish stuff like roaches anymore fix: Fixes bear traps triggering on floating / flying mobs /🆑 --------- Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
172 lines
5.9 KiB
Plaintext
172 lines
5.9 KiB
Plaintext
#define MEATSPIKE_IRONROD_REQUIREMENT 4
|
|
|
|
/obj/structure/kitchenspike_frame
|
|
name = "meatspike frame"
|
|
icon = 'icons/obj/service/kitchen.dmi'
|
|
icon_state = "spikeframe"
|
|
desc = "The frame of a meat spike."
|
|
density = TRUE
|
|
anchored = FALSE
|
|
max_integrity = 200
|
|
|
|
/obj/structure/kitchenspike_frame/Initialize(mapload)
|
|
. = ..()
|
|
register_context()
|
|
|
|
/obj/structure/kitchenspike_frame/examine(mob/user)
|
|
. = ..()
|
|
. += "It can be <b>welded</b> apart."
|
|
. += "You could attach <b>[MEATSPIKE_IRONROD_REQUIREMENT]</b> iron rods to it to create a <b>Meat Spike</b>."
|
|
|
|
/obj/structure/kitchenspike_frame/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
|
|
if(isnull(held_item))
|
|
return NONE
|
|
|
|
var/message = ""
|
|
if(held_item.tool_behaviour == TOOL_WELDER)
|
|
message = "Deconstruct"
|
|
else if(held_item.tool_behaviour == TOOL_WRENCH)
|
|
message = "Bolt Down Frame"
|
|
|
|
if(!message)
|
|
return NONE
|
|
context[SCREENTIP_CONTEXT_LMB] = message
|
|
return CONTEXTUAL_SCREENTIP_SET
|
|
|
|
/obj/structure/kitchenspike_frame/welder_act(mob/living/user, obj/item/tool)
|
|
if(!tool.tool_start_check(user, amount = 0))
|
|
return FALSE
|
|
to_chat(user, span_notice("You begin cutting \the [src] apart..."))
|
|
if(!tool.use_tool(src, user, 5 SECONDS, volume = 50))
|
|
return TRUE
|
|
visible_message(span_notice("[user] slices apart \the [src]."),
|
|
span_notice("You cut \the [src] apart with \the [tool]."),
|
|
span_hear("You hear welding."))
|
|
new /obj/item/stack/sheet/iron(loc, MEATSPIKE_IRONROD_REQUIREMENT)
|
|
qdel(src)
|
|
return TRUE
|
|
|
|
/obj/structure/kitchenspike_frame/wrench_act(mob/living/user, obj/item/tool)
|
|
default_unfasten_wrench(user, tool)
|
|
return TRUE
|
|
|
|
/obj/structure/kitchenspike_frame/attackby(obj/item/attacking_item, mob/user, params)
|
|
add_fingerprint(user)
|
|
if(!istype(attacking_item, /obj/item/stack/rods))
|
|
return ..()
|
|
var/obj/item/stack/rods/used_rods = attacking_item
|
|
if(used_rods.get_amount() >= MEATSPIKE_IRONROD_REQUIREMENT)
|
|
used_rods.use(MEATSPIKE_IRONROD_REQUIREMENT)
|
|
balloon_alert(user, "meatspike built")
|
|
var/obj/structure/new_meatspike = new /obj/structure/kitchenspike(loc)
|
|
transfer_fingerprints_to(new_meatspike)
|
|
qdel(src)
|
|
return
|
|
balloon_alert(user, "[MEATSPIKE_IRONROD_REQUIREMENT] rods needed!")
|
|
|
|
/obj/structure/kitchenspike
|
|
name = "meat spike"
|
|
icon = 'icons/obj/service/kitchen.dmi'
|
|
icon_state = "spike"
|
|
desc = "A spike for collecting meat from animals."
|
|
density = TRUE
|
|
anchored = TRUE
|
|
buckle_lying = FALSE
|
|
can_buckle = TRUE
|
|
max_integrity = 250
|
|
|
|
/obj/structure/kitchenspike/Initialize(mapload)
|
|
. = ..()
|
|
register_context()
|
|
|
|
/obj/structure/kitchenspike/examine(mob/user)
|
|
. = ..()
|
|
. += "<b>Drag a mob</b> onto it to hook it in place."
|
|
. += "A <b>crowbar</b> could remove those spikes."
|
|
|
|
/obj/structure/kitchenspike/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
|
|
if(isnull(held_item))
|
|
return NONE
|
|
|
|
if(held_item.tool_behaviour == TOOL_CROWBAR)
|
|
context[SCREENTIP_CONTEXT_LMB] = "Remove Spikes"
|
|
return CONTEXTUAL_SCREENTIP_SET
|
|
|
|
return NONE
|
|
|
|
/obj/structure/kitchenspike/attack_paw(mob/user, list/modifiers)
|
|
return attack_hand(user, modifiers)
|
|
|
|
/obj/structure/kitchenspike/crowbar_act(mob/living/user, obj/item/tool)
|
|
if(has_buckled_mobs())
|
|
to_chat(user, span_warning("You can't do that while something's on the spike!"))
|
|
return TRUE
|
|
|
|
if(tool.use_tool(src, user, 2 SECONDS, volume = 100))
|
|
to_chat(user, span_notice("You pry the spikes out of the frame."))
|
|
deconstruct(TRUE)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/obj/structure/kitchenspike/user_buckle_mob(mob/living/target, mob/user, check_loc = TRUE)
|
|
if(!iscarbon(target) && !isanimal_or_basicmob(target))
|
|
return
|
|
if(!do_after(user, 10 SECONDS, target))
|
|
return
|
|
return ..()
|
|
|
|
/obj/structure/kitchenspike/post_buckle_mob(mob/living/target)
|
|
playsound(src.loc, 'sound/effects/splat.ogg', 25, TRUE)
|
|
target.emote("scream")
|
|
target.add_splatter_floor()
|
|
target.adjustBruteLoss(30)
|
|
target.setDir(2)
|
|
var/matrix/m180 = matrix(target.transform)
|
|
m180.Turn(180)
|
|
animate(target, transform = m180, time = 3)
|
|
target.pixel_y = target.base_pixel_y + PIXEL_Y_OFFSET_LYING
|
|
ADD_TRAIT(target, TRAIT_MOVE_UPSIDE_DOWN, REF(src))
|
|
|
|
/obj/structure/kitchenspike/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
|
|
if(buckled_mob != user)
|
|
buckled_mob.visible_message(span_notice("[user] tries to pull [buckled_mob] free of [src]!"),\
|
|
span_notice("[user] is trying to pull you off [src], opening up fresh wounds!"),\
|
|
span_hear("You hear a squishy wet noise."))
|
|
if(!do_after(user, 30 SECONDS, target = src))
|
|
if(buckled_mob?.buckled)
|
|
buckled_mob.visible_message(span_notice("[user] fails to free [buckled_mob]!"),\
|
|
span_notice("[user] fails to pull you off of [src]."))
|
|
return
|
|
|
|
else
|
|
buckled_mob.visible_message(span_warning("[buckled_mob] struggles to break free from [src]!"),\
|
|
span_notice("You struggle to break free from [src], exacerbating your wounds! (Stay still for two minutes.)"),\
|
|
span_hear("You hear a wet squishing noise.."))
|
|
buckled_mob.adjustBruteLoss(30)
|
|
if(!do_after(buckled_mob, 2 MINUTES, target = src))
|
|
if(buckled_mob?.buckled)
|
|
to_chat(buckled_mob, span_warning("You fail to free yourself!"))
|
|
return
|
|
return ..()
|
|
|
|
/obj/structure/kitchenspike/post_unbuckle_mob(mob/living/buckled_mob)
|
|
buckled_mob.adjustBruteLoss(30)
|
|
INVOKE_ASYNC(buckled_mob, TYPE_PROC_REF(/mob, emote), "scream")
|
|
buckled_mob.AdjustParalyzed(20)
|
|
var/matrix/m180 = matrix(buckled_mob.transform)
|
|
m180.Turn(180)
|
|
animate(buckled_mob, transform = m180, time = 3)
|
|
buckled_mob.pixel_y = buckled_mob.base_pixel_y + PIXEL_Y_OFFSET_LYING
|
|
REMOVE_TRAIT(buckled_mob, TRAIT_MOVE_UPSIDE_DOWN, REF(src))
|
|
|
|
/obj/structure/kitchenspike/deconstruct(disassembled = TRUE)
|
|
if(disassembled)
|
|
var/obj/structure/meatspike_frame = new /obj/structure/kitchenspike_frame(src.loc)
|
|
transfer_fingerprints_to(meatspike_frame)
|
|
else
|
|
new /obj/item/stack/sheet/iron(src.loc, 4)
|
|
new /obj/item/stack/rods(loc, MEATSPIKE_IRONROD_REQUIREMENT)
|
|
qdel(src)
|
|
|
|
#undef MEATSPIKE_IRONROD_REQUIREMENT
|