#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 __forceResetCUnitID() { 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 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.player_id, unit.unit_vis, unit.dir, unit.pos.x, unit.pos.y ); return buff; } // Get a unit from a string descriptor CUnit CUnit::GetUnitFromString(const std::string& unit ) { CUnit ret; unsigned int id; int player; char vis; char dir; unsigned int posx; unsigned int posy; sscanf(unit.c_str(), UNIT_FORMATTER, &id, &player, &vis, &dir, &posx, &posy ); ret.unit_id = (unit_id_t)id; ret.player_id = (Player) player; 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() ) , player_id ( Player::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) ) , player_id ( std::move(unit.player_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) ; player_id = std::move(unit.player_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) && (player_id == rhs.player_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; }