diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm
index 12e5bfc549e..7499bc46a0d 100644
--- a/code/game/objects/effects/decals/crayon.dm
+++ b/code/game/objects/effects/decals/crayon.dm
@@ -5,7 +5,6 @@
plane = DIRTY_PLANE
layer = DIRTY_LAYER
anchored = TRUE
-
var/art_type
var/art_color
var/art_shade
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index 5b8ef6ced41..0971ca95a6b 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -69,7 +69,7 @@
shadeColour = new_colour
return
-/obj/item/pen/crayon/afterattack(atom/target, mob/user, proximity)
+/obj/item/pen/crayon/afterattack(atom/target, mob/user, proximity, click_parameters)
if(!proximity) return
if(istype(target,/turf/simulated/floor))
var/drawtype = tgui_input_list(user, "Choose what you'd like to draw.", "Crayon scribbles", list("graffiti","rune","letter","arrow"))
@@ -99,7 +99,16 @@
return
to_chat(user, "You start drawing an arrow on the [target.name].")
if(instant || do_after(user, 50))
- new /obj/effect/decal/cleanable/crayon(target,colour,shadeColour,drawtype)
+ var/list/mouse_control = params2list(click_parameters)
+ var/p_x = 0
+ var/p_y = 0
+ if(mouse_control["icon-x"])
+ p_x = text2num(mouse_control["icon-x"]) - 16
+ if(mouse_control["icon-y"])
+ p_y = text2num(mouse_control["icon-y"]) - 16
+ var/atom/new_graffiti = new /obj/effect/decal/cleanable/crayon(target,colour,shadeColour,drawtype)
+ new_graffiti.pixel_x = p_x
+ new_graffiti.pixel_y = p_y
to_chat(user, "You finish drawing.")
var/msg = "[user.client.key] ([user]) has drawn [drawtype] (with [src]) at [target.x],[target.y],[target.z]."
diff --git a/code/game/turfs/simulated/floor_attackby.dm b/code/game/turfs/simulated/floor_attackby.dm
index f561843e1d5..6dce78fb477 100644
--- a/code/game/turfs/simulated/floor_attackby.dm
+++ b/code/game/turfs/simulated/floor_attackby.dm
@@ -1,4 +1,4 @@
-/turf/simulated/floor/attackby(var/obj/item/C, var/mob/user)
+/turf/simulated/floor/attackby(var/obj/item/C, var/mob/user, attack_modifier, click_parameters)
if(!C || !user)
return 0
@@ -14,7 +14,7 @@
if(isliving(user))
var/mob/living/L = user
if(L.a_intent == I_HELP)
- if(try_graffiti(L, C)) // back by unpopular demand
+ try_graffiti(L, C, click_parameters) // back by unpopular demand
return
*/
diff --git a/code/game/turfs/simulated/wall_attacks.dm b/code/game/turfs/simulated/wall_attacks.dm
index 650d3b92623..ec57b041496 100644
--- a/code/game/turfs/simulated/wall_attacks.dm
+++ b/code/game/turfs/simulated/wall_attacks.dm
@@ -134,14 +134,14 @@
return success_smash(user)
return fail_smash(user)
-/turf/simulated/wall/attackby(var/obj/item/W, var/mob/user)
+/turf/simulated/wall/attackby(var/obj/item/W, var/mob/user, attack_modifier, click_parameters)
user.setClickCooldown(user.get_attack_speed(W))
/*
//As with the floors, only this time it works AND tries pushing the wall after it's done.
if(!construction_stage && user.a_intent == I_HELP)
- if(try_graffiti(user,W))
+ if(try_graffiti(user,W, click_parameters))
return
*/
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 9b552ee4534..a15e738ed53 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -362,7 +362,7 @@
/turf/proc/can_engrave()
return FALSE
-/turf/proc/try_graffiti(var/mob/vandal, var/obj/item/tool)
+/turf/proc/try_graffiti(var/mob/vandal, var/obj/item/tool, click_parameters)
if(!tool || !tool.sharp || !can_engrave())
return FALSE
@@ -395,6 +395,18 @@
graffiti.message = message
graffiti.author = vandal.ckey
+ if(click_parameters)
+ var/list/mouse_control = params2list(click_parameters)
+ var/p_x = 0
+ var/p_y = 0
+ if(mouse_control["icon-x"])
+ p_x = text2num(mouse_control["icon-x"]) - 16
+ if(mouse_control["icon-y"])
+ p_y = text2num(mouse_control["icon-y"]) - 16
+
+ graffiti.pixel_x = p_x
+ graffiti.pixel_y = p_y
+
if(lowertext(message) == "elbereth")
to_chat(vandal, span_notice("You feel much safer."))
diff --git a/code/modules/persistence/datum/persistence_datum.dm b/code/modules/persistence/datum/persistence_datum.dm
index 0f35c7af3d9..ddbe532186c 100644
--- a/code/modules/persistence/datum/persistence_datum.dm
+++ b/code/modules/persistence/datum/persistence_datum.dm
@@ -126,6 +126,9 @@
. += "
|
"
for(var/thing in my_tracks)
+ var/data = GetAdminDataStringFor(thing, can_modify, user)
+ if(!isnull(data))
+ . += "[GetAdminDataStringFor(thing, can_modify, user)]
"
. += "[GetAdminDataStringFor(thing, can_modify, user)]
"
. += "
|
"
diff --git a/code/modules/persistence/effects/filth.dm b/code/modules/persistence/effects/filth.dm
index c1fa359bac0..2a7ea87a412 100644
--- a/code/modules/persistence/effects/filth.dm
+++ b/code/modules/persistence/effects/filth.dm
@@ -2,6 +2,15 @@
name = "filth"
entries_expire_at = 4 // 4 rounds, 24 hours.
var/saves_dirt = TRUE //VOREStation edit
+ has_admin_data = TRUE
+
+/datum/persistent/filth/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user)
+ if(istype(thing, /obj/effect/decal/cleanable/crayon))
+ var/obj/effect/decal/cleanable/crayon/CRAY = thing
+ if(can_modify)
+ return "[thing] | Loc:([CRAY.x],[CRAY.y],[CRAY.z]) P_X: [CRAY.pixel_x] P_Y: [CRAY.pixel_y] Color: [CRAY.art_color] Shading: [CRAY.art_shade] Type: [CRAY.art_type] | Destroy | "
+ return "[thing] | "
+ return null
/datum/persistent/filth/IsValidEntry(var/atom/entry)
. = ..() && entry.invisibility == 0
@@ -9,20 +18,44 @@
/datum/persistent/filth/CheckTokenSanity(var/list/token)
// byond's json implementation is "questionable", and uses types as keys and values without quotes sometimes even though they aren't valid json
token["path"] = istext(token["path"]) ? text2path(token["path"]) : token["path"]
- return ..() && ispath(token["path"]) && (!saves_dirt || isnum(token["dirt"]))
+ token["pixel_x"] = istext(token["pixel_x"]) ? text2num(token["pixel_x"]) : token["pixel_x"]
+ token["pixel_y"] = istext(token["pixel_y"]) ? text2num(token["pixel_y"]) : token["pixel_y"]
+ return ..() && ispath(token["path"]) && (!saves_dirt || isnum(token["dirt"])) && isnum(token["pixel_x"]) && isnum(token["pixel_y"])
/datum/persistent/filth/CheckTurfContents(var/turf/T, var/list/token)
var/_path = token["path"]
- return (locate(_path) in T) ? FALSE : TRUE
+ // return (locate(_path) in T) ? FALSE : TRUE
+ if(!ispath(_path, /obj/effect/decal/cleanable/crayon))
+ return (locate(_path) in T) ? FALSE : TRUE
+
+// Crayon drawings aren't handled in graffiti, so we need to check if someone made "art" seperately from blood, dirt, etc.
+ var/too_much_crayon = 0
+ for(var/obj/effect/decal/cleanable/crayon/C in T)
+ too_much_crayon++
+ if(too_much_crayon >= 5)
+ return FALSE
+ return TRUE
/datum/persistent/filth/CreateEntryInstance(var/turf/creating, var/list/token)
var/_path = token["path"]
if (isspace(creating) || iswall(creating) ||isopenspace(creating))
return
- if (saves_dirt)
- new _path(creating, token["age"]+1, token["dirt"])
+ // new _path(creating, token["age"]+1)
+ var/atom/inst
+ if(ispath(_path, /obj/effect/decal/cleanable/crayon))
+ if(!findtext(token["art_color"], GLOB.is_color) || !findtext(token["art_shade"], GLOB.is_color) || !istext(token["art_type"]))
+ return
+ inst = new _path(creating, token["art_color"], token["art_shade"], token["art_type"], token["age"]+1)
else
- new _path(creating, token["age"]+1)
+ if (saves_dirt)
+ new _path(creating, token["age"]+1, token["dirt"])
+ else
+ new _path(creating, token["age"]+1)
+ if(inst)
+ if(token["pixel_x"])
+ inst.pixel_x = token["pixel_x"]
+ if(token["pixel_y"])
+ inst.pixel_y = token["pixel_y"]
/datum/persistent/filth/GetEntryAge(var/atom/entry)
var/obj/effect/decal/cleanable/filth = entry
@@ -43,3 +76,11 @@
LAZYADDASSOC(., "path", "[GetEntryPath(entry)]")
if (saves_dirt)
LAZYADDASSOC(., "dirt", GetEntryDirt(entry))
+ LAZYADDASSOC(., "pixel_x", "[entry.pixel_x]")
+ LAZYADDASSOC(., "pixel_y", "[entry.pixel_y]")
+
+ if(istype(entry, /obj/effect/decal/cleanable/crayon))
+ var/obj/effect/decal/cleanable/crayon/Inst = entry
+ LAZYADDASSOC(., "art_type", "[Inst.art_type]")
+ LAZYADDASSOC(., "art_color", "[Inst.art_color]")
+ LAZYADDASSOC(., "art_shade", "[Inst.art_shade]")
diff --git a/code/modules/persistence/effects/graffiti.dm b/code/modules/persistence/effects/graffiti.dm
index 0a17787a65f..0f543c82e91 100644
--- a/code/modules/persistence/effects/graffiti.dm
+++ b/code/modules/persistence/effects/graffiti.dm
@@ -3,6 +3,11 @@
entries_expire_at = 4 // This previously was at 50 rounds??? Over 10 days.
has_admin_data = TRUE
+/datum/persistent/graffiti/CheckTokenSanity(var/list/token)
+ token["pixel_x"] = istext(token["pixel_x"]) ? text2num(token["pixel_x"]) : token["pixel_x"]
+ token["pixel_y"] = istext(token["pixel_y"]) ? text2num(token["pixel_y"]) : token["pixel_y"]
+ return ..() && isnum(token["pixel_x"]) && isnum(token["pixel_y"])
+
/datum/persistent/graffiti/GetValidTurf(var/turf/T, var/list/token)
var/turf/checking_turf = ..()
if(istype(checking_turf) && checking_turf.can_engrave())
@@ -20,6 +25,10 @@
var/obj/effect/decal/writing/inst = new /obj/effect/decal/writing(creating, token["age"]+1, token["message"], token["author"])
if(token["icon_state"])
inst.icon_state = token["icon_state"]
+ if(token["pixel_x"])
+ inst.pixel_x = token["pixel_x"]
+ if(token["pixel_y"])
+ inst.pixel_y = token["pixel_y"]
/datum/persistent/graffiti/IsValidEntry(var/atom/entry)
. = ..()
@@ -37,6 +46,8 @@
LAZYADDASSOC(., "author", "[save_graffiti.author ? save_graffiti.author : "unknown"]")
LAZYADDASSOC(., "message", "[save_graffiti.message]")
LAZYADDASSOC(., "icon_state", "[save_graffiti.icon_state]")
+ LAZYADDASSOC(., "pixel_x", "[save_graffiti.pixel_x]")
+ LAZYADDASSOC(., "pixel_y", "[save_graffiti.pixel_y]")
/datum/persistent/graffiti/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user)
var/obj/effect/decal/writing/save_graffiti = thing
diff --git a/code/modules/persistence/effects/trash.dm b/code/modules/persistence/effects/trash.dm
index 2e221456340..434a1397357 100644
--- a/code/modules/persistence/effects/trash.dm
+++ b/code/modules/persistence/effects/trash.dm
@@ -1,14 +1,13 @@
/datum/persistent/filth/trash
name = "trash"
- saves_dirt = FALSE //VOREStation edit
+ saves_dirt = FALSE
+ has_admin_data = FALSE
/datum/persistent/filth/trash/CheckTurfContents(var/turf/T, var/list/tokens)
var/too_much_trash = 0
for(var/obj/item/trash/trash in T)
- //VOREStation Addition Start
if(istype(T, /obj/item/trash/spitwad) || istype(T, /obj/item/trash/spitgum))
return FALSE
- //VOREStation Addition End
too_much_trash++
if(too_much_trash >= 5)
return FALSE