Files
Bubberstation/code/modules/power/lighting/light_items.dm
SkyratBot 3fa98bd2cc [MIRROR] Adds UPSIDE_DOWN movetype for negative gravity / makes Atrocinator affected by less things [MDB IGNORE] (#25155)
* Adds `UPSIDE_DOWN` movetype for negative gravity / makes Atrocinator affected by less things (#79785)

## 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>

* Adds `UPSIDE_DOWN` movetype for negative gravity / makes Atrocinator affected by less things

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Ghom <42542238+Ghommie@ users.noreply.github.com>
2023-11-20 17:10:59 -05:00

143 lines
4.6 KiB
Plaintext

// the light item
// can be tube or bulb subtypes
// will fit into empty /obj/machinery/light of the corresponding type
/obj/item/light
icon = 'icons/obj/lighting.dmi'
force = 2
throwforce = 5
w_class = WEIGHT_CLASS_TINY
custom_materials = list(/datum/material/glass=SMALL_MATERIAL_AMOUNT)
grind_results = list(/datum/reagent/silicon = 5, /datum/reagent/nitrogen = 10) //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs
///How much light it gives off
var/brightness = 2
///LIGHT_OK, LIGHT_BURNED or LIGHT_BROKEN
var/status = LIGHT_OK
///Base icon state for each bulb types
var/base_state
///Number of times switched on and off
var/switchcount = 0
/obj/item/light/Initialize(mapload)
. = ..()
create_reagents(LIGHT_REAGENT_CAPACITY, INJECTABLE | DRAINABLE | SEALED_CONTAINER | TRANSPARENT)
AddComponent(/datum/component/caltrop, min_damage = force)
update_icon_state()
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
)
AddElement(/datum/element/connect_loc, loc_connections)
AddElement(/datum/element/update_icon_updates_onmob)
AddComponent(/datum/component/golem_food, golem_food_key = /obj/item/light, extra_validation = CALLBACK(src, PROC_REF(is_intact)))
/obj/item/light/attackby(obj/item/attacking_item, mob/user, params)
. = ..()
if(istype(attacking_item, /obj/item/lightreplacer))
var/obj/item/lightreplacer/lightreplacer = attacking_item
lightreplacer.attackby(src, user)
/// Returns true if bulb is intact
/obj/item/light/proc/is_intact()
return status == LIGHT_OK
/obj/item/light/suicide_act(mob/living/carbon/user)
if (status == LIGHT_BROKEN)
user.visible_message(span_suicide("[user] begins to stab [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!"))
else
user.visible_message(span_suicide("[user] begins to eat \the [src]! It looks like [user.p_theyre()] not very bright!"))
shatter()
return BRUTELOSS
/obj/item/light/tube
name = "light tube"
desc = "A replacement light tube."
icon_state = "ltube"
base_state = "ltube"
inhand_icon_state = "ltube"
brightness = 8
custom_price = PAYCHECK_CREW * 0.5
/obj/item/light/tube/update_icon_state()
. = ..()
switch(status)
if(LIGHT_BURNED)
inhand_icon_state = "[base_state]-burned"
if(LIGHT_BROKEN)
inhand_icon_state = "[base_state]-broken"
/obj/item/light/tube/broken
status = LIGHT_BROKEN
sharpness = SHARP_POINTY
/obj/item/light/bulb
name = "light bulb"
desc = "A replacement light bulb."
icon_state = "lbulb"
base_state = "lbulb"
inhand_icon_state = "contvapour"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
brightness = 4
custom_price = PAYCHECK_CREW * 0.4
/obj/item/light/bulb/broken
status = LIGHT_BROKEN
sharpness = SHARP_POINTY
/obj/item/light/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum)
if(!..()) //not caught by a mob
shatter()
// update the icon state and description of the light
/obj/item/light/update_icon_state()
. = ..()
switch(status)
if(LIGHT_OK)
icon_state = base_state
if(LIGHT_BURNED)
icon_state = "[base_state]-burned"
if(LIGHT_BROKEN)
icon_state = "[base_state]-broken"
/obj/item/light/update_desc()
. = ..()
switch(status)
if(LIGHT_OK)
desc = "A replacement [name]."
if(LIGHT_BURNED)
desc = "A burnt-out [name]."
if(LIGHT_BROKEN)
desc = "A broken [name]."
/obj/item/light/proc/on_entered(datum/source, atom/movable/moving_atom)
SIGNAL_HANDLER
if(!isliving(moving_atom))
return
var/mob/living/moving_mob = moving_atom
if(!(moving_mob.movement_type & MOVETYPES_NOT_TOUCHING_GROUND) || moving_mob.buckled)
playsound(src, 'sound/effects/footstep/glass_step.ogg', HAS_TRAIT(moving_mob, TRAIT_LIGHT_STEP) ? 30 : 50, TRUE)
if(status == LIGHT_BURNED || status == LIGHT_OK)
shatter(moving_mob)
/obj/item/light/attack(mob/living/M, mob/living/user, def_zone)
..()
shatter(M)
/obj/item/light/attack_atom(obj/O, mob/living/user, params)
..()
shatter(O)
/obj/item/light/proc/shatter(target)
if(status == LIGHT_OK || status == LIGHT_BURNED)
visible_message(span_danger("[src] shatters."),span_hear("You hear a small glass object shatter."))
status = LIGHT_BROKEN
force = 5
sharpness = SHARP_POINTY
playsound(loc, 'sound/effects/glasshit.ogg', 75, TRUE)
if(length(reagents.reagent_list))
visible_message(span_danger("The contents of [src] splash onto you as you step on it!"),span_hear("You feel the contents of [src] splash onto you as you step on it!."))
reagents.expose(target, TOUCH)
update_appearance(UPDATE_DESC | UPDATE_ICON)