Lemurian Sea (#22686)

changes:
  - refactor: "Refactors Gravity Generator UI from HTML to TGUI."
- rscadd: "Adds sector-based modifier var 'overmap_hazards_multiplier'
for generating total overmap hazard count."
  - soundadd: "Adds new Lemurian Sea 'welcome' announcements."
- rscadd: "Added Lemurian Sea gravitic anomalies as overmap hazards and
random events."
  - rscadd: "Adds ADPI/The Voices."
- rscadd: "Adds ADPI Panel for modmins to send ADPI messages to a single
character or all characters from their respective pools, or custom
messages."
- balance: "Vaurca Hivenet communication, the Hivenet Manifest, and
Hivenet Echoes are now disabled while the ship is in Lemurian Sea
sectors."
This commit is contained in:
Batrachophreno
2026-06-13 16:25:49 +00:00
committed by GitHub
parent a11c25bef6
commit 0c7ab8baa7
53 changed files with 1818 additions and 417 deletions
+3
View File
@@ -14,6 +14,7 @@ GLOBAL_LIST_INIT(admin_verbs_default, list(
GLOBAL_LIST_INIT(admin_verbs_admin, list(
/client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game.*/
/client/proc/invisimin, /*allows our mob to go invisible/visible*/
/client/proc/adpi_panel,
// /datum/admins/proc/show_traitor_panel, /*interface which shows a mob's mind*/ -Removed due to rare practical use. Moved to debug verbs ~Errorage */
/datum/admins/proc/show_game_mode, /*Configuration window for the current game mode.*/
/datum/admins/proc/force_mode_latespawn, /*Force the mode to try a latespawn proc*/
@@ -125,6 +126,7 @@ GLOBAL_LIST_INIT(admin_verbs_sounds, list(
GLOBAL_LIST_INIT(admin_verbs_fun, list(
/client/proc/object_talk,
/client/proc/adpi_panel,
/client/proc/cmd_admin_dress,
/client/proc/cmd_admin_grab_observers,
/client/proc/cmd_admin_gib_self,
@@ -447,6 +449,7 @@ GLOBAL_LIST_INIT(admin_verbs_mod, list(
/client/proc/odyssey_panel,
/client/proc/jobbans,
/client/proc/cmd_admin_subtle_message, /*send an message to somebody as a 'voice in their head'*/
/client/proc/adpi_panel,
/datum/admins/proc/paralyze_mob,
/client/proc/toggleattacklogs,
/client/proc/cmd_admin_check_contents,
@@ -1,33 +0,0 @@
/**********
* Gravity *
**********/
/datum/admin_secret_item/random_event/gravity/New()
..()
name = "Toggle [station_name(TRUE)] Artificial Gravity"
/datum/admin_secret_item/random_event/gravity/can_execute(var/mob/user)
if(!(SSticker.mode))
return 0
return ..()
/datum/admin_secret_item/random_event/gravity/execute(var/mob/user)
. = ..()
if(!.)
return
GLOB.gravity_is_on = !GLOB.gravity_is_on
for(var/A in SSmachinery.gravity_generators)
var/obj/structure/machinery/gravity_generator/main/B = A
B.eventshutofftoggle()
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","Grav")
if(GLOB.gravity_is_on)
log_admin("[key_name(user)] toggled gravity on.")
message_admins(SPAN_NOTICE("[key_name_admin(user)] toggled gravity on."), 1)
command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.")
else
log_admin("[key_name(user)] toggled gravity off.")
message_admins(SPAN_NOTICE("[key_name_admin(usr)] toggled gravity off."), 1)
command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system reinitializes. Further failures may result in a gravitational collapse and formation of blackholes. Have a nice day.")
+3
View File
@@ -939,6 +939,9 @@
if(!(GLOB.all_languages[LANGUAGE_VAURCA] in H.languages))
to_chat(usr, "The person you are trying to contact is incapable of recieving Hivenet transmissions.")
return
if(is_lemurian_sea_sector())
to_chat(usr, "The Lemurian Sea prevents Hivenet transmissions.")
return
var/input = sanitize(input(src.owner, "Please enter a message to reply to [key_name(H)] via the Hivenet.", "Outgoing transmission from the Hive...", ""))
if(!input) return
to_chat(src.owner, "You sent [input] to [H] via a secure Hivenet channel.")
+14
View File
@@ -1143,3 +1143,17 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("[key_name_admin(usr)] used the Narration Panel")
log_admin("[key_name(usr)] used the Narration Panel")
feedback_add_details("admin_verb", "AONP")
/client/proc/adpi_panel()
set category = "Fun"
set name = "ADPI Panel"
if(!check_rights(R_ADMIN|R_FUN, TRUE))
return
var/datum/tgui_module/adpi_panel/panel = new
panel.ui_interact(usr)
message_admins("[key_name_admin(usr)] used the ADPI Panel")
log_admin("[key_name(usr)] used the ADPI Panel")
feedback_add_details("admin_verb", "ADPI")
@@ -12,7 +12,8 @@
var/list/possible_exoplanets = list(/obj/effect/overmap/visitable/sector/exoplanet/snow, /obj/effect/overmap/visitable/sector/exoplanet/desert)
///Guaranteed planets to spawn. This ignores the map exoplanet limit, so don't put too many planets in here.
var/list/guaranteed_exoplanets = list()
var/list/cargo_price_coef = list( //how much the space sector afffects how expensive is ordering from that cargo supplier
/// How much the space sector afffects how expensive is ordering from that cargo supplier
var/list/cargo_price_coef = list(
"nanotrasen" = 1,
"orion" = 1,
"hephaestus" = 1,
@@ -60,9 +61,15 @@
/// Does this sector permit communication with Central Command? Reserved for remote/uncharted sectors. The EBS system is unaffected as it is necessary for certain CCIA functions (eg. scuttling).
var/ccia_link = TRUE
///Does this sector allow Vaurcae catch fluff echoes of the greater Hivenet? Primarily for Lemurian Sea, but some super remote areas also fit. Obviously, consult w/ lore.
/// Does this sector allow Vaurcae catch fluff echoes of the greater Hivenet? Primarily for Lemurian Sea, but some super remote areas also fit. Obviously, consult w/ lore.
var/hivenet_echoes = TRUE
/// Whether ghost roles are available in this sector.
var/ghostroles_enabled = TRUE
/// Whether away sites are loaded in this sector.
var/away_sites_enabled = TRUE
/// This variable is a multiplier applied to the 'overmap_event_areas' datum/map/var to increase or decrease the total number of hazards spawned in the sector.
var/overmap_hazards_multiplier = 1.0
//vars used by the meteor random event
var/list/meteors_minor = list(
@@ -231,6 +238,9 @@
/// Returns a flat list of all possible away sites that can spawn in this sector.
/datum/space_sector/proc/possible_sites_in_sector()
if(!away_sites_enabled)
return list()
var/list/away_sites = list()
for(var/id in SSmapping.away_sites_templates)
var/datum/map_template/ruin/away_site = SSmapping.away_sites_templates[id]
+25 -2
View File
@@ -6,6 +6,7 @@
starlight_color = "#2d0850"
starlight_power = 1//slightly darker though for spooky factor
starlight_range = 2
overmap_hazards_multiplier = 1.4
possible_exoplanets = list(/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid, /obj/effect/overmap/visitable/sector/exoplanet/grass/grove, /obj/effect/overmap/visitable/sector/exoplanet/barren, /obj/effect/overmap/visitable/sector/exoplanet/lava, /obj/effect/overmap/visitable/sector/exoplanet/desert, /obj/effect/overmap/visitable/sector/exoplanet/snow)
cargo_price_coef = list(
@@ -38,18 +39,40 @@
name = SECTOR_LEMURIAN_SEA
description = "The Lemurian Sea is an astrological curiosity which is entirely free of stars. This region is a relatively new discovery and classification, having only been officially broken off of Lights Edge by most astrographical institutions following the rediscovery of Assunzione and limited exploration beyond its position on the border of what would become the Lemurian Sea. Most astrological charts advise avoiding the region as travelers are known to report a feeling of general uneasiness while passing through it and many vessels are known to have disappeared within the Sea. "
skybox_icon = "void"//its just black
possible_exoplanets = null//nothing should be here
possible_exoplanets = list(/obj/effect/overmap/visitable/sector/exoplanet/barren/asteroid)
starlight_color = "#000000"
starlight_power = 0
starlight_range = 0
overmap_hazards_multiplier = 2.0
cargo_price_coef = list(
"nanotrasen" = 6.0,
"orion" = 6.0,
"hephaestus" = 6.0,
"zeng_hu" = 6.0,
"eckharts" = 6.0,
"getmore" = 6.0,
"arizi" = 6.0,
"blam" = 6.0,
"iac" = 6.0,
"zharkov" = 6.0,
"virgo" = 6.0,
"bishop" = 6.0,
"xion" = 6.0,
"zavodskoi" = 6.0,
)
lobby_tracks = list(
'sound/music/lobby/lights_edge/lights_edge_1.ogg',
'sound/music/lobby/lights_edge/lights_edge_2.ogg',
'sound/music/lobby/dangerous_space/dangerous_space_1.ogg'
)
sector_welcome_message = 'sound/AI/welcome_lemurian_sea_outer.ogg'
hivenet_echoes = FALSE
ghostroles_enabled = FALSE
away_sites_enabled = FALSE
ccia_link = FALSE
/datum/space_sector/lemurian_sea/far
name = SECTOR_LEMURIAN_SEA_FAR
ccia_link = FALSE
sector_welcome_message = 'sound/AI/welcome_lemurian_sea_inner.ogg'
+4
View File
@@ -384,6 +384,10 @@ GLOBAL_LIST_INIT(severity_to_string, alist(EVENT_LEVEL_MUNDANE = "Mundane", EVEN
new /datum/event_meta(EVENT_LEVEL_MAJOR, "APC Damage", /datum/event/apc_damage,
20, list(ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_JANITOR = 20)),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Dark Matter Influx", /datum/event/gravity_anomaly,
5, list(ASSIGNMENT_ENGINEER = 20), is_one_shot = TRUE,
pop_needed = 12),
)
#undef ASSIGNMENT_ANY
+2 -5
View File
@@ -11,10 +11,7 @@
/datum/event/gravity/start()
..()
// TO-DO: I'm not gonna touch this can of worms right now, but this effectively means that gravity is global for everyone,
// meaning, if the horizon loses gravity, EVERYONE DOES. this seriously needs to be fixed, and i'm commenting out the gravity flux event until that is done
GLOB.gravity_is_on = 0
for(var/obj/structure/machinery/gravity_generator/main/generator in SSmachinery.gravity_generators)
if(generator.z in affecting_z)
generator.eventshutofftoggle()
return
// generator.eventshutofftoggle()
+247
View File
@@ -0,0 +1,247 @@
/datum/event/gravity_anomaly
announceWhen = 0
startWhen = 90 SECONDS
endWhen = 60 SECONDS // Actually gets set in setup()
ic_name = "a gravitational anomaly"
var/list/valid_victims
has_skybox_image = TRUE
var/global/lightning_color
var/next_camera_drift = 0
var/next_gravity_surge = 0
var/nausea_minor = list(
"You feel the deck lurch beneath you.",
"The world feels like it's tilting madly.",
"An illusory sense of your center of gravity shifting briefly comes over you."
)
var/nausea_mild_organic = list(
"You feel a sudden lurching in your guts and inner ear.",
"You suddenly feel a nauseating sense of vertigo.",
"An overwhelming sense of nausea briefly makes you dizzy."
)
var/nausea_mild_ipc = list(
"Your proprioceptive faculties briefly surge with misinputs.",
"With a lurch, it feels like you briefly lose any sense of gyroscopic orientation.",
"Your visual input registers normal, but your cognition insists the room is spinning rapidly."
)
var/nausea_strong_organic = list(
"A huge surge of a sick feeling rises in your gorge.",
"You suddenly feel like you've been spinning in circles for an hour straight.",
"Your inner ear and your brain are screaming at you to stop rotating, but you're not."
)
var/nausea_strong_ipc = list(
"ERR: GYROSCOPIC ARRAY COMPILER RETURNING VALUES OF INVALID TYPE",
"ERR: CRITICAL DESYNCHRONIZATION IN PRIMARY AND SECONDARY MOTOR FUNCTIONAL POSITIONAL FEEDBACK",
"ERR: SENSORY FACULTIES ENCOUNTERING MULTIPLE VALUE DISCONTINUITIES"
)
/datum/event/gravity_anomaly/setup()
endWhen = rand(5 MINUTES, 25 MINUTES)
/datum/event/gravity_anomaly/announce()
command_announcement.Announce(
"Feedback surge detected in gravity generation systems due to influx of dark matter. Instability to be expected until clear of the effect; gravity shutdown recommended for the duration of the effect.",
"Dark Matter Influx",
zlevels = affecting_z
)
/datum/event/gravity_anomaly/start()
..()
next_camera_drift = activeFor
schedule_next_gravity_surge()
valid_victims = list()
for(var/mob/living/carbon/human/victim in GLOB.player_list)
// We don't bother excluding players not on the Horizon here; we check for that whenever we're going to potentially shove them around.
// This way, someone entering or leaving the Horizon z-levels will be affected by the event appropriately.
valid_victims += victim
if(!(victim.z in affecting_z))
continue
notify_victim_of_start(victim)
/datum/event/gravity_anomaly/end(faked)
valid_victims?.Cut()
..()
/datum/event/gravity_anomaly/get_skybox_image()
if(!lightning_color)
lightning_color = pick( "#aa11ee")
var/image/res = overlay_image('icons/skybox/electrobox.dmi', "lightning", lightning_color, RESET_COLOR)
res.blend_mode = BLEND_ADD
return res
/datum/event/gravity_anomaly/tick()
..()
if(!has_active_gravity_generator())
return
var/list/current_victims = get_current_victims()
if(!length(current_victims))
return
if(activeFor >= next_camera_drift)
apply_camera_drift(current_victims)
next_camera_drift = activeFor + rand(2, 4)
for(var/mob/living/carbon/human/victim in current_victims)
var/current_effect = pick_victim_disturbance()
if(current_effect)
apply_effect(victim, current_effect)
/datum/event/gravity_anomaly/proc/notify_victim_of_start(var/mob/living/carbon/human/victim)
if(isipc(victim))
to_chat(victim, SPAN_MACHINE_WARNING("Your proprioceptive faculties briefly surge with misinputs; something is definitely Wrong with the gravity."))
else
to_chat(victim, SPAN_WARNING("You suddenly feel a nauseating sense of vertigo; something is definitely Wrong with the gravity."))
/datum/event/gravity_anomaly/proc/has_active_gravity_generator()
for(var/obj/structure/machinery/gravity_generator/main/grav_gen in SSmachinery.gravity_generators)
if(!(grav_gen?.z in affecting_z))
continue
if(grav_gen.on)
return TRUE
return FALSE
/datum/event/gravity_anomaly/proc/pick_victim_disturbance()
if(activeFor >= next_gravity_surge && prob(50))
schedule_next_gravity_surge()
if(prob(10))
return "surge_hilarious"
return "surge_default"
switch(rand(1,100))
if(1 to 20)
return "nausea_minor"
if(21 to 28)
return "nausea_mild"
if(29 to 31)
return "nausea_strong"
else
return null
/datum/event/gravity_anomaly/proc/schedule_next_gravity_surge()
next_gravity_surge = activeFor + rand(20, 60)
/datum/event/gravity_anomaly/proc/get_current_victims()
var/list/current_victims = list()
for(var/mob/living/carbon/human/potential_victim in valid_victims)
if(can_affect_victim(potential_victim))
current_victims += potential_victim
return current_victims
/datum/event/gravity_anomaly/proc/can_affect_victim(var/mob/living/carbon/human/potential_victim)
if(!potential_victim)
return FALSE
// Have they entered or left the Horizon? Skip if not aboard.
if(!(potential_victim.z in affecting_z))
return FALSE
// Is there gravity where they are? IE. is the grav generator on/off OR are they on the holodeck w/ zero gravity, OR are they EVA? Skip if no artificial gravity for whatever reason.
if(!potential_victim.has_gravity())
return FALSE
return TRUE
/datum/event/gravity_anomaly/proc/apply_effect(var/mob/living/carbon/human/victim, var/current_effect)
switch(current_effect)
if("nausea_minor")
apply_nausea_minor(victim)
if("nausea_mild")
apply_nausea_mild(victim)
if("nausea_strong")
apply_nausea_strong(victim)
if("surge_default")
apply_surge_default(victim)
if("surge_hilarious")
apply_surge_hilarious(victim)
else
log_admin("Failed to generate grav anom result for user [victim].")
/datum/event/gravity_anomaly/proc/apply_camera_drift(var/list/current_victims)
for(var/mob/living/carbon/human/victim in current_victims)
if(prob(15))
continue
shake_camera(victim, rand(3 SECONDS, 10 SECONDS), 0.1, TRUE)
/datum/event/gravity_anomaly/proc/apply_nausea_minor(var/mob/living/carbon/human/victim)
victim.dizziness += rand(2, 4)
victim.confused += 1
if(prob(10))
to_chat(victim, SPAN_WARNING(pick(nausea_minor)))
/datum/event/gravity_anomaly/proc/apply_nausea_mild(var/mob/living/carbon/human/victim)
victim.dizziness += rand(3, 6)
victim.confused += rand(0, 1)
if(isipc(victim))
if(prob(20))
to_chat(victim, SPAN_MACHINE_WARNING(pick(nausea_mild_ipc)))
else
if(prob(20))
to_chat(victim, SPAN_WARNING(pick(nausea_mild_organic)))
if(prob(10))
victim.vomit()
/datum/event/gravity_anomaly/proc/apply_nausea_strong(var/mob/living/carbon/human/victim)
victim.dizziness += rand(8, 15)
victim.confused += rand(1, 3)
if(prob(50))
if(isipc(victim))
to_chat(victim, SPAN_MACHINE_WARNING(pick(nausea_strong_ipc)))
else
to_chat(victim, SPAN_WARNING(pick(nausea_strong_organic)))
victim.vomit()
/datum/event/gravity_anomaly/proc/apply_surge_default(var/mob/living/carbon/human/victim)
victim.dizziness += rand(4, 10)
victim.confused += rand(1, 5)
if(prob(50))
if(isipc(victim))
to_chat(victim, SPAN_MACHINE_WARNING(pick(nausea_strong_ipc)))
else
to_chat(victim, SPAN_WARNING(pick(nausea_strong_organic)))
victim.vomit()
if(prob(70))
if(victim.buckled_to)
to_chat(victim, SPAN_WARNING("Sudden gravity flux presses you into your chair!"))
shake_camera(victim, 3, 1)
else if(victim.Check_Shoegrip(FALSE))
to_chat(victim, SPAN_WARNING("You feel immense pressure in your feet as the artificial gravity surges!"))
victim.apply_damage(10, DAMAGE_PAIN, BP_L_FOOT)
victim.apply_damage(10, DAMAGE_PAIN, BP_R_FOOT)
shake_camera(victim, 5, 1)
else
to_chat(victim, SPAN_WARNING("The floor lurches beneath you!"))
shake_camera(victim, 10, 1)
victim.visible_message(SPAN_DANGER("[victim.name] is tossed around by a sudden knot in the artifical gravity field!"))
victim.throw_at_random(FALSE, 4, 1)
victim.Weaken(3)
/datum/event/gravity_anomaly/proc/apply_surge_hilarious(var/mob/living/carbon/human/victim)
victim.dizziness += rand(8, 15)
victim.confused += rand(1, 10)
if(isipc(victim))
to_chat(victim, SPAN_MACHINE_WARNING(pick(nausea_strong_ipc)))
else
to_chat(victim, SPAN_WARNING(pick(nausea_strong_organic)))
if(prob(33))
victim.vomit()
if(prob(60))
if(victim.buckled_to)
to_chat(victim, SPAN_WARNING("Sudden gravity flux rattles you in your chair!"))
shake_camera(victim, 5, 2)
else if(victim.Check_Shoegrip(FALSE))
victim.apply_damage(20, DAMAGE_PAIN, BP_L_FOOT)
victim.apply_damage(10, DAMAGE_BRUTE, BP_L_FOOT)
victim.apply_damage(20, DAMAGE_PAIN, BP_R_FOOT)
victim.apply_damage(10, DAMAGE_BRUTE, BP_R_FOOT)
to_chat(victim, SPAN_WARNING("You feel like your ankles are about to be ripped apart as the artificial gravity surges!"))
shake_camera(victim, 8, 2)
else
victim.visible_message(SPAN_DANGER("[victim.name] is flung violently by a horrible gravity flux!"))
victim.Weaken(8)
if(prob(90))
victim.throw_at_random(FALSE, 7, 1)
else
victim.fall_impact(1)
/datum/event/gravity_anomaly/announce_end()
. = ..()
if(.)
command_announcement.Announce("Gravimetric sensors indicate reduced levels of dark matter flux; artificial gravity is now safe for regular use.", "Dark Matter Influx", zlevels = affecting_z)
+8
View File
@@ -84,6 +84,9 @@
//Return a error message if the user CANT see the ghost spawner. Otherwise FALSE
/datum/ghostspawner/proc/cant_see(mob/user) //If the user can see the spawner in the menu
if(SSatlas?.current_sector && !SSatlas.current_sector.ghostroles_enabled)
return "Ghost roles are unavailable in this sector."
if(req_perms) //Only those with the correct flags can see restricted roles
if(check_rights(req_perms, show_msg=FALSE, user=user))
return FALSE //Return early and dont perform whitelist checks if staff flags are met
@@ -109,6 +112,8 @@
/datum/ghostspawner/proc/cant_spawn(mob/user) //If the user can spawn using the spawner
if(!ROUND_IS_STARTED)
return "The round is not started yet."
if(SSatlas?.current_sector && !SSatlas.current_sector.ghostroles_enabled)
return "Ghost roles are unavailable in this sector."
var/cant_see = cant_see(user)
if(cant_see) //If we cant see it, we cant spawn it
return cant_see
@@ -243,6 +248,9 @@
return isobserver(user) && loc_type == GS_LOC_POS
/datum/ghostspawner/proc/is_enabled()
if(SSatlas?.current_sector && !SSatlas.current_sector.ghostroles_enabled)
return FALSE
if(loc_type == GS_LOC_ATOM)
return enabled && !!length(spawn_atoms)
if(max_count)
@@ -1,56 +0,0 @@
grins widely at you.
mumbles something while looking away from you.
screams!
suddenly clutches at their chest!
stumbles.
laughs!
watches you, unblinking.
twitches.
holds up a very familiar key...
cowers from you.
bleeds profusely from their eyes!
drools.
flails about, unable to breathe!
grows a fabulous head of hair!
snorts!
waves at you to come closer.
hums your favorite song.
doesn't seem to cast a shadow.
beeps.
is going to die if they don't get help!
yawns.
points a gun at you!
whispers into their headset while watching you.
frowns at you.
shakes their head at you.
looks around.
swats at the air!
coughs up a tooth.
shivers.
looks behind you.
spits blood.
shrieks!
applies some lipstick.
scowls.
looks at you and frowns.
wipes the blood from their hands.
sneezes.
screams as a loud snapping sound comes from their body!
snaps.
holds up a bloodied organ and examines it.
giggles.
looks at you and clenches a fist.
jabs a finger at you!
stomps their feet.
seems to phase out for a moment.
coughs up a plume of colorful smoke.
huffs.
licks their eyeball.
unhinges their jaw for a moment.
gives you an incredulous look.
backs away from you.
quickly shoves a knife into their pocket.
quickly holsters a gun.
blinks rapidly.
slams their hands together!
closely watches you.
@@ -1,97 +0,0 @@
Give it back!
Don't worry, we'll never be apart.
Just let me help you.
You don't know anything!
I forgive you.
Don't you remember me?
You can't keep doing this!
Help!
Are you okay?
You need to see a doctor!
Wait, who are you?
Wait, who were you?
Are you ready?
Remember our song?
Did you hear that?
Why are we here?
Let's get going!
Just go away!
It's okay, I'm here.
Where are we going?
Oh, did you forget?
You forgot about me already, didn't you?
You're not safe here.
Why are you asking me?
Don't you know any better?
It's you or me.
I can't lose you again.
You're bleeding!
You're hurt!
They're looking for you.
How are you?
Shut up for once.
Will you join me?
Didn't you call for me?
I know you lied to me.
You just had to ruin everything, didn't you?
It's so nice to see you!
Did you remember your assignment?
Don't give up!
Nobody else believes in you, but I do.
When's the shuttle coming?
The shuttle will be here in a minute.
I tried calling you last night. You never answer.
What is THAT supposed to be?
Did you hear about the fire?
I heard the news; I'm so sorry.
I didn't mean it!
What happened to your face?!
Apparently someone died.
Remember me from high-school? Well I have this great business deal proposition...
Bored?
Once you are a player with MaxBet, you will also receive lucrative weekly and monthly promotions.
Find your secret skrell crush.
We know who you are. Expect us.
This staff assistant is making mad credits and basically, you're fucking stupid.
You have a secret admirer!
Where's your ID?
You know nobody wants you here, right?
Uh, do you know you're bleeding?
I know your secret, you know. You're bad at hiding it.
I would kill you if I could get away with it.
You should probably leave, trust me.
You'd better wake up before you forget how to.
You cannot kill me in a way that matters.
Life is too short for regrets.
There's an interesting rumor about you.
I heard what you did before you worked here.
You're disgusting.
I know you're a liar.
Your beliefs are ridiculous.
Fuck off, you nuisance.
Coming here was a mistake and you know it.
I wonder how much you'll scream?
So, you're spreading rumors about me?
Let's dance!
I know how you die. Do you want to?
I wonder how loud you'll scream.
Come on, let's get out of here.
You know I like you, right?
Why don't you just admit it?
Cry about it.
I can't believe you actually did it.
You can trust me.
I'd never betray you.
I'm excited for you to join us.
I come from the future to give warning!
Hum that song I like, please?
Just give me a hug. I need it.
Can you tell me I'm doing okay?
Isn't this all stupid?
Don't tell anyone I told you this, but...
They'll never accept you.
Someone told me they had a crush on you but were too shy to say it.
Well, you fucked it up. Again.
Let's die together.
I'm not feeling too hot.
I feel like you're the only one I can trust.
@@ -1,57 +0,0 @@
Wait, what was that?
Something is crawling on you!
Is any of this real?
You can't catch your breath!
Something's watching you...
You feel unsteady!
You're sure you've never been to this place before...
You can't feel your skin!
What just brushed your shoulder?
You hear someone whispering to you. It sounds so familiar.
When are you getting that drink you ordered?
Wait, where did your child go? What did they look like again..? You have one, right?
Crap, that assignment is due today!
When did you die, again? It's hard to remember...
You'll die if it gets any warmer!
Weren't you getting married today?
Why is it so cold here?
You need to get away from here, it's not safe!
Who are all these people?
You feel exhausted!
You're so thirsty!
Where did you put your jacket?
Finally, you can see again!
Your face feels soft.
When was your funeral supposed to be?
This place has changed...
Why is it so. Damn. Loud?!
Oh no...
You feel itchy all over!
Someone's behind you!
Where did your gun go?
You feel like you're getting sick.
Your blood feels weird.
Someone here was trying to kill you, you just know it!
Wait, this isn't your ID.
Are those footsteps?
Was that a gunshot?
Something's buzzing in your ear.
Wait, what were you doing?
You hear a constant dripping sound.
Your skin feels wet.
You feel a sudden chill.
All your problems seem to melt away.
Your head feels foggy.
The people around you really are great, aren't they?
You feel homesick.
Why does it smell like rust?
Wait, is that blood on the floor?
You feel particularly charitable.
Did you always have this many fingers?
When's the last time you ate?
Oh shit, these aren't your clothes!
You have to leave. Right now.
You suddenly feel antsy.
You can't seem to focus on anything except your problems.
Everything seems so overwhelming.
How do you wake up?
@@ -76,6 +76,18 @@
style_open = "<span class='langchat' style=font-size:20pt;text-align:center valign='top'>"
style_close = "</span>"
/atom/movable/screen/text/screen_text/adpi_message
maptext_height = 64
maptext_width = 480
maptext_x = 0
maptext_y = 0
screen_loc = "LEFT,TOP-3"
letters_per_update = 1
fade_out_delay = 8 SECONDS
style_open = "<span class='langchat' style=font-size:20pt;text-align:center valign='top'>"
style_close = "</span>"
///proc for actually playing this screen_text on a mob.
/atom/movable/screen/text/screen_text/proc/play_to_client()
player?.add_to_screen(src)
-1
View File
@@ -1430,7 +1430,6 @@ GLOBAL_LIST_INIT_TYPED(total_extraction_beacons, /obj/structure/extraction_point
target = get_atom_on_turf(src)
if(!target)
target = src
QDEL_NULL(effect_overlay)
if(location)
new /obj/effect/overlay/temp/explosion(location)
playsound(location, 'sound/effects/Explosion1.ogg', 100, 1)
@@ -197,6 +197,11 @@
set category = "Storyteller"
set desc = "Switch if Vaurcae can hear faint echoes (fluff) of the greater Hivenet. They will notice."
if(is_lemurian_sea_sector())
SSatlas.current_sector.hivenet_echoes = FALSE
to_chat(src, "The Fog prevents Hivenet Echoes from being restored in the Lemurian Sea.")
return
if(SSatlas.current_sector.hivenet_echoes)
SSatlas.current_sector.hivenet_echoes = FALSE
to_chat(src, "Vaurcae have been cut off from echoes (fluff) of the greater Hivenet.")
+11
View File
@@ -234,6 +234,10 @@
/datum/language/bug/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
log_say("[key_name(speaker)] : ([name]) [message]")
if(is_lemurian_sea_sector())
to_chat(speaker, SPAN_WARNING("You attempt to reach the Hivenet, but find nothing!"))
return
var/mob/living/carbon/human/H = speaker //Check for Preimminent Shaper robes, which obscure Hive affiliation
var/obj/item/clothing/head/shaper/helmet = H.get_equipped_item(slot_head)
if(!speaker_mask)
@@ -304,6 +308,9 @@
return "[verb], <span class='message'><span class='[message_color]'>\"[capitalize(message)]\"</span></span>"
/datum/language/bug/check_special_condition(var/mob/other)
if(is_lemurian_sea_sector())
return 0
if(istype(other, /mob/living/silicon))
var/mob/living/silicon/S = other
if(S.can_hear_hivenet)
@@ -340,6 +347,10 @@
return 0
/datum/language/bug/check_speech_restrict(var/mob/speaker)
if(is_lemurian_sea_sector())
to_chat(speaker, SPAN_WARNING("You attempt to reach the Hivenet, but find nothing!"))
return FALSE
var/mob/living/carbon/human/H = speaker
var/obj/item/organ/internal/vaurca/neuralsocket/S = H.internal_organs_by_name[BP_NEURAL_SOCKET]
var/obj/item/organ/internal/augment/language/vekatak/V = H.internal_organs_by_name[BP_AUG_LANGUAGE_VEKATAK]
@@ -1658,6 +1658,10 @@
to_chat(src, SPAN_DANGER("Your mind is dark, unable to communicate with the Hive."))
return
if(is_lemurian_sea_sector())
to_chat(src, SPAN_DANGER("The Fog cuts you off from the Hivenet."))
return
if(!istype(S) && !istype(V))
to_chat(src, SPAN_WARNING("You do not have a functional connection to the Hivenet!"))
return
@@ -2050,6 +2054,9 @@
if(!istype(S))
to_chat(src, SPAN_WARNING("You require a functional neural socket to do this!"))
return FALSE
if(is_lemurian_sea_sector())
to_chat(src, SPAN_DANGER("The Fog cuts you off from the Hivenet."))
return FALSE
if(S.last_action > world.time)
to_chat(src, SPAN_WARNING("You must wait before attempting another Hivenet action!"))
return FALSE
@@ -2185,6 +2192,10 @@
to_chat(src, SPAN_WARNING("You are not connected to the Hivenet!"))
return
if(is_lemurian_sea_sector())
to_chat(src, SPAN_WARNING("You attempt to reach the Hivenet, but find nothing!"))
return
if(within_jamming_range(src))
to_chat(src, SPAN_WARNING("You attempt to reach the Hivenet, but find nothing!"))
return
@@ -2204,6 +2215,10 @@
set desc = "Get a list of all vaurca currently on the Hivenet."
set category = "Hivenet"
if(is_lemurian_sea_sector())
to_chat(src, SPAN_WARNING("You attempt to query the Hivenet, but find nothing."))
return
var/list/all_vaurca = list()
for(var/mob/living/carbon/human/vaurca in GLOB.human_mob_list)
if(!vaurca.stat && isvaurca(vaurca) && vaurca.internal_organs_by_name[BP_NEURAL_SOCKET])
@@ -169,8 +169,8 @@
return default_language
return GLOB.all_languages[LANGUAGE_LOCAL_DRONE]
/mob/living/silicon/robot/drone/fall_impact()
..(damage_mod = 0.05) //reduces fall damage by 95%
/mob/living/silicon/robot/drone/fall_impact(levels_fallen, stopped_early = FALSE, var/damage_mod = 1)
..(levels_fallen, stopped_early, damage_mod * 0.05) //reduces fall damage by 95%
/mob/living/silicon/robot/drone/construction
// Look and feel
@@ -64,7 +64,7 @@
blood_overlay_icon = initial(blood_overlay_icon)
handle_blood(TRUE)
/mob/living/simple_animal/carp/fall_impact()
/mob/living/simple_animal/carp/fall_impact(levels_fallen, stopped_early = FALSE, var/damage_mod = 1)
src.visible_message(SPAN_NOTICE("\The [src] gently floats to a stop."))
return FALSE
@@ -209,7 +209,7 @@
. = ..()
set_flee_target(throwingdatum?.thrower?.resolve() ? throwingdatum.thrower.resolve() : src.loc)
/mob/living/simple_animal/cat/fall_impact()
/mob/living/simple_animal/cat/fall_impact(levels_fallen, stopped_early = FALSE, var/damage_mod = 1)
src.visible_message(SPAN_NOTICE("\The [src] lands softly on \the [loc]!"))
return FALSE
@@ -211,7 +211,7 @@
/mob/living/simple_animal/hostile/retaliate/minedrone/adjustHalLoss(var/damage)
return
/mob/living/simple_animal/hostile/retaliate/minedrone/fall_impact()
/mob/living/simple_animal/hostile/retaliate/minedrone/fall_impact(levels_fallen, stopped_early = FALSE, var/damage_mod = 1)
visible_message(SPAN_DANGER("\The [src] bounces harmlessly on its inflated wheels."))
return FALSE
+11 -5
View File
@@ -481,11 +481,13 @@ GLOBAL_LIST_INIT(organ_rel_size, list(
#define TILES_PER_SECOND 0.7
/// Shake the camera of the person viewing the mob SO REAL!
/// Takes the mob to shake, the time span to shake for, and the amount of tiles we're allowed to shake by in tiles
/// Takes the mob to shake, the time span to shake for, and the amount of tiles we're allowed to shake by in tiles.
/// Set drift to exactly TRUE for slower, gentler movement instead of impact-like shaking.
/// Duration isn't taken as a strict limit, since we don't trust our coders to not make things feel shitty. So it's more like a soft cap.
/proc/shake_camera(mob/M, duration, strength=1)
/proc/shake_camera(mob/M, duration, strength=1, drift = FALSE)
if(!M || !M.client || duration < 1)
return
var/drift_mode = (drift == TRUE)
var/client/C = M.client
var/oldx = C.pixel_x
var/oldy = C.pixel_y
@@ -505,8 +507,12 @@ GLOBAL_LIST_INIT(organ_rel_size, list(
var/x_pos = rand(min_x, max_x) + oldx
var/y_pos = rand(min_y, max_y) + oldy
//We take the smaller of our two distances so things still have the propencity to feel somewhat jerky
var/time = round(max(min(abs(last_x - x_pos), abs(last_y - y_pos)) * time_scalar, 1))
var/time
if(drift_mode)
time = round(clamp(max(abs(last_x - x_pos), abs(last_y - y_pos)) * time_scalar * 6, 6, 20))
else
//We take the smaller of our two distances so things still have the propencity to feel somewhat jerky
time = round(max(min(abs(last_x - x_pos), abs(last_y - y_pos)) * time_scalar, 1))
if (time_spent == 0)
animate(C, pixel_x=x_pos, pixel_y=y_pos, time=time)
@@ -518,7 +524,7 @@ GLOBAL_LIST_INIT(organ_rel_size, list(
//We go based on time spent, so there is a chance we'll overshoot our duration. Don't care
time_spent += time
animate(pixel_x=oldx, pixel_y=oldy, time=3)
animate(pixel_x=oldx, pixel_y=oldy, time = drift_mode ? 10 : 3)
#undef TILES_PER_SECOND
+52 -17
View File
@@ -13,11 +13,14 @@
// Acquire the list of not-yet utilized overmap turfs on this Z-level
var/list/candidate_turfs = block(locate(OVERMAP_EDGE, OVERMAP_EDGE, z_level),locate(overmap_size - OVERMAP_EDGE, overmap_size - OVERMAP_EDGE,z_level))
candidate_turfs = where(candidate_turfs, /proc/can_not_locate, /obj/effect/overmap/visitable)
var/list/available_event_types = get_available_event_types()
if(!length(available_event_types))
return
for(var/i = 1 to number_of_events)
if(!candidate_turfs.len)
break
var/overmap_event_type = pick(subtypesof(/datum/overmap_event))
var/overmap_event_type = pick(available_event_types)
var/datum/overmap_event/datum_spawn = new overmap_event_type
var/list/event_turfs = acquire_event_turfs(datum_spawn.count, datum_spawn.radius, candidate_turfs, datum_spawn.continuous)
@@ -29,6 +32,15 @@
qdel(datum_spawn)//idk help how do I do this better?
/singleton/overmap_event_handler/proc/get_available_event_types()
var/list/available_event_types = list()
for(var/overmap_event_type in subtypesof(/datum/overmap_event))
var/datum/overmap_event/datum_spawn = new overmap_event_type
if(datum_spawn.spawns_in_current_sector())
available_event_types += overmap_event_type
qdel(datum_spawn)
return available_event_types
/singleton/overmap_event_handler/proc/acquire_event_turfs(var/number_of_turfs, var/distance_from_origin, var/list/candidate_turfs, var/continuous = TRUE)
number_of_turfs = min(number_of_turfs, candidate_turfs.len)
candidate_turfs = candidate_turfs.Copy() // Not this proc's responsibility to adjust the given lists
@@ -195,6 +207,8 @@
var/ship_delay_time = 10
/// Ticks up each process until move speed is matched, at which point the event will move
var/ship_delay_counter = 0
/// Text that appears in the tooltip.
var/tooltip_text = "A hazard."
/obj/effect/overmap/event/Initialize()
. = ..()
@@ -266,6 +280,7 @@
opacity = 1
event_icon_states = list("meteor1", "meteor2", "meteor3", "meteor4")
difficulty = EVENT_LEVEL_MAJOR
tooltip_text = "Large rocks and debris traveling at high speed that can destroy entire hull sections."
/obj/effect/overmap/event/electric
name = "electrical storm"
@@ -273,6 +288,7 @@
event_icon_states = list("electrical1", "electrical2")
difficulty = EVENT_LEVEL_MAJOR
can_be_destroyed = FALSE
tooltip_text = "Electromagnetic storm effects that can damage or disable electrical grids."
/obj/effect/overmap/event/dust
name = "dust cloud"
@@ -280,6 +296,7 @@
opacity = 1
event_icon_states = list("dust1", "dust2", "dust3", "dust4")
can_be_destroyed = FALSE
tooltip_text = "Small dust and debris traveling at high speed that can damage or destroy external windows."
/obj/effect/overmap/event/ion
name = "ion cloud"
@@ -287,6 +304,7 @@
event_icon_states = list("ion1", "ion2", "ion3", "ion4")
difficulty = EVENT_LEVEL_MAJOR
can_be_destroyed = FALSE
tooltip_text = "Ionic effects that can damage synthetics like IPCs or AI, as well as disrupt telecommunications."
/obj/effect/overmap/event/carp
name = "carp shoal"
@@ -294,6 +312,7 @@
difficulty = EVENT_LEVEL_MODERATE
event_icon_states = list("carp")
movable_event_chance = 30
tooltip_text = "Xenofauna: usually hostile."
/obj/effect/overmap/event/carp/major
name = "carp school"
@@ -301,22 +320,40 @@
difficulty = EVENT_LEVEL_MAJOR
movable_event_chance = 15
// see comment at code/modules/events/gravity.dm
// tl;dr gravity is handled globally, meaning if the horizon loses gravity, everyone does
// /obj/effect/overmap/event/gravity
// name = "dark matter influx"
// events = list(/datum/event/gravity)
// can_be_destroyed = FALSE
/obj/effect/overmap/event/gravity_anomaly
name = "gravitic anomaly"
events = list(/datum/event/gravity_anomaly)
difficulty = EVENT_LEVEL_MODERATE
event_icon_states = list("grav1")
can_be_destroyed = FALSE
tooltip_text = "Unstable gravitic shear effects detected; wide-field artificial gravity should be powered down before transit."
///These now are basically only used to spawn hazards. Will be useful when we need to spawn group of moving hazards
/obj/effect/overmap/event/MouseEntered(location, control, params)
. = ..()
openToolTip(usr, src, params, tooltip_text)
/obj/effect/overmap/event/MouseExited(location, control, params)
. = ..()
closeToolTip(usr)
/// These now are basically only used to spawn hazards. Will be useful when we need to spawn group of moving hazards
/datum/overmap_event
var/name = "map event"
var/radius = 2
var/count = 6
var/hazards
var/opacity = 0
/// If it should form continous blobs, or can have gaps
/// If it should form continous blobs, or can have gaps.
var/continuous = TRUE
/// If set, this event will only spawn in the named space sectors.
var/list/sectors = list()
/datum/overmap_event/proc/spawns_in_current_sector()
if(!length(sectors))
return TRUE
if(!SSatlas.current_sector)
return FALSE
return (SSatlas.current_sector.name in sectors)
/datum/overmap_event/meteor
name = "asteroid field"
@@ -359,11 +396,9 @@
opacity = 1
hazards = /obj/effect/overmap/event/carp/major
// see comment at code/modules/events/gravity.dm
// tl;dr gravity is handled globally, meaning if the horizon loses gravity, everyone does
// this needs to be fixed before we can uncomment this
// /datum/overmap_event/gravity
// name = "dark matter influx"
// count = 12
// radius = 4
// hazards = /obj/effect/overmap/event/gravity
/datum/overmap_event/gravity
name = "dark matter influx"
count = 15
radius = 8
hazards = /obj/effect/overmap/event/gravity_anomaly
sectors = list(SECTOR_LEMURIAN_SEA, SECTOR_LEMURIAN_SEA_FAR)
+16 -8
View File
@@ -32,15 +32,23 @@
var/list/map_z = list()
var/known = 0 //shows up on nav computers automatically
var/scannable //if set to TRUE will show up on ship sensors for detailed scans
var/unknown_id // A unique identifier used when this entity is scanned. Assigned in Initialize().
var/requires_contact = TRUE //whether or not the effect must be identified by ship sensors before being seen.
var/instant_contact = FALSE //do we instantly identify ourselves to any ship in sensors range?
var/sensor_range_override = FALSE //When true, this overmap object will be scanned with range instead of view.
/// Shows up on nav computers automatically
var/known = 0
/// If set to TRUE will show up on ship sensors for detailed scans
var/scannable
/// A unique identifier used when this entity is scanned. Assigned in Initialize().
var/unknown_id
/// Whether or not the effect must be identified by ship sensors before being seen.
var/requires_contact = TRUE
/// Do we instantly identify ourselves to any ship in sensors range?
var/instant_contact = FALSE
/// When true, this overmap object will be scanned with range instead of view.
var/sensor_range_override = FALSE
var/sensor_visibility = 10 //how likely it is to increase identification process each scan.
var/vessel_mass = 10000 // metric tonnes, very rough number, affects acceleration provided by engines
/// How likely it is to increase identification process each scan.
var/sensor_visibility = 10
/// Metric tonnes, very rough number, affects acceleration provided by engines
var/vessel_mass = 10000
var/image/targeted_overlay
+146 -149
View File
@@ -2,10 +2,11 @@
#define POWER_UP 1
#define POWER_DOWN 2
#define GRAV_NEEDS_SCREWDRIVER 0
#define GRAV_NEEDS_WELDING 1
#define GRAV_NEEDS_PLASTEEL 2
#define GRAV_NEEDS_WRENCH 3
#define GRAV_OPERATIONAL 0
#define GRAV_NEEDS_SCREWDRIVER 1
#define GRAV_NEEDS_WELDING 2
#define GRAV_NEEDS_PLASTEEL 3
#define GRAV_NEEDS_WRENCH 4
#define AREA_ERRNONE 0
#define AREA_STATION 1
@@ -16,18 +17,18 @@
//
/obj/structure/machinery/gravity_generator
name = "gravitational generator"
desc = "A device which produces a gravaton field when set up."
name = "gravity generator"
desc = "A complex and energy-hungry device which produces a graviton field over a modest radius when active."
icon = 'icons/obj/machinery/gravity_generator.dmi'
anchored = 1
density = 1
anchored = TRUE
density = TRUE
use_power = POWER_USE_OFF
unacidable = 1
unacidable = TRUE
var/sprite_number = 0
light_color = LIGHT_COLOR_CYAN
light_power = 1
light_range = 8
var/datum/looping_sound/gravgen/soundloop
light_power = 1.4
light_range = 6
interact_offline = TRUE
/obj/structure/machinery/gravity_generator/ex_act(severity)
if(severity == 1) // Very sturdy.
@@ -108,23 +109,47 @@
/obj/structure/machinery/gravity_generator/main
icon_state = "on_8"
idle_power_usage = 0
active_power_usage = 3000
idle_power_usage = 5 KILO WATTS
active_power_usage = 10 KILO WATTS
power_channel = AREA_USAGE_ENVIRON
sprite_number = 8
interact_offline = 1
var/on = 1
var/breaker = 1
/// Whether the gravity generator is currently active.
var/on = TRUE
/// If the main breaker is on/off, to enable/disable gravity.
var/breaker = TRUE
/// If the generator is idle, charging, or down.
var/charging_state = POWER_IDLE
/// How much charge the gravity generator has, goes down when breaker is shut, and shuts down at 0.
var/charge_count = 100
/// The gravity core overlay currently used.
var/current_overlay = null
/// Currently configured gravity strength.
var/setting = 1.0
/// Audio for when the gravgen is on
var/datum/looping_sound/gravgen/soundloop
var/list/sprite_parts = list()
var/obj/middle = null
var/charging_state = POWER_IDLE
var/charge_count = 100
var/current_overlay = null
var/broken_state = 0
/// When broken, what stage it is at (GRAV_NEEDS_SCREWDRIVER:0) (GRAV_NEEDS_WELDING:1) (GRAV_NEEDS_PLASTEEL:2) (GRAV_NEEDS_WRENCH:3)
var/broken_state = GRAV_OPERATIONAL
var/list/localareas = list()
var/round_start = 2 //To help stop a bug with round start
var/backpanelopen = 0
var/eventon = 0
var/panel_open_heavy = 0
/obj/structure/machinery/gravity_generator/main/Initialize()
. = ..()
soundloop = new(src, start_immediately = FALSE)
addtimer(CALLBACK(src, PROC_REF(updateareas)), 10)
return INITIALIZE_HINT_LATELOAD
/obj/structure/machinery/gravity_generator/main/LateInitialize()
..()
if(SSatlas.current_map.use_overmap && !linked)
var/my_sector = GLOB.map_sectors["[z]"]
if (istype(my_sector, /obj/effect/overmap/visitable))
attempt_hook_up(my_sector)
if(linked)
linked.gravity_generator = src
/obj/structure/machinery/gravity_generator/main/Destroy()
LOG_DEBUG("Gravity Generator Destroyed")
@@ -138,20 +163,6 @@
linked?.gravity_generator = null
return ..()
/obj/structure/machinery/gravity_generator/main/proc/eventshutofftoggle() // Used by the gravity event. Bypasses charging and all of that stuff.
breaker = 0
set_state(eventon)
sleep(20)
charge_count = 0
breaker = 1
charging_state = POWER_UP
set_power()
eventon = !eventon
addtimer(CALLBACK(src, PROC_REF(reset_event)), 100) // Because it takes 100 seconds for it to recharge. And we need to make sure we resen this var
/obj/structure/machinery/gravity_generator/main/proc/reset_event()
eventon = !eventon
/obj/structure/machinery/gravity_generator/main/proc/setup_parts()
var/turf/our_turf = get_turf(src)
// 9x9 block obtained from the bottom middle of the block
@@ -184,7 +195,7 @@
charge_count = 0
breaker = 0
set_power()
set_state(0)
disable()
investigate_log("has broken down.", "gravity")
/obj/structure/machinery/gravity_generator/main/set_fix()
@@ -232,65 +243,50 @@
else
..()
if(attacking_item.tool_behaviour == TOOL_CROWBAR)
if(backpanelopen)
if(panel_open_heavy)
attacking_item.play_tool_sound(get_turf(src), 50)
to_chat(user, SPAN_NOTICE("You replace the back panel."))
backpanelopen = 0
panel_open_heavy = 0
else
attacking_item.play_tool_sound(get_turf(src), 50)
to_chat(user, SPAN_NOTICE("You open the back panel."))
backpanelopen = 1
panel_open_heavy = 1
if(old_broken_state != broken_state)
update_icon()
/obj/structure/machinery/gravity_generator/main/attack_hand(mob/user as mob)
if(!..())
return interact(user)
/obj/structure/machinery/gravity_generator/main/interact(mob/user as mob)
if(stat & BROKEN)
if(..(user))
return
var/dat = "Gravity Generator Breaker: "
if(!eventon)
if(breaker)
dat += "<span class='linkOn'>ON</span> <A href='byond://?src=[REF(src)];gentoggle=1'>OFF</A>"
else
dat += "<A href='byond://?src=[REF(src)];gentoggle=1'>ON</A> <span class='linkOn'>OFF</span> "
if(backpanelopen)
dat += "<br>Emergency shutoff:<br>"
dat += "<A href='byond://?src=[REF(src)];eshutoff=1'>Red Button</A>"
ui_interact(user)
dat += "<br>Generator Status:<br><div class='statusDisplay'>"
if(charging_state != POWER_IDLE)
dat += "<font class='bad'>WARNING</font> Radiation Detected. <br>[charging_state == POWER_UP ? "Charging..." : "Discharging..."]"
else if(on)
dat += "Powered."
else
dat += "Unpowered."
/obj/structure/machinery/gravity_generator/main/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "GravityGenerator", name)
ui.open()
dat += "<br>Gravity Charge: [charge_count]%</div>"
else
dat += "<h3><font class='bad'>ERROR: SYSTEM MALFUNCTION. PLEASE WAIT...</font></h3>"
var/datum/browser/popup = new(user, "gravgen", name)
popup.set_content(dat)
popup.open()
/obj/structure/machinery/gravity_generator/main/ui_data(mob/user)
var/list/data = list()
data["breaker"] = breaker
data["charge_count"] = charge_count
data["charging_state"] = charging_state
data["on"] = on
data["operational"] = (stat & BROKEN) ? FALSE : TRUE
/obj/structure/machinery/gravity_generator/main/Topic(href, href_list)
return data
if(..())
/obj/structure/machinery/gravity_generator/main/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
if(href_list["gentoggle"])
breaker = !breaker
investigate_log("was toggled [breaker ? "<font color='green'>ON</font>" : SPAN_WARNING("OFF")] by [usr.key].", "gravity")
set_power()
src.updateUsrDialog()
else if(href_list["eshutoff"])
investigate_log("was shut off by [usr.key].", "gravity")
eshutoff()
switch(action)
if("gentoggle")
breaker = !breaker
set_power()
. = TRUE
/obj/structure/machinery/gravity_generator/main/power_change()
..()
@@ -302,8 +298,8 @@
if(charge_count > 0)
charge_count = 0
playsound(src.loc, 'sound/effects/EMPulse.ogg', 100, 1)
pulse_radiation(100)
set_state(0)
// SSradiation.radiate(src, 100)
disable()
if(middle)
middle.ClearOverlays()
if(prob(1)) //It will spawn a small one and eat the generator. Won't cause any other issues considering it's a 1x1 and will go away on it's own.
@@ -328,70 +324,88 @@
// Set the charging state based on power/breaker.
/obj/structure/machinery/gravity_generator/main/proc/set_power()
var/new_state = 0
var/new_state = FALSE
if(stat & (NOPOWER|BROKEN) || !breaker)
new_state = 0
new_state = FALSE
else if(breaker)
new_state = 1
new_state = TRUE
charging_state = new_state ? POWER_UP : POWER_DOWN // Startup sequence animation.
investigate_log("is now [charging_state == POWER_UP ? "charging" : "discharging"].", "gravity")
update_icon()
// Set the state of the gravity.
/obj/structure/machinery/gravity_generator/main/proc/set_state(var/new_state)
/obj/structure/machinery/gravity_generator/main/proc/enable()
charging_state = POWER_IDLE
var/gravity_changed = (on != new_state)
on = new_state
update_use_power(on ? POWER_USE_ACTIVE : POWER_USE_IDLE)
var/gravity_changed = FALSE
if(!on)
gravity_changed = TRUE
on = TRUE
update_use_power(POWER_USE_ACTIVE)
soundloop.start()
// Sound the alert if gravity was just enabled or disabled.
var/alert = 0
var/area/area = get_area(src)
var/areadisplayname = get_area_display_name(area)
if(new_state) // If we turned on
if(!area.has_gravity())
alert = 1
GLOB.gravity_is_on = 1
soundloop.start(src)
investigate_log("was brought online and is now producing gravity for this level.", "gravity")
message_admins("The gravity generator was brought online. (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>[areadisplayname]</a>)")
else
if(area.has_gravity())
alert = 1
GLOB.gravity_is_on = 0
soundloop.stop(src)
investigate_log("was brought offline and there is now no gravity for this level.", "gravity")
message_admins("The gravity generator was brought offline with no backup generator. (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>[areadisplayname]</a>)")
update_icon()
if(!area.has_gravity())
soundloop.start(src)
investigate_log("was brought online and is now producing gravity for this level.", "gravity")
message_admins("The gravity generator was brought online. (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>[areadisplayname]</a>)")
update_list(gravity_changed)
shake_everyone()
src.updateUsrDialog()
/obj/structure/machinery/gravity_generator/main/proc/disable()
charging_state = POWER_IDLE
var/gravity_changed = FALSE
if(on)
gravity_changed = TRUE
on = FALSE
update_use_power(POWER_USE_IDLE)
soundloop.stop()
// Sound the alert if gravity was just enabled or disabled.
var/area/area = get_area(src)
var/areadisplayname = get_area_display_name(area)
if(area.has_gravity())
soundloop.stop(src)
investigate_log("was brought offline and there is now no gravity for this level.", "gravity")
message_admins("The gravity generator was brought offline with no backup generator. (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>[areadisplayname]</a>)")
update_list(gravity_changed)
shake_everyone()
src.updateUsrDialog()
if(alert)
shake_everyone()
// Charge/Discharge and turn on/off gravity when you reach 0/100 percent.
// Also emit radiation and handle the overlays.
/obj/structure/machinery/gravity_generator/main/process()
if(stat & BROKEN)
return
// if(on || charging_state != POWER_IDLE)
// SSradiation.radiate(src, 20)
if(charging_state != POWER_IDLE)
if(charging_state == POWER_UP && charge_count >= 100)
set_state(1)
enable()
else if(charging_state == POWER_DOWN && charge_count <= 0)
set_state(0)
disable()
else
if(charging_state == POWER_UP)
charge_count += rand(1,5)
charge_count += rand(3,5)
else if(charging_state == POWER_DOWN)
charge_count -= rand(1,5)
charge_count -= rand(3,5)
if(charge_count % 4 == 0 && prob(75)) // Let them know it is charging/discharging.
playsound(src.loc, 'sound/effects/EMPulse.ogg', 100, 1)
updateDialog()
if(prob(30)) // To help stop "Your clothes feel warm" spam.
pulse_radiation()
var/overlay_state = null
switch(charge_count)
if(0 to 20)
@@ -417,15 +431,12 @@
middle.AddOverlays(overlay_state)
current_overlay = overlay_state
/obj/structure/machinery/gravity_generator/main/proc/pulse_radiation(var/amount = 20)
SSradiation.radiate(src, amount)
// Shake everyone on the z level to let them know that gravity was enagaged/disenagaged.
/// Shake everyone on the z level to let them know that gravity was enagaged/disenagaged.
/obj/structure/machinery/gravity_generator/main/proc/shake_everyone()
var/turf/our_turf = get_turf(src)
for(var/mob/M in GLOB.mob_list)
var/turf/their_turf = get_turf(M)
if(their_turf && (their_turf.z == our_turf.z))
var/list/connected_z_levels = GetConnectedZlevels(our_turf.z)
for(var/mob/living/M in GLOB.mob_list)
if(M.z in connected_z_levels)
M.update_gravity(M.mob_has_gravity())
if(M.client)
if(!M) return
@@ -447,21 +458,6 @@
A.gravitychange(FALSE)
SSmachinery.gravity_generators -= src
/obj/structure/machinery/gravity_generator/main/Initialize()
. = ..()
soundloop = new(src, start_immediately = FALSE)
addtimer(CALLBACK(src, PROC_REF(updateareas)), 10)
return INITIALIZE_HINT_LATELOAD
/obj/structure/machinery/gravity_generator/main/LateInitialize()
..()
if(SSatlas.current_map.use_overmap && !linked)
var/my_sector = GLOB.map_sectors["[z]"]
if (istype(my_sector, /obj/effect/overmap/visitable))
attempt_hook_up(my_sector)
if(linked)
linked.gravity_generator = src
/obj/structure/machinery/gravity_generator/main/proc/updateareas()
for(var/area/A in GLOB.the_station_areas)
if(!(get_area_type(A) == AREA_STATION))
@@ -471,36 +467,37 @@
/obj/structure/machinery/gravity_generator/main/proc/get_area_type(var/area/A = get_area(src))
if (A.name == "Space")
return AREA_SPACE
else if(A.alwaysgravity == 1 || A.nevergravity == 1)
else if(A.alwaysgravity == TRUE || A.nevergravity == TRUE)
return AREA_SPECIAL
else
return AREA_STATION
/obj/structure/machinery/gravity_generator/main/proc/throw_up_and_down(var/area/Area)
if(!Area)
return
/obj/structure/machinery/gravity_generator/main/proc/throw_up_and_down()
to_world("<h2 class='alert'>Station Announcement:</h2>")
to_world(SPAN_DANGER("Warning! Localized Gravity Failure in \the [Area]. Brace for dangerous gravity change!"))
sleep(50)
set_state(FALSE)
sleep(30)
set_state(TRUE)
to_world(SPAN_DANGER("Warning! Localized gravity failure, buckle yourself securely now! Brace! Brace!"))
disable()
addtimer(CALLBACK(src, PROC_REF(throw_carbons_down)), 5 SECONDS)
/obj/structure/machinery/gravity_generator/main/proc/throw_carbons_down()
enable()
var/turf/our_turf = get_turf(src)
var/list/connected_z_levels = GetConnectedZlevels(our_turf.z)
for(var/mob/living/M in GLOB.mob_list)
var/turf/their_turf = get_turf(M)
if(their_turf?.loc == Area)
if(M.z in connected_z_levels)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/clothing/shoes/magboots/boots = H.get_equipped_item(slot_shoes)
if(istype(boots))
if(istype(boots) || H.buckled_to)
to_chat(M, SPAN_WARNING("You feel a surge of nausea and g-force, but you avoid being thrown around!"))
continue
to_chat(M, SPAN_DANGER("Suddenly the gravity pushed you up to the ceiling and dropped you back on the floor with great force!"))
M.fall_impact(1)
M.fall_impact(levels_fallen = 1)
#undef POWER_IDLE
#undef POWER_UP
#undef POWER_DOWN
#undef GRAV_OPERATIONAL
#undef GRAV_NEEDS_SCREWDRIVER
#undef GRAV_NEEDS_WELDING
#undef GRAV_NEEDS_PLASTEEL
+2 -2
View File
@@ -32,9 +32,9 @@
if(randomize_range)
switch(lighttype)
if("tube")
brightness_range = rand(6,9)
brightness_range = rand(5,8) // LEMURIAN SEA - INCREASE BY 1,1 AFTER ARC
if("bulb")
brightness_range = rand(4,6)
brightness_range = rand(3,5) // LEMURIAN SEA - INCREASE BY 1,1 AFTER ARC
if(randomize_color)
brightness_color = pick(randomized_colors)
update()
+4 -3
View File
@@ -117,6 +117,7 @@
/obj/structure/machinery/light/Initialize(mapload)
. = ..()
LAZYADD(SSmachinery.all_lights, src)
if (!has_power())
stat |= NOPOWER
@@ -148,6 +149,7 @@
set_pixel_offsets()
/obj/structure/machinery/light/Destroy()
LAZYREMOVE(SSmachinery.all_lights, src)
QDEL_NULL(cell)
return ..()
@@ -239,7 +241,7 @@
message_admins("LOG: Rigged light explosion, last touched by [fingerprintslast]")
explode()
else if( prob( min(60, switchcount*switchcount*0.01) ) )
else if(prob(min(60,(switchcount**2) * 0.05))) // LEMURIAN SEA, REDUCE 0.05 -> 0.01 AFTER ARC
if(status == LIGHT_OK && trigger)
status = LIGHT_BURNED
stat |= BROKEN
@@ -566,8 +568,7 @@
else
return ..()
// break the light and make sparks if was on
/// Break the light and make sparks if was on
/obj/structure/machinery/light/proc/broken(skip_sound_and_sparks = 0)
if(status == LIGHT_EMPTY)
return
+120
View File
@@ -0,0 +1,120 @@
/datum/tgui_module/adpi_panel/ui_state(mob/user)
return GLOB.staff_state
/datum/tgui_module/adpi_panel/ui_interact(var/mob/user, var/datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ADPIPanel", "ADPI Panel", 700, 520)
ui.open()
/datum/tgui_module/adpi_panel/ui_data(mob/user)
var/list/data = list()
data["targets"] = get_adpi_targets()
return data
/datum/tgui_module/adpi_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
if(!can_use_adpi_panel(ui.user))
return FALSE
var/custom_message = sanitizeSafe(params["message"], MAX_MESSAGE_LEN)
if(!length(custom_message))
custom_message = null
if(action == "send_target")
var/mob/living/target = locate(params["target"]) in GLOB.living_mob_list
if(!is_adpi_target(target))
to_chat(ui.user, SPAN_WARNING("That target is no longer valid."))
return TRUE
if(!SShallucinations.send_admin_adpi_message(target, custom_message))
to_chat(ui.user, SPAN_WARNING("No ADPI message could be sent to [target]."))
return TRUE
log_adpi_send(ui.user, list(target), custom_message)
return TRUE
if(action == "send_all")
var/list/targets = get_adpi_target_mobs()
var/list/sent_targets = list()
for(var/mob/living/target in targets)
if(SShallucinations.send_admin_adpi_message(target, custom_message))
sent_targets += target
if(!length(sent_targets))
to_chat(ui.user, SPAN_WARNING("No ADPI messages could be sent."))
return TRUE
log_adpi_send(ui.user, sent_targets, custom_message)
return TRUE
if(action == "refresh")
ui.send_full_update()
return TRUE
/datum/tgui_module/adpi_panel/proc/can_use_adpi_panel(var/mob/user)
return check_rights(R_ADMIN|R_MOD|R_FUN, 0, user)
/datum/tgui_module/adpi_panel/proc/is_adpi_target(var/mob/living/target)
if(!istype(target))
return FALSE
if(!target.client || !target.mind || target.stat == DEAD)
return FALSE
if(SShallucinations.is_adpi_excluded(target))
return FALSE
if(SShallucinations.is_adpi_blocked(target))
return FALSE
return TRUE
/datum/tgui_module/adpi_panel/proc/get_adpi_target_mobs()
var/list/targets = list()
for(var/mob/living/target in GLOB.living_mob_list)
if(is_adpi_target(target))
targets += target
return targets
/datum/tgui_module/adpi_panel/proc/get_adpi_targets()
var/list/targets = list()
var/list/names = list()
var/list/namecounts = list()
for(var/mob/living/target in get_adpi_target_mobs())
var/name = target.name
if(name in names)
namecounts[name]++
name = "[name] ([namecounts[name]])"
else
names.Add(name)
namecounts[name] = 1
if(target.real_name && target.real_name != target.name)
name += " \[[target.real_name]\]"
var/job = ""
if(ishuman(target))
var/mob/living/carbon/human/H = target
job = H.job
targets += list(list(
"name" = name,
"ref" = REF(target),
"key" = target.key,
"job" = job,
"can_random" = can_random_adpi(target)
))
return targets
/datum/tgui_module/adpi_panel/proc/can_random_adpi(var/mob/living/target)
SShallucinations.ensure_adpi_lists_loaded()
return SShallucinations.has_adpi_messages(target, FALSE)
/datum/tgui_module/adpi_panel/proc/log_adpi_send(var/mob/user, var/list/targets, var/custom_message)
var/admin_target_text = length(targets) == 1 ? key_name_admin(targets[1]) : "[length(targets)] characters"
var/log_target_text = length(targets) == 1 ? key_name(targets[1]) : "[length(targets)] characters"
var/message_text = custom_message ? ": [sanitize_tg(custom_message)]" : " using random pool messages"
message_admins("[key_name_admin(user)] sent ADPI to [admin_target_text][message_text]", 1)
log_admin("[key_name(user)] sent ADPI to [log_target_text][message_text]")
@@ -6,15 +6,22 @@
all_vaurca = set_all_vaurca
/datum/tgui_module/hivenet_manifest/ui_interact(var/mob/user, var/datum/tgui/ui)
if(is_lemurian_sea_sector())
to_chat(user, SPAN_WARNING("You attempt to query the Hivenet, but find nothing."))
return
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "HivenetManifest", "Hivenet Manifest", 350, 400)
ui.autoupdate = FALSE
ui.open()
/datum/tgui_module/hivenet_manifest/ui_data(mob/user)
var/list/data = list()
if(is_lemurian_sea_sector())
SStgui.close_uis(src)
return data
var/list/zora_vaurca = list()
var/list/cthur_vaurca = list()
var/list/klax_vaurca = list()