Skip to content

Commit

Permalink
Paper fixes and updates (tgstation#51731)
Browse files Browse the repository at this point in the history
* Updates to alot of paper.

More clean up and forms work well.  Preview bug fixed as well.

* Update tgui.bundle.js
  • Loading branch information
WarlockD authored Jun 21, 2020
1 parent e33eb92 commit 750a868
Show file tree
Hide file tree
Showing 5 changed files with 391 additions and 307 deletions.
232 changes: 137 additions & 95 deletions code/modules/paperwork/paper.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,52 @@
#define MODE_READING 0
#define MODE_WRITING 1
#define MODE_STAMPING 2


/**
** This is a custom ui state. All it really does is keep track of pen
** being used and if they are editing it or not. This way we can keep
** the data with the ui rather than on the paper
**/
/datum/ui_state/default/paper_state
/// What edit mode we are in and who is
/// writing on it right now
var/edit_mode = MODE_READING
/// Setup for writing to a sheet
var/pen_color = "black"
var/pen_font = ""
var/is_crayon = FALSE
/// Setup for stamping a sheet
// Why not the stamp obj? I have no idea
// what happens to states out of scope so
// don't want to put instances in this
var/stamp_icon_state = ""
var/stamp_name = ""
var/stamp_class = ""


/datum/ui_state/default/paper_state/proc/copy_from(datum/ui_state/default/paper_state/from)
switch(from.edit_mode)
if(MODE_READING)
edit_mode = MODE_READING
if(MODE_WRITING)
edit_mode = MODE_WRITING
pen_color = from.pen_color
pen_font = from.pen_font
is_crayon = from.is_crayon
if(MODE_STAMPING)
edit_mode = MODE_STAMPING
stamp_icon_state = from.stamp_icon_state
stamp_class = from.stamp_class
stamp_name = from.stamp_name


/**
** 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
** paper and getting rid of that crashing bug
**/
/obj/item/paper
var/static/regex/sign_regex = regex("%s(?:ign)?(?=\\s|$)", "igm")
name = "paper"
gender = NEUTER
icon = 'icons/obj/bureaucracy.dmi'
Expand Down Expand Up @@ -51,23 +90,31 @@
var/contact_poison // Reagent ID to transfer on contact
var/contact_poison_volume = 0

// ui stuff
var/ui_x = 600
var/ui_y = 800
// Ok, so WHY are we caching the ui's?
// Since we are not using autoupdate we
// need some way to update the ui's of
// other people looking at it and if
// its been updated. Yes yes, lame
// but canot be helped. However by
// doing it this way, we can see
// live updates and have multipule
// people look at it
var/list/viewing_ui = list()


/// When the sheet can be "filled out"
/// This is an associated list
var/list/form_fields = null
var/list/form_fields = list()
var/field_counter = 1
/// What edit mode we are in and who is
/// writing on it right now
var/edit_mode = MODE_READING
var/mob/living/edit_usr = null
/// Setup for writing to a sheet
var/pen_color = "black"
var/pen_font = ""
var/is_crayon = FALSE
/// Setup for stamping a sheet
var/obj/item/stamp/current_stamp = null
var/stamp_class = null

/obj/item/paper/Destroy()
close_all_ui()
stamps = null
stamped = null
. = ..()

/**
** This proc copies this sheet of paper to a new
Expand Down Expand Up @@ -160,10 +207,6 @@


/obj/item/paper/attack_self(mob/user)
if(edit_usr == user)
// we are shifting out of editing mode
edit_mode = MODE_READING
edit_usr = null
if(rigged && (SSevents.holidays && SSevents.holidays[APRIL_FOOLS]))
if(!spam_flag)
spam_flag = TRUE
Expand All @@ -190,47 +233,49 @@
return user.can_read(src) // checks if the user can read.


/**
** This creates the ui, since we are using a custom state but not much else
** just makes it easyer to make it. Also we make a custom ui_key as I am
** not sure how tgui handles many producers?
**/
/obj/item/paper/proc/create_ui(mob/user, datum/ui_state/default/paper_state/state)
ui_interact(user, "main", null, FALSE, null, state)


/obj/item/paper/attackby(obj/item/P, mob/living/carbon/human/user, params)
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
to_chat(user, "<span class='warning'>This sheet of paper is full!</span>")
return
if(edit_mode != MODE_READING)
to_chat(user, "<span class='warning'>[edit_usr] is already working on this sheet!</span>")
return

edit_mode = MODE_WRITING
edit_usr = user
var/datum/ui_state/default/paper_state/state = new
state.edit_mode = MODE_WRITING
// should a crayon be in the same subtype as a pen? How about a brush or charcoal?
// TODO: Convert all writing stuff to one type, /obj/item/art_tool maybe?
is_crayon = istype(P, /obj/item/toy/crayon);
if(is_crayon)
state.is_crayon = istype(P, /obj/item/toy/crayon);
if(state.is_crayon)
var/obj/item/toy/crayon/PEN = P
pen_font = CRAYON_FONT
pen_color = PEN.paint_color
state.pen_font = CRAYON_FONT
state.pen_color = PEN.paint_color
else
var/obj/item/pen/PEN = P
pen_font = PEN.font
pen_color = PEN.colour
state.pen_font = PEN.font
state.pen_color = PEN.colour

ui_interact(user)
create_ui(user, state)
return
else if(istype(P, /obj/item/stamp))

if(edit_mode != MODE_READING)
to_chat(user, "<span class='warning'>[edit_usr] is already working on this sheet!</span>")
return

edit_mode = MODE_STAMPING // we are read only becausse the sheet is full
edit_usr = user
current_stamp = P
var/datum/ui_state/default/paper_state/state = new
state.edit_mode = MODE_STAMPING // we are read only becausse the sheet is full
state.stamp_icon_state = P.icon_state

var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/simple/paper)
stamp_class = sheet.icon_class_name(P.icon_state)
state.stamp_class = sheet.icon_class_name(P.icon_state)

to_chat(user, "<span class='notice'>You ready your stamp over the paper! </span>")

ui_interact(user)
create_ui(user, state)
return /// Normaly you just stamp, you don't need to read the thing
else if(P.get_temperature())
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10))
Expand All @@ -243,13 +288,13 @@

user.dropItemToGround(src)
user.visible_message("<span class='danger'>[user] lights [src] ablaze with [P]!</span>", "<span class='danger'>You light [src] on fire!</span>")
close_all_ui()
fire_act()
else
if(edit_mode != MODE_READING)
to_chat(user, "You look at the sheet while [edit_usr] edits it")
else
edit_mode = MODE_READING
ui_interact(user) // The other ui will be created with just read mode outside of this
// cut paper? the sky is the limit!
var/datum/ui_state/default/paper_state/state = new
state.edit_mode = MODE_READING
create_ui(user, state) // The other ui will be created with just read mode outside of this

. = ..()

Expand All @@ -265,67 +310,71 @@
..()
cut_overlay("paper_onfire_overlay")

/obj/item/paper/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
/obj/item/paper/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/default/paper_state/state = new)
ui_key = "main-[REF(user)]"
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/paper)
assets.send(user)
// The x size is because we double the width for the editor
ui = new(user, src, ui_key, "PaperSheet", name, ui_x, ui_y, master_ui, state)
ui.set_autoupdate(FALSE)
viewing_ui[user] = ui
ui.open()
else
var/datum/ui_state/default/paper_state/last_state = ui.state
if(last_state)
last_state.copy_from(state)
else
ui.state = state


/obj/item/paper/ui_close(mob/user)
/// close the editing window and change the mode
if(edit_usr != null && user == edit_usr)
edit_mode = MODE_READING
edit_usr = null
current_stamp = null
stamp_class = null

viewing_ui[user] = null
. = ..()


/obj/item/paper/proc/ui_force_close()
var/datum/tgui/ui = SStgui.try_update_ui(usr, src, "main");
if(ui)
ui.close()


/obj/item/paper/proc/ui_update()
var/datum/tgui/ui = SStgui.try_update_ui(usr, src, "main");
if(ui)
// Again, we have to do this as autoupdate is off
/obj/item/paper/proc/update_all_ui()
for(var/datum/tgui/ui in viewing_ui)
ui.update()

// Again, we have to do this as autoupdate is off
/obj/item/paper/proc/close_all_ui()
for(var/datum/tgui/ui in viewing_ui)
ui.close()
viewing_ui = list()

/obj/item/paper/ui_data(mob/user)
var/list/data = list()

var/datum/tgui/ui = viewing_ui[user]
var/datum/ui_state/default/paper_state/state = ui.state

// Should all this go in static data and just do a forced update?
data["text"] = info
data["max_length"] = MAX_PAPER_LENGTH
data["paper_state"] = icon_state /// TODO: show the sheet will bloodied or crinkling?
data["paper_color"] = !color || color == "white" ? "#FFFFFF" : color // color might not be set
data["stamps"] = stamps

if(edit_usr == null || user != edit_usr)
data["edit_mode"] = MODE_READING /// Eveyone else is just an observer
else
data["edit_mode"] = edit_mode
data["edit_mode"] = state.edit_mode
data["edit_usr"] = "[ui.user]";

// pen info for editing
data["is_crayon"] = is_crayon
data["pen_font"] = pen_font
data["pen_color"] = pen_color

data["is_crayon"] = state.is_crayon
data["pen_font"] = state.pen_font
data["pen_color"] = state.pen_color
// stamping info for..stamping
data["stamp_class"] = stamp_class
data["stamp_class"] = state.stamp_class

data["field_counter"] = field_counter
data["form_fields"] = form_fields

return data


/obj/item/paper/ui_act(action, params)
/obj/item/paper/ui_act(action, params, datum/tgui/ui, datum/ui_state/default/paper_state/state)
if(..())
return
switch(action)
Expand All @@ -338,23 +387,23 @@
stamps = new/list()
if(stamps.len < MAX_PAPER_STAMPS)
// I hate byond when dealing with freaking lists
stamps += list(list(stamp_class, stamp_x, stamp_y,stamp_r)) /// WHHHHY
stamps += list(list(state.stamp_class, stamp_x, stamp_y,stamp_r)) /// WHHHHY

/// This does the overlay stuff
if (isnull(stamped))
stamped = new/list()
if(stamped.len < MAX_PAPER_STAMPS_OVERLAYS)
var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[current_stamp.icon_state]")
var/mutable_appearance/stampoverlay = mutable_appearance('icons/obj/bureaucracy.dmi', "paper_[state.stamp_icon_state]")
stampoverlay.pixel_x = rand(-2, 2)
stampoverlay.pixel_y = rand(-3, 2)
add_overlay(stampoverlay)
LAZYADD(stamped, current_stamp.icon_state)
LAZYADD(stamped, state.stamp_icon_state)

edit_usr.visible_message("<span class='notice'>[edit_usr] stamps [src] with [current_stamp]!</span>", "<span class='notice'>You stamp [src] with [current_stamp]!</span>")
ui.user.visible_message("<span class='notice'>[ui.user] stamps [src] with [state.stamp_name]!</span>", "<span class='notice'>You stamp [src] with [state.stamp_name]!</span>")
else
to_chat(usr, pick("You try to stamp but you miss!", "There is no where else you can stamp!"))

ui_update()
update_all_ui()
. = TRUE

if("save")
Expand All @@ -366,29 +415,22 @@
if(paper_len > MAX_PAPER_LENGTH)
// Side note, the only way we should get here is if
// the javascript was modified, somehow, outside of
// byond.
log_paper("[key_name(edit_usr)] writing to paper [name], and overwrote it by [paper_len-MAX_PAPER_LENGTH], aborting")
ui_force_close()
else if(paper_len == 0)
to_chat(usr, pick("Writing block strikes again!", "You forgot to write anthing!"))
ui_force_close()
// byond. but right now we are logging it as
// the generated html might get beyond this limit
log_paper("[key_name(ui.user)] writing to paper [name], and overwrote it by [paper_len-MAX_PAPER_LENGTH]")
if(paper_len == 0)
to_chat(ui.user, pick("Writing block strikes again!", "You forgot to write anthing!"))
else
// Next find the sign marker and replace it with somones sig
// All other processing should of been done in the js module
in_paper = sign_regex.Replace(in_paper, "<font face=\"[SIGNFONT]\"><i>[edit_usr]</i></font>")
// Do the same with form fields
log_paper("[key_name(edit_usr)] writing to paper [name]")
if(info != in_paper)
to_chat(usr, "You have added to your paper masterpiece!");
log_paper("[key_name(ui.user)] writing to paper [name]")
if(info != in_paper)
to_chat(ui.user, "You have added to your paper masterpiece!");
info = in_paper
if(fields && fields.len > 0)
for(var/key in fields) // In case somone %sign in a field
form_fields[key] = sign_regex.Replace(fields[key], "<font face=\"[SIGNFONT]\"><i>[edit_usr]</i></font>")

/// Switch ui to reading mode
edit_mode = MODE_READING
edit_usr = null
ui_update()
for(var/key in fields)
form_fields[key] = fields[key];


update_all_ui()
update_icon()

. = TRUE
Expand Down
Loading

0 comments on commit 750a868

Please sign in to comment.