Skip to content

Commit

Permalink
Allow techniques on reach attacks. (CleverRaven#69103)
Browse files Browse the repository at this point in the history
* Let techniques trigger on reach attacks according to the newly added flags "reach_ok" and "reach_teq".

* Remove the skill_stabbing constant since it was no longer being used.

* Update the documentation.
  • Loading branch information
prharvey authored Nov 5, 2023
1 parent e21fcd9 commit 15f2ff3
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 10 deletions.
2 changes: 1 addition & 1 deletion data/json/martialarts.json
Original file line number Diff line number Diff line change
Expand Up @@ -1313,7 +1313,7 @@
]
}
],
"techniques": [ "tec_sojutsu_feint", "tec_sojutsu_shove", "tec_sojutsu_trip" ],
"techniques": [ "tec_sojutsu_feint", "tec_sojutsu_shove", "tec_sojutsu_trip", "tec_sojutsu_jab" ],
"weapon_category": [ "POLEARMS" ]
},
{
Expand Down
20 changes: 20 additions & 0 deletions data/json/techniques.json
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,7 @@
"skill_requirements": [ { "name": "melee", "level": 2 } ],
"melee_allowed": true,
"forbidden_buffs_all": [ "buff_medievalpole_onmove" ],
"reach_ok": true,
"mult_bonuses": [
{ "stat": "damage", "type": "bash", "scale": 1.1 },
{ "stat": "damage", "type": "cut", "scale": 1.1 },
Expand Down Expand Up @@ -1388,6 +1389,7 @@
"melee_allowed": true,
"required_buffs_all": "buff_medievalpole_onmiss",
"crit_ok": true,
"reach_ok": true,
"weighting": 2,
"condition": {
"and": [
Expand Down Expand Up @@ -1417,6 +1419,7 @@
"condition": { "npc_has_effect": "downed" },
"condition_desc": "* Only works on a <info>downed</info> target",
"crit_tec": true,
"reach_ok": true,
"weighting": 2,
"mult_bonuses": [
{ "stat": "damage", "type": "bash", "scale": 1.5 },
Expand Down Expand Up @@ -2796,6 +2799,7 @@
"messages": [ "You deftly trip %s!", "<npcname> deftly trips %s!" ],
"skill_requirements": [ { "name": "melee", "level": 3 } ],
"melee_allowed": true,
"reach_ok": true,
"condition": {
"and": [
{ "math": [ "u_val('size') + 1", ">=", "n_val('size')" ] },
Expand All @@ -2813,6 +2817,22 @@
],
"attack_vectors": [ "WEAPON" ]
},
{
"type": "technique",
"id": "tec_sojutsu_jab",
"name": "Jab",
"messages": [ "You quickly strike %s!", "<npcname> quickly strikes %s!" ],
"skill_requirements": [ { "name": "melee", "level": 2 } ],
"melee_allowed": true,
"reach_tec": true,
"mult_bonuses": [
{ "stat": "movecost", "scale": 0.5 },
{ "stat": "damage", "type": "bash", "scale": 0.66 },
{ "stat": "damage", "type": "cut", "scale": 0.66 },
{ "stat": "damage", "type": "stab", "scale": 0.66 }
],
"attack_vectors": [ "WEAPON" ]
},
{
"type": "technique",
"id": "tec_sojutsu_feint",
Expand Down
2 changes: 2 additions & 0 deletions doc/MARTIALART_JSON.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@
"needs_ammo": true, // Technique works only if weapon is loaded; Consume 1 charge per attack
"crit_tec": true, // This technique only works on a critical hit
"crit_ok": true, // This technique works on both normal and critical hits
"reach_tec": true, // This technique only works on a reach attack hit
"reach_ok": true, // This technique works on both normal and reach attack hits
"attack_override": false, // This technique replaces the base attack it triggered on, nulling damage and movecost (instead using the tech's flat_bonuses), and counts as unarmed for the purposes of skill training and special melee effects
"condition": "u_is_outside",// Optional (array of) dialog conditions the attack requires to trigger. Failing these will disqualify the tech from being selected
"condition_desc": "Needs X",// Description string describing the conditions of this attack (since dialog conditions can't be automatically evaluated)
Expand Down
9 changes: 9 additions & 0 deletions src/martialarts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ void ma_technique::load( const JsonObject &jo, const std::string &src )
optional( jo, was_loaded, "crit_ok", crit_ok, false );
optional( jo, was_loaded, "attack_override", attack_override, false );
optional( jo, was_loaded, "wall_adjacent", wall_adjacent, false );
optional( jo, was_loaded, "reach_tec", reach_tec, false );
optional( jo, was_loaded, "reach_ok", reach_ok, false );

optional( jo, was_loaded, "needs_ammo", needs_ammo, false );

Expand Down Expand Up @@ -1866,6 +1868,13 @@ std::string ma_technique::get_description() const
dump += _( "* Will only activate on a <info>crit</info>" ) + std::string( "\n" );
}

if( reach_ok ) {
dump += _( "* Can activate on a <info>normal</info> or a <info>reach attack</info> hit" ) +
std::string( "\n" );
} else if( reach_tec ) {
dump += _( "* Will only activate on a <info>reach attack</info>" ) + std::string( "\n" );
}

if( side_switch ) {
dump += _( "* Moves target <info>behind</info> you" ) + std::string( "\n" );
}
Expand Down
2 changes: 2 additions & 0 deletions src/martialarts.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ class ma_technique
bool dummy = false;
bool crit_tec = false;
bool crit_ok = false;
bool reach_tec = false; // only possible to use during a reach attack
bool reach_ok = false; // possible to use during a reach attack
bool attack_override = false; // The attack replaces the one it triggered off of

ma_requirements reqs;
Expand Down
29 changes: 20 additions & 9 deletions src/melee.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ static const move_mode_id move_mode_prone( "prone" );

static const skill_id skill_melee( "melee" );
static const skill_id skill_spellcraft( "spellcraft" );
static const skill_id skill_stabbing( "stabbing" );
static const skill_id skill_unarmed( "unarmed" );

static const trait_id trait_ARM_TENTACLES( "ARM_TENTACLES" );
Expand Down Expand Up @@ -725,10 +724,10 @@ bool Character::melee_attack_abstract( Creature &t, bool allow_special,

// Pick one or more special attacks
matec_id technique_id;
if( allow_special && !has_force_technique ) {
technique_id = pick_technique( t, cur_weapon, critical_hit, false, false );
} else if( has_force_technique ) {
if( has_force_technique ) {
technique_id = force_technique;
} else if( allow_special ) {
technique_id = pick_technique( t, cur_weapon, critical_hit, false, false );
} else {
technique_id = tec_none;
}
Expand Down Expand Up @@ -957,7 +956,8 @@ int Character::get_total_melee_stamina_cost( const item *weap ) const

void Character::reach_attack( const tripoint &p, int forced_movecost )
{
matec_id force_technique = tec_none;
static const matec_id no_technique_id( "" );
matec_id force_technique = no_technique_id;
/** @EFFECT_MELEE >5 allows WHIP_DISARM technique */
if( weapon.has_flag( flag_WHIP ) && ( get_skill_level( skill_melee ) > 5 ) && one_in( 3 ) ) {
force_technique = WHIP_DISARM;
Expand All @@ -979,15 +979,15 @@ void Character::reach_attack( const tripoint &p, int forced_movecost )
// 1 / mult because mult is the percent penalty, in the form 1.0 == 100%
const float weary_mult = 1.0f / exertion_adjusted_move_multiplier( EXTRA_EXERCISE );
int move_cost = attack_speed( weapon ) * weary_mult;
float skill = std::min( 10.0f, get_skill_level( skill_stabbing ) );
float skill = std::min( 10.0f, get_skill_level( skill_melee ) );
int t = 0;
map &here = get_map();
std::vector<tripoint> path = line_to( pos(), p, t, 0 );
path.pop_back(); // Last point is our critter
for( const tripoint &path_point : path ) {
// Possibly hit some unintended target instead
Creature *inter = creatures.creature_at( path_point );
/** @EFFECT_STABBING decreases chance of hitting intervening target on reach attack */
/** @EFFECT_MELEE decreases chance of hitting intervening target on reach attack */
if( inter != nullptr &&
!x_in_y( ( target_size * target_size + 1 ) * skill,
( inter->get_size() * inter->get_size() + 1 ) * 10 ) ) {
Expand All @@ -1003,7 +1003,6 @@ void Character::reach_attack( const tripoint &p, int forced_movecost )
}
critter = inter;
break;
/** @EFFECT_STABBING increases ability to reach attack through fences */
} else if( here.impassable( path_point ) &&
// Fences etc. Spears can stab through those
!( weapon.has_flag( flag_SPEAR ) &&
Expand Down Expand Up @@ -1031,7 +1030,7 @@ void Character::reach_attack( const tripoint &p, int forced_movecost )
}

reach_attacking = true;
melee_attack_abstract( *critter, false, force_technique, false, forced_movecost );
melee_attack_abstract( *critter, true, force_technique, false, forced_movecost );
reach_attacking = false;
}

Expand Down Expand Up @@ -1527,6 +1526,18 @@ std::vector<matec_id> Character::evaluate_techniques( Creature &t, const item_lo
continue;
}

// skip non reach ok techniques if reach attacking
if( !( tec.reach_ok || tec.reach_tec ) && reach_attacking ) {
add_msg_debug( debugmode::DF_MELEE, "Not usable with reach attack, attack discarded" );
continue;
}

// skip reach techniques if not reach attacking
if( tec.reach_tec && !reach_attacking ) {
add_msg_debug( debugmode::DF_MELEE, "Only usable with reach attack, attack discarded" );
continue;
}

// skip dodge counter techniques if it's not a dodge count, and vice versa
if( dodge_counter != tec.dodge_counter ) {
add_msg_debug( debugmode::DF_MELEE, "Not a dodge counter, attack discarded" );
Expand Down

0 comments on commit 15f2ff3

Please sign in to comment.