-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MIRROR] Malicious Intent - adds mauling people with entrenching tool…
…s and machetes (#5276) * Malicious Intent - adds mauling people with entrenching tools and machetes (#4701) * Put the boots to him. Well-done. * the war * the rule of beasts * bad at amputating --------- Co-authored-by: Hatterhat <[email protected]> * [MIRROR] Malicious Intent - adds mauling people with entrenching tools and machetes --------- Co-authored-by: Hatterhat <[email protected]> Co-authored-by: Hatterhat <[email protected]> Co-authored-by: StealsThePRs <[email protected]>
- Loading branch information
1 parent
7a406b9
commit 49916cc
Showing
12 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
modular_nova/master_files/code/modules/surgery/amputation.dm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/datum/surgery_step/sever_limb/New() | ||
implements += list( | ||
/obj/item/machete = 75, | ||
) | ||
return ..() | ||
|
||
// doesn't work on robo limbs | ||
/datum/surgery_step/sever_limb/mechanic/New() | ||
. = ..() | ||
implements -= list( | ||
/obj/item/machete, | ||
) |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/** | ||
* The mauling element, adapted nearly wholesale from kneecapping, replaces the item's secondary attack with an aimed attack at limbs under certain circumstances. | ||
* | ||
* Element is incompatible with non-items. Requires the parent item to have a force equal to or greater than WOUND_MINIMUM_DAMAGE. | ||
* Also requires that the parent can actually get past pre_secondary_attack without the attack chain cancelling. | ||
* | ||
* As kneecapping, mauling attacks have a wounding bonus between severe and critical+10 wound thresholds. Without some serious wound protecting | ||
* armour this all but guarantees a wound of some sort. The attack is directed specifically at a limb and the limb takes the damage. | ||
* | ||
* Requires the attacker to be aiming for a limb, which will be targeted specifically. They will than have a 3-second long | ||
* do_after before executing the attack. | ||
* | ||
* Mauling, much like kneecapping, requires the target to either be on the floor, immobilised or buckled to something. And also to have an appropriate limb. | ||
* | ||
* Passing all the checks will cancel the entire attack chain. | ||
*/ | ||
/datum/element/mauling | ||
|
||
/datum/element/mauling/Attach(datum/target) | ||
if(!isitem(target)) | ||
stack_trace("Mauling element added to non-item object: \[[target]\]") | ||
return ELEMENT_INCOMPATIBLE | ||
|
||
var/obj/item/target_item = target | ||
|
||
if(target_item.force < WOUND_MINIMUM_DAMAGE) | ||
stack_trace("Mauling element added to item with too little force to wound: \[[target]\]") | ||
return ELEMENT_INCOMPATIBLE | ||
|
||
. = ..() | ||
|
||
if(. == ELEMENT_INCOMPATIBLE) | ||
return | ||
|
||
RegisterSignal(target, COMSIG_ITEM_ATTACK_SECONDARY , PROC_REF(try_maul_target)) | ||
|
||
/datum/element/mauling/Detach(datum/target) | ||
UnregisterSignal(target, COMSIG_ITEM_ATTACK_SECONDARY) | ||
|
||
return ..() | ||
|
||
/** | ||
* Signal handler for COMSIG_ITEM_ATTACK_SECONDARY. Does checks for pacifism, zones and target state before either returning nothing | ||
* if the special attack could not be attempted, performing the ordinary attack procs instead - Or cancelling the attack chain if | ||
* the attack can be started. | ||
*/ | ||
/datum/element/mauling/proc/try_maul_target(obj/item/source, mob/living/carbon/target, mob/attacker, params) | ||
SIGNAL_HANDLER | ||
|
||
if(HAS_TRAIT(attacker, TRAIT_PACIFISM)) | ||
return | ||
|
||
if(!iscarbon(target)) | ||
return | ||
|
||
if(!target.buckled && !HAS_TRAIT(target, TRAIT_FLOORED) && !HAS_TRAIT(target, TRAIT_IMMOBILIZED)) | ||
return | ||
|
||
var/obj/item/bodypart/limb_target = target.get_bodypart(attacker.zone_selected) | ||
|
||
if(!limb_target) | ||
return | ||
|
||
. = COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN | ||
|
||
INVOKE_ASYNC(src, PROC_REF(do_maul_target), source, limb_target, target, attacker) | ||
|
||
/** | ||
* After a short do_after, attacker applies damage to the given limb with a significant wounding bonus, applying the weapon's force as damage. | ||
*/ | ||
/datum/element/mauling/proc/do_maul_target(obj/item/weapon, obj/item/bodypart/limb, mob/living/carbon/target, mob/attacker) | ||
if(LAZYACCESS(attacker.do_afters, weapon)) | ||
return | ||
|
||
attacker.visible_message(span_warning("[attacker] carefully aims [attacker.p_their()] [weapon] at [target]'s [limb.plaintext_zone]!"), span_danger("You carefully aim \the [weapon] for a swing at [target]'s [limb.plaintext_zone]!")) | ||
log_combat(attacker, target, "started aiming a swing to maul", weapon) | ||
|
||
if(do_after(attacker, 3 SECONDS, target, interaction_key = weapon)) | ||
attacker.visible_message(span_warning("[attacker] swings [attacker.p_their()] [weapon] at [target]'s [limb.plaintext_zone]!"), span_danger("You swing \the [weapon] at [target]'s [limb.plaintext_zone]!")) | ||
var/wound_to_inflict = WOUND_BLUNT | ||
if(weapon.sharpness & SHARP_EDGED) | ||
wound_to_inflict = WOUND_SLASH | ||
else if(weapon.sharpness & SHARP_POINTY) | ||
wound_to_inflict = WOUND_PIERCE | ||
var/min_wound = limb.get_wound_threshold_of_wound_type(wound_to_inflict, WOUND_SEVERITY_SEVERE, return_value_if_no_wound = 30, wound_source = weapon) | ||
var/max_wound = limb.get_wound_threshold_of_wound_type(wound_to_inflict, WOUND_SEVERITY_CRITICAL, return_value_if_no_wound = 50, wound_source = weapon) | ||
|
||
limb.receive_damage(brute = weapon.force, wound_bonus = rand(min_wound, max_wound + 10), sharpness = weapon.sharpness, damage_source = "mauling") | ||
// make sure we're actually able to feel pain | ||
if(!target.has_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy)) | ||
target.emote("scream") | ||
log_combat(attacker, target, "mauled", weapon) | ||
target.update_damage_overlays() | ||
attacker.do_attack_animation(target, used_item = weapon) | ||
playsound(source = get_turf(weapon), soundin = weapon.hitsound, vol = weapon.get_clamped_volume(), vary = TRUE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
/obj/item/machete | ||
name = "surplus machete" | ||
icon = 'modular_nova/modules/mauling_melees/icons/objects.dmi' | ||
icon_state = "machete" | ||
lefthand_file = 'modular_nova/modules/mauling_melees/icons/lefthands.dmi' | ||
righthand_file = 'modular_nova/modules/mauling_melees/icons/righthands.dmi' | ||
inhand_icon_state = "machete" | ||
desc = "An nondescript machete with a rubberized, non-conductive handle. Could be from some old military surplus, or from a recent stockpile, or anywhere in between. \ | ||
Good for hacking away at things, like plants, people, or plantpeople." | ||
obj_flags = NONE | ||
force = 20 | ||
w_class = WEIGHT_CLASS_BULKY | ||
throwforce = 10 | ||
hitsound = 'sound/items/weapons/bladeslice.ogg' | ||
throw_speed = 1 | ||
throw_range = 5 | ||
custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 6) | ||
attack_verb_continuous = list("slashes", "slices", "tears", "lacerates", "rips", "dices", "cuts") | ||
attack_verb_simple = list("slash", "slice", "tear", "lacerate", "rip", "dice", "cut") | ||
sharpness = SHARP_EDGED | ||
armor_type = /datum/armor/item_knife | ||
wound_bonus = 10 | ||
bare_wound_bonus = 20 | ||
tool_behaviour = TOOL_KNIFE | ||
/* | ||
20 force, 10 wb, 20 bwb = 30, 50 against bare skin | ||
compare/contrast force/wound bonuses with the captain's sabre, i guess | ||
which at time of writing is 20 force 5 wb 20 bwb = 25, 45 against bare skin, BUT has 75 AP/50 melee-only blockchance | ||
the shamshir also has the same damage/wound stats but "only" 25 AP/20 blockchance | ||
*/ | ||
|
||
/obj/item/machete/Initialize(mapload) | ||
. = ..() | ||
// not great for butchering. kind of unwieldy for doing so | ||
AddComponent(/datum/component/butchering, \ | ||
speed = 6 SECONDS, \ | ||
effectiveness = 80, \ | ||
bonus_modifier = force - 10, \ | ||
) | ||
// but it's good for murdering plantpeople | ||
AddElement(/datum/element/bane, mob_biotypes = MOB_PLANT, damage_multiplier = 0.5, requires_combat_mode = FALSE) | ||
// Kill. | ||
AddElement(/datum/element/mauling) | ||
|
||
/obj/item/machete/afterattack(atom/target, mob/user, click_parameters) | ||
. = ..() | ||
if(target.resistance_flags & INDESTRUCTIBLE) | ||
return | ||
if(istype(target, /obj/structure/flora)) | ||
var/obj/structure/flora/flora_target = target | ||
if(!(flora_target.flora_flags & FLORA_HERBAL) && !(flora_target.flora_flags & FLORA_WOODEN)) | ||
return | ||
target.take_damage(force) // simulate taking double damage | ||
|
||
#define MACHETE_BACK 0 | ||
#define MACHETE_WAIST 1 | ||
#define MACHETE_LEG 2 | ||
/obj/item/storage/belt/machete | ||
name = "surplus machete scabbard" | ||
desc = "A large synthetic-leather scabbard used to carry some kind of machete. A compact set of buckles suggests the ability to be strapped to the back, waist, or some kinds of armor." | ||
icon = 'modular_nova/modules/mauling_melees/icons/objects.dmi' | ||
worn_icon = 'modular_nova/modules/mauling_melees/icons/back.dmi' | ||
lefthand_file = 'modular_nova/modules/mauling_melees/icons/lefthands.dmi' | ||
righthand_file = 'modular_nova/modules/mauling_melees/icons/righthands.dmi' | ||
icon_state = "msheath" | ||
inhand_icon_state = "msheath" | ||
worn_icon_state = "msheath" | ||
slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK | ITEM_SLOT_SUITSTORE | ||
/// Used for deciding the worn icon_state variant, using defines for MACHETE_BACK, MACHETE_WAIST, MACHETE_LEG. | ||
var/worn_variant = MACHETE_BACK | ||
|
||
/obj/item/storage/belt/machete/Initialize(mapload) | ||
. = ..() | ||
AddElement(/datum/element/update_icon_updates_onmob) | ||
atom_storage.max_slots = 1 | ||
// not a rifle but this is the sound tgmc uses | ||
atom_storage.rustle_sound = 'modular_nova/modules/mauling_melees/sounds/rifle_draw.ogg' | ||
atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY | ||
atom_storage.set_holdable(/obj/item/machete) | ||
atom_storage.click_alt_open = FALSE | ||
RegisterSignal(atom_storage, COMSIG_STORAGE_REMOVED_ITEM, PROC_REF(on_item_removed)) | ||
|
||
/obj/item/storage/belt/machete/examine(mob/user) | ||
. = ..() | ||
if(length(contents)) | ||
. += span_notice("Alt-click it to quickly draw the blade.") | ||
|
||
/obj/item/storage/belt/machete/click_alt(mob/user) | ||
for(var/obj/item/machete/machete in contents) | ||
user.visible_message(span_notice("[user] takes [machete] out of [src]."), span_notice("You take [machete] out of [src].")) | ||
machete.remove_item_from_storage(user) | ||
user.put_in_hands(machete) | ||
update_appearance() | ||
return CLICK_ACTION_SUCCESS | ||
balloon_alert(user, "it's empty!") | ||
|
||
/obj/item/storage/belt/machete/update_icon_state() | ||
icon_state = initial(icon_state) | ||
inhand_icon_state = initial(inhand_icon_state) | ||
worn_icon_state = initial(worn_icon_state) | ||
worn_icon_state += "[worn_variant]" | ||
if(contents.len) | ||
icon_state += "-full" | ||
inhand_icon_state += "-full" | ||
worn_icon_state += "-full" | ||
return ..() | ||
|
||
/obj/item/storage/belt/machete/full/PopulateContents() | ||
new /obj/item/machete(src) | ||
update_appearance() | ||
|
||
/// triggers on item removal from the scabbard - plays a draw sound, which should be the rustle sound | ||
/// had to snowflake it because remove rustle sounds are. never triggered in the code. funnily enough | ||
/obj/item/storage/belt/machete/proc/on_item_removed() | ||
SIGNAL_HANDLER | ||
playsound(src, atom_storage.rustle_sound, 50, TRUE, -5) | ||
|
||
/// alt rmb to change wear style | ||
/obj/item/storage/belt/machete/click_alt_secondary(mob/user) | ||
switch(worn_variant) | ||
if (MACHETE_BACK) | ||
worn_variant = MACHETE_WAIST | ||
to_chat(user, "You adjust [src] to hang sideways behind your back.") | ||
if (MACHETE_WAIST) | ||
worn_variant = MACHETE_LEG | ||
to_chat(user, "You adjust [src] to hang down your leg.") | ||
if (MACHETE_LEG) | ||
worn_variant = MACHETE_BACK | ||
to_chat(user, "You adjust [src] to hang across your back.") | ||
update_appearance() | ||
|
||
#undef MACHETE_BACK | ||
#undef MACHETE_WAIST | ||
#undef MACHETE_LEG | ||
|
||
/obj/item/trench_tool/Initialize(mapload) | ||
. = ..() | ||
AddElement(/datum/element/mauling) |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters