Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jsonized time to atack skill data #35830

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions data/json/skills.json
Expand Up @@ -130,6 +130,7 @@
"name": "archery",
"description": "Your skill in using bow weapons, from hand-carved self bows to complex compound bows. Quiet and effective, they require strength of body and sight to wield, and are not terribly accurate over a long distance.",
"tags": [ "combat_skill" ],
"time_to_attack": { "min_time": 20, "base_time": 220, "time_reduction_per_level": 25 },
"companion_combat_rank_factor": 1,
"companion_survival_rank_factor": 1,
"display_category": "display_ranged",
Expand All @@ -156,6 +157,7 @@
"name": "launchers",
"description": "Your skill in using heavy weapons like rocket, grenade or missile launchers. These weapons have a variety of applications and may carry immense destructive power, but they are cumbersome and hard to manage.",
"tags": [ "combat_skill" ],
"time_to_attack": { "min_time": 30, "base_time": 200, "time_reduction_per_level": 20 },
"display_category": "display_ranged"
},
{
Expand All @@ -164,6 +166,7 @@
"name": "handguns",
"description": "Handguns have poor accuracy compared to rifles, but are usually quick to fire and reload faster than other guns. They are very effective at close quarters, though unsuited for long range engagement.",
"tags": [ "combat_skill" ],
"time_to_attack": { "min_time": 10, "base_time": 80, "time_reduction_per_level": 10 },
"display_category": "display_ranged",
"companion_skill_practice": [ { "skill": "hunting", "weight": 25 } ]
},
Expand All @@ -173,6 +176,7 @@
"name": "rifles",
"description": "Rifles have terrific range and accuracy compared to other firearms, but may be slow to fire and reload, and can prove difficult to use in close quarters. Fully automatic rifles can fire rapidly, but are harder to handle properly.",
"tags": [ "combat_skill" ],
"time_to_attack": { "min_time": 30, "base_time": 150, "time_reduction_per_level": 15 },
"display_category": "display_ranged",
"companion_skill_practice": [ { "skill": "hunting", "weight": 45 } ]
},
Expand All @@ -182,6 +186,7 @@
"name": "shotguns",
"description": "Shotguns are easy to shoot and can inflict massive damage, but their effectiveness and accuracy decline rapidly with range. Slugs can be loaded into shotguns to provide greater range, though they are somewhat inaccurate.",
"tags": [ "combat_skill" ],
"time_to_attack": { "min_time": 70, "base_time": 150, "time_reduction_per_level": 25 },
"display_category": "display_ranged",
"companion_skill_practice": [ { "skill": "hunting", "weight": 25 } ]
},
Expand All @@ -191,6 +196,7 @@
"name": "submachine guns",
"description": "Comprised of an automatic rifle carbine designed to fire a pistol cartridge, submachine guns can reload and fire quickly, sometimes in bursts, but they are relatively inaccurate and may be prone to mechanical failures.",
"tags": [ "combat_skill" ],
"time_to_attack": { "min_time": 20, "base_time": 80, "time_reduction_per_level": 10 },
"display_category": "display_ranged",
"companion_skill_practice": [ { "skill": "hunting", "weight": 25 } ]
},
Expand All @@ -200,6 +206,7 @@
"name": "throwing",
"description": "Your skill in throwing objects over a distance. Skill increases accuracy, and at higher levels, the range of a throw.",
"tags": [ "combat_skill" ],
"time_to_attack": { "min_time": 50, "base_time": 220, "time_reduction_per_level": 25 },
"display_category": "display_ranged"
},
{
Expand All @@ -208,6 +215,7 @@
"name": "melee",
"description": "Your skill and finesse in personal combat, both with and without a weapon. Higher levels can significantly increase the accuracy and effectiveness of your physical attacks.",
"tags": [ "combat_skill" ],
"time_to_attack": { "min_time": 50, "base_time": 200, "time_reduction_per_level": 20 },
"companion_combat_rank_factor": 1,
"display_category": "display_melee",
"companion_skill_practice": [
Expand Down
37 changes: 9 additions & 28 deletions src/ranged.cpp
Expand Up @@ -62,6 +62,7 @@
#include "material.h"
#include "type_id.h"
#include "point.h"
#include "skill.h"

const skill_id skill_throw( "throw" );
const skill_id skill_gun( "gun" );
Expand All @@ -84,7 +85,7 @@ static const fault_id fault_gun_unlubricated( "fault_gun_unlubricated" );
static const fault_id fault_gun_chamber_spent( "fault_gun_chamber_spent" );

static projectile make_gun_projectile( const item &gun );
int time_to_fire( const Character &p, const itype &firing );
int time_to_attack( const Character &p, const itype &firing );
static void cycle_action( item &weap, const tripoint &pos );
void make_gun_sound_effect( const player &p, bool burst, item *weapon );

Expand Down Expand Up @@ -470,7 +471,7 @@ int player::fire_gun( const tripoint &target, int shots, item &gun )
last_target_pos = cata::nullopt;

// Use different amounts of time depending on the type of gun and our skill
moves -= time_to_fire( *this, *gun.type );
moves -= time_to_attack( *this, *gun.type );

// Practice the base gun skill proportionally to number of hits, but always by one.
practice( skill_gun, ( hits + 1 ) * 5 );
Expand Down Expand Up @@ -998,7 +999,7 @@ static int print_ranged_chance( const player &p, const catacurses::window &w, in
if( mode == TARGET_MODE_THROW || mode == TARGET_MODE_THROW_BLIND ) {
moves_to_fire = throw_cost( p, ranged_weapon );
} else {
moves_to_fire = p.gun_engagement_moves( ranged_weapon, threshold, recoil ) + time_to_fire( p,
moves_to_fire = p.gun_engagement_moves( ranged_weapon, threshold, recoil ) + time_to_attack( p,
*ranged_weapon.type );
}

Expand Down Expand Up @@ -2181,32 +2182,12 @@ static projectile make_gun_projectile( const item &gun )
return proj;
}

int time_to_fire( const Character &p, const itype &firing )
int time_to_attack( const Character &p, const itype &firing )
{
struct time_info_t {
int min_time; // absolute floor on the time taken to fire.
int base; // the base or max time taken to fire.
int reduction; // the reduction in time given per skill level.
};

static const std::map<skill_id, time_info_t> map {
{skill_id {"pistol"}, {10, 80, 10}},
{skill_id {"shotgun"}, {70, 150, 25}},
{skill_id {"smg"}, {20, 80, 10}},
{skill_id {"rifle"}, {30, 150, 15}},
{skill_id {"archery"}, {20, 220, 25}},
{skill_id {"throw"}, {50, 220, 25}},
{skill_id {"launcher"}, {30, 200, 20}},
{skill_id {"melee"}, {50, 200, 20}}
};

const skill_id &skill_used = firing.gun->skill_used;
const auto it = map.find( skill_used );
// TODO: maybe JSON-ize this in some way? Probably as part of the skill class.
static const time_info_t default_info{ 50, 220, 25 };

const time_info_t &info = ( it == map.end() ) ? default_info : it->second;
return std::max( info.min_time, info.base - info.reduction * p.get_skill_level( skill_used ) );
const time_info_t &info = skill_used->time_to_attack();
return std::max( info.min_time,
info.base_time - info.time_reduction_per_level * p.get_skill_level( skill_used ) );
}

static void cycle_action( item &weap, const tripoint &pos )
Expand Down Expand Up @@ -2452,7 +2433,7 @@ double player::gun_value( const item &weap, int ammo ) const
damage_factor += 0.5f * gun_damage.damage_units.front().res_pen;
}

int move_cost = time_to_fire( *this, *weap.type );
int move_cost = time_to_attack( *this, *weap.type );
if( gun.clip != 0 && gun.clip < 10 ) {
// TODO: RELOAD_ONE should get a penalty here
int reload_cost = gun.reload_time + encumb( bp_hand_l ) + encumb( bp_hand_r );
Expand Down
19 changes: 13 additions & 6 deletions src/skill.cpp
Expand Up @@ -92,18 +92,25 @@ void Skill::load_skill( JsonObject &jsobj )
return s._ident == ident;
} ), end( skills ) );

std::unordered_map<std::string, int> companion_skill_practice;
translation name, desc;
translation name;
jsobj.read( "name", name );
translation desc;
jsobj.read( "description", desc );
JsonArray ja = jsobj.get_array( "companion_skill_practice" );
while( ja.has_more() ) {
JsonObject jo = ja.next_object();
companion_skill_practice.emplace( jo.get_string( "skill" ), jo.get_int( "weight" ) );
std::unordered_map<std::string, int> companion_skill_practice;
for( JsonObject jo_csp : jsobj.get_array( "companion_skill_practice" ) ) {
companion_skill_practice.emplace( jo_csp.get_string( "skill" ), jo_csp.get_int( "weight" ) );
}
time_info_t time_to_attack;
if( jsobj.has_object( "time_to_attack" ) ) {
JsonObject jso_tta = jsobj.get_object( "time_to_attack" );
jso_tta.read( "min_time", time_to_attack.min_time );
jso_tta.read( "base_time", time_to_attack.base_time );
jso_tta.read( "time_reduction_per_level", time_to_attack.time_reduction_per_level );
}
skill_displayType_id display_type = skill_displayType_id( jsobj.get_string( "display_category" ) );
Skill sk( ident, name, desc, jsobj.get_tags( "tags" ), display_type );

sk._time_to_attack = time_to_attack;
sk._companion_combat_rank_factor = jsobj.get_int( "companion_combat_rank_factor", 0 );
sk._companion_survival_rank_factor = jsobj.get_int( "companion_survival_rank_factor", 0 );
sk._companion_industry_rank_factor = jsobj.get_int( "companion_industry_rank_factor", 0 );
Expand Down
13 changes: 13 additions & 0 deletions src/skill.h
Expand Up @@ -20,6 +20,15 @@ class JsonOut;
class recipe;
class item;

struct time_info_t {
// Absolute floor on the time taken to attack.
int min_time = 50;
// The base or max time taken to attack.
int base_time = 220;
// The reduction in time given per skill level.
int time_reduction_per_level = 25;
};

class Skill
{
friend class string_id<Skill>;
Expand All @@ -28,6 +37,7 @@ class Skill
translation _name;
translation _description;
std::set<std::string> _tags;
time_info_t _time_to_attack;
ZhilkinSerg marked this conversation as resolved.
Show resolved Hide resolved
skill_displayType_id _display_type;
std::unordered_map<std::string, int> _companion_skill_practice;
// these are not real skills, they depend on context
Expand Down Expand Up @@ -68,6 +78,9 @@ class Skill
skill_displayType_id display_category() const {
return _display_type;
}
time_info_t time_to_attack() const {
return _time_to_attack;
}
int companion_combat_rank_factor() const {
return _companion_combat_rank_factor;
}
Expand Down