From 9976291ca493af3544b9678d13d62c8d5f467b0c Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Tue, 24 May 2016 10:54:22 -0400 Subject: [PATCH 01/19] Refactors dislocation, clearer distinction between is_dislocated() and is_usable() Dislocation no longer relies on adjusting dislocated state of children. Fixes dislocating and relocating parent organs magically fixing children or protecting children from being dislocated. Dislocated limbs no longer count as unusable, since they already count for stance damage and dropping items anyways. In addition, dislocated limbs add to traumatic_shock Also corrects a misusage of traumatic_shock --- code/modules/mob/living/carbon/carbon.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 2 +- .../living/carbon/human/human_attackhand.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 5 +- code/modules/mob/living/carbon/shock.dm | 4 +- code/modules/organs/organ_external.dm | 48 +++++++++++-------- 6 files changed, 37 insertions(+), 26 deletions(-) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 6b9cbf0258..294b9c8669 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -194,7 +194,7 @@ status += "hurts when touched" if(org.status & ORGAN_DEAD) status += "is bruised and necrotic" - if(!org.is_usable()) + if(!org.is_usable() || org.is_dislocated()) status += "dangling uselessly" if(status.len) src.show_message("My [org.name] is [english_list(status)].",1) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index d6a88f35ff..01614964e3 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1324,7 +1324,7 @@ var/list/limbs = list() for(var/limb in organs_by_name) var/obj/item/organ/external/current_limb = organs_by_name[limb] - if(current_limb && current_limb.dislocated == 2) + if(current_limb && current_limb.dislocated > 0 && !current_limb.is_parent_dislocated()) //if the parent is also dislocated you will have to relocate that first limbs |= limb var/choice = input(usr,"Which joint do you wish to relocate?") as null|anything in limbs diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 7cc3156f18..d8d40ab660 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -326,7 +326,7 @@ if(!target_zone) return 0 var/obj/item/organ/external/organ = get_organ(check_zone(target_zone)) - if(!organ || organ.is_dislocated() || organ.dislocated == -1) + if(!organ || organ.dislocated > 0 || organ.dislocated == -1) //don't use is_dislocated() here, that checks parent return 0 user.visible_message("[user] begins to dislocate [src]'s [organ.joint]!") diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 80798fa57b..8e892436e0 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -847,7 +847,10 @@ if(!isSynthetic() && (species.flags & IS_PLANT) && (!light_organ || light_organ.is_broken())) if(nutrition < 200) take_overall_damage(2,0) - traumatic_shock++ + + //traumatic_shock is updated every tick, incrementing that is pointless - shock_stage is the counter. + //Not that it matters much for diona, who have NO_PAIN. + shock_stage++ // TODO: stomach and bloodstream organ. if(!isSynthetic()) diff --git a/code/modules/mob/living/carbon/shock.dm b/code/modules/mob/living/carbon/shock.dm index 92eccc66df..370d3f89d2 100644 --- a/code/modules/mob/living/carbon/shock.dm +++ b/code/modules/mob/living/carbon/shock.dm @@ -23,8 +23,10 @@ if(istype(src,/mob/living/carbon/human)) var/mob/living/carbon/human/M = src for(var/obj/item/organ/external/organ in M.organs) - if(organ && (organ.is_broken() || organ.open)) + if(organ.is_broken() || organ.open) src.traumatic_shock += 30 + else if(organ.is_dislocated()) + src.traumatic_shock += 15 if(src.traumatic_shock < 0) src.traumatic_shock = 0 diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index a1a31fad7c..d3b309fd84 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -60,7 +60,7 @@ var/cannot_gib // Impossible to gib, distinct from amputation. var/joint = "joint" // Descriptive string used in dislocation. var/amputation_point // Descriptive string used in amputation. - var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ. + var/dislocated = 0 // If you target a joint, you can dislocate the limb, impairing it's usefulness and causing pain var/encased // Needs to be opened with a saw to access the organs. // Surgery vars. @@ -156,32 +156,38 @@ /obj/item/organ/external/proc/is_dislocated() if(dislocated > 0) return 1 - if(parent) - return parent.is_dislocated() + if(is_parent_dislocated()) + return 1//if any parent is dislocated, we are considered dislocated as well return 0 -/obj/item/organ/external/proc/dislocate(var/primary) - if(dislocated != -1) - if(primary) - dislocated = 2 - else - dislocated = 1 - owner.verbs |= /mob/living/carbon/human/proc/undislocate - if(children && children.len) - for(var/obj/item/organ/external/child in children) - child.dislocate() +/obj/item/organ/external/proc/is_parent_dislocated() + var/obj/item/organ/external/O = parent + while(O && O.dislocated != -1) + if(O.dislocated == 1) + return 1 + O = O.parent + return 0 + + +/obj/item/organ/external/proc/dislocate() + if(dislocated == -1) + return + + dislocated = 1 + if(owner) + owner.verbs |= /mob/living/carbon/human/proc/undislocate /obj/item/organ/external/proc/undislocate() - if(dislocated != -1) - dislocated = 0 - if(children && children.len) - for(var/obj/item/organ/external/child in children) - if(child.dislocated == 1) - child.undislocate() + if(dislocated == -1) + return + + dislocated = 0 if(owner) owner.shock_stage += 20 + + //check to see if we still need the verb for(var/obj/item/organ/external/limb in owner.organs) - if(limb.dislocated == 2) + if(limb.dislocated == 1) return owner.verbs -= /mob/living/carbon/human/proc/undislocate @@ -1085,7 +1091,7 @@ Note that amputating the affected organ does in fact remove the infection from t return 0 /obj/item/organ/external/proc/is_usable() - return !is_dislocated() && !(status & (ORGAN_MUTATED|ORGAN_DEAD)) + return !(status & (ORGAN_MUTATED|ORGAN_DEAD)) /obj/item/organ/external/proc/is_malfunctioning() return ((robotic >= ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam)) From fcb8c63d2a40e8cde8e1d5fcf787a4b1ee52f520 Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Tue, 24 May 2016 11:44:00 -0400 Subject: [PATCH 02/19] Fixes organs listed under organ tag instead of organ name when using undislocate verb --- code/modules/mob/living/carbon/human/human.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 01614964e3..e884dbcd5d 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1325,7 +1325,7 @@ for(var/limb in organs_by_name) var/obj/item/organ/external/current_limb = organs_by_name[limb] if(current_limb && current_limb.dislocated > 0 && !current_limb.is_parent_dislocated()) //if the parent is also dislocated you will have to relocate that first - limbs |= limb + limbs |= current_limb var/choice = input(usr,"Which joint do you wish to relocate?") as null|anything in limbs if(!choice) From 36e53d4b98a3f2dd1a30509ed6a85b6b7bb7ac0d Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Tue, 24 May 2016 11:47:11 -0400 Subject: [PATCH 03/19] Fixes disarm-attacking being very likely to break the limb before dislocating it. Also makes it possible to 'strike to cripple' with stunbatons --- code/game/objects/items/weapons/stunbaton.dm | 2 +- code/modules/mob/living/carbon/human/human_defense.dm | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index b7e55cddb8..5e01c43e55 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -122,7 +122,7 @@ var/mob/living/carbon/human/H = target affecting = H.get_organ(hit_zone) - if(user.a_intent == I_HURT) + if(user.a_intent == I_HURT || user.a_intent == I_DISARM) . = ..() //whacking someone causes a much poorer electrical contact than deliberately prodding them. agony *= 0.5 diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 614bbe1de8..810946f26f 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -245,7 +245,13 @@ emp_act /mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/blocked) if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100) return 0 - if(prob(W.force * (100 - blocked)/100)) + + if(W.damtype != BRUTE) + return 0 + + //want the dislocation chance to be such that the limb is expected to dislocate after dealing a fraction of the damage needed to break the limb + var/dislocate_chance = (W.force/2)/(0.5 * organ.min_broken_damage * config.organ_health_multiplier)*100 + if(prob(dislocate_chance * (W.force * (100 - blocked)/100))) visible_message("[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")]!") organ.dislocate(1) return 1 From 37cf0d3fffd3fb4c4719eb49770c2396f821453f Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Tue, 24 May 2016 12:13:50 -0400 Subject: [PATCH 04/19] Updates changelog --- html/changelogs/HarpyEagle-dislocation-cleanup.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/HarpyEagle-dislocation-cleanup.yml diff --git a/html/changelogs/HarpyEagle-dislocation-cleanup.yml b/html/changelogs/HarpyEagle-dislocation-cleanup.yml new file mode 100644 index 0000000000..84ae3a66b6 --- /dev/null +++ b/html/changelogs/HarpyEagle-dislocation-cleanup.yml @@ -0,0 +1,7 @@ +author: HarpyEagle + +delete-after: True + +changes: + - bugfix: "Fixes disarm-attack dislocation chances being so low that you were very likely to break the targeted limb before it would dislocate." + - bugfix: "It is now possible to disarm-attack with stunbatons like with other melee weapons. Note that this means that using a stunbaton on disarm intent will hurt people." From 6ecf6bc1541ba67f1b055c73bad6844d8747c574 Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Wed, 25 May 2016 23:04:03 -0400 Subject: [PATCH 05/19] Cleans up stance handling. Now that dislocation no longer implicates !is_usable(), we can tidy up stance_damage calculation. Also fixes stance being processed every tick except for the fourth, instead of the inverse --- code/modules/mob/living/carbon/human/human_organs.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index f65b9926c8..8db85ef5fe 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -68,7 +68,7 @@ /mob/living/carbon/human/proc/handle_stance() // Don't need to process any of this if they aren't standing anyways // unless their stance is damaged, and we want to check if they should stay down - if (!stance_damage && (lying || resting) && (life_tick % 4) == 0) + if (!stance_damage && (lying || resting) && (life_tick % 4) != 0) return stance_damage = 0 @@ -80,7 +80,7 @@ var/limb_pain for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot")) var/obj/item/organ/external/E = organs_by_name[limb_tag] - if(!E || (E.status & (ORGAN_MUTATED|ORGAN_DEAD)) || E.is_stump()) //should just be !E.is_usable() here but dislocation screws that up. + if(!E || !E.is_usable()) stance_damage += 2 // let it fail even if just foot&leg else if (E.is_malfunctioning()) //malfunctioning only happens intermittently so treat it as a missing limb when it procs @@ -93,7 +93,7 @@ spark_system.start() spawn(10) qdel(spark_system) - else if (E.is_broken() || !E.is_usable()) + else if (E.is_broken()) stance_damage += 1 else if (E.is_dislocated()) stance_damage += 0.5 From b410d43eb536aa45970b221d6e10a2017a855b21 Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Thu, 26 May 2016 13:51:21 -0400 Subject: [PATCH 06/19] Adjusts attack_joint() so that disarm attacking is actually useful If disarm attacking deals half damage but is expected to deal half the damage to the limb before dislocating it, it's not any more useful than just breaking their limbs, other than the fact that you do less damage --- .../mob/living/carbon/human/human_defense.dm | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 810946f26f..6edefd2951 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -187,11 +187,13 @@ emp_act // Handle striking to cripple. if(user.a_intent == I_DISARM) - effective_force /= 2 - if(..(I, user, effective_force, blocked, hit_zone)) - attack_joint(affecting, I, blocked) - else + effective_force *= 0.66 //reduced effective force... + if(!..(I, user, effective_force, blocked, hit_zone)) return 0 + + //set the dislocate mult less than the effective force mult so that + //dislocating limbs on disarm is a bit easier than breaking limbs on harm + attack_joint(affecting, I, effective_force, 0.5, blocked) //...but can dislocate joints else if(!..()) return 0 @@ -242,7 +244,7 @@ emp_act return 1 -/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/blocked) +/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/effective_force, var/dislocate_mult, var/blocked) if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100) return 0 @@ -250,8 +252,8 @@ emp_act return 0 //want the dislocation chance to be such that the limb is expected to dislocate after dealing a fraction of the damage needed to break the limb - var/dislocate_chance = (W.force/2)/(0.5 * organ.min_broken_damage * config.organ_health_multiplier)*100 - if(prob(dislocate_chance * (W.force * (100 - blocked)/100))) + var/dislocate_chance = effective_force/(dislocate_mult * organ.min_broken_damage * config.organ_health_multiplier)*100 + if(prob(dislocate_chance * (100 - blocked)/100)) visible_message("[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")]!") organ.dislocate(1) return 1 From fd3a3175ae8577a90b807b3fca44c36f12473a9e Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Fri, 13 May 2016 00:03:05 -0400 Subject: [PATCH 07/19] Moving while unable to move and grabbed acts as a shortcut for resist --- code/modules/mob/mob_grab.dm | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 47e0584740..b41d07dbb6 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -3,12 +3,17 @@ ///Process_Grab() ///Called by client/Move() -///Checks to see if you are grabbing anything and if moving will affect your grab. +///Checks to see if you are grabbing or being grabbed by anything and if moving will affect your grab. /client/proc/Process_Grab() - if(istype(mob, /mob/living)) + //if we are being grabbed + if(isliving(mob)) var/mob/living/L = mob - for(var/obj/item/weapon/grab/G in list(L.l_hand, L.r_hand)) - G.reset_kill_state() //no wandering across the station/asteroid while choking someone + if(!L.canmove && L.grabbed_by.len) + L.resist() //shortcut for resisting grabs + + //if we are grabbing someone + 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" From 0ba2aef187d295e5abbc2d409eea639ee5f53961 Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Tue, 24 May 2016 12:46:53 -0400 Subject: [PATCH 08/19] Fixes jointlock not accounting for species with less health or NO_PAIN --- code/modules/mob/mob_grab_specials.dm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm index 5158a7f3d0..af50746cd4 100644 --- a/code/modules/mob/mob_grab_specials.dm +++ b/code/modules/mob/mob_grab_specials.dm @@ -51,10 +51,16 @@ return attacker.visible_message("[attacker] [pick("bent", "twisted")] [target]'s [organ.name] into a jointlock!") + + if(target.species.flags & NO_PAIN) + return + var/armor = target.run_armor_check(target, "melee") if(armor < 60) target << "You feel extreme pain!" - affecting.adjustHalLoss(Clamp(0, 60-affecting.halloss, 30)) //up to 60 halloss + + var/max_halloss = round(target.species.total_health * 0.8) //up to 80% of passing out + affecting.adjustHalLoss(Clamp(0, max_halloss - affecting.halloss, 30)) /obj/item/weapon/grab/proc/attack_eye(mob/living/carbon/human/target, mob/living/carbon/human/attacker) if(!istype(attacker)) From 6599f64b10986257697c8982ce355902f67602b4 Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Tue, 24 May 2016 13:37:48 -0400 Subject: [PATCH 09/19] Stripping no longer uses requests, removes it from mob code --- code/modules/mob/living/living.dm | 4 ---- code/modules/mob/mob_defines.dm | 1 - 2 files changed, 5 deletions(-) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 4d2e254d30..51bac7bfb7 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -623,10 +623,6 @@ default behaviour is: /mob/living/proc/resist_grab() var/resisting = 0 - for(var/obj/O in requests) - requests.Remove(O) - qdel(O) - resisting++ for(var/obj/item/weapon/grab/G in grabbed_by) resisting++ switch(G.state) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index b67e58af3e..5b937a57e2 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -121,7 +121,6 @@ var/datum/hud/hud_used = null var/list/grabbed_by = list( ) - var/list/requests = list( ) var/list/mapobjs = list() From 69dd0bb5d0b97ab6ad7157b1e0e0d66d8dd730cf Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Tue, 24 May 2016 14:05:29 -0400 Subject: [PATCH 10/19] Makes it easier to break free of a grab by a smaller mob --- code/modules/mob/living/living.dm | 15 +------------- code/modules/mob/mob_grab.dm | 34 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 51bac7bfb7..be397a6def 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -625,20 +625,7 @@ default behaviour is: var/resisting = 0 for(var/obj/item/weapon/grab/G in grabbed_by) resisting++ - switch(G.state) - if(GRAB_PASSIVE) - qdel(G) - if(GRAB_AGGRESSIVE) - //Not standing up makes it much harder to break, so it is easier to cuff someone who is down without forcing them into unconsciousness. - //Otherwise, it's the same chance of breaking the grab as disarm. - if(incapacitated(INCAPACITATION_KNOCKDOWN)? prob(15) : prob(60)) - visible_message("[src] has broken free of [G.assailant]'s grip!") - qdel(G) - if(GRAB_NECK) - //If the you move when grabbing someone then it's easier for them to break free. Same if the affected mob is immune to stun. - if (((world.time - G.assailant.l_move_time < 30 || !stunned) && prob(15)) || prob(3)) - visible_message("[src] has broken free of [G.assailant]'s headlock!") - qdel(G) + G.handle_resist() if(resisting) visible_message("[src] resists!") diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index b41d07dbb6..cb7146af27 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -340,6 +340,40 @@ hud.icon_state = "kill" state = GRAB_NECK +/obj/item/weapon/grab/proc/handle_resist() + var/grab_name + var/break_strength = 1 + var/list/break_chance_table = list(100) + switch(state) + //if(GRAB_PASSIVE) + + if(GRAB_AGGRESSIVE) + grab_name = "grip" + //Being knocked down makes it harder to break a grab, so it is easier to cuff someone who is down without forcing them into unconsciousness. + if(!affecting.incapacitated(INCAPACITATION_KNOCKDOWN)) + break_strength++ + break_chance_table = list(15, 60, 100) + + if(GRAB_NECK) + grab_name = "headlock" + //If the you move when grabbing someone then it's easier for them to break free. Same if the affected mob is immune to stun. + if(world.time - assailant.l_move_time < 30 || !affecting.stunned) + break_strength++ + break_chance_table = list(3, 18, 45, 100) + + //It's easier to break out of a grab by a smaller mob + break_strength += max(size_difference(affecting, assailant), 0) + + var/break_chance = break_chance_table[Clamp(break_strength, 1, break_chance_table.len)] + if(prob(break_chance)) + if(grab_name) + affecting.visible_message("[affecting] has broken free of [assailant]'s [grab_name]!") + qdel(src) + +//returns the number of size categories between affecting and assailant, rounded. Positive means A is larger than B +/obj/item/weapon/grab/proc/size_difference(mob/A, mob/B) + return round(log(2, A.mob_size/B.mob_size), 1) + /obj/item/weapon/grab var/destroying = 0 From 8fc62cdbbcb4325690f8c850ef37c459caa84b6e Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Tue, 24 May 2016 15:18:01 -0400 Subject: [PATCH 11/19] Small mobs can no longer pin larger mobs --- code/modules/mob/mob_grab.dm | 4 ++-- code/modules/mob/mob_grab_specials.dm | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index cb7146af27..e34890d1cd 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -136,7 +136,7 @@ handle_eye_mouth_covering(affecting, assailant, assailant.zone_sel.selecting) if(force_down) - if(affecting.loc != assailant.loc) + if(affecting.loc != assailant.loc || size_difference(affecting, assailant) > 0) force_down = 0 else affecting.Weaken(2) @@ -237,7 +237,7 @@ if(state < GRAB_AGGRESSIVE) if(!allow_upgrade) return - if(!affecting.lying) + if(!affecting.lying || size_difference(affecting, assailant) > 0) assailant.visible_message("[assailant] has grabbed [affecting] aggressively (now hands)!") else assailant.visible_message("[assailant] pins [affecting] down to the ground (now hands)!") diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm index af50746cd4..e7b75a2e5d 100644 --- a/code/modules/mob/mob_grab_specials.dm +++ b/code/modules/mob/mob_grab_specials.dm @@ -131,6 +131,10 @@ return if(force_down) attacker << "You are already pinning [target] to the ground." + return + if(size_difference(affecting, assailant) > 0) + attacker << "You are too small to do that!" + return attacker.visible_message("[attacker] starts forcing [target] to the ground!") if(do_after(attacker, 20) && target) From 0f864e1390ba3ccb06d170cda2d30d39bb53d5cf Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Tue, 24 May 2016 15:36:26 -0400 Subject: [PATCH 12/19] Limits distance that mobs can be thrown based on relative size --- code/modules/mob/living/carbon/carbon.dm | 36 +++++++++++++----------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 294b9c8669..0f1b570026 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -309,14 +309,19 @@ if(!item) return + var/throw_range = item.throw_range if (istype(item, /obj/item/weapon/grab)) var/obj/item/weapon/grab/G = item item = G.throw_held() //throw the person instead of the grab if(ismob(item)) + var/mob/M = item + + //limit throw range by relative mob size + throw_range = round(M.throw_range * min(src.mob_size/M.mob_size, 1)) + 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 = "tile at [start_T.x], [start_T.y], [start_T.z] in area [get_area(start_T)]" var/end_T_descriptor = "tile at [end_T.x], [end_T.y], [end_T.z] in area [get_area(end_T)]" @@ -324,31 +329,28 @@ usr.attack_log += text("\[[time_stamp()]\] Has thrown [M.name] ([M.ckey]) from [start_T_descriptor] with the target [end_T_descriptor]") msg_admin_attack("[usr.name] ([usr.ckey]) has thrown [M.name] ([M.ckey]) from [start_T_descriptor] with the target [end_T_descriptor] (JMP)") - if(!item) return //Grab processing has a chance of returning null - - - src.remove_from_mob(item) - item.loc = src.loc + src.drop_from_inventory(item) + if(!item || !isturf(item.loc)) + return //actually throw it! - if (item) - src.visible_message("\red [src] has thrown [item].") + src.visible_message("\red [src] has thrown [item].") - if(!src.lastarea) - src.lastarea = get_area(src.loc) - if((istype(src.loc, /turf/space)) || (src.lastarea.has_gravity == 0)) - src.inertia_dir = get_dir(target, src) - step(src, inertia_dir) + if(!src.lastarea) + src.lastarea = get_area(src.loc) + if((istype(src.loc, /turf/space)) || (src.lastarea.has_gravity == 0)) + src.inertia_dir = get_dir(target, src) + step(src, inertia_dir) /* - if(istype(src.loc, /turf/space) || (src.flags & NOGRAV)) //they're in space, move em one space in the opposite direction - src.inertia_dir = get_dir(target, src) - step(src, inertia_dir) + if(istype(src.loc, /turf/space) || (src.flags & NOGRAV)) //they're in space, move em one space in the opposite direction + src.inertia_dir = get_dir(target, src) + step(src, inertia_dir) */ - item.throw_at(target, item.throw_range, item.throw_speed, src) + item.throw_at(target, throw_range, item.throw_speed, src) /mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) ..() From 78cd94b1133fe17e331f08cc83d140d46715ec6d Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Tue, 24 May 2016 16:14:05 -0400 Subject: [PATCH 13/19] Fixes #12877 --- code/modules/mob/holder.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index 121b999d21..d608bb0988 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -114,6 +114,11 @@ var/list/holder_mob_icon_cache = list() if(!holder_type || buckled || pinned.len) return + if(self_grab) + if(src.incapacitated()) return + else + if(grabber.incapacitated()) return + var/obj/item/weapon/holder/H = new holder_type(get_turf(src)) H.held_mob = src src.forceMove(H) From f860acd93a42dacb990ea25c9388f33dd67bfbda Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Tue, 24 May 2016 16:19:03 -0400 Subject: [PATCH 14/19] Updates changelog --- html/changelogs/HarpyEagle-mob-grab.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 html/changelogs/HarpyEagle-mob-grab.yml diff --git a/html/changelogs/HarpyEagle-mob-grab.yml b/html/changelogs/HarpyEagle-mob-grab.yml new file mode 100644 index 0000000000..04125ebdf9 --- /dev/null +++ b/html/changelogs/HarpyEagle-mob-grab.yml @@ -0,0 +1,9 @@ +author: HarpyEagle + +delete-after: True + +changes: + - rscadd: "Trying to move while being grabbed will now automatically resist." + - tweak: "Small mobs are no longer able to pin larger mobs." + - tweak: "Resisting a smaller mob's grab is more likely to be successful." + - bugfix: "Fixed being able to climb onto a larger mob while restrained, weakened, unconscious, or dead." From 8a2135c9179d031046fdccb4005a26244fa006ed Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Wed, 25 May 2016 05:53:51 -0400 Subject: [PATCH 15/19] Replaces macro with span --- code/modules/mob/living/carbon/carbon.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 0f1b570026..4eaf5aa8fe 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -334,7 +334,7 @@ return //actually throw it! - src.visible_message("\red [src] has thrown [item].") + src.visible_message("[src] has thrown [item].") if(!src.lastarea) src.lastarea = get_area(src.loc) From cf76d6dac4bb704d07a33d6c66e69ebadb1be0eb Mon Sep 17 00:00:00 2001 From: Yoshax Date: Mon, 20 Jun 2016 00:18:34 +0100 Subject: [PATCH 16/19] Fix stuff --- code/modules/mob/mob_grab.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index e34890d1cd..dde0cef8b2 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -11,9 +11,9 @@ if(!L.canmove && L.grabbed_by.len) L.resist() //shortcut for resisting grabs - //if we are grabbing someone - 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 + //if we are grabbing someone + for(var/obj/item/weapon/grab/G in list(L.l_hand, L.r_hand)) + G.reset_kill_state() //no wandering across the station/asteroid while choking someone /obj/item/weapon/grab name = "grab" From f0c8e0e516d316c153e449d5ee11ff2305a0e3e9 Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Wed, 8 Jun 2016 14:50:49 -0400 Subject: [PATCH 17/19] Makes smaller mobs have smaller organs --- code/modules/mob/living/carbon/human/species/species.dm | 2 +- code/modules/mob/mob_grab.dm | 2 +- code/modules/mob/mob_helpers.dm | 3 +++ code/modules/organs/organ.dm | 1 + code/modules/organs/subtypes/standard.dm | 2 ++ 5 files changed, 8 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 25a8149e48..def9ae59f2 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -190,6 +190,7 @@ /datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs. + H.mob_size = mob_size for(var/obj/item/organ/organ in H.contents) if((organ in H.organs) || (organ in H.internal_organs)) qdel(organ) @@ -249,7 +250,6 @@ H.mob_swap_flags = swap_flags H.mob_push_flags = push_flags H.pass_flags = pass_flags - H.mob_size = mob_size /datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns). return diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index dde0cef8b2..e40b14dffd 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -372,7 +372,7 @@ //returns the number of size categories between affecting and assailant, rounded. Positive means A is larger than B /obj/item/weapon/grab/proc/size_difference(mob/A, mob/B) - return round(log(2, A.mob_size/B.mob_size), 1) + return mob_size_difference(A.mob_size, B.mob_size) /obj/item/weapon/grab var/destroying = 0 diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 22da202ede..2f788862f8 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -5,6 +5,9 @@ return L.mob_size <= MOB_SMALL return 0 +//returns the number of size categories between two mob_sizes, rounded. Positive means A is larger than B +/proc/mob_size_difference(var/mob_size_A, var/mob_size_B) + return round(log(2, mob_size_A/mob_size_B), 1) /proc/istiny(A) if(A && istype(A, /mob/living)) diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 13eef2eaf4..d8533239e7 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -50,6 +50,7 @@ var/list/organ_cache = list() max_damage = min_broken_damage * 2 if(istype(holder)) src.owner = holder + src.w_class = max(src.w_class + mob_size_difference(holder.mob_size, MOB_MEDIUM), 1) //smaller mobs have smaller organs. species = all_species["Human"] if(holder.dna) dna = holder.dna.Clone() diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/organs/subtypes/standard.dm index 36fc7ba677..d26193c876 100644 --- a/code/modules/organs/subtypes/standard.dm +++ b/code/modules/organs/subtypes/standard.dm @@ -2,6 +2,8 @@ ORGAN DEFINES ****************************************************/ +//Make sure that w_class is set as if the parent mob was medium sized! This is because w_class is adjusted automatically for mob_size in New() + /obj/item/organ/external/chest name = "upper body" organ_tag = BP_TORSO From 621241f7056e4dd5492948a712fa7e4f795f51c2 Mon Sep 17 00:00:00 2001 From: HarpyEagle Date: Wed, 8 Jun 2016 20:53:26 -0400 Subject: [PATCH 18/19] Adds SLOT_BELT to heads --- code/modules/organs/subtypes/standard.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/organs/subtypes/standard.dm index d26193c876..e33a319f69 100644 --- a/code/modules/organs/subtypes/standard.dm +++ b/code/modules/organs/subtypes/standard.dm @@ -150,6 +150,7 @@ organ_tag = BP_HEAD icon_name = "head" name = "head" + slot_flags = SLOT_BELT max_damage = 75 min_broken_damage = 35 w_class = 3 From 386b575af1efc0058dc59bcc5596909b2d1d4555 Mon Sep 17 00:00:00 2001 From: Yoshax Date: Mon, 20 Jun 2016 00:47:17 +0100 Subject: [PATCH 19/19] Fixes diona stuff --- code/modules/organs/subtypes/diona.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/organs/subtypes/diona.dm b/code/modules/organs/subtypes/diona.dm index ab5c436758..0776e318b4 100644 --- a/code/modules/organs/subtypes/diona.dm +++ b/code/modules/organs/subtypes/diona.dm @@ -206,4 +206,5 @@ amputation_point = "branch" joint = "structural ligament" dislocated = -1 - vital = 0 \ No newline at end of file + vital = 0 + slot_flags = SLOT_BELT