mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-06-23 23:24:55 +01:00
bff56bf388
## About The Pull Request Each type of anomaly core has an effect when pulsed by an assembly, button, or wire. Most of these effects are a weaker version of their respective reactive armor's unique effect (except for pyro and vortex anomalies, which make stealth armor solely because there isn't specific reactive armor for them). In particular: - Pyro anomalies make a 3x3 area of hotspots around themselves. - Gravity anomalies gently pull most unanchored objects in a 2 tile radius. - Flux anomalies make a short range 10 kJ tesla zap that usually doesn't propagate more than a single time. - Bluespace anomalies teleport the object they are connected to up to 4 tiles away. They will teleport out of storage, and they will teleport out of your hands or equipment slots unless they have NODROP. This has a 15 second cooldown, which is longer than reactive teleport armor. - Vortex anomalies do a weaker version of the the vortex thing, but limited to a 1 tile radius around the core. This has a 5 second cooldown, and can potentially destroy the core or what it's attached to. - Bioscrambler anomalies perform a bioscramble pulse in a 1 tile range. This has a 10 second cooldown. - Hallucination anomalies perform a hallucination pulse in a 1 tile range, adding 20 seconds of hallucinations, up to a maximum of 1 minute. This has a 10 second cooldown, so hallucinations from a single pulsed core can stack if you stay in range. - Dimensional anomalies perform a dimensional shift in the same range as the science relic. This has a fixed 15 second cooldown. - Ectoplasmic anomalies haunt a few objects in a 5x5 area around the core for 30 seconds. This has a 60 second cooldown. - Weather anomalies cause a single lightning bolt to strike a random open turf in a 5x5 area around the core. This bolt deals less damage than the reactive weather armor's bolts, and does not have an AOE. ## Why It's Good For The Game Gives both the station and antagonists additional uses for anomaly cores, beyond the ones that are specific items printed by science. As some examples: - A bundle of wired flux anomalies surrounded by tesla coils can provide a decent drip-feed of free power to the station - only on the level of several pacmans, but better than nothing. - Bluespace anomalies give you a manual version of the reactive teleport armor's teleport, but you'll need to get creative in order to actually teleport yourself and not just what you attached the core to. - People who really want to play the bioscrambler lottery can keep doing it after the original anomaly is neutralized. ## Changelog 🆑 add: Anomaly cores now have effects when pulsed by an assembly, button, or wire. These effects are generally weaker versions of the effects of the source anomalies, or of their respective reactive armors, and many have a 50% longer cooldown than said armors. /🆑
174 lines
5.5 KiB
Plaintext
174 lines
5.5 KiB
Plaintext
|
|
/obj/item/assembly
|
|
name = "assembly"
|
|
desc = "A small electronic device that should never exist."
|
|
icon = 'icons/obj/devices/new_assemblies.dmi'
|
|
icon_state = ""
|
|
obj_flags = CONDUCTS_ELECTRICITY
|
|
w_class = WEIGHT_CLASS_SMALL
|
|
custom_materials = list(/datum/material/iron=SMALL_MATERIAL_AMOUNT)
|
|
throwforce = 2
|
|
throw_speed = 3
|
|
throw_range = 7
|
|
drop_sound = 'sound/items/handling/component_drop.ogg'
|
|
pickup_sound = 'sound/items/handling/component_pickup.ogg'
|
|
|
|
/**
|
|
* Set to true if the device has different icons for each position.
|
|
* This will prevent things such as visible lasers from facing the incorrect direction when transformed by assembly_holder's update_appearance()
|
|
*/
|
|
var/is_position_sensitive = FALSE
|
|
/// Flags related to this assembly. See [assemblies.dm]
|
|
var/assembly_flags = NONE
|
|
var/secured = TRUE
|
|
var/list/attached_overlays = null
|
|
var/obj/item/assembly_holder/holder = null
|
|
var/assembly_behavior = ASSEMBLY_FUNCTIONAL_OUTPUT // how does the assembly behave with respect to what it's connected to
|
|
var/datum/wires/connected = null
|
|
COOLDOWN_DECLARE(next_activate)
|
|
/// Length of the cooldown between activations
|
|
var/activation_cooldown = 3 SECONDS
|
|
|
|
/obj/item/assembly/Destroy()
|
|
holder = null
|
|
return ..()
|
|
|
|
/obj/item/assembly/get_part_rating()
|
|
return 1
|
|
|
|
/**
|
|
* on_attach: Called when attached to a holder, wiring datum, or other special assembly
|
|
*
|
|
* Will also be called if the assembly holder is attached to a plasma (internals) tank or welding fuel (dispenser) tank.
|
|
*/
|
|
/obj/item/assembly/proc/on_attach()
|
|
SHOULD_CALL_PARENT(TRUE)
|
|
if(!holder && connected)
|
|
holder = connected.holder
|
|
SEND_SIGNAL(src, COMSIG_ASSEMBLY_ATTACHED, holder)
|
|
|
|
/**
|
|
* on_detach: Called when removed from an assembly holder or wiring datum
|
|
*/
|
|
/obj/item/assembly/proc/on_detach()
|
|
SHOULD_CALL_PARENT(TRUE)
|
|
if(connected)
|
|
connected = null
|
|
if(!holder)
|
|
return FALSE
|
|
var/atom/was_holder = holder
|
|
holder = null
|
|
forceMove(was_holder.drop_location())
|
|
SEND_SIGNAL(src, COMSIG_ASSEMBLY_DETACHED, was_holder)
|
|
return TRUE
|
|
|
|
/**
|
|
* holder_movement: Called when the assembly's holder detects movement
|
|
*/
|
|
/obj/item/assembly/proc/holder_movement()
|
|
if(!holder)
|
|
return FALSE
|
|
setDir(holder.dir)
|
|
return TRUE
|
|
|
|
/obj/item/assembly/proc/is_secured(mob/user)
|
|
if(!secured)
|
|
to_chat(user, span_warning("\The [src] is unsecured!"))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/**
|
|
* Pulsed: This device was pulsed by another device
|
|
*
|
|
* * pulser: Who triggered the pulse
|
|
*/
|
|
/obj/item/assembly/proc/pulsed(mob/pulser)
|
|
INVOKE_ASYNC(src, PROC_REF(activate), pulser)
|
|
SEND_SIGNAL(src, COMSIG_ASSEMBLY_PULSED)
|
|
return TRUE
|
|
|
|
/**
|
|
* Pulse: This device is emitting a pulse to act on another device
|
|
*/
|
|
/obj/item/assembly/proc/pulse()
|
|
// if we have connected wires and are a pulsing assembly, pulse it
|
|
if(connected)
|
|
connected.pulse_assembly(src)
|
|
// otherwise if we're attached to a holder, process the activation of it with our flags
|
|
else if(holder)
|
|
holder.process_activation(src)
|
|
return TRUE
|
|
|
|
/// What the device does when turned on
|
|
/obj/item/assembly/proc/activate(mob/activator)
|
|
if(QDELETED(src) || !secured || !COOLDOWN_FINISHED(src, next_activate))
|
|
return FALSE
|
|
COOLDOWN_START(src, next_activate, activation_cooldown)
|
|
return TRUE
|
|
|
|
/obj/item/assembly/proc/toggle_secure()
|
|
secured = !secured
|
|
update_appearance()
|
|
return secured
|
|
|
|
// This is overwritten so that clumsy people can set off mousetraps even when in a holder.
|
|
// We are not going deeper than that however (won't set off if in a tank bomb or anything with wires)
|
|
// That would need to be added to all parent objects, or a signal created, whatever.
|
|
// Anyway this return check prevents you from picking up every assembly inside the holder at once.
|
|
/obj/item/assembly/attack_hand(mob/living/user, list/modifiers)
|
|
if(holder || connected)
|
|
return
|
|
. = ..()
|
|
|
|
/obj/item/assembly/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
|
|
if(isassembly(attacking_item))
|
|
var/obj/item/assembly/new_assembly = attacking_item
|
|
// Check both our's and their's assembly flags to see if either should not duplicate
|
|
// If so, and we match types, don't create a holder - block it
|
|
if(((new_assembly.assembly_flags|assembly_flags) & ASSEMBLY_NO_DUPLICATES) && istype(new_assembly, type))
|
|
balloon_alert(user, "can't attach another [new_assembly.name]!")
|
|
return
|
|
if(new_assembly.secured)
|
|
balloon_alert(user, "[new_assembly.name] is not attachable!")
|
|
return
|
|
if(secured)
|
|
balloon_alert(user, "[name] is not attachable!")
|
|
return
|
|
|
|
holder = new /obj/item/assembly_holder(drop_location())
|
|
holder.assemble(src, new_assembly, user)
|
|
holder.balloon_alert(user, "parts combined")
|
|
return
|
|
|
|
if(istype(attacking_item, /obj/item/assembly_holder))
|
|
var/obj/item/assembly_holder/added_to_holder = attacking_item
|
|
added_to_holder.try_add_assembly(src, user)
|
|
return
|
|
|
|
return ..()
|
|
|
|
/obj/item/assembly/screwdriver_act(mob/living/user, obj/item/I)
|
|
if(..())
|
|
return TRUE
|
|
if(toggle_secure())
|
|
to_chat(user, span_notice("\The [src] is ready!"))
|
|
else
|
|
to_chat(user, span_notice("\The [src] can now be attached!"))
|
|
add_fingerprint(user)
|
|
return TRUE
|
|
|
|
/obj/item/assembly/examine(mob/user)
|
|
. = ..()
|
|
. += span_notice("\The [src] [secured? "is secured and ready to be used!" : "can be attached to other things."]")
|
|
|
|
/obj/item/assembly/ui_host(mob/user)
|
|
// In order, return:
|
|
// - The conencted wiring datum's owner, or
|
|
// - The thing your assembly holder is attached to, or
|
|
// - the assembly holder itself, or
|
|
// - us
|
|
return connected?.holder || holder?.master || holder || src
|
|
|
|
/obj/item/assembly/ui_state(mob/user)
|
|
return GLOB.hands_state
|