Skip to content

Commit

Permalink
Version 0.6.0
Browse files Browse the repository at this point in the history
Added:
Walls now defined in Battle Rules files
Friendly fire is optional among teams
Debug mode now works
  • Loading branch information
OneLoneCoder committed Jul 3, 2018
1 parent 0c330c3 commit a5626aa
Show file tree
Hide file tree
Showing 17 changed files with 190 additions and 49 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ VS2018_BUILD_CGE/BuildOutputs
VS2018_BUILD_CGE/Debug
VS2018_BUILD_CGE/Release
*.user
*.zip
112 changes: 88 additions & 24 deletions Core/BattleRoyale_Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,35 +87,71 @@ void OneLoneCoder_BattleRoyale::Update(float fElapsedTime)
if (bullet.x<0.0f || bullet.x > 200.0f || bullet.y <0.0f || bullet.y > 200.0f)
bullet.bDead = true;

// Taken from Programming Balls #2 video Bullets Vs Walls
for (auto wall : vecWalls)
{
// Check that line formed by velocity vector, intersects with line segment
float fLineX1 = wall.ex - wall.sx;
float fLineY1 = wall.ey - wall.sy;

float fLineX2 = bullet.x - wall.sx;
float fLineY2 = bullet.y - wall.sy;

float fEdgeLength = fLineX1 * fLineX1 + fLineY1 * fLineY1;

// This is nifty - It uses the DP of the line segment vs the line to the object, to work out
// how much of the segment is in the "shadow" of the object vector. The min and max clamp
// this to lie between 0 and the line segment length, which is then normalised. We can
// use this to calculate the closest point on the line segment
float t = std::max(0.0f, std::min(fEdgeLength, (fLineX1 * fLineX2 + fLineY1 * fLineY2))) / fEdgeLength;

// Which we do here
float fClosestPointX = wall.sx + t * fLineX1;
float fClosestPointY = wall.sy + t * fLineY1;

// And once we know the closest point, we can check if the ball has collided with the segment in the
// same way we check if two balls have collided
float fDistance = sqrtf((bullet.x - fClosestPointX)*(bullet.x - fClosestPointX) + (bullet.y - fClosestPointY)*(bullet.y - fClosestPointY));

if (fDistance <= 1.0f)
{
bullet.bDead = true;
}
}

// Has bullet hit a robot?
for (auto &robot : vecRobots)
{
{
// Ignore if bullet was fired by owner of bullet (can't shoot yourself!)
if (bullet.owner != robot->status.id)
{
// Ignore if robot has shields raised
if (!robot->status.shielded)
{
if (powf(bullet.x - robot->status.posx, 2.0f) + powf(bullet.y - robot->status.posy, 2.0f) <= 16.0f)
if (powf(bullet.x - robot->status.posx, 2.0f) + powf(bullet.y - robot->status.posy, 2.0f) <= powf(BattleRoyale_Parameters::fCollisionRadius, 2.0f))
{
// Bullet has hit robot
robot->muxUpdatingSensors.lock();
if (robot->status.health > 0)
// If friendly fire is not allowed, and robots are on same team then ignore
if (robot->status.team != bullet.team || BattleRoyale_Parameters::bAllowFriendlyFire)
{
robot->status.health -= BattleRoyale_Parameters::nBulletDamage;
if (robot->status.health <= 0)
// Bullet has hit robot
robot->muxUpdatingSensors.lock();
if (robot->status.health > 0)
{
robot->status.health = 0;
listAnnouncements.push_back({ robot->status.id, sAnnouncement::ANNOUNCE_ELIMINATION });
robot->status.health -= BattleRoyale_Parameters::nBulletDamage;
if (robot->status.health <= 0)
{
robot->status.health = 0;
listAnnouncements.push_back({ robot->status.id, sAnnouncement::ANNOUNCE_ELIMINATION });
}
}
}
robot->muxUpdatingSensors.unlock();
robot->muxUpdatingSensors.unlock();

// Kill Bullet
bullet.bDead = true;
// Kill Bullet
bullet.bDead = true;
}
}
}
}
}
}
}

Expand Down Expand Up @@ -181,7 +217,7 @@ void OneLoneCoder_BattleRoyale::Update(float fElapsedTime)
robot->wall.e = std::min(robot->wall.e, d);
}

// Check for enemy proximity
// Check for enemy proximity, first set to maximum range
robot->enemy.n = 2000.0f;
robot->enemy.s = 2000.0f;
robot->enemy.w = 2000.0f;
Expand Down Expand Up @@ -241,16 +277,44 @@ void OneLoneCoder_BattleRoyale::Update(float fElapsedTime)
// Update the robots mechanics
robot->UpdateStateMachine(fElapsedTime, this);

// Collision Handle
if (robot->status.posx < 0.0f) robot->status.posx = 0.5f;
if (robot->status.posx >= nArenaWidth) robot->status.posx = (float)nArenaWidth - 0.5f;
if (robot->status.posy < 0.0f) robot->status.posy = 0.5f;
if (robot->status.posy >= nArenaHeight) robot->status.posy = (float)nArenaHeight - 0.5f;
// Collision Handle Robot Vs Wall

// Taken from Programming Balls #2 video
for (auto wall : vecWalls)
{
// Check that line formed by velocity vector, intersects with line segment
float fLineX1 = wall.ex - wall.sx;
float fLineY1 = wall.ey - wall.sy;

float fLineX2 = robot->status.posx - wall.sx;
float fLineY2 = robot->status.posy - wall.sy;

float fEdgeLength = fLineX1 * fLineX1 + fLineY1 * fLineY1;

// This is nifty - It uses the DP of the line segment vs the line to the object, to work out
// how much of the segment is in the "shadow" of the object vector. The min and max clamp
// this to lie between 0 and the line segment length, which is then normalised. We can
// use this to calculate the closest point on the line segment
float t = std::max(0.0f, std::min(fEdgeLength, (fLineX1 * fLineX2 + fLineY1 * fLineY2))) / fEdgeLength;

//DrawLine(robot->status.posx, robot->status.posy, robot->wall.n * cosf(robot->status.angle) + robot->status.posx, robot->wall.n * sinf(robot->status.angle) + robot->status.posy, PIXEL_SOLID, FG_RED);
//DrawLine(robot->status.posx, robot->status.posy, robot->wall.s * cosf(robot->status.angle + 3.14159f) + robot->status.posx, robot->wall.s * sinf(robot->status.angle + 3.14159f) + robot->status.posy, PIXEL_SOLID, FG_RED);
//DrawLine(robot->status.posx, robot->status.posy, robot->wall.w * cosf(robot->status.angle - (3.14159f / 2.0f)) + robot->status.posx, robot->wall.w * sinf(robot->status.angle - (3.14159f / 2.0f)) + robot->status.posy, PIXEL_SOLID, FG_RED);
//DrawLine(robot->status.posx, robot->status.posy, robot->wall.e * cosf(robot->status.angle + (3.14159f / 2.0f)) + robot->status.posx, robot->wall.e * sinf(robot->status.angle + (3.14159f / 2.0f)) + robot->status.posy, PIXEL_SOLID, FG_RED);
// Which we do here
float fClosestPointX = wall.sx + t * fLineX1;
float fClosestPointY = wall.sy + t * fLineY1;

// And once we know the closest point, we can check if the ball has collided with the segment in the
// same way we check if two balls have collided
float fDistance = sqrtf((robot->status.posx - fClosestPointX)*(robot->status.posx - fClosestPointX) + (robot->status.posy - fClosestPointY)*(robot->status.posy - fClosestPointY));

if (fDistance <= (robot->status.radius))
{
// Calculate displacement required
float fOverlap = -0.5f * (robot->status.radius);

// Displace Current Ball away from collision
robot->status.posx -= fOverlap * (robot->status.posx - fClosestPointX) / fDistance;
robot->status.posy -= fOverlap * (robot->status.posy - fClosestPointY) / fDistance;
}
}
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions Core/BattleRoyale_Parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ int BattleRoyale_Parameters::nBulletDamage = 1;
float BattleRoyale_Parameters::fBulletSpeed = 100.0f;
int BattleRoyale_Parameters::nSelfDestructBullets = 10;
int BattleRoyale_Parameters::nBattleMode = 1;
float BattleRoyale_Parameters::fCollisionRadius = 4.0f;
bool BattleRoyale_Parameters::bAllowFriendlyFire = false;

std::vector<std::pair<int, std::string>> BattleRoyale_Parameters::vecRobots;
std::vector<std::string> BattleRoyale_Parameters::vecTeamNames;
std::vector<std::tuple<float, float, float, float>> BattleRoyale_Parameters::vecWalls;


BattleRoyale_Parameters::BattleRoyale_Parameters()
Expand Down Expand Up @@ -90,6 +94,14 @@ bool BattleRoyale_Parameters::LoadParameters(std::string sFile)
lua_getglobal(L, "SelfDestructBullets");
if (lua_isinteger(L, -1)) BattleRoyale_Parameters::nSelfDestructBullets = (int)lua_tointeger(L, -1);

lua_getglobal(L, "RobotHitRadius");
if (lua_isnumber(L, -1)) BattleRoyale_Parameters::fCollisionRadius = (float)lua_tonumber(L, -1);

lua_getglobal(L, "AllowFriendlyFire");
if (lua_isboolean(L, -1)) BattleRoyale_Parameters::bAllowFriendlyFire = (bool)lua_toboolean(L, -1);


// Read in teams
lua_getglobal(L, "Teams"); // -1 Table "Teams"
if (lua_istable(L, -1))
{
Expand All @@ -114,6 +126,32 @@ bool BattleRoyale_Parameters::LoadParameters(std::string sFile)
}
}

// Read in walls
lua_getglobal(L, "Walls"); // -1 Table "Teams"
if (lua_istable(L, -1))
{
lua_pushnil(L); // -2 Key Nil : -1 Table "Teams"

while (lua_next(L, -2) != 0) // -1 Table : -2 Key "TeamName" : -3 Table "Teams"
{
if (lua_istable(L, -1))
{
lua_gettable(L, -1); // -1 Table : -2 Table Value : -3 Key "TeamName" : -4 Table "Teams"
lua_pushnil(L); // -1 Key Nil : -2 Table : -3 Table Value : -4 Key "TeamName" : -5 Table "Teams"
float f[4];
int i = 0;
while (lua_next(L, -2) != 0) // -1 Value "BotFile" : -2 Key Nil : -3 Table : -4 Table Value : -5 Key "TeamName" : -6 Table "Teams"
{
f[i] = (float)lua_tonumber(L, -1);
i++;
lua_pop(L, 1); // -1 Key Nil : -2 Table : -3 Table Value : -4 Key "TeamName" : -5 Table "Teams"
}

vecWalls.push_back({ f[0], f[1], f[2], f[3] });
}
lua_pop(L, 1); // -1 Table : -2 Table Value : -3 Key "TeamName" : -4 Table "Teams"
}
}

return true;
}
4 changes: 4 additions & 0 deletions Core/BattleRoyale_Parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <atomic>
#include <condition_variable>
#include <cmath>
#include <tuple>

extern "C"
{
Expand Down Expand Up @@ -40,10 +41,13 @@ class BattleRoyale_Parameters
static int nBulletDamage;
static float fBulletSpeed;
static int nSelfDestructBullets;
static float fCollisionRadius;
static bool bAllowFriendlyFire;


static int nBattleMode;
static std::vector<std::pair<int, std::string>> vecRobots;
static std::vector<std::string> vecTeamNames;
static std::vector<std::tuple<float, float, float, float>> vecWalls;
};

7 changes: 7 additions & 0 deletions Core/BattleRoyale_Robot.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct sBullet
float vx;
float vy;
int owner;
int team;
bool bDead = false;
};

Expand All @@ -105,6 +106,7 @@ class cRobot
bool shielded = false;
bool cloaked = false;
int team = 0;
float radius = BattleRoyale_Parameters::fCollisionRadius;
std::string sDebugOutput;
} status;

Expand Down Expand Up @@ -146,6 +148,11 @@ class cRobot
std::vector<MAP_ENTRY> entries;
} map;

struct SIGNALS
{
bool b[4];
} signals;

enum STATES
{
STATE_WAIT_FOR_COMMAND,
Expand Down
21 changes: 19 additions & 2 deletions Releases/BattleRoyaleRules.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,28 @@ BulletSpeed = 100.0
-- Self Destruct Bullet count
SelfDestructBullets = 10

-- Size of collision circle around bot
RobotHitRadius = 4.0

-- Bots on same team can hurt each other
AllowFriendlyFire = false

-- DO NOT CHANGE ABOVE HERE =======================================

Walls = {
{0, 0, 200, 0},
{0, 0, 0, 200},
{0, 200, 100, 200},
{100, 200, 100, 150},
{100, 150, 150, 100},
{150, 100, 200, 100},
{200, 100, 200, 0}
}



-- Robots can be loaded into teams
Teams = {}
Teams["GoodGuys"] = {"javidbot.lua", "javidbot.lua"}
Teams["BadGuys"] = {"nullbot.lua", "nullbot.lua"}
Teams["GoodGuys"] = {"javidbot.lua", "javidbot.lua", "nullbot.lua", "nullbot.lua"}
Teams["BadGuys"] = {"nullbot.lua", "nullbot.lua", "brankbot.lua", "brankbot.lua"}

Binary file modified Releases/olcBattleRoyale_CGE_Big.exe
Binary file not shown.
Binary file modified Releases/olcBattleRoyale_CGE_GL_Big.exe
Binary file not shown.
Binary file modified Releases/olcBattleRoyale_CGE_RasterFont.exe
Binary file not shown.
Binary file modified Releases/olcBattleRoyale_CGE_Small.exe
Binary file not shown.
2 changes: 1 addition & 1 deletion Releases/robots/JavidBot.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function Update()
i = 0
while i < count and me.team == map[i].team do
i = i + 1
end
end

if battle.enemies > 0 then
TurnToAngle(math.atan2(map[i].y-me.y, map[i].x-me.x))
Expand Down
6 changes: 3 additions & 3 deletions Releases/robots/NullBot.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ function Update()
end


me = GetStatus()
if me.health < 3 then
--me = GetStatus()
--if me.health < 3 then
-- SelfDestruct()
end
--end
end
4 changes: 3 additions & 1 deletion VS2018_BUILD_CGE/BattleRoyale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ int main(int argc, char** argv)
}
}
else
brp.LoadParameters("BattleRoyaleRules.lua");
{
if(!brp.LoadParameters("BattleRoyaleRules.lua")) return -1;
}

// Launch Simulation
OneLoneCoder_BattleRoyaleConsole demo;
Expand Down
28 changes: 10 additions & 18 deletions VS2018_BUILD_CGE/BattleRoyale_Console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ bool OneLoneCoder_BattleRoyaleConsole::OnUserCreate()
// STEP 1) Configure Battle Engine Parameters
// This needs to be performed before any robots are loaded
// into the OLCBRE
engine.AddWall(0.0f, 0.0f, 200.0f, 0.0f);
engine.AddWall(0.0f, 200.0f, 200.0f, 200.0f);
engine.AddWall(0.0f, 0.0f, 0.0f, 200.0f);
engine.AddWall(200.0f, 0.0f, 200.0f, 200.0f);

// Add walls to arena
for (auto w : BattleRoyale_Parameters::vecWalls)
engine.AddWall(std::get<0>(w), std::get<1>(w), std::get<2>(w), std::get<3>(w));


// These are just console only graphics resources
sprFont = new olcSprite(L"assets/javidx9_nesfont8x8.spr");
Expand Down Expand Up @@ -85,18 +86,6 @@ bool OneLoneCoder_BattleRoyaleConsole::OnUserUpdate(float fElapsedTime)
{
if (!engine.IsBattleStarted())
{
/*ifstream data("battle.txt", ios::in | ios::binary);
vector<string> botFiles;
if (data.is_open())
{
while (!data.eof() && botFiles.size() < 8)
{
string s;
data >> s;
botFiles.push_back(s);
}
}*/

// Robots to load will be defined in BattlRoyale_Parameters
for (auto &s : BattleRoyale_Parameters::vecRobots)
{
Expand Down Expand Up @@ -167,8 +156,11 @@ bool OneLoneCoder_BattleRoyaleConsole::OnUserUpdate(float fElapsedTime)
else
{
DrawWireFrameModel(vecRobotModel, robot->status.posx, robot->status.posy, (float)rand(), 3.0f, robot->status.nColour, PIXEL_SOLID);
bDisplayError = true;
sErrorMessage = robot->status.sDebugOutput;
if (BattleRoyale_Parameters::bDebugMode)
{
bDisplayError = true;
sErrorMessage = robot->status.sDebugOutput;
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions VS2018_BUILD_CGE/olcBattleRoyale.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.27130.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "olcBattleRoyale", "olcBattleRoyale.vcxproj", "{57B3E944-D224-4D2A-92F9-674070570C12}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DF0EC50A-4AEB-4EC0-A9D2-9DEBF126E1A8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Expand Down
Loading

0 comments on commit a5626aa

Please sign in to comment.