Merges Pull and Grab into a single functionality. Pulling someone is now the same as a passive grab. You can start pulling someone with ctrlclick or by using the grab intent with empty hand. Using the grab intent again on the pulled person tries to grab them aggressively, then neck grab, then kill grab.

Two mobs can no longer pull the same mob at the same time. Pulling someone break any other pull/grab from other mob on that person.

The grab item is gone entirely.

You can now only grab one mob at a time, instead of two (one for each hand).

Being aggressively grabbed or more now counts as being restrained (like handcuffed). A neck grab or more makes you lie down and prevents you from getting up until the grab is broken.

Fixes movement when moving with a grabbed person.
Fixes movement when moving a pulled person around you diagonally.
Fixes neckgrab moving the victim on your turf even if the turf is dense.
This commit is contained in:
phil235
2016-05-24 01:28:04 +02:00
parent 910d1e1ffe
commit 11ca987acb
62 changed files with 518 additions and 893 deletions

View File

@@ -39,11 +39,10 @@
//Grab levels
#define GRAB_PASSIVE 1
#define GRAB_AGGRESSIVE 2
#define GRAB_NECK 3
#define GRAB_UPGRADING 4
#define GRAB_KILL 5
#define GRAB_PASSIVE 0
#define GRAB_AGGRESSIVE 1
#define GRAB_NECK 2
#define GRAB_KILL 3
//Hostile Mob AI Status

View File

@@ -150,8 +150,9 @@
#define CLICK_CD_RANGE 4
#define CLICK_CD_BREAKOUT 100
#define CLICK_CD_HANDCUFFED 10
#define CLICK_CD_TKSTRANGLE 10
#define CLICK_CD_RESIST 20
#define CLICK_CD_GRABBING 10
//click cooldowns, in tenths of a second
@@ -423,3 +424,7 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
// Shuttle return values
#define SHUTTLE_ALREADY_DOCKED 7
// Diagonal movement
#define FIRST_DIAG_STEP 1
#define SECOND_DIAG_STEP 2

View File

@@ -77,7 +77,7 @@
CtrlClickOn(A)
return
if(stat || paralysis || stunned || weakened || sleeping)
if(incapacitated(ignore_restraints = 1))
return
face_atom(A)

View File

@@ -159,20 +159,6 @@
/obj/screen/drop/Click()
usr.drop_item_v()
/obj/screen/grab
name = "grab"
/obj/screen/grab/Click()
var/obj/item/weapon/grab/G = master
G.s_click(src)
return 1
/obj/screen/grab/attack_hand()
return
/obj/screen/grab/attackby()
return
/obj/screen/act_intent
name = "intent"
icon_state = "help"

View File

@@ -45,10 +45,6 @@
if(affected_mob.notransform)
return
affected_mob.notransform = 1
affected_mob.canmove = 0
affected_mob.icon = null
affected_mob.overlays.Cut()
affected_mob.invisibility = INVISIBILITY_ABSTRACT
for(var/obj/item/W in affected_mob)
if(istype(W, /obj/item/weapon/implant))
qdel(W)

View File

@@ -323,10 +323,16 @@
add_to_streak("G",D)
if(check_streak(A,D))
return 1
D.grabbedby(A,1)
var/obj/item/weapon/grab/G = A.get_active_hand()
if(G)
G.state = GRAB_AGGRESSIVE //Instant aggressive grab
if(A.grab_state > GRAB_AGGRESSIVE)
D.grabbedby(A, 1)
else
A.start_pulling(D, 1)
if(A.pulling)
D.drop_r_hand()
D.drop_l_hand()
D.stop_pulling()
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
return 1
/datum/martial_art/the_sleeping_carp/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
add_to_streak("H",D)

View File

@@ -13,10 +13,12 @@
var/verb_yell = "yells"
var/inertia_dir = 0
var/pass_flags = 0
var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move
glide_size = 8
appearance_flags = TILE_BOUND
/atom/movable/Move(atom/newloc, direct = 0)
if(!loc || !newloc) return 0
var/atom/oldloc = loc
@@ -25,28 +27,38 @@
if (!(direct & (direct - 1))) //Cardinal move
. = ..()
else //Diagonal move, split it into cardinal moves
moving_diagonally = FIRST_DIAG_STEP
if (direct & 1)
if (direct & 4)
if (step(src, NORTH))
moving_diagonally = SECOND_DIAG_STEP
. = step(src, EAST)
else if (step(src, EAST))
moving_diagonally = SECOND_DIAG_STEP
. = step(src, NORTH)
else if (direct & 8)
if (step(src, NORTH))
moving_diagonally = SECOND_DIAG_STEP
. = step(src, WEST)
else if (step(src, WEST))
moving_diagonally = SECOND_DIAG_STEP
. = step(src, NORTH)
else if (direct & 2)
if (direct & 4)
if (step(src, SOUTH))
moving_diagonally = SECOND_DIAG_STEP
. = step(src, EAST)
else if (step(src, EAST))
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
else if (direct & 8)
if (step(src, SOUTH))
moving_diagonally = SECOND_DIAG_STEP
. = step(src, WEST)
else if (step(src, WEST))
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
moving_diagonally = 0
if(!loc || (loc == oldloc && oldloc != newloc))
last_move = 0
@@ -80,10 +92,8 @@
qdel(AM)
loc = null
invisibility = INVISIBILITY_ABSTRACT
if (pulledby)
if (pulledby.pulling == src)
pulledby.pulling = null
pulledby = null
if(pulledby)
pulledby.stop_pulling()
// Previously known as HasEntered()
@@ -104,6 +114,8 @@
/atom/movable/proc/forceMove(atom/destination)
if(destination)
if(pulledby)
pulledby.stop_pulling()
var/atom/oldloc = loc
if(oldloc)
oldloc.Exited(src, destination)
@@ -123,8 +135,6 @@
/mob/living/forceMove(atom/destination)
stop_pulling()
if(pulledby)
pulledby.stop_pulling()
if(buckled)
buckled.unbuckle_mob(src,force=1)
if(buckled_mobs.len)
@@ -199,6 +209,9 @@
return 0
//use a modified version of Bresenham's algorithm to get from the atom's current position to that of the target
if(pulledby)
pulledby.stop_pulling()
throwing = 1
if(spin) //if we don't want the /atom/movable to spin.
SpinAnimation(5, 1)

View File

@@ -15,23 +15,21 @@
user << "<span class='warning'>We are already absorbing!</span>"
return
var/obj/item/weapon/grab/G = user.get_active_hand()
if(!istype(G))
user << "<span class='warning'>We must be grabbing a creature in our active hand to absorb them!</span>"
if(!user.pulling || !iscarbon(user.pulling))
user << "<span class='warning'>We must be grabbing a creature to absorb them!</span>"
return
if(G.state <= GRAB_NECK)
if(user.grab_state <= GRAB_NECK)
user << "<span class='warning'>We must have a tighter grip to absorb this creature!</span>"
return
var/mob/living/carbon/target = G.affecting
var/mob/living/carbon/target = user.pulling
return changeling.can_absorb_dna(user,target)
/obj/effect/proc_holder/changeling/absorbDNA/sting_action(mob/user)
var/datum/changeling/changeling = user.mind.changeling
var/obj/item/weapon/grab/G = user.get_active_hand()
var/mob/living/carbon/human/target = G.affecting
var/mob/living/carbon/human/target = user.pulling
changeling.isabsorbing = 1
for(var/stage = 1, stage<=3, stage++)
switch(stage)
@@ -122,11 +120,10 @@
/obj/effect/proc_holder/changeling/swap_form/can_sting(mob/living/carbon/user)
if(!..())
return
var/obj/item/weapon/grab/G = user.get_active_hand()
if(!istype(G) || (G.state < GRAB_AGGRESSIVE))
user << "<span class='warning'>We must have an aggressive grab on creature in our active hand to do this!</span>"
if(!user.pulling || !iscarbon(user.pulling) || user.grab_state < GRAB_AGGRESSIVE)
user << "<span class='warning'>We must have an aggressive grab on creature to do this!</span>"
return
var/mob/living/carbon/target = G.affecting
var/mob/living/carbon/target = user.pulling
if((target.disabilities & NOCLONE) || (target.disabilities & HUSK))
user << "<span class='warning'>DNA of [target] is ruined beyond usability!</span>"
return
@@ -137,8 +134,7 @@
/obj/effect/proc_holder/changeling/swap_form/sting_action(mob/living/carbon/user)
var/obj/item/weapon/grab/G = user.get_active_hand()
var/mob/living/carbon/target = G.affecting
var/mob/living/carbon/target = user.pulling
var/datum/changeling/changeling = user.mind.changeling
user << "<span class='notice'>We tighen our grip. We must hold still....</span>"

View File

@@ -27,7 +27,7 @@ var/hsboxspawn = 1
var/hsbinfo = null
//items that shouldn't spawn on the floor because they would bug or act weird
var/global/list/spawn_forbidden = list(
/obj/item/weapon/grab, /obj/item/tk_grab, /obj/item/weapon/implant, // not implanter, the actual thing that is inside you
/obj/item/tk_grab, /obj/item/weapon/implant, // not implanter, the actual thing that is inside you
/obj/item/assembly,/obj/item/device/onetankbomb, /obj/item/radio, /obj/item/device/pda/ai,
/obj/item/device/uplink, /obj/item/smallDelivery, /obj/item/missile,/obj/item/projectile,
/obj/item/borg/sight,/obj/item/borg/stun,/obj/item/weapon/robot_module)

View File

@@ -152,19 +152,6 @@
if(default_deconstruction_crowbar(I))
return
if(istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I
if(!ismob(G.affecting))
return
if(!state_open)
user << "<span class='notice'>Open the scanner first.</span>"
return
var/mob/M = G.affecting
M.forceMove(loc)
qdel(G)
return
return ..()
/obj/machinery/dna_scannernew/attack_hand(mob/user)

View File

@@ -192,14 +192,6 @@
if(default_deconstruction_screwdriver(user, null, null, W))
update_icon()
return
else if(istype(W,/obj/item/weapon/grab))
if(state_open)
var/obj/item/weapon/grab/G = W
if(iscorgi(G.affecting))
has_corgi = 1
G.affecting.loc = src
qdel(G)
update_icon()
else if(user.a_intent != "harm")
@@ -232,6 +224,17 @@
user << "<span class='warning'>[src] is busy.</span>"
return
if(user.pulling && user.a_intent == "grab" && isliving(user.pulling))
var/mob/living/L = user.pulling
if(L.buckled || L.buckled_mobs.len)
return
if(state_open)
if(iscorgi(L))
has_corgi = 1
L.forceMove(src)
update_icon()
return
if(!state_open)
open_machine()
else

View File

@@ -409,7 +409,7 @@ obj/item/proc/item_action_slot_check(slot, mob/user)
set category = "Object"
set name = "Pick up"
if(usr.stat || usr.restrained() || !Adjacent(usr) || usr.stunned || usr.weakened || usr.lying)
if(usr.incapacitated() || !Adjacent(usr) || usr.lying)
return
if(usr.get_active_hand() == null) // Let me know if this has any problems -Yota

View File

@@ -69,24 +69,7 @@
add_implants()
ready = 1
src.updateUsrDialog()
return
/obj/machinery/implantchair/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = W
if(!ismob(G.affecting))
return
var/mob/M = G.affecting
if(M.buckled_mobs.len)
user << "[M] will not fit into [src] because they have a creature on them!"
return
if(put_mob(M))
qdel(G)
updateUsrDialog()
else
return ..()
updateUsrDialog()
/obj/machinery/implantchair/go_out(mob/M)

View File

@@ -85,7 +85,7 @@
qdel(src)
singulo.process()
return
..()
. = ..()
/obj/item/weapon/storage/backpack/holding/proc/failcheck(mob/user)
if (prob(src.reliability)) return 1 //No failure

View File

@@ -198,6 +198,8 @@
if(!S.amount)
qdel(S)
else
if(S.pulledby)
S.pulledby.stop_pulling()
S.loc = src
orient2hud(usr)
@@ -342,7 +344,7 @@
/obj/item/weapon/storage/bag/tray/handle_item_insertion(obj/item/I, prevent_warning = 0)
overlays += image("icon" = I.icon, "icon_state" = I.icon_state, "layer" = -1)
..()
. = ..()
/*

View File

@@ -301,6 +301,8 @@
return 0
if(silent)
prevent_warning = 1
if(W.pulledby)
W.pulledby.stop_pulling()
W.loc = src
W.on_enter_storage(src)
if(usr)

View File

@@ -51,7 +51,7 @@
combined_access |= I.access
/obj/item/weapon/storage/wallet/handle_item_insertion(obj/item/W, prevent_warning = 0)
. = ..(W, prevent_warning)
. = ..()
if(.)
if(istype(W, /obj/item/weapon/card/id))
refreshID()

View File

@@ -50,38 +50,37 @@
qdel(src)
else
user << "<span class='notice'>You can't do that while something's on the spike!</span>"
else if(istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I
if(istype(G.affecting, /mob/living/))
if(!buckled_mobs.len)
if(do_mob(user, src, 120))
if(buckled_mobs.len) //to prevent spam/queing up attacks
return
if(G.affecting.buckled)
return
var/mob/living/H = G.affecting
playsound(src.loc, "sound/effects/splat.ogg", 25, 1)
H.visible_message("<span class='danger'>[user] slams [G.affecting] onto the meat spike!</span>", "<span class='userdanger'>[user] slams you onto the meat spike!</span>", "<span class='italics'>You hear a squishy wet noise.</span>")
H.loc = src.loc
H.emote("scream")
if(istype(H, /mob/living/carbon/human)) //So you don't get human blood when you spike a giant spidere
var/turf/pos = get_turf(H)
pos.add_blood_floor(H)
H.adjustBruteLoss(30)
H.buckled = src
H.dir = 2
buckle_mob(H, force=1)
var/matrix/m180 = matrix(H.transform)
m180.Turn(180)
animate(H, transform = m180, time = 3)
H.pixel_y = H.get_standard_pixel_y_offset(180)
qdel(G)
return
user << "<span class='danger'>You can't use that on the spike!</span>"
else
return ..()
/obj/structure/kitchenspike/attack_hand(mob/user)
if(user.pulling && isliving(user.pulling) && user.a_intent == "grab" && !buckled_mobs.len)
var/mob/living/L = user.pulling
if(do_mob(user, src, 120))
if(buckled_mobs.len) //to prevent spam/queing up attacks
return
if(L.buckled)
return
playsound(src.loc, "sound/effects/splat.ogg", 25, 1)
L.visible_message("<span class='danger'>[user] slams [L] onto the meat spike!</span>", "<span class='userdanger'>[user] slams you onto the meat spike!</span>", "<span class='italics'>You hear a squishy wet noise.</span>")
L.loc = src.loc
L.emote("scream")
if(ishuman(L)) //So you don't get human blood when you spike a giant spider
var/turf/pos = get_turf(L)
pos.add_blood_floor(L)
L.adjustBruteLoss(30)
L.buckled = src
L.dir = 2
buckle_mob(L, force=1)
var/matrix/m180 = matrix(L.transform)
m180.Turn(180)
animate(L, transform = m180, time = 3)
L.pixel_y = L.get_standard_pixel_y_offset(180)
else
..()
/obj/structure/kitchenspike/user_buckle_mob(mob/living/M, mob/living/user) //Don't want them getting put on the rack other than by spiking
return

View File

@@ -97,6 +97,19 @@
take_damage(rand(180,280), BRUTE, 0)
return 1
/obj/structure/table/attack_hand(mob/living/user)
if(user.a_intent == "grab" && user.pulling && isliving(user.pulling))
var/mob/living/pushed_mob = user.pulling
if(pushed_mob.buckled)
user << "<span class='warning'>[pushed_mob] is buckled to [pushed_mob.buckled]!</span>"
return
if(user.grab_state < GRAB_AGGRESSIVE)
user << "<span class='warning'>You need a better grip to do that!</span>"
return
tablepush(user, pushed_mob)
user.stop_pulling()
else
..()
/obj/structure/table/attack_tk() // no telehulk sorry
return
@@ -123,39 +136,15 @@
var/atom/movable/mover = caller
. = . || mover.checkpass(PASSTABLE)
/obj/structure/table/proc/tablepush(obj/item/I, mob/user)
if(get_dist(src, user) < 2)
var/obj/item/weapon/grab/G = I
if(G.affecting.buckled)
user << "<span class='warning'>[G.affecting] is buckled to [G.affecting.buckled]!</span>"
return 0
if(G.state < GRAB_AGGRESSIVE)
user << "<span class='warning'>You need a better grip to do that!</span>"
return 0
if(!G.confirm())
return 0
G.affecting.loc = src.loc
if(istype(src, /obj/structure/table/optable))
var/obj/structure/table/optable/OT = src
G.affecting.resting = 1
G.affecting.update_canmove()
visible_message("<span class='notice'>[G.assailant] has laid [G.affecting] on [src].</span>")
OT.patient = G.affecting
OT.check_patient()
qdel(I)
return 1
G.affecting.Weaken(2)
G.affecting.visible_message("<span class='danger'>[G.assailant] pushes [G.affecting] onto [src].</span>", \
"<span class='userdanger'>[G.assailant] pushes [G.affecting] onto [src].</span>")
add_logs(G.assailant, G.affecting, "pushed")
qdel(I)
return 1
qdel(I)
/obj/structure/table/proc/tablepush(mob/living/user, mob/living/pushed_mob)
pushed_mob.loc = src.loc
pushed_mob.Weaken(2)
pushed_mob.visible_message("<span class='danger'>[user] pushes [pushed_mob] onto [src].</span>", \
"<span class='userdanger'>[user] pushes [pushed_mob] onto [src].</span>")
add_logs(user, pushed_mob, "pushed")
/obj/structure/table/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/grab))
tablepush(I, user)
return
if(!(flags & NODECONSTRUCT))
if(istype(I, /obj/item/weapon/screwdriver) && deconstruction_ready)
table_deconstruct(user, 1)
@@ -375,6 +364,13 @@
computer.table = src
break
/obj/structure/table/optable/tablepush(mob/living/user, mob/living/pushed_mob)
pushed_mob.loc = src.loc
pushed_mob.resting = 1
pushed_mob.update_canmove()
visible_message("<span class='notice'>[user] has laid [pushed_mob] on [src].</span>")
check_patient()
/obj/structure/table/optable/proc/check_patient()
var/mob/M = locate(/mob/living/carbon/human, loc)
if(M)

View File

@@ -60,41 +60,44 @@
/obj/structure/transit_tube/station/attack_hand(mob/user)
if(!pod_moving)
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
if(icon_state == "closed")
open_animation()
if(user.pulling && user.a_intent == "grab" && isliving(user.pulling))
if(icon_state == "open")
var/mob/living/GM = user.pulling
if(user.grab_state >= GRAB_AGGRESSIVE)
if(GM.buckled || GM.buckled_mobs.len)
user << "<span class='warning'>[GM] is attached to something!</span>"
return
for(var/obj/structure/transit_tube_pod/pod in loc)
pod.visible_message("<span class='warning'>[user] starts putting [GM] into the [pod]!</span>")
if(do_after(user, 15, target = src))
if(GM && user.grab_state >= GRAB_AGGRESSIVE && user.pulling == GM && !GM.buckled && !GM.buckled_mobs.len)
GM.Weaken(5)
src.Bumped(GM)
break
else
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
if(icon_state == "closed")
open_animation()
else if(icon_state == "open")
if(pod.contents.len && user.loc != pod)
user.visible_message("[user] starts emptying [pod]'s contents onto the floor.", "<span class='notice'>You start emptying [pod]'s contents onto the floor...</span>")
if(do_after(user, 10, target = src)) //So it doesn't default to close_animation() on fail
if(pod.loc == loc)
for(var/atom/movable/AM in pod)
AM.loc = get_turf(user)
if(ismob(AM))
var/mob/M = AM
M.Weaken(5)
else if(icon_state == "open")
if(pod.contents.len && user.loc != pod)
user.visible_message("[user] starts emptying [pod]'s contents onto the floor.", "<span class='notice'>You start emptying [pod]'s contents onto the floor...</span>")
if(do_after(user, 10, target = src)) //So it doesn't default to close_animation() on fail
if(pod.loc == loc)
for(var/atom/movable/AM in pod)
AM.loc = get_turf(user)
if(ismob(AM))
var/mob/M = AM
M.Weaken(5)
else
close_animation()
break
else
close_animation()
break
/obj/structure/transit_tube/station/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weapon/grab))
if(icon_state == "open")
var/obj/item/weapon/grab/G = W
if(ismob(G.affecting) && G.state >= GRAB_AGGRESSIVE)
var/mob/GM = G.affecting
for(var/obj/structure/transit_tube_pod/pod in loc)
pod.visible_message("<span class='warning'>[user] starts putting [GM] into the [pod]!</span>")
if(do_after(user, 15, target = src) && GM && G && G.affecting == GM)
GM.Weaken(5)
src.Bumped(GM)
qdel(G)
break
else if(istype(W, /obj/item/weapon/crowbar))
if(istype(W, /obj/item/weapon/crowbar))
for(var/obj/structure/transit_tube_pod/pod in loc)
if(pod.contents)
user << "<span class='warning'>Empty the pod first!</span>"

View File

@@ -22,12 +22,37 @@
playsound(src.loc, "swing_hit", 25, 1)
swirlie.visible_message("<span class='danger'>[user] slams the toilet seat onto [swirlie]'s head!</span>", "<span class='userdanger'>[user] slams the toilet seat onto your head!</span>", "<span class='italics'>You hear reverberating porcelain.</span>")
swirlie.adjustBruteLoss(5)
return
if(cistern && !open)
else if(user.pulling && user.a_intent == "grab" && isliving(user.pulling))
user.changeNext_move(CLICK_CD_MELEE)
var/mob/living/GM = user.pulling
if(user.grab_state >= GRAB_AGGRESSIVE)
if(GM.loc != get_turf(src))
user << "<span class='warning'>[GM] needs to be on [src]!</span>"
return
if(!swirlie)
if(open)
GM.visible_message("<span class='danger'>[user] starts to give [GM] a swirlie!</span>", "<span class='userdanger'>[user] starts to give you a swirlie...</span>")
swirlie = GM
if(do_after(user, 30, 0, target = src))
GM.visible_message("<span class='danger'>[user] gives [GM] a swirlie!</span>", "<span class='userdanger'>[user] gives you a swirlie!</span>", "<span class='italics'>You hear a toilet flushing.</span>")
if(iscarbon(GM))
var/mob/living/carbon/C = GM
if(!C.internal)
C.adjustOxyLoss(5)
else
GM.adjustOxyLoss(5)
swirlie = null
else
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
GM.visible_message("<span class='danger'>[user] slams [GM.name] into [src]!</span>", "<span class='userdanger'>[user] slams you into [src]!</span>")
GM.adjustBruteLoss(5)
else
user << "<span class='warning'>You need a tighter grip!</span>"
else if(cistern && !open)
if(!contents.len)
user << "<span class='notice'>The cistern is empty.</span>"
return
else
var/obj/item/I = pick(contents)
if(ishuman(user))
@@ -36,10 +61,9 @@
I.loc = get_turf(src)
user << "<span class='notice'>You find [I] in the cistern.</span>"
w_items -= I.w_class
return
open = !open
update_icon()
else
open = !open
update_icon()
/obj/structure/toilet/update_icon()
@@ -54,7 +78,6 @@
user.visible_message("[user] [cistern ? "replaces the lid on the cistern" : "lifts the lid off the cistern"]!", "<span class='notice'>You [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"]!</span>", "<span class='italics'>You hear grinding porcelain.</span>")
cistern = !cistern
update_icon()
return
else if(cistern)
if(user.a_intent != "harm")
@@ -70,7 +93,6 @@
I.loc = src
w_items += I.w_class
user << "<span class='notice'>You carefully place [I] into the cistern.</span>"
return
else if(istype(I, /obj/item/weapon/reagent_containers))
if (!open)
@@ -78,39 +100,6 @@
var/obj/item/weapon/reagent_containers/RG = I
RG.reagents.add_reagent("water", min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this))
user << "<span class='notice'>You fill [RG] from [src]. Gross.</span>"
return
else if(istype(I, /obj/item/weapon/grab))
user.changeNext_move(CLICK_CD_MELEE)
var/obj/item/weapon/grab/G = I
if(!G.confirm())
return
if(isliving(G.affecting))
var/mob/living/GM = G.affecting
if(G.state >= GRAB_AGGRESSIVE)
if(GM.loc != get_turf(src))
user << "<span class='warning'>[GM] needs to be on [src]!</span>"
return
if(!swirlie)
if(open)
GM.visible_message("<span class='danger'>[user] starts to give [GM] a swirlie!</span>", "<span class='userdanger'>[user] starts to give you a swirlie...</span>")
swirlie = GM
if(do_after(user, 30, 0, target = src))
GM.visible_message("<span class='danger'>[user] gives [GM] a swirlie!</span>", "<span class='userdanger'>[user] gives you a swirlie!</span>", "<span class='italics'>You hear a toilet flushing.</span>")
if(iscarbon(GM))
var/mob/living/carbon/C = GM
if(!C.internal)
C.adjustOxyLoss(5)
else
GM.adjustOxyLoss(5)
swirlie = null
else
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
GM.visible_message("<span class='danger'>[user] slams [GM.name] into [src]!</span>", "<span class='userdanger'>[user] slams you into [src]!</span>")
GM.adjustBruteLoss(5)
else
user << "<span class='warning'>You need a tighter grip!</span>"
else
return ..()
@@ -125,24 +114,20 @@
anchored = 1
/obj/structure/urinal/attackby(obj/item/I, mob/user, params)
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 >= GRAB_AGGRESSIVE)
if(GM.loc != get_turf(src))
user << "<span class='notice'>[GM.name] needs to be on [src].</span>"
return
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("<span class='danger'>[user] slams [GM] into [src]!</span>", "<span class='danger'>You slam [GM] into [src]!</span>")
GM.adjustBruteLoss(8)
else
user << "<span class='warning'>You need a tighter grip!</span>"
/obj/structure/urinal/attack_hand(mob/user)
if(user.pulling && user.a_intent == "grab" && isliving(user.pulling))
var/mob/living/GM = user.pulling
if(user.grab_state >= GRAB_AGGRESSIVE)
if(GM.loc != get_turf(src))
user << "<span class='notice'>[GM.name] needs to be on [src].</span>"
return
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("<span class='danger'>[user] slams [GM] into [src]!</span>", "<span class='danger'>You slam [GM] into [src]!</span>")
GM.adjustBruteLoss(8)
else
user << "<span class='warning'>You need a tighter grip!</span>"
else
return ..()
..()
/obj/machinery/shower
name = "shower"

View File

@@ -95,16 +95,13 @@
if(operating)
user << "<span class='danger'>It's locked and running.</span>"
return
else
src.startgibbing(user)
/obj/machinery/gibber/attackby(obj/item/P, mob/user, params)
if(istype(P, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = P
if(!iscarbon(G.affecting))
if(user.pulling && user.a_intent == "grab" && isliving(user.pulling))
var/mob/living/L = user.pulling
if(!iscarbon(L))
user << "<span class='danger'>This item is not suitable for the gibber!</span>"
return
var/mob/living/carbon/C = G.affecting
var/mob/living/carbon/C = L
if(C.buckled ||C.buckled_mobs.len)
user << "<span class='warning'>[C] is attached to something!</span>"
return
@@ -112,17 +109,19 @@
user << "<span class='danger'>Subject may not have abiotic items on.</span>"
return
user.visible_message("<span class='danger'>[user] starts to put [G.affecting] into the gibber!</span>")
user.visible_message("<span class='danger'>[user] starts to put [C] into the gibber!</span>")
src.add_fingerprint(user)
if(do_after(user, gibtime, target = src) && G && G.affecting && G.affecting == C && !C.buckled && !C.buckled_mobs.len && !occupant)
user.visible_message("<span class='danger'>[user] stuffs [G.affecting] into the gibber!</span>")
C.reset_perspective(src)
C.loc = src
occupant = C
qdel(G)
update_icon()
if(do_after(user, gibtime, target = src))
if(C && user.pulling == C && !C.buckled && !C.buckled_mobs.len && !occupant)
user.visible_message("<span class='danger'>[user] stuffs [C] into the gibber!</span>")
C.forceMove(src)
occupant = C
update_icon()
else
startgibbing(user)
else if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", P))
/obj/machinery/gibber/attackby(obj/item/P, mob/user, params)
if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", P))
return
else if(exchange_parts(user, P))

View File

@@ -57,18 +57,6 @@
if(stat) //NOPOWER etc
return
if(istype(O, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = O
if(!user.Adjacent(G.affecting))
return
var/grabbed = G.affecting
if(ismonkey(grabbed))
var/mob/living/carbon/monkey/target = grabbed
stuff_monkey_in(target, user)
user.drop_item()
return
else
user << "<span class='danger'>The machine only accepts monkeys!</span>"
else
return ..()

View File

@@ -182,22 +182,12 @@
if(default_deconstruction_crowbar(O))
return
var/atom/movable/what = O
if(istype(O, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = O
if(!user.Adjacent(G.affecting))
return
if(G.affecting.buckled || G.affecting.buckled_mobs.len)
user << "<span class='warning'>[G.affecting] is attached to somthing!</span>"
return
what = G.affecting
var/datum/food_processor_process/P = select_recipe(what)
var/datum/food_processor_process/P = select_recipe(O)
if(P)
user.visible_message("[user] put [what] into [src].", \
"You put the [what] into [src].")
user.visible_message("[user] put [O] into [src].", \
"You put the [O] into [src].")
user.drop_item()
what.loc = src
O.loc = src
return 1
else
if(user.a_intent != "harm")

View File

@@ -81,7 +81,7 @@
countEggs()
/obj/item/weapon/storage/bag/easterbasket/handle_item_insertion(obj/item/I, prevent_warning = 0)
..()
. = ..()
countEggs()
//Bunny Suit

View File

@@ -82,7 +82,7 @@
M.apply_damage(10, STAMINA)
if(prob(5))
M.Weaken(3)
visible_message("<span class='danger'>[M] is knocked right off \his feet!</span>", 3)
visible_message("<span class='danger'>[M] is knocked right off \his feet!</span>")
//
// Structures
@@ -97,20 +97,22 @@
density = 1
/obj/structure/holohoop/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2)
var/obj/item/weapon/grab/G = W
if(G.state < GRAB_AGGRESSIVE)
if(get_dist(src,user)<2)
if(user.drop_item(src))
visible_message("<span class='warning'> [user] dunks [W] into \the [src]!</span>")
/obj/structure/holohoop/attack_hand(mob/user)
if(user.pulling && user.a_intent == "grab" && isliving(user.pulling))
var/mob/living/L = user.pulling
if(user.grab_state < GRAB_AGGRESSIVE)
user << "<span class='warning'>You need a better grip to do that!</span>"
return
G.affecting.loc = src.loc
G.affecting.Weaken(5)
visible_message("<span class='danger'>[G.assailant] dunks [G.affecting] into \the [src]!</span>", 3)
qdel(W)
return
else if (istype(W, /obj/item) && get_dist(src,user)<2)
user.drop_item(src)
visible_message("<span class='warning'> [user] dunks [W] into \the [src]!</span>", 3)
return
L.loc = src.loc
L.Weaken(5)
visible_message("<span class='danger'>[user] dunks [L] into \the [src]!</span>")
user.stop_pulling()
else
..()
/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target, height=0)
if (istype(mover,/obj/item) && mover.throwing)
@@ -119,12 +121,12 @@
return
if(prob(50))
I.loc = src.loc
visible_message("<span class='warning'> Swish! \the [I] lands in \the [src].</span>", 3)
visible_message("<span class='warning'> Swish! \the [I] lands in \the [src].</span>")
else
visible_message("<span class='danger'> \the [I] bounces off of \the [src]'s rim!</span>", 3)
visible_message("<span class='danger'> \the [I] bounces off of \the [src]'s rim!</span>")
return 0
else
return ..(mover, target, height)
return ..()

View File

@@ -581,12 +581,11 @@
update_icons()
update_hands = 0
if(grabbed_by.len > 0)
for(var/obj/item/weapon/grab/G in grabbed_by)
if(Adjacent(G))
a_intent = "disarm"
G.assailant.attack_hand(src)
inactivity_period = 10
if(pulledby)
if(Adjacent(pulledby))
a_intent = "disarm"
pulledby.attack_hand(src)
inactivity_period = 10
if(buckled)
resist()

View File

@@ -31,8 +31,8 @@
l_hand = W
W.layer = 20 //TODO: move to equipped?
W.equipped(src,slot_l_hand)
if(pulling == W)
stop_pulling()
if(W.pulledby)
W.pulledby.stop_pulling()
update_inv_l_hand()
W.pixel_x = initial(W.pixel_x)
W.pixel_y = initial(W.pixel_y)
@@ -49,8 +49,8 @@
r_hand = W
W.layer = 20
W.equipped(src,slot_r_hand)
if(pulling == W)
stop_pulling()
if(W.pulledby)
W.pulledby.stop_pulling()
update_inv_r_hand()
W.pixel_x = initial(W.pixel_x)
W.pixel_y = initial(W.pixel_y)

View File

@@ -83,10 +83,8 @@
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to disarm [src]!</span>")
/mob/living/carbon/alien/humanoid/restrained()
if (handcuffed)
return 1
return 0
/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
. = handcuffed
/mob/living/carbon/alien/humanoid/show_inv(mob/user)
@@ -127,6 +125,12 @@
playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
..(I, cuff_break = 1)
/mob/living/carbon/alien/humanoid/resist_grab(moving_resist)
if(pulledby.grab_state)
visible_message("<span class='danger'>[src] has broken free of [pulledby]'s grip!</span>")
pulledby.stop_pulling()
. = 0
/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0)
if(leaping)
return -32
@@ -172,4 +176,10 @@ proc/alien_type_present(var/alienpath)
/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath)
if(breath && breath.total_moles() > 0 && !sneaking)
playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5)
..()
..()
/mob/living/carbon/alien/humanoid/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src && pulling && grab_state >= GRAB_AGGRESSIVE && !pulling.anchored && iscarbon(pulling))
devour_mob(pulling, devour_time = 60)
else
..()

View File

@@ -70,8 +70,8 @@
return
/mob/living/carbon/alien/larva/restrained()
return 0
/mob/living/carbon/alien/larva/restrained(ignore_grab)
. = 0
// new damage icon system
// now constructs damage icon for each organ from mask * damage field

View File

@@ -8,6 +8,7 @@
return 0
var/toxins_used = 0
var/tox_detect_threshold = 0.02
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
var/list/breath_gases = breath.gases
@@ -16,7 +17,7 @@
//Partial pressure of the toxins in our breath
var/Toxins_pp = (breath_gases["plasma"][MOLES]/breath.total_moles())*breath_pressure
if(Toxins_pp) // Detect toxins in air
if(Toxins_pp > tox_detect_threshold) // Detect toxins in air
adjustPlasma(breath_gases["plasma"][MOLES]*250)
throw_alert("alien_tox", /obj/screen/alert/alien_tox)

View File

@@ -208,47 +208,38 @@
throw_mode_off()
if(!target || !isturf(loc))
return
if(istype(target, /obj/screen)) return
var/atom/movable/item = src.get_active_hand()
if(!item || (item.flags & (NODROP|ABSTRACT)))
if(istype(target, /obj/screen))
return
if(istype(item, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = item
item = G.get_mob_if_throwable() //throw the person instead of the grab
qdel(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)
if(start_T && end_T)
var/mob/M = item
var/start_T_descriptor = "<font color='#6b5d00'>tile at [start_T.x], [start_T.y], [start_T.z] in area [get_area(start_T)]</font>"
var/end_T_descriptor = "<font color='#6b4400'>tile at [end_T.x], [end_T.y], [end_T.z] in area [get_area(end_T)]</font>"
var/atom/movable/thrown_thing
var/obj/item/I = src.get_active_hand()
add_logs(src, M, "thrown", addition="from [start_T_descriptor] with the target [end_T_descriptor]")
if(!I)
if(pulling && isliving(pulling) && grab_state >= GRAB_AGGRESSIVE)
var/mob/living/throwable_mob = pulling
if(!throwable_mob.buckled)
thrown_thing = throwable_mob
stop_pulling()
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
var/turf/end_T = get_turf(target)
if(start_T && end_T)
var/start_T_descriptor = "<font color='#6b5d00'>tile at [start_T.x], [start_T.y], [start_T.z] in area [get_area(start_T)]</font>"
var/end_T_descriptor = "<font color='#6b4400'>tile at [end_T.x], [end_T.y], [end_T.z] in area [get_area(end_T)]</font>"
add_logs(src, throwable_mob, "thrown", addition="from [start_T_descriptor] with the target [end_T_descriptor]")
if(!item) return //Grab processing has a chance of returning null
if(!ismob(item)) //Honk mobs don't have a dropped() proc honk
unEquip(item)
if(src.client)
src.client.screen -= item
//actually throw it!
if(item)
item.layer = initial(item.layer)
src.visible_message("<span class='danger'>[src] has thrown [item].</span>")
else if(!(I.flags & (NODROP|ABSTRACT)))
thrown_thing = I
unEquip(I)
if(thrown_thing)
visible_message("<span class='danger'>[src] has thrown [thrown_thing].</span>")
newtonian_move(get_dir(target, src))
thrown_thing.throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src)
item.throw_at(target, item.throw_range, item.throw_speed, src)
/mob/living/carbon/restrained()
if (handcuffed)
return 1
return
/mob/living/carbon/restrained(ignore_grab)
. = (handcuffed || (!ignore_grab && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE))
/mob/living/carbon/proc/canBeHandcuffed()
return 0

View File

@@ -94,3 +94,15 @@
adjustFireLoss(M.powerlevel * rand(6,10))
updatehealth()
return 1
/mob/living/carbon/proc/devour_mob(mob/living/carbon/C, devour_time = 130)
C.visible_message("<span class='danger'>[src] is attempting to devour [C]!</span>", \
"<span class='userdanger'>[src] is attempting to devour you!</span>")
if(!do_mob(src, C, devour_time))
return
if(pulling && pulling == C && grab_state >= GRAB_AGGRESSIVE && a_intent == "grab")
C.visible_message("<span class='danger'>[src] devours [C]!</span>", \
"<span class='userdanger'>[src] devours you!</span>")
C.forceMove(src)
stomach_contents.Add(C)
add_logs(src, C, "devoured")

View File

@@ -1,5 +1,6 @@
/mob/living/carbon/movement_delay()
. = ..()
. += grab_state * 3
if(legcuffed)
. += legcuffed.slowdown

View File

@@ -46,6 +46,9 @@
if(fire_stacks < 0)
msg += "It's soaked in water.\n"
if(pulledby && pulledby.grab_state)
msg += "It's restrained by [pulledby]'s grip.\n"
if(stat == UNCONSCIOUS)
msg += "It isn't responding to anything around it; it seems to be asleep.\n"
msg += "</span>"

View File

@@ -236,6 +236,9 @@
msg += "[t_He] looks a little soaked.\n"
if(pulledby && pulledby.grab_state)
msg += "[t_He] [t_is] restrained by [pulledby]'s grip.\n"
if(nutrition < NUTRITION_LEVEL_STARVING - 50)
msg += "[t_He] [t_is] severely malnourished.\n"
else if(nutrition >= NUTRITION_LEVEL_FAT)

View File

@@ -264,11 +264,6 @@
I.acid_act(acidpwr, acid_volume_left)
acid_volume_left = max(acid_volume_left - acid_decay, 0)
/mob/living/carbon/human/grabbedby(mob/living/user)
if(w_uniform)
w_uniform.add_fingerprint(user)
..()
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
if(..())
@@ -369,3 +364,14 @@
skipcatch = 1 //can't catch the now embedded item
return ..()
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (disabilities & FAT) && ismonkey(pulling))
devour_mob(pulling)
else
..()
/mob/living/carbon/human/grippedby(mob/living/user)
if(w_uniform)
w_uniform.add_fingerprint(user)
..()

View File

@@ -1,10 +1,7 @@
/mob/living/carbon/human/restrained()
if (handcuffed)
return 1
if (wear_suit && wear_suit.breakouttime)
return 1
return 0
/mob/living/carbon/human/restrained(ignore_grab)
. = ((wear_suit && wear_suit.breakouttime) || ..())
/mob/living/carbon/human/canBeHandcuffed()
return 1

View File

@@ -89,6 +89,7 @@
if(I.flags_inv & HIDEJUMPSUIT)
update_inv_w_uniform()
if(wear_suit.breakouttime) //when equipping a straightjacket
stop_pulling() //can't pull if restrained
update_action_buttons_icon() //certain action buttons will no longer be usable.
update_inv_wear_suit()
if(slot_w_uniform)

View File

@@ -974,22 +974,6 @@
H.visible_message("<span class='warning'>[M] has broken [H]'s grip on [H.pulling]!</span>")
talked = 1
H.stop_pulling()
//BubbleWrap: Disarming also breaks a grab - this will also stop someone being choked, won't it?
if(istype(H.l_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/lgrab = H.l_hand
if(lgrab.affecting)
H.visible_message("<span class='warning'>[M] has broken [H]'s grip on [lgrab.affecting]!</span>")
talked = 1
spawn(1)
qdel(lgrab)
if(istype(H.r_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/rgrab = H.r_hand
if(rgrab.affecting)
H.visible_message("<span class='warning'>[M] has broken [H]'s grip on [rgrab.affecting]!</span>")
talked = 1
spawn(1)
qdel(rgrab)
//End BubbleWrap
if(!talked) //BubbleWrap

View File

@@ -29,6 +29,9 @@
else if(I == r_hand)
r_hand = null
if(I.pulledby)
I.pulledby.stop_pulling()
I.screen_loc = null // will get moved if inventory is visible
I.loc = src
I.equipped(src, slot)

View File

@@ -17,14 +17,6 @@
for(var/obj/item/organ/O in internal_organs)
O.on_life()
//grab processing
if(istype(l_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = l_hand
G.process()
if(istype(r_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = r_hand
G.process()
//Updates the number of stored chemicals for powers
handle_changeling()
@@ -54,7 +46,7 @@
var/datum/gas_mixture/breath
if(health <= config.health_threshold_crit)
if(health <= config.health_threshold_crit || (pulledby && pulledby.grab_state >= GRAB_KILL))
losebreath++
//Suffocate

View File

@@ -13,7 +13,7 @@
..()
if(!client && stat == CONSCIOUS)
if(prob(33) && canmove && isturf(loc) && !pulledby && !grabbed_by.len)
if(prob(33) && canmove && isturf(loc) && !pulledby)
step(src, pick(cardinal))
if(prob(1))
emote(pick("scratch","jump","roll","tail"))

View File

@@ -105,7 +105,7 @@ Sorry Giacom. Please don't be mad :(
//Should stop you pushing a restrained person out of the way
if(isliving(M))
var/mob/living/L = M
if((L.pulledby && L.restrained()) || L.grabbed_by.len)
if(L.pulledby && L.pulledby != src && L.restrained())
if(!(world.time % 5))
src << "<span class='warning'>[L] is restrained, you cannot push past.</span>"
return 1
@@ -118,32 +118,42 @@ Sorry Giacom. Please don't be mad :(
src << "<span class='warning'>[L] is restraining [P], you cannot push past.</span>"
return 1
//switch our position with M
//BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
if((M.a_intent == "help" || M.restrained()) && (a_intent == "help" || restrained()) && M.canmove && canmove && !M.buckled && !M.buckled_mobs.len) // mutual brohugs all around!
if(loc && !loc.Adjacent(M.loc))
return 1
now_pushing = 1
var/oldloc = loc
var/oldMloc = M.loc
var/M_passmob = (M.pass_flags & PASSMOB) // we give PASSMOB to both mobs to avoid bumping other mobs during swap.
var/src_passmob = (pass_flags & PASSMOB)
M.pass_flags |= PASSMOB
pass_flags |= PASSMOB
M.Move(oldloc)
Move(oldMloc)
if(!src_passmob)
pass_flags &= ~PASSMOB
if(!M_passmob)
M.pass_flags &= ~PASSMOB
now_pushing = 0
if(moving_diagonally)//no mob swap during diagonal moves.
return 1
if(!M.buckled && !M.buckled_mobs.len)
var/mob_swap
//the puller can always swap with its victim if on grab intent
if(M.pulledby == src && a_intent == "grab")
mob_swap = 1
//restrained people act if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
else if((M.restrained() || M.a_intent == "help") && (restrained() || a_intent == "help"))
mob_swap = 1
if(mob_swap)
//switch our position with M
if(loc && !loc.Adjacent(M.loc))
return 1
now_pushing = 1
var/oldloc = loc
var/oldMloc = M.loc
var/M_passmob = (M.pass_flags & PASSMOB) // we give PASSMOB to both mobs to avoid bumping other mobs during swap.
var/src_passmob = (pass_flags & PASSMOB)
M.pass_flags |= PASSMOB
pass_flags |= PASSMOB
M.Move(oldloc)
Move(oldMloc)
if(!src_passmob)
pass_flags &= ~PASSMOB
if(!M_passmob)
M.pass_flags &= ~PASSMOB
now_pushing = 0
return 1
//okay, so we didn't switch. but should we push?
//not if he's not CANPUSH of course
if(!(M.status_flags & CANPUSH))
@@ -162,6 +172,8 @@ Sorry Giacom. Please don't be mad :(
/mob/living/proc/PushAM(atom/movable/AM)
if(now_pushing)
return 1
if(moving_diagonally)// no pushing during diagonal moves.
return 1
if(!client && (mob_size < MOB_SIZE_SMALL))
return
if(!AM.anchored)
@@ -191,7 +203,7 @@ Sorry Giacom. Please don't be mad :(
//same as above
/mob/living/pointed(atom/A as mob|obj|turf in view())
if(src.stat || !src.canmove || src.restrained())
if(incapacitated())
return 0
if(src.status_flags & FAKEDEATH)
return 0
@@ -546,67 +558,29 @@ Sorry Giacom. Please don't be mad :(
else
return 0
if (restrained())
var/atom/movable/pullee = pulling
if(pullee && get_dist(src, pullee) > 1)
stop_pulling()
var/cuff_dragged = 0
if (restrained())
for(var/mob/living/M in range(1, src))
if (M.pulling == src && !M.incapacitated())
cuff_dragged = 1
if (!cuff_dragged && pulling && !throwing && (get_dist(src, pulling) <= 1 || pulling.loc == loc))
var/turf/T = loc
. = ..()
if (pulling && pulling.loc)
if(!isturf(pulling.loc))
stop_pulling()
return
else
if(Debug)
diary <<"pulling disappeared? at [__LINE__] in mob.dm - pulling = [pulling]"
diary <<"REPORT THIS"
/////
if(pulling && pulling.anchored)
var/turf/T = loc
. = ..()
if(. && pulling && pulling == pullee) //we were pulling a thing and didn't lose it during our move.
if(pulling.anchored)
stop_pulling()
return
if (!restrained())
var/diag = get_dir(src, pulling)
if ((diag - 1) & diag)
else
diag = null
if ((get_dist(src, pulling) > 1 || diag))
if (isliving(pulling))
var/mob/living/M = pulling
var/pull_ok = 1
if (M.grabbed_by.len)
if (prob(75))
var/obj/item/weapon/grab/G = pick(M.grabbed_by)
visible_message("<span class='danger'>[src] has pulled [G.affecting] from [G.assailant]'s grip.</span>")
qdel(G)
else
pull_ok = 0
if (M.grabbed_by.len)
pull_ok = 0
if (pull_ok)
var/atom/movable/t = M.pulling
M.stop_pulling()
var/pull_dir = get_dir(src, pulling)
if(get_dist(src, pulling) > 1 || ((pull_dir - 1) & pull_dir)) //puller and pullee more than one tile away or in diagonal position
if(isliving(pulling))
var/mob/living/M = pulling
if(M.lying && !M.buckled && (prob(M.getBruteLoss() / 2)))
makeTrail(T, M)
pulling.Move(T, get_dir(pulling, T)) //the pullee tries to reach our previous position
if(pulling && get_dist(src, pulling) > 1) //the pullee couldn't keep up
stop_pulling()
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move.
pulledby.stop_pulling()
//this is the gay blood on floor shit -- Added back -- Skie
if(M.lying && !M.buckled && (prob(M.getBruteLoss() / 2)))
makeTrail(T, M)
pulling.Move(T, get_dir(pulling, T))
if(M)
M.start_pulling(t)
else
if (pulling)
pulling.Move(T, get_dir(pulling, T))
else
stop_pulling()
. = ..()
if (s_active && !(s_active in contents) && !(s_active.loc in contents))
// It's ugly. But everything related to inventory/storage is. -- c0
s_active.close(src)
@@ -662,34 +636,15 @@ Sorry Giacom. Please don't be mad :(
set name = "Resist"
set category = "IC"
if(!isliving(src) || next_move > world.time || stat || weakened || stunned || paralysis)
if(!isliving(src) || next_move > world.time || incapacitated(ignore_restraints = 1))
return
changeNext_move(CLICK_CD_RESIST)
//resisting grabs (as if it helps anyone...)
if(!restrained())
var/resisting = 0
for(var/obj/O in requests)
qdel(O)
resisting++
for(var/X in grabbed_by)
var/obj/item/weapon/grab/G = X
resisting++
if(G.state == GRAB_PASSIVE)
qdel(G)
else
if(G.state == GRAB_AGGRESSIVE)
if(prob(25))
visible_message("<span class='danger'>[src] has broken free of [G.assailant]'s grip!</span>")
qdel(G)
else
if(G.state == GRAB_NECK)
if(prob(5))
visible_message("<span class='danger'>[src] has broken free of [G.assailant]'s headlock!</span>")
qdel(G)
if(resisting)
visible_message("<span class='danger'>[src] resists!</span>")
return
if(!restrained(ignore_grab = 1) && pulledby)
visible_message("<span class='danger'>[src] resists against [pulledby]'s grip!</span>")
resist_grab()
return
//unbuckling yourself
if(buckled && last_special <= world.time)
@@ -707,6 +662,22 @@ Sorry Giacom. Please don't be mad :(
resist_restraints() //trying to remove cuffs.
/mob/proc/resist_grab(moving_resist)
return 1 //returning 0 means we successfully broke free
/mob/living/resist_grab(moving_resist)
. = 1
if(pulledby.grab_state)
if(prob(30/pulledby.grab_state))
visible_message("<span class='danger'>[src] has broken free of [pulledby]'s grip!</span>")
pulledby.stop_pulling()
return 0
if(moving_resist && client) //we resisted by trying to move
client.move_delay = world.time + 20
else
pulledby.stop_pulling()
return 0
/mob/living/proc/resist_buckle()
buckled.user_unbuckle_mob(src,src)
@@ -1024,3 +995,7 @@ Sorry Giacom. Please don't be mad :(
for(var/datum/objective/sintouched/acedia/A in src.mind.objectives)
return 1
return 0
/mob/living/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0)
stop_pulling()
. = ..()

View File

@@ -174,28 +174,51 @@
/mob/living/acid_act(acidpwr, toxpwr, acid_volume)
take_organ_damage(min(10*toxpwr, acid_volume * toxpwr))
/mob/living/proc/grabbedby(mob/living/carbon/user,supress_message = 0)
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src || anchored)
return 0
if(!user.pulling || user.pulling != src)
user.start_pulling(src, supress_message)
return
if(!(status_flags & CANPUSH))
user << "<span class='warning'>[src] can't be grabbed more aggressively!</span>"
return 0
grippedby(user)
add_logs(user, src, "grabbed", addition="passively")
if(anchored || !Adjacent(user))
return 0
if(buckled)
user << "<span class='warning'>You cannot grab [src], \he is buckled in!</span>"
return 0
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(user, src)
if(!user.put_in_active_hand(G)) //if we can't put the grab in our hand for some reason, we delete it.
qdel(G)
G.synch()
LAssailant = user
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(!supress_message)
visible_message("<span class='danger'>[user] has grabbed [src] passively!</span>")
//proc to upgrade a simple pull into a more aggressive grab.
/mob/living/proc/grippedby(mob/living/carbon/user)
if(user.grab_state < GRAB_KILL)
user.changeNext_move(CLICK_CD_GRABBING)
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
var/old_grab_state = user.grab_state
var/grab_upgrade_time = 40
visible_message("<span class='danger'>[user] starts to tighten \his grip on [src]!</span>", \
"<span class='userdanger'>[user] starts to tighten \his grip on you!</span>")
if(do_mob(user, src, grab_upgrade_time))
if(user.pulling && user.pulling == src && user.grab_state == old_grab_state && user.a_intent == "grab")
user.grab_state++
switch(user.grab_state)
if(GRAB_AGGRESSIVE)
add_logs(user, src, "grabbed", addition="aggressively")
visible_message("<span class='danger'>[user] has grabbed [src] aggressively!</span>", \
"<span class='userdanger'>[user] has grabbed [src] aggressively!</span>")
drop_r_hand()
drop_l_hand()
stop_pulling()
if(GRAB_NECK)
visible_message("<span class='danger'>[user] has grabbed [src] by the neck!</span>",\
"<span class='userdanger'>[user] has grabbed you by the neck!</span>")
update_canmove() //we fall down
if(!buckled && !density)
Move(user.loc)
if(GRAB_KILL)
visible_message("<span class='danger'>[user] is strangling [src]!</span>", \
"<span class='userdanger'>[user] is strangling you!</span>")
update_canmove() //we fall down
if(!buckled && !density)
Move(user.loc)
return 1
/mob/living/attack_slime(mob/living/simple_animal/slime/M)
@@ -295,8 +318,8 @@
M.do_attack_animation(src)
return 1
/mob/living/incapacitated()
if(stat || paralysis || stunned || weakened || restrained())
/mob/living/incapacitated(ignore_restraints, ignore_grab)
if(stat || paralysis || stunned || weakened || (!ignore_restraints && restrained(ignore_grab)))
return 1
//Looking for irradiate()? It's been moved to radiation.dm under the rad_act() for mobs.

View File

@@ -60,4 +60,4 @@
var/list/butcher_results = null
var/hellbound = 0 //People who've signed infernal contracts are unrevivable.

View File

@@ -357,8 +357,8 @@ var/list/ai_list = list()
return 1
return 0
/mob/living/silicon/ai/restrained()
return 0
/mob/living/silicon/ai/restrained(ignore_grab)
. = 0
/mob/living/silicon/ai/emp_act(severity)
if (prob(30))

View File

@@ -95,8 +95,8 @@
/mob/living/silicon/pai/blob_act(obj/effect/blob/B)
return 0
/mob/living/silicon/pai/restrained()
return 0
/mob/living/silicon/pai/restrained(ignore_grab)
. = 0
/mob/living/silicon/pai/emp_act(severity)
// 20% chance to kill

View File

@@ -378,8 +378,8 @@
if(connected_ai)
stat("Master AI:", connected_ai.name)
/mob/living/silicon/robot/restrained()
return 0
/mob/living/silicon/robot/restrained(ignore_grab)
. = 0
/mob/living/silicon/robot/ex_act(severity, target)
switch(severity)

View File

@@ -467,7 +467,7 @@
if (aicamera)
return aicamera.selectpicture(aicamera)
/mob/living/silicon/grabbedby(mob/living/user)
/mob/living/silicon/grippedby(mob/living/user)
return
/mob/living/silicon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash/noise)

View File

@@ -81,10 +81,9 @@
drop_r_hand()
var/obj/item/clothing/head/drone_holder/DH = new /obj/item/clothing/head/drone_holder(src)
DH.updateVisualAppearence(src)
DH.contents += src
DH.drone = src
user.put_in_hands(DH)
src.loc = DH
forceMove(DH)
return
..()

View File

@@ -91,6 +91,9 @@
r_hand = null
update_inv_hands()
if(I.pulledby)
I.pulledby.stop_pulling()
I.screen_loc = null // will get moved if inventory is visible
I.loc = src
I.equipped(src, slot)

View File

@@ -32,7 +32,7 @@
environment_smash = 0
mouse_opacity = 2
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_SMALL
mob_size = MOB_SIZE_TINY
flying = 1
gold_core_spawnable = 1
search_objects = 1 //have to find those plant trays!

View File

@@ -228,7 +228,7 @@
/mob/living/simple_animal/hostile/statue/sentience_act()
faction -= "neutral"
/mob/living/simple_animal/hostile/statue/restrained()
/mob/living/simple_animal/hostile/statue/restrained(ignore_grab)
. = ..()
if(can_be_seen(loc))
return 1

View File

@@ -172,6 +172,9 @@
/mob/living/simple_animal/handle_environment(datum/gas_mixture/environment)
var/atmos_suitable = 1
if(pulledby && pulledby.grab_state >= GRAB_KILL && atmos_requirements["min_oxy"])
atmos_suitable = 0 //getting choked
var/atom/A = src.loc
if(isturf(A))
var/turf/T = A

View File

@@ -389,7 +389,7 @@
sleep(3)
if(user)
step_away(src,user,15)
canmove = 1
update_canmove()
/mob/living/simple_animal/slime/pet
docile = 1

View File

@@ -179,44 +179,10 @@ var/next_mob_id = 0
return r_hand
return null
/mob/proc/ret_grab(obj/effect/list_container/mobl/L, flag)
if ((!( istype(l_hand, /obj/item/weapon/grab) ) && !( istype(r_hand, /obj/item/weapon/grab) )))
if (!( L ))
return null
else
return L.container
else
if (!( L ))
L = new /obj/effect/list_container/mobl( null )
L.container += src
L.master = src
if (istype(l_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = l_hand
if (!( L.container.Find(G.affecting) ))
L.container += G.affecting
if (G.affecting)
G.affecting.ret_grab(L, 1)
if (istype(r_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = r_hand
if (!( L.container.Find(G.affecting) ))
L.container += G.affecting
if (G.affecting)
G.affecting.ret_grab(L, 1)
if (!( flag ))
if (L.master == src)
var/list/temp = list( )
temp += L.container
//L = null
qdel(L)
return temp
else
return L.container
/mob/proc/restrained(ignore_grab)
return
/mob/proc/restrained()
return
/mob/proc/incapacitated()
/mob/proc/incapacitated(ignore_restraints, ignore_grab)
return
//This proc is called whenever someone clicks an inventory ui slot.
@@ -333,12 +299,14 @@ var/next_mob_id = 0
return 1
//this and stop_pulling really ought to be /mob/living procs
/mob/proc/start_pulling(atom/movable/AM)
/mob/proc/start_pulling(atom/movable/AM, supress_message = 0)
if(!AM || !src)
return
if(AM == src || !isturf(AM.loc))
return
if(AM.anchored)
if(AM.anchored || AM.throwing)
return
if(throwing || incapacitated())
return
AM.add_fingerprint(src)
@@ -350,13 +318,21 @@ var/next_mob_id = 0
return
stop_pulling()
changeNext_move(CLICK_CD_GRABBING)
if(AM.pulledby)
visible_message("<span class='danger'>[src] has pulled [AM] from [AM.pulledby]'s grip.</span>")
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
pulling = AM
AM.pulledby = src
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
update_pull_hud_icon()
if(ismob(AM))
var/mob/M = AM
if(!supress_message)
visible_message("<span class='warning'>[src] has grabbed [M] passively!</span>")
if(!iscarbon(src))
M.LAssailant = null
else
@@ -368,11 +344,15 @@ var/next_mob_id = 0
if(pulling)
pulling.pulledby = null
if(ismob(pulling))
var/mob/M = pulling
M.update_canmove()// mob gets up if it was lyng down in a chokehold
pulling = null
grab_state = 0
update_pull_hud_icon()
/mob/proc/update_pull_hud_icon()
if(client && hud_used)
if(hud_used)
if(hud_used.pull_icon)
hud_used.pull_icon.update_icon(src)
@@ -677,10 +657,11 @@ var/next_mob_id = 0
//Robots, animals and brains have their own version so don't worry about them
/mob/proc/update_canmove()
var/ko = weakened || paralysis || stat || (status_flags & FAKEDEATH)
var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK
var/buckle_lying = !(buckled && !buckled.buckle_lying)
var/has_legs = get_num_legs()
var/has_arms = get_num_arms()
if(ko || resting || stunned)
if(ko || resting || stunned || chokehold)
drop_r_hand()
drop_l_hand()
unset_machine()
@@ -691,10 +672,12 @@ var/next_mob_id = 0
if(buckled)
lying = 90*buckle_lying
else
if((ko || resting || !has_legs) && !lying)
fall(ko)
canmove = !(ko || resting || stunned || buckled || (!has_legs && !has_arms))
else if(!lying)
if(resting)
fall()
else if(ko || !has_legs || chokehold)
fall(forced = 1)
canmove = !(ko || resting || stunned || chokehold || buckled || (!has_legs && !has_arms))
density = !lying
if(lying)
if(layer == initial(layer)) //to avoid special cases like hiding larvas.

View File

@@ -32,7 +32,10 @@
var/other_mobs = null
var/memory = ""
var/disabilities = 0 //Carbon
var/atom/movable/pulling = null
var/grab_state = 0
var/next_move = null
var/notransform = null //Carbon
var/hand = null
@@ -86,9 +89,6 @@
var/research_scanner = 0 //For research scanner equipped mobs. Enable to show research data when examining.
var/list/grabbed_by = list( )
var/list/requests = list( )
var/list/mapobjs = list()
var/in_throw_mode = 0

View File

@@ -1,223 +0,0 @@
#define UPGRADE_COOLDOWN 40
#define UPGRADE_KILL_TIMER 100
/obj/item/weapon/grab
name = "grab"
flags = NOBLUDGEON | ABSTRACT
var/obj/screen/grab/hud = null
var/mob/affecting = null
var/mob/assailant = null
var/state = GRAB_PASSIVE
var/allow_upgrade = 1
var/last_upgrade = 0
layer = 21
item_state = "nothing"
w_class = 5
/obj/item/weapon/grab/New(mob/user, mob/victim)
..()
assailant = user
affecting = victim
hud = new /obj/screen/grab(src)
hud.icon_state = "reinforce"
hud.name = "reinforce grab"
hud.master = src
affecting.grabbed_by += src
/obj/item/weapon/grab/Destroy()
if(affecting)
affecting.grabbed_by -= src
affecting = null
if(assailant)
if(assailant.client)
assailant.client.screen -= hud
assailant = null
qdel(hud)
return ..()
//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/get_mob_if_throwable()
if(affecting)
if(affecting.buckled)
return null
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(assailant.r_hand == src)
hud.screen_loc = ui_rhand
else
hud.screen_loc = ui_lhand
/obj/item/weapon/grab/process()
if(!confirm())
return 0
if(assailant.client)
assailant.client.screen -= hud
assailant.client.screen += hud
if(assailant.pulling == affecting)
assailant.stop_pulling()
if(state <= GRAB_AGGRESSIVE)
allow_upgrade = 1
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)
allow_upgrade = 0
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)
allow_upgrade = 0
if(state == GRAB_AGGRESSIVE)
var/h = affecting.hand
affecting.hand = 0
affecting.drop_item()
affecting.hand = 1
affecting.drop_item()
affecting.hand = h
for(var/X in affecting.grabbed_by)
var/obj/item/weapon/grab/G = X
if(G == src) continue
if(G.state == GRAB_AGGRESSIVE)
allow_upgrade = 0
if(allow_upgrade)
hud.icon_state = "reinforce"
else
hud.icon_state = "!reinforce"
else
if(!affecting.buckled)
affecting.loc = assailant.loc
var/breathing_tube = affecting.getorganslot("breathing_tube")
if(state >= GRAB_NECK)
affecting.Stun(5) //It will hamper your voice, being choked and all.
if(isliving(affecting) && !breathing_tube)
var/mob/living/L = affecting
L.adjustOxyLoss(1)
if(state >= GRAB_KILL)
affecting.Weaken(5) //Should keep you down unless you get help.
if(!breathing_tube)
affecting.losebreath = min(affecting.losebreath + 2, 3)
/obj/item/weapon/grab/attack_self(mob/user)
s_click(hud)
/obj/item/weapon/grab/proc/s_click(obj/screen/S)
if(!affecting)
return
if(state == GRAB_UPGRADING)
return
if(world.time < (last_upgrade + UPGRADE_COOLDOWN))
return
if(!assailant.canmove || assailant.lying)
qdel(src)
return
last_upgrade = world.time
if(state < GRAB_AGGRESSIVE)
if(!allow_upgrade)
return
assailant.visible_message("<span class='danger'>[assailant] grabs [affecting] aggressively!</span>")
state = GRAB_AGGRESSIVE
icon_state = "grabbed1"
else
if(state < GRAB_NECK)
if(isslime(affecting))
assailant << "<span class='danger'>You squeeze [affecting], but nothing interesting happens!</span>"
return
assailant.visible_message("<span class='danger'>[assailant] moves \his grip to [affecting]'s neck!</span>")
state = GRAB_NECK
icon_state = "grabbed+1"
if(!affecting.buckled)
affecting.loc = assailant.loc
add_logs(assailant, affecting, "neck-grabbed")
hud.icon_state = "disarm/kill"
hud.name = "disarm/kill"
else
if(state < GRAB_UPGRADING)
assailant.visible_message("<span class='danger'>[assailant] starts to tighten \his grip on [affecting]'s neck!</span>")
hud.icon_state = "disarm/kill1"
state = GRAB_UPGRADING
if(do_after(assailant, UPGRADE_KILL_TIMER, target = affecting))
if(state == GRAB_KILL)
return
if(!affecting)
qdel(src)
return
if(!assailant.canmove || assailant.lying)
qdel(src)
return
state = GRAB_KILL
assailant.visible_message("<span class='danger'>[assailant] tightens \his grip on [affecting]'s neck!</span>")
add_logs(assailant, affecting, "strangled")
assailant.changeNext_move(CLICK_CD_TKSTRANGLE)
if(!affecting.getorganslot("breathing_tube"))
affecting.losebreath += 1
else
if(assailant)
assailant.visible_message("<span class='danger'>[assailant] is unable to tighten \his grip on [affecting]'s neck!</span>")
hud.icon_state = "disarm/kill"
state = GRAB_NECK
//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)
qdel(src)
return 0
if(affecting)
if(!isturf(assailant.loc) || ( !isturf(affecting.loc) || assailant.loc != affecting.loc && get_dist(assailant, affecting) > 1) )
qdel(src)
return 0
return 1
/obj/item/weapon/grab/attack(mob/M, mob/user)
if(!affecting)
return
if(M == affecting)
s_click(hud)
return
if(M == assailant && state >= GRAB_AGGRESSIVE)
if( (ishuman(user) && (user.disabilities & FAT) && ismonkey(affecting) ) || ( isalien(user) && iscarbon(affecting) ) )
var/mob/living/carbon/attacker = user
user.visible_message("<span class='danger'>[user] is attempting to devour [affecting]!</span>")
if(istype(user, /mob/living/carbon/alien/humanoid/hunter))
if(!do_mob(user, affecting, 60)) return
else
if(!do_mob(user, affecting, 130)) return
user.visible_message("<span class='danger'>[user] devours [affecting]!</span>")
affecting.loc = user
attacker.stomach_contents.Add(affecting)
qdel(src)
add_logs(user, affecting, "attempted to put", src, "into [M]")
/obj/item/weapon/grab/dropped()
..()
qdel(src)
#undef UPGRADE_COOLDOWN
#undef UPGRADE_KILL_TIMER

View File

@@ -8,9 +8,6 @@
if(buckled == mover)
return 1
if(ismob(mover))
var/mob/moving_mob = mover
if ((other_mobs && moving_mob.other_mobs))
return 1
if (mover in buckled_mobs)
return 1
return (!mover.density || !density || lying)
@@ -114,7 +111,7 @@
Process_Incorpmove(direct)
return 0
if(Process_Grab())
if(Process_Grab()) //are we restrained by someone's grip?
return
if(mob.buckled) //if we're buckled to something, tell it we moved.
@@ -136,54 +133,10 @@
if(!mob.Process_Spacemove(direct))
return 0
if(mob.restrained()) //Why being pulled while cuffed prevents you from moving
for(var/mob/M in orange(1, mob))
if(M.pulling == mob)
if(!M.incapacitated() && mob.Adjacent(M))
src << "<span class='warning'>You're restrained! You can't move!</span>"
move_delay = world.time + 10
return 0
else
M.stop_pulling()
//We are now going to move
moving = 1
move_delay = mob.movement_delay() + world.time
//Something with pulling things
if(locate(/obj/item/weapon/grab, mob))
move_delay = max(move_delay, world.time + 7)
var/list/L = mob.ret_grab()
if(istype(L, /list))
if(L.len == 2)
L -= mob
var/mob/M = L[1]
if(M)
if ((get_dist(mob, M) <= 1 || M.loc == mob.loc))
. = ..()
if(M)//Mob may get deleted during parent call
if (isturf(M.loc))
var/diag = get_dir(mob, M)
if ((diag - 1) & diag)
else
diag = null
if ((get_dist(mob, M) > 1 || diag))
step(M, get_dir(M.loc, mob.loc))
else
for(var/mob/M in L)
M.other_mobs = 1
if(mob != M)
M.animate_movement = 3
for(var/mob/M in L)
spawn( 0 )
step(M, direct)
return
spawn( 1 )
M.other_mobs = null
M.animate_movement = 2
return
if(mob.confused)
if(mob.confused > 40)
step(mob, pick(cardinal))
@@ -207,39 +160,14 @@
///Called by client/Move()
///Checks to see if you are being grabbed and if so attemps to break it
/client/proc/Process_Grab()
if(mob.grabbed_by.len)
var/list/grabbing = list()
if(mob.pulledby)
if(mob.restrained(ignore_grab = 1))
move_delay = world.time + 10
src << "<span class='warning'>You're restrained! You can't move!</span>"
return 1
else
return mob.resist_grab(1)
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/X in mob.grabbed_by)
var/obj/item/weapon/grab/G = X
switch(G.state)
if(GRAB_PASSIVE)
if(!grabbing.Find(G.assailant)) //moving always breaks a passive grab unless we are also grabbing our grabber.
qdel(G)
if(GRAB_AGGRESSIVE)
move_delay = world.time + 10
if(!prob(25))
return 1
mob.visible_message("<span class='danger'>[mob] has broken free of [G.assailant]'s grip!</span>")
qdel(G)
if(GRAB_NECK)
move_delay = world.time + 10
if(!prob(5))
return 1
mob.visible_message("<span class='danger'>[mob] has broken free of [G.assailant]'s headlock!</span>")
qdel(G)
return 0
///Process_Incorpmove
///Called by client/Move()
@@ -352,27 +280,19 @@
/mob/proc/mob_negates_gravity()
return 0
//moves the mob/object we're pulling
/mob/proc/Move_Pulled(atom/A)
if (!canmove || restrained() || !pulling)
if (!pulling)
return
if (pulling.anchored)
return
if (!pulling.Adjacent(src))
if (pulling.anchored || !pulling.Adjacent(src))
stop_pulling()
return
if (A == loc && pulling.density)
return
if (!Process_Spacemove(get_dir(pulling.loc, A)))
return
if (ismob(pulling))
var/mob/M = pulling
var/atom/movable/t = M.pulling
M.stop_pulling()
step(pulling, get_dir(pulling.loc, A))
if(M)
M.start_pulling(t)
else
step(pulling, get_dir(pulling.loc, A))
return
step(pulling, get_dir(pulling.loc, A))
/mob/proc/slip(s_amount, w_amount, obj/O, lube)
return

View File

@@ -109,7 +109,7 @@
/obj/vehicle/Move(NewLoc,Dir=0,step_x=0,step_y=0)
..()
. = ..()
handle_vehicle_layer()
handle_vehicle_offsets()

View File

@@ -1229,7 +1229,6 @@
#include "code\modules\mob\mob.dm"
#include "code\modules\mob\mob_cleanup.dm"
#include "code\modules\mob\mob_defines.dm"
#include "code\modules\mob\mob_grab.dm"
#include "code\modules\mob\mob_helpers.dm"
#include "code\modules\mob\mob_movement.dm"
#include "code\modules\mob\mob_transformation_simple.dm"