mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -77,7 +77,7 @@
|
||||
CtrlClickOn(A)
|
||||
return
|
||||
|
||||
if(stat || paralysis || stunned || weakened || sleeping)
|
||||
if(incapacitated(ignore_restraints = 1))
|
||||
return
|
||||
|
||||
face_atom(A)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
. = ..()
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
countEggs()
|
||||
|
||||
/obj/item/weapon/storage/bag/easterbasket/handle_item_insertion(obj/item/I, prevent_warning = 0)
|
||||
..()
|
||||
. = ..()
|
||||
countEggs()
|
||||
|
||||
//Bunny Suit
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
@@ -1,5 +1,6 @@
|
||||
/mob/living/carbon/movement_delay()
|
||||
. = ..()
|
||||
. += grab_state * 3
|
||||
if(legcuffed)
|
||||
. += legcuffed.slowdown
|
||||
|
||||
|
||||
@@ -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>"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
@@ -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.
|
||||
|
||||
@@ -60,4 +60,4 @@
|
||||
|
||||
var/list/butcher_results = null
|
||||
var/hellbound = 0 //People who've signed infernal contracts are unrevivable.
|
||||
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
|
||||
|
||||
/obj/vehicle/Move(NewLoc,Dir=0,step_x=0,step_y=0)
|
||||
..()
|
||||
. = ..()
|
||||
handle_vehicle_layer()
|
||||
handle_vehicle_offsets()
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user