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