Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graffiti centers on where you click. #9255

Merged
merged 3 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions code/game/objects/effects/decals/crayon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,38 @@
icon = 'icons/obj/rune.dmi'
plane = DIRTY_PLANE
anchored = 1
var/art_type
var/art_color
var/art_shade

/obj/effect/decal/cleanable/crayon/Initialize(var/ml, main = "#FFFFFF",shade = "#000000",var/type = "rune")
. = ..(ml, 0) // mapload, age
name = type
desc = "A [type] drawn in crayon."

// Persistence vars.
art_type = type
art_color = main
art_shade = shade

switch(type)
if("rune")
type = "rune[rand(1,6)]"
if("graffiti")
type = pick("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa")

var/icon/mainOverlay = new/icon('icons/effects/crayondecal.dmi',"[type]",2.1)
var/icon/shadeOverlay = new/icon('icons/effects/crayondecal.dmi',"[type]s",2.1)
update_icon()

add_hiddenprint(usr)

/obj/effect/decal/cleanable/crayon/update_icon()
cut_overlays()
var/icon/mainOverlay = new/icon('icons/effects/crayondecal.dmi',"[art_type]",2.1)
var/icon/shadeOverlay = new/icon('icons/effects/crayondecal.dmi',"[art_type]s",2.1)

mainOverlay.Blend(main,ICON_ADD)
shadeOverlay.Blend(shade,ICON_ADD)
mainOverlay.Blend(art_color,ICON_ADD)
shadeOverlay.Blend(art_shade,ICON_ADD)

add_overlay(mainOverlay)
add_overlay(shadeOverlay)

add_hiddenprint(usr)
return
17 changes: 14 additions & 3 deletions code/game/objects/items/crayons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
shadeColour = input(user, "Please select the shade colour.", "Crayon colour") as color
return

/obj/item/pen/crayon/afterattack(atom/target, mob/user as mob, proximity)
/obj/item/pen/crayon/afterattack(atom/target, mob/user as mob, proximity, click_parameters)
if(!proximity) return
if(istype(target,/turf/simulated/floor))
var/drawtype = input("Choose what you'd like to draw.", "Crayon scribbles") in list("graffiti","rune","letter","arrow")
Expand Down Expand Up @@ -93,7 +93,18 @@
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.")

if(config.log_graffiti)
Expand Down Expand Up @@ -209,4 +220,4 @@
..()

/obj/item/pen/crayon/attack_self(var/mob/user)
return
return
4 changes: 2 additions & 2 deletions code/game/turfs/simulated/floor_attackby.dm
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -29,7 +29,7 @@
if(isliving(user))
var/mob/living/L = user
if(L.a_intent == I_HELP && L.is_preference_enabled(/datum/client_preference/engrave_graffiti))
try_graffiti(L, C)
try_graffiti(L, C, click_parameters)

if(istype(C, /obj/item/stack/tile/roofing))
var/expended_tile = FALSE // To track the case. If a ceiling is built in a multiz zlevel, it also necessarily roofs it against weather
Expand Down
6 changes: 3 additions & 3 deletions code/game/turfs/simulated/wall_attacks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@
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))

if(!construction_stage && user.a_intent == I_HELP && user.is_preference_enabled(/datum/client_preference/engrave_graffiti))
if(try_graffiti(user,W))
if(try_graffiti(user,W,click_parameters))
return

if (!user.IsAdvancedToolUser())
Expand Down Expand Up @@ -405,4 +405,4 @@
return

else if(!istype(W,/obj/item/rcd) && !istype(W, /obj/item/reagent_containers))
return attack_hand(user)
return attack_hand(user)
14 changes: 13 additions & 1 deletion code/game/turfs/turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,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.sharp || !can_engrave())
return FALSE
Expand Down Expand Up @@ -341,6 +341,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 class='notice'>You feel much safer.</span>")

Expand Down
4 changes: 3 additions & 1 deletion code/modules/persistence/datum/persistence_datum.dm
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@
. += "<tr><td colspan = 4><hr></td></tr>"

for(var/thing in my_tracks)
. += "<tr>[GetAdminDataStringFor(thing, can_modify, user)]</tr>"
var/data = GetAdminDataStringFor(thing, can_modify, user)
if(!isnull(data))
. += "<tr>[GetAdminDataStringFor(thing, can_modify, user)]</tr>"
. += "<tr><td colspan = 4><hr></td></tr>"


Expand Down
57 changes: 53 additions & 4 deletions code/modules/persistence/effects/filth.dm
Original file line number Diff line number Diff line change
@@ -1,22 +1,57 @@
/datum/persistent/filth
name = "filth"
entries_expire_at = 4 // 4 rounds, 24 hours.
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 "<td colspan = 3>[thing]</td><td>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]</td><td><a href='byond://?src=\ref[src];caller=\ref[user];remove_entry=\ref[thing]'>Destroy</a></td>"
return "<td colspan = 4>[thing]</td>"
return null

/datum/persistent/filth/IsValidEntry(var/atom/entry)
. = ..() && entry.invisibility == 0

/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"])
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"]) && 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
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"]
new _path(creating, token["age"]+1)
var/atom/inst = new _path(creating, token["age"]+1)
if(token["pixel_x"])
inst.pixel_x = token["pixel_x"]
if(token["pixel_y"])
inst.pixel_y = token["pixel_y"]

if(istype(inst, /obj/effect/decal/cleanable/crayon))
var/obj/effect/decal/cleanable/crayon/Crayart = inst
if(token["art_type"])
Crayart.art_type = token["art_type"]
if(token["art_color"])
Crayart.art_color = token["art_color"]
if(token["art_shade"])
Crayart.art_shade = token["art_shade"]

Crayart.update_icon()

/datum/persistent/filth/GetEntryAge(var/atom/entry)
var/obj/effect/decal/cleanable/filth = entry
Expand All @@ -28,4 +63,18 @@

/datum/persistent/filth/CompileEntry(var/atom/entry)
. = ..()
LAZYADDASSOC(., "path", "[GetEntryPath(entry)]")
LAZYADDASSOC(., "path", "[GetEntryPath(entry)]")
to_world("path is [GetEntryPath(entry)]")
LAZYADDASSOC(., "pixel_x", "[entry.pixel_x]")
to_world("pixel_x is [entry.pixel_x]")
LAZYADDASSOC(., "pixel_y", "[entry.pixel_y]")
to_world("pixel_y is [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]")
to_world("art type is [Inst.art_type]")
LAZYADDASSOC(., "art_color", "[Inst.art_color]")
to_world("art color is [Inst.art_color]")
LAZYADDASSOC(., "art_shade", "[Inst.art_shade]")
to_world("art shade is [Inst.art_shade]")
14 changes: 13 additions & 1 deletion code/modules/persistence/effects/graffiti.dm
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,20 @@
return FALSE
return TRUE

/datum/persistent/graffiti/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["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/CreateEntryInstance(var/turf/creating, var/list/token)
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)
. = ..()
Expand All @@ -37,10 +47,12 @@
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
if(can_modify)
. = "<td colspan = 2>[save_graffiti.message]</td><td>[save_graffiti.author]</td><td><a href='byond://?src=\ref[src];caller=\ref[user];remove_entry=\ref[thing]'>Destroy</a></td>"
else
. = "<td colspan = 3>[save_graffiti.message]</td><td>[save_graffiti.author]</td>"
. = "<td colspan = 3>[save_graffiti.message]</td><td>[save_graffiti.author]</td>"
3 changes: 2 additions & 1 deletion code/modules/persistence/effects/trash.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/datum/persistent/filth/trash
name = "trash"
has_admin_data = FALSE

/datum/persistent/filth/trash/CheckTurfContents(var/turf/T, var/list/tokens)
var/too_much_trash = 0
Expand All @@ -14,4 +15,4 @@
return trash.age

/datum/persistent/filth/trash/GetEntryPath(var/atom/entry)
return entry.type
return entry.type
Binary file modified icons/effects/writing.dmi
Binary file not shown.