Skip to content

Commit

Permalink
enchantment cache
Browse files Browse the repository at this point in the history
  • Loading branch information
KorGgenT committed Sep 26, 2019
1 parent 9a54879 commit c5b8bc7
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 19 deletions.
41 changes: 36 additions & 5 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3951,11 +3951,11 @@ std::string get_stat_name( Character::stat Stat )
{
switch( Stat ) {
// *INDENT-OFF*
case Character::stat::STRENGTH: return pgettext("strength stat", "STR");
case Character::stat::DEXTERITY: return pgettext("dexterity stat", "DEX");
case Character::stat::INTELLIGENCE: return pgettext("intelligence stat", "INT");
case Character::stat::PERCEPTION: return pgettext("perception stat", "PER");
// *INDENT-ON*
case Character::stat::STRENGTH: return pgettext( "strength stat", "STR" );
case Character::stat::DEXTERITY: return pgettext( "dexterity stat", "DEX" );
case Character::stat::INTELLIGENCE: return pgettext( "intelligence stat", "INT" );
case Character::stat::PERCEPTION: return pgettext( "perception stat", "PER" );
// *INDENT-ON*
default:
return pgettext( "fake stat there's an error", "ERR" );
break;
Expand Down Expand Up @@ -4048,3 +4048,34 @@ std::string Character::get_highest_category() const
}
return sMaxCat;
}

void Character::recalculate_enchantment_cache()
{
// start by resetting the cache to all inventory items
enchantment_cache = inv.get_active_enchantment_cache( *this );

for( const enchantment &ench : weapon.get_enchantments() ) {
if( ench.is_active( *this, weapon ) ) {
enchantment_cache.force_add( ench );
}
}

for( const item &worn_it : worn ) {
for( const enchantment &ench : worn_it.get_enchantments() ) {
if( ench.is_active( *this, worn_it ) ) {
enchantment_cache.force_add( ench );
}
}
}
}

double Character::calculate_by_enchantment( double modify, enchantment::mod value,
bool round_output ) const
{
modify += enchantment_cache.get_value_add( value );
modify *= 1.0 + enchantment_cache.get_value_multiply( value );
if( round_output ) {
modify = round( modify );
}
return modify;
}
10 changes: 10 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "type_id.h"
#include "units.h"
#include "point.h"
#include "magic_enchantment.h"

struct pathfinding_settings;
class item_location;
Expand Down Expand Up @@ -486,6 +487,11 @@ class Character : public Creature, public visitable<Character>

std::array<std::array<int, NUM_WATER_TOLERANCE>, num_bp> mut_drench;
public:
// recalculates enchantment cache by iterating through all held, worn, and wielded items
void recalculate_enchantment_cache();
// gets add and mult value from enchantment cache
double calculate_by_enchantment( double modify, enchantment::mod value,
bool round_output = false ) const;
/** Handles things like destruction of armor, etc. */
void mutation_effect( const trait_id &mut );
/** Handles what happens when you lose a mutation. */
Expand Down Expand Up @@ -1055,6 +1061,10 @@ class Character : public Creature, public visitable<Character>
faction *my_fac = nullptr;

private:
// a cache of all active enchantment values.
// is recalculated every turn in Character::recalculate_enchantment_cache
enchantment enchantment_cache;

// A unique ID number, assigned by the game class. Values should never be reused.
character_id id;

Expand Down
13 changes: 1 addition & 12 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11262,14 +11262,7 @@ void game::process_artifact( item &it, player &p )
const std::vector<art_effect_passive> &ew = it.type->artifact->effects_wielded;
effects.insert( effects.end(), ew.begin(), ew.end() );
}
std::vector<enchantment> active_enchantments;
if( it.is_relic() ) {
for( const enchantment &ench : it.get_enchantments() ) {
if( ench.is_active( p, it ) ) {
active_enchantments.emplace_back( ench );
}
}
}

if( it.is_tool() ) {
// Recharge it if necessary
if( it.ammo_remaining() < it.ammo_capacity() && calendar::once_every( 1_minutes ) ) {
Expand Down Expand Up @@ -11334,10 +11327,6 @@ void game::process_artifact( item &it, player &p )
}
}

for( const enchantment &ench : active_enchantments ) {
ench.activate_passive( p );
}

for( const art_effect_passive &i : effects ) {
switch( i ) {
case AEP_STR_UP:
Expand Down
15 changes: 15 additions & 0 deletions src/inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,21 @@ std::vector<item *> inventory::active_items()
return ret;
}

enchantment inventory::get_active_enchantment_cache( const Character &owner ) const
{
enchantment temp_cache;
for( const std::list<item> &elem : items ) {
for( const item &check_item : elem ) {
for( const enchantment &ench : check_item.get_enchantments() ) {
if( ench.is_active( owner, check_item ) ) {
temp_cache.force_add( ench );
}
}
}
}
return temp_cache;
}

void inventory::assign_empty_invlet( item &it, const Character &p, const bool force )
{
const std::string auto_setting = get_option<std::string>( "AUTO_INV_ASSIGN" );
Expand Down
4 changes: 4 additions & 0 deletions src/inventory.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "cata_utility.h"
#include "item.h"
#include "item_stack.h"
#include "magic_enchantment.h"
#include "visitable.h"
#include "units.h"

Expand Down Expand Up @@ -223,6 +224,9 @@ class inventory : public visitable<inventory>

void copy_invlet_of( const inventory &other );

// gets a singular enchantment that is an amalgamation of all items that have active enchantments
enchantment get_active_enchantment_cache( const Character &owner ) const;

private:
invlet_favorites invlet_cache;
char find_usable_cached_invlet( const std::string &item_type );
Expand Down
26 changes: 25 additions & 1 deletion src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8035,7 +8035,7 @@ void item::reset_temp_check()

void item::process_artifact( player *carrier, const tripoint & /*pos*/ )
{
if( !is_artifact() && !is_relic() ) {
if( !is_artifact() ) {
return;
}
// Artifacts are currently only useful for the player character, the messages
Expand All @@ -8047,6 +8047,30 @@ void item::process_artifact( player *carrier, const tripoint & /*pos*/ )
}
}

void item::process_relic( Character *carrier )
{
if( !is_relic() ) {
return;
}
std::vector<enchantment> active_enchantments;

for( const enchantment &ench : get_enchantments() ) {
if( ench.is_active( *carrier, *this ) ) {
active_enchantments.emplace_back( ench );
}
}

for( const enchantment &ench : active_enchantments ) {
ench.activate_passive( *carrier );
}

// Recalculate, as it might have changed (by mod_*_bonus above)
carrier->str_cur = carrier->get_str();
carrier->int_cur = carrier->get_int();
carrier->dex_cur = carrier->get_dex();
carrier->per_cur = carrier->get_per();
}

bool item::process_corpse( player *carrier, const tripoint &pos )
{
// some corpses rez over time
Expand Down
1 change: 1 addition & 0 deletions src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,7 @@ class item : public visitable<item>
* @param pos The location of the artifact (should be the player location if carried).
*/
void process_artifact( player *carrier, const tripoint &pos );
void process_relic( Character *carrier );

bool destroyed_at_zero_charges() const;
// Most of the is_whatever() functions call the same function in our itype
Expand Down
7 changes: 6 additions & 1 deletion src/magic_enchantment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,12 @@ bool enchantment::add( const enchantment &rhs )
if( !stacks_with( rhs ) ) {
return false;
}
force_add( rhs );
return true;
}

void enchantment::force_add( const enchantment &rhs )
{
for( const std::pair<mod, int> &pair_values : rhs.values_add ) {
values_add[pair_values.first] += pair_values.second;
}
Expand All @@ -319,7 +325,6 @@ bool enchantment::add( const enchantment &rhs )
intermittent_activation[act_pair.first].emplace_back( fake );
}
}
return true;
}

int enchantment::get_value_add( const mod value ) const
Expand Down
3 changes: 3 additions & 0 deletions src/magic_enchantment.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ class enchantment
// if their conditions don't match, return false. else true.
bool add( const enchantment &rhs );

// adds two enchantments together and ignores their conditions
void force_add( const enchantment &rhs );

int get_value_add( mod value ) const;
double get_value_multiply( mod value ) const;

Expand Down
1 change: 1 addition & 0 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ void player::process_turn()

visit_items( [this]( item * e ) {
e->process_artifact( this, pos() );
e->process_relic( this );
return VisitResponse::NEXT;
} );

Expand Down

0 comments on commit c5b8bc7

Please sign in to comment.