diff --git a/code/game/objects/items/hazardtape.dm b/code/game/objects/items/hazardtape.dm new file mode 100644 index 00000000000..30da0179076 --- /dev/null +++ b/code/game/objects/items/hazardtape.dm @@ -0,0 +1,258 @@ +#define MAX_TAPE_RANGE 3 +//The max length of a line of hazard tape by tile range + +//Define all tape types in hazardtape.dm +/obj/item/tapeproj + icon = 'icons/obj/holotape.dmi' + icon_state = "rollstart" + w_class = 2.0 + var/turf/start + var/turf/end + var/tape_type = /obj/item/holotape + var/icon_base + var/charging = 0 + +/obj/item/holotape + icon = 'icons/obj/holotape.dmi' + anchored = 1 + density = 1 + var/icon_base + var/health = 10 + +/obj/item/tapeproj/security + name = "security holotape projector" + desc = "A security hard-light holotape projector used to block crime scenes from non-security staff. It can be placed in segments along hallways or on airlocks to restrict access." + icon_state = "security_start" + tape_type = /obj/item/holotape/security + icon_base = "security" + +/obj/item/holotape/security + name = "security holotape" + desc = "A length of security hard-light holotape. It reads: SECURITY LINE | DO NOT CROSS." + req_access = list(access_security) + icon_base = "security" + +/obj/item/tapeproj/engineering + name = "engineering holotape projector" + desc = "An engineering hard-light holotape projector used to block hazardous areas from non-engineering staff. It can be placed in segments along hallways or on airlocks to restrict access." + icon_state = "engineering_start" + tape_type = /obj/item/holotape/engineering + icon_base = "engineering" + +/obj/item/holotape/engineering + name = "engineering holotape" + desc = "A length of engineering hard-light holotape. It reads: HAZARD AHEAD | DO NOT CROSS." + req_one_access = list(access_engine,access_atmospherics,access_security) + icon_base = "engineering" + +/obj/item/tapeproj/dropped() + reset() + +/obj/item/tapeproj/equipped() + reset() + +/obj/item/tapeproj/proc/reset() + if(icon_state == "[icon_base]_stop") + icon_state = "[icon_base]_start" + start = null + return + +/obj/item/tapeproj/attack_self(var/mob/user) + if(charging) + usr << "[src] is recharging!" + return + if(icon_state == "[icon_base]_start") + start = get_turf(src) + usr << "You project the start of the [icon_base] holotape." + icon_state = "[icon_base]_stop" + else + icon_state = "[icon_base]_start" + end = get_turf(src) + if(start.y != end.y && start.x != end.x || start.z != end.z) + usr << "[src] can only be projected horizontally or vertically." + return + if(get_dist(start,end) >= MAX_TAPE_RANGE) + usr << "Your holotape segment is too long! It must be [MAX_TAPE_RANGE] tiles long or shorter!" + 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/can_place = 1 + while (cur!=end && 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/holotape) && O.density) + can_place = 0 + break + cur = get_step_towards(cur,end) + if(!can_place) + usr << "You can't project the [icon_base] holotape through that!" + return + + cur = start + var/tapetest = 0 + while (cur!=end) + for(var/obj/item/holotape/Ptest in cur) + if(Ptest.icon_state == "[Ptest.icon_base]_[dir]") + tapetest = 1 + if(tapetest != 1) + var/obj/item/holotape/P = new tape_type(cur) + P.icon_state = "[P.icon_base]_[dir]" + cur = get_step_towards(cur,end) + + usr << "You finish project the legnth of [icon_base] holotape." + user.visible_message("[user] finishes projecting the length of [icon_base] holotape.") + + charging = 1 + spawn(40) + charging = 0 + +/obj/item/tapeproj/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + if(charging) + return + + if(proximity_flag == 0) // not adjacent + return + + if(istype(target, /obj/machinery/door/airlock) || istype(target, /obj/machinery/door/firedoor)) + var/turf = get_turf(target) + + if(locate(tape_type) in turf) //Don't you dare stack tape + return + + user << "You start projecting the [icon_base] holotape onto [target]." + + if(!do_mob(user, target, 30)) + return + + var/atom/tape = new tape_type(turf) + tape.icon_state = "[icon_base]_door" + tape.layer = 3.2 + + user << "You project the [icon_base] holotape onto [target]." + + charging = 1 + spawn(40) + charging = 0 + +/obj/item/holotape/Bumped(var/mob/M) + if(src.allowed(M)) + var/turf/T = get_turf(src) + M.loc = T + +/obj/item/holotape/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(!density) return 1 + if(air_group || (height==0)) return 1 + + if((mover.flags & 2 || istype(mover, /obj/effect/meteor) || mover.throwing == 1) ) + return 1 + else + return 0 + +/obj/item/holotape/attack_hand(mob/living/user) + if(user.a_intent == "help" && src.allowed(user) && src.density) + user.show_viewers("[user] lifts [src], allowing passage.") + src.density = 0 + spawn(200) + src.density = 1 + else + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(src) + playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1) + user.visible_message("[user] hits [src].", \ + "You hit [src]." ) + + health -= rand(1,2) + healthcheck() + +/obj/item/holotape/proc/healthcheck() + if(health <= 0) + breaktape() + +/obj/item/holotape/ex_act(severity, target) + breaktape() + +/obj/item/holotape/blob_act() + breaktape() + +/obj/item/holotape/attack_paw(mob/living/user) + attack_hand(user) + +/obj/item/holotape/bullet_act(var/obj/item/projectile/Proj) + if(!Proj) + return + ..() + if((Proj.damage_type != STAMINA)) + src.health -= Proj.damage*0.3 + healthcheck() + return + +/obj/item/holotape/attackby(obj/item/weapon/W as obj, mob/user as mob) + user.changeNext_move(CLICK_CD_MELEE) + add_fingerprint(user) + switch(W.damtype) + if(STAMINA) + return + if(BURN) + playsound(loc, 'sound/items/welder.ogg', 80, 1) + else + playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1) + health -= W.force * 0.3 + + healthcheck() + ..() + return + +/obj/item/holotape/hitby(AM as mob|obj) + ..() + visible_message("[src] was hit by [AM].") + var/tforce = 0 + if(ismob(AM)) + tforce = 5 + else if(isobj(AM)) + var/obj/item/I = AM + tforce = max(0, I.throwforce * 0.5) + playsound(loc, 'sound/weapons/Egloves.ogg', 80, 1) + health = max(0, health - tforce) + healthcheck() + +/obj/item/holotape/proc/breaktape() + 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/holotape/P in cur) + if(P.icon_state == icon_dir) + N = 0 + del(P) + cur = get_step(cur,dir[i]) + + del(src) + return + +#undef MAX_TAPE_RANGE \ 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 8484f67c549..c8dac873ad8 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -18,8 +18,6 @@ else new /obj/item/weapon/storage/backpack/satchel_eng(src) new /obj/item/weapon/storage/backpack/dufflebag/engineering(src) - new /obj/item/areaeditor/blueprints(src) - new /obj/item/weapon/storage/box/permits(src) new /obj/item/clothing/under/rank/chief_engineer(src) new /obj/item/clothing/head/hardhat/white(src) new /obj/item/clothing/head/welding(src) @@ -29,7 +27,10 @@ new /obj/item/device/radio/headset/heads/ce(src) new /obj/item/weapon/storage/toolbox/mechanical(src) new /obj/item/clothing/suit/hazardvest(src) + new /obj/item/weapon/storage/box/permits(src) + new /obj/item/areaeditor/blueprints(src) new /obj/item/weapon/airlock_painter(src) + new /obj/item/tapeproj/engineering(src) new /obj/item/clothing/mask/gas(src) new /obj/item/device/multitool(src) new /obj/item/device/flash/handheld(src) @@ -106,10 +107,11 @@ new /obj/item/weapon/storage/backpack/dufflebag/engineering(src) new /obj/item/clothing/under/rank/engineer(src) new /obj/item/clothing/shoes/workboots(src) - new /obj/item/weapon/storage/toolbox/mechanical(src) // new /obj/item/weapon/cartridge/engineering(src) new /obj/item/device/radio/headset/headset_eng(src) new /obj/item/clothing/suit/hazardvest(src) + new /obj/item/weapon/storage/toolbox/mechanical(src) + new /obj/item/tapeproj/engineering(src) new /obj/item/clothing/mask/gas(src) new /obj/item/clothing/glasses/meson(src) return @@ -133,6 +135,7 @@ new /obj/item/weapon/storage/backpack/satchel_norm(src) new /obj/item/weapon/storage/backpack/dufflebag/engineering(src) new /obj/item/weapon/tank/internals/emergency_oxygen/engi(src) + new /obj/item/tapeproj/engineering(src) new /obj/item/weapon/watertank/atmos(src) new /obj/item/clothing/suit/fire/atmos(src) new /obj/item/clothing/head/hardhat/atmos(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 30fc7329d5b..4ec805ea742 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -80,6 +80,7 @@ new /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch(src) new /obj/item/weapon/storage/lockbox/loyalty(src) new /obj/item/weapon/storage/box/flashbangs(src) + new /obj/item/tapeproj/security(src) new /obj/item/clothing/mask/gas/sechailer/swat(src) new /obj/item/weapon/shield/riot/tele(src) new /obj/item/weapon/melee/baton/loaded(src) @@ -111,6 +112,7 @@ new /obj/item/clothing/mask/gas/sechailer(src) new /obj/item/weapon/storage/box/flashbangs(src) new /obj/item/weapon/storage/box/zipties(src) + new /obj/item/tapeproj/security(src) new /obj/item/weapon/reagent_containers/spray/pepper(src) new /obj/item/weapon/melee/baton/loaded(src) new /obj/item/weapon/gun/energy/gun/advtaser(src) @@ -205,9 +207,9 @@ new /obj/item/clothing/head/fedora(src) new /obj/item/clothing/shoes/laceup(src) new /obj/item/weapon/storage/box/evidence(src) - new /obj/item/weapon/clipboard(src) new /obj/item/device/radio/headset/headset_sec/alt(src) new /obj/item/device/detective_scanner(src) + new /obj/item/tapeproj/security(src) new /obj/item/clothing/suit/armor/vest/det_suit(src) new /obj/item/ammo_box/c38(src) new /obj/item/ammo_box/c38(src) diff --git a/icons/obj/holotape.dmi b/icons/obj/holotape.dmi new file mode 100644 index 00000000000..d73ef7b7a7f Binary files /dev/null and b/icons/obj/holotape.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 428476630ae..c470ff64200 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -535,6 +535,7 @@ #include "code\game\objects\items\candle.dm" #include "code\game\objects\items\crayons.dm" #include "code\game\objects\items\documents.dm" +#include "code\game\objects\items\hazardtape.dm" #include "code\game\objects\items\latexballoon.dm" #include "code\game\objects\items\shooting_range.dm" #include "code\game\objects\items\toys.dm"