Continual updates until merged

This commit is contained in:
Poojawa
2018-09-17 04:55:03 -05:00
parent 99e57fb221
commit bc0d14c193
53 changed files with 358 additions and 200 deletions

1
.gitignore vendored
View File

@@ -2,6 +2,7 @@
#Ignore everything in datafolder and subdirectories
/data/**/*
/tmp/**/*
#Ignore byond config folder.
/cfg/**/*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -164,4 +164,7 @@ GLOBAL_LIST_INIT(bitfields, list(
"TRANSPARENT" = TRANSPARENT,
"AMOUNT_VISIBLE" = AMOUNT_VISIBLE,
),
"car_traits" = list(
"CAN_KIDNAP" = CAN_KIDNAP,
),
))

View File

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

View File

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

View File

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

View File

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

View File

@@ -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, "<b>Round ID:</b> [GLOB.round_id]")
if(GLOB.revdata.originmastercommit)
to_chat(src, "<b>Server revision compiled on:</b> [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]<a href=\"[CONFIG_GET(string/githuburl)]/commit/[pc]\">[copytext(pc, 1, min(length(pc), 11))]</a>")
else
to_chat(src, "Master revision unknown")
to_chat(src, "Revision: [GLOB.revdata.commit]")
msg += "<b>Round ID:</b> [GLOB.round_id]"
// Revision information
var/datum/getrev/revdata = GLOB.revdata
msg += "<b>Server revision compiled on:</b> [revdata.date]"
var/pc = revdata.originmastercommit
if(pc)
msg += "Master commit: <a href=\"[CONFIG_GET(string/githuburl)]/commit/[pc]\">[pc]</a>"
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, "<b>Current Informational Settings:</b>")
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 += "<br><b>Current Informational Settings:</b>"
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, "<b>Game Mode Odds for current round:</b>")
msg += "<b>Game Mode Odds for current round:</b>"
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, "<b>All Game Mode Odds:</b>")
msg += "<b>All Game Mode Odds:</b>"
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("<br>"))

View File

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

View File

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

View File

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

View File

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

View File

@@ -86,7 +86,7 @@
if(!active)
return
if(surplus() > 1500)
if(surplus() >= 1500)
add_load(1500)
if(cooldown <= world.time)
cooldown = world.time + 80

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -137,6 +137,7 @@
#include "code\__HELPERS\time.dm"
#include "code\__HELPERS\type2type.dm"
#include "code\__HELPERS\type2type_vr.dm"
#include "code\__HELPERS\typelists.dm"
#include "code\__HELPERS\unsorted.dm"
#include "code\__HELPERS\view.dm"
#include "code\__HELPERS\sorts\__main.dm"
@@ -2912,6 +2913,7 @@
#include "modular_citadel\code\modules\mob\living\carbon\carbon.dm"
#include "modular_citadel\code\modules\mob\living\carbon\damage_procs.dm"
#include "modular_citadel\code\modules\mob\living\carbon\reindex_screams.dm"
#include "modular_citadel\code\modules\mob\living\carbon\human\human.dm"
#include "modular_citadel\code\modules\mob\living\carbon\human\human_defense.dm"
#include "modular_citadel\code\modules\mob\living\carbon\human\human_movement.dm"
#include "modular_citadel\code\modules\mob\living\carbon\human\life.dm"

View File

@@ -2,5 +2,5 @@
echo node.js and all dependencies must be installed for this script to work.
echo If this script fails try installing dependencies again.
REM Build minified assets
cmd /c gulp --min
node node_modules/gulp/bin/gulp.js --min
pause

View File

@@ -3,14 +3,6 @@ echo node.js 5.3.0 or newer must be installed for this script to work.
echo If this script fails, try closing editors and running it again first.
echo Any warnings about optional dependencies can be safely ignored.
pause
REM Install npm-cache
cmd /c npm install npm-cache -g
REM Install Gulp
cmd /c npm install gulp-cli -g
REM Install tgui dependencies
cmd /c npm-cache install npm
REM Flatten dependency tree
cmd /c npm dedupe
REM Clean dependency tree
cmd /c npm prune
REM Install dependencies
npm ci
pause

View File

@@ -6,7 +6,7 @@ set -e
if [ "$BUILD_TOOLS" = true ];
then
md5sum -c - <<< "49bc6b1b9ed56c83cceb6674bd97cb34 *html/changelogs/example.yml";
cd tgui && source ~/.nvm/nvm.sh && gulp && cd ..;
(cd tgui && source ~/.nvm/nvm.sh && npm ci && node node_modules/gulp/bin/gulp.js --min)
phpenv global 5.6
php -l tools/WebhookProcessor/github_webhook_processor.php;
php -l tools/TGUICompiler.php;

View File

@@ -5,7 +5,6 @@ source dependencies.sh
if [ "$BUILD_TOOLS" = true ]; then
rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $NODE_VERSION
npm install -g gulp-cli
pip3 install --user PyYaml -q
pip3 install --user beautifulsoup4 -q
fi;