mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-26 13:39:16 +01:00
Anomaly Core Rigging (#19361)
* Funky * More evil zaps * fix :) * This one too
This commit is contained in:
@@ -2,3 +2,17 @@
|
||||
#define TELEPORT_CHANNEL_BLUESPACE "bluespace"
|
||||
/// Quantum-based teleportation, requires both sender and receiver, but is free from normal disruption
|
||||
#define TELEPORT_CHANNEL_QUANTUM "quantum"
|
||||
|
||||
// Container flags for get_teleportable_container
|
||||
/// Count mob inventory as a valid container
|
||||
#define TELEPORT_CONTAINER_INCLUDE_INVENTORY (1<<0)
|
||||
/// Count rigsuits with at least one sealed part as valid containers, even if mob inventory is not a valid container
|
||||
#define TELEPORT_CONTAINER_INCLUDE_SEALED_RIGSUIT (1<<1)
|
||||
/// Count atom storage as a valid container
|
||||
#define TELEPORT_CONTAINER_INCLUDE_STORAGE (1<<2)
|
||||
/// Count closets as a valid container
|
||||
#define TELEPORT_CONTAINER_INCLUDE_CLOSET (1<<3)
|
||||
/// Count vehicles as a valid container
|
||||
#define TELEPORT_CONTAINER_INCLUDE_VEHICLE (1<<4)
|
||||
/// Count mech equipment (particularly cargo holds and sleepers) as a valid container
|
||||
#define TELEPORT_CONTAINER_INCLUDE_MECH_EQUIPMENT (1<<5)
|
||||
|
||||
@@ -192,3 +192,46 @@ GLOBAL_LIST_INIT(bluespace_item_types, list(
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
// Gets the topmost teleportable container
|
||||
/proc/get_teleportable_container(atom/movable/teleportable, container_flags = ALL)
|
||||
while(ismovable(teleportable.loc))
|
||||
if(!(container_flags & TELEPORT_CONTAINER_INCLUDE_STORAGE) && isitem(teleportable))
|
||||
var/obj/item/item = teleportable
|
||||
if(item.storage_depth(item.loc))
|
||||
break
|
||||
var/atom/movable/movable = teleportable.loc
|
||||
if(movable.anchored)
|
||||
break
|
||||
if(isliving(movable))
|
||||
var/mob/living/living = movable
|
||||
if(!(container_flags & TELEPORT_CONTAINER_INCLUDE_INVENTORY))
|
||||
var/list/equipped = living.get_equipped_items(INCLUDE_HELD|INCLUDE_POCKETS)
|
||||
if((teleportable in equipped) && !HAS_TRAIT(teleportable, TRAIT_NODROP))
|
||||
if(istype(teleportable, /obj/item/rig) && (container_flags & TELEPORT_CONTAINER_INCLUDE_SEALED_RIGSUIT))
|
||||
var/obj/item/rig/rigsuit = teleportable
|
||||
var/sealed = TRUE
|
||||
for(var/obj/item/clothing/part as anything in rigsuit)
|
||||
if((part == rigsuit || part.loc != rigsuit) && rigsuit.offline)
|
||||
sealed = FALSE
|
||||
break
|
||||
if(!sealed)
|
||||
break
|
||||
else
|
||||
break
|
||||
if(living.buckled)
|
||||
if(living.buckled.anchored)
|
||||
break
|
||||
else
|
||||
var/obj/buckle_obj = living.buckled
|
||||
buckle_obj.unbuckle_mob(living)
|
||||
if(!(container_flags & TELEPORT_CONTAINER_INCLUDE_CLOSET) && istype(movable, /obj/structure/closet))
|
||||
break
|
||||
if(!(container_flags & TELEPORT_CONTAINER_INCLUDE_MECH_EQUIPMENT) && istype(movable, /obj/item/mecha_parts/mecha_equipment))
|
||||
break
|
||||
if(!(container_flags & TELEPORT_CONTAINER_INCLUDE_VEHICLE) && istype(movable, /obj/vehicle))
|
||||
var/obj/vehicle/vehicle = movable
|
||||
if(vehicle.load)
|
||||
break
|
||||
teleportable = movable
|
||||
return teleportable
|
||||
|
||||
@@ -159,6 +159,14 @@
|
||||
/datum/supply_pack/sci/anomaly_harvesting
|
||||
name = "Anomaly Harvesting crate"
|
||||
desc = "Contains the tools to start anomaly harvesting. Requires Research access."
|
||||
cost = 300
|
||||
cost = 350
|
||||
containertype = /obj/structure/largecrate/anomaly
|
||||
access = ACCESS_RESEARCH
|
||||
|
||||
/datum/supply_pack/sci/latent_anomaly
|
||||
name = "Latent Anomaly crate"
|
||||
desc = "Contains a latent anomaly core."
|
||||
cost = 300
|
||||
contains = list(/obj/item/assembly/signaler/anomaly/choice)
|
||||
containertype = /obj/structure/closet/crate/secure/science
|
||||
access = ACCESS_RESEARCH
|
||||
|
||||
@@ -54,9 +54,7 @@
|
||||
if(prob(15))
|
||||
person.Stun(2)
|
||||
to_chat(person, span_danger(pick("You have a coughing fit!", "You can't stop coughing!")))
|
||||
addtimer(CALLBACK(person, TYPE_PROC_REF(/mob, emote), "cough"), 1 SECONDS)
|
||||
addtimer(CALLBACK(person, TYPE_PROC_REF(/mob, emote), "cough"), 3 SECONDS)
|
||||
addtimer(CALLBACK(person, TYPE_PROC_REF(/mob, emote), "cough"), 6 SECONDS)
|
||||
addtimer(CALLBACK(src, PROC_REF(extraCough), person), 3 SECONDS)
|
||||
|
||||
for(var/turf/simulated/floor/ground in circleviewturfs(src, 3))
|
||||
if(ground.can_dirty)
|
||||
@@ -69,6 +67,10 @@
|
||||
if(prob(2))
|
||||
new /obj/effect/decal/cleanable/filth(ground)
|
||||
|
||||
/obj/effect/anomaly/dust/proc/extraCough(mob/living/coughing)
|
||||
coughing.emote("cough")
|
||||
addtimer(CALLBACK(coughing, TYPE_PROC_REF(/mob, emote), "cough"), 3 SECONDS)
|
||||
|
||||
/obj/effect/anomaly/dust/detonate()
|
||||
COOLDOWN_RESET(src, pulse_cooldown)
|
||||
anomalyEffect()
|
||||
|
||||
@@ -171,9 +171,10 @@
|
||||
/obj/effect/anomaly/weather/rain
|
||||
selected_weather = /datum/anomalous_weather/rain
|
||||
|
||||
/*
|
||||
/obj/effect/anomaly/weather/acidrain
|
||||
selected_weather = /datum/anomalous_weather/rain/acid
|
||||
|
||||
*/
|
||||
/obj/effect/anomaly/weather/storm
|
||||
selected_weather = /datum/anomalous_weather/rain/storm
|
||||
|
||||
|
||||
@@ -157,12 +157,12 @@
|
||||
T.wet_floor(1)
|
||||
if(prob(0.025) && !isopenturf(T))
|
||||
lightning_strike(T)
|
||||
|
||||
/*
|
||||
/datum/anomalous_weather/rain/acid
|
||||
name = "Acid Rain"
|
||||
reagent_id = REAGENT_ID_SACID
|
||||
telegraph_message = "Strange clouds begin to cover the ceiling, an acidid tinge on them..."
|
||||
|
||||
*/
|
||||
/datum/anomalous_weather/hail
|
||||
name = "Hail"
|
||||
icon_state = "snowfall_heavy_old"
|
||||
|
||||
@@ -27,16 +27,12 @@
|
||||
///var used for attack_self chain
|
||||
var/special_handling = FALSE
|
||||
|
||||
COOLDOWN_DECLARE(next_activate)
|
||||
var/activation_cooldown = 3 SECONDS
|
||||
|
||||
/obj/item/assembly/proc/holder_movement()
|
||||
return
|
||||
|
||||
/obj/item/assembly/proc/process_cooldown()
|
||||
if(cooldown)
|
||||
return FALSE
|
||||
cooldown = TRUE
|
||||
VARSET_IN(src, cooldown, FALSE, 2 SECONDS)
|
||||
return TRUE
|
||||
|
||||
/obj/item/assembly/proc/pulsed(var/radio = 0)
|
||||
if(holder && (wires & WIRE_RECEIVE))
|
||||
activate()
|
||||
@@ -52,8 +48,9 @@
|
||||
return 1
|
||||
|
||||
/obj/item/assembly/proc/activate()
|
||||
if(!secured || !process_cooldown())
|
||||
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()
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
return TRUE
|
||||
|
||||
/obj/item/assembly/infra/proc/trigger_beam()
|
||||
if(!process_cooldown())
|
||||
if(!COOLDOWN_FINISHED(src, next_activate))
|
||||
return FALSE
|
||||
pulse(0)
|
||||
QDEL_LIST_NULL(i_beams) //They will get recreated next process() if the situation is still appropriate
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
sense()
|
||||
|
||||
/obj/item/assembly/prox_sensor/proc/sense()
|
||||
if((!holder && !secured) || !scanning || !process_cooldown())
|
||||
if((!holder && !secured) || !scanning || !COOLDOWN_FINISHED(src, next_activate))
|
||||
return FALSE
|
||||
var/turf/mainloc = get_turf(src)
|
||||
pulse(0)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
set_frequency(frequency)
|
||||
|
||||
/obj/item/assembly/signaler/activate()
|
||||
if(!process_cooldown())
|
||||
if(!COOLDOWN_FINISHED(src, next_activate))
|
||||
return FALSE
|
||||
signal()
|
||||
return TRUE
|
||||
@@ -82,6 +82,8 @@
|
||||
..()
|
||||
|
||||
/obj/item/assembly/signaler/proc/signal()
|
||||
if(!COOLDOWN_FINISHED(src, next_activate))
|
||||
return FALSE
|
||||
if(!radio_connection)
|
||||
return
|
||||
if(is_jammed(src))
|
||||
@@ -92,6 +94,7 @@
|
||||
signal.encryption = code
|
||||
signal.data["message"] = "ACTIVATE"
|
||||
radio_connection.post_signal(src, signal)
|
||||
COOLDOWN_START(src, next_activate, activation_cooldown)
|
||||
|
||||
/obj/item/assembly/signaler/pulse(var/radio = 0)
|
||||
if(is_jammed(src))
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
return FALSE
|
||||
if(signal.encryption != code)
|
||||
return FALSE
|
||||
for(var/obj/effect/anomaly/anomaly in get_turf(src))
|
||||
if(istype(loc, /obj/effect/anomaly))
|
||||
var/obj/effect/anomaly/anomaly = loc
|
||||
anomaly.anomalyNeutralize()
|
||||
return TRUE
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/attack_self(mob/user)
|
||||
. = ..(user)
|
||||
@@ -63,11 +65,39 @@
|
||||
icon_state = "flux_core"
|
||||
anomaly_type = /obj/effect/anomaly/flux
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/flux/receive_signal()
|
||||
if(..())
|
||||
return
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/human = loc
|
||||
human.electrocute_act(5, src)
|
||||
return
|
||||
|
||||
var/source = null
|
||||
if(connected)
|
||||
var/datum/wires/wires = connected
|
||||
source = wires.holder
|
||||
tesla_zap(source ? source : src, 2, 1000, FALSE, TRUE, 1)
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/bluespace
|
||||
name = "\improper bluespace anomaly core"
|
||||
desc = "The neutralized core of a bluespace anomaly. It keeps phasing in and out of view. It'd probably be valuable for research."
|
||||
icon_state = "anomaly_core"
|
||||
anomaly_type = /obj/effect/anomaly/bluespace
|
||||
activation_cooldown = 15 SECONDS
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/bluespace/receive_signal()
|
||||
if(..())
|
||||
return
|
||||
var/atom/movable/to_teleport = get_teleportable_container(src, container_flags = TELEPORT_CONTAINER_INCLUDE_SEALED_RIGSUIT|TELEPORT_CONTAINER_INCLUDE_CLOSET)
|
||||
if(!to_teleport)
|
||||
return
|
||||
if(isliving(to_teleport.loc))
|
||||
var/mob/living/creature = to_teleport.loc
|
||||
creature.drop_from_inventory(to_teleport, get_turf(creature))
|
||||
var/turf/teleportable_turf = get_turf(to_teleport)
|
||||
playsound(teleportable_turf, 'sound/effects/phasein.ogg', 100, TRUE)
|
||||
do_teleport(to_teleport, teleportable_turf, 4, channel = TELEPORT_CHANNEL_BLUESPACE)
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/grav
|
||||
name = "\improper gravitational anomaly core"
|
||||
@@ -75,23 +105,68 @@
|
||||
icon_state = "grav_core"
|
||||
anomaly_type = /obj/effect/anomaly/grav
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/grav/receive_signal()
|
||||
if(..())
|
||||
return
|
||||
for(var/obj/object in orange(2, get_turf(src)))
|
||||
if(!object.anchored)
|
||||
step_towards(object, src)
|
||||
for(var/mob/living/living in orange(2, get_turf(src)))
|
||||
if(!living.can_overcome_gravity())
|
||||
step_towards(living, src)
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/dimensional
|
||||
name = "\improper dimensional anomaly core"
|
||||
desc = "The neutralized core of a dimensional anomaly. Objects reflected on its surface don't look quite right. It'd probably be valuable for research."
|
||||
icon_state = "dimensional_core"
|
||||
anomaly_type = /obj/effect/anomaly/dimensional
|
||||
activation_cooldown = 15 SECONDS
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/dimensional/receive_signal()
|
||||
if(..())
|
||||
return
|
||||
var/turf/our_turf = get_turf(src)
|
||||
if(!our_turf)
|
||||
return
|
||||
var/theme_path = pick(subtypesof(/datum/dimension_theme))
|
||||
var/datum/dimension_theme/theme = new theme_path
|
||||
|
||||
for(var/turf/turf as anything in RANGE_TURFS(1, our_turf))
|
||||
theme.apply_theme(turf, show_effect = TRUE)
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/bioscrambler
|
||||
name = "\improper bioscrambler anomaly core"
|
||||
desc = "The neutralized core of a bioscrambler anomaly. It's squirming, as if moving. It'd probably be valuable for research."
|
||||
icon_state = "bioscrambler_core"
|
||||
anomaly_type = /obj/effect/anomaly/bioscrambler
|
||||
activation_cooldown = 10 SECONDS
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/bioscrambler/receive_signal()
|
||||
if(..())
|
||||
return
|
||||
new /obj/effect/temp_visual/circle_wave/bioscrambler(get_turf(src))
|
||||
for(var/mob/living/carbon/nearby in hearers(1, get_turf(src)))
|
||||
randmutb(nearby)
|
||||
domutcheck(nearby, null)
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/hallucination
|
||||
name = "\improper hallucination anomaly core"
|
||||
desc = "The neutralized core of a hallucination anomaly. It seems to be moving, but it's probably your imagination. It'd probably be valuable for research."
|
||||
icon_state = "hallucination_core"
|
||||
anomaly_type = /obj/effect/anomaly/hallucination
|
||||
activation_cooldown = 10 SECONDS
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/hallucination/receive_signal()
|
||||
if(..())
|
||||
return
|
||||
for(var/mob/living/nearby_living in view(get_turf(src), 2))
|
||||
if(HAS_TRAIT(nearby_living, TRAIT_MADNESS_IMMUNE))
|
||||
continue
|
||||
|
||||
if(nearby_living.is_blind())
|
||||
continue
|
||||
|
||||
nearby_living.hallucination += 25
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/pyro
|
||||
name = "\improper pyroclastic anomaly core"
|
||||
@@ -99,14 +174,63 @@
|
||||
icon_state = "pyro_core"
|
||||
anomaly_type = /obj/effect/anomaly/pyro
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/pyro/receive_signal()
|
||||
if(..())
|
||||
return
|
||||
var/turf/our_turf = get_turf(src)
|
||||
if(!our_turf)
|
||||
return
|
||||
playsound(our_turf, 'sound/magic/fireball.ogg', 100, TRUE)
|
||||
for(var/turf/turf as anything in RANGE_TURFS(1, our_turf))
|
||||
our_turf.assume_gas(GAS_PHORON, 10, T20C)
|
||||
our_turf.hotspot_expose(700, 400)
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/weather
|
||||
name = "\improper weather anomaly core"
|
||||
desc = "The neutralized core of a weather anomaly. The sound of thunder can be heard in the distance. It'd probably be valuable for research."
|
||||
icon_state = "weather_core"
|
||||
anomaly_type = /obj/effect/anomaly/weather
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/weather/receive_signal()
|
||||
if(..())
|
||||
return
|
||||
var/turf/our_turf = get_turf(src)
|
||||
if(!our_turf)
|
||||
return
|
||||
var/list/possible_targets = list()
|
||||
for(var/turf/turf as anything in RANGE_TURFS(2, our_turf))
|
||||
possible_targets += turf
|
||||
if(!length(possible_targets))
|
||||
return
|
||||
var/turf/target = pick(possible_targets)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(lightning_strike), target), 1 SECONDS)
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/dust
|
||||
name = "\improper dust anomaly core"
|
||||
desc = "The neutralized core of a dust anomaly. It seems to leave some dirt on touch. It'd probably be valuable for research."
|
||||
icon_state = "dust_core"
|
||||
anomaly_type = /obj/effect/anomaly/dust
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/dust/receive_signal()
|
||||
if(..())
|
||||
return
|
||||
new /obj/effect/temp_visual/circle_wave/dirt(get_turf(src))
|
||||
for(var/mob/living/carbon/human/person in view(get_turf(src), 2))
|
||||
person.germ_level += rand(5, 10)
|
||||
if(person.isSynthetic())
|
||||
continue
|
||||
if(person.is_mouth_covered())
|
||||
continue
|
||||
if(!person.has_lungs())
|
||||
continue
|
||||
person.emote(prob(50) ? "cough" : "sneeze")
|
||||
person.Weaken(2)
|
||||
person.adjustOxyLoss(10)
|
||||
if(prob(15))
|
||||
person.Stun(2)
|
||||
to_chat(person, span_danger(pick("You have a coughing fit!", "You can't stop coughing!")))
|
||||
addtimer(CALLBACK(src, PROC_REF(extraCough), person), 3 SECONDS)
|
||||
|
||||
/obj/item/assembly/signaler/anomaly/dust/proc/extraCough(mob/living/coughing)
|
||||
coughing.emote("cough")
|
||||
addtimer(CALLBACK(coughing, TYPE_PROC_REF(/mob, emote), "cough"), 3 SECONDS)
|
||||
|
||||
Reference in New Issue
Block a user