diff --git a/code/__DEFINES/text.dm b/code/__DEFINES/text.dm
index 58ab98b132b..48487531d0f 100644
--- a/code/__DEFINES/text.dm
+++ b/code/__DEFINES/text.dm
@@ -9,3 +9,11 @@
/// Simply removes the < and > characters, and limits the length of the message.
#define STRIP_HTML_SIMPLE(text, limit) (GLOB.angular_brackets.Replace(copytext(text, 1, limit), ""))
+
+///Index access defines for paper/var/add_info_style
+#define ADD_INFO_COLOR 1
+#define ADD_INFO_FONT 2
+#define ADD_INFO_SIGN 3
+
+///Adds a html style to a text string. Hacky, but that's how inputted text appear on paper sheets after going through the UI.
+#define PAPER_MARK_TEXT(text, color, font) "[text]\n \n"
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 5c5d667bf85..c1bb2815720 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -526,6 +526,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Trait applied when the MMI component is added to an [/obj/item/integrated_circuit]
#define TRAIT_COMPONENT_MMI "component_mmi"
+/// Trait applied when the MMI component is added to an [/obj/item/integrated_circuit]
+#define TRAIT_COMPONENT_PRINTER "component_printer"
/// If present on a [/mob/living/carbon], will make them appear to have a medium level disease on health HUDs.
#define TRAIT_DISEASELIKE_SEVERITY_MEDIUM "diseaselike_severity_medium"
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index ff5563b1d8c..6b028aa5745 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -1131,11 +1131,15 @@ GLOBAL_LIST_EMPTY(PDAs)
A.analyzer_act(user, src)
if (!scanmode && istype(A, /obj/item/paper) && owner)
- var/obj/item/paper/PP = A
- if (!PP.info)
+ var/obj/item/paper/paper = A
+ if (!paper.get_info_length())
to_chat(user, span_warning("Unable to scan! Paper is blank."))
return
- notehtml = PP.info
+ notehtml = paper.info
+ if(paper.add_info)
+ for(var/index in 1 to length(paper.add_info))
+ var/list/style = paper.add_info_style[index]
+ notehtml += PAPER_MARK_TEXT(paper.add_info[index], style[ADD_INFO_COLOR], style[ADD_INFO_FONT])
note = replacetext(notehtml, "
", "\[br\]")
note = replacetext(note, "
", "\[*\]")
note = replacetext(note, "", "\[list\]")
diff --git a/code/game/objects/items/inspector.dm b/code/game/objects/items/inspector.dm
index df7e35b9c85..83aec23cb0b 100644
--- a/code/game/objects/items/inspector.dm
+++ b/code/game/objects/items/inspector.dm
@@ -160,7 +160,7 @@
. += span_notice("\The [src] contains data on [scanned_area.name].")
else if(scanned_area)
. += span_notice("\The [src] contains data on a vague area on station, you should throw it away.")
- else if(info)
+ else if(get_info_length())
icon_state = "slipfull"
. += span_notice("Wait a minute, this isn't an encrypted inspection report! You should throw it away.")
else
@@ -358,7 +358,7 @@
. += span_notice("\The [src] contains no data on [scanned_area.name].")
else if(scanned_area)
. += span_notice("\The [src] contains no data on a vague area on station, you should throw it away.")
- else if(info)
+ else if(get_info_length())
. += span_notice("Wait a minute, this isn't an encrypted inspection report! You should throw it away.")
else
. += span_notice("Wait a minute, this thing's blank! You should throw it away.")
diff --git a/code/game/objects/structures/votingbox.dm b/code/game/objects/structures/votingbox.dm
index 4fa008b9455..c2261e733d1 100644
--- a/code/game/objects/structures/votingbox.dm
+++ b/code/game/objects/structures/votingbox.dm
@@ -117,7 +117,7 @@
to_chat(user,span_notice("You cast your vote."))
/obj/structure/votebox/proc/valid_vote(obj/item/paper/I)
- if(length_char(I.info) > VOTE_TEXT_LIMIT || findtext(I.info,"Voting Results:
"))
+ if(I.get_info_length() > VOTE_TEXT_LIMIT || findtext(I.info,"Voting Results:
"))
return FALSE
return TRUE
diff --git a/code/modules/modular_computers/hardware/printer.dm b/code/modules/modular_computers/hardware/printer.dm
index fc174d6fc45..cf3687b22c9 100644
--- a/code/modules/modular_computers/hardware/printer.dm
+++ b/code/modules/modular_computers/hardware/printer.dm
@@ -59,7 +59,7 @@
/// Number of sheets we're adding
var/num_to_add = 0
for(var/obj/item/paper/the_paper as anything in bin.papers) // Search for the first blank sheet of paper, then toss it in
- if(the_paper.info != "") // Uh oh, paper has words!
+ if(the_paper.get_info_length()) // Uh oh, paper has words!
continue
if(istype(the_paper, /obj/item/paper/carbon)) // Add both the carbon, and the copy
var/obj/item/paper/carbon/carbon_paper = the_paper
diff --git a/code/modules/paperwork/carbonpaper.dm b/code/modules/paperwork/carbonpaper.dm
index 66c5d51aba5..4fc883ba9af 100644
--- a/code/modules/paperwork/carbonpaper.dm
+++ b/code/modules/paperwork/carbonpaper.dm
@@ -10,7 +10,7 @@
icon_state = "paper"
else
icon_state = "paper_stack"
- if(info)
+ if(info || add_info)
icon_state = "[icon_state]_words"
return ..()
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 6ceb111bf7f..24d9cf01f6c 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -11,6 +11,10 @@
#define MODE_WRITING 1
#define MODE_STAMPING 2
+#define DEFAULT_ADD_INFO_COLOR "black"
+#define DEFAULT_ADD_INFO_FONT "Verdana"
+#define DEFAULT_ADD_INFO_SIGN "signature"
+
/**
* Paper is now using markdown (like in github pull notes) for ALL rendering
* so we do loose a bit of functionality but we gain in easy of use of
@@ -40,6 +44,15 @@
color = "white"
/// What's actually written on the paper.
var/info = ""
+ /**
+ * What's been written on the paper by things other than players.
+ * Will be sanitized by the UI, and finally
+ * added to info when the user edits the paper text.
+ */
+ var/list/add_info
+ /// The font color, face and the signature of the above.
+ var/list/add_info_style
+
var/show_written_words = TRUE
/// The (text for the) stamps on the paper.
@@ -70,9 +83,13 @@
if(colored)
new_paper.color = color
new_paper.info = info
+ new_paper.add_info_style = add_info_style.Copy()
else //This basically just breaks the existing color tag, which we need to do because the innermost tag takes priority.
- var/static/greyscale_info = regex("", "i")
+ new_paper.info = replacetext(info, greyscale_info, "nocolor=$1>")
+ for(var/list/style as anything in add_info_style)
+ LAZYADD(new_paper.add_info_style, list(list(DEFAULT_ADD_INFO_COLOR, style[ADD_INFO_FONT], style[ADD_INFO_SIGN])))
+ new_paper.add_info = add_info?.Copy()
new_paper.stamps = stamps?.Copy()
new_paper.stamped = stamped?.Copy()
new_paper.form_fields = form_fields.Copy()
@@ -86,11 +103,14 @@
* icons. You can modify the pen_color after if need
* be.
*/
-/obj/item/paper/proc/setText(text)
+/obj/item/paper/proc/setText(text, update_icon = TRUE)
info = text
+ add_info = null
+ add_info_style = null
form_fields = null
field_counter = 0
- update_icon_state()
+ if(update_icon)
+ update_appearance()
/obj/item/paper/pickup(user)
if(contact_poison && ishuman(user))
@@ -108,7 +128,7 @@
update_appearance()
/obj/item/paper/update_icon_state()
- if(info && show_written_words)
+ if((info || add_info) && show_written_words)
icon_state = "[initial(icon_state)]_words"
return ..()
@@ -136,7 +156,7 @@
return (BRUTELOSS)
/obj/item/paper/proc/clearpaper()
- info = ""
+ setText("", update_icon = FALSE)
stamps = null
LAZYCLEARLIST(stamped)
cut_overlays()
@@ -196,6 +216,21 @@
add_fingerprint(user)
fire_act(I.get_temperature())
+/obj/item/paper/proc/add_info(text, color = DEFAULT_ADD_INFO_COLOR, font = DEFAULT_ADD_INFO_FONT, signature = DEFAULT_ADD_INFO_SIGN)
+ LAZYADD(add_info, text)
+ LAZYADD(add_info_style, list(list(color, font, signature)))
+
+/obj/item/paper/proc/get_info_length()
+ . = length_char(info)
+ for(var/index in 1 to length(add_info))
+ var/style = LAZYACCESS(add_info_style, index)
+ if(style)
+ var/static/regex/sign_regex = regex("%s(?:ign)?(?=\\s|$)?", "igm")
+ var/signed_text = sign_regex.Replace(add_info[index], style[ADD_INFO_SIGN])
+ . += length_char(PAPER_MARK_TEXT(signed_text, style[ADD_INFO_COLOR], style[ADD_INFO_FONT]))
+ else
+ . += length_char(add_info[index])
+
/obj/item/paper/attackby(obj/item/P, mob/living/user, params)
if(burn_paper_product_attackby_check(P, user))
SStgui.close_uis(src)
@@ -206,7 +241,7 @@
P.attackby(src, user)
return
else if(istype(P, /obj/item/pen) || istype(P, /obj/item/toy/crayon))
- if(length(info) >= MAX_PAPER_LENGTH) // Sheet must have less than 1000 charaters
+ if(get_info_length() >= MAX_PAPER_LENGTH) // Sheet must have less than 5000 charaters
to_chat(user, span_warning("This sheet of paper is full!"))
return
ui_interact(user)
@@ -226,6 +261,8 @@
. = ..()
if(.)
info = "[stars(info)]"
+ for(var/index in 1 to add_info)
+ add_info[index] = "[stars(add_info[index])]"
/obj/item/paper/ui_assets(mob/user)
return list(
@@ -239,17 +276,30 @@
ui = new(user, src, "PaperSheet", name)
ui.open()
-
/obj/item/paper/ui_static_data(mob/user)
. = list()
.["text"] = info
+ if(length(add_info))
+ .["add_text"] = add_info
+ .["add_color"] = list()
+ .["add_font"] = list()
+ .["add_sign"] = list()
+ for(var/index in 1 to length(add_info))
+ var/list/style = LAZYACCESS(add_info_style, index)
+ if(!islist(index) || length(style) < ADD_INFO_SIGN) // failsafe for malformed add_info_style.
+ var/list/corrected_style = list(DEFAULT_ADD_INFO_COLOR, DEFAULT_ADD_INFO_FONT, DEFAULT_ADD_INFO_SIGN)
+ LAZYADD(add_info_style, corrected_style)
+ style = corrected_style
+ .["add_color"] += style[ADD_INFO_COLOR]
+ .["add_font"] += style[ADD_INFO_FONT]
+ .["add_sign"] += style[ADD_INFO_SIGN]
+
.["max_length"] = MAX_PAPER_LENGTH
.["paper_color"] = !color || color == "white" ? "#FFFFFF" : color // color might not be set
.["paper_state"] = icon_state /// TODO: show the sheet will bloodied or crinkling?
.["stamps"] = stamps
-
/obj/item/paper/ui_data(mob/user)
var/list/data = list()
data["edit_usr"] = "[user.real_name]"
@@ -355,9 +405,10 @@
if(info != in_paper)
to_chat(ui.user, "You have added to your paper masterpiece!");
info = in_paper
+ add_info = null
+ add_info_style = null
update_static_data(usr,ui)
-
update_appearance()
. = TRUE
@@ -400,3 +451,6 @@
#undef MODE_READING
#undef MODE_WRITING
#undef MODE_STAMPING
+#undef DEFAULT_ADD_INFO_COLOR
+#undef DEFAULT_ADD_INFO_FONT
+#undef DEFAULT_ADD_INFO_SIGN
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index 1f551c570c2..a11cac4e048 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -93,7 +93,7 @@
to_chat(usr, span_warning("[src] is currently busy copying something. Please wait until it is finished."))
return FALSE
if(paper_copy)
- if(!length(paper_copy.info))
+ if(!paper_copy.get_info_length())
to_chat(usr, span_warning("An error message flashes across [src]'s screen: \"The supplied paper is blank. Aborting.\""))
return FALSE
// Basic paper
@@ -234,7 +234,10 @@
give_pixel_offset(copied_paper)
//the font color dependant on the amount of toner left.
- copied_paper.info = " 10 ? "#101010" : "#808080"]>[copied_paper.info]"
+ var/chosen_color = toner_cartridge.charges > 10 ? "#101010" : "#808080"
+ copied_paper.info = "[copied_paper.info]"
+ for(var/list/style as anything in copied_paper.add_info_style)
+ style[ADD_INFO_COLOR] = chosen_color
copied_paper.name = paper_copy.name
toner_cartridge.charges -= PAPER_TONER_USE
diff --git a/code/modules/religion/rites.dm b/code/modules/religion/rites.dm
index 2742bb9ca96..0e7cfa57738 100644
--- a/code/modules/religion/rites.dm
+++ b/code/modules/religion/rites.dm
@@ -420,7 +420,7 @@
for(var/obj/item/paper/could_writ in get_turf(religious_tool))
if(istype(could_writ, /obj/item/paper/holy_writ))
continue
- if(could_writ.info) //blank paper pls
+ if(could_writ.get_info_length()) //blank paper pls
continue
writ_target = could_writ //PLEASE SIGN MY AUTOGRAPH
return ..()
@@ -614,7 +614,7 @@
/datum/religion_rites/sparring_contract/perform_rite(mob/living/user, atom/religious_tool)
for(var/obj/item/paper/could_contract in get_turf(religious_tool))
- if(could_contract.info) //blank paper pls
+ if(could_contract.get_info_length()) //blank paper pls
continue
contract_target = could_contract
return ..()
diff --git a/code/modules/research/designs/wiremod_designs.dm b/code/modules/research/designs/wiremod_designs.dm
index 3b96e0c2453..99c75416452 100644
--- a/code/modules/research/designs/wiremod_designs.dm
+++ b/code/modules/research/designs/wiremod_designs.dm
@@ -263,6 +263,11 @@
id = "comp_typecast"
build_path = /obj/item/circuit_component/typecast
+/datum/design/component/printer
+ name = "Printer Component"
+ id = "comp_printer"
+ build_path = /obj/item/circuit_component/printer
+
/datum/design/component/pinpointer
name = "Proximity Pinpointer Component"
id = "comp_pinpointer"
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index ec09ac0c85e..24b84f5440e 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -242,6 +242,7 @@
"comp_ntnet_send",
"comp_pinpointer",
"comp_pressuresensor",
+ "comp_printer",
"comp_radio",
"comp_random",
"comp_router",
diff --git a/code/modules/wiremod/components/action/printer.dm b/code/modules/wiremod/components/action/printer.dm
new file mode 100644
index 00000000000..e6052d2a5cf
--- /dev/null
+++ b/code/modules/wiremod/components/action/printer.dm
@@ -0,0 +1,138 @@
+/**
+ * # Printer Component
+ *
+ * Allows for text strings to be printed on a paper. Requires a shell.
+ */
+/obj/item/circuit_component/printer
+ display_name = "Printer"
+ desc = "A component that prints a string input on a paper. Requires a shell and paper. \
+ Attack with paper to load them in the circuit. Use in hand to dump the bottom-most paper."
+ circuit_flags = CIRCUIT_FLAG_REFUSE_MODULE
+
+ /// Prints stuff on the leftmost paper in the loaded_papers list.
+ var/datum/port/input/print
+ /// The selected font-family used when printing text on paper
+ var/datum/port/input/option/typeface
+ /// The RGB values of the color used when printing text on paper
+ var/datum/port/input/text_color_red
+ var/datum/port/input/text_color_green
+ var/datum/port/input/text_color_blue
+ /// Used to eject the leftmost paper on the loaded_papers list.
+ var/datum/port/input/eject
+ /// The signature that'll replace any %s and %sign used when printing text on paper.
+ var/datum/port/input/signature
+
+ /// The list of papers currently loaded on the component
+ var/list/obj/item/paper/loaded_papers
+ /// The maximum paper capacity of the component
+ var/max_paper_capacity = 10
+
+/obj/item/circuit_component/printer/populate_ports()
+ print = add_input_port("Print", PORT_TYPE_STRING, trigger = .proc/print_on_paper)
+ text_color_red = add_input_port("Color (Red)", PORT_TYPE_NUMBER, trigger = null, default = 0)
+ text_color_green = add_input_port("Color (Green)", PORT_TYPE_NUMBER, trigger = null, default = 0)
+ text_color_blue = add_input_port("Color (Blue)", PORT_TYPE_NUMBER, trigger = null, default = 0)
+ signature = add_input_port("Signature", PORT_TYPE_STRING, trigger = null, default = "signature")
+ eject = add_input_port("Eject", PORT_TYPE_SIGNAL, trigger = .proc/eject_paper, order = 2)
+
+/obj/item/circuit_component/printer/populate_options()
+ var/static/typeface_options = list(
+ PRINTER_FONT,
+ PEN_FONT,
+ FOUNTAIN_PEN_FONT,
+ CRAYON_FONT,
+ "Impact",
+ "Webdings",
+ )
+ typeface = add_option_port("Typeface", typeface_options, trigger = null)
+
+/obj/item/circuit_component/printer/Destroy()
+ QDEL_LIST(loaded_papers)
+ return ..()
+
+/obj/item/circuit_component/printer/add_to(obj/item/integrated_circuit/add_to)
+ . = ..()
+ if(HAS_TRAIT(add_to, TRAIT_COMPONENT_PRINTER))
+ return FALSE
+ ADD_TRAIT(add_to, TRAIT_COMPONENT_PRINTER, src)
+
+/obj/item/circuit_component/printer/removed_from(obj/item/integrated_circuit/removed_from)
+ REMOVE_TRAIT(removed_from, TRAIT_COMPONENT_PRINTER, src)
+ return ..()
+
+/obj/item/circuit_component/printer/register_shell(atom/movable/shell)
+ RegisterSignal(shell, COMSIG_PARENT_ATTACKBY_SECONDARY, .proc/handle_secondary_attackby)
+ RegisterSignal(shell, COMSIG_PARENT_EXAMINE, .proc/on_examine)
+
+/obj/item/circuit_component/printer/unregister_shell(atom/movable/shell)
+ UnregisterSignal(shell, list(COMSIG_PARENT_ATTACKBY_SECONDARY, COMSIG_PARENT_EXAMINE))
+
+/obj/item/circuit_component/printer/get_ui_notices()
+ . = ..()
+ . += create_ui_notice("Papers Stored: [length(loaded_papers)]/[max_paper_capacity]", "orange", "info")
+
+///Allows for paper to be loaded while inside the shell.
+/obj/item/circuit_component/printer/proc/handle_secondary_attackby(atom/movable/shell, obj/item/item, mob/living/attacker)
+ SIGNAL_HANDLER
+ if(istype(item, /obj/item/paper))
+ load_paper(item, attacker)
+ return COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN
+
+/obj/item/circuit_component/printer/proc/on_examine(datum/source, mob/user, list/examine_list)
+ SIGNAL_HANDLER
+ examine_list += span_notice("It's a printer component installed in. Right-click with paper to reload it.")
+
+/obj/item/circuit_component/printer/attackby(obj/item/item, mob/living/user, params)
+ if(istype(item, /obj/item/paper))
+ load_paper(item, user)
+ else
+ return ..()
+
+/obj/item/circuit_component/printer/proc/load_paper(obj/item/paper/paper, mob/living/user)
+ if(length(loaded_papers) >= max_paper_capacity)
+ to_chat(user, span_warning("[src] can't hold any more paper."))
+ else if(user.transferItemToLoc(paper, src))
+ LAZYADD(loaded_papers, paper)
+ to_chat(user, span_notice("You load [paper] in [src]."))
+ else
+ to_chat(user, span_warning("[paper] seems to be stuck to your hand."))
+
+/obj/item/circuit_component/printer/attack_self(mob/living/user)
+ . = ..()
+ var/obj/item/paper/paper = loaded_papers?[1]
+ if(paper)
+ user.put_in_hands(paper)
+ to_chat(user, span_notice("You remove [paper] from [src]."))
+
+/obj/item/circuit_component/printer/Exited(atom/movable/movable)
+ . = ..()
+ if(movable in loaded_papers)
+ LAZYREMOVE(loaded_papers, movable)
+
+/obj/item/circuit_component/printer/pre_input_received(datum/port/input/port)
+ if(port != print)
+ return
+ text_color_red.set_value(clamp(text_color_red.value, 0, 255))
+ text_color_green.set_value(clamp(text_color_green.value, 0, 255))
+ text_color_blue.set_value(clamp(text_color_blue.value, 0, 255))
+ signature.set_value(reject_bad_text(signature.value, MAX_NAME_LEN, FALSE) || "signature")
+
+/obj/item/circuit_component/printer/proc/print_on_paper(datum/port/input/port)
+ if(!print.value)
+ return
+ var/obj/item/paper/paper = loaded_papers?[1]
+ if(!paper)
+ return
+ paper.add_info(print.value, rgb(text_color_red, text_color_green, text_color_blue), typeface.value, signature.value)
+ log_paper("Printer component writing to paper [paper.name]. [parent.get_creator()].")
+
+/obj/item/circuit_component/printer/proc/eject_paper(datum/port/input/port, list/return_values)
+ var/obj/item/paper/paper = loaded_papers?[1]
+ if(!paper)
+ return
+ playsound(src, "sound/machines/dotprinter.ogg", 30, TRUE)
+ if(isliving(parent?.shell?.loc))
+ var/mob/living/living_loc = parent.shell.loc
+ living_loc.put_in_hands(paper)
+ else
+ paper.forceMove(drop_location())
diff --git a/code/modules/wiremod/core/component.dm b/code/modules/wiremod/core/component.dm
index b7a9fb5cfc1..357858be7a7 100644
--- a/code/modules/wiremod/core/component.dm
+++ b/code/modules/wiremod/core/component.dm
@@ -81,6 +81,8 @@
trigger_output = add_output_port("Triggered", PORT_TYPE_SIGNAL, order = 2)
if(circuit_flags & CIRCUIT_FLAG_INSTANT)
ui_color = "orange"
+ if(circuit_flags & CIRCUIT_FLAG_REFUSE_MODULE)
+ desc += " Incompatible with module components."
/obj/item/circuit_component/Destroy()
if(parent)
diff --git a/sound/machines/dotprinter.ogg b/sound/machines/dotprinter.ogg
new file mode 100644
index 00000000000..6ab9cd9421a
Binary files /dev/null and b/sound/machines/dotprinter.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 01239aa531c..3cbe848dd61 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -3905,6 +3905,7 @@
#include "code\modules\wiremod\components\action\light.dm"
#include "code\modules\wiremod\components\action\mmi.dm"
#include "code\modules\wiremod\components\action\pathfind.dm"
+#include "code\modules\wiremod\components\action\printer.dm"
#include "code\modules\wiremod\components\action\pull.dm"
#include "code\modules\wiremod\components\action\radio.dm"
#include "code\modules\wiremod\components\action\soundemitter.dm"
diff --git a/tgui/packages/tgui/interfaces/PaperSheet.js b/tgui/packages/tgui/interfaces/PaperSheet.js
index f2bbd30ae76..9878eaab243 100644
--- a/tgui/packages/tgui/interfaces/PaperSheet.js
+++ b/tgui/packages/tgui/interfaces/PaperSheet.js
@@ -4,6 +4,7 @@
* @author Original WarlockD (https://github.com/warlockd)
* @author Changes stylemistake
* @author Changes ThePotato97
+ * @author Changes Ghommie
* @license MIT
*/
@@ -235,7 +236,6 @@ const PaperSheetView = (props, context) => {
height="100%" >
{
+ const out = { text: text };
+ // check if we are adding to paper, if not
+ // we still have to check if someone entered something
+ // into the fields
+ value = value.trim();
+ if (value.length > 0) {
+ // First lets make sure it ends in a new line
+ value += value[value.length] === "\n" ? " \n" : "\n \n";
+ // Second, we sanitize the text of html
+ const sanitized_text = sanitizeText(value);
+ const signed_text = signDocument(sanitized_text, color, user_name);
+ // Third we replace the [__] with fields as markedjs fucks them up
+ const fielded_text = createFields(
+ signed_text, font, 12, color, field_counter);
+ // Fourth, parse the text using markup
+ const formatted_text = run_marked_default(fielded_text.text);
+ // Fifth, we wrap the created text in the pin color, and font.
+ // crayon is bold ( tags), maybe make fountain pin italic?
+ const fonted_text = setFontinText(
+ formatted_text, font, color, is_crayon);
+ out.text += fonted_text;
+ out.field_counter = fielded_text.counter;
+ }
+ if (do_fields) {
+ // finally we check all the form fields to see
+ // if any data was entered by the user and
+ // if it was return the data and modify the text
+ const final_processing = checkAllFields(
+ out.text, font, color, user_name, is_crayon);
+ out.text = final_processing.text;
+ out.form_fields = final_processing.fields;
+ }
+ return out;
+};
+
// ugh. So have to turn this into a full
// component too if I want to keep updates
// low and keep the weird flashing down
@@ -366,58 +412,24 @@ class PaperSheetEdit extends Component {
this.state = {
previewSelected: "Preview",
old_text: props.value || "",
+ counter: props.counter || 0,
textarea_text: "",
combined_text: props.value || "",
};
}
- // This is the main rendering part, this creates the html from marked text
- // as well as the form fields
- createPreview(value, do_fields = false) {
+ createPreviewFromData(value, do_fields = false) {
const { data } = useBackend(this.context);
- const {
- text,
- pen_color,
- pen_font,
- is_crayon,
- field_counter,
- edit_usr,
- } = data;
- const out = { text: text };
- // check if we are adding to paper, if not
- // we still have to check if someone entered something
- // into the fields
- value = value.trim();
- if (value.length > 0) {
- // First lets make sure it ends in a new line
- value += value[value.length] === "\n" ? " \n" : "\n \n";
- // Second, we sanitize the text of html
- const sanitized_text = sanitizeText(value);
- const signed_text = signDocument(sanitized_text, pen_color, edit_usr);
- // Third we replace the [__] with fields as markedjs fucks them up
- const fielded_text = createFields(
- signed_text, pen_font, 12, pen_color, field_counter);
- // Fourth, parse the text using markup
- const formatted_text = run_marked_default(fielded_text.text);
- // Fifth, we wrap the created text in the pin color, and font.
- // crayon is bold ( tags), maybe make fountain pin italic?
- const fonted_text = setFontinText(
- formatted_text, pen_font, pen_color, is_crayon);
- out.text += fonted_text;
- out.field_counter = fielded_text.counter;
- }
- if (do_fields) {
- // finally we check all the form fields to see
- // if any data was entered by the user and
- // if it was return the data and modify the text
- const final_processing = checkAllFields(
- out.text, pen_font, pen_color, edit_usr, is_crayon);
- out.text = final_processing.text;
- out.form_fields = final_processing.fields;
- }
- return out;
+ return createPreview(value,
+ this.state.old_text,
+ do_fields,
+ this.state.counter,
+ data.pen_color,
+ data.pen_font,
+ data.edit_usr,
+ data.is_crayon,
+ );
}
-
onInputHandler(e, value) {
if (value !== this.state.textarea_text) {
const combined_length = this.state.old_text.length
@@ -438,19 +450,21 @@ class PaperSheetEdit extends Component {
}
this.setState(() => ({
textarea_text: value,
- combined_text: this.createPreview(value),
+ combined_text: this.createPreviewFromData(value),
}));
}
}
// the final update send to byond, final upkeep
finalUpdate(new_text) {
const { act } = useBackend(this.context);
- const final_processing = this.createPreview(new_text, true);
+ const final_processing = this.createPreviewFromData(new_text, true);
act('save', final_processing);
this.setState(() => { return {
textarea_text: "",
previewSelected: "save",
combined_text: final_processing.text,
+ old_text: final_processing.text,
+ counter: final_processing.field_counter,
}; });
// byond should switch us to readonly mode from here
}
@@ -489,7 +503,7 @@ class PaperSheetEdit extends Component {
const new_state = {
previewSelected: "Preview",
textarea_text: this.state.textarea_text,
- combined_text: this.createPreview(
+ combined_text: this.createPreviewFromData(
this.state.textarea_text).text,
};
return new_state;
@@ -515,7 +529,7 @@ class PaperSheetEdit extends Component {
const new_state = {
previewSelected: "confirm",
textarea_text: this.state.textarea_text,
- combined_text: this.createPreview(
+ combined_text: this.createPreviewFromData(
this.state.textarea_text).text,
};
return new_state;
@@ -566,7 +580,33 @@ export const PaperSheet = (props, context) => {
sizeX,
sizeY,
name,
+ add_text,
+ add_font,
+ add_color,
+ add_sign,
+ field_counter,
} = data;
+ // some features can add text to a paper sheet outside of this ui
+ // we need to parse, sanitize and add any of it to the text value.
+ const values = { text: text, field_counter: field_counter };
+ if (add_text) {
+ for (let index = 0; index < add_text.length; index++) {
+ const used_color = add_color[index];
+ const used_font = add_font[index];
+ const used_sign = add_sign[index];
+ const processing = createPreview(
+ add_text[index],
+ values.text,
+ false,
+ values.field_counter,
+ used_color,
+ used_font,
+ used_sign
+ );
+ values.text = processing.text;
+ values.field_counter = processing.field_counter;
+ }
+ }
const stamp_list = !stamps
? []
: stamps;
@@ -575,14 +615,15 @@ export const PaperSheet = (props, context) => {
case 0:
return (
);
case 1:
return (
{
case 2:
return (
);