diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm
index a68276a3100..6fbdba918ed 100644
--- a/code/game/objects/items/weapons/kitchen.dm
+++ b/code/game/objects/items/weapons/kitchen.dm
@@ -153,6 +153,7 @@
icon_state = "knife"
desc = "A general purpose Chef's Knife made by SpaceCook Incorporated. Guaranteed to stay sharp for years to come."
flags = FPRINT | TABLEPASS | CONDUCT
+ sharp = 1
force = 10.0
w_class = 3.0
throwforce = 6.0
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 08af5cda280..92e6b78d754 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -146,5 +146,5 @@
item_state = "harpoon"
force = 20
throwforce = 15
- w_class = 2
+ w_class = 3
attack_verb = list("jabbed","stabbed","ripped")
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 63d685bfbdd..fc93d905b63 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -45,7 +45,7 @@
if(istype(tmob, /mob/living/carbon/human))
for(var/mob/M in range(tmob, 1))
- if( ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) )
+ if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) )
if ( !(world.time % 5) )
src << "\red [tmob] is restrained, you cannot push past"
now_pushing = 0
@@ -1153,6 +1153,11 @@
affected.implants -= selection
shock_stage+=10
+ for(var/obj/item/weapon/O in pinned)
+ if(O == selection)
+ pinned -= O
+ src.anchored = 0
+
if(prob(10)) //I'M SO ANEMIC I COULD JUST -DIE-.
var/datum/wound/internal_bleeding/I = new (15)
affected.wounds += I
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index a3bc884c171..f7b2caecae3 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -61,7 +61,7 @@
P.on_hit(src, absorb)
return absorb
-/mob/living/hitby(atom/movable/AM as mob|obj,var/speed)//Standardization and logging -Sieve
+/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = 5)//Standardization and logging -Sieve
if(istype(AM,/obj/))
var/obj/O = AM
var/zone = ran_zone("chest",75)//Hits a random part of the body, geared towards the chest
@@ -73,11 +73,43 @@
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [zone].", "Your armor has softened hit to your [zone].")
if(armor < 2)
apply_damage(O.throwforce*(speed/5), dtype, zone, armor, O.sharp, O)
+
if(!O.fingerprintslast)
return
+
var/client/assailant = directory[ckey(O.fingerprintslast)]
if(assailant && assailant.mob && istype(assailant.mob,/mob))
var/mob/M = assailant.mob
src.attack_log += text("\[[time_stamp()]\] Has been hit with [O], last touched by [M.name] ([assailant.ckey])")
M.attack_log += text("\[[time_stamp()]\] Hit [src.name] ([src.ckey]) with [O]")
log_attack("[src.name] ([src.ckey]) was hit by [O], last touched by [M.name] ([assailant.ckey])")
+
+ // Begin BS12 momentum-transfer code.
+
+ if(speed > 20)
+ var/obj/item/weapon/W = O
+ var/momentum = speed/2
+ var/dir = get_dir(M,src)
+ visible_message("\red [src] staggers under the impact!","\red You stagger under the impact!")
+
+ src.throw_at(get_edge_target_turf(src,dir),1,momentum)
+
+ if(near_wall(dir,2) && W.w_class >= 3 && W.sharp) //If they're close to a wall and the projectile is suitable.
+ visible_message("[src] is pinned to the wall by [O]!","You are pinned to the wall by [O]!")
+ src.anchored = 1
+ src.pinned += O
+
+
+/mob/living/proc/near_wall(var/direction,var/distance=1)
+ var/turf/T = get_step(get_turf(src),direction)
+ var/i = 1
+ while(i>0 && i<=distance)
+ if(T.density) //Turf is a wall!
+ return 1
+ i++
+ T = get_step(T,direction)
+
+ return 0
+
+
+// End BS12 momentum-transfer code.
\ No newline at end of file
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 19d94b42f5a..8d76b47513c 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -24,7 +24,6 @@
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
var/incorporeal_move = 0 //0 is off, 1 is normal, 2 is for ninjas.
-
var/t_plasma = null
var/t_oxygen = null
var/t_sl_gas = null
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 253e4ee43dc..6e9beda1bad 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -583,24 +583,31 @@ var/list/slot_equipment_priority = list( \
pulling = null
/mob/proc/start_pulling(var/atom/movable/AM)
+
if ( !AM || !usr || src==AM || !isturf(src.loc) ) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort!
return
- if (!( AM.anchored ))
- if(pulling)
- var/pulling_old = pulling
- stop_pulling()
- // Are we pulling the same thing twice? Just stop pulling.
- if(pulling_old == AM)
- return
- src.pulling = AM
- AM.pulledby = src
- if(ismob(AM))
- var/mob/M = AM
- if(!iscarbon(src))
- M.LAssailant = null
- else
- M.LAssailant = usr
+ if (AM.anchored)
+ return
+
+ var/mob/M = AM
+ if(ismob(AM))
+ if(!iscarbon(src))
+ M.LAssailant = null
+ else
+ M.LAssailant = usr
+ if (M.pinned.len)
+ usr << "They're pinned, gtfo."
+ return
+
+ if(pulling)
+ var/pulling_old = pulling
+ stop_pulling()
+ // Are we pulling the same thing twice? Just stop pulling.
+ if(pulling_old == AM)
+ return
+ src.pulling = AM
+ AM.pulledby = src
/mob/proc/can_use_hands()
return
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 9715e6ed20c..140e5b63572 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -85,6 +85,7 @@
var/lastpuke = 0
var/unacidable = 0
var/small = 0
+ var/list/pinned = list() //List of things pinning this creature to walls (see living_defense.dm)
var/name_archive //For admin things like possession
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index cec9b06861a..80d55c0a041 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -256,7 +256,6 @@
if(!mob.canmove) return
-
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
// if(!mob.Process_Spacemove(0)) return 0
@@ -279,6 +278,10 @@
src << "\blue You're restrained! You can't move!"
return 0
+ if(mob.pinned.len)
+ src << "\blue You're pinned to a wall by [mob.pinned[1]]!"
+ return 0
+
move_delay = world.time//set move delay
mob.last_move_intent = world.time + 10
switch(mob.m_intent)
diff --git a/code/modules/projectiles/guns/projectile/bow.dm b/code/modules/projectiles/guns/projectile/bow.dm
index a052f198422..25f4276d9a0 100644
--- a/code/modules/projectiles/guns/projectile/bow.dm
+++ b/code/modules/projectiles/guns/projectile/bow.dm
@@ -7,7 +7,7 @@
item_state = "bolt"
flags = FPRINT | TABLEPASS
throwforce = 12
- w_class = 2.0
+ w_class = 3.0
sharp = 1
/obj/item/weapon/arrow/proc/removed() //Helper for metal rods falling apart..
@@ -33,7 +33,7 @@
icon = 'icons/obj/weapons.dmi'
icon_state = "crossbow"
item_state = "crossbow-solid"
- w_class = 4.0
+ w_class = 5.0
flags = FPRINT | TABLEPASS | CONDUCT | USEDELAY
slot_flags = SLOT_BELT | SLOT_BACK
@@ -59,6 +59,7 @@
var/obj/item/stack/rods/R = W
R.use(1)
arrow = new /obj/item/weapon/arrow/rod(src)
+ arrow.fingerprintslast = src.fingerprintslast
arrow.loc = src
user.visible_message("[user] haphazardly jams [arrow] into [src].","You jam [arrow] into [src].")
if(cell)
@@ -156,6 +157,10 @@
else if(target == user)
return
+ if(!tension)
+ user << "You haven't drawn back the bolt!"
+ return 0
+
if (!arrow)
user << "You have no arrow nocked to [src]!"
return 0
diff --git a/code/modules/projectiles/guns/projectile/pneumatic.dm b/code/modules/projectiles/guns/projectile/pneumatic.dm
index 7d2f0c3b498..fe6c2651bd5 100644
--- a/code/modules/projectiles/guns/projectile/pneumatic.dm
+++ b/code/modules/projectiles/guns/projectile/pneumatic.dm
@@ -4,7 +4,7 @@
icon = 'icons/obj/gun.dmi'
icon_state = "pneumatic"
item_state = "pneumatic"
- w_class = 4.0
+ w_class = 5.0
flags = FPRINT | TABLEPASS | CONDUCT | USEDELAY
slot_flags = SLOT_BELT
max_w_class = 3