mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-11 23:23:28 +01:00
[PTBF] [ready for review] Anomalous particulate processing objective. (#30649)
* pausing work on this till pickweight * push * more stuff * proper file it * these 2 would be interested * and examine fix * I should be more awake before resolving merge conflicts * god you are stupid stop commiting every 2 seconds * temp buff size change * Event inhand descriptions * behold the c o d e * the rest of the owl * sprite correction * 2 more words to the list * and this one * yes I am having too much fun with this * m o r e * better glow, tech levels * Apply suggestions from code review Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> Signed-off-by: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> * message admins, variable * Apply suggestions from code review Co-authored-by: Taurtura <141481662+Taurtura@users.noreply.github.com> Signed-off-by: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> * PPPProcessor --------- Signed-off-by: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> Co-authored-by: PollardTheDragon <144391971+PollardTheDragon@users.noreply.github.com> Co-authored-by: Taurtura <141481662+Taurtura@users.noreply.github.com>
This commit is contained in:
@@ -19,6 +19,9 @@
|
||||
var/countdown_colour
|
||||
var/obj/effect/countdown/anomaly/countdown
|
||||
|
||||
/// Used by the canister grenades to modify functions.
|
||||
var/canister_spawned = FALSE
|
||||
|
||||
/// Do we drop a core when we're neutralized?
|
||||
var/drops_core = TRUE
|
||||
|
||||
@@ -93,6 +96,11 @@
|
||||
// Else, anomaly core gets deleted by qdel(src).
|
||||
qdel(src)
|
||||
|
||||
// Used by the anomalous canister grenades to make them balanced for grenade use.
|
||||
/obj/effect/anomaly/proc/anomalous_canister_setup()
|
||||
canister_spawned = TRUE
|
||||
return
|
||||
|
||||
/obj/effect/anomaly/item_interaction(mob/living/user, obj/item/used, list/modifiers)
|
||||
if(istype(used, /obj/item/analyzer))
|
||||
to_chat(user, "<span class='notice'>Analyzing... [src]'s unstable field is fluctuating along frequency [format_frequency(aSignal.frequency)], code [aSignal.code].</span>")
|
||||
@@ -107,11 +115,16 @@
|
||||
aSignal = /obj/item/assembly/signaler/anomaly/grav
|
||||
var/obj/effect/warp_effect/supermatter/warp
|
||||
|
||||
/obj/effect/anomaly/grav/Initialize(mapload, new_lifespan, _drops_core = TRUE, event_spawned = TRUE)
|
||||
/obj/effect/anomaly/grav/Initialize(mapload, new_lifespan, _drops_core = TRUE)
|
||||
. = ..()
|
||||
warp = new(src)
|
||||
vis_contents += warp
|
||||
if(!event_spawned) //So an anomaly in the hallway is assured to have some risk to it, but not make sm / vetus too much pain
|
||||
|
||||
var/static/list/loc_connections = list(
|
||||
COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered),
|
||||
)
|
||||
AddElement(/datum/element/connect_loc, loc_connections)
|
||||
if(!_drops_core) // So an anomaly in the hallway is assured to have some risk to it, but not make sm / vetus too much pain
|
||||
return
|
||||
for(var/I in 1 to 3)
|
||||
if(prob(75))
|
||||
@@ -119,11 +132,6 @@
|
||||
if(prob(75))
|
||||
new /obj/item/shard(loc)
|
||||
|
||||
var/static/list/loc_connections = list(
|
||||
COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered),
|
||||
)
|
||||
AddElement(/datum/element/connect_loc, loc_connections)
|
||||
|
||||
/obj/effect/anomaly/grav/Destroy()
|
||||
vis_contents -= warp
|
||||
QDEL_NULL(warp) // don't want to leave it hanging
|
||||
@@ -207,7 +215,7 @@
|
||||
canshock = TRUE
|
||||
for(var/mob/living/M in get_turf(src))
|
||||
mobShock(M)
|
||||
if(explosive) //Let us not fuck up the sm that much
|
||||
if(explosive || canister_spawned) // Let us not fuck up the sm that much
|
||||
tesla_zap(src, zap_range, power, zap_flags)
|
||||
|
||||
/obj/effect/anomaly/flux/proc/on_atom_entered(datum/source, atom/movable/entered)
|
||||
@@ -224,18 +232,22 @@
|
||||
canshock = FALSE //Just so you don't instakill yourself if you slam into the anomaly five times in a second.
|
||||
M.electrocute_act(shockdamage, name, flags = SHOCK_NOGLOVES)
|
||||
if(!knockdown)
|
||||
M.Weaken(explosive ? 6 SECONDS : 3 SECONDS) //Back to being deadly if you touch it, rather than just being able to crawl out of it. Non explosive ones less deadly, since you can't loot them
|
||||
M.Weaken((explosive || canister_spawned) ? 6 SECONDS : 3 SECONDS) // Back to being deadly if you touch it, rather than just being able to crawl out of it. Non explosive ones less deadly, since you can't loot them
|
||||
else
|
||||
M.KnockDown(3 SECONDS)
|
||||
|
||||
/obj/effect/anomaly/flux/detonate()
|
||||
if(explosive)
|
||||
if(explosive && !canister_spawned)
|
||||
explosion(src, 1, 4, 16, 18, FALSE) // Set adminlog to FALSE for custom logging
|
||||
message_admins("\A [name] has detonated at [impact_area][ADMIN_COORDJMP(impact_area)]")
|
||||
log_admin("\A [name] has detonated at [impact_area]")
|
||||
else
|
||||
new /obj/effect/particle_effect/sparks(loc)
|
||||
|
||||
/obj/effect/anomaly/flux/anomalous_canister_setup()
|
||||
power = 3000
|
||||
return ..()
|
||||
|
||||
/obj/effect/anomaly/bluespace
|
||||
name = "bluespace anomaly"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
@@ -336,6 +348,10 @@
|
||||
M.client.screen -= blueeffect
|
||||
qdel(blueeffect)
|
||||
|
||||
/obj/effect/anomaly/bluespace/anomalous_canister_setup()
|
||||
mass_teleporting = FALSE
|
||||
return ..()
|
||||
|
||||
/obj/effect/anomaly/pyro
|
||||
name = "pyroclastic anomaly"
|
||||
icon_state = "mustard"
|
||||
@@ -362,7 +378,7 @@
|
||||
T.blind_release_air(air)
|
||||
|
||||
/obj/effect/anomaly/pyro/detonate()
|
||||
if(produces_slime)
|
||||
if(produces_slime && !canister_spawned)
|
||||
INVOKE_ASYNC(src, PROC_REF(makepyroslime))
|
||||
if(drops_core)
|
||||
message_admins("\A [name] has detonated at [impact_area][ADMIN_COORDJMP(impact_area)]")
|
||||
@@ -524,12 +540,14 @@
|
||||
step_towards(O, src)
|
||||
for(var/mob/living/M in T.contents)
|
||||
step_towards(M, src)
|
||||
if(drops_core)
|
||||
if(drops_core || canister_spawned)
|
||||
M.Weaken(3.5 SECONDS) //You ran into a black hole, you ride the pain train.
|
||||
M.KnockDown(7 SECONDS)
|
||||
|
||||
//Damaging the turf
|
||||
if(T && prob(turf_removal_chance))
|
||||
if(isfloorturf(T) && canister_spawned)
|
||||
return
|
||||
T.ex_act(ex_act_force)
|
||||
|
||||
#undef ANOMALY_MOVECHANCE
|
||||
|
||||
@@ -0,0 +1,485 @@
|
||||
|
||||
/// The number of anomalous particulate gatherings per objective
|
||||
#define NUM_ANOM_PER_OBJ 5
|
||||
|
||||
/datum/anomalous_particulate_tracker
|
||||
/// The total number of gatherings that have been drained, for tracking.
|
||||
var/num_drained = 0
|
||||
/// List of tracked influences (reality smashes)
|
||||
var/list/obj/effect/anomalous_particulate/smashes = list()
|
||||
/// List of minds with the objective to get particulate
|
||||
var/list/datum/mind/tracked_objectiveholders = list()
|
||||
|
||||
/datum/anomalous_particulate_tracker/Destroy(force)
|
||||
if(GLOB.anomaly_smash_track == src)
|
||||
stack_trace("[type] was deleted. Antagonists may no longer access any particulate. Fix it, or call coder support.")
|
||||
message_admins("The [type] was deleted. Antagonists may no longer access any particulate. Fix it, or call coder support.")
|
||||
QDEL_LIST_CONTENTS(smashes)
|
||||
tracked_objectiveholders.Cut()
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Generates a set amount of reality smashes
|
||||
* based on the number of already existing smashes
|
||||
* and the number of minds we're tracking.
|
||||
*/
|
||||
/datum/anomalous_particulate_tracker/proc/generate_new_influences()
|
||||
var/how_many_can_we_make = 0
|
||||
for(var/antag_number in 1 to length(tracked_objectiveholders))
|
||||
how_many_can_we_make += max(NUM_ANOM_PER_OBJ - antag_number + 1, 1)
|
||||
|
||||
var/location_sanity = 0
|
||||
while((length(smashes) + num_drained) < how_many_can_we_make && location_sanity < 100)
|
||||
var/turf/chosen_location = get_safe_random_station_turf_equal_weight()
|
||||
|
||||
// We don't want them close to each other - at least 1 tile of separation
|
||||
var/list/nearby_things = range(1, chosen_location)
|
||||
var/obj/effect/anomalous_particulate/what_if_i_have_one = locate() in nearby_things
|
||||
var/obj/effect/visible_anomalous_particulate/what_if_i_had_one_but_its_used = locate() in nearby_things
|
||||
if(what_if_i_have_one || what_if_i_had_one_but_its_used)
|
||||
location_sanity++
|
||||
continue
|
||||
|
||||
new /obj/effect/anomalous_particulate(chosen_location)
|
||||
|
||||
/**
|
||||
* Adds a mind to the list of people that need things spawned
|
||||
*
|
||||
* Use this whenever you want to add someone to the list
|
||||
*/
|
||||
/datum/anomalous_particulate_tracker/proc/add_tracked_mind(datum/mind/obj_mind)
|
||||
tracked_objectiveholders |= obj_mind
|
||||
|
||||
// If our holder is on station, generate some new influences
|
||||
if(ishuman(obj_mind.current) && is_teleport_allowed(obj_mind.current.z))
|
||||
generate_new_influences()
|
||||
|
||||
/**
|
||||
* Removes a mind from the list of people that need things spawned
|
||||
*
|
||||
* Use this whenever you want to remove someone from the list
|
||||
*/
|
||||
/datum/anomalous_particulate_tracker/proc/remove_tracked_mind(datum/mind/obj_mind)
|
||||
tracked_objectiveholders -= obj_mind
|
||||
|
||||
#define BLUESPACE 1
|
||||
#define GRAV 2
|
||||
#define PYRO 3
|
||||
#define FLUX 4
|
||||
#define VORTEX 5
|
||||
#define CRYO 6
|
||||
|
||||
/obj/effect/visible_anomalous_particulate
|
||||
name = "cloud of anomalous particulate"
|
||||
icon_state = "particulate_cloud"
|
||||
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
alpha = 0
|
||||
invisibility = INVISIBILITY_LEVEL_TWO
|
||||
/// The effect on examine
|
||||
var/examine_effect
|
||||
/// The effect on touch / bump
|
||||
var/bump_effect
|
||||
/// The effect passively
|
||||
var/process_effect
|
||||
|
||||
/*
|
||||
* What does this do?
|
||||
* First, we choose a sprite for the texture, and rotate it.
|
||||
* Next, a shape. Also potentially rotated.
|
||||
* Finally, a transparent overlay to apply over the first texture.
|
||||
* After that we queue up the fade in and effects
|
||||
*/
|
||||
/obj/effect/visible_anomalous_particulate/Initialize(mapload)
|
||||
. = ..()
|
||||
addtimer(CALLBACK(src, PROC_REF(show_presence)), 15 SECONDS)
|
||||
var/icon/our_icon
|
||||
switch(rand(1, 10)) // texture
|
||||
if(1 to 3)
|
||||
our_icon = icon('icons/effects/effects.dmi', "particulate_cloud")
|
||||
if(4 to 6)
|
||||
our_icon = icon('icons/effects/effects.dmi', "cryoanomaly")
|
||||
if(7 to 8)
|
||||
our_icon = icon('icons/effects/effects.dmi', "anom")
|
||||
if(9)
|
||||
our_icon = icon('icons/effects/effects.dmi', "void_conduit")
|
||||
if(10)
|
||||
our_icon = icon('icons/effects/effects.dmi', "static_base")
|
||||
|
||||
var/icon/alpha_mask
|
||||
switch(rand(1, 8)) // shape
|
||||
if(1 to 6)
|
||||
alpha_mask = new('icons/effects/effects.dmi', "void_conduit")
|
||||
if(7)
|
||||
alpha_mask = new('icons/effects/effects.dmi', "cryoanomaly")
|
||||
if(8)
|
||||
alpha_mask = new('icons/effects/effects.dmi', "anom")
|
||||
switch(rand(1,8))
|
||||
if(1)
|
||||
alpha_mask.Turn(0)
|
||||
if(2)
|
||||
alpha_mask.Turn(90)
|
||||
if(3)
|
||||
alpha_mask.Turn(180)
|
||||
if(4)
|
||||
alpha_mask.Turn(270)
|
||||
if(5 to 8)
|
||||
alpha_mask.Turn(rand(1, 359))
|
||||
|
||||
switch(rand(1,8))
|
||||
if(1)
|
||||
our_icon.Turn(0)
|
||||
if(2)
|
||||
our_icon.Turn(90)
|
||||
if(3)
|
||||
our_icon.Turn(180)
|
||||
if(4)
|
||||
our_icon.Turn(270)
|
||||
if(5 to 8)
|
||||
our_icon.Turn(rand(1, 359))
|
||||
|
||||
our_icon.AddAlphaMask(alpha_mask) // Finally, let's mix in a distortion effect.
|
||||
icon = our_icon
|
||||
switch(rand(1,9))
|
||||
if(1)
|
||||
color = list(0.2,0.45,0,0, 0,1,0,0, 0,0,0.2,0, 0,0,0,1, 0,0,0,0) // green
|
||||
if(2)
|
||||
color = list(1,0,0,0, 0,0.4,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0) // purple per video 1
|
||||
if(3)
|
||||
color = list(0.4,0,0,0, 0,1.1,0,0, 0,0,1.65,0, -0.3,0.15,0,1, 0,0,0,0) // light blue
|
||||
if(4)
|
||||
color = list(0.5,1,0.9,0, 0,1,0,0, 0,0,0.5,0, 0,0,0,1, 0,0,0,0) // green blue
|
||||
if(5)
|
||||
color = list(0.8,0,0,0.35,0.2,0, 0.5,0,0.65,0.1,0,0) // red
|
||||
if(6)
|
||||
color = list(1.3,0,0,0, 0,1.65,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) // green blue
|
||||
if(7)
|
||||
color = list(-1,0,0,0, 0,-1,0,0, 0,0,-1,0, (rand(1,100) / 100),(rand(1,100) / 100),(rand(1,100) / 100),1, 0,0,0,0) // random inverted
|
||||
if(8)
|
||||
color = list(-1,0,0,0, 0,-1,0,0, 0,0,-1,0, 0.8,0.85,0.95,1, 0,0,0,0) // cool inverted
|
||||
if(9)
|
||||
color = list((rand(1,100) / 100),0,0,0, 0,(rand(1,100) / 100),0,0, 0,0,(rand(1,100) / 100),0, 0,0,0,1, 0,0,0,0) // random normal
|
||||
|
||||
var/mutable_appearance/theme_icon
|
||||
var/MA_alpha = pick(30, 40, 20, 25, 35, 10, 60)
|
||||
switch(rand(1, 5)) // final overlay effect
|
||||
if(1 to 3)
|
||||
theme_icon = mutable_appearance('icons/effects/effects.dmi', "static_base", FLOAT_LAYER - 1, alpha = MA_alpha, appearance_flags = appearance_flags | RESET_TRANSFORM)
|
||||
if(4)
|
||||
theme_icon = mutable_appearance('icons/effects/effects.dmi', "emp_disable", FLOAT_LAYER - 1, alpha = MA_alpha, appearance_flags = appearance_flags | RESET_TRANSFORM)
|
||||
if(5)
|
||||
theme_icon = mutable_appearance('icons/effects/effects.dmi', "anom", FLOAT_LAYER - 1, alpha = MA_alpha, appearance_flags = appearance_flags | RESET_TRANSFORM)
|
||||
theme_icon.blend_mode = BLEND_INSET_OVERLAY
|
||||
var/matrix/M_three = matrix()
|
||||
switch(rand(1,8))
|
||||
if(1)
|
||||
M_three.Turn(0)
|
||||
if(2)
|
||||
M_three.Turn(90)
|
||||
if(3)
|
||||
M_three.Turn(180)
|
||||
if(4)
|
||||
M_three.Turn(270)
|
||||
if(5 to 8)
|
||||
M_three.Turn(rand(1, 359))
|
||||
|
||||
theme_icon.transform = M_three
|
||||
overlays += theme_icon
|
||||
// Applies some random effects to the final image
|
||||
switch(rand(1,5))
|
||||
if(1)
|
||||
add_filter("distort_1", 3, motion_blur_filter(1, 1))
|
||||
if(2)
|
||||
add_filter("distort_2", 1, gauss_blur_filter(size = 0.5))
|
||||
if(3)
|
||||
add_filter("distort_3", 2, angular_blur_filter(size = 5))
|
||||
if(4)
|
||||
apply_wibbly_filters(src)
|
||||
if(5) // No visual effect
|
||||
alpha = 1
|
||||
alpha = 1 // Resets the alpha for the show_presence fade in
|
||||
alpha = 0
|
||||
|
||||
|
||||
/obj/effect/visible_anomalous_particulate/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
|
||||
/*
|
||||
* Makes the influence fade in after 15 seconds.
|
||||
*/
|
||||
/obj/effect/visible_anomalous_particulate/proc/show_presence()
|
||||
invisibility = 0
|
||||
animate(src, alpha = 180, time = 15 SECONDS)
|
||||
addtimer(CALLBACK(src, PROC_REF(fade_presence)), 15 SECONDS)
|
||||
configure_effects()
|
||||
|
||||
/*
|
||||
* Makes the influence fade out over 20 minutes.
|
||||
*/
|
||||
/obj/effect/visible_anomalous_particulate/proc/fade_presence()
|
||||
animate(src, alpha = 0, time = 20 MINUTES)
|
||||
QDEL_IN(src, 20 MINUTES)
|
||||
|
||||
/*
|
||||
* Sets up the effects for looking at it / bumping into it / aoe.
|
||||
*/
|
||||
/obj/effect/visible_anomalous_particulate/proc/configure_effects()
|
||||
examine_effect = pick(BLUESPACE, GRAV, PYRO, FLUX, VORTEX, CRYO)
|
||||
bump_effect = pick(BLUESPACE, GRAV, PYRO, FLUX, VORTEX, CRYO)
|
||||
process_effect = pick(BLUESPACE, GRAV, PYRO, FLUX, VORTEX, CRYO)
|
||||
if(process_effect == VORTEX)
|
||||
set_light(
|
||||
l_range = 7,
|
||||
l_power = -3,
|
||||
l_color = "#ddd6cf")
|
||||
START_PROCESSING(SSobj, src)
|
||||
var/static/list/loc_connections = list(
|
||||
COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered),
|
||||
)
|
||||
AddElement(/datum/element/connect_loc, loc_connections)
|
||||
|
||||
/obj/effect/visible_anomalous_particulate/proc/on_atom_entered(datum/source, atom/movable/entered)
|
||||
trigger_bump_effect(entered)
|
||||
|
||||
/obj/effect/visible_anomalous_particulate/Bump(atom/A)
|
||||
trigger_bump_effect(A)
|
||||
|
||||
/obj/effect/visible_anomalous_particulate/Bumped(atom/movable/AM)
|
||||
trigger_bump_effect(AM)
|
||||
|
||||
/obj/effect/visible_anomalous_particulate/attack_hand(mob/living/user, list/modifiers)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
trigger_bump_effect(user)
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/effect/visible_anomalous_particulate/proc/trigger_bump_effect(atom/A)
|
||||
if(!isliving(A))
|
||||
return
|
||||
var/mob/living/victim = A
|
||||
switch(bump_effect)
|
||||
if(BLUESPACE) // Easy out of a department... but you'll be slow and unable to fight well for a minute.
|
||||
to_chat(victim, "<span class='userdanger'>You feel like everything around you is moving twice as fast!</span>")
|
||||
victim.apply_status_effect(STATUS_EFFECT_BLUESPACESLOWDOWN_LONG)
|
||||
victim.Slowed(1 MINUTES, 1)
|
||||
do_teleport(victim, get_turf(victim), 21, sound_in = 'sound/effects/phasein.ogg', safe_turf_pick = TRUE)
|
||||
if(GRAV) // Yeet
|
||||
to_chat(victim, "<span class='userdanger'>You bounce right off [src]!</span>")
|
||||
var/atom/target = get_edge_target_turf(victim, get_dir(src, get_step_away(victim, src)))
|
||||
victim.throw_at(target, 20, 3)
|
||||
if(PYRO) // I mean yeah, hot
|
||||
to_chat(victim, "<span class='danger'>[src] is perhaps a bit hot to the touch.</span>")
|
||||
victim.adjust_fire_stacks(12)
|
||||
victim.IgniteMob()
|
||||
if(FLUX) // Shock them... or charge the cell in the item they are holding!
|
||||
if(!ishuman(victim))
|
||||
victim.electrocute_act(20, src, flags = SHOCK_NOGLOVES)
|
||||
return
|
||||
var/list/hand_items = list(victim.get_active_hand(), victim.get_inactive_hand())
|
||||
var/charged_item = null
|
||||
for(var/obj/item in hand_items)
|
||||
if(istype(item, /obj/item/stock_parts/cell/))
|
||||
var/obj/item/stock_parts/cell/C = item
|
||||
C.charge = C.maxcharge
|
||||
charged_item = C
|
||||
break
|
||||
else if(item.contents)
|
||||
var/obj/I = null
|
||||
for(I in item.contents)
|
||||
if(istype(I, /obj/item/stock_parts/cell/))
|
||||
var/obj/item/stock_parts/cell/C = I
|
||||
C.charge = C.maxcharge
|
||||
item.update_icon()
|
||||
charged_item = item
|
||||
break
|
||||
if(!charged_item)
|
||||
victim.electrocute_act(20, src, flags = SHOCK_NOGLOVES)
|
||||
return
|
||||
to_chat(victim, "<span class='notice'>[charged_item] suddenly feels very warm!</span>")
|
||||
if(VORTEX) // sharp particulate
|
||||
to_chat(victim, "<span class='userdanger'>As you pass through [src], sharp particulate cuts into you!</span>")
|
||||
victim.adjustBruteLoss(30)
|
||||
if(CRYO) // slowdown via cold
|
||||
to_chat(victim, "<span class='userdanger'>As you pass through [src], you feel quite cold!</span>")
|
||||
victim.adjust_bodytemperature(-230)
|
||||
|
||||
|
||||
/obj/effect/visible_anomalous_particulate/examine(mob/user)
|
||||
. = ..()
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(hasHUD(user, ANOMALOUS_HUD))
|
||||
to_chat(user, "<span class='warning'>Your protective gear shields you from the anomalous effects. Best not to look at it without them.</span>")
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/victim = user
|
||||
switch(examine_effect)
|
||||
if(BLUESPACE) // Just a slowdown in spacetime
|
||||
to_chat(victim, "<span class='userdanger'>[src] really begins to draw in your focus, time slips on by around you...</span>")
|
||||
victim.apply_status_effect(STATUS_EFFECT_BLUESPACESLOWDOWN)
|
||||
victim.Slowed(15 SECONDS, 1)
|
||||
if(GRAV) // bonk to the head
|
||||
to_chat(victim, "<span class='userdanger'>Your head hurts just looking at [src]!</span>")
|
||||
victim.adjustBrainLoss(10)
|
||||
if(PYRO) // Just a nice warm glow
|
||||
to_chat(victim, "<span class='notice'>[src] gives off a nice warm glow.</span>")
|
||||
if(FLUX) // Emp yourself. This can be considered a benefit.
|
||||
to_chat(victim, "<span class='userdanger'>As you focus on [src], a shock travels through you and your electronics!</span>")
|
||||
victim.emp_act(EMP_LIGHT)
|
||||
if(VORTEX) // Darkness consumes you. Or your vision, for a moment
|
||||
to_chat(victim, "<span class='userdanger'>[src] is so dark that... everything else kinda is.</span>")
|
||||
victim.AdjustEyeBlind(5 SECONDS)
|
||||
if(CRYO) // A cool refresher. Though a bit toxic.
|
||||
to_chat(victim, "<span class='warning'>A cool feeling passes through you, closing your wounds. Feels... a bit off though...</span>")
|
||||
victim.adjustBruteLoss(-10)
|
||||
victim.adjustFireLoss(-20)
|
||||
victim.adjustToxLoss(15)
|
||||
victim.adjust_bodytemperature(-75)
|
||||
|
||||
/obj/effect/visible_anomalous_particulate/process()
|
||||
var/turf/our_turf = get_turf(src)
|
||||
var/area/to_be_modified = get_area(our_turf)
|
||||
switch(process_effect)
|
||||
if(BLUESPACE) // Condense a crystal now and then
|
||||
if(prob(2))
|
||||
visible_message( "<span class='notice'>A drop of blue particulate from [src] condenses into a shining crystal.</span>")
|
||||
new /obj/item/stack/ore/bluespace_crystal/refined(get_turf(src))
|
||||
if(GRAV) // Nice gravity. Invert it.
|
||||
if(prob(1))
|
||||
if(has_gravity(src, our_turf))
|
||||
to_be_modified.gravitychange(FALSE, to_be_modified)
|
||||
else
|
||||
to_be_modified.gravitychange(TRUE, to_be_modified)
|
||||
if(PYRO) // Keeps the room warm
|
||||
var/datum/milla_safe/visible_anomalous_particulate/milla = new()
|
||||
milla.invoke_async(src)
|
||||
if(FLUX) // Science we need like 10 power cells please
|
||||
if(to_be_modified.apc)
|
||||
var/obj/machinery/power/apc/A = to_be_modified.apc[1]
|
||||
if(A.operating && A.cell)
|
||||
A.cell.charge = max(0, A.cell.charge - 25)
|
||||
if(A.charging == APC_FULLY_CHARGED) // If the cell was full
|
||||
A.charging = APC_IS_CHARGING // It's no longer full
|
||||
// Vortex just has darkness, no process needed
|
||||
if(CRYO) // A cool blue glow. AKA a radioactive one.
|
||||
if(prob(33))
|
||||
radiation_pulse(src, 1600, ALPHA_RAD)
|
||||
radiation_pulse(src, 1600, BETA_RAD)
|
||||
radiation_pulse(src, 1600, GAMMA_RAD)
|
||||
|
||||
/datum/milla_safe/visible_anomalous_particulate
|
||||
|
||||
/datum/milla_safe/visible_anomalous_particulate/on_run(obj/effect/visible_anomalous_particulate/source)
|
||||
var/turf/simulated/L = get_turf(source)
|
||||
if(!istype(L))
|
||||
return
|
||||
var/datum/gas_mixture/env = get_turf_air(L)
|
||||
if(env.temperature() == 60 + T0C)
|
||||
return
|
||||
var/transfer_moles = 0.25 * env.total_moles()
|
||||
|
||||
var/datum/gas_mixture/removed = env.remove(transfer_moles)
|
||||
|
||||
if(!removed)
|
||||
return
|
||||
var/heat_capacity = removed.heat_capacity()
|
||||
|
||||
if(heat_capacity)
|
||||
if(removed.temperature() < 60 + T0C)
|
||||
removed.set_temperature(min(removed.temperature() + 80000 / heat_capacity, 1000))
|
||||
else
|
||||
removed.set_temperature(max(removed.temperature() - 80000 / heat_capacity, TCMB))
|
||||
env.merge(removed)
|
||||
|
||||
/obj/effect/visible_anomalous_particulate/add_fingerprint(mob/living/M, ignoregloves)
|
||||
return // No detective you can not scan the fucking influence to find out who touched it
|
||||
|
||||
#undef BLUESPACE
|
||||
#undef GRAV
|
||||
#undef PYRO
|
||||
#undef FLUX
|
||||
#undef CRYO
|
||||
#undef VORTEX
|
||||
|
||||
/obj/effect/anomalous_particulate
|
||||
name = "cloud of anomalous particulate"
|
||||
icon_state = "hud_anom"
|
||||
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
invisibility = INVISIBILITY_LEVEL_TWO
|
||||
hud_possible = list(ANOMALOUS_HUD)
|
||||
/// Whether we're currently being drained or not.
|
||||
var/being_drained = FALSE
|
||||
|
||||
/obj/effect/anomalous_particulate/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.anomaly_smash_track.smashes += src
|
||||
prepare_huds()
|
||||
for(var/datum/atom_hud/data/anomalous/a_hud in GLOB.huds)
|
||||
a_hud.add_to_hud(src)
|
||||
do_hud_stuff()
|
||||
|
||||
/obj/effect/anomalous_particulate/Destroy()
|
||||
GLOB.anomaly_smash_track.smashes -= src
|
||||
return ..()
|
||||
|
||||
/obj/effect/anomalous_particulate/add_fingerprint(mob/living/M, ignoregloves)
|
||||
return // No detective you can not scan the fucking influence to find out who touched it
|
||||
|
||||
/obj/effect/anomalous_particulate/attack_by(obj/item/attacking, mob/user, params)
|
||||
if(..())
|
||||
return FINISH_ATTACK
|
||||
if(drain_with_device(user, attacking))
|
||||
return FINISH_ATTACK
|
||||
return ..()
|
||||
|
||||
/obj/effect/anomalous_particulate/proc/drain_with_device(mob/user, obj/item/ppp_processor/processor)
|
||||
if(!istype(processor) || being_drained)
|
||||
return FALSE
|
||||
INVOKE_ASYNC(src, PROC_REF(drain_influence), user, processor)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Begin to drain the influence, setting being_drained,
|
||||
* registering an examine signal, and beginning a do_after.
|
||||
*
|
||||
* If successful, the influence is drained and deleted.
|
||||
*/
|
||||
/obj/effect/anomalous_particulate/proc/drain_influence(mob/living/user, obj/item/ppp_processor/processor)
|
||||
if(processor.clouds_processed >= 3)
|
||||
to_chat(user, "<span class='warning'>Your PPPProcessor is full!</span>")
|
||||
return
|
||||
if(processor.clouds_processed == -1)
|
||||
to_chat(user, "<span class='warning'>Your PPPProcessor has no canisters to collect particulate with!</span>")
|
||||
return
|
||||
being_drained = TRUE
|
||||
to_chat(user, "<span class='notice'>Your PPPProcessor begins to energize and collect [src]...</span>")
|
||||
|
||||
if(!do_after(user, 10 SECONDS, target = src, hidden = TRUE))
|
||||
being_drained = FALSE
|
||||
return
|
||||
|
||||
// Aaand now we delete it
|
||||
after_drain(user, processor)
|
||||
|
||||
/**
|
||||
* Handle the effects of the drain.
|
||||
*/
|
||||
/obj/effect/anomalous_particulate/proc/after_drain(mob/living/user, obj/item/ppp_processor/processor)
|
||||
if(user)
|
||||
to_chat(user, "<span class='warning'>[src] begins to intensify!</span>")
|
||||
|
||||
new /obj/effect/visible_anomalous_particulate(drop_location())
|
||||
|
||||
processor.collect()
|
||||
if(processor.clouds_processed >= 3)
|
||||
to_chat(user, "<span class='notice'>[processor] has it's 3 canisters filled. Be sure to process the information!</span>")
|
||||
|
||||
GLOB.anomaly_smash_track.num_drained++
|
||||
qdel(src)
|
||||
|
||||
#undef NUM_ANOM_PER_OBJ
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/obj/item/nuke_core
|
||||
name = "plutonium core"
|
||||
desc = "Extremely radioactive. Wear goggles."
|
||||
icon = 'icons/obj/nuke_tools.dmi'
|
||||
icon = 'icons/obj/theft_tools.dmi'
|
||||
icon_state = "plutonium_core"
|
||||
inhand_icon_state = "plutoniumcore"
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
@@ -39,7 +39,7 @@
|
||||
/obj/item/nuke_core_container
|
||||
name = "nuke core container"
|
||||
desc = "A lead-lined secure container produced by the Syndicate for the express purpose of extracting the valuable radioactive cores of nuclear weapons."
|
||||
icon = 'icons/obj/nuke_tools.dmi'
|
||||
icon = 'icons/obj/theft_tools.dmi'
|
||||
icon_state = "core_container_empty"
|
||||
inhand_icon_state = "syringe_kit"
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF //Don't want people trying to break it open with acid, then destroying the core.
|
||||
@@ -349,7 +349,7 @@
|
||||
/obj/item/scalpel/supermatter
|
||||
name = "supermatter scalpel"
|
||||
desc = "A scalpel with a fragile tip of condensed hyper-noblium gas, searingly cold to the touch, that can safely shave a sliver off a supermatter crystal."
|
||||
icon = 'icons/obj/nuke_tools.dmi'
|
||||
icon = 'icons/obj/theft_tools.dmi'
|
||||
icon_state = "supermatter_scalpel"
|
||||
toolspeed = 0.5
|
||||
damtype = BURN
|
||||
@@ -363,7 +363,7 @@
|
||||
/obj/item/retractor/supermatter
|
||||
name = "supermatter extraction tongs"
|
||||
desc = "A pair of tongs made from condensed hyper-noblium gas, searingly cold to the touch, that can safely grip a supermatter sliver."
|
||||
icon = 'icons/obj/nuke_tools.dmi'
|
||||
icon = 'icons/obj/theft_tools.dmi'
|
||||
icon_state = "supermatter_tongs"
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
@@ -440,3 +440,315 @@
|
||||
)
|
||||
QDEL_NULL(sliver)
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
|
||||
// This device is used to analyze and trigger the particulate
|
||||
/obj/item/ppp_processor
|
||||
name = "\improper Prototype Portable Particulate Processor"
|
||||
desc = "The Prototype Portable Particulate Processor, or PPPProcessor, for short, is a device designed to energize, collect, \
|
||||
and process anomalous particulate."
|
||||
icon = 'icons/obj/theft_tools.dmi'
|
||||
icon_state = "PPP_Processor_0"
|
||||
worn_icon_state = "gun"
|
||||
inhand_icon_state = "gun"
|
||||
lefthand_file = 'icons/mob/inhands/guns_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/guns_righthand.dmi'
|
||||
force = 10
|
||||
throwforce = 10
|
||||
attack_verb = list("processed", "perforated", "pounded", "pasted", "proded", "punished", "plowed into", "pommeled", "pummeled", "penetrated", "probed", "pulsed", "pulverized", "pillaged", "persecuted", "pasted", "peppered", "plundered", "put down", "pushed")
|
||||
origin_tech = "programming=6;plasma=6;syndicate=3"
|
||||
new_attack_chain = TRUE
|
||||
/// How many clouds have been processed?
|
||||
var/clouds_processed = 0
|
||||
/// Have we used it in hand to fully process the particulate and eject the canisters?
|
||||
var/fully_processed_particulate = FALSE
|
||||
/// Are we possibly processing particularly powerful packets?
|
||||
var/presently_processing_particular_particultate = FALSE
|
||||
/// The soundloop we use.
|
||||
var/datum/looping_sound/kitchen/microwave/me_cro_wah_vey
|
||||
|
||||
/obj/item/ppp_processor/Initialize(mapload)
|
||||
. = ..()
|
||||
me_cro_wah_vey = new /datum/looping_sound/kitchen/microwave(list(src), FALSE)
|
||||
|
||||
/obj/item/ppp_processor/Destroy()
|
||||
QDEL_NULL(me_cro_wah_vey)
|
||||
return ..()
|
||||
|
||||
/obj/item/ppp_processor/examine(mob/user)
|
||||
. = ..()
|
||||
if(fully_processed_particulate)
|
||||
. += "<span class='notice'>[src] has processed the data you now possess. All you need to do is present it after this shift.</span>"
|
||||
return
|
||||
if(clouds_processed < 3)
|
||||
. += "<span class='notice'>[src] has only [clouds_processed] out of 3 samples.</span>"
|
||||
if(clouds_processed == 3)
|
||||
. += "<span class='notice'>[src] has all 3 samples. Use it in hand to process the particulate.</span>"
|
||||
|
||||
|
||||
/obj/item/ppp_processor/activate_self(mob/user)
|
||||
if(..())
|
||||
return
|
||||
if(fully_processed_particulate)
|
||||
to_chat(user, "<span class='notice'>[src] has already processed and ejected the particulate canisters. Just make sure to escape with the processor!</span>")
|
||||
return
|
||||
if(clouds_processed < 3)
|
||||
to_chat(user, "<span class='warning'>[src] has only [clouds_processed] out of 3 samples. You still need to collect more!</span>")
|
||||
return
|
||||
if(presently_processing_particular_particultate)
|
||||
to_chat(user, "<span class='warning'>[src] is presently processing particularly powerful packets of your particular particulate. Wait for it to finish before proceeding.</span>")
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>[src] is presently processing the particulate. Please hold as processing finishes, and be aware it may eject collection canisters.</span>")
|
||||
if(me_cro_wah_vey)
|
||||
me_cro_wah_vey.start()
|
||||
addtimer(CALLBACK(src, PROC_REF(perfectly_processed), user), 15 SECONDS)
|
||||
presently_processing_particular_particultate = TRUE
|
||||
|
||||
/obj/item/ppp_processor/update_icon_state()
|
||||
. = ..()
|
||||
switch(clouds_processed)
|
||||
if(-1)
|
||||
icon_state = "PPP_Processor_-1"
|
||||
if(0)
|
||||
icon_state = "PPP_Processor_0"
|
||||
if(1)
|
||||
icon_state = "PPP_Processor_1"
|
||||
if(2)
|
||||
icon_state = "PPP_Processor_2"
|
||||
if(3)
|
||||
icon_state = "PPP_Processor_3"
|
||||
|
||||
/obj/item/ppp_processor/proc/collect()
|
||||
clouds_processed++
|
||||
update_icon()
|
||||
|
||||
/obj/item/ppp_processor/proc/perfectly_processed(mob/user)
|
||||
if(!QDELETED(user))
|
||||
to_chat(user, "<span class='notice'>[src] has perfectly processed the particulate. You may now use the canisters however you wish. Ensure the processor gets back to us.</span>")
|
||||
me_cro_wah_vey.stop()
|
||||
presently_processing_particular_particultate = FALSE
|
||||
clouds_processed = -1
|
||||
fully_processed_particulate = TRUE
|
||||
update_icon()
|
||||
var/list/potential_grenade_rewards = list()
|
||||
potential_grenade_rewards += subtypesof(/obj/item/grenade/anomalous_canister)
|
||||
potential_grenade_rewards += /obj/item/grenade/anomalous_canister
|
||||
potential_grenade_rewards += /obj/effect/abstract/dummy_mini_spawner
|
||||
potential_grenade_rewards -= /obj/item/grenade/anomalous_canister/mini
|
||||
|
||||
var/turf/our_turf = get_turf(src)
|
||||
our_turf.visible_message("<span class='warning'>Three containers are ejected out of [src].</span>")
|
||||
for(var/i in 1 to 3)
|
||||
var/obj/item/new_toy = pick_n_take(potential_grenade_rewards)
|
||||
new new_toy(get_turf(src))
|
||||
|
||||
/obj/item/clothing/glasses/hud/anomalous
|
||||
name = "anomalous particulate scanner HUD"
|
||||
desc = "A heads-up display that scans for anomalous particulate. Has a built in chameleon function, to help it blend in."
|
||||
icon_state = "sunhudmed"
|
||||
inhand_icon_state = "sunglasses"
|
||||
hud_types = DATA_HUD_ANOMALOUS
|
||||
|
||||
var/datum/action/item_action/chameleon_change/chameleon_action
|
||||
|
||||
/obj/item/clothing/glasses/hud/anomalous/Initialize(mapload)
|
||||
. = ..()
|
||||
chameleon_action = new(src)
|
||||
chameleon_action.chameleon_type = /obj/item/clothing/glasses
|
||||
chameleon_action.chameleon_name = "HUD"
|
||||
chameleon_action.chameleon_blacklist = list()
|
||||
chameleon_action.initialize_disguises()
|
||||
|
||||
/obj/item/clothing/glasses/hud/anomalous/Destroy()
|
||||
QDEL_NULL(chameleon_action)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/glasses/hud/anomalous/emp_act(severity)
|
||||
. = ..()
|
||||
chameleon_action.emp_randomise()
|
||||
|
||||
// The parent anomalous grenade type. Spawns a random anomaly.
|
||||
/obj/item/grenade/anomalous_canister
|
||||
name = "anomalous particulate canister"
|
||||
desc = "This canister contains a cloud of charged anomalous particulate. It can be armed to create a temporary anomaly. \
|
||||
Be careful, with a glass exterior, it may shatter early when thrown."
|
||||
icon_state = "anomalous_canister"
|
||||
inhand_icon_state = "emp"
|
||||
origin_tech = "magnets=6;combat=6;syndicate=2"
|
||||
/// The type of anomaly the canister will spawn.
|
||||
var/obj/effect/anomaly/anomaly_type
|
||||
/// The lifetime of the anomaly.
|
||||
var/anomaly_lifetime = 45 SECONDS
|
||||
/// How many anomalies the grenade will spawn
|
||||
var/number_of_anomalies = 1
|
||||
/// Have we primed? It contains a cloud of particulate matter. Breaking it is going to let the anomaly out.
|
||||
var/has_primed = FALSE
|
||||
/// Chance to be a varient that the glass will shatter when thrown earlier than expected. The smaller canisters are more metal spheres, and will not.
|
||||
var/shatter_chance = 20
|
||||
|
||||
/obj/item/grenade/anomalous_canister/Initialize(mapload)
|
||||
. = ..()
|
||||
anomaly_type = pick(subtypesof(/obj/effect/anomaly))
|
||||
if(prob(shatter_chance))
|
||||
AddElement(/datum/element/shatters_when_thrown, /obj/effect/decal/cleanable/glass, 1, "shatter")
|
||||
|
||||
/obj/item/grenade/anomalous_canister/Destroy()
|
||||
prime()
|
||||
return ..()
|
||||
|
||||
/obj/item/grenade/anomalous_canister/prime()
|
||||
if(has_primed)
|
||||
return
|
||||
has_primed = TRUE
|
||||
var/turf/our_turf = get_turf(src)
|
||||
our_turf.visible_message("<span class='danger'>[src] shatters open, the [(number_of_anomalies - 1) ? "clouds" : "cloud"] of particulate rapidly forming into something more!</span>")
|
||||
playsound(src, "shatter", 70, TRUE)
|
||||
update_mob()
|
||||
for(var/i in 1 to number_of_anomalies)
|
||||
var/obj/effect/anomaly/A = new anomaly_type(our_turf, anomaly_lifetime, FALSE)
|
||||
A.anomalous_canister_setup()
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/grenade/anomalous_canister/dual_core
|
||||
name = "dual clouded anomalous particulate canister"
|
||||
icon_state = "anomalous_canister_dual"
|
||||
number_of_anomalies = 2
|
||||
anomaly_lifetime = 30 SECONDS
|
||||
|
||||
/obj/item/grenade/anomalous_canister/dual_core/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>Two smaller clouds of particulate are swirling around in this canister. It will likely form into two anomalies.</span>"
|
||||
|
||||
/obj/item/grenade/anomalous_canister/condensed
|
||||
name = "condensed anomalous particulate canister"
|
||||
icon_state = "anomalous_canister_condensed"
|
||||
anomaly_lifetime = 90 SECONDS
|
||||
|
||||
/obj/item/grenade/anomalous_canister/condensed/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>A large cloud of resiliant particulate is floating in this canister. It will last longer than other anomalies.</span>"
|
||||
|
||||
/obj/item/grenade/anomalous_canister/stabilized
|
||||
name = "stabilized anomalous particulate canister"
|
||||
desc = "The cloud of this particulate has stabilized enough for the computer to predict the anomaly it will condense into..."
|
||||
icon_state = "anomalous_canister_stable"
|
||||
|
||||
/obj/item/grenade/anomalous_canister/stabilized/examine(mob/user)
|
||||
. = ..()
|
||||
. += "<span class='notice'>The predicted result for the cloud to condense into is displayed as \an [anomaly_type::name]!</span>"
|
||||
|
||||
/obj/effect/abstract/dummy_mini_spawner
|
||||
|
||||
/obj/effect/abstract/dummy_mini_spawner/Initialize(mapload)
|
||||
. = ..()
|
||||
var/turf/our_turf = get_turf(src)
|
||||
our_turf.visible_message("<span class='warning'>One of the containers splits into 3 smaller capsules!</span>")
|
||||
for(var/i in 1 to 3)
|
||||
new /obj/item/grenade/anomalous_canister/mini(our_turf)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/item/grenade/anomalous_canister/mini
|
||||
name = "miniature anomalous particulate canister"
|
||||
desc = "This small sphere contains a small cloud of particulate. Likely won't form an anomally, but should still have a noticable impact"
|
||||
icon_state = "anomalous_canister_mini"
|
||||
w_class = 1
|
||||
shatter_chance = 0
|
||||
|
||||
/obj/item/grenade/anomalous_canister/mini/prime()
|
||||
if(has_primed)
|
||||
return
|
||||
has_primed = TRUE
|
||||
update_mob()
|
||||
var/turf/our_turf = get_turf(src)
|
||||
our_turf.visible_message("<span class='danger'>[src] activates and...</span>")
|
||||
playsound(src, "shatter", 70, TRUE)
|
||||
switch(anomaly_type)
|
||||
if(/obj/effect/anomaly/bluespace) // Teleport and slow combat for 15
|
||||
if(!is_teleport_allowed(z))
|
||||
visible_message("<span class='warning'>[src]'s fragments begin rapidly vibrating and blink out of existence.</span>")
|
||||
qdel(src)
|
||||
return
|
||||
for(var/mob/living/L in range(7, our_turf))
|
||||
do_teleport(L, get_turf(L), 7, sound_in = 'sound/effects/phasein.ogg')
|
||||
L.apply_status_effect(STATUS_EFFECT_BLUESPACESLOWDOWN)
|
||||
if(/obj/effect/anomaly/flux) // shock
|
||||
for(var/mob/living/L in view(7, our_turf))
|
||||
L.Beam(get_turf(src), icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = 5) // What? Why are we beaming from the mob to the turf? Turf to mob generates really odd results.
|
||||
L.electrocute_act(20, "electrical blast", flags = SHOCK_NOGLOVES)
|
||||
L.KnockDown(6 SECONDS)
|
||||
if(/obj/effect/anomaly/grav) // repulse
|
||||
var/list/thrownatoms = list()
|
||||
var/atom/throwtarget
|
||||
var/distfromcaster
|
||||
for(var/turf/T in range(7, our_turf)) // Done this way so things don't get thrown all around hilariously.
|
||||
for(var/atom/movable/AM in T)
|
||||
thrownatoms += AM
|
||||
|
||||
for(var/am in thrownatoms)
|
||||
var/atom/movable/AM = am
|
||||
if(AM == src || AM.anchored || AM.move_resist == INFINITY)
|
||||
continue
|
||||
|
||||
throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(AM, src)))
|
||||
distfromcaster = get_dist(src, AM)
|
||||
if(distfromcaster == 0)
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
M.Weaken(8 SECONDS)
|
||||
M.adjustBruteLoss(5)
|
||||
to_chat(M, "<span class='userdanger'>You're slammed into the floor by an anomalous force!</span>")
|
||||
else
|
||||
new /obj/effect/temp_visual/gravpush(get_turf(AM), get_dir(src, AM)) // created sparkles will disappear on their own
|
||||
if(isliving(AM))
|
||||
var/mob/living/M = AM
|
||||
M.Weaken(3 SECONDS)
|
||||
to_chat(M, "<span class='userdanger'>You're thrown back by a anomalous force!</span>")
|
||||
spawn(0)
|
||||
AM.throw_at(throwtarget, ((clamp((5 - (clamp(distfromcaster - 2, 0, distfromcaster))), 3, 5))), 1) // So stuff gets tossed around at the same time.
|
||||
if(/obj/effect/anomaly/pyro) // burn
|
||||
var/datum/gas_mixture/air = new()
|
||||
air.set_temperature(1000)
|
||||
air.set_toxins(20)
|
||||
air.set_oxygen(20)
|
||||
our_turf.blind_release_air(air)
|
||||
for(var/mob/living/L in view(7, our_turf))
|
||||
L.adjust_fire_stacks(6)
|
||||
L.IgniteMob()
|
||||
if(/obj/effect/anomaly/cryo) // weaker anomaly grenade
|
||||
for(var/turf/simulated/floor/T in view(4, our_turf))
|
||||
T.MakeSlippery(TURF_WET_ICE)
|
||||
for(var/mob/living/carbon/C in T)
|
||||
C.adjust_bodytemperature(-230)
|
||||
C.apply_status_effect(/datum/status_effect/freon)
|
||||
if(/obj/effect/anomaly/bhole) // big smoke that doesn't last as long as a smoke grenade
|
||||
var/datum/effect_system/smoke_spread/smoke
|
||||
smoke = new /datum/effect_system/smoke_spread/bad()
|
||||
smoke.set_up(20, FALSE, src)
|
||||
playsound(our_turf, 'sound/effects/smoke.ogg', 50, TRUE, -3)
|
||||
smoke.start()
|
||||
if(!QDELETED(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/paper/guides/antag/anomalous_particulate
|
||||
name = "Particulate gathering instructions"
|
||||
info = {"<b>Instructions on your new PPPProcessor and HUD</b><br>
|
||||
<br>
|
||||
First off, equip your glasses. You will need them to find the particulate. We heavily advise against losing them.<br>
|
||||
<br>
|
||||
This will allow you to identify the uncharged anomalous particulate aboard the station. It can be anywhere, stalk out rooms and or use cameras to find it.\
|
||||
It will look like <b>purple sparkles, with a yellow and red square targeting highlight.</b><br>
|
||||
<br>
|
||||
Afterwords, approach the particulate with the PPPProcessor, and use it on the particulate. It will charge and capture a sample of it.<br>
|
||||
<br>
|
||||
<b>Warning:</b> Charged particulate is dangerous. Wear the goggles and leave the area. Try not to get caught in doing so.<br>
|
||||
<br>
|
||||
After collecting 3 diffrent unique samples (We will not accept a sample another agent has collected), use the scanner in hand to begin processing the particulate.<br>
|
||||
<br>
|
||||
After a short processing period, processing will be complete and you can bring the processor back to us. Additionally, 3 collection cansiters should eject.<br>
|
||||
<br>
|
||||
Feel free to use the canisters however you wish, they should be effective weapons, though do write down the results for us.
|
||||
<br><hr>
|
||||
<font size =\"1\"><i>We are not liable for any health conditions you may recive from scanning particulate or using the canisters.</i></font>
|
||||
"}
|
||||
|
||||
|
||||
@@ -518,6 +518,16 @@
|
||||
new /obj/item/nuke_core_container/supermatter(src)
|
||||
new /obj/item/paper/guides/antag/supermatter_sliver(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/anomalous_particulate
|
||||
|
||||
desc = "It's just an ordinary box."
|
||||
icon_state = "box"
|
||||
|
||||
/obj/item/storage/box/syndie_kit/anomalous_particulate/populate_contents()
|
||||
new /obj/item/ppp_processor(src)
|
||||
new /obj/item/clothing/glasses/hud/anomalous(src)
|
||||
new /obj/item/paper/guides/antag/anomalous_particulate(src)
|
||||
|
||||
/obj/item/storage/box/syndie_kit/revolver
|
||||
name = "\improper .357 revolver kit"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user