Skip to content

Commit

Permalink
Singularity tweaks (#499)
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorDinamit authored Jan 13, 2024
1 parent 9164c33 commit bd4940a
Showing 1 changed file with 107 additions and 69 deletions.
176 changes: 107 additions & 69 deletions code/modules/power/singularity/singularity.dm
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,17 @@
var/last_warning

var/chained = 0//Adminbus chain-grab
// We only check IsContained() every ~30 seconds
var/next_contained_check_time = 0
var/last_contained_check = TRUE

/obj/singularity/New(loc, var/starting_energy = 50, var/temp = 0)
/obj/singularity/New(loc, starting_energy = 50, temp = 0)
//CARN: admin-alert for chuckle-fuckery.
admin_investigate_setup()
energy = starting_energy

if (temp)
addtimer(CALLBACK(null, /proc/qdel, src), temp)
if(temp)
QDEL_IN(src, temp)

..()
START_PROCESSING(SSobj, src)
Expand All @@ -48,9 +51,9 @@

/obj/singularity/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
return ..()

/obj/singularity/attack_hand(mob/user as mob)
/obj/singularity/attack_hand(mob/user)
consume(user)
return 1

Expand Down Expand Up @@ -83,11 +86,11 @@
dissipate()
check_energy()

if (current_size >= STAGE_TWO)
if(current_size >= STAGE_TWO)
move()
pulse()

if (prob(event_chance)) //Chance for it to run a special event TODO: Come up with one or two more that fit.
if(prob(event_chance)) //Chance for it to run a special event TODO: Come up with one or two more that fit.
event()

/obj/singularity/attack_ai() //To prevent ais from gibbing themselves when they click on one.
Expand All @@ -97,13 +100,13 @@
last_warning = world.time
var/count = locate(/obj/machinery/containment_field) in orange(30, src)

if (!count)
if(!count)
message_admins("A singulo has been created without containment fields active ([x], [y], [z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>).")

investigate_log("was created. [count ? "" : "<font color='red'>No containment fields were active.</font>"]", I_SINGULO)

/obj/singularity/proc/dissipate()
if (!dissipate)
if(!dissipate)
return

if(dissipate_track >= dissipate_delay)
Expand All @@ -118,11 +121,11 @@
return
var/temp_allowed_size = allowed_size

if (force_size)
if(force_size)
temp_allowed_size = force_size

switch (temp_allowed_size)
if (STAGE_ONE)
switch(temp_allowed_size)
if(STAGE_ONE)
SetName("gravitational singularity")
desc = "A gravitational singularity."
current_size = STAGE_ONE
Expand All @@ -139,7 +142,7 @@
emp_strong_range = 3
overlays.Cut()
visible_message("<span class='notice'>The singularity has shrunk to a rather pitiful size.</span>")
if (STAGE_TWO) //1 to 3 does not check for the turfs if you put the gens right next to a 1x1 then its going to eat them.
if(STAGE_TWO) //1 to 3 does not check for the turfs if you put the gens right next to a 1x1 then its going to eat them.
SetName("gravitational singularity")
desc = "A gravitational singularity."
current_size = STAGE_TWO
Expand All @@ -161,8 +164,8 @@
visible_message("<span class='notice'>The singularity noticeably grows in size.</span>")
else
visible_message("<span class='notice'>The singularity has shrunk to a less powerful size.</span>")
if (STAGE_THREE)
if ((check_turfs_in(1, 2)) && (check_turfs_in(2, 2)) && (check_turfs_in(4, 2)) && (check_turfs_in(8, 2)))
if(STAGE_THREE)
if((check_turfs_in(1, 2)) && (check_turfs_in(2, 2)) && (check_turfs_in(4, 2)) && (check_turfs_in(8, 2)))
SetName("gravitational singularity")
desc = "A gravitational singularity."
current_size = STAGE_THREE
Expand All @@ -185,7 +188,7 @@
else
visible_message("<span class='notice'>The singularity has returned to a safe size.</span>")
if(STAGE_FOUR)
if ((check_turfs_in(1, 3)) && (check_turfs_in(2, 3)) && (check_turfs_in(4, 3)) && (check_turfs_in(8, 3)))
if((check_turfs_in(1, 3)) && (check_turfs_in(2, 3)) && (check_turfs_in(4, 3)) && (check_turfs_in(8, 3)))
SetName("gravitational singularity")
desc = "A gravitational singularity."
current_size = STAGE_FOUR
Expand Down Expand Up @@ -245,61 +248,61 @@
overlays = list("emfield_s11")
visible_message("<span class='sinister'><font size='3'>You witness the creation of a destructive force that cannot possibly be stopped by human hands.</font></span>")

if (current_size == allowed_size)
if(current_size == allowed_size)
investigate_log("<font color='red'>grew to size [current_size].</font>", I_SINGULO)
return 1
else if (current_size < (--temp_allowed_size) && current_size != STAGE_SUPER)
else if(current_size < (--temp_allowed_size) && current_size != STAGE_SUPER)
expand(temp_allowed_size)
else
return 0

/obj/singularity/proc/check_energy()
if (energy <= 0)
if(energy <= 0)
investigate_log("collapsed.", I_SINGULO)
qdel(src)
return 0
return FALSE

switch (energy) //Some of these numbers might need to be changed up later -Mport.
if (1 to 399)
switch(energy) //Some of these numbers might need to be changed up later -Mport.
if(1 to 399)
allowed_size = STAGE_ONE
if (400 to 799)
if(400 to 799)
allowed_size = STAGE_TWO
if (800 to 1199)
if(800 to 1199)
allowed_size = STAGE_THREE
if (1200 to 2499)
if(1200 to 2499)
allowed_size = STAGE_FOUR
if(2500 to 499999)
allowed_size = STAGE_FIVE
if(500000 to INFINITY)
allowed_size = STAGE_SUPER

if (current_size != allowed_size && current_size != STAGE_SUPER)
if(current_size != allowed_size && current_size != STAGE_SUPER)
expand(null, current_size < allowed_size)
return 1
return TRUE

/obj/singularity/proc/eat()
for(var/atom/X in orange(grav_pull, src))
var/dist = get_dist(X, src)
var/obj/singularity/S = src
if(!istype(src))
return
for(var/atom/A in range(grav_pull, src))
if(A == src)
continue
var/dist = get_dist(A, src)
if(dist > consume_range)
X.singularity_pull(S, current_size)
else if(dist <= consume_range)
consume(X)

//for (var/turf/T in trange(grav_pull, src)) //TODO: Create a similar trange for orange to prevent snowflake of self check.
// consume(T)

A.singularity_pull(src, current_size)
continue
consume(A)
return

/obj/singularity/proc/consume(atom/A)
if(A == src)
return
// Prevents the singulo from consuming turfs when it's contained
if(isturf(A) && IsContained())
return
energy += A.singularity_act(src, current_size)
return

/obj/singularity/proc/move(force_move = 0)
/obj/singularity/proc/move(force_move = FALSE)
if(!move_self)
return 0
return FALSE

var/movement_dir = pick(GLOB.alldirs - last_failed_movement)

Expand All @@ -309,10 +312,19 @@
if(target && prob(60))
movement_dir = get_dir(src,target) //moves to a singulo beacon, if there is one

if(!target && (current_size >= STAGE_FIVE) && prob(5)) // Random chance to move through z-levels at later stages
var/turf/destination
destination = pick(GetAbove(src), GetBelow(src))
forceMove(destination)
var/atom/atom_target = target
if((!atom_target || atom_target?.z != z) && !IsContained() && (current_size >= STAGE_THREE) && prob(5)) // Random chance to move through z-levels at later stages
var/list/valid_destinations = list()
var/turf/T1 = GetAbove(src)
if(isturf(T1))
valid_destinations += T1
var/turf/T2 = GetBelow(src)
if(isturf(T2))
valid_destinations += T2
if(LAZYLEN(valid_destinations))
var/turf/destination = pick(valid_destinations)
forceMove(destination)
return

if(current_size >= 9)//The superlarge one does not care about things in its way
spawn(0)
Expand All @@ -327,7 +339,7 @@
return 1
else
last_failed_movement = movement_dir
return 0
return FALSE

/obj/singularity/proc/check_turfs_in(var/direction = 0, var/step = 0)
if(!direction)
Expand Down Expand Up @@ -383,45 +395,71 @@
return 0
return 1

/obj/singularity/proc/can_move(const/turf/T)
if (!isturf(T))
return 0
/obj/singularity/proc/can_move(turf/T)
if(!isturf(T))
return FALSE

if ((locate(/obj/machinery/containment_field) in T) || (locate(/obj/machinery/shieldwall) in T))
return 0
else if (locate(/obj/machinery/field_generator) in T)
return !ContainmentCheck(T)

/obj/singularity/proc/ContainmentCheck(turf/T)
if(!istype(T))
T = get_turf(src)

if((locate(/obj/machinery/containment_field) in T) || (locate(/obj/machinery/shieldwall) in T))
return TRUE

else if(locate(/obj/machinery/field_generator) in T)
var/obj/machinery/field_generator/G = locate(/obj/machinery/field_generator) in T
if(G && G.active)
return TRUE

if (G && G.active)
return 0
else if (locate(/obj/machinery/shieldwallgen) in T)
else if(locate(/obj/machinery/shieldwallgen) in T)
var/obj/machinery/shieldwallgen/S = locate(/obj/machinery/shieldwallgen) in T
if(S && S.active)
return TRUE

if (S && S.active)
return 0
return 1
return FALSE

// God-awful check that looks around the singulo; If FALSE - it can eat turfs and travel through z-levels
/obj/singularity/proc/IsContained()
if(current_size >= STAGE_FIVE)
return FALSE

if(world.time < next_contained_check_time)
return last_contained_check

for(var/turf/T in range(6))
if(!ContainmentCheck(T))
last_contained_check = FALSE
// Might as well forget about checking entirely
next_contained_check_time = INFINITY
return FALSE

last_contained_check = TRUE
next_contained_check_time = world.time + 30 SECONDS
return TRUE

/obj/singularity/proc/event()
var/numb = pick(1, 2, 3, 4, 5, 6)

switch (numb)
if (1) //EMP.
switch(numb)
if(1) //EMP.
emp_area()
if (2, 3) //Irradiate area
if(2, 3) //Irradiate area
irradiate()
if (4) //Stun mobs who lack optic scanners.
if(4) //Stun mobs who lack optic scanners.
mezzer()
else
return 0
return FALSE
if(current_size == 11)
smwave()
return 1
return TRUE


/obj/singularity/proc/irradiate()
var/radiation = 15
if (src.energy>200)
radiation = round(((src.energy-150)/50)*5,1)
if(energy > 200)
radiation = round(((energy-150)/50)*5, 1)
SSradiation.radiate(src, radiation)

/obj/singularity/proc/mezzer()
Expand All @@ -431,7 +469,7 @@
if(M.status_flags & GODMODE)
continue
if(M.stat == CONSCIOUS)
if (istype(M,/mob/living/carbon/human))
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(istype(H.glasses,/obj/item/clothing/glasses/meson) && current_size != 11)
to_chat(H, "<span class=\"notice\">You look directly into The [src.name], good thing you had your protective eyewear on!</span>")
Expand All @@ -441,7 +479,7 @@
to_chat(M, "<span class='danger'>You look directly into The [src.name] and feel [current_size == 11 ? "helpless" : "weak"].</span>")
M.apply_effect(3, STUN)
for(var/mob/O in viewers(M, null))
O.show_message(text("<span class='danger'>[] stares blankly at The []!</span>", M, src), 1)
O.show_message("<span class='danger'>[M] stares blankly at the [src]!</span>", 1)

/obj/singularity/proc/emp_area()
empulse(src, emp_strong_range, emp_weak_range)
Expand All @@ -460,7 +498,7 @@

/obj/singularity/proc/pulse()
for(var/obj/machinery/power/rad_collector/R in rad_collectors)
if (get_dist(R, src) <= 15) //Better than using orange() every process.
if(get_dist(R, src) <= 15) //Better than using orange() every process.
R.receive_pulse(energy)

/obj/singularity/proc/on_capture()
Expand Down

0 comments on commit bd4940a

Please sign in to comment.