Files
Bubberstation/code/modules/vehicles/sealed.dm
MrMelbert 5261efb67f Re-refactors batons / Refactors attack chain force modifiers (#90809)
## About The Pull Request

Melee attack chain now has a list passed along with it,
`attack_modifiers`, which you can stick force modifiers to change the
resulting attack

This is basically a soft implementation of damage packets until a more
definitive pr, but one that only applies to item attack chain, and not
unarmed attacks.

This change was done to facilitate a baton refactor - batons no longer
hack together their own attack chain, and are now integrated straight
into the real attack chain. This refactor itself was done because batons
don't send any attack signals, which has been annoying in the past (for
swing combat).

## Changelog

🆑 Melbert
refactor: Batons have been refactored again. Baton stuns now properly
count as an attack, when before it was a nothing. Report any oddities,
particularly in regards to harmbatonning vs normal batonning.
refactor: The method of adjusting item damage mid-attack has been
refactored - some affected items include the Nullblade and knives.
Report any strange happenings with damage numbers.
refactor: A few objects have been moved to the new interaction chain -
records consoles, mawed crucible, alien weeds and space vines, hedges,
restaurant portals, and some mobs - to name a few.
fix: Spears only deal bonus damage against secure lockers, not all
closet types (including crates)
/🆑
2025-05-19 13:32:12 +10:00

177 lines
5.4 KiB
Plaintext

/obj/vehicle/sealed
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
interaction_flags_atom = parent_type::interaction_flags_atom | INTERACT_ATOM_IGNORE_MOBILITY
interaction_flags_mouse_drop = NEED_HANDS
var/enter_delay = 2 SECONDS
var/mouse_pointer
var/headlights_toggle = FALSE
///Determines which occupants provide access when bumping into doors
var/access_provider_flags = VEHICLE_CONTROL_DRIVE
/obj/vehicle/sealed/Initialize(mapload)
. = ..()
RegisterSignal(src, COMSIG_SUPERMATTER_CONSUMED, PROC_REF(on_entered_supermatter))
/obj/vehicle/sealed/generate_actions()
. = ..()
initialize_passenger_action_type(/datum/action/vehicle/sealed/climb_out)
/obj/vehicle/sealed/generate_action_type()
var/datum/action/vehicle/sealed/E = ..()
. = E
if(istype(E))
E.vehicle_entered_target = src
/obj/vehicle/sealed/mouse_drop_receive(atom/dropping, mob/M, params)
if(!istype(dropping) || !istype(M))
return ..()
if(M == dropping)
mob_try_enter(M)
return ..()
/obj/vehicle/sealed/Exited(atom/movable/gone, direction)
. = ..()
if(ismob(gone))
remove_occupant(gone)
// so that we can check the access of the vehicle's occupants. Ridden vehicles do this in the riding component, but these don't have that
/obj/vehicle/sealed/Bump(atom/A)
. = ..()
if(istype(A, /obj/machinery/door))
var/obj/machinery/door/conditionalwall = A
for(var/mob/occupant as anything in return_controllers_with_flag(access_provider_flags))
if(conditionalwall.try_safety_unlock(occupant))
return
conditionalwall.bumpopen(occupant)
/obj/vehicle/sealed/after_add_occupant(mob/M)
. = ..()
ADD_TRAIT(M, TRAIT_HANDS_BLOCKED, VEHICLE_TRAIT)
/obj/vehicle/sealed/after_remove_occupant(mob/M)
. = ..()
REMOVE_TRAIT(M, TRAIT_HANDS_BLOCKED, VEHICLE_TRAIT)
/obj/vehicle/sealed/proc/mob_try_enter(mob/rider)
if(!istype(rider))
return FALSE
var/enter_delay = get_enter_delay(rider)
if (enter_delay == 0)
if (enter_checks(rider))
mob_enter(rider)
return TRUE
return FALSE
if (do_after(rider, enter_delay, src, timed_action_flags = IGNORE_HELD_ITEM, extra_checks = CALLBACK(src, PROC_REF(enter_checks), rider)))
mob_enter(rider)
return TRUE
return FALSE
/// returns enter do_after delay for the given mob in ticks
/obj/vehicle/sealed/proc/get_enter_delay(mob/M)
return enter_delay
///Extra checks to perform during the do_after to enter the vehicle
/obj/vehicle/sealed/proc/enter_checks(mob/M)
return occupant_amount() < max_occupants
/obj/vehicle/sealed/proc/mob_enter(mob/M, silent = FALSE)
if(!istype(M))
return FALSE
if(!silent)
M.visible_message(span_notice("[M] climbs into \the [src]!"))
M.forceMove(src)
add_occupant(M)
return TRUE
/obj/vehicle/sealed/proc/mob_try_exit(mob/M, mob/user, silent = FALSE, randomstep = FALSE)
mob_exit(M, silent, randomstep)
/obj/vehicle/sealed/proc/mob_exit(mob/M, silent = FALSE, randomstep = FALSE)
if(!istype(M))
return FALSE
remove_occupant(M)
if(!isAI(M))//This is the ONE mob we don't want to be moved to the vehicle that should be handled when used
M.forceMove(exit_location(M))
else
return TRUE
if(randomstep)
var/turf/target_turf = get_step(exit_location(M), pick(GLOB.cardinals))
M.throw_at(target_turf, 5, 10)
if(!silent)
M.visible_message(span_notice("[M] drops out of \the [src]!"))
return TRUE
/obj/vehicle/sealed/proc/exit_location(M)
return drop_location()
/obj/vehicle/sealed/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if(key_type && !is_key(inserted_key) && is_key(I))
if(user.transferItemToLoc(I, src))
to_chat(user, span_notice("You insert [I] into [src]."))
if(inserted_key) //just in case there's an invalid key
inserted_key.forceMove(drop_location())
inserted_key = I
inserted_key.forceMove(src)
else
to_chat(user, span_warning("[I] seems to be stuck to your hand!"))
return
return ..()
/obj/vehicle/sealed/proc/remove_key(mob/user)
if(!inserted_key)
to_chat(user, span_warning("There is no key in [src]!"))
return
if(!is_occupant(user) || !(occupants[user] & VEHICLE_CONTROL_DRIVE))
to_chat(user, span_warning("You must be driving [src] to remove [src]'s key!"))
return
to_chat(user, span_notice("You remove [inserted_key] from [src]."))
if(!HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
user.put_in_hands(inserted_key)
else
inserted_key.equip_to_best_slot(user)
inserted_key = null
/obj/vehicle/sealed/Destroy()
dump_mobs()
return ..()
/obj/vehicle/sealed/proc/dump_mobs(randomstep = TRUE)
for(var/i in occupants)
mob_exit(i, randomstep = randomstep)
if(iscarbon(i))
var/mob/living/carbon/Carbon = i
Carbon.Paralyze(40)
/obj/vehicle/sealed/proc/dump_specific_mobs(flag, randomstep = TRUE)
for(var/i in occupants)
if(!(occupants[i] & flag))
continue
mob_exit(i, randomstep = randomstep)
if(iscarbon(i))
var/mob/living/carbon/C = i
C.Paralyze(40)
/obj/vehicle/sealed/AllowDrop()
return FALSE
/obj/vehicle/sealed/relaymove(mob/living/user, direction)
if(canmove)
vehicle_move(direction)
return TRUE
/// Sinced sealed vehicles (cars and mechs) don't have riding components, the actual movement is handled here from [/obj/vehicle/sealed/proc/relaymove]
/obj/vehicle/sealed/proc/vehicle_move(direction)
return FALSE
/// When we touch a crystal, kill everything inside us
/obj/vehicle/sealed/proc/on_entered_supermatter(atom/movable/vehicle, atom/movable/supermatter)
SIGNAL_HANDLER
for (var/mob/passenger as anything in occupants)
if(!isAI(passenger))
passenger.Bump(supermatter)