diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 63ba22d87f8..d5074339113 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -86,7 +86,7 @@ src << "This creature's DNA is ruined beyond useability!" return - if(!G.killing) + if(!G.state > GRAB_NECK) src << "We must have a tighter grip to absorb this creature." return diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index 27851eb0815..0d0eeb328bd 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -399,7 +399,7 @@ /obj/structure/table/holotable/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) var/obj/item/weapon/grab/G = W - if(G.state<2) + if(G.state < GRAB_AGGRESSIVE) user << "\red You need a better grip to do that!" return G.affecting.loc = src.loc @@ -510,7 +510,7 @@ /obj/structure/holohoop/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) var/obj/item/weapon/grab/G = W - if(G.state<2) + if(G.state < GRAB_AGGRESSIVE) user << "\red You need a better grip to do that!" return G.affecting.loc = src.loc diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index fc9583a8446..1c952b9534f 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -137,7 +137,7 @@ if(isalien(user)&&(ishuman(G.affecting)||ismonkey(G.affecting))) //Only aliens can stick humans and monkeys into resin walls. Also, the wall must not have a person inside already. if(!affecting) - if(G.state<2) + if(G.state < GRAB_AGGRESSIVE) user << "\red You need a better grip to do that!" return G.affecting.loc = src diff --git a/code/game/objects/structures/OpTable.dm b/code/game/objects/structures/OpTable.dm index 577b2141cc4..d0284309419 100644 --- a/code/game/objects/structures/OpTable.dm +++ b/code/game/objects/structures/OpTable.dm @@ -31,6 +31,8 @@ /obj/structure/optable/attackby(obj/item/weapon/W, mob/user) if(istype(W, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = W + if(!G.confirm()) + return if(ismob(G.affecting)) var/mob/M = G.affecting M.resting = 1 diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 58c98dc649a..b6624d64fdf 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -304,8 +304,7 @@ return 0 -/obj/structure/table/MouseDrop_T(obj/O as obj, mob/user as mob) - +/obj/structure/table/MouseDrop_T(obj/O, mob/user) if ((!( istype(O, /obj/item/weapon) ) || user.get_active_hand() != O)) return if(isrobot(user)) @@ -316,17 +315,18 @@ return -/obj/structure/table/attackby(obj/item/weapon/W as obj, mob/user as mob) - if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2) +/obj/structure/table/attackby(obj/item/weapon/W, mob/user) + if (istype(W, /obj/item/weapon/grab) && get_dist(src, user) < 2) var/obj/item/weapon/grab/G = W - if(G.state<2) - user << "\red You need a better grip to do that!" + if(G.state < GRAB_AGGRESSIVE) + user << "You need a better grip to do that!" return - if(!G.update()) + if(!G.confirm()) return G.affecting.loc = src.loc G.affecting.Weaken(5) - visible_message("\red [G.assailant] puts [G.affecting] on the table.") + G.affecting.visible_message("[G.assailant] pushes [G.affecting] onto [src].", \ + "[G.assailant] pushes [G.affecting] onto [src].") del(W) return @@ -373,8 +373,10 @@ if (istype(W, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = W - if(G.state<2) - user << "\red You need a better grip to do that!" + if(G.state < GRAB_AGGRESSIVE) + user << "You need a better grip to do that!" + return + if(!G.confirm()) return G.affecting.loc = src.loc G.affecting.Weaken(5) @@ -422,8 +424,10 @@ if (istype(W, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = W - if(G.state<2) - user << "\red You need a better grip to do that!" + if(G.state < GRAB_AGGRESSIVE) + user << "You need a better grip to do that!" + return + if(!G.confirm()) return G.affecting.loc = src.loc G.affecting.Weaken(5) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 1cb52101c57..b45d042f86f 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -1,5 +1,3 @@ -//todo: toothbrushes, and some sort of "toilet-filthinator" for the hos - /obj/structure/toilet name = "toilet" desc = "The HT-451, a torque rotation-based, waste disposal unit for small matter. This one seems remarkably clean." @@ -12,13 +10,15 @@ var/w_items = 0 //the combined w_class of all the items in the cistern var/mob/living/swirlie = null //the mob being given a swirlie + /obj/structure/toilet/New() open = round(rand(0, 1)) update_icon() -/obj/structure/toilet/attack_hand(mob/living/user as mob) + +/obj/structure/toilet/attack_hand(mob/living/user) if(swirlie) - usr.visible_message("[user] slams the toilet seat onto [swirlie]'s head!", "You slam the toilet seat onto [swirlie]'s head!", "You hear reverberating porcelain.") + user.visible_message("[user] slams the toilet seat onto [swirlie]'s head!", "You slam the toilet seat onto [swirlie]'s head!", "You hear reverberating porcelain.") swirlie.adjustBruteLoss(8) return @@ -39,10 +39,12 @@ open = !open update_icon() + /obj/structure/toilet/update_icon() icon_state = "toilet[open][cistern]" -/obj/structure/toilet/attackby(obj/item/I as obj, mob/living/user as mob) + +/obj/structure/toilet/attackby(obj/item/I, mob/living/user) if(istype(I, /obj/item/weapon/crowbar)) user << "You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]." playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1) @@ -54,13 +56,13 @@ if(istype(I, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = I - + if(!G.confirm()) + return if(isliving(G.affecting)) var/mob/living/GM = G.affecting - - if(G.state > 1) + if(G.state >= GRAB_AGGRESSIVE) if(GM.loc != get_turf(src)) - user << "[GM.name] needs to be on [src]." + user << "[GM] needs to be on [src]." return if(open && !swirlie) user.visible_message("[user] starts to give [GM] a swirlie!", "You start to give [GM] a swirlie!") @@ -103,12 +105,15 @@ density = 0 anchored = 1 + /obj/structure/urinal/attackby(obj/item/I, mob/user) if(istype(I, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = I + if(!G.confirm()) + return if(isliving(G.affecting)) var/mob/living/GM = G.affecting - if(G.state > 1) + if(G.state >= GRAB_AGGRESSIVE) if(GM.loc != get_turf(src)) user << "[GM.name] needs to on [src]." return @@ -133,7 +138,6 @@ var/watertemp = "normal" //freezing, normal, or boiling var/mobpresent = 0 //true if there is a mob on the shower's loc, this is to ease process() -//add heat controls? when emagged, you can freeze to death in it? /obj/effect/mist name = "mist" @@ -143,6 +147,7 @@ anchored = 1 mouse_opacity = 0 + /obj/machinery/shower/attack_hand(mob/M) on = !on update_icon() @@ -153,6 +158,7 @@ for (var/atom/movable/G in loc) G.clean_blood() + /obj/machinery/shower/attackby(obj/item/I, mob/user) if(I.type == /obj/item/device/analyzer) user << "The water temperature seems to be [watertemp]." @@ -168,6 +174,7 @@ watertemp = "normal" user.visible_message("[user] adjusts the shower with the [I].", "You adjust the shower with the [I].") + /obj/machinery/shower/update_icon() //this is terribly unreadable, but basically it makes the shower mist up overlays.Cut() //once it's been on for a while, in addition to handling the water overlay. if(mymist) @@ -193,6 +200,7 @@ del(mymist) ismist = 0 + /obj/machinery/shower/HasEntered(atom/movable/O) ..() wash(O) @@ -200,11 +208,13 @@ mobpresent += 1 check_heat(O) + /obj/machinery/shower/Uncrossed(atom/movable/O) if(ismob(O)) mobpresent -= 1 ..() + //Yes, showers are super powerful as far as washing goes. /obj/machinery/shower/proc/wash(atom/movable/O) if(!on) return @@ -282,11 +292,13 @@ if(istype(E,/obj/effect/rune) || istype(E,/obj/effect/decal/cleanable) || istype(E,/obj/effect/overlay)) del(E) + /obj/machinery/shower/process() if(!on || !mobpresent) return for(var/mob/living/carbon/C in loc) check_heat(C) + /obj/machinery/shower/proc/check_heat(mob/M) if(!on || watertemp == "normal") return if(iscarbon(M)) @@ -321,6 +333,7 @@ anchored = 1 var/busy = 0 //Something's being washed at the moment + /obj/structure/sink/attack_hand(mob/user) if(isrobot(user) || isAI(user)) return @@ -342,6 +355,7 @@ user.clean_blood() user.visible_message("[user] washes their hands in [src].") + /obj/structure/sink/attackby(obj/item/O, mob/user) if(busy) user << "Someone's already washing here." diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 5d2ce6005d8..c8d8f59816a 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -309,7 +309,7 @@ if ("grab") if (M == src) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, M, src) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src) M.put_in_active_hand(G) diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index bd3669f46e5..0f8445e6cab 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -284,7 +284,7 @@ if ("grab") if (M == src) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) M.put_in_active_hand(G) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index d2f721dc7dc..14f089b0ee7 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -352,6 +352,7 @@ if (istype(item, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = item item = G.throw() //throw the person instead of the grab + del(G) //We delete the grab, as it needs to stay around until it's returned. if(ismob(item)) var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors var/turf/end_T = get_turf(target) diff --git a/code/modules/mob/living/carbon/human/human_attackalien.dm b/code/modules/mob/living/carbon/human/human_attackalien.dm index ac9be4fc29b..7bbdfd71c7a 100644 --- a/code/modules/mob/living/carbon/human/human_attackalien.dm +++ b/code/modules/mob/living/carbon/human/human_attackalien.dm @@ -10,7 +10,7 @@ if(M == src) return if (w_uniform) w_uniform.add_fingerprint(M) - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, M, src) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src) M.put_in_active_hand(G) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 3faa4db79ca..3ef75e29e76 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -83,12 +83,13 @@ return 1 if("grab") - if(M == src) return 0 - if(w_uniform) w_uniform.add_fingerprint(M) - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, M, src) + if(M == src) + return 0 + if(w_uniform) + w_uniform.add_fingerprint(M) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src) M.put_in_active_hand(G) - grabbed_by += G G.synch() LAssailant = M diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index 6c222bbcbec..c71e701802a 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -456,7 +456,7 @@ if ("grab") if (M == src) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) M.put_in_active_hand(G) @@ -547,7 +547,7 @@ if ("grab") if (M == src) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) M.put_in_active_hand(G) diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 98ceb030e5e..c69514d370f 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -230,7 +230,7 @@ if (M == src) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) M.put_in_active_hand(G) @@ -299,7 +299,7 @@ if ("grab") if (M == src) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) M.put_in_active_hand(G) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index d1e3b371684..76523b879cd 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -588,7 +588,7 @@ if ("grab") if (M == src) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) M.put_in_active_hand(G) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 3091517fbce..4a3fc6c1c96 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -266,7 +266,7 @@ if (!(status_flags & CANPUSH)) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) M.put_in_active_hand(G) @@ -302,7 +302,7 @@ if(!(status_flags & CANPUSH)) return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M, M, src ) + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) M.put_in_active_hand(G) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 1a3d90e0120..faa3d0ea514 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -80,38 +80,11 @@ M.show_message( message, 1, blind_message, 2) -//This is awful -/mob/attackby(obj/item/weapon/W as obj, mob/user as mob) +//This is awful, still. +/mob/attackby(obj/item/I, mob/user) + if(I && istype(I)) //The istype is necessary for things like bodybags which are structures that do not have an attack() proc. + I.attack(src, user) - //Holding a balloon will shield you from an item that is_sharp() ... cause that makes sense - if (user.intent != "harm") - if (istype(src.l_hand,/obj/item/latexballon) && src.l_hand:air_contents && is_sharp(W)) - return src.l_hand.attackby(W) - if (istype(src.r_hand,/obj/item/latexballon) && src.r_hand:air_contents && is_sharp(W)) - return src.r_hand.attackby(W) - - //If src is grabbing someone and facing the attacker, the src will use the grabbed person as a shield - var/shielded = 0 - if (locate(/obj/item/weapon/grab, src)) - var/mob/safe = null - if (istype(src.l_hand, /obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = src.l_hand - if ((G.state == 3 && get_dir(src, user) == src.dir)) - safe = G.affecting - if (istype(src.r_hand, /obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = src.r_hand - if ((G.state == 3 && get_dir(src, user) == src.dir)) - safe = G.affecting - if (safe) - return safe.attackby(W, user) - - //If the mob is not wearing a shield or otherwise is not shielded - if ((!( shielded ) || !( W.flags ) & NOSHIELD)) - spawn( 0 ) - if (W && istype(W, /obj/item)) //The istype is necessary for things like bodybags which are structures that do not have an attack() proc. - W.attack(src, user) - return - return /mob/proc/findname(msg) for(var/mob/M in mob_list) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 05f460a6000..59be7c3bb7e 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -1,18 +1,17 @@ +#define UPGRADE_COOLDOWN 40 +#define UPGRADE_KILL_TIMER 100 + /obj/item/weapon/grab name = "grab" icon = 'icons/mob/screen1.dmi' icon_state = "grabbed" - var/obj/screen/grab/hud1 = null + var/obj/screen/grab/hud = null var/mob/affecting = null - var/atom/movable/structure = null // if the grab is not grabbing a mob var/mob/assailant = null - var/state = 1.0 + var/state = GRAB_PASSIVE - var/killing = 0.0 // 1 = about to kill, 2 = killing - var/kill_loc = null - - var/allow_upgrade = 1.0 - var/last_suffocate = 1.0 + var/allow_upgrade = 1 + var/last_upgrade = 0 layer = 21 abstract = 1.0 @@ -20,64 +19,60 @@ w_class = 5.0 +/obj/item/weapon/grab/New(mob/user, mob/victim) + ..() + loc = user + assailant = user + affecting = victim + + if(affecting.anchored) + del(src) + return + + hud = new /obj/screen/grab(src) + hud.icon_state = "reinforce" + hud.name = "reinforce grab" + hud.master = src + + +//Used by throw code to hand over the mob, instead of throwing the grab. The grab is then deleted by the throw code. /obj/item/weapon/grab/proc/throw() - if(affecting) - if(state >= 2) - var/grabee = affecting - spawn(1) - del(src) - return grabee - else - spawn(1) - del(src) - return null - - else if(structure) - var/grabee = structure - spawn(1) - del(src) - return grabee - + if(state >= GRAB_AGGRESSIVE) + return affecting return null +//This makes sure that the grab screen object is displayed in the correct hand. /obj/item/weapon/grab/proc/synch() if(affecting) - if(affecting.anchored)//This will prevent from grabbing people that are anchored. - del(src) - if (assailant.r_hand == src) - hud1.screen_loc = ui_rhand + if(assailant.r_hand == src) + hud.screen_loc = ui_rhand else - hud1.screen_loc = ui_lhand - return + hud.screen_loc = ui_lhand /obj/item/weapon/grab/process() + confirm() - update() + if(assailant.client) + assailant.client.screen -= hud + assailant.client.screen += hud - if (assailant.client) - assailant.client.screen -= hud1 - assailant.client.screen += hud1 - if (assailant.pulling == affecting || assailant.pulling == structure) + if(assailant.pulling == affecting) assailant.stop_pulling() - if (structure) - structure.loc = assailant.loc - structure.layer = assailant.layer + 1 - - if (state <= 2) + if(state <= GRAB_AGGRESSIVE) allow_upgrade = 1 - if ((assailant.l_hand && assailant.l_hand != src && istype(assailant.l_hand, /obj/item/weapon/grab))) + if((assailant.l_hand && assailant.l_hand != src && istype(assailant.l_hand, /obj/item/weapon/grab))) var/obj/item/weapon/grab/G = assailant.l_hand - if (G.affecting != affecting) + if(G.affecting != affecting) allow_upgrade = 0 - if ((assailant.r_hand && assailant.r_hand != src && istype(assailant.r_hand, /obj/item/weapon/grab))) + if((assailant.r_hand && assailant.r_hand != src && istype(assailant.r_hand, /obj/item/weapon/grab))) var/obj/item/weapon/grab/G = assailant.r_hand - if (G.affecting != affecting) + if(G.affecting != affecting) allow_upgrade = 0 - if (state == 2) + if(state == GRAB_AGGRESSIVE) var/h = affecting.hand affecting.hand = 0 affecting.drop_item() @@ -85,188 +80,122 @@ affecting.drop_item() affecting.hand = h for(var/obj/item/weapon/grab/G in affecting.grabbed_by) - if (G.state == 2) + if(G.state == GRAB_AGGRESSIVE) allow_upgrade = 0 - if (allow_upgrade) - hud1.icon_state = "reinforce" + if(allow_upgrade) + hud.icon_state = "reinforce" else - hud1.icon_state = "!reinforce" + hud.icon_state = "!reinforce" else - if (!( affecting.buckled )) + if(!affecting.buckled) affecting.loc = assailant.loc - if ((killing == 2 && state == 3)) - if(assailant.loc != kill_loc) - assailant.visible_message("[assailant] lost \his tightened grip on [affecting]'s neck!") - killing = 0 - hud1.icon_state = "disarm/kill" - return - affecting.Weaken(5) // Should keep you down unless you get help. - affecting.Stun(5) // It will hamper your voice, being choked and all. + + if(state >= GRAB_NECK) + affecting.Stun(5) //It will hamper your voice, being choked and all. + if(isliving(affecting)) + var/mob/living/L = affecting + L.adjustOxyLoss(1) + + if(state >= GRAB_KILL) + affecting.Weaken(5) //Should keep you down unless you get help. affecting.losebreath = min(affecting.losebreath + 2, 3) - return -/obj/item/weapon/grab/proc/s_click(obj/screen/S as obj) - if (!affecting) +/obj/item/weapon/grab/proc/s_click(obj/screen/S) + if(!affecting) return - if(killing) + if(state == GRAB_UPGRADING) return - if (assailant.next_move > world.time) + if(assailant.next_move > world.time) return - if ((!( assailant.canmove ) || assailant.lying)) - //SN src = null + if(last_upgrade > world.time + UPGRADE_COOLDOWN) + return + if(!assailant.canmove || assailant.lying) del(src) return - switch(S.id) - if(1.0) - if (state >= 3) - if (!( killing )) - assailant.visible_message("\red [assailant] has temporarily tightened \his grip on [affecting]!") - //Foreach goto(97) - assailant.next_move = world.time + 10 - //affecting.stunned = max(2, affecting.stunned) - //affecting.paralysis = max(1, affecting.paralysis) - affecting.losebreath = min(affecting.losebreath + 1, 3) - last_suffocate = world.time - flick("disarm/killf", S) - else - return + last_upgrade = world.time -/obj/item/weapon/grab/proc/s_dbclick(obj/screen/S as obj) - //if ((assailant.next_move > world.time && !( last_suffocate < world.time + 2 ))) - // return - - if (!affecting) - return - if ((!( assailant.canmove ) || assailant.lying)) - del(src) - return - if(killing) - return - - switch(S.id) - if(1.0) - if (state < 2) - if (!( allow_upgrade )) + if(state < GRAB_AGGRESSIVE) + if(!allow_upgrade) + return + assailant.visible_message("[assailant] has grabbed [affecting] aggressively (now hands)!") + state = GRAB_AGGRESSIVE + icon_state = "grabbed1" + else + if(state < GRAB_NECK) + if(istype(affecting, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = affecting + if(FAT in H.mutations) + assailant << "You can't strangle [affecting] through all that fat!" return - assailant.visible_message("[assailant] has grabbed [affecting] aggressively (now hands)!") - state = 2 - icon_state = "grabbed1" - /*if (prob(75)) - for(var/mob/O in viewers(assailant, null)) - O.show_message(text("\red [] has grabbed [] aggressively (now hands)!", assailant, affecting), 1) - state = 2 - icon_state = "grabbed1" - else - for(var/mob/O in viewers(assailant, null)) - O.show_message(text("\red [] has failed to grab [] aggressively!", assailant, affecting), 1) - del(src) - return*/ - else - if (state < 3) - if(istype(affecting, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = affecting - if(FAT in H.mutations) - assailant << "You can't strangle [affecting] through all that fat!" - return - /*Hrm might want to add this back in - //we should be able to strangle the Captain if he is wearing a hat - for(var/obj/item/clothing/C in list(H.head, H.wear_suit, H.wear_mask, H.w_uniform)) - if(C.body_parts_covered & HEAD) - assailant << "\blue You have to take off [affecting]'s [C.name] first!" - return + if(isslime(affecting)) + assailant << "You squeeze [affecting], but nothing interesting happens." + return - if(istype(H.wear_suit, /obj/item/clothing/suit/space) || istype(H.wear_suit, /obj/item/clothing/suit/armor) || istype(H.wear_suit, /obj/item/clothing/suit/bio_suit) || istype(H.wear_suit, /obj/item/clothing/suit/swat_suit)) - assailant << "\blue You can't strangle [affecting] through their suit collar!" - return - */ - - if(istype(affecting, /mob/living/carbon/slime)) - assailant << "You squeeze [affecting], but nothing interesting happens." + assailant.visible_message("[assailant] has reinforced \his grip on [affecting] (now neck)!") + state = GRAB_NECK + icon_state = "grabbed+1" + if(!affecting.buckled) + affecting.loc = assailant.loc + affecting.attack_log += "\[[time_stamp()]\] Has had their neck grabbed by [assailant.name] ([assailant.ckey])" + assailant.attack_log += "\[[time_stamp()]\] Grabbed the neck of [affecting.name] ([affecting.ckey])" + log_attack("[assailant.name] ([assailant.ckey]) grabbed the neck of [affecting.name] ([affecting.ckey])") + hud.icon_state = "disarm/kill" + hud.name = "disarm/kill" + else + if(state < GRAB_UPGRADING) + assailant.visible_message("[assailant] starts to tighten \his grip on [affecting]'s neck!") + hud.icon_state = "disarm/kill1" + state = GRAB_UPGRADING + if(do_after(assailant, UPGRADE_KILL_TIMER)) + if(state == GRAB_KILL) return + if(!affecting) + del(src) + return + if(!assailant.canmove || assailant.lying) + del(src) + return + state = GRAB_KILL + assailant.visible_message("[assailant] has tightened \his grip on [affecting]'s neck!") + affecting.attack_log += "\[[time_stamp()]\] Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])" + assailant.attack_log += "\[[time_stamp()]\] Strangled (kill intent) [affecting.name] ([affecting.ckey])" + log_attack("[assailant.name] ([assailant.ckey]) Strangled (kill intent) [affecting.name] ([affecting.ckey])") - assailant.visible_message("[assailant] has reinforced \his grip on [affecting] (now neck)!") - state = 3 - icon_state = "grabbed+1" - if (!( affecting.buckled )) - affecting.loc = assailant.loc - affecting.attack_log += text("\[[time_stamp()]\] Has had their neck grabbed by [assailant.name] ([assailant.ckey])") - assailant.attack_log += text("\[[time_stamp()]\] Grabbed the neck of [affecting.name] ([affecting.ckey])") - log_attack("[assailant.name] ([assailant.ckey]) grabbed the neck of [affecting.name] ([affecting.ckey])") - hud1.icon_state = "disarm/kill" - hud1.name = "disarm/kill" + assailant.next_move = world.time + 10 + affecting.losebreath += 1 else - if (state >= 3 && !killing) - assailant.visible_message("[assailant] starts to tighten \his grip on [affecting]'s neck!") - hud1.icon_state = "disarm/kill1" - killing = 1 - if(do_after(assailant, 40)) - if(killing == 2) - return - if(!affecting) - del(src) - return - if ((!( assailant.canmove ) || assailant.lying)) - del(src) - return - killing = 2 - kill_loc = assailant.loc - assailant.visible_message("[assailant] has tightened \his grip on [affecting]'s neck!") - affecting.attack_log += text("\[[time_stamp()]\] Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])") - assailant.attack_log += text("\[[time_stamp()]\] Strangled (kill intent) [affecting.name] ([affecting.ckey])") - log_attack("[assailant.name] ([assailant.ckey]) Strangled (kill intent) [affecting.name] ([affecting.ckey])") - - assailant.next_move = world.time + 10 - affecting.losebreath += 1 - else - assailant.visible_message("[assailant] was unable to tighten \his grip on [affecting]'s neck!") - killing = 0 - hud1.icon_state = "disarm/kill" - return + assailant.visible_message("[assailant] was unable to tighten \his grip on [affecting]'s neck!") + hud.icon_state = "disarm/kill" + state = GRAB_NECK -/obj/item/weapon/grab/New(var/location, mob/user as mob, mob/affected as mob) - ..() - src.loc = location - src.assailant = user - src.affecting = affected - // HUD - hud1 = new /obj/screen/grab( src ) - hud1.icon_state = "reinforce" - hud1.name = "Reinforce Grab" - hud1.id = 1 - hud1.master = src - return - -/obj/item/weapon/grab/proc/update() - if(!assailant || (!affecting && !structure)) +//This is used to make sure the victim hasn't managed to yackety sax away before using the grab. +/obj/item/weapon/grab/proc/confirm() + if(!assailant || !affecting) del(src) - return + return 0 - if(affecting && !structure) - if ((!( isturf(assailant.loc) ) || (!( isturf(affecting.loc) ) || (assailant.loc != affecting.loc && get_dist(assailant, affecting) > 1)))) - //SN src = null + if(affecting) + if(!isturf(assailant.loc) || ( !isturf(affecting.loc) || assailant.loc != affecting.loc && get_dist(assailant, affecting) > 1) ) del(src) - return - else if(!affecting && structure) - if (!isturf(structure.loc) || !isturf(structure.loc) || (assailant.loc != structure.loc && get_dist(assailant, structure) > 1)) - del(src) - return + return 0 + return 1 -/obj/item/weapon/grab/attack(mob/M as mob, mob/user as mob) - if(!affecting) return - if (M == affecting) - if (state < 3) - s_dbclick(hud1) - else - s_click(hud1) +/obj/item/weapon/grab/attack(mob/M, mob/user) + if(!affecting) return - if(M == assailant && state >= 2) - if( ( ishuman(user) && (FAT in user.mutations) && ismonkey(affecting) ) || ( isalien(user) && iscarbon(affecting) ) ) + + if(M == affecting) + s_click(hud) + return + + if(M == assailant && state >= GRAB_AGGRESSIVE) + if( (ishuman(user) && (FAT in user.mutations) && ismonkey(affecting) ) || ( isalien(user) && iscarbon(affecting) ) ) var/mob/living/carbon/attacker = user user.visible_message("[user] is attempting to devour [affecting]!") if(istype(user, /mob/living/carbon/alien/humanoid/hunter)) @@ -281,10 +210,7 @@ /obj/item/weapon/grab/dropped() del(src) - return - /obj/item/weapon/grab/Del() - del(hud1) - ..() - return \ No newline at end of file + del(hud) + ..() \ No newline at end of file diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 77f97bf356f..3b33257d711 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -351,23 +351,31 @@ /client/proc/Process_Grab() if(locate(/obj/item/weapon/grab, locate(/obj/item/weapon/grab, mob.grabbed_by.len))) var/list/grabbing = list() + if(istype(mob.l_hand, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = mob.l_hand grabbing += G.affecting + if(istype(mob.r_hand, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = mob.r_hand grabbing += G.affecting + for(var/obj/item/weapon/grab/G in mob.grabbed_by) - if((G.state == 1)&&(!grabbing.Find(G.assailant))) del(G) - if(G.state == 2) - move_delay = world.time + 10 - if(!prob(25)) return 1 - mob.visible_message("\red [mob] has broken free of [G.assailant]'s grip!") + if(G.state == GRAB_PASSIVE && !grabbing.Find(G.assailant)) del(G) - if(G.state == 3) + + if(G.state == GRAB_AGGRESSIVE) move_delay = world.time + 10 - if(!prob(5)) return 1 - mob.visible_message("\red [mob] has broken free of [G.assailant]'s headlock!") + if(!prob(25)) + return 1 + mob.visible_message("[mob] has broken free of [G.assailant]'s grip!") + del(G) + + if(G.state == GRAB_NECK) + move_delay = world.time + 10 + if(!prob(5)) + return 1 + mob.visible_message("[mob] has broken free of [G.assailant]'s headlock!") del(G) return 0 diff --git a/code/modules/mob/screen.dm b/code/modules/mob/screen.dm index 7872601f80e..03fbcea0be5 100644 --- a/code/modules/mob/screen.dm +++ b/code/modules/mob/screen.dm @@ -3,7 +3,6 @@ icon = 'icons/mob/screen1.dmi' layer = 20.0 unacidable = 1 - var/id = 0.0 var/obj/master /obj/screen/text @@ -57,21 +56,21 @@ /obj/screen/grab name = "grab" + icon = 'icons/mob/screen1.dmi' master = null /obj/screen/storage name = "storage" master = null -/obj/screen/storage/attack_hand(mob/user as mob) - if(src.master) +/obj/screen/storage/attack_hand(mob/user) + if(master) var/obj/item/I = user.get_active_hand() if(I) - src.master.attackby(I, user) - return + master.attackby(I, user) /obj/screen/zone_sel - name = "Damage Zone" + name = "damage zone" icon = 'icons/mob/screen1.dmi' icon_state = "zone_sel" var/selecting = "chest" @@ -229,12 +228,8 @@ return /obj/screen/grab/Click() - master:s_click(src) - return - -/obj/screen/grab/DblClick() - master:s_dbclick(src) - return + var/obj/item/weapon/grab/G = master + G.s_click(src) /obj/screen/grab/attack_hand() return @@ -521,49 +516,44 @@ var/mob/living/L = usr //resisting grabs (as if it helps anyone...) - if ((!( L.stat ) && L.canmove && !( L.restrained() ))) + if(!L.stat && L.canmove && !L.restrained()) var/resisting = 0 for(var/obj/O in L.requests) del(O) resisting++ for(var/obj/item/weapon/grab/G in usr.grabbed_by) resisting++ - if (G.state == 1) + if(G.state == GRAB_PASSIVE) del(G) else - if (G.state == 2) - if (prob(25)) - for(var/mob/O in viewers(L, null)) - O.show_message(text("\red [] has broken free of []'s grip!", L, G.assailant), 1) + if(G.state == GRAB_AGGRESSIVE) + if(prob(25)) + L.visible_message("[L] has broken free of [G.assailant]'s grip!") del(G) else - if (G.state == 3) - if (prob(5)) - for(var/mob/O in viewers(usr, null)) - O.show_message(text("\red [] has broken free of []'s headlock!", L, G.assailant), 1) + if(G.state == GRAB_NECK) + if(prob(5)) + L.visible_message("[L] has broken free of [G.assailant]'s headlock!") del(G) if(resisting) - for(var/mob/O in viewers(usr, null)) - O.show_message(text("\red [] resists!", L), 1) + L.visible_message("[L] resists!") //unbuckling yourself - if(L.buckled && (L.last_special <= world.time) ) + if(L.buckled && L.last_special <= world.time) if(iscarbon(L)) var/mob/living/carbon/C = L - if( C.handcuffed ) + if(C.handcuffed) C.next_move = world.time + 100 C.last_special = world.time + 100 - C << "\red You attempt to unbuckle yourself. (This will take around 2 minutes and you need to stand still)" - for(var/mob/O in viewers(L)) - O.show_message("\red [usr] attempts to unbuckle themself!", 1) + C.visible_message("[usr] attempts to unbuckle themself!", \ + "You attempt to unbuckle yourself. (This will take around 2 minutes and you need to stay still.)") spawn(0) if(do_after(usr, 1200)) if(!C.buckled) return - for(var/mob/O in viewers(C)) - O.show_message("\red [usr] manages to unbuckle themself!", 1) - C << "\blue You successfully unbuckle yourself." + C.visible_message("[usr] manages to unbuckle themself!", \ + "You successfully unbuckle yourself.") C.buckled.manual_unbuckle(C) else L.buckled.manual_unbuckle(L) @@ -588,9 +578,9 @@ //okay, so the closet is either welded or locked... resist!!! usr.next_move = world.time + 100 L.last_special = world.time + 100 - L << "\red You lean on the back of \the [C] and start pushing the door open. (this will take about [breakout_time] minutes)" + L << "You lean on the back of [C] and start pushing the door open. (this will take about [breakout_time] minutes.)" for(var/mob/O in viewers(usr.loc)) - O.show_message("\red The [L.loc] begins to shake violently!", 1) + O << "[C] begins to shake violently!" spawn(0) @@ -618,18 +608,16 @@ sleep(10) SC.broken = 1 SC.locked = 0 - usr << "\red You successfully break out!" - for(var/mob/O in viewers(L.loc)) - O.show_message("\red \the [usr] successfully broke out of \the [SC]!", 1) + L.visible_message("[L] successfully broke out of [SC]!", \ + "You successfully break out of [SC]!") if(istype(SC.loc, /obj/structure/bigDelivery)) //Do this to prevent contents from being opened into nullspace (read: bluespace) var/obj/structure/bigDelivery/BD = SC.loc BD.attack_hand(usr) SC.open() else C.welded = 0 - usr << "\red You successfully break out!" - for(var/mob/O in viewers(L.loc)) - O.show_message("\red \the [usr] successfully broke out of \the [C]!", 1) + L.visible_message("[L] successfully broke out of [C]!", \ + "You successfully break out of [C]!") if(istype(C.loc, /obj/structure/bigDelivery)) //nullspace ect.. read the comment above var/obj/structure/bigDelivery/BD = C.loc BD.attack_hand(usr) @@ -642,16 +630,14 @@ CM.next_move = world.time + 100 CM.last_special = world.time + 100 if(isalienadult(CM) || (HULK in usr.mutations))//Don't want to do a lot of logic gating here. - usr << "\red You attempt to break your handcuffs. (This will take around 5 seconds and you need to stand still)" - for(var/mob/O in viewers(CM)) - O.show_message(text("\red [] is trying to break the handcuffs!", CM), 1) + CM.visible_message("[CM] is trying to break [CM.handcuffed]!", \ + "You attempt to break [CM.handcuffed]. (This will take around 5 seconds and you need to stand still.)") spawn(0) if(do_after(CM, 50)) if(!CM.handcuffed || CM.buckled) return - for(var/mob/O in viewers(CM)) - O.show_message(text("\red [] manages to break the handcuffs!", CM), 1) - CM << "\red You successfully break your handcuffs." + CM.visible_message("[CM] manages to break [CM.handcuffed]!" , \ + "You successfully break [CM.handcuffed]!") CM.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) del(CM.handcuffed) CM.handcuffed = null @@ -663,16 +649,14 @@ if(istype(HC)) //If you are handcuffed with actual handcuffs... Well what do I know, maybe someone will want to handcuff you with toilet paper in the future... breakouttime = HC.breakouttime displaytime = breakouttime / 600 //Minutes - CM << "\red You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)" - for(var/mob/O in viewers(CM)) - O.show_message( "\red [usr] attempts to remove \the [HC]!", 1) + CM.visible_message("[usr] attempts to remove [HC]!", \ + "You attempt to remove [HC]. (This will take around [displaytime] minutes and you need to stand still.)") spawn(0) if(do_after(CM, breakouttime)) if(!CM.handcuffed || CM.buckled) return // time leniency for lag which also might make this whole thing pointless but the server - for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink - O.show_message("\red [CM] manages to remove the handcuffs!", 1) - CM << "\blue You successfully remove \the [CM.handcuffed]." + CM.visible_message("[CM] manages to remove [CM.handcuffed]!", \ + "You successfully remove [CM.handcuffed].") CM.handcuffed.loc = usr.loc CM.handcuffed = null CM.update_inv_handcuffed(0) @@ -680,16 +664,14 @@ CM.next_move = world.time + 100 CM.last_special = world.time + 100 if(isalienadult(CM) || (HULK in usr.mutations))//Don't want to do a lot of logic gating here. - usr << "\red You attempt to break your legcuffs. (This will take around 5 seconds and you need to stand still)" - for(var/mob/O in viewers(CM)) - O.show_message(text("\red [] is trying to break the legcuffs!", CM), 1) + CM.visible_message("[CM] is trying to break [CM.legcuffed]!", \ + "You attempt to break [CM.legcuffed]. (This will take around 5 seconds and you need to stand still.)") spawn(0) if(do_after(CM, 50)) if(!CM.legcuffed || CM.buckled) return - for(var/mob/O in viewers(CM)) - O.show_message(text("\red [] manages to break the legcuffs!", CM), 1) - CM << "\red You successfully break your legcuffs." + CM.visible_message("[CM] manages to break [CM.legcuffed]!", \ + "You successfully break [CM.legcuffed].") CM.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) del(CM.legcuffed) CM.legcuffed = null @@ -701,16 +683,14 @@ if(istype(HC)) //If you are legcuffed with actual legcuffs... Well what do I know, maybe someone will want to legcuff you with toilet paper in the future... breakouttime = HC.breakouttime displaytime = breakouttime / 600 //Minutes - CM << "\red You attempt to remove \the [HC]. (This will take around [displaytime] minutes and you need to stand still)" - for(var/mob/O in viewers(CM)) - O.show_message( "\red [usr] attempts to remove \the [HC]!", 1) + CM.visible_message("[CM] attempts to remove [HC]!", \ + "You attempt to remove [HC]. (This will take around [displaytime] minutes and you need to stand still.)") spawn(0) if(do_after(CM, breakouttime)) if(!CM.legcuffed || CM.buckled) - return // time leniency for lag which also might make this whole thing pointless but the server - for(var/mob/O in viewers(CM))// lags so hard that 40s isn't lenient enough - Quarxink - O.show_message("\red [CM] manages to remove the legcuffs!", 1) - CM << "\blue You successfully remove \the [CM.legcuffed]." + return //time leniency for lag which also might make this whole thing pointless but the server + CM.visible_message("[CM] manages to remove [CM.legcuffed]!", \ + "You successfully remove [CM.legcuffed].") CM.legcuffed.loc = usr.loc CM.legcuffed = null CM.update_inv_legcuffed(0) \ No newline at end of file diff --git a/code/setup.dm b/code/setup.dm index 90bb652a922..278db4f6f05 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -430,6 +430,13 @@ var/list/global_mutations = list() // list of hidden mutation things var/static/list/scarySounds = list('sound/weapons/thudswoosh.ogg','sound/weapons/Taser.ogg','sound/weapons/armbomb.ogg','sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg','sound/voice/hiss5.ogg','sound/voice/hiss6.ogg','sound/effects/Glassbr1.ogg','sound/effects/Glassbr2.ogg','sound/effects/Glassbr3.ogg','sound/items/Welder.ogg','sound/items/Welder2.ogg','sound/machines/airlock.ogg','sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg') +//Grab levels +#define GRAB_PASSIVE 1 +#define GRAB_AGGRESSIVE 2 +#define GRAB_NECK 3 +#define GRAB_UPGRADING 4 +#define GRAB_KILL 5 + //Security levels #define SEC_LEVEL_GREEN 0 #define SEC_LEVEL_BLUE 1 diff --git a/html/changelog.html b/html/changelog.html index 4dc786c7f93..0d1fdcc412c 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,7 @@ should be listed in the changelog upon commit tho. Thanks. -->

Petethegoat updated:

diff --git a/icons/mob/screen1.dmi b/icons/mob/screen1.dmi index 6040e7107ce..7ba0ca6f792 100644 Binary files a/icons/mob/screen1.dmi and b/icons/mob/screen1.dmi differ