diff options
| author | XaviDCR92 <xavi.dcr@gmail.com> | 2018-07-09 19:26:13 +0200 |
|---|---|---|
| committer | XaviDCR92 <xavi.dcr@gmail.com> | 2018-07-09 19:26:13 +0200 |
| commit | f0b654b9bf3bc2a93c1f89d4cc3edcf77b948555 (patch) | |
| tree | 91b7404dca0b6eb136cb7f9b144435419144b777 /UnitOld.c | |
| parent | d85464781580796bbcc744ae732e56d1920e3b0f (diff) | |
| download | pocketempires-f0b654b9bf3bc2a93c1f89d4cc3edcf77b948555.tar.gz | |
Game has been restructured in favor of OOP
Diffstat (limited to 'UnitOld.c')
| -rw-r--r-- | UnitOld.c | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/UnitOld.c b/UnitOld.c new file mode 100644 index 0000000..a7cbf97 --- /dev/null +++ b/UnitOld.c @@ -0,0 +1,452 @@ +/* ************************************** + * Includes * + * **************************************/ + +#include "Unit.h" + +/* Units sprite data */ +#include "PeasantSpr.i" +#include "SoldierSpr.i" + +/* Buildings sprite data */ +#include "BarracksSpr.i" +#include "TownCentre.i" + +/* ************************************** + * Defines * + * **************************************/ + +/* ************************************** +* Structs and enums * +* **************************************/ + +struct t_coordinates +{ + int8_t x; + int8_t y; +}; + +/* ************************************** +* Local prototypes * +* **************************************/ + +/* ************************************** + * Local variables * + * **************************************/ + +/* Tables */ +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, + [SOLDIER] = 1, + [BARRACKS] = 0, + [TOWN_CENTER] = 0 }; + +static const char* const UnitActionsTable_Level[MAX_ACTIONS] = { [ACTION_BUILD_BARRACKS] = "B.BARR", + [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_BUILD_TOWER_CENTER)), + [SOLDIER] = 0, + [BARRACKS] = (1 << ACTION_CREATE_SOLDIER), + [TOWN_CENTER] = (1 << ACTION_CREATE_PEASANT) }; + +/* **************. */ +/* 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}, + [TOWN_CENTER - FIRST_BUILDING_ID] = {.x = -3, .y = 0} }; + +void UnitInit(void) +{ + /* *********************************** + * Unit sprite data init + * ***********************************/ + + 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; + + 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); + UnitWalkingShadowSprTable[PEASANT].flip = 0; + 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); + UnitSprTable[BARRACKS].flip = 0; + UnitSprTable[BARRACKS].rotation = 0; + UnitSprTable[BARRACKS].color = GFX_BLACK; + + UnitSprTable[TOWN_CENTER].Data = TownCentreSprData; + UnitSprTable[TOWN_CENTER].w = GfxGetWidthFromSpriteData(TownCentreSprData); + UnitSprTable[TOWN_CENTER].h = GfxGetHeightFromSpriteData(TownCentreSprData); + UnitSprTable[TOWN_CENTER].flip = 0; + UnitSprTable[TOWN_CENTER].rotation = 0; + UnitSprTable[TOWN_CENTER].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; + + UnitWalkingShadowSprTable[TOWN_CENTER].Data = TownCentreShadowSprData; + UnitWalkingShadowSprTable[TOWN_CENTER].w = GfxGetWidthFromSpriteData(TownCentreShadowSprData); + UnitWalkingShadowSprTable[TOWN_CENTER].h = GfxGetHeightFromSpriteData(TownCentreShadowSprData); + UnitWalkingShadowSprTable[TOWN_CENTER].flip = 0; + UnitWalkingShadowSprTable[TOWN_CENTER].rotation = 0; + UnitWalkingShadowSprTable[TOWN_CENTER].color = GFX_GRAY; +} + +void UnitDrawShadow(TYPE_UNIT *ptrUnit, TYPE_CAMERA *ptrCamera) +{ + uint8_t id = ptrUnit->id; + + CameraApplyCoordinatesToSprite( ptrCamera, + &UnitWalkingShadowSprTable[id], + ptrUnit->x + UnitShadowOffsetTable[id - FIRST_BUILDING_ID].x, + ptrUnit->y + UnitShadowOffsetTable[id - FIRST_BUILDING_ID].y ); + + GfxDrawSprite(&UnitWalkingShadowSprTable[id]); +} + +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 != false) + { + 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 != false) + { + ptrSpr->flip |= GFX_FLIPH; + } + break; + + case DIRECTION_DOWN: + if (ptrUnit->mirror != false) + { + ptrSpr->flip |= GFX_FLIPH; + } + break; + + case DIRECTION_LEFT: + ptrSpr->rotation = GFX_ROTCCW; + ptrSpr->flip |= GFX_FLIPH; + + if (ptrUnit->mirror != false) + { + ptrSpr->flip |= GFX_FLIPV; + } + break; + + case DIRECTION_RIGHT: + ptrSpr->rotation = GFX_ROTCCW; + + if (ptrUnit->mirror != false) + { + ptrSpr->flip |= GFX_FLIPV; + } + break; + } + } + else + { + /* *******************. */ + /* Buildings. */ + /* *******************. */ + ptrSpr = &UnitSprTable[id]; + } + + CameraApplyCoordinatesToSprite( ptrCamera, + ptrSpr, + ptrUnit->x, + ptrUnit->y ); + + GfxDrawSprite(ptrSpr); + + if ( (bHighlighted != false) || (ptrUnit->selected != false) ) + { + 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 != false) + { + 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(TYPE_UNIT_ID id) +{ + return GfxGetWidthFromSpriteData(UnitSprTable[id].Data); +} + +uint8_t UnitGetHeightFromID(TYPE_UNIT_ID id) +{ + return GfxGetHeightFromSpriteData(UnitSprTable[id].Data); +} + +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; + ptrUnit->target_y = y; + ptrUnit->walking = true; +} + +void UnitAttackAccepted(TYPE_UNIT *ptrUnit) +{ + ptrUnit->selecting_attack = true; +} + +bool UnitCheckCollisionAgainstOtherUnits(TYPE_COLLISION_BLOCK* cb, TYPE_UNIT *ptrUnitArray, TYPE_UNIT* ptrCurrentUnit) +{ + for (uint8_t i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) + { + TYPE_UNIT *ptrOtherUnit = &ptrUnitArray[i]; + TYPE_COLLISION_BLOCK ocb = {.x = ptrOtherUnit->x, + .y = ptrOtherUnit->y, + .w = UnitGetWidthFromID(ptrOtherUnit->id), + .h = UnitGetHeightFromID(ptrOtherUnit->id)}; + + if (ptrOtherUnit->alive == false) + { + continue; + } + + if (ptrOtherUnit == ptrCurrentUnit) + { + /* We are referring to the same TYPE_UNIT instance. Discard. */ + continue; + } + + if (SystemCollisionCheck(cb, &ocb) != false) + { + return true; + } + } + + return false; +} + +void UnitHandler(TYPE_UNIT* unitArray, size_t sz) +{ + size_t i; + + for (i = 0; i < sz; i++) + { + TYPE_UNIT *ptrUnit = &unitArray[i]; + + if (ptrUnit->alive == false) + { + continue; + } + + bool bMoving = true; + + if (ptrUnit->walking != false) + { + int16_t x_dist = ptrUnit->target_x - (ptrUnit->x + (UnitGetWidthFromID(ptrUnit->id) >> 1)); + int16_t y_dist = ptrUnit->target_y - (ptrUnit->y + (UnitGetHeightFromID(ptrUnit->id) >> 1)); + uint8_t unit_speed = UnitSpeedTable[ptrUnit->id]; + + int8_t x_d = 0; + int8_t y_d = 0; + + if ( (uint16_t)abs(x_dist) > (uint16_t)(abs(y_dist) << 2) ) /* Add some hysteresis so unit does not change constantly its direction */ + { + if (x_dist >= (int16_t)unit_speed) + { + x_d = unit_speed; + ptrUnit->dir = DIRECTION_RIGHT; + } + else if (x_dist <= (int16_t)-unit_speed) + { + x_d = (int8_t)-unit_speed; + ptrUnit->dir = DIRECTION_LEFT; + } + else + { + bMoving = false; + } + } + else + { + if (y_dist >= (int16_t)unit_speed) + { + y_d = unit_speed; + ptrUnit->dir = DIRECTION_DOWN; + } + else if (y_dist <= (int16_t)-unit_speed) + { + y_d = (int8_t)-unit_speed; + ptrUnit->dir = DIRECTION_UP; + } + else + { + bMoving = false; + } + } + + /* ~ if ( (ptrUnit->x - UnitSpeedTable[ptrUnit->id]) > ptrUnit->target_x). */ + /* ~ {. */ + /* ~ ptrUnit->dir = DIRECTION_LEFT;. */ + /* ~ x_d = (int8_t)-UnitSpeedTable[ptrUnit->id];. */ + /* ~ }. */ + /* ~ else if ( (ptrUnit->x + UnitSpeedTable[ptrUnit->id]) < ptrUnit->target_x). */ + /* ~ {. */ + /* ~ ptrUnit->dir = DIRECTION_RIGHT;. */ + /* ~ x_d = (int8_t)UnitSpeedTable[ptrUnit->id];. */ + /* ~ }. */ + /* ~ else if ( (ptrUnit->y - UnitSpeedTable[ptrUnit->id]) > ptrUnit->target_y). */ + /* ~ {. */ + /* ~ ptrUnit->dir = DIRECTION_UP;. */ + /* ~ y_d = (int8_t)-UnitSpeedTable[ptrUnit->id];. */ + /* ~ }. */ + /* ~ else if ( (ptrUnit->y + UnitSpeedTable[ptrUnit->id]) < ptrUnit->target_y). */ + /* ~ {. */ + /* ~ ptrUnit->dir = DIRECTION_DOWN;. */ + /* ~ y_d = (int8_t)UnitSpeedTable[ptrUnit->id];. */ + /* ~ }. */ + /* ~ else. */ + /* ~ {. */ + /* ~ bMoving = false;. */ + /* ~ }. */ + + if (ptrUnit->walking != false) + { + TYPE_COLLISION_BLOCK cu = { .x = ptrUnit->x + x_d, + .y = ptrUnit->y + y_d, + .w = UnitGetWidthFromID(ptrUnit->id), + .h = UnitGetHeightFromID(ptrUnit->id) }; + + if (UnitCheckCollisionAgainstOtherUnits(&cu, unitArray, ptrUnit) == true) + { + switch (ptrUnit->dir) + { + case DIRECTION_LEFT: + /* Fall through. */ + case DIRECTION_RIGHT: + y_d = -x_d; + x_d = 0; + ptrUnit->dir = y_d > 0? DIRECTION_DOWN: DIRECTION_UP; + break; + + case DIRECTION_UP: + /* Fall through. */ + case DIRECTION_DOWN: + x_d = y_d; + y_d = 0; + ptrUnit->dir = x_d > 0? DIRECTION_RIGHT: DIRECTION_LEFT; + break; + } + } + } + + ptrUnit->walking = bMoving; + + if (ptrUnit->walking != false) + { + /* If no collision is detected, keep moving to the new position */ + ptrUnit->x += x_d; + ptrUnit->y += y_d; + } + } + } +} + +uint8_t UnitGetAvailableActions(TYPE_UNIT *ptrUnit) +{ + return UnitActionsTable[ptrUnit->id]; +} + +const char* UnitGetActionString(UNIT_ACTION action) +{ + return UnitActionsTable_Level[action]; +} |
