Merge branch 'master' into void-but-for-real

This commit is contained in:
kiwedespars
2021-03-12 23:10:19 -08:00
67 changed files with 424 additions and 210 deletions
@@ -7,98 +7,79 @@
// Over Time, tick down toward a "Solar Flare" of UV buffeting the station. This period is harmful to vamps.
/obj/effect/sunlight
//var/amDay = FALSE
var/cancel_me = FALSE
var/amDay = FALSE
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()
. = ..()
INVOKE_ASYNC(src, .proc/countdown)
INVOKE_ASYNC(src, .proc/hud_tick)
/obj/effect/sunlight/proc/countdown()
set waitfor = FALSE
/obj/effect/sunlight/proc/start_countdown()
START_PROCESSING(SSweather, src) //it counts as weather right
time_til_cycle = nighttime_duration
while(!cancel_me)
time_til_cycle = nightime_duration
// Part 1: Night (all is well)
while(time_til_cycle > TIME_BLOODSUCKER_DAY_WARN)
sleep(10)
if(cancel_me)
return
//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!
// 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)
/obj/effect/sunlight/process()
// Update all Bloodsucker sunlight huds
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.update_sunlight(max(0, time_til_cycle), amDay) // This pings all HUDs
time_til_cycle--
if(amDay)
if(time_til_cycle > 0 && time_til_cycle % 4 == 0)
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)
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>",\
"<span class = 'announce'>The solar flare has ended, and the daylight danger has passed...for now.</span>")
amDay = FALSE
day_end() // Remove VANISHING ACT power from all vamps who have it! Clear Warnings (sunlight, locker protection)
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
issued_XP = FALSE
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.update_sunlight(max(0, time_til_cycle), amDay) // This pings all HUDs
sleep(10)
time_til_cycle --
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)
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 = "")
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
@@ -162,32 +143,6 @@
M.current.updatehealth()
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()
// It's late...! Give the "Vanishing Act" gohome power to bloodsuckers.
for(var/datum/mind/M in SSticker.mode.bloodsuckers)
+1 -1
View File
@@ -1626,7 +1626,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
for(var/modified_limb in modified_limbs)
if(modified_limbs[modified_limb][1] == LOADOUT_LIMB_PROSTHETIC && modified_limb != limb_type)
number_of_prosthetics += 1
if(number_of_prosthetics > MAXIMUM_LOADOUT_PROSTHETICS)
if(number_of_prosthetics == MAXIMUM_LOADOUT_PROSTHETICS)
to_chat(user, "<span class='danger'>You can only have up to two prosthetic limbs!</span>")
else
//save the actual prosthetic data
+67
View 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 -1
View File
@@ -4,7 +4,7 @@
department_head = list("Chief Medical Officer")
department_flag = MEDSCI
faction = "Station"
total_positions = 3
total_positions = 2
spawn_positions = 2
supervisors = "the chief medical officer"
selection_color = "#74b5e0"
+2 -2
View File
@@ -47,7 +47,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
return ..()
/obj/machinery/ore_silo/proc/remote_attackby(obj/machinery/M, mob/user, obj/item/stack/I)
/obj/machinery/ore_silo/proc/remote_attackby(obj/machinery/M, mob/user, obj/item/stack/I, remote = null)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
// stolen from /datum/component/material_container/proc/OnAttackBy
if(user.a_intent != INTENT_HELP)
@@ -63,7 +63,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
return
// assumes unlimited space...
var/amount = I.amount
materials.user_insert(I, user)
materials.user_insert(I, user, remote)
silo_log(M, "deposited", amount, "sheets", item_mats)
return TRUE
+3 -1
View File
@@ -334,7 +334,9 @@
I.moveToNullspace()
else
I.forceMove(newloc)
I.dropped(src, silent)
on_item_dropped(I)
if(I.dropped(src) == ITEM_RELOCATED_BY_DROPPED)
return FALSE
return TRUE
//This is a SAFE proc. Use this instead of equip_to_slot()!
+23 -37
View File
@@ -1,5 +1,4 @@
#define SOLAR_GEN_RATE 1500
#define OCCLUSION_DISTANCE 20
/obj/machinery/power/solar
name = "solar panel"
@@ -14,8 +13,8 @@
integrity_failure = 0.33
var/id
var/obscured = FALSE
var/sunfrac = 0 //[0-1] measure of obscuration -- multipllier against power generation
var/list/obscured = list()
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_target = 0 //same but what way we're going to face next time we turn
var/obj/machinery/power/solar_control/control
@@ -133,40 +132,28 @@
///trace towards sun to see if we're in shadow
/obj/machinery/power/solar/proc/occlusion_setup()
obscured = TRUE
var/distance = OCCLUSION_DISTANCE
var/target_x = round(sin(SSsun.azimuth), 0.01)
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
obscured = list()
for(var/S in SSsun.suns)
if(check_obscured(S))
obscured |= S
///calculates the fraction of the sunlight that the panel receives
/obj/machinery/power/solar/proc/update_solar_exposure()
needs_to_update_solar_exposure = FALSE
sunfrac = 0
if(obscured)
return 0
var/sun_azimuth = SSsun.azimuth
if(azimuth_current == sun_azimuth) //just a quick optimization for the most frequent case
. = 1
else
//dot product of sun and panel -- Lambert's Cosine Law
. = cos(azimuth_current - sun_azimuth)
. = clamp(round(., 0.01), 0, 1)
sunfrac = .
total_flux = 0
for(var/S in SSsun.suns)
if(S in obscured)
continue
var/datum/sun/sun = S
var/sun_azimuth = sun.azimuth
var/cur_pow = 0
if(azimuth_current == sun_azimuth) //just a quick optimization for the most frequent case
cur_pow = sun.power_mod
else
//dot product of sun and panel -- Lambert's Cosine Law
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()
if(stat & BROKEN)
@@ -177,10 +164,10 @@
update_turn()
if(needs_to_update_solar_exposure)
update_solar_exposure()
if(sunfrac <= 0)
if(total_flux <= 0)
return
var/sgen = SOLAR_GEN_RATE * sunfrac * efficiency
var/sgen = SOLAR_GEN_RATE * total_flux * efficiency
add_avail(sgen)
if(control)
control.gen += sgen
@@ -385,7 +372,7 @@
track = mode
if(mode == SOLAR_TRACK_AUTO)
if(connected_tracker)
connected_tracker.sun_update(SSsun, SSsun.azimuth)
connected_tracker.sun_update(SSsun, SSsun.primary_sun, SSsun.suns)
else
track = SOLAR_TRACK_OFF
return TRUE
@@ -483,4 +470,3 @@ Congratulations, you should have a working solar array. If you are having troubl
"}
#undef SOLAR_GEN_RATE
#undef OCCLUSION_DISTANCE
+3 -3
View File
@@ -41,10 +41,10 @@
control = null
///Tell the controller to turn the solar panels
/obj/machinery/power/tracker/proc/sun_update(datum/source, azimuth)
setDir(angle2dir(azimuth))
/obj/machinery/power/tracker/proc/sun_update(datum/source, datum/sun/primary_sun, list/datum/sun/suns)
setDir(angle2dir(primary_sun.azimuth))
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)
if(!S)
@@ -88,9 +88,9 @@
mix_message = "The mixture boils off a yellow, smelly vapor..."//Sulfur burns off, leaving the camphor
/datum/chemical_reaction/anaphroplus
name = "pentacamphor"
name = "hexacamphor"
id = /datum/reagent/drug/anaphrodisiacplus
results = list(/datum/reagent/drug/anaphrodisiacplus = 1)
required_reagents = list(/datum/reagent/drug/aphrodisiac = 5, /datum/reagent/acetone = 1)
required_temp = 300
required_reagents = list(/datum/reagent/drug/anaphrodisiac = 6, /datum/reagent/acetone = 1)
required_temp = 400
mix_message = "The mixture thickens and heats up slighty..."
@@ -30,7 +30,7 @@
stored_research = new
host_research = SSresearch.science_tech
update_research()
materials = AddComponent(/datum/component/remote_materials, "lathe", mapload)
materials = AddComponent(/datum/component/remote_materials, "lathe", mapload, _after_insert=CALLBACK(src, .proc/AfterMaterialInsert))
RefreshParts()
/obj/machinery/rnd/production/Destroy()
@@ -22,3 +22,6 @@
/obj/machinery/rnd/production/circuit_imprinter/disconnect_console()
linked_console.linked_imprinter = null
..()
/obj/machinery/rnd/production/circuit_imprinter/AfterMaterialInsert() //doesnt use have an animation like lathes do
return
+6 -6
View File
@@ -94,13 +94,13 @@
..()
/obj/machinery/rnd/proc/AfterMaterialInsert(item_inserted, id_inserted, amount_inserted)
var/stack_name
var/mat_name
if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal))
stack_name = "bluespace"
mat_name = "bluespace"
use_power(MINERAL_MATERIAL_AMOUNT / 10)
else
var/obj/item/stack/S = item_inserted
stack_name = S.name
var/datum/material/M = id_inserted
mat_name = M.name
use_power(min(1000, (amount_inserted / 100)))
add_overlay("protolathe_[stack_name]")
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[stack_name]"), 10)
add_overlay("protolathe_[mat_name]")
addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[mat_name]"), 10)