diff --git a/code/game/objects/items/weapons/RCL.dm b/code/game/objects/items/weapons/RCL.dm new file mode 100644 index 00000000000..524fd38eb80 --- /dev/null +++ b/code/game/objects/items/weapons/RCL.dm @@ -0,0 +1,151 @@ +/obj/item/weapon/twohanded/rcl + name = "rapid cable layer (RCL)" + desc = "A device used to rapidly deploy cables. It has screws on the side which can be removed to slide off the cables." + icon = 'icons/obj/tools.dmi' + icon_state = "rcl-0" + item_state = "rcl-0" + opacity = 0 + force = 5 //Plastic is soft + throwforce = 5 + throw_speed = 1 + throw_range = 7 + w_class = WEIGHT_CLASS_NORMAL + origin_tech = "engineering=4;materials=4" + var/max_amount = 90 + var/active = 0 + var/obj/structure/cable/last = null + var/obj/item/stack/cable_coil/loaded = null + +/obj/item/weapon/twohanded/rcl/attackby(obj/item/weapon/W, mob/user) + if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = W + if(!loaded) + if(user.drop_item()) + loaded = W + loaded.forceMove(src) + loaded.max_amount = max_amount //We store a lot. + else + to_chat(user, "[user.get_active_hand()] is stuck to your hand!") + return + else + if(loaded.amount < max_amount) + var/amount = min(loaded.amount + C.amount, max_amount) + C.use(amount - loaded.amount) + loaded.amount = amount + else + return + update_icon() + to_chat(user, "You add the cables to the [src]. It now contains [loaded.amount].") + else if(isscrewdriver(W)) + if(!loaded) + return + to_chat(user, "You loosen the securing screws on the side, allowing you to lower the guiding edge and retrieve the wires.") + while(loaded.amount > 30) //There are only two kinds of situations: "nodiff" (60,90), or "diff" (31-59, 61-89) + var/diff = loaded.amount % 30 + if(diff) + loaded.use(diff) + new /obj/item/stack/cable_coil(user.loc, diff) + else + loaded.use(30) + new /obj/item/stack/cable_coil(user.loc, 30) + loaded.max_amount = initial(loaded.max_amount) + loaded.forceMove(user.loc) + user.put_in_hands(loaded) + loaded = null + update_icon() + else + ..() + +/obj/item/weapon/twohanded/rcl/examine(mob/user) + ..() + if(loaded) + to_chat(user, "It contains [loaded.amount]/[max_amount] cables.") + +/obj/item/weapon/twohanded/rcl/Destroy() + if(loaded) + qdel(loaded) + loaded = null + last = null + active = 0 + return ..() + +/obj/item/weapon/twohanded/rcl/update_icon() + if(!loaded) + icon_state = "rcl-0" + item_state = "rcl-0" + return + switch(loaded.amount) + if(61 to INFINITY) + icon_state = "rcl-30" + item_state = "rcl" + if(31 to 60) + icon_state = "rcl-20" + item_state = "rcl" + if(1 to 30) + icon_state = "rcl-10" + item_state = "rcl" + else + icon_state = "rcl-0" + item_state = "rcl-0" + +/obj/item/weapon/twohanded/rcl/proc/is_empty(mob/user, loud = 1) + update_icon() + if(!loaded || !loaded.amount) + if(loud) + to_chat(user, "The last of the cables unreel from [src].") + if(loaded) + qdel(loaded) + loaded = null + unwield(user) + active = wielded + return 1 + return 0 + +/obj/item/weapon/twohanded/rcl/dropped(mob/wearer) + ..() + active = 0 + last = null + +/obj/item/weapon/twohanded/rcl/attack_self(mob/user) + ..() + active = wielded + if(!active) + last = null + else if(!last) + for(var/obj/structure/cable/C in get_turf(user)) + if(C.d1 == 0 || C.d2 == 0) + last = C + break + +/obj/item/weapon/twohanded/rcl/moved(mob/user, turf/old_loc, direct) + if(active) + trigger(user) + +/obj/item/weapon/twohanded/rcl/proc/trigger(mob/user) + if(is_empty(user, 0)) + to_chat(user, "\The [src] is empty!") + return + if(last) + if(get_dist(last, user) == 1) //hacky, but it works + var/turf/T = get_turf(user) + if(!isturf(T) || T.intact || !T.can_have_cabling()) + last = null + return + if(get_dir(last, user) == last.d2) + //Did we just walk backwards? Well, that's the one direction we CAN'T complete a stub. + last = null + return + loaded.cable_join(last, user) + if(is_empty(user)) + return //If we've run out, display message and exit + else + last = null + last = loaded.place_turf(get_turf(loc), user, turn(user.dir, 180)) + is_empty(user) //If we've run out, display message + +/obj/item/weapon/twohanded/rcl/pre_loaded/New() //Comes preloaded with cable, for testing stuff + ..() + loaded = new() + loaded.max_amount = max_amount + loaded.amount = max_amount + update_icon() \ No newline at end of file diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 69b0df22ae3..a5e4190d6ea 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -386,15 +386,25 @@ if(ticker) cameranet.updateVisibility(src) -/turf/attackby(obj/item/C, mob/user, params) - if(can_lay_cable() && istype(C, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/coil = C - for(var/obj/structure/cable/LC in src) - if((LC.d1==0)||(LC.d2==0)) - LC.attackby(C,user) - return - coil.place_turf(src, user) - return 1 +/turf/attackby(obj/item/I, mob/user, params) + if(can_lay_cable()) + if(istype(I, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = I + for(var/obj/structure/cable/LC in src) + if(LC.d1 == 0 || LC.d2==0) + LC.attackby(C,user) + return + C.place_turf(src, user) + return 1 + else if(istype(I, /obj/item/weapon/twohanded/rcl)) + var/obj/item/weapon/twohanded/rcl/R = I + if(R.loaded) + for(var/obj/structure/cable/LC in src) + if(LC.d1 == 0 || LC.d2==0) + LC.attackby(R, user) + return + R.loaded.place_turf(src, user) + R.is_empty(user) return 0 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 8b8fafd32b7..52fdbdf0328 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -199,6 +199,10 @@ var/atom/O = mob.loc return O.relaymove(mob, direct) + if(istype(mob.get_active_hand(), /obj/item)) + var/obj/item/I = mob.get_active_hand() + I.moved(mob, n, direct) + if(!mob.Process_Spacemove(direct)) return 0 diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 849511a48e7..176ce72f005 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -114,7 +114,7 @@ By design, d1 is the smallest direction and d2 is the highest // /obj/structure/cable/attackby(obj/item/W, mob/user) - var/turf/T = src.loc + var/turf/T = get_turf(src) if(T.intact) return @@ -149,7 +149,7 @@ By design, d1 is the smallest direction and d2 is the highest if(c.d1 == 12 || c.d2 == 12) c.qdel()*/ ///// Z-Level Stuff - investigate_log("was cut by [key_name(usr, usr.client)] in [user.loc.loc]([T.x], [T.y], [T.z] - JMP)","wires") + investigate_log("was cut by [key_name(usr, usr.client)] in [get_area(user)]([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])","wires") qdel(src) // qdel return @@ -162,6 +162,12 @@ By design, d1 is the smallest direction and d2 is the highest return coil.cable_join(src, user) + else if(istype(W, /obj/item/weapon/twohanded/rcl)) + var/obj/item/weapon/twohanded/rcl/R = W + if(R.loaded) + R.loaded.cable_join(src, user) + R.is_empty(user) + else if(istype(W, /obj/item/device/multitool)) if(powernet && (powernet.avail > 0)) // is it powered? @@ -197,12 +203,12 @@ By design, d1 is the smallest direction and d2 is the highest qdel(src) // qdel if(2.0) if(prob(50)) - new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color) + new/obj/item/stack/cable_coil(get_turf(src), src.d1 ? 2 : 1, color) qdel(src) // qdel if(3.0) if(prob(25)) - new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color) + new/obj/item/stack/cable_coil(get_turf(src), src.d1 ? 2 : 1, color) qdel(src) // qdel return @@ -505,7 +511,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( // General procedures /////////////////////////////////// //you can use wires to heal robotics -/obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob) +/obj/item/stack/cable_coil/attack(mob/M, mob/user) if(ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/S = H.organs_by_name[user.zone_sel.selecting] @@ -613,11 +619,11 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( return C // called when cable_coil is clicked on a turf/simulated/floor -/obj/item/stack/cable_coil/proc/place_turf(turf/T, mob/user) +/obj/item/stack/cable_coil/proc/place_turf(turf/T, mob/user, dirnew) if(!isturf(user.loc)) return - if(!T.can_have_cabling()) + if(!isturf(T) || T.intact || !T.can_have_cabling()) to_chat(user, "You can only lay cables on catwalks and plating!") return @@ -629,44 +635,46 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( to_chat(user, "You can't lay cable at a place that far away!") return - else - var/dirn - + var/dirn = null + if(!dirnew) //If we weren't given a direction, come up with one! (Called as null from catwalk.dm and floor.dm) if(user.loc == T) - dirn = user.dir // if laying on the tile we're on, lay in the direction we're facing + dirn = user.dir //If laying on the tile we're on, lay in the direction we're facing else dirn = get_dir(T, user) + else + dirn = dirnew - for(var/obj/structure/cable/LC in T) - if(LC.d2 == dirn && LC.d1 == 0) - to_chat(user, "There's already a cable at that position!") - return + for(var/obj/structure/cable/LC in T) + if(LC.d2 == dirn && LC.d1 == 0) + to_chat(user, "There's already a cable at that position!") + return - var/obj/structure/cable/C = get_new_cable(T) + var/obj/structure/cable/C = get_new_cable(T) - //set up the new cable - C.d1 = 0 //it's a O-X node cable - C.d2 = dirn - C.add_fingerprint(user) - C.updateicon() + //set up the new cable + C.d1 = 0 //it's a O-X node cable + C.d2 = dirn + C.add_fingerprint(user) + C.updateicon() - //create a new powernet with the cable, if needed it will be merged later - var/datum/powernet/PN = new() - PN.add_cable(C) + //create a new powernet with the cable, if needed it will be merged later + var/datum/powernet/PN = new() + PN.add_cable(C) - C.mergeConnectedNetworks(C.d2) //merge the powernet with adjacents powernets - C.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets + C.mergeConnectedNetworks(C.d2) //merge the powernet with adjacents powernets + C.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets - if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions - C.mergeDiagonalsNetworks(C.d2) + if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions + C.mergeDiagonalsNetworks(C.d2) + use(1) - use(1) + if(C.shock(user, 50)) + if(prob(50)) //fail + new /obj/item/stack/cable_coil(get_turf(C), 1, C.color) + qdel(C) // qdel - if(C.shock(user, 50)) - if(prob(50)) //fail - new/obj/item/stack/cable_coil(C.loc, 1, C.color) - qdel(C) // qdel + return C // called when cable_coil is click on an installed obj/cable // or click on a turf that already contains a "node" cable @@ -675,7 +683,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( if(!isturf(U)) return - var/turf/T = C.loc + var/turf/T = get_turf(C) if(!isturf(T) || T.intact) // sanity checks, also stop use interacting with T-scanner revealed cable return @@ -700,38 +708,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( // cable is pointing at us, we're standing on an open tile // so create a stub pointing at the clicked cable on our tile - var/fdirn = turn(dirn, 180) // the opposite direction - - for(var/obj/structure/cable/LC in U) // check to make sure there's not a cable there already - if(LC.d1 == fdirn || LC.d2 == fdirn) - to_chat(user, "There's already a cable at that position.") - return - - var/obj/structure/cable/NC = new(U) - NC.cableColor(color) - - NC.d1 = 0 - NC.d2 = fdirn - NC.add_fingerprint() - NC.updateicon() - - //create a new powernet with the cable, if needed it will be merged later - var/datum/powernet/newPN = new() - newPN.add_cable(NC) - - NC.mergeConnectedNetworks(NC.d2) //merge the powernet with adjacents powernets - NC.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets - - if(NC.d2 & (NC.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions - NC.mergeDiagonalsNetworks(NC.d2) - - use(1) - - if(NC.shock(user, 50)) - if(prob(50)) //fail - new/obj/item/stack/cable_coil(NC.loc, 1, NC.color) - qdel(NC) // qdel - + place_turf(T, user, turn(dirn, 180)) return // exisiting cable doesn't point at our position, so see if it's a stub @@ -777,7 +754,7 @@ var/global/list/datum/stack_recipe/cable_coil_recipes = list( if(C.shock(user, 50)) if(prob(50)) //fail - new/obj/item/stack/cable_coil(C.loc, 2, C.color) + new/obj/item/stack/cable_coil(get_turf(C), 2, C.color) qdel(C) // qdel return diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 0c9090c5b81..9682a110971 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index 0f889055ad0..023222ad451 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi index d1aca5822c3..00f5ac98691 100644 Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ diff --git a/paradise.dme b/paradise.dme index c0fe429cc82..258cabc1507 100644 --- a/paradise.dme +++ b/paradise.dme @@ -807,6 +807,7 @@ #include "code\game\objects\items\weapons\power_cells.dm" #include "code\game\objects\items\weapons\powerfist.dm" #include "code\game\objects\items\weapons\RCD.dm" +#include "code\game\objects\items\weapons\RCL.dm" #include "code\game\objects\items\weapons\RSF.dm" #include "code\game\objects\items\weapons\scissors.dm" #include "code\game\objects\items\weapons\scrolls.dm"