Revert "MODsuits"

This commit is contained in:
Jerry Wester
2023-01-08 17:30:26 -07:00
committed by GitHub
parent efb2d19cb9
commit ae347f3399
87 changed files with 40 additions and 6809 deletions

View File

@@ -1,357 +0,0 @@
/obj/item/mod/module
name = "MOD module"
icon = 'icons/obj/clothing/modsuit/mod_modules.dmi'
icon_state = "module"
/// If it can be removed
var/removable = TRUE
/// If it's passive, togglable, usable or active
var/module_type = MODULE_PASSIVE
/// Is the module active
var/active = FALSE
/// How much space it takes up in the MOD
var/complexity = 0
/// Power use when idle
var/idle_power_cost = DEFAULT_CHARGE_DRAIN * 0
/// Power use when active
var/active_power_cost = DEFAULT_CHARGE_DRAIN * 0
/// Power use when used, we call it manually
var/use_power_cost = DEFAULT_CHARGE_DRAIN * 0
/// ID used by their TGUI
var/tgui_id
/// Linked MODsuit
var/obj/item/mod/control/mod
/// If we're an active module, what item are we?
var/obj/item/device
/// Overlay given to the user when the module is inactive
var/overlay_state_inactive
/// Overlay given to the user when the module is active
var/overlay_state_active
/// Overlay given to the user when the module is used, lasts until cooldown finishes
var/overlay_state_use
/// Icon file for the overlay.
var/overlay_icon_file = 'icons/mob/clothing/modsuit/mod_modules.dmi'
/// Does the overlay use the control unit's colors?
var/use_mod_colors = FALSE
/// What modules are we incompatible with?
var/list/incompatible_modules = list()
/// Cooldown after use
var/cooldown_time = 0
/// The mouse button needed to use this module
var/used_signal
/// If we're allowed to use this module while phased out.
var/allowed_in_phaseout = FALSE
/// If we're allowed to use this module while the suit is disabled.
var/allowed_inactive = FALSE
/// Timer for the cooldown
COOLDOWN_DECLARE(cooldown_timer)
/obj/item/mod/module/Initialize(mapload)
. = ..()
if(module_type != MODULE_ACTIVE)
return
if(ispath(device))
device = new device(src)
ADD_TRAIT(device, TRAIT_NODROP, MOD_TRAIT)
RegisterSignal(device, COMSIG_PARENT_PREQDELETED, .proc/on_device_deletion)
RegisterSignal(src, COMSIG_ATOM_EXITED, .proc/on_exit)
/obj/item/mod/module/Destroy()
mod?.uninstall(src)
if(device)
UnregisterSignal(device, COMSIG_PARENT_PREQDELETED)
QDEL_NULL(device)
return ..()
/obj/item/mod/module/examine(mob/user)
. = ..()
if(user.hud_list[DIAG_HUD] && user.client.images & user.hud_list[DIAG_HUD])
. += span_notice("Complexity level: [complexity]")
/// Called from MODsuit's install() proc, so when the module is installed.
/obj/item/mod/module/proc/on_install()
return
/// Called from MODsuit's uninstall() proc, so when the module is uninstalled.
/obj/item/mod/module/proc/on_uninstall()
return
/// Called when the MODsuit is activated
/obj/item/mod/module/proc/on_suit_activation()
return
/// Called when the MODsuit is deactivated
/obj/item/mod/module/proc/on_suit_deactivation()
return
/// Called when the MODsuit is equipped
/obj/item/mod/module/proc/on_equip()
return
/// Called when the MODsuit is unequipped
/obj/item/mod/module/proc/on_unequip()
return
/// Called when the module is selected from the TGUI
/obj/item/mod/module/proc/on_select()
if(((!mod.active || mod.activating) && !allowed_inactive) || module_type == MODULE_PASSIVE)
if(mod.wearer)
balloon_alert(mod.wearer, "not active!")
return
if(module_type != MODULE_USABLE)
if(active)
on_deactivation()
else
on_activation()
else
on_use()
SEND_SIGNAL(mod, COMSIG_MOD_MODULE_SELECTED, src)
/// Called when the module is activated
/obj/item/mod/module/proc/on_activation()
if(!COOLDOWN_FINISHED(src, cooldown_timer))
balloon_alert(mod.wearer, "on cooldown!")
return FALSE
if(!mod.active || mod.activating || !mod.cell?.charge)
balloon_alert(mod.wearer, "unpowered!")
return FALSE
if(!allowed_in_phaseout && istype(mod.wearer.loc, /obj/effect/dummy/phased_mob))
//specifically a to_chat because the user is phased out.
to_chat(mod.wearer, span_warning("You cannot activate this right now."))
return FALSE
if(module_type == MODULE_ACTIVE)
if(mod.selected_module && !mod.selected_module.on_deactivation())
return
mod.selected_module = src
if(device)
if(mod.wearer.put_in_hands(device))
balloon_alert(mod.wearer, "[device] extended")
RegisterSignal(mod.wearer, COMSIG_ATOM_EXITED, .proc/on_exit)
else
balloon_alert(mod.wearer, "can't extend [device]!")
return
else
update_signal()
balloon_alert(mod.wearer, "[src] activated, alt-click to use")
active = TRUE
mod.wearer.update_inv_back()
return TRUE
/// Called when the module is deactivated
/obj/item/mod/module/proc/on_deactivation()
active = FALSE
if(module_type == MODULE_ACTIVE)
mod.selected_module = null
if(device)
mod.wearer.transferItemToLoc(device, src, TRUE)
balloon_alert(mod.wearer, "[device] retracted")
UnregisterSignal(mod.wearer, COMSIG_ATOM_EXITED)
else
balloon_alert(mod.wearer, "[src] deactivated")
UnregisterSignal(mod.wearer, used_signal)
used_signal = null
mod.wearer.update_inv_back()
return TRUE
/// Called when the module is used
/obj/item/mod/module/proc/on_use()
if(!COOLDOWN_FINISHED(src, cooldown_timer))
return FALSE
if(!check_power(use_power_cost))
return FALSE
if(!allowed_in_phaseout && istype(mod.wearer.loc, /obj/effect/dummy/phased_mob))
//specifically a to_chat because the user is phased out.
to_chat(mod.wearer, span_warning("You cannot activate this right now."))
return FALSE
COOLDOWN_START(src, cooldown_timer, cooldown_time)
addtimer(CALLBACK(mod.wearer, /mob.proc/update_inv_back), cooldown_time)
mod.wearer.update_inv_back()
return TRUE
/// Called when an activated module without a device is used
/obj/item/mod/module/proc/on_select_use(atom/target)
if(mod.wearer.incapacitated(ignore_grab = TRUE))
return FALSE
mod.wearer.face_atom(target)
if(!on_use())
return FALSE
return TRUE
/// Called when an activated module without a device is active and the user alt/middle-clicks
/obj/item/mod/module/proc/on_special_click(mob/source, atom/target)
SIGNAL_HANDLER
on_select_use(target)
return COMSIG_MOB_CANCEL_CLICKON
/// Called on the MODsuit's process
/obj/item/mod/module/proc/on_process(delta_time)
if(active)
if(!drain_power(active_power_cost * delta_time))
on_deactivation()
return FALSE
on_active_process(delta_time)
else
drain_power(idle_power_cost * delta_time)
return TRUE
/// Called on the MODsuit's process if it is an active module
/obj/item/mod/module/proc/on_active_process(delta_time)
return
/// Drains power from the suit cell
/obj/item/mod/module/proc/drain_power(amount)
if(!check_power(amount))
return FALSE
mod.cell.charge = max(0, mod.cell.charge - amount)
return TRUE
/obj/item/mod/module/proc/check_power(amount)
if(!mod.cell || (mod.cell.charge < amount))
return FALSE
return TRUE
/// Adds additional things to the MODsuit ui_data()
/obj/item/mod/module/proc/add_ui_data()
return list()
/// Creates a list of configuring options for this module
/obj/item/mod/module/proc/get_configuration()
return list()
/// Generates an element of the get_configuration list with a display name, type and value
/obj/item/mod/module/proc/add_ui_configuration(display_name, type, value, list/values)
return list("display_name" = display_name, "type" = type, "value" = value, "values" = values)
/// Receives configure edits from the TGUI and edits the vars
/obj/item/mod/module/proc/configure_edit(key, value)
return
/// Called when the device moves to a different place on active modules
/obj/item/mod/module/proc/on_exit(datum/source, atom/movable/part, direction)
SIGNAL_HANDLER
if(!active)
return
if(part.loc == src)
return
if(part.loc == mod.wearer)
return
if(part == device)
on_deactivation()
/// Called when the device gets deleted on active modules
/obj/item/mod/module/proc/on_device_deletion(datum/source)
SIGNAL_HANDLER
if(source == device)
device = null
qdel(src)
/// Generates an icon to be used for the suit's worn overlays
/obj/item/mod/module/proc/generate_worn_overlay()
. = list()
if(!mod.active)
return
var/used_overlay
if(overlay_state_use && !COOLDOWN_FINISHED(src, cooldown_timer))
used_overlay = overlay_state_use
else if(overlay_state_active && active)
used_overlay = overlay_state_active
else if(overlay_state_inactive)
used_overlay = overlay_state_inactive
else
return
var/mutable_appearance/module_icon = mutable_appearance(overlay_icon_file, used_overlay)
if(!use_mod_colors)
module_icon.appearance_flags |= RESET_COLOR
. += module_icon
/// Updates the signal used by active modules to be activated
/obj/item/mod/module/proc/update_signal()
mod.selected_module.used_signal = COMSIG_MOB_ALTCLICKON
RegisterSignal(mod.wearer, mod.selected_module.used_signal, /obj/item/mod/module.proc/on_special_click)
/obj/item/mod/module/anomaly_locked
name = "MOD anomaly locked module"
desc = "A form of a module, locked behind an anomalous core to function."
incompatible_modules = list(/obj/item/mod/module/anomaly_locked)
/// The core item the module runs off.
var/obj/item/assembly/signaler/anomaly/core
/// Accepted types of anomaly cores.
var/list/accepted_anomalies = list(/obj/item/assembly/signaler/anomaly)
/// If this one starts with a core in.
var/prebuilt = FALSE
/obj/item/mod/module/anomaly_locked/Initialize(mapload)
. = ..()
if(!prebuilt || !length(accepted_anomalies))
return
var/core_path = pick(accepted_anomalies)
core = new core_path(src)
update_icon_state()
/obj/item/mod/module/anomaly_locked/Destroy()
QDEL_NULL(core)
return ..()
/obj/item/mod/module/anomaly_locked/examine(mob/user)
. = ..()
if(!length(accepted_anomalies))
return
if(core)
. += span_notice("There is a [core.name] installed in it. You could remove it with a <b>screwdriver</b>...")
else
var/list/core_list = list()
for(var/path in accepted_anomalies)
var/atom/core_path = path
core_list += initial(core_path.name)
. += span_notice("You need to insert \a [english_list(core_list, and_text = " or ")] for this module to function.")
/obj/item/mod/module/anomaly_locked/on_select()
if(!core)
balloon_alert(mod.wearer, "no core!")
return
return ..()
/obj/item/mod/module/anomaly_locked/on_process(delta_time)
. = ..()
if(!core)
return FALSE
/obj/item/mod/module/anomaly_locked/on_active_process(delta_time)
if(!core)
return FALSE
return TRUE
/obj/item/mod/module/anomaly_locked/attackby(obj/item/item, mob/living/user, params)
if(item.type in accepted_anomalies)
if(core)
balloon_alert(user, "core already in!")
return
if(!user.transferItemToLoc(item, src))
return
core = item
balloon_alert(user, "core installed")
playsound(src, 'sound/machines/click.ogg', 30, TRUE)
update_icon_state()
else
return ..()
/obj/item/mod/module/anomaly_locked/screwdriver_act(mob/living/user, obj/item/tool)
. = ..()
if(!core)
balloon_alert(user, "no core!")
return
balloon_alert(user, "removing core...")
if(!do_after(user, 3 SECONDS, target = src))
balloon_alert(user, "interrupted!")
return
balloon_alert(user, "core removed")
core.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
user.put_in_hands(core)
core = null
update_icon_state()
/obj/item/mod/module/anomaly_locked/update_icon_state()
icon_state = initial(icon_state) + (core ? "-core" : "")
return ..()

View File

@@ -1,96 +0,0 @@
/obj/item/mod/module/anti_magic/on_suit_activation()
ADD_TRAIT(mod.wearer, TRAIT_ANTIMAGIC, MOD_TRAIT)
ADD_TRAIT(mod.wearer, TRAIT_HOLY, MOD_TRAIT)
/obj/item/mod/module/anti_magic/on_suit_deactivation()
REMOVE_TRAIT(mod.wearer, TRAIT_ANTIMAGIC, MOD_TRAIT)
REMOVE_TRAIT(mod.wearer, TRAIT_HOLY, MOD_TRAIT)
/obj/item/mod/module/anti_magic/wizard
name = "MOD magic neutralizer module"
desc = "The caster wielding this spell gains an invisible barrier around them, channeling arcane power through \
specialized runes engraved onto the surface of the suit to generate anti-magic field. \
The field will neutralize all magic that comes into contact with the user. \
It will not protect the caster from social ridicule."
icon_state = "magic_neutralizer"
/obj/item/mod/module/anti_magic/wizard/on_suit_activation()
ADD_TRAIT(mod.wearer, TRAIT_ANTIMAGIC_NO_SELFBLOCK, MOD_TRAIT)
/obj/item/mod/module/anti_magic/wizard/on_suit_deactivation()
REMOVE_TRAIT(mod.wearer, TRAIT_ANTIMAGIC_NO_SELFBLOCK, MOD_TRAIT)
/obj/item/mod/module/kinesis //TODO POST-MERGE MAKE NOT SUCK ASS, MAKE BALLER AS FUCK
name = "MOD kinesis module"
desc = "A modular plug-in to the forearm, this module was presumed lost for many years, \
despite the suits it used to be mounted on still seeing some circulation. \
This piece of technology allows the user to generate precise anti-gravity fields, \
letting them move objects as small as a titanium rod to as large as industrial machinery. \
Oddly enough, it doesn't seem to work on living creatures."
icon_state = "kinesis"
// module_type = MODULE_ACTIVE
module_type = MODULE_TOGGLE
// complexity = 3
complexity = 0
active_power_cost = DEFAULT_CHARGE_DRAIN*0.75
// use_power_cost = DEFAULT_CHARGE_DRAIN*3
removable = FALSE
incompatible_modules = list(/obj/item/mod/module/kinesis)
cooldown_time = 0.5 SECONDS
var/has_tk = FALSE
/obj/item/mod/module/kinesis/on_activation()
. = ..()
if(!.)
return
if(mod.wearer.dna.check_mutation(TK))
has_tk = TRUE
else
mod.wearer.dna.add_mutation(TK)
/obj/item/mod/module/kinesis/on_deactivation()
. = ..()
if(!.)
return
if(has_tk)
has_tk = FALSE
return
mod.wearer.dna.remove_mutation(TK)
/obj/item/mod/module/insignia
name = "MOD insignia module"
desc = "Despite the existence of IFF systems, radio communique, and modern methods of deductive reasoning involving \
the wearer's own eyes, colorful paint jobs remain a popular way for different factions in the galaxy to display who \
they are. This system utilizes a series of tiny moving paint sprayers to both apply and remove different \
color patterns to and from the suit."
icon_state = "insignia"
removable = FALSE
incompatible_modules = list(/obj/item/mod/module/insignia)
overlay_state_inactive = "insignia"
/obj/item/mod/module/insignia/generate_worn_overlay()
overlay_state_inactive = "[initial(overlay_state_inactive)]-[mod.skin]"
. = ..()
for(var/mutable_appearance/appearance as anything in .)
appearance.color = color
/obj/item/mod/module/insignia/commander
color = "#4980a5"
/obj/item/mod/module/insignia/security
color = "#b30d1e"
/obj/item/mod/module/insignia/engineer
color = "#e9c80e"
/obj/item/mod/module/insignia/medic
color = "#ebebf5"
/obj/item/mod/module/insignia/janitor
color = "#7925c7"
/obj/item/mod/module/insignia/clown
color = "#ff1fc7"
/obj/item/mod/module/insignia/chaplain
color = "#f0a00c"

View File

@@ -1,215 +0,0 @@
//Engineering modules for MODsuits
///Welding Protection - Makes the helmet protect from flashes and welding.
/obj/item/mod/module/welding
name = "MOD welding protection module"
desc = "A module installed into the visor of the suit, this projects a \
polarized, holographic overlay in front of the user's eyes. It's rated high enough for \
immunity against extremities such as spot and arc welding, solar eclipses, and handheld flashlights."
icon_state = "welding"
complexity = 1
incompatible_modules = list(/obj/item/mod/module/welding)
overlay_state_inactive = "module_welding"
/obj/item/mod/module/welding/on_suit_activation()
mod.helmet.flash_protect = 2
/obj/item/mod/module/welding/on_suit_deactivation(deleting = FALSE)
if(deleting)
return
mod.helmet.flash_protect = initial(mod.helmet.flash_protect)
///T-Ray Scan - Scans the terrain for undertile objects.
/obj/item/mod/module/t_ray
name = "MOD t-ray scan module"
desc = "A module installed into the visor of the suit, allowing the user to use a pulse of terahertz radiation \
to essentially echolocate things beneath the floor, mostly cables and pipes. \
A staple of atmospherics work, and counter-smuggling work."
icon_state = "tray"
module_type = MODULE_TOGGLE
complexity = 1
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
incompatible_modules = list(/obj/item/mod/module/t_ray)
cooldown_time = 0.5 SECONDS
/// T-ray scan range.
var/range = 4
/obj/item/mod/module/t_ray/on_active_process(delta_time)
t_ray_scan(mod.wearer, 0.8 SECONDS, range)
///Magnetic Stability - Gives the user a slowdown but makes them negate gravity and be immune to slips.
/obj/item/mod/module/magboot
name = "MOD magnetic stability module"
desc = "These are powerful electromagnets fitted into the suit's boots, allowing users both \
excellent traction no matter the condition indoors, and to essentially hitch a ride on the exterior of a hull. \
However, these basic models do not feature computerized systems to automatically toggle them on and off, \
so numerous users report a certain stickiness to their steps."
icon_state = "magnet"
module_type = MODULE_TOGGLE
complexity = 2
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
incompatible_modules = list(/obj/item/mod/module/magboot)
cooldown_time = 0.5 SECONDS
/// Slowdown added onto the suit.
var/slowdown_active = 2
/obj/item/mod/module/magboot/on_activation()
. = ..()
if(!.)
return
mod.boots.clothing_flags |= NOSLIP
ADD_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT)
mod.slowdown += slowdown_active
mod.wearer.update_gravity(mod.wearer.has_gravity())
mod.wearer.update_equipment_speed_mods()
/obj/item/mod/module/magboot/on_deactivation(display_message = TRUE, deleting = FALSE)
. = ..()
if(!.)
return
mod.boots.clothing_flags &= ~NOSLIP
REMOVE_TRAIT(mod.wearer, TRAIT_NOSLIPWATER, MOD_TRAIT)
mod.slowdown -= slowdown_active
mod.wearer.update_gravity(mod.wearer.has_gravity())
mod.wearer.update_equipment_speed_mods()
/obj/item/mod/module/magboot/advanced
name = "MOD advanced magnetic stability module"
removable = FALSE
complexity = 0
slowdown_active = 0
///Emergency Tether - Shoots a grappling hook projectile in 0g that throws the user towards it.
/obj/item/mod/module/tether
name = "MOD emergency tether module"
desc = "A custom-built grappling-hook powered by a winch capable of hauling the user. \
While some older models of cargo-oriented grapples have capacities of a few tons, \
these are only capable of working in zero-gravity environments, a blessing to some Engineers."
icon_state = "tether"
module_type = MODULE_ACTIVE
complexity = 3
use_power_cost = DEFAULT_CHARGE_DRAIN
incompatible_modules = list(/obj/item/mod/module/tether)
cooldown_time = 1.5 SECONDS
/obj/item/mod/module/tether/on_use()
if(mod.wearer.has_gravity(get_turf(src)))
balloon_alert(mod.wearer, "too much gravity!")
playsound(src, "gun_dry_fire", 25, TRUE)
return FALSE
return ..()
/obj/item/mod/module/tether/on_select_use(atom/target)
. = ..()
if(!.)
return
var/obj/item/projectile/tether = new /obj/item/projectile/tether(mod.wearer.loc)
tether.preparePixelProjectile(target, mod.wearer)
tether.firer = mod.wearer
playsound(src, 'sound/weapons/batonextend.ogg', 25, TRUE)
INVOKE_ASYNC(tether, /obj/item/projectile.proc/fire)
drain_power(use_power_cost)
/obj/item/projectile/tether
name = "tether"
icon_state = "tether_projectile"
icon = 'icons/obj/clothing/modsuit/mod_modules.dmi'
damage = 0
nodamage = TRUE
range = 10
hitsound = 'sound/weapons/batonextend.ogg'
hitsound_wall = 'sound/weapons/batonextend.ogg'
suppressed = SUPPRESSED_VERY
hit_threshhold = LATTICE_LAYER
/// Reference to the beam following the projectile.
var/line
/obj/item/projectile/tether/fire(setAngle)
if(firer)
line = firer.Beam(src, "line", 'icons/obj/clothing/modsuit/mod_modules.dmi')
..()
/obj/item/projectile/tether/on_hit(atom/target)
. = ..()
if(firer)
firer.throw_at(target, 10, 1, firer, FALSE, FALSE, null, MOVE_FORCE_NORMAL, TRUE)
/obj/item/projectile/tether/Destroy()
QDEL_NULL(line)
return ..()
///Radiation Protection - Protects the user from radiation, gives them a geiger counter and rad info in the panel.
/obj/item/mod/module/rad_protection
name = "MOD radiation protection module"
desc = "A module utilizing polymers and reflective shielding to protect the user against ionizing radiation."
icon_state = "radshield"
complexity = 2
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
incompatible_modules = list(/obj/item/mod/module/rad_protection)
/obj/item/mod/module/rad_protection/on_suit_activation()
mod.armor = mod.armor.modifyRating(rad = 65)
mod.rad_flags = RAD_PROTECT_CONTENTS|RAD_NO_CONTAMINATE
for(var/obj/item/part in mod.mod_parts)
part.armor = mod.armor
part.rad_flags = mod.rad_flags
/obj/item/mod/module/rad_protection/on_suit_deactivation(deleting = FALSE)
mod.armor = mod.armor.modifyRating(rad = -65)
mod.rad_flags = NONE
for(var/obj/item/part in mod.mod_parts)
part.armor = mod.armor
part.rad_flags = mod.rad_flags
///Constructor - Lets you build quicker and create RCD holograms.
/obj/item/mod/module/constructor
name = "MOD constructor module"
desc = "This module entirely occupies the wearer's forearm, notably causing conflict with \
advanced arm servos meant to carry crewmembers. However, it contains the \
latest engineering schematics combined with inbuilt memory to help the user build walls."
icon_state = "constructor"
module_type = MODULE_USABLE
complexity = 2
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
use_power_cost = DEFAULT_CHARGE_DRAIN * 2
incompatible_modules = list(/obj/item/mod/module/constructor, /obj/item/mod/module/quick_carry)
cooldown_time = 11 SECONDS
/obj/item/mod/module/constructor/on_suit_activation()
ADD_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, MOD_TRAIT)
/obj/item/mod/module/constructor/on_suit_deactivation(deleting = FALSE)
REMOVE_TRAIT(mod.wearer, TRAIT_QUICK_BUILD, MOD_TRAIT)
///Mister - Sprays water over an area.
/obj/item/mod/module/mister
name = "MOD water mister module"
desc = "A module containing a mister, able to spray it over areas."
icon_state = "mister"
module_type = MODULE_ACTIVE
complexity = 2
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
device = /obj/item/reagent_containers/spray/mister
incompatible_modules = list(/obj/item/mod/module/mister)
cooldown_time = 0.5 SECONDS
/// Volume of our reagent holder.
var/volume = 500
/obj/item/mod/module/mister/Initialize(mapload)
create_reagents(volume, OPENCONTAINER)
return ..()
///Resin Mister - Sprays resin over an area.
/obj/item/mod/module/mister/atmos
name = "MOD resin mister module"
desc = "An atmospheric resin mister, able to fix up areas quickly."
device = /obj/item/extinguisher/mini/nozzle/mod
volume = 250
/obj/item/mod/module/mister/atmos/Initialize(mapload)
. = ..()
reagents.add_reagent(/datum/reagent/water, volume)
/obj/item/extinguisher/mini/nozzle/mod
name = "MOD atmospheric mister"
desc = "An atmospheric resin mister with three modes, mounted as a module."

View File

@@ -1,402 +0,0 @@
//General modules for MODsuits
///Storage - Adds a storage component to the suit.
/obj/item/mod/module/storage
name = "MOD storage containment 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)
module_type = MODULE_USABLE
cooldown_time = 0.5 SECONDS
allowed_inactive = TRUE
/// Bag we have stored.
var/obj/item/storage/backpack/stored
/obj/item/mod/module/storage/attackby(obj/item/I, mob/user, params)
if(!istype(I, /obj/item/storage/backpack))
return ..()
var/obj/item/storage/backpack/B = I
if(stored)
balloon_alert(user, "backpack already installed!")
return
if(!user.transferItemToLoc(B, src))
return
stored = B
balloon_alert(user, "backpack installed")
playsound(src, 'sound/machines/click.ogg', 30, TRUE)
/obj/item/mod/module/storage/screwdriver_act(mob/living/user, obj/item/tool)
. = ..()
if(!stored)
balloon_alert(user, "no backpack!")
return
balloon_alert(user, "removing backpack...")
if(!do_after(user, 3 SECONDS, target = src))
balloon_alert(user, "interrupted!")
return
balloon_alert(user, "backpack removed")
stored.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
user.put_in_hands(stored)
stored = null
/obj/item/mod/module/storage/on_use()
. = ..()
if(!.)
return
if(!stored)
var/obj/item/storage/backpack/holding = mod.wearer.get_active_held_item()
if(!holding)
balloon_alert(mod.wearer, "no backpack installed!")
return
if(!istype(holding))
balloon_alert(mod.wearer, "it doesn't fit!")
return
if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE))
stored = holding
balloon_alert(mod.wearer, "backpack stored")
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
else if(mod.wearer.put_in_active_hand(stored, forced = FALSE, ignore_animation = TRUE))
balloon_alert(mod.wearer, "backpack retrieved")
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
else
balloon_alert(mod.wearer, "backpack storage full!")
/obj/item/mod/module/storage/Exited(atom/movable/gone, direction)
. = ..()
if(gone == stored)
stored = null
/obj/item/mod/module/storage/Destroy()
QDEL_NULL(stored)
return ..()
///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/effect_system/trail_follow/ion/ion_trail
/obj/item/mod/module/jetpack/Initialize(mapload)
. = ..()
ion_trail = new
ion_trail.set_up(src)
/obj/item/mod/module/jetpack/Destroy()
QDEL_NULL(ion_trail)
return ..()
/obj/item/mod/module/jetpack/on_activation()
. = ..()
if(!.)
return
ion_trail.start()
RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, .proc/move_react)
RegisterSignal(mod.wearer, COMSIG_MOVABLE_SPACEMOVE, .proc/spacemove_react, override = TRUE)
if(full_speed)
mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed)
else
mod.wearer.add_movespeed_modifier(/datum/movespeed_modifier/jetpack)
/obj/item/mod/module/jetpack/on_deactivation(display_message = TRUE, deleting = FALSE)
. = ..()
stabilizers = FALSE
ion_trail.stop()
UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED)
mod.wearer.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed)
mod.wearer.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack)
/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")
stabilizers = text2num(value)
/obj/item/mod/module/jetpack/proc/move_react(mob/user)
allow_thrust()
/obj/item/mod/module/jetpack/proc/allow_thrust(use_fuel = TRUE)
if(!active)
return FALSE
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/spacemove_react(mob/user, movement_dir)
SIGNAL_HANDLER
if(active && (movement_dir || stabilizers))
return COMSIG_MOVABLE_STOP_SPACEMOVE
/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
mod.helmet.visor_flags_cover &= ~HEADCOVERSMOUTH
/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_color = COLOR_WHITE
light_range = 4
light_power = 1
/// 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
mod.set_light(light_range, light_power, light_color)
active_power_cost = base_power * light_range
/obj/item/mod/module/flashlight/on_deactivation(display_message = TRUE, deleting = FALSE)
. = ..()
if(!.)
return
mod.set_light(0, 0)
/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()
. = ..()
if(!active)
return
var/mutable_appearance/light_icon = mutable_appearance(overlay_icon_file, "module_light_on")
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
var/list/hsl = rgb2hsl(hex2num(copytext(value,2,4)),hex2num(copytext(value,4,6)),hex2num(copytext(value,6,8)))
if(hsl[3] < 0.5)
balloon_alert(mod.wearer, "too dark!")
return
mod.set_light_color(value)
mod.wearer.regenerate_icons()
light_color = value
if("light_range")
mod.set_light_range(clamp(value, min_range, max_range))
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/reagent_containers/food/snacks/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
///Thermal Regulator - Naw.
///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)
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/on_mod_activation)
RegisterSignal(mod, COMSIG_MOD_MODULE_REMOVAL, .proc/on_mod_removal)
RegisterSignal(mod, COMSIG_ATOM_EMP_ACT, .proc/on_emp)
RegisterSignal(mod, COMSIG_ATOM_EMAG_ACT, .proc/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
///Sign Language Translator - I want, but no

View File

@@ -1,157 +0,0 @@
//Maint modules for MODsuits
///Springlock Mechanism - allows your modsuit to activate faster, but reagents are very dangerous.
/obj/item/mod/module/springlock
name = "MOD springlock module"
desc = "A module that spans the entire size of the MOD unit, sitting under the outer shell. \
This mechanical exoskeleton pushes out of the way when the user enters and it helps in booting \
up, but was taken out of modern suits because of the springlock's tendency to \"snap\" back \
into place when exposed to humidity. You know what it's like to have an entire exoskeleton enter you?"
icon_state = "springlock"
complexity = 3 // it is inside every part of your suit, so
incompatible_modules = list(/obj/item/mod/module/springlock)
/obj/item/mod/module/springlock/on_install()
mod.activation_step_time *= 0.5
/obj/item/mod/module/springlock/on_uninstall(deleting = FALSE)
mod.activation_step_time *= 2
/obj/item/mod/module/springlock/on_suit_activation()
RegisterSignal(mod.wearer, COMSIG_ATOM_EXPOSE_REAGENTS, .proc/on_wearer_exposed)
/obj/item/mod/module/springlock/on_suit_deactivation(deleting = FALSE)
UnregisterSignal(mod.wearer, COMSIG_ATOM_EXPOSE_REAGENTS)
///Signal fired when wearer is exposed to reagents
/obj/item/mod/module/springlock/proc/on_wearer_exposed(atom/source, list/reagents, datum/reagents/source_reagents, methods, volume_modifier, show_message, from_gas)
SIGNAL_HANDLER
if(!reagents.len)
return
if(!(methods & (VAPOR|PATCH|TOUCH)))
return //remove non-touch reagent exposure
to_chat(mod.wearer, span_danger("[src] makes an ominous click sound..."))
playsound(src, 'sound/items/modsuit/springlock.ogg', 75, TRUE)
addtimer(CALLBACK(src, .proc/snap_shut), rand(3 SECONDS, 5 SECONDS))
RegisterSignal(mod, COMSIG_MOD_ACTIVATE, .proc/on_activate_spring_block)
///Signal fired when wearer attempts to activate/deactivate suits
/obj/item/mod/module/springlock/proc/on_activate_spring_block(datum/source, user)
SIGNAL_HANDLER
balloon_alert(user, "springlocks aren't responding...?")
return MOD_CANCEL_ACTIVATE
///Delayed death proc of the suit after the wearer is exposed to reagents
/obj/item/mod/module/springlock/proc/snap_shut()
UnregisterSignal(mod, COMSIG_MOD_ACTIVATE)
if(!mod.wearer) //while there is a guaranteed user when on_wearer_exposed() fires, that isn't the same case for this proc
return
mod.wearer.visible_message("[src] inside [mod.wearer]'s [mod.name] snaps shut, mutilating the user inside!", span_userdanger("*SNAP*"))
mod.wearer.emote("scream")
playsound(mod.wearer, 'sound/effects/snap.ogg', 75, TRUE, frequency = 0.5)
playsound(mod.wearer, 'sound/effects/splat.ogg', 50, TRUE, frequency = 0.5)
mod.wearer.client?.give_award(/datum/award/achievement/misc/springlock, mod.wearer)
mod.wearer.apply_damage(500, BRUTE, forced = TRUE, spread_damage = TRUE, sharpness = SHARP_POINTY) //boggers, bogchamp, etc
if(!HAS_TRAIT(mod.wearer, TRAIT_NODEATH))
mod.wearer.death() //just in case, for some reason, they're still alive
flash_color(mod.wearer, flash_color = "#FF0000", flash_time = 10 SECONDS)
///Rave Visor - Pointless
///Tanner - Maybe another time
///Balloon Blower - Blows a balloon.
/obj/item/mod/module/balloon
name = "MOD balloon blower module"
desc = "A strange module invented years ago by some ingenious mimes. It blows balloons."
icon_state = "bloon"
module_type = MODULE_USABLE
complexity = 1
use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
incompatible_modules = list(/obj/item/mod/module/balloon)
cooldown_time = 15 SECONDS
/obj/item/mod/module/balloon/on_use()
. = ..()
if(!.)
return
if(!do_after(mod.wearer, 10 SECONDS, target = mod))
return FALSE
mod.wearer.adjustOxyLoss(20)
playsound(src, 'sound/items/modsuit/inflate_bloon.ogg', 50, TRUE)
var/obj/item/toy/balloon/balloon = new(get_turf(src))
mod.wearer.put_in_hands(balloon)
drain_power(use_power_cost)
///Paper Dispenser - Dispenses (sometimes burning) paper sheets.
/obj/item/mod/module/paper_dispenser
name = "MOD paper dispenser module"
desc = "A simple module designed by the bureaucrats of Torch Bay. \
It dispenses 'warm, clean, and crisp sheets of paper' onto a nearby table. Usually."
icon_state = "paper_maker"
module_type = MODULE_USABLE
complexity = 1
use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
incompatible_modules = list(/obj/item/mod/module/paper_dispenser)
cooldown_time = 5 SECONDS
/// The total number of sheets created by this MOD. The more sheets, them more likely they set on fire.
var/num_sheets_dispensed = 0
/obj/item/mod/module/paper_dispenser/on_use()
. = ..()
if(!.)
return
if(!do_after(mod.wearer, 1 SECONDS, target = mod))
return FALSE
var/obj/item/paper/crisp_paper = new(get_turf(src))
crisp_paper.desc = "It's crisp and warm to the touch. Must be fresh."
var/obj/structure/table/nearby_table = locate() in range(1, mod.wearer)
playsound(get_turf(src), 'sound/machines/click.ogg', 50, TRUE)
balloon_alert(mod.wearer, "dispensed paper[nearby_table ? " onto table":""]")
mod.wearer.put_in_hands(crisp_paper)
if(nearby_table)
mod.wearer.transferItemToLoc(crisp_paper, nearby_table.drop_location(), silent = FALSE)
// Up to a 30% chance to set the sheet on fire, +2% per sheet made
if(prob(min(num_sheets_dispensed * 2, 30)))
if(crisp_paper in mod.wearer.held_items)
mod.wearer.dropItemToGround(crisp_paper, force = TRUE)
crisp_paper.balloon_alert(mod.wearer, "PC LOAD LETTER!")
crisp_paper.visible_message(span_warning("[crisp_paper] bursts into flames, it's too crisp!"))
crisp_paper.fire_act(1000, 100)
drain_power(use_power_cost)
num_sheets_dispensed++
///Stamper - Extends a stamp that can switch between accept/deny modes.
/obj/item/mod/module/stamp
name = "MOD stamper module"
desc = "A module installed into the wrist of the suit, this functions as a high-power stamp, \
able to switch between accept and deny modes."
icon_state = "stamp"
module_type = MODULE_ACTIVE
complexity = 1
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
device = /obj/item/stamp/mod
incompatible_modules = list(/obj/item/mod/module/stamp)
cooldown_time = 0.5 SECONDS
/obj/item/stamp/mod
name = "MOD electronic stamp"
desc = "A high-power stamp, able to switch between accept and deny mode when used."
/obj/item/stamp/mod/attack_self(mob/user, modifiers)
. = ..()
if(icon_state == "stamp-ok")
icon_state = "stamp-deny"
else
icon_state = "stamp-ok"
balloon_alert(user, "switched mode")
///Atrocinator - Perhaps another time

View File

@@ -1,189 +0,0 @@
//Medical modules for MODsuits
#define HEALTH_SCAN "Health"
#define WOUND_SCAN "Wound"
#define CHEM_SCAN "Chemical"
///Health Analyzer - Gives the user a ranged health analyzer and their health status in the panel.
/obj/item/mod/module/health_analyzer
name = "MOD health analyzer module"
desc = "A module installed into the glove of the suit. This is a high-tech biological scanning suite, \
allowing the user indepth information on the vitals and injuries of others even at a distance, \
all with the flick of the wrist. Data is displayed in a convenient package on HUD in the helmet, \
but it's up to you to do something with it."
icon_state = "health"
module_type = MODULE_ACTIVE
complexity = 2
use_power_cost = DEFAULT_CHARGE_DRAIN
incompatible_modules = list(/obj/item/mod/module/health_analyzer)
cooldown_time = 0.5 SECONDS
tgui_id = "health_analyzer"
/// Scanning mode, changes how we scan something.
var/mode = HEALTH_SCAN
/// List of all scanning modes.
var/static/list/modes = list(HEALTH_SCAN, WOUND_SCAN, CHEM_SCAN)
/obj/item/mod/module/health_analyzer/add_ui_data()
. = ..()
.["userhealth"] = mod.wearer?.health || 0
.["usermaxhealth"] = mod.wearer?.getMaxHealth() || 0
.["userbrute"] = mod.wearer?.getBruteLoss() || 0
.["userburn"] = mod.wearer?.getFireLoss() || 0
.["usertoxin"] = mod.wearer?.getToxLoss() || 0
.["useroxy"] = mod.wearer?.getOxyLoss() || 0
/obj/item/mod/module/health_analyzer/on_select_use(atom/target)
. = ..()
if(!.)
return
if(!isliving(target) || !mod.wearer.can_read(src))
return
switch(mode)
if(HEALTH_SCAN)
healthscan(mod.wearer, target)
if(WOUND_SCAN)
woundscan(mod.wearer, target)
if(CHEM_SCAN)
chemscan(mod.wearer, target)
drain_power(use_power_cost)
/obj/item/mod/module/health_analyzer/get_configuration()
. = ..()
.["mode"] = add_ui_configuration("Scan Mode", "list", mode, modes)
/obj/item/mod/module/health_analyzer/configure_edit(key, value)
switch(key)
if("mode")
mode = value
#undef HEALTH_SCAN
#undef WOUND_SCAN
#undef CHEM_SCAN
///Quick Carry - Lets the user carry bodies quicker.
/obj/item/mod/module/quick_carry
name = "MOD quick carry module"
desc = "A suite of advanced servos, redirecting power from the suit's arms to help carry the wounded; \
or simply for fun. However, Nanotrasen has locked the module's ability to assist in hand-to-hand combat."
icon_state = "carry"
complexity = 1
idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
incompatible_modules = list(/obj/item/mod/module/quick_carry, /obj/item/mod/module/constructor)
/obj/item/mod/module/quick_carry/on_suit_activation()
ADD_TRAIT(mod.wearer, TRAIT_QUICKER_CARRY, MOD_TRAIT)
/obj/item/mod/module/quick_carry/on_suit_deactivation(deleting = FALSE)
REMOVE_TRAIT(mod.wearer, TRAIT_QUICKER_CARRY, MOD_TRAIT)
/obj/item/mod/module/quick_carry/advanced
name = "MOD advanced quick carry module"
removable = FALSE
complexity = 0
///Injector - No piercing syringes, replace another time
///Organ Thrower
///Patrient Transport
///Defibrillator - Gives the suit an extendable pair of shock paddles.
/obj/item/mod/module/defibrillator
name = "MOD defibrillator module"
desc = "A module built into the gauntlets of the suit; commonly known as the 'Healing Hands' by medical professionals. \
The user places their palms above the patient. Onboard computers in the suit calculate the necessary voltage, \
and a modded targeting computer determines the best position for the user to push. \
Twenty five pounds of force are applied to the patient's skin. Shocks travel from the suit's gloves \
and counter-shock the heart, and the wearer returns to Medical a hero. Don't you even think about using it as a weapon; \
regulations on manufacture and software locks expressly forbid it."
icon_state = "defibrillator"
module_type = MODULE_ACTIVE
complexity = 2
use_power_cost = DEFAULT_CHARGE_DRAIN * 25
device = /obj/item/shockpaddles/mod
overlay_state_inactive = "module_defibrillator"
overlay_state_active = "module_defibrillator_active"
incompatible_modules = list(/obj/item/mod/module/defibrillator)
cooldown_time = 0.5 SECONDS
var/defib_cooldown = 5 SECONDS
/obj/item/mod/module/defibrillator/Initialize(mapload)
. = ..()
RegisterSignal(device, COMSIG_DEFIBRILLATOR_SUCCESS, .proc/on_defib_success)
/obj/item/mod/module/defibrillator/Destroy()
UnregisterSignal(device, COMSIG_DEFIBRILLATOR_SUCCESS)
. = ..()
/obj/item/mod/module/defibrillator/proc/on_defib_success(obj/item/shockpaddles/source)
drain_power(use_power_cost)
source.recharge(defib_cooldown)
return COMPONENT_DEFIB_STOP
/obj/item/shockpaddles/mod
name = "MOD defibrillator gauntlets"
req_defib = FALSE
icon_state = "defibgauntlets0"
item_state = "defibgauntlets0"
base_icon_state = "defibgauntlets"
/obj/item/mod/module/defibrillator/combat
name = "MOD combat defibrillator module"
desc = "A module built into the gauntlets of the suit; commonly known as the 'Healing Hands' by medical professionals. \
The user places their palms above the patient. Onboard computers in the suit calculate the necessary voltage, \
and a modded targeting computer determines the best position for the user to push. \
Twenty five pounds of force are applied to the patient's skin. Shocks travel from the suit's gloves \
and counter-shock the heart, and the wearer returns to Medical a hero. \
Interdyne Pharmaceutics marketed the domestic version of the Healing Hands as foolproof and unusable as a weapon. \
But when it came time to provide their operatives with usable medical equipment, they didn't hesitate to remove \
those in-built safeties. Operatives in the field can benefit from what they dub as 'Stun Gloves', able to apply shocks \
straight to a victims heart to disable them, or maybe even outright stop their heart with enough power."
complexity = 1
module_type = MODULE_ACTIVE
overlay_state_inactive = "module_defibrillator_combat"
overlay_state_active = "module_defibrillator_combat_active"
device = /obj/item/shockpaddles/syndicate/mod
defib_cooldown = 2.5 SECONDS
/obj/item/shockpaddles/syndicate/mod
name = "MOD combat defibrillator gauntlets"
req_defib = FALSE
icon_state = "syndiegauntlets0"
item_state = "syndiegauntlets0"
base_icon_state = "syndiegauntlets"
///Thread Ripper
///Surgical Processor - Lets you do advanced surgeries portably.
/obj/item/mod/module/surgical_processor
name = "MOD surgical processor module"
desc = "A module using an onboard surgical computer which can be connected to other computers to download and \
perform advanced surgeries on the go."
icon_state = "surgical_processor"
module_type = MODULE_ACTIVE
complexity = 2
active_power_cost = DEFAULT_CHARGE_DRAIN
device = /obj/item/surgical_processor/mod
incompatible_modules = list(/obj/item/mod/module/surgical_processor)
cooldown_time = 0.5 SECONDS
/obj/item/surgical_processor/mod
name = "MOD surgical processor"
/obj/item/mod/module/surgical_processor/preloaded
desc = "A module using an onboard surgical computer which can be connected to other computers to download and \
perform advanced surgeries on the go. This one came pre-loaded with some advanced surgeries."
device = /obj/item/surgical_processor/mod/preloaded
/obj/item/surgical_processor/mod/preloaded
advanced_surgeries = list(
/datum/surgery/advanced/pacify,
/datum/surgery/healing/combo/upgraded/femto,
/datum/surgery/advanced/brainwashing,
/datum/surgery/advanced/bioware/nerve_splicing,
/datum/surgery/advanced/bioware/nerve_grounding,
/datum/surgery/advanced/bioware/vein_threading,
/datum/surgery/advanced/bioware/muscled_veins,
/datum/surgery/advanced/bioware/ligament_hook,
/datum/surgery/advanced/bioware/ligament_reinforcement
)

View File

@@ -1,135 +0,0 @@
//Science modules for MODsuits
///Reagent Scanner - Lets the user scan reagents.
/obj/item/mod/module/reagent_scanner
name = "MOD reagent scanner module"
desc = "A module based off research-oriented Nanotrasen HUDs, this is capable of scanning the contents of \
containers and projecting the information in an easy-to-read format on the wearer's display. \
It cannot detect flavors, so that's up to you."
icon_state = "scanner"
module_type = MODULE_TOGGLE
complexity = 1
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
incompatible_modules = list(/obj/item/mod/module/reagent_scanner)
cooldown_time = 0.5 SECONDS
/obj/item/mod/module/reagent_scanner/on_activation()
. = ..()
if(!.)
return
ADD_TRAIT(mod.wearer, TRAIT_REAGENT_SCANNER, MOD_TRAIT)
/obj/item/mod/module/reagent_scanner/on_deactivation(display_message = TRUE, deleting = FALSE)
. = ..()
if(!.)
return
REMOVE_TRAIT(mod.wearer, TRAIT_REAGENT_SCANNER, MOD_TRAIT)
/obj/item/mod/module/reagent_scanner/advanced
name = "MOD advanced reagent scanner module"
complexity = 0
removable = FALSE
var/explosion_detection_dist = 21
var/had_research_scanner = FALSE
/obj/item/mod/module/reagent_scanner/advanced/on_activation()
. = ..()
if(!.)
return
had_research_scanner = mod.wearer.research_scanner
mod.wearer.research_scanner = TRUE
RegisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION, .proc/sense_explosion)
/obj/item/mod/module/reagent_scanner/advanced/on_deactivation(display_message = TRUE, deleting = FALSE)
. = ..()
if(!.)
return
mod.wearer.research_scanner = had_research_scanner
had_research_scanner = FALSE
UnregisterSignal(SSdcs, COMSIG_GLOB_EXPLOSION)
/obj/item/mod/module/reagent_scanner/advanced/proc/sense_explosion(datum/source, turf/epicenter,
devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
SIGNAL_HANDLER
var/turf/wearer_turf = get_turf(mod.wearer)
if(wearer_turf.z == epicenter.z)
return
if(get_dist(epicenter, wearer_turf) > explosion_detection_dist)
return
to_chat(mod.wearer, span_notice("Explosion detected! Epicenter: [devastation_range], Outer: [heavy_impact_range], Shock: [light_impact_range]"))
///Anti-Gravity - Makes the user weightless.
/obj/item/mod/module/anomaly_locked/antigrav
name = "MOD anti-gravity module"
desc = "A module that uses a gravitational core to make the user completely weightless."
icon_state = "antigrav"
module_type = MODULE_TOGGLE
complexity = 3
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.7
incompatible_modules = list(/obj/item/mod/module/anomaly_locked)
cooldown_time = 0.5 SECONDS
accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/grav)
/obj/item/mod/module/anomaly_locked/antigrav/on_activation()
. = ..()
if(!.)
return
if(mod.wearer.has_gravity())
new /obj/effect/temp_visual/mook_dust(get_turf(src))
mod.wearer.AddElement(/datum/element/forced_gravity, 0)
mod.wearer.update_gravity(mod.wearer.has_gravity())
playsound(src, 'sound/effects/gravhit.ogg', 50)
/obj/item/mod/module/anomaly_locked/antigrav/on_deactivation(display_message = TRUE, deleting = FALSE)
. = ..()
if(!.)
return
mod.wearer.RemoveElement(/datum/element/forced_gravity, 0)
mod.wearer.update_gravity(mod.wearer.has_gravity())
if(deleting)
return
if(mod.wearer.has_gravity())
new /obj/effect/temp_visual/mook_dust(get_turf(src))
playsound(src, 'sound/effects/gravhit.ogg', 50)
/obj/item/mod/module/anomaly_locked/antigrav/prebuilt
prebuilt = TRUE
///Teleporter - Lets the user teleport to a nearby location.
/obj/item/mod/module/anomaly_locked/teleporter
name = "MOD teleporter module"
desc = "A module that uses a bluespace core to let the user transport their particles elsewhere."
icon_state = "teleporter"
module_type = MODULE_ACTIVE
complexity = 3
use_power_cost = DEFAULT_CHARGE_DRAIN * 5
cooldown_time = 5 SECONDS
accepted_anomalies = list(/obj/item/assembly/signaler/anomaly/bluespace)
/// Time it takes to teleport
var/teleport_time = 3 SECONDS
/obj/item/mod/module/anomaly_locked/teleporter/on_select_use(atom/target)
. = ..()
if(!.)
return
var/turf/open/target_turf = get_turf(target)
if(!istype(target_turf) || is_blocked_turf(target_turf) || !(target_turf in view(mod.wearer)))
balloon_alert(mod.wearer, "invalid target!")
return
balloon_alert(mod.wearer, "teleporting...")
var/matrix/pre_matrix = matrix()
pre_matrix.Scale(4, 0.25)
var/matrix/post_matrix = matrix()
post_matrix.Scale(0.25, 4)
animate(mod.wearer, teleport_time, color = COLOR_CYAN, transform = pre_matrix.Multiply(mod.wearer.transform), easing = SINE_EASING|EASE_OUT)
if(!do_after(mod.wearer, teleport_time, target = mod))
balloon_alert(mod.wearer, "interrupted!")
animate(mod.wearer, teleport_time*0.1, color = null, transform = post_matrix.Multiply(mod.wearer.transform), easing = SINE_EASING|EASE_IN)
return
animate(mod.wearer, teleport_time*0.1, color = null, transform = post_matrix.Multiply(mod.wearer.transform), easing = SINE_EASING|EASE_IN)
if(!do_teleport(mod.wearer, target_turf, asoundin = 'sound/effects/phasein.ogg'))
return
drain_power(use_power_cost)
/obj/item/mod/module/anomaly_locked/teleporter/prebuilt
prebuilt = TRUE

View File

@@ -1,207 +0,0 @@
//Security modules for MODsuits
///Cloaking - Lowers the user's visibility, can be interrupted by being touched or attacked.
/obj/item/mod/module/stealth
name = "MOD prototype cloaking module"
desc = "A complete retrofitting of the suit, this is a form of visual concealment tech employing esoteric technology \
to bend light around the user, as well as mimetic materials to make the surface of the suit match the \
surroundings based off sensor data. For some reason, this tech is rarely seen."
icon_state = "cloak"
module_type = MODULE_TOGGLE
complexity = 4
active_power_cost = DEFAULT_CHARGE_DRAIN * 2
use_power_cost = DEFAULT_CHARGE_DRAIN * 10
incompatible_modules = list(/obj/item/mod/module/stealth)
cooldown_time = 5 SECONDS
/// Whether or not the cloak turns off on bumping.
var/bumpoff = TRUE
/// The alpha applied when the cloak is on.
var/stealth_alpha = 50
/obj/item/mod/module/stealth/on_activation()
. = ..()
if(!.)
return
if(bumpoff)
RegisterSignal(mod.wearer, COMSIG_LIVING_MOB_BUMP, .proc/unstealth)
RegisterSignal(mod.wearer, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_unarmed_attack)
RegisterSignal(mod.wearer, COMSIG_ATOM_BULLET_ACT, .proc/on_bullet_act)
RegisterSignal(mod.wearer, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_PAW), .proc/unstealth)
animate(mod.wearer, alpha = stealth_alpha, time = 1.5 SECONDS)
drain_power(use_power_cost)
/obj/item/mod/module/stealth/on_deactivation(display_message = TRUE, deleting = FALSE)
. = ..()
if(!.)
return
if(bumpoff)
UnregisterSignal(mod.wearer, COMSIG_LIVING_MOB_BUMP)
UnregisterSignal(mod.wearer, list(COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ITEM_ATTACK, COMSIG_PARENT_ATTACKBY, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_BULLET_ACT, COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_PAW))
animate(mod.wearer, alpha = 255, time = 1.5 SECONDS)
/obj/item/mod/module/stealth/proc/unstealth(datum/source)
SIGNAL_HANDLER
to_chat(mod.wearer, span_warning("[src] gets discharged from contact!"))
do_sparks(2, TRUE, src)
drain_power(use_power_cost)
on_deactivation(display_message = TRUE, deleting = FALSE)
/obj/item/mod/module/stealth/proc/on_unarmed_attack(datum/source, atom/target)
SIGNAL_HANDLER
if(!isliving(target))
return
unstealth(source)
/obj/item/mod/module/stealth/proc/on_bullet_act(datum/source, obj/item/projectile/projectile)
SIGNAL_HANDLER
if(projectile.nodamage)
return
unstealth(source)
///Magnetic Harness - Automatically puts guns in your suit storage when you drop them.
/obj/item/mod/module/magnetic_harness
name = "MOD magnetic harness module"
desc = "Based off old TerraGov harness kits, this magnetic harness automatically attaches dropped guns back to the wearer."
icon_state = "mag_harness"
complexity = 2
use_power_cost = DEFAULT_CHARGE_DRAIN
incompatible_modules = list(/obj/item/mod/module/magnetic_harness)
/// Time before we activate the magnet.
var/magnet_delay = 0.8 SECONDS
/// The typecache of all guns we allow.
var/static/list/guns_typecache
/// The guns already allowed by the modsuit chestplate.
var/list/already_allowed_guns = list()
/obj/item/mod/module/magnetic_harness/Initialize(mapload)
. = ..()
if(!guns_typecache)
guns_typecache = typecacheof(list(/obj/item/gun/ballistic, /obj/item/gun/energy, /obj/item/gun/grenadelauncher, /obj/item/gun/chem, /obj/item/gun/syringe))
/obj/item/mod/module/magnetic_harness/on_install()
already_allowed_guns = guns_typecache & mod.chestplate.allowed
mod.chestplate.allowed |= guns_typecache
/obj/item/mod/module/magnetic_harness/on_uninstall(deleting = FALSE)
if(deleting)
return
mod.chestplate.allowed -= (guns_typecache - already_allowed_guns)
/obj/item/mod/module/magnetic_harness/on_suit_activation()
RegisterSignal(mod.wearer, COMSIG_MOB_UNEQUIPPED_ITEM, .proc/check_dropped_item)
/obj/item/mod/module/magnetic_harness/on_suit_deactivation(deleting = FALSE)
UnregisterSignal(mod.wearer, COMSIG_MOB_UNEQUIPPED_ITEM)
/obj/item/mod/module/magnetic_harness/proc/check_dropped_item(datum/source, obj/item/dropped_item, force, new_location)
SIGNAL_HANDLER
if(!is_type_in_typecache(dropped_item, guns_typecache))
return
if(new_location != get_turf(src))
return
addtimer(CALLBACK(src, .proc/pick_up_item, dropped_item), magnet_delay)
/obj/item/mod/module/magnetic_harness/proc/pick_up_item(obj/item/item)
if(!isturf(item.loc) || !item.Adjacent(mod.wearer))
return
if(!mod.wearer.equip_to_slot_if_possible(item, ITEM_SLOT_SUITSTORE, qdel_on_fail = FALSE, disable_warning = TRUE))
return
playsound(src, 'sound/items/modsuit/magnetic_harness.ogg', 50, TRUE)
balloon_alert(mod.wearer, "[item] reattached")
drain_power(use_power_cost)
///Pepper Shoulders
///Holster - Instantly holsters any not huge gun.
/obj/item/mod/module/holster
name = "MOD holster module"
desc = "Based off typical storage compartments, this system allows the suit to holster a \
standard firearm across its surface and allow for extremely quick retrieval. \
While some users prefer the chest, others the forearm for quick deployment, \
some law enforcement prefer the holster to extend from the thigh."
icon_state = "holster"
module_type = MODULE_USABLE
complexity = 2
incompatible_modules = list(/obj/item/mod/module/holster)
cooldown_time = 0.5 SECONDS
allowed_inactive = TRUE
/// Gun we have holstered.
var/obj/item/gun/holstered
/obj/item/mod/module/holster/on_use()
. = ..()
if(!.)
return
if(!holstered)
var/obj/item/gun/holding = mod.wearer.get_active_held_item()
if(!holding)
balloon_alert(mod.wearer, "nothing to holster!")
return
if(!istype(holding) || holding.w_class > WEIGHT_CLASS_BULKY)
balloon_alert(mod.wearer, "it doesn't fit!")
return
if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE))
holstered = holding
balloon_alert(mod.wearer, "weapon holstered")
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
else if(mod.wearer.put_in_active_hand(holstered, forced = FALSE, ignore_animation = TRUE))
balloon_alert(mod.wearer, "weapon drawn")
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
else
balloon_alert(mod.wearer, "holster full!")
/obj/item/mod/module/holster/on_uninstall(deleting = FALSE)
if(holstered)
holstered.forceMove(drop_location())
/obj/item/mod/module/holster/Exited(atom/movable/gone, direction)
. = ..()
if(gone == holstered)
holstered = null
/obj/item/mod/module/holster/Destroy()
QDEL_NULL(holstered)
return ..()
///Megaphone - Lets you speak loud.
/obj/item/mod/module/megaphone
name = "MOD megaphone module"
desc = "A microchip megaphone linked to a MODsuit, for very important purposes, like: loudness."
icon_state = "megaphone"
module_type = MODULE_TOGGLE
complexity = 1
use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5
incompatible_modules = list(/obj/item/mod/module/megaphone)
cooldown_time = 0.5 SECONDS
/// List of spans we add to the speaker.
var/list/voicespan = list(SPAN_COMMAND)
/obj/item/mod/module/megaphone/on_activation()
. = ..()
if(!.)
return
RegisterSignal(mod.wearer, COMSIG_MOB_SAY, .proc/handle_speech)
/obj/item/mod/module/megaphone/on_deactivation(display_message = TRUE, deleting = FALSE)
. = ..()
if(!.)
return
UnregisterSignal(mod.wearer, COMSIG_MOB_SAY)
/obj/item/mod/module/megaphone/proc/handle_speech(datum/source, list/speech_args)
SIGNAL_HANDLER
speech_args[SPEECH_SPANS] |= voicespan
drain_power(use_power_cost)
///Criminal Capture
///Mirage grenade dispenser
///Projectile Dampener
///Active Sonar

View File

@@ -1,66 +0,0 @@
//Service modules for MODsuits
///Bike Horn - Plays a bike horn sound.
/obj/item/mod/module/bikehorn
name = "MOD bike horn module"
desc = "A shoulder-mounted piece of heavy sonic artillery, this module uses the finest femto-manipulator technology to \
precisely deliver an almost lethal squeeze to... a bike horn, producing a significantly memorable sound."
icon_state = "bikehorn"
module_type = MODULE_USABLE
complexity = 1
use_power_cost = DEFAULT_CHARGE_DRAIN
incompatible_modules = list(/obj/item/mod/module/bikehorn)
cooldown_time = 1 SECONDS
/obj/item/mod/module/bikehorn/on_use()
. = ..()
if(!.)
return
playsound(src, 'sound/items/bikehorn.ogg', 100, FALSE)
drain_power(use_power_cost)
///Microwave Beam - Microwaves items instantly.
/obj/item/mod/module/microwave_beam
name = "MOD microwave beam module"
desc = "An oddly domestic device, this module is installed into the user's palm, \
hooking up with culinary scanners located in the helmet to blast food with precise microwave radiation, \
allowing them to cook food from a distance, with the greatest of ease. Not recommended for use against grapes."
icon_state = "microwave_beam"
module_type = MODULE_ACTIVE
complexity = 2
use_power_cost = DEFAULT_CHARGE_DRAIN * 5
incompatible_modules = list(/obj/item/mod/module/microwave_beam)
cooldown_time = 10 SECONDS
var/obj/machinery/microwave/microwave
/obj/item/mod/module/microwave_beam/Initialize(mapload)
microwave = new()
. = ..()
/obj/item/mod/module/microwave_beam/Destroy()
QDEL_NULL(microwave)
. = ..()
/obj/item/mod/module/microwave_beam/on_select_use(atom/target)
. = ..()
if(!.)
return
if(!isitem(target))
return
if(!isturf(target.loc))
balloon_alert(mod.wearer, "must be on the floor!")
return
var/obj/item/microwave_target = target
var/turf/microwave_target_loc = target.loc
var/datum/effect_system/spark_spread/spark_effect = new()
spark_effect.set_up(2, 1, mod.wearer)
spark_effect.start()
mod.wearer.Beam(target,icon_state="lightning[rand(1,12)]", time = 5)
if(microwave_target.microwave_act(microwave))
playsound(src, 'sound/machines/microwave/microwave-end.ogg', 50, FALSE)
else
balloon_alert(mod.wearer, "can't be microwaved!")
var/datum/effect_system/spark_spread/spark_effect_two = new()
spark_effect_two.set_up(2, 1, microwave_target_loc)
spark_effect_two.start()
drain_power(use_power_cost)

View File

@@ -1,229 +0,0 @@
//Supply modules for MODsuits
///Internal GPS - Extends a GPS you can use.
/obj/item/mod/module/gps
name = "MOD internal GPS module"
desc = "This module uses common Nanotrasen technology to calculate the user's position anywhere in space, \
down to the exact coordinates. This information is fed to a central database viewable from the device itself, \
though using it to help people is up to you."
icon_state = "gps"
module_type = MODULE_USABLE
complexity = 1
use_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
incompatible_modules = list(/obj/item/mod/module/gps)
cooldown_time = 0.5 SECONDS
allowed_inactive = TRUE
/obj/item/mod/module/gps/Initialize(mapload)
. = ..()
AddComponent(/datum/component/gps/item, "MOD0", state = GLOB.deep_inventory_state, overlay_state = FALSE)
/obj/item/mod/module/gps/on_use()
. = ..()
if(!.)
return
attack_self(mod.wearer)
///Hydraulic Clamp - Lets you pick up and drop crates.
/obj/item/mod/module/clamp
name = "MOD hydraulic clamp module"
desc = "A series of actuators installed into both arms of the suit, boasting a lifting capacity of almost a ton. \
However, this design has been locked by Nanotrasen to be primarily utilized for lifting various crates. \
A lot of people would say that loading cargo is a dull job, but you could not disagree more."
icon_state = "clamp"
module_type = MODULE_ACTIVE
complexity = 3
use_power_cost = DEFAULT_CHARGE_DRAIN
incompatible_modules = list(/obj/item/mod/module/clamp)
cooldown_time = 0.5 SECONDS
overlay_state_inactive = "module_clamp"
overlay_state_active = "module_clamp_on"
/// Time it takes to load a crate.
var/load_time = 3 SECONDS
/// The max amount of crates you can carry.
var/max_crates = 3
/// The crates stored in the module.
var/list/stored_crates = list()
/obj/item/mod/module/clamp/on_select_use(atom/target)
. = ..()
if(!.)
return
if(!mod.wearer.Adjacent(target))
return
if(istype(target, /obj/structure/closet) || istype(target, /obj/structure/bigDelivery))
var/atom/movable/picked_crate = target
if(!check_crate_pickup(picked_crate))
return
playsound(src, 'sound/mecha/hydraulic.ogg', 25, TRUE)
if(!do_after(mod.wearer, load_time, target = target))
balloon_alert(mod.wearer, "interrupted!")
return
if(!check_crate_pickup(picked_crate))
return
stored_crates += picked_crate
picked_crate.forceMove(src)
balloon_alert(mod.wearer, "picked up [picked_crate]")
drain_power(use_power_cost)
else if(length(stored_crates))
var/turf/target_turf = get_turf(target)
if(is_blocked_turf(target_turf))
return
playsound(src, 'sound/mecha/hydraulic.ogg', 25, TRUE)
if(!do_after(mod.wearer, load_time, target = target))
balloon_alert(mod.wearer, "interrupted!")
return
if(is_blocked_turf(target_turf))
return
var/atom/movable/dropped_crate = pop(stored_crates)
dropped_crate.forceMove(target_turf)
balloon_alert(mod.wearer, "dropped [dropped_crate]")
drain_power(use_power_cost)
else
balloon_alert(mod.wearer, "invalid target!")
/obj/item/mod/module/clamp/on_suit_deactivation(deleting = FALSE)
if(deleting)
return
for(var/atom/movable/crate as anything in stored_crates)
crate.forceMove(drop_location())
stored_crates -= crate
/obj/item/mod/module/clamp/proc/check_crate_pickup(atom/movable/target)
if(length(stored_crates) >= max_crates)
balloon_alert(mod.wearer, "too many crates!")
return FALSE
for(var/mob/living/mob in target.GetAllContents())
if(mob.mob_size < MOB_SIZE_HUMAN)
continue
balloon_alert(mod.wearer, "crate too heavy!")
return FALSE
return TRUE
/obj/item/mod/module/clamp/loader
name = "MOD loader hydraulic clamp module"
icon_state = "clamp_loader"
complexity = 0
removable = FALSE
overlay_state_inactive = null
overlay_state_active = "module_clamp_loader"
load_time = 1 SECONDS
max_crates = 5
use_mod_colors = TRUE
///Drill - Lets you dig through rock and basalt.
/obj/item/mod/module/drill // TODO: Would be cooler with a built-in drill, but meh
name = "MOD pickaxe/drill storage module"
desc = "Provides a convenient storage compartment for pickaxes and drills."
icon_state = "drill"
complexity = 2
incompatible_modules = list(/obj/item/mod/module/drill)
cooldown_time = 0.5 SECONDS
allowed_inactive = TRUE
module_type = MODULE_USABLE
/// Pickaxe we have stored.
var/obj/item/pickaxe/stored
/obj/item/mod/module/drill/on_use()
. = ..()
if(!.)
return
if(!stored)
var/obj/item/pickaxe/holding = mod.wearer.get_active_held_item()
if(!holding)
balloon_alert(mod.wearer, "nothing to store!")
return
if(!istype(holding))
balloon_alert(mod.wearer, "it doesn't fit!")
return
if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE))
stored = holding
balloon_alert(mod.wearer, "mining instrument stored")
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
else if(mod.wearer.put_in_active_hand(stored, forced = FALSE, ignore_animation = TRUE))
balloon_alert(mod.wearer, "mining instrument retrieved")
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
else
balloon_alert(mod.wearer, "mining instrument storage full!")
/obj/item/mod/module/drill/on_uninstall(deleting = FALSE)
if(stored)
stored.forceMove(drop_location())
/obj/item/mod/module/drill/Exited(atom/movable/gone, direction)
. = ..()
if(gone == stored)
stored = null
/obj/item/mod/module/drill/Destroy()
QDEL_NULL(stored)
return ..()
/obj/item/mod/module/orebag // TODO
name = "MOD mining satchel storage module"
desc = "Provides a convenient storage department for a mining satchel."
icon_state = "ore"
module_type = MODULE_USABLE
complexity = 1
use_power_cost = DEFAULT_CHARGE_DRAIN * 0.2
incompatible_modules = list(/obj/item/mod/module/orebag)
cooldown_time = 0.5 SECONDS
allowed_inactive = TRUE
/// Pickaxe we have stored.
var/obj/item/storage/bag/ore/stored
/obj/item/mod/module/orebag/on_use()
. = ..()
if(!.)
return
if(!stored)
var/obj/item/storage/bag/ore/holding = mod.wearer.get_active_held_item()
if(!holding)
balloon_alert(mod.wearer, "nothing to store!")
return
if(!istype(holding))
balloon_alert(mod.wearer, "it doesn't fit!")
return
if(mod.wearer.transferItemToLoc(holding, src, force = FALSE, silent = TRUE))
stored = holding
balloon_alert(mod.wearer, "mining satchel stored")
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, .proc/Pickup_ores)
else if(mod.wearer.put_in_active_hand(stored, forced = FALSE, ignore_animation = TRUE))
UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED)
balloon_alert(mod.wearer, "mining satchel retrieved")
playsound(src, 'sound/weapons/revolverempty.ogg', 100, TRUE)
else
balloon_alert(mod.wearer, "mining satchel storage full!")
/obj/item/mod/module/orebag/on_uninstall(deleting = FALSE)
if(stored)
UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED)
stored.forceMove(drop_location())
/obj/item/mod/module/orebag/on_equip()
if(stored)
RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, .proc/Pickup_ores)
/obj/item/mod/module/orebag/on_unequip()
if(stored)
UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED)
/obj/item/mod/module/orebag/Exited(atom/movable/gone, direction)
. = ..()
if(gone == stored)
UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED)
stored = null
/obj/item/mod/module/orebag/Destroy()
if(stored)
UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED)
QDEL_NULL(stored)
return ..()
/obj/item/mod/module/orebag/proc/Pickup_ores()
if(stored)
stored.Pickup_ores(mod.wearer)
// Ash accretion looks cool, but can't be arsed to implement
// Same with sphere transformation

View File

@@ -1,91 +0,0 @@
//Visor modules for MODsuits
///Base Visor - Adds a specific HUD and traits to you.
/obj/item/mod/module/visor
name = "MOD visor module"
desc = "A heads-up display installed into the visor of the suit. They say these also let you see behind you."
module_type = MODULE_TOGGLE
complexity = 2
active_power_cost = DEFAULT_CHARGE_DRAIN * 0.3
incompatible_modules = list(/obj/item/mod/module/visor)
cooldown_time = 0.5 SECONDS
/// The HUD type given by the visor.
var/hud_type
/// The traits given by the visor.
var/list/visor_traits = list()
/obj/item/mod/module/visor/on_activation()
. = ..()
if(!.)
return
if(hud_type)
var/datum/atom_hud/hud = GLOB.huds[hud_type]
hud.add_hud_to(mod.wearer)
for(var/trait in visor_traits)
ADD_TRAIT(mod.wearer, trait, MOD_TRAIT)
mod.wearer.update_sight()
/obj/item/mod/module/visor/on_deactivation(display_message = TRUE, deleting = FALSE)
. = ..()
if(!.)
return
if(hud_type)
var/datum/atom_hud/hud = GLOB.huds[hud_type]
hud.remove_hud_from(mod.wearer)
for(var/trait in visor_traits)
REMOVE_TRAIT(mod.wearer, trait, MOD_TRAIT)
mod.wearer.update_sight()
//Medical Visor - Gives you a medical HUD.
/obj/item/mod/module/visor/medhud
name = "MOD medical visor module"
desc = "A heads-up display installed into the visor of the suit. This cross-references suit sensor data with a modern \
biological scanning suite, allowing the user to visualize the current health of organic lifeforms, as well as \
access data such as patient files in a convenient readout. They say these also let you see behind you."
icon_state = "medhud_visor"
hud_type = DATA_HUD_MEDICAL_ADVANCED
//Diagnostic Visor - Gives you a diagnostic HUD.
/obj/item/mod/module/visor/diaghud
name = "MOD diagnostic visor module"
desc = "A heads-up display installed into the visor of the suit. This uses a series of advanced sensors to access data \
from advanced machinery, exosuits, and other devices, allowing the user to visualize current power levels \
and integrity of such. They say these also let you see behind you."
icon_state = "diaghud_visor"
hud_type = DATA_HUD_DIAGNOSTIC_ADVANCED
//Security Visor - Gives you a security HUD.
/obj/item/mod/module/visor/sechud
name = "MOD security visor module"
desc = "A heads-up display installed into the visor of the suit. This module is a heavily-retrofitted targeting system, \
plugged into various criminal databases to be able to view arrest records, command simple security-oriented robots, \
and generally know who to shoot. They say these also let you see behind you."
icon_state = "sechud_visor"
hud_type = DATA_HUD_SECURITY_ADVANCED
//Meson Visor - Gives you meson vision.
/obj/item/mod/module/visor/meson
name = "MOD meson visor module"
desc = "A heads-up display installed into the visor of the suit. This module is based off well-loved meson scanner \
technology, used by construction workers and miners across the galaxy to see basic structural and terrain layouts \
through walls, regardless of lighting conditions. They say these also let you see behind you."
icon_state = "meson_visor"
visor_traits = list(TRAIT_MESON_VISION)
//Thermal Visor - Gives you thermal vision.
/obj/item/mod/module/visor/thermal
name = "MOD thermal visor module"
desc = "A heads-up display installed into the visor of the suit. This uses a small IR scanner to detect and identify \
the thermal radiation output of objects near the user. While it can detect the heat output of even something as \
small as a rodent, it still produces irritating red overlay. They say these also let you see behind you."
icon_state = "thermal_visor"
visor_traits = list(TRAIT_THERMAL_VISION)
//Night Visor - Gives you night vision.
/obj/item/mod/module/visor/night
name = "MOD night visor module"
desc = "A heads-up display installed into the visor of the suit. Typical for both civilian and military applications, \
this allows the user to perceive their surroundings while in complete darkness, enhancing the view by tenfold; \
yet brightening everything into a spooky green glow. They say these also let you see behind you."
icon_state = "night_visor"
visor_traits = list(TRAIT_TRUE_NIGHT_VISION)