Skip to content
Open
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
///from base of /mob/living/proc/melee_swing()
#define COMSIG_LIVING_MELEE_SWING "mob_melee_swing"

#define COMSIG_LIVING_JUMP_PREP_TOGGLE "living_jump_prep_toggle"

//from base of living/set_pull_offset(): (mob/living/pull_target, grab_state)
Expand Down
5 changes: 5 additions & 0 deletions code/_onclick/click.dm
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,13 @@
else
if(LAZYACCESS(modifiers, RIGHT_CLICK))
ranged_secondary_attack(A, modifiers)
/* // DARKPACK EDIT REMOVAL - COMBAT
else
RangedAttack(A, modifiers)
*/
// DARKPACK EDIT ADD START - COMBAT
RangedAttack(A, modifiers)
// DARKPACK EDIT ADD END

/// Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it
/atom/proc/IsObscured()
Expand Down
8 changes: 7 additions & 1 deletion code/modules/surgery/bodyparts/helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,13 @@

/mob/living/carbon/get_attacking_limb(atom/target, datum/martial_art/attacker_style)
var/obj/item/organ/brain/brain = get_organ_slot(ORGAN_SLOT_BRAIN)
var/obj/item/bodypart/attacking_bodypart = attacker_style?.get_attacking_limb(src, target) || brain?.get_attacking_limb(target) || get_active_hand()
// DARKPACK EDIT CHANGE START - COMBAT
var/obj/item/bodypart/attacking_bodypart
if(ishuman(target))
attacking_bodypart = attacker_style?.get_attacking_limb(src, target) || brain?.get_attacking_limb(target) || get_active_hand()
else
attacking_bodypart = get_active_hand()
// DARKPACK EDIT CHANGE END

if(attacking_bodypart.unarmed_attack_effect == ATTACK_EFFECT_BITE)
if(is_mouth_covered(ITEM_SLOT_MASK))
Expand Down
4 changes: 4 additions & 0 deletions config/darkpack_config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,7 @@ LOG_STATS

## Bool for if roleplay only merits/quirks are enabled
ROLEPLAY_ONLY_MERITS 1

## Configs for the type of attack we use when we click at a ranged distance. Only one can be enabled at a time.
#DIRECTIONAL_COMBAT
SWING_COMBAT
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
//Initializes Jumping on the player
AddComponent(/datum/component/jumper)
AddComponent(/datum/component/violation_observer, violation_aoe)
if(CONFIG_GET(flag/swing_combat))
AddElement(/datum/element/swing_attack)
else if(CONFIG_GET(flag/directional_combat))
AddElement(/datum/element/directional_attack)
update_visible_name()
9 changes: 9 additions & 0 deletions modular_darkpack/modules/combat/code/combat_config.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/datum/config_entry/flag/directional_combat

/datum/config_entry/flag/swing_combat


/datum/preference/toggle/ranged_click_to_melee
category = PREFERENCE_CATEGORY_GAME_PREFERENCES
savefile_key = "ranged_click_to_melee"
savefile_identifier = PREFERENCE_PLAYER
49 changes: 49 additions & 0 deletions modular_darkpack/modules/combat/code/directional_attack.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*!
* This element allows the mob its attached to the ability to click an adjacent mob by clicking a distant atom
* that is in the general direction relative to the parent.
*/
/datum/element/directional_attack/Attach(datum/target)
. = ..()
if(!isliving(target))
return ELEMENT_INCOMPATIBLE

RegisterSignal(target, COMSIG_MOB_ATTACK_RANGED, PROC_REF(on_ranged_attack))

/datum/element/directional_attack/Detach(datum/source, ...)
. = ..()
UnregisterSignal(source, COMSIG_MOB_ATTACK_RANGED)

/**
* This proc handles clicks on tiles that aren't adjacent to the source mob
* In addition to clicking the distant tile, it checks the tile in the direction and clicks the mob in the tile if there is one
* Arguments:
* * source - The mob clicking
* * clicked_atom - The atom being clicked (should be a distant one)
* * click_params - Miscellaneous click parameters, passed from Click itself
*/
/datum/element/directional_attack/proc/on_ranged_attack(mob/living/source, atom/clicked_atom, click_params)
SIGNAL_HANDLER

if(!source.combat_mode)
return

if(!source?.client?.prefs?.read_preference(/datum/preference/toggle/ranged_click_to_melee))
return

if(QDELETED(clicked_atom))
return

var/turf/turf_to_check = get_step(source, angle2dir(get_angle(source, clicked_atom)))
if(!turf_to_check || !source.Adjacent(turf_to_check))
return

var/mob/living/target_mob
for(target_mob in turf_to_check)
if(target_mob == source)
continue
if(!target_mob || target_mob.stat == DEAD)
continue
//This is here to undo the +1 the click on the distant turf adds so we can click the mob near us
source.next_click = world.time - 1
INVOKE_ASYNC(source, TYPE_PROC_REF(/mob, ClickOn), target_mob, list2params(click_params))
return
119 changes: 119 additions & 0 deletions modular_darkpack/modules/combat/code/swing.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/mob/living/proc/melee_swing(visual_effect, atom/swung_item)
playsound(loc, 'modular_darkpack/modules/combat/sounds/swing.ogg', 50, TRUE)
var/atom/hit_target
var/turf/center_turf = get_step(src, dir)
var/turf/left_turf = get_step(center_turf, turn(dir, -90))
var/turf/right_turf = get_step(center_turf, turn(dir, 90))

for(var/turf/swung_turf in list(center_turf, left_turf, right_turf))
var/mob/living/living_on_turf = locate() in swung_turf
if(!living_on_turf)
continue
if(living_on_turf.stat == DEAD)
continue
hit_target = living_on_turf
break
/* // More likely then not, not acctually what your trying to click on. Revisit
if(!hit_target)
for(var/obj/swung_object in center_turf)
if(swung_object.obj_flags & CAN_BE_HIT)
hit_target = swung_object
break
*/

if(!visual_effect)
visual_effect = get_swing_visual(hit_target, swung_item)
new visual_effect(get_turf(src), dir)

// Originally this was in front of searching for turfs but SURELY you would want this after you get a target. Right?
SEND_SIGNAL(src, COMSIG_LIVING_MELEE_SWING, hit_target, center_turf, left_turf, right_turf)

if(hit_target)
// changeNext_move(CLICK_CD_MELEE)
return hit_target
else
changeNext_move(CLICK_CD_RANGE) // Whiff punish (to avoid people spam clicking and the visuals looking dumb)

/mob/living/proc/get_swing_visual(atom/target, atom/swung_item)
return /obj/effect/temp_visual/dir_setting/swing_effect

// unarmed_attack_effect = ATTACK_EFFECT_CLAW


/mob/living/carbon/get_swing_visual(atom/target, atom/swung_item)
. = ..()

if(!swung_item)
var/obj/item/bodypart/attacking_bodypart = get_attacking_limb(target)
if(attacking_bodypart?.unarmed_attack_effect == ATTACK_EFFECT_CLAW)
return /obj/effect/temp_visual/dir_setting/claw_effect


/obj/item/proc/can_swing()
// Technicly meant for no flavor text but is semi widly used as a "noncombat" weapon check
if(!(item_flags & NOBLUDGEON))
return TRUE

/obj/item/gun/can_swing()
return FALSE


/obj/effect/temp_visual/dir_setting/swing_effect
icon = 'modular_darkpack/modules/combat/icons/swing.dmi'
icon_state = "swing1"
pixel_w = -32
pixel_z = -32
duration = 0.3 SECONDS

/obj/effect/temp_visual/dir_setting/claw_effect
icon = 'modular_darkpack/modules/combat/icons/swing.dmi'
icon_state = "claw1"
pixel_w = -32
pixel_z = -32
duration = 0.3 SECONDS


/*!
* This element allows the mob its attached to the ability to click an adjacent mob by clicking a distant atom
* that is in the general direction relative to the parent.
*/
/datum/element/swing_attack/Attach(datum/target)
. = ..()
if(!isliving(target))
return ELEMENT_INCOMPATIBLE

RegisterSignal(target, COMSIG_MOB_ATTACK_RANGED, PROC_REF(on_ranged_attack))

/datum/element/swing_attack/Detach(datum/source, ...)
. = ..()
UnregisterSignal(source, COMSIG_MOB_ATTACK_RANGED)

/**
* This proc handles clicks on tiles that aren't adjacent to the source mob
* In addition to clicking the distant tile, it checks the tile in the direction and clicks the mob in the tile if there is one
* Arguments:
* * source - The mob clicking
* * clicked_atom - The atom being clicked (should be a distant one)
* * click_params - Miscellaneous click parameters, passed from Click itself
*/
/datum/element/swing_attack/proc/on_ranged_attack(mob/living/source, atom/clicked_atom, click_params)
SIGNAL_HANDLER

if(!source.combat_mode)
return

if(!source?.client?.prefs?.read_preference(/datum/preference/toggle/ranged_click_to_melee))
return

if(QDELETED(clicked_atom))
return

var/obj/item/held_item = source.get_active_held_item()
if(held_item && !held_item.can_swing())
return

var/atom/swing_result = source.melee_swing(swung_item = held_item)
if(swing_result?.IsReachableBy(source, held_item ? held_item.reach : 1))
//This is here to undo the +1 the click on the distant turf adds so we can click the mob near us
source.next_click = world.time - 1
INVOKE_ASYNC(source, TYPE_PROC_REF(/mob, ClickOn), swing_result, list2params(click_params))
Binary file added modular_darkpack/modules/combat/icons/swing.dmi
Binary file not shown.
3 changes: 3 additions & 0 deletions tgstation.dme
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// DM Environment file for tgstation.dme.

Check failure on line 1 in tgstation.dme

View workflow job for this annotation

GitHub Actions / Run Linters / linters

Ticked File Enforcement

Missing include for modular_darkpack\modules\dwelling\code\area_dwelling.dm.

Check failure on line 1 in tgstation.dme

View workflow job for this annotation

GitHub Actions / Run Linters / linters

Ticked File Enforcement

Missing include for modular_darkpack\modules\dwelling\code\obj_dwelling.dm.

Check failure on line 1 in tgstation.dme

View workflow job for this annotation

GitHub Actions / Run Linters / linters

Ticked File Enforcement

Missing include for modular_darkpack\modules\dwelling\code\_dwelling_gvars_defines.dm.

Check failure on line 1 in tgstation.dme

View workflow job for this annotation

GitHub Actions / Run Linters / linters

Ticked File Enforcement

Missing include for modular_darkpack\modules\economy\code\stocks_license.dm.

Check failure on line 1 in tgstation.dme

View workflow job for this annotation

GitHub Actions / Run Linters / linters

Ticked File Enforcement

Missing include for modular_darkpack\modules\effects\code\reflection.dm.

Check failure on line 1 in tgstation.dme

View workflow job for this annotation

GitHub Actions / Run Linters / linters

Ticked File Enforcement

Missing include for modular_darkpack\modules\latejoin_antagonists\code\latejoin_subsystem.dm.

Check failure on line 1 in tgstation.dme

View workflow job for this annotation

GitHub Actions / Run Linters / linters

Ticked File Enforcement

Missing include for modular_darkpack\modules\powers\code\discipline\mytherceria.dm.

Check failure on line 1 in tgstation.dme

View workflow job for this annotation

GitHub Actions / Run Linters / linters

Ticked File Enforcement

Missing include for modular_darkpack\modules\powers\code\discipline\healer_valeren.dm.

Check failure on line 1 in tgstation.dme

View workflow job for this annotation

GitHub Actions / Run Linters / linters

Ticked File Enforcement

Missing include for modular_darkpack\modules\weather\code\weather.dm.

Check failure on line 1 in tgstation.dme

View workflow job for this annotation

GitHub Actions / Run Linters / linters

Ticked File Enforcement

Missing include for modular_darkpack\modules\merits_flaws\code\old_quirks.dm.
// All manual changes should be made outside the BEGIN_ and END_ blocks.
// New source code should be placed in .dm files: choose File/New --> Code File.

Expand Down Expand Up @@ -7145,6 +7145,9 @@
#include "modular_darkpack\modules\clothes\code\neck.dm"
#include "modular_darkpack\modules\clothes\code\suit.dm"
#include "modular_darkpack\modules\clothes\code\under.dm"
#include "modular_darkpack\modules\combat\code\combat_config.dm"
#include "modular_darkpack\modules\combat\code\directional_attack.dm"
#include "modular_darkpack\modules\combat\code\swing.dm"
#include "modular_darkpack\modules\company_logos\code\company_logos.dm"
#include "modular_darkpack\modules\company_logos\code\pentex.dm"
#include "modular_darkpack\modules\curtains\code\curtains.dm"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { CheckboxInput, type FeatureToggle } from '../base';

export const ranged_click_to_melee: FeatureToggle = {
name: 'Distant clicks trigger melee swings',
category: 'GAMEPLAY',
description: `
Clicking on a tile out of your range creates a swing or directional attack.
`,
component: CheckboxInput,
};
Loading