upstream merge

This commit is contained in:
Hatterhat
2020-01-04 01:48:50 -06:00
131 changed files with 1426 additions and 651 deletions
+1 -1
View File
@@ -693,7 +693,7 @@
var/prev_dynamic_voting = CONFIG_GET(flag/dynamic_voting)
CONFIG_SET(flag/dynamic_voting,!prev_dynamic_voting)
if (!prev_dynamic_voting)
to_chat(world, "<B>Vote is now between extended and dynamic chaos.</B>")
to_chat(world, "<B>Vote is now a ranked choice of dynamic storytellers.</B>")
else
to_chat(world, "<B>Vote is now between extended and secret.</B>")
log_admin("[key_name(usr)] [prev_dynamic_voting ? "disabled" : "enabled"] dynamic voting.")
+19
View File
@@ -35,6 +35,9 @@ GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list(
/client/proc/cmd_admin_grantfullaccess,
/client/proc/cmd_admin_areatest_all,
/client/proc/cmd_admin_areatest_station,
#ifdef TESTING
/client/proc/see_dirty_varedits,
#endif
/client/proc/cmd_admin_test_atmos_controllers,
/client/proc/cmd_admin_rejuvenate,
/datum/admins/proc/show_traitor_panel,
@@ -84,8 +87,24 @@ GLOBAL_PROTECT(admin_verbs_debug_mapping)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Camera Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Camera Range")
#ifdef TESTING
GLOBAL_LIST_EMPTY(dirty_vars)
/client/proc/see_dirty_varedits()
set category = "Mapping"
set name = "Dirty Varedits"
var/list/dat = list()
dat += "<h3>Abandon all hope ye who enter here</h3><br><br>"
for(var/thing in GLOB.dirty_vars)
dat += "[thing]<br>"
CHECK_TICK
var/datum/browser/popup = new(usr, "dirty_vars", "Dirty Varedits", 900, 750)
popup.set_content(dat.Join())
popup.open()
#endif
/client/proc/sec_camera_report()
set category = "Mapping"
set name = "Camera Report"
@@ -139,7 +139,7 @@
var/new_thing_type = fabrication_values["new_obj_type"]
if(isturf(target)) //if our target is a turf, we're just going to ChangeTurf it and assume it'll work out.
var/turf/T = target
T.ChangeTurf(new_thing_type)
T.ChangeTurf(new_thing_type, flags = CHANGETURF_INHERIT_AIR)
else
if(new_thing_type)
if(fabrication_values["dir_in_new"])
@@ -59,7 +59,7 @@
if(anchored)
T.PlaceOnTop(/turf/closed/wall/clockwork)
else
T.PlaceOnTop(/turf/open/floor/clockwork)
T.PlaceOnTop(/turf/open/floor/clockwork, flags = CHANGETURF_INHERIT_AIR)
new /obj/structure/falsewall/brass(T)
qdel(src)
else
@@ -239,9 +239,9 @@
var/turf/T = safepick(validturfs)
if(T)
if(istype(T, /turf/open/floor/plating))
T.PlaceOnTop(/turf/open/floor/engine/cult)
T.PlaceOnTop(/turf/open/floor/engine/cult, flags = CHANGETURF_INHERIT_AIR)
else
T.ChangeTurf(/turf/open/floor/engine/cult)
T.ChangeTurf(/turf/open/floor/engine/cult, flags = CHANGETURF_INHERIT_AIR)
else
var/turf/open/floor/engine/cult/F = safepick(cultturfs)
if(F)
@@ -76,9 +76,10 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
var/threat_spent = CONFIG_GET(number/dynamic_warops_cost)
mode.spend_threat(threat_spent)
mode.log_threat("Nuke ops spent [threat_spent] on war ops.")
if(!(mode.storyteller.flags & WAROPS_ALWAYS_ALLOWED))
var/threat_spent = CONFIG_GET(number/dynamic_warops_cost)
mode.spend_threat(threat_spent)
mode.log_threat("Nuke ops spent [threat_spent] on war ops.")
SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1)
qdel(src)
@@ -101,12 +102,13 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
return FALSE
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
if(mode.threat_level < CONFIG_GET(number/dynamic_warops_requirement))
to_chat(user, "Due to the dynamic space in which the station resides, you are too deep into Nanotrasen territory to reasonably go loud.")
return FALSE
else if(mode.threat < CONFIG_GET(number/dynamic_warops_cost))
to_chat(user, "Due to recent threats on the station, Nanotrasen is looking too closely for a war declaration to be wise.")
return FALSE
if(!(mode.storyteller.flags & WAROPS_ALWAYS_ALLOWED))
if(mode.threat_level < CONFIG_GET(number/dynamic_warops_requirement))
to_chat(user, "Due to the dynamic space in which the station resides, you are too deep into Nanotrasen territory to reasonably go loud.")
return FALSE
else if(mode.threat < CONFIG_GET(number/dynamic_warops_cost))
to_chat(user, "Due to recent threats on the station, Nanotrasen is looking too closely for a war declaration to be wise.")
return FALSE
return TRUE
/obj/item/nuclear_challenge/clownops
@@ -80,6 +80,8 @@
if(istype(SSticker.mode,/datum/game_mode/dynamic))
mode = SSticker.mode
is_dynamic = TRUE
if(mode.storyteller.flags & NO_ASSASSIN)
is_hijacker = FALSE
if(GLOB.joined_player_list.len>=GLOB.dynamic_high_pop_limit)
is_hijacker = (prob(10) && mode.threat_level > CONFIG_GET(number/dynamic_hijack_high_population_requirement))
else
@@ -180,7 +182,7 @@
destroy_objective.owner = owner
destroy_objective.find_target()
add_objective(destroy_objective)
else if(prob(30))
else if(prob(30) || (mode.storyteller.flags & NO_ASSASSIN))
var/datum/objective/maroon/maroon_objective = new
maroon_objective.owner = owner
maroon_objective.find_target()
@@ -57,10 +57,10 @@
if(item.parent)
var/static/pipenetwarnings = 10
if(pipenetwarnings > 0)
warning("build_pipeline(): [item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) Nearby: ([item.x], [item.y], [item.z])")
log_mapping("build_pipeline(): [item.type] added to a pipenet while still having one. (pipes leading to the same spot stacking in one turf) Nearby: ([item.x], [item.y], [item.z]).")
pipenetwarnings -= 1
if(pipenetwarnings == 0)
warning("build_pipeline(): further messages about pipenets will be suppressed")
log_mapping("build_pipeline(): further messages about pipenets will be suppressed")
members += item
possible_expansions += item
@@ -56,7 +56,7 @@
pixel_y = (new_layer - PIPING_LAYER_DEFAULT) * PIPING_LAYER_P_Y
/obj/machinery/meter/process_atmos()
if(!target)
if(!(target?.flags_1 & INITIALIZED_1))
icon_state = "meterX"
return 0
+3 -3
View File
@@ -22,9 +22,9 @@
if(istype(object,/turf) && left_click && !alt_click && !ctrl_click)
var/turf/T = object
if(isspaceturf(object))
T.PlaceOnTop(/turf/open/floor/plating)
T.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
else if(isplatingturf(object))
T.PlaceOnTop(/turf/open/floor/plasteel)
T.PlaceOnTop(/turf/open/floor/plasteel, flags = CHANGETURF_INHERIT_AIR)
else if(isfloorturf(object))
T.PlaceOnTop(/turf/closed/wall)
else if(iswallturf(object))
@@ -35,7 +35,7 @@
log_admin("Build Mode: [key_name(c)] deleted [object] at [AREACOORD(object)]")
if(isturf(object))
var/turf/T = object
T.ScrapeAway()
T.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
else if(isobj(object))
qdel(object)
return
+4 -5
View File
@@ -13,17 +13,16 @@
//////////////////// Paperwork and Writing Supplies //////////////////////////
//////////////////////////////////////////////////////////////////////////////
/* I did it Kevin
/datum/supply_pack/misc/abandonedcrate
name = "Abandoned Crate"
desc = "Someone keeps finding these locked crates out in the boonies. How about you take a crack at it, we've had our fill. WARNING: EXPLOSIVE"
name = "Loot Box"
desc = "Try your luck with these highly secure loot boxes! Solve the lock, win great prizes! WARNING: EXPLOSIVE FAILURE."
contraband = TRUE
cost = 12800
cost = 15000
contains = list(/obj/structure/closet/crate/secure/loot)
crate_name = "abandoned crate"
crate_type = /obj/structure/closet/crate/large
dangerous = TRUE
*/
/datum/supply_pack/misc/artsupply
name = "Art Supplies"
desc = "Make some happy little accidents with six canvasses, two easels, two boxes of crayons, and a rainbow crayon!"
+11
View File
@@ -195,6 +195,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/auto_fit_viewport = TRUE
var/uplink_spawn_loc = UPLINK_PDA
var/sprint_spacebar = FALSE
var/sprint_toggle = FALSE
var/list/exp = list()
var/list/menuoptions
@@ -889,6 +892,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</a><br>"
dat += "<b>Ambient Occlusion:</b> <a href='?_src_=prefs;preference=ambientocclusion'>[ambientocclusion ? "Enabled" : "Disabled"]</a><br>"
dat += "<b>Fit Viewport:</b> <a href='?_src_=prefs;preference=auto_fit_viewport'>[auto_fit_viewport ? "Auto" : "Manual"]</a><br>"
dat += "<b>Sprint Key:</b> <a href='?_src_=prefs;preference=sprint_key'>[sprint_spacebar ? "Space" : "Shift"]</a><br>"
dat += "<b>Toggle Sprint:</b> <a href='?_src_=prefs;preference=sprint_toggle'>[sprint_toggle ? "Enabled" : "Disabled"]</a><br>"
if (CONFIG_GET(flag/maprotation) && CONFIG_GET(flag/tgstyle_maprotation))
var/p_map = preferred_map
@@ -2239,6 +2244,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(auto_fit_viewport && parent)
parent.fit_viewport()
if("sprint_key")
sprint_spacebar = !sprint_spacebar
if("sprint_toggle")
sprint_toggle = !sprint_toggle
if("save")
save_preferences()
save_character()
@@ -167,6 +167,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["parallax"] >> parallax
S["ambientocclusion"] >> ambientocclusion
S["auto_fit_viewport"] >> auto_fit_viewport
S["sprint_spacebar"] >> sprint_spacebar
S["sprint_toggle"] >> sprint_toggle
S["menuoptions"] >> menuoptions
S["enable_tips"] >> enable_tips
S["tip_delay"] >> tip_delay
@@ -204,6 +206,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
parallax = sanitize_integer(parallax, PARALLAX_INSANE, PARALLAX_DISABLE, null)
ambientocclusion = sanitize_integer(ambientocclusion, 0, 1, initial(ambientocclusion))
auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport))
sprint_spacebar = sanitize_integer(sprint_spacebar, 0, 1, initial(sprint_spacebar))
sprint_toggle = sanitize_integer(sprint_toggle, 0, 1, initial(sprint_toggle))
ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form))
ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit))
ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION)
@@ -264,6 +268,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["parallax"], parallax)
WRITE_FILE(S["ambientocclusion"], ambientocclusion)
WRITE_FILE(S["auto_fit_viewport"], auto_fit_viewport)
WRITE_FILE(S["sprint_spacebar"], sprint_spacebar)
WRITE_FILE(S["sprint_toggle"], sprint_toggle)
WRITE_FILE(S["menuoptions"], menuoptions)
WRITE_FILE(S["enable_tips"], enable_tips)
WRITE_FILE(S["tip_delay"], tip_delay)
@@ -219,7 +219,7 @@
name = "space cola snowcone"
desc = "Space Cola drizzled over a snowball in a paper cup."
icon_state = "soda_sc"
list_reagents = list("nutriment" = 1, "space_cola" = 5)
list_reagents = list("nutriment" = 1, "cola" = 5)
tastes = list("ice" = 1, "water" = 1, "cola" = 5)
/obj/item/reagent_containers/food/snacks/snowcones/spacemountainwind
@@ -248,4 +248,4 @@
desc = "A very colorful snowball in a paper cup."
icon_state = "rainbow_sc"
list_reagents = list("nutriment" = 5, "laughter" = 25)
tastes = list("ice" = 1, "water" = 1, "sunlight" = 5, "light" = 5, "slime" = 5, "paint" = 3, "clouds" = 3)
tastes = list("ice" = 1, "water" = 1, "sunlight" = 5, "light" = 5, "slime" = 5, "paint" = 3, "clouds" = 3)
+24 -1
View File
@@ -8,6 +8,8 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
//On client, created on login
/datum/chatOutput
var/client/owner //client ref
var/total_checks = 0
var/last_check = 0
var/loaded = FALSE // Has the client loaded the browser output area?
var/list/messageQueue //If they haven't loaded chat, this is where messages will go until they do
var/cookieSent = FALSE // Has the client sent a cookie for analysis
@@ -150,6 +152,18 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
//Called by client, sent data to investigate (cookie history so far)
/datum/chatOutput/proc/analyzeClientData(cookie = "")
//Spam check
if(world.time > last_check + (3 SECONDS))
last_check = world.time
total_checks = 0
total_checks += 1
if(total_checks > SPAM_TRIGGER_AUTOMUTE)
message_admins("[key_name(owner)] kicked for goonchat topic spam")
qdel(owner)
return
if(!cookie)
return
@@ -158,13 +172,22 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
if (connData && islist(connData) && connData.len > 0 && connData["connData"])
connectionHistory = connData["connData"] //lol fuck
var/list/found = new()
for(var/i in connectionHistory.len to 1 step -1)
if(connectionHistory.len > 5)
message_admins("[key_name(src.owner)] was kicked for an invalid ban cookie)")
qdel(owner)
return
for(var/i in min(connectionHistory.len, 5) to 1 step -1)
if(QDELETED(owner))
//he got cleaned up before we were done
return
var/list/row = src.connectionHistory[i]
if (!row || row.len < 3 || (!row["ckey"] || !row["compid"] || !row["ip"])) //Passed malformed history object
return
if (world.IsBanned(row["ckey"], row["ip"], row["compid"], real_bans_only=TRUE))
found = row
break
CHECK_TICK
//Uh oh this fucker has a history of playing on a banned account!!
if (found.len > 0)
@@ -421,8 +421,8 @@ function handleClientData(ckey, ip, compid) {
return; //Record already exists
}
}
if (opts.clientData.length >= opts.clientDataLimit) {
//Lets make sure we obey our limit (can connect from server with higher limit)
while (opts.clientData.length >= opts.clientDataLimit) {
opts.clientData.shift();
}
} else {
+1 -3
View File
@@ -59,9 +59,7 @@
return
var/area/AS = get_area(src)
if(istype(AS, /area/holodeck))
log_world("### MAPPING ERROR")
log_world("Holodeck computer cannot be in a holodeck.")
log_world("This would cause circular power dependency.")
log_mapping("Holodeck computer cannot be in a holodeck, This would cause circular power dependency.")
qdel(src)
return
else
+12 -2
View File
@@ -58,13 +58,23 @@
return
switch(_key)
if("Shift")
sprint_hotkey(TRUE)
if(!user.prefs.sprint_spacebar)
user.prefs.sprint_toggle ? togglesprint() : sprint_hotkey(TRUE) //Yes, this looks hacky. Yes, this works.
return
if("Space")
if(user.prefs.sprint_spacebar)
user.prefs.sprint_toggle ? togglesprint() : sprint_hotkey(TRUE)
return
return ..()
/mob/living/carbon/human/key_up(_key, client/user)
switch(_key)
if("Shift")
sprint_hotkey(FALSE)
if(!user.prefs.sprint_spacebar && !user.prefs.sprint_toggle)
sprint_hotkey(FALSE)
return
if("Space")
if(user.prefs.sprint_spacebar && !user.prefs.sprint_toggle)
sprint_hotkey(FALSE)
return
return ..()
+9 -2
View File
@@ -70,7 +70,7 @@
//initialize things that are normally initialized after map load
parsed.initTemplateBounds()
smooth_zlevel(world.maxz)
log_game("Z-level [name] loaded at at [x],[y],[world.maxz]")
log_game("Z-level [name] loaded at [x],[y],[world.maxz]")
return level
@@ -84,6 +84,13 @@
if(T.y+height > world.maxy)
return
var/list/border = block(locate(max(T.x-1, 1), max(T.y-1, 1), T.z),
locate(min(T.x+width+1, world.maxx), min(T.y+height+1, world.maxy), T.z))
for(var/L in border)
var/turf/turf_to_disable = L
SSair.remove_from_active(turf_to_disable) //stop processing turfs along the border to prevent runtimes, we return it in initTemplateBounds()
turf_to_disable.atmos_adjacent_turfs?.Cut()
// Accept cached maps, but don't save them automatically - we don't want
// ruins clogging up memory for the whole round.
var/datum/parsed_map/parsed = cached_map || new(file(mappath))
@@ -100,7 +107,7 @@
//initialize things that are normally initialized after map load
parsed.initTemplateBounds()
log_game("[name] loaded at at [T.x],[T.y],[T.z]")
log_game("[name] loaded at [T.x],[T.y],[T.z]")
return bounds
/datum/map_template/proc/get_affected_turfs(turf/T, centered = FALSE)
+9 -21
View File
@@ -18,7 +18,7 @@
/obj/effect/baseturf_helper/LateInitialize()
if(!baseturf_to_replace)
baseturf_to_replace = typecacheof(/turf/open/space)
baseturf_to_replace = typecacheof(list(/turf/open/space,/turf/baseturf_bottom))
else if(!length(baseturf_to_replace))
baseturf_to_replace = list(baseturf_to_replace = TRUE)
else if(baseturf_to_replace[baseturf_to_replace[1]] != TRUE) // It's not associative
@@ -45,7 +45,6 @@
thing.PlaceOnBottom(null, baseturf)
else if(baseturf_to_replace[thing.baseturfs])
thing.assemble_baseturfs(baseturf)
return
else
thing.PlaceOnBottom(null, baseturf)
@@ -107,16 +106,16 @@
/obj/effect/mapping_helpers/airlock/cyclelink_helper/Initialize(mapload)
. = ..()
if(!mapload)
log_world("### MAP WARNING, [src] spawned outside of mapload!")
log_mapping("[src] spawned outside of mapload!")
return
var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc
if(airlock)
if(airlock.cyclelinkeddir)
log_world("### MAP WARNING, [src] at [AREACOORD(src)] tried to set [airlock] cyclelinkeddir, but it's already set!")
log_mapping("[src] at [AREACOORD(src)] tried to set [airlock] cyclelinkeddir, but it's already set!")
else
airlock.cyclelinkeddir = dir
else
log_world("### MAP WARNING, [src] failed to find an airlock at [AREACOORD(src)]")
log_mapping("[src] failed to find an airlock at [AREACOORD(src)]")
/obj/effect/mapping_helpers/airlock/locked
@@ -126,16 +125,16 @@
/obj/effect/mapping_helpers/airlock/locked/Initialize(mapload)
. = ..()
if(!mapload)
log_world("### MAP WARNING, [src] spawned outside of mapload!")
log_mapping("[src] spawned outside of mapload!")
return
var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc
if(airlock)
if(airlock.locked)
log_world("### MAP WARNING, [src] at [AREACOORD(src)] tried to bolt [airlock] but it's already locked!")
log_mapping("[src] at [AREACOORD(src)] tried to bolt [airlock] but it's already locked!")
else
airlock.locked = TRUE
else
log_world("### MAP WARNING, [src] failed to find an airlock at [AREACOORD(src)]")
log_mapping("[src] failed to find an airlock at [AREACOORD(src)]")
/obj/effect/mapping_helpers/airlock/unres
name = "airlock unresctricted side helper"
@@ -144,13 +143,13 @@
/obj/effect/mapping_helpers/airlock/unres/Initialize(mapload)
. = ..()
if(!mapload)
log_world("### MAP WARNING, [src] spawned outside of mapload!")
log_mapping("[src] spawned outside of mapload!")
return
var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc
if(airlock)
airlock.unres_sides ^= dir
else
log_world("### MAP WARNING, [src] failed to find an airlock at [AREACOORD(src)]")
log_mapping("[src] failed to find an airlock at [AREACOORD(src)]")
//needs to do its thing before spawn_rivers() is called
@@ -164,17 +163,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
var/turf/T = get_turf(src)
T.flags_1 |= NO_LAVA_GEN_1
/// Adds the map it is on to the z_is_planet list
/obj/effect/mapping_helpers/planet_z
name = "planet z helper"
layer = POINT_LAYER
/obj/effect/mapping_helpers/planet_z/Initialize()
. = ..()
var/datum/space_level/S = SSmapping.get_level(z)
S.traits[ZTRAIT_PLANET] = TRUE
//This helper applies components to things on the map directly.
/obj/effect/mapping_helpers/component_injector
name = "Component Injector"
+14 -6
View File
@@ -8,18 +8,26 @@ GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new)
var/list/attributes
var/target_path
/datum/map_preloader/proc/setup(list/the_attributes, path)
/world/proc/preloader_setup(list/the_attributes, path)
if(the_attributes.len)
GLOB.use_preloader = TRUE
attributes = the_attributes
target_path = path
var/datum/map_preloader/preloader_local = GLOB._preloader
preloader_local.attributes = the_attributes
preloader_local.target_path = path
/datum/map_preloader/proc/load(atom/what)
/world/proc/preloader_load(atom/what)
GLOB.use_preloader = FALSE
for(var/attribute in attributes)
var/value = attributes[attribute]
var/datum/map_preloader/preloader_local = GLOB._preloader
for(var/attribute in preloader_local.attributes)
var/value = preloader_local.attributes[attribute]
if(islist(value))
value = deepCopyList(value)
#ifdef TESTING
if(what.vars[attribute] == value)
var/message = "<font color=green>[what.type]</font> at [AREACOORD(what)] - <b>VAR:</b> <font color=red>[attribute] = [isnull(value) ? "null" : (isnum(value) ? value : "\"[value]\"")]</font>"
log_mapping("DIRTY VAR: [message]")
GLOB.dirty_vars += message
#endif
what.vars[attribute] = value
/area/template_noop
+4 -4
View File
@@ -306,8 +306,8 @@
//first instance the /area and remove it from the members list
index = members.len
if(members[index] != /area/template_noop)
GLOB._preloader.setup(members_attributes[index])//preloader for assigning set variables on atom creation
var/atype = members[index]
world.preloader_setup(members_attributes[index], atype)//preloader for assigning set variables on atom creation
var/atom/instance = areaCache[atype]
if (!instance)
instance = GLOB.areas_by_type[atype]
@@ -318,7 +318,7 @@
instance.contents.Add(crds)
if(GLOB.use_preloader && instance)
GLOB._preloader.load(instance)
world.preloader_load(instance)
//then instance the /turf and, if multiple tiles are presents, simulates the DMM underlays piling effect
@@ -354,7 +354,7 @@
//Instance an atom at (x,y,z) and gives it the variables in attributes
/datum/parsed_map/proc/instance_atom(path,list/attributes, turf/crds, no_changeturf, placeOnTop)
GLOB._preloader.setup(attributes, path)
world.preloader_setup(attributes, path)
if(crds)
if(ispath(path, /turf))
@@ -368,7 +368,7 @@
. = create_atom(path, crds)//first preloader pass
if(GLOB.use_preloader && .)//second preloader pass, for those atoms that don't ..() in New()
GLOB._preloader.load(.)
world.preloader_load(.)
//custom CHECK_TICK here because we don't want things created while we're sleeping to not initialize
if(TICK_CHECK)
@@ -926,7 +926,7 @@
timer = world.time + create_delay + 1
if(do_after(user, create_delay, target = T))
var/old_name = T.name
if(T.TerraformTurf(turf_type))
if(T.TerraformTurf(turf_type, flags = CHANGETURF_INHERIT_AIR))
user.visible_message("<span class='danger'>[user] turns \the [old_name] into [transform_string]!</span>")
message_admins("[ADMIN_LOOKUPFLW(user)] fired the lava staff at [ADMIN_VERBOSEJMP(T)]")
log_game("[key_name(user)] fired the lava staff at [AREACOORD(T)].")
@@ -937,7 +937,7 @@
qdel(L)
else
var/old_name = T.name
if(T.TerraformTurf(reset_turf_type))
if(T.TerraformTurf(reset_turf_type, flags = CHANGETURF_INHERIT_AIR))
user.visible_message("<span class='danger'>[user] turns \the [old_name] into [reset_string]!</span>")
timer = world.time + reset_cooldown
playsound(T,'sound/magic/fireball.ogg', 200, 1)
+2 -2
View File
@@ -50,7 +50,7 @@
/obj/machinery/mineral/ore_redemption/examine(mob/user)
. = ..()
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Smelting <b>[sheet_per_ore]</b> sheet(s) per piece of ore.<br>Ore pickup speed at <b>[ore_pickup_rate]</b>.</span>"
. += "<span class='notice'>The status display reads: Smelting <b>[sheet_per_ore]</b> sheet(s) per piece of ore.<br>Reward point generation at <b>[point_upgrade*100]%</b>.<br>Ore pickup speed at <b>[ore_pickup_rate]</b>.</span>"
/obj/machinery/mineral/ore_redemption/proc/smelt_ore(obj/item/stack/ore/O)
var/datum/component/material_container/mat_container = materials.mat_container
@@ -63,7 +63,7 @@
ore_buffer -= O
if(O && O.refined_type)
points += O.points * O.amount
points += O.points * point_upgrade * O.amount
var/material_amount = mat_container.get_item_material_amount(O)
-9
View File
@@ -260,15 +260,6 @@
viewalerts = 1
src << browse(dat, "window=aialerts&can_close=0")
/mob/living/silicon/ai/proc/ai_roster()
var/dat = "<html><head><title>Crew Roster</title></head><body><b>Crew Roster:</b><br><br>"
dat += GLOB.data_core.get_manifest()
dat += "</body></html>"
src << browse(dat, "window=airoster")
onclose(src, "airoster")
/mob/living/silicon/ai/proc/ai_call_shuttle()
if(control_disabled)
to_chat(usr, "<span class='warning'>Wireless control is disabled!</span>")
@@ -1298,4 +1298,12 @@
/mob/living/silicon/robot/adjustStaminaLossBuffered(amount, updating_health = 1)
if(istype(cell))
cell.charge -= amount*5
cell.charge -= amount*5
/mob/living/silicon/robot/verb/viewmanifest()
set category = "Robot Commands"
set name = "View Crew Manifest"
if(usr.stat == DEAD)
return //won't work if dead
ai_roster()
@@ -389,6 +389,15 @@
if (aicamera)
return aicamera.selectpicture(user)
/mob/living/silicon/proc/ai_roster()
var/dat = "<html><head><title>Crew Roster</title></head><body><b>Crew Roster:</b><br><br>"
dat += GLOB.data_core.get_manifest()
dat += "</body></html>"
src << browse(dat, "window=airoster")
onclose(src, "airoster")
/mob/living/silicon/update_transform()
var/matrix/ntransform = matrix(transform) //aka transform.Copy()
var/changed = 0
@@ -318,9 +318,9 @@
sleep(50)
if(mode == BOT_REPAIRING && src.loc == target_turf)
if(autotile) //Build the floor and include a tile.
target_turf.PlaceOnTop(/turf/open/floor/plasteel)
target_turf.PlaceOnTop(/turf/open/floor/plasteel, flags = CHANGETURF_INHERIT_AIR)
else //Build a hull plating without a floor tile.
target_turf.PlaceOnTop(/turf/open/floor/plating)
target_turf.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
else
var/turf/open/floor/F = target_turf
@@ -334,7 +334,7 @@
if(mode == BOT_REPAIRING && F && src.loc == F)
F.broken = 0
F.burnt = 0
F.PlaceOnTop(/turf/open/floor/plasteel)
F.PlaceOnTop(/turf/open/floor/plasteel, flags = CHANGETURF_INHERIT_AIR)
if(replacetiles && F.type != initial(tiletype.turf_type) && specialtiles && !isplatingturf(F))
anchored = TRUE
@@ -345,7 +345,7 @@
if(mode == BOT_REPAIRING && F && src.loc == F)
F.broken = 0
F.burnt = 0
F.PlaceOnTop(initial(tiletype.turf_type))
F.PlaceOnTop(initial(tiletype.turf_type), flags = CHANGETURF_INHERIT_AIR)
specialtiles -= 1
if(specialtiles == 0)
speak("Requesting refill of custom floortiles to continue replacing.")
@@ -486,10 +486,7 @@ Difficulty: Very Hard
if(isturf(Stuff))
var/turf/T = Stuff
if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors)
var/turf/open/O = T.ChangeTurf(NewTerrainFloors)
if(O.air)
var/datum/gas_mixture/G = O.air
G.copy_from_turf(O)
var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR)
if(prob(florachance) && NewFlora.len && !is_blocked_turf(O, TRUE))
var/atom/Picked = pick(NewFlora)
new Picked(O)
@@ -25,7 +25,7 @@
mob_size = MOB_SIZE_LARGE
layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
flags_1 = PREVENT_CONTENTS_EXPLOSION_1
flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1
var/list/crusher_loot
var/medal_type
var/score_type = BOSS_SCORE
@@ -20,7 +20,7 @@
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
mob_size = MOB_SIZE_LARGE
var/icon_aggro = null
var/crusher_drop_mod = 5
var/crusher_drop_mod = 25
/mob/living/simple_animal/hostile/asteroid/Initialize(mapload)
. = ..()
@@ -58,7 +58,7 @@
/mob/living/simple_animal/hostile/asteroid/death(gibbed)
SSblackbox.record_feedback("tally", "mobs_killed_mining", 1, type)
var/datum/status_effect/crusher_damage/C = has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
if(C && crusher_loot && prob((C.total_damage/maxHealth) * crusher_drop_mod)) //on average, you'll need to kill 20 creatures before getting the item
if(C && crusher_loot && prob((C.total_damage/maxHealth) * crusher_drop_mod)) //on average, you'll need to kill 4 creatures before getting the item
spawn_crusher_loot()
..(gibbed)
@@ -91,5 +91,5 @@
visible_message("<span class='boldannounce'>The tendril falls inward, the ground around it widening into a yawning chasm!</span>")
for(var/turf/T in range(2,src))
if(!T.density)
T.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland)
T.TerraformTurf(/turf/open/chasm/lavaland, /turf/open/chasm/lavaland, flags = CHANGETURF_INHERIT_AIR)
qdel(src)
+5
View File
@@ -37,6 +37,7 @@
var/burst_spread = 0 //Spread induced by the gun itself during burst fire per iteration. Only checked if spread is 0.
var/randomspread = 1 //Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once.
var/inaccuracy_modifier = 1
var/pb_knockback = 0
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
@@ -125,6 +126,10 @@
if(message)
if(pointblank)
user.visible_message("<span class='danger'>[user] fires [src] point blank at [pbtarget]!</span>", null, null, COMBAT_MESSAGE_RANGE)
if(pb_knockback > 0)
var/atom/throw_target = get_edge_target_turf(pbtarget, user.dir)
pbtarget.throw_at(throw_target, pb_knockback, 2)
else
user.visible_message("<span class='danger'>[user] fires [src]!</span>", null, null, COMBAT_MESSAGE_RANGE)
@@ -267,6 +267,7 @@
fire_delay = 0
pin = /obj/item/firing_pin/implant/pindicate
actions_types = list()
pb_knockback = 2
/obj/item/gun/ballistic/automatic/shotgun/bulldog/unrestricted
pin = /obj/item/firing_pin
@@ -273,6 +273,7 @@
"Maple" = "dshotgun-l",
"Rosewood" = "dshotgun-p"
)
pb_knockback = 3 // it's a super shotgun!
/obj/item/gun/ballistic/revolver/doublebarrel/attackby(obj/item/A, mob/user, params)
..()
@@ -12,6 +12,8 @@
var/recentpump = 0 // to prevent spammage
weapon_weight = WEAPON_MEDIUM
pb_knockback = 2
/obj/item/gun/ballistic/shotgun/attackby(obj/item/A, mob/user, params)
. = ..()
if(.)
@@ -56,6 +56,7 @@
item_flags = NONE
casing_ejector = FALSE
can_suppress = FALSE
pb_knockback = 0
/obj/item/gun/ballistic/shotgun/toy/process_chamber(empty_chamber = 0)
..()
+1 -1
View File
@@ -93,7 +93,7 @@
/obj/item/projectile/magic/door/proc/CreateDoor(turf/T)
var/door_type = pick(door_types)
var/obj/structure/mineral_door/D = new door_type(T)
T.ChangeTurf(/turf/open/floor/plating)
T.ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
D.Open()
/obj/item/projectile/magic/door/proc/OpenDoor(var/obj/machinery/door/D)
@@ -1870,133 +1870,82 @@
reagent_state = LIQUID
color = "#b51d05"
taste_description = "carpet" // Your tounge feels furry.
var/carpet_type = /turf/open/floor/carpet
/datum/reagent/carpet/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet)
F.PlaceOnTop(carpet_type, flags = CHANGETURF_INHERIT_AIR)
..()
/datum/reagent/carpet/black
name = "Liquid Black Carpet"
id = "blackcarpet"
color = "#363636"
/datum/reagent/carpet/black/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/black)
..()
carpet_type = /turf/open/floor/carpet/black
/datum/reagent/carpet/blackred
name = "Liquid Red Black Carpet"
id = "blackredcarpet"
color = "#342125"
/datum/reagent/carpet/blackred/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/blackred)
..()
carpet_type = /turf/open/floor/carpet/blackred
/datum/reagent/carpet/monochrome
name = "Liquid Monochrome Carpet"
id = "monochromecarpet"
color = "#b4b4b4"
/datum/reagent/carpet/monochrome/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/monochrome)
..()
carpet_type = /turf/open/floor/carpet/monochrome
/datum/reagent/carpet/blue
name = "Liquid Blue Carpet"
id = "bluecarpet"
color = "#1256ff"
/datum/reagent/carpet/blue/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/blue)
..()
carpet_type = /turf/open/floor/carpet/blue
/datum/reagent/carpet/cyan
name = "Liquid Cyan Carpet"
id = "cyancarpet"
color = "#3acfb9"
/datum/reagent/carpet/cyan/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/cyan)
..()
carpet_type = /turf/open/floor/carpet/cyan
/datum/reagent/carpet/green
name = "Liquid Green Carpet"
id = "greencarpet"
color = "#619b62"
/datum/reagent/carpet/green/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/green)
..()
carpet_type = /turf/open/floor/carpet/green
/datum/reagent/carpet/orange
name = "Liquid Orange Carpet"
id = "orangecarpet"
color = "#cc7900"
/datum/reagent/carpet/orange/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/orange)
..()
carpet_type = /turf/open/floor/carpet/orange
/datum/reagent/carpet/purple
name = "Liquid Purple Carpet"
id = "purplecarpet"
color = "#6d3392"
carpet_type = /turf/open/floor/carpet/purple
/datum/reagent/carpet/purple/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/purple)
..()
/datum/reagent/carpet/red
name = "Liquid Red Carpet"
id = "redcarpet"
color = "#871515"
carpet_type = /turf/open/floor/carpet/red
/datum/reagent/carpet/red/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/red)
..()
/datum/reagent/carpet/royalblack
name = "Liquid Royal Black Carpet"
id = "royalblackcarpet"
color = "#483d05"
carpet_type = /turf/open/floor/carpet/royalblack
/datum/reagent/carpet/royalblack/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/royalblack)
..()
/datum/reagent/carpet/royalblue
name = "Liquid Royal Blue Carpet"
id = "royalbluecarpet"
color = "#24227e"
/datum/reagent/carpet/royalblue/reaction_turf(turf/T, reac_volume)
if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
var/turf/open/floor/F = T
F.PlaceOnTop(/turf/open/floor/carpet/royalblue)
..()
carpet_type = /turf/open/floor/carpet/royalblue
// Virology virus food chems.
@@ -53,7 +53,7 @@
if(isplatingturf(T))
var/turf/open/floor/plating/F = T
if(prob(10 + F.burnt + 5*F.broken)) //broken or burnt plating is more susceptible to being destroyed
F.ScrapeAway()
F.ScrapeAway(flags = CHANGETURF_INHERIT_AIR)
if(isfloorturf(T))
var/turf/open/floor/F = T
if(prob(reac_volume))
@@ -123,24 +123,11 @@ GLOBAL_LIST_INIT(food_reagents, build_reagents_to_food()) //reagentid = related
/datum/chemical_reaction/randomized/proc/LoadOldRecipe(recipe_data)
created = text2num(recipe_data["timestamp"])
var/req_reag = unwrap_reagent_list(recipe_data["required_reagents"])
if(!req_reag)
return FALSE
required_reagents = req_reag
var/req_catalysts = unwrap_reagent_list(recipe_data["required_catalysts"])
if(!req_catalysts)
return FALSE
required_catalysts = req_catalysts
required_reagents = SANITIZE_LIST(recipe_data["required_reagents"])
required_catalysts = SANITIZE_LIST(recipe_data["required_catalysts"])
required_temp = recipe_data["required_temp"]
is_cold_recipe = recipe_data["is_cold_recipe"]
var/temp_results = unwrap_reagent_list(recipe_data["results"])
if(!temp_results)
return FALSE
results = temp_results
results = SANITIZE_LIST(recipe_data["results"])
var/containerpath = text2path(recipe_data["required_container"])
if(!containerpath)
return FALSE
@@ -109,11 +109,13 @@
/obj/item/reagent_containers/glass/beaker
name = "beaker"
desc = "A beaker. It can hold up to 50 units. Unable to withstand extreme pHes"
desc = "A beaker. It can hold up to 60 units. Unable to withstand extreme pHes."
icon = 'icons/obj/chemical.dmi'
volume = 60
icon_state = "beaker"
item_state = "beaker"
materials = list(MAT_GLASS=500)
possible_transfer_amounts = list(5,10,15,20,25,30,60)
beaker_weakness_bitflag = PH_WEAK
/obj/item/reagent_containers/glass/beaker/Initialize()
@@ -156,28 +158,28 @@
/obj/item/reagent_containers/glass/beaker/jar
name = "honey jar"
desc = "A jar for honey. It can hold up to 50 units of sweet delight. Unable to withstand reagents of an extreme pH."
desc = "A jar for honey. It can hold up to 60 units of sweet delight. Unable to withstand reagents of an extreme pH."
icon = 'icons/obj/chemical.dmi'
icon_state = "vapour"
/obj/item/reagent_containers/glass/beaker/large
name = "large beaker"
desc = "A large beaker. Can hold up to 100 units. Unable to withstand reagents of an extreme pH."
desc = "A large beaker. Can hold up to 120 units. Unable to withstand reagents of an extreme pH."
icon_state = "beakerlarge"
materials = list(MAT_GLASS=2500)
volume = 100
volume = 120
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
possible_transfer_amounts = list(5,10,15,20,25,30,40,60,120)
container_HP = 3
/obj/item/reagent_containers/glass/beaker/plastic
name = "x-large beaker"
desc = "An extra-large beaker. Can hold up to 150 units. Is able to resist acid and alkaline solutions, but melts at 444K"
desc = "An extra-large beaker. Can hold up to 180 units. Is able to resist acid and alkaline solutions, but melts at 444 K."
icon_state = "beakerwhite"
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000)
volume = 150
volume = 180
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,150)
possible_transfer_amounts = list(5,10,15,20,25,30,40,60,120,180)
/obj/item/reagent_containers/glass/beaker/plastic/Initialize()
beaker_weakness_bitflag &= ~PH_WEAK
@@ -191,14 +193,14 @@
/obj/item/reagent_containers/glass/beaker/meta
name = "metamaterial beaker"
desc = "A large beaker. Can hold up to 200 units. Is able to withstand all chemical situations."
desc = "A large beaker. Can hold up to 240 units, and is able to withstand all chemical situations."
icon_state = "beakergold"
materials = list(MAT_GLASS=2500, MAT_PLASTIC=3000, MAT_GOLD=1000, MAT_TITANIUM=1000)
volume = 200
volume = 240
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,200)
possible_transfer_amounts = list(5,10,15,20,25,30,40,60,120,200,240)
/obj/item/reagent_containers/glass/beaker/meta/Initialize()
/obj/item/reagent_containers/glass/beaker/meta/Initialize() // why the fuck can't you just set the beaker weakness bitflags to nothing? fuck you
beaker_weakness_bitflag &= ~PH_WEAK
. = ..()
@@ -228,7 +230,7 @@
volume = 300
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300)
container_HP = 4
container_HP = 5
/obj/item/reagent_containers/glass/beaker/cryoxadone
list_reagents = list("cryoxadone" = 30)
@@ -1,6 +1,6 @@
//hypovials used with the MkII hypospray. See hypospray.dm.
/obj/item/reagent_containers/glass/bottle/vial
/obj/item/reagent_containers/glass/bottle/vial // these have literally no fucking right to just be better beakers that you can shit out of a chemmaster
name = "broken hypovial"
desc = "A hypovial compatible with most hyposprays."
icon_state = "hypovial"
@@ -27,6 +27,8 @@
for(var/R in comes_with)
reagents.add_reagent(R,comes_with[R])
update_icon()
// beaker_weakness_bitflag |= PH_WEAK // fuck you if you're using these like beakers
// beaker_weakness_bitflag |= TEMP_WEAK
/obj/item/reagent_containers/glass/bottle/vial/on_reagent_change()
@@ -60,11 +62,11 @@
/obj/item/reagent_containers/glass/bottle/vial/small
name = "hypovial"
volume = 60
possible_transfer_amounts = list(5,10)
possible_transfer_amounts = list(1,2,5,10,20,30)
/obj/item/reagent_containers/glass/bottle/vial/small/bluespace
volume = 120
possible_transfer_amounts = list(5,10)
possible_transfer_amounts = list(1,2,5,10,20,30,40)
name = "bluespace hypovial"
icon_state = "hypovialbs"
unique_reskin = null
@@ -74,7 +76,7 @@
desc = "A large hypovial, for deluxe hypospray models."
icon_state = "hypoviallarge"
volume = 120
possible_transfer_amounts = list(5,10,15,20)
possible_transfer_amounts = list(1,2,5,10,20,30,40,60)
unique_reskin = list("large hypovial" = "hypoviallarge",
"large red hypovial" = "hypoviallarge-b",
"large blue hypovial" = "hypoviallarge-d",
@@ -106,7 +108,7 @@
add_overlay(filling)
/obj/item/reagent_containers/glass/bottle/vial/large/bluespace
possible_transfer_amounts = list(5,10,15,20)
possible_transfer_amounts = list(1,2,5,10,20,30,40,60)
name = "bluespace large hypovial"
volume = 240
icon_state = "hypoviallargebs"
+1 -1
View File
@@ -31,7 +31,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id)
/obj/machinery/conveyor/inverted/Initialize(mapload)
. = ..()
if(mapload && !(dir in GLOB.diagonals))
log_game("### MAPPING ERROR: [src] at [AREACOORD(src)] spawned without using a diagonal dir. Please replace with a normal version.")
log_mapping("[src] at [AREACOORD(src)] spawned without using a diagonal dir. Please replace with a normal version.")
// Auto conveyour is always on unless unpowered
@@ -25,6 +25,20 @@
program_type = /datum/nanite_program/viral
category = list("Utility Nanites")
/datum/design/nanites/research
name = "Distributed Computing"
desc = "The nanites aid the research servers by performing a portion of its calculations, increasing research point generation."
id = "research_nanites"
program_type = /datum/nanite_program/research
category = list("Utility Nanites")
/datum/design/nanites/researchplus
name = "Neural Network"
desc = "The nanites link the host's brains together forming a neural research network, that becomes more efficient with the amount of total hosts. Can be overloaded to increase research output."
id = "researchplus_nanites"
program_type = /datum/nanite_program/researchplus
category = list("Utility Nanites")
/datum/design/nanites/monitoring
name = "Monitoring"
desc = "The nanites monitor the host's vitals and location, sending them to the suit sensor network."
@@ -39,6 +53,13 @@
program_type = /datum/nanite_program/triggered/self_scan
category = list("Utility Nanites")
/datum/design/nanites/dermal_button
name = "Dermal Button"
desc = "Displays a button on the host's skin, which can be used to send a signal to the nanites."
id = "dermal_button_nanites"
program_type = /datum/nanite_program/dermal_button
category = list("Utility Nanites")
/datum/design/nanites/stealth
name = "Stealth"
desc = "The nanites hide their activity and programming from superficial scans."
@@ -46,6 +67,15 @@
program_type = /datum/nanite_program/stealth
category = list("Utility Nanites")
/datum/design/nanites/reduced_diagnostics
name = "Reduced Diagnostics"
desc = "Disables some high-cost diagnostics in the nanites, making them unable to communicate their program list to portable scanners. \
Doing so saves some power, slightly increasing their replication speed."
id = "red_diag_nanites"
program_type = /datum/nanite_program/reduced_diagnostics
category = list("Utility Nanites")
/datum/design/nanites/access
name = "Subdermal ID"
desc = "The nanites store the host's ID access rights in a subdermal magnetic strip. Updates when triggered, copying the host's current access."
@@ -130,7 +130,7 @@
/datum/nanite_program/stealth
name = "Stealth"
desc = "The nanites hide their activity and programming from superficial scans."
desc = "The nanites mask their activity from superficial scans, becoming undetectable by HUDs and non-specialized scanners."
rogue_types = list(/datum/nanite_program/toxic)
use_rate = 0.2
@@ -142,6 +142,22 @@
. = ..()
nanites.stealth = FALSE
/datum/nanite_program/reduced_diagnostics
name = "Reduced Diagnostics"
desc = "Disables some high-cost diagnostics in the nanites, making them unable to communicate their program list to portable scanners. \
Doing so saves some power, slightly increasing their replication speed."
rogue_types = list(/datum/nanite_program/toxic)
use_rate = -0.1
/datum/nanite_program/reduced_diagnostics/enable_passive_effect()
. = ..()
nanites.diagnostics = FALSE
/datum/nanite_program/reduced_diagnostics/disable_passive_effect()
. = ..()
nanites.diagnostics = TRUE
/datum/nanite_program/relay
name = "Relay"
desc = "The nanites receive and relay long-range nanite signals."
@@ -271,3 +287,138 @@
if(fault == src)
return
fault.software_error()
/datum/nanite_program/dermal_button
name = "Dermal Button"
desc = "Displays a button on the host's skin, which can be used to send a signal to the nanites."
extra_settings = list("Sent Code","Button Name","Icon","Color")
unique = FALSE
var/datum/action/innate/nanite_button/button
var/button_name = "Button"
var/icon = "power"
var/color = "green"
var/sent_code = 0
/datum/nanite_program/dermal_button/set_extra_setting(user, setting)
if(setting == "Sent Code")
var/new_code = input(user, "Set the sent code (1-9999):", name, null) as null|num
if(isnull(new_code))
return
sent_code = CLAMP(round(new_code, 1), 1, 9999)
if(setting == "Button Name")
var/new_button_name = stripped_input(user, "Choose the name for the button.", "Button Name", button_name, MAX_NAME_LEN)
if(!new_button_name)
return
button_name = new_button_name
if(setting == "Icon")
var/new_icon = input("Select the icon to display on the button:", name) as null|anything in list("one","two","three","four","five","plus","minus","power")
if(!new_icon)
return
icon = new_icon
if(setting == "Color")
var/new_color = input("Select the color of the button's icon:", name) as null|anything in list("green","red","yellow","blue")
if(!new_color)
return
color = new_color
/datum/nanite_program/dermal_button/get_extra_setting(setting)
if(setting == "Sent Code")
return sent_code
if(setting == "Button Name")
return button_name
if(setting == "Icon")
return capitalize(icon)
if(setting == "Color")
return capitalize(color)
/datum/nanite_program/dermal_button/copy_extra_settings_to(datum/nanite_program/dermal_button/target)
target.sent_code = sent_code
target.button_name = button_name
target.icon = icon
target.color = color
/datum/nanite_program/dermal_button/enable_passive_effect()
. = ..()
if(!button)
button = new(src, button_name, icon, color)
button.target = host_mob
button.Grant(host_mob)
/datum/nanite_program/dermal_button/disable_passive_effect()
. = ..()
if(button)
button.Remove(host_mob)
/datum/nanite_program/dermal_button/on_mob_remove()
. = ..()
qdel(button)
/datum/nanite_program/dermal_button/proc/press()
if(activated)
host_mob.visible_message("<span class='notice'>[host_mob] presses a button on [host_mob.p_their()] forearm.</span>",
"<span class='notice'>You press the nanite button on your forearm.</span>", null, 2)
SEND_SIGNAL(host_mob, COMSIG_NANITE_SIGNAL, sent_code, "a [name] program")
/datum/action/innate/nanite_button
name = "Button"
icon_icon = 'icons/mob/actions/actions_items.dmi'
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
button_icon_state = "power_green"
var/datum/nanite_program/dermal_button/program
/datum/action/innate/nanite_button/New(datum/nanite_program/dermal_button/_program, _name, _icon, _color)
..()
program = _program
name = _name
button_icon_state = "[_icon]_[_color]"
/datum/action/innate/nanite_button/Activate()
program.press()
/datum/nanite_program/research
name = "Distributed Computing"
desc = "The nanites aid the research servers by performing a portion of its calculations, increasing research point generation."
use_rate = 0.2
rogue_types = list(/datum/nanite_program/toxic)
/datum/nanite_program/research/active_effect()
if(!iscarbon(host_mob))
return
var/points = 1
if(!host_mob.client) //less brainpower
points *= 0.25
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points))
/datum/nanite_program/researchplus
name = "Neural Network"
desc = "The nanites link the host's brains together forming a neural research network, that becomes more efficient with the amount of total hosts."
use_rate = 0.3
rogue_types = list(/datum/nanite_program/brain_decay)
/datum/nanite_program/researchplus/enable_passive_effect()
. = ..()
if(!iscarbon(host_mob))
return
if(host_mob.client)
SSnanites.neural_network_count++
else
SSnanites.neural_network_count += 0.25
/datum/nanite_program/researchplus/disable_passive_effect()
. = ..()
if(!iscarbon(host_mob))
return
if(host_mob.client)
SSnanites.neural_network_count--
else
SSnanites.neural_network_count -= 0.25
/datum/nanite_program/researchplus/active_effect()
if(!iscarbon(host_mob))
return
var/mob/living/carbon/C = host_mob
var/points = round(SSnanites.neural_network_count / 12, 0.1)
if(!C.client) //less brainpower
points *= 0.25
SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points))
+13 -1
View File
@@ -130,4 +130,16 @@
program_type = /datum/nanite_program/pacifying
/obj/item/disk/nanite_program/stun
program_type = /datum/nanite_program/triggered/stun
program_type = /datum/nanite_program/triggered/stun
/obj/item/disk/nanite_program/dermal_button
program_type = /datum/nanite_program/dermal_button
/obj/item/disk/nanite_program/research
program_type = /datum/nanite_program/research
/obj/item/disk/nanite_program/researchplus
program_type = /datum/nanite_program/researchplus
/obj/item/disk/nanite_program/reduced_diagnostics
program_type = /datum/nanite_program/reduced_diagnostics
+4 -4
View File
@@ -960,7 +960,7 @@
prereq_ids = list("datatheory","robotics")
design_ids = list("nanite_disk","nanite_remote","nanite_scanner",\
"nanite_chamber","public_nanite_chamber","nanite_chamber_control","nanite_programmer","nanite_program_hub","nanite_cloud_control",\
"relay_nanites", "monitoring_nanites", "access_nanites", "repairing_nanites","sensor_nanite_volume", "repeater_nanites", "relay_repeater_nanites")
"relay_nanites", "monitoring_nanites", "access_nanites", "repairing_nanites","sensor_nanite_volume", "repeater_nanites", "relay_repeater_nanites","red_diag_nanites")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -969,7 +969,7 @@
display_name = "Smart Nanite Programming"
description = "Nanite programs that require nanites to perform complex actions, act independently, roam or seek targets."
prereq_ids = list("nanite_base","adv_robotics")
design_ids = list("purging_nanites", "metabolic_nanites", "stealth_nanites", "memleak_nanites","sensor_voice_nanites", "voice_nanites")
design_ids = list("purging_nanites", "research_nanites", "metabolic_nanites", "stealth_nanites", "memleak_nanites","sensor_voice_nanites", "voice_nanites")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000)
export_price = 4000
@@ -978,7 +978,7 @@
display_name = "Mesh Nanite Programming"
description = "Nanite programs that require static structures and membranes."
prereq_ids = list("nanite_base","engineering")
design_ids = list("hardening_nanites", "refractive_nanites", "cryo_nanites", "conductive_nanites", "shock_nanites", "emp_nanites", "temperature_nanites")
design_ids = list("hardening_nanites", "dermal_button_nanites", "refractive_nanites", "cryo_nanites", "conductive_nanites", "shock_nanites", "emp_nanites", "temperature_nanites")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -1015,7 +1015,7 @@
display_name = "Harmonic Nanite Programming"
description = "Nanite programs that require seamless integration between nanites and biology."
prereq_ids = list("nanite_bio","nanite_smart","nanite_mesh")
design_ids = list("fakedeath_nanites","aggressive_nanites","defib_nanites","regenerative_plus_nanites","brainheal_plus_nanites","purging_plus_nanites","adrenaline_nanites")
design_ids = list("fakedeath_nanites","researchplus_nanites","aggressive_nanites","defib_nanites","regenerative_plus_nanites","brainheal_plus_nanites","purging_plus_nanites","adrenaline_nanites")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000)
export_price = 8000
@@ -108,7 +108,7 @@
if (levels.len)
dest = locate(T.x, T.y, pick(levels))
T.ChangeTurf(/turf/open/chasm)
T.ChangeTurf(/turf/open/chasm, flags = CHANGETURF_INHERIT_AIR)
var/turf/open/chasm/C = T
C.set_target(dest)
C.drop(user)
+1 -1
View File
@@ -31,7 +31,7 @@
if(ispath(summoned_object_type, /turf))
var/turf/O = spawn_place
var/N = summoned_object_type
O.ChangeTurf(N)
O.ChangeTurf(N, flags = CHANGETURF_INHERIT_AIR)
else
var/atom/summoned_object = new summoned_object_type(spawn_place)
+2 -2
View File
@@ -234,7 +234,7 @@
dancefloor_exists = FALSE
for(var/i in 1 to dancefloor_turfs.len)
var/turf/T = dancefloor_turfs[i]
T.ChangeTurf(dancefloor_turfs_types[i])
T.ChangeTurf(dancefloor_turfs_types[i], flags = CHANGETURF_INHERIT_AIR)
else
var/list/funky_turfs = RANGE_TURFS(1, user)
for(var/turf/closed/solid in funky_turfs)
@@ -248,7 +248,7 @@
var/turf/T = t
dancefloor_turfs[i] = T
dancefloor_turfs_types[i] = T.type
T.ChangeTurf((i % 2 == 0) ? /turf/open/floor/light/colour_cycle/dancefloor_a : /turf/open/floor/light/colour_cycle/dancefloor_b)
T.ChangeTurf((i % 2 == 0) ? /turf/open/floor/light/colour_cycle/dancefloor_a : /turf/open/floor/light/colour_cycle/dancefloor_b, flags = CHANGETURF_INHERIT_AIR)
i++
/datum/effect_system/smoke_spread/transparent/dancefloor_devil