diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm
index c030807cc33..2b4d99cb8c2 100644
--- a/code/__HELPERS/_logging.dm
+++ b/code/__HELPERS/_logging.dm
@@ -165,6 +165,18 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
//reusing the PDA option because I really don't think news comments are worth a config option
WRITE_LOG(GLOB.world_pda_log, "COMMENT: [text]")
+/proc/log_uplink(text)
+ if (CONFIG_GET(flag/log_uplink))
+ WRITE_LOG(GLOB.world_uplink_log, "UPLINK: [text]")
+
+/proc/log_spellbook(text)
+ if (CONFIG_GET(flag/log_uplink))
+ WRITE_LOG(GLOB.world_uplink_log, "SPELLBOOK: [text]")
+
+/proc/log_codex_ciatrix(text)
+ if (CONFIG_GET(flag/log_uplink))
+ WRITE_LOG(GLOB.world_uplink_log, "CODEX: [text]")
+
/proc/log_telecomms(text)
if (CONFIG_GET(flag/log_telecomms))
WRITE_LOG(GLOB.world_telecomms_log, "TCOMMS: [text]")
diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm
index af50698a003..20dd6b6df87 100644
--- a/code/_globalvars/logging.dm
+++ b/code/_globalvars/logging.dm
@@ -20,6 +20,8 @@ GLOBAL_VAR(sql_error_log)
GLOBAL_PROTECT(sql_error_log)
GLOBAL_VAR(world_pda_log)
GLOBAL_PROTECT(world_pda_log)
+GLOBAL_VAR(world_uplink_log)
+GLOBAL_PROTECT(world_uplink_log)
GLOBAL_VAR(world_telecomms_log)
GLOBAL_PROTECT(world_telecomms_log)
GLOBAL_VAR(world_manifest_log)
diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm
index 99a6ae0b379..afa8bd15a53 100644
--- a/code/controllers/configuration/entries/general.dm
+++ b/code/controllers/configuration/entries/general.dm
@@ -86,6 +86,8 @@
/datum/config_entry/flag/log_pda // log pda messages
+/datum/config_entry/flag/log_uplink // log uplink/spellbook/codex ciatrix purchases and refunds
+
/datum/config_entry/flag/log_telecomms // log telecomms messages
/datum/config_entry/flag/log_twitter // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm
index 105bcbdef9f..5073ec6a616 100644
--- a/code/datums/components/uplink.dm
+++ b/code/datums/components/uplink.dm
@@ -88,6 +88,7 @@
var/amt = TC.amount
telecrystals += amt
TC.use(amt)
+ log_uplink("[key_name(user)] loaded [amt] telecrystals into [parent]'s uplink")
/datum/component/uplink/proc/set_gamemode(_gamemode)
gamemode = _gamemode
@@ -107,6 +108,7 @@
var/cost = UI.refund_amount || UI.cost
if(I.type == path && UI.refundable && I.check_uplink_validity())
telecrystals += cost
+ log_uplink("[key_name(user)] refunded [UI] for [cost] telecrystals using [parent]'s uplink")
if(purchase_log)
purchase_log.total_spent -= cost
to_chat(user, "[I] refunded.")
diff --git a/code/game/world.dm b/code/game/world.dm
index 8842c825637..75a6c3fdf74 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -132,6 +132,7 @@ GLOBAL_VAR(restart_counter)
GLOB.world_attack_log = "[GLOB.log_directory]/attack.log"
GLOB.world_econ_log = "[GLOB.log_directory]/econ.log"
GLOB.world_pda_log = "[GLOB.log_directory]/pda.log"
+ GLOB.world_uplink_log = "[GLOB.log_directory]/uplink.log"
GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log"
GLOB.world_manifest_log = "[GLOB.log_directory]/manifest.log"
GLOB.world_href_log = "[GLOB.log_directory]/hrefs.log"
@@ -155,6 +156,7 @@ GLOBAL_VAR(restart_counter)
start_log(GLOB.world_attack_log)
start_log(GLOB.world_econ_log)
start_log(GLOB.world_pda_log)
+ start_log(GLOB.world_uplink_log)
start_log(GLOB.world_telecomms_log)
start_log(GLOB.world_manifest_log)
start_log(GLOB.world_href_log)
@@ -270,7 +272,7 @@ GLOBAL_VAR(restart_counter)
TgsEndProcess()
log_world("World rebooted at [time_stamp()]")
-
+
TgsReboot()
shutdown_logging() // Past this point, no logging procs can be used, at risk of data loss.
..()
diff --git a/code/modules/antagonists/eldritch_cult/eldritch_book.dm b/code/modules/antagonists/eldritch_cult/eldritch_book.dm
index 705a3f9d1da..9be366f43a7 100644
--- a/code/modules/antagonists/eldritch_cult/eldritch_book.dm
+++ b/code/modules/antagonists/eldritch_cult/eldritch_book.dm
@@ -131,6 +131,7 @@
if(initial(EK.name) != ekname)
continue
if(cultie.gain_knowledge(EK))
+ log_codex_ciatrix("[key_name(last_user)] gained knowledge of [EK]")
charge -= initial(EK.cost)
return TRUE
diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm
index ade99a7002e..0c8807f6b97 100644
--- a/code/modules/antagonists/wizard/equipment/spellbook.dm
+++ b/code/modules/antagonists/wizard/equipment/spellbook.dm
@@ -32,34 +32,37 @@
S = new spell_type()
//Check if we got the spell already
for(var/obj/effect/proc_holder/spell/aspell in user.mind.spell_list)
- if(initial(S.name) == initial(aspell.name)) // Not using directly in case it was learned from one spellbook then upgraded in another
- if(aspell.spell_level >= aspell.level_max)
- to_chat(user, "This spell cannot be improved further!")
- return FALSE
- else
- aspell.name = initial(aspell.name)
- aspell.spell_level++
- aspell.charge_max = round(initial(aspell.charge_max) - aspell.spell_level * (initial(aspell.charge_max) - aspell.cooldown_min)/ aspell.level_max)
- if(aspell.charge_max < aspell.charge_counter)
- aspell.charge_counter = aspell.charge_max
- switch(aspell.spell_level)
- if(1)
- to_chat(user, "You have improved [aspell.name] into Efficient [aspell.name].")
- aspell.name = "Efficient [aspell.name]"
- if(2)
- to_chat(user, "You have further improved [aspell.name] into Quickened [aspell.name].")
- aspell.name = "Quickened [aspell.name]"
- if(3)
- to_chat(user, "You have further improved [aspell.name] into Free [aspell.name].")
- aspell.name = "Free [aspell.name]"
- if(4)
- to_chat(user, "You have further improved [aspell.name] into Instant [aspell.name].")
- aspell.name = "Instant [aspell.name]"
- if(aspell.spell_level >= aspell.level_max)
- to_chat(user, "This spell cannot be strengthened any further!")
- SSblackbox.record_feedback("nested tally", "wizard_spell_improved", 1, list("[name]", "[aspell.spell_level]"))
- return TRUE
+ if(initial(S.name) != initial(aspell.name)) // Not using directly in case it was learned from one spellbook then upgraded in another
+ continue
+ if(aspell.spell_level >= aspell.level_max)
+ to_chat(user, "This spell cannot be improved further!")
+ return FALSE
+
+ aspell.name = initial(aspell.name)
+ aspell.spell_level++
+ aspell.charge_max = round(LERP(initial(aspell.charge_max), aspell.cooldown_min, aspell.spell_level / aspell.level_max))
+ if(aspell.charge_max < aspell.charge_counter)
+ aspell.charge_counter = aspell.charge_max
+ switch(aspell.spell_level)
+ if(1)
+ to_chat(user, "You have improved [aspell.name] into Efficient [aspell.name].")
+ aspell.name = "Efficient [aspell.name]"
+ if(2)
+ to_chat(user, "You have further improved [aspell.name] into Quickened [aspell.name].")
+ aspell.name = "Quickened [aspell.name]"
+ if(3)
+ to_chat(user, "You have further improved [aspell.name] into Free [aspell.name].")
+ aspell.name = "Free [aspell.name]"
+ if(4)
+ to_chat(user, "You have further improved [aspell.name] into Instant [aspell.name].")
+ aspell.name = "Instant [aspell.name]"
+ if(aspell.spell_level >= aspell.level_max)
+ to_chat(user, "This spell cannot be strengthened any further!")
+ log_spellbook("[key_name(user)] improved their knowledge of [src] to level [aspell.spell_level] for [cost] points")
+ SSblackbox.record_feedback("nested tally", "wizard_spell_improved", 1, list("[name]", "[aspell.spell_level]"))
+ return TRUE
//No same spell found - just learn it
+ log_spellbook("[key_name(user)] learned [src] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
user.mind.AddSpell(S)
to_chat(user, "You have learned [S.name].")
@@ -87,6 +90,7 @@
if(initial(S.name) == initial(aspell.name))
spell_levels = aspell.spell_level
user.mind.spell_list.Remove(aspell)
+ log_spellbook("[key_name(user)] refunded [src] for [cost * (spell_levels+1)] points")
qdel(S)
return cost * (spell_levels+1)
return -1
@@ -296,6 +300,7 @@
/datum/spellbook_entry/item/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
new item_path(get_turf(user))
+ log_spellbook("[key_name(user)] bought [src] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
return TRUE
@@ -509,6 +514,7 @@
return TRUE
/datum/spellbook_entry/summon/ghosts/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
+ log_spellbook("[key_name(user)] cast [src] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
new /datum/round_event/wizard/ghost()
active = TRUE
@@ -528,6 +534,7 @@
return !CONFIG_GET(flag/no_summon_guns)
/datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
+ log_spellbook("[key_name(user)] cast [src] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
rightandwrong(SUMMON_GUNS, user, 10)
active = TRUE
@@ -547,6 +554,7 @@
return !CONFIG_GET(flag/no_summon_magic)
/datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
+ log_spellbook("[key_name(user)] cast [src] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
rightandwrong(SUMMON_MAGIC, user, 10)
active = TRUE
@@ -569,6 +577,7 @@
return !CONFIG_GET(flag/no_summon_events)
/datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/spellbook/book)
+ log_spellbook("[key_name(user)] cast [src] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
summonevents()
times++
@@ -588,6 +597,7 @@
cost = 4
/datum/spellbook_entry/summon/curse_of_madness/Buy(mob/living/carbon/human/user, obj/item/spellbook/book)
+ log_spellbook("[key_name(user)] cast [src] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
active = TRUE
var/message = stripped_input(user, "Whisper a secret truth to drive your victims to madness.", "Whispers of Madness")
diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm
index 6d2c5980c3a..c594ce1e6c2 100644
--- a/code/modules/uplink/uplink_items.dm
+++ b/code/modules/uplink/uplink_items.dm
@@ -111,6 +111,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
/datum/uplink_item/proc/purchase(mob/user, datum/component/uplink/U)
var/atom/A = spawn_item(item, user, U)
+ log_uplink("[key_name(user)] purchased [src] for [cost] telecrystals from [U.parent]'s uplink")
if(purchase_log_vis && U.purchase_log)
U.purchase_log.LogPurchase(A, src, cost)
@@ -247,6 +248,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
var/crate_value = starting_crate_value
var/obj/structure/closet/crate/C = spawn_item(/obj/structure/closet/crate, user, U)
+ log_uplink("[key_name(user)] puchased [src] worth [crate_value] telecrystals for [cost] telecrystals using [U.parent]'s uplink")
if(U.purchase_log)
U.purchase_log.LogPurchase(C, src, cost)
while(crate_value)
@@ -260,6 +262,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
continue
crate_value -= I.cost
var/obj/goods = new I.item(C)
+ log_uplink("- [key_name(user)] received [goods] from [src]")
if(U.purchase_log)
U.purchase_log.LogPurchase(goods, I, 0)
return C
@@ -286,6 +289,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
if(possible_items.len)
var/datum/uplink_item/I = pick(possible_items)
+ log_uplink("[key_name(user)] purchased a random uplink item from [U.parent]'s uplink with [U.telecrystals] telecrystals remaining")
SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name))
U.MakePurchase(user, I)
diff --git a/config/config.txt b/config/config.txt
index aab82d2fda2..b78140242e6 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -112,6 +112,9 @@ LOG_ATTACK
## log pda messages
LOG_PDA
+## log uplink purchases
+LOG_UPLINK
+
## log telecomms messages
LOG_TELECOMMS