From 5786fa9ede3d1e357b218902f6461a2da226b9a3 Mon Sep 17 00:00:00 2001
From: Kapu1178 <75460809+Kapu1178@users.noreply.github.com>
Date: Thu, 29 Feb 2024 19:59:32 -0500
Subject: [PATCH 01/19] ambiguous codex
---
code/__HELPERS/cmp.dm | 4 +
code/controllers/subsystem/codex.dm | 58 +++++++++---
.../codex/categories/_codex_category.dm | 91 ++++++++++---------
code/modules/codex/categories/gases.dm | 2 +-
code/modules/codex/categories/reagents.dm | 2 +-
code/modules/codex/categories/surgery.dm | 2 +-
.../modules/codex/categories/uncategorized.dm | 2 +-
code/modules/codex/codex_client.dm | 41 +++------
code/modules/codex/entries/_codex_entry.dm | 17 +++-
code/modules/codex/entries/machinery.dm | 2 +-
code/modules/codex/entries/mechcomp.dm | 2 +-
code/modules/codex/entries/power.dm | 2 +-
code/modules/codex/entries/tools.dm | 2 +-
.../goon_reagents/medicine_reagents.dm | 2 -
.../chemistry/goon_reagents/other_reagents.dm | 4 -
code/modules/reagents/chemistry/reagents.dm | 2 +-
.../chemistry/reagents/dispenser_reagents.dm | 1 -
.../chemistry/reagents/food_reagents.dm | 1 -
.../chemistry/reagents/medicine_reagents.dm | 1 -
.../chemistry/reagents/other_reagents.dm | 7 --
.../chemistry/reagents/toxin_reagents.dm | 2 -
code/modules/unit_tests/codex.dm | 25 -----
22 files changed, 133 insertions(+), 139 deletions(-)
diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm
index 183b7c70f160..65ec73432775 100644
--- a/code/__HELPERS/cmp.dm
+++ b/code/__HELPERS/cmp.dm
@@ -202,3 +202,7 @@ GLOBAL_VAR_INIT(cmp_field, "name")
/// Orders lists by the size of lists in their contents
/proc/cmp_list_length(list/A, list/B)
return length(A) - length(B)
+
+/// Orders codex entries by name alphabetically
+/proc/cmp_codex_name(datum/codex_entry/a, datum/codex_entry/b)
+ return sorttext(b.name, a.name)
diff --git a/code/controllers/subsystem/codex.dm b/code/controllers/subsystem/codex.dm
index 94f44d129483..1b9f7bce21fa 100644
--- a/code/controllers/subsystem/codex.dm
+++ b/code/controllers/subsystem/codex.dm
@@ -59,6 +59,7 @@ SUBSYSTEM_DEF(codex)
string = replacetextEx(string, linkRegex.match, replacement)
return string
+/// Returns a codex entry for the given query. May return a list if multiple are found, or null if none.
/datum/controller/subsystem/codex/proc/get_codex_entry(entry)
if(isatom(entry))
var/atom/entity = entry
@@ -66,6 +67,9 @@ SUBSYSTEM_DEF(codex)
if(.)
return
return entries_by_path[entity.type] || get_entry_by_string(entity.name)
+
+ if(isdatum(entry))
+ entry = entry:type
if(ispath(entry))
return entries_by_path[entry]
if(istext(entry))
@@ -74,13 +78,40 @@ SUBSYSTEM_DEF(codex)
/datum/controller/subsystem/codex/proc/get_entry_by_string(string)
return entries_by_string[codex_sanitize(string)]
+/// Presents a codex entry to a mob. If it receives a list of entries, it will prompt them to choose one.
/datum/controller/subsystem/codex/proc/present_codex_entry(mob/presenting_to, datum/codex_entry/entry)
- if(entry && istype(presenting_to) && presenting_to.client)
- var/datum/browser/popup = new(presenting_to, "codex", "Codex", nheight=425) //"codex\ref[entry]"
- var/entry_data = entry.get_codex_body(presenting_to)
- popup.set_content(parse_links(jointext(entry_data, null), presenting_to))
- popup.open()
-
+ if(!entry || !istype(presenting_to) || !presenting_to.client)
+ return
+
+ if(islist(entry))
+ present_codex_search(presenting_to, entry)
+ return
+
+ var/datum/browser/popup = new(presenting_to, "codex", "Codex", nheight=425) //"codex\ref[entry]"
+ var/entry_data = entry.get_codex_body(presenting_to)
+ popup.set_content(parse_links(jointext(entry_data, null), presenting_to))
+ popup.open()
+
+#define CODEX_ENTRY_LIMIT 10
+/// Presents a list of codex entries to a mob.
+/datum/controller/subsystem/codex/proc/present_codex_search(mob/presenting_to, list/entries, search_query)
+ var/list/codex_data = list()
+ codex_data += "
[all_entries.len] matches[search_query ? "for '[search_query]'" : ""]:
"
+
+ if(LAZYLEN(entries) > CODEX_ENTRY_LIMIT)
+ codex_data += "Showing first [CODEX_ENTRY_LIMIT] entries. [all_entries.len - 5] result\s omitted."
+ codex_data += ""
+
+ for(var/i = 1 to min(entries.len, CODEX_ENTRY_LIMIT))
+ var/datum/codex_entry/entry = entries[i]
+ codex_data += "[entry.name] | View |
"
+ codex_data += "
"
+
+ var/datum/browser/popup = new(presenting_to, "codex-search", "Codex Search") //"codex-search"
+ popup.set_content(codex_data.Join())
+ popup.open()
+
+#undef CODEX_ENTRY_LIMIT
/datum/controller/subsystem/codex/proc/get_guide(category)
var/datum/codex_category/cat = codex_categories[category]
. = cat?.guide_html
@@ -91,25 +122,26 @@ SUBSYSTEM_DEF(codex)
return list()
searching = codex_sanitize(searching)
+
if(!searching)
return list()
+
if(!search_cache[searching])
- var/list/results
+ var/list/results = list()
if(entries_by_string[searching])
- results = list(entries_by_string[searching])
+ results = entries_by_string[searching]
else
- results = list()
- for(var/entry_title in entries_by_string)
- var/datum/codex_entry/entry = entries_by_string[entry_title]
+ for(var/datum/codex_entry/entry as anything in all_entries)
if(findtext(entry.name, searching) || findtext(entry.lore_text, searching) || findtext(entry.mechanics_text, searching) || findtext(entry.antag_text, searching))
- results |= entry
+ results += entry
+
search_cache[searching] = sortTim(results, GLOBAL_PROC_REF(cmp_name_asc))
return search_cache[searching]
/datum/controller/subsystem/codex/Topic(href, href_list)
. = ..()
if(!. && href_list["show_examined_info"] && href_list["show_to"])
- var/mob/showing_mob = locate(href_list["show_to"])
+ var/mob/showing_mob = locate(href_list["show_to"])
if(!istype(showing_mob))
return
var/atom/showing_atom = locate(href_list["show_examined_info"])
diff --git a/code/modules/codex/categories/_codex_category.dm b/code/modules/codex/categories/_codex_category.dm
index e0cdbfb5d58f..988f66a9860c 100644
--- a/code/modules/codex/categories/_codex_category.dm
+++ b/code/modules/codex/categories/_codex_category.dm
@@ -14,61 +14,64 @@
/datum/codex_category/proc/Populate()
SHOULD_CALL_PARENT(TRUE)
- if(length(items))
- var/lore_text = "[desc]
" + "
"
- if(guide_name && guide_html)
- lore_text += "This category has an associated guide.
"
+ if(!length(items))
+ return
- items = sortTim(items, GLOBAL_PROC_REF(cmp_text_asc), TRUE)
- var/list/links = list()
- for(var/item as anything in items)
- var/datum/codex_entry/item_entry = SScodex.get_entry_by_string(item)
- if(!item_entry)
- stack_trace("Invalid item supplied to codex category Populate(): [item]")
- continue
- var/starter = uppertext(copytext(strip_improper(item_entry.name), 1, 2))
- LAZYADD(links[starter], "[item_entry.name]")
- LAZYDISTINCTADD(item_entry.categories, src)
+ var/lore_text = "[desc]
" + "
"
+ if(guide_name && guide_html)
+ lore_text += "This category has an associated guide.
"
- var/list/link_cells = list()
- for(var/letter in GLOB.alphabet_upper)
- if(length(links[letter]))
- link_cells += "[letter]\n \n \n[jointext(links[letter], "\n \n")] | \n"
+ items = sortTim(items, GLOBAL_PROC_REF(cmp_codex_name))
- var/list/link_table = list("")
- var/link_counter = 0
- for(var/i = 1 to length(link_cells))
- if(link_counter == 0)
- link_table += ""
- link_table += link_cells[i]
- if(link_counter == link_columns)
- link_table += "
"
- link_counter++
- if(link_counter > link_columns)
- link_counter = 0
+ var/list/links = list()
+ for(var/datum/codex_entry/item_entry as anything in items)
+ if(!istype(item_entry))
+ stack_trace("Invalid item supplied to codex category Populate(): [item_entry]")
+ continue
- if(link_counter != link_columns)
+ var/starter = uppertext(copytext(strip_improper(item_entry.name), 1, 2))
+ LAZYADD(links[starter], "[item_entry.name]")
+ LAZYDISTINCTADD(item_entry.categories, src)
+
+ var/list/link_cells = list()
+ for(var/letter in GLOB.alphabet_upper)
+ if(length(links[letter]))
+ link_cells += "[letter]\n \n \n[jointext(links[letter], "\n \n")] | \n"
+
+ var/list/link_table = list("")
+ var/link_counter = 0
+ for(var/i = 1 to length(link_cells))
+ if(link_counter == 0)
+ link_table += ""
+ link_table += link_cells[i]
+ if(link_counter == link_columns)
link_table += "
"
- link_table += "
"
+ link_counter++
+ if(link_counter > link_columns)
+ link_counter = 0
- lore_text += jointext(link_table, "\n")
- var/datum/codex_entry/entry = new(
- _display_name = "[name] (category)",
- _lore_text = lore_text
- )
- // Categorize the categories.
- var/datum/codex_category/categories/cats_cat = SScodex.codex_categories[/datum/codex_category/categories]
- LAZYDISTINCTADD(entry.categories, cats_cat)
- LAZYDISTINCTADD(cats_cat.items, entry.name)
+ if(link_counter != link_columns)
+ link_table += ""
+ link_table += "
"
+
+ lore_text += jointext(link_table, "\n")
+ var/datum/codex_entry/entry = new(
+ _display_name = "[name] (category)",
+ _lore_text = lore_text
+ )
+ // Categorize the categories.
+ var/datum/codex_category/categories/cats_cat = SScodex.codex_categories[/datum/codex_category/categories]
+ LAZYDISTINCTADD(entry.categories, cats_cat)
+ LAZYDISTINCTADD(cats_cat.items, entry)
if(guide_html)
- var/datum/codex_entry/entry = new(
+ var/datum/codex_entry/guide_entry = new(
_display_name = "Guide to [capitalize(guide_name || name)]",
_mechanics_text = guide_html,
_disambiguator = "guide"
)
- LAZYDISTINCTADD(entry.categories, src)
+ LAZYDISTINCTADD(guide_entry.categories, src)
// It's a guide so we track it.
var/datum/codex_category/guides/guides_cat = SScodex.codex_categories[/datum/codex_category/guides]
- LAZYDISTINCTADD(entry.categories, guides_cat)
- LAZYDISTINCTADD(guides_cat.items, entry.name)
+ LAZYDISTINCTADD(guide_entry.categories, guides_cat)
+ LAZYDISTINCTADD(guides_cat.items, guide_entry)
diff --git a/code/modules/codex/categories/gases.dm b/code/modules/codex/categories/gases.dm
index 54c78ac41d4b..9cdaa7ed9fa7 100644
--- a/code/modules/codex/categories/gases.dm
+++ b/code/modules/codex/categories/gases.dm
@@ -28,6 +28,6 @@
_mechanics_text = jointext(material_info, null)
)
- items |= entry.name
+ items += entry
return ..()
diff --git a/code/modules/codex/categories/reagents.dm b/code/modules/codex/categories/reagents.dm
index 9f7fec0ad2d5..1fecdb01fc35 100644
--- a/code/modules/codex/categories/reagents.dm
+++ b/code/modules/codex/categories/reagents.dm
@@ -50,6 +50,6 @@
entry.mechanics_text += "
It can be produced as follows:
"
entry.mechanics_text += jointext(production_strings, "
")
- items += entry.name
+ items += entry
return ..()
diff --git a/code/modules/codex/categories/surgery.dm b/code/modules/codex/categories/surgery.dm
index cc37bad0dedc..b6ebc7ae8c01 100644
--- a/code/modules/codex/categories/surgery.dm
+++ b/code/modules/codex/categories/surgery.dm
@@ -88,6 +88,6 @@
_mechanics_text = jointext(info, null)
)
- items |= entry.name
+ items += entry
return ..()
diff --git a/code/modules/codex/categories/uncategorized.dm b/code/modules/codex/categories/uncategorized.dm
index 8c4aff560a67..f45058700903 100644
--- a/code/modules/codex/categories/uncategorized.dm
+++ b/code/modules/codex/categories/uncategorized.dm
@@ -7,5 +7,5 @@
for(var/datum/codex_entry/entry as anything in SScodex.all_entries)
if(!length(entry.categories))
LAZYADD(entry.categories, src)
- items |= entry.name
+ items += entry
return ..()
diff --git a/code/modules/codex/codex_client.dm b/code/modules/codex/codex_client.dm
index dab3d6963601..c9d24332eec4 100644
--- a/code/modules/codex/codex_client.dm
+++ b/code/modules/codex/codex_client.dm
@@ -1,6 +1,5 @@
/client
var/codex_cooldown = FALSE
- var/const/max_codex_entries_shown = 10
/client/verb/search_codex(searching as text)
@@ -22,36 +21,26 @@
codex_cooldown = world.time + 1 SECONDS
- var/list/all_entries = SScodex.retrieve_entries_for_string(searching)
+ var/list/found_entries = SScodex.retrieve_entries_for_string(searching)
if(mob && mob.mind && !length(mob.mind.antag_datums))
- all_entries = all_entries.Copy() // So we aren't messing with the codex search cache.
- for(var/datum/codex_entry/entry in all_entries)
+ found_entries = found_entries.Copy() // So we aren't messing with the codex search cache.
+ for(var/datum/codex_entry/entry in found_entries)
if(entry.antag_text && !entry.mechanics_text && !entry.lore_text)
- all_entries -= entry
+ found_entries -= entry
//Put entries with match in the name first
- for(var/datum/codex_entry/entry in all_entries)
+ for(var/datum/codex_entry/entry as anything in found_entries)
if(findtext(entry.name, searching))
- all_entries -= entry
- all_entries.Insert(1, entry)
-
- if(LAZYLEN(all_entries) == 1)
- SScodex.present_codex_entry(mob, all_entries[1])
- else
- if(LAZYLEN(all_entries) > 1)
- var/list/codex_data = list("[all_entries.len] matches for '[searching]':
")
- if(LAZYLEN(all_entries) > max_codex_entries_shown)
- codex_data += "Showing first [max_codex_entries_shown] entries. [all_entries.len - 5] result\s omitted."
- codex_data += ""
- for(var/i = 1 to min(all_entries.len, max_codex_entries_shown))
- var/datum/codex_entry/entry = all_entries[i]
- codex_data += "[entry.name] | View |
"
- codex_data += "
"
- var/datum/browser/popup = new(mob, "codex-search", "Codex Search") //"codex-search"
- popup.set_content(codex_data.Join())
- popup.open()
- else
+ found_entries -= entry
+ found_entries.Insert(1, entry)
+
+ switch(LAZYLEN(found_entries))
+ if(null)
to_chat(src, span_alert("The codex reports no matches for '[searching]'."))
+ if(1)
+ SScodex.present_codex_entry(mob, found_entries[1])
+ else
+ SScodex.present_codex_search(mob, found_entries, searching)
/client/verb/list_codex_entries()
@@ -69,7 +58,7 @@
codex_cooldown = world.time + 1 SECONDS
var/datum/browser/popup = new(mob, "codex", "Codex Index") //"codex-index"
- var/datum/codex_entry/nexus = SScodex.get_entry_by_string("nexus")
+ var/datum/codex_entry/nexus = SScodex.get_codex_entry(/datum/codex_entry/nexus)
var/list/codex_data = list(nexus.get_codex_header(mob).Join(), "Codex Entries
")
codex_data += ""
diff --git a/code/modules/codex/entries/_codex_entry.dm b/code/modules/codex/entries/_codex_entry.dm
index b80a38af534f..60015b61a677 100644
--- a/code/modules/codex/entries/_codex_entry.dm
+++ b/code/modules/codex/entries/_codex_entry.dm
@@ -62,6 +62,9 @@
stack_trace("Trying to save codex entry for [name] by path [associated_path] but one already exists!")
SScodex.entries_by_path[associated_path] = src
+ /// We always point to our own entry. Duh.
+ SScodex.entries_by_path[type] = src
+
if(!name)
if(length(associated_strings))
name = associated_strings[1]
@@ -74,12 +77,18 @@
if(!clean_string)
associated_strings -= associated_string
continue
+
if(clean_string != associated_string)
associated_strings -= associated_string
associated_strings |= clean_string
- if(SScodex.entries_by_string[clean_string])
- stack_trace("Trying to save codex entry for [name] by string [clean_string] but one already exists!")
- SScodex.entries_by_string[clean_string] = src
+
+ var/existing_entry = SScodex.entries_by_string[clean_string]
+ if(islist(existing_entry))
+ existing_entry += src
+ else if(existing_entry)
+ SScodex.entries_by_string[clean_string] = list(existing_entry, src)
+ else
+ SScodex.entries_by_string[clean_string] = src
..()
@@ -92,7 +101,7 @@
. = list()
if(presenting_to)
- var/datum/codex_entry/linked_entry = SScodex.get_entry_by_string("nexus")
+ var/datum/codex_entry/linked_entry = SScodex.get_codex_entry(/datum/codex_entry/nexus)
. += "Home"
if(presenting_to.client)
. += "Search Codex"
diff --git a/code/modules/codex/entries/machinery.dm b/code/modules/codex/entries/machinery.dm
index 1feb94184fa8..4d3fb8c9c479 100644
--- a/code/modules/codex/entries/machinery.dm
+++ b/code/modules/codex/entries/machinery.dm
@@ -4,7 +4,7 @@
/datum/codex_entry/machine/New(_display_name, list/_associated_paths, list/_associated_strings, _lore_text, _mechanics_text, _antag_text, _controls_text)
. = ..()
- GLOB.machine_codex_entries += name
+ GLOB.machine_codex_entries += src
/datum/codex_entry/machine/airlock
name = "Airlock"
diff --git a/code/modules/codex/entries/mechcomp.dm b/code/modules/codex/entries/mechcomp.dm
index bfa9585dcf1c..fdf07e2dd60b 100644
--- a/code/modules/codex/entries/mechcomp.dm
+++ b/code/modules/codex/entries/mechcomp.dm
@@ -4,7 +4,7 @@
/datum/codex_entry/mechcomp/New(_display_name, list/_associated_paths, list/_associated_strings, _lore_text, _mechanics_text, _antag_text, _controls_text)
. = ..()
- GLOB.mechcomp_codex_entries += name
+ GLOB.mechcomp_codex_entries += src
/datum/codex_entry/mechcomp/array
name = "Array (Data Type)"
diff --git a/code/modules/codex/entries/power.dm b/code/modules/codex/entries/power.dm
index 9f021752fd86..364c8be436db 100644
--- a/code/modules/codex/entries/power.dm
+++ b/code/modules/codex/entries/power.dm
@@ -5,7 +5,7 @@
/datum/codex_entry/power/New(_display_name, list/_associated_paths, list/_associated_strings, _lore_text, _mechanics_text, _antag_text, _controls_text)
. = ..()
- GLOB.power_codex_entries += name
+ GLOB.power_codex_entries += src
/datum/codex_entry/power/supermatter
name = "Supermatter Engine"
diff --git a/code/modules/codex/entries/tools.dm b/code/modules/codex/entries/tools.dm
index 4d17228009e9..b508e8abe689 100644
--- a/code/modules/codex/entries/tools.dm
+++ b/code/modules/codex/entries/tools.dm
@@ -5,7 +5,7 @@
/datum/codex_entry/tool/New(_display_name, list/_associated_paths, list/_associated_strings, _lore_text, _mechanics_text, _antag_text, _controls_text)
. = ..()
- GLOB.tool_codex_entries += name
+ GLOB.tool_codex_entries += src
/datum/codex_entry/tool/crowbar
name = "Crowbar"
diff --git a/code/modules/reagents/chemistry/goon_reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/goon_reagents/medicine_reagents.dm
index bc0593cb1fc8..42a3ff15165d 100644
--- a/code/modules/reagents/chemistry/goon_reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/goon_reagents/medicine_reagents.dm
@@ -3,8 +3,6 @@
description = "Purges alcoholic substance from the patient's body and eliminates its side effects."
color = "#00B4C8"
taste_description = "raw egg"
- show_in_codex = TRUE
-
/datum/reagent/medicine/antihol/affect_blood(mob/living/carbon/C, removed)
C.remove_status_effect(/datum/status_effect/dizziness)
diff --git a/code/modules/reagents/chemistry/goon_reagents/other_reagents.dm b/code/modules/reagents/chemistry/goon_reagents/other_reagents.dm
index 25e8191d7f5d..335c46bf1a34 100644
--- a/code/modules/reagents/chemistry/goon_reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/goon_reagents/other_reagents.dm
@@ -58,7 +58,6 @@
burning_volume = 0.05 //but has a lot of hydrocarbons
addiction_types = null
- show_in_codex = TRUE
/datum/reagent/stable_plasma
name = "Stable Plasma"
@@ -105,7 +104,6 @@
touch_met = 2
var/clean_types = CLEAN_WASH
chemical_flags = REAGENT_CLEANS
- show_in_codex = TRUE
/datum/reagent/space_cleaner/expose_obj(obj/exposed_obj, reac_volume)
. = ..()
@@ -322,7 +320,6 @@
reagent_state = LIQUID
color = "#E7EA91"
taste_description = "acid"
- show_in_codex = TRUE
/datum/reagent/acetone
name = "Acetone"
@@ -332,7 +329,6 @@
color = "#808080"
metabolization_rate = 0.04
value = DISPENSER_REAGENT_VALUE
- show_in_codex = TRUE
/datum/reagent/acetone/affect_blood(mob/living/carbon/C, removed)
C.adjustToxLoss(removed * 3, FALSE)
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index 0cce32a58c98..a29c8e5ab71e 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -78,7 +78,7 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
var/chemical_flags = NONE
/// Does this reagent and its recipe appear in the Codex?
- var/show_in_codex = FALSE
+ var/show_in_codex = TRUE
///Thermodynamic vars
///How hot this reagent burns when it's on fire - null means it can't burn
diff --git a/code/modules/reagents/chemistry/reagents/dispenser_reagents.dm b/code/modules/reagents/chemistry/reagents/dispenser_reagents.dm
index 4399e3f4e58f..f101fb1c06ad 100644
--- a/code/modules/reagents/chemistry/reagents/dispenser_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/dispenser_reagents.dm
@@ -144,7 +144,6 @@
var/meltdose = 20 // How much is needed to melt
var/max_damage = 40
value = DISPENSER_REAGENT_VALUE
- show_in_codex = TRUE
/datum/reagent/toxin/acid/affect_blood(mob/living/carbon/C, removed)
C.adjustFireLoss(removed * acidpwr, FALSE)
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index c38cfbd86d2a..98c7d33d2c57 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -356,7 +356,6 @@
color = "#FFFFFF" // rgb: 255,255,255
taste_description = "salt"
penetrates_skin = NONE
- show_in_codex = TRUE
/datum/reagent/consumable/salt/expose_turf(turf/exposed_turf, reac_volume)
. = ..()
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 10347a9c1a78..61938dc4904a 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -10,7 +10,6 @@
taste_description = "bitterness"
chemical_flags = REAGENT_IGNORE_MOB_SIZE
abstract_type = /datum/reagent/medicine
- show_in_codex = TRUE
/datum/reagent/medicine/adminordrazine //An OP chemical for admins
name = "Adminordrazine"
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index c1f2282ee2fb..b129b28196b1 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -99,7 +99,6 @@
chemical_flags = REAGENT_CLEANS | REAGENT_IGNORE_MOB_SIZE
touch_met = INFINITY
ingest_met = INFINITY
- show_in_codex = TRUE
metabolization_rate = 1
// Holy water. Mostly the same as water, it also heals the plant a little with the power of the spirits. Also ALSO increases instability.
@@ -572,7 +571,6 @@
name = "Technetium 99"
description = "A radioactive tracer agent that can improve a scanner's ability to detect internal organ damage. Will poison the patient when present very slowly, purging or using a low dose is recommended after use."
metabolization_rate = 0.2
- show_in_codex = TRUE
/datum/reagent/technetium/affect_blood(mob/living/carbon/C, removed)
if(!(current_cycle % 8))
@@ -921,7 +919,6 @@
color = "#c8a5dc"
overdose_threshold = 30
value = 1.8
- show_in_codex = TRUE
/datum/reagent/impedrezene/on_mob_metabolize(mob/living/carbon/C, class)
ADD_TRAIT(C, TRAIT_IMPEDREZENE, CHEM_TRAIT_SOURCE(class))
@@ -1067,8 +1064,6 @@
color = "#D3B913"
taste_description = "sweetness"
- show_in_codex = TRUE
-
/datum/reagent/cryptobiolin
name = "Cryptobiolin"
description = "Cryptobiolin causes confusion and dizziness."
@@ -1076,8 +1071,6 @@
metabolization_rate = 0.3
taste_description = "sourness"
- show_in_codex = TRUE
-
/datum/reagent/cryptobiolin/affect_blood(mob/living/carbon/C, removed)
. = ..()
C.set_timed_status_effect(2 SECONDS, /datum/status_effect/dizziness, only_if_higher = TRUE)
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index 1af3f8c3d498..09059b023191 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -38,7 +38,6 @@
toxpwr = 0.5
taste_description = "slime"
taste_mult = 0.9
- show_in_codex = TRUE
/datum/reagent/toxin/mutagen/expose_mob(mob/living/exposed_mob, reac_volume, exposed_temperature = T20C, datum/reagents/source, methods=TOUCH, show_message = TRUE, touch_protection = 0)
. = ..()
@@ -805,7 +804,6 @@
color = "#F0FFF0"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
toxpwr = 0
- show_in_codex = TRUE
/datum/reagent/toxin/lipolicide/affect_blood(mob/living/carbon/C, removed)
. = ..()
diff --git a/code/modules/unit_tests/codex.dm b/code/modules/unit_tests/codex.dm
index c1f3d98a4009..c747f9cb1508 100644
--- a/code/modules/unit_tests/codex.dm
+++ b/code/modules/unit_tests/codex.dm
@@ -1,28 +1,3 @@
-/datum/unit_test/codex_string_uniqueness
-
-/datum/unit_test/codex_string_uniqueness/Run()
- var/list/seen_strings = list()
- for(var/datum/codex_entry/entry as anything in SScodex.all_entries)
- for(var/associated_string in entry.associated_strings)
- if(seen_strings[associated_string])
- TEST_FAIL("Codex String Not Unique:'[associated_string]' - [entry.type]|[entry.name] - first seen: [seen_strings[associated_string]]")
- else
- seen_strings[associated_string] = "[entry.type]|[entry.name]"
-
-/datum/unit_test/codex_overlap
-
-/datum/unit_test/codex_overlap/Run()
- for(var/check_string in SScodex.entries_by_string)
- var/clean_check_string = lowertext(check_string)
- for(var/other_string in SScodex.entries_by_string)
- var/clean_other_string = lowertext(other_string)
- if(clean_other_string != clean_check_string && SScodex.entries_by_string[other_string] != SScodex.entries_by_string[check_string])
- if(findtext(clean_check_string, clean_other_string))
- TEST_FAIL("Codex Overlap: [check_string], [other_string]")
- else if(findtext(clean_other_string, clean_check_string))
- TEST_FAIL("Codex Overlap: [other_string], [check_string]")
-
-
/datum/unit_test/codex_links
/datum/unit_test/codex_links/Run()
From 73be26c0c114c53e96c5fa3e7dd82a92d7c758bd Mon Sep 17 00:00:00 2001
From: Kapu1178 <75460809+Kapu1178@users.noreply.github.com>
Date: Thu, 29 Feb 2024 20:17:35 -0500
Subject: [PATCH 02/19] code tweaks
---
code/controllers/subsystem/codex.dm | 28 +++++++++++++++++-----------
code/modules/codex/codex_client.dm | 6 ------
2 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/code/controllers/subsystem/codex.dm b/code/controllers/subsystem/codex.dm
index 1b9f7bce21fa..6d3de9461b3a 100644
--- a/code/controllers/subsystem/codex.dm
+++ b/code/controllers/subsystem/codex.dm
@@ -126,17 +126,23 @@ SUBSYSTEM_DEF(codex)
if(!searching)
return list()
- if(!search_cache[searching])
- var/list/results = list()
- if(entries_by_string[searching])
- results = entries_by_string[searching]
- else
- for(var/datum/codex_entry/entry as anything in all_entries)
- if(findtext(entry.name, searching) || findtext(entry.lore_text, searching) || findtext(entry.mechanics_text, searching) || findtext(entry.antag_text, searching))
- results += entry
-
- search_cache[searching] = sortTim(results, GLOBAL_PROC_REF(cmp_name_asc))
- return search_cache[searching]
+ . = search_cache[searching]
+ if(.)
+ return .
+
+ var/list/results = list()
+ if(entries_by_string[searching])
+ results = entries_by_string[searching]
+ else
+ for(var/datum/codex_entry/entry as anything in all_entries)
+ if(findtext(entry.name, searching))
+ results.Insert(1, entry) // If it's in the name, put it at the front of the list.
+
+ else if(findtext(entry.lore_text, searching) || findtext(entry.mechanics_text, searching) || findtext(entry.antag_text, searching))
+ results += entry
+
+ search_cache[searching] = sortTim(results, GLOBAL_PROC_REF(cmp_name_asc))
+ . = search_cache[searching]
/datum/controller/subsystem/codex/Topic(href, href_list)
. = ..()
diff --git a/code/modules/codex/codex_client.dm b/code/modules/codex/codex_client.dm
index c9d24332eec4..79acc26db8cc 100644
--- a/code/modules/codex/codex_client.dm
+++ b/code/modules/codex/codex_client.dm
@@ -28,12 +28,6 @@
if(entry.antag_text && !entry.mechanics_text && !entry.lore_text)
found_entries -= entry
- //Put entries with match in the name first
- for(var/datum/codex_entry/entry as anything in found_entries)
- if(findtext(entry.name, searching))
- found_entries -= entry
- found_entries.Insert(1, entry)
-
switch(LAZYLEN(found_entries))
if(null)
to_chat(src, span_alert("The codex reports no matches for '[searching]'."))
From 51f2c492471c4fde37c3819ea9121afa69bd678d Mon Sep 17 00:00:00 2001
From: Kapu1178 <75460809+Kapu1178@users.noreply.github.com>
Date: Thu, 29 Feb 2024 20:25:16 -0500
Subject: [PATCH 03/19] grammar
---
code/controllers/subsystem/codex.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/controllers/subsystem/codex.dm b/code/controllers/subsystem/codex.dm
index 6d3de9461b3a..5da94c815df2 100644
--- a/code/controllers/subsystem/codex.dm
+++ b/code/controllers/subsystem/codex.dm
@@ -96,7 +96,7 @@ SUBSYSTEM_DEF(codex)
/// Presents a list of codex entries to a mob.
/datum/controller/subsystem/codex/proc/present_codex_search(mob/presenting_to, list/entries, search_query)
var/list/codex_data = list()
- codex_data += "[all_entries.len] matches[search_query ? "for '[search_query]'" : ""]:
"
+ codex_data += "[all_entries.len] matches[search_query ? " for '[search_query]'" : ""]:
"
if(LAZYLEN(entries) > CODEX_ENTRY_LIMIT)
codex_data += "Showing first [CODEX_ENTRY_LIMIT] entries. [all_entries.len - 5] result\s omitted."
From 9f255ea05d0e602cbfcbbc6caadf983b268a9393 Mon Sep 17 00:00:00 2001
From: pitaden <32023715+pitaden@users.noreply.github.com>
Date: Sat, 2 Mar 2024 06:33:54 -0600
Subject: [PATCH 04/19] reaction thermics and unstable reagents
there's almost certainly more reagents that would need unstable_temperature. and I still feel silly having that variable only get used by the codex.
---
code/modules/codex/categories/reagents.dm | 52 ++++++++++++++++++-
code/modules/reagents/chemistry/reagents.dm | 5 ++
.../chemistry/reagents/drink_reagents.dm | 1 +
.../chemistry/reagents/other_reagents.dm | 2 +
.../chemistry/reagents/toxin_reagents.dm | 5 +-
5 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/code/modules/codex/categories/reagents.dm b/code/modules/codex/categories/reagents.dm
index 9f7fec0ad2d5..71dfc5c622b3 100644
--- a/code/modules/codex/categories/reagents.dm
+++ b/code/modules/codex/categories/reagents.dm
@@ -24,12 +24,20 @@
for(var/datum/reagent/reactant as anything in reaction.required_reagents)
reactant_values += "[reaction.required_reagents[reactant]]u [lowertext(initial(reactant.name))]"
-
var/list/catalysts = list()
for(var/datum/reagent/catalyst as anything in reaction.required_catalysts)
catalysts += "[reaction.required_catalysts[catalyst]]u [lowertext(initial(catalyst.name))]"
+ var/datum/reagent/unstable_min = null
+ var/datum/reagent/unstable_max = null
+
+ for(var/datum/reagent/chemical as anything in reaction.required_catalysts + reaction.required_reagents)
+ if(chemical.unstable_temperature)
+ if(!chemical.unstable_cold && (!unstable_min || unstable_min.unstable_temperature > chemical.unstable_temperature))
+ unstable_min = chemical
+ if(chemical.unstable_cold && (!unstable_max || unstable_max.unstable_temperature < chemical.unstable_temperature))
+ unstable_max = chemical
if(length(catalysts))
production_strings += "- [jointext(reactant_values, " + ")] (catalysts: [jointext(catalysts, ", ")]): [reaction.results[R]]u [lowertext(initial(R.name))]"
@@ -38,11 +46,51 @@
production_strings += "- Optimal temperature: [KELVIN_TO_CELSIUS(reaction.optimal_temp)]C ([reaction.optimal_temp]K)"
- if (reaction.overheat_temp < NO_OVERHEAT)
+ if (unstable_min)
+ production_strings += "- Overheat temperature: [KELVIN_TO_CELSIUS(unstable_min.unstable_temperature)]C ([unstable_min.unstable_temperature]K)"
+ else if (reaction.overheat_temp < NO_OVERHEAT)
production_strings += "- Overheat temperature: [KELVIN_TO_CELSIUS(reaction.overheat_temp)]C ([reaction.overheat_temp]K)"
+
+ if (unstable_max)
+ production_strings += "- Overcooled temperature: [KELVIN_TO_CELSIUS(unstable_max.unstable_temperature)]C ([unstable_max.unstable_temperature]K)"
+
if (reaction.required_temp > 0)
production_strings += "- Required temperature: [KELVIN_TO_CELSIUS(reaction.required_temp)]C ([reaction.required_temp]K)"
+
+ if(reaction.thermic_constant != 0)
+ // lifted outta modules/reagents/chemistry/holder.dm
+ var/thermic_string = ""
+ var/thermic = reaction.thermic_constant
+ if(reaction.reaction_flags & REACTION_HEAT_ARBITARY)
+ thermic *= 100 //Because arbitary is a lower scale
+ switch(thermic)
+ if(-INFINITY to -1500)
+ thermic_string = "overwhelmingly endothermic"
+ if(-1500 to -1000)
+ thermic_string = "extremely endothermic"
+ if(-1000 to -500)
+ thermic_string = "strongly endothermic"
+ if(-500 to -200)
+ thermic_string = "moderately endothermic"
+ if(-200 to -50)
+ thermic_string = "endothermic"
+ if(-50 to 0)
+ thermic_string = "weakly endothermic"
+ if(0 to 50)
+ thermic_string = "weakly exothermic"
+ if(50 to 200)
+ thermic_string = "exothermic"
+ if(200 to 500)
+ thermic_string = "moderately exothermic"
+ if(500 to 1000)
+ thermic_string = "strongly exothermic"
+ if(1000 to 1500)
+ thermic_string = "extremely exothermic"
+ if(1500 to INFINITY)
+ thermic_string = "overwhelmingly exothermic"
+ production_strings += "- The reaction is [thermic_string]"
+
if(length(production_strings))
if(!entry.mechanics_text)
entry.mechanics_text = "It can be produced as follows:
"
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index 0cce32a58c98..fe420453bf63 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -86,6 +86,11 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
///How much is consumed when it is burnt per second
var/burning_volume = 0.5
+ ///The highest temperature this reagent can exist at. Currently only used by codex entries.
+ var/unstable_temperature = null
+ ///If true, unstable_temperature is the /lowest/ temperature this reagent can exist at. Currently only used by codex entries.
+ var/unstable_cold = FALSE
+
///Assoc list with key type of addiction this reagent feeds, and value amount of addiction points added per unit of reagent metabolzied (which means * REAGENTS_METABOLISM every life())
var/list/addiction_types = null
diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
index a517a7fbcc31..24becefeb02b 100644
--- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
@@ -655,6 +655,7 @@
glass_icon_state = "iceglass"
glass_name = "glass of ice"
glass_desc = "Generally, you're supposed to put something else in there too..."
+ unstable_temperature = WATER_MATTERSTATE_CHANGE_TEMP+0.5
/datum/reagent/consumable/ice/affect_ingest(mob/living/carbon/C, removed)
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index c1f2282ee2fb..2fc3182026c0 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -8,6 +8,8 @@
glass_desc = "The father of all refreshments."
shot_glass_icon_state = "shotglassclear"
chemical_flags = REAGENT_CLEANS
+ unstable_temperature = WATER_MATTERSTATE_CHANGE_TEMP-0.5
+ unstable_cold = TRUE
metabolization_rate = 2
ingest_met = 2
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index 1af3f8c3d498..561413dcc96c 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -74,6 +74,7 @@
penetrates_skin = NONE
burning_temperature = 4500//plasma is hot!!
burning_volume = 0.3//But burns fast
+ unstable_temperature = LIQUID_PLASMA_BP
/datum/reagent/toxin/plasma/on_new(data)
@@ -97,7 +98,7 @@
/// Handles plasma boiling.
/datum/reagent/toxin/plasma/proc/on_temp_change(datum/reagents/_holder, old_temp)
SIGNAL_HANDLER
- if(holder.chem_temp < LIQUID_PLASMA_BP)
+ if(holder.chem_temp < unstable_temperature)
return
if(!holder.my_atom)
return
@@ -113,7 +114,7 @@
if(!istype(exposed_turf))
return
- if(exposed_temperature >= LIQUID_PLASMA_BP)
+ if(exposed_temperature >= unstable_temperature)
exposed_turf.assume_gas(GAS_PLASMA, reac_volume / REAGENT_GAS_EXCHANGE_FACTOR, exposed_temperature)
/datum/reagent/toxin/plasma/expose_mob(mob/living/exposed_mob, reac_volume, exposed_temperature, datum/reagents/source, methods, show_message, touch_protection)
From 856e3ffd05edb182bc905e14e018ac55fd6a6a66 Mon Sep 17 00:00:00 2001
From: pitaden <32023715+pitaden@users.noreply.github.com>
Date: Sat, 2 Mar 2024 10:26:21 -0600
Subject: [PATCH 05/19] pyrotechnic
it SEEMS like these are the only chemicals that'd benefit from having unstable_temperature
---
code/modules/codex/categories/reagents.dm | 2 +-
.../chemistry/reagents/pyrotechnic_reagents.dm | 12 +++++++++++-
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/code/modules/codex/categories/reagents.dm b/code/modules/codex/categories/reagents.dm
index 71dfc5c622b3..52602217c278 100644
--- a/code/modules/codex/categories/reagents.dm
+++ b/code/modules/codex/categories/reagents.dm
@@ -46,7 +46,7 @@
production_strings += "- Optimal temperature: [KELVIN_TO_CELSIUS(reaction.optimal_temp)]C ([reaction.optimal_temp]K)"
- if (unstable_min)
+ if (unstable_min && unstable_min.unstable_temperature < reaction.overheat_temp)
production_strings += "- Overheat temperature: [KELVIN_TO_CELSIUS(unstable_min.unstable_temperature)]C ([unstable_min.unstable_temperature]K)"
else if (reaction.overheat_temp < NO_OVERHEAT)
production_strings += "- Overheat temperature: [KELVIN_TO_CELSIUS(reaction.overheat_temp)]C ([reaction.overheat_temp]K)"
diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
index 1e3bf8de6407..d3c0715b1554 100644
--- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm
@@ -45,6 +45,7 @@
description = "Nitroglycerin is a heavy, colorless, oily, explosive liquid obtained by nitrating glycerol."
color = "#808080" // rgb: 128, 128, 128
taste_description = "oil"
+ unstable_temperature = 474
/datum/reagent/stabilizing_agent
@@ -102,12 +103,15 @@
exposed_mob.adjust_fire_stacks(min(reac_volume/5, 10))
var/turf/T = get_turf(exposed_mob)
T.create_fire(1, 10)
+
+
/datum/reagent/liquid_dark_matter
name = "Liquid Dark Matter"
description = "Sucks everything into the detonation point."
reagent_state = LIQUID
color = "#210021"
taste_description = "compressed bitterness"
+ unstable_temperature = 474
/datum/reagent/gunpowder
@@ -117,7 +121,7 @@
color = "#000000"
metabolization_rate = 0.125 * REAGENTS_METABOLISM
taste_description = "salt"
-
+ unstable_temperature = 474
/datum/reagent/gunpowder/on_new(data)
. = ..()
@@ -153,6 +157,7 @@
reagent_state = SOLID
color = "#FFFFFF"
taste_description = "salt"
+ unstable_temperature = 474
/datum/reagent/tatp
@@ -161,6 +166,7 @@
reagent_state = SOLID
color = "#FFFFFF"
taste_description = "death"
+ unstable_temperature = 501 // technically it goes from 501 to 599
/datum/reagent/flash_powder
@@ -169,6 +175,7 @@
reagent_state = LIQUID
color = "#C8C8C8"
taste_description = "salt"
+ unstable_temperature = 374
/datum/reagent/smoke_powder
@@ -177,6 +184,7 @@
reagent_state = LIQUID
color = "#C8C8C8"
taste_description = "smoke"
+ unstable_temperature = 374
/datum/reagent/sonic_powder
@@ -185,6 +193,7 @@
reagent_state = LIQUID
color = "#C8C8C8"
taste_description = "loud noises"
+ unstable_temperature = 374
/datum/reagent/napalm
@@ -281,3 +290,4 @@
reagent_state = LIQUID
color = "#5A64C8"
taste_description = "air and bitterness"
+ unstable_temperature = 474
From 9b8ff98d013e73d7144d252d0eb333ba9dc6bb8f Mon Sep 17 00:00:00 2001
From: Changelogs
Date: Wed, 28 Feb 2024 01:07:22 +0000
Subject: [PATCH 06/19] Automatic changelog compile [ci skip]
---
html/changelogs/AutoChangeLog-pr-813.yml | 29 ---------------------
html/changelogs/AutoChangeLog-pr-826.yml | 4 ---
html/changelogs/AutoChangeLog-pr-845.yml | 4 ---
html/changelogs/archive/2024-02.yml | 32 ++++++++++++++++++++++++
4 files changed, 32 insertions(+), 37 deletions(-)
delete mode 100644 html/changelogs/AutoChangeLog-pr-813.yml
delete mode 100644 html/changelogs/AutoChangeLog-pr-826.yml
delete mode 100644 html/changelogs/AutoChangeLog-pr-845.yml
diff --git a/html/changelogs/AutoChangeLog-pr-813.yml b/html/changelogs/AutoChangeLog-pr-813.yml
deleted file mode 100644
index d29900983114..000000000000
--- a/html/changelogs/AutoChangeLog-pr-813.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-author: Kapu1178, Fikou, Tau-Ceti, Baystation12, Aurorastation, with help from Lohikar,
- Ter, and Lummox. Hitsplatter sprites modified by 13spacemen.
-delete-after: true
-changes:
- - bugfix: Fingerprints are now applied in more situations. Did you know that punching
- someone didn't apply fingerprints?
- - bugfix: Fingerprints are now applied more realistically, attempting to add to
- clothing first where applicable.
- - bugfix: Blood is now left on items you touch if your hands or gloves are bloody.
- - bugfix: Tracking blood on feet/shoes works correctly.
- - refactor: Rewrote the forensics component into a datum.
- - rscadd: Two new forensic information classes, Trace DNA and Gunshot Residue. Trace
- DNA is left by doing things such as biting, smoking a cigarette, or drinking.
- Gunshot Residue is left by ballistic firearms.
- - rscadd: Fingerprints are now only partially left, sometimes requiring multiple
- touches to give full clarity to the print.
- - rscadd: Blood can now be colors other than red.
- - rscadd: There is more blood.
- - rscadd: Detective now gets a filing cabinet that contains a paper copy of each
- crew member's record when they joined.
- - qol: Cleaned up evidence bag behavior to be in line with other storage objects.
- - rscadd: Added sample kits for different forensic information. Fingerprint cards
- for fingerprints, swabs for trace DNA or blood DNA, a fiber kit for material
- fibers, and finger print powder for finding fingerprints on objects.
- - rscadd: Scene cards to mark crime scenes.
- - rscadd: Detective now gets an Electron Microscope, to analyze fingerprints, fibers,
- and residue.
- - refactor: Rewrote the Forensic Scanner into the DNA Scanner. It is now only used
- for trace DNA and blood DNA samples.
diff --git a/html/changelogs/AutoChangeLog-pr-826.yml b/html/changelogs/AutoChangeLog-pr-826.yml
deleted file mode 100644
index d648b90d980d..000000000000
--- a/html/changelogs/AutoChangeLog-pr-826.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: Kapu1178
-delete-after: true
-changes:
- - bugfix: Items hide other items EVEN BETTER.
diff --git a/html/changelogs/AutoChangeLog-pr-845.yml b/html/changelogs/AutoChangeLog-pr-845.yml
deleted file mode 100644
index e357ca332eaf..000000000000
--- a/html/changelogs/AutoChangeLog-pr-845.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: francinum
-delete-after: true
-changes:
- - admin: A Lag Switch has been added to disable VV Icon Previews.
diff --git a/html/changelogs/archive/2024-02.yml b/html/changelogs/archive/2024-02.yml
index d0a0ffd8b7ed..f258bd4e460d 100644
--- a/html/changelogs/archive/2024-02.yml
+++ b/html/changelogs/archive/2024-02.yml
@@ -121,3 +121,35 @@
- rscadd: You can now take a drag off a cigarette by clicking yourself while holding
it.
- rscadd: Cigarettes now leave tiny smoke particles sometimes.
+2024-02-28:
+ Kapu1178:
+ - bugfix: Items hide other items EVEN BETTER.
+ ? Kapu1178, Fikou, Tau-Ceti, Baystation12, Aurorastation, with help from Lohikar,
+ Ter, and Lummox. Hitsplatter sprites modified by 13spacemen.
+ : - bugfix: Fingerprints are now applied in more situations. Did you know that punching
+ someone didn't apply fingerprints?
+ - bugfix: Fingerprints are now applied more realistically, attempting to add to
+ clothing first where applicable.
+ - bugfix: Blood is now left on items you touch if your hands or gloves are bloody.
+ - bugfix: Tracking blood on feet/shoes works correctly.
+ - refactor: Rewrote the forensics component into a datum.
+ - rscadd: Two new forensic information classes, Trace DNA and Gunshot Residue.
+ Trace DNA is left by doing things such as biting, smoking a cigarette, or
+ drinking. Gunshot Residue is left by ballistic firearms.
+ - rscadd: Fingerprints are now only partially left, sometimes requiring multiple
+ touches to give full clarity to the print.
+ - rscadd: Blood can now be colors other than red.
+ - rscadd: There is more blood.
+ - rscadd: Detective now gets a filing cabinet that contains a paper copy of each
+ crew member's record when they joined.
+ - qol: Cleaned up evidence bag behavior to be in line with other storage objects.
+ - rscadd: Added sample kits for different forensic information. Fingerprint cards
+ for fingerprints, swabs for trace DNA or blood DNA, a fiber kit for material
+ fibers, and finger print powder for finding fingerprints on objects.
+ - rscadd: Scene cards to mark crime scenes.
+ - rscadd: Detective now gets an Electron Microscope, to analyze fingerprints,
+ fibers, and residue.
+ - refactor: Rewrote the Forensic Scanner into the DNA Scanner. It is now only
+ used for trace DNA and blood DNA samples.
+ francinum:
+ - admin: A Lag Switch has been added to disable VV Icon Previews.
From 686c8f7d57e97afc7aae7d7516ebf89e5ab934df Mon Sep 17 00:00:00 2001
From: DaedalusDock-Services
<123522349+DaedalusDock-Services@users.noreply.github.com>
Date: Wed, 28 Feb 2024 01:59:12 -0500
Subject: [PATCH 07/19] Update TGS DMAPI (#848)
Co-authored-by: tgstation-server
---
code/__DEFINES/tgs.dm | 4 ++--
code/modules/tgs/v5/api.dm | 4 ++++
code/modules/tgs/v5/topic.dm | 3 ++-
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm
index dc49d2c6f02c..a4fb6d40be73 100644
--- a/code/__DEFINES/tgs.dm
+++ b/code/__DEFINES/tgs.dm
@@ -1,6 +1,6 @@
// tgstation-server DMAPI
-#define TGS_DMAPI_VERSION "7.1.0"
+#define TGS_DMAPI_VERSION "7.1.1"
// All functions and datums outside this document are subject to change with any version and should not be relied on.
@@ -496,7 +496,7 @@
/// Returns a list of connected [/datum/tgs_chat_channel]s if TGS is present, null otherwise. This function may sleep if the call to [/world/proc/TgsNew] is sleeping!
/world/proc/TgsChatChannelInfo()
return
-
+
/**
* Trigger an event in TGS. Requires TGS version >= 6.3.0. Returns [TRUE] if the event was triggered successfully, [FALSE] otherwise. This function may sleep!
*
diff --git a/code/modules/tgs/v5/api.dm b/code/modules/tgs/v5/api.dm
index 9b64931f8f92..95b8edd3ee5c 100644
--- a/code/modules/tgs/v5/api.dm
+++ b/code/modules/tgs/v5/api.dm
@@ -48,6 +48,10 @@
var/datum/tgs_version/api_version = ApiVersion()
version = null // we want this to be the TGS version, not the interop version
+
+ // sleep once to prevent an issue where world.Export on the first tick can hang indefinitely
+ sleep(world.tick_lag)
+
var/list/bridge_response = Bridge(DMAPI5_BRIDGE_COMMAND_STARTUP, list(DMAPI5_BRIDGE_PARAMETER_MINIMUM_SECURITY_LEVEL = minimum_required_security_level, DMAPI5_BRIDGE_PARAMETER_VERSION = api_version.raw_parameter, DMAPI5_PARAMETER_CUSTOM_COMMANDS = ListCustomCommands(), DMAPI5_PARAMETER_TOPIC_PORT = GetTopicPort()))
if(!istype(bridge_response))
TGS_ERROR_LOG("Failed initial bridge request!")
diff --git a/code/modules/tgs/v5/topic.dm b/code/modules/tgs/v5/topic.dm
index e66edc27206a..e1f2cb638578 100644
--- a/code/modules/tgs/v5/topic.dm
+++ b/code/modules/tgs/v5/topic.dm
@@ -177,7 +177,8 @@
reattach_response[DMAPI5_PARAMETER_CUSTOM_COMMANDS] = ListCustomCommands()
reattach_response[DMAPI5_PARAMETER_TOPIC_PORT] = GetTopicPort()
- pending_events.Cut()
+ for(var/eventId in pending_events)
+ pending_events[eventId] = TRUE
return reattach_response
From a24954a58a504255fd9487a18e13344b5e471bfb Mon Sep 17 00:00:00 2001
From: Gallyus <5572280+francinum@users.noreply.github.com>
Date: Wed, 28 Feb 2024 02:04:10 -0500
Subject: [PATCH 08/19] Config error log is now moved properly. (#849)
---
code/game/world.dm | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/code/game/world.dm b/code/game/world.dm
index cd92b08d56f5..bd7abbdd4294 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -162,7 +162,7 @@ GLOBAL_VAR(restart_counter)
GLOB.demo_log = "[GLOB.log_directory]/demo.log"
- GLOB.config_error_log = "[GLOB.log_directory]/config_error.log"
+ //Config Error Log must be set later to ensure that we move the files over.
#ifdef UNIT_TESTS
GLOB.test_log = "[GLOB.log_directory]/tests.log"
@@ -189,10 +189,14 @@ GLOBAL_VAR(restart_counter)
var/latest_changelog = file("[global.config.directory]/../html/changelogs/archive/" + time2text(world.timeofday, "YYYY-MM") + ".yml")
GLOB.changelog_hash = fexists(latest_changelog) ? md5(latest_changelog) : 0 //for telling if the changelog has changed recently
+
+ // Okay, we have a properly constructed log directory and we're all clean and safe. Sort the config error log properly.
if(fexists(GLOB.config_error_log))
fcopy(GLOB.config_error_log, "[GLOB.log_directory]/config_error.log")
fdel(GLOB.config_error_log)
+ // NOW we can change the write directory handle over.
+ GLOB.config_error_log = "[GLOB.log_directory]/config_error.log"
if(GLOB.round_id)
log_game("Round ID: [GLOB.round_id]")
From d68a7a38e4dc0a17bdf9240bbe443afa45df4f5e Mon Sep 17 00:00:00 2001
From: Kapu1178 <75460809+Kapu1178@users.noreply.github.com>
Date: Wed, 28 Feb 2024 17:04:15 -0500
Subject: [PATCH 09/19] fix storage action (#850)
---
code/datums/storage/storage.dm | 3 +++
html/browser/common.css | 4 ++--
tgui/packages/tgui-panel/styles/goon/chat-dark.scss | 3 ++-
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm
index 0272b29d27ec..a0d3ecb4ce50 100644
--- a/code/datums/storage/storage.dm
+++ b/code/datums/storage/storage.dm
@@ -283,6 +283,9 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches)
QDEL_NULL(modeswitch_action)
return
+ if(!isnull(modeswitch_action))
+ return
+
if(!isitem(parent))
return
diff --git a/html/browser/common.css b/html/browser/common.css
index 5ac9fa4a44ca..b93c048cf65b 100644
--- a/html/browser/common.css
+++ b/html/browser/common.css
@@ -263,7 +263,7 @@ div.notice
padding: 4px;
margin: 3px 0;
text-align: center;
- text-shadow: 0 0 5px #FFCC00;
+ text-shadow: 0 0 0.417em #FFCC00;
overflow: hidden;
font-size: 15px;
font-family: monospace;
@@ -286,7 +286,7 @@ div.notice
}
.computerText{
- text-shadow: 0 0 5px #C8C8C8;
+ text-shadow: 0 0 0.417em #C8C8C8;
color: #ffffff;
}
diff --git a/tgui/packages/tgui-panel/styles/goon/chat-dark.scss b/tgui/packages/tgui-panel/styles/goon/chat-dark.scss
index 2be673365334..847db519af02 100644
--- a/tgui/packages/tgui-panel/styles/goon/chat-dark.scss
+++ b/tgui/packages/tgui-panel/styles/goon/chat-dark.scss
@@ -285,7 +285,7 @@ em {
.ooc {
color: #cca300;
font-weight: bold;
- text-shadow: 0 0 2px #db7900;
+ text-shadow: 0 0 0.15em #db7900;
}
.looc {
@@ -418,6 +418,7 @@ em {
.bolddanger {
color: #dd3535;
+ text-shadow: 0 0 0.3em #FF0000;
font-weight: bold;
}
From 44b9b702dfb44306ac30a80edea506c56737e00e Mon Sep 17 00:00:00 2001
From: Changelog Generation
Date: Wed, 28 Feb 2024 17:04:46 -0500
Subject: [PATCH 10/19] Automatic changelog generation for PR #850 [ci skip]
---
html/changelogs/AutoChangeLog-pr-850.yml | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-850.yml
diff --git a/html/changelogs/AutoChangeLog-pr-850.yml b/html/changelogs/AutoChangeLog-pr-850.yml
new file mode 100644
index 000000000000..9e28f2b62f8b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-850.yml
@@ -0,0 +1,5 @@
+author: Kapu1178
+delete-after: true
+changes:
+ - bugfix: Storage objects no longer infinitely add action buttons.
+ - bugfix: Some text effects scale with font size.
From d38d9e4d54669343664aa4954e53f09d414c7bba Mon Sep 17 00:00:00 2001
From: Changelogs
Date: Thu, 29 Feb 2024 01:07:26 +0000
Subject: [PATCH 11/19] Automatic changelog compile [ci skip]
---
html/changelogs/AutoChangeLog-pr-850.yml | 5 -----
html/changelogs/archive/2024-02.yml | 4 ++++
2 files changed, 4 insertions(+), 5 deletions(-)
delete mode 100644 html/changelogs/AutoChangeLog-pr-850.yml
diff --git a/html/changelogs/AutoChangeLog-pr-850.yml b/html/changelogs/AutoChangeLog-pr-850.yml
deleted file mode 100644
index 9e28f2b62f8b..000000000000
--- a/html/changelogs/AutoChangeLog-pr-850.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: Kapu1178
-delete-after: true
-changes:
- - bugfix: Storage objects no longer infinitely add action buttons.
- - bugfix: Some text effects scale with font size.
diff --git a/html/changelogs/archive/2024-02.yml b/html/changelogs/archive/2024-02.yml
index f258bd4e460d..ddf4e7383cbb 100644
--- a/html/changelogs/archive/2024-02.yml
+++ b/html/changelogs/archive/2024-02.yml
@@ -153,3 +153,7 @@
used for trace DNA and blood DNA samples.
francinum:
- admin: A Lag Switch has been added to disable VV Icon Previews.
+2024-02-29:
+ Kapu1178:
+ - bugfix: Storage objects no longer infinitely add action buttons.
+ - bugfix: Some text effects scale with font size.
From 4b020f0c860e9edecd14053df93570ee96eec653 Mon Sep 17 00:00:00 2001
From: pitaden <32023715+pitaden@users.noreply.github.com>
Date: Thu, 29 Feb 2024 13:49:55 -0600
Subject: [PATCH 12/19] smaller plasma stacks (#852)
---
.../aesthetics/stacks/stack_objects.dmi | Bin 52305 -> 39423 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/modular_pariah/modules/aesthetics/stacks/stack_objects.dmi b/modular_pariah/modules/aesthetics/stacks/stack_objects.dmi
index 415474587ab390528b699e10e057d1cce07af58f..ab2fdf5fc6952dcf586b992678b125d174be4175 100644
GIT binary patch
literal 39423
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
Ysk~=KXe}1VVmus8Rb7=jCEE}G1t={F`2YX_
literal 52305
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