Skip to content

Commit

Permalink
Fixes For Worn Enchanted Armor (#54852)
Browse files Browse the repository at this point in the history
* fixed it all

* add check for multi wearing
  • Loading branch information
bombasticSlacks authored Jan 30, 2022
1 parent 8a77ece commit b8599a1
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 31 deletions.
6 changes: 6 additions & 0 deletions data/json/flags.json
Original file line number Diff line number Diff line change
Expand Up @@ -1332,6 +1332,12 @@
"id": "MOUNTED_GUN",
"type": "json_flag"
},
{
"id": "MUNDANE",
"//": "For items that have relic data but aren't actually magic",
"info": "This item is designed to have special effects",
"type": "json_flag"
},
{
"id": "MYCUS_OK",
"type": "json_flag"
Expand Down
34 changes: 19 additions & 15 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8676,32 +8676,36 @@ void Character::on_item_wear( const item &it )
{
invalidate_inventory_validity_cache();
for( const trait_id &mut : it.mutations_from_wearing( *this ) ) {
mutation_effect( mut, true );
recalc_sight_limits();
calc_encumbrance();

// If the stamina is higher than the max (Languorous), set it back to max
if( get_stamina() > get_stamina_max() ) {
set_stamina( get_stamina_max() );
}
// flag these mutations to be added at the start of the next turn
// without doing this you still count as wearing the item providing
// the traits so most the calcs don't work in mutation_loss_effect
mutations_to_add.push_back( mut );
}
morale->on_item_wear( it );
}

void Character::on_item_takeoff( const item &it )
{
invalidate_inventory_validity_cache();
for( const trait_id &mut : it.mutations_from_wearing( *this ) ) {
mutation_loss_effect( mut );
recalc_sight_limits();
calc_encumbrance();
if( get_stamina() > get_stamina_max() ) {
set_stamina( get_stamina_max() );
}
for( const trait_id &mut : it.mutations_from_wearing( *this, true ) ) {
// flag these mutations to be removed at the start of the next turn
// without doing this you still count as wearing the item providing
// the traitssdd so most the calcs don't work in mutation_loss_effect
mutations_to_remove.push_back( mut );

}
morale->on_item_takeoff( it );
}

void Character::enchantment_wear_change()
{
recalc_sight_limits();
calc_encumbrance();
if( get_stamina() > get_stamina_max() ) {
set_stamina( get_stamina_max() );
}
}

void Character::on_item_acquire( const item &it )
{
if( is_avatar() && it.has_item_with( []( const item & it ) {
Expand Down
10 changes: 9 additions & 1 deletion src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -2246,7 +2246,8 @@ class Character : public Creature, public visitable
/** Get the idents of all base traits. */
std::vector<trait_id> get_base_traits() const;
/** Get the idents of all traits/mutations. */
std::vector<trait_id> get_mutations( bool include_hidden = true ) const;
std::vector<trait_id> get_mutations( bool include_hidden = true,
bool ignore_enchantment = false ) const;
const std::bitset<NUM_VISION_MODES> &get_vision_modes() const {
return vision_mode_cache;
}
Expand Down Expand Up @@ -2599,6 +2600,8 @@ class Character : public Creature, public visitable
void on_item_wear( const item &it );
/** Called when an item is taken off */
void on_item_takeoff( const item &it );
// things to call when mutations enchantments change
void enchantment_wear_change();
/** Called when an item is washed */
void on_worn_item_washed( const item &it );
/** Called when an item is acquired (picked up, worn, or wielded) */
Expand Down Expand Up @@ -3286,6 +3289,11 @@ class Character : public Creature, public visitable
* Pointers to mutation branches in @ref my_mutations.
*/
std::vector<const mutation_branch *> cached_mutations;

// if the player puts on and takes off items these mutations
// are added or removed at the beginning of the next
std::vector<trait_id> mutations_to_remove;
std::vector<trait_id> mutations_to_add;
/**
* The amount of weight the Character is carrying.
* If it is nullopt, needs to be recalculated
Expand Down
17 changes: 17 additions & 0 deletions src/character_body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,23 @@ void Character::update_body( const time_point &from, const time_point &to )
}
update_stomach( from, to );
recalculate_enchantment_cache();
// after recalcing the enchantment cache can properly remove and add mutations
const std::vector<trait_id> &current_traits = get_mutations();
for( const trait_id &mut : mutations_to_remove ) {
// check if the player still has a mutation
// since a trait from an item might be provided by another item as well
auto it = std::find( current_traits.begin(), current_traits.end(), mut );
if( it == current_traits.end() ) {
mutation_loss_effect( mut );
enchantment_wear_change();
}
}
for( const trait_id &mut : mutations_to_add ) {
mutation_effect( mut, true );
enchantment_wear_change();
}
mutations_to_add.clear();
mutations_to_remove.clear();
if( ticks_between( from, to, 3_minutes ) > 0 ) {
magic->update_mana( *this, to_turns<float>( 3_minutes ) );
}
Expand Down
1 change: 1 addition & 0 deletions src/flag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ const flag_id flag_MELTS( "MELTS" );
const flag_id flag_MESSY( "MESSY" );
const flag_id flag_MISSION_ITEM( "MISSION_ITEM" );
const flag_id flag_MOUNTED_GUN( "MOUNTED_GUN" );
const flag_id flag_MUNDANE( "MUNDANE" );
const flag_id flag_MUSHY( "MUSHY" );
const flag_id flag_MUTE( "MUTE" );
const flag_id flag_MYCUS_OK( "MYCUS_OK" );
Expand Down
1 change: 1 addition & 0 deletions src/flag.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ extern const flag_id flag_MELTS;
extern const flag_id flag_MESSY;
extern const flag_id flag_MISSION_ITEM;
extern const flag_id flag_MOUNTED_GUN;
extern const flag_id flag_MUNDANE;
extern const flag_id flag_MUSHY;
extern const flag_id flag_MYCUS_OK;
extern const flag_id flag_NANOFAB_TEMPLATE;
Expand Down
6 changes: 3 additions & 3 deletions src/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5405,7 +5405,7 @@ nc_color item::color_in_inventory( const Character *const ch ) const
ret = c_red;
} else if( is_filthy() || has_own_flag( flag_DIRTY ) ) {
ret = c_brown;
} else if( is_relic() ) {
} else if( is_relic() && !has_flag( flag_MUNDANE ) ) {
ret = c_pink;
} else if( is_bionic() ) {
if( !player_character.has_bionic( type->bionic->id ) || type->bionic->id->dupes_allowed ) {
Expand Down Expand Up @@ -11790,7 +11790,7 @@ void item::reset_temp_check()
last_temp_check = calendar::turn;
}

std::vector<trait_id> item::mutations_from_wearing( const Character &guy ) const
std::vector<trait_id> item::mutations_from_wearing( const Character &guy, bool removing ) const
{
if( !is_relic() ) {
return std::vector<trait_id> {};
Expand All @@ -11804,7 +11804,7 @@ std::vector<trait_id> item::mutations_from_wearing( const Character &guy ) const
}
}

for( const trait_id &char_mut : guy.get_mutations() ) {
for( const trait_id &char_mut : guy.get_mutations( true, removing ) ) {
for( auto iter = muts.begin(); iter != muts.end(); ) {
if( char_mut == *iter ) {
iter = muts.erase( iter );
Expand Down
2 changes: 1 addition & 1 deletion src/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -1615,7 +1615,7 @@ class item : public visitable
bool use_relic( Character &guy, const tripoint &pos );
bool has_relic_recharge() const;
bool has_relic_activation() const;
std::vector<trait_id> mutations_from_wearing( const Character &guy ) const;
std::vector<trait_id> mutations_from_wearing( const Character &guy, bool removing = false ) const;

/**
* Name of the item type (not the item), with proper plural.
Expand Down
9 changes: 9 additions & 0 deletions src/mutation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,15 @@ void Character::mutation_effect( const trait_id &mut, const bool worn_destroyed_
if( !branch.conflicts_with_item( armor ) ) {
return false;
}

// if an item gives an enchantment it shouldn't break or be shoved off
for( const enchantment &ench : armor.get_enchantments() ) {
for( const trait_id &inner_mut : ench.get_mutations() ) {
if( mut == inner_mut ) {
return false;
}
}
}
if( !worn_destroyed_override && branch.destroys_gear ) {
add_msg_player_or_npc( m_bad,
_( "Your %s is destroyed!" ),
Expand Down
25 changes: 14 additions & 11 deletions src/newcharacter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4163,7 +4163,8 @@ std::vector<trait_id> Character::get_base_traits() const
return std::vector<trait_id>( my_traits.begin(), my_traits.end() );
}

std::vector<trait_id> Character::get_mutations( bool include_hidden ) const
std::vector<trait_id> Character::get_mutations( bool include_hidden,
bool ignore_enchantments ) const
{
std::vector<trait_id> result;
result.reserve( my_mutations.size() + enchantment_cache->get_mutations().size() );
Expand All @@ -4172,17 +4173,19 @@ std::vector<trait_id> Character::get_mutations( bool include_hidden ) const
result.push_back( t.first );
}
}
for( const trait_id &ench_trait : enchantment_cache->get_mutations() ) {
if( include_hidden || ench_trait->player_display ) {
bool found = false;
for( const trait_id &exist : result ) {
if( exist == ench_trait ) {
found = true;
break;
if( !ignore_enchantments ) {
for( const trait_id &ench_trait : enchantment_cache->get_mutations() ) {
if( include_hidden || ench_trait->player_display ) {
bool found = false;
for( const trait_id &exist : result ) {
if( exist == ench_trait ) {
found = true;
break;
}
}
if( !found ) {
result.push_back( ench_trait );
}
}
if( !found ) {
result.push_back( ench_trait );
}
}
}
Expand Down

0 comments on commit b8599a1

Please sign in to comment.