Change unit Attack behaviour to a charge
All charges on a turn are evaluated at the same time, step by step
This commit is contained in:
parent
4b37246e53
commit
3fc1f5ee5d
4 changed files with 156 additions and 59 deletions
|
@ -108,14 +108,12 @@ int CTTRTSGame::VerifyPos(uvector2 vec) const
|
||||||
// Get a units new position
|
// Get a units new position
|
||||||
uvector2 CTTRTSGame::GetNewPosition( const OrderUnitPair& pair ) const
|
uvector2 CTTRTSGame::GetNewPosition( const OrderUnitPair& pair ) const
|
||||||
{
|
{
|
||||||
|
|
||||||
// Grab the order
|
// Grab the order
|
||||||
switch ( pair.order.command)
|
switch ( pair.order.command)
|
||||||
{
|
{
|
||||||
// For forward orders, grab in front
|
// For forward orders, grab in front
|
||||||
case command_c::F:
|
case command_c::F:
|
||||||
return pair.unit.getInFront();
|
return pair.unit.getInFront();
|
||||||
break;
|
|
||||||
// For all other orders, just grab the old position
|
// For all other orders, just grab the old position
|
||||||
default:
|
default:
|
||||||
return pair.unit.getPos();
|
return pair.unit.getPos();
|
||||||
|
@ -158,7 +156,6 @@ int CTTRTSGame::SimulateToNextTurn()
|
||||||
if ( possible )
|
if ( possible )
|
||||||
{
|
{
|
||||||
pair.unit.setPos(newpos);
|
pair.unit.setPos(newpos);
|
||||||
pair.order = COrder();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -167,60 +164,115 @@ int CTTRTSGame::SimulateToNextTurn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vector of units to kill
|
// Turn all units that need turning
|
||||||
std::vector< unit_id_t > toKill;
|
|
||||||
|
|
||||||
// Attempt all actions
|
|
||||||
for ( OrderUnitPair& pair : m_OrderUnitPairs )
|
for ( OrderUnitPair& pair : m_OrderUnitPairs )
|
||||||
{
|
{
|
||||||
switch ( pair.order.command)
|
switch ( pair.order.command)
|
||||||
{
|
{
|
||||||
case command_c::A:
|
case command_c::L:
|
||||||
{
|
|
||||||
// Verify that there's a unit in front to attack
|
|
||||||
uvector2 infront = pair.unit.getInFront();
|
|
||||||
|
|
||||||
// Check if there's any unit in front
|
|
||||||
// FRIENDLY FIRE IS ENABLED
|
|
||||||
for ( const OrderUnitPair& pair2 : m_OrderUnitPairs )
|
|
||||||
{
|
|
||||||
// if the unit is infront of our unit, then add it to the kill list
|
|
||||||
if( pair2.unit.getPos() == infront )
|
|
||||||
{
|
|
||||||
toKill.push_back(pair2.unit.getID());
|
|
||||||
pair.order = COrder();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case command_c::L:
|
|
||||||
{
|
{
|
||||||
// Simply turn left
|
// Simply turn left
|
||||||
pair.unit.turnLeft();
|
pair.unit.turnLeft();
|
||||||
pair.order = COrder();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case command_c::R:
|
case command_c::R:
|
||||||
{
|
{
|
||||||
// Simply turn right
|
// Simply turn right
|
||||||
pair.unit.turnRight();
|
pair.unit.turnRight();
|
||||||
pair.order = COrder();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort and erase all duplicates
|
// Iterate through all charge states
|
||||||
std::sort( toKill.begin(), toKill.end() );
|
bool charging = true;
|
||||||
toKill.erase( std::unique( toKill.begin(), toKill.end() ), toKill.end() );
|
while(charging)
|
||||||
|
{
|
||||||
// Iterate through all kill orders
|
// Assume no more charging
|
||||||
for ( auto id : toKill )
|
charging = false;
|
||||||
|
// Initially move all units
|
||||||
|
for ( OrderUnitPair& pair : m_OrderUnitPairs )
|
||||||
|
{
|
||||||
|
if ( pair.order.command == command_c::A )
|
||||||
|
{
|
||||||
|
uvector2 newpos = pair.unit.getInFront();
|
||||||
|
// If move would be within the arena
|
||||||
|
if ( ( newpos.x <= dimensions.x-1 ) && ( newpos.y <= dimensions.y-1 ) )
|
||||||
|
{
|
||||||
|
pair.unit.setPos(newpos);
|
||||||
|
|
||||||
|
// Unit moved, so more charging needs to be done
|
||||||
|
charging = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector< unit_id_t > toKill; // Vector to store which units to kill
|
||||||
|
|
||||||
|
// Initially move all units to check for pass through
|
||||||
|
for ( OrderUnitPair& pair1 : m_OrderUnitPairs )
|
||||||
|
if ( pair1.order.command == command_c::A )
|
||||||
|
for ( OrderUnitPair& pair2 : m_OrderUnitPairs )
|
||||||
|
if ( pair1.unit.getID() != pair2.unit.getID() // Don't check the same units
|
||||||
|
&& pair2.order.command == command_c::A )
|
||||||
|
{
|
||||||
|
if( CheckForPassThrough(pair1.unit,pair2.unit) )
|
||||||
|
{
|
||||||
|
toKill.push_back(pair1.unit.getID());
|
||||||
|
toKill.push_back(pair2.unit.getID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kill all units to kill
|
||||||
|
KillAll(toKill);
|
||||||
|
toKill.clear();
|
||||||
|
|
||||||
|
// Check for all matching spots
|
||||||
|
for ( OrderUnitPair& pair1 : m_OrderUnitPairs )
|
||||||
|
for ( OrderUnitPair& pair2 : m_OrderUnitPairs )
|
||||||
|
{
|
||||||
|
if( pair1.unit.getID() == pair2.unit.getID() ) continue; // Don't check the same units
|
||||||
|
|
||||||
|
if( pair1.unit.getPos() == pair2.unit.getPos() )
|
||||||
|
{
|
||||||
|
if( pair1.order.command == command_c::A )
|
||||||
|
{
|
||||||
|
toKill.push_back(pair2.unit.getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pair2.order.command == command_c::A )
|
||||||
|
{
|
||||||
|
toKill.push_back(pair1.unit.getID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kill all units to kill
|
||||||
|
KillAll(toKill);
|
||||||
|
toKill.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear all orders
|
||||||
|
for ( OrderUnitPair& pair : m_OrderUnitPairs )
|
||||||
|
pair.order = COrder();
|
||||||
|
|
||||||
|
// Increment the current turn
|
||||||
|
turn++;
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Kill all units in list
|
||||||
|
void CTTRTSGame::KillAll( std::vector< unit_id_t >& vec )
|
||||||
|
{
|
||||||
|
// Sort and erase all duplicates
|
||||||
|
std::sort( vec.begin(), vec.end() );
|
||||||
|
vec.erase( std::unique( vec.begin(), vec.end() ), vec.end() );
|
||||||
|
for ( auto id : vec )
|
||||||
{
|
{
|
||||||
// Kill the units
|
|
||||||
for ( OrderUnitPairVector::iterator it = m_OrderUnitPairs.begin();
|
for ( OrderUnitPairVector::iterator it = m_OrderUnitPairs.begin();
|
||||||
it != m_OrderUnitPairs.end();
|
it != m_OrderUnitPairs.end();
|
||||||
it++ )
|
it++ )
|
||||||
|
@ -230,21 +282,42 @@ int CTTRTSGame::SimulateToNextTurn()
|
||||||
// Remove the unit from our alive unit pairs
|
// Remove the unit from our alive unit pairs
|
||||||
m_OrderUnitPairs.erase(it);
|
m_OrderUnitPairs.erase(it);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if two units passed through each other
|
||||||
|
bool CTTRTSGame::CheckForPassThrough( const CUnit& one, const CUnit& two )
|
||||||
|
{
|
||||||
|
uvector2 pos1 = one.getPos();
|
||||||
|
uvector2 pos2 = two.getPos();
|
||||||
|
dir_t dir1 = one.getDir();
|
||||||
|
dir_t dir2 = two.getDir();
|
||||||
|
|
||||||
|
if( pos1.x == pos2.x ) { // Same col
|
||||||
|
if (pos1.y == (pos2.y + 1)) {
|
||||||
|
if (dir1 == dir_t::N && dir2 == dir_t::S)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (pos1.y == (pos2.y - 1)) {
|
||||||
|
if (dir1 == dir_t::S && dir2 == dir_t::N)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( pos1.y == pos2.y ) { // Same row
|
||||||
|
if( pos1.x == (pos2.x+1) ) {
|
||||||
|
if( dir1 == dir_t::E && dir2 == dir_t::W )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if( pos1.x == (pos2.x-1) ) {
|
||||||
|
if( dir1 == dir_t::E && dir2 == dir_t::W )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all orders
|
return false;
|
||||||
for ( OrderUnitPair& pair : m_OrderUnitPairs )
|
|
||||||
{
|
|
||||||
pair.order = COrder();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment the current turn
|
|
||||||
turn++;
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a unit, nonzero return value indicates error
|
// Add a unit, nonzero return value indicates error
|
||||||
|
@ -301,7 +374,8 @@ int CTTRTSGame::VerifyOrder( Team team, const COrder& order ) const
|
||||||
for ( const OrderUnitPair& pair : m_OrderUnitPairs )
|
for ( const OrderUnitPair& pair : m_OrderUnitPairs )
|
||||||
{
|
{
|
||||||
// Accept if we have the unit
|
// Accept if we have the unit
|
||||||
if ( pair.unit.getID() == unitID )
|
if ( pair.unit.getID() == unitID
|
||||||
|
&& pair.unit.getTeam() == team )
|
||||||
{
|
{
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -318,7 +392,7 @@ const CUnit& CTTRTSGame::GetUnitByIDConst( unit_id_t id ) const
|
||||||
for ( const OrderUnitPair& pair : m_OrderUnitPairs )
|
for ( const OrderUnitPair& pair : m_OrderUnitPairs )
|
||||||
{
|
{
|
||||||
// Attempt the unit add
|
// Attempt the unit add
|
||||||
if ( pair.unit.getID() )
|
if ( pair.unit.getID() == id )
|
||||||
return pair.unit;
|
return pair.unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,13 +401,28 @@ const CUnit& CTTRTSGame::GetUnitByIDConst( unit_id_t id ) const
|
||||||
return invalid_unit;
|
return invalid_unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get an order by unit ID
|
||||||
|
const COrder& CTTRTSGame::GetOrderByIDConst( unit_id_t id ) const
|
||||||
|
{
|
||||||
|
for ( const OrderUnitPair& pair : m_OrderUnitPairs )
|
||||||
|
{
|
||||||
|
// Attempt the unit add
|
||||||
|
if ( pair.unit.getID() == id )
|
||||||
|
return pair.order;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return an invalid unit
|
||||||
|
static COrder invalid_order;
|
||||||
|
return invalid_order;
|
||||||
|
}
|
||||||
|
|
||||||
// Get unit by unit ID
|
// Get unit by unit ID
|
||||||
CUnit& CTTRTSGame::GetUnitByID( unit_id_t id )
|
CUnit& CTTRTSGame::GetUnitByID( unit_id_t id )
|
||||||
{
|
{
|
||||||
for ( OrderUnitPair& pair : m_OrderUnitPairs )
|
for ( OrderUnitPair& pair : m_OrderUnitPairs )
|
||||||
{
|
{
|
||||||
// Attempt the unit add
|
// Attempt the unit add
|
||||||
if ( pair.unit.getID() )
|
if ( pair.unit.getID() == id )
|
||||||
return pair.unit;
|
return pair.unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ public:
|
||||||
|
|
||||||
// Get a unit by it's ID
|
// Get a unit by it's ID
|
||||||
const CUnit& GetUnitByIDConst( unit_id_t id ) const;
|
const CUnit& GetUnitByIDConst( unit_id_t id ) const;
|
||||||
|
const COrder& GetOrderByIDConst( unit_id_t id ) const;
|
||||||
|
|
||||||
// Get dimensions
|
// Get dimensions
|
||||||
inline const uvector2 &GetDimensions() const { return dimensions; }
|
inline const uvector2 &GetDimensions() const { return dimensions; }
|
||||||
|
@ -100,7 +101,7 @@ public:
|
||||||
|
|
||||||
// Get a vector of the teams in the current game
|
// Get a vector of the teams in the current game
|
||||||
std::vector<Team> GetTeams() const;
|
std::vector<Team> GetTeams() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Verify any order or position - non-zero is error
|
// Verify any order or position - non-zero is error
|
||||||
|
@ -110,6 +111,12 @@ private:
|
||||||
// Get a units new position after an order
|
// Get a units new position after an order
|
||||||
uvector2 GetNewPosition( const OrderUnitPair& pair ) const;
|
uvector2 GetNewPosition( const OrderUnitPair& pair ) const;
|
||||||
|
|
||||||
|
// Check for a pass through
|
||||||
|
static bool CheckForPassThrough( const CUnit& one, const CUnit& two );
|
||||||
|
|
||||||
|
// Kill all units in list
|
||||||
|
void KillAll( std::vector< unit_id_t >& vec );
|
||||||
|
|
||||||
// Get unit by unit ID
|
// Get unit by unit ID
|
||||||
CUnit& GetUnitByID( unit_id_t id );
|
CUnit& GetUnitByID( unit_id_t id );
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
// Type for all orders ( as a char )
|
// Type for all orders ( as a char )
|
||||||
enum class command_c : char
|
enum class command_c : char
|
||||||
{
|
{
|
||||||
F = 'F',
|
F = 'F', // Move forward one square
|
||||||
L = 'L',
|
L = 'L', // Turn left
|
||||||
R = 'R',
|
R = 'R', // Turn right
|
||||||
A = 'A',
|
A = 'A', // Attack forwards until a unit or edge of the arena is hit
|
||||||
NUM_INVALID
|
NUM_INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,7 @@ private:
|
||||||
|
|
||||||
// Typedef for a vector of units
|
// Typedef for a vector of units
|
||||||
typedef std::vector< CUnit > CUnitVector;
|
typedef std::vector< CUnit > CUnitVector;
|
||||||
|
typedef std::vector< unit_id_t > CUnitIDVector;
|
||||||
|
|
||||||
// Simple validation
|
// Simple validation
|
||||||
inline bool CUnit::valid() const
|
inline bool CUnit::valid() const
|
||||||
|
|
Loading…
Add table
Reference in a new issue