Merge branch 'master' into the-fuck-am-i-doing
This commit is contained in:
@@ -415,7 +415,7 @@ Example config:
|
||||
while(recent_round)
|
||||
adjustment += repeated_mode_adjust[recent_round]
|
||||
recent_round = SSpersistence.saved_modes.Find(name,recent_round+1,0)
|
||||
probability *= ((100-adjustment)/100)
|
||||
probability *= max(0,((100-adjustment)/100))
|
||||
runnable_storytellers[S] = probability
|
||||
return runnable_storytellers
|
||||
|
||||
@@ -448,7 +448,7 @@ Example config:
|
||||
while(recent_round)
|
||||
adjustment += repeated_mode_adjust[recent_round]
|
||||
recent_round = SSpersistence.saved_modes.Find(M.config_tag,recent_round+1,0)
|
||||
final_weight *= ((100-adjustment)/100)
|
||||
final_weight *= max(0,((100-adjustment)/100))
|
||||
runnable_modes[M] = final_weight
|
||||
return runnable_modes
|
||||
|
||||
|
||||
@@ -22,11 +22,10 @@
|
||||
|
||||
/datum/config_entry/string/cross_comms_name
|
||||
|
||||
/datum/config_entry/string/medal_hub_address
|
||||
|
||||
/datum/config_entry/string/medal_hub_password
|
||||
protection = CONFIG_ENTRY_HIDDEN
|
||||
/datum/config_entry/string/cross_comms_network
|
||||
protection = CONFIG_ENTRY_LOCKED
|
||||
|
||||
/// cit config
|
||||
/datum/config_entry/keyed_list/cross_server_bunker_override
|
||||
key_mode = KEY_MODE_TEXT
|
||||
value_mode = VALUE_MODE_TEXT
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
SUBSYSTEM_DEF(achievements)
|
||||
name = "Achievements"
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_ACHIEVEMENTS
|
||||
var/achievements_enabled = FALSE
|
||||
|
||||
///List of achievements
|
||||
var/list/datum/award/achievement/achievements = list()
|
||||
///List of scores
|
||||
var/list/datum/award/score/scores = list()
|
||||
///List of all awards
|
||||
var/list/datum/award/awards = list()
|
||||
|
||||
/datum/controller/subsystem/achievements/Initialize(timeofday)
|
||||
if(!SSdbcore.Connect())
|
||||
return ..()
|
||||
achievements_enabled = TRUE
|
||||
|
||||
for(var/T in subtypesof(/datum/award/achievement))
|
||||
var/instance = new T
|
||||
achievements[T] = instance
|
||||
awards[T] = instance
|
||||
|
||||
for(var/T in subtypesof(/datum/award/score))
|
||||
var/instance = new T
|
||||
scores[T] = instance
|
||||
awards[T] = instance
|
||||
|
||||
update_metadata()
|
||||
|
||||
for(var/i in GLOB.clients)
|
||||
var/client/C = i
|
||||
if(!C.player_details.achievements.initialized)
|
||||
C.player_details.achievements.InitializeData()
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/achievements/Shutdown()
|
||||
save_achievements_to_db()
|
||||
|
||||
/datum/controller/subsystem/achievements/proc/save_achievements_to_db()
|
||||
var/list/cheevos_to_save = list()
|
||||
for(var/ckey in GLOB.player_details)
|
||||
var/datum/player_details/PD = GLOB.player_details[ckey]
|
||||
if(!PD || !PD.achievements)
|
||||
continue
|
||||
cheevos_to_save += PD.achievements.get_changed_data()
|
||||
if(!length(cheevos_to_save))
|
||||
return
|
||||
SSdbcore.MassInsert(format_table_name("achievements"),cheevos_to_save,duplicate_key = TRUE)
|
||||
|
||||
//Update the metadata if any are behind
|
||||
/datum/controller/subsystem/achievements/proc/update_metadata()
|
||||
var/list/current_metadata = list()
|
||||
//select metadata here
|
||||
var/datum/db_query/Q = SSdbcore.NewQuery("SELECT achievement_key,achievement_version FROM [format_table_name("achievement_metadata")]")
|
||||
if(!Q.Execute(async = TRUE))
|
||||
qdel(Q)
|
||||
return
|
||||
else
|
||||
while(Q.NextRow())
|
||||
current_metadata[Q.item[1]] = text2num(Q.item[2])
|
||||
qdel(Q)
|
||||
|
||||
var/list/to_update = list()
|
||||
for(var/T in awards)
|
||||
var/datum/award/A = awards[T]
|
||||
if(!A.database_id)
|
||||
continue
|
||||
if(!current_metadata[A.database_id] || current_metadata[A.database_id] < A.achievement_version)
|
||||
to_update += list(A.get_metadata_row())
|
||||
|
||||
if(to_update.len)
|
||||
SSdbcore.MassInsert(format_table_name("achievement_metadata"),to_update,duplicate_key = TRUE)
|
||||
@@ -1,6 +1,8 @@
|
||||
/*! How material datums work
|
||||
Materials are now instanced datums, with an associative list of them being kept in SSmaterials. We only instance the materials once and then re-use these instances for everything.
|
||||
|
||||
These materials call on_applied() on whatever item they are applied to, common effects are adding components, changing color and changing description. This allows us to differentiate items based on the material they are made out of.area
|
||||
|
||||
*/
|
||||
|
||||
SUBSYSTEM_DEF(materials)
|
||||
@@ -14,12 +16,16 @@ SUBSYSTEM_DEF(materials)
|
||||
var/list/materialtypes_by_category
|
||||
///A cache of all material combinations that have been used
|
||||
var/list/list/material_combos
|
||||
///List of stackcrafting recipes for materials using rigid materials
|
||||
///List of stackcrafting recipes for materials using base recipes
|
||||
var/list/base_stack_recipes = list(
|
||||
new /datum/stack_recipe("Chair", /obj/structure/chair/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
|
||||
new /datum/stack_recipe("Toilet", /obj/structure/toilet/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
|
||||
new /datum/stack_recipe("Sink Frame", /obj/structure/sink/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
|
||||
new /datum/stack_recipe("Floor tile", /obj/item/stack/tile/material, 1, 4, 20, applies_mats = TRUE),
|
||||
)
|
||||
///List of stackcrafting recipes for materials using rigid recipes
|
||||
var/list/rigid_stack_recipes = list(
|
||||
new /datum/stack_recipe("chair", /obj/structure/chair/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
|
||||
new /datum/stack_recipe("toilet", /obj/structure/toilet/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
|
||||
new /datum/stack_recipe("sink", /obj/structure/sink/greyscale, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
|
||||
new /datum/stack_recipe("Floor tile", /obj/item/stack/tile/material, 1, 4, 20, applies_mats = TRUE)
|
||||
// new /datum/stack_recipe("Carving block", /obj/structure/carving_block, 5, one_per_turf = TRUE, on_floor = TRUE, applies_mats = TRUE),
|
||||
)
|
||||
|
||||
///Ran on initialize, populated the materials and materials_by_category dictionaries with their appropiate vars (See these variables for more info)
|
||||
@@ -29,7 +35,11 @@ SUBSYSTEM_DEF(materials)
|
||||
materialtypes_by_category = list()
|
||||
material_combos = list()
|
||||
for(var/type in subtypesof(/datum/material))
|
||||
var/datum/material/ref = new type
|
||||
var/datum/material/ref = type
|
||||
// if(!(initial(ref.init_flags) & MATERIAL_INIT_MAPLOAD))
|
||||
// continue // Do not initialize
|
||||
|
||||
ref = new ref
|
||||
materials[type] = ref
|
||||
for(var/c in ref.categories)
|
||||
materials_by_category[c] += list(ref)
|
||||
@@ -40,7 +50,6 @@ SUBSYSTEM_DEF(materials)
|
||||
InitializeMaterials()
|
||||
return materials[fakemat] || fakemat
|
||||
|
||||
|
||||
///Returns a list to be used as an object's custom_materials. Lists will be cached and re-used based on the parameters.
|
||||
/datum/controller/subsystem/materials/proc/FindOrCreateMaterialCombo(list/materials_declaration, multiplier)
|
||||
if(!material_combos)
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
SUBSYSTEM_DEF(medals)
|
||||
name = "Medals"
|
||||
flags = SS_NO_FIRE
|
||||
var/hub_enabled = FALSE
|
||||
|
||||
/datum/controller/subsystem/medals/Initialize(timeofday)
|
||||
if(CONFIG_GET(string/medal_hub_address) && CONFIG_GET(string/medal_hub_password))
|
||||
hub_enabled = TRUE
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/medals/proc/UnlockMedal(medal, client/player)
|
||||
set waitfor = FALSE
|
||||
if(!medal || !hub_enabled)
|
||||
return
|
||||
if(isnull(world.SetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))))
|
||||
hub_enabled = FALSE
|
||||
log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.key]")
|
||||
message_admins("Error! Failed to contact hub to award [medal] medal to [player.key]!")
|
||||
return
|
||||
to_chat(player, "<span class='greenannounce'><B>Achievement unlocked: [medal]!</B></span>")
|
||||
|
||||
|
||||
/datum/controller/subsystem/medals/proc/SetScore(score, client/player, increment, force)
|
||||
set waitfor = FALSE
|
||||
if(!score || !hub_enabled)
|
||||
return
|
||||
|
||||
var/list/oldscore = GetScore(score, player, TRUE)
|
||||
if(increment)
|
||||
if(!oldscore[score])
|
||||
oldscore[score] = 1
|
||||
else
|
||||
oldscore[score] = (text2num(oldscore[score]) + 1)
|
||||
else
|
||||
oldscore[score] = force
|
||||
|
||||
var/newscoreparam = list2params(oldscore)
|
||||
|
||||
if(isnull(world.SetScores(player.ckey, newscoreparam, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))))
|
||||
hub_enabled = FALSE
|
||||
log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.key]")
|
||||
message_admins("Error! Failed to contact hub to set [score] score for [player.key]!")
|
||||
|
||||
/datum/controller/subsystem/medals/proc/GetScore(score, client/player, returnlist)
|
||||
if(!score || !hub_enabled)
|
||||
return
|
||||
|
||||
var/scoreget = world.GetScores(player.ckey, score, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
|
||||
if(isnull(scoreget))
|
||||
hub_enabled = FALSE
|
||||
log_game("SCORE ERROR: Could not contact hub to get score. Score:[score] player:[player.key]")
|
||||
message_admins("Error! Failed to contact hub to get score: [score] for [player.key]!")
|
||||
return
|
||||
. = params2list(scoreget)
|
||||
if(!returnlist)
|
||||
return .[score]
|
||||
|
||||
/datum/controller/subsystem/medals/proc/CheckMedal(medal, client/player)
|
||||
if(!medal || !hub_enabled)
|
||||
return
|
||||
|
||||
if(isnull(world.GetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))))
|
||||
hub_enabled = FALSE
|
||||
log_game("MEDAL ERROR: Could not contact hub to get medal:[medal] player: [player.key]")
|
||||
message_admins("Error! Failed to contact hub to get [medal] medal for [player.key]!")
|
||||
return
|
||||
to_chat(player, "[medal] is unlocked")
|
||||
|
||||
/datum/controller/subsystem/medals/proc/LockMedal(medal, client/player)
|
||||
if(!player || !medal || !hub_enabled)
|
||||
return
|
||||
var/result = world.ClearMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))
|
||||
switch(result)
|
||||
if(null)
|
||||
hub_enabled = FALSE
|
||||
log_game("MEDAL ERROR: Could not contact hub to clear medal:[medal] player:[player.key]")
|
||||
message_admins("Error! Failed to contact hub to clear [medal] medal for [player.key]!")
|
||||
if(TRUE)
|
||||
message_admins("Medal: [medal] removed for [player.key]")
|
||||
if(FALSE)
|
||||
message_admins("Medal: [medal] was not found for [player.key]. Unable to clear.")
|
||||
|
||||
|
||||
/datum/controller/subsystem/medals/proc/ClearScore(client/player)
|
||||
if(isnull(world.SetScores(player.ckey, "", CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password))))
|
||||
log_game("MEDAL ERROR: Could not contact hub to clear scores for [player.key]!")
|
||||
message_admins("Error! Failed to contact hub to clear scores for [player.key]!")
|
||||
@@ -70,3 +70,8 @@ PROCESSING_SUBSYSTEM_DEF(weather)
|
||||
A = W
|
||||
break
|
||||
return A
|
||||
|
||||
/datum/controller/subsystem/processing/weather/proc/get_weather_by_type(datum/weather/weather_datum_type)
|
||||
for(var/V in processing)
|
||||
if(istype(V,weather_datum_type))
|
||||
return V
|
||||
|
||||
@@ -12,6 +12,10 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/list/beacons = list()
|
||||
var/list/transit = list()
|
||||
|
||||
//Now it only for ID generation
|
||||
var/list/assoc_mobile = list()
|
||||
var/list/assoc_stationary = list()
|
||||
|
||||
var/list/transit_requesters = list()
|
||||
var/list/transit_request_failures = list()
|
||||
|
||||
@@ -26,6 +30,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/emergencyCallAmount = 0 //how many times the escape shuttle was called
|
||||
var/emergencyNoEscape
|
||||
var/emergencyNoRecall = FALSE
|
||||
var/adminEmergencyNoRecall = FALSE
|
||||
var/list/hostileEnvironments = list() //Things blocking escape shuttle from leaving
|
||||
var/list/tradeBlockade = list() //Things blocking cargo from leaving.
|
||||
var/supplyBlocked = FALSE
|
||||
@@ -65,6 +70,8 @@ SUBSYSTEM_DEF(shuttle)
|
||||
|
||||
var/datum/turf_reservation/preview_reservation
|
||||
|
||||
var/shuttle_loading
|
||||
|
||||
/datum/controller/subsystem/shuttle/Initialize(timeofday)
|
||||
ordernum = rand(1, 9000)
|
||||
|
||||
@@ -134,7 +141,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
break
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/CheckAutoEvac()
|
||||
if(emergencyNoEscape || emergencyNoRecall || !emergency || !SSticker.HasRoundStarted())
|
||||
if(emergencyNoEscape || adminEmergencyNoRecall || emergencyNoRecall || !emergency || !SSticker.HasRoundStarted())
|
||||
return
|
||||
|
||||
var/threshold = CONFIG_GET(number/emergency_shuttle_autocall_threshold)
|
||||
@@ -179,31 +186,26 @@ SUBSYSTEM_DEF(shuttle)
|
||||
return S
|
||||
WARNING("couldn't find dock with id: [id]")
|
||||
|
||||
/// Check if we can call the evac shuttle.
|
||||
/// Returns TRUE if we can. Otherwise, returns a string detailing the problem.
|
||||
/datum/controller/subsystem/shuttle/proc/canEvac(mob/user)
|
||||
var/srd = CONFIG_GET(number/shuttle_refuel_delay)
|
||||
if(world.time - SSticker.round_start_time < srd)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle is refueling. Please wait [DisplayTimeText(srd - (world.time - SSticker.round_start_time))] before trying again.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle is refueling. Please wait [DisplayTimeText(srd - (world.time - SSticker.round_start_time))] before attempting to call."
|
||||
|
||||
switch(emergency.mode)
|
||||
if(SHUTTLE_RECALL)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle may not be called while returning to CentCom.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle may not be called while returning to CentCom."
|
||||
if(SHUTTLE_CALL)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle is already on its way.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle is already on its way."
|
||||
if(SHUTTLE_DOCKED)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle is already here.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle is already here."
|
||||
if(SHUTTLE_IGNITING)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle is firing its engines to leave.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle is firing its engines to leave."
|
||||
if(SHUTTLE_ESCAPE)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle is moving away to a safe distance.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle is moving away to a safe distance."
|
||||
if(SHUTTLE_STRANDED)
|
||||
to_chat(user, "<span class='alert'>The emergency shuttle has been disabled by CentCom.</span>")
|
||||
return FALSE
|
||||
return "The emergency shuttle has been disabled by CentCom."
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -221,7 +223,9 @@ SUBSYSTEM_DEF(shuttle)
|
||||
Good luck.")
|
||||
emergency = backup_shuttle
|
||||
|
||||
if(!canEvac(user))
|
||||
var/can_evac_or_fail_reason = SSshuttle.canEvac(user)
|
||||
if(can_evac_or_fail_reason != TRUE)
|
||||
to_chat(user, "<span class='alert'>[can_evac_or_fail_reason]</span>")
|
||||
return
|
||||
|
||||
call_reason = trim(html_encode(call_reason))
|
||||
@@ -250,10 +254,11 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/area/A = get_area(user)
|
||||
|
||||
log_shuttle("[key_name(user)] has called the emergency shuttle.")
|
||||
deadchat_broadcast(" has called the shuttle at <span class='name'>[A.name]</span>.", "<span class='name'>[user.real_name]</span>", user)
|
||||
deadchat_broadcast(" has called the shuttle at <span class='name'>[A.name]</span>.", "<span class='name'>[user.real_name]</span>", user) //, message_type=DEADCHAT_ANNOUNCEMENT)
|
||||
if(call_reason)
|
||||
SSblackbox.record_feedback("text", "shuttle_reason", 1, "[call_reason]")
|
||||
log_shuttle("Shuttle call reason: [call_reason]")
|
||||
SSticker.emergency_reason = call_reason
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] has called the shuttle. (<A HREF='?_src_=holder;[HrefToken()];trigger_centcom_recall=1'>TRIGGER CENTCOM RECALL</A>)")
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/centcom_recall(old_timer, admiral_message)
|
||||
@@ -288,7 +293,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
emergency.cancel(get_area(user))
|
||||
log_shuttle("[key_name(user)] has recalled the shuttle.")
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] has recalled the shuttle.")
|
||||
deadchat_broadcast(" has recalled the shuttle from <span class='name'>[get_area_name(user, TRUE)]</span>.", "<span class='name'>[user.real_name]</span>", user)
|
||||
deadchat_broadcast(" has recalled the shuttle from <span class='name'>[get_area_name(user, TRUE)]</span>.", "<span class='name'>[user.real_name]</span>", user) //, message_type=DEADCHAT_ANNOUNCEMENT)
|
||||
return 1
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/canRecall()
|
||||
@@ -314,7 +319,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
if (!SSticker.IsRoundInProgress())
|
||||
return
|
||||
|
||||
var/callShuttle = 1
|
||||
var/callShuttle = TRUE
|
||||
|
||||
for(var/thing in GLOB.shuttle_caller_list)
|
||||
if(isAI(thing))
|
||||
@@ -330,7 +335,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
|
||||
var/turf/T = get_turf(thing)
|
||||
if(T && is_station_level(T.z))
|
||||
callShuttle = 0
|
||||
callShuttle = FALSE
|
||||
break
|
||||
|
||||
if(callShuttle)
|
||||
@@ -406,7 +411,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
else
|
||||
if(M.initiate_docking(getDock(destination)) != DOCKING_SUCCESS)
|
||||
return 2
|
||||
return 0 //dock successful
|
||||
return 0 //dock successful
|
||||
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/moveShuttle(shuttleId, dockId, timed)
|
||||
@@ -664,7 +669,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
emergencyNoRecall = TRUE
|
||||
endvote_passed = TRUE
|
||||
|
||||
/datum/controller/subsystem/shuttle/proc/action_load(datum/map_template/shuttle/loading_template, obj/docking_port/stationary/destination_port)
|
||||
/datum/controller/subsystem/shuttle/proc/action_load(datum/map_template/shuttle/loading_template, obj/docking_port/stationary/destination_port, replace = FALSE)
|
||||
// Check for an existing preview
|
||||
if(preview_shuttle && (loading_template != preview_template))
|
||||
preview_shuttle.jumpToNullSpace()
|
||||
@@ -673,8 +678,8 @@ SUBSYSTEM_DEF(shuttle)
|
||||
QDEL_NULL(preview_reservation)
|
||||
|
||||
if(!preview_shuttle)
|
||||
if(load_template(loading_template))
|
||||
preview_shuttle.linkup(loading_template, destination_port)
|
||||
load_template(loading_template)
|
||||
// preview_shuttle.linkup(loading_template, destination_port)
|
||||
preview_template = loading_template
|
||||
|
||||
// get the existing shuttle information, if any
|
||||
@@ -684,7 +689,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
|
||||
if(istype(destination_port))
|
||||
D = destination_port
|
||||
else if(existing_shuttle)
|
||||
else if(existing_shuttle && replace)
|
||||
timer = existing_shuttle.timer
|
||||
mode = existing_shuttle.mode
|
||||
D = existing_shuttle.get_docked()
|
||||
@@ -703,11 +708,12 @@ SUBSYSTEM_DEF(shuttle)
|
||||
WARNING("Template shuttle [preview_shuttle] cannot dock at [D] ([result]).")
|
||||
return
|
||||
|
||||
if(existing_shuttle)
|
||||
if(existing_shuttle && replace)
|
||||
existing_shuttle.jumpToNullSpace()
|
||||
|
||||
var/list/force_memory = preview_shuttle.movement_force
|
||||
preview_shuttle.movement_force = list("KNOCKDOWN" = 0, "THROW" = 0)
|
||||
preview_shuttle.mode = SHUTTLE_PREARRIVAL//No idle shuttle moving. Transit dock get removed if shuttle moves too long.
|
||||
preview_shuttle.initiate_docking(D)
|
||||
preview_shuttle.movement_force = force_memory
|
||||
|
||||
@@ -718,7 +724,7 @@ SUBSYSTEM_DEF(shuttle)
|
||||
preview_shuttle.timer = timer
|
||||
preview_shuttle.mode = mode
|
||||
|
||||
preview_shuttle.register()
|
||||
preview_shuttle.register(replace)
|
||||
|
||||
// TODO indicate to the user that success happened, rather than just
|
||||
// blanking the modification tab
|
||||
@@ -848,7 +854,8 @@ SUBSYSTEM_DEF(shuttle)
|
||||
return data
|
||||
|
||||
/datum/controller/subsystem/shuttle/ui_act(action, params)
|
||||
if(..())
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/mob/user = usr
|
||||
@@ -891,22 +898,10 @@ SUBSYSTEM_DEF(shuttle)
|
||||
SSblackbox.record_feedback("text", "shuttle_manipulator", 1, "[M.name]")
|
||||
break
|
||||
|
||||
if("preview")
|
||||
if(S)
|
||||
. = TRUE
|
||||
unload_preview()
|
||||
load_template(S)
|
||||
if(preview_shuttle)
|
||||
preview_template = S
|
||||
user.forceMove(get_turf(preview_shuttle))
|
||||
if("load")
|
||||
if(existing_shuttle == backup_shuttle)
|
||||
// TODO make the load button disabled
|
||||
WARNING("The shuttle that the selected shuttle will replace \
|
||||
is the backup shuttle. Backup shuttle is required to be \
|
||||
intact for round sanity.")
|
||||
else if(S)
|
||||
if(S && !shuttle_loading)
|
||||
. = TRUE
|
||||
shuttle_loading = TRUE
|
||||
// If successful, returns the mobile docking port
|
||||
var/obj/docking_port/mobile/mdp = action_load(S)
|
||||
if(mdp)
|
||||
@@ -914,3 +909,38 @@ SUBSYSTEM_DEF(shuttle)
|
||||
message_admins("[key_name_admin(usr)] loaded [mdp] with the shuttle manipulator.")
|
||||
log_admin("[key_name(usr)] loaded [mdp] with the shuttle manipulator.</span>")
|
||||
SSblackbox.record_feedback("text", "shuttle_manipulator", 1, "[mdp.name]")
|
||||
shuttle_loading = FALSE
|
||||
|
||||
if("preview")
|
||||
//if(preview_shuttle && (loading_template != preview_template))
|
||||
if(S && !shuttle_loading)
|
||||
. = TRUE
|
||||
shuttle_loading = TRUE
|
||||
unload_preview()
|
||||
load_template(S)
|
||||
if(preview_shuttle)
|
||||
preview_template = S
|
||||
user.forceMove(get_turf(preview_shuttle))
|
||||
shuttle_loading = FALSE
|
||||
|
||||
if("replace")
|
||||
if(existing_shuttle == backup_shuttle)
|
||||
// TODO make the load button disabled
|
||||
WARNING("The shuttle that the selected shuttle will replace \
|
||||
is the backup shuttle. Backup shuttle is required to be \
|
||||
intact for round sanity.")
|
||||
else if(S && !shuttle_loading)
|
||||
. = TRUE
|
||||
shuttle_loading = TRUE
|
||||
// If successful, returns the mobile docking port
|
||||
var/obj/docking_port/mobile/mdp = action_load(S, replace = TRUE)
|
||||
if(mdp)
|
||||
user.forceMove(get_turf(mdp))
|
||||
message_admins("[key_name_admin(usr)] load/replaced [mdp] with the shuttle manipulator.")
|
||||
log_admin("[key_name(usr)] load/replaced [mdp] with the shuttle manipulator.</span>")
|
||||
SSblackbox.record_feedback("text", "shuttle_manipulator", 1, "[mdp.name]")
|
||||
shuttle_loading = FALSE
|
||||
if(emergency == mdp) //you just changed the emergency shuttle, there are events in game + captains that can change your snowflake choice.
|
||||
var/set_purchase = alert(usr, "Do you want to also disable shuttle purchases/random events that would change the shuttle?", "Butthurt Admin Prevention", "Yes, disable purchases/events", "No, I want to possibly get owned")
|
||||
if(set_purchase == "Yes, disable purchases/events")
|
||||
SSshuttle.shuttle_purchased = SHUTTLEPURCHASE_FORCED
|
||||
|
||||
@@ -1,32 +1,63 @@
|
||||
#define OCCLUSION_DISTANCE 20
|
||||
|
||||
/datum/sun
|
||||
var/azimuth = 0 // clockwise, top-down rotation from 0 (north) to 359
|
||||
var/power_mod = 1 // how much power this sun is outputting relative to standard
|
||||
|
||||
|
||||
/datum/sun/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
if(var_name == NAMEOF(src, azimuth))
|
||||
SSsun.complete_movement()
|
||||
|
||||
/atom/proc/check_obscured(datum/sun/sun, distance = OCCLUSION_DISTANCE)
|
||||
var/target_x = round(sin(sun.azimuth), 0.01)
|
||||
var/target_y = round(cos(sun.azimuth), 0.01)
|
||||
var/x_hit = x
|
||||
var/y_hit = y
|
||||
var/turf/hit
|
||||
|
||||
for(var/run in 1 to distance)
|
||||
x_hit += target_x
|
||||
y_hit += target_y
|
||||
hit = locate(round(x_hit, 1), round(y_hit, 1), z)
|
||||
if(hit.opacity)
|
||||
return TRUE
|
||||
if(hit.x == 1 || hit.x == world.maxx || hit.y == 1 || hit.y == world.maxy) //edge of the map
|
||||
break
|
||||
return FALSE
|
||||
|
||||
SUBSYSTEM_DEF(sun)
|
||||
name = "Sun"
|
||||
wait = 1 MINUTES
|
||||
flags = SS_NO_TICK_CHECK
|
||||
|
||||
var/azimuth = 0 ///clockwise, top-down rotation from 0 (north) to 359
|
||||
var/list/datum/sun/suns = list()
|
||||
var/datum/sun/primary_sun
|
||||
var/azimuth_mod = 1 ///multiplier against base_rotation
|
||||
var/base_rotation = 6 ///base rotation in degrees per fire
|
||||
|
||||
/datum/controller/subsystem/sun/Initialize(start_timeofday)
|
||||
azimuth = rand(0, 359)
|
||||
primary_sun = new
|
||||
suns += primary_sun
|
||||
primary_sun.azimuth = rand(0, 359)
|
||||
azimuth_mod = round(rand(50, 200)/100, 0.01) // 50% - 200% of standard rotation
|
||||
if(prob(50))
|
||||
azimuth_mod *= -1
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/sun/fire(resumed = FALSE)
|
||||
azimuth += azimuth_mod * base_rotation
|
||||
azimuth = round(azimuth, 0.01)
|
||||
if(azimuth >= 360)
|
||||
azimuth -= 360
|
||||
if(azimuth < 0)
|
||||
azimuth += 360
|
||||
for(var/S in suns)
|
||||
var/datum/sun/sun = S
|
||||
sun.azimuth += azimuth_mod * base_rotation
|
||||
sun.azimuth = round(sun.azimuth, 0.01)
|
||||
if(sun.azimuth >= 360)
|
||||
sun.azimuth -= 360
|
||||
if(sun.azimuth < 0)
|
||||
sun.azimuth += 360
|
||||
complete_movement()
|
||||
|
||||
/datum/controller/subsystem/sun/proc/complete_movement()
|
||||
SEND_SIGNAL(src, COMSIG_SUN_MOVED, azimuth)
|
||||
SEND_SIGNAL(src, COMSIG_SUN_MOVED, primary_sun, suns)
|
||||
|
||||
/datum/controller/subsystem/sun/vv_edit_var(var_name, var_value)
|
||||
. = ..()
|
||||
if(var_name == NAMEOF(src, azimuth))
|
||||
complete_movement()
|
||||
#undef OCCLUSION_DISTANCE
|
||||
|
||||
@@ -69,6 +69,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/modevoted = FALSE //Have we sent a vote for the gamemode?
|
||||
|
||||
var/station_integrity = 100 // stored at roundend for use in some antag goals
|
||||
var/emergency_reason
|
||||
|
||||
/datum/controller/subsystem/ticker/Initialize(timeofday)
|
||||
load_mode()
|
||||
@@ -563,7 +564,10 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(STATION_DESTROYED_NUKE)
|
||||
news_message = "We would like to reassure all employees that the reports of a Syndicate backed nuclear attack on [station_name()] are, in fact, a hoax. Have a secure day!"
|
||||
if(STATION_EVACUATED)
|
||||
news_message = "The crew of [station_name()] has been evacuated amid unconfirmed reports of enemy activity."
|
||||
if(emergency_reason)
|
||||
news_message = "[station_name()] has been evacuated after transmitting the following distress beacon:\n\n[emergency_reason]"
|
||||
else
|
||||
news_message = "The crew of [station_name()] has been evacuated amid unconfirmed reports of enemy activity."
|
||||
if(BLOB_WIN)
|
||||
news_message = "[station_name()] was overcome by an unknown biological outbreak, killing all crew on board. Don't let it happen to you! Remember, a clean work station is a safe work station."
|
||||
if(BLOB_NUKE)
|
||||
@@ -589,7 +593,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(WIZARD_KILLED)
|
||||
news_message = "Tensions have flared with the Space Wizard Federation following the death of one of their members aboard [station_name()]."
|
||||
if(STATION_NUKED)
|
||||
news_message = "[station_name()] activated its self destruct device for unknown reasons. Attempts to clone the Captain so he can be arrested and executed are underway."
|
||||
news_message = "[station_name()] activated its self-destruct device for unknown reasons. Attempts to clone the Captain so he can be arrested and executed are underway."
|
||||
if(CLOCK_SUMMON)
|
||||
news_message = "The garbled messages about hailing a mouse and strange energy readings from [station_name()] have been discovered to be an ill-advised, if thorough, prank by a clown."
|
||||
if(CLOCK_SILICONS)
|
||||
@@ -604,7 +608,8 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(SSblackbox.first_death)
|
||||
var/list/ded = SSblackbox.first_death
|
||||
if(ded.len)
|
||||
news_message += " NT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""]"
|
||||
var/last_words = ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""
|
||||
news_message += " NT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]"
|
||||
else
|
||||
news_message += " NT Sanctioned Psykers proudly confirm reports that nobody died this shift!"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user