Skip to content

Commit

Permalink
STS: prevent reading your way to STR, DEX, and PER
Browse files Browse the repository at this point in the history
For all the skills but intelligence, it doesn't make much sense to learn
skills by reading. It probably doesn't make some sense for a bit of the
intelligence skills, but someone else can easily change that in the
future.

Because stat bonuses are now based on skill experience, as opposed to
number of skills, Stats Through Skills now emphasizes fewer, higher
skills, as opposed to more, lower skills.

The new formula:
cbrt( 0.9 * experience - 0.5 )
Roughly matches the old formula
sqrt( skills - 3 ) ^ 0.4
in the amount of experience required to get each stat bonus.
It does, however gain slightly faster than the old one.

Because I basically reinvented Stats Through Skills, I put my name in
authors.
  • Loading branch information
anothersimulacrum committed Apr 10, 2020
1 parent 5e64b28 commit 62a4a94
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 32 deletions.
38 changes: 25 additions & 13 deletions data/mods/StatsThroughSkills/modinfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,49 @@
"type": "MOD_INFO",
"ident": "StatsThroughSkills",
"name": "Stats Through Skills",
"authors": [ "Ryan \"DeNarr\" Saige", "Kevin Granade" ],
"authors": [ "Ryan \"DeNarr\" Saige", "Kevin Granade", "anothersimulacrum" ],
"description": "Allows stats to raise via skill progression.",
"category": "rebalance",
"dependencies": [ "dda" ]
},
{
"type": "skill_boost",
"stat": "str",
"skills": [ "mechanics", "swimming", "bashing", "cutting", "melee", "throw" ],
"skill_offset": -3,
"scaling_power": 0.4
"skills_practice": [ "mechanics", "swimming", "bashing", "cutting", "melee", "throw" ],
"skills_knowledge": [ ],
"skill_offset": -0.5,
"scaling_power": 0.33,
"coefficient": 0.9,
"max_stat": 5
},
{
"type": "skill_boost",
"stat": "dex",
"skills": [ "driving", "survival", "tailor", "traps", "dodge", "stabbing", "unarmed" ],
"skill_offset": -3,
"scaling_power": 0.4
"skills_practice": [ "driving", "survival", "tailor", "traps", "dodge", "stabbing", "unarmed" ],
"skills_knowledge": [ ],
"skill_offset": -0.5,
"scaling_power": 0.33,
"coefficient": 0.9,
"max_stat": 5
},
{
"type": "skill_boost",
"stat": "int",
"skills": [ "barter", "computer", "cooking", "electronics", "fabrication", "firstaid", "speech" ],
"skill_offset": -3,
"scaling_power": 0.4
"skills_practice": [ "barter", "computer", "cooking", "electronics", "fabrication", "firstaid", "speech" ],
"skills_knowledge": [ "barter", "computer", "cooking", "electronics", "fabrication", "firstaid", "speech" ],
"skill_offset": -0.5,
"scaling_power": 0.33,
"coefficient": 0.9,
"max_stat": 5
},
{
"type": "skill_boost",
"stat": "per",
"skills": [ "archery", "gun", "launcher", "pistol", "rifle", "shotgun", "smg" ],
"skill_offset": -3,
"scaling_power": 0.4
"skills_practice": [ "archery", "gun", "launcher", "pistol", "rifle", "shotgun", "smg" ],
"skills_knowledge": [ ],
"skill_offset": -0.5,
"scaling_power": 0.33,
"coefficient": 0.9,
"max_stat": 5
}
]
30 changes: 22 additions & 8 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1544,11 +1544,18 @@ void Character::recalc_hp()
int str_boost_val = 0;
cata::optional<skill_boost> str_boost = skill_boost::get( "str" );
if( str_boost ) {
int skill_total = 0;
for( const std::string &skill_str : str_boost->skills() ) {
skill_total += get_skill_level( skill_id( skill_str ) );
int exercise_total = 0;
for( const std::string &skill_str : str_boost->skills_practice() ) {
const SkillLevel &lvl = get_skill_level_object( skill_id( skill_str ) );
exercise_total += lvl.total_exercise( PRACTICE );
}
str_boost_val = str_boost->calc_bonus( skill_total );

for( const std::string &skill_str : str_boost->skills_knowledge() ) {
const SkillLevel &lvl = get_skill_level_object( skill_id( skill_str ) );
exercise_total += lvl.total_exercise( KNOWLEDGE );
}

str_boost_val = str_boost->calc_bonus( std::floor( exercise_total / 1000 ) );
}
// Mutated toughness stacks with starting, by design.
float hp_mod = 1.0f + mutation_value( "hp_modifier" ) + mutation_value( "hp_modifier_secondary" );
Expand Down Expand Up @@ -3210,11 +3217,18 @@ void Character::apply_skill_boost()
remove_value( bonus_name );
}
// End migration code
int skill_total = 0;
for( const std::string &skill_str : boost.skills() ) {
skill_total += get_skill_level( skill_id( skill_str ) );
int experience_total = 0;
for( const std::string &skill_str : boost.skills_practice() ) {
const SkillLevel &lvl = get_skill_level_object( skill_id( skill_str ) );
experience_total += lvl.total_exercise( PRACTICE );
}
mod_stat( boost.stat(), boost.calc_bonus( skill_total ) );

for( const std::string &skill_str : boost.skills_knowledge() ) {
const SkillLevel &lvl = get_skill_level_object( skill_id( skill_str ) );
experience_total += lvl.total_exercise( KNOWLEDGE );
}

mod_stat( boost.stat(), boost.calc_bonus( std::floor( experience_total / 1000 ) ) );
if( boost.stat() == "str" ) {
recalc_hp();
}
Expand Down
19 changes: 19 additions & 0 deletions src/skill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,24 @@ void SkillLevel::train( int amount, skill_exercise_type type, bool skip_scaling
}
}

int SkillLevel::total_exercise( skill_exercise_type type ) const
{
int all_exercise = 0;
for( int i = 1; i <= _level; ++i ) {
all_exercise += static_cast<int>( std::pow( i, 2 ) * 100 );
}

switch( type ) {
case PRACTICE:
return _practice + static_cast<int>( _practice_ratio * all_exercise );
case KNOWLEDGE:
return _knowledge + static_cast<int>( ( 1 - _practice_ratio ) * all_exercise );
case NUM_SKILL_EXERCISE_TYPE:
return _practice + _knowledge + all_exercise;
}
return 0;
}

namespace
{
time_duration rustRate( int level )
Expand Down Expand Up @@ -454,3 +472,4 @@ double price_adjustment( int barter_skill )
return 1.0;
}
}

5 changes: 4 additions & 1 deletion src/skill.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ template <typename T> class string_id;

enum skill_exercise_type : int {
PRACTICE,
KNOWLEDGE
KNOWLEDGE,
NUM_SKILL_EXERCISE_TYPE
};

struct time_info_t {
Expand Down Expand Up @@ -189,6 +190,8 @@ class SkillLevel

void readBook( int minimumGain, int maximumGain, int maximumLevel = -1 );

int total_exercise( skill_exercise_type type = NUM_SKILL_EXERCISE_TYPE ) const;

bool operator==( const SkillLevel &b ) const {
return _level == b._level && _knowledge == b._knowledge && _practice == b._practice;
}
Expand Down
21 changes: 15 additions & 6 deletions src/skill_boost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@ void skill_boost::load_boost( const JsonObject &jo, const std::string &src )

void skill_boost::load( const JsonObject &jo, const std::string & )
{
mandatory( jo, was_loaded, "skills", _skills );
mandatory( jo, was_loaded, "skills_practice", _skills_practice );
mandatory( jo, was_loaded, "skills_knowledge", _skills_knowledge );
mandatory( jo, was_loaded, "coefficient", _coefficient );
mandatory( jo, was_loaded, "skill_offset", _offset );
mandatory( jo, was_loaded, "scaling_power", _power );
mandatory( jo, was_loaded, "max_stat", _max_stat );
}

void skill_boost::reset()
Expand All @@ -49,15 +52,21 @@ std::string skill_boost::stat() const
return id.str();
}

const std::vector<std::string> &skill_boost::skills() const
const std::vector<std::string> &skill_boost::skills_practice() const
{
return _skills;
return _skills_practice;
}

float skill_boost::calc_bonus( int skill_total ) const
const std::vector<std::string> &skill_boost::skills_knowledge() const
{
if( skill_total + _offset <= 0 ) {
return _skills_knowledge;
}

float skill_boost::calc_bonus( int exp_total ) const
{
if( ( _coefficient * exp_total ) + _offset <= 0 ) {
return 0.0;
}
return std::max( 0.0, std::floor( std::pow( skill_total + _offset, _power ) ) );
return clamp( std::floor( std::pow( ( _coefficient * exp_total ) + _offset, _power ) ), 0.0f,
_max_stat );
}
12 changes: 8 additions & 4 deletions src/skill_boost.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ class skill_boost
skill_boost() = default;

std::string stat() const;
const std::vector<std::string> &skills() const;
float calc_bonus( int skill_total ) const;
const std::vector<std::string> &skills_practice() const;
const std::vector<std::string> &skills_knowledge() const;
float calc_bonus( int exp_total ) const;

static void load_boost( const JsonObject &jo, const std::string &src );
static void reset();
Expand All @@ -32,9 +33,12 @@ class skill_boost
friend class generic_factory<skill_boost>;
string_id<skill_boost> id;
bool was_loaded = false;
std::vector<std::string> _skills;
int _offset = 0;
std::vector<std::string> _skills_practice;
std::vector<std::string> _skills_knowledge;
float _coefficient = 0.0f;
float _offset = 0.0f;
float _power = 0.0f;
float _max_stat = 0.0f;

void load( const JsonObject &jo, const std::string &src );
};
Expand Down

0 comments on commit 62a4a94

Please sign in to comment.