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

Introduce character_id type #33344

Merged
merged 2 commits into from
Aug 20, 2019
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
24 changes: 13 additions & 11 deletions src/avatar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ bool avatar::read( int inventory_position, const bool continuous )

add_msg( m_debug, "avatar::read: time_taken = %d", time_taken );
player_activity act( activity_id( "ACT_READ" ), time_taken, continuous ? activity.index : 0,
reader->getID() );
reader->getID().get_value() );
act.targets.emplace_back( item_location( *this, &it ) );

// If the player hasn't read this book before, skim it to get an idea of what's in it.
Expand Down Expand Up @@ -660,11 +660,11 @@ bool avatar::read( int inventory_position, const bool continuous )
} else if( skill && lvl < type->level ) {
const double penalty = static_cast<double>( time_taken ) / time_to_read( it, *reader, elem );
learners.insert( {elem, elem == reader ? _( " (reading aloud to you)" ) : ""} );
act.values.push_back( elem->getID() );
act.values.push_back( elem->getID().get_value() );
act.str_values.push_back( to_string( penalty ) );
} else {
fun_learners.insert( {elem, elem == reader ? _( " (reading aloud to you)" ) : "" } );
act.values.push_back( elem->getID() );
act.values.push_back( elem->getID().get_value() );
act.str_values.emplace_back( "1" );
}
}
Expand Down Expand Up @@ -709,7 +709,7 @@ bool avatar::read( int inventory_position, const bool continuous )

if( skill ) {
const int lvl = get_skill_level( skill );
menu.addentry( getID(), lvl < type->level, '0',
menu.addentry( getID().get_value(), lvl < type->level, '0',
string_format( _( "Read until you gain a level | current level: %d" ), lvl ) );
} else {
menu.addentry( -1, false, '0', _( "Read until you gain a level" ) );
Expand All @@ -719,7 +719,8 @@ bool avatar::read( int inventory_position, const bool continuous )
if( skill && !learners.empty() ) {
add_header( _( "Read until this NPC gains a level:" ) );
for( const auto &elem : learners ) {
menu.addentry( elem.first->getID(), true, -1, get_text( learners, elem ) );
menu.addentry( elem.first->getID().get_value(), true, -1,
get_text( learners, elem ) );
}
}
if( !fun_learners.empty() ) {
Expand Down Expand Up @@ -754,7 +755,7 @@ bool avatar::read( int inventory_position, const bool continuous )
menu.title = string_format( _( "Train %s from manual:" ),
martial_art_learned_from( *it.type )->name );
menu.addentry( -1, true, 1, _( "Train once." ) );
menu.addentry( getID(), true, 2, _( "Train until tired or success." ) );
menu.addentry( getID().get_value(), true, 2, _( "Train until tired or success." ) );
menu.query( true );
if( menu.ret == UILIST_CANCEL ) {
add_msg( m_info, _( "Never mind." ) );
Expand All @@ -779,10 +780,11 @@ bool avatar::read( int inventory_position, const bool continuous )

if( !continuous ||
!std::all_of( learners.begin(), learners.end(), [&]( const std::pair<npc *, std::string> &elem ) {
return std::count( activity.values.begin(), activity.values.end(), elem.first->getID() ) != 0;
return std::count( activity.values.begin(), activity.values.end(),
elem.first->getID().get_value() ) != 0;
} ) ||
!std::all_of( activity.values.begin(), activity.values.end(), [&]( int elem ) {
return learners.find( g->find_npc( elem ) ) != learners.end();
return learners.find( g->find_npc( character_id( elem ) ) ) != learners.end();
} ) ) {

if( learners.size() == 1 ) {
Expand Down Expand Up @@ -943,7 +945,7 @@ void avatar::do_read( item &book )

std::vector<std::pair<player *, double>> learners; //learners and their penalties
for( size_t i = 0; i < activity.values.size(); i++ ) {
player *n = g->find_npc( activity.values[i] );
player *n = g->find_npc( character_id( activity.values[i] ) );
if( n != nullptr ) {
const std::string &s = activity.get_str_value( i, "1" );
learners.push_back( { n, strtod( s.c_str(), nullptr ) } );
Expand Down Expand Up @@ -1015,7 +1017,7 @@ void avatar::do_read( item &book )
}
} else {
//skill_level == originalSkillLevel
if( activity.index == learner->getID() ) {
if( activity.index == learner->getID().get_value() ) {
continuous = true;
}
if( learner->is_player() ) {
Expand Down Expand Up @@ -1077,7 +1079,7 @@ void avatar::do_read( item &book )
m->second.call( *this, book, false, pos() );
continuous = false;
} else {
if( activity.index == g->u.getID() ) {
if( activity.index == g->u.getID().get_value() ) {
continuous = true;
switch( rng( 1, 5 ) ) {
case 1:
Expand Down
3 changes: 3 additions & 0 deletions src/avatar.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class avatar : public player
void randomize( bool random_scenario, points_left &points, bool play_now = false );
bool load_template( const std::string &template_name, points_left &points );

bool is_avatar() const override {
return true;
}
avatar *as_avatar() override {
return this;
}
Expand Down
2 changes: 1 addition & 1 deletion src/basecamp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ void basecamp::validate_assignees()
++it2;
}
}
for( auto elem : g->get_follower_list() ) {
for( character_id elem : g->get_follower_list() ) {
npc_ptr npc_to_add = overmap_buffer.find_npc( elem );
if( !npc_to_add ) {
continue;
Expand Down
2 changes: 1 addition & 1 deletion src/cata_tiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1692,7 +1692,7 @@ bool cata_tiles::draw_from_id_string( std::string id, TILE_CATEGORY category,
// NPC
if( id.substr( 4 ) == "npc_" ) {
if( npc *const guy = g->critter_at<npc>( pos ) ) {
seed = guy->getID();
seed = guy->getID().get_value();
break;
}
}
Expand Down
19 changes: 18 additions & 1 deletion src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ Character::Character() :
hp_cur( {{ 0 }} ),
hp_max( {{ 0 }} ),
damage_bandaged( {{ 0 }} ),
damage_disinfected( {{ 0 }} )
damage_disinfected( {{ 0 }} ),
id( -1 )
{
str_max = 0;
dex_max = 0;
Expand Down Expand Up @@ -159,6 +160,22 @@ Character::~Character() = default;
Character::Character( Character && ) = default;
Character &Character::operator=( Character && ) = default;

void Character::setID( character_id i )
{
if( id.is_valid() ) {
debugmsg( "tried to set id of a npc/player, but has already a id: %d", id.get_value() );
} else if( !i.is_valid() ) {
debugmsg( "tried to set invalid id of a npc/player: %d", i.get_value() );
} else {
id = i;
}
}

character_id Character::getID() const
{
return this->id;
}

field_type_id Character::bloodType() const
{
if( has_trait( trait_ACIDBLOOD ) ) {
Expand Down
8 changes: 8 additions & 0 deletions src/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "bodypart.h"
#include "calendar.h"
#include "character_id.h"
#include "creature.h"
#include "game_constants.h"
#include "inventory.h"
Expand Down Expand Up @@ -165,6 +166,10 @@ class Character : public Creature, public visitable<Character>
public:
~Character() override;

character_id getID() const;
// sets the ID, will *only* succeed when the current id is not valid
void setID( character_id i );

field_type_id bloodType() const override;
field_type_id gibType() const override;
bool is_warm() const override;
Expand Down Expand Up @@ -962,6 +967,9 @@ class Character : public Creature, public visitable<Character>
mutable pimpl<pathfinding_settings> path_settings;

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

/** Needs (hunger, starvation, thirst, fatigue, etc.) */
int stored_calories;
int healthy_calories;
Expand Down
58 changes: 58 additions & 0 deletions src/character_id.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#pragma once
#ifndef CATA_CHARACTER_ID_H
#define CATA_CHARACTER_ID_H

#include <cassert>
#include <ostream>

class JsonIn;
class JsonOut;

class character_id
{
public:
character_id() : value( -1 ) {}

explicit character_id( int i ) : value( i ) {
}

bool is_valid() const {
return value > 0;
}

int get_value() const {
return value;
}

character_id &operator++() {
++value;
return *this;
}

void serialize( JsonOut & ) const;
void deserialize( JsonIn & );
private:
int value;
};

inline bool operator==( character_id l, character_id r )
{
return l.get_value() == r.get_value();
}

inline bool operator!=( character_id l, character_id r )
{
return l.get_value() != r.get_value();
}

inline bool operator<( character_id l, character_id r )
{
return l.get_value() < r.get_value();
}

inline std::ostream &operator<<( std::ostream &o, character_id id )
{
return o << id.get_value();
}

#endif // CATA_CHARACTER_ID_H
2 changes: 1 addition & 1 deletion src/computer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1706,7 +1706,7 @@ SEARCHING FOR NEAREST REFUGEE CENTER, PLEASE WAIT ... " ) );
} );

if( !has_mission ) {
const auto mission = mission::reserve_new( mission_type, -1 );
const auto mission = mission::reserve_new( mission_type, character_id() );
mission->assign( g->u );
mission_target = mission->get_target();
}
Expand Down
3 changes: 3 additions & 0 deletions src/creature.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ class Creature
virtual bool is_player() const {
return false;
}
virtual bool is_avatar() const {
return false;
}
virtual bool is_npc() const {
return false;
}
Expand Down
30 changes: 15 additions & 15 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ void game::init_ui( const bool resized )

// Only refresh if we are in-game, otherwise all resources are not initialized
// and this refresh will crash the game.
if( resized && u.getID() != -1 ) {
if( resized && u.getID().is_valid() ) {
refresh_all();
}
}
Expand Down Expand Up @@ -628,7 +628,7 @@ void game::setup()

m = map( get_option<bool>( "ZLEVELS" ) );

next_npc_id = 1;
next_npc_id = character_id( 1 );
next_mission_id = 1;
new_game = true;
uquit = QUIT_NO; // We haven't quit the game
Expand Down Expand Up @@ -855,7 +855,7 @@ bool game::start_game()
}
// Assign all of this scenario's missions to the player.
for( const mission_type_id &m : scen->missions() ) {
const auto mission = mission::reserve_new( m, -1 );
const auto mission = mission::reserve_new( m, character_id() );
mission->assign( u );
}

Expand Down Expand Up @@ -1838,7 +1838,7 @@ int game::assign_mission_id()
return ret;
}

npc *game::find_npc( int id )
npc *game::find_npc( character_id id )
{
return overmap_buffer.find_npc( id ).get();
}
Expand Down Expand Up @@ -1882,13 +1882,13 @@ void game::record_npc_kill( const npc &p )
npc_kills.push_back( p.get_name() );
}

void game::add_npc_follower( const int &id )
void game::add_npc_follower( const character_id &id )
{
follower_ids.insert( id );
u.follower_ids.insert( id );
}

void game::remove_npc_follower( const int &id )
void game::remove_npc_follower( const character_id &id )
{
follower_ids.erase( id );
u.follower_ids.erase( id );
Expand Down Expand Up @@ -1940,7 +1940,7 @@ void game::validate_camps()
}
}

std::set<int> game::get_follower_list()
std::set<character_id> game::get_follower_list()
{
return follower_ids;
}
Expand Down Expand Up @@ -2715,7 +2715,7 @@ void game::load( const save_t &name )
e->set_owner( g->faction_manager_ptr->get( faction_id( "your_followers" ) ) );
}
// legacy, needs to be here as we access the map.
if( u.getID() == 0 || u.getID() == -1 ) {
if( !u.getID().is_valid() ) {
// player does not have a real id, so assign a new one,
u.setID( assign_npc_id() );
// The vehicle stores the IDs of the boarded players, so update it, too.
Expand Down Expand Up @@ -3755,10 +3755,10 @@ void game::reset_light_level()
}

//Gets the next free ID, also used for player ID's.
int game::assign_npc_id()
character_id game::assign_npc_id()
{
int ret = next_npc_id;
next_npc_id++;
character_id ret = next_npc_id;
++next_npc_id;
return ret;
}

Expand Down Expand Up @@ -4681,7 +4681,7 @@ template std::shared_ptr<monster> game::shared_from<monster>( const monster & );
template std::shared_ptr<npc> game::shared_from<npc>( const npc & );

template<typename T>
T *game::critter_by_id( const int id )
T *game::critter_by_id( const character_id id )
{
if( id == u.getID() ) {
// player is always alive, therefore no is-dead check
Expand All @@ -4691,9 +4691,9 @@ T *game::critter_by_id( const int id )
}

// monsters don't have ids
template player *game::critter_by_id<player>( int );
template npc *game::critter_by_id<npc>( int );
template Creature *game::critter_by_id<Creature>( int );
template player *game::critter_by_id<player>( character_id );
template npc *game::critter_by_id<npc>( character_id );
template Creature *game::critter_by_id<Creature>( character_id );

monster *game::summon_mon( const mtype_id &id, const tripoint &p )
{
Expand Down
Loading