mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Merge remote-tracking branch 'upstream/master' into dev-freeze
This commit is contained in:
@@ -277,7 +277,11 @@ What a mess.*/
|
||||
else
|
||||
P.info += "<B>General Record Lost!</B><BR>"
|
||||
P.info += "</TT>"
|
||||
P.name = "Employment Record ([active1.fields["name"]])"
|
||||
if(active1)
|
||||
P.name = "Employment Record ([active1.fields["name"]])"
|
||||
else
|
||||
P.name = "Employment Record (Unknown/Invald Entry)"
|
||||
log_debug("[usr] ([usr.ckey]) attempted to print a null employee record, this should be investigated.")
|
||||
printing = null
|
||||
//RECORD DELETE
|
||||
if ("Delete All Records")
|
||||
|
||||
@@ -287,14 +287,18 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
|
||||
|
||||
/* --- Loop through the receivers and categorize them --- */
|
||||
|
||||
if (R.client && !(R.client.prefs.toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios.
|
||||
continue
|
||||
if (R.client)
|
||||
if(R.client.prefs)
|
||||
if(!(R.client.prefs.toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios.
|
||||
continue
|
||||
else
|
||||
log_debug("Client prefs found to be null in /proc/Broadcast_Message() for mob [R] and client [R.ckey], this should be investigated.")
|
||||
|
||||
if(istype(R, /mob/new_player)) // we don't want new players to hear messages. rare but generates runtimes.
|
||||
continue
|
||||
|
||||
// Ghosts hearing all radio chat don't want to hear syndicate intercepts, they're duplicates
|
||||
if(data == 3 && istype(R, /mob/dead/observer) && R.client && (R.client.prefs.toggles & CHAT_GHOSTRADIO))
|
||||
if(data == 3 && istype(R, /mob/dead/observer) && R.client && R.client.prefs && (R.client.prefs.toggles & CHAT_GHOSTRADIO))
|
||||
continue
|
||||
|
||||
// --- Check for compression ---
|
||||
@@ -490,8 +494,12 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
|
||||
|
||||
/* --- Loop through the receivers and categorize them --- */
|
||||
|
||||
if (R.client && !(R.client.prefs.toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios.
|
||||
continue
|
||||
if (R.client)
|
||||
if(R.client.prefs)
|
||||
if(!(R.client.prefs.toggles & CHAT_RADIO)) //Adminning with 80 people on can be fun when you're trying to talk and all you can hear is radios.
|
||||
continue
|
||||
else
|
||||
log_debug("Client prefs found to be null in /proc/Broadcast_SimpleMessage() for mob [R] and client [R.ckey], this should be investigated.")
|
||||
|
||||
|
||||
// --- Check for compression ---
|
||||
|
||||
@@ -336,7 +336,7 @@
|
||||
path = list()
|
||||
|
||||
/mob/living/bot/secbot/proc/check_threat(var/mob/living/M)
|
||||
if(!M || !istype(M) || M.stat)
|
||||
if(!M || !istype(M) || M.stat || src == M)
|
||||
return 0
|
||||
|
||||
if(emagged)
|
||||
|
||||
@@ -575,12 +575,14 @@ default behaviour is:
|
||||
|
||||
if(can_resist())
|
||||
next_move = world.time + 20
|
||||
process_resist()
|
||||
resist_grab()
|
||||
if(!weakened && !restrained())
|
||||
process_resist()
|
||||
|
||||
/mob/living/proc/can_resist()
|
||||
//need to allow !canmove, or otherwise neck grabs can't be resisted
|
||||
//so just check weakened instead.
|
||||
if(stat || weakened)
|
||||
//similar thing with weakened and pinning
|
||||
if(stat)
|
||||
return 0
|
||||
if(next_move > world.time)
|
||||
return 0
|
||||
@@ -592,10 +594,6 @@ default behaviour is:
|
||||
escape_inventory(src.loc)
|
||||
return
|
||||
|
||||
//resisting grabs (as if it helps anyone...)
|
||||
if (!restrained())
|
||||
resist_grab()
|
||||
|
||||
//unbuckling yourself
|
||||
if(buckled)
|
||||
spawn() escape_buckle()
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
#define UPGRADE_COOLDOWN 40
|
||||
#define UPGRADE_KILL_TIMER 100
|
||||
|
||||
///Process_Grab()
|
||||
///Called by client/Move()
|
||||
///Checks to see if you are grabbing anything and if moving will affect your grab.
|
||||
/client/proc/Process_Grab()
|
||||
for(var/obj/item/weapon/grab/G in list(mob.l_hand, mob.r_hand))
|
||||
G.reset_kill_state() //no wandering across the station/asteroid while choking someone
|
||||
|
||||
/obj/item/weapon/grab
|
||||
name = "grab"
|
||||
icon = 'icons/mob/screen1.dmi'
|
||||
@@ -69,7 +76,6 @@
|
||||
else
|
||||
hud.screen_loc = ui_lhand
|
||||
|
||||
|
||||
/obj/item/weapon/grab/process()
|
||||
if(gcDestroyed) // GC is trying to delete us, we'll kill our processing so we can cleanly GC
|
||||
return PROCESS_KILL
|
||||
@@ -116,23 +122,9 @@
|
||||
affecting.drop_l_hand()
|
||||
affecting.drop_r_hand()
|
||||
|
||||
var/hit_zone = assailant.zone_sel.selecting
|
||||
var/announce = 0
|
||||
if(hit_zone != last_hit_zone)
|
||||
announce = 1
|
||||
last_hit_zone = hit_zone
|
||||
if(ishuman(affecting))
|
||||
switch(hit_zone)
|
||||
if("mouth")
|
||||
if(announce)
|
||||
assailant.visible_message("<span class='warning'>[assailant] covers [affecting]'s mouth!</span>")
|
||||
if(affecting:silent < 3)
|
||||
affecting:silent = 3
|
||||
if("eyes")
|
||||
if(announce)
|
||||
assailant.visible_message("<span class='warning'>[assailant] covers [affecting]'s eyes!</span>")
|
||||
if(affecting:eye_blind < 3)
|
||||
affecting:eye_blind = 3
|
||||
if(iscarbon(affecting))
|
||||
handle_eye_mouth_covering(affecting, assailant, assailant.zone_sel.selecting)
|
||||
|
||||
if(force_down)
|
||||
if(affecting.loc != assailant.loc)
|
||||
force_down = 0
|
||||
@@ -153,6 +145,21 @@
|
||||
|
||||
adjust_position()
|
||||
|
||||
/obj/item/weapon/grab/proc/handle_eye_mouth_covering(mob/living/carbon/target, mob/user, var/target_zone)
|
||||
var/announce = (target_zone != last_hit_zone) //only display messages when switching between different target zones
|
||||
last_hit_zone = target_zone
|
||||
|
||||
switch(target_zone)
|
||||
if("mouth")
|
||||
if(announce)
|
||||
user.visible_message("<span class='warning'>\The [user] covers [target]'s mouth!</span>")
|
||||
if(target.silent < 3)
|
||||
target.silent = 3
|
||||
if("eyes")
|
||||
if(announce)
|
||||
assailant.visible_message("<span class='warning'>[assailant] covers [affecting]'s eyes!</span>")
|
||||
if(affecting.eye_blind < 3)
|
||||
affecting.eye_blind = 3
|
||||
|
||||
/obj/item/weapon/grab/attack_self()
|
||||
return s_click(hud)
|
||||
@@ -202,8 +209,6 @@
|
||||
if(EAST)
|
||||
animate(affecting, pixel_x =-shift, pixel_y = 0, 5, 1, LINEAR_EASING)
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/grab/proc/s_click(obj/screen/S)
|
||||
if(!affecting)
|
||||
return
|
||||
@@ -226,11 +231,8 @@
|
||||
assailant.visible_message("<span class='warning'>[assailant] has grabbed [affecting] aggressively (now hands)!</span>")
|
||||
else
|
||||
assailant.visible_message("<span class='warning'>[assailant] pins [affecting] down to the ground (now hands)!</span>")
|
||||
force_down = 1
|
||||
affecting.Weaken(3)
|
||||
step_to(assailant, affecting)
|
||||
assailant.set_dir(EAST) //face the victim
|
||||
affecting.set_dir(SOUTH) //face up
|
||||
apply_pinning(affecting, assailant)
|
||||
|
||||
state = GRAB_AGGRESSIVE
|
||||
icon_state = "grabbed1"
|
||||
hud.icon_state = "reinforce1"
|
||||
@@ -264,7 +266,6 @@
|
||||
affecting.set_dir(WEST)
|
||||
adjust_position()
|
||||
|
||||
|
||||
//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)
|
||||
@@ -278,17 +279,18 @@
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/weapon/grab/attack(mob/M, mob/living/user)
|
||||
if(!affecting)
|
||||
return
|
||||
|
||||
if(world.time < (last_action + 20))
|
||||
return
|
||||
|
||||
|
||||
last_action = world.time
|
||||
reset_kill_state() //using special grab moves will interrupt choking them
|
||||
|
||||
//clicking on the victim while grabbing them
|
||||
if(M == affecting)
|
||||
if(ishuman(M))
|
||||
last_action = world.time
|
||||
if(ishuman(affecting))
|
||||
var/hit_zone = assailant.zone_sel.selecting
|
||||
flick(hud.icon_state, hud)
|
||||
switch(assailant.a_intent)
|
||||
@@ -297,160 +299,37 @@
|
||||
assailant << "<span class='warning'>You are no longer pinning [affecting] to the ground.</span>"
|
||||
force_down = 0
|
||||
return
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/E = H.get_organ(hit_zone)
|
||||
if(E && !(E.status & ORGAN_DESTROYED))
|
||||
assailant.visible_message("<span class='notice'>[assailant] starts inspecting [affecting]'s [E.name] carefully.</span>")
|
||||
if(do_mob(assailant,H, 10))
|
||||
if(E.wounds.len)
|
||||
assailant << "<span class='warning'>You find [E.get_wounds_desc()]</span>"
|
||||
else
|
||||
assailant << "<span class='notice'>You find no visible wounds.</span>"
|
||||
else
|
||||
assailant << "<span class='notice'>You must stand still to inspect [E] for wounds.</span>"
|
||||
assailant << "<span class='notice'>Checking bones now...</span>"
|
||||
if(do_mob(assailant, H, 20))
|
||||
if(E.status & ORGAN_BROKEN)
|
||||
assailant << "<span class='warning'>The [E.encased ? E.encased : "bone in the [E.name]"] moves slightly when you poke it!</span>"
|
||||
H.custom_pain("Your [E.name] hurts where it's poked.")
|
||||
else
|
||||
assailant << "<span class='notice'>The [E.encased ? E.encased : "bones in the [E.name]"] seem to be fine.</span>"
|
||||
else
|
||||
assailant << "<span class='notice'>You must stand still to feel [E] for fractures.</span>"
|
||||
assailant << "<span class='notice'>Checking skin now...</span>"
|
||||
if(do_mob(assailant, H, 10))
|
||||
var/bad = 0
|
||||
if(H.getToxLoss() >= 40)
|
||||
assailant << "<span class='warning'>[H] has an unhealthy skin discoloration.</span>"
|
||||
bad = 1
|
||||
if(H.getOxyLoss() >= 20)
|
||||
assailant << "<span class='warning'>[H]'s skin is unusaly pale.</span>"
|
||||
bad = 1
|
||||
if(E.status & ORGAN_DEAD)
|
||||
assailant << "<span class='warning'>[E] is decaying!</span>"
|
||||
bad = 1
|
||||
if(!bad)
|
||||
assailant << "<span class='notice'>[H]'s skin is normal.</span>"
|
||||
else
|
||||
assailant << "<span class='notice'>You must stand still to check [H]'s skin for abnormalities.</span>"
|
||||
else
|
||||
assailant << "<span class='notice'>[H] is missing that bodypart.</span>"
|
||||
inspect_organ(affecting, assailant, hit_zone)
|
||||
|
||||
if(I_GRAB)
|
||||
if(state < GRAB_AGGRESSIVE)
|
||||
assailant << "<span class='warning'>You require a better grab to do this.</span>"
|
||||
return
|
||||
var/obj/item/organ/external/organ = affecting:get_organ(check_zone(hit_zone))
|
||||
if(!organ || organ.dislocated == -1)
|
||||
return
|
||||
assailant.visible_message("<span class='danger'>[assailant] [pick("bent", "twisted")] [affecting]'s [organ.name] into a jointlock!</span>")
|
||||
var/armor = affecting:run_armor_check(affecting, "melee")
|
||||
if(armor < 2)
|
||||
affecting << "<span class='danger'>You feel extreme pain!</span>"
|
||||
affecting.adjustHalLoss(Clamp(0, 40-affecting.halloss, 40)) //up to 40 halloss
|
||||
return
|
||||
jointlock(affecting, assailant, hit_zone)
|
||||
|
||||
if(I_HURT)
|
||||
|
||||
if(hit_zone == "eyes")
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
var/datum/unarmed_attack/attack = H.get_unarmed_attack(src, hit_zone)
|
||||
if(!attack)
|
||||
return
|
||||
|
||||
if(state < GRAB_NECK)
|
||||
assailant << "<span class='warning'>You require a better grab to do this.</span>"
|
||||
return
|
||||
if((affecting:head && affecting:head.flags & HEADCOVERSEYES) || \
|
||||
(affecting:wear_mask && affecting:wear_mask.flags & MASKCOVERSEYES) || \
|
||||
(affecting:glasses && affecting:glasses.flags & GLASSESCOVERSEYES))
|
||||
assailant << "<span class='danger'>You're going to need to remove the eye covering first.</span>"
|
||||
return
|
||||
if(!affecting.has_eyes())
|
||||
assailant << "<span class='danger'>You cannot locate any eyes on [affecting]!</span>"
|
||||
return
|
||||
assailant.attack_log += text("\[[time_stamp()]\] <font color='red'>Attacked [affecting.name]'s eyes using grab ([affecting.ckey])</font>")
|
||||
affecting.attack_log += text("\[[time_stamp()]\] <font color='orange'>Had eyes attacked by [assailant.name]'s grab ([assailant.ckey])</font>")
|
||||
msg_admin_attack("[key_name(assailant)] attacked [key_name(affecting)]'s eyes using a grab action.")
|
||||
|
||||
attack.handle_eye_attack(assailant, affecting)
|
||||
else if(hit_zone != "head")
|
||||
if(state < GRAB_NECK)
|
||||
assailant << "<span class='warning'>You require a better grab to do this.</span>"
|
||||
return
|
||||
if(affecting:grab_joint(assailant))
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
return
|
||||
attack_eye(affecting, assailant)
|
||||
else if(hit_zone == "head")
|
||||
headbut(affecting, assailant)
|
||||
else
|
||||
if(affecting.lying)
|
||||
return
|
||||
assailant.visible_message("<span class='danger'>[assailant] thrusts \his head into [affecting]'s skull!</span>")
|
||||
var/damage = 20
|
||||
var/obj/item/clothing/hat = assailant.head
|
||||
if(istype(hat))
|
||||
damage += hat.force * 10
|
||||
var/armor = affecting:run_armor_check(affecting, "melee")
|
||||
affecting.apply_damage(damage*rand(90, 110)/100, BRUTE, "head", armor)
|
||||
assailant.apply_damage(10*rand(90, 110)/100, BRUTE, "head", assailant:run_armor_check("head", "melee"))
|
||||
if(!armor && prob(damage))
|
||||
affecting.apply_effect(20, PARALYZE)
|
||||
affecting.visible_message("<span class='danger'>[affecting] has been knocked unconscious!</span>")
|
||||
playsound(assailant.loc, "swing_hit", 25, 1, -1)
|
||||
assailant.attack_log += text("\[[time_stamp()]\] <font color='red'>Headbutted [affecting.name] ([affecting.ckey])</font>")
|
||||
affecting.attack_log += text("\[[time_stamp()]\] <font color='orange'>Headbutted by [assailant.name] ([assailant.ckey])</font>")
|
||||
msg_admin_attack("[key_name(assailant)] has headbutted [key_name(affecting)]")
|
||||
assailant.drop_from_inventory(src)
|
||||
src.loc = null
|
||||
qdel(src)
|
||||
return
|
||||
dislocate(affecting, assailant, hit_zone)
|
||||
|
||||
if(I_DISARM)
|
||||
if(state < GRAB_AGGRESSIVE)
|
||||
assailant << "<span class='warning'>You require a better grab to do this.</span>"
|
||||
return
|
||||
assailant << "<span class='warning'>You start forcing [affecting] to the ground.</span>"
|
||||
if(!force_down)
|
||||
if(do_after(assailant, 20) && affecting)
|
||||
assailant.visible_message("<span class='danger'>[assailant] is forcing [affecting] to the ground!</span>")
|
||||
force_down = 1
|
||||
affecting.Weaken(3)
|
||||
affecting.lying = 1
|
||||
step_to(assailant, affecting)
|
||||
assailant.set_dir(EAST) //face the victim
|
||||
affecting.set_dir(SOUTH) //face up
|
||||
return
|
||||
else
|
||||
assailant << "<span class='warning'>You are already pinning [affecting] to the ground.</span>"
|
||||
return
|
||||
|
||||
pin_down(affecting, assailant)
|
||||
|
||||
//clicking on yourself while grabbing them
|
||||
if(M == assailant && state >= GRAB_AGGRESSIVE)
|
||||
|
||||
var/can_eat
|
||||
if((FAT in user.mutations) && issmall(affecting))
|
||||
can_eat = 1
|
||||
else
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(istype(H) && H.species.gluttonous)
|
||||
if(H.species.gluttonous == 2)
|
||||
can_eat = 2
|
||||
else if(!ishuman(affecting) && !issmall(affecting) && (affecting.small || iscarbon(affecting)))
|
||||
can_eat = 1
|
||||
|
||||
if(can_eat)
|
||||
var/mob/living/carbon/attacker = user
|
||||
user.visible_message("<span class='danger'>[user] is attempting to devour [affecting]!</span>")
|
||||
if(can_eat == 2)
|
||||
if(!do_mob(user, affecting)||!do_after(user, 30)) return
|
||||
else
|
||||
if(!do_mob(user, affecting)||!do_after(user, 100)) return
|
||||
user.visible_message("<span class='danger'>[user] devours [affecting]!</span>")
|
||||
affecting.loc = user
|
||||
attacker.stomach_contents.Add(affecting)
|
||||
qdel(src)
|
||||
|
||||
devour(affecting, assailant)
|
||||
|
||||
/obj/item/weapon/grab/dropped()
|
||||
loc = null
|
||||
if(!destroying)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/grab/proc/reset_kill_state()
|
||||
if(state == GRAB_KILL)
|
||||
assailant.visible_message("<span class='warning'>[assailant] lost \his tight grip on [affecting]'s neck!</span>")
|
||||
hud.icon_state = "kill"
|
||||
state = GRAB_NECK
|
||||
|
||||
/obj/item/weapon/grab
|
||||
var/destroying = 0
|
||||
|
||||
|
||||
165
code/modules/mob/mob_grab_specials.dm
Normal file
165
code/modules/mob/mob_grab_specials.dm
Normal file
@@ -0,0 +1,165 @@
|
||||
|
||||
/obj/item/weapon/grab/proc/inspect_organ(mob/living/carbon/human/H, mob/user, var/target_zone)
|
||||
|
||||
var/obj/item/organ/external/E = H.get_organ(target_zone)
|
||||
|
||||
if(!E || (E.status & ORGAN_DESTROYED))
|
||||
user << "<span class='notice'>[H] is missing that bodypart.</span>"
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] starts inspecting [affecting]'s [E.name] carefully.</span>")
|
||||
if(!do_mob(user,H, 10))
|
||||
user << "<span class='notice'>You must stand still to inspect [E] for wounds.</span>"
|
||||
else if(E.wounds.len)
|
||||
user << "<span class='warning'>You find [E.get_wounds_desc()]</span>"
|
||||
else
|
||||
user << "<span class='notice'>You find no visible wounds.</span>"
|
||||
|
||||
user << "<span class='notice'>Checking bones now...</span>"
|
||||
if(!do_mob(user, H, 20))
|
||||
user << "<span class='notice'>You must stand still to feel [E] for fractures.</span>"
|
||||
else if(E.status & ORGAN_BROKEN)
|
||||
user << "<span class='warning'>The [E.encased ? E.encased : "bone in the [E.name]"] moves slightly when you poke it!</span>"
|
||||
H.custom_pain("Your [E.name] hurts where it's poked.")
|
||||
else
|
||||
user << "<span class='notice'>The [E.encased ? E.encased : "bones in the [E.name]"] seem to be fine.</span>"
|
||||
|
||||
user << "<span class='notice'>Checking skin now...</span>"
|
||||
if(!do_mob(user, H, 10))
|
||||
user << "<span class='notice'>You must stand still to check [H]'s skin for abnormalities.</span>"
|
||||
else
|
||||
var/bad = 0
|
||||
if(H.getToxLoss() >= 40)
|
||||
user << "<span class='warning'>[H] has an unhealthy skin discoloration.</span>"
|
||||
bad = 1
|
||||
if(H.getOxyLoss() >= 20)
|
||||
user << "<span class='warning'>[H]'s skin is unusaly pale.</span>"
|
||||
bad = 1
|
||||
if(E.status & ORGAN_DEAD)
|
||||
user << "<span class='warning'>[E] is decaying!</span>"
|
||||
bad = 1
|
||||
if(!bad)
|
||||
user << "<span class='notice'>[H]'s skin is normal.</span>"
|
||||
|
||||
/obj/item/weapon/grab/proc/jointlock(mob/living/carbon/human/target, mob/attacker, var/target_zone)
|
||||
if(state < GRAB_AGGRESSIVE)
|
||||
attacker << "<span class='warning'>You require a better grab to do this.</span>"
|
||||
return
|
||||
|
||||
var/obj/item/organ/external/organ = target.get_organ(check_zone(target_zone))
|
||||
if(!organ || organ.dislocated == -1)
|
||||
return
|
||||
|
||||
attacker.visible_message("<span class='danger'>[attacker] [pick("bent", "twisted")] [target]'s [organ.name] into a jointlock!</span>")
|
||||
var/armor = target.run_armor_check(target, "melee")
|
||||
if(armor < 2)
|
||||
target << "<span class='danger'>You feel extreme pain!</span>"
|
||||
affecting.adjustHalLoss(Clamp(0, 60-affecting.halloss, 30)) //up to 60 halloss
|
||||
|
||||
/obj/item/weapon/grab/proc/attack_eye(mob/living/carbon/human/target, mob/living/carbon/human/attacker)
|
||||
if(!istype(attacker))
|
||||
return
|
||||
|
||||
var/datum/unarmed_attack/attack = attacker.get_unarmed_attack(target, "eyes")
|
||||
|
||||
if(!attack)
|
||||
return
|
||||
if(state < GRAB_NECK)
|
||||
attacker << "<span class='warning'>You require a better grab to do this.</span>"
|
||||
return
|
||||
for(var/obj/item/protection in list(target.head, target.wear_mask, target.glasses))
|
||||
if(protection && (protection.flags & HEADCOVERSEYES))
|
||||
attacker << "<span class='danger'>You're going to need to remove the eye covering first.</span>"
|
||||
return
|
||||
if(!target.has_eyes())
|
||||
attacker << "<span class='danger'>You cannot locate any eyes on [target]!</span>"
|
||||
return
|
||||
|
||||
attacker.attack_log += text("\[[time_stamp()]\] <font color='red'>Attacked [target.name]'s eyes using grab ([target.ckey])</font>")
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Had eyes attacked by [attacker.name]'s grab ([attacker.ckey])</font>")
|
||||
msg_admin_attack("[key_name(attacker)] attacked [key_name(target)]'s eyes using a grab action.")
|
||||
|
||||
attack.handle_eye_attack(attacker, target)
|
||||
|
||||
/obj/item/weapon/grab/proc/headbut(mob/living/carbon/human/target, mob/living/carbon/human/attacker)
|
||||
if(!istype(attacker))
|
||||
return
|
||||
if(target.lying)
|
||||
return
|
||||
attacker.visible_message("<span class='danger'>[attacker] thrusts \his head into [target]'s skull!</span>")
|
||||
|
||||
var/damage = 20
|
||||
var/obj/item/clothing/hat = attacker.head
|
||||
if(istype(hat))
|
||||
damage += hat.force * 10
|
||||
|
||||
var/armor = target.run_armor_check("head", "melee")
|
||||
target.apply_damage(damage*rand(90, 110)/100, BRUTE, "head", armor)
|
||||
attacker.apply_damage(10*rand(90, 110)/100, BRUTE, "head", attacker.run_armor_check("head", "melee"))
|
||||
|
||||
if(!armor && prob(damage))
|
||||
target.apply_effect(20, PARALYZE)
|
||||
target.visible_message("<span class='danger'>[target] has been knocked unconscious!</span>")
|
||||
|
||||
playsound(attacker.loc, "swing_hit", 25, 1, -1)
|
||||
attacker.attack_log += text("\[[time_stamp()]\] <font color='red'>Headbutted [target.name] ([target.ckey])</font>")
|
||||
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Headbutted by [attacker.name] ([attacker.ckey])</font>")
|
||||
msg_admin_attack("[key_name(attacker)] has headbutted [key_name(target)]")
|
||||
|
||||
attacker.drop_from_inventory(src)
|
||||
src.loc = null
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/grab/proc/dislocate(mob/living/carbon/human/target, mob/living/attacker, var/target_zone)
|
||||
if(state < GRAB_NECK)
|
||||
attacker << "<span class='warning'>You require a better grab to do this.</span>"
|
||||
return
|
||||
if(target.grab_joint(attacker, target_zone))
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
return
|
||||
|
||||
/obj/item/weapon/grab/proc/pin_down(mob/target, mob/attacker)
|
||||
if(state < GRAB_AGGRESSIVE)
|
||||
attacker << "<span class='warning'>You require a better grab to do this.</span>"
|
||||
return
|
||||
if(force_down)
|
||||
attacker << "<span class='warning'>You are already pinning [target] to the ground.</span>"
|
||||
|
||||
attacker.visible_message("<span class='danger'>[attacker] starts forcing [target] to the ground!</span>")
|
||||
if(do_after(attacker, 20) && target)
|
||||
last_action = world.time
|
||||
attacker.visible_message("<span class='danger'>[attacker] forces [target] to the ground!</span>")
|
||||
apply_pinning(target, attacker)
|
||||
|
||||
/obj/item/weapon/grab/proc/apply_pinning(mob/target, mob/attacker)
|
||||
force_down = 1
|
||||
target.Weaken(3)
|
||||
target.lying = 1
|
||||
step_to(attacker, target)
|
||||
attacker.set_dir(EAST) //face the victim
|
||||
target.set_dir(SOUTH) //face up
|
||||
|
||||
/obj/item/weapon/grab/proc/devour(mob/target, mob/user)
|
||||
var/can_eat
|
||||
if((FAT in user.mutations) && issmall(target))
|
||||
can_eat = 1
|
||||
else
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(istype(H) && H.species.gluttonous)
|
||||
if(H.species.gluttonous == 2)
|
||||
can_eat = 2
|
||||
else if(!ishuman(target) && !issmall(target) && (target.small || iscarbon(target)))
|
||||
can_eat = 1
|
||||
|
||||
if(can_eat)
|
||||
var/mob/living/carbon/attacker = user
|
||||
user.visible_message("<span class='danger'>[user] is attempting to devour [target]!</span>")
|
||||
if(can_eat == 2)
|
||||
if(!do_mob(user, target)||!do_after(user, 30)) return
|
||||
else
|
||||
if(!do_mob(user, target)||!do_after(user, 100)) return
|
||||
user.visible_message("<span class='danger'>[user] devours [target]!</span>")
|
||||
target.loc = user
|
||||
attacker.stomach_contents.Add(target)
|
||||
qdel(src)
|
||||
@@ -360,16 +360,6 @@
|
||||
return Move(n, direct)
|
||||
|
||||
|
||||
///Process_Grab()
|
||||
///Called by client/Move()
|
||||
///Checks to see if you are grabbing anything and if moving will affect your grab.
|
||||
/client/proc/Process_Grab()
|
||||
for(var/obj/item/weapon/grab/G in list(mob.l_hand, mob.r_hand))
|
||||
if(G.state == GRAB_KILL) //no wandering across the station/asteroid while choking someone
|
||||
mob.visible_message("<span class='warning'>[mob] lost \his tight grip on [G.affecting]'s neck!</span>")
|
||||
G.hud.icon_state = "kill"
|
||||
G.state = GRAB_NECK
|
||||
|
||||
///Process_Incorpmove
|
||||
///Called by client/Move()
|
||||
///Allows mobs to run though walls
|
||||
|
||||
Reference in New Issue
Block a user