Skip to content

Commit

Permalink
Move activate_mutation and deactivate_mutation to Character (#35227)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fris0uman authored and ZhilkinSerg committed Nov 8, 2019
1 parent 7afefd7 commit 5a117d8
Show file tree
Hide file tree
Showing 9 changed files with 276 additions and 219 deletions.
53 changes: 53 additions & 0 deletions src/avatar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1530,3 +1530,56 @@ bool avatar::wield( item &target )

return true;
}

bool avatar::invoke_item( item *used, const tripoint &pt )
{
const std::map<std::string, use_function> &use_methods = used->type->use_methods;

if( use_methods.empty() ) {
return false;
} else if( use_methods.size() == 1 ) {
return invoke_item( used, use_methods.begin()->first, pt );
}

uilist umenu;

umenu.text = string_format( _( "What to do with your %s?" ), used->tname() );
umenu.hilight_disabled = true;

for( const auto &e : use_methods ) {
const auto res = e.second.can_call( *this, *used, false, pt );
umenu.addentry_desc( MENU_AUTOASSIGN, res.success(), MENU_AUTOASSIGN, e.second.get_name(),
res.str() );
}

umenu.desc_enabled = std::any_of( umenu.entries.begin(),
umenu.entries.end(), []( const uilist_entry & elem ) {
return !elem.desc.empty();
} );

umenu.query();

int choice = umenu.ret;
if( choice < 0 || choice >= static_cast<int>( use_methods.size() ) ) {
return false;
}

const std::string &method = std::next( use_methods.begin(), choice )->first;

return invoke_item( used, method, pt );
}

bool avatar::invoke_item( item *used )
{
return Character::invoke_item( used );
}

bool avatar::invoke_item( item *used, const std::string &method, const tripoint &pt )
{
return Character::invoke_item( used, method, pt );
}

bool avatar::invoke_item( item *used, const std::string &method )
{
return Character::invoke_item( used, method );
}
6 changes: 6 additions & 0 deletions src/avatar.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ class avatar : public player

bool wield( item &target ) override;

using Character::invoke_item;
bool invoke_item( item *, const tripoint &pt ) override;
bool invoke_item( item * ) override;
bool invoke_item( item *, const std::string &, const tripoint &pt ) override;
bool invoke_item( item *, const std::string & ) override;

private:
map_memory player_map_memory;
bool show_map_memory;
Expand Down
155 changes: 155 additions & 0 deletions src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include "lightmap.h"
#include "rng.h"
#include "stomach.h"
#include "text_snippets.h"
#include "ui.h"
#include "veh_type.h"
#include "vehicle.h"
Expand Down Expand Up @@ -179,6 +180,7 @@ static const trait_id trait_PYROMANIA( "PYROMANIA" );
static const trait_id trait_ROOTS2( "ROOTS2" );
static const trait_id trait_ROOTS3( "ROOTS3" );
static const trait_id trait_SEESLEEP( "SEESLEEP" );
static const trait_id trait_SELFAWARE( "SELFAWARE" );
static const trait_id trait_SHELL2( "SHELL2" );
static const trait_id trait_SHELL( "SHELL" );
static const trait_id trait_SHOUT2( "SHOUT2" );
Expand Down Expand Up @@ -2912,6 +2914,38 @@ void Character::mod_int_bonus( int nint )
int_cur = std::max( 0, int_max + int_bonus );
}

void Character::print_health() const
{
if( !is_player() ) {
return;
}
int current_health = get_healthy();
if( has_trait( trait_SELFAWARE ) ) {
add_msg_if_player( _( "Your current health value is %d." ), current_health );
}

if( current_health > 0 &&
( has_effect( effect_common_cold ) || has_effect( effect_flu ) ) ) {
return;
}

static const std::map<int, std::string> msg_categories = {
{ -100, "health_horrible" },
{ -50, "health_very_bad" },
{ -10, "health_bad" },
{ 10, "" },
{ 50, "health_good" },
{ 100, "health_very_good" },
{ INT_MAX, "health_great" }
};

auto iter = msg_categories.lower_bound( current_health );
if( iter != msg_categories.end() && !iter->second.empty() ) {
const std::string &msg = SNIPPET.random_from_category( iter->second );
add_msg_if_player( current_health > 0 ? m_good : m_bad, msg );
}
}

namespace io
{
template<>
Expand Down Expand Up @@ -5083,6 +5117,127 @@ void Character::update_stamina( int turns )
set_stamina( std::min( std::max( get_stamina(), 0 ), max_stam ) );
}

bool Character::invoke_item( item *used )
{
return invoke_item( used, pos() );
}

bool Character::invoke_item( item *, const tripoint & )
{
return false;
}

bool Character::invoke_item( item *used, const std::string &method )
{
return invoke_item( used, method, pos() );
}

bool Character::invoke_item( item *used, const std::string &method, const tripoint &pt )
{
if( !has_enough_charges( *used, true ) ) {
return false;
}

item *actually_used = used->get_usable_item( method );
if( actually_used == nullptr ) {
debugmsg( "Tried to invoke a method %s on item %s, which doesn't have this method",
method.c_str(), used->tname() );
return false;
}

int charges_used = actually_used->type->invoke( *this->as_player(), *actually_used, pt, method );
if( charges_used == 0 ) {
return false;
}
// Prevent accessing the item as it may have been deleted by the invoked iuse function.

if( used->is_tool() || used->is_medication() || used->get_contained().is_medication() ) {
return consume_charges( *actually_used, charges_used );
} else if( used->is_bionic() || used->is_deployable() || method == "place_trap" ) {
i_rem( used );
return true;
}

return false;
}

bool Character::has_enough_charges( const item &it, bool show_msg ) const
{
if( !it.is_tool() || !it.ammo_required() ) {
return true;
}
if( it.has_flag( "USE_UPS" ) ) {
if( has_charges( "UPS", it.ammo_required() ) || it.ammo_sufficient() ) {
return true;
}
if( show_msg ) {
add_msg_if_player( m_info,
ngettext( "Your %s needs %d charge from some UPS.",
"Your %s needs %d charges from some UPS.",
it.ammo_required() ),
it.tname(), it.ammo_required() );
}
return false;
} else if( !it.ammo_sufficient() ) {
if( show_msg ) {
add_msg_if_player( m_info,
ngettext( "Your %s has %d charge but needs %d.",
"Your %s has %d charges but needs %d.",
it.ammo_remaining() ),
it.tname(), it.ammo_remaining(), it.ammo_required() );
}
return false;
}
return true;
}

bool Character::consume_charges( item &used, int qty )
{
if( qty < 0 ) {
debugmsg( "Tried to consume negative charges" );
return false;
}

if( qty == 0 ) {
return false;
}

if( !used.is_tool() && !used.is_food() && !used.is_medication() ) {
debugmsg( "Tried to consume charges for non-tool, non-food, non-med item" );
return false;
}

// Consume comestibles destroying them if no charges remain
if( used.is_food() || used.is_medication() ) {
used.charges -= qty;
if( used.charges <= 0 ) {
i_rem( &used );
return true;
}
return false;
}

// Tools which don't require ammo are instead destroyed
if( used.is_tool() && !used.ammo_required() ) {
i_rem( &used );
return true;
}

// USE_UPS never occurs on base items but is instead added by the UPS tool mod
if( used.has_flag( "USE_UPS" ) ) {
// With the new UPS system, we'll want to use any charges built up in the tool before pulling from the UPS
// The usage of the item was already approved, so drain item if possible, otherwise use UPS
if( used.charges >= qty ) {
used.ammo_consume( qty, pos() );
} else {
use_charges( "UPS", qty );
}
} else {
used.ammo_consume( std::min( qty, used.ammo_remaining() ), pos() );
}
return false;
}

int Character::item_handling_cost( const item &it, bool penalties, int base_cost ) const
{
int mv = base_cost;
Expand Down
31 changes: 31 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ class Character : public Creature, public visitable<Character>
virtual void mod_per_bonus( int nper );
virtual void mod_int_bonus( int nint );

// Prints message(s) about current health
void print_health() const;

/** Getters for health values exclusive to characters */
virtual int get_healthy() const;
virtual int get_healthy_mod() const;
Expand Down Expand Up @@ -506,6 +509,10 @@ class Character : public Creature, public visitable<Character>
void set_mutation( const trait_id &flag );
void unset_mutation( const trait_id &flag );

// Trigger and disable mutations that can be so toggled.
void activate_mutation( const trait_id &mutation );
void deactivate_mutation( const trait_id &mut );

/** Converts a body_part to an hp_part */
static hp_part bp_to_hp( body_part bp );
/** Converts an hp_part to a body_part */
Expand Down Expand Up @@ -788,6 +795,30 @@ class Character : public Creature, public visitable<Character>
return false;
}

/**
* Asks how to use the item (if it has more than one use_method) and uses it.
* Returns true if it destroys the item. Consumes charges from the item.
* Multi-use items are ONLY supported when all use_methods are iuse_actor!
*/
virtual bool invoke_item( item *, const tripoint &pt );
/** As above, but with a pre-selected method. Debugmsg if this item doesn't have this method. */
virtual bool invoke_item( item *, const std::string &, const tripoint &pt );
/** As above two, but with position equal to current position */
virtual bool invoke_item( item * );
virtual bool invoke_item( item *, const std::string & );

/**
* Has the item enough charges to invoke its use function?
* Also checks if UPS from this player is used instead of item charges.
*/
bool has_enough_charges( const item &it, bool show_msg ) const;

/** Consume charges of a tool or comestible item, potentially destroying it in the process
* @param used item consuming the charges
* @param qty number of charges to consume which must be non-zero
* @return true if item was destroyed */
bool consume_charges( item &used, int qty );

/**
* Calculate (but do not deduct) the number of moves required when handling (e.g. storing, drawing etc.) an item
* @param it Item to calculate handling cost for
Expand Down
6 changes: 3 additions & 3 deletions src/mutation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,10 +415,10 @@ bool Character::can_install_cbm_on_bp( const std::vector<body_part> &bps ) const
return can_install;
}

void player::activate_mutation( const trait_id &mut )
void Character::activate_mutation( const trait_id &mut )
{
const mutation_branch &mdata = mut.obj();
auto &tdata = my_mutations[mut];
trait_data &tdata = my_mutations[mut];
int cost = mdata.cost;
// Preserve the fake weapon used to initiate ranged mutation firing
static item mut_ranged( weapon );
Expand Down Expand Up @@ -568,7 +568,7 @@ void player::activate_mutation( const trait_id &mut )
}
}

void player::deactivate_mutation( const trait_id &mut )
void Character::deactivate_mutation( const trait_id &mut )
{
my_mutations[mut].powered = false;

Expand Down
22 changes: 22 additions & 0 deletions src/npc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2832,6 +2832,28 @@ void npc::process_turn()
// TODO: Make NPCs leave the player if there's a path out of map and player is sleeping/unseen/etc.
}

bool npc::invoke_item( item *used, const tripoint &pt )
{
const auto &use_methods = used->type->use_methods;

if( use_methods.empty() ) {
return false;
} else if( use_methods.size() == 1 ) {
return Character::invoke_item( used, use_methods.begin()->first, pt );
}
return false;
}

bool npc::invoke_item( item *used, const std::string &method )
{
return Character::invoke_item( used, method );
}

bool npc::invoke_item( item *used )
{
return Character::invoke_item( used );
}

std::array<std::pair<std::string, overmap_location_str_id>, npc_need::num_needs> npc::need_data = {
{
{ "need_none", overmap_location_str_id( "source_of_anything" ) },
Expand Down
5 changes: 5 additions & 0 deletions src/npc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,11 @@ class npc : public player
void execute_action( npc_action action ); // Performs action
void process_turn() override;

using Character::invoke_item;
bool invoke_item( item *, const tripoint &pt ) override;
bool invoke_item( item *used, const std::string &method ) override;
bool invoke_item( item * ) override;

/** rates how dangerous a target is from 0 (harmless) to 1 (max danger) */
float evaluate_enemy( const Creature &target ) const;

Expand Down
Loading

0 comments on commit 5a117d8

Please sign in to comment.