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

[WIP][CR] Adding vitamins and toxin levels monitor functions to Blood Analyser CBM #37582

Closed
62 changes: 58 additions & 4 deletions src/bionics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "ui.h"
#include "vehicle.h"
#include "vpart_position.h"
#include "vitamin.h"
#include "weather.h"
#include "weather_gen.h"
#include "calendar.h"
Expand Down Expand Up @@ -388,7 +389,6 @@ bool Character::activate_bionic( int b, bool eff_only )
{ effect_datura, translate_marker( "Anticholinergic Tropane Alkaloids" ) },
// TODO: Hallucinations not inducted by chemistry
{ effect_hallu, translate_marker( "Hallucinations" ) },
{ effect_visuals, translate_marker( "Hallucinations" ) },
}
};

Expand All @@ -412,7 +412,10 @@ bool Character::activate_bionic( int b, bool eff_only )

std::vector<std::string> good;
std::vector<std::string> bad;

std::vector<std::string> vit;
std::vector<std::string> tox;
std::vector<std::string> drug;
std::vector<std::string> cnt;
if( get_rad() > 0 ) {
bad.push_back( _( "Irradiated" ) );
}
Expand All @@ -430,8 +433,38 @@ bool Character::activate_bionic( int b, bool eff_only )
}
}

const size_t win_h = std::min( static_cast<size_t>( TERMY ), bad.size() + good.size() + 2 );
const int win_w = 46;
const std::map<vitamin_id, vitamin> &vit_all = vitamin::all();
for( const auto &v : vit_all ) {
if( !v.second.has_flag( "NO_DISPLAY" ) && !v.second.has_flag( "NOT_IN_BLOOD" ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document the new flag and the additional behavior of the old one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we shouldn't check NO_DISPLAY here at all. If vitamin is not showing in comestibles UI doesn't necessary mean it shouldn't be displayed by Blood Analyzer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's definitely use for a flag that means that the vitamin is never displayed - perhaps the food one should have a separate flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to use NOT_IN_BLOOD flag to tell Blood Analyzer to ignore that vitamin... Maybe should change it to BLOOD_ANALYZER to do the opposite - only show vitamins with this flag.

switch( v.second.type() ) {
case vitamin_type::VITAMIN:
if( !v.second.get_string_level( vitamin_get( v.first ) ).empty() ) {
vit.push_back( v.second.get_string_level( vitamin_get( v.first ) ) );
}
break;
case vitamin_type::TOXIN:
if( !v.second.get_string_level( vitamin_get( v.first ) ).empty() ) {
tox.push_back( v.second.get_string_level( vitamin_get( v.first ) ) );
}
break;
case vitamin_type::DRUG:
if( !v.second.get_string_level( vitamin_get( v.first ) ).empty() ) {
drug.push_back( v.second.get_string_level( vitamin_get( v.first ) ) );
}
break;
default:
if( !v.second.get_string_level( vitamin_get( v.first ) ).empty() ) {
cnt.push_back( v.second.get_string_level( vitamin_get( v.first ) ) );
}
}
}
}

const int effect_spacing = ( good.empty() && bad.empty() ) ? 1 : good.size() + bad.size();
const size_t win_h = std::min( static_cast<size_t>( TERMY ),
effect_spacing + vit.size() + tox.size() + drug.size() + cnt.size() + 2 );
//const int win_w = 46;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove any commented out code, it's no longer useful.

Suggested change
//const int win_w = 46;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do when figure out how exactly I should optimize Analyzer window width.

const int win_w = 80;
catacurses::window w = catacurses::newwin( win_h, win_w, point( ( TERMX - win_w ) / 2,
( TERMY - win_h ) / 2 ) );
draw_border( w, c_red, string_format( " %s ", _( "Blood Test Results" ) ) );
Expand All @@ -447,6 +480,27 @@ bool Character::activate_bionic( int b, bool eff_only )
}
}
}
for( size_t line = effect_spacing + 1; line < ( win_h - 1 ) &&
line <= effect_spacing + vit.size(); ++line ) {
trim_and_print( w, point( 2, line ), win_w - 3, c_yellow,
vit[line - 1 - effect_spacing] );
}
for( size_t line = effect_spacing + vit.size() + 1; line < ( win_h - 1 ) &&
line <= effect_spacing + vit.size() + tox.size(); ++line ) {
trim_and_print( w, point( 2, line ), win_w - 3, c_yellow,
tox[line - 1 - effect_spacing - vit.size()] );
}
for( size_t line = effect_spacing + vit.size() + tox.size() + 1; line < ( win_h - 1 ) &&
line <= effect_spacing + vit.size() + tox.size() + drug.size(); ++line ) {
trim_and_print( w, point( 2, line ), win_w - 3, c_yellow,
drug[line - 1 - effect_spacing - vit.size() - drug.size()] );
}
for( size_t line = effect_spacing + vit.size() + tox.size() + drug.size() + 1;
line < ( win_h - 1 ) &&
line <= effect_spacing + vit.size() + tox.size() + drug.size() + cnt.size(); ++line ) {
trim_and_print( w, point( 2, line ), win_w - 3, c_yellow,
cnt[line - 1 - effect_spacing - vit.size() - drug.size() - cnt.size()] );
}
wrefresh( w );
catacurses::refresh();
inp_mngr.wait_for_any_key();
Expand Down
57 changes: 57 additions & 0 deletions src/vitamin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,63 @@ int vitamin::severity( int qty ) const
return 0;
}

std::string vitamin::get_string_level( int qty ) const
{
float norm_level = 1.0f;
if( type_ == vitamin_type::VITAMIN ) {
if( id_ == "vitA" ) {
norm_level = 2.0f;
} else if( id_ == "vitB" ) {
norm_level = 2.75f;
} else if( id_ == "vitC" ) {
norm_level = 2.2f;
} else if( id_ == "iron" ) {
norm_level = 1.23f;
} else if( id_ == "calcium" ) {
norm_level = 1.1f;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This data (norm_level), should probably be in JSON, not hardcoded.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or dynamically determined.

}
float v_level = 0.0f;
if( ( disease_.size() > 0 ) && !disease_[0].first ) {
v_level = norm_level * qty / disease_[0].first;
} else if( ( disease_excess_.size() > 0 ) && !disease_excess_[0].first ) {
v_level = norm_level * qty / disease_excess_[0].first;
} else {
return "";
}
if( v_level != 0 ) {
std::string message = string_format( _( "%s level is %.2f times %s than normal." ), name(),
std::abs( v_level ), ( v_level < 0 ? _( "higher" ) : _( "lower" ) ) );
const int sev = severity( qty );
if( sev ) {
const std::vector<std::string> s = { "", _( "Minor" ), _( "Severe" ), _( "Extreme" ) };
message += string_format( " %s %s.", s[std::abs( sev )],
( sev < 0 ? _( "deficiency" ) : _( "excess" ) ) );
}
return message;
} else {
return string_format( _( "%s level is normal." ), name() );
}
}
if( type_ == vitamin_type::TOXIN ) {
if( id_ == "mutant_toxin" ) {
if( qty > ( disease_excess_[2].first ) ) {
return _( "Deadly levels of unknown toxins detected." );
} else if( qty > ( disease_excess_[1].first ) ) {
return _( "Extreme levels of unknown toxins detected." );
} else if( qty > ( disease_excess_[0].first ) ) {
return _( "Dangerous levels of unknown toxins detected." );
} else if( qty > ( disease_excess_[0].first / 2 ) ) {
return _( "Significant levels of unknown toxins detected." );
} else if( qty > ( disease_excess_[0].first / 4 ) ) {
return _( "Traces of unknown toxins detected." );
} else {
return "";
}
}
}
return "";
}

void vitamin::load_vitamin( const JsonObject &jo )
{
vitamin vit;
Expand Down
3 changes: 3 additions & 0 deletions src/vitamin.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ class vitamin
/** Get intensity of deficiency or zero if not deficient for specified qty */
int severity( int qty ) const;

/** Get text description of specified vitamin level*/
std::string get_string_level( int qty ) const;

/** Load vitamin from JSON definition */
static void load_vitamin( const JsonObject &jo );

Expand Down