293 lines
8.3 KiB
C
293 lines
8.3 KiB
C
/* **************************************
|
|
* Includes *
|
|
* **************************************/
|
|
|
|
#include "Unit.h"
|
|
#include "PeasantSpr.c"
|
|
#include "BarracksSpr.c"
|
|
|
|
/* **************************************
|
|
* Defines *
|
|
* **************************************/
|
|
|
|
#define MAX_ACTIONS 3
|
|
|
|
/* **************************************
|
|
* Structs and enums *
|
|
* **************************************/
|
|
|
|
struct t_coordinates
|
|
{
|
|
int8_t x;
|
|
int8_t y;
|
|
};
|
|
|
|
/* **************************************
|
|
* Local prototypes *
|
|
* **************************************/
|
|
|
|
static void UnitBuildAccepted(TYPE_UNIT* ptrUnit);
|
|
static void UnitAttackAccepted(TYPE_UNIT* ptrUnit);
|
|
|
|
/* **************************************
|
|
* Local variables *
|
|
* **************************************/
|
|
|
|
/* Tables */
|
|
static uint8_t const UnitHPTable[MAX_UNITS_BUILDINGS] = { [PEASANT] = 25 ,
|
|
[BARRACKS] = 100 };
|
|
static uint8_t const UnitSpeedTable[MAX_UNITS_BUILDINGS] = { [PEASANT] = 1 ,
|
|
[BARRACKS] = 0 };
|
|
|
|
static TYPE_UNIT_ACTION const UnitActionsTable_Level0[MAX_ACTIONS] = { [ACTION_BUILD] = {"BUILD", &UnitBuildAccepted} ,
|
|
[ACTION_ATTACK] = {"ATTACK", &UnitAttackAccepted} ,
|
|
[ACTION_CREATE_UNIT] = {"CREATE", NULL} };
|
|
|
|
static uint8_t const UnitActionsTable[MAX_UNITS_BUILDINGS] = { [PEASANT] = ((1 << ACTION_BUILD) | (1 << ACTION_ATTACK)),
|
|
[BARRACKS] = (1 << ACTION_CREATE_UNIT) };
|
|
|
|
// **************
|
|
// Sprite tables
|
|
// **************
|
|
static TYPE_SPRITE UnitSprTable[MAX_UNITS_BUILDINGS];
|
|
static TYPE_SPRITE UnitWalkingShadowSprTable[MAX_UNITS_BUILDINGS];
|
|
static const struct t_coordinates UnitShadowOffsetTable[MAX_BUILDING_ID - FIRST_BUILDING_ID] = { [BARRACKS - FIRST_BUILDING_ID] = {.x = -6, .y = 0} };
|
|
|
|
void UnitInit(void)
|
|
{
|
|
enum
|
|
{
|
|
BARRACKS_SHADOW_OFFSET_X = -8,
|
|
BARRACKS_SHADOW_OFFSET_Y = 0
|
|
};
|
|
|
|
UnitSprTable[PEASANT].Data = Peasant_SprData;
|
|
UnitSprTable[PEASANT].w = GfxGetWidthFromSpriteData(Peasant_SprData);
|
|
UnitSprTable[PEASANT].h = GfxGetHeightFromSpriteData(Peasant_SprData);
|
|
UnitSprTable[PEASANT].flip = 0;
|
|
UnitSprTable[PEASANT].rotation = 0;
|
|
UnitSprTable[PEASANT].color = GFX_BLACK;
|
|
|
|
UnitWalkingShadowSprTable[PEASANT].Data = Peasant_Walking_SprData;
|
|
UnitWalkingShadowSprTable[PEASANT].w = GfxGetWidthFromSpriteData(Peasant_Walking_SprData);
|
|
UnitWalkingShadowSprTable[PEASANT].h = GfxGetHeightFromSpriteData(Peasant_Walking_SprData);
|
|
UnitWalkingShadowSprTable[PEASANT].flip = 0;
|
|
UnitWalkingShadowSprTable[PEASANT].rotation = 0;
|
|
UnitWalkingShadowSprTable[PEASANT].color = GFX_BLACK;
|
|
|
|
UnitSprTable[BARRACKS].Data = BarracksSpr_Data;
|
|
UnitSprTable[BARRACKS].w = GfxGetWidthFromSpriteData(BarracksSpr_Data);
|
|
UnitSprTable[BARRACKS].h = GfxGetHeightFromSpriteData(BarracksSpr_Data);
|
|
UnitSprTable[BARRACKS].flip = 0;
|
|
UnitSprTable[BARRACKS].rotation = 0;
|
|
UnitSprTable[BARRACKS].color = GFX_BLACK;
|
|
|
|
UnitWalkingShadowSprTable[BARRACKS].Data = BarracksShadowSpr_Data;
|
|
UnitWalkingShadowSprTable[BARRACKS].w = GfxGetWidthFromSpriteData(BarracksShadowSpr_Data);
|
|
UnitWalkingShadowSprTable[BARRACKS].h = GfxGetHeightFromSpriteData(BarracksShadowSpr_Data);
|
|
UnitWalkingShadowSprTable[BARRACKS].flip = 0;
|
|
UnitWalkingShadowSprTable[BARRACKS].rotation = 0;
|
|
UnitWalkingShadowSprTable[BARRACKS].color = GFX_GRAY;
|
|
}
|
|
|
|
void UnitDraw(TYPE_UNIT* ptrUnit, TYPE_CAMERA* ptrCamera, bool bHighlighted)
|
|
{
|
|
uint8_t id = ptrUnit->id;
|
|
TYPE_SPRITE * ptrSpr;
|
|
|
|
if (ptrUnit->alive == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (ptrUnit->building == false)
|
|
{
|
|
enum
|
|
{
|
|
WALK_FRAMES = 4
|
|
};
|
|
|
|
// ***************
|
|
// Units
|
|
// ***************
|
|
|
|
ptrSpr = ptrUnit->walking ? &UnitWalkingShadowSprTable[id] : &UnitSprTable[id];
|
|
|
|
ptrSpr->rotation = GFX_NOROT;
|
|
ptrSpr->flip = GFX_NOFLIP;
|
|
|
|
if (ptrUnit->walking == true)
|
|
{
|
|
if (++ptrUnit->walk_counter > WALK_FRAMES)
|
|
{
|
|
ptrUnit->walk_counter = 0;
|
|
ptrUnit->mirror = ptrUnit->mirror ? false : true;
|
|
}
|
|
}
|
|
|
|
switch (ptrUnit->dir)
|
|
{
|
|
case DIRECTION_UP:
|
|
ptrSpr->flip |= GFX_FLIPV;
|
|
|
|
if (ptrUnit->mirror == true)
|
|
{
|
|
ptrSpr->flip |= GFX_FLIPH;
|
|
}
|
|
break;
|
|
|
|
case DIRECTION_DOWN:
|
|
if (ptrUnit->mirror == true)
|
|
{
|
|
ptrSpr->flip |= GFX_FLIPH;
|
|
}
|
|
break;
|
|
|
|
case DIRECTION_LEFT:
|
|
ptrSpr->rotation = GFX_ROTCCW;
|
|
ptrSpr->flip |= GFX_FLIPH;
|
|
|
|
if (ptrUnit->mirror == true)
|
|
{
|
|
ptrSpr->flip |= GFX_FLIPV;
|
|
}
|
|
break;
|
|
|
|
case DIRECTION_RIGHT:
|
|
ptrSpr->rotation = GFX_ROTCCW;
|
|
|
|
if (ptrUnit->mirror == true)
|
|
{
|
|
ptrSpr->flip |= GFX_FLIPV;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
// Invalid direction
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// *******************
|
|
// Buildings
|
|
// *******************
|
|
|
|
CameraApplyCoordinatesToSprite( ptrCamera,
|
|
&UnitWalkingShadowSprTable[id],
|
|
ptrUnit->x + UnitShadowOffsetTable[id - FIRST_BUILDING_ID].x,
|
|
ptrUnit->y + UnitShadowOffsetTable[id - FIRST_BUILDING_ID].y );
|
|
|
|
GfxDrawSprite(&UnitWalkingShadowSprTable[id]);
|
|
|
|
ptrSpr = &UnitSprTable[id];
|
|
}
|
|
|
|
CameraApplyCoordinatesToSprite( ptrCamera,
|
|
ptrSpr,
|
|
ptrUnit->x,
|
|
ptrUnit->y );
|
|
|
|
GfxDrawSprite(ptrSpr);
|
|
|
|
if ( (bHighlighted == true) || (ptrUnit->selected == true) )
|
|
{
|
|
TYPE_COLLISION_BLOCK cb = CameraApplyCoordinatesToCoordinates(ptrCamera, ptrUnit->x, ptrUnit->y);
|
|
int8_t colour = ptrUnit->selected? GFX_BLACK : GFX_GRAY;
|
|
uint8_t w = UnitGetWidthFromID(id);
|
|
uint8_t h = UnitGetHeightFromID(id);
|
|
|
|
if (ptrUnit->building == true)
|
|
{
|
|
GfxDrawRectangle(cb.x - (w >> 3), cb.y - (h >> 3), w + (w >> 2), h + (h >> 2), colour);
|
|
}
|
|
else
|
|
{
|
|
GfxDrawCircle(cb.x + (w >> 1), cb.y + (h >> 1), w, colour);
|
|
}
|
|
}
|
|
}
|
|
|
|
uint8_t UnitGetWidthFromID(uint8_t id)
|
|
{
|
|
return GfxGetWidthFromSpriteData(UnitSprTable[id].Data);
|
|
}
|
|
|
|
uint8_t UnitGetHeightFromID(uint8_t id)
|
|
{
|
|
return GfxGetHeightFromSpriteData(UnitSprTable[id].Data);
|
|
}
|
|
|
|
uint8_t UnitGetHpFromID(uint8_t id)
|
|
{
|
|
return UnitHPTable[id];
|
|
}
|
|
|
|
void UnitMoveTo(TYPE_UNIT* ptrUnit, uint16_t x, uint16_t y)
|
|
{
|
|
ptrUnit->target_x = x;
|
|
ptrUnit->target_y = y;
|
|
ptrUnit->walking = true;
|
|
}
|
|
|
|
void UnitAttackAccepted(TYPE_UNIT* ptrUnit)
|
|
{
|
|
ptrUnit->selecting_attack = true;
|
|
}
|
|
|
|
void UnitHandler(TYPE_UNIT* ptrUnit)
|
|
{
|
|
bool bMoving = false;
|
|
|
|
if (ptrUnit->walking == true)
|
|
{
|
|
if ( (ptrUnit->x - UnitSpeedTable[ptrUnit->id]) > ptrUnit->target_x)
|
|
{
|
|
ptrUnit->dir = DIRECTION_LEFT;
|
|
ptrUnit->x -= UnitSpeedTable[ptrUnit->id];
|
|
bMoving = true;
|
|
}
|
|
else if ( (ptrUnit->x + UnitSpeedTable[ptrUnit->id]) < ptrUnit->target_x)
|
|
{
|
|
ptrUnit->dir = DIRECTION_RIGHT;
|
|
ptrUnit->x += UnitSpeedTable[ptrUnit->id];
|
|
bMoving = true;
|
|
}
|
|
|
|
if ( (ptrUnit->y - UnitSpeedTable[ptrUnit->id]) > ptrUnit->target_y)
|
|
{
|
|
ptrUnit->dir = DIRECTION_UP;
|
|
ptrUnit->y -= UnitSpeedTable[ptrUnit->id];
|
|
bMoving = true;
|
|
}
|
|
else if ( (ptrUnit->y + UnitSpeedTable[ptrUnit->id]) < ptrUnit->target_y)
|
|
{
|
|
ptrUnit->dir = DIRECTION_DOWN;
|
|
ptrUnit->y += UnitSpeedTable[ptrUnit->id];
|
|
bMoving = true;
|
|
}
|
|
|
|
ptrUnit->walking = bMoving;
|
|
}
|
|
}
|
|
|
|
void UnitAcceptAction(TYPE_UNIT* ptrUnit)
|
|
{
|
|
|
|
}
|
|
|
|
uint8_t UnitGetAvailableActions(TYPE_UNIT* ptrUnit)
|
|
{
|
|
return UnitActionsTable[ptrUnit->id];
|
|
}
|
|
|
|
void UnitBuildAccepted(TYPE_UNIT* ptrUnit)
|
|
{
|
|
|
|
}
|
|
|
|
const char* UnitGetActionString(UNIT_ACTION action)
|
|
{
|
|
return UnitActionsTable_Level0[action].str;
|
|
}
|