graffiti 
The graffiti editor: the custom sprite editor's shell on a graffiti piece, whose canvas, tools and history it reuses.
A studio session edits a piece for its owner's library, which its saves go into. A surface session paints live on a wall, a floor or a full-tile window: the piece goes on top of the tile's stack at its first stroke and is recomposited there at a paced cadence, the can is charged once the session ends with paint on the surface, and a piece it didn't save goes in the library's Unfinished slot, ready to resume on that tile.
The editor belongs to the account it is registered to in SSgraffiti.editors, and ends with its window.
Vars | |
| can | The spray can the session was opened from. A surface session paints with it and charges it. |
|---|---|
| composite_cooldown | When the surface may be recomposited again. |
| kind | "studio" or "surface". |
| pending_tab | The spray can tab the window asked for as it closed, for the can to reopen on. |
| piece_colors | Colours added through the picker, which the palette offers beside the paint's own, oldest first. A queue of GRAFFITI_PICKED_COLORS: one more drops the oldest. |
| piece_desc | The piece's description as the library keeps it: the opened piece's, or "" for a new one. A save takes the library piece's current one, which only the Custom Graffiti tab changes. |
| piece_id | The library piece saves go over, or null until the first save. |
| piece_name | The piece's name as the library keeps it: the opened piece's, or "Untitled" for a new one. A save takes the library piece's current one, which only the Custom Graffiti tab changes. |
| placement | The piece's placement on the surface, packed as SSgraffiti keeps it, or null until it has one. The left half of a two-tile piece. |
| placement2 | The right half's placement of a two-tile piece, packed, or null. |
| refusals | Tile -> list(when it is asked again, the notice it gave) for each tile that refused the piece's paint: "0" for a one-tile piece, "1" and "2" for a two-tile piece's halves. |
| saved_encoding | json_encode() of the piece as opened or last saved, which unsaved changes are told by. While the editor is built, the piece it opens. |
| sent_views | Layer id -> list(the codes of its view the window was last sent, their serial), so an update sends a view only once it changes. Null for a window that has none yet. |
| spray_cooldown | When the last spray sound ends. |
| started | When the session started. |
| surface | The wall, floor or window tile a surface session paints: the left tile of a two-tile piece. |
| view_serial | The serial the codes sent last went under. New codes take the next, so a serial never comes twice. |
Procs | |
| New | Opens a piece, or a blank one, for a session. |
| apply_live | Puts the piece on its surface as it is now, the first time on top of each tile's stack, and counts the composite against the painter's pace and its time against every painter's (SSgraffiti's spend_composite()). An unpainted piece leaves the surface as it is. While every tile waits out a refusal, the composite only shows that refusal again, flattening nothing and costing no pace. |
| can_edit | Whether a mob may act on this editor: the account it is registered to, until the session ends. |
| can_gone | Lets go of the spray can as it is deleted. A surface session without it ends at its next check. |
| can_hide_parts | Graffiti has no body parts to hide. |
| composite_due | Whether the surface may be recomposited now: the painter's pace allows costly work, the last composite was GRAFFITI_COMPOSITE_SPACING ago, or GRAFFITI_COMPOSITE_SLOW_SPACING once the round's GRAFFITI_COMPOSITE_BUDGET is spent, and it is the editor's turn among every painter's composites (SSgraffiti's composite_turn()). |
| costly_work_due | A due composite is costly work, which SScustom_sprite_work keeps within its overrun budget. Waiting strokes bring one in the run that drains them. |
| create_preview_body | Graffiti draws on no body: the window composes its own preview. |
| create_workspace | A one-view workspace of uniform layers in colours that may be translucent. |
| current_package | Graffiti saves pieces, never style packages. |
| draft_edited | Marks the draft changed, as every window edit does. A surface session asks for its surface to be recomposited. |
| draw_waiting_views | No views wait to be drawn: graffiti has one view and no server pictures. |
| editor_act | Handles the graffiti window's own actions and refuses the hair editor's ones that mean nothing here, such as hair, guides, previews, tints, style files and views. A surface session whose painter can no longer paint ends first. |
| emissives_allowed | Any layer may glow. |
| end_session | Ends the session and closes its window. The strokes still waiting go in first. A surface session leaves its piece on the surface through leave_surface(). A piece that changed since it was opened or saved goes in the library's Unfinished slot, under the name and description its library piece has (take_library_names()), resumable on the surface while it is still there. A pane loosened under the piece drops all of its paint first, both halves of a two-tile piece, and the piece goes in the slot as a plain draft, with no tile to resume on. |
| end_surface | Ends a surface session on its surface. A kept piece stays there through leave_surface(), unless a pane loosened under it, which drops all of its paint first. Either way the tiles' decals let go of their merges. |
| initial_package | The piece being opened, which the constructor keeps in saved_encoding until the workspace is built. |
| leave_surface | Leaves a surface session's piece on the surface as the session ends: composited one last time, without an empty piece or a half of a two-tile piece left without paint. With paint left, the can is charged once, never refused, unless the session resumed a draft and changed nothing, and each tile the piece is on is marked as the painter's work and the painter given the graffiti achievement, as for a finished paint job. |
| place_art | Puts the piece, flattened, on each of its tiles (place_tile()). |
| place_tile | Puts one tile's art of the piece on the surface: as new art for the tile's placement, or as a new placement once the art has paint. The halves of a two-tile piece share one placement id. A tile that refuses the paint, as a full map of connected painters' graffiti does, isn't asked again for GRAFFITI_PLACE_RETRY; meanwhile its refusal shows again, and a placement it has keeps its old art. |
| rebuild_resources | There are no guides or previews to build, so the editor is always ready. |
| refresh_preview | The window previews graffiti itself; nothing is drawn on the server. |
| run_deferred_work | Applies the strokes still waiting, then recomposites a surface session's surface when it is due, then does the base editor's work. |
| sample_paint | The eyedropper: makes a layer's pixel the brush colour, alpha and all. |
| save_drawing | Saves the piece into its owner's library: over its library piece, or as a new one the first time or when asked. An unchanged piece is acknowledged without writing, and writes wait for graffiti_library_write_due(). The piece keeps the name and description its library piece has (take_library_names()), so a rename alone writes nothing. |
| session_problem | Returns why a surface session can't go on: its painter must stay beside the surface, holding the uncapped can and able to use it, the surface must still take graffiti, the piece must still be on it, and the session must not have run past GRAFFITI_SESSION_LIMIT. |
| surface_problem | Returns why a surface session's surface can't take its paint any more: it no longer takes graffiti, or the piece is gone from it. |
| take_library_names | Takes the name and description the library holds for the piece, which the Custom Graffiti tab may have changed since it was opened or saved. The piece as last saved takes them too, so a rename alone isn't an unsaved change. |
| take_pending_tab | Returns the spray can tab the window asked for as it closed, once. |
| tile_background | Returns the graffiti a tile shows beneath this session's piece, which the window draws under the canvas. A stack the decal keeps no merge of, as one shown from its sheet, is merged here, as the session opens, which GRAFFITI_START_COOLDOWN paces, and the decal keeps the merge while the session paints there. |
| ui_act | Takes the window's request for every view (canvasResync), which the base editor leaves: the window lacks a view it was sent, as after a reload, or one carried by an update it never drew. The next update brings them all: push()'s at once, or, while strokes wait for the budget and the base editor takes nothing but strokes, the drain's, so no update shows the canvas without the strokes that wait. |
| ui_close | Closing the window ends the session. A window closed for a spray can tab hands back to the can's window on it. |
| ui_interact | Opens the window, or refreshes the open one. |
Var Details
can 
The spray can the session was opened from. A surface session paints with it and charges it.
composite_cooldown 
When the surface may be recomposited again.
kind 
"studio" or "surface".
pending_tab 
The spray can tab the window asked for as it closed, for the can to reopen on.
piece_colors 
Colours added through the picker, which the palette offers beside the paint's own, oldest first. A queue of GRAFFITI_PICKED_COLORS: one more drops the oldest.
piece_desc 
The piece's description as the library keeps it: the opened piece's, or "" for a new one. A save takes the library piece's current one, which only the Custom Graffiti tab changes.
piece_id 
The library piece saves go over, or null until the first save.
piece_name 
The piece's name as the library keeps it: the opened piece's, or "Untitled" for a new one. A save takes the library piece's current one, which only the Custom Graffiti tab changes.
placement 
The piece's placement on the surface, packed as SSgraffiti keeps it, or null until it has one. The left half of a two-tile piece.
placement2 
The right half's placement of a two-tile piece, packed, or null.
refusals 
Tile -> list(when it is asked again, the notice it gave) for each tile that refused the piece's paint: "0" for a one-tile piece, "1" and "2" for a two-tile piece's halves.
saved_encoding 
json_encode() of the piece as opened or last saved, which unsaved changes are told by. While the editor is built, the piece it opens.
sent_views 
Layer id -> list(the codes of its view the window was last sent, their serial), so an update sends a view only once it changes. Null for a window that has none yet.
spray_cooldown 
When the last spray sound ends.
started 
When the session started.
surface 
The wall, floor or window tile a surface session paints: the left tile of a two-tile piece.
view_serial 
The serial the codes sent last went under. New codes take the next, so a serial never comes twice.
Proc Details
New
Opens a piece, or a blank one, for a session.
Arguments:
- preferences: The owner's preferences, which pace the editor's costly work and keep their saved swatches, or null.
- piece: The canonical piece to open, a copy the editor may keep, or null for a blank one.
- piece_id: The library piece it is, or null.
- can: The spray can it was opened from, or null.
- surface: The wall, floor or window tile to paint live, or null for a studio session.
apply_live
Puts the piece on its surface as it is now, the first time on top of each tile's stack, and counts the composite against the painter's pace and its time against every painter's (SSgraffiti's spend_composite()). An unpainted piece leaves the surface as it is. While every tile waits out a refusal, the composite only shows that refusal again, flattening nothing and costing no pace.
Arguments:
- user: The painter, whose ckey and character name new placements carry.
can_edit
Whether a mob may act on this editor: the account it is registered to, until the session ends.
Arguments:
- user: The mob.
Returns:
- TRUE/FALSE
can_gone
Lets go of the spray can as it is deleted. A surface session without it ends at its next check.
can_hide_parts
Graffiti has no body parts to hide.
composite_due
Whether the surface may be recomposited now: the painter's pace allows costly work, the last composite was GRAFFITI_COMPOSITE_SPACING ago, or GRAFFITI_COMPOSITE_SLOW_SPACING once the round's GRAFFITI_COMPOSITE_BUDGET is spent, and it is the editor's turn among every painter's composites (SSgraffiti's composite_turn()).
Returns:
- TRUE/FALSE
costly_work_due
A due composite is costly work, which SScustom_sprite_work keeps within its overrun budget. Waiting strokes bring one in the run that drains them.
create_preview_body
Graffiti draws on no body: the window composes its own preview.
create_workspace
A one-view workspace of uniform layers in colours that may be translucent.
current_package
Graffiti saves pieces, never style packages.
draft_edited
Marks the draft changed, as every window edit does. A surface session asks for its surface to be recomposited.
draw_waiting_views
No views wait to be drawn: graffiti has one view and no server pictures.
editor_act
Handles the graffiti window's own actions and refuses the hair editor's ones that mean nothing here, such as hair, guides, previews, tints, style files and views. A surface session whose painter can no longer paint ends first.
Arguments:
- action: The action.
- params: Its params, as the window sent them.
- ui: The window.
Returns:
- TRUE/FALSE: Whether the window updates.
- null: The base editor handles the action: strokes and history, clearing a layer, notices and saved swatches.
emissives_allowed
Any layer may glow.
end_session
Ends the session and closes its window. The strokes still waiting go in first. A surface session leaves its piece on the surface through leave_surface(). A piece that changed since it was opened or saved goes in the library's Unfinished slot, under the name and description its library piece has (take_library_names()), resumable on the surface while it is still there. A pane loosened under the piece drops all of its paint first, both halves of a two-tile piece, and the piece goes in the slot as a plain draft, with no tile to resume on.
Arguments:
- user: The owner.
- keep: Whether the piece is kept. An admin deleting its paint ends the session with nothing kept: no last composite, no charge and no Unfinished piece.
end_surface
Ends a surface session on its surface. A kept piece stays there through leave_surface(), unless a pane loosened under it, which drops all of its paint first. Either way the tiles' decals let go of their merges.
Arguments:
- user: The painter.
- piece: The piece as it ends, or null when nothing is painted.
- keep: Whether the piece is kept, as end_session() takes it.
Returns:
- list: Where the Unfinished piece resumes: the map, its left tile's anchor and its placement id.
- null: It resumes nowhere.
initial_package
The piece being opened, which the constructor keeps in saved_encoding until the workspace is built.
leave_surface
Leaves a surface session's piece on the surface as the session ends: composited one last time, without an empty piece or a half of a two-tile piece left without paint. With paint left, the can is charged once, never refused, unless the session resumed a draft and changed nothing, and each tile the piece is on is marked as the painter's work and the painter given the graffiti achievement, as for a finished paint job.
Arguments:
- user: The painter.
- piece: The piece as it ends, or null for no last composite: nothing is painted, or a pane loosened under it.
Returns:
- list: The placements the piece left on the surface, packed.
place_art
Puts the piece, flattened, on each of its tiles (place_tile()).
Arguments:
- user: The painter.
- art: The flattened piece.
- decoded: The art's graffiti_art_decode().
- evicted: Filled with the ids of the painter's own placements a new one took past their caps.
place_tile
Puts one tile's art of the piece on the surface: as new art for the tile's placement, or as a new placement once the art has paint. The halves of a two-tile piece share one placement id. A tile that refuses the paint, as a full map of connected painters' graffiti does, isn't asked again for GRAFFITI_PLACE_RETRY; meanwhile its refusal shows again, and a placement it has keeps its old art.
Arguments:
- packed: The tile's placement so far, packed, or null.
- tile: The tile.
- art: The tile's art.
- half: 1 or 2 for the left or right half of a two-tile piece, else 0.
- user: The painter.
- decoded: The art's graffiti_art_decode().
- evicted: Filled with the ids of the painter's own placements a new one took past their caps, for apply_live() to tell the painter once.
Returns:
- text: The tile's placement now, packed. One that is gone stays as it was, so the session sees it is gone, and so does one refused its new art.
- null: The tile has none: its art has no paint yet, or the surface refused it.
rebuild_resources
There are no guides or previews to build, so the editor is always ready.
refresh_preview
The window previews graffiti itself; nothing is drawn on the server.
run_deferred_work
Applies the strokes still waiting, then recomposites a surface session's surface when it is due, then does the base editor's work.
Returns:
- TRUE/FALSE: FALSE while the composite or strokes have to wait, so the subsystem keeps the editor queued.
sample_paint
The eyedropper: makes a layer's pixel the brush colour, alpha and all.
Arguments:
- column: The pixel's column.
- row: Its row, from the top.
- id: The layer to sample, or anything else for the topmost layer painted there.
Returns:
- TRUE/FALSE: Whether a colour was taken.
save_drawing
Saves the piece into its owner's library: over its library piece, or as a new one the first time or when asked. An unchanged piece is acknowledged without writing, and writes wait for graffiti_library_write_due(). The piece keeps the name and description its library piece has (take_library_names()), so a rename alone writes nothing.
Arguments:
- user: The owner.
- copy: Whether to save a new piece rather than over this one.
Returns:
- TRUE/FALSE: Whether the library holds the piece as it is now. On FALSE the status line says why.
session_problem
Returns why a surface session can't go on: its painter must stay beside the surface, holding the uncapped can and able to use it, the surface must still take graffiti, the piece must still be on it, and the session must not have run past GRAFFITI_SESSION_LIMIT.
Arguments:
- user: The painter.
Returns:
- text: Why the session ends, to tell the painter.
- null: It goes on, or it is a studio session.
surface_problem
Returns why a surface session's surface can't take its paint any more: it no longer takes graffiti, or the piece is gone from it.
Returns:
- text: Why the session ends, to tell the painter.
- null: The surface still takes it.
take_library_names
Takes the name and description the library holds for the piece, which the Custom Graffiti tab may have changed since it was opened or saved. The piece as last saved takes them too, so a rename alone isn't an unsaved change.
Arguments:
- library: The owner's library, or null.
take_pending_tab
Returns the spray can tab the window asked for as it closed, once.
Returns:
- text: "stencils" or "graffiti".
- null: The window didn't ask for one.
tile_background
Returns the graffiti a tile shows beneath this session's piece, which the window draws under the canvas. A stack the decal keeps no merge of, as one shown from its sheet, is merged here, as the session opens, which GRAFFITI_START_COOLDOWN paces, and the decal keeps the merge while the session paints there.
Arguments:
- tile: The tile.
- packed: This session's placement on it, packed, or null.
Returns:
- list: The merged art of the pieces beneath this session's, or of the whole stack before it has one there.
- null: Nothing else shows there, or someone has painted over this session's piece.
ui_act
Takes the window's request for every view (canvasResync), which the base editor leaves: the window lacks a view it was sent, as after a reload, or one carried by an update it never drew. The next update brings them all: push()'s at once, or, while strokes wait for the budget and the base editor takes nothing but strokes, the drain's, so no update shows the canvas without the strokes that wait.
Arguments:
- action: The action.
- params: Its params, as the window sent them.
- ui: The window.
- state: The window's state.
Returns:
- TRUE/FALSE: Whether the window updates at once.
ui_close
Closing the window ends the session. A window closed for a spray can tab hands back to the can's window on it.
ui_interact
Opens the window, or refreshes the open one.
Arguments:
- user: The owner.
- ui: The open window, when tgui refreshes it.