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

Hyper-metabolism rework #45687

Merged
merged 9 commits into from
Dec 5, 2020
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions data/json/mutations/mutations.json
Original file line number Diff line number Diff line change
Expand Up @@ -3279,13 +3279,32 @@
"id": "EATHEALTH",
"name": { "str": "Hyper-Metabolism" },
"points": 15,
"description": "You metabolize nutrients so rapidly that you can convert food directly into useful tissue. Excess nutrition will convert to HP, rather than being wasted. Activate to skip prompt for overeating.",
"description": "Your particular metabolism allows you to burn calories at a prodigious rate to regenerate tissues in a matter of minutes, this is however a very wasteful process. Activate to start healing.",
"prereqs": [ "HUNGER3" ],
"types": [ "METABOLISM" ],
"threshreq": [ "THRESH_CHIMERA" ],
"category": [ "CHIMERA" ],
"valid": false,
"active": true
"active": true,
"transform": {
"target": "EATHEALTH_active",
"msg_transform": "Your hyper-metabolism starts burning up calories.",
"active": true,
"moves": 0
}
},
{
"type": "mutation",
"id": "EATHEALTH_active",
"name": { "str": "Hyper-Metabolism: burning" },
"description": "You're burning calories like crazy to heal your wounds.",
"copy-from": "EATHEALTH",
"cost": 1,
"time": 1,
"hunger": true,
"healing_awake": 300.0,
"healing_resting": 350.0,
"transform": { "target": "EATHEALTH", "msg_transform": "Your hyper-metabolism slows down.", "active": false, "moves": 0 }
},
{
"type": "mutation",
Expand Down
12 changes: 8 additions & 4 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,7 @@ class Character : public Creature, public visitable<Character>
virtual int get_hunger() const;
virtual int get_starvation() const;
virtual int get_thirst() const;
/** Gets character's minimum hunger and thirst */
int stomach_capacity() const;

std::pair<std::string, nc_color> get_thirst_description() const;
std::pair<std::string, nc_color> get_hunger_description() const;
std::pair<std::string, nc_color> get_fatigue_description() const;
Expand Down Expand Up @@ -1152,6 +1151,11 @@ class Character : public Creature, public visitable<Character>
void mutation_loss_effect( const trait_id &mut );

bool has_active_mutation( const trait_id &b ) const;

int get_cost_timer( const trait_id &mut_id ) const;
void set_cost_timer( const trait_id &mut, int set );
void mod_cost_timer( const trait_id &mut, int mod );

/** Picks a random valid mutation and gives it to the Character, possibly removing/changing others along the way */
void mutate();
/** Returns true if the player doesn't have the mutation or a conflicting one and it complies with the force typing */
Expand Down Expand Up @@ -2754,8 +2758,8 @@ class Character : public Creature, public visitable<Character>
std::map<bodypart_id, float> bodypart_exposure();
private:
/** suffer() subcalls */
void suffer_water_damage( const mutation_branch &mdata );
void suffer_mutation_power( const mutation_branch &mdata, Character::trait_data &tdata );
void suffer_water_damage( const trait_id &mut_id );
void suffer_mutation_power( const trait_id &mut_id );
void suffer_while_underwater();
void suffer_from_addictions();
void suffer_while_awake( int current_stim );
Expand Down
37 changes: 0 additions & 37 deletions src/consumption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,23 +143,6 @@ static const std::map<itype_id, int> plut_charges = {
{ itype_id( "plut_slurry" ), PLUTONIUM_CHARGES / 2 }
};

int Character::stomach_capacity() const
{
if( has_trait( trait_GIZZARD ) ) {
return 0;
}

if( has_active_mutation( trait_HIBERNATE ) ) {
return -620;
}

if( has_trait( trait_GOURMAND ) || has_trait( trait_HIBERNATE ) ) {
return -60;
}

return -20;
}

// TODO: Move pizza scraping here.
static int compute_default_effective_kcal( const item &comest, const Character &you,
const cata::flat_set<flag_id> &extra_flags = {} )
Expand Down Expand Up @@ -1342,8 +1325,6 @@ bool Character::consume_effects( item &food )
mod_fatigue( nutr );
}
}
// TODO: remove this
int capacity = stomach_capacity();
// Moved here and changed a bit - it was too complex
// Incredibly minor stuff like this shouldn't require complexity
if( !is_npc() && has_trait( trait_SLIMESPAWNER ) &&
Expand All @@ -1365,24 +1346,6 @@ bool Character::consume_effects( item &food )
add_msg_if_player( m_good, _( "hey, you look like me! let's work together!" ) );
}

// Last thing that happens before capping hunger
if( get_hunger() < capacity && has_trait( trait_EATHEALTH ) ) {
int excess_food = capacity - get_hunger();
add_msg_player_or_npc( _( "You feel the %s filling you out." ),
_( "<npcname> looks better after eating the %s." ),
food.tname() );
// Guaranteed 1 HP healing, no matter what. You're welcome. ;-)
if( excess_food <= 5 ) {
healall( 1 );
} else {
// Straight conversion, except it's divided amongst all your body parts.
healall( excess_food /= 5 );
}

// Note: We want this here to prevent "you can't finish this" messages
set_hunger( capacity );
}

nutrients food_nutrients = compute_effective_nutrients( food );
const units::volume water_vol = ( food.get_comestible()->quench > 0 ) ?
food.get_comestible()->quench *
Expand Down
26 changes: 26 additions & 0 deletions src/mutation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,32 @@ bool Character::has_active_mutation( const trait_id &b ) const
return iter != my_mutations.end() && iter->second.powered;
}

int Character::get_cost_timer( const trait_id &mut ) const
{
const auto iter = my_mutations.find( mut );
if( iter != my_mutations.end() ) {
return iter->second.charge;
} else {
debugmsg( "Tried to get cost timer of %s but doesn't have this mutation.", mut.c_str() );
}
return 0;
}

void Character::set_cost_timer( const trait_id &mut, int set )
{
const auto iter = my_mutations.find( mut );
if( iter != my_mutations.end() ) {
iter->second.charge = set;
} else {
debugmsg( "Tried to set cost timer of %s but doesn't have this mutation.", mut.c_str() );
}
}

void Character::mod_cost_timer( const trait_id &mut, int mod )
{
set_cost_timer( mut, get_cost_timer( mut ) + mod );
}

bool Character::is_category_allowed( const std::vector<mutation_category_id> &category ) const
{
bool allowed = false;
Expand Down
64 changes: 30 additions & 34 deletions src/suffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,11 @@ static float addiction_scaling( float at_min, float at_max, float add_lvl )
return lerp( at_min, at_max, ( add_lvl - MIN_ADDICTION_LEVEL ) / MAX_ADDICTION_LEVEL );
}

void Character::suffer_water_damage( const mutation_branch &mdata )
void Character::suffer_water_damage( const trait_id &mut_id )
{
for( const std::pair<const bodypart_str_id, bodypart> &elem : get_body() ) {
const float wetness_percentage = elem.second.get_wetness_percentage();
const int dmg = mdata.weakness_to_water * wetness_percentage;
const int dmg = mut_id->weakness_to_water * wetness_percentage;
if( dmg > 0 ) {
apply_damage( nullptr, elem.first, dmg );
add_msg_player_or_npc( m_bad, _( "Your %s is damaged by the water." ),
Expand All @@ -193,51 +193,49 @@ void Character::suffer_water_damage( const mutation_branch &mdata )
}
}

void Character::suffer_mutation_power( const mutation_branch &mdata,
Character::trait_data &tdata )
void Character::suffer_mutation_power( const trait_id &mut_id )
{
if( tdata.powered && tdata.charge > 0 ) {
// Already-on units just lose a bit of charge
tdata.charge--;
if( get_cost_timer( mut_id ) > 0 ) {
// Not ready to consume cost yet, the timer ticks on
mod_cost_timer( mut_id, -1 );
} else {
// Not-on units, or those with zero charge, have to pay the power cost
if( mdata.cooldown > 0 ) {
tdata.powered = true;
tdata.charge = mdata.cooldown - 1;
}
if( mdata.hunger ) {
// does not directly modify hunger, but burns kcal
mod_stored_nutr( mdata.cost );
// Ready to consume cost: pay the power cost and reset timer
if( mut_id->cooldown > 0 ) {
set_cost_timer( mut_id, mut_id->cooldown - 1 );
}
if( mut_id->hunger ) {
if( get_bmi() < character_weight_category::underweight ) {
add_msg_if_player( m_warning,
_( "You're too malnourished to keep your %s going." ),
mdata.name() );
tdata.powered = false;
mut_id->name() );
deactivate_mutation( mut_id );
} else {
// does not directly modify hunger, but burns kcal
mod_stored_nutr( mut_id->cost );
}
}
if( mdata.thirst ) {
mod_thirst( mdata.cost );
if( mut_id->thirst ) {
// Well into Dehydrated
if( get_thirst() >= 260 ) {
add_msg_if_player( m_warning,
_( "You're too dehydrated to keep your %s going." ),
mdata.name() );
tdata.powered = false;
mut_id->name() );
deactivate_mutation( mut_id );
} else {
mod_thirst( mut_id->cost );
}
}
if( mdata.fatigue ) {
mod_fatigue( mdata.cost );
if( mut_id->fatigue ) {
// Exhausted
if( get_fatigue() >= fatigue_levels::EXHAUSTED ) {
add_msg_if_player( m_warning,
_( "You're too exhausted to keep your %s going." ),
mdata.name() );
tdata.powered = false;
mut_id->name() );
deactivate_mutation( mut_id );
} else {
mod_fatigue( mut_id->cost );
}
}
if( !tdata.powered ) {
apply_mods( mdata.id, false );
}
}
}

Expand Down Expand Up @@ -1529,14 +1527,12 @@ void Character::suffer()
process_bionic( i );
}

for( std::pair<const trait_id, Character::trait_data> &mut : my_mutations ) {
const mutation_branch &mdata = mut.first.obj();
for( const trait_id &mut_id : get_mutations() ) {
if( calendar::once_every( 1_minutes ) ) {
suffer_water_damage( mdata );
suffer_water_damage( mut_id );
}
Character::trait_data &tdata = mut.second;
if( tdata.powered ) {
suffer_mutation_power( mdata, tdata );
if( has_active_mutation( mut_id ) ) {
suffer_mutation_power( mut_id );
}
}

Expand Down