diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm
index 50be738ecce..9d820f68925 100644
--- a/code/game/objects/items/weapons/policetape.dm
+++ b/code/game/objects/items/weapons/policetape.dm
@@ -18,8 +18,22 @@ var/list/tape_roll_applications = list()
anchored = 1
var/lifted = 0
var/crumpled = 0
+ var/tape_dir = 0
var/icon_base
+/obj/item/tape/update_icon()
+ //Possible directional bitflags: 0 (AIRLOCK), 1 (NORTH), 2 (SOUTH), 4 (EAST), 8 (WEST), 3 (VERTICAL), 12 (HORIZONTAL)
+ switch (tape_dir)
+ if(0) // AIRLOCK
+ icon_state = "[icon_base]_door_[crumpled]"
+ if(3) // VERTICAL
+ icon_state = "[icon_base]_v_[crumpled]"
+ if(12) // HORIZONTAL
+ icon_state = "[icon_base]_h_[crumpled]"
+ else // END POINT (1|2|4|8)
+ icon_state = "[icon_base]_dir_[crumpled]"
+ dir = tape_dir
+
/obj/item/tape/New()
..()
if(!hazard_overlays)
@@ -32,7 +46,7 @@ var/list/tape_roll_applications = list()
/obj/item/taperoll/police
name = "police tape"
desc = "A roll of police tape used to block off crime scenes from the public."
- icon_state = "police_start"
+ icon_state = "police"
tape_type = /obj/item/tape/police
icon_base = "police"
@@ -45,7 +59,7 @@ var/list/tape_roll_applications = list()
/obj/item/taperoll/engineering
name = "engineering tape"
desc = "A roll of engineering tape used to block off working areas from the public."
- icon_state = "engineering_start"
+ icon_state = "engineering"
tape_type = /obj/item/tape/engineering
icon_base = "engineering"
@@ -55,58 +69,146 @@ var/list/tape_roll_applications = list()
req_one_access = list(access_engine,access_atmospherics)
icon_base = "engineering"
+/obj/item/taperoll/atmos
+ name = "atmospherics tape"
+ desc = "A roll of atmospherics tape used to block off working areas from the public."
+ icon_state = "atmos"
+ tape_type = /obj/item/tape/atmos
+ icon_base = "atmos"
+
+/obj/item/tape/atmos
+ name = "atmospherics tape"
+ desc = "A length of atmospherics tape. Better not cross it."
+ req_one_access = list(access_engine,access_atmospherics)
+ icon_base = "atmos"
+
+/obj/item/taperoll/update_icon()
+ overlays.Cut()
+ if(ismob(loc))
+ if(!start)
+ overlays += "start"
+ else
+ overlays += "stop"
+
+/obj/item/taperoll/dropped(mob/user)
+ ..()
+ update_icon()
+
+/obj/item/taperoll/pickup(mob/user)
+ ..()
+ update_icon()
+
/obj/item/taperoll/attack_self(mob/user as mob)
- if(icon_state == "[icon_base]_start")
+ if(!start)
start = get_turf(src)
usr << "You place the first end of \the [src]."
- icon_state = "[icon_base]_stop"
+ update_icon()
else
- icon_state = "[icon_base]_start"
end = get_turf(src)
if(start.y != end.y && start.x != end.x || start.z != end.z)
+ start = null
+ update_icon()
usr << "\The [src] can only be laid horizontally or vertically."
return
+ if(start == end)
+ // spread tape in all directions, provided there is a wall/window
+ var/turf/T
+ var/possible_dirs = 0
+ for(var/dir in cardinal)
+ T = get_step(start, dir)
+ if(T && T.density)
+ possible_dirs += dir
+ else
+ for(var/obj/structure/window/W in T)
+ if(W.is_fulltile() || W.dir == reverse_dir[dir])
+ possible_dirs += dir
+ if(!possible_dirs)
+ start = null
+ update_icon()
+ usr << "You can't place \the [src] here."
+ return
+ if(possible_dirs & (NORTH|SOUTH))
+ var/obj/item/tape/TP = new tape_type(start)
+ for(var/dir in list(NORTH, SOUTH))
+ if (possible_dirs & dir)
+ TP.tape_dir += dir
+ TP.update_icon()
+ if(possible_dirs & (EAST|WEST))
+ var/obj/item/tape/TP = new tape_type(start)
+ for(var/dir in list(EAST, WEST))
+ if (possible_dirs & dir)
+ TP.tape_dir += dir
+ TP.update_icon()
+ start = null
+ update_icon()
+ usr << "You finish placing \the [src]."
+ return
+
var/turf/cur = start
- var/dir
- if (start.x == end.x)
- var/d = end.y-start.y
- if(d) d = d/abs(d)
- end = get_turf(locate(end.x,end.y+d,end.z))
- dir = "v"
- else
- var/d = end.x-start.x
- if(d) d = d/abs(d)
- end = get_turf(locate(end.x+d,end.y,end.z))
- dir = "h"
+ var/orientation = get_dir(start, end)
+ var/dir = 0
+ switch(orientation)
+ if(NORTH, SOUTH) dir = NORTH|SOUTH // North-South taping
+ if(EAST, WEST) dir = EAST|WEST // East-West taping
var/can_place = 1
- while (cur!=end && can_place)
+ while (can_place)
if(cur.density == 1)
can_place = 0
else if (istype(cur, /turf/space))
can_place = 0
else
for(var/obj/O in cur)
- if(!istype(O, /obj/item/tape) && O.density)
+ if(O.density)
can_place = 0
break
+ if(cur == end)
+ break
cur = get_step_towards(cur,end)
if (!can_place)
+ start = null
+ update_icon()
usr << "You can't run \the [src] through that!"
return
cur = start
- var/tapetest = 0
- while (cur!=end)
- for(var/obj/item/tape/Ptest in cur)
- if(Ptest.icon_state == "[Ptest.icon_base]_[dir]")
+ var/tapetest
+ var/tape_dir
+ while (1)
+ tapetest = 0
+ tape_dir = dir
+ if(cur == start)
+ var/turf/T = get_step(start, reverse_dir[orientation])
+ if(T && !T.density)
+ tape_dir = orientation
+ for(var/obj/structure/window/W in T)
+ if(W.is_fulltile() || W.dir == orientation)
+ tape_dir = dir
+ else if(cur == end)
+ var/turf/T = get_step(end, orientation)
+ if(T && !T.density)
+ tape_dir = reverse_dir[orientation]
+ for(var/obj/structure/window/W in T)
+ if(W.is_fulltile() || W.dir == reverse_dir[orientation])
+ tape_dir = dir
+ for(var/obj/item/tape/T in cur)
+ if((T.tape_dir == tape_dir) && (T.icon_base == icon_base))
tapetest = 1
- if(tapetest != 1)
- var/obj/item/tape/P = new tape_type(cur)
- P.icon_state = "[P.icon_base]_[dir]"
+ break
+ if(!tapetest)
+ var/obj/item/tape/T = new tape_type(cur)
+ T.tape_dir = tape_dir
+ T.update_icon()
+ if(tape_dir & SOUTH)
+ T.layer += 0.1 // Must always show above other tapes
+ if(cur == end)
+ break
cur = get_step_towards(cur,end)
+ start = null
+ update_icon()
usr << "You finish placing \the [src]."
+ return
/obj/item/taperoll/afterattack(var/atom/A, mob/user as mob, proximity)
if(!proximity)
@@ -140,7 +242,7 @@ var/list/tape_roll_applications = list()
/obj/item/tape/proc/crumple()
if(!crumpled)
crumpled = 1
- icon_state = "[icon_state]_c"
+ update_icon()
name = "crumpled [name]"
/obj/item/tape/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
@@ -149,6 +251,8 @@ var/list/tape_roll_applications = list()
add_fingerprint(M)
if (!allowed(M)) //only select few learn art of not crumpling the tape
M << "You are not supposed to go past [src]..."
+ if(M.a_intent == I_HELP)
+ return 0
crumple()
return ..(mover)
@@ -158,13 +262,45 @@ var/list/tape_roll_applications = list()
/obj/item/tape/attack_hand(mob/user as mob)
if (user.a_intent == I_HELP && src.allowed(user))
user.show_viewers("\The [user] lifts \the [src], allowing passage.")
- crumple()
- lifted = 1
- spawn(200)
- lifted = 0
+ for(var/obj/item/tape/T in gettapeline())
+ T.lift(100) //~10 seconds
else
breaktape(null, user)
+/obj/item/tape/proc/lift(time)
+ lifted = 1
+ layer = 8
+ spawn(time)
+ lifted = 0
+ layer = initial(layer)
+
+// Returns a list of all tape objects connected to src, including itself.
+/obj/item/tape/proc/gettapeline()
+ var/list/dirs = list()
+ if(tape_dir & NORTH)
+ dirs += NORTH
+ if(tape_dir & SOUTH)
+ dirs += SOUTH
+ if(tape_dir & WEST)
+ dirs += WEST
+ if(tape_dir & EAST)
+ dirs += EAST
+
+ var/list/obj/item/tape/tapeline = list()
+ for (var/obj/item/tape/T in get_turf(src))
+ tapeline += T
+ for(var/dir in dirs)
+ var/turf/cur = get_step(src, dir)
+ var/not_found = 0
+ while (!not_found)
+ not_found = 1
+ for (var/obj/item/tape/T in cur)
+ tapeline += T
+ not_found = 0
+ cur = get_step(cur, dir)
+ return tapeline
+
+
/obj/item/tape/proc/breaktape(obj/item/weapon/W as obj, mob/user as mob)
@@ -173,27 +309,11 @@ var/list/tape_roll_applications = list()
return
user.show_viewers("\The [user] breaks \the [src]!")
- var/dir[2]
- var/icon_dir = src.icon_state
- if(icon_dir == "[src.icon_base]_h")
- dir[1] = EAST
- dir[2] = WEST
- if(icon_dir == "[src.icon_base]_v")
- dir[1] = NORTH
- dir[2] = SOUTH
-
- for(var/i=1;i<3;i++)
- var/N = 0
- var/turf/cur = get_step(src,dir[i])
- while(N != 1)
- N = 1
- for (var/obj/item/tape/P in cur)
- if(P.icon_state == icon_dir)
- N = 0
- qdel(P)
- cur = get_step(cur,dir[i])
-
- qdel(src)
- return
-
+ for (var/obj/item/tape/T in gettapeline())
+ if(T == src)
+ continue
+ if(T.tape_dir & get_dir(T, src))
+ qdel(T)
+ qdel(src) //TODO: Dropping a trash item holding fibers/fingerprints of all broken tape parts
+ return
\ No newline at end of file
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
index a3e3ad86181..bd2b216888b 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
@@ -160,6 +160,6 @@
new /obj/item/clothing/suit/storage/hazardvest(src)
new /obj/item/clothing/mask/gas(src)
new /obj/item/weapon/cartridge/atmos(src)
- new /obj/item/taperoll/engineering(src)
+ new /obj/item/taperoll/atmos(src)
new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering/atmos(src)
return
diff --git a/html/changelogs/Hubblenaut-tape.yml b/html/changelogs/Hubblenaut-tape.yml
new file mode 100644
index 00000000000..fa97c1a036c
--- /dev/null
+++ b/html/changelogs/Hubblenaut-tape.yml
@@ -0,0 +1,41 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Hubblenaut
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Adds tape for atmospherics."
+ - tweak: "Tape graphics and algorithm changes. Looks a lot more appealing now."
+ - tweak: "Starting and ending tape on the same turf will connect it to all surrounding walls/windows."
+ - tweak: "Lifting a part of the tape will lift an entire tape section."
+ - tweak: "Mobs on help intent do stop for tape."
+ - bugfix: "Crumpled tape does not affect tape breaking behavior anymore."
diff --git a/icons/policetape.dmi b/icons/policetape.dmi
index 841878f73fc..03efe3aef22 100644
Binary files a/icons/policetape.dmi and b/icons/policetape.dmi differ