Merge branch 'master' into the-fuck-am-i-doing

This commit is contained in:
Fabian
2021-05-05 17:26:41 +02:00
641 changed files with 318305 additions and 311402 deletions
@@ -22,7 +22,7 @@
var/motd
// var/policy
// var/static/regex/ic_filter_regex
var/static/regex/ic_filter_regex
/datum/controller/configuration/proc/admin_reload()
if(IsAdminAdvancedProcCall())
@@ -53,7 +53,7 @@
loadmaplist(CONFIG_MAPS_FILE)
LoadMOTD()
// LoadPolicy()
// LoadChatFilter()
LoadChatFilter()
if (Master)
Master.OnConfigLoad()
@@ -404,9 +404,9 @@ Example config:
if(!Get(/datum/config_entry/flag/no_storyteller_threat_removal))
var/min_chaos = (probabilities in storyteller_min_chaos) ? storyteller_min_chaos[config_tag] : initial(S.min_chaos)
var/max_chaos = (probabilities in storyteller_max_chaos) ? storyteller_max_chaos[config_tag] : initial(S.max_chaos)
if(SSpersistence.average_dynamic_threat < min_chaos)
if(SSpersistence.average_threat + 50 < min_chaos)
continue
if(SSpersistence.average_dynamic_threat > max_chaos)
if(SSpersistence.average_threat + 50 > max_chaos)
continue
if(SSpersistence.saved_storytellers.len == repeated_mode_adjust.len)
var/name = initial(S.name)
@@ -486,7 +486,7 @@ Example config:
continue
runnable_modes[M] = probabilities[M.config_tag]
return runnable_modes
/*
/datum/controller/configuration/proc/LoadChatFilter()
var/list/in_character_filter = list()
if(!fexists("[directory]/in_character_filter.txt"))
@@ -499,7 +499,7 @@ Example config:
continue
in_character_filter += REGEX_QUOTE(line)
ic_filter_regex = in_character_filter.len ? regex("\\b([jointext(in_character_filter, "|")])\\b", "i") : null
*/
//Message admins when you can.
/datum/controller/configuration/proc/DelayedMessageAdmins(text)
addtimer(CALLBACK(GLOBAL_PROC, /proc/message_admins, text), 0)
+75
View File
@@ -0,0 +1,75 @@
SUBSYSTEM_DEF(activity)
name = "Activity tracking"
flags = SS_BACKGROUND | SS_NO_TICK_CHECK
priority = FIRE_PRIORITY_ACTIVITY
wait = 1 MINUTES
var/list/deferred_threats = list()
var/current_threat = 0
var/list/threat_history = list()
var/list/threats = list()
/datum/controller/subsystem/activity/Initialize(timeofday)
RegisterSignal(SSdcs,COMSIG_GLOB_EXPLOSION,.proc/on_explosion)
RegisterSignal(SSdcs,COMSIG_GLOB_MOB_DEATH,.proc/on_death)
/datum/controller/subsystem/activity/fire(resumed = 0)
calculate_threat()
/datum/controller/subsystem/activity/proc/calculate_threat()
threats = deferred_threats.Copy()
deferred_threats.Cut()
threats["antagonists"] = 0
for(var/datum/antagonist/A in GLOB.antagonists)
if(A?.owner?.current && A.owner.current.stat != DEAD)
threats["antagonists"] += A.threat()
threats["events"] = 0
for(var/r in SSevents.running)
var/datum/round_event/R = r
threats["events"] += R.threat()
threats["players"] = 0
SEND_SIGNAL(src, COMSIG_THREAT_CALC, threats)
for(var/m in GLOB.player_list)
var/mob/M = m
if (M?.mind?.assigned_role && M.stat != DEAD)
var/datum/job/J = SSjob.GetJob(M.mind.assigned_role)
if(J)
if(length(M.mind.antag_datums))
threats["players"] += J.GetThreat()
else
threats["players"] -= J.GetThreat()
else if(M?.stat == DEAD && !M.voluntary_ghosted)
threats["dead_players"] += 1
current_threat = 0
for(var/threat_type in threats)
current_threat += threats[threat_type]
threat_history += "[world.time]"
threat_history["[world.time]"] = current_threat
/datum/controller/subsystem/activity/proc/get_average_threat()
if(!length(threat_history))
return 0
var/total_weight = 0
var/total_amt = 0
for(var/i in 1 to threat_history.len-1)
var/weight = (text2num(threat_history[i+1])-text2num(threat_history[i]))
total_weight += weight
total_amt += weight * (threat_history[threat_history[i]])
return round(total_amt / total_weight,0.1)
/datum/controller/subsystem/activity/proc/get_max_threat()
. = 0
for(var/threat in threat_history)
. = max(threat_history[threat], .)
/datum/controller/subsystem/activity/proc/on_explosion(datum/source, atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
if(!("explosions" in deferred_threats))
deferred_threats["explosions"] = 0
var/area/A = get_area(epicenter)
if(is_station_level(epicenter.z) && (A.area_flags & BLOBS_ALLOWED) && !istype(A, /area/asteroid))
deferred_threats["explosions"] += devastation_range**2 + heavy_impact_range**2 / 4 + light_impact_range**2 / 8 // 75 for a maxcap
/datum/controller/subsystem/activity/proc/on_death(datum/source, mob/M, gibbed)
if(!("crew_deaths" in deferred_threats))
deferred_threats["crew_deaths"] = 0
if(M?.mind && SSjob.GetJob(M.mind.assigned_role))
deferred_threats["crew_deaths"] += 1
+89
View File
@@ -0,0 +1,89 @@
SUBSYSTEM_DEF(blackmarket)
name = "Blackmarket"
flags = SS_BACKGROUND
init_order = INIT_ORDER_DEFAULT
// Descriptions for each shipping method.
var/shipping_method_descriptions = list(
SHIPPING_METHOD_LAUNCH="Launches the item at the station from space, cheap but you might not recieve your item at all.",
SHIPPING_METHOD_LTSRBT="Long-To-Short-Range-Bluespace-Transceiver, a machine that recieves items outside the station and then teleports them to the location of the uplink.",
SHIPPING_METHOD_TELEPORT="Teleports the item in a random area in the station, you get 60 seconds to get there first though."
)
var/list/datum/blackmarket_market/markets = list() // List of all existing markets.
var/list/obj/machinery/ltsrbt/telepads = list() // List of existing ltsrbts.
var/list/queued_purchases = list() // Currently queued purchases.
/datum/controller/subsystem/blackmarket/Initialize(timeofday)
for(var/market in subtypesof(/datum/blackmarket_market))
markets[market] += new market
for(var/item in subtypesof(/datum/blackmarket_item))
var/datum/blackmarket_item/I = new item()
if(!I.item)
continue
for(var/M in I.markets)
if(!markets[M])
stack_trace("SSblackmarket: Item [I] available in market that does not exist.")
continue
markets[M].add_item(item)
qdel(I)
. = ..()
/datum/controller/subsystem/blackmarket/fire(resumed)
while(length(queued_purchases))
var/datum/blackmarket_purchase/purchase = queued_purchases[1]
queued_purchases.Cut(1,2)
if(!purchase.uplink || QDELETED(purchase.uplink)) // Uh oh, uplink is gone. We will just keep the money and you will not get your order.
queued_purchases -= purchase
qdel(purchase)
continue
switch(purchase.method)
if(SHIPPING_METHOD_LTSRBT) // Find a ltsrbt pad and make it handle the shipping.
if(!telepads.len)
continue
var/free_pad_found = FALSE // Prioritize pads that don't have a cooldown active.
for(var/obj/machinery/ltsrbt/pad in telepads)
if(pad.recharge_cooldown)
continue
pad.add_to_queue(purchase)
queued_purchases -= purchase
free_pad_found = TRUE
break
if(free_pad_found)
continue
var/obj/machinery/ltsrbt/pad = pick(telepads)
to_chat(recursive_loc_check(purchase.uplink.loc, /mob), "<span class='notice'>[purchase.uplink] flashes a message noting that the order is being processed by [pad].</span>")
queued_purchases -= purchase
pad.add_to_queue(purchase)
if(SHIPPING_METHOD_TELEPORT) // Get random area, throw it somewhere there.
var/turf/targetturf = get_safe_random_station_turf()
if (!targetturf) // This shouldn't happen.
continue
to_chat(recursive_loc_check(purchase.uplink.loc, /mob), "<span class='notice'>[purchase.uplink] flashes a message noting that the order is being teleported to [get_area(targetturf)] in 60 seconds.</span>")
addtimer(CALLBACK(src, /datum/controller/subsystem/blackmarket/proc/fake_teleport, purchase.entry.spawn_item(), targetturf), 60 SECONDS) // do_teleport does not want to teleport items from nullspace, so it just forceMoves and does sparks.
queued_purchases -= purchase
qdel(purchase)
if(SHIPPING_METHOD_LAUNCH) // Get the current location of the uplink if it exists, then throws the item from space at the station from a random direction.
var/startSide = pick(GLOB.cardinals)
var/turf/T = get_turf(purchase.uplink)
var/pickedloc = spaceDebrisStartLoc(startSide, T.z)
var/atom/movable/item = purchase.entry.spawn_item(pickedloc)
item.throw_at(purchase.uplink, 3, 3, spin = FALSE)
to_chat(recursive_loc_check(purchase.uplink.loc, /mob), "<span class='notice'>[purchase.uplink] flashes a message noting the order is being launched at the station from [dir2text(startSide)].</span>")
queued_purchases -= purchase
qdel(purchase)
if(MC_TICK_CHECK)
break
/datum/controller/subsystem/blackmarket/proc/fake_teleport(atom/movable/item, turf/target) // Used to make a teleportation effect as do_teleport does not like moving items from nullspace.
item.forceMove(target)
var/datum/effect_system/spark_spread/sparks = new
sparks.set_up(5, 1, target)
sparks.attach(item)
sparks.start()
/datum/controller/subsystem/blackmarket/proc/queue_item(datum/blackmarket_purchase/P) // Used to add /datum/blackmarket_purchase to queued_purchases var. Returns TRUE when queued.
if(P.method == SHIPPING_METHOD_LTSRBT && !telepads.len)
return FALSE
queued_purchases += P
return TRUE
+21 -34
View File
@@ -490,42 +490,29 @@ SUBSYSTEM_DEF(job)
job.after_spawn(H, M, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not.
equip_loadout(N, H, TRUE)//CIT CHANGE - makes players spawn with in-backpack loadout items properly. A little hacky but it works
if(ishuman(H) && H.client && N)
if(H.client && H.client.prefs && length(H.client.prefs.tcg_cards))
var/obj/item/tcgcard_binder/binder = new(get_turf(H))
H.equip_to_slot_if_possible(binder, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)
for(var/card_type in H.client.prefs.tcg_cards)
if(card_type)
if(islist(H.client.prefs.tcg_cards[card_type]))
for(var/duplicate in H.client.prefs.tcg_cards[card_type])
var/obj/item/tcg_card/card = new(get_turf(H), card_type, duplicate)
card.forceMove(binder)
binder.cards.Add(card)
else
var/obj/item/tcg_card/card = new(get_turf(H), card_type, H.client.prefs.tcg_cards[card_type])
var/list/tcg_cards
if(ishuman(H))
if(length(H.client?.prefs?.tcg_cards))
tcg_cards = H.client.prefs.tcg_cards
else if(length(N?.client?.prefs?.tcg_cards))
tcg_cards = N.client.prefs.tcg_cards
if(tcg_cards)
var/obj/item/tcgcard_binder/binder = new(get_turf(H))
H.equip_to_slot_if_possible(binder, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)
for(var/card_type in N.client.prefs.tcg_cards)
if(card_type)
if(islist(H.client.prefs.tcg_cards[card_type]))
for(var/duplicate in N.client.prefs.tcg_cards[card_type])
var/obj/item/tcg_card/card = new(get_turf(H), card_type, duplicate)
card.forceMove(binder)
binder.cards.Add(card)
binder.check_for_exodia()
if(length(H.client.prefs.tcg_decks))
binder.decks = H.client.prefs.tcg_decks
else
if(H && N.client.prefs && length(N.client.prefs.tcg_cards))
var/obj/item/tcgcard_binder/binder = new(get_turf(H))
H.equip_to_slot_if_possible(binder, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)
for(var/card_type in N.client.prefs.tcg_cards)
if(card_type)
if(islist(H.client.prefs.tcg_cards[card_type]))
for(var/duplicate in N.client.prefs.tcg_cards[card_type])
var/obj/item/tcg_card/card = new(get_turf(H), card_type, duplicate)
card.forceMove(binder)
binder.cards.Add(card)
else
var/obj/item/tcg_card/card = new(get_turf(H), card_type, N.client.prefs.tcg_cards[card_type])
card.forceMove(binder)
binder.cards.Add(card)
binder.check_for_exodia()
if(length(N.client.prefs.tcg_decks))
binder.decks = N.client.prefs.tcg_decks
else
var/obj/item/tcg_card/card = new(get_turf(H), card_type, N.client.prefs.tcg_cards[card_type])
card.forceMove(binder)
binder.cards.Add(card)
binder.check_for_exodia()
if(length(N.client.prefs.tcg_decks))
binder.decks = N.client.prefs.tcg_decks
return H
/*
+26 -5
View File
@@ -34,6 +34,9 @@ SUBSYSTEM_DEF(mapping)
var/list/reservation_ready = list()
var/clearing_reserved_turfs = FALSE
///All possible biomes in assoc list as type || instance
var/list/biomes = list()
// Z-manager stuff
var/station_start // should only be used for maploading-related tasks
var/space_levels_so_far = 0
@@ -79,10 +82,12 @@ SUBSYSTEM_DEF(mapping)
config = old_config
GLOB.year_integer += config.year_offset
GLOB.announcertype = (config.announcertype == "standard" ? (prob(1) ? "medibot" : "classic") : config.announcertype)
initialize_biomes()
loadWorld()
repopulate_sorted_areas()
process_teleport_locs() //Sets up the wizard teleport locations
preloadTemplates()
#ifndef LOWMEMORYMODE
// Create space ruin levels
while (space_levels_so_far < config.space_ruin_levels)
@@ -92,15 +97,16 @@ SUBSYSTEM_DEF(mapping)
for (var/i in 1 to config.space_empty_levels)
++space_levels_so_far
empty_space = add_new_zlevel("Empty Area [space_levels_so_far]", list(ZTRAIT_LINKAGE = CROSSLINKED))
// and the transit level
transit = add_new_zlevel("Transit/Reserved", list(ZTRAIT_RESERVED = TRUE))
// Pick a random away mission.
if(CONFIG_GET(flag/roundstart_away))
createRandomZlevel()
// Pick a random VR level.
// Load the virtual reality hub
if(CONFIG_GET(flag/roundstart_vr))
to_chat(world, "<span class='boldannounce'>Loading virtual reality...</span>")
createRandomZlevel(VIRT_REALITY_NAME, list(ZTRAIT_AWAY = TRUE, ZTRAIT_VR = TRUE), GLOB.potential_vr_levels)
to_chat(world, "<span class='boldannounce'>Virtual reality loaded.</span>")
// Generate mining ruins
loading_ruins = TRUE
@@ -115,7 +121,7 @@ SUBSYSTEM_DEF(mapping)
// needs to be whitelisted for underground too so place_below ruins work
seedRuins(ice_ruins, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/surface/outdoors/unexplored, /area/icemoon/underground/unexplored), ice_ruins_templates)
for (var/ice_z in ice_ruins)
spawn_rivers(ice_z, 4, /turf/open/transparent/openspace/icemoon, /area/icemoon/surface/outdoors/unexplored/rivers)
spawn_rivers(ice_z, 4, /turf/open/openspace/icemoon, /area/icemoon/surface/outdoors/unexplored/rivers)
var/list/ice_ruins_underground = levels_by_trait(ZTRAIT_ICE_RUINS_UNDERGROUND)
if (ice_ruins_underground.len)
@@ -133,8 +139,13 @@ SUBSYSTEM_DEF(mapping)
if (station_ruins.len)
seedRuins(station_ruins, (SSmapping.config.station_ruin_budget < 0) ? CONFIG_GET(number/station_space_budget) : SSmapping.config.station_ruin_budget, list(/area/space/station_ruins), station_ruins_templates)
SSmapping.seedStation()
loading_ruins = FALSE
#endif
// Run map generation after ruin generation to prevent issues
run_map_generation()
// Add the transit level
transit = add_new_zlevel("Transit/Reserved", list(ZTRAIT_RESERVED = TRUE))
repopulate_sorted_areas()
// Set up Z-level transitions.
setup_map_transitions()
@@ -320,7 +331,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
for(var/area/A in world)
if (is_type_in_typecache(A, station_areas_blacklist))
continue
if (!A.contents.len || !A.unique)
if (!A.contents.len || !(A.area_flags & UNIQUE_AREA))
continue
var/turf/picked = A.contents[1]
if (is_station_level(picked.z))
@@ -329,6 +340,10 @@ GLOBAL_LIST_EMPTY(the_station_areas)
if(!GLOB.the_station_areas.len)
log_world("ERROR: Station areas list failed to generate!")
/datum/controller/subsystem/mapping/proc/run_map_generation()
for(var/area/A in world)
A.RunGeneration()
/datum/controller/subsystem/mapping/proc/maprotate()
var/players = GLOB.clients.len
var/list/mapvotes = list()
@@ -584,6 +599,12 @@ GLOBAL_LIST_EMPTY(the_station_areas)
used_turfs.Cut()
reserve_turfs(clearing)
///Initialize all biomes, assoc as type || instance
/datum/controller/subsystem/mapping/proc/initialize_biomes()
for(var/biome_path in subtypesof(/datum/biome))
var/datum/biome/biome_instance = new biome_path()
biomes[biome_path] += biome_instance
/datum/controller/subsystem/mapping/proc/reg_in_areas_in_z(list/areas)
for(var/B in areas)
var/area/A = B
+1 -1
View File
@@ -1,7 +1,7 @@
SUBSYSTEM_DEF(min_spawns)
name = "Minimum Spawns" /// this hot steaming pile of garbage makes sure theres a minimum of tendrils scattered around
init_order = INIT_ORDER_DEFAULT
flags = SS_BACKGROUND | SS_NO_FIRE
flags = SS_NO_FIRE | SS_NO_INIT
wait = 2
var/where_we_droppin_boys_iterations = 0
var/snaxi_snowflake_check = FALSE
@@ -6,7 +6,7 @@
var/list/saved_chaos = list(5,5,5)
var/list/saved_dynamic_rules = list(list(),list(),list())
var/list/saved_storytellers = list("foo","bar","baz")
var/list/average_dynamic_threat = 50
var/average_threat = 50
var/list/saved_maps
/datum/controller/subsystem/persistence/SaveServerPersistence()
@@ -38,9 +38,10 @@
saved_chaos[3] = saved_chaos[2]
saved_chaos[2] = saved_chaos[1]
saved_chaos[1] = SSticker.mode.get_chaos()
average_threat = (SSactivity.get_average_threat() + average_threat) / 2
json_file = file("data/RecentChaos.json")
file_data = list()
file_data["data"] = saved_chaos
file_data["data"] = saved_chaos + average_threat
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
@@ -49,10 +50,9 @@
saved_storytellers[3] = saved_storytellers[2]
saved_storytellers[2] = saved_storytellers[1]
saved_storytellers[1] = mode.storyteller.name
average_dynamic_threat = (mode.max_threat + average_dynamic_threat) / 2
var/json_file = file("data/RecentStorytellers.json")
var/list/file_data = list()
file_data["data"] = saved_storytellers + average_dynamic_threat
file_data["data"] = saved_storytellers
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
@@ -94,6 +94,9 @@
if(!json)
return
saved_chaos = json["data"]
if(saved_chaos.len > 3)
average_threat = saved_chaos[4]
saved_chaos.len = 3
/datum/controller/subsystem/persistence/proc/LoadRecentRulesets()
var/json_file = file("data/RecentRulesets.json")
@@ -112,9 +115,6 @@
if(!json)
return
saved_storytellers = json["data"]
if(saved_storytellers.len > 3)
average_dynamic_threat = saved_storytellers[4]
saved_storytellers.len = 3
/datum/controller/subsystem/persistence/proc/LoadRecentMaps()
var/json_file = file("data/RecentMaps.json")
@@ -47,5 +47,5 @@ SUBSYSTEM_DEF(processing)
* If you override this do not call parent, as it will return PROCESS_KILL. This is done to prevent objects that dont override process() from staying in the processing list
*/
/datum/proc/process(delta_time)
set waitfor = FALSE
// SHOULD_NOT_SLEEP(TRUE)
return PROCESS_KILL
+2 -2
View File
@@ -609,9 +609,9 @@ SUBSYSTEM_DEF(ticker)
var/list/ded = SSblackbox.first_death
if(ded.len)
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]"
news_message += "\nNT 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!"
news_message += "\nNT Sanctioned Psykers proudly confirm reports that nobody died this shift!"
if(news_message)
send2otherserver(news_source, news_message,"News_Report")