works on planet stuff

This commit is contained in:
Neerti
2017-02-06 20:45:21 -05:00
parent 867c0ba2f4
commit 1d9e7c8c08
25 changed files with 1144 additions and 9 deletions

View 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)

View File

@@ -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()

View File

@@ -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

View 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))

View 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))

View 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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View 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

View 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>"

View 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]"

View 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()

View File

@@ -0,0 +1,2 @@
/datum/planet/sif
name = "Sif"

View 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.

View 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

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -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