#include #include "unit.h" #include // for std::map namespace { // Helper function for generating unique unit ids during static init unit_id_t get_unique_unit_id(unit_id_t* set = nullptr) { static unit_id_t p = 0; // If we have a set value, then set our int if( set ) p = *set; return p++; } // Map of visual representation of unit V typedef std::map< dir_t, unitVis_c > dir_to_vis_map; // Helper function to get the vis map during static init const dir_to_vis_map& get_vis_map_V() { static const dir_to_vis_map sk_visMap = { {dir_t::N,'^'}, {dir_t::E,'>'}, {dir_t::S,'v'}, {dir_t::W,'<'}, }; return sk_visMap; } } // force a reset of the unit ID value void forceResetUnitId() { unit_id_t i = 0; get_unique_unit_id(&i); } // Get a unit from a visual CUnit CUnit::GetUnitFromVis( unitVis_c vis ) { CUnit unit; unit.setFromVisual(vis); return unit; } // Get a string descriptor of a unit // "U id:[unit_id] team:[team_id] player:[player_id] vis:[unit_vis] dir:[dir] pos:[pos.x],[pos.y]" std::string CUnit::GetStringFromUnit(const CUnit& unit ) { static char buff[128]; memset(buff,0,sizeof(buff)); snprintf(buff,128, UNIT_FORMATTER, unit.unit_id, (int)unit.team_id, unit.unit_vis, unit.dir, unit.pos.x, unit.pos.y ); return buff; } // Get a unit from a string descriptor // "U id:[unit_id] team:[team_id] player:[player_id] vis:[unit_vis] dir:[dir] pos:[pos.x],[pos.y]" CUnit CUnit::GetUnitFromString(const std::string& unit ) { CUnit ret; unsigned int id; int team; char vis; char dir; unsigned int posx; unsigned int posy; sscanf(unit.c_str(), UNIT_FORMATTER, &id, &team, &vis, &dir, &posx, &posy ); ret.unit_id = (unit_id_t)id; ret.team_id = (Team)team; ret.unit_vis = (unitVis_c)vis; ret.dir = (dir_t)dir; ret.pos = uvector2(posx,posy); return ret; } // Plain constructor CUnit::CUnit() : unit_id ( get_unique_unit_id() ) , team_id ( Team::NUM_INVALID ) , unit_vis ( unitVis_invalid ) , dir ( dir_t::S ) , pos ( { ucoord_invalid, ucoord_invalid } ) { updateMyVisual(); } // Move constructor CUnit::CUnit(CUnit&& unit) : unit_id ( std::move(unit.unit_id) ) , team_id ( std::move(unit.team_id) ) , unit_vis ( std::move(unit.unit_vis) ) , dir ( std::move(unit.dir) ) , pos ( std::move(unit.pos) ) { updateMyVisual(); } // Move asignment operator CUnit& CUnit::operator=(CUnit&& unit) { unit_id = std::move(unit.unit_id) ; team_id = std::move(unit.team_id) ; unit_vis = std::move(unit.unit_vis) ; dir = std::move(unit.dir) ; pos = std::move(unit.pos) ; return *this; } // Equals operator bool CUnit::operator==(const CUnit& rhs) { return (unit_id == rhs.unit_id) && (team_id == rhs.team_id) && (unit_vis == rhs.unit_vis) && (dir == rhs.dir) && (pos == rhs.pos); } // Update the visual representation of the unit unitVis_c CUnit::updateMyVisual() { // Start at invalid setVisual(unitVis_invalid); dir_to_vis_map::const_iterator it = get_vis_map_V().find(dir); // If found set to new vis if( it != get_vis_map_V().end() ) setVisual(it->second); return getVisual(); } // Set the unit from visual bool CUnit::setFromVisual( const unitVis_c& vis ) { dir_to_vis_map::const_iterator it; for( it = get_vis_map_V().begin(); it != get_vis_map_V().end(); it++ ) { if( it->second == vis ) { dir = it->first; updateMyVisual(); return true; } } // No matching direction to visual return false; } // Turn unit left dir_t CUnit::turnLeft() { switch( dir ) { case dir_t::N: dir = dir_t::W; break; case dir_t::E: dir = dir_t::N; break; case dir_t::S: dir = dir_t::E; break; case dir_t::W: dir = dir_t::S; break; } updateMyVisual(); return getDir(); } // Turn unit right dir_t CUnit::turnRight() { switch( dir ) { case dir_t::N: dir = dir_t::E; break; case dir_t::E: dir = dir_t::S; break; case dir_t::S: dir = dir_t::W; break; case dir_t::W: dir = dir_t::N; break; } updateMyVisual(); return getDir(); } // Turn unit around dir_t CUnit::turnAround() { switch( dir ) { case dir_t::N: dir = dir_t::S; break; case dir_t::E: dir = dir_t::W; break; case dir_t::S: dir = dir_t::N; break; case dir_t::W: dir = dir_t::E; break; } updateMyVisual(); return getDir(); } // Get the co-ordinate infront of the unit uvector2 CUnit::getInFront() const { vector2 delta = vecFromDir(dir); return pos + delta; }