From bc0d14c193b5bc229203cde2c54adf30e1570094 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Mon, 17 Sep 2018 04:55:03 -0500 Subject: [PATCH] Continual updates until merged --- .gitignore | 1 + code/__DEFINES/citadel_defines.dm | 5 + code/__DEFINES/research.dm | 2 + code/__DEFINES/rust_g.dm | 3 + code/__DEFINES/subsystems.dm | 1 + code/__HELPERS/roundend.dm | 9 +- code/__HELPERS/typelists.dm | 43 +++++++ code/_globalvars/bitfields.dm | 3 + code/controllers/master.dm | 8 +- code/controllers/subsystem/job.dm | 1 + code/controllers/subsystem/mapping.dm | 8 +- code/controllers/subsystem/title.dm | 10 +- code/datums/helper_datums/getrev.dm | 111 +++++++++--------- code/datums/shuttles.dm | 32 ++--- code/game/atoms.dm | 6 +- code/game/machinery/autolathe.dm | 3 +- code/game/machinery/doppler_array.dm | 43 +++++-- code/game/machinery/syndicatebeacon.dm | 2 +- code/game/objects/items.dm | 8 +- code/game/objects/items/devices/powersink.dm | 6 +- code/game/objects/structures/grille.dm | 4 +- code/game/objects/structures/window.dm | 76 +++++------- code/game/turfs/simulated/floor.dm | 6 +- .../turfs/simulated/floor/mineral_floor.dm | 3 +- code/game/turfs/simulated/minerals.dm | 14 +-- code/game/world.dm | 9 +- code/modules/admin/NewBan.dm | 4 +- code/modules/admin/sql_message_system.dm | 3 + code/modules/antagonists/cult/runes.dm | 3 +- code/modules/goonchat/browserOutput.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 3 + code/modules/mob/living/emote.dm | 19 ++- code/modules/ninja/suit/ninjaDrainAct.dm | 4 +- code/modules/power/apc.dm | 2 +- code/modules/power/cable.dm | 24 +++- code/modules/power/power.dm | 26 +++- code/modules/power/powernet.dm | 4 +- code/modules/power/singularity/emitter.dm | 6 +- code/modules/research/techweb/_techweb.dm | 2 +- config/game_options.txt | 1 + dependencies.sh | 4 +- .../modules/mob/living/carbon/human/human.dm | 14 +++ .../carbon/human/species_types/furrypeople.dm | 1 + rust_g.dll | Bin 410624 -> 1159168 bytes sound/voice/catpeople/nyaha.ogg | Bin 0 -> 8711 bytes sound/voice/catpeople/nyahaha1.ogg | Bin 0 -> 13027 bytes sound/voice/catpeople/nyahaha2.ogg | Bin 0 -> 11944 bytes sound/voice/catpeople/nyahehe.ogg | Bin 0 -> 9792 bytes tgstation.dme | 2 + tgui/build_assets.bat | 2 +- tgui/install_dependencies.bat | 12 +- tools/travis/build_tools.sh | 2 +- tools/travis/install_build_tools.sh | 1 - 53 files changed, 358 insertions(+), 200 deletions(-) create mode 100644 code/__HELPERS/typelists.dm create mode 100644 modular_citadel/code/modules/mob/living/carbon/human/human.dm create mode 100644 sound/voice/catpeople/nyaha.ogg create mode 100644 sound/voice/catpeople/nyahaha1.ogg create mode 100644 sound/voice/catpeople/nyahaha2.ogg create mode 100644 sound/voice/catpeople/nyahehe.ogg diff --git a/.gitignore b/.gitignore index ce50b70af5..f67727febb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ #Ignore everything in datafolder and subdirectories /data/**/* +/tmp/**/* #Ignore byond config folder. /cfg/**/* diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm index 136a52acf7..7744b24d0f 100644 --- a/code/__DEFINES/citadel_defines.dm +++ b/code/__DEFINES/citadel_defines.dm @@ -97,6 +97,11 @@ //Citadel istypes #define isborer(A) (istype(A, /mob/living/simple_animal/borer)) #define isipcperson(A) (is_species(A, /datum/species/ipc)) +#define ismammal(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/mammal) ) +#define isavian(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/avian) ) +#define isaquatic(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/aquatic) ) +#define isinsect(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/insect) ) +#define isxenoperson(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/xeno) ) #define CITADEL_MENTOR_OOC_COLOUR "#224724" diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm index 16776ed8e2..95b89ae04e 100644 --- a/code/__DEFINES/research.dm +++ b/code/__DEFINES/research.dm @@ -71,3 +71,5 @@ #define TECHWEB_POINT_TYPE_LIST_ASSOCIATIVE_NAMES list(\ TECHWEB_POINT_TYPE_GENERIC = "General Research"\ ) + +#define TECHWEB_BOMB_POINTCAP 50000 //Adjust as needed; Stops toxins from nullifying RND progression mechanics. Current Value Cap Radius: 100 diff --git a/code/__DEFINES/rust_g.dm b/code/__DEFINES/rust_g.dm index a905fd5186..ccd5b92c79 100644 --- a/code/__DEFINES/rust_g.dm +++ b/code/__DEFINES/rust_g.dm @@ -3,5 +3,8 @@ #define rustg_dmi_strip_metadata(fname) call(RUST_G, "dmi_strip_metadata")(fname) +#define rustg_git_revparse(rev) call(RUST_G, "rg_git_revparse")(rev) +#define rustg_git_commit_date(rev) call(RUST_G, "rg_git_commit_date")(rev) + #define rustg_log_write(fname, text) call(RUST_G, "log_write")(fname, text) /proc/rustg_log_close_all() return call(RUST_G, "log_close_all")() diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index b60894edea..f54a0542f4 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -51,6 +51,7 @@ // Subsystems shutdown in the reverse of the order they initialize in // The numbers just define the ordering, they are meaningless otherwise. +#define INIT_ORDER_TITLE 20 #define INIT_ORDER_GARBAGE 19 #define INIT_ORDER_DBCORE 18 #define INIT_ORDER_BLACKBOX 17 diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 84d4a40135..c3b7a6bfed 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -531,10 +531,11 @@ return sync_ranks_with_db() var/list/sql_admins = list() - for(var/datum/admins/A in GLOB.protected_admins) - var/sql_ckey = sanitizeSQL(A.owner.ckey) + for(var/i in GLOB.protected_admins) + var/datum/admins/A = GLOB.protected_admins[i] + var/sql_ckey = sanitizeSQL(A.target) var/sql_rank = sanitizeSQL(A.rank.name) - sql_admins = list(list("ckey" = "'[sql_ckey]'", "rank" = "'[sql_rank]'")) + sql_admins += list(list("ckey" = "'[sql_ckey]'", "rank" = "'[sql_rank]'")) SSdbcore.MassInsert(format_table_name("admin"), sql_admins, duplicate_key = TRUE) var/datum/DBQuery/query_admin_rank_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] p INNER JOIN [format_table_name("admin")] a ON p.ckey = a.ckey SET p.lastadminrank = a.rank") query_admin_rank_update.Execute() @@ -582,4 +583,4 @@ qdel(query_update_everything_ranks) return qdel(query_update_everything_ranks) - qdel(query_check_everything_ranks) + qdel(query_check_everything_ranks) \ No newline at end of file diff --git a/code/__HELPERS/typelists.dm b/code/__HELPERS/typelists.dm new file mode 100644 index 0000000000..f271b9204d --- /dev/null +++ b/code/__HELPERS/typelists.dm @@ -0,0 +1,43 @@ +GLOBAL_LIST_EMPTY(typelists) + +#ifndef TESTING + +/datum/proc/typelist(key, list/values = list()) + var/list/mytypelist = GLOB.typelists[type] || (GLOB.typelists[type] = list()) + return mytypelist[key] || (mytypelist[key] = values.Copy()) + +#else +// mostly the same code as above, just more verbose, slower and has tallying for saved lists +/datum/proc/typelist(key, list/values) + if (!values) + values = list() + GLOB.typelistkeys |= key + if (GLOB.typelists[type]) + if (GLOB.typelists[type][key]) + GLOB.typelists[type]["[key]-saved"]++ + return GLOB.typelists[type][key] + else + GLOB.typelists[type][key] = values.Copy() + else + GLOB.typelists[type] = list() + GLOB.typelists[type][key] = values.Copy() + return GLOB.typelists[type][key] + +GLOBAL_LIST_EMPTY(typelistkeys) + +/proc/tallytypelistsavings() + var/savings = list() + var/saveditems = list() + for (var/key in GLOB.typelistkeys) + savings[key] = 0 + saveditems[key] = 0 + + for (var/type in GLOB.typelists) + for (var/saving in savings) + if (GLOB.typelists[type]["[saving]-saved"]) + savings[saving] += GLOB.typelists[type]["[saving]-saved"] + saveditems[saving] += (GLOB.typelists[type]["[saving]-saved"] * length(GLOB.typelists[type][saving])) + + for (var/saving in savings) + to_chat(world, "Savings for [saving]: [savings[saving]] lists, [saveditems[saving]] items") +#endif \ No newline at end of file diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 021ea298a8..0760b81927 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -164,4 +164,7 @@ GLOBAL_LIST_INIT(bitfields, list( "TRANSPARENT" = TRANSPARENT, "AMOUNT_VISIBLE" = AMOUNT_VISIBLE, ), + "car_traits" = list( + "CAN_KIDNAP" = CAN_KIDNAP, + ), )) diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 0cc0c622d7..125da84a30 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -164,12 +164,15 @@ GLOBAL_REAL(Master, /datum/controller/master) = new // Please don't stuff random bullshit here, // Make a subsystem, give it the SS_NO_FIRE flag, and do your work in it's Initialize() -/datum/controller/master/Initialize(delay, init_sss) +/datum/controller/master/Initialize(delay, init_sss, tgs_prime) set waitfor = 0 if(delay) sleep(delay) + if(tgs_prime) + world.TgsInitializationComplete() + if(init_sss) init_subtypes(/datum/controller/subsystem, subsystems) @@ -202,7 +205,6 @@ GLOBAL_REAL(Master, /datum/controller/master) = new world.fps = CONFIG_GET(number/fps) var/initialized_tod = REALTIMEOFDAY - world.TgsInitializationComplete() if(sleep_offline_after_initializations) world.sleep_offline = TRUE sleep(1) @@ -612,4 +614,4 @@ GLOBAL_REAL(Master, /datum/controller/master) = new if (client_count < CONFIG_GET(number/mc_tick_rate/disable_high_pop_mc_mode_amount)) processing = CONFIG_GET(number/mc_tick_rate/base_mc_tick_rate) else if (client_count > CONFIG_GET(number/mc_tick_rate/high_pop_mc_mode_amount)) - processing = CONFIG_GET(number/mc_tick_rate/high_pop_mc_tick_rate) + processing = CONFIG_GET(number/mc_tick_rate/high_pop_mc_tick_rate) \ No newline at end of file diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 75d214722a..5e960e0f96 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -15,6 +15,7 @@ SUBSYSTEM_DEF(job) var/overflow_role = "Assistant" /datum/controller/subsystem/job/Initialize(timeofday) + SSmapping.HACK_LoadMapConfig() if(!occupations.len) SetupOccupations() if(CONFIG_GET(flag/load_jobs_from_txt)) diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 3a25d889e0..9b70cb9117 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -34,17 +34,17 @@ SUBSYSTEM_DEF(mapping) var/datum/space_level/transit var/datum/space_level/empty_space -/datum/controller/subsystem/mapping/PreInit() +//dlete dis once #39770 is resolved +/datum/controller/subsystem/mapping/proc/HACK_LoadMapConfig() if(!config) #ifdef FORCE_MAP config = load_map_config(FORCE_MAP) #else config = load_map_config(error_if_missing = FALSE) #endif - return ..() - /datum/controller/subsystem/mapping/Initialize(timeofday) + HACK_LoadMapConfig() if(initialized) return if(config.defaulted) @@ -493,4 +493,4 @@ GLOBAL_LIST_EMPTY(the_station_areas) clearing |= used_turfs //used turfs is an associative list, BUT, reserve_turfs() can still handle it. If the code above works properly, this won't even be needed as the turfs would be freed already. unused_turfs.Cut() used_turfs.Cut() - reserve_turfs(clearing) + reserve_turfs(clearing) \ No newline at end of file diff --git a/code/controllers/subsystem/title.dm b/code/controllers/subsystem/title.dm index 94dff9b742..b19cf47693 100644 --- a/code/controllers/subsystem/title.dm +++ b/code/controllers/subsystem/title.dm @@ -1,13 +1,14 @@ SUBSYSTEM_DEF(title) name = "Title Screen" - flags = SS_NO_FIRE|SS_NO_INIT + flags = SS_NO_FIRE + init_order = INIT_ORDER_TITLE var/file_path var/icon/icon var/icon/previous_icon var/turf/closed/indestructible/splashscreen/splash_turf -/datum/controller/subsystem/title/PreInit() +/datum/controller/subsystem/title/Initialize() if(file_path && icon) return @@ -21,6 +22,7 @@ SUBSYSTEM_DEF(title) var/list/title_screens = list() var/use_rare_screens = prob(1) + SSmapping.HACK_LoadMapConfig() for(var/S in provisional_title_screens) var/list/L = splittext(S,"+") if((L.len == 1 && L[1] != "blank.png")|| (L.len > 1 && ((use_rare_screens && lowertext(L[1]) == "rare") || (lowertext(L[1]) == lowertext(SSmapping.config.map_name))))) @@ -39,6 +41,8 @@ SUBSYSTEM_DEF(title) if(splash_turf) splash_turf.icon = icon + return ..() + /datum/controller/subsystem/title/vv_edit_var(var_name, var_value) . = ..() if(.) @@ -62,4 +66,4 @@ SUBSYSTEM_DEF(title) icon = SStitle.icon splash_turf = SStitle.splash_turf file_path = SStitle.file_path - previous_icon = SStitle.previous_icon + previous_icon = SStitle.previous_icon \ No newline at end of file diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index 46de2c5c92..a719223ea7 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -1,44 +1,40 @@ /datum/getrev - var/originmastercommit - var/commit - var/list/testmerge = list() + var/commit // git rev-parse HEAD var/date + var/originmastercommit // git rev-parse origin/master + var/list/testmerge = list() /datum/getrev/New() testmerge = world.TgsTestMerges() - log_world("Running /tg/ revision:") var/datum/tgs_revision_information/revinfo = world.TgsRevision() if(revinfo) commit = revinfo.commit originmastercommit = revinfo.origin_commit else - var/list/logs = world.file2list(".git/logs/HEAD") - if(logs.len) - logs = splittext(logs[logs.len - 1], " ") - date = unix2date(text2num(logs[5])) - commit = logs[2] - log_world("[commit]: [date]") - else - log_world("Unable to read git logs, revision information not available") - originmastercommit = commit = "Unknown" - date = unix2date(world.timeofday) - return - logs = world.file2list(".git/logs/refs/remotes/origin/master") - if(logs.len) - originmastercommit = splittext(logs[logs.len - 1], " ")[2] + commit = rustg_git_revparse("HEAD") + if(commit) + date = rustg_git_commit_date(commit) + originmastercommit = rustg_git_revparse("origin/master") - if(testmerge.len) - log_world(commit) - for(var/line in testmerge) - if(line) - var/datum/tgs_revision_information/test_merge/tm = line - var/tmcommit = tm.commit - log_world("Test merge active of PR #[tm.number] commit [tmcommit]") - SSblackbox.record_feedback("nested tally", "testmerged_prs", 1, list("[tm.number]", "[tmcommit]")) - if(originmastercommit) - log_world("Based off origin/master commit [originmastercommit]") - else if(originmastercommit) - log_world(originmastercommit) + // goes to DD log and config_error.txt + log_world(get_log_message()) + +/datum/getrev/proc/get_log_message() + var/list/msg = list() + msg += "Running /tg/ revision: [date]" + if(originmastercommit) + msg += "origin/master: [originmastercommit]" + + for(var/line in testmerge) + var/datum/tgs_revision_information/test_merge/tm = line + msg += "Test merge active of PR #[tm.number] commit [tm.commit]" + + if(commit && commit != originmastercommit) + msg += "HEAD: [commit]" + else if(!originmastercommit) + msg += "No commit information" + + return msg.Join("\n") /datum/getrev/proc/GetTestMergeInfo(header = TRUE) if(!testmerge.len) @@ -57,28 +53,34 @@ set name = "Show Server Revision" set desc = "Check the current server code revision" + var/list/msg = list("") + // Round ID if(GLOB.round_id) - to_chat(src, "Round ID: [GLOB.round_id]") - if(GLOB.revdata.originmastercommit) - to_chat(src, "Server revision compiled on: [GLOB.revdata.date]") - var/prefix = "" - if(GLOB.revdata.testmerge.len) - to_chat(src, GLOB.revdata.GetTestMergeInfo()) - prefix = "Based off origin/master commit: " - var/pc = GLOB.revdata.originmastercommit - to_chat(src, "[prefix][copytext(pc, 1, min(length(pc), 11))]") - else - to_chat(src, "Master revision unknown") - to_chat(src, "Revision: [GLOB.revdata.commit]") + msg += "Round ID: [GLOB.round_id]" + + // Revision information + var/datum/getrev/revdata = GLOB.revdata + msg += "Server revision compiled on: [revdata.date]" + var/pc = revdata.originmastercommit + if(pc) + msg += "Master commit: [pc]" + if(revdata.testmerge.len) + msg += revdata.GetTestMergeInfo() + if(revdata.commit && revdata.commit != revdata.originmastercommit) + msg += "Local commit: [revdata.commit]" + else if(!pc) + msg += "No commit information" if(world.TgsAvailable()) - to_chat(src, "Server tools version: [world.TgsVersion()]") - to_chat(src, "Current Informational Settings:") - to_chat(src, "Protect Authority Roles From Traitor: [CONFIG_GET(flag/protect_roles_from_antagonist)]") - to_chat(src, "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]") - to_chat(src, "Enforce Human Authority: [CONFIG_GET(flag/enforce_human_authority)]") - to_chat(src, "Allow Latejoin Antagonists: [CONFIG_GET(flag/allow_latejoin_antagonists)]") - to_chat(src, "Enforce Continuous Rounds: [length(CONFIG_GET(keyed_list/continuous))] of [config.modes.len] roundtypes") - to_chat(src, "Allow Midround Antagonists: [length(CONFIG_GET(keyed_list/midround_antag))] of [config.modes.len] roundtypes") + msg += "Server tools version: [world.TgsVersion()]" + + // Game mode odds + msg += "
Current Informational Settings:" + msg += "Protect Authority Roles From Traitor: [CONFIG_GET(flag/protect_roles_from_antagonist)]" + msg += "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]" + msg += "Enforce Human Authority: [CONFIG_GET(flag/enforce_human_authority)]" + msg += "Allow Latejoin Antagonists: [CONFIG_GET(flag/allow_latejoin_antagonists)]" + msg += "Enforce Continuous Rounds: [length(CONFIG_GET(keyed_list/continuous))] of [config.modes.len] roundtypes" + msg += "Allow Midround Antagonists: [length(CONFIG_GET(keyed_list/midround_antag))] of [config.modes.len] roundtypes" if(CONFIG_GET(flag/show_game_type_odds)) var/list/probabilities = CONFIG_GET(keyed_list/probability) if(SSticker.IsRoundInProgress()) @@ -99,17 +101,18 @@ probs[ctag] = 1 prob_sum += probabilities[ctag] if(current_odds_differ) - to_chat(src, "Game Mode Odds for current round:") + msg += "Game Mode Odds for current round:" for(var/ctag in probs) if(probabilities[ctag] > 0) var/percentage = round(probabilities[ctag] / prob_sum * 100, 0.1) - to_chat(src, "[ctag] [percentage]%") + msg += "[ctag] [percentage]%" - to_chat(src, "All Game Mode Odds:") + msg += "All Game Mode Odds:" var/sum = 0 for(var/ctag in probabilities) sum += probabilities[ctag] for(var/ctag in probabilities) if(probabilities[ctag] > 0) var/percentage = round(probabilities[ctag] / sum * 100, 0.1) - to_chat(src, "[ctag] [percentage]%") + msg += "[ctag] [percentage]%" + to_chat(src, msg.Join("
")) \ No newline at end of file diff --git a/code/datums/shuttles.dm b/code/datums/shuttles.dm index 8e6ce98fc7..39f6555db0 100644 --- a/code/datums/shuttles.dm +++ b/code/datums/shuttles.dm @@ -28,26 +28,30 @@ if(!cached_map) return + discover_port_offset() + + if(!cache) + cached_map = null + +/datum/map_template/shuttle/proc/discover_port_offset() var/key var/list/models = cached_map.grid_models for(key in models) if(findtext(models[key], "[/obj/docking_port/mobile]")) // Yay compile time checks break // This works by assuming there will ever only be one mobile dock in a template at most - - var/datum/grid_set/gset + for(var/i in cached_map.gridSets) - gset = i + var/datum/grid_set/gset = i var/ycrd = gset.ycrd for(var/line in gset.gridLines) - if(key != line) - ycrd-- - continue - port_x_offset = gset.xcrd - port_y_offset = ycrd - break - - if(!cache) - cached_map = null + var/xcrd = gset.xcrd + for(var/j in 1 to length(line) step cached_map.key_len) + if(key == copytext(line, j, j + cached_map.key_len)) + port_x_offset = xcrd + port_y_offset = ycrd + return + ++xcrd + --ycrd /datum/map_template/shuttle/load(turf/T, centered, register=TRUE) . = ..() @@ -67,7 +71,7 @@ if(register) port.register() if(isnull(port_x_offset)) - return + continue switch(port.dir) // Yeah this looks a little ugly but mappers had to do this in their head before if(NORTH) port.width = width @@ -519,4 +523,4 @@ /datum/map_template/shuttle/snowdin/excavation suffix = "excavation" - name = "Snowdin Excavation Elevator" + name = "Snowdin Excavation Elevator" \ No newline at end of file diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 4689361e71..2af31607ea 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -74,6 +74,9 @@ var/turf/T = loc T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways. + if (canSmoothWith) + canSmoothWith = typelist("canSmoothWith", canSmoothWith) + ComponentInitialize() return INITIALIZE_HINT_NORMAL @@ -694,9 +697,10 @@ Proc for attack log creation, because really why not /atom/movable/proc/get_filter(name) if(filter_data && filter_data[name]) return filters[filter_data.Find(name)] - + /atom/movable/proc/remove_filter(name) if(filter_data[name]) filter_data -= name update_filters() return TRUE + \ No newline at end of file diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 84059e8029..5a54ccd5df 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -201,6 +201,7 @@ else for(var/i=1, i<=multiplier, i++) var/obj/item/new_item = new being_built.build_path(A) + new_item.materials = new_item.materials.Copy() for(var/mat in materials_used) new_item.materials[mat] = materials_used[mat] / multiplier new_item.autolathe_crafted(src) @@ -379,4 +380,4 @@ //Called when the object is constructed by an autolathe //Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes /obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A) - return + return \ No newline at end of file diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 9d522f8f1c..7fb240c711 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -111,22 +111,39 @@ GLOBAL_LIST_EMPTY(doppler_arrays) return FALSE if(!istype(linked_techweb)) say("Warning: No linked research system!") - return - var/adjusted = orig_light - 10 - if(adjusted <= 0) + return + + var/point_gain = 0 + + /*****The Point Calculator*****/ + + if(orig_light < 10) say("Explosion not large enough for research calculations.") return - var/point_gain = techweb_scale_bomb(adjusted) - techweb_scale_bomb(linked_techweb.max_bomb_value) - if(point_gain <= 0) - say("Explosion not large enough for research calculations.") + else if(orig_light < 4500) + point_gain = (83300 * orig_light) / (orig_light + 3000) + else + point_gain = TECHWEB_BOMB_POINTCAP + + /*****The Point Capper*****/ + if(point_gain > linked_techweb.largest_bomb_value) + if(point_gain <= TECHWEB_BOMB_POINTCAP || linked_techweb.largest_bomb_value < TECHWEB_BOMB_POINTCAP) + var/old_tech_largest_bomb_value = linked_techweb.largest_bomb_value //held so we can pull old before we do math + linked_techweb.largest_bomb_value = point_gain + point_gain -= old_tech_largest_bomb_value + point_gain = min(point_gain,TECHWEB_BOMB_POINTCAP) + else + linked_techweb.largest_bomb_value = TECHWEB_BOMB_POINTCAP + point_gain = 1000 + + linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, point_gain) + say("Gained [point_gain] points from explosion dataset.") + + else //you've made smaller bombs + say("Data already captured. Aborting.") return - linked_techweb.max_bomb_value = adjusted - linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, point_gain) - say("Gained [point_gain] points from explosion dataset.") + /obj/machinery/doppler_array/research/science/Initialize() . = ..() - linked_techweb = SSresearch.science_tech - -/proc/techweb_scale_bomb(lightradius) - return (lightradius ** 0.5) * 3000 + linked_techweb = SSresearch.science_tech \ No newline at end of file diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index 6b78ca0319..a1ed7fb848 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -86,7 +86,7 @@ if(!active) return - if(surplus() > 1500) + if(surplus() >= 1500) add_load(1500) if(cooldown <= world.time) cooldown = world.time + 80 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index cb8386d8b2..455f4f4ab1 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -110,8 +110,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder! /obj/item/Initialize() - if (!materials) - materials = list() + + materials = typelist("materials", materials) + + if (attack_verb) + attack_verb = typelist("attack_verb", attack_verb) + . = ..() for(var/path in actions_types) new path(src) diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 1a5c7a9b43..5276655dda 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -122,8 +122,8 @@ // found a powernet, so drain up to max power from it - var/drained = min ( drain_rate, PN.avail ) - PN.load += drained + var/drained = min ( drain_rate, attached.newavail() ) + attached.add_delayedload(drained) power_drained += drained // if tried to drain more than available on powernet @@ -137,6 +137,8 @@ power_drained += 50 if(A.charging == 2) // If the cell was full A.charging = 1 // It's no longer full + if(drained >= drain_rate) + break if(power_drained > max_power * 0.98) if (!admins_warned) diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index dc5219b9ec..93ce26e0ae 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -270,8 +270,8 @@ var/obj/structure/cable/C = T.get_cable_node() if(C) playsound(src, 'sound/magic/lightningshock.ogg', 100, 1, extrarange = 5) - tesla_zap(src, 3, C.powernet.avail * 0.01, TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN | TESLA_ALLOW_DUPLICATES) //Zap for 1/100 of the amount of power. At a million watts in the grid, it will be as powerful as a tesla revolver shot. - C.powernet.load += C.powernet.avail * 0.0375 // you can gain up to 3.5 via the 4x upgrades power is halved by the pole so thats 2x then 1X then .5X for 3.5x the 3 bounces shock. + tesla_zap(src, 3, C.newavail() * 0.01, TESLA_MOB_DAMAGE | TESLA_OBJ_DAMAGE | TESLA_MOB_STUN | TESLA_ALLOW_DUPLICATES) //Zap for 1/100 of the amount of power. At a million watts in the grid, it will be as powerful as a tesla revolver shot. + C.add_delayedload(C.newavail() * 0.0375) // you can gain up to 3.5 via the 4x upgrades power is halved by the pole so thats 2x then 1X then .5X for 3.5x the 3 bounces shock. return ..() /obj/structure/grille/get_dumping_location(datum/component/storage/source,mob/user) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index f00fd08ee5..3dcf91ae8f 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -18,7 +18,6 @@ var/glass_type = /obj/item/stack/sheet/glass var/glass_amount = 1 var/mutable_appearance/crack_overlay - var/list/debris = list() can_be_unanchored = TRUE resistance_flags = ACID_PROOF armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) @@ -27,7 +26,6 @@ var/breaksound = "shatter" var/hitsound = 'sound/effects/Glasshit.ogg' var/rad_insulation = RAD_VERY_LIGHT_INSULATION - var/spawn_cleanable_shards = TRUE /obj/structure/window/examine(mob/user) ..() @@ -56,22 +54,8 @@ ini_dir = dir air_update_turf(1) - // Precreate our own debris - - var/shards = 1 if(fulltile) - shards++ setDir() - var/rods = 0 - if(reinf) - rods++ - if(fulltile) - rods++ - - for(var/i in 1 to shards) - debris += new /obj/item/shard(src) - if(rods) - debris += new /obj/item/stack/rods(src, rods) //windows only block while reinforced and fulltile, so we'll use the proc real_explosion_block = explosion_block @@ -98,8 +82,6 @@ /obj/structure/window/narsie_act() add_atom_colour(NARSIE_WINDOW_COLOUR, FIXED_COLOUR_PRIORITY) - for(var/obj/item/shard/shard in debris) - shard.add_atom_colour(NARSIE_WINDOW_COLOUR, FIXED_COLOUR_PRIORITY) /obj/structure/window/ratvar_act() if(!fulltile) @@ -288,16 +270,17 @@ if(!disassembled) playsound(src, breaksound, 70, 1) if(!(flags_1 & NODECONSTRUCT_1)) - if(spawn_cleanable_shards) - new /obj/effect/decal/cleanable/glass(get_turf(src)) - for(var/i in debris) - var/obj/item/I = i - I.forceMove(drop_location()) - transfer_fingerprints_to(I) - debris -= I + for(var/obj/item/shard/debris in spawnDebris(drop_location())) + transfer_fingerprints_to(debris) // transfer fingerprints to shards only qdel(src) update_nearby_icons() +/obj/structure/window/proc/spawnDebris(location) + . = list() + . += new /obj/item/shard(location) + . += new /obj/effect/decal/cleanable/glass(location) + if (reinf) + . += new /obj/item/stack/rods(location, (fulltile ? 2 : 1)) /obj/structure/window/proc/can_be_rotated(mob/user,rotation_type) if(anchored) @@ -425,7 +408,6 @@ explosion_block = 1 glass_type = /obj/item/stack/sheet/plasmaglass rad_insulation = RAD_NO_INSULATION - spawn_cleanable_shards = FALSE /obj/structure/window/plasma/spawner/east dir = EAST @@ -521,7 +503,6 @@ fulltile = TRUE flags_1 = PREVENT_CLICK_UNDER_1 smooth = SMOOTH_TRUE - canSmoothWith = list(/obj/structure/window/fulltile, /obj/structure/window/reinforced/fulltile, /obj/structure/window/reinforced/tinted/fulltile, /obj/structure/window/plasma/fulltile, /obj/structure/window/plasma/reinforced/fulltile) level = 3 glass_amount = 2 @@ -616,18 +597,15 @@ var/made_glow = FALSE /obj/structure/window/reinforced/clockwork/Initialize(mapload, direct) - if(fulltile) - made_glow = TRUE . = ..() - QDEL_LIST(debris) - var/amount_of_gears = 2 - if(fulltile) - new /obj/effect/temp_visual/ratvar/window(get_turf(src)) - amount_of_gears = 4 - for(var/i in 1 to amount_of_gears) - debris += new /obj/item/clockwork/alloy_shards/medium/gear_bit() change_construction_value(fulltile ? 2 : 1) +/obj/structure/window/reinforced/clockwork/spawnDebris(location) + . = list() + var/gearcount = fulltile ? 4 : 2 + for(var/i in 1 to gearcount) + . += new /obj/item/clockwork/alloy_shards/medium/gear_bit(location) + /obj/structure/window/reinforced/clockwork/setDir(direct) if(!made_glow) var/obj/effect/E = new /obj/effect/temp_visual/ratvar/window/single(get_turf(src)) @@ -646,7 +624,7 @@ /obj/structure/window/reinforced/clockwork/narsie_act() take_damage(rand(25, 75), BRUTE) - if(src) + if(!QDELETED(src)) var/previouscolor = color color = "#960000" animate(src, color = previouscolor, time = 8) @@ -666,6 +644,17 @@ level = 3 glass_amount = 2 +/obj/structure/window/reinforced/clockwork/spawnDebris(location) + . = list() + for(var/i in 1 to 4) + . += new /obj/item/clockwork/alloy_shards/medium/gear_bit(location) + +/obj/structure/window/reinforced/clockwork/Initialize(mapload, direct) + made_glow = TRUE + new /obj/effect/temp_visual/ratvar/window(get_turf(src)) + return ..() + + /obj/structure/window/reinforced/clockwork/fulltile/unanchored anchored = FALSE @@ -687,7 +676,6 @@ decon_speed = 10 CanAtmosPass = ATMOS_PASS_YES resistance_flags = FLAMMABLE - spawn_cleanable_shards = FALSE armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) breaksound = 'sound/items/poster_ripped.ogg' hitsound = 'sound/weapons/slashmiss.ogg' @@ -696,13 +684,13 @@ /obj/structure/window/paperframe/Initialize() . = ..() - QDEL_LIST(debris) - var/papers = rand(1,4) - debris += new /obj/item/stack/sheet/mineral/wood() - for(var/i in 1 to papers) - debris += new /obj/item/paper/natural() update_icon() +/obj/structure/window/paperframe/spawnDebris(location) + . = list(new /obj/item/stack/sheet/mineral/wood(location)) + for (var/i in 1 to rand(1,4)) + . += new /obj/item/paper/natural(location) + /obj/structure/window/paperframe/attack_hand(mob/user) . = ..() if(.) @@ -747,4 +735,4 @@ update_icon() return ..() - update_icon() + update_icon() \ No newline at end of file diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 777cbedd26..f658cafbeb 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -22,10 +22,8 @@ tiled_dirt = TRUE /turf/open/floor/Initialize(mapload) - if (!broken_states) - broken_states = list("damaged1", "damaged2", "damaged3", "damaged4", "damaged5") - if (!burnt_states) - burnt_states = list() + broken_states = typelist("broken_states", broken_states) + burnt_states = typelist("burnt_states", burnt_states) if(!broken && broken_states && (icon_state in broken_states)) broken = TRUE if(!burnt && burnt_states && (icon_state in burnt_states)) diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm index a470e3e0a1..a77417e4e4 100644 --- a/code/game/turfs/simulated/floor/mineral_floor.dm +++ b/code/game/turfs/simulated/floor/mineral_floor.dm @@ -20,8 +20,7 @@ if(!broken_states) broken_states = list("[initial(icon_state)]_dam") . = ..() - if (!icons) - icons = list() + icons = typelist("icons", icons) /turf/open/floor/mineral/update_icon() diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index 61c7950e88..0004a4485b 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -131,17 +131,17 @@ T.ChangeTurf(type) /turf/closed/mineral/random - var/mineralSpawnChanceList + var/list/mineralSpawnChanceList = list(/turf/closed/mineral/uranium = 5, /turf/closed/mineral/diamond = 1, /turf/closed/mineral/gold = 10, + /turf/closed/mineral/silver = 12, /turf/closed/mineral/plasma = 20, /turf/closed/mineral/iron = 40, /turf/closed/mineral/titanium = 11, + /turf/closed/mineral/gibtonite = 4, /turf/open/floor/plating/asteroid/airless/cave = 2, /turf/closed/mineral/bscrystal = 1) //Currently, Adamantine won't spawn as it has no uses. -Durandan var/mineralChance = 13 var/display_icon_state = "rock" /turf/closed/mineral/random/Initialize() - if (!mineralSpawnChanceList) - mineralSpawnChanceList = list( - /turf/closed/mineral/uranium = 5, /turf/closed/mineral/diamond = 1, /turf/closed/mineral/gold = 10, - /turf/closed/mineral/silver = 12, /turf/closed/mineral/plasma = 20, /turf/closed/mineral/iron = 40, /turf/closed/mineral/titanium = 11, - /turf/closed/mineral/gibtonite = 4, /turf/open/floor/plating/asteroid/airless/cave = 2, /turf/closed/mineral/bscrystal = 1) + + mineralSpawnChanceList = typelist("mineralSpawnChanceList", mineralSpawnChanceList) + if (display_icon_state) icon_state = display_icon_state . = ..() @@ -522,4 +522,4 @@ turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface baseturfs = /turf/open/floor/plating/asteroid/basalt/lava_land_surface initial_gas_mix = LAVALAND_DEFAULT_ATMOS - defer_change = 1 + defer_change = 1 \ No newline at end of file diff --git a/code/game/world.dm b/code/game/world.dm index 26c01c63c4..e83a01e7f2 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -10,7 +10,7 @@ GLOBAL_VAR(restart_counter) SetupExternalRSC() - GLOB.config_error_log = GLOB.world_manifest_log = GLOB.world_pda_log = GLOB.world_job_debug_log = GLOB.sql_error_log = GLOB.world_href_log = GLOB.world_runtime_log = GLOB.world_attack_log = GLOB.world_game_log = "data/logs/config_error.log" //temporary file used to record errors with loading config, moved to log directory once logging is set bl + GLOB.config_error_log = GLOB.world_manifest_log = GLOB.world_pda_log = GLOB.world_job_debug_log = GLOB.sql_error_log = GLOB.world_href_log = GLOB.world_runtime_log = GLOB.world_attack_log = GLOB.world_game_log = "data/logs/config_error.[GUID()].log" //temporary file used to record errors with loading config, moved to log directory once logging is set bl make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once) @@ -48,7 +48,7 @@ GLOBAL_VAR(restart_counter) cit_initialize() - Master.Initialize(10, FALSE) + Master.Initialize(10, FALSE, TRUE) if(TEST_RUN_PARAMETER in params) HandleTestRun() @@ -133,6 +133,11 @@ GLOBAL_VAR(restart_counter) if(GLOB.round_id) log_game("Round ID: [GLOB.round_id]") + // This was printed early in startup to the world log and config_error.log, + // but those are both private, so let's put the commit info in the runtime + // log which is ultimately public. + log_runtime(GLOB.revdata.get_log_message()) + /world/Topic(T, addr, master, key) TGS_TOPIC //redirect to server tools if necessary diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm index 7905a8d155..be79dce06e 100644 --- a/code/modules/admin/NewBan.dm +++ b/code/modules/admin/NewBan.dm @@ -61,7 +61,9 @@ GLOBAL_PROTECT(Banlist) return 1 /proc/LoadBans() - + if(!CONFIG_GET(flag/ban_legacy_system)) + return + GLOB.Banlist = new("data/banlist.bdb") log_admin("Loading Banlist") diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm index 45a643dcac..72ec3da8f9 100644 --- a/code/modules/admin/sql_message_system.dm +++ b/code/modules/admin/sql_message_system.dm @@ -554,6 +554,9 @@ #define NOTESFILE "data/player_notes.sav" //if the AUTOCONVERT_NOTES is turned on, anytime a player connects this will be run to try and add all their notes to the databas /proc/convert_notes_sql(ckey) + if(!fexists(NOTESFILE)) + return + var/savefile/notesfile = new(NOTESFILE) if(!notesfile) log_game("Error: Cannot access [NOTESFILE]") diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 0c592c65e7..aff0292b87 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -147,10 +147,9 @@ structure_check() searches for nearby cultist structures required for the invoca /obj/effect/rune/proc/do_invoke_glow() set waitfor = FALSE - var/oldtransform = transform animate(src, transform = matrix()*2, alpha = 0, time = 5, flags = ANIMATION_END_NOW) //fade out sleep(5) - animate(src, transform = oldtransform, alpha = 255, time = 0, flags = ANIMATION_END_NOW) + animate(src, transform = matrix(), alpha = 255, time = 0, flags = ANIMATION_END_NOW) /obj/effect/rune/proc/fail_invoke() //This proc contains the effects of a rune if it is not invoked correctly, through either invalid wording or not enough cultists. By default, it's just a basic fizzle. diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index ba50a8396e..463df71f71 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -3,7 +3,7 @@ For the main html chat area *********************************/ //Precaching a bunch of shit -GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of icons for the browser output +GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of icons for the browser output //On client, created on login /datum/chatOutput diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 1633e42752..312fc315e9 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -916,6 +916,9 @@ /mob/living/carbon/human/species/dullahan race = /datum/species/dullahan +/mob/living/carbon/human/species/felinid + race = /datum/species/human/felinid + /mob/living/carbon/human/species/fly race = /datum/species/fly diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 320b75b052..2dad832aa4 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -209,13 +209,22 @@ /datum/emote/living/laugh/run_emote(mob/user, params) . = ..() - if(. && ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.dna.species.id == "human" && (!H.mind || !H.mind.miming)) + if(. && iscarbon(user)) //Citadel Edit because this is hilarious + var/mob/living/carbon/C = user + if(!C.mind || C.mind.miming) + return + if(iscatperson(C)) //we ask for is cat first because they're a subtype that tests true for ishumanbasic because HERESY + playsound(C, pick('sound/voice/catpeople/nyahaha1.ogg', + 'sound/voice/catpeople/nyahaha2.ogg', + 'sound/voice/catpeople/nyaha.ogg', + 'sound/voice/catpeople/nyahehe.ogg'), + 50, 1) + return + if(ishumanbasic(C)) if(user.gender == FEMALE) - playsound(H, 'sound/voice/human/womanlaugh.ogg', 50, 1) + playsound(C, 'sound/voice/human/womanlaugh.ogg', 50, 1) else - playsound(H, pick('sound/voice/human/manlaugh1.ogg', 'sound/voice/human/manlaugh2.ogg'), 50, 1) + playsound(C, pick('sound/voice/human/manlaugh1.ogg', 'sound/voice/human/manlaugh2.ogg'), 50, 1) /datum/emote/living/look key = "look" diff --git a/code/modules/ninja/suit/ninjaDrainAct.dm b/code/modules/ninja/suit/ninjaDrainAct.dm index 8b9abbee7a..861ffb9446 100644 --- a/code/modules/ninja/suit/ninjaDrainAct.dm +++ b/code/modules/ninja/suit/ninjaDrainAct.dm @@ -169,8 +169,8 @@ They *could* go in their appropriate files, but this is supposed to be modular drain = (round((rand(G.mindrain, G.maxdrain))/2)) var/drained = 0 if(PN && do_after(H,10, target = src)) - drained = min(drain, PN.avail) - PN.load += drained + drained = min(drain, delayed_surplus()) + add_delayedload(drained) if(drained < drain)//if no power on net, drain apcs for(var/obj/machinery/power/terminal/T in PN.nodes) if(istype(T.master, /obj/machinery/power/apc)) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index f48826df9d..3d466d9448 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -1104,7 +1104,7 @@ /obj/machinery/power/apc/add_load(amount) if(terminal && terminal.powernet) - terminal.powernet.load += amount + terminal.add_load(amount) /obj/machinery/power/apc/avail() if(terminal) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 7060edecbd..7b3b2ba7bd 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -199,6 +199,10 @@ By design, d1 is the smallest direction and d2 is the highest // Power related /////////////////////////////////////////// +// All power generation handled in add_avail() +// Machines should use add_load(), surplus(), avail() +// Non-machines should use add_delayedload(), delayed_surplus(), newavail() + /obj/structure/cable/proc/add_avail(amount) if(powernet) powernet.newavail += amount @@ -209,7 +213,7 @@ By design, d1 is the smallest direction and d2 is the highest /obj/structure/cable/proc/surplus() if(powernet) - return powernet.avail-powernet.load + return CLAMP(powernet.avail-powernet.load, 0, powernet.avail) else return 0 @@ -219,6 +223,22 @@ By design, d1 is the smallest direction and d2 is the highest else return 0 +/obj/structure/cable/proc/add_delayedload(amount) + if(powernet) + powernet.delayedload += amount + +/obj/structure/cable/proc/delayed_surplus() + if(powernet) + return CLAMP(powernet.newavail - powernet.delayedload, 0, powernet.newavail) + else + return 0 + +/obj/structure/cable/proc/newavail() + if(powernet) + return powernet.newavail + else + return 0 + ///////////////////////////////////////////////// // Cable laying helpers //////////////////////////////////////////////// @@ -828,4 +848,4 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai /obj/item/stack/cable_coil/cut/random item_color = null - color = "#ffffff" + color = "#ffffff" \ No newline at end of file diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index f6110cb081..58a259de3a 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -25,6 +25,10 @@ ////////////////////////////// // common helper procs for all power machines +// All power generation handled in add_avail() +// Machines should use add_load(), surplus(), avail() +// Non-machines should use add_delayedload(), delayed_surplus(), newavail() + /obj/machinery/power/proc/add_avail(amount) if(powernet) powernet.newavail += amount @@ -38,7 +42,7 @@ /obj/machinery/power/proc/surplus() if(powernet) - return powernet.avail - powernet.load + return CLAMP(powernet.avail-powernet.load, 0, powernet.avail) else return 0 @@ -48,6 +52,22 @@ else return 0 +/obj/machinery/power/proc/add_delayedload(amount) + if(powernet) + powernet.delayedload += amount + +/obj/machinery/power/proc/delayed_surplus() + if(powernet) + return CLAMP(powernet.newavail - powernet.delayedload, 0, powernet.newavail) + else + return 0 + +/obj/machinery/power/proc/newavail() + if(powernet) + return powernet.newavail + else + return 0 + /obj/machinery/power/proc/disconnect_terminal() // machines without a terminal will just return, no harm no fowl. return @@ -341,7 +361,7 @@ source_area.use_power(drained_energy/GLOB.CELLRATE) else if (istype(power_source, /datum/powernet)) var/drained_power = drained_energy/GLOB.CELLRATE //convert from "joules" to "watts" - PN.load+=drained_power + PN.delayedload += (min(drained_power, max(PN.newavail - PN.delayedload, 0))) else if (istype(power_source, /obj/item/stock_parts/cell)) cell.use(drained_energy) return drained_energy @@ -364,4 +384,4 @@ /area/proc/get_apc() for(var/obj/machinery/power/apc/APC in GLOB.apcs_list) if(APC.area == src) - return APC + return APC \ No newline at end of file diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm index c34edc53f3..3b70383bee 100644 --- a/code/modules/power/powernet.dm +++ b/code/modules/power/powernet.dm @@ -13,6 +13,7 @@ var/viewavail = 0 // the available power as it appears on the power console (gradually updated) var/viewload = 0 // the load as it appears on the power console (gradually updated) var/netexcess = 0 // excess power on the powernet (typically avail-load)/////// + var/delayedload = 0 // load applied to powernet between power ticks. /datum/powernet/New() SSmachines.powernets += src @@ -88,7 +89,8 @@ viewload = round(0.8 * viewload + 0.2 * load) // reset the powernet - load = 0 + load = delayedload + delayedload = 0 avail = newavail newavail = 0 diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index eebdd5c9da..9d2ad4c12a 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -160,7 +160,7 @@ update_icon() return if(active == TRUE) - if(!active_power_usage || avail(active_power_usage)) + if(!active_power_usage || surplus() >= active_power_usage) add_load(active_power_usage) if(!powered) powered = TRUE @@ -189,7 +189,7 @@ return FALSE if(state != EMITTER_WELDED) return FALSE - if(avail(active_power_usage)) + if(surplus() >= active_power_usage) add_load(active_power_usage) fire_beam() @@ -495,4 +495,4 @@ #undef EMITTER_UNWRENCHED #undef EMITTER_WRENCHED -#undef EMITTER_WELDED +#undef EMITTER_WELDED \ No newline at end of file diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index f11b0ad709..dbfca477d6 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -16,7 +16,7 @@ var/list/obj/machinery/computer/rdconsole/consoles_accessing = list() var/id = "generic" var/list/research_logs = list() //IC logs. - var/max_bomb_value = 0 + var/largest_bomb_value = 0 var/organization = "Third-Party" //Organization name, used for display. var/list/last_bitcoins = list() //Current per-second production, used for display only. var/list/tiers = list() //Assoc list, datum = number, 1 is available, 2 is all reqs are 1, so on diff --git a/config/game_options.txt b/config/game_options.txt index f4d76c670c..3a1febf6dd 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -411,6 +411,7 @@ ROUNDSTART_RACES lizard #ROUNDSTART_RACES moth ROUNDSTART_RACES plasmaman #ROUNDSTART_RACES shadow +ROUNDSTART_RACES felinid ## Races that are better than humans in some ways, but worse in others #ROUNDSTART_RACES jelly diff --git a/dependencies.sh b/dependencies.sh index 12fce4e866..59f84f145a 100644 --- a/dependencies.sh +++ b/dependencies.sh @@ -10,10 +10,10 @@ export BYOND_MAJOR=512 export BYOND_MINOR=1441 #rust_g git tag -export RUST_G_VERSION=0.4.0 +export RUST_G_VERSION=0.4.1 #bsql git tag export BSQL_VERSION=v1.4.0.0 #node version -export NODE_VERSION=4 +export NODE_VERSION=8 diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human.dm b/modular_citadel/code/modules/mob/living/carbon/human/human.dm new file mode 100644 index 0000000000..fcdaa9caad --- /dev/null +++ b/modular_citadel/code/modules/mob/living/carbon/human/human.dm @@ -0,0 +1,14 @@ +/mob/living/carbon/human/species/mammal + race = /datum/species/human/mammal + +/mob/living/carbon/human/species/avian + race = /datum/species/human/avian + +/mob/living/carbon/human/species/aquatic + race = /datum/species/human/aquatic + +/mob/living/carbon/human/species/insect + race = /datum/species/human/insect + +/mob/living/carbon/human/species/xeno + race = /datum/species/human/xeno \ No newline at end of file diff --git a/modular_citadel/code/modules/mob/living/carbon/human/species_types/furrypeople.dm b/modular_citadel/code/modules/mob/living/carbon/human/species_types/furrypeople.dm index ef3c9487ba..ece58dcf3a 100644 --- a/modular_citadel/code/modules/mob/living/carbon/human/species_types/furrypeople.dm +++ b/modular_citadel/code/modules/mob/living/carbon/human/species_types/furrypeople.dm @@ -52,6 +52,7 @@ /datum/species/mammal/on_species_loss(mob/living/carbon/human/C) C.draw_citadel_parts(TRUE) . = ..() + //AVIAN// /datum/species/avian name = "Avian" diff --git a/rust_g.dll b/rust_g.dll index 44e38ef0dd4b4105a1c2a6d1004b861b0253595b..ec072b01b00ebde836724c789b867e2fa62c4f37 100644 GIT binary patch literal 1159168 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