mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-13 11:12:14 +00:00
## About The Pull Request This is a remake of: - #77188 - #86655 Both were DNM'd due to a lack of difficulty requirements for spawning a singularity as a shuttle event. --- **No Escape - Final Traitor Objective:** - Spawns a special singularity beacon, syndicate inducer, and wrench. - The beacon must be powered with an inducer and planted on the shuttle to work. - The beacon slowly increases the chance of a massive STAGE SIX (11x11) singularity to appear (1% every 8 seconds) - The beacon can be turned on at any time, but will only increase the chance while on the shuttle and if it is in transit - After 5 seconds the crew gets an announcement that a singularity is approaching and has an extra minute of transit time due to time dilation - If the beacon is turned off or destroyed it decreases the probability by the same rate. (-1% every 8 seconds) - If the beacon is spaced while active it decreases the probability by x2 rate. (-2% every 8 seconds) - If the singularity is spawned while the beacon is disabled or spaced, there is a chance for it to not directly hit the shuttle (but since it's so big it will likely brush against the side) To prevent the singularity from instantly appearing and to give the crew a chance to react, it starts with a negative probability that takes 15 seconds to reach 0%. Deactivating, destroying, or spacing the beacon will slowly reverse the chance but it's not an instant guarantee. So the longer you wait to act, the worse your chances are! I cleaned up quite a bit of the singularity code while I was working on this. CC @Time-Green @MrMelbert ## Why It's Good For The Game There have been several attempts to add a singularity shuttle event that could be triggered but it was deemed too chaotic or the requirements too easy so they were restricted to admin-only events. Making it a final traitor objective, sets a high requirement that must be achieved before activating it as a doomsday event. It also gives the crew a chance to intervene and stop the event before disaster strikes. It's similar to a syndicate bomb ticking down while on the shuttle that serves to be climatic. ## Changelog 🆑 add: Add no escape final traitor objective that spawns a stage six (11x11) singularity shuttle event. /🆑
519 lines
16 KiB
Plaintext
519 lines
16 KiB
Plaintext
/// The gravitational singularity
|
|
/obj/singularity
|
|
name = "gravitational singularity"
|
|
desc = "A gravitational singularity."
|
|
icon = 'icons/obj/machines/engine/singularity.dmi'
|
|
icon_state = "singularity_s1"
|
|
anchored = TRUE
|
|
density = TRUE
|
|
move_resist = INFINITY
|
|
plane = MASSIVE_OBJ_PLANE
|
|
plane = ABOVE_LIGHTING_PLANE
|
|
light_range = 6
|
|
appearance_flags = LONG_GLIDE
|
|
|
|
/// the prepended string to the icon state (singularity_s1, dark_matter_s1, etc)
|
|
var/singularity_icon_variant = "singularity"
|
|
|
|
/// The singularity component itself.
|
|
/// A weak ref in case an admin removes the component to preserve the functionality.
|
|
var/datum/weakref/singularity_component
|
|
/// type of singularity component made
|
|
var/singularity_component_type = /datum/component/singularity
|
|
///Current singularity size, from 1 to 6
|
|
var/current_size = 1
|
|
///Current allowed size for the singulo
|
|
var/allowed_size = 1
|
|
///maximum size this singuloth can get to.
|
|
var/maximum_stage = STAGE_SIX
|
|
|
|
///How strong are we?
|
|
var/energy = 50
|
|
///Do we lose energy over time?
|
|
var/dissipate = TRUE
|
|
/// How long should it take for us to dissipate in seconds?
|
|
var/dissipate_delay = 20
|
|
/// How much energy do we lose every dissipate_delay?
|
|
var/dissipate_strength = 1
|
|
/// How long its been (in seconds) since the last dissipation
|
|
var/time_since_last_dissipiation = 0
|
|
///Prob for event each tick
|
|
var/event_chance = 10
|
|
///Can i move by myself?
|
|
var/move_self = TRUE
|
|
///If the singularity has eaten a supermatter shard and can go to stage six
|
|
var/consumed_supermatter = FALSE
|
|
/// Is the black hole collapsing into nothing
|
|
var/collapsing = FALSE
|
|
/// How long it's been since the singulo last acted, in seconds
|
|
var/time_since_act = 0
|
|
/// What the game tells ghosts when you make one
|
|
var/ghost_notification_message = "IT'S LOOSE"
|
|
|
|
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE | PASSCLOSEDTURF | PASSMACHINE | PASSSTRUCTURE | PASSDOORS
|
|
flags_1 = SUPERMATTER_IGNORES_1
|
|
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF | SHUTTLE_CRUSH_PROOF
|
|
obj_flags = CAN_BE_HIT | DANGEROUS_POSSESSION
|
|
|
|
/obj/singularity/Initialize(mapload, starting_energy)
|
|
. = ..()
|
|
|
|
energy = starting_energy || energy
|
|
|
|
START_PROCESSING(SSsinguloprocess, src)
|
|
SSpoints_of_interest.make_point_of_interest(src)
|
|
|
|
var/datum/component/singularity/new_component = AddComponent(
|
|
singularity_component_type, \
|
|
consume_callback = CALLBACK(src, PROC_REF(consume)), \
|
|
)
|
|
|
|
singularity_component = WEAKREF(new_component)
|
|
|
|
check_energy()
|
|
|
|
for (var/obj/machinery/power/singularity_beacon/singu_beacon as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/power/singularity_beacon))
|
|
if (singu_beacon.active)
|
|
new_component.target = singu_beacon
|
|
break
|
|
|
|
if (!mapload)
|
|
notify_ghosts(
|
|
ghost_notification_message,
|
|
source = src,
|
|
header = ghost_notification_message,
|
|
ghost_sound = 'sound/machines/warning-buzzer.ogg',
|
|
notify_volume = 75,
|
|
)
|
|
|
|
/obj/singularity/Destroy()
|
|
STOP_PROCESSING(SSsinguloprocess, src)
|
|
return ..()
|
|
|
|
/obj/singularity/attack_tk(mob/user)
|
|
if(!iscarbon(user))
|
|
return
|
|
. = COMPONENT_CANCEL_ATTACK_CHAIN
|
|
var/mob/living/carbon/jedi = user
|
|
jedi.visible_message(
|
|
span_danger("[jedi]'s head begins to collapse in on itself!"),
|
|
span_userdanger("Your head feels like it's collapsing in on itself! This was really not a good idea!"),
|
|
span_hear("You hear something crack and explode in gore.")
|
|
)
|
|
jedi.Stun(3 SECONDS)
|
|
new /obj/effect/gibspawner/generic(get_turf(jedi), jedi)
|
|
jedi.apply_damage(30, BRUTE, BODY_ZONE_HEAD)
|
|
if(QDELETED(jedi))
|
|
return // damage was too much
|
|
if(jedi.stat == DEAD)
|
|
jedi.ghostize()
|
|
var/obj/item/bodypart/head/rip_u = jedi.get_bodypart(BODY_ZONE_HEAD)
|
|
rip_u.dismember(BURN) //nice try jedi
|
|
qdel(rip_u)
|
|
return
|
|
addtimer(CALLBACK(src, PROC_REF(carbon_tk_part_two), jedi), 0.1 SECONDS)
|
|
|
|
/obj/singularity/proc/carbon_tk_part_two(mob/living/carbon/jedi)
|
|
if(QDELETED(jedi))
|
|
return
|
|
new /obj/effect/gibspawner/generic(get_turf(jedi), jedi)
|
|
jedi.apply_damage(30, BRUTE, BODY_ZONE_HEAD)
|
|
if(QDELETED(jedi))
|
|
return // damage was too much
|
|
if(jedi.stat == DEAD)
|
|
jedi.ghostize()
|
|
var/obj/item/bodypart/head/rip_u = jedi.get_bodypart(BODY_ZONE_HEAD)
|
|
if(rip_u)
|
|
rip_u.dismember(BURN)
|
|
qdel(rip_u)
|
|
return
|
|
addtimer(CALLBACK(src, PROC_REF(carbon_tk_part_three), jedi), 0.1 SECONDS)
|
|
|
|
/obj/singularity/proc/carbon_tk_part_three(mob/living/carbon/jedi)
|
|
if(QDELETED(jedi))
|
|
return
|
|
new /obj/effect/gibspawner/generic(get_turf(jedi), jedi)
|
|
jedi.apply_damage(30, BRUTE, BODY_ZONE_HEAD)
|
|
if(QDELETED(jedi))
|
|
return // damage was too much
|
|
jedi.ghostize()
|
|
var/obj/item/bodypart/head/rip_u = jedi.get_bodypart(BODY_ZONE_HEAD)
|
|
if(rip_u)
|
|
rip_u.dismember(BURN)
|
|
qdel(rip_u)
|
|
|
|
/obj/singularity/ex_act(severity, target)
|
|
switch(severity)
|
|
if(EXPLODE_DEVASTATE)
|
|
if(current_size <= STAGE_TWO)
|
|
investigate_log("has been destroyed by a heavy explosion.", INVESTIGATE_ENGINE)
|
|
qdel(src)
|
|
return
|
|
|
|
energy -= round(((energy + 1) / 2), 1)
|
|
if(EXPLODE_HEAVY)
|
|
energy -= round(((energy + 1) / 3), 1)
|
|
if(EXPLODE_LIGHT)
|
|
energy -= round(((energy + 1) / 4), 1)
|
|
|
|
return TRUE
|
|
|
|
/obj/singularity/process(seconds_per_tick)
|
|
time_since_act += seconds_per_tick
|
|
if(time_since_act < 2)
|
|
return
|
|
time_since_act = 0
|
|
if(current_size >= STAGE_TWO)
|
|
if(prob(event_chance))
|
|
event()
|
|
dissipate(seconds_per_tick)
|
|
check_energy()
|
|
|
|
/obj/singularity/proc/dissipate(seconds_per_tick)
|
|
if (!dissipate)
|
|
return
|
|
|
|
time_since_last_dissipiation += seconds_per_tick
|
|
|
|
// Uses a while in case of especially long delta times
|
|
while (time_since_last_dissipiation >= dissipate_delay)
|
|
energy -= dissipate_strength
|
|
time_since_last_dissipiation -= dissipate_delay
|
|
|
|
/obj/singularity/proc/expand(force_size)
|
|
var/temp_allowed_size = allowed_size
|
|
|
|
if(force_size)
|
|
temp_allowed_size = force_size
|
|
|
|
if(temp_allowed_size >= STAGE_SIX && !consumed_supermatter)
|
|
temp_allowed_size = STAGE_FIVE
|
|
|
|
//cap it off if the singuloth has a maximum stage
|
|
temp_allowed_size = min(temp_allowed_size, maximum_stage)
|
|
|
|
if(temp_allowed_size == maximum_stage)
|
|
//It cant go smaller due to e loss
|
|
dissipate = FALSE
|
|
|
|
var/new_grav_pull
|
|
var/new_consume_range
|
|
|
|
switch(temp_allowed_size)
|
|
if(STAGE_ONE)
|
|
current_size = STAGE_ONE
|
|
icon = 'icons/obj/machines/engine/singularity.dmi'
|
|
icon_state = "[singularity_icon_variant]_s1"
|
|
pixel_x = 0
|
|
pixel_y = 0
|
|
new_grav_pull = 4
|
|
new_consume_range = 0
|
|
dissipate_delay = 10
|
|
time_since_last_dissipiation = 0
|
|
dissipate_strength = 1
|
|
if(STAGE_TWO)
|
|
if(check_cardinals_range(1, TRUE))
|
|
current_size = STAGE_TWO
|
|
icon = 'icons/effects/96x96.dmi'
|
|
icon_state = "[singularity_icon_variant]_s3"
|
|
pixel_x = -32
|
|
pixel_y = -32
|
|
new_grav_pull = 6
|
|
new_consume_range = 1
|
|
dissipate_delay = 5
|
|
time_since_last_dissipiation = 0
|
|
dissipate_strength = 5
|
|
if(STAGE_THREE)
|
|
if(check_cardinals_range(2, TRUE))
|
|
current_size = STAGE_THREE
|
|
icon = 'icons/effects/160x160.dmi'
|
|
icon_state = "[singularity_icon_variant]_s5"
|
|
pixel_x = -64
|
|
pixel_y = -64
|
|
new_grav_pull = 8
|
|
new_consume_range = 2
|
|
dissipate_delay = 4
|
|
time_since_last_dissipiation = 0
|
|
dissipate_strength = 20
|
|
if(STAGE_FOUR)
|
|
if(check_cardinals_range(3, TRUE))
|
|
current_size = STAGE_FOUR
|
|
icon = 'icons/effects/224x224.dmi'
|
|
icon_state = "[singularity_icon_variant]_s7"
|
|
pixel_x = -96
|
|
pixel_y = -96
|
|
new_grav_pull = 10
|
|
new_consume_range = 3
|
|
dissipate_delay = 10
|
|
time_since_last_dissipiation = 0
|
|
dissipate_strength = 10
|
|
if(STAGE_FIVE)//this one also lacks a check for gens because it eats everything
|
|
current_size = STAGE_FIVE
|
|
icon = 'icons/effects/288x288.dmi'
|
|
icon_state = "[singularity_icon_variant]_s9"
|
|
pixel_x = -128
|
|
pixel_y = -128
|
|
new_grav_pull = 10
|
|
new_consume_range = 4
|
|
dissipate = FALSE //It cant go smaller due to e loss
|
|
if(STAGE_SIX) //This only happens if a stage 5 singulo consumes a supermatter shard.
|
|
current_size = STAGE_SIX
|
|
icon = 'icons/effects/352x352.dmi'
|
|
icon_state = "[singularity_icon_variant]_s11"
|
|
pixel_x = -160
|
|
pixel_y = -160
|
|
new_grav_pull = 15
|
|
new_consume_range = 5
|
|
dissipate = FALSE
|
|
|
|
if(temp_allowed_size == STAGE_SIX)
|
|
AddComponent(/datum/component/vision_hurting)
|
|
else
|
|
qdel(GetComponent(/datum/component/vision_hurting))
|
|
|
|
var/datum/component/singularity/resolved_singularity = singularity_component.resolve()
|
|
if (!isnull(resolved_singularity))
|
|
resolved_singularity.consume_range = new_consume_range
|
|
resolved_singularity.grav_pull = new_grav_pull
|
|
resolved_singularity.disregard_failed_movements = current_size >= STAGE_FIVE
|
|
resolved_singularity.roaming = move_self && current_size >= STAGE_TWO
|
|
resolved_singularity.singularity_size = current_size
|
|
|
|
if(current_size == allowed_size)
|
|
investigate_log("grew to size [current_size].", INVESTIGATE_ENGINE)
|
|
return TRUE
|
|
else if(current_size < (--temp_allowed_size))
|
|
expand(temp_allowed_size)
|
|
else
|
|
return FALSE
|
|
|
|
/obj/singularity/proc/check_energy()
|
|
if(energy <= 0)
|
|
investigate_log("collapsed.", INVESTIGATE_ENGINE)
|
|
qdel(src)
|
|
return FALSE
|
|
switch(energy)//Some of these numbers might need to be changed up later -Mport
|
|
if(STAGE_ONE_ENERGY_REQUIREMENT to STAGE_TWO_ENERGY_REQUIREMENT)
|
|
allowed_size = STAGE_ONE
|
|
if(STAGE_TWO_ENERGY_REQUIREMENT to STAGE_THREE_ENERGY_REQUIREMENT)
|
|
allowed_size = STAGE_TWO
|
|
if(STAGE_THREE_ENERGY_REQUIREMENT to STAGE_FOUR_ENERGY_REQUIREMENT)
|
|
allowed_size = STAGE_THREE
|
|
if(STAGE_FOUR_ENERGY_REQUIREMENT to STAGE_FIVE_ENERGY_REQUIREMENT)
|
|
allowed_size = STAGE_FOUR
|
|
if(STAGE_FIVE_ENERGY_REQUIREMENT to STAGE_SIX_ENERGY_REQUIREMENT)
|
|
allowed_size = STAGE_FIVE
|
|
if(STAGE_SIX_ENERGY_REQUIREMENT to INFINITY)
|
|
allowed_size = consumed_supermatter ? STAGE_SIX : STAGE_FIVE
|
|
|
|
if(current_size != allowed_size)
|
|
expand()
|
|
return TRUE
|
|
|
|
/obj/singularity/proc/consume(atom/thing)
|
|
if(istype(thing, /obj/item/storage/backpack/holding) && !consumed_supermatter && !collapsing)
|
|
consume_boh(thing)
|
|
return
|
|
|
|
var/gain = thing.singularity_act(current_size, src)
|
|
energy += gain
|
|
if(istype(thing, /obj/machinery/power/supermatter_crystal) && !consumed_supermatter)
|
|
supermatter_upgrade()
|
|
|
|
/obj/singularity/proc/supermatter_upgrade()
|
|
name = "supermatter-charged [initial(name)]"
|
|
desc = "[initial(desc)] It glows fiercely with inner fire."
|
|
consumed_supermatter = TRUE
|
|
set_light(10)
|
|
|
|
/obj/singularity/proc/consume_boh(obj/boh)
|
|
collapsing = TRUE
|
|
name = "unstable [initial(name)]"
|
|
desc = "[initial(desc)] It seems to be collapsing in on itself."
|
|
visible_message(
|
|
message = span_danger("As [src] consumes [boh], it begins to collapse in on itself!"),
|
|
blind_message = span_hear("You hear aggressive crackling!"),
|
|
vision_distance = 15,
|
|
)
|
|
playsound(loc, 'sound/effects/clockcult_gateway_disrupted.ogg', 200, vary = TRUE, extrarange = 3, falloff_exponent = 1, frequency = -1, pressure_affected = FALSE, ignore_walls = TRUE, falloff_distance = 7)
|
|
addtimer(CALLBACK(src, PROC_REF(consume_boh_sfx)), 4 SECONDS)
|
|
animate(src, time = 4 SECONDS, transform = transform.Scale(0.25), flags = ANIMATION_PARALLEL, easing = ELASTIC_EASING)
|
|
animate(time = 0.5 SECONDS, alpha = 0)
|
|
QDEL_IN(src, 4.1 SECONDS)
|
|
qdel(boh)
|
|
|
|
/obj/singularity/proc/consume_boh_sfx()
|
|
playsound(loc, 'sound/effects/supermatter.ogg', 200, vary = TRUE, extrarange = 3, falloff_exponent = 1, frequency = 0.5, pressure_affected = FALSE, ignore_walls = TRUE, falloff_distance = 7)
|
|
|
|
/obj/singularity/proc/check_cardinals_range(steps, retry_with_move = FALSE)
|
|
. = length(GLOB.cardinals) //Should be 4.
|
|
for(var/i in GLOB.cardinals)
|
|
. -= check_turfs_in(i, steps) //-1 for each working direction
|
|
if(. && retry_with_move) //If there's still a positive value it means it didn't pass. Retry with move if applicable
|
|
for(var/i in GLOB.cardinals)
|
|
if(step(src, i)) //Move in each direction.
|
|
if(check_cardinals_range(steps, FALSE)) //New location passes, return true.
|
|
return TRUE
|
|
return !.
|
|
|
|
/obj/singularity/proc/check_turfs_in(direction = 0, step = 0)
|
|
if(!direction)
|
|
return FALSE
|
|
var/steps = 0
|
|
if(!step)
|
|
switch(current_size)
|
|
if(STAGE_ONE)
|
|
steps = 1
|
|
if(STAGE_TWO)
|
|
steps = 2
|
|
if(STAGE_THREE)
|
|
steps = 3
|
|
if(STAGE_FOUR)
|
|
steps = 4
|
|
if(STAGE_FIVE)
|
|
steps = 5
|
|
else
|
|
steps = step
|
|
var/list/turfs = list()
|
|
var/turf/considered_turf = loc
|
|
for(var/i in 1 to steps)
|
|
considered_turf = get_step(considered_turf,direction)
|
|
if(!isturf(considered_turf))
|
|
return FALSE
|
|
turfs.Add(considered_turf)
|
|
var/dir2 = 0
|
|
var/dir3 = 0
|
|
switch(direction)
|
|
if(NORTH, SOUTH)
|
|
dir2 = 4
|
|
dir3 = 8
|
|
if(EAST, WEST)
|
|
dir2 = 1
|
|
dir3 = 2
|
|
var/turf/other_turf = considered_turf
|
|
for(var/j = 1 to steps-1)
|
|
other_turf = get_step(other_turf,dir2)
|
|
if(!isturf(other_turf))
|
|
return FALSE
|
|
turfs.Add(other_turf)
|
|
for(var/k = 1 to steps-1)
|
|
considered_turf = get_step(considered_turf,dir3)
|
|
if(!isturf(considered_turf))
|
|
return FALSE
|
|
turfs.Add(considered_turf)
|
|
for(var/turf/check_turf in turfs)
|
|
if(isnull(check_turf))
|
|
continue
|
|
if(!can_move(check_turf))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/obj/singularity/proc/can_move(turf/considered_turf)
|
|
if(!considered_turf)
|
|
return FALSE
|
|
if (HAS_TRAIT(considered_turf, TRAIT_CONTAINMENT_FIELD))
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/obj/singularity/proc/event()
|
|
var/numb = rand(1,4)
|
|
switch(numb)
|
|
if(1)//EMP
|
|
emp_area()
|
|
if(2)//Stun mobs who lack optic scanners
|
|
mezzer()
|
|
if(3,4) //Sets all nearby mobs on fire
|
|
if(current_size < STAGE_SIX)
|
|
return FALSE
|
|
combust_mobs()
|
|
else
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/obj/singularity/proc/combust_mobs()
|
|
for(var/mob/living/carbon/burned_mob in urange(20, src, 1))
|
|
burned_mob.visible_message(
|
|
span_warning("[burned_mob]'s skin bursts into flame!"),
|
|
span_userdanger("You feel an inner fire as your skin bursts into flames!")
|
|
)
|
|
burned_mob.adjust_fire_stacks(5)
|
|
burned_mob.ignite_mob()
|
|
return
|
|
|
|
/obj/singularity/proc/mezzer()
|
|
for(var/mob/living/carbon/stunned_mob in oviewers(8, src))
|
|
if(stunned_mob.stat == DEAD || stunned_mob.is_blind())
|
|
continue
|
|
|
|
if(!ishuman(stunned_mob))
|
|
apply_stun(stunned_mob)
|
|
continue
|
|
|
|
var/mob/living/carbon/human/stunned_human = stunned_mob
|
|
if(istype(stunned_human.glasses, /obj/item/clothing/glasses/meson))
|
|
var/obj/item/clothing/glasses/meson/check_meson = stunned_human.glasses
|
|
if(check_meson.vision_flags & SEE_TURFS)
|
|
to_chat(stunned_human, span_notice("You look directly into the [name], good thing you had your protective eyewear on!"))
|
|
continue
|
|
|
|
apply_stun(stunned_mob)
|
|
|
|
/obj/singularity/proc/apply_stun(mob/living/carbon/stunned_mob)
|
|
stunned_mob.apply_effect(60, EFFECT_STUN)
|
|
stunned_mob.visible_message(
|
|
span_danger("[stunned_mob] stares blankly at the [name]!"),
|
|
span_userdanger("You look directly into the [name] and feel weak.")
|
|
)
|
|
|
|
/obj/singularity/proc/emp_area()
|
|
empulse(src, 8, 10)
|
|
|
|
/obj/singularity/singularity_act()
|
|
var/gain = (energy/2)
|
|
var/dist = max((current_size - 2),1)
|
|
investigate_log("has been destroyed by another singularity.", INVESTIGATE_ENGINE)
|
|
explosion(
|
|
src,
|
|
devastation_range = dist,
|
|
heavy_impact_range = dist * 2,
|
|
light_impact_range = dist * 4
|
|
)
|
|
qdel(src)
|
|
return gain
|
|
|
|
/obj/singularity/deadchat_plays(mode = DEMOCRACY_MODE, cooldown = 12 SECONDS)
|
|
. = AddComponent(/datum/component/deadchat_control/cardinal_movement, mode, list(), cooldown, CALLBACK(src, PROC_REF(stop_deadchat_plays)))
|
|
|
|
if(. == COMPONENT_INCOMPATIBLE)
|
|
return
|
|
|
|
move_self = FALSE
|
|
|
|
/obj/singularity/proc/stop_deadchat_plays()
|
|
move_self = TRUE
|
|
|
|
/obj/singularity/deadchat_controlled/Initialize(mapload, starting_energy)
|
|
. = ..()
|
|
deadchat_plays(mode = DEMOCRACY_MODE)
|
|
|
|
/// Special singularity spawned by being sucked into a black hole during emagged orion trail.
|
|
/obj/singularity/orion
|
|
move_self = FALSE
|
|
|
|
/obj/singularity/orion/Initialize(mapload)
|
|
. = ..()
|
|
var/datum/component/singularity/singularity = singularity_component.resolve()
|
|
singularity?.grav_pull = 1
|
|
|
|
/obj/singularity/orion/process(seconds_per_tick)
|
|
if(SPT_PROB(0.5, seconds_per_tick))
|
|
mezzer()
|
|
|
|
/// Special singularity that spawns for shuttle events only
|
|
/obj/singularity/shuttle_event
|
|
anchored = FALSE // this is required to work with shuttle event otherwise singularity gets stuck and doesn't move
|
|
|
|
/obj/singularity/shuttle_event/no_escape
|
|
energy = STAGE_SIX_ENERGY
|
|
consumed_supermatter = TRUE // so we can get to the final stage
|