mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-25 01:22:13 +00:00
Adds Random Notes (#5644)
Adds SSDocs, which manages randomly spawned documents.
These documents can be specified in a json file or in a database.
Adds /obj/random/document and adds /obj/random/document to the loot pool of /obj/random/loot.
Actually adding the notes to spawn is up to loredevs. If there are no notes to choose from, /obj/random/document will leave a blank sheet.
The notes can have HTML in them, meaning custom CSS and images. We're giving the loredevs a good bit of responsibility here.
This commit is contained in:
@@ -283,6 +283,9 @@ var/list/gamemode_cache = list()
|
||||
|
||||
var/rounds_until_hard_restart = -1 // Changes how often a hard restart will be executed.
|
||||
|
||||
var/docs_load_docs_from
|
||||
var/docs_image_host
|
||||
|
||||
var/ert_base_chance = 10
|
||||
var/ert_green_inc = 1
|
||||
var/ert_yellow_inc = 1
|
||||
@@ -886,6 +889,11 @@ var/list/gamemode_cache = list()
|
||||
if ("rounds_until_hard_restart")
|
||||
rounds_until_hard_restart = text2num(value)
|
||||
|
||||
if ("docs_load_docs_from")
|
||||
docs_load_docs_from = value
|
||||
if ("docs_image_host")
|
||||
docs_image_host = value
|
||||
|
||||
if ("ert_base_chance")
|
||||
ert_base_chance = text2num(value)
|
||||
if ("ert_green_inc")
|
||||
|
||||
231
code/controllers/subsystems/documents.dm
Normal file
231
code/controllers/subsystems/documents.dm
Normal file
@@ -0,0 +1,231 @@
|
||||
#define SSDOCS_MEDIUM_PAPER "paper"
|
||||
#define SSDOCS_MEDIUM_FILE "file"
|
||||
|
||||
var/datum/controller/subsystem/docs/SSdocs
|
||||
|
||||
/datum/controller/subsystem/docs
|
||||
name = "Documents"
|
||||
wait = 30 SECONDS
|
||||
flags = SS_NO_FIRE
|
||||
init_order = SS_INIT_MISC_FIRST
|
||||
|
||||
var/total_docs = 0
|
||||
var/list/docs = list()
|
||||
var/list/docs_by_tags = list()
|
||||
var/list/total_by_tags = list()
|
||||
|
||||
/datum/controller/subsystem/docs/Recover()
|
||||
src.docs = SSdocs.docs
|
||||
src.docs_by_tags = SSdocs.docs_by_tags
|
||||
|
||||
/datum/controller/subsystem/docs/Initialize(timeofday)
|
||||
//Load in the docs config
|
||||
if(config.docs_load_docs_from == "sql")
|
||||
log_debug("SSdocs: Attempting to Load from SQL")
|
||||
load_from_sql()
|
||||
else if(config.docs_load_docs_from == "json")
|
||||
log_debug("SSdocs: Attempting to Load from JSON")
|
||||
load_from_json()
|
||||
else
|
||||
log_game("SSdocs: invalid load option specified in config")
|
||||
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/docs/New()
|
||||
NEW_SS_GLOBAL(SSdocs)
|
||||
|
||||
/*
|
||||
Fetching Data
|
||||
*/
|
||||
//A rewritten version of pickweight.
|
||||
/datum/controller/subsystem/docs/proc/pick_document()
|
||||
var/subtotal = rand() * src.total_docs
|
||||
for (var/doc in docs)
|
||||
subtotal -= docs[doc].chance
|
||||
if (subtotal <= 0)
|
||||
return docs[doc]
|
||||
return null
|
||||
|
||||
//Pick a document by one tag
|
||||
/datum/controller/subsystem/docs/proc/pick_document_by_tag(var/tag)
|
||||
if(!docs_by_tags[tag])
|
||||
return null
|
||||
var/subtotal = rand() * src.total_by_tags[tag]
|
||||
for (var/doc in docs_by_tags[tag])
|
||||
subtotal -= docs_by_tags[tag][doc].chance
|
||||
if (subtotal <= 0)
|
||||
return docs_by_tags[tag][doc]
|
||||
return null
|
||||
|
||||
//Pick a document by any tag from a list of tags. Weighted.
|
||||
/datum/controller/subsystem/docs/proc/pick_document_by_any_tag(var/list/tags)
|
||||
if(!istype(tags) || !tags.len)
|
||||
return null
|
||||
var/total_chance = 0
|
||||
var/tag_sublist = list()
|
||||
for(var/t in tags)
|
||||
if(!total_by_tags[t])
|
||||
return null
|
||||
total_chance += total_by_tags[t]
|
||||
tag_sublist += docs_by_tags[t]
|
||||
var/subtotal = total_chance * rand()
|
||||
for(var/doc in tag_sublist)
|
||||
subtotal -= tag_sublist[doc].chance
|
||||
if(subtotal <= 0)
|
||||
return tag_sublist[doc]
|
||||
return null
|
||||
|
||||
//Pick a document by multiple tags that it must have.
|
||||
/datum/controller/subsystem/docs/proc/pick_document_by_tags(var/list/tags)
|
||||
if(!istype(tags) || !tags.len)
|
||||
return null
|
||||
var/list/tag_sublist = docs_by_tags[pick(tags)] // the list cannot start off as empty
|
||||
for(var/t in tags)
|
||||
if(!docs_by_tags[t])
|
||||
return null
|
||||
tag_sublist &= docs_by_tags[t]
|
||||
log_ss("docs", "Tag sublist has length [tag_sublist.len].")
|
||||
var/subtotal = 0
|
||||
for(var/datum/docs_document/dd in tag_sublist)
|
||||
subtotal += dd.chance
|
||||
subtotal *= rand()
|
||||
for (var/doc in tag_sublist)
|
||||
subtotal -= tag_sublist[doc].chance
|
||||
if (subtotal <= 0)
|
||||
return tag_sublist[doc]
|
||||
return null
|
||||
/*
|
||||
Loading Data
|
||||
*/
|
||||
//Reset docs to prep for loading in new items
|
||||
/datum/controller/subsystem/docs/proc/reset_docs()
|
||||
docs = list()
|
||||
docs_by_tags = list()
|
||||
total_docs = 0
|
||||
total_by_tags = list()
|
||||
|
||||
//Load the document data from SQL
|
||||
/datum/controller/subsystem/docs/proc/load_from_sql()
|
||||
if(!establish_db_connection(dbcon))
|
||||
log_debug("SSdocs: SQL ERROR - Failed to connect. - Falling back to JSON")
|
||||
return load_from_json()
|
||||
else
|
||||
//Reset the currently loaded data
|
||||
reset_docs()
|
||||
|
||||
//Load the categories
|
||||
var/DBQuery/document_query = dbcon.NewQuery("SELECT name, title, chance, content, tags FROM ss13_documents WHERE deleted_at IS NULL")
|
||||
document_query.Execute()
|
||||
while(document_query.NextRow())
|
||||
CHECK_TICK
|
||||
try
|
||||
add_document(
|
||||
document_query.item[1],
|
||||
document_query.item[2],
|
||||
text2num(document_query.item[3]),
|
||||
document_query.item[4],
|
||||
json_decode(document_query.item[5]))
|
||||
catch(var/exception/ec)
|
||||
log_debug("SSdocs: Error when loading document: [ec]")
|
||||
return 1
|
||||
|
||||
//Loads the document data from JSON
|
||||
/datum/controller/subsystem/docs/proc/load_from_json()
|
||||
var/list/docsconfig = list()
|
||||
try
|
||||
docsconfig = json_decode(return_file_text("config/docs.json"))
|
||||
catch(var/exception/ej)
|
||||
log_debug("SSdocs: Warning: Could not load config, as docs.json is missing - [ej]")
|
||||
return 0
|
||||
|
||||
//Reset the currently loaded data
|
||||
reset_docs()
|
||||
|
||||
//Load the documents
|
||||
for (var/document in docsconfig)
|
||||
CHECK_TICK
|
||||
try
|
||||
add_document(
|
||||
docsconfig[document]["name"],
|
||||
docsconfig[document]["title"],
|
||||
docsconfig[document]["chance"],
|
||||
docsconfig[document]["content"],
|
||||
docsconfig[document]["tags"])
|
||||
catch(var/exception/ec)
|
||||
log_ss("docs","Error when loading document: [ec]")
|
||||
return 1
|
||||
|
||||
/datum/controller/subsystem/docs/proc/add_document(var/name,var/title,var/chance,var/content,var/tags)
|
||||
var/datum/docs_document/dd = new()
|
||||
dd.name = name
|
||||
dd.title = title
|
||||
dd.chance = chance
|
||||
dd.content = content
|
||||
if(istext(tags))
|
||||
tags = splittext(tags, ";")
|
||||
dd.tags = tags
|
||||
|
||||
//Adds the document to the docs, sorted by tags
|
||||
for(var/t in tags)
|
||||
if(!(docs_by_tags[t]))
|
||||
docs_by_tags[t] = list()
|
||||
total_by_tags[t] = 0
|
||||
docs_by_tags[t][dd.name] += dd
|
||||
total_by_tags[t] += dd.chance
|
||||
|
||||
//Add the document to the docs list
|
||||
docs[dd.name] = dd
|
||||
total_docs += dd.chance
|
||||
return dd
|
||||
|
||||
/datum/docs_document
|
||||
var/name = "document" // internal name of the document
|
||||
var/title = "paper" // player-facing title of the document
|
||||
var/chance = 0
|
||||
var/content = "" // Can contain html, but pencode is not processed.
|
||||
var/list/tags = list() // A list of tags that apply to the document.
|
||||
|
||||
/obj/random/document
|
||||
name = "random document"
|
||||
desc = "This is a random text document."
|
||||
icon = 'icons/obj/bureaucracy.dmi'
|
||||
icon_state = "paper"
|
||||
has_postspawn = 1
|
||||
var/tags = list() // for use by mappers, typically
|
||||
|
||||
/obj/random/document/item_to_spawn()
|
||||
return /obj/item/weapon/paper
|
||||
|
||||
/obj/random/document/post_spawn(var/obj/item/weapon/paper/spawned)
|
||||
if(!istype(spawned))
|
||||
return
|
||||
var/list/total_tags = tags | list(SSDOCS_MEDIUM_PAPER)
|
||||
var/datum/docs_document/doc
|
||||
if (total_tags.len == 1)
|
||||
doc = SSdocs.pick_document_by_tag(total_tags[1])
|
||||
else
|
||||
doc = SSdocs.pick_document_by_tags(total_tags)
|
||||
|
||||
if (!istype(doc))
|
||||
log_ss("docs","Null paper acquired in post_spawn!")
|
||||
return null
|
||||
|
||||
log_ss("docs","Document [doc.name] successfully spawned!")
|
||||
var/obj/item/weapon/paper/P = spawned
|
||||
P.set_content(doc.title, doc.content)
|
||||
|
||||
/obj/random/document/junk/post_spawn(var/obj/item/spawned)
|
||||
..()
|
||||
if(istype(spawned, /obj/item/weapon/paper) && prob(80)) // 1 in 5 junk-spawned documents will be perfectly readable
|
||||
var/obj/item/weapon/paper/P = spawned
|
||||
P.info = stars(P.info, 85) // 85% readable, preserves tags
|
||||
P.icon_state = "scrap"
|
||||
|
||||
/datum/controller/subsystem/docs/proc/create_file(var/datum/docs_document/file)
|
||||
var/datum/computer_file/data/F = new/datum/computer_file/data()
|
||||
F.filename = file.title
|
||||
F.filetype = "TXT"
|
||||
log_ss("docs","Digital file created: [file.title].TXT")
|
||||
F.stored_data = file.content
|
||||
F.calculate_size()
|
||||
return F
|
||||
Reference in New Issue
Block a user