Skip to content

Commit

Permalink
polearms: do less damage in close
Browse files Browse the repository at this point in the history
Add a new flag, "POLEARM", which causes a reach weapon to do 70% of its
normal damage (before armor) if it is used against an adjacent target.

Apply the flag to most polearm weapons and pikes but not spears.

Update the NPC melee weapon evaluation to reduce the value of polearms.
  • Loading branch information
mlangsdorf committed Apr 18, 2020
1 parent cedb55f commit 8a1a71b
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 20 deletions.
6 changes: 6 additions & 0 deletions data/json/flags.json
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,12 @@
"//": "Increases warmth for hands if the player's hands are cold and the player is wielding nothing.",
"info": "This clothing has <info>pockets</info> to warm your hands when you are wielding nothing."
},
{
"id": "POLEARM",
"type": "json_flag",
"context": [ "GENERIC", "TOOL" ],
"info": "As a weapon, this item needs considerable space to use properly and does 70% of its normal damage to adjacent enemies."
},
{
"id": "POWERED",
"type": "json_flag",
Expand Down
4 changes: 2 additions & 2 deletions data/json/items/melee/bludgeons.json
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@
"description": "This is a versatile polearm with a spiked hammer head, a spike, and a hook attached to a long stick.",
"price": 50000,
"material": [ "wood", "steel" ],
"flags": [ "DURABLE_MELEE", "REACH_ATTACK", "NONCONDUCTIVE", "SHEATH_SPEAR", "SPEAR", "ALWAYS_TWOHAND" ],
"flags": [ "DURABLE_MELEE", "REACH_ATTACK", "NONCONDUCTIVE", "POLEARM", "SHEATH_SPEAR", "SPEAR", "ALWAYS_TWOHAND" ],
"techniques": [ "WBLOCK_1", "WIDE", "SWEEP" ],
"weight": "3200 g",
"volume": "3750 ml",
Expand All @@ -583,7 +583,7 @@
"price": 4000,
"price_postapoc": 500,
"material": [ "wood", "aluminum" ],
"flags": [ "REACH_ATTACK", "NONCONDUCTIVE", "SHEATH_SPEAR", "SPEAR", "ALWAYS_TWOHAND" ],
"flags": [ "REACH_ATTACK", "NONCONDUCTIVE", "POLEARM", "SHEATH_SPEAR", "SPEAR", "ALWAYS_TWOHAND" ],
"techniques": [ "WBLOCK_1", "SWEEP" ],
"weight": "2700 g",
"volume": "3750 ml",
Expand Down
26 changes: 13 additions & 13 deletions data/json/items/melee/spears_and_polearms.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"color": "light_gray",
"techniques": [ "WIDE", "BRUTAL" ],
"qualities": [ [ "CUT", 1 ], [ "BUTCHER", -22 ] ],
"flags": [ "FRAGILE_MELEE", "NONCONDUCTIVE", "SHEATH_SPEAR", "REACH_ATTACK", "ALWAYS_TWOHAND" ]
"flags": [ "FRAGILE_MELEE", "NONCONDUCTIVE", "POLEARM", "SHEATH_SPEAR", "REACH_ATTACK", "ALWAYS_TWOHAND" ]
},
{
"id": "spear_spike",
Expand Down Expand Up @@ -278,7 +278,7 @@
"description": "This is a versatile polearm with an axe blade, a spike, and other fun things attached to a long stick.",
"price": 50000,
"material": [ "wood", "steel" ],
"flags": [ "DURABLE_MELEE", "REACH_ATTACK", "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"flags": [ "DURABLE_MELEE", "REACH_ATTACK", "NONCONDUCTIVE", "POLEARM", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"techniques": [ "WBLOCK_1", "WIDE", "SWEEP" ],
"weight": "3175 g",
"volume": "3750 ml",
Expand All @@ -297,7 +297,7 @@
"description": "This is a dull, cheaply made replica of a polearm with an axe blade, a spike, and other fun things attached to a long stick.",
"price": 5000,
"material": [ "wood", "aluminum" ],
"flags": [ "REACH_ATTACK", "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"flags": [ "REACH_ATTACK", "NONCONDUCTIVE", "POLEARM", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"techniques": [ "WBLOCK_1", "SWEEP" ],
"weight": "1644 g",
"volume": "3750 ml",
Expand All @@ -317,7 +317,7 @@
"price": 50000,
"material": [ "steel", "wood" ],
"qualities": [ [ "CUT", 1 ], [ "BUTCHER", -28 ] ],
"flags": [ "DURABLE_MELEE", "REACH_ATTACK", "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"flags": [ "DURABLE_MELEE", "REACH_ATTACK", "NONCONDUCTIVE", "POLEARM", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"techniques": [ "WIDE", "WBLOCK_1" ],
"weight": "2100 g",
"volume": "2500 ml",
Expand All @@ -341,7 +341,7 @@
"bashing": 6,
"cutting": 37,
"qualities": [ [ "CUT", 1 ], [ "BUTCHER", -24 ] ],
"flags": [ "DURABLE_MELEE", "REACH_ATTACK", "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"flags": [ "DURABLE_MELEE", "REACH_ATTACK", "NONCONDUCTIVE", "POLEARM", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"price": 80000,
"price_postapoc": 9500
},
Expand All @@ -360,7 +360,7 @@
"cutting": 21,
"to_hit": 2,
"qualities": [ [ "CUT", 1 ], [ "BUTCHER", -24 ] ],
"flags": [ "REACH_ATTACK", "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"flags": [ "REACH_ATTACK", "NONCONDUCTIVE", "POLEARM", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"price": 8000,
"price_postapoc": 1500
},
Expand All @@ -378,7 +378,7 @@
"bashing": 13,
"cutting": 1,
"to_hit": -1,
"flags": [ "REACH_ATTACK", "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"flags": [ "REACH_ATTACK", "NONCONDUCTIVE", "POLEARM", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ],
"price": 8000,
"price_postapoc": 500
},
Expand All @@ -396,7 +396,7 @@
"volume": "2250 ml",
"bashing": 2,
"cutting": 24,
"flags": [ "STAB", "REACH_ATTACK", "SHEATH_SPEAR" ],
"flags": [ "STAB", "POLEARM", "REACH_ATTACK", "SHEATH_SPEAR" ],
"//": "Description says it can slash. STAB currently doesn't slash, but at least it doesn't give the spear bonus",
"price": 8000,
"price_postapoc": 4500,
Expand Down Expand Up @@ -460,7 +460,7 @@
"color": "brown",
"techniques": [ "IMPALE", "WBLOCK_2" ],
"qualities": [ [ "COOK", 1 ] ],
"flags": [ "DURABLE_MELEE", "SPEAR", "REACH_ATTACK", "REACH3", "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ]
"flags": [ "DURABLE_MELEE", "POLEARM", "SPEAR", "REACH_ATTACK", "REACH3", "NONCONDUCTIVE", "SHEATH_SPEAR", "ALWAYS_TWOHAND" ]
},
{
"id": "pike_fake",
Expand All @@ -481,7 +481,7 @@
"looks_like": "pike",
"techniques": [ "IMPALE", "WBLOCK_2" ],
"qualities": [ [ "COOK", 1 ] ],
"flags": [ "SPEAR", "REACH_ATTACK", "REACH3", "NONCONDUCTIVE", "ALWAYS_TWOHAND" ]
"flags": [ "POLEARM", "SPEAR", "REACH_ATTACK", "REACH3", "NONCONDUCTIVE", "ALWAYS_TWOHAND" ]
},
{
"id": "pike_inferior",
Expand All @@ -502,7 +502,7 @@
"looks_like": "pike",
"techniques": [ "IMPALE", "WBLOCK_2" ],
"qualities": [ [ "COOK", 1 ] ],
"flags": [ "SPEAR", "REACH_ATTACK", "REACH3", "NONCONDUCTIVE", "ALWAYS_TWOHAND" ]
"flags": [ "POLEARM", "SPEAR", "REACH_ATTACK", "REACH3", "NONCONDUCTIVE", "ALWAYS_TWOHAND" ]
},
{
"type": "GENERIC",
Expand All @@ -521,7 +521,7 @@
"color": "light_gray",
"techniques": [ "WIDE", "BRUTAL" ],
"qualities": [ [ "CUT", 1 ], [ "BUTCHER", -22 ] ],
"flags": [ "DURABLE_MELEE", "NONCONDUCTIVE", "SHEATH_SPEAR", "REACH_ATTACK", "ALWAYS_TWOHAND" ]
"flags": [ "DURABLE_MELEE", "NONCONDUCTIVE", "POLEARM", "SHEATH_SPEAR", "REACH_ATTACK", "ALWAYS_TWOHAND" ]
},
{
"id": "spear_dory",
Expand Down Expand Up @@ -559,7 +559,7 @@
"symbol": "/",
"color": "yellow",
"techniques": [ "WBLOCK_1", "DEF_DISARM" ],
"flags": [ "DURABLE_MELEE", "REACH_ATTACK", "ALWAYS_TWOHAND" ]
"flags": [ "DURABLE_MELEE", "POLEARM", "REACH_ATTACK", "ALWAYS_TWOHAND" ]
},
{
"id": "spear_stone",
Expand Down
3 changes: 2 additions & 1 deletion doc/JSON_FLAGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -795,10 +795,11 @@ List of known flags, used in both `terrain.json` and `furniture.json`.
- ```NO_CVD``` Item can never be used with a CVD machine
- ```NO_RELOAD``` Item can never be reloaded (even if has a valid ammo type).
- ```NO_UNWIELD``` Cannot unwield this item.
- ```POLEARM``` Item is clumsy up close and does 70% of normal damage against adjacent targets. Should be paired with REACH_ATTACK. Simple reach piercing weapons like spears should not get this flag.
- ```REACH_ATTACK``` Allows to perform reach attack.
- ```SHEATH_KNIFE``` Item can be sheathed in a knife sheath, it applicable to small/medium knives (with volume not bigger than 2)
- ```SHEATH_SWORD``` Item can be sheathed in a sword scabbard
- ```SPEAR``` When making reach attacks intervening THIN_OBSTACLE terrain is not an obstacle
- ```SPEAR``` When making reach attacks intervening THIN_OBSTACLE terrain is not an obstacle. Should be paired with REACH_ATTACK.
- ```UNARMED_WEAPON``` Wielding this item still counts as unarmed combat.
- ```WHIP``` Has a chance of disarming the opponent.
Expand Down
1 change: 1 addition & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ class Character : public Creature, public visitable<Character>
std::string melee_special_effects( Creature &t, damage_instance &d, item &weap );
/** Performs special attacks and their effects (poisonous, stinger, etc.) */
void perform_special_attacks( Creature &t, dealt_damage_instance &dealt_dam );
bool reach_attacking = false;

/** Returns a vector of valid mutation attacks */
std::vector<special_attack> mutation_attacks( Creature &t ) const;
Expand Down
4 changes: 2 additions & 2 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4877,7 +4877,7 @@ damage_instance item::base_damage_thrown() const
return type->thrown_damage;
}

int item::reach_range( const player &p ) const
int item::reach_range( const Character &guy ) const
{
int res = 1;

Expand All @@ -4888,7 +4888,7 @@ int item::reach_range( const player &p ) const
// for guns consider any attached gunmods
if( is_gun() && !is_gunmod() ) {
for( const std::pair<const gun_mode_id, gun_mode> &m : gun_all_modes() ) {
if( p.is_npc() && m.second.flags.count( "NPC_AVOID" ) ) {
if( guy.is_npc() && m.second.flags.count( "NPC_AVOID" ) ) {
continue;
}
if( m.second.melee() ) {
Expand Down
2 changes: 1 addition & 1 deletion src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ class item : public visitable<item>
/*@}*/

/** Max range weapon usable for melee attack accounting for player/NPC abilities */
int reach_range( const player &p ) const;
int reach_range( const Character &guy ) const;

/**
* Sets time until activation for an item that will self-activate in the future.
Expand Down
9 changes: 9 additions & 0 deletions src/melee.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,11 @@ void Character::melee_attack( Creature &t, bool allow_special, const matec_id &f
technique_id = tec_none;
d.mult_damage( 0.1 );
}
// polearms and pikes (but not spears) do less damage to adjacent targets
if( cur_weapon.reach_range( *this ) > 1 && !reach_attacking &&
cur_weapon.has_flag( "POLEARM" ) ) {
d.mult_damage( 0.7 );
}

const ma_technique &technique = technique_id.obj();

Expand Down Expand Up @@ -2203,6 +2208,10 @@ double player::melee_value( const item &weap ) const
if( reach > 1.0f ) {
my_value *= 1.0f + 0.5f * ( std::sqrt( reach ) - 1.0f );
}
// value polearms less to account for the trickiness of keeping the right range
if( weapon.has_flag( "POLEARM" ) ) {
my_value *= 0.8;
}

// value style weapons more
if( !martial_arts_data.enumerate_known_styles( weap.type->get_id() ).empty() ) {
Expand Down
1 change: 0 additions & 1 deletion src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,6 @@ class player : public Character
// Turned to false for simulating NPCs on distant missions so they don't drop all their gear in sight
bool death_drops;

bool reach_attacking = false;
bool manual_examine = false;
vproto_id starting_vehicle;
std::vector<mtype_id> starting_pets;
Expand Down

0 comments on commit 8a1a71b

Please sign in to comment.