mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-01-05 23:13:06 +00:00
works on planet stuff
This commit is contained in:
12
code/controllers/Processes/planet.dm
Normal file
12
code/controllers/Processes/planet.dm
Normal file
@@ -0,0 +1,12 @@
|
||||
/datum/controller/process/planet
|
||||
var/list/planets = list()
|
||||
|
||||
/datum/controller/process/planet/setup()
|
||||
name = "planet"
|
||||
schedule_interval = 600 // every minute
|
||||
planet_sif = new()
|
||||
planets.Add(planet_sif)
|
||||
|
||||
/datum/controller/process/planet/doWork()
|
||||
for(var/datum/planet/P in planets)
|
||||
P.process(schedule_interval / 10)
|
||||
@@ -347,7 +347,7 @@
|
||||
put_mob(usr)
|
||||
return
|
||||
|
||||
/atom/proc/return_air_for_internal_lifeform()
|
||||
/atom/proc/return_air_for_internal_lifeform(var/mob/living/lifeform)
|
||||
return return_air()
|
||||
|
||||
/obj/machinery/atmospherics/unary/cryo_cell/return_air_for_internal_lifeform()
|
||||
|
||||
@@ -32,6 +32,19 @@
|
||||
..()
|
||||
icon_state = "tree_[rand(1, 6)]"
|
||||
|
||||
/obj/structure/flora/tree/sif
|
||||
name = "glowing tree"
|
||||
desc = "It's a tree, except this one seems quite alien. It glows a deep blue."
|
||||
icon = 'icons/obj/flora/deadtrees.dmi'
|
||||
icon_state = "tree_sif"
|
||||
|
||||
/obj/structure/flora/tree/sif/New()
|
||||
update_icon()
|
||||
|
||||
/obj/structure/flora/tree/sif/update_icon()
|
||||
set_light(5, 1, "#33ccff")
|
||||
overlays.Cut()
|
||||
overlays.Add(image(icon = 'icons/obj/flora/deadtrees.dmi', icon_state = "[icon_state]_glow", layer = LIGHTING_LAYER + 0.1))
|
||||
|
||||
//grass
|
||||
/obj/structure/flora/grass
|
||||
|
||||
239
code/game/turfs/simulated/floor_outdoors.dm
Normal file
239
code/game/turfs/simulated/floor_outdoors.dm
Normal file
@@ -0,0 +1,239 @@
|
||||
/client/verb/test_outdoors_lights()
|
||||
var/amount_range = input("Range", "Light Test", 2) as num
|
||||
var/amount_brightness = input("Brightness", "Light Test", 1) as num
|
||||
var/new_color = input("Color", "Light Test", "#FFFFFF") as color
|
||||
|
||||
for(var/turf/simulated/floor/outdoors/T in outdoor_turfs)
|
||||
T.set_light(amount_range, amount_brightness, new_color)
|
||||
world << "Finished."
|
||||
|
||||
/*
|
||||
/client/verb/test_outdoor_time()
|
||||
var/new_time = input("New time, in hours", "Day/Night cycle", 1) as num
|
||||
var/datum/time/sif/time = new()
|
||||
time = time.add_hours(new_time)
|
||||
world << time.show_time("hh:mm:ss")
|
||||
|
||||
var/length_of_day = time.seconds_in_day / 10 / 60 / 60 // 32
|
||||
var/noon = length_of_day / 2
|
||||
var/distance_from_noon = abs(text2num(time.show_time("hh")) - noon)
|
||||
var/lerp_weight = distance_from_noon / noon
|
||||
|
||||
var/noon_range = 5
|
||||
var/midnight_range = 3
|
||||
|
||||
var/noon_brightness = 1
|
||||
var/midnight_brightness = 0.06
|
||||
|
||||
// var/amount_range = Interpolate(noon_range, midnight_range, weight = lerp_weight)
|
||||
var/amount_range = 2
|
||||
var/amount_brightness = Interpolate(noon_brightness, midnight_brightness, weight = lerp_weight) ** 3
|
||||
|
||||
world << "Changing time. [outdoor_turfs.len] turfs need to be updated. Expected ETA: [outdoor_turfs.len * 0.0033] seconds."
|
||||
world << "Setting outdoor tiles to set_light([amount_range], [amount_brightness])."
|
||||
var/i = 0
|
||||
for(var/turf/simulated/floor/outdoors/T in outdoor_turfs)
|
||||
T.set_light(amount_range, amount_brightness, "#FFFFFF")
|
||||
i++
|
||||
if(i % 30 == 0)
|
||||
sleep(1)
|
||||
world << "Finished."
|
||||
*/
|
||||
|
||||
/client/verb/test_outdoor_timelapse()
|
||||
var/i = 32
|
||||
var/j = 0
|
||||
while(i)
|
||||
test_outdoor_time(j)
|
||||
j++
|
||||
i--
|
||||
sleep(5 SECONDS)
|
||||
|
||||
/client/verb/test_outdoor_snow()
|
||||
for(var/turf/simulated/floor/T in outdoor_turfs)
|
||||
T.overlays |= image(icon = 'icons/turf/outdoors.dmi', icon_state = "snowfall_med", layer = LIGHTING_LAYER - 1)
|
||||
|
||||
|
||||
/client/verb/test_outdoor_time(new_time as num)
|
||||
//var/new_time = input("New time, in hours", "Day/Night cycle", 1) as num
|
||||
var/datum/time/sif/time = new()
|
||||
time = time.add_hours(new_time)
|
||||
world << time.show_time("hh:mm:ss")
|
||||
|
||||
var/length_of_day = time.seconds_in_day / 10 / 60 / 60 // 32
|
||||
var/noon = length_of_day / 2
|
||||
var/distance_from_noon = abs(text2num(time.show_time("hh")) - noon)
|
||||
var/sun_position = distance_from_noon / noon
|
||||
sun_position = abs(sun_position - 1)
|
||||
|
||||
var/low_brightness = null
|
||||
var/high_brightness = null
|
||||
|
||||
var/low_color = null
|
||||
var/high_color = null
|
||||
var/min = 0
|
||||
switch(sun_position)
|
||||
if(0 to 0.40) // Night
|
||||
low_brightness = 0.2
|
||||
low_color = "#000066"
|
||||
|
||||
high_brightness = 0.5
|
||||
high_color = "#66004D"
|
||||
world << "Night."
|
||||
min = 0
|
||||
|
||||
if(0.40 to 0.50) // Twilight
|
||||
low_brightness = 0.6
|
||||
low_color = "#66004D"
|
||||
|
||||
high_brightness = 0.8
|
||||
high_color = "#CC3300"
|
||||
world << "Twilight."
|
||||
min = 0.40
|
||||
|
||||
if(0.50 to 0.70) // Sunrise/set
|
||||
low_brightness = 0.8
|
||||
low_color = "#CC3300"
|
||||
|
||||
high_brightness = 0.9
|
||||
high_color = "#FF9933"
|
||||
world << "Sunrise/set."
|
||||
min = 0.50
|
||||
|
||||
if(0.70 to 1.00) // Noon
|
||||
low_brightness = 0.9
|
||||
low_color = "#DDDDDD"
|
||||
|
||||
high_brightness = 1.0
|
||||
high_color = "#FFFFFF"
|
||||
world << "Noon."
|
||||
min = 0.70
|
||||
|
||||
//var/lerp_weight = (sun_position * 4 % 1) / (0.25 / 4) // This weirdness is needed because otherwise the compiler divides by zero.
|
||||
var/lerp_weight = (abs(min - sun_position)) * 4
|
||||
world << "lerp_weight is [lerp_weight], sun_position is [sun_position]."
|
||||
var/new_brightness = Interpolate(low_brightness, high_brightness, weight = lerp_weight)
|
||||
|
||||
var/list/low_color_list = hex2rgb(low_color)
|
||||
var/low_r = low_color_list[1]
|
||||
var/low_g = low_color_list[2]
|
||||
var/low_b = low_color_list[3]
|
||||
|
||||
var/list/high_color_list = hex2rgb(high_color)
|
||||
var/high_r = high_color_list[1]
|
||||
var/high_g = high_color_list[2]
|
||||
var/high_b = high_color_list[3]
|
||||
|
||||
var/new_r = Interpolate(low_r, high_r, weight = lerp_weight)
|
||||
var/new_g = Interpolate(low_g, high_g, weight = lerp_weight)
|
||||
var/new_b = Interpolate(low_b, high_b, weight = lerp_weight)
|
||||
|
||||
var/new_color = rgb(new_r, new_g, new_b)
|
||||
|
||||
world << "Changing time. [outdoor_turfs.len] turfs need to be updated. Expected ETA: [outdoor_turfs.len * 0.0033] seconds."
|
||||
world << "Setting outdoor tiles to set_light(2, [new_brightness], [new_color])."
|
||||
var/i = 0
|
||||
for(var/turf/simulated/floor/T in outdoor_turfs)
|
||||
T.set_light(2, new_brightness, new_color)
|
||||
i++
|
||||
if(i % 30 == 0)
|
||||
sleep(1)
|
||||
world << "Finished."
|
||||
|
||||
|
||||
/turf/simulated/floor/proc/update_icon_edge()
|
||||
if(edge_blending_priority)
|
||||
// world << "edge_blending_priority detected"
|
||||
for(var/checkdir in cardinal)
|
||||
// world << "Checking [checkdir] dir."
|
||||
var/turf/simulated/T = get_step(src, checkdir)
|
||||
// world << "Found [T] ([T.x], [T.y], [T.z])."
|
||||
if(istype(T) && T.edge_blending_priority && edge_blending_priority < T.edge_blending_priority && icon_state != T.icon_state)
|
||||
// world << "edge_blending_priority of [T] was higher than [src]."
|
||||
var/cache_key = "[T.get_edge_icon_state()]-[checkdir]"
|
||||
// world << "cache_key is [cache_key]"
|
||||
if(!turf_edge_cache[cache_key])
|
||||
turf_edge_cache[cache_key] = image(icon = 'icons/turf/outdoors_edge.dmi', icon_state = "[T.get_edge_icon_state()]-edge", dir = checkdir)
|
||||
// world << "Made new entry to cache."
|
||||
overlays += turf_edge_cache[cache_key]
|
||||
// world << "Applied overlay."
|
||||
|
||||
/turf/simulated/proc/get_edge_icon_state()
|
||||
return icon_state
|
||||
|
||||
/turf/simulated/floor/outdoors/update_icon()
|
||||
overlays.Cut()
|
||||
update_icon_edge()
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/outdoors/mud
|
||||
name = "grass"
|
||||
icon_state = "mud_dark"
|
||||
edge_blending_priority = 2
|
||||
|
||||
|
||||
/turf/simulated/floor/outdoors/rocks
|
||||
name = "rocks"
|
||||
desc = "Hard as a rock."
|
||||
icon_state = "rockwall"
|
||||
edge_blending_priority = 1
|
||||
|
||||
var/list/grass_types = list(
|
||||
/obj/structure/flora/ausbushes/sparsegrass,
|
||||
/obj/structure/flora/ausbushes/fullgrass
|
||||
)
|
||||
|
||||
/turf/simulated/floor/outdoors/grass
|
||||
name = "grass"
|
||||
icon_state = "grass"
|
||||
edge_blending_priority = 3
|
||||
demote_turf = /turf/simulated/floor/outdoors
|
||||
var/grass_chance = 20
|
||||
|
||||
/turf/simulated/floor/outdoors/grass/sif
|
||||
name = "growth"
|
||||
icon_state = "grass_sif"
|
||||
edge_blending_priority = 3
|
||||
grass_chance = 0
|
||||
|
||||
|
||||
/turf/simulated/floor/outdoors/grass/sif/forest
|
||||
name = "thick growth"
|
||||
icon_state = "grass_sif_dark"
|
||||
edge_blending_priority = 4
|
||||
|
||||
/turf/simulated/floor/outdoors/grass/New()
|
||||
if(prob(50))
|
||||
icon_state += "2"
|
||||
//edge_blending_priority++
|
||||
|
||||
if(grass_chance && prob(grass_chance))
|
||||
var/grass_type = pick(grass_types)
|
||||
new grass_type(src)
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/outdoors/grass/forest
|
||||
name = "thick grass"
|
||||
icon_state = "grass-dark"
|
||||
grass_chance = 80
|
||||
//tree_prob = 20
|
||||
edge_blending_priority = 4
|
||||
|
||||
/turf/simulated/floor/outdoors/snow
|
||||
name = "snow"
|
||||
icon_state = "snow"
|
||||
edge_blending_priority = 5
|
||||
movement_cost = 2
|
||||
var/list/crossed_dirs = list()
|
||||
|
||||
/turf/simulated/floor/outdoors/snow/Entered(atom/A)
|
||||
if(isliving(A))
|
||||
var/mdir = "[A.dir]"
|
||||
crossed_dirs[mdir] = 1
|
||||
update_icon()
|
||||
. = ..()
|
||||
|
||||
/turf/simulated/floor/outdoors/snow/update_icon()
|
||||
overlays.Cut()
|
||||
for(var/d in crossed_dirs)
|
||||
overlays += image(icon = 'icons/turf/outdoors.dmi', icon_state = "snow_footprints", dir = text2num(d))
|
||||
46
code/game/turfs/simulated/outdoors/outdoors.dm
Normal file
46
code/game/turfs/simulated/outdoors/outdoors.dm
Normal file
@@ -0,0 +1,46 @@
|
||||
var/list/turf_edge_cache = list()
|
||||
var/list/outdoor_turfs = list()
|
||||
|
||||
/turf/
|
||||
// If greater than 0, this turf will apply edge overlays on top of other turfs cardinally adjacent to it, if those adjacent turfs are of a different icon_state,
|
||||
// and if those adjacent turfs have a lower edge_blending_priority.
|
||||
// TODO: Place on base /turf/ ?
|
||||
var/edge_blending_priority = 0
|
||||
var/outdoors = FALSE
|
||||
|
||||
/turf/simulated/floor/outdoors
|
||||
name = "dirt"
|
||||
desc = "Quite dirty."
|
||||
icon = 'icons/turf/outdoors.dmi'
|
||||
icon_state = "dirt-dark"
|
||||
edge_blending_priority = 1
|
||||
outdoors = TRUE
|
||||
var/demote_turf = /turf/simulated/floor/outdoors // If something destructive happens, the turf gets replaced by this one.
|
||||
|
||||
/turf/simulated/floor/outdoors/initialize()
|
||||
update_icon()
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/New()
|
||||
if(outdoors)
|
||||
outdoor_turfs.Add(src)
|
||||
//set_light(2, 0.06, "#FFFFFF")
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/Destroy()
|
||||
if(outdoors)
|
||||
outdoor_turfs.Remove(src)
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/outdoors/ex_act(severity)
|
||||
switch(severity)
|
||||
if(2)
|
||||
if(prob(33))
|
||||
return
|
||||
if(3)
|
||||
if(prob(66))
|
||||
return
|
||||
if(demote_turf && src.type != demote_turf)
|
||||
ChangeTurf(demote_turf)
|
||||
else
|
||||
ChangeTurf(get_base_turf_by_area(src))
|
||||
86
code/game/turfs/simulated/water.dm
Normal file
86
code/game/turfs/simulated/water.dm
Normal file
@@ -0,0 +1,86 @@
|
||||
// This doesn't inherit from /outdoors/ so that the pool can use it as well.
|
||||
/turf/simulated/floor/water
|
||||
name = "shallow water"
|
||||
desc = "A body of water. It seems shallow enough to walk through, if needed."
|
||||
icon = 'icons/turf/outdoors.dmi'
|
||||
icon_state = "water_shallow"
|
||||
var/under_state = "rockwall"
|
||||
edge_blending_priority = -1
|
||||
movement_cost = 4
|
||||
outdoors = TRUE
|
||||
var/movement_message = "You are slowed considerably from the water as you move across it." // Displayed to mobs crossing from one water tile to another.
|
||||
var/depth = 1 // Higher numbers indicates deeper water.
|
||||
|
||||
/turf/simulated/floor/water/New()
|
||||
update_icon()
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/water/update_icon()
|
||||
// icon_state = "rockwall"
|
||||
..() // To get the edges. This also gets rid of other overlays so it needs to go first.
|
||||
// var/image/water_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = "water_shallow", layer = FLOAT_LAYER - 0.1) // Layer is slightly lower so that the adjacent edges go over the water.
|
||||
var/image/floorbed_sprite = image(icon = 'icons/turf/outdoors.dmi', icon_state = under_state)
|
||||
//water_sprite.alpha = 150
|
||||
underlays.Add(floorbed_sprite)
|
||||
update_icon_edge()
|
||||
|
||||
/turf/simulated/floor/water/get_edge_icon_state()
|
||||
return "water_shallow"
|
||||
|
||||
/turf/simulated/floor/water/return_air_for_internal_lifeform(var/mob/living/L)
|
||||
if(L && L.lying)
|
||||
if(L.can_breathe_water())
|
||||
var/datum/gas_mixture/water_breath = new()
|
||||
var/amount = (ONE_ATMOSPHERE * BREATH_VOLUME) / (R_IDEAL_GAS_EQUATION * T20C)
|
||||
water_breath.adjust_gas("oxygen", amount) // Assuming water breathes just extract the oxygen directly from the water.
|
||||
return water_breath
|
||||
else
|
||||
return null // Lying down means they're submerged, which means no air.
|
||||
return return_air() // Otherwise their head is above the water, so get the air from the atmosphere instead.
|
||||
|
||||
/turf/simulated/floor/water/Entered(atom/movable/AM, atom/oldloc)
|
||||
if(istype(AM, /mob/living))
|
||||
var/mob/living/L = AM
|
||||
L.adjust_fire_stacks(-50)
|
||||
L.update_water()
|
||||
if(!istype(oldloc, /turf/simulated/floor/water))
|
||||
to_chat(L, "<span class='warning'>You get drenched in water from entering \the [src]!</span>")
|
||||
else
|
||||
to_chat(L, "<span class='warning'>[movement_message]</span>")
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/water/Exited(atom/movable/AM, atom/newloc)
|
||||
if(istype(AM, /mob/living))
|
||||
var/mob/living/L = AM
|
||||
L.update_water()
|
||||
if(!istype(newloc, /turf/simulated/floor/water))
|
||||
to_chat(L, "<span class='warning'>You climb out of \the [src].</span>")
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/water/deep
|
||||
name = "deep water"
|
||||
desc = "A body of water. It seems quite deep."
|
||||
// icon_state = "seadeep" // So it shows up in the map editor as water.
|
||||
under_state = "abyss"
|
||||
edge_blending_priority = -2
|
||||
movement_cost = 8
|
||||
movement_message = "You swim forwards."
|
||||
depth = 2
|
||||
/*
|
||||
/turf/simulated/floor/water/deep/update_icon()
|
||||
..() // To get the edges. This also gets rid of other overlays so it needs to go first.
|
||||
icon_state = "abyss"
|
||||
*/
|
||||
/mob/living/proc/can_breathe_water()
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/can_breathe_water()
|
||||
if(species && species.name == "Skrell")
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/proc/check_submerged()
|
||||
var/turf/simulated/floor/water/T = loc
|
||||
if(istype(T))
|
||||
return T.depth
|
||||
return 0
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
var/list/decals
|
||||
|
||||
var/movement_cost = 0 // How much the turf slows down movement, if any.
|
||||
|
||||
/turf/New()
|
||||
..()
|
||||
for(var/atom/movable/AM as mob|obj in src)
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
S.update_starlight()
|
||||
|
||||
W.levelupdate()
|
||||
W.update_icon(1)
|
||||
. = W
|
||||
|
||||
else
|
||||
@@ -74,6 +75,7 @@
|
||||
S.update_starlight()
|
||||
|
||||
W.levelupdate()
|
||||
W.update_icon(1)
|
||||
. = W
|
||||
|
||||
lighting_overlay = old_lighting_overlay
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// This is a wall you surround the area of your "planet" with, that makes the atmosphere inside stay within bounds, even if canisters
|
||||
// are opened or other strange things occur.
|
||||
var/list/planetary_walls = list()
|
||||
|
||||
/turf/unsimulated/wall/planetary
|
||||
name = "railroading"
|
||||
desc = "Choo choo!"
|
||||
@@ -17,6 +19,14 @@
|
||||
phoron = 0
|
||||
temperature = T20C
|
||||
|
||||
/turf/unsimulated/wall/planetary/New()
|
||||
..()
|
||||
planetary_walls.Add(src)
|
||||
|
||||
/turf/unsimulated/wall/planetary/Destroy()
|
||||
planetary_walls.Remove(src)
|
||||
..()
|
||||
|
||||
// Normal station/earth air.
|
||||
/turf/unsimulated/wall/planetary/normal
|
||||
oxygen = MOLES_O2STANDARD
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
var/datum/gas_mixture/environment
|
||||
if(loc)
|
||||
environment = loc.return_air_for_internal_lifeform()
|
||||
environment = loc.return_air_for_internal_lifeform(src)
|
||||
|
||||
if(environment)
|
||||
breath = environment.remove_volume(volume_needed)
|
||||
|
||||
@@ -79,6 +79,10 @@
|
||||
var/obj/item/pulled = pulling
|
||||
tally += max(pulled.slowdown, 0)
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && T.movement_cost)
|
||||
tally += T.movement_cost
|
||||
|
||||
return (tally+config.human_delay)
|
||||
|
||||
/mob/living/carbon/human/Process_Spacemove(var/check_drift = 0)
|
||||
|
||||
@@ -132,8 +132,9 @@ Please contact me on #coderbus IRC. ~Carn x
|
||||
#define L_HAND_LAYER 24
|
||||
#define R_HAND_LAYER 25
|
||||
#define FIRE_LAYER 26 //If you're on fire
|
||||
#define WATER_LAYER 27 //If you're submerged in water.
|
||||
#define TARGETED_LAYER 27 //BS12: Layer for the target overlay from weapon targeting system
|
||||
#define TOTAL_LAYERS 27
|
||||
#define TOTAL_LAYERS 28
|
||||
//////////////////////////////////
|
||||
|
||||
/mob/living/carbon/human
|
||||
@@ -461,6 +462,7 @@ var/global/list/damage_icon_parts = list()
|
||||
update_inv_legcuffed(0)
|
||||
update_inv_pockets(0)
|
||||
update_fire(0)
|
||||
update_water(0)
|
||||
update_surgery(0)
|
||||
UpdateDamageIcon()
|
||||
update_icons()
|
||||
@@ -1116,6 +1118,18 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_water(var/update_icons=1)
|
||||
overlays_standing[WATER_LAYER] = null
|
||||
var/depth = check_submerged()
|
||||
if(depth)
|
||||
if(!lying)
|
||||
overlays_standing[WATER_LAYER] = image("icon" = 'icons/mob/submerged.dmi', "icon_state" = "human_swimming_[depth]")
|
||||
else
|
||||
// overlays_standing[WATER_LAYER] = image("icon" = 'icons/mob/submerged.dmi', "icon_state" = "mob_submerged")
|
||||
|
||||
if(update_icons)
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/human/proc/update_surgery(var/update_icons=1)
|
||||
overlays_standing[SURGERY_LEVEL] = null
|
||||
var/image/total = new
|
||||
@@ -1151,4 +1165,5 @@ var/global/list/damage_icon_parts = list()
|
||||
#undef R_HAND_LAYER
|
||||
#undef TARGETED_LAYER
|
||||
#undef FIRE_LAYER
|
||||
#undef WATER_LAYER
|
||||
#undef TOTAL_LAYERS
|
||||
|
||||
@@ -774,6 +774,7 @@ default behaviour is:
|
||||
density = 0
|
||||
if(l_hand) unEquip(l_hand)
|
||||
if(r_hand) unEquip(r_hand)
|
||||
update_water() // Submerges the mob.
|
||||
else
|
||||
density = initial(density)
|
||||
|
||||
@@ -792,3 +793,6 @@ default behaviour is:
|
||||
update_icons()
|
||||
return canmove
|
||||
|
||||
/mob/living/proc/update_water() // Involves overlays for humans. Maybe we'll get submerged sprites for borgs in the future?
|
||||
return
|
||||
|
||||
|
||||
381
code/modules/mob/living/lobby/lobby.dm
Normal file
381
code/modules/mob/living/lobby/lobby.dm
Normal file
@@ -0,0 +1,381 @@
|
||||
//This is a mob that's used for the new lobby. For the old lobby mob, check code/modules/mob/new_player.dm
|
||||
/mob/living/lobby
|
||||
name = "You"
|
||||
desc = "Who else would it be?"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "ghost"
|
||||
var/ready = 0
|
||||
var/spawning = 0//Referenced when you want to delete the new_player later on in the code.
|
||||
var/totalPlayers = 0 //Player counts for the Lobby tab
|
||||
var/totalPlayersReady = 0
|
||||
var/isolated = 1 //Used to check if we should maintain the illusion of being alone.
|
||||
var/do_adjacency_check = 1
|
||||
universal_speak = 1
|
||||
var/list/visisble_players = list()
|
||||
var/list/furnature = list()
|
||||
var/list/shown_furnature = list()
|
||||
|
||||
// invisibility = 101
|
||||
|
||||
density = 0
|
||||
|
||||
|
||||
/mob/living/lobby/New()
|
||||
mob_list += src
|
||||
go_to_lobby()
|
||||
|
||||
//Gratutious copypasta
|
||||
/mob/living/lobby/Stat()
|
||||
..()
|
||||
|
||||
if(statpanel("Lobby") && ticker)
|
||||
if(ticker.hide_mode)
|
||||
stat("Game Mode:", "Secret")
|
||||
else
|
||||
if(ticker.hide_mode == 0)
|
||||
stat("Game Mode:", "[master_mode]") // Old setting for showing the game mode
|
||||
|
||||
if(ticker.current_state == GAME_STATE_PREGAME)
|
||||
stat("Time To Start:", "[ticker.pregame_timeleft][round_progressing ? "" : " (DELAYED)"]")
|
||||
stat("Players: [totalPlayers]", "Players Ready: [totalPlayersReady]")
|
||||
totalPlayers = 0
|
||||
totalPlayersReady = 0
|
||||
for(var/mob/new_player/player in player_list)
|
||||
stat("[player.key]", (player.ready) ? ("(Playing)"):(null))
|
||||
totalPlayers++
|
||||
if(player.ready)
|
||||
totalPlayersReady++
|
||||
for(var/mob/living/lobby/player in player_list)
|
||||
stat("[player.key]", (player.ready) ? ("(Playing)"):(null))
|
||||
totalPlayers++
|
||||
if(player.ready)
|
||||
totalPlayersReady++
|
||||
|
||||
/mob/living/lobby/proc/update_details()
|
||||
name = client.prefs.real_name
|
||||
update_icon()
|
||||
|
||||
|
||||
/mob/living/lobby/update_icon()
|
||||
..()
|
||||
client.prefs.update_preview_icon()
|
||||
icon = client.prefs.preview_icon
|
||||
|
||||
|
||||
/mob/living/lobby/proc/go_to_lobby()
|
||||
var/obj/O = locate("landmark*Lobby-Start")
|
||||
if(istype(O))
|
||||
loc = O.loc
|
||||
else
|
||||
src << "<span class='danger'>Unfortunately, the game wasn't able to find you a suitable location for your lobby mob to spawn. \
|
||||
Please report this as a bug.</span>"
|
||||
|
||||
/*
|
||||
/mob/living/lobby/proc/IsJobAvailable(rank)
|
||||
var/datum/job/job = job_master.GetJob(rank)
|
||||
if(!job)
|
||||
return 0
|
||||
if(!job.is_position_available())
|
||||
return 0
|
||||
if(jobban_isbanned(src,rank))
|
||||
return 0
|
||||
if(!job.player_old_enough(src.client))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/lobby/proc/close_spawn_windows()
|
||||
src << browse(null, "window=latechoices") //closes late choices window
|
||||
src << browse(null, "window=playersetup") //closes the player setup window
|
||||
|
||||
/mob/living/lobby/proc/LateChoices()
|
||||
var/name = client.prefs.be_random_name ? "friend" : client.prefs.real_name
|
||||
|
||||
var/dat = "<html><body><center>"
|
||||
dat += "<b>Welcome, [name].<br></b>"
|
||||
dat += "Round Duration: [round_duration()]<br>"
|
||||
|
||||
if(emergency_shuttle) //In case Nanotrasen decides reposess CentComm's shuttles.
|
||||
if(emergency_shuttle.going_to_centcom()) //Shuttle is going to centcomm, not recalled
|
||||
dat += "<font color='red'><b>The station has been evacuated.</b></font><br>"
|
||||
if(emergency_shuttle.online())
|
||||
if (emergency_shuttle.evac) // Emergency shuttle is past the point of no recall
|
||||
dat += "<font color='red'>The station is currently undergoing evacuation procedures.</font><br>"
|
||||
else // Crew transfer initiated
|
||||
dat += "<font color='red'>The station is currently undergoing crew transfer procedures.</font><br>"
|
||||
|
||||
dat += "Choose from the following open positions:<br>"
|
||||
for(var/datum/job/job in job_master.occupations)
|
||||
if(job && IsJobAvailable(job.title))
|
||||
var/active = 0
|
||||
// Only players with the job assigned and AFK for less than 10 minutes count as active
|
||||
for(var/mob/M in player_list) if(M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 * 60 * 10)
|
||||
active++
|
||||
dat += "<a href='byond://?src=\ref[src];SelectedJob=[job.title]'>[job.title] ([job.current_positions]) (Active: [active])</a><br>"
|
||||
|
||||
dat += "</center>"
|
||||
src << browse(dat, "window=latechoices;size=300x640;can_close=1")
|
||||
|
||||
/mob/living/lobby/proc/AttemptLateSpawn(rank,var/spawning_at)
|
||||
world << "AttemptLateSpawn() was called."
|
||||
if (src != usr)
|
||||
return 0
|
||||
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
|
||||
usr << "\red The round is either not ready, or has already finished..."
|
||||
return 0
|
||||
if(!config.enter_allowed)
|
||||
usr << "<span class='notice'>There is an administrative lock on entering the game!</span>"
|
||||
return 0
|
||||
if(!IsJobAvailable(rank))
|
||||
src << alert("[rank] is not available. Please try another.")
|
||||
return 0
|
||||
|
||||
spawning = 1
|
||||
close_spawn_windows()
|
||||
|
||||
job_master.AssignRole(src, rank, 1)
|
||||
|
||||
var/mob/living/character = create_character() //creates the human and transfers vars and mind
|
||||
character = job_master.EquipRank(character, rank, 1) //equips the human
|
||||
UpdateFactionList(character)
|
||||
equip_custom_items(character)
|
||||
|
||||
// AIs don't need a spawnpoint, they must spawn at an empty core
|
||||
if(character.mind.assigned_role == "AI")
|
||||
|
||||
character = character.AIize(move=0) // AIize the character, but don't move them yet
|
||||
|
||||
// IsJobAvailable for AI checks that there is an empty core available in this list
|
||||
var/obj/structure/AIcore/deactivated/C = empty_playable_ai_cores[1]
|
||||
empty_playable_ai_cores -= C
|
||||
|
||||
character.loc = C.loc
|
||||
|
||||
// AnnounceCyborg(character, rank, "has been downloaded to the empty core in \the [character.loc.loc]")
|
||||
ticker.mode.latespawn(character)
|
||||
|
||||
qdel(C)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
//Find our spawning point.
|
||||
var/join_message = job_master.LateSpawn(character, rank)
|
||||
|
||||
character.lastarea = get_area(loc)
|
||||
// Moving wheelchair if they have one
|
||||
if(character.buckled && istype(character.buckled, /obj/structure/bed/chair/wheelchair))
|
||||
character.buckled.loc = character.loc
|
||||
character.buckled.set_dir(character.dir)
|
||||
|
||||
ticker.mode.latespawn(character)
|
||||
|
||||
if(character.mind.assigned_role != "Cyborg")
|
||||
data_core.manifest_inject(character)
|
||||
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
|
||||
|
||||
//Grab some data from the character prefs for use in random news procs.
|
||||
|
||||
AnnounceArrival(character, rank, join_message)
|
||||
// else
|
||||
// AnnounceCyborg(character, rank, join_message)
|
||||
|
||||
qdel(src)
|
||||
|
||||
/mob/living/lobby/proc/has_admin_rights()
|
||||
return check_rights(R_ADMIN, 0, src)
|
||||
|
||||
/mob/living/lobby/proc/is_species_whitelisted(datum/species/S)
|
||||
if(!S)
|
||||
return 1
|
||||
return is_alien_whitelisted(src, S.name) || !config.usealienwhitelist || !(S.spawn_flags & IS_WHITELISTED)
|
||||
|
||||
/mob/living/lobby/proc/create_character()
|
||||
spawning = 1
|
||||
close_spawn_windows()
|
||||
|
||||
var/mob/living/carbon/human/new_character
|
||||
|
||||
var/use_species_name
|
||||
var/datum/species/chosen_species
|
||||
if(client.prefs.species)
|
||||
chosen_species = all_species[client.prefs.species]
|
||||
use_species_name = chosen_species.get_station_variant() //Only used by pariahs atm.
|
||||
|
||||
if(chosen_species && use_species_name)
|
||||
// Have to recheck admin due to no usr at roundstart. Latejoins are fine though.
|
||||
if(is_species_whitelisted(chosen_species) || has_admin_rights())
|
||||
new_character = new(loc, use_species_name)
|
||||
|
||||
if(!new_character)
|
||||
new_character = new(loc)
|
||||
|
||||
new_character.lastarea = get_area(loc)
|
||||
|
||||
for(var/lang in client.prefs.alternate_languages)
|
||||
var/datum/language/chosen_language = all_languages[lang]
|
||||
if(chosen_language)
|
||||
if(!config.usealienwhitelist || !(chosen_language.flags & WHITELISTED) || is_alien_whitelisted(src, lang) || has_admin_rights() \
|
||||
|| (new_character.species && (chosen_language.name in new_character.species.secondary_langs)))
|
||||
new_character.add_language(lang)
|
||||
|
||||
if(ticker.random_players)
|
||||
new_character.gender = pick(MALE, FEMALE)
|
||||
client.prefs.real_name = random_name(new_character.gender)
|
||||
client.prefs.randomize_appearance_for(new_character)
|
||||
else
|
||||
client.prefs.copy_to(new_character)
|
||||
|
||||
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo
|
||||
|
||||
if(mind)
|
||||
mind.active = 0 //we wish to transfer the key manually
|
||||
mind.original = new_character
|
||||
mind.transfer_to(new_character) //won't transfer key since the mind is not active
|
||||
|
||||
new_character.name = real_name
|
||||
new_character.dna.ready_dna(new_character)
|
||||
new_character.dna.b_type = client.prefs.b_type
|
||||
new_character.sync_organ_dna()
|
||||
if(client.prefs.disabilities)
|
||||
// Set defer to 1 if you add more crap here so it only recalculates struc_enzymes once. - N3X
|
||||
new_character.dna.SetSEState(GLASSESBLOCK,1,0)
|
||||
new_character.disabilities |= NEARSIGHTED
|
||||
|
||||
// And uncomment this, too.
|
||||
//new_character.dna.UpdateSE()
|
||||
|
||||
// Do the initial caching of the player's body icons.
|
||||
new_character.force_update_limbs()
|
||||
new_character.update_eyes()
|
||||
new_character.regenerate_icons()
|
||||
|
||||
new_character.key = key //Manually transfer the key to log them in
|
||||
|
||||
return new_character
|
||||
|
||||
/mob/living/lobby/proc/late_join()
|
||||
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
|
||||
usr << "<span class='danger'>The round is either not ready, or has already finished...</span>"
|
||||
return
|
||||
|
||||
if(client.prefs.species != "Human" && !check_rights(R_ADMIN, 0))
|
||||
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
|
||||
src << alert("You are currently not whitelisted to play [client.prefs.species].")
|
||||
return 0
|
||||
|
||||
var/datum/species/S = all_species[client.prefs.species]
|
||||
if(!(S.spawn_flags & IS_WHITELISTED))
|
||||
src << alert("Your current species,[client.prefs.species], is not available for play on the station.")
|
||||
return 0
|
||||
|
||||
LateChoices()
|
||||
|
||||
/mob/living/lobby/verb/late_join_verb()
|
||||
set name = "Late join"
|
||||
set desc = "Late join manually."
|
||||
set category = "Lobby Verbs"
|
||||
late_join()
|
||||
|
||||
/mob/living/lobby/proc/become_observer()
|
||||
if(alert(src,"Are you sure you wish to observe? You will have to wait 30 minutes before being able to respawn!","Player Setup","Yes","No") == "Yes")
|
||||
if(!client)
|
||||
return 1
|
||||
var/mob/dead/observer/observer = new()
|
||||
|
||||
spawning = 1
|
||||
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo
|
||||
|
||||
|
||||
observer.started_as_observer = 1
|
||||
close_spawn_windows()
|
||||
var/obj/O = locate("landmark*Observer-Start")
|
||||
if(istype(O))
|
||||
src << "<span class='notice'>Now teleporting.</span>"
|
||||
observer.loc = O.loc
|
||||
else
|
||||
src << "<span class='danger'>Could not locate an observer spawn point. Use the Teleport verb to jump to the station map.</span>"
|
||||
observer.timeofdeath = world.time // Set the time of death so that the respawn timer works correctly.
|
||||
|
||||
announce_ghost_joinleave(src)
|
||||
client.prefs.update_preview_icon()
|
||||
observer.icon = client.prefs.preview_icon
|
||||
observer.alpha = 127
|
||||
|
||||
if(client.prefs.be_random_name)
|
||||
client.prefs.real_name = random_name(client.prefs.gender)
|
||||
observer.real_name = client.prefs.real_name
|
||||
observer.name = observer.real_name
|
||||
if(!client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
|
||||
observer.verbs -= /mob/dead/observer/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
|
||||
observer.key = key
|
||||
qdel(src)
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/lobby/verb/observe_verb()
|
||||
set name = "Observe"
|
||||
set desc = "Lets you observe the round. Remember, you won't be able to join the game for another 30 minutes!"
|
||||
set category = "Lobby Verbs"
|
||||
become_observer()
|
||||
|
||||
/mob/living/lobby/proc/ViewManifest()
|
||||
var/dat = "<html><body>"
|
||||
dat += "<h4>Northern Star Manifest</h4>"
|
||||
dat += data_core.get_manifest(OOC = 1)
|
||||
|
||||
src << browse(dat, "window=manifest;size=370x420;can_close=1")
|
||||
|
||||
/mob/living/lobby/verb/show_manifest()
|
||||
set name = "Show Manifest"
|
||||
set desc = "Views a copy of the Northern Star's manifest."
|
||||
set category = "Lobby Verbs"
|
||||
ViewManifest()
|
||||
|
||||
/mob/living/lobby/MayRespawn()
|
||||
return 1
|
||||
|
||||
/mob/living/lobby/verb/return_to_lobby()
|
||||
set name = "Return to Lobby"
|
||||
set desc = "For testing only!"
|
||||
set category = "Lobby Verbs"
|
||||
|
||||
var/obj/O = locate("landmark*Lobby-Start")
|
||||
if(istype(O))
|
||||
src << "<span class='notice'>Now teleporting.</span>"
|
||||
loc = O.loc
|
||||
|
||||
/mob/living/lobby/Topic(href, href_list[])
|
||||
if(!client)
|
||||
return 0
|
||||
if(href_list["SelectedJob"])
|
||||
|
||||
if(!config.enter_allowed)
|
||||
usr << "<span class='notice'>There is an administrative lock on entering the game!</span>"
|
||||
return
|
||||
else if(ticker && ticker.mode && ticker.mode.explosion_in_progress)
|
||||
usr << "<span class='danger'>The station is currently exploding. Joining would go poorly.</span>"
|
||||
return
|
||||
|
||||
if(client.prefs.species != "Human")
|
||||
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
|
||||
src << alert("You are currently not whitelisted to play [client.prefs.species].")
|
||||
return 0
|
||||
|
||||
var/datum/species/S = all_species[client.prefs.species]
|
||||
if(!(S.spawn_flags & CAN_JOIN))
|
||||
src << alert("Your current species, [client.prefs.species], is not available for play on the station.")
|
||||
return 0
|
||||
|
||||
AttemptLateSpawn(href_list["SelectedJob"],client.prefs.spawnpoint)
|
||||
return
|
||||
*/
|
||||
/mob/proc/make_into_lobby_mob()
|
||||
var/mob/new_player/M = new /mob/living/lobby()
|
||||
if(!client)
|
||||
log_game("[usr.key] AM failed due to disconnect.")
|
||||
qdel(M)
|
||||
return
|
||||
|
||||
M.key = key
|
||||
if(M.mind)
|
||||
M.mind.reset()
|
||||
return
|
||||
24
code/modules/mob/living/lobby/login.dm
Normal file
24
code/modules/mob/living/lobby/login.dm
Normal file
@@ -0,0 +1,24 @@
|
||||
/mob/living/lobby
|
||||
var/client/my_client // Need to keep track of this ourselves, since by the time Logout() is called the client has already been nulled
|
||||
|
||||
/mob/living/lobby/Login()
|
||||
update_details()
|
||||
if(join_motd)
|
||||
src << "<div class=\"motd\">[join_motd]</div>"
|
||||
|
||||
if(!mind)
|
||||
mind = new /datum/mind(key)
|
||||
mind.active = 1
|
||||
mind.current = src
|
||||
|
||||
my_client = client
|
||||
|
||||
player_list |= src
|
||||
|
||||
client.playtitlemusic()
|
||||
|
||||
src << "<span class='notice'>You are currently inside your residence. Have a look around, if you want.<br>\
|
||||
The <b>wardrobe</b> is used to customize how you look, as well as select the job you plan to go to the Northern Star as (character setup).<br>\
|
||||
Your <b>laptop</b> will show you a copy of the Northern Star's manifest.<br>\
|
||||
Your <b>HV (Holovision)</b> is also there, assuming you're not busy right now (click it to observe the round as a ghost).<br>\
|
||||
When you're ready to leave for the Northern Star (join the round), click the <b>airlock</b>.</span>"
|
||||
23
code/modules/mob/living/lobby/say.dm
Normal file
23
code/modules/mob/living/lobby/say.dm
Normal file
@@ -0,0 +1,23 @@
|
||||
/mob/living/lobby/say(var/message)
|
||||
message = sanitize(message)
|
||||
|
||||
if (!message)
|
||||
return
|
||||
|
||||
log_say("Lobby/[src.key] : [message]")
|
||||
|
||||
src << "<span class='name'>[src]</span> says, \"[message]\"" // Since lobby mobs are "isolated", only they hear themselves.
|
||||
|
||||
|
||||
/mob/living/lobby/emote(var/act, var/type, var/message)
|
||||
//message = sanitize(message) - already sanitized in verb/me_verb()
|
||||
|
||||
if(!message)
|
||||
return
|
||||
|
||||
if(act != "me")
|
||||
return
|
||||
|
||||
log_emote("Lobby/[src.key] : [message]")
|
||||
|
||||
src << "<span class='name'>[src]</span> [message]"
|
||||
137
code/modules/planet/planet.dm
Normal file
137
code/modules/planet/planet.dm
Normal file
@@ -0,0 +1,137 @@
|
||||
// This holds information about a specific 'planetside' area, such as its time, weather, etc. This will most likely be used to model Sif,
|
||||
// but away missions may also have use for this.
|
||||
|
||||
var/datum/planet/sif/planet_sif = null
|
||||
|
||||
/datum/planet
|
||||
var/name = "a rock"
|
||||
var/desc = "Someone neglected to write a nice description for this poor rock."
|
||||
|
||||
var/datum/time/current_time = new() // Holds the current time for sun positioning. Note that we assume day and night is the same length because simplicity.
|
||||
var/sun_process_interval = 1 HOUR
|
||||
var/sun_last_process = null // world.time
|
||||
|
||||
var/datum/weather_holder/current_weather = new()
|
||||
var/weather_process_interval = 20 MINUTES
|
||||
var/weather_last_process = null // world.time as well.
|
||||
|
||||
/datum/planet/sif
|
||||
name = "Sif"
|
||||
desc = "Sif is a terrestrial planet in the Vir system. It is somewhat earth-like, in that it has oceans, a \
|
||||
breathable atmosphere, a magnetic field, weather, and similar gravity to Earth. It is currently the capital planet of Vir. \
|
||||
Its center of government is the equatorial city and site of first settlement, New Reykjavik." // Ripped straight from the wiki.
|
||||
current_time = new /datum/time/sif() // 32 hour clocks are nice.
|
||||
current_weather = new /datum/weather_holder/sif() // Cold weather is also nice.
|
||||
|
||||
/datum/planet/New()
|
||||
..()
|
||||
current_time = current_time.make_random_time()
|
||||
update_sun()
|
||||
update_weather()
|
||||
|
||||
/datum/planet/proc/process(amount)
|
||||
if(current_time)
|
||||
current_time = current_time.add_seconds(amount)
|
||||
world << "It's currently [current_time.show_time("hh:mm")] on [name]."
|
||||
if(sun_last_process <= world.time - sun_process_interval)
|
||||
update_sun()
|
||||
if(weather_last_process <= world.time - weather_process_interval)
|
||||
update_weather()
|
||||
world << "Processed [name]."
|
||||
|
||||
|
||||
/datum/planet/proc/update_sun()
|
||||
sun_last_process = world.time
|
||||
world << "Praise the sun!"
|
||||
|
||||
|
||||
/datum/planet/sif/update_sun()
|
||||
..()
|
||||
var/datum/time/time = current_time
|
||||
var/length_of_day = time.seconds_in_day / 10 / 60 / 60 // 32
|
||||
var/noon = length_of_day / 2
|
||||
var/distance_from_noon = abs(text2num(time.show_time("hh")) - noon)
|
||||
var/sun_position = distance_from_noon / noon
|
||||
sun_position = abs(sun_position - 1)
|
||||
|
||||
var/low_brightness = null
|
||||
var/high_brightness = null
|
||||
|
||||
var/low_color = null
|
||||
var/high_color = null
|
||||
var/min = 0
|
||||
|
||||
switch(sun_position)
|
||||
if(0 to 0.40) // Night
|
||||
low_brightness = 0.2
|
||||
low_color = "#000066"
|
||||
|
||||
high_brightness = 0.5
|
||||
high_color = "#66004D"
|
||||
world << "Night."
|
||||
min = 0
|
||||
|
||||
if(0.40 to 0.50) // Twilight
|
||||
low_brightness = 0.6
|
||||
low_color = "#66004D"
|
||||
|
||||
high_brightness = 0.8
|
||||
high_color = "#CC3300"
|
||||
world << "Twilight."
|
||||
min = 0.40
|
||||
|
||||
if(0.50 to 0.70) // Sunrise/set
|
||||
low_brightness = 0.8
|
||||
low_color = "#CC3300"
|
||||
|
||||
high_brightness = 0.9
|
||||
high_color = "#FF9933"
|
||||
world << "Sunrise/set."
|
||||
min = 0.50
|
||||
|
||||
if(0.70 to 1.00) // Noon
|
||||
low_brightness = 0.9
|
||||
low_color = "#DDDDDD"
|
||||
|
||||
high_brightness = 1.0
|
||||
high_color = "#FFFFFF"
|
||||
world << "Noon."
|
||||
min = 0.70
|
||||
|
||||
//var/lerp_weight = (sun_position * 4 % 1) / (0.25 / 4) // This weirdness is needed because otherwise the compiler divides by zero.
|
||||
var/lerp_weight = (abs(min - sun_position)) * 4
|
||||
world << "lerp_weight is [lerp_weight], sun_position is [sun_position]."
|
||||
var/new_brightness = Interpolate(low_brightness, high_brightness, weight = lerp_weight)
|
||||
|
||||
var/list/low_color_list = hex2rgb(low_color)
|
||||
var/low_r = low_color_list[1]
|
||||
var/low_g = low_color_list[2]
|
||||
var/low_b = low_color_list[3]
|
||||
|
||||
var/list/high_color_list = hex2rgb(high_color)
|
||||
var/high_r = high_color_list[1]
|
||||
var/high_g = high_color_list[2]
|
||||
var/high_b = high_color_list[3]
|
||||
|
||||
var/new_r = Interpolate(low_r, high_r, weight = lerp_weight)
|
||||
var/new_g = Interpolate(low_g, high_g, weight = lerp_weight)
|
||||
var/new_b = Interpolate(low_b, high_b, weight = lerp_weight)
|
||||
|
||||
var/new_color = rgb(new_r, new_g, new_b)
|
||||
|
||||
world << "Changing time. [outdoor_turfs.len] turfs need to be updated. Expected ETA: [outdoor_turfs.len * 0.0033] seconds."
|
||||
world << "Setting outdoor tiles to set_light(2, [new_brightness], [new_color])."
|
||||
var/i = 0
|
||||
for(var/turf/simulated/floor/T in outdoor_turfs)
|
||||
T.set_light(2, new_brightness, new_color)
|
||||
i++
|
||||
if(i % 30 == 0)
|
||||
sleep(1)
|
||||
world << "Finished."
|
||||
|
||||
|
||||
|
||||
/datum/planet/proc/update_weather()
|
||||
weather_last_process = world.time
|
||||
if(current_weather)
|
||||
current_weather.update()
|
||||
2
code/modules/planet/sif.dm
Normal file
2
code/modules/planet/sif.dm
Normal file
@@ -0,0 +1,2 @@
|
||||
/datum/planet/sif
|
||||
name = "Sif"
|
||||
86
code/modules/planet/time.dm
Normal file
86
code/modules/planet/time.dm
Normal file
@@ -0,0 +1,86 @@
|
||||
// This datum allows one to add and subtract various lengths of time. It really shines when using an alternate time system.
|
||||
|
||||
/datum/time
|
||||
// Note that the following is actually measured in 10ths of a second.
|
||||
var/seconds_in_day = 60 * 60 * 24 * 10 // 86,400 seconds
|
||||
var/seconds_in_hour = 60 * 60 * 10 // 3,600 seconds
|
||||
var/seconds_in_minute = 60 * 10
|
||||
|
||||
// This holds the amount of seconds.
|
||||
var/seconds_stored = 0
|
||||
|
||||
/datum/time/New(new_time)
|
||||
if(new_time)
|
||||
seconds_stored = new_time
|
||||
..()
|
||||
|
||||
/datum/time/proc/add_seconds(amount)
|
||||
var/answer = seconds_stored + amount * 10
|
||||
if(answer >= seconds_in_day)
|
||||
rollover(answer)
|
||||
return new type(answer)
|
||||
|
||||
/datum/time/proc/add_minutes(amount)
|
||||
var/real_amount = amount * seconds_in_minute
|
||||
var/answer = real_amount + seconds_stored
|
||||
if(answer >= seconds_in_day)
|
||||
rollover(answer)
|
||||
return new type(answer)
|
||||
|
||||
/datum/time/proc/add_hours(amount)
|
||||
var/real_amount = amount * seconds_in_hour
|
||||
var/answer = real_amount + seconds_stored
|
||||
if(answer >= seconds_in_day)
|
||||
rollover(answer)
|
||||
return new type(answer)
|
||||
|
||||
/datum/time/proc/rollover(time)
|
||||
return max(time - seconds_in_day, 0)
|
||||
|
||||
/datum/time/proc/make_random_time()
|
||||
return new type(rand(0, seconds_in_day - 1))
|
||||
|
||||
// This works almost exactly like time2text.
|
||||
// The advantage of this is that it can handle time systems beyond 24h.
|
||||
// The downside is a lack of date capability.
|
||||
/datum/time/proc/show_time(format)
|
||||
var/time = seconds_stored
|
||||
while(time >= seconds_in_day) // First, get rid of extra days.
|
||||
time = rollover(time)
|
||||
|
||||
var/hours = time / seconds_in_hour
|
||||
var/remaining_hour = time % seconds_in_hour
|
||||
var/minutes = remaining_hour / seconds_in_minute
|
||||
var/seconds = remaining_hour % seconds_in_minute / 10
|
||||
|
||||
|
||||
var/hour_text = num2text(Floor(hours))
|
||||
if(length(hour_text) < 2)
|
||||
hour_text = "0[hour_text]" // Add padding if needed, to look more like time2text().
|
||||
|
||||
var/minute_text = num2text(Floor(minutes))
|
||||
if(length(minute_text) < 2)
|
||||
minute_text = "0[minute_text]"
|
||||
|
||||
var/second_text = num2text(Floor(seconds))
|
||||
if(length(second_text) < 2)
|
||||
second_text = "0[second_text]"
|
||||
|
||||
var/answer = replacetext(format, "hh", hour_text)
|
||||
answer = replacetext(answer, "mm", minute_text)
|
||||
answer = replacetext(answer, "ss", second_text)
|
||||
return answer
|
||||
/*
|
||||
/client/verb/test_time_systems()
|
||||
var/input_seconds = input("Put in a number of seconds.", "Time Test") as num
|
||||
//input_seconds = min(input_seconds, 864000)
|
||||
world << "time2text() result: [time2text(input_seconds, "hh mm ss")]"
|
||||
var/datum/time/time = new (input_seconds)
|
||||
world << "show_time() result: [time.show_time("hh mm ss")]"
|
||||
var/datum/time/sif/sif = new (input_seconds)
|
||||
world << "sif show_time() result: [sif.show_time("hh mm ss")]"
|
||||
*/
|
||||
// 115,200
|
||||
// We're gonna pretend there are 32 hours in a Sif day instead of 32.64 for the purposes of not losing sanity. We lose 38m 24s but the alternative is a path to madness.
|
||||
/datum/time/sif
|
||||
seconds_in_day = 60 * 60 * 32 * 10 // 115,200 seconds. If we did 32.64 hours/day it would be around 117,504 seconds instead.
|
||||
45
code/modules/planet/weather.dm
Normal file
45
code/modules/planet/weather.dm
Normal file
@@ -0,0 +1,45 @@
|
||||
#define WEATHER_CLEAR "clear"
|
||||
#define WEATHER_OVERCAST "overcast"
|
||||
#define WEATHER_LIGHT_SNOW "light snow"
|
||||
#define WEATHER_SNOW "snow"
|
||||
#define WEATHER_BLIZZARD "blizzard"
|
||||
#define WEATHER_RAIN "rain"
|
||||
#define WEATHER_STORM "storm"
|
||||
#define WEATHER_HAIL "hail"
|
||||
#define WEATHER_WINDY "windy"
|
||||
#define WEATHER_HOT "hot"
|
||||
|
||||
/datum/weather_holder
|
||||
var/current_weather = WEATHER_CLEAR
|
||||
var/temperature = T20C
|
||||
var/wind_dir = 0
|
||||
var/wind_speed = 0
|
||||
var/list/allowed_weather_types = list()
|
||||
var/planetary_wall_type = null // Which walls to look for when updating temperature.
|
||||
|
||||
/datum/weather_holder/proc/update()
|
||||
//TODO: Do actual weather.
|
||||
|
||||
update_temperature()
|
||||
world << "Temperature is now [temperature]."
|
||||
|
||||
/datum/weather_holder/proc/update_temperature()
|
||||
for(var/turf/unsimulated/wall/planetary/wall in planetary_walls)
|
||||
if(ispath(wall.type, planetary_wall_type))
|
||||
wall.temperature = temperature
|
||||
wall.make_air()
|
||||
|
||||
/datum/weather_holder/sif
|
||||
temperature = T0C
|
||||
allowed_weather_types = list(
|
||||
WEATHER_CLEAR,
|
||||
WEATHER_OVERCAST,
|
||||
WEATHER_LIGHT_SNOW,
|
||||
WEATHER_SNOW,
|
||||
WEATHER_BLIZZARD,
|
||||
WEATHER_RAIN,
|
||||
WEATHER_STORM,
|
||||
WEATHER_HAIL,
|
||||
WEATHER_WINDY
|
||||
)
|
||||
planetary_wall_type = /turf/unsimulated/wall/planetary/sif
|
||||
BIN
icons/mob/submerged.dmi
Normal file
BIN
icons/mob/submerged.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 28 KiB |
BIN
icons/turf/outdoors.dmi
Normal file
BIN
icons/turf/outdoors.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
BIN
icons/turf/outdoors_edge.dmi
Normal file
BIN
icons/turf/outdoors_edge.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
14
polaris.dme
14
polaris.dme
@@ -148,6 +148,7 @@
|
||||
#include "code\controllers\Processes\mob.dm"
|
||||
#include "code\controllers\Processes\nanoui.dm"
|
||||
#include "code\controllers\Processes\obj.dm"
|
||||
#include "code\controllers\Processes\planet.dm"
|
||||
#include "code\controllers\Processes\scheduler.dm"
|
||||
#include "code\controllers\Processes\Shuttle.dm"
|
||||
#include "code\controllers\Processes\sun.dm"
|
||||
@@ -997,12 +998,15 @@
|
||||
#include "code\game\turfs\simulated\floor_attackby.dm"
|
||||
#include "code\game\turfs\simulated\floor_damage.dm"
|
||||
#include "code\game\turfs\simulated\floor_icon.dm"
|
||||
#include "code\game\turfs\simulated\floor_outdoors.dm"
|
||||
#include "code\game\turfs\simulated\floor_static.dm"
|
||||
#include "code\game\turfs\simulated\floor_types.dm"
|
||||
#include "code\game\turfs\simulated\wall_attacks.dm"
|
||||
#include "code\game\turfs\simulated\wall_icon.dm"
|
||||
#include "code\game\turfs\simulated\wall_types.dm"
|
||||
#include "code\game\turfs\simulated\walls.dm"
|
||||
#include "code\game\turfs\simulated\water.dm"
|
||||
#include "code\game\turfs\simulated\outdoors\outdoors.dm"
|
||||
#include "code\game\turfs\snow\snow.dm"
|
||||
#include "code\game\turfs\space\cracked_asteroid.dm"
|
||||
#include "code\game\turfs\space\space.dm"
|
||||
@@ -1781,6 +1785,10 @@
|
||||
#include "code\modules\paperwork\photography.dm"
|
||||
#include "code\modules\paperwork\silicon_photography.dm"
|
||||
#include "code\modules\paperwork\stamps.dm"
|
||||
#include "code\modules\planet\planet.dm"
|
||||
#include "code\modules\planet\sif.dm"
|
||||
#include "code\modules\planet\time.dm"
|
||||
#include "code\modules\planet\weather.dm"
|
||||
#include "code\modules\power\apc.dm"
|
||||
#include "code\modules\power\batteryrack.dm"
|
||||
#include "code\modules\power\breaker_box.dm"
|
||||
@@ -2155,9 +2163,5 @@
|
||||
#include "code\ZAS\Zone.dm"
|
||||
#include "interface\interface.dm"
|
||||
#include "interface\skin.dmf"
|
||||
#include "maps\polaris-1.dmm"
|
||||
#include "maps\polaris-2.dmm"
|
||||
#include "maps\polaris-3.dmm"
|
||||
#include "maps\polaris-4.dmm"
|
||||
#include "maps\polaris-5.dmm"
|
||||
#include "maps\plane-1.dmm"
|
||||
// END_INCLUDE
|
||||
|
||||
Reference in New Issue
Block a user