mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-11 10:22:13 +00:00
Merge pull request #14306 from Putnam3145/supernova
Adds a supernova event, with tweaks to allow this
This commit is contained in:
@@ -22,7 +22,7 @@
|
|||||||
#define COMPONENT_GLOB_BLOCK_CINEMATIC 1
|
#define COMPONENT_GLOB_BLOCK_CINEMATIC 1
|
||||||
|
|
||||||
// signals from globally accessible objects
|
// signals from globally accessible objects
|
||||||
/// from SSsun when the sun changes position : (azimuth)
|
/// from SSsun when the sun changes position : (primary_sun, suns)
|
||||||
#define COMSIG_SUN_MOVED "sun_moved"
|
#define COMSIG_SUN_MOVED "sun_moved"
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
@@ -70,3 +70,8 @@ PROCESSING_SUBSYSTEM_DEF(weather)
|
|||||||
A = W
|
A = W
|
||||||
break
|
break
|
||||||
return A
|
return A
|
||||||
|
|
||||||
|
/datum/controller/subsystem/processing/weather/proc/get_weather_by_type(datum/weather/weather_datum_type)
|
||||||
|
for(var/V in processing)
|
||||||
|
if(istype(V,weather_datum_type))
|
||||||
|
return V
|
||||||
|
|||||||
@@ -1,32 +1,63 @@
|
|||||||
|
#define OCCLUSION_DISTANCE 20
|
||||||
|
|
||||||
|
/datum/sun
|
||||||
|
var/azimuth = 0 // clockwise, top-down rotation from 0 (north) to 359
|
||||||
|
var/power_mod = 1 // how much power this sun is outputting relative to standard
|
||||||
|
|
||||||
|
|
||||||
|
/datum/sun/vv_edit_var(var_name, var_value)
|
||||||
|
. = ..()
|
||||||
|
if(var_name == NAMEOF(src, azimuth))
|
||||||
|
SSsun.complete_movement()
|
||||||
|
|
||||||
|
/atom/proc/check_obscured(datum/sun/sun, distance = OCCLUSION_DISTANCE)
|
||||||
|
var/target_x = round(sin(sun.azimuth), 0.01)
|
||||||
|
var/target_y = round(cos(sun.azimuth), 0.01)
|
||||||
|
var/x_hit = x
|
||||||
|
var/y_hit = y
|
||||||
|
var/turf/hit
|
||||||
|
|
||||||
|
for(var/run in 1 to distance)
|
||||||
|
x_hit += target_x
|
||||||
|
y_hit += target_y
|
||||||
|
hit = locate(round(x_hit, 1), round(y_hit, 1), z)
|
||||||
|
if(hit.opacity)
|
||||||
|
return TRUE
|
||||||
|
if(hit.x == 1 || hit.x == world.maxx || hit.y == 1 || hit.y == world.maxy) //edge of the map
|
||||||
|
break
|
||||||
|
return FALSE
|
||||||
|
|
||||||
SUBSYSTEM_DEF(sun)
|
SUBSYSTEM_DEF(sun)
|
||||||
name = "Sun"
|
name = "Sun"
|
||||||
wait = 1 MINUTES
|
wait = 1 MINUTES
|
||||||
flags = SS_NO_TICK_CHECK
|
flags = SS_NO_TICK_CHECK
|
||||||
|
|
||||||
var/azimuth = 0 ///clockwise, top-down rotation from 0 (north) to 359
|
var/list/datum/sun/suns = list()
|
||||||
|
var/datum/sun/primary_sun
|
||||||
var/azimuth_mod = 1 ///multiplier against base_rotation
|
var/azimuth_mod = 1 ///multiplier against base_rotation
|
||||||
var/base_rotation = 6 ///base rotation in degrees per fire
|
var/base_rotation = 6 ///base rotation in degrees per fire
|
||||||
|
|
||||||
/datum/controller/subsystem/sun/Initialize(start_timeofday)
|
/datum/controller/subsystem/sun/Initialize(start_timeofday)
|
||||||
azimuth = rand(0, 359)
|
primary_sun = new
|
||||||
|
suns += primary_sun
|
||||||
|
primary_sun.azimuth = rand(0, 359)
|
||||||
azimuth_mod = round(rand(50, 200)/100, 0.01) // 50% - 200% of standard rotation
|
azimuth_mod = round(rand(50, 200)/100, 0.01) // 50% - 200% of standard rotation
|
||||||
if(prob(50))
|
if(prob(50))
|
||||||
azimuth_mod *= -1
|
azimuth_mod *= -1
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/datum/controller/subsystem/sun/fire(resumed = FALSE)
|
/datum/controller/subsystem/sun/fire(resumed = FALSE)
|
||||||
azimuth += azimuth_mod * base_rotation
|
for(var/S in suns)
|
||||||
azimuth = round(azimuth, 0.01)
|
var/datum/sun/sun = S
|
||||||
if(azimuth >= 360)
|
sun.azimuth += azimuth_mod * base_rotation
|
||||||
azimuth -= 360
|
sun.azimuth = round(sun.azimuth, 0.01)
|
||||||
if(azimuth < 0)
|
if(sun.azimuth >= 360)
|
||||||
azimuth += 360
|
sun.azimuth -= 360
|
||||||
|
if(sun.azimuth < 0)
|
||||||
|
sun.azimuth += 360
|
||||||
complete_movement()
|
complete_movement()
|
||||||
|
|
||||||
/datum/controller/subsystem/sun/proc/complete_movement()
|
/datum/controller/subsystem/sun/proc/complete_movement()
|
||||||
SEND_SIGNAL(src, COMSIG_SUN_MOVED, azimuth)
|
SEND_SIGNAL(src, COMSIG_SUN_MOVED, primary_sun, suns)
|
||||||
|
|
||||||
/datum/controller/subsystem/sun/vv_edit_var(var_name, var_value)
|
#undef OCCLUSION_DISTANCE
|
||||||
. = ..()
|
|
||||||
if(var_name == NAMEOF(src, azimuth))
|
|
||||||
complete_movement()
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
target_trait = ZTRAIT_STATION
|
target_trait = ZTRAIT_STATION
|
||||||
|
|
||||||
immunity_type = "rad"
|
immunity_type = "rad"
|
||||||
|
|
||||||
var/radiation_intensity = 100
|
var/radiation_intensity = 100
|
||||||
|
|
||||||
/datum/weather/rad_storm/telegraph()
|
/datum/weather/rad_storm/telegraph()
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
// Init Sunlight (called from datum_bloodsucker.on_gain(), in case game mode isn't even Bloodsucker
|
// Init Sunlight (called from datum_bloodsucker.on_gain(), in case game mode isn't even Bloodsucker
|
||||||
/datum/game_mode/proc/check_start_sunlight()
|
/datum/game_mode/proc/check_start_sunlight()
|
||||||
// Already Sunlight (and not about to cancel)
|
// Already Sunlight (and not about to cancel)
|
||||||
if(istype(bloodsucker_sunlight) && !bloodsucker_sunlight.cancel_me)
|
if(istype(bloodsucker_sunlight))
|
||||||
return
|
return
|
||||||
bloodsucker_sunlight = new ()
|
bloodsucker_sunlight = new ()
|
||||||
|
|
||||||
@@ -97,7 +97,6 @@
|
|||||||
if(!istype(bloodsucker_sunlight))
|
if(!istype(bloodsucker_sunlight))
|
||||||
return
|
return
|
||||||
if(bloodsuckers.len <= 0)
|
if(bloodsuckers.len <= 0)
|
||||||
bloodsucker_sunlight.cancel_me = TRUE
|
|
||||||
qdel(bloodsucker_sunlight)
|
qdel(bloodsucker_sunlight)
|
||||||
bloodsucker_sunlight = null
|
bloodsucker_sunlight = null
|
||||||
|
|
||||||
|
|||||||
@@ -7,98 +7,79 @@
|
|||||||
// Over Time, tick down toward a "Solar Flare" of UV buffeting the station. This period is harmful to vamps.
|
// Over Time, tick down toward a "Solar Flare" of UV buffeting the station. This period is harmful to vamps.
|
||||||
/obj/effect/sunlight
|
/obj/effect/sunlight
|
||||||
//var/amDay = FALSE
|
//var/amDay = FALSE
|
||||||
var/cancel_me = FALSE
|
|
||||||
var/amDay = FALSE
|
var/amDay = FALSE
|
||||||
var/time_til_cycle = 0
|
var/time_til_cycle = 0
|
||||||
var/nightime_duration = 900 //15 Minutes
|
var/nighttime_duration = 900 //15 Minutes
|
||||||
|
var/issued_XP = FALSE
|
||||||
|
|
||||||
/obj/effect/sunlight/Initialize()
|
/obj/effect/sunlight/Initialize()
|
||||||
. = ..()
|
. = ..()
|
||||||
INVOKE_ASYNC(src, .proc/countdown)
|
|
||||||
INVOKE_ASYNC(src, .proc/hud_tick)
|
|
||||||
|
|
||||||
/obj/effect/sunlight/proc/countdown()
|
/obj/effect/sunlight/proc/start_countdown()
|
||||||
set waitfor = FALSE
|
START_PROCESSING(SSweather, src) //it counts as weather right
|
||||||
|
time_til_cycle = nighttime_duration
|
||||||
|
|
||||||
while(!cancel_me)
|
/obj/effect/sunlight/process()
|
||||||
|
// Update all Bloodsucker sunlight huds
|
||||||
time_til_cycle = nightime_duration
|
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
|
||||||
|
if(!istype(M) || !istype(M.current))
|
||||||
// Part 1: Night (all is well)
|
continue
|
||||||
while(time_til_cycle > TIME_BLOODSUCKER_DAY_WARN)
|
var/datum/antagonist/bloodsucker/bloodsuckerdatum = M.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
|
||||||
sleep(10)
|
if(istype(bloodsuckerdatum))
|
||||||
if(cancel_me)
|
bloodsuckerdatum.update_sunlight(max(0, time_til_cycle), amDay) // This pings all HUDs
|
||||||
return
|
time_til_cycle--
|
||||||
//sleep(TIME_BLOODSUCKER_NIGHT - TIME_BLOODSUCKER_DAY_WARN)
|
if(amDay)
|
||||||
warn_daylight(1,"<span class = 'danger'>Solar Flares will bombard the station with dangerous UV in [TIME_BLOODSUCKER_DAY_WARN / 60] minutes. <b>Prepare to seek cover in a coffin or closet.</b></span>") // time2text <-- use Help On
|
if(time_til_cycle > 0 && time_til_cycle % 4 == 0)
|
||||||
give_home_power() // Give VANISHING ACT power to all vamps with a lair!
|
|
||||||
|
|
||||||
// Part 2: Night Ending
|
|
||||||
while(time_til_cycle > TIME_BLOODSUCKER_DAY_FINAL_WARN)
|
|
||||||
sleep(10)
|
|
||||||
if(cancel_me)
|
|
||||||
return
|
|
||||||
//sleep(TIME_BLOODSUCKER_DAY_WARN - TIME_BLOODSUCKER_DAY_FINAL_WARN)
|
|
||||||
message_admins("BLOODSUCKER NOTICE: Daylight beginning in [TIME_BLOODSUCKER_DAY_FINAL_WARN] seconds.)")
|
|
||||||
warn_daylight(2,"<span class = 'userdanger'>Solar Flares are about to bombard the station! You have [TIME_BLOODSUCKER_DAY_FINAL_WARN] seconds to find cover!</span>",\
|
|
||||||
"<span class = 'danger'>In [TIME_BLOODSUCKER_DAY_FINAL_WARN / 10], your master will be at risk of a Solar Flare. Make sure they find cover!</span>")
|
|
||||||
|
|
||||||
// (FINAL LIL WARNING)
|
|
||||||
while(time_til_cycle > 5)
|
|
||||||
sleep(10)
|
|
||||||
if(cancel_me)
|
|
||||||
return
|
|
||||||
//sleep(TIME_BLOODSUCKER_DAY_FINAL_WARN - 50)
|
|
||||||
warn_daylight(3,"<span class = 'userdanger'>Seek cover, for Sol rises!</span>")
|
|
||||||
|
|
||||||
// Part 3: Night Ending
|
|
||||||
while(time_til_cycle > 0)
|
|
||||||
sleep(10)
|
|
||||||
if(cancel_me)
|
|
||||||
return
|
|
||||||
//sleep(50)
|
|
||||||
warn_daylight(4,"<span class = 'userdanger'>Solar flares bombard the station with deadly UV light!</span><br><span class = ''>Stay in cover for the next [TIME_BLOODSUCKER_DAY / 60] minutes or risk Final Death!</span>",\
|
|
||||||
"<span class = 'danger'>Solar flares bombard the station with UV light!</span>")
|
|
||||||
|
|
||||||
// Part 4: Day
|
|
||||||
amDay = TRUE
|
|
||||||
message_admins("BLOODSUCKER NOTICE: Daylight Beginning (Lasts for [TIME_BLOODSUCKER_DAY / 60] minutes.)")
|
|
||||||
time_til_cycle = TIME_BLOODSUCKER_DAY
|
|
||||||
sleep(10) // One second grace period.
|
|
||||||
//var/daylight_time = TIME_BLOODSUCKER_DAY
|
|
||||||
var/issued_XP = FALSE
|
|
||||||
while(time_til_cycle > 0)
|
|
||||||
punish_vamps()
|
punish_vamps()
|
||||||
sleep(TIME_BLOODSUCKER_BURN_INTERVAL)
|
|
||||||
if(cancel_me)
|
|
||||||
return
|
|
||||||
//daylight_time -= TIME_BLOODSUCKER_BURN_INTERVAL
|
|
||||||
// Issue Level Up!
|
|
||||||
if(!issued_XP && time_til_cycle <= 5)
|
if(!issued_XP && time_til_cycle <= 5)
|
||||||
issued_XP = TRUE
|
issued_XP = TRUE
|
||||||
vamps_rank_up()
|
// Cycle through all vamp antags and check if they're inside a closet.
|
||||||
|
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
|
||||||
|
if(!istype(M) || !istype(M.current))
|
||||||
|
continue
|
||||||
|
var/datum/antagonist/bloodsucker/bloodsuckerdatum = M.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
|
||||||
|
if(istype(bloodsuckerdatum))
|
||||||
|
bloodsuckerdatum.RankUp() // Rank up! Must still be in a coffin to level!
|
||||||
|
|
||||||
warn_daylight(5,"<span class = 'announce'>The solar flare has ended, and the daylight danger has passed...for now.</span>",\
|
warn_daylight(5,"<span class = 'announce'>The solar flare has ended, and the daylight danger has passed...for now.</span>",\
|
||||||
"<span class = 'announce'>The solar flare has ended, and the daylight danger has passed...for now.</span>")
|
"<span class = 'announce'>The solar flare has ended, and the daylight danger has passed...for now.</span>")
|
||||||
amDay = FALSE
|
amDay = FALSE
|
||||||
day_end() // Remove VANISHING ACT power from all vamps who have it! Clear Warnings (sunlight, locker protection)
|
issued_XP = FALSE
|
||||||
nightime_duration += 100 //Each day makes the night a minute longer.
|
|
||||||
message_admins("BLOODSUCKER NOTICE: Daylight Ended. Resetting to Night (Lasts for [nightime_duration / 60] minutes.)")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/obj/effect/sunlight/proc/hud_tick()
|
|
||||||
set waitfor = FALSE
|
|
||||||
while(!cancel_me)
|
|
||||||
// Update all Bloodsucker sunlight huds
|
|
||||||
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
|
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
|
||||||
if(!istype(M) || !istype(M.current))
|
if(!istype(M) || !istype(M.current))
|
||||||
continue
|
continue
|
||||||
var/datum/antagonist/bloodsucker/bloodsuckerdatum = M.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
|
var/datum/antagonist/bloodsucker/bloodsuckerdatum = M.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
|
||||||
if(istype(bloodsuckerdatum))
|
if(!istype(bloodsuckerdatum))
|
||||||
bloodsuckerdatum.update_sunlight(max(0, time_til_cycle), amDay) // This pings all HUDs
|
continue
|
||||||
sleep(10)
|
// Reset Warnings
|
||||||
time_til_cycle --
|
bloodsuckerdatum.warn_sun_locker = FALSE
|
||||||
|
bloodsuckerdatum.warn_sun_burn = FALSE
|
||||||
|
// Remove Dawn Powers
|
||||||
|
for(var/datum/action/bloodsucker/P in bloodsuckerdatum.powers)
|
||||||
|
if(istype(P, /datum/action/bloodsucker/gohome))
|
||||||
|
bloodsuckerdatum.powers -= P
|
||||||
|
P.Remove(M.current)
|
||||||
|
nighttime_duration += 100 //Each day makes the night a minute longer.
|
||||||
|
time_til_cycle = nighttime_duration
|
||||||
|
message_admins("BLOODSUCKER NOTICE: Daylight Ended. Resetting to Night (Lasts for [nighttime_duration / 60] minutes.)")
|
||||||
|
else
|
||||||
|
switch(time_til_cycle)
|
||||||
|
if(TIME_BLOODSUCKER_DAY_WARN)
|
||||||
|
//sleep(TIME_BLOODSUCKER_NIGHT - TIME_BLOODSUCKER_DAY_WARN)
|
||||||
|
warn_daylight(1,"<span class = 'danger'>Solar Flares will bombard the station with dangerous UV in [TIME_BLOODSUCKER_DAY_WARN / 60] minutes. <b>Prepare to seek cover in a coffin or closet.</b></span>") // time2text <-- use Help On
|
||||||
|
give_home_power() // Give VANISHING ACT power to all vamps with a lair!
|
||||||
|
if(TIME_BLOODSUCKER_DAY_FINAL_WARN)
|
||||||
|
message_admins("BLOODSUCKER NOTICE: Daylight beginning in [TIME_BLOODSUCKER_DAY_FINAL_WARN] seconds.)")
|
||||||
|
warn_daylight(2,"<span class = 'userdanger'>Solar Flares are about to bombard the station! You have [TIME_BLOODSUCKER_DAY_FINAL_WARN] seconds to find cover!</span>",\
|
||||||
|
"<span class = 'danger'>In [TIME_BLOODSUCKER_DAY_FINAL_WARN / 10], your master will be at risk of a Solar Flare. Make sure they find cover!</span>")
|
||||||
|
if(5)
|
||||||
|
warn_daylight(3,"<span class = 'userdanger'>Seek cover, for Sol rises!</span>")
|
||||||
|
if(0)
|
||||||
|
warn_daylight(4,"<span class = 'userdanger'>Solar flares bombard the station with deadly UV light!</span><br><span class = ''>Stay in cover for the next [TIME_BLOODSUCKER_DAY / 60] minutes or risk Final Death!</span>",\
|
||||||
|
"<span class = 'danger'>Solar flares bombard the station with UV light!</span>")
|
||||||
|
amDay = TRUE
|
||||||
|
message_admins("BLOODSUCKER NOTICE: Daylight Beginning (Lasts for [TIME_BLOODSUCKER_DAY / 60] minutes.)")
|
||||||
|
time_til_cycle = TIME_BLOODSUCKER_DAY
|
||||||
|
|
||||||
/obj/effect/sunlight/proc/warn_daylight(danger_level =0, vampwarn = "", vassalwarn = "")
|
/obj/effect/sunlight/proc/warn_daylight(danger_level =0, vampwarn = "", vassalwarn = "")
|
||||||
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
|
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
|
||||||
@@ -162,32 +143,6 @@
|
|||||||
M.current.updatehealth()
|
M.current.updatehealth()
|
||||||
SEND_SIGNAL(M.current, COMSIG_ADD_MOOD_EVENT, "vampsleep", /datum/mood_event/daylight_2)
|
SEND_SIGNAL(M.current, COMSIG_ADD_MOOD_EVENT, "vampsleep", /datum/mood_event/daylight_2)
|
||||||
|
|
||||||
/obj/effect/sunlight/proc/day_end()
|
|
||||||
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
|
|
||||||
if(!istype(M) || !istype(M.current))
|
|
||||||
continue
|
|
||||||
var/datum/antagonist/bloodsucker/bloodsuckerdatum = M.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
|
|
||||||
if(!istype(bloodsuckerdatum))
|
|
||||||
continue
|
|
||||||
// Reset Warnings
|
|
||||||
bloodsuckerdatum.warn_sun_locker = FALSE
|
|
||||||
bloodsuckerdatum.warn_sun_burn = FALSE
|
|
||||||
// Remove Dawn Powers
|
|
||||||
for(var/datum/action/bloodsucker/P in bloodsuckerdatum.powers)
|
|
||||||
if(istype(P, /datum/action/bloodsucker/gohome))
|
|
||||||
bloodsuckerdatum.powers -= P
|
|
||||||
P.Remove(M.current)
|
|
||||||
|
|
||||||
/obj/effect/sunlight/proc/vamps_rank_up()
|
|
||||||
set waitfor = FALSE
|
|
||||||
// Cycle through all vamp antags and check if they're inside a closet.
|
|
||||||
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
|
|
||||||
if(!istype(M) || !istype(M.current))
|
|
||||||
continue
|
|
||||||
var/datum/antagonist/bloodsucker/bloodsuckerdatum = M.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)
|
|
||||||
if(istype(bloodsuckerdatum))
|
|
||||||
bloodsuckerdatum.RankUp() // Rank up! Must still be in a coffin to level!
|
|
||||||
|
|
||||||
/obj/effect/sunlight/proc/give_home_power()
|
/obj/effect/sunlight/proc/give_home_power()
|
||||||
// It's late...! Give the "Vanishing Act" gohome power to bloodsuckers.
|
// It's late...! Give the "Vanishing Act" gohome power to bloodsuckers.
|
||||||
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
|
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
|
||||||
|
|||||||
67
code/modules/events/supernova.dm
Normal file
67
code/modules/events/supernova.dm
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/datum/round_event_control/supernova
|
||||||
|
name = "Supernova"
|
||||||
|
typepath = /datum/round_event/supernova
|
||||||
|
weight = 10
|
||||||
|
max_occurrences = 2
|
||||||
|
min_players = 2
|
||||||
|
|
||||||
|
/datum/round_event/supernova
|
||||||
|
announceWhen = 40
|
||||||
|
startWhen = 1
|
||||||
|
endWhen = 300
|
||||||
|
var/power = 1
|
||||||
|
var/datum/sun/supernova
|
||||||
|
var/storm_count = 0
|
||||||
|
|
||||||
|
/datum/round_event/supernova/setup()
|
||||||
|
announceWhen = rand(4, 60)
|
||||||
|
supernova = new
|
||||||
|
SSsun.suns += supernova
|
||||||
|
if(prob(50))
|
||||||
|
power = rand(5,100) / 100
|
||||||
|
else
|
||||||
|
power = rand(5,5000) / 100
|
||||||
|
supernova.azimuth = rand(0, 359)
|
||||||
|
supernova.power_mod = 0
|
||||||
|
|
||||||
|
/datum/round_event/supernova/announce()
|
||||||
|
var/message = "Our tachyon-doppler array has detected a supernova in your vicinity. Peak flux from the supernova estimated to be [round(power,0.1)] times current solar flux. [power > 4 ? "Short burts of radiation may be possible, so please prepare accordingly." : ""]"
|
||||||
|
if(prob(power * 25))
|
||||||
|
priority_announce(message)
|
||||||
|
else
|
||||||
|
print_command_report(message)
|
||||||
|
|
||||||
|
|
||||||
|
/datum/round_event/supernova/start()
|
||||||
|
supernova.power_mod = 0.00000002 * power
|
||||||
|
var/explosion_size = rand(1000000000, 999999999)
|
||||||
|
var/turf/epicenter = get_turf_in_angle(supernova.azimuth, SSmapping.get_station_center(), world.maxx / 2)
|
||||||
|
for(var/array in GLOB.doppler_arrays)
|
||||||
|
var/obj/machinery/doppler_array/A = array
|
||||||
|
A.sense_explosion(epicenter, explosion_size/2, explosion_size, 0, 107000000 / power, explosion_size/2, explosion_size, 0)
|
||||||
|
if(power > 1 && SSticker.mode.bloodsucker_sunlight?.time_til_cycle > 90)
|
||||||
|
var/obj/effect/sunlight/sucker_light = SSticker.mode.bloodsucker_sunlight
|
||||||
|
sucker_light.time_til_cycle = 90
|
||||||
|
sucker_light.warn_daylight(1,"<span class = 'danger'>A supernova will bombard the station with dangerous UV in [90 / 60] minutes. <b>Prepare to seek cover in a coffin or closet.</b></span>")
|
||||||
|
sucker_light.give_home_power()
|
||||||
|
|
||||||
|
/datum/round_event/supernova/tick()
|
||||||
|
var/midpoint = (endWhen-startWhen)/2
|
||||||
|
switch(activeFor)
|
||||||
|
if(startWhen to midpoint)
|
||||||
|
supernova.power_mod = min(supernova.power_mod*1.2, power)
|
||||||
|
if(endWhen-10 to endWhen)
|
||||||
|
supernova.power_mod /= 4
|
||||||
|
if(prob(round(supernova.power_mod / 2)) && storm_count < 3 && !SSweather.get_weather_by_type(/datum/weather/rad_storm))
|
||||||
|
SSweather.run_weather(/datum/weather/rad_storm/supernova)
|
||||||
|
storm_count++
|
||||||
|
|
||||||
|
/datum/round_event/supernova/end()
|
||||||
|
SSsun.suns -= supernova
|
||||||
|
qdel(supernova)
|
||||||
|
|
||||||
|
/datum/weather/rad_storm/supernova
|
||||||
|
weather_duration_lower = 50
|
||||||
|
weather_duration_lower = 100
|
||||||
|
telegraph_duration = 100
|
||||||
|
radiation_intensity = 50
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
#define SOLAR_GEN_RATE 1500
|
#define SOLAR_GEN_RATE 1500
|
||||||
#define OCCLUSION_DISTANCE 20
|
|
||||||
|
|
||||||
/obj/machinery/power/solar
|
/obj/machinery/power/solar
|
||||||
name = "solar panel"
|
name = "solar panel"
|
||||||
@@ -14,8 +13,8 @@
|
|||||||
integrity_failure = 0.33
|
integrity_failure = 0.33
|
||||||
|
|
||||||
var/id
|
var/id
|
||||||
var/obscured = FALSE
|
var/list/obscured = list()
|
||||||
var/sunfrac = 0 //[0-1] measure of obscuration -- multipllier against power generation
|
var/total_flux = 0 // multipllier against power generation -- measured by obscuration of all suns
|
||||||
var/azimuth_current = 0 //[0-360) degrees, which direction are we facing?
|
var/azimuth_current = 0 //[0-360) degrees, which direction are we facing?
|
||||||
var/azimuth_target = 0 //same but what way we're going to face next time we turn
|
var/azimuth_target = 0 //same but what way we're going to face next time we turn
|
||||||
var/obj/machinery/power/solar_control/control
|
var/obj/machinery/power/solar_control/control
|
||||||
@@ -133,40 +132,28 @@
|
|||||||
|
|
||||||
///trace towards sun to see if we're in shadow
|
///trace towards sun to see if we're in shadow
|
||||||
/obj/machinery/power/solar/proc/occlusion_setup()
|
/obj/machinery/power/solar/proc/occlusion_setup()
|
||||||
obscured = TRUE
|
obscured = list()
|
||||||
|
for(var/S in SSsun.suns)
|
||||||
var/distance = OCCLUSION_DISTANCE
|
if(check_obscured(S))
|
||||||
var/target_x = round(sin(SSsun.azimuth), 0.01)
|
obscured |= S
|
||||||
var/target_y = round(cos(SSsun.azimuth), 0.01)
|
|
||||||
var/x_hit = x
|
|
||||||
var/y_hit = y
|
|
||||||
var/turf/hit
|
|
||||||
|
|
||||||
for(var/run in 1 to distance)
|
|
||||||
x_hit += target_x
|
|
||||||
y_hit += target_y
|
|
||||||
hit = locate(round(x_hit, 1), round(y_hit, 1), z)
|
|
||||||
if(hit.opacity)
|
|
||||||
return
|
|
||||||
if(hit.x == 1 || hit.x == world.maxx || hit.y == 1 || hit.y == world.maxy) //edge of the map
|
|
||||||
break
|
|
||||||
obscured = FALSE
|
|
||||||
|
|
||||||
///calculates the fraction of the sunlight that the panel receives
|
///calculates the fraction of the sunlight that the panel receives
|
||||||
/obj/machinery/power/solar/proc/update_solar_exposure()
|
/obj/machinery/power/solar/proc/update_solar_exposure()
|
||||||
needs_to_update_solar_exposure = FALSE
|
needs_to_update_solar_exposure = FALSE
|
||||||
sunfrac = 0
|
total_flux = 0
|
||||||
if(obscured)
|
for(var/S in SSsun.suns)
|
||||||
return 0
|
if(S in obscured)
|
||||||
|
continue
|
||||||
var/sun_azimuth = SSsun.azimuth
|
var/datum/sun/sun = S
|
||||||
if(azimuth_current == sun_azimuth) //just a quick optimization for the most frequent case
|
var/sun_azimuth = sun.azimuth
|
||||||
. = 1
|
var/cur_pow = 0
|
||||||
else
|
if(azimuth_current == sun_azimuth) //just a quick optimization for the most frequent case
|
||||||
//dot product of sun and panel -- Lambert's Cosine Law
|
cur_pow = sun.power_mod
|
||||||
. = cos(azimuth_current - sun_azimuth)
|
else
|
||||||
. = clamp(round(., 0.01), 0, 1)
|
//dot product of sun and panel -- Lambert's Cosine Law
|
||||||
sunfrac = .
|
cur_pow = cos(azimuth_current - sun_azimuth) * sun.power_mod
|
||||||
|
cur_pow = clamp(round(cur_pow, 0.01), 0, 1)
|
||||||
|
total_flux += cur_pow
|
||||||
|
|
||||||
/obj/machinery/power/solar/process()
|
/obj/machinery/power/solar/process()
|
||||||
if(stat & BROKEN)
|
if(stat & BROKEN)
|
||||||
@@ -177,10 +164,10 @@
|
|||||||
update_turn()
|
update_turn()
|
||||||
if(needs_to_update_solar_exposure)
|
if(needs_to_update_solar_exposure)
|
||||||
update_solar_exposure()
|
update_solar_exposure()
|
||||||
if(sunfrac <= 0)
|
if(total_flux <= 0)
|
||||||
return
|
return
|
||||||
|
|
||||||
var/sgen = SOLAR_GEN_RATE * sunfrac * efficiency
|
var/sgen = SOLAR_GEN_RATE * total_flux * efficiency
|
||||||
add_avail(sgen)
|
add_avail(sgen)
|
||||||
if(control)
|
if(control)
|
||||||
control.gen += sgen
|
control.gen += sgen
|
||||||
@@ -385,7 +372,7 @@
|
|||||||
track = mode
|
track = mode
|
||||||
if(mode == SOLAR_TRACK_AUTO)
|
if(mode == SOLAR_TRACK_AUTO)
|
||||||
if(connected_tracker)
|
if(connected_tracker)
|
||||||
connected_tracker.sun_update(SSsun, SSsun.azimuth)
|
connected_tracker.sun_update(SSsun, SSsun.primary_sun, SSsun.suns)
|
||||||
else
|
else
|
||||||
track = SOLAR_TRACK_OFF
|
track = SOLAR_TRACK_OFF
|
||||||
return TRUE
|
return TRUE
|
||||||
@@ -483,4 +470,3 @@ Congratulations, you should have a working solar array. If you are having troubl
|
|||||||
"}
|
"}
|
||||||
|
|
||||||
#undef SOLAR_GEN_RATE
|
#undef SOLAR_GEN_RATE
|
||||||
#undef OCCLUSION_DISTANCE
|
|
||||||
|
|||||||
@@ -41,10 +41,10 @@
|
|||||||
control = null
|
control = null
|
||||||
|
|
||||||
///Tell the controller to turn the solar panels
|
///Tell the controller to turn the solar panels
|
||||||
/obj/machinery/power/tracker/proc/sun_update(datum/source, azimuth)
|
/obj/machinery/power/tracker/proc/sun_update(datum/source, datum/sun/primary_sun, list/datum/sun/suns)
|
||||||
setDir(angle2dir(azimuth))
|
setDir(angle2dir(primary_sun.azimuth))
|
||||||
if(control && control.track == SOLAR_TRACK_AUTO)
|
if(control && control.track == SOLAR_TRACK_AUTO)
|
||||||
control.set_panels(azimuth)
|
control.set_panels(primary_sun.azimuth)
|
||||||
|
|
||||||
/obj/machinery/power/tracker/proc/Make(obj/item/solar_assembly/S)
|
/obj/machinery/power/tracker/proc/Make(obj/item/solar_assembly/S)
|
||||||
if(!S)
|
if(!S)
|
||||||
|
|||||||
@@ -2069,6 +2069,7 @@
|
|||||||
#include "code\modules\events\spontaneous_appendicitis.dm"
|
#include "code\modules\events\spontaneous_appendicitis.dm"
|
||||||
#include "code\modules\events\stray_cargo.dm"
|
#include "code\modules\events\stray_cargo.dm"
|
||||||
#include "code\modules\events\supermatter_surge.dm"
|
#include "code\modules\events\supermatter_surge.dm"
|
||||||
|
#include "code\modules\events\supernova.dm"
|
||||||
#include "code\modules\events\travelling_trader.dm"
|
#include "code\modules\events\travelling_trader.dm"
|
||||||
#include "code\modules\events\vent_clog.dm"
|
#include "code\modules\events\vent_clog.dm"
|
||||||
#include "code\modules\events\wisdomcow.dm"
|
#include "code\modules\events\wisdomcow.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user