mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-30 11:32:20 +00:00
Makes the code compatible with 515.1594+
Few simple changes and one very painful one.
Let's start with the easy:
* puts call behind `LIBCALL` define, so call_ext is properly used in 515
* Adds `NAMEOF_STATIC(_,X)` macro for nameof in static definitions since
src is now invalid there.
* Fixes tgui and devserver. From 515 onward the tmp3333{procid} cache
directory is not appened to base path in browser controls so we don't
check for it in base js and put the dev server dummy window file in
actual directory not the byond root.
* Renames the few things that had /final/ in typepath to ultimate since
final is a new keyword
And the very painful change:
`.proc/whatever` format is no longer valid, so we're replacing it with
new nameof() function. All this wrapped in three new macros.
`PROC_REF(X)`,`TYPE_PROC_REF(TYPE,X)`,`GLOBAL_PROC_REF(X)`. Global is
not actually necessary but if we get nameof that does not allow globals
it would be nice validation.
This is pretty unwieldy but there's no real alternative.
If you notice anything weird in the commits let me know because majority
was done with regex replace.
@tgstation/commit-access Since the .proc/stuff is pretty big change.
Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
598 lines
24 KiB
Plaintext
598 lines
24 KiB
Plaintext
//General modules for MODsuits
|
|
|
|
///Storage - Adds a storage component to the suit.
|
|
/obj/item/mod/module/storage
|
|
name = "MOD storage module"
|
|
desc = "What amounts to a series of integrated storage compartments and specialized pockets installed across \
|
|
the surface of the suit, useful for storing various bits, and or bobs."
|
|
icon_state = "storage"
|
|
complexity = 3
|
|
incompatible_modules = list(/obj/item/mod/module/storage, /obj/item/mod/module/plate_compression)
|
|
/// Max weight class of items in the storage.
|
|
var/max_w_class = WEIGHT_CLASS_NORMAL
|
|
/// Max combined weight of all items in the storage.
|
|
var/max_combined_w_class = 15
|
|
/// Max amount of items in the storage.
|
|
var/max_items = 7
|
|
|
|
/obj/item/mod/module/storage/Initialize(mapload)
|
|
. = ..()
|
|
create_storage(max_specific_storage = max_w_class, max_total_storage = max_combined_w_class, max_slots = max_items)
|
|
atom_storage.allow_big_nesting = TRUE
|
|
atom_storage.locked = TRUE
|
|
|
|
/obj/item/mod/module/storage/on_install()
|
|
var/datum/storage/modstorage = mod.create_storage(max_specific_storage = max_w_class, max_total_storage = max_combined_w_class, max_slots = max_items)
|
|
modstorage.set_real_location(src)
|
|
atom_storage.locked = FALSE
|
|
RegisterSignal(mod.chestplate, COMSIG_ITEM_PRE_UNEQUIP, PROC_REF(on_chestplate_unequip))
|
|
|
|
/obj/item/mod/module/storage/on_uninstall(deleting = FALSE)
|
|
var/datum/storage/modstorage = mod.atom_storage
|
|
atom_storage.locked = TRUE
|
|
qdel(modstorage)
|
|
if(!deleting)
|
|
atom_storage.remove_all(get_turf(src))
|
|
UnregisterSignal(mod.chestplate, COMSIG_ITEM_PRE_UNEQUIP)
|
|
|
|
/obj/item/mod/module/storage/proc/on_chestplate_unequip(obj/item/source, force, atom/newloc, no_move, invdrop, silent)
|
|
if(QDELETED(source) || !mod.wearer || newloc == mod.wearer || !mod.wearer.s_store)
|
|
return
|
|
to_chat(mod.wearer, span_notice("[src] tries to store [mod.wearer.s_store] inside itself."))
|
|
if(atom_storage?.attempt_insert(mod.wearer.s_store, mod.wearer, override = TRUE))
|
|
mod.wearer.temporarilyRemoveItemFromInventory(mod.wearer.s_store)
|
|
|
|
/obj/item/mod/module/storage/large_capacity
|
|
name = "MOD expanded storage module"
|
|
desc = "Reverse engineered by Nakamura Engineering from Donk Corporation designs, this system of hidden compartments \
|
|
is entirely within the suit, distributing items and weight evenly to ensure a comfortable experience for the user; \
|
|
whether smuggling, or simply hauling."
|
|
icon_state = "storage_large"
|
|
max_combined_w_class = 21
|
|
max_items = 14
|
|
|
|
/obj/item/mod/module/storage/syndicate
|
|
name = "MOD syndicate storage module"
|
|
desc = "A storage system using nanotechnology developed by Cybersun Industries, these compartments use \
|
|
esoteric technology to compress the physical matter of items put inside of them, \
|
|
essentially shrinking items for much easier and more portable storage."
|
|
icon_state = "storage_syndi"
|
|
max_combined_w_class = 30
|
|
max_items = 21
|
|
|
|
/obj/item/mod/module/storage/belt
|
|
name = "MOD case storage module"
|
|
desc = "Some concessions had to be made when creating a compressed modular suit core. \
|
|
As a result, Roseus Galactic equipped their suit with a slimline storage case. \
|
|
If you find this equipped to a standard modular suit, then someone has almost certainly shortchanged you on a proper storage module."
|
|
icon_state = "storage_case"
|
|
complexity = 0
|
|
max_w_class = WEIGHT_CLASS_SMALL
|
|
removable = FALSE
|
|
max_combined_w_class = 21
|
|
max_items = 7
|
|
|
|
/obj/item/mod/module/storage/bluespace
|
|
name = "MOD bluespace storage module"
|
|
desc = "A storage system developed by Nanotrasen, these compartments employ \
|
|
miniaturized bluespace pockets for the ultimate in storage technology; regardless of the weight of objects put inside."
|
|
icon_state = "storage_large"
|
|
max_w_class = WEIGHT_CLASS_GIGANTIC
|
|
max_combined_w_class = 60
|
|
max_items = 21
|
|
|
|
///Ion Jetpack - Lets the user fly freely through space using battery charge.
|
|
/obj/item/mod/module/jetpack
|
|
name = "MOD ion jetpack module"
|
|
desc = "A series of electric thrusters installed across the suit, this is a module highly anticipated by trainee Engineers. \
|
|
Rather than using gasses for combustion thrust, these jets are capable of accelerating ions using \
|
|
charge from the suit's charge. Some say this isn't Nakamura Engineering's first foray into jet-enabled suits."
|
|
icon_state = "jetpack"
|
|
module_type = MODULE_TOGGLE
|
|
complexity = 3
|
|
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
|
|
use_power_cost = DEFAULT_CHARGE_DRAIN
|
|
incompatible_modules = list(/obj/item/mod/module/jetpack)
|
|
cooldown_time = 0.5 SECONDS
|
|
overlay_state_inactive = "module_jetpack"
|
|
overlay_state_active = "module_jetpack_on"
|
|
/// Do we stop the wearer from gliding in space.
|
|
var/stabilizers = FALSE
|
|
/// Do we give the wearer a speed buff.
|
|
var/full_speed = FALSE
|
|
var/datum/callback/get_mover
|
|
var/datum/callback/check_on_move
|
|
|
|
/obj/item/mod/module/jetpack/Initialize(mapload)
|
|
. = ..()
|
|
get_mover = CALLBACK(src, PROC_REF(get_user))
|
|
check_on_move = CALLBACK(src, PROC_REF(allow_thrust))
|
|
refresh_jetpack()
|
|
|
|
/obj/item/mod/module/jetpack/Destroy()
|
|
get_mover = null
|
|
check_on_move = null
|
|
return ..()
|
|
|
|
/obj/item/mod/module/jetpack/proc/refresh_jetpack()
|
|
AddComponent(/datum/component/jetpack, stabilizers, COMSIG_MODULE_TRIGGERED, COMSIG_MODULE_DEACTIVATED, MOD_ABORT_USE, get_mover, check_on_move, /datum/effect_system/trail_follow/ion/grav_allowed)
|
|
|
|
/obj/item/mod/module/jetpack/proc/set_stabilizers(new_stabilizers)
|
|
if(stabilizers == new_stabilizers)
|
|
return
|
|
stabilizers = new_stabilizers
|
|
refresh_jetpack()
|
|
|
|
/obj/item/mod/module/jetpack/on_activation()
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
if(full_speed)
|
|
mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed)
|
|
|
|
/obj/item/mod/module/jetpack/on_deactivation(display_message = TRUE, deleting = FALSE)
|
|
. = ..()
|
|
if(full_speed)
|
|
mod.wearer.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed)
|
|
|
|
/obj/item/mod/module/jetpack/get_configuration()
|
|
. = ..()
|
|
.["stabilizers"] = add_ui_configuration("Stabilizers", "bool", stabilizers)
|
|
|
|
/obj/item/mod/module/jetpack/configure_edit(key, value)
|
|
switch(key)
|
|
if("stabilizers")
|
|
set_stabilizers(text2num(value))
|
|
|
|
/obj/item/mod/module/jetpack/proc/allow_thrust(use_fuel = TRUE)
|
|
if(!use_fuel)
|
|
return check_power(use_power_cost)
|
|
if(!drain_power(use_power_cost))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/obj/item/mod/module/jetpack/proc/get_user()
|
|
return mod.wearer
|
|
|
|
/obj/item/mod/module/jetpack/advanced
|
|
name = "MOD advanced ion jetpack module"
|
|
desc = "An improvement on the previous model of electric thrusters. This one achieves higher speeds through \
|
|
mounting of more jets and a red paint applied on it."
|
|
icon_state = "jetpack_advanced"
|
|
overlay_state_inactive = "module_jetpackadv"
|
|
overlay_state_active = "module_jetpackadv_on"
|
|
full_speed = TRUE
|
|
|
|
///Eating Apparatus - Lets the user eat/drink with the suit on.
|
|
/obj/item/mod/module/mouthhole
|
|
name = "MOD eating apparatus module"
|
|
desc = "A favorite by Miners, this modification to the helmet utilizes a nanotechnology barrier infront of the mouth \
|
|
to allow eating and drinking while retaining protection and atmosphere. However, it won't free you from masks, \
|
|
lets pepper spray pass through and it will do nothing to improve the taste of a goliath steak."
|
|
icon_state = "apparatus"
|
|
complexity = 1
|
|
incompatible_modules = list(/obj/item/mod/module/mouthhole)
|
|
overlay_state_inactive = "module_apparatus"
|
|
/// Former flags of the helmet.
|
|
var/former_flags = NONE
|
|
/// Former visor flags of the helmet.
|
|
var/former_visor_flags = NONE
|
|
|
|
/obj/item/mod/module/mouthhole/on_install()
|
|
former_flags = mod.helmet.flags_cover
|
|
former_visor_flags = mod.helmet.visor_flags_cover
|
|
mod.helmet.flags_cover &= ~HEADCOVERSMOUTH|PEPPERPROOF
|
|
mod.helmet.visor_flags_cover &= ~HEADCOVERSMOUTH|PEPPERPROOF
|
|
|
|
/obj/item/mod/module/mouthhole/on_uninstall(deleting = FALSE)
|
|
if(deleting)
|
|
return
|
|
mod.helmet.flags_cover |= former_flags
|
|
mod.helmet.visor_flags_cover |= former_visor_flags
|
|
|
|
///EMP Shield - Protects the suit from EMPs.
|
|
/obj/item/mod/module/emp_shield
|
|
name = "MOD EMP shield module"
|
|
desc = "A field inhibitor installed into the suit, protecting it against feedback such as \
|
|
electromagnetic pulses that would otherwise damage the electronic systems of the suit or it's modules. \
|
|
However, it will take from the suit's power to do so."
|
|
icon_state = "empshield"
|
|
complexity = 1
|
|
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
|
incompatible_modules = list(/obj/item/mod/module/emp_shield)
|
|
|
|
/obj/item/mod/module/emp_shield/on_install()
|
|
mod.AddElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_WIRES|EMP_PROTECT_CONTENTS)
|
|
|
|
/obj/item/mod/module/emp_shield/on_uninstall(deleting = FALSE)
|
|
mod.RemoveElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_WIRES|EMP_PROTECT_CONTENTS)
|
|
|
|
/obj/item/mod/module/emp_shield/advanced
|
|
name = "MOD advanced EMP shield module"
|
|
desc = "An advanced field inhibitor installed into the suit, protecting it against feedback such as \
|
|
electromagnetic pulses that would otherwise damage the electronic systems of the suit or electronic devices on the wearer, \
|
|
including augmentations. However, it will take from the suit's power to do so."
|
|
complexity = 2
|
|
|
|
/obj/item/mod/module/emp_shield/advanced/on_suit_activation()
|
|
mod.wearer.AddElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_CONTENTS)
|
|
|
|
/obj/item/mod/module/emp_shield/advanced/on_suit_deactivation(deleting)
|
|
mod.wearer.RemoveElement(/datum/element/empprotection, EMP_PROTECT_SELF|EMP_PROTECT_CONTENTS)
|
|
|
|
///Flashlight - Gives the suit a customizable flashlight.
|
|
/obj/item/mod/module/flashlight
|
|
name = "MOD flashlight module"
|
|
desc = "A simple pair of configurable flashlights installed on the left and right sides of the helmet, \
|
|
useful for providing light in a variety of ranges and colors. \
|
|
Some survivalists prefer the color green for their illumination, for reasons unknown."
|
|
icon_state = "flashlight"
|
|
module_type = MODULE_TOGGLE
|
|
complexity = 1
|
|
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
|
incompatible_modules = list(/obj/item/mod/module/flashlight)
|
|
cooldown_time = 0.5 SECONDS
|
|
overlay_state_inactive = "module_light"
|
|
light_system = MOVABLE_LIGHT_DIRECTIONAL
|
|
light_color = COLOR_WHITE
|
|
light_range = 4
|
|
light_power = 1
|
|
light_on = FALSE
|
|
/// Charge drain per range amount.
|
|
var/base_power = DEFAULT_CHARGE_DRAIN * 0.1
|
|
/// Minimum range we can set.
|
|
var/min_range = 2
|
|
/// Maximum range we can set.
|
|
var/max_range = 5
|
|
|
|
/obj/item/mod/module/flashlight/on_activation()
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
set_light_flags(light_flags | LIGHT_ATTACHED)
|
|
set_light_on(active)
|
|
active_power_cost = base_power * light_range
|
|
|
|
/obj/item/mod/module/flashlight/on_deactivation(display_message = TRUE, deleting = FALSE)
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
set_light_flags(light_flags & ~LIGHT_ATTACHED)
|
|
set_light_on(active)
|
|
|
|
/obj/item/mod/module/flashlight/on_process(delta_time)
|
|
active_power_cost = base_power * light_range
|
|
return ..()
|
|
|
|
/obj/item/mod/module/flashlight/generate_worn_overlay(mutable_appearance/standing)
|
|
. = ..()
|
|
if(!active)
|
|
return
|
|
var/mutable_appearance/light_icon = mutable_appearance(overlay_icon_file, "module_light_on", layer = standing.layer + 0.2)
|
|
light_icon.appearance_flags = RESET_COLOR
|
|
light_icon.color = light_color
|
|
. += light_icon
|
|
|
|
/obj/item/mod/module/flashlight/get_configuration()
|
|
. = ..()
|
|
.["light_color"] = add_ui_configuration("Light Color", "color", light_color)
|
|
.["light_range"] = add_ui_configuration("Light Range", "number", light_range)
|
|
|
|
/obj/item/mod/module/flashlight/configure_edit(key, value)
|
|
switch(key)
|
|
if("light_color")
|
|
value = input(usr, "Pick new light color", "Flashlight Color") as color|null
|
|
if(!value)
|
|
return
|
|
if(is_color_dark(value, 50))
|
|
balloon_alert(mod.wearer, "too dark!")
|
|
return
|
|
set_light_color(value)
|
|
mod.wearer.update_clothing(mod.slot_flags)
|
|
if("light_range")
|
|
set_light_range(clamp(value, min_range, max_range))
|
|
|
|
///Dispenser - Dispenses an item after a time passes.
|
|
/obj/item/mod/module/dispenser
|
|
name = "MOD burger dispenser module"
|
|
desc = "A rare piece of technology reverse-engineered from a prototype found in a Donk Corporation vessel. \
|
|
This can draw incredible amounts of power from the suit's charge to create edible organic matter in the \
|
|
palm of the wearer's glove; however, research seemed to have entirely stopped at burgers. \
|
|
Notably, all attempts to get it to dispense Earl Grey tea have failed."
|
|
icon_state = "dispenser"
|
|
module_type = MODULE_USABLE
|
|
complexity = 3
|
|
use_power_cost = DEFAULT_CHARGE_DRAIN * 2
|
|
incompatible_modules = list(/obj/item/mod/module/dispenser)
|
|
cooldown_time = 5 SECONDS
|
|
/// Path we dispense.
|
|
var/dispense_type = /obj/item/food/burger/plain
|
|
/// Time it takes for us to dispense.
|
|
var/dispense_time = 0 SECONDS
|
|
|
|
/obj/item/mod/module/dispenser/on_use()
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
if(dispense_time && !do_after(mod.wearer, dispense_time, target = mod))
|
|
balloon_alert(mod.wearer, "interrupted!")
|
|
return FALSE
|
|
var/obj/item/dispensed = new dispense_type(mod.wearer.loc)
|
|
mod.wearer.put_in_hands(dispensed)
|
|
balloon_alert(mod.wearer, "[dispensed] dispensed")
|
|
playsound(src, 'sound/machines/click.ogg', 100, TRUE)
|
|
drain_power(use_power_cost)
|
|
return dispensed
|
|
|
|
///Longfall - Nullifies fall damage, removing charge instead.
|
|
/obj/item/mod/module/longfall
|
|
name = "MOD longfall module"
|
|
desc = "Useful for protecting both the suit and the wearer, \
|
|
utilizing commonplace systems to convert the possible damage from a fall into kinetic charge, \
|
|
as well as internal gyroscopes to ensure the user's safe falling. \
|
|
Useful for mining, monorail tracks, or even skydiving!"
|
|
icon_state = "longfall"
|
|
complexity = 1
|
|
use_power_cost = DEFAULT_CHARGE_DRAIN * 5
|
|
incompatible_modules = list(/obj/item/mod/module/longfall)
|
|
|
|
/obj/item/mod/module/longfall/on_suit_activation()
|
|
RegisterSignal(mod.wearer, COMSIG_LIVING_Z_IMPACT, PROC_REF(z_impact_react))
|
|
|
|
/obj/item/mod/module/longfall/on_suit_deactivation(deleting = FALSE)
|
|
UnregisterSignal(mod.wearer, COMSIG_LIVING_Z_IMPACT)
|
|
|
|
/obj/item/mod/module/longfall/proc/z_impact_react(datum/source, levels, turf/fell_on)
|
|
if(!drain_power(use_power_cost*levels))
|
|
return
|
|
new /obj/effect/temp_visual/mook_dust(fell_on)
|
|
mod.wearer.Stun(levels * 1 SECONDS)
|
|
to_chat(mod.wearer, span_notice("[src] protects you from the damage!"))
|
|
return NO_Z_IMPACT_DAMAGE
|
|
|
|
///Thermal Regulator - Regulates the wearer's core temperature.
|
|
/obj/item/mod/module/thermal_regulator
|
|
name = "MOD thermal regulator module"
|
|
desc = "Advanced climate control, using an inner body glove interwoven with thousands of tiny, \
|
|
flexible cooling lines. This circulates coolant at various user-controlled temperatures, \
|
|
ensuring they're comfortable; even if they're some that like it hot."
|
|
icon_state = "regulator"
|
|
module_type = MODULE_TOGGLE
|
|
complexity = 2
|
|
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
|
incompatible_modules = list(/obj/item/mod/module/thermal_regulator)
|
|
cooldown_time = 0.5 SECONDS
|
|
/// The temperature we are regulating to.
|
|
var/temperature_setting = BODYTEMP_NORMAL
|
|
/// Minimum temperature we can set.
|
|
var/min_temp = 293.15
|
|
/// Maximum temperature we can set.
|
|
var/max_temp = 318.15
|
|
|
|
/obj/item/mod/module/thermal_regulator/get_configuration()
|
|
. = ..()
|
|
.["temperature_setting"] = add_ui_configuration("Temperature", "number", temperature_setting - T0C)
|
|
|
|
/obj/item/mod/module/thermal_regulator/configure_edit(key, value)
|
|
switch(key)
|
|
if("temperature_setting")
|
|
temperature_setting = clamp(value + T0C, min_temp, max_temp)
|
|
|
|
/obj/item/mod/module/thermal_regulator/on_active_process(delta_time)
|
|
mod.wearer.adjust_bodytemperature(get_temp_change_amount((temperature_setting - mod.wearer.bodytemperature), 0.08 * delta_time))
|
|
|
|
///DNA Lock - Prevents people without the set DNA from activating the suit.
|
|
/obj/item/mod/module/dna_lock
|
|
name = "MOD DNA lock module"
|
|
desc = "A module which engages with the various locks and seals tied to the suit's systems, \
|
|
enabling it to only be worn by someone corresponding with the user's exact DNA profile; \
|
|
however, this incredibly sensitive module is shorted out by EMPs. Luckily, cloning has been outlawed."
|
|
icon_state = "dnalock"
|
|
module_type = MODULE_USABLE
|
|
complexity = 2
|
|
use_power_cost = DEFAULT_CHARGE_DRAIN * 3
|
|
incompatible_modules = list(/obj/item/mod/module/dna_lock, /obj/item/mod/module/eradication_lock)
|
|
cooldown_time = 0.5 SECONDS
|
|
/// The DNA we lock with.
|
|
var/dna = null
|
|
|
|
/obj/item/mod/module/dna_lock/on_install()
|
|
RegisterSignal(mod, COMSIG_MOD_ACTIVATE, PROC_REF(on_mod_activation))
|
|
RegisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL, PROC_REF(on_mod_removal))
|
|
RegisterSignal(mod, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp))
|
|
RegisterSignal(mod, COMSIG_ATOM_EMAG_ACT, PROC_REF(on_emag))
|
|
|
|
/obj/item/mod/module/dna_lock/on_uninstall(deleting = FALSE)
|
|
UnregisterSignal(mod, COMSIG_MOD_ACTIVATE)
|
|
UnregisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL)
|
|
UnregisterSignal(mod, COMSIG_ATOM_EMP_ACT)
|
|
UnregisterSignal(mod, COMSIG_ATOM_EMAG_ACT)
|
|
|
|
/obj/item/mod/module/dna_lock/on_use()
|
|
. = ..()
|
|
if(!.)
|
|
return
|
|
dna = mod.wearer.dna.unique_enzymes
|
|
balloon_alert(mod.wearer, "dna updated")
|
|
drain_power(use_power_cost)
|
|
|
|
/obj/item/mod/module/dna_lock/emp_act(severity)
|
|
. = ..()
|
|
if(. & EMP_PROTECT_SELF)
|
|
return
|
|
on_emp(src, severity)
|
|
|
|
/obj/item/mod/module/dna_lock/emag_act(mob/user, obj/item/card/emag/emag_card)
|
|
. = ..()
|
|
on_emag(src, user, emag_card)
|
|
|
|
/obj/item/mod/module/dna_lock/proc/dna_check(mob/user)
|
|
if(!iscarbon(user))
|
|
return FALSE
|
|
var/mob/living/carbon/carbon_user = user
|
|
if(!dna || (carbon_user.has_dna() && carbon_user.dna.unique_enzymes == dna))
|
|
return TRUE
|
|
balloon_alert(user, "dna locked!")
|
|
return FALSE
|
|
|
|
/obj/item/mod/module/dna_lock/proc/on_emp(datum/source, severity)
|
|
SIGNAL_HANDLER
|
|
|
|
dna = null
|
|
|
|
/obj/item/mod/module/dna_lock/proc/on_emag(datum/source, mob/user, obj/item/card/emag/emag_card)
|
|
SIGNAL_HANDLER
|
|
|
|
dna = null
|
|
|
|
/obj/item/mod/module/dna_lock/proc/on_mod_activation(datum/source, mob/user)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!dna_check(user))
|
|
return MOD_CANCEL_ACTIVATE
|
|
|
|
/obj/item/mod/module/dna_lock/proc/on_mod_removal(datum/source, mob/user)
|
|
SIGNAL_HANDLER
|
|
|
|
if(!dna_check(user))
|
|
return MOD_CANCEL_REMOVAL
|
|
|
|
///Plasma Stabilizer - Prevents plasmamen from igniting in the suit
|
|
/obj/item/mod/module/plasma_stabilizer
|
|
name = "MOD plasma stabilizer module"
|
|
desc = "This system essentially forms an atmosphere of its own, within the suit, \
|
|
efficiently and quickly preventing oxygen from causing the user's head to burst into flame. \
|
|
This allows plasmamen to safely remove their helmet, allowing for easier \
|
|
equipping of any MODsuit-related equipment, or otherwise. \
|
|
The purple glass of the visor seems to be constructed for nostalgic purposes."
|
|
icon_state = "plasma_stabilizer"
|
|
complexity = 1
|
|
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
|
incompatible_modules = list(/obj/item/mod/module/plasma_stabilizer)
|
|
overlay_state_inactive = "module_plasma"
|
|
|
|
/obj/item/mod/module/plasma_stabilizer/on_equip()
|
|
ADD_TRAIT(mod.wearer, TRAIT_NOSELFIGNITION_HEAD_ONLY, MOD_TRAIT)
|
|
|
|
/obj/item/mod/module/plasma_stabilizer/on_unequip()
|
|
REMOVE_TRAIT(mod.wearer, TRAIT_NOSELFIGNITION_HEAD_ONLY, MOD_TRAIT)
|
|
|
|
|
|
//Finally, https://pipe.miroware.io/5b52ba1d94357d5d623f74aa/mspfa/Nuke%20Ops/Panels/0648.gif can be real:
|
|
///Hat Stabilizer - Allows displaying a hat over the MOD-helmet, à la plasmamen helmets.
|
|
/obj/item/mod/module/hat_stabilizer
|
|
name = "MOD hat stabilizer module"
|
|
desc = "A simple set of deployable stands, directly atop one's head; \
|
|
these will deploy under a select few hats to keep them from falling off, allowing them to be worn atop the sealed helmet. \
|
|
You still need to take the hat off your head while the helmet deploys, though. \
|
|
This is a must-have for Nanotrasen Captains, enabling them to show off their authoritative hat even while in their MODsuit."
|
|
icon_state = "hat_holder"
|
|
incompatible_modules = list(/obj/item/mod/module/hat_stabilizer)
|
|
/*Intentionally left inheriting 0 complexity and removable = TRUE;
|
|
even though it comes inbuilt into the Magnate/Corporate MODS and spawns in maints, I like the idea of stealing them*/
|
|
/// Currently "stored" hat. No armor or function will be inherited, ONLY the icon.
|
|
var/obj/item/clothing/head/attached_hat
|
|
/// Whitelist of attachable hats, read note in Initialize() below this line
|
|
var/static/list/attachable_hats_list
|
|
|
|
/obj/item/mod/module/hat_stabilizer/Initialize(mapload)
|
|
. = ..()
|
|
attachable_hats_list = typecacheof(
|
|
//List of attachable hats. Make sure these and their subtypes are all tested, so they dont appear janky.
|
|
//This list should also be gimmicky, so captains can have fun. I.E. the Santahat, Pirate hat, Tophat, Chefhat...
|
|
//Yes, I said it, the captain should have fun.
|
|
list(
|
|
/obj/item/clothing/head/hats/caphat,
|
|
/obj/item/clothing/head/costume/crown,
|
|
/obj/item/clothing/head/hats/centhat,
|
|
/obj/item/clothing/head/hats/centcom_cap,
|
|
/obj/item/clothing/head/costume/pirate,
|
|
/obj/item/clothing/head/costume/santa,
|
|
/obj/item/clothing/head/utility/hardhat/reindeer,
|
|
/obj/item/clothing/head/costume/sombrero/green,
|
|
/obj/item/clothing/head/costume/kitty,
|
|
/obj/item/clothing/head/costume/rabbitears,
|
|
/obj/item/clothing/head/costume/festive,
|
|
/obj/item/clothing/head/costume/powdered_wig,
|
|
/obj/item/clothing/head/costume/weddingveil,
|
|
/obj/item/clothing/head/hats/tophat,
|
|
/obj/item/clothing/head/costume/nursehat,
|
|
/obj/item/clothing/head/utility/chefhat,
|
|
/obj/item/clothing/head/costume/papersack,
|
|
/obj/item/clothing/head/caphat/beret,
|
|
))
|
|
|
|
/obj/item/mod/module/hat_stabilizer/on_suit_activation()
|
|
RegisterSignal(mod.helmet, COMSIG_PARENT_EXAMINE, PROC_REF(add_examine))
|
|
RegisterSignal(mod.helmet, COMSIG_PARENT_ATTACKBY, PROC_REF(place_hat))
|
|
RegisterSignal(mod.helmet, COMSIG_ATOM_ATTACK_HAND_SECONDARY, PROC_REF(remove_hat))
|
|
|
|
/obj/item/mod/module/hat_stabilizer/on_suit_deactivation(deleting = FALSE)
|
|
if(deleting)
|
|
return
|
|
if(attached_hat) //knock off the helmet if its on their head. Or, technically, auto-rightclick it for them; that way it saves us code, AND gives them the bubble
|
|
remove_hat(src, mod.wearer)
|
|
UnregisterSignal(mod.helmet, COMSIG_PARENT_EXAMINE)
|
|
UnregisterSignal(mod.helmet, COMSIG_PARENT_ATTACKBY)
|
|
UnregisterSignal(mod.helmet, COMSIG_ATOM_ATTACK_HAND_SECONDARY)
|
|
|
|
/obj/item/mod/module/hat_stabilizer/proc/add_examine(datum/source, mob/user, list/base_examine)
|
|
SIGNAL_HANDLER
|
|
if(attached_hat)
|
|
base_examine += span_notice("There's \a [attached_hat] placed on the helmet. Right-click to remove it.")
|
|
else
|
|
base_examine += span_notice("There's nothing placed on the helmet. Yet.")
|
|
|
|
/obj/item/mod/module/hat_stabilizer/proc/place_hat(datum/source, obj/item/hitting_item, mob/user)
|
|
SIGNAL_HANDLER
|
|
if(!istype(hitting_item, /obj/item/clothing/head))
|
|
return
|
|
if(!mod.active)
|
|
balloon_alert(user, "suit must be active!")
|
|
return
|
|
if(!is_type_in_typecache(hitting_item, attachable_hats_list))
|
|
balloon_alert(user, "this hat won't fit!")
|
|
return
|
|
if(attached_hat)
|
|
balloon_alert(user, "hat already attached!")
|
|
return
|
|
if(mod.wearer.transferItemToLoc(hitting_item, src, force = FALSE, silent = TRUE))
|
|
attached_hat = hitting_item
|
|
balloon_alert(user, "hat attached, right-click to remove")
|
|
mod.wearer.update_clothing(mod.slot_flags)
|
|
|
|
/obj/item/mod/module/hat_stabilizer/generate_worn_overlay()
|
|
. = ..()
|
|
if(attached_hat)
|
|
. += attached_hat.build_worn_icon(default_layer = ABOVE_BODY_FRONT_HEAD_LAYER-0.1, default_icon_file = 'icons/mob/clothing/head/default.dmi')
|
|
|
|
/obj/item/mod/module/hat_stabilizer/proc/remove_hat(datum/source, mob/user)
|
|
SIGNAL_HANDLER
|
|
. = SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
|
|
if(!attached_hat)
|
|
return
|
|
attached_hat.forceMove(drop_location())
|
|
if(user.put_in_active_hand(attached_hat))
|
|
balloon_alert(user, "hat removed")
|
|
else
|
|
balloon_alert_to_viewers("the hat falls to the floor!")
|
|
attached_hat = null
|
|
mod.wearer.update_clothing(mod.slot_flags)
|
|
|
|
///Sign Language Translator - allows people to sign over comms using the modsuit's gloves.
|
|
/obj/item/mod/module/signlang_radio
|
|
name = "MOD glove translator module"
|
|
desc = "A module that adds motion sensors into the suit's gloves, \
|
|
which works in tandem with a short-range subspace transmitter, \
|
|
letting the audibly impaired use sign language over comms."
|
|
icon_state = "signlang_radio"
|
|
complexity = 1
|
|
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
|
|
incompatible_modules = list(/obj/item/mod/module/signlang_radio)
|
|
|
|
/obj/item/mod/module/signlang_radio/on_suit_activation()
|
|
ADD_TRAIT(mod.wearer, TRAIT_CAN_SIGN_ON_COMMS, MOD_TRAIT)
|
|
|
|
/obj/item/mod/module/signlang_radio/on_suit_deactivation(deleting = FALSE)
|
|
REMOVE_TRAIT(mod.wearer, TRAIT_CAN_SIGN_ON_COMMS, MOD_TRAIT)
|