[MIRROR] Bible refactor [MDB IGNORE] (#21190)

* Bible refactor

* Delete book.dm

* updatepaths

* you're meaning to tell me i have to edit CODE??

---------

Co-authored-by: ChungusGamer666 <82850673+ChungusGamer666@users.noreply.github.com>
Co-authored-by: Tom <8881105+tf-4@users.noreply.github.com>
Co-authored-by: Jolly-66 <70232195+Jolly-66@users.noreply.github.com>
This commit is contained in:
SkyratBot
2023-05-16 09:34:10 -04:00
committed by GitHub
co-authored by ChungusGamer666 Tom Jolly-66
parent 71e0d530d3
commit d3f2386664
52 changed files with 1274 additions and 1414 deletions
+353
View File
@@ -0,0 +1,353 @@
GLOBAL_LIST_INIT(biblenames, list(
"Bible",
"Quran",
"Scrapbook",
"Burning Bible",
"Clown Bible",
"Banana Bible",
"Creeper Bible",
"White Bible",
"Holy Light",
"The God Delusion",
"Tome",
"The King in Yellow",
"Ithaqua",
"Scientology",
"Melted Bible",
"Necronomicon",
"Insulationism",
"Guru Granth Sahib",
"Kojiki",
))
//If you get these two lists not matching in size, there will be runtimes and I will hurt you in ways you couldn't even begin to imagine
// if your bible has no custom itemstate, use one of the existing ones
GLOBAL_LIST_INIT(biblestates, list(
"bible",
"koran",
"scrapbook",
"burning",
"honk1",
"honk2",
"creeper",
"white",
"holylight",
"atheist",
"tome",
"kingyellow",
"ithaqua",
"scientology",
"melted",
"necronomicon",
"insuls",
"gurugranthsahib",
"kojiki",
))
GLOBAL_LIST_INIT(bibleitemstates, list(
"bible",
"koran",
"scrapbook",
"burning",
"honk1",
"honk2",
"creeper",
"white",
"holylight",
"atheist",
"tome",
"kingyellow",
"ithaqua",
"scientology",
"melted",
"necronomicon",
"kingyellow",
"gurugranthsahib",
"kojiki",
))
/obj/item/book/bible
name = "bible"
desc = "Apply to head repeatedly."
icon = 'icons/obj/storage/book.dmi'
icon_state = "bible"
worn_icon_state = "bible"
inhand_icon_state = "bible"
lefthand_file = 'icons/mob/inhands/items/books_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/books_righthand.dmi'
force_string = "holy"
unique = TRUE
/// Deity this bible is related to
var/deity_name = "Space Jesus"
/obj/item/book/bible/Initialize(mapload)
. = ..()
AddComponent(/datum/component/anti_magic, MAGIC_RESISTANCE_HOLY)
carve_out()
/obj/item/book/bible/examine(mob/user)
. = ..()
if(deity_name)
. += span_notice("This bible has been approved by [deity_name].")
if(user.mind?.holy_role)
if(GLOB.chaplain_altars.len)
. += span_notice("[src] has an expansion pack to replace any broken Altar.")
else
. += span_notice("[src] can be unpacked by hitting the floor of a holy area with it.")
/obj/item/book/bible/burn_paper_product_attackby_check(obj/item/attacking_item, mob/living/user, bypass_clumsy)
. = ..()
// no deity to cast a curse upon thee
if(!deity_name)
return
if(. && (resistance_flags & ON_FIRE))
var/datum/component/omen/existing_omen = user.GetComponent(/datum/component/omen)
//DOUBLE CURSED?! Just straight up gib the guy.
if(existing_omen)
to_chat(user, span_userdanger("[deity_name] <b>SMITE</b> thee!"))
add_memory_in_range(user, 7, /datum/memory/witnessed_gods_wrath, protagonist = user, deuteragonist = src, antagonist = deity_name)
user.client?.give_award(/datum/award/achievement/misc/gods_wrath, user)
user.gib()
else
to_chat(user, span_userdanger("[deity_name] cast a curse upon thee!"))
user.AddComponent(/datum/component/omen/bible)
/obj/item/book/bible/carve_out(obj/item/carving_item, mob/living/user)
. = ..()
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
/obj/item/book/bible/suicide_act(mob/living/user)
user.visible_message(span_suicide("[user] is offering [user.p_them()]self to [deity_name]! It looks like [user.p_theyre()] trying to commit suicide!"))
return BRUTELOSS
/obj/item/book/bible/attack_self(mob/living/carbon/human/user)
if(GLOB.bible_icon_state)
return FALSE
if(user?.mind?.holy_role != HOLY_ROLE_HIGHPRIEST)
return FALSE
var/list/skins = list()
for(var/i in 1 to GLOB.biblestates.len)
var/image/bible_image = image(icon = 'icons/obj/storage/book.dmi', icon_state = GLOB.biblestates[i])
skins += list("[GLOB.biblenames[i]]" = bible_image)
var/choice = show_radial_menu(user, src, skins, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 40, require_near = TRUE)
if(!choice)
return FALSE
var/bible_index = GLOB.biblenames.Find(choice)
if(!bible_index)
return FALSE
icon_state = GLOB.biblestates[bible_index]
inhand_icon_state = GLOB.bibleitemstates[bible_index]
switch(icon_state)
if("honk1")
user.dna.add_mutation(/datum/mutation/human/clumsy)
user.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(user), ITEM_SLOT_MASK)
if("honk2")
user.dna.add_mutation(/datum/mutation/human/clumsy)
user.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/clown_hat(user), ITEM_SLOT_MASK)
if("insuls")
var/obj/item/clothing/gloves/color/fyellow/insuls = new
insuls.name = "insuls"
insuls.desc = "A mere copy of the true insuls."
insuls.siemens_coefficient = 0.99999
user.equip_to_slot(insuls, ITEM_SLOT_GLOVES)
GLOB.bible_icon_state = icon_state
GLOB.bible_inhand_icon_state = inhand_icon_state
SSblackbox.record_feedback("text", "religion_book", 1, "[choice]")
/**
* Checks if we are allowed to interact with a radial menu
*
* Arguments:
* * user The mob interacting with the menu
*/
/obj/item/book/bible/proc/check_menu(mob/living/carbon/human/user)
if(GLOB.bible_icon_state)
return FALSE
if(!istype(user) || !user.is_holding(src))
return FALSE
if(user.incapacitated())
return FALSE
if(user.mind?.holy_role != HOLY_ROLE_HIGHPRIEST)
return FALSE
return TRUE
/obj/item/book/bible/proc/make_new_altar(atom/bible_smacked, mob/user)
var/new_altar_area = get_turf(bible_smacked)
balloon_alert(user, "unpacking bible...")
if(!do_after(user, 15 SECONDS, new_altar_area))
return
new /obj/structure/altar_of_gods(new_altar_area)
qdel(src)
/obj/item/book/bible/proc/bless(mob/living/blessed, mob/living/user)
if(GLOB.religious_sect)
return GLOB.religious_sect.sect_bless(blessed,user)
if(!ishuman(blessed))
return
var/mob/living/carbon/human/built_in_his_image = blessed
for(var/obj/item/bodypart/bodypart as anything in built_in_his_image.bodyparts)
if(!IS_ORGANIC_LIMB(bodypart))
balloon_alert(user, "can't heal metal!")
return FALSE
var/heal_amt = 10
var/list/hurt_limbs = built_in_his_image.get_damaged_bodyparts(1, 1, BODYTYPE_ORGANIC)
if(length(hurt_limbs))
for(var/obj/item/bodypart/affecting as anything in hurt_limbs)
if(affecting.heal_damage(heal_amt, heal_amt, BODYTYPE_ORGANIC))
built_in_his_image.update_damage_overlays()
built_in_his_image.visible_message(span_notice("[user] heals [built_in_his_image] with the power of [deity_name]!"))
to_chat(built_in_his_image, span_boldnotice("May the power of [deity_name] compel you to be healed!"))
playsound(built_in_his_image, SFX_PUNCH, 25, TRUE, -1)
built_in_his_image.add_mood_event("blessing", /datum/mood_event/blessing)
return TRUE
/obj/item/book/bible/attack(mob/living/target_mob, mob/living/carbon/human/user, params, heal_mode = TRUE)
if(!ISADVANCEDTOOLUSER(user))
balloon_alert(user, "not dextrous enough!")
return
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
to_chat(user, span_danger("[src] slips out of your hand and hits your head."))
user.take_bodypart_damage(10)
user.Unconscious(40 SECONDS)
return
if(!user.mind?.holy_role)
to_chat(user, span_danger("The book sizzles in your hands."))
user.take_bodypart_damage(burn = 10)
return
if(!heal_mode)
return ..()
if(target_mob.stat == DEAD)
target_mob.visible_message(span_danger("[user] smacks [target_mob]'s lifeless corpse with [src]."))
playsound(target_mob, SFX_PUNCH, 25, TRUE, -1)
return
if(user == target_mob)
balloon_alert(user, "can't heal yourself!")
return
var/smack = TRUE
if(prob(60) && bless(target_mob, user))
smack = FALSE
else if(iscarbon(target_mob))
var/mob/living/carbon/carbon_target = target_mob
if(!istype(carbon_target.head, /obj/item/clothing/head/helmet))
carbon_target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5, 60)
carbon_target.balloon_alert(carbon_target, "you feel dumber!")
if(smack)
target_mob.visible_message(span_danger("[user] beats [target_mob] over the head with [src]!"), \
span_userdanger("[user] beats [target_mob] over the head with [src]!"))
playsound(target_mob, SFX_PUNCH, 25, TRUE, -1)
log_combat(user, target_mob, "attacked", src)
/obj/item/book/bible/afterattack(atom/bible_smacked, mob/user, proximity_flag, click_parameters)
. = ..()
if(!proximity_flag)
return
if(SEND_SIGNAL(bible_smacked, COMSIG_BIBLE_SMACKED, user, proximity_flag, click_parameters) & COMSIG_END_BIBLE_CHAIN)
return . | AFTERATTACK_PROCESSED_ITEM
if(isfloorturf(bible_smacked))
if(user.mind?.holy_role)
var/area/current_area = get_area(bible_smacked)
if(!GLOB.chaplain_altars.len && istype(current_area, /area/station/service/chapel))
make_new_altar(bible_smacked, user)
return
for(var/obj/effect/rune/nearby_runes in range(2, user))
nearby_runes.invisibility = 0
bible_smacked.balloon_alert(user, "floor smacked!")
if(user.mind?.holy_role)
if(bible_smacked.reagents && bible_smacked.reagents.has_reagent(/datum/reagent/water)) // blesses all the water in the holder
. |= AFTERATTACK_PROCESSED_ITEM
bible_smacked.balloon_alert(user, "blessed")
var/water2holy = bible_smacked.reagents.get_reagent_amount(/datum/reagent/water)
bible_smacked.reagents.del_reagent(/datum/reagent/water)
bible_smacked.reagents.add_reagent(/datum/reagent/water/holywater,water2holy)
if(bible_smacked.reagents && bible_smacked.reagents.has_reagent(/datum/reagent/fuel/unholywater)) // yeah yeah, copy pasted code - sue me
. |= AFTERATTACK_PROCESSED_ITEM
bible_smacked.balloon_alert(user, "purified")
var/unholy2holy = bible_smacked.reagents.get_reagent_amount(/datum/reagent/fuel/unholywater)
bible_smacked.reagents.del_reagent(/datum/reagent/fuel/unholywater)
bible_smacked.reagents.add_reagent(/datum/reagent/water/holywater,unholy2holy)
if(istype(bible_smacked, /obj/item/book/bible) && !istype(bible_smacked, /obj/item/book/bible/syndicate))
. |= AFTERATTACK_PROCESSED_ITEM
bible_smacked.balloon_alert(user, "converted")
var/obj/item/book/bible/other_bible = bible_smacked
other_bible.name = name
other_bible.icon_state = icon_state
other_bible.inhand_icon_state = inhand_icon_state
other_bible.deity_name = deity_name
if(istype(bible_smacked, /obj/item/cult_bastard) && !IS_CULTIST(user))
. |= AFTERATTACK_PROCESSED_ITEM
var/obj/item/cult_bastard/sword = bible_smacked
bible_smacked.balloon_alert(user, "exorcising...")
playsound(src,'sound/hallucinations/veryfar_noise.ogg',40,TRUE)
if(do_after(user, 4 SECONDS, target = sword))
playsound(src,'sound/effects/pray_chaplain.ogg',60,TRUE)
for(var/obj/item/soulstone/stone in sword.contents)
stone.required_role = null
for(var/mob/living/simple_animal/shade/shade in stone)
var/datum/antagonist/cult/cultist = shade.mind.has_antag_datum(/datum/antagonist/cult)
if(cultist)
cultist.silent = TRUE
cultist.on_removal()
shade.icon_state = "shade_holy"
shade.name = "Purified [shade.name]"
stone.release_shades(user)
qdel(stone)
new /obj/item/nullrod/claymore(get_turf(sword))
user.visible_message(span_notice("[user] exorcises [sword]!"))
qdel(sword)
/obj/item/book/bible/booze
desc = "To be applied to the head repeatedly."
/obj/item/book/bible/booze/Initialize(mapload)
. = ..()
new /obj/item/reagent_containers/cup/glass/bottle/whiskey(src)
/obj/item/book/bible/syndicate
name = "Syndicate Tome"
desc = "A very ominous tome resembling a bible."
icon_state ="ebook"
item_flags = NO_BLOOD_ON_ITEM
throw_speed = 2
throw_range = 7
throwforce = 18
force = 18
hitsound = 'sound/weapons/sear.ogg'
damtype = BURN
attack_verb_continuous = list("attacks", "burns", "blesses", "damns", "scorches", "curses", "smites")
attack_verb_simple = list("attack", "burn", "bless", "damn", "scorch", "curses", "smites")
deity_name = "The Syndicate"
var/uses = 1
var/owner_name
/obj/item/book/bible/syndicate/attack_self(mob/living/carbon/human/user, modifiers)
if(!uses || !istype(user))
return
user.mind.holy_role = HOLY_ROLE_PRIEST
uses -= 1
to_chat(user, span_userdanger("You try to open the book AND IT BITES YOU!"))
playsound(src.loc, 'sound/effects/snap.ogg', 50, TRUE)
var/active_hand_zone = (!(user.active_hand_index % RIGHT_HANDS) ? BODY_ZONE_R_ARM : BODY_ZONE_L_ARM)
user.apply_damage(5, BRUTE, active_hand_zone, attacking_item = src)
to_chat(user, span_notice("Your name appears on the inside cover, in blood."))
owner_name = user.real_name
/obj/item/book/bible/syndicate/examine(mob/user)
. = ..()
if(owner_name)
. += span_warning("The name [owner_name] is written in blood inside the cover.")
/obj/item/book/bible/syndicate/attack(mob/living/target_mob, mob/living/carbon/human/user, params, heal_mode = TRUE)
if(!user.combat_mode)
return ..()
return ..(target_mob, user, heal_mode = FALSE)
+57 -113
View File
@@ -1,84 +1,9 @@
//Some information about how html sanitization is handled
//All book info datums should store sanitized data. This cannot be worked around
//All inputs and outputs from the round (DB calls) need to use sanitized data
//All tgui menus should get unsanitized data, since jsx handles that on its own
//Everything else should use sanitized data. Yes including names, it's an xss vuln because of how chat works
///A datum which contains all the metadata of a book
/datum/book_info
///The title of the book
var/title
///The "author" of the book
var/author
///The info inside the book
var/content
/datum/book_info/New(_title, _author, _content)
title = _title
author = _author
content = _content
/datum/book_info/proc/set_title(_title, trusted = FALSE) //Trusted should only be used for books read from the db, or in cases that we can be sure the info has already been sanitized
if(trusted)
title = _title
return
title = reject_bad_text(trim(html_encode(_title), 30))
/datum/book_info/proc/get_title(default="N/A") //Loads in an html decoded version of the title. Only use this for tgui menus, absolutely nothing else.
return html_decode(title) || "N/A"
/datum/book_info/proc/set_author(_author, trusted = FALSE)
if(trusted)
author = _author
return
author = trim(html_encode(_author), MAX_NAME_LEN)
/datum/book_info/proc/get_author(default="N/A")
return html_decode(author) || "N/A"
/datum/book_info/proc/set_content(_content, trusted = FALSE)
if(trusted)
content = _content
return
content = trim(html_encode(_content), MAX_PAPER_LENGTH)
/datum/book_info/proc/set_content_using_paper(obj/item/paper/paper)
// Just the paper's raw data.
var/raw_content = ""
for(var/datum/paper_input/text_input as anything in paper.raw_text_inputs)
raw_content += text_input.to_raw_html()
content = trim(html_encode(raw_content), MAX_PAPER_LENGTH)
/datum/book_info/proc/get_content(default="N/A")
return html_decode(content) || "N/A"
///Returns a copy of the book_info datum
/datum/book_info/proc/return_copy()
var/datum/book_info/copycat = new(title, author, content)
return copycat
///Modify an existing book_info datum to match your data
/datum/book_info/proc/copy_into(datum/book_info/copycat)
copycat.set_title(title, trusted = TRUE)
copycat.set_author(author, trusted = TRUE)
copycat.set_content(content, trusted = TRUE)
return copycat
/datum/book_info/proc/compare(datum/book_info/cmp_with)
if(author != cmp_with.author)
return FALSE
if(title != cmp_with.title)
return FALSE
if(content != cmp_with.content)
return FALSE
return TRUE
/obj/item/book
name = "book"
desc = "Crack it open, inhale the musk of its pages, and learn something new."
icon = 'icons/obj/library.dmi'
icon_state ="book"
worn_icon_state = "book"
desc = "Crack it open, inhale the musk of its pages, and learn something new."
throw_speed = 1
throw_range = 5
w_class = WEIGHT_CLASS_NORMAL //upped to three because books are, y'know, pretty big. (and you could hide them inside eachother recursively forever)
@@ -87,22 +12,25 @@
resistance_flags = FLAMMABLE
drop_sound = 'sound/items/handling/book_drop.ogg'
pickup_sound = 'sound/items/handling/book_pickup.ogg'
///Game time in 1/10th seconds
/// Maximum icon state number
var/maximum_book_state = 8
/// Game time in 1/10th seconds
var/due_date = 0
///false - Normal book, true - Should not be treated as normal book, unable to be copied, unable to be modified
/// false - Normal book, true - Should not be treated as normal book, unable to be copied, unable to be modified
var/unique = FALSE
/// whether or not we have been carved out
var/carved = FALSE
/// Specific window size for the book, i.e: "1920x1080", Size x Width
var/window_size = null
///The initial title, for use in var editing and such
/// The initial title, for use in var editing and such
var/starting_title
///The initial author, for use in var editing and such
/// The initial author, for use in var editing and such
var/starting_author
///The initial bit of content, for use in var editing and such
/// The initial bit of content, for use in var editing and such
var/starting_content
///The packet of information that describes this book
/// The packet of information that describes this book
var/datum/book_info/book_data
///Maximum icon state number
var/maximum_book_state = 8
/obj/item/book/Initialize(mapload)
. = ..()
@@ -110,6 +38,11 @@
AddElement(/datum/element/falling_hazard, damage = 5, wound_bonus = 0, hardhat_safety = TRUE, crushes = FALSE, impact_sound = drop_sound)
/obj/item/book/examine(mob/user)
. = ..()
if(carved)
. += span_notice("[src] has been hollowed out.")
/obj/item/book/ui_static_data(mob/user)
var/list/data = list()
data["author"] = book_data.get_author()
@@ -118,8 +51,11 @@
return data
/obj/item/book/ui_interact(mob/living/user, datum/tgui/ui)
if(carved)
balloon_alert(user, "book is carved out!")
return
if(!length(book_data.get_content()))
balloon_alert(user, "this book is blank!")
balloon_alert(user, "book is blank!")
return
if(istype(user) && !isnull(user.mind))
@@ -134,10 +70,6 @@
ui = new(user, src, "MarkdownViewer", name)
ui.open()
/// Generates a random icon state for the book
/obj/item/book/proc/gen_random_icon_state()
icon_state = "book[rand(1, maximum_book_state)]"
/obj/item/book/attack_self(mob/user)
if(user.is_blind())
to_chat(user, span_warning("You are blind and can't read anything!"))
@@ -149,7 +81,7 @@
user.visible_message(span_notice("[user] opens a book titled \"[book_data.title]\" and begins reading intently."))
ui_interact(user)
/obj/item/book/attackby(obj/item/attacking_item, mob/user, params)
/obj/item/book/attackby(obj/item/attacking_item, mob/living/user, params)
if(burn_paper_product_attackby_check(attacking_item, user))
return
@@ -162,6 +94,9 @@
if(unique)
to_chat(user, span_warning("These pages don't seem to take the ink well! Looks like you can't modify it."))
return
if(carved)
to_chat(user, span_warning("The book has been carved out! There is nothing to be vandalized."))
return
var/choice = tgui_input_list(usr, "What would you like to change?", "Book Alteration", list("Title", "Contents", "Author", "Cancel"))
if(isnull(choice))
@@ -197,15 +132,12 @@
to_chat(user, span_warning("The name is invalid."))
return
book_data.set_author(html_decode(author)) //Setting this encodes, don't want to double up
else
return
else if(istype(attacking_item, /obj/item/barcodescanner))
var/obj/item/barcodescanner/scanner = attacking_item
var/obj/machinery/computer/libraryconsole/bookmanagement/computer = scanner.computer_ref?.resolve()
if(!computer)
to_chat(user, span_alert("[scanner]'s screen flashes: 'No associated computer found!'"))
return ..()
return
scanner.book_data = book_data.return_copy()
switch(scanner.mode)
@@ -231,23 +163,35 @@
computer.inventory[ref(our_copy)] = our_copy
computer.inventory_update()
to_chat(user, span_notice("[scanner]'s screen flashes: 'Book stored in buffer. Title added to general inventory.'"))
else if(((attacking_item.sharpness & SHARP_EDGED) || (attacking_item.tool_behaviour == TOOL_KNIFE) || (attacking_item.tool_behaviour == TOOL_WIRECUTTER)) && !(flags_1 & HOLOGRAM_1))
to_chat(user, span_notice("You begin to carve out [book_data.title]..."))
if(do_after(user, 30, target = src))
to_chat(user, span_notice("You carve out the pages from [book_data.title]! You didn't want to read it anyway."))
var/obj/item/storage/book/carved_out = new
carved_out.name = src.name
carved_out.title = book_data.title
carved_out.icon_state = src.icon_state
if(user.is_holding(src))
qdel(src)
user.put_in_hands(carved_out)
return
else
carved_out.forceMove(drop_location())
qdel(src)
return
else if(try_carve(attacking_item, user, params))
return
else
return ..()
return ..()
/// Generates a random icon state for the book
/obj/item/book/proc/gen_random_icon_state()
icon_state = "book[rand(1, maximum_book_state)]"
/// Called when user attempts to carve the book with an item
/obj/item/book/proc/try_carve(obj/item/carving_item, mob/living/user, params)
if(carved)
return FALSE
if(!user.combat_mode)
return FALSE
if(!((carving_item.sharpness & SHARP_EDGED) && (carving_item.tool_behaviour != TOOL_KNIFE) && (carving_item.tool_behaviour != TOOL_WIRECUTTER)))
return FALSE
//i hate balloon alerts i hate them so god damn much
balloon_alert(user, "carving out...")
if(!do_after(user, 3 SECONDS, target = src))
balloon_alert(user, "interrupted!")
return FALSE
carve_out(carving_item, user)
return TRUE
/// Called when the book gets carved successfully
/obj/item/book/proc/carve_out(obj/item/carving_item, mob/living/user)
if(user)
balloon_alert(user, "carved out")
playsound(src, 'sound/effects/cloth_rip.ogg', vol = 75, vary = TRUE)
carved = TRUE
create_storage(max_slots = 1)
return TRUE
+74
View File
@@ -0,0 +1,74 @@
//Some information about how html sanitization is handled
//All book info datums should store sanitized data. This cannot be worked around
//All inputs and outputs from the round (DB calls) need to use sanitized data
//All tgui menus should get unsanitized data, since jsx handles that on its own
//Everything else should use sanitized data. Yes including names, it's an xss vuln because of how chat works
///A datum which contains all the metadata of a book
/datum/book_info
///The title of the book
var/title
///The "author" of the book
var/author
///The info inside the book
var/content
/datum/book_info/New(_title, _author, _content)
title = _title
author = _author
content = _content
/datum/book_info/proc/set_title(_title, trusted = FALSE) //Trusted should only be used for books read from the db, or in cases that we can be sure the info has already been sanitized
if(trusted)
title = _title
return
title = reject_bad_text(trim(html_encode(_title), 30))
/datum/book_info/proc/get_title(default="N/A") //Loads in an html decoded version of the title. Only use this for tgui menus, absolutely nothing else.
return html_decode(title) || "N/A"
/datum/book_info/proc/set_author(_author, trusted = FALSE)
if(trusted)
author = _author
return
author = trim(html_encode(_author), MAX_NAME_LEN)
/datum/book_info/proc/get_author(default="N/A")
return html_decode(author) || "N/A"
/datum/book_info/proc/set_content(_content, trusted = FALSE)
if(trusted)
content = _content
return
content = trim(html_encode(_content), MAX_PAPER_LENGTH)
/datum/book_info/proc/set_content_using_paper(obj/item/paper/paper)
// Just the paper's raw data.
var/raw_content = ""
for(var/datum/paper_input/text_input as anything in paper.raw_text_inputs)
raw_content += text_input.to_raw_html()
content = trim(html_encode(raw_content), MAX_PAPER_LENGTH)
/datum/book_info/proc/get_content(default="N/A")
return html_decode(content) || "N/A"
///Returns a copy of the book_info datum
/datum/book_info/proc/return_copy()
var/datum/book_info/copycat = new(title, author, content)
return copycat
///Modify an existing book_info datum to match your data
/datum/book_info/proc/copy_into(datum/book_info/copycat)
copycat.set_title(title, trusted = TRUE)
copycat.set_author(author, trusted = TRUE)
copycat.set_content(content, trusted = TRUE)
return copycat
/datum/book_info/proc/compare(datum/book_info/cmp_with)
if(author != cmp_with.author)
return FALSE
if(title != cmp_with.title)
return FALSE
if(content != cmp_with.content)
return FALSE
return TRUE
+1 -1
View File
@@ -648,7 +648,7 @@
return TRUE
/obj/machinery/computer/libraryconsole/bookmanagement/proc/print_bible()
var/obj/item/storage/book/bible/holy_book = new(loc)
var/obj/item/book/bible/holy_book = new(loc)
if(!GLOB.bible_icon_state || !GLOB.bible_inhand_icon_state)
return
holy_book.icon_state = GLOB.bible_icon_state