* Modified shadows for Town centre.

* Bugfixes in unit movement and collision detection. Now it should work fine.
* Added include guards to all *.i files.
* Other minor changes
This commit is contained in:
XaviDCR92 2017-11-05 05:38:31 +01:00
parent 2cf2d608af
commit 8fba2176bc
18 changed files with 2163 additions and 1995 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

11
Gfx.cpp
View File

@ -146,6 +146,17 @@ void GfxDrawCircle(uint16_t x, uint16_t y, uint8_t radius, int8_t color)
}
}
void GfxDrawFillCircle(uint16_t x, uint16_t y, uint8_t radius, int8_t color)
{
if (GfxIsInsideScreenArea(x, y, radius, radius) == true)
{
int8_t orig_color = gb.display.getColor();
gb.display.setColor(color);
gb.display.fillCircle(x, y, radius);
gb.display.setColor(orig_color);
}
}
void GfxDrawRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, int8_t color)
{
if (GfxIsInsideScreenArea(x, y, w, h) == true)

1
Gfx.h
View File

@ -61,6 +61,7 @@ typedef struct t_Camera TYPE_CAMERA;
void GfxDrawSprite(TYPE_SPRITE* ptrSprite);
void GfxDrawCircle(uint16_t x, uint16_t y, uint8_t radius, int8_t color);
void GfxDrawFillCircle(uint16_t x, uint16_t y, uint8_t radius, int8_t color);
void GfxDrawRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, int8_t color);
void GfxFillRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, int8_t color);
void GfxDrawLine(uint8_t x0, uint8_t x1, uint8_t y0, uint8_t y1, uint8_t color);

View File

@ -1,3 +1,6 @@
#ifndef MOUSE_SPR_I__
#define MOUSE_SPR_I__
const uint8_t PROGMEM MouseSprData[] =
{
8,8, //width and height
@ -11,3 +14,5 @@ const uint8_t PROGMEM MouseSprData[] =
B00000100,
};
#endif // MOUSE_SPR_I__

View File

@ -1,3 +1,6 @@
#ifndef PEASANT_SPR_I__
#define PEASANT_SPR_I__
// Default direction: Down
@ -28,3 +31,5 @@ const uint8_t PROGMEM Peasant_SprData[] =
0x00,
};
#endif // PEASANT_SPR_I__

View File

@ -30,6 +30,13 @@ Player::~Player(void)
void Player::Init(void)
{
enum
{
DEFAULT_WOOD = 1000,
DEFAULT_GOLD = 1000,
DEFAULT_FOOD = 1000
};
uint8_t i;
unit_i = 0;
@ -46,17 +53,14 @@ void Player::Init(void)
TYPE_COLLISION_BLOCK cb;
Resources.Wood = 25;
Resources.Gold = 50;
Resources.Food = 75;
Resources.Wood = DEFAULT_WOOD;
Resources.Gold = DEFAULT_GOLD;
Resources.Food = DEFAULT_FOOD;
cb.x = SystemRand(0, 20);
cb.y = SystemRand(0, 20);
cb.x = SystemRand(0, 24);
cb.y = SystemRand(0, 24);
if (createUnit(TOWN_CENTER, cb) == false)
{
GfxPrintText_Flash(F("Failed to create building!"));
}
createUnit(TOWN_CENTER, cb);
cb.x = SystemRand(48, 56);
cb.y = SystemRand(48, 56);
@ -68,10 +72,7 @@ void Player::Init(void)
showActionsMenu = false;
anyUnitSelected = false;
if (createUnit(PEASANT, cb) == false)
{
GfxPrintText_Flash(F("Failed to create unit!"));
}
createUnit(PEASANT, cb);
}
void Player::showHealth(uint8_t hp)
@ -152,8 +153,8 @@ void Player::ShowResources(void)
{
char str[16];
gb.display.setColor(GFX_WHITE);
gb.display.fillRect(0, 0, X_SCREEN_RESOLUTION, 5);
gb.display.setColor(GFX_GRAY);
gb.display.fillRect(0, 0, X_SCREEN_RESOLUTION, 8);
snprintf(str, sizeof(str), "W=%d", Resources.Wood);
@ -161,11 +162,15 @@ void Player::ShowResources(void)
snprintf(str, sizeof(str), "G=%d", Resources.Gold);
GfxPrintTextFont(str, font3x3, 22, 1);
GfxPrintTextFont(str, font3x3, 2, 5);
snprintf(str, sizeof(str), "F=%d", Resources.Food);
GfxPrintTextFont(str, font3x3, 42, 1);
snprintf(str, sizeof(str), "%d/%d", unit_i, PLAYER_MAX_UNITS_BUILDINGS);
GfxPrintTextFont(str, font3x3, 42, 5);
}
@ -191,7 +196,7 @@ bool Player::checkNewBuildingPosition(TYPE_COLLISION_BLOCK * cb)
bldgCB.w = UnitGetWidthFromID(ptrUnit->id);
bldgCB.h = UnitGetHeightFromID(ptrUnit->id);
if (SystemCollisionCheck(*cb, bldgCB) == true)
if (SystemCollisionCheck(cb, &bldgCB) == true)
{
success = false;
}
@ -227,29 +232,48 @@ bool Player::checkNewBuildingPosition(TYPE_COLLISION_BLOCK * cb)
return true;
}
bool Player::createUnit(TYPE_UNIT_ID id, TYPE_COLLISION_BLOCK cb)
void Player::createUnit(TYPE_UNIT_ID id, TYPE_COLLISION_BLOCK cb)
{
TYPE_RESOURCES res = UnitNeededResourcesFromID(id);
if ( (Resources.Food < res.Food)
||
(Resources.Wood < res.Wood)
||
(Resources.Gold < res.Gold) )
{
GfxPrintText_Flash(F("Insuff. resources"));
return;
}
if (unit_i < PLAYER_MAX_UNITS_BUILDINGS)
{
TYPE_UNIT* ptrNewUnit = &units[unit_i];
TYPE_UNIT* ptrNewUnit = &units[unit_i++];
ptrNewUnit->id = id;
ptrNewUnit->x = cb.x;
ptrNewUnit->y = cb.y;
ptrNewUnit->hp = UnitGetHpFromID(id);
ptrNewUnit->alive = true;
ptrNewUnit->building = (id > MAX_UNIT_ID);
unit_i++;
/* Substract resources from player */
Resources.Wood -= res.Wood;
Resources.Gold -= res.Gold;
Resources.Food -= res.Food;
return true;
if (ptrNewUnit->building == true)
{
GfxPrintText_Flash(F("Building created"));
}
else
{
GfxPrintText_Flash(F("Unit created"));
}
}
else
{
return false;
GfxPrintText_Flash(F("Popul. limit"));
}
return false;
}
TYPE_COLLISION_BLOCK Player::GetCursorPos(void)
@ -422,10 +446,18 @@ void Player::ButtonAReleased(void)
ActionCreateUnit(ptrUnit, PEASANT);
break;
case ACTION_CREATE_SOLDIER:
ActionCreateUnit(ptrUnit, SOLDIER);
break;
case ACTION_BUILD_BARRACKS:
ActionCreateBuilding(ptrUnit, BARRACKS);
break;
case ACTION_BUILD_TOWER_CENTER:
ActionCreateBuilding(ptrUnit, TOWN_CENTER);
break;
default:
break;
}

View File

@ -13,7 +13,7 @@
* Defines *
* **************************************/
#define PLAYER_NAME_LENGTH 16
#define PLAYER_NAME_LENGTH 16
#define PLAYER_MAX_UNITS_BUILDINGS 32
/* **************************************
@ -22,9 +22,9 @@
typedef struct t_Resource
{
uint8_t Wood;
uint8_t Gold;
uint8_t Food;
uint16_t Wood;
uint16_t Gold;
uint16_t Food;
}TYPE_RESOURCES;
/* **************************************
@ -44,7 +44,7 @@ class Player
char* getName(void) {return name;}
void setHuman(bool value) { human = value; }
bool isHuman(void) {return human;}
bool createUnit(TYPE_UNIT_ID id, TYPE_COLLISION_BLOCK cb);
void createUnit(TYPE_UNIT_ID id, TYPE_COLLISION_BLOCK cb);
uint8_t getPopulation(void) {return (unit_i + 1);}
void ShowResources(void);

26
SoldierSpr.i Normal file
View File

@ -0,0 +1,26 @@
#ifndef UNIT_SPR_I__
#define UNIT_SPR_I__
const uint8_t SoldierSprData[] PROGMEM = {8,8,
0x3C,
0x42,
0x99,
0xBD,
0xFE,
0x58,
0x40,
0x40,
};
const uint8_t SoldierSprData_Walking[] PROGMEM = {8,8,
0xE0,
0xBC,
0xC2,
0x99,
0xBD,
0xFF,
0x5D,
0x47,
};
#endif // UNIT_SPR_I__

BIN
Sprites/SoldierSpr.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -271,8 +271,8 @@ bool SystemArrayCompare(unsigned short * arr1, unsigned short * arr2, size_t sz)
return true;
}
bool SystemCollisionCheck(TYPE_COLLISION_BLOCK c1, TYPE_COLLISION_BLOCK c2)
bool SystemCollisionCheck(TYPE_COLLISION_BLOCK* c1, TYPE_COLLISION_BLOCK* c2)
{
return (bool)check_bb_collision( c1.x, c1.y, c1.w, c1.h,
c2.x, c2.y, c2.w, c2.h );
return (bool)check_bb_collision( c1->x, c1->y, c1->w, c1->h,
c2->x, c2->y, c2->w, c2->h );
}

View File

@ -84,7 +84,7 @@ void SystemTimerRemove(TYPE_TIMER * timer);
// Compares two arrays of unsigned short type.
bool SystemArrayCompare(unsigned short * arr1, unsigned short * arr2, size_t sz);
// Checks collision of two objects
bool SystemCollisionCheck(TYPE_COLLISION_BLOCK c1, TYPE_COLLISION_BLOCK c2);
bool SystemCollisionCheck(TYPE_COLLISION_BLOCK* c1, TYPE_COLLISION_BLOCK* c2);
/* **************************************
* Global Variables *

View File

@ -1,3 +1,6 @@
#ifndef TOWN_CENTRE_I__
#define TOWN_CENTRE_I__
const uint8_t TownCentreSprData[] PROGMEM = {24,24,
0x3,0xFF,0xC0,
0xC,0x0,0x30,
@ -30,24 +33,26 @@ const uint8_t TownCentreShadowSprData[] PROGMEM = {24,24,
0x7E,0x0,0x0,
0xF8,0x0,0x0,
0xF0,0x0,0x0,
0xE0,0x0,0x0,
0xE0,0x0,0x4,
0xE0,0x0,0x4,
0xE0,0x0,0x4,
0xE2,0xE0,0x4,
0xE2,0x80,0x4,
0xE2,0x80,0x4,
0xE2,0x80,0x4,
0xE2,0x80,0x4,
0xE2,0x80,0x4,
0xE2,0xE0,0x4,
0xE0,0x60,0xC,
0xE0,0x0,0x10,
0xE0,0x0,0x0,
0xE0,0x0,0x0,
0xE0,0x1,0x80,
0xF0,0x1,0x80,
0xF8,0x1,0x80,
0x7E,0x1,0x80,
0xF8,0x0,0x0,
0xF8,0x0,0x4,
0xF8,0x0,0x4,
0xF8,0x0,0x4,
0xFA,0xE0,0x4,
0xFA,0x80,0x4,
0xFA,0x80,0x4,
0xFA,0x80,0x4,
0xFA,0x80,0x4,
0xFA,0x80,0x4,
0xFA,0xE0,0x4,
0xF8,0x60,0xC,
0xF8,0x0,0x10,
0xFC,0x0,0x0,
0xFF,0x0,0x0,
0xFF,0xF1,0x80,
0xFF,0xF1,0x80,
0xFF,0xF1,0x80,
0x7F,0xF1,0x80,
0x1F,0x81,0x80,
};
#endif // TOWN_CENTRE_I__

97
Unit.c
View File

@ -3,7 +3,12 @@
* **************************************/
#include "Unit.h"
/* Units sprite data */
#include "PeasantSpr.i"
#include "SoldierSpr.i"
/* Buildings sprite data */
#include "BarracksSpr.i"
#include "TownCentre.i"
@ -30,21 +35,31 @@ struct t_coordinates
* **************************************/
/* Tables */
static uint8_t const UnitHPTable[MAX_UNITS_BUILDINGS] = { [PEASANT] = 25 ,
[BARRACKS] = 100,
[TOWN_CENTER] = 200 };
static uint8_t const UnitHPTable[MAX_UNITS_BUILDINGS] = { [PEASANT] = 25,
[SOLDIER] = 80,
[BARRACKS] = 100,
[TOWN_CENTER] = 200 };
static TYPE_RESOURCES const UnitResourcesTable[MAX_UNITS_BUILDINGS] = { [PEASANT] = {.Wood = 0, .Gold = 0, .Food = 50},
[SOLDIER] = {.Wood = 25, .Gold = 10, .Food = 50},
[BARRACKS] = {.Wood = 100, .Gold = 0, .Food = 0},
[TOWN_CENTER] = {.Wood = 200, .Gold = 0, .Food = 0} };
static uint8_t const UnitSpeedTable[MAX_UNITS_BUILDINGS] = { [PEASANT] = 1,
[BARRACKS] = 0,
[TOWN_CENTER] = 0 };
[SOLDIER] = 1,
[BARRACKS] = 0,
[TOWN_CENTER] = 0 };
static const char* const UnitActionsTable_Level[MAX_ACTIONS] = { [ACTION_BUILD_BARRACKS] = "B.BARR",
[ACTION_ATTACK] = "ATTACK",
[ACTION_CREATE_PEASANT] = "C.PEAS."};
static const char* const UnitActionsTable_Level[MAX_ACTIONS] = { [ACTION_BUILD_BARRACKS] = "B.BARR",
[ACTION_ATTACK] = "ATTACK",
[ACTION_CREATE_PEASANT] = "C.PEAS.",
[ACTION_CREATE_SOLDIER] = "C.SLDR.",
[ACTION_BUILD_TOWER_CENTER] = "C.TWNC."};
static uint8_t const UnitActionsTable[MAX_UNITS_BUILDINGS] = { [PEASANT] = ((1 << ACTION_BUILD_BARRACKS) | (1 << ACTION_ATTACK)),
[BARRACKS] = (1 << ACTION_CREATE_PEASANT),
[TOWN_CENTER] = (1 << ACTION_CREATE_PEASANT) };
static uint8_t const UnitActionsTable[MAX_UNITS_BUILDINGS] = { [PEASANT] = ((1 << ACTION_BUILD_BARRACKS) | (1 << ACTION_BUILD_TOWER_CENTER) | (1 << ACTION_ATTACK)),
[SOLDIER] = (1 << ACTION_ATTACK),
[BARRACKS] = (1 << ACTION_CREATE_SOLDIER),
[TOWN_CENTER] = (1 << ACTION_CREATE_PEASANT) };
// **************
// Sprite tables
@ -56,6 +71,10 @@ static const struct t_coordinates UnitShadowOffsetTable[MAX_BUILDING_ID - FIRST_
void UnitInit(void)
{
/* ***********************************
* Unit sprite data init
* ***********************************/
UnitSprTable[PEASANT].Data = Peasant_SprData;
UnitSprTable[PEASANT].w = GfxGetWidthFromSpriteData(Peasant_SprData);
UnitSprTable[PEASANT].h = GfxGetHeightFromSpriteData(Peasant_SprData);
@ -63,6 +82,13 @@ void UnitInit(void)
UnitSprTable[PEASANT].rotation = 0;
UnitSprTable[PEASANT].color = GFX_BLACK;
UnitSprTable[SOLDIER].Data = SoldierSprData;
UnitSprTable[SOLDIER].w = GfxGetWidthFromSpriteData(SoldierSprData);
UnitSprTable[SOLDIER].h = GfxGetHeightFromSpriteData(SoldierSprData);
UnitSprTable[SOLDIER].flip = 0;
UnitSprTable[SOLDIER].rotation = 0;
UnitSprTable[SOLDIER].color = GFX_BLACK;
UnitWalkingShadowSprTable[PEASANT].Data = Peasant_Walking_SprData;
UnitWalkingShadowSprTable[PEASANT].w = GfxGetWidthFromSpriteData(Peasant_Walking_SprData);
UnitWalkingShadowSprTable[PEASANT].h = GfxGetHeightFromSpriteData(Peasant_Walking_SprData);
@ -70,6 +96,17 @@ void UnitInit(void)
UnitWalkingShadowSprTable[PEASANT].rotation = 0;
UnitWalkingShadowSprTable[PEASANT].color = GFX_BLACK;
UnitWalkingShadowSprTable[SOLDIER].Data = SoldierSprData_Walking;
UnitWalkingShadowSprTable[SOLDIER].w = GfxGetWidthFromSpriteData(SoldierSprData_Walking);
UnitWalkingShadowSprTable[SOLDIER].h = GfxGetHeightFromSpriteData(SoldierSprData_Walking);
UnitWalkingShadowSprTable[SOLDIER].flip = 0;
UnitWalkingShadowSprTable[SOLDIER].rotation = 0;
UnitWalkingShadowSprTable[SOLDIER].color = GFX_BLACK;
/* ***********************************
* Buildings sprite data init
* ***********************************/
UnitSprTable[BARRACKS].Data = BarracksSpr_Data;
UnitSprTable[BARRACKS].w = GfxGetWidthFromSpriteData(BarracksSpr_Data);
UnitSprTable[BARRACKS].h = GfxGetHeightFromSpriteData(BarracksSpr_Data);
@ -213,21 +250,26 @@ void UnitDraw(TYPE_UNIT* ptrUnit, TYPE_CAMERA* ptrCamera, bool bHighlighted)
}
}
uint8_t UnitGetWidthFromID(uint8_t id)
uint8_t UnitGetWidthFromID(TYPE_UNIT_ID id)
{
return GfxGetWidthFromSpriteData(UnitSprTable[id].Data);
}
uint8_t UnitGetHeightFromID(uint8_t id)
uint8_t UnitGetHeightFromID(TYPE_UNIT_ID id)
{
return GfxGetHeightFromSpriteData(UnitSprTable[id].Data);
}
uint8_t UnitGetHpFromID(uint8_t id)
uint8_t UnitGetHpFromID(TYPE_UNIT_ID id)
{
return UnitHPTable[id];
}
TYPE_RESOURCES UnitNeededResourcesFromID(TYPE_UNIT_ID id)
{
return UnitResourcesTable[id];
}
void UnitMoveTo(TYPE_UNIT* ptrUnit, uint16_t x, uint16_t y)
{
ptrUnit->target_x = x;
@ -264,37 +306,28 @@ void UnitHandler(TYPE_UNIT* unitArray, size_t sz)
if ( (ptrUnit->x - UnitSpeedTable[ptrUnit->id]) > ptrUnit->target_x)
{
ptrUnit->dir = DIRECTION_LEFT;
x_d = -UnitSpeedTable[ptrUnit->id];
//~ ptrUnit->x -= UnitSpeedTable[ptrUnit->id];
x_d = (int8_t)-UnitSpeedTable[ptrUnit->id];
}
else if ( (ptrUnit->x + UnitSpeedTable[ptrUnit->id]) < ptrUnit->target_x)
{
ptrUnit->dir = DIRECTION_RIGHT;
x_d = UnitSpeedTable[ptrUnit->id];
//~ ptrUnit->x += UnitSpeedTable[ptrUnit->id];
x_d = (int8_t)UnitSpeedTable[ptrUnit->id];
}
if ( (ptrUnit->y - UnitSpeedTable[ptrUnit->id]) > ptrUnit->target_y)
else if ( (ptrUnit->y - UnitSpeedTable[ptrUnit->id]) > ptrUnit->target_y)
{
ptrUnit->dir = DIRECTION_UP;
y_d = -UnitSpeedTable[ptrUnit->id];
//~ ptrUnit->y -= UnitSpeedTable[ptrUnit->id];
y_d = (int8_t)-UnitSpeedTable[ptrUnit->id];
}
else if ( (ptrUnit->y + UnitSpeedTable[ptrUnit->id]) < ptrUnit->target_y)
{
ptrUnit->dir = DIRECTION_DOWN;
y_d = UnitSpeedTable[ptrUnit->id];
//~ ptrUnit->y += UnitSpeedTable[ptrUnit->id];
y_d = (int8_t)UnitSpeedTable[ptrUnit->id];
}
else
{
x_d = ptrUnit->x - ptrUnit->target_x;
y_d = ptrUnit->y - ptrUnit->target_y;
bMoving = false;
}
ptrUnit->walking = bMoving;
if (ptrUnit->walking == true)
{
// If player is still walking, check collisions
@ -324,18 +357,20 @@ void UnitHandler(TYPE_UNIT* unitArray, size_t sz)
ou.x = ptrOtherUnit->x;
ou.y = ptrOtherUnit->x;
ou.y = ptrOtherUnit->y;
ou.w = UnitGetWidthFromID(ptrOtherUnit->id);
ou.h = UnitGetHeightFromID(ptrOtherUnit->id);
if (SystemCollisionCheck(cu, ou) == true)
if (SystemCollisionCheck(&cu, &ou) == true)
{
ptrUnit->walking = false;
bMoving = false;
break;
}
}
}
ptrUnit->walking = bMoving;
if (ptrUnit->walking == true)
{
// If no collision is detected, keep moving to the new position

64
Unit.h
View File

@ -7,6 +7,7 @@
#include "Global_Inc.h"
#include "Camera.h"
#include "Player.h"
#ifdef __cplusplus
extern "C"
@ -29,29 +30,11 @@ typedef enum t_unitdirection
DIRECTION_DOWN
}UNIT_DIRECTION;
typedef struct t_Unit
{
uint16_t x;
uint16_t y;
uint16_t target_x;
uint16_t target_y;
uint8_t hp;
uint8_t id;
UNIT_DIRECTION dir;
bool mirror; // True = down or left; true = up or right
bool building;
bool walking;
bool alive;
bool selected;
bool selecting_attack;
bool attacking;
uint8_t walk_counter;
}TYPE_UNIT;
typedef enum t_unitid
{
// Walking units
PEASANT = 0,
PEASANT,
SOLDIER,
MAX_UNIT_ID,
@ -68,6 +51,25 @@ typedef enum t_unitid
FIRST_BUILDING_ID = BARRACKS
}TYPE_UNIT_ID;
typedef struct t_Unit
{
uint16_t x;
uint16_t y;
uint16_t target_x;
uint16_t target_y;
uint8_t hp;
TYPE_UNIT_ID id;
UNIT_DIRECTION dir;
bool mirror; // True = down or left; true = up or right
bool building;
bool walking;
bool alive;
bool selected;
bool selecting_attack;
bool attacking;
uint8_t walk_counter;
}TYPE_UNIT;
typedef struct
{
const char* str;
@ -79,32 +81,36 @@ typedef enum t_availableactions
ACTION_BUILD_BARRACKS,
ACTION_ATTACK,
ACTION_CREATE_PEASANT,
ACTION_CREATE_SOLDIER,
ACTION_BUILD_TOWER_CENTER,
MAX_ACTIONS
}UNIT_ACTION;
typedef struct t_Camera TYPE_CAMERA;
typedef struct t_Resource TYPE_RESOURCES;
/* **************************************
* Global prototypes *
* **************************************/
// Initialization and handling
void UnitInit(void);
void UnitHandler(TYPE_UNIT* unitArray, size_t sz);
void UnitInit(void);
void UnitHandler(TYPE_UNIT* unitArray, size_t sz);
// Unit information
uint8_t UnitGetHpFromID(uint8_t id);
uint8_t UnitGetWidthFromID(uint8_t id);
uint8_t UnitGetHeightFromID(uint8_t id);
uint8_t UnitGetAvailableActions(TYPE_UNIT* ptrUnit);
uint8_t UnitGetHpFromID(TYPE_UNIT_ID id);
uint8_t UnitGetWidthFromID(TYPE_UNIT_ID id);
uint8_t UnitGetHeightFromID(TYPE_UNIT_ID id);
uint8_t UnitGetAvailableActions(TYPE_UNIT* ptrUnit);
TYPE_RESOURCES UnitNeededResourcesFromID(TYPE_UNIT_ID id);
// Rendering
void UnitDraw(TYPE_UNIT* ptrUnit, TYPE_CAMERA* ptrCamera, bool bHighlighted);
void UnitDraw(TYPE_UNIT* ptrUnit, TYPE_CAMERA* ptrCamera, bool bHighlighted);
void UnitMoveTo(TYPE_UNIT* ptrUnit, uint16_t x, uint16_t y);
void UnitMoveTo(TYPE_UNIT* ptrUnit, uint16_t x, uint16_t y);
// Selection index
const char* UnitGetActionString(UNIT_ACTION action);
const char* UnitGetActionString(UNIT_ACTION action);
#ifdef __cplusplus
}