From ed1f2cc04cd66a0e740ba1ad8a7893c21ee67aca Mon Sep 17 00:00:00 2001 From: DZD Date: Tue, 14 Apr 2015 17:59:13 -0400 Subject: [PATCH] Martial Arts port from /tg/ - Ports tgstation/-tg-station#8810 and tgstation/-tg-station#8942 - Puts copypasta grab code in alien_defenses.dm and human_attackhand.dm files into a single proc in living_defense.dm, grabbedby. --- code/datums/martial.dm | 306 ++++++++++++++++++ .../mob/living/carbon/alien/alien_defenses.dm | 39 +-- .../living/carbon/human/human_attackhand.dm | 247 +++++++------- .../mob/living/carbon/human/human_defines.dm | 2 + code/modules/mob/living/living_defense.dm | 21 ++ paradise.dme | 1 + 6 files changed, 455 insertions(+), 161 deletions(-) create mode 100644 code/datums/martial.dm diff --git a/code/datums/martial.dm b/code/datums/martial.dm new file mode 100644 index 00000000000..3f13b49b4b5 --- /dev/null +++ b/code/datums/martial.dm @@ -0,0 +1,306 @@ +/datum/martial_art + var/name = "Martial Art" + var/streak = "" + var/max_streak_length = 6 + var/current_target = null + var/temporary = 0 + var/datum/martial_art/base = null // The permanent style + +/datum/martial_art/proc/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + return 0 + +/datum/martial_art/proc/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + return 0 + +/datum/martial_art/proc/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + return 0 + +/datum/martial_art/proc/add_to_streak(var/element,var/mob/living/carbon/human/D) + if(D != current_target) + current_target = D + streak = "" + streak = streak+element + if(length(streak) > max_streak_length) + streak = copytext(streak,2) + return + +/datum/martial_art/proc/basic_hit(var/mob/living/carbon/human/A,var/mob/living/carbon/human/D) + add_logs(A, D, "punched") + A.do_attack_animation(D) + var/damage = rand(0,9) + + var/atk_verb = "punch" + if(D.lying) + atk_verb = "kick" + + if(!damage) + playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + D.visible_message("[A] has attempted to [atk_verb] [D]!") + return 0 + + var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting)) + var/armor_block = D.run_armor_check(affecting, "melee") + + playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) + + D.visible_message("[A] has [atk_verb]ed [D]!", \ + "[A] has [atk_verb]ed [D]!") + + D.apply_damage(damage, BRUTE, affecting, armor_block) + if((D.stat != DEAD) && damage >= 9) + D.visible_message("[A] has weakened [D]!!", \ + "[A] has weakened [D]!") + D.apply_effect(4, WEAKEN, armor_block) + D.forcesay(hit_appends) + else if(D.lying) + D.forcesay(hit_appends) + return 1 + +/datum/martial_art/proc/teach(var/mob/living/carbon/human/H,var/make_temporary=0) + if(make_temporary) + temporary = 1 + if(H.martial_art && H.martial_art.temporary) + if(temporary) + base = H.martial_art.base + else + H.martial_art.base = src //temporary styles have priority + return + H.martial_art = src + +/datum/martial_art/proc/remove(var/mob/living/carbon/human/H) + if(H.martial_art != src) + return + H.martial_art = base + + +/datum/martial_art/boxing + name = "Boxing" + +/datum/martial_art/boxing/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + A << " Can't disarm while boxing!" + return 1 + +/datum/martial_art/boxing/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + A << " Can't grab while boxing!" + return 1 + +/datum/martial_art/boxing/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + add_logs(A, D, "punched") + A.do_attack_animation(D) + + var/atk_verb = pick("left hook","right hook","straight punch") + + var/damage = rand(5,8) + + if(!damage) + playsound(D.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + D.visible_message("[A] has attempted to hit [D] with a [atk_verb]!") + return 0 + + + var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting)) + var/armor_block = D.run_armor_check(affecting, "melee") + + playsound(D.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) + + + D.visible_message("[A] has hit [D] with a [atk_verb]!", \ + "[A] has hit [D] with a [atk_verb]!") + + D.apply_damage(damage, STAMINA, affecting, armor_block) + if(D.getStaminaLoss() > 50) + var/knockout_prob = D.getStaminaLoss() + rand(-15,15) + if((D.stat != DEAD) && prob(knockout_prob)) + D.visible_message("[A] has knocked [D] out with a haymaker!", \ + "[A] has knocked [D] out with a haymaker!") + D.apply_effect(10,WEAKEN,armor_block) + D.SetSleeping(5) + D.forcesay(hit_appends) + else if(D.lying) + D.forcesay(hit_appends) + return 1 + +/datum/martial_art/wrestling + name = "Wrestling" + +/datum/martial_art/wrestling/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + D.grabbedby(A,1) + var/obj/item/weapon/grab/G = A.get_active_hand() + if(G && prob(50)) + G.state = GRAB_AGGRESSIVE + D.visible_message("[A] has [D] in a clinch!", \ + "[A] has [D] in a clinch!") + else + D.visible_message("[A] fails to get [D] in a clinch!", \ + "[A] fails to get [D] in a clinch!") + return 1 + + +/datum/martial_art/wrestling/proc/Suplex(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + add_logs(A, D, "suplexed") + D.visible_message("[A] suplexes [D]!", \ + "[A] suplexes [D]!") + D.forceMove(A.loc) + var/armor_block = D.run_armor_check(null, "melee") + D.apply_damage(30, BRUTE, null, armor_block) + D.apply_effect(6, WEAKEN, armor_block) + A.SpinAnimation(10,1) + + D.SpinAnimation(10,1) + spawn(3) + armor_block = A.run_armor_check(null, "melee") + A.apply_effect(4, WEAKEN, armor_block) + return + +/datum/martial_art/wrestling/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + if(istype(A.get_inactive_hand(),/obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = A.get_inactive_hand() + if(G.affecting == D) + Suplex(A,D) + return 1 + harm_act(A,D) + return 1 + +/datum/martial_art/wrestling/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + D.grabbedby(A,1) + D.visible_message("[A] holds [D] down!", \ + "[A] holds [D] down!") + var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_sel.selecting)) + var/armor_block = D.run_armor_check(affecting, "melee") + D.apply_damage(10, STAMINA, affecting, armor_block) + return 1 + +#define TORNADO_COMBO "HHD" +#define THROWBACK_COMBO "DHD" +#define PLASMA_COMBO "HDDDH" + +/datum/martial_art/plasma_fist + name = "Plasma Fist" + +/datum/martial_art/plasma_fist/proc/check_streak(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + if(findtext(streak,TORNADO_COMBO)) + streak = "" + Tornado(A,D) + return 1 + if(findtext(streak,THROWBACK_COMBO)) + streak = "" + Throwback(A,D) + return 1 + if(findtext(streak,PLASMA_COMBO)) + streak = "" + Plasma(A,D) + return 1 + return 0 + +/datum/martial_art/plasma_fist/proc/Tornado(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + A.say("TORNADO SWEEP!") + spawn(0) + for(var/i in list(NORTH,SOUTH,EAST,WEST,EAST,SOUTH,NORTH,SOUTH,EAST,WEST,EAST,SOUTH)) + A.dir = i + playsound(A.loc, 'sound/weapons/punch1.ogg', 15, 1, -1) + sleep(1) + var/obj/effect/proc_holder/spell/wizard/aoe_turf/repulse/R = new(null) + var/list/turfs = list() + for(var/turf/T in range(1,A)) + turfs.Add(T) + R.cast(turfs) + return + +/datum/martial_art/plasma_fist/proc/Throwback(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + D.visible_message("[A] has hit [D] with Plasma Punch!", \ + "[A] has hit [D] with Plasma Punch!") + playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) + var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A))) + D.throw_at(throw_target, 200, 4) + A.say("HYAH!") + return + +/datum/martial_art/plasma_fist/proc/Plasma(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + A.do_attack_animation(D) + playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1) + A.say("PLASMA FIST!") + D.visible_message("[A] has hit [D] with THE PLASMA FIST TECHNIQUE!", \ + "[A] has hit [D] with THE PLASMA FIST TECHNIQUE!") + D.gib() + return + +/datum/martial_art/plasma_fist/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + add_to_streak("H") + if(check_streak(A,D)) + return 1 + basic_hit(A,D) + return 1 + +/datum/martial_art/plasma_fist/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + add_to_streak("D") + if(check_streak(A,D)) + return 1 + basic_hit(A,D) + return 1 + +/datum/martial_art/plasma_fist/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) + add_to_streak("G") + if(check_streak(A,D)) + return 1 + basic_hit(A,D) + return 1 + + +//ITEMS + +/obj/item/clothing/gloves/boxing + var/datum/martial_art/boxing/style = new + +/obj/item/clothing/gloves/boxing/equipped(mob/user, slot) + if(!ishuman(user)) + return + if(slot == slot_gloves) + var/mob/living/carbon/human/H = user + style.teach(H,1) + return + +/obj/item/clothing/gloves/boxing/dropped(mob/user) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(H.get_item_by_slot(slot_gloves) == src) + style.remove(H) + return + +/obj/item/weapon/storage/belt/champion/wrestling + name = "Wrestling Belt" + var/datum/martial_art/wrestling/style = new + +/obj/item/weapon/storage/belt/champion/wrestling/equipped(mob/user, slot) + if(!ishuman(user)) + return + if(slot == slot_belt) + var/mob/living/carbon/human/H = user + style.teach(H,1) + return + +/obj/item/weapon/storage/belt/champion/wrestling/dropped(mob/user) + if(!ishuman(user)) + return + var/mob/living/carbon/human/H = user + if(H.get_item_by_slot(slot_belt) == src) + style.remove(H) + return + +/obj/item/weapon/plasma_fist_scroll + name = "Plasma Fist Scroll" + desc = "Teaches the traditional wizard martial art." + icon = 'icons/obj/wizard.dmi' + icon_state ="scroll2" + var/used = 0 + +/obj/item/weapon/plasma_fist_scroll/attack_self(mob/user as mob) + if(!ishuman(user)) + return + if(!used) + var/mob/living/carbon/human/H = user + var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null) + F.teach(H) + H << "You learn the PLASMA FIST style." + used = 1 + desc += "It looks like it's magic was used up." diff --git a/code/modules/mob/living/carbon/alien/alien_defenses.dm b/code/modules/mob/living/carbon/alien/alien_defenses.dm index 9f57ad843ce..95ed75f18a0 100644 --- a/code/modules/mob/living/carbon/alien/alien_defenses.dm +++ b/code/modules/mob/living/carbon/alien/alien_defenses.dm @@ -1,6 +1,6 @@ /mob/living/carbon/alien/hitby(atom/movable/AM) ..(AM, 1) - + /*Code for aliens attacking aliens. Because aliens act on a hivemind, I don't see them as very aggressive with each other. As such, they can either help or harm other aliens. Help works like the human help command while harm is a simple nibble. In all, this is a lot like the monkey code. /N @@ -25,23 +25,8 @@ In all, this is a lot like the monkey code. /N visible_message("[M.name] nuzzles [src] trying to wake it up!") if ("grab") - if (M == src || anchored) - return - if (!(status_flags & CANPUSH)) - return - - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) - - M.put_in_active_hand(G) - - grabbed_by += G - G.synch() - - LAssailant = M - - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has grabbed [] passively!", M, src), 1) + src.grabbedby(M) + return 1 else if (health > 0) @@ -69,23 +54,7 @@ In all, this is a lot like the monkey code. /N if("help") help_shake_act(M) if("grab") - if (M == src || anchored) - return - if (!(status_flags & CANPUSH)) - return - - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) - - M.put_in_active_hand(G) - - grabbed_by += G - G.synch() - - LAssailant = M - - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("\red [] has grabbed [] passively!", M, src), 1) + src.grabbedby(M) if ("harm", "disarm") return 1 return 0 diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 848d5f11b51..b2be2f8e29d 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -53,6 +53,8 @@ // log_debug("No gloves, [M] is truing to infect [src]") M.spread_disease_to(src, "Contact") + var/datum/martial_art/attacker_style = M.martial_art + switch(M.a_intent) if("help") if(health >= config.health_threshold_crit) @@ -81,149 +83,142 @@ return 1 if("grab") - if(M == src || anchored) - return 0 - if(w_uniform) - w_uniform.add_fingerprint(M) - - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src) - if(buckled) - M << "You cannot grab [src], \he is buckled in!" - if(!G) //the grab will delete itself in New if affecting is anchored - return - M.put_in_active_hand(G) - grabbed_by += G - G.synch() - LAssailant = M - - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - visible_message("[M] has grabbed [src] passively!") - add_logs(src, M, "grabbed", addition="passively") - return 1 + if(attacker_style && attacker_style.grab_act(H, src)) + return 1 + else + src.grabbedby(M) + return 1 if("harm") - var/datum/unarmed_attack/attack = M.species.unarmed - //Vampire code - if(M.zone_sel && M.zone_sel.selecting == "head" && src != M) - if(M.mind && M.mind.vampire && (M.mind in ticker.mode.vampires) && !M.mind.vampire.draining) - if((head && (head.flags & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags & MASKCOVERSMOUTH))) - M << "\red Remove their mask!" - return 0 - if((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH))) - M << "\red Remove your mask!" - return 0 - if(mind && mind.vampire && (mind in ticker.mode.vampires)) - M << "\red Your fangs fail to pierce [src.name]'s cold flesh" - return 0 - if(SKELETON in mutations) - M << "\red There is no blood in a skeleton!" - return 0 - //we're good to suck the blood, blaah - M.handle_bloodsucking(src) - add_logs(src, M, "vampirebit") - message_admins("[M.name] ([M.ckey]) vampirebit [src.name] ([src.ckey])") - return - //end vampire codes - - M.do_attack_animation(src) - add_logs(src, M, "[pick(attack.attack_verb)]ed") - - if(!iscarbon(M)) - LAssailant = null + if(attacker_style && attacker_style.harm_act(H, src)) + return 1 else - LAssailant = M + var/datum/unarmed_attack/attack = M.species.unarmed - var/damage = rand(0, M.species.max_hurt_damage)//BS12 EDIT - if(!damage) - playsound(loc, attack.miss_sound, 25, 1, -1) - visible_message("\red [M] tried to [pick(attack.attack_verb)] [src]!") - return 0 + //Vampire code + if(M.zone_sel && M.zone_sel.selecting == "head" && src != M) + if(M.mind && M.mind.vampire && (M.mind in ticker.mode.vampires) && !M.mind.vampire.draining) + if((head && (head.flags & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags & MASKCOVERSMOUTH))) + M << "\red Remove their mask!" + return 0 + if((M.head && (M.head.flags & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags & MASKCOVERSMOUTH))) + M << "\red Remove your mask!" + return 0 + if(mind && mind.vampire && (mind in ticker.mode.vampires)) + M << "\red Your fangs fail to pierce [src.name]'s cold flesh" + return 0 + if(SKELETON in mutations) + M << "\red There is no blood in a skeleton!" + return 0 + //we're good to suck the blood, blaah + M.handle_bloodsucking(src) + add_logs(src, M, "vampirebit") + message_admins("[M.name] ([M.ckey]) vampirebit [src.name] ([src.ckey])") + return + //end vampire codes + M.do_attack_animation(src) + add_logs(src, M, "[pick(attack.attack_verb)]ed") - var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) - var/armor_block = run_armor_check(affecting, "melee") - - if(HULK in M.mutations) - damage += 5 - Weaken(4) - - playsound(loc, attack.attack_sound, 25, 1, -1) - - visible_message("\red [M] [pick(attack.attack_verb)]ed [src]!") - - damage += attack.damage - apply_damage(damage, BRUTE, affecting, armor_block, sharp=attack.sharp, edge=attack.edge) //moving this back here means Armalis are going to knock you down 70% of the time, but they're pure adminbus anyway. - if((stat != DEAD) && damage >= 9) - visible_message("[M] has weakened [src]!", \ - "[M] has weakened [src]!") - apply_effect(4, WEAKEN, armor_block) - forcesay(hit_appends) - else if(lying) - forcesay(hit_appends) - - - if("disarm") - add_logs(src, M, "disarmed") - - if(w_uniform) - w_uniform.add_fingerprint(M) - var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) - var/randn = rand(1, 100) - if (randn <= 25) - apply_effect(2, WEAKEN, run_armor_check(affecting, "melee")) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - visible_message("\red [M] has pushed [src]!") - M.attack_log += text("\[[time_stamp()]\] Pushed [src.name] ([src.ckey])") - src.attack_log += text("\[[time_stamp()]\] Has been pushed by [M.name] ([M.ckey])") if(!iscarbon(M)) LAssailant = null else LAssailant = M - log_attack("[M.name] ([M.ckey]) pushed [src.name] ([src.ckey])") - return + var/damage = rand(0, M.species.max_hurt_damage)//BS12 EDIT + if(!damage) + playsound(loc, attack.miss_sound, 25, 1, -1) + visible_message("\red [M] tried to [pick(attack.attack_verb)] [src]!") + return 0 -/* if(randn <= 45 && !lying) - if(head) - var/obj/item/clothing/head/H = head - if(!istype(H) || prob(H.loose)) - if(unEquip(H)) - if(prob(60)) - step_away(H,M) - visible_message("[M] has knocked [src]'s [H] off!", - "[M] knocked \the [H] clean off your head!") */ - var/talked = 0 // BubbleWrap + var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) + var/armor_block = run_armor_check(affecting, "melee") - if(randn <= 60) - //BubbleWrap: Disarming breaks a pull - if(pulling) - visible_message("\red [M] has broken [src]'s grip on [pulling]!") - talked = 1 - stop_pulling() + if(HULK in M.mutations) + damage += 5 + Weaken(4) - //BubbleWrap: Disarming also breaks a grab - this will also stop someone being choked, won't it? - if(istype(l_hand, /obj/item/weapon/grab)) - var/obj/item/weapon/grab/lgrab = l_hand - if(lgrab.affecting) - visible_message("\red [M] has broken [src]'s grip on [lgrab.affecting]!") + playsound(loc, attack.attack_sound, 25, 1, -1) + + visible_message("\red [M] [pick(attack.attack_verb)]ed [src]!") + + damage += attack.damage + apply_damage(damage, BRUTE, affecting, armor_block, sharp=attack.sharp, edge=attack.edge) //moving this back here means Armalis are going to knock you down 70% of the time, but they're pure adminbus anyway. + if((stat != DEAD) && damage >= 9) + visible_message("[M] has weakened [src]!", \ + "[M] has weakened [src]!") + apply_effect(4, WEAKEN, armor_block) + forcesay(hit_appends) + else if(lying) + forcesay(hit_appends) + + + if("disarm") + if(attacker_style && attacker_style.disarm_act(H, src)) + return 1 + else + add_logs(src, M, "disarmed") + + if(w_uniform) + w_uniform.add_fingerprint(M) + var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) + var/randn = rand(1, 100) + if (randn <= 25) + apply_effect(2, WEAKEN, run_armor_check(affecting, "melee")) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + visible_message("\red [M] has pushed [src]!") + M.attack_log += text("\[[time_stamp()]\] Pushed [src.name] ([src.ckey])") + src.attack_log += text("\[[time_stamp()]\] Has been pushed by [M.name] ([M.ckey])") + if(!iscarbon(M)) + LAssailant = null + else + LAssailant = M + + log_attack("[M.name] ([M.ckey]) pushed [src.name] ([src.ckey])") + return + + /* if(randn <= 45 && !lying) + if(head) + var/obj/item/clothing/head/H = head + if(!istype(H) || prob(H.loose)) + if(unEquip(H)) + if(prob(60)) + step_away(H,M) + visible_message("[M] has knocked [src]'s [H] off!", + "[M] knocked \the [H] clean off your head!") */ + + var/talked = 0 // BubbleWrap + + if(randn <= 60) + //BubbleWrap: Disarming breaks a pull + if(pulling) + visible_message("\red [M] has broken [src]'s grip on [pulling]!") talked = 1 - spawn(1) - del(lgrab) - if(istype(r_hand, /obj/item/weapon/grab)) - var/obj/item/weapon/grab/rgrab = r_hand - if(rgrab.affecting) - visible_message("\red [M] has broken [src]'s grip on [rgrab.affecting]!") - talked = 1 - spawn(1) - del(rgrab) - //End BubbleWrap + stop_pulling() - if(!talked) //BubbleWrap - if(drop_item()) - visible_message("\red [M] has disarmed [src]!") - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - return + //BubbleWrap: Disarming also breaks a grab - this will also stop someone being choked, won't it? + if(istype(l_hand, /obj/item/weapon/grab)) + var/obj/item/weapon/grab/lgrab = l_hand + if(lgrab.affecting) + visible_message("\red [M] has broken [src]'s grip on [lgrab.affecting]!") + talked = 1 + spawn(1) + del(lgrab) + if(istype(r_hand, /obj/item/weapon/grab)) + var/obj/item/weapon/grab/rgrab = r_hand + if(rgrab.affecting) + visible_message("\red [M] has broken [src]'s grip on [rgrab.affecting]!") + talked = 1 + spawn(1) + del(rgrab) + //End BubbleWrap + + if(!talked) //BubbleWrap + if(drop_item()) + visible_message("\red [M] has disarmed [src]!") + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + return playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 04189211f2f..b792385f581 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -55,6 +55,8 @@ var/speech_problem_flag = 0 + var/datum/martial_art/martial_art = null + var/miming = null //Toggle for the mime's abilities. var/special_voice = "" // For changing our voice. Used by a symptom. var/said_last_words=0 diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 5af3c8953c0..deb84cdf5e4 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -257,3 +257,24 @@ IgniteMob() //Mobs on Fire end + +/mob/living/proc/grabbedby(mob/living/carbon/user,var/supress_message = 0) + if(user == src || anchored) + return 0 + if(!(status_flags & CANPUSH)) + return 0 + + add_logs(user, src, "grabbed", addition="passively") + + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(user, src) + if(buckled) + user << "You cannot grab [src], \he is buckled in!" + if(!G) //the grab will delete itself in New if src is anchored + return 0 + user.put_in_active_hand(G) + G.synch() + LAssailant = user + + playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + if(!supress_message) + visible_message("[user] has grabbed [src] passively!") diff --git a/paradise.dme b/paradise.dme index f4bdc02c04c..899cc7bde06 100644 --- a/paradise.dme +++ b/paradise.dme @@ -134,6 +134,7 @@ #include "code\datums\computerfiles.dm" #include "code\datums\datacore.dm" #include "code\datums\datumvars.dm" +#include "code\datums\martial.dm" #include "code\datums\medical_effects.dm" #include "code\datums\mind.dm" #include "code\datums\mixed.dm"