Merge remote-tracking branch 'upstream/master' into TGUI_Updoot
This commit is contained in:
@@ -681,3 +681,11 @@
|
||||
continue
|
||||
if(istype(D, path))
|
||||
return TRUE
|
||||
|
||||
/proc/safe_json_encode(list/L, default = "")
|
||||
. = default
|
||||
return json_encode(L)
|
||||
|
||||
/proc/safe_json_decode(string, default = list())
|
||||
. = default
|
||||
return json_decode(string)
|
||||
|
||||
@@ -402,7 +402,7 @@
|
||||
for (var/i in GLOB.ai_list)
|
||||
var/mob/living/silicon/ai/aiPlayer = i
|
||||
if(aiPlayer.mind)
|
||||
parts += "<b>[aiPlayer.name]</b> (Played by: <b>[aiPlayer.mind.key]</b>)'s laws [aiPlayer.stat != DEAD ? "at the end of the round" : "when it was <span class='redtext'>deactivated</span>"] were:"
|
||||
parts += "<b>[aiPlayer.name]</b>[aiPlayer.mind.hide_ckey ? "" : " (Played by: <b>[aiPlayer.mind.key]</b>)"]'s laws [aiPlayer.stat != DEAD ? "at the end of the round" : "when it was <span class='redtext'>deactivated</span>"] were:"
|
||||
parts += aiPlayer.laws.get_law_list(include_zeroth=TRUE)
|
||||
|
||||
parts += "<b>Total law changes: [aiPlayer.law_change_counter]</b>"
|
||||
@@ -413,14 +413,14 @@
|
||||
for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots)
|
||||
borg_num--
|
||||
if(robo.mind)
|
||||
robolist += "<b>[robo.name]</b> (Played by: <b>[robo.mind.key]</b>)[robo.stat == DEAD ? " <span class='redtext'>(Deactivated)</span>" : ""][borg_num ?", ":""]<br>"
|
||||
robolist += "<b>[robo.name]</b>[robo.mind.hide_ckey ? "" : " (Played by: <b>[robo.mind.key]</b>)"] [robo.stat == DEAD ? " <span class='redtext'>(Deactivated)</span>" : ""][borg_num ?", ":""]<br>"
|
||||
parts += "[robolist]"
|
||||
if(!borg_spacer)
|
||||
borg_spacer = TRUE
|
||||
|
||||
for (var/mob/living/silicon/robot/robo in GLOB.silicon_mobs)
|
||||
if (!robo.connected_ai && robo.mind)
|
||||
parts += "[borg_spacer?"<br>":""]<b>[robo.name]</b> (Played by: <b>[robo.mind.key]</b>) [(robo.stat != DEAD)? "<span class='greentext'>survived</span> as an AI-less borg!" : "was <span class='redtext'>unable to survive</span> the rigors of being a cyborg without an AI."] Its laws were:"
|
||||
parts += "[borg_spacer?"<br>":""]<b>[robo.name]</b>[robo.mind.hide_ckey ? "" : " (Played by: <b>[robo.mind.key]</b>)"] [(robo.stat != DEAD)? "<span class='greentext'>survived</span> as an AI-less borg!" : "was <span class='redtext'>unable to survive</span> the rigors of being a cyborg without an AI."] Its laws were:"
|
||||
|
||||
if(robo) //How the hell do we lose robo between here and the world messages directly above this?
|
||||
parts += robo.laws.get_law_list(include_zeroth=TRUE)
|
||||
@@ -529,7 +529,7 @@
|
||||
var/jobtext = ""
|
||||
if(ply.assigned_role)
|
||||
jobtext = " the <b>[ply.assigned_role]</b>"
|
||||
var/text = "<b>[ply.key]</b> was <b>[ply.name]</b>[jobtext] and"
|
||||
var/text = "<b>[ply.hide_ckey ? "<b>[ply.name]</b>[jobtext] " : "[ply.key]</b> was <b>[ply.name]</b>[jobtext] and "]"
|
||||
if(ply.current)
|
||||
if(ply.current.stat == DEAD)
|
||||
text += " <span class='redtext'>died</span>"
|
||||
|
||||
@@ -462,16 +462,14 @@
|
||||
else
|
||||
. = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307))
|
||||
|
||||
/proc/fusionpower2text(power) //used when displaying fusion power on analyzers
|
||||
switch(power)
|
||||
if(0 to 5)
|
||||
return "low"
|
||||
if(5 to 20)
|
||||
return "mid"
|
||||
if(20 to 50)
|
||||
return "high"
|
||||
if(50 to INFINITY)
|
||||
return "super"
|
||||
/proc/instability2text(instability) //used when displaying fusion power on analyzers
|
||||
switch(instability)
|
||||
if(0 to 2)
|
||||
return "stable, meaning that its heat will always increase."
|
||||
if(2 to 3)
|
||||
return "metastable, meaning that its heat will trend upwards."
|
||||
if (3 to INFINITY)
|
||||
return "unstable, meaning that its heat will trend downwards."
|
||||
|
||||
/proc/color2hex(color) //web colors
|
||||
if(!color)
|
||||
|
||||
@@ -107,13 +107,8 @@ GLOBAL_LIST_INIT(maintenance_loot, list(
|
||||
/obj/item/toy/eightball = 1,
|
||||
/obj/item/reagent_containers/pill/floorpill = 1,
|
||||
/obj/item/reagent_containers/food/snacks/cannedpeaches/maint = 2,
|
||||
/obj/item/storage/daki = 3, //VERY IMPORTANT CIT CHANGE - adds bodypillows to maint
|
||||
/obj/item/storage/pill_bottle/penis_enlargement = 2,
|
||||
/obj/item/storage/pill_bottle/breast_enlargement = 2,
|
||||
/obj/item/clothing/shoes/wheelys = 1,
|
||||
/obj/item/clothing/shoes/kindleKicks = 1,
|
||||
/obj/item/autosurgeon/penis = 1,
|
||||
/obj/item/autosurgeon/testicles = 1,
|
||||
/obj/item/storage/box/marshmallow = 2,
|
||||
/obj/item/clothing/gloves/tackler/offbrand = 1,
|
||||
/obj/item/stack/sticky_tape = 1,
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
var/special_role
|
||||
var/list/restricted_roles = list()
|
||||
|
||||
var/hide_ckey = FALSE //hide ckey from round-end report
|
||||
|
||||
var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button.
|
||||
|
||||
var/linglink
|
||||
@@ -69,6 +71,7 @@
|
||||
///What character we spawned in as- either at roundstart or latejoin, so we know for persistent scars if we ended as the same person or not
|
||||
var/mob/original_character
|
||||
|
||||
|
||||
/datum/mind/New(var/key)
|
||||
skill_holder = new(src)
|
||||
src.key = key
|
||||
@@ -138,6 +141,8 @@
|
||||
if(L.client?.prefs && L.client.prefs.auto_ooc && L.client.prefs.chat_toggles & CHAT_OOC)
|
||||
DISABLE_BITFIELD(L.client.prefs.chat_toggles,CHAT_OOC)
|
||||
|
||||
hide_ckey = current.client?.prefs?.hide_ckey
|
||||
|
||||
SEND_SIGNAL(src, COMSIG_MIND_TRANSFER, new_character, old_character)
|
||||
SEND_SIGNAL(new_character, COMSIG_MOB_ON_NEW_MIND)
|
||||
|
||||
@@ -782,6 +787,7 @@
|
||||
if(!mind.name)
|
||||
mind.name = real_name
|
||||
mind.current = src
|
||||
mind.hide_ckey = client?.prefs?.hide_ckey
|
||||
|
||||
/mob/living/carbon/mind_initialize()
|
||||
..()
|
||||
|
||||
@@ -285,7 +285,7 @@
|
||||
S.rabid = TRUE
|
||||
S.amount_grown = SLIME_EVOLUTION_THRESHOLD
|
||||
S.Evolve()
|
||||
offer_control(S)
|
||||
offer_control(S,POLL_IGNORE_SENTIENCE_POTION)
|
||||
|
||||
/////////////////////
|
||||
|
||||
|
||||
@@ -729,10 +729,10 @@ GENETICS SCANNER
|
||||
to_chat(user, "<span class='notice'>[target] is empty!</span>")
|
||||
|
||||
if(cached_scan_results && cached_scan_results["fusion"]) //notify the user if a fusion reaction was detected
|
||||
var/fusion_power = round(cached_scan_results["fusion"], 0.01)
|
||||
var/tier = fusionpower2text(fusion_power)
|
||||
var/instability = round(cached_scan_results["fusion"], 0.01)
|
||||
var/tier = instability2text(instability)
|
||||
to_chat(user, "<span class='boldnotice'>Large amounts of free neutrons detected in the air indicate that a fusion reaction took place.</span>")
|
||||
to_chat(user, "<span class='notice'>Power of the last fusion reaction: [fusion_power]\n This power indicates it was a [tier]-tier fusion reaction.</span>")
|
||||
to_chat(user, "<span class='notice'>Instability of the last fusion reaction: [instability]\n This indicates it was [tier].</span>")
|
||||
return
|
||||
|
||||
/obj/item/analyzer/proc/scan_turf(mob/user, turf/location)
|
||||
@@ -783,10 +783,10 @@ GENETICS SCANNER
|
||||
to_chat(user, "<span class='info'>Temperature: [round(environment.return_temperature()-T0C, 0.01)] °C ([round(environment.return_temperature(), 0.01)] K)</span>")
|
||||
|
||||
if(cached_scan_results && cached_scan_results["fusion"]) //notify the user if a fusion reaction was detected
|
||||
var/fusion_power = round(cached_scan_results["fusion"], 0.01)
|
||||
var/tier = fusionpower2text(fusion_power)
|
||||
var/instability = round(cached_scan_results["fusion"], 0.01)
|
||||
var/tier = instability2text(instability)
|
||||
to_chat(user, "<span class='boldnotice'>Large amounts of free neutrons detected in the air indicate that a fusion reaction took place.</span>")
|
||||
to_chat(user, "<span class='notice'>Power of the last fusion reaction: [fusion_power]\n This power indicates it was a [tier]-tier fusion reaction.</span>")
|
||||
to_chat(user, "<span class='notice'>Instability of the last fusion reaction: [instability]\n This indicates it was [tier].</span>")
|
||||
|
||||
/obj/item/analyzer/ranged
|
||||
desc = "A hand-held scanner which uses advanced spectroscopy and infrared readings to analyze gases as a distance. Alt-Click to use the built in barometer function."
|
||||
@@ -992,4 +992,4 @@ GENETICS SCANNER
|
||||
#undef SCANMODE_CHEMICAL
|
||||
#undef SCANMODE_WOUND
|
||||
#undef SCANNER_CONDENSED
|
||||
#undef SCANNER_VERBOSE
|
||||
#undef SCANNER_VERBOSE
|
||||
|
||||
@@ -234,6 +234,9 @@
|
||||
/obj/item/melee/rapier/attack(mob/living/target, mob/living/user)
|
||||
. = ..()
|
||||
if(iscarbon(target))
|
||||
if(HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
visible_message("<span class='warning'>[user] gently taps [target] with [src].</span>",null,null,COMBAT_MESSAGE_RANGE)
|
||||
log_combat(user, target, "slept", src)
|
||||
var/mob/living/carbon/H = target
|
||||
H.Dizzy(10)
|
||||
H.adjustStaminaLoss(30)
|
||||
|
||||
@@ -20,8 +20,6 @@ GLOBAL_LIST(topic_status_cache)
|
||||
|
||||
log_world("World loaded at [TIME_STAMP("hh:mm:ss", FALSE)]!")
|
||||
|
||||
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.[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)
|
||||
@@ -87,17 +85,6 @@ GLOBAL_LIST(topic_status_cache)
|
||||
#endif
|
||||
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, /proc/addtimer, cb, 10 SECONDS))
|
||||
|
||||
/world/proc/SetupExternalRSC()
|
||||
#if (PRELOAD_RSC == 0)
|
||||
GLOB.external_rsc_urls = world.file2list("[global.config.directory]/external_rsc_urls.txt","\n")
|
||||
var/i=1
|
||||
while(i<=GLOB.external_rsc_urls.len)
|
||||
if(GLOB.external_rsc_urls[i])
|
||||
i++
|
||||
else
|
||||
GLOB.external_rsc_urls.Cut(i,i+1)
|
||||
#endif
|
||||
|
||||
/world/proc/SetupLogs()
|
||||
var/override_dir = params[OVERRIDE_LOG_DIRECTORY_PARAMETER]
|
||||
if(!override_dir)
|
||||
|
||||
@@ -163,6 +163,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
)
|
||||
var/custom_speech_verb = "default" //if your say_mod is to be something other than your races
|
||||
var/custom_tongue = "default" //if your tongue is to be something other than your races
|
||||
var/chosen_limb_id //body sprite selected to load for the users limbs, null means default, is sanitized when loaded
|
||||
|
||||
/// Security record note section
|
||||
var/security_records
|
||||
@@ -246,7 +247,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
/// Which of the 5 persistent scar slots we randomly roll to load for this round, if enabled. Actually rolled in [/datum/preferences/proc/load_character(slot)]
|
||||
var/scars_index = 1
|
||||
|
||||
var/chosen_limb_id //body sprite selected to load for the users limbs, null means default, is sanitized when loaded
|
||||
var/hide_ckey = FALSE //pref for hiding if your ckey shows round-end or not
|
||||
|
||||
/datum/preferences/New(client/C)
|
||||
parent = C
|
||||
@@ -372,6 +373,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "[medical_records]"
|
||||
else
|
||||
dat += "[TextPreview(medical_records)]...<BR>"
|
||||
dat += "<br><a href='?_src_=prefs;preference=hide_ckey;task=input'><b>Hide ckey: [hide_ckey ? "Enabled" : "Disabled"]</b></a><br>"
|
||||
dat += "</tr></table>"
|
||||
|
||||
//Character Appearance
|
||||
@@ -1448,6 +1450,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if(!isnull(msg))
|
||||
features["ooc_notes"] = msg
|
||||
|
||||
if("hide_ckey")
|
||||
hide_ckey = !hide_ckey
|
||||
if(user)
|
||||
user.mind?.hide_ckey = hide_ckey
|
||||
|
||||
if("hair")
|
||||
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference","#"+hair_color) as color|null
|
||||
if(new_hair)
|
||||
|
||||
@@ -515,7 +515,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
S["scars4"] >> scars_list["4"]
|
||||
S["scars5"] >> scars_list["5"]
|
||||
S["chosen_limb_id"] >> chosen_limb_id
|
||||
|
||||
S["hide_ckey"] >> hide_ckey //saved per-character
|
||||
|
||||
//Custom names
|
||||
for(var/custom_name_id in GLOB.preferences_custom_names)
|
||||
@@ -859,6 +859,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["joblessrole"] , joblessrole)
|
||||
//Write prefs
|
||||
WRITE_FILE(S["job_preferences"] , job_preferences)
|
||||
WRITE_FILE(S["hide_ckey"] , hide_ckey)
|
||||
|
||||
//Quirks
|
||||
WRITE_FILE(S["all_quirks"] , all_quirks)
|
||||
@@ -874,6 +875,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
WRITE_FILE(S["scars4"] , scars_list["4"])
|
||||
WRITE_FILE(S["scars5"] , scars_list["5"])
|
||||
|
||||
|
||||
//gear loadout
|
||||
if(chosen_gear.len)
|
||||
var/text_to_save = chosen_gear.Join("|")
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
set_colour(new_colour)
|
||||
. = ..()
|
||||
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_SLIME, 7.5)
|
||||
set_nutrition(rand(650, 800))
|
||||
|
||||
/mob/living/simple_animal/slime/Destroy()
|
||||
for (var/A in actions)
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
var/datum/callback/CB = foo
|
||||
CB.Invoke()
|
||||
|
||||
mind?.hide_ckey = client?.prefs?.hide_ckey
|
||||
|
||||
log_message("Client [key_name(src)] has taken ownership of mob [src]([src.type])", LOG_OWNERSHIP)
|
||||
SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client)
|
||||
|
||||
|
||||
@@ -431,7 +431,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
/mob/living/getImplant(type)
|
||||
return locate(type) in implants
|
||||
|
||||
/proc/offer_control(mob/M)
|
||||
/proc/offer_control(mob/M,ignore_category=null)
|
||||
to_chat(M, "Control of your mob has been offered to dead players.")
|
||||
if(usr)
|
||||
log_admin("[key_name(usr)] has offered control of ([key_name(M)]) to ghosts.")
|
||||
@@ -445,7 +445,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
var/datum/antagonist/A = M.mind.has_antag_datum(/datum/antagonist/)
|
||||
if(A)
|
||||
poll_message = "[poll_message] Status:[A.name]."
|
||||
var/list/mob/candidates = pollCandidatesForMob(poll_message, ROLE_PAI, null, FALSE, 100, M)
|
||||
var/list/mob/candidates = pollCandidatesForMob(poll_message, ROLE_PAI, null, FALSE, 100, M, ignore_category)
|
||||
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/C = pick(candidates)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#ifdef UNIT_TESTS
|
||||
#include "anchored_mobs.dm"
|
||||
#include "character_saving.dm"
|
||||
#include "component_tests.dm"
|
||||
#include "reagent_id_typos.dm"
|
||||
#include "reagent_recipe_collisions.dm"
|
||||
|
||||
14
code/modules/unit_tests/character_saving.dm
Normal file
14
code/modules/unit_tests/character_saving.dm
Normal file
@@ -0,0 +1,14 @@
|
||||
/datum/unit_test/character_saving/Run()
|
||||
try
|
||||
var/datum/preferences/P = new
|
||||
P.load_path("test")
|
||||
P.features["flavor_text"] = "Foo"
|
||||
P.features["ooc_notes"] = "Bar"
|
||||
P.save_character()
|
||||
P.load_character()
|
||||
if(P.features["flavor_text"] != "Foo")
|
||||
Fail("Flavor text is failing to save.")
|
||||
if(P.features["ooc_notes"] != "Bar")
|
||||
Fail("OOC text is failing to save.")
|
||||
catch(var/exception/e)
|
||||
Fail("Failed to save and load character due to exception [e.name]")
|
||||
@@ -26,7 +26,12 @@
|
||||
/obj/item/clothing/under/shorts/polychromic/pantsu = 3,
|
||||
/obj/item/clothing/under/misc/poly_bottomless = 3,
|
||||
/obj/item/clothing/under/misc/poly_tanktop = 3,
|
||||
/obj/item/clothing/under/misc/poly_tanktop/female = 3
|
||||
/obj/item/clothing/under/misc/poly_tanktop/female = 3,
|
||||
/obj/item/autosurgeon/penis = 3,
|
||||
/obj/item/autosurgeon/testicles = 3,
|
||||
/obj/item/storage/pill_bottle/penis_enlargement = 5,
|
||||
/obj/item/storage/pill_bottle/breast_enlargement = 5,
|
||||
/obj/item/storage/daki = 4
|
||||
)
|
||||
contraband = list(
|
||||
/obj/item/clothing/neck/petcollar/locked = 2,
|
||||
|
||||
Reference in New Issue
Block a user