Skip to content
This repository has been archived by the owner on Jan 22, 2020. It is now read-only.

Commit

Permalink
Added persistent graffiti. (#766)
Browse files Browse the repository at this point in the history
* Updated game year. Now syncs with Mondays and is closer to intended period.

* Added cross-round graffiti.
  • Loading branch information
MistakeNot4892 committed Apr 23, 2018
1 parent 47d60d3 commit 7aed518
Show file tree
Hide file tree
Showing 12 changed files with 250 additions and 3 deletions.
3 changes: 2 additions & 1 deletion code/__defines/subsystem-priority.dm
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#define SS_INIT_SEEDS 8
#define SS_INIT_SEEDS 9
#define SS_INIT_PERSISTENCE 8 // Initialize round-start map objects from previous rounds.
#define SS_INIT_MISC_FIRST 7
#define SS_INIT_WIRELESS 6 // Wireless pair queue flush.
#define SS_INIT_AIR 5 // Air setup and pre-bake.
Expand Down
97 changes: 97 additions & 0 deletions code/controllers/subsystems/initialization/persistence.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#define GRAFFITI_AGE_DECAY 10
#define GRAFFITI_AGE_MAX 50
#define GRAFFITI_AGE_SCRAMBLE_WEIGHT 0.5
#define GRAFFITI_FILE "data/persistent/[lowertext(using_map.name)]-graffiti.txt"

var/datum/controller/subsystem/persistence/SSpersistence

/datum/controller/subsystem/persistence
name = "Persistence"
init_order = SS_INIT_PERSISTENCE
flags = SS_NO_FIRE
var/list/graffiti

/datum/controller/subsystem/persistence/New()
NEW_SS_GLOBAL(SSpersistence)

/datum/controller/subsystem/persistence/Initialize()

if(!fexists(GRAFFITI_FILE))
return

for(var/graffiti_line in file2list(GRAFFITI_FILE, "\n"))

if(!graffiti_line)
continue

// Break the line up.
var/list/graffiti_tokens = splittext(graffiti_line, "\t")
if(graffiti_tokens.len < 6)
continue

var/_x = text2num(graffiti_tokens[1])
var/_y = text2num(graffiti_tokens[2])
var/_z = text2num(graffiti_tokens[3])
var/_n = text2num(graffiti_tokens[4])
var/_author = graffiti_tokens[5]
var/_message = graffiti_tokens[6]

// Sanity checks.
if(isnull(_n) || isnull(_x) || isnull(_y) || isnull(_z))
continue

// Too old, get outta here.
if(_n > GRAFFITI_AGE_MAX)
continue

// If it's old enough we start to trim it down and scramble parts.
if(_n >= GRAFFITI_AGE_DECAY)
var/decayed_message = ""
for(var/i = 1 to length(_message))
var/char = copytext(_message, i, i + 1)
if(prob(round(_n * GRAFFITI_AGE_SCRAMBLE_WEIGHT)))
if(prob(99))
decayed_message += pick(".",",","-","'","\\","/","\"",":",";")
else
decayed_message += char
_message = decayed_message

// If it has decayed to nothing we ditch it and move on.
if(!length(_message))
continue

// Message is valid, find a valid turf for it.
var/turf/T = locate(_x, _y, _z)
if(!istype(T) || !T.can_engrave())
continue

// Is the turf full of other crap?
var/too_much_graffiti = 0
for(var/obj/effect/decal/writing/W in T)
too_much_graffiti++
if(too_much_graffiti >= 5)
continue

// Finalize the decal.
var/obj/effect/decal/writing/new_graffiti = new(T)
new_graffiti.message = _message
new_graffiti.graffiti_age = _n+1
new_graffiti.author = _author

/datum/controller/subsystem/persistence/Shutdown()
// Goodnight sweet prince.
// Please for the love of god don't point this at a directory.
if(fexists(GRAFFITI_FILE)) fdel(GRAFFITI_FILE)
var/graffiti_file = file(GRAFFITI_FILE)
for(var/thing in graffiti)
var/obj/effect/decal/writing/save_graffiti = thing
if(save_graffiti.graffiti_age >= GRAFFITI_AGE_MAX)
continue
var/turf/T = save_graffiti.loc
if(!istype(T) || !T.can_engrave())
continue
graffiti_file << "[save_graffiti.x]\t[save_graffiti.y]\t[save_graffiti.z]\t[save_graffiti.graffiti_age]\t[save_graffiti.author ? save_graffiti.author : "unknown"]\t[save_graffiti.message]"

#undef GRAFFITI_AGE_DECAY
#undef GRAFFITI_AGE_MAX
#undef GRAFFITI_AGE_SCRAMBLE_WEIGHT
3 changes: 2 additions & 1 deletion code/game/objects/effects/decals/Cleanable/humans.dm
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ var/global/list/image/splatter_cache=list()
drips |= icon_state

/obj/effect/decal/cleanable/blood/writing
icon_state = "tracks"
icon_state = "writing"
icon = 'icons/effects/writing.dmi'
desc = "It looks like a writing in blood."
gender = NEUTER
random_icon_states = list("writing1","writing2","writing3","writing4","writing5")
Expand Down
1 change: 1 addition & 0 deletions code/game/objects/items/weapons/tools.dm
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
center_of_mass = "x=16;y=7"
attack_verb = list("stabbed")
lock_picking_level = 5
sharp = TRUE

/obj/item/screwdriver/isscrewdriver()
return 1
Expand Down
2 changes: 1 addition & 1 deletion code/global.dm
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ var/diary = null
var/href_logfile = null
var/game_version = "ES13 <b><font color = '#FF0000'>r0-indev</font></b>"
var/changelog_hash = ""
var/game_year = (text2num(time2text(world.realtime, "YYYY")) + 210)
var/game_year = (text2num(time2text(world.realtime, "YYYY")) + 220)

var/round_progressing = 1
var/master_mode = "extended" // "extended"
Expand Down
33 changes: 33 additions & 0 deletions code/modules/persistence/graffiti/graffiti_decal.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/obj/effect/decal/writing
name = "writing"
icon_state = "graffiti"
icon = 'icons/effects/writing.dmi'
desc = "It looks like someone has scratched something here."
gender = NEUTER
blend_mode = BLEND_SUBTRACT
alpha = 80
auto_init = TRUE

var/message
var/graffiti_age = 0
var/author = "unknown"

/obj/effect/decal/writing/initialize()

var/list/random_icon_states = list("writing1","writing2","writing3","writing4","writing5")
for(var/obj/effect/decal/writing/W in loc)
random_icon_states.Remove(W.icon_state)
if(random_icon_states.len)
icon_state = pick(random_icon_states)
else
icon_state = "writing1"
LAZYADD(SSpersistence.graffiti, src)
. = ..()

/obj/effect/decal/writing/Destroy()
LAZYREMOVE(SSpersistence.graffiti, src)
. = ..()

/obj/effect/decal/writing/examine(mob/user)
..(user)
user << "It reads \"[message]\"."
20 changes: 20 additions & 0 deletions code/modules/persistence/graffiti/graffiti_flooring.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/decl/flooring
var/can_engrave = TRUE

/decl/flooring/grass
can_engrave = FALSE

/decl/flooring/asteroid
can_engrave = FALSE

/decl/flooring/carpet
can_engrave = FALSE

/decl/flooring/carpet/blue
can_engrave = FALSE

/decl/flooring/reinforced/circuit
can_engrave = FALSE

/decl/flooring/reinforced/shuttle
can_engrave = FALSE
85 changes: 85 additions & 0 deletions code/modules/persistence/graffiti/graffiti_turf.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/turf/proc/can_engrave()
return FALSE

/turf/proc/try_graffiti(var/mob/vandal, var/obj/item/tool)

if(!tool.sharp || !can_engrave())
return FALSE

var/too_much_graffiti = 0
for(var/obj/effect/decal/writing/W in src)
too_much_graffiti++
if(too_much_graffiti >= 5)
to_chat(vandal, "<span class='warning'>There's too much graffiti here to add more.</span>")
return FALSE

var/message = sanitize(input("Enter a message to engrave.", "Graffiti") as null|text, trim = TRUE)
if(!message)
return FALSE

if(!vandal || vandal.incapacitated() || !Adjacent(vandal) || !tool.loc == vandal)
return FALSE

vandal.visible_message("<span class='warning'>\The [vandal] begins carving something into \the [src].</span>")

if(!do_after(vandal, max(20, length(message)), src))
return FALSE

vandal.visible_message("<span class='notice'>\The [vandal] carves some graffiti into \the [src].</span>")
var/obj/effect/decal/writing/graffiti = new(src)
graffiti.message = message
graffiti.author = vandal.ckey

if(lowertext(message) == "elbereth")
to_chat(vandal, "<span class='notice'>You feel much safer.</span>")

return TRUE

/turf/simulated/wall/can_engrave()
return (material && material.hardness >= 10 && material.hardness <= 100)

/turf/simulated/floor/can_engrave()
return (!flooring || flooring.can_engrave)

/turf/simulated/floor/natural/can_engrave()
return FALSE

/turf/simulated/floor/water/can_engrave()
return FALSE

/turf/simulated/wall/attackby(var/obj/item/thing, var/mob/user)
if(!construction_stage && try_graffiti(user, thing))
return
. = ..()

/turf/simulated/floor/attackby(var/obj/item/thing, var/mob/user)

if(thing.isscrewdriver() && flooring && (flooring.flags & TURF_REMOVE_SCREWDRIVER))
return ..()

// Place graffiti.
if(try_graffiti(user, thing))
return

// Clear graffiti.
if(thing.iswelder())
var/obj/item/weldingtool/welder = thing
if(welder.isOn())
var/obj/effect/decal/writing/W = locate() in src
if(W && welder.remove_fuel(0,user) && do_after(user, 5, src))
if(W)
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
user.visible_message("<span class='notice'>\The [user] clears away some graffiti.</span>")
qdel(W)
return
. = ..()

/turf/simulated/floor/make_plating(var/place_product, var/defer_icon_update)
. = ..()
for(var/obj/effect/decal/writing/W in src)
qdel(W)

/turf/simulated/floor/set_flooring(var/decl/flooring/newflooring)
. = ..()
for(var/obj/effect/decal/writing/W in src)
qdel(W)
4 changes: 4 additions & 0 deletions europa.dme
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@
#include "code\controllers\subsystems\vote.dm"
#include "code\controllers\subsystems\wireless.dm"
#include "code\controllers\subsystems\initialization\legacy_init.dm"
#include "code\controllers\subsystems\initialization\persistence.dm"
#include "code\controllers\subsystems\processing\airflow.dm"
#include "code\controllers\subsystems\processing\nanoui.dm"
#include "code\controllers\subsystems\processing\processing.dm"
Expand Down Expand Up @@ -1746,6 +1747,9 @@
#include "code\modules\paperwork\photography.dm"
#include "code\modules\paperwork\silicon_photography.dm"
#include "code\modules\paperwork\stamps.dm"
#include "code\modules\persistence\graffiti\graffiti_decal.dm"
#include "code\modules\persistence\graffiti\graffiti_flooring.dm"
#include "code\modules\persistence\graffiti\graffiti_turf.dm"
#include "code\modules\pharmacy\_pharmacy.dm"
#include "code\modules\pharmacy\pharmacy_bottles.dm"
#include "code\modules\pharmacy\pharmacy_bottles_premade.dm"
Expand Down
5 changes: 5 additions & 0 deletions html/changelogs/zuhayr-graffiti.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
author: Zuhayr
delete-after: True
changes:
- tweak: "Accidentally snuck a lore change into a feature PR. Game year is now 2238."
- rscadd: "Added persistent graffiti. Use a sharp object to engrave or a welder to remove."
Binary file modified icons/effects/blood.dmi
Binary file not shown.
Binary file added icons/effects/writing.dmi
Binary file not shown.

0 comments on commit 7aed518

Please sign in to comment.