Kinda improved pathfinding algorithm. Still some work TODO.
Fixed some errors in DEBUG_VAR macro. Shadows are now drawn before any other object. Different strings are now shown depending on the number of selected units. Some work on calculating actions mask when different types of units are selected. Still some work TODO.
This commit is contained in:
parent
7b05778e3e
commit
d854647815
BIN
Exe/POCKET.ELF
BIN
Exe/POCKET.ELF
Binary file not shown.
2373
Exe/POCKET.HEX
2373
Exe/POCKET.HEX
File diff suppressed because it is too large
Load Diff
858
Exe/POCKET.MAP
858
Exe/POCKET.MAP
File diff suppressed because it is too large
Load Diff
|
@ -26,8 +26,8 @@
|
|||
#define DEBUG_VAR(var, suff, x, y) if (1) \
|
||||
{ \
|
||||
char buffer##suff[16]; \
|
||||
Systemitoa(str, sizeof(buffer##suff[16]), var); \
|
||||
GfxPrintText(buffer##suff, x - (strlen(buffer##suff)<<3), y); \
|
||||
Systemitoa(buffer##suff, sizeof(buffer##suff), var); \
|
||||
GfxPrintText(buffer##suff, x, y); \
|
||||
}
|
||||
|
||||
/* *************************************
|
||||
|
|
191
Player.cpp
191
Player.cpp
|
@ -98,20 +98,25 @@ void Player::showHealth(uint8_t hp)
|
|||
|
||||
void Player::DrawHandler(void)
|
||||
{
|
||||
enum
|
||||
{
|
||||
PROGRESS_BAR_X = X_SCREEN_RESOLUTION - 16,
|
||||
PROGRESS_BAR_Y = Y_SCREEN_RESOLUTION - 4,
|
||||
PROGRESS_BAR_W = ACCEPT_UNIT_BUILDING_OPTIONS_FRAMES << 1,
|
||||
PROGRESS_BAR_H = 3,
|
||||
};
|
||||
|
||||
uint8_t i;
|
||||
bool bAnyoneSelected = false;
|
||||
|
||||
for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++)
|
||||
{
|
||||
TYPE_UNIT *u = &units[i];
|
||||
|
||||
if ( (u->alive == false) || (u->building == false) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UnitDrawShadow(u, &Camera);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++)
|
||||
{
|
||||
TYPE_UNIT* u = &units[i];
|
||||
TYPE_UNIT *u = &units[i];
|
||||
|
||||
if (u->alive == false)
|
||||
{
|
||||
|
@ -130,33 +135,26 @@ void Player::DrawHandler(void)
|
|||
if ( (u->selected != false) && (bAnyoneSelected == false) )
|
||||
{
|
||||
bAnyoneSelected = true;
|
||||
|
||||
showHealth(u->hp);
|
||||
}
|
||||
}
|
||||
|
||||
if (human != false)
|
||||
{
|
||||
if (bAnyoneSelected != false)
|
||||
{
|
||||
GfxDrawRectangle(PROGRESS_BAR_X, PROGRESS_BAR_Y, PROGRESS_BAR_W, PROGRESS_BAR_H, GFX_BLACK);
|
||||
|
||||
if (showActionsMenu_counter != 0)
|
||||
{
|
||||
GfxFillRectangle(PROGRESS_BAR_X, PROGRESS_BAR_Y, showActionsMenu_counter << 1, PROGRESS_BAR_H, GFX_BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
ActionsMenu();
|
||||
|
||||
ShowResources();
|
||||
MenuDrawHandler();
|
||||
}
|
||||
}
|
||||
|
||||
void Player::MenuDrawHandler(void)
|
||||
{
|
||||
ActionsMenu();
|
||||
|
||||
ShowResources();
|
||||
}
|
||||
|
||||
void Player::ShowResources(void)
|
||||
{
|
||||
char str[8];
|
||||
uint8_t i;
|
||||
size_t i;
|
||||
|
||||
str[1] = '=';
|
||||
|
||||
|
@ -181,22 +179,12 @@ void Player::ShowResources(void)
|
|||
|
||||
GfxPrintTextFont(str, font3x3, 42, 1);
|
||||
|
||||
Systemitoa(str, 3, getAliveUnits());
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (str[i] == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
i = Systemitoa(str, 3, getAliveUnits());
|
||||
|
||||
str[i++] = '/';
|
||||
|
||||
Systemitoa(&str[i], sizeof(str) - i, PLAYER_MAX_UNITS_BUILDINGS);
|
||||
|
||||
//~ snprintf(str, sizeof(str), "%d/%d", unit_i, PLAYER_MAX_UNITS_BUILDINGS);
|
||||
|
||||
GfxPrintTextFont(str, font3x3, 42, 5);
|
||||
}
|
||||
|
||||
|
@ -210,7 +198,7 @@ bool Player::checkNewBuildingPosition(TYPE_COLLISION_BLOCK * cb)
|
|||
|
||||
for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++)
|
||||
{
|
||||
TYPE_UNIT* ptrUnit = &units[i];
|
||||
TYPE_UNIT *ptrUnit = &units[i];
|
||||
success = false;
|
||||
|
||||
if (ptrUnit->building == false)
|
||||
|
@ -338,7 +326,8 @@ void Player::UnitBuildingSelection(void)
|
|||
{
|
||||
enum
|
||||
{
|
||||
MAX_ALLOWED_DISTANCE = (X_SCREEN_RESOLUTION * X_SCREEN_RESOLUTION) + (Y_SCREEN_RESOLUTION) * (Y_SCREEN_RESOLUTION)
|
||||
X_MAX_ALLOWED_DISTANCE = X_SCREEN_RESOLUTION >> 1,
|
||||
Y_MAX_ALLOWED_DISTANCE = Y_SCREEN_RESOLUTION >> 1
|
||||
};
|
||||
|
||||
uint16_t i;
|
||||
|
@ -349,7 +338,7 @@ void Player::UnitBuildingSelection(void)
|
|||
|
||||
for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++)
|
||||
{
|
||||
TYPE_UNIT* u = &units[i];
|
||||
TYPE_UNIT *u = &units[i];
|
||||
|
||||
if ( (u->alive == false) || (u->selected != false) )
|
||||
{
|
||||
|
@ -359,8 +348,13 @@ void Player::UnitBuildingSelection(void)
|
|||
TYPE_COLLISION_BLOCK cursor_cb = GetCursorPos();
|
||||
TYPE_COLLISION_BLOCK u_cb = {u->x, u->y, UnitGetWidthFromID(u->id), UnitGetHeightFromID(u->id) };
|
||||
|
||||
uint16_t dist_x = (u_cb.x + (u_cb.w >> 1) - cursor_cb.x);
|
||||
uint16_t dist_y = (u_cb.y + (u_cb.h >> 1) - cursor_cb.y);
|
||||
int16_t dist_x = (u_cb.x + (u_cb.w >> 1) - cursor_cb.x);
|
||||
int16_t dist_y = (u_cb.y + (u_cb.h >> 1) - cursor_cb.y);
|
||||
|
||||
if ( (abs(dist_x) > X_MAX_ALLOWED_DISTANCE) || (abs(dist_y) > Y_MAX_ALLOWED_DISTANCE) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
dist = SystemGetHyp(dist_x, dist_y);
|
||||
|
||||
|
@ -371,41 +365,90 @@ void Player::UnitBuildingSelection(void)
|
|||
}
|
||||
}
|
||||
|
||||
selectedUnitCandidate = dist < (uint32_t)MAX_ALLOWED_DISTANCE? nearest_unit: NO_SELECTION;
|
||||
selectedUnitCandidate = nearest_unit;
|
||||
}
|
||||
|
||||
void Player::ActionsMenu(void)
|
||||
{
|
||||
if (showActionsMenu != false)
|
||||
enum
|
||||
{
|
||||
for (uint8_t i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++)
|
||||
ALL_ACTIONS_MASK = 0xFF
|
||||
};
|
||||
|
||||
uint8_t selectedUnits = 0;
|
||||
uint8_t availableActions = ALL_ACTIONS_MASK;
|
||||
|
||||
TYPE_UNIT *ptrSelectedUnit = NULL;
|
||||
|
||||
for (uint8_t i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++)
|
||||
{
|
||||
TYPE_UNIT *ptrUnit = &units[i];
|
||||
|
||||
if (ptrUnit->selected != false)
|
||||
{
|
||||
TYPE_UNIT* ptrUnit = &units[i];
|
||||
|
||||
if (ptrUnit->selected != false)
|
||||
{
|
||||
uint8_t availableActions = UnitGetAvailableActions(ptrUnit);
|
||||
|
||||
if (availableActions != 0)
|
||||
{
|
||||
if (!(availableActions & (1 << showActionsMenu_index) ) )
|
||||
{
|
||||
IncreaseShowActionsMenuIndex();
|
||||
}
|
||||
|
||||
UNIT_ACTION action = (UNIT_ACTION)(showActionsMenu_index);
|
||||
|
||||
const char* str = UnitGetActionString(action);
|
||||
|
||||
GfxPrintTextFont(str, font3x3, 40, Y_SCREEN_RESOLUTION - 4);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ptrSelectedUnit = ptrUnit;
|
||||
selectedUnits++;
|
||||
availableActions &= UnitGetAvailableActions(ptrUnit);
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedUnits != 0)
|
||||
{
|
||||
if (selectedUnits == 1)
|
||||
{
|
||||
showHealth(ptrSelectedUnit->hp);
|
||||
}
|
||||
else
|
||||
{
|
||||
enum
|
||||
{
|
||||
UNITS_SELECTED_NUMBER_STR_SIZE = 3 /* "000" */,
|
||||
UNITS_SELECTED_STR = UNITS_SELECTED_NUMBER_STR_SIZE + 6 /* strlen("units\0") */,
|
||||
|
||||
UNITS_SELECTED_TEXT_X = 4,
|
||||
UNITS_SELECTED_TEXT_Y = Y_SCREEN_RESOLUTION - 4,
|
||||
};
|
||||
|
||||
char unitsSelectedStr[UNITS_SELECTED_STR];
|
||||
size_t i = Systemitoa(unitsSelectedStr, UNITS_SELECTED_NUMBER_STR_SIZE, selectedUnits);
|
||||
|
||||
//~ strcpy(&unitsSelectedStr[i], "units");
|
||||
memcpy(&unitsSelectedStr[i], "units\0", 6 /* strlen("units")*/);
|
||||
|
||||
GfxPrintTextFont(unitsSelectedStr, font3x3, UNITS_SELECTED_TEXT_X, UNITS_SELECTED_TEXT_Y);
|
||||
}
|
||||
|
||||
if ( (availableActions != 0)
|
||||
&&
|
||||
(availableActions != ALL_ACTIONS_MASK) )
|
||||
{
|
||||
enum
|
||||
{
|
||||
PROGRESS_BAR_X = X_SCREEN_RESOLUTION - 16,
|
||||
PROGRESS_BAR_Y = Y_SCREEN_RESOLUTION - 4,
|
||||
PROGRESS_BAR_W = ACCEPT_UNIT_BUILDING_OPTIONS_FRAMES << 1,
|
||||
PROGRESS_BAR_H = 3,
|
||||
};
|
||||
|
||||
if (!(availableActions & (1 << showActionsMenu_index) ) )
|
||||
{
|
||||
IncreaseShowActionsMenuIndex();
|
||||
}
|
||||
|
||||
GfxDrawRectangle(PROGRESS_BAR_X, PROGRESS_BAR_Y, PROGRESS_BAR_W, PROGRESS_BAR_H, GFX_BLACK);
|
||||
|
||||
GfxFillRectangle(PROGRESS_BAR_X, PROGRESS_BAR_Y, showActionsMenu_counter << 1, PROGRESS_BAR_H, GFX_BLACK);
|
||||
|
||||
if (showActionsMenu != false)
|
||||
{
|
||||
UNIT_ACTION action = (UNIT_ACTION)(showActionsMenu_index);
|
||||
|
||||
const char* str = UnitGetActionString(action);
|
||||
|
||||
GfxPrintTextFont(str, font3x3, 40, Y_SCREEN_RESOLUTION - 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Player::Handler(void)
|
||||
|
@ -472,7 +515,7 @@ void Player::ButtonAReleased(void)
|
|||
{
|
||||
// When actions menu is not active, select unit if
|
||||
// a candidate is present
|
||||
TYPE_UNIT* ptrUnit = &units[selectedUnitCandidate];
|
||||
TYPE_UNIT *ptrUnit = &units[selectedUnitCandidate];
|
||||
|
||||
ptrUnit->selected = true;
|
||||
anyUnitSelected = true;
|
||||
|
@ -487,7 +530,7 @@ void Player::ButtonAReleased(void)
|
|||
|
||||
for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++)
|
||||
{
|
||||
TYPE_UNIT* ptrUnit = &units[i];
|
||||
TYPE_UNIT *ptrUnit = &units[i];
|
||||
|
||||
if (ptrUnit->selected != false)
|
||||
{
|
||||
|
@ -523,7 +566,7 @@ void Player::ButtonAReleased(void)
|
|||
showActionsMenu = (showActionsMenu_counter < ACCEPT_UNIT_BUILDING_OPTIONS_FRAMES)? false: true;
|
||||
}
|
||||
|
||||
void Player::ActionCreateUnit(TYPE_UNIT* ptrUnit, TYPE_UNIT_ID unit)
|
||||
void Player::ActionCreateUnit(TYPE_UNIT *ptrUnit, TYPE_UNIT_ID unit)
|
||||
{
|
||||
enum
|
||||
{
|
||||
|
@ -594,7 +637,7 @@ void Player::ButtonBPressed(void)
|
|||
/* Cancel selection of all units */
|
||||
for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++)
|
||||
{
|
||||
TYPE_UNIT* ptrUnit = &units[i];
|
||||
TYPE_UNIT *ptrUnit = &units[i];
|
||||
|
||||
if (ptrUnit->selected != false)
|
||||
{
|
||||
|
@ -621,7 +664,7 @@ void Player::ButtonBReleased(void)
|
|||
|
||||
for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++)
|
||||
{
|
||||
TYPE_UNIT* ptrUnit = &units[i];
|
||||
TYPE_UNIT *ptrUnit = &units[i];
|
||||
|
||||
if (ptrUnit->selected != false)
|
||||
{
|
||||
|
@ -651,7 +694,7 @@ void Player::ButtonLeftReleased(void)
|
|||
|
||||
for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++)
|
||||
{
|
||||
TYPE_UNIT* ptrUnit = &units[i];
|
||||
TYPE_UNIT *ptrUnit = &units[i];
|
||||
|
||||
if (ptrUnit->selected != false)
|
||||
{
|
||||
|
@ -692,7 +735,7 @@ void Player::IncreaseShowActionsMenuIndex(void)
|
|||
|
||||
for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++)
|
||||
{
|
||||
TYPE_UNIT* ptrUnit = &units[i];
|
||||
TYPE_UNIT *ptrUnit = &units[i];
|
||||
|
||||
if (ptrUnit->selected != false)
|
||||
{
|
||||
|
|
3
Player.h
3
Player.h
|
@ -78,6 +78,7 @@ class Player
|
|||
void showHealth(uint8_t hp);
|
||||
void ButtonHandler(void);
|
||||
void ActionsMenu(void);
|
||||
void MenuDrawHandler(void);
|
||||
TYPE_COLLISION_BLOCK GetCursorPos(void);
|
||||
|
||||
// Unit selection
|
||||
|
@ -93,7 +94,7 @@ class Player
|
|||
void IncreaseShowActionsMenuIndex();
|
||||
|
||||
// Action callbacks
|
||||
void ActionCreateUnit(TYPE_UNIT* ptrUnit, TYPE_UNIT_ID unit);
|
||||
void ActionCreateUnit(TYPE_UNIT *ptrUnit, TYPE_UNIT_ID unit);
|
||||
void ActionCreateBuilding(TYPE_UNIT_ID bldg);
|
||||
|
||||
// Collision detection
|
||||
|
|
18
System.c
18
System.c
|
@ -277,13 +277,13 @@ bool SystemCollisionCheck(TYPE_COLLISION_BLOCK* c1, TYPE_COLLISION_BLOCK* c2)
|
|||
c2->x, c2->y, c2->w, c2->h );
|
||||
}
|
||||
|
||||
bool Systemitoa(char* str, size_t sz, int16_t value)
|
||||
size_t Systemitoa(char* str, size_t sz, int16_t value)
|
||||
{
|
||||
if (sz != 0)
|
||||
{
|
||||
bool first_digit_found = false;
|
||||
uint16_t i;
|
||||
uint8_t j = 0;
|
||||
uint8_t bytes_written = 0;
|
||||
|
||||
/* Example: 65535 */
|
||||
/* Another example: -32767 */
|
||||
|
@ -291,7 +291,7 @@ bool Systemitoa(char* str, size_t sz, int16_t value)
|
|||
if (value & 0x8000)
|
||||
{
|
||||
/* Sign bit */
|
||||
str[j++] = '-';
|
||||
str[bytes_written++] = '-';
|
||||
}
|
||||
|
||||
for (i = 10000; i >= 1; i /= 10)
|
||||
|
@ -311,20 +311,20 @@ bool Systemitoa(char* str, size_t sz, int16_t value)
|
|||
continue;
|
||||
}
|
||||
|
||||
str[j++] = digit + '0';
|
||||
str[bytes_written++] = digit + '0';
|
||||
|
||||
if (j >= (sz - 1))
|
||||
if (bytes_written >= (sz - 1))
|
||||
{
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
str[j] = '\0';
|
||||
str[bytes_written] = '\0';
|
||||
|
||||
return true;
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t SystemGetHyp(uint16_t x, uint16_t y)
|
||||
|
|
3
System.h
3
System.h
|
@ -86,7 +86,8 @@ 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);
|
||||
// Transforms integer to string. Use this instead of sprintf() as much as possible.
|
||||
bool Systemitoa(char* str, size_t sz, int16_t value);
|
||||
// Returns the number of bytes written into "str". In case of error, 0 is returned.
|
||||
size_t Systemitoa(char* str, size_t sz, int16_t value);
|
||||
// Return hypothenuse of two points
|
||||
uint32_t SystemGetHyp(uint16_t x, uint16_t y);
|
||||
|
||||
|
|
131
Unit.c
131
Unit.c
|
@ -135,7 +135,19 @@ void UnitInit(void)
|
|||
UnitWalkingShadowSprTable[TOWN_CENTER].color = GFX_GRAY;
|
||||
}
|
||||
|
||||
void UnitDraw(TYPE_UNIT* ptrUnit, TYPE_CAMERA* ptrCamera, bool bHighlighted)
|
||||
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;
|
||||
|
@ -213,14 +225,6 @@ void UnitDraw(TYPE_UNIT* ptrUnit, TYPE_CAMERA* ptrCamera, bool bHighlighted)
|
|||
// *******************
|
||||
// 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];
|
||||
}
|
||||
|
||||
|
@ -269,23 +273,23 @@ TYPE_RESOURCES UnitNeededResourcesFromID(TYPE_UNIT_ID id)
|
|||
return UnitResourcesTable[id];
|
||||
}
|
||||
|
||||
void UnitMoveTo(TYPE_UNIT* ptrUnit, uint16_t x, uint16_t y)
|
||||
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)
|
||||
void UnitAttackAccepted(TYPE_UNIT *ptrUnit)
|
||||
{
|
||||
ptrUnit->selecting_attack = true;
|
||||
}
|
||||
|
||||
bool UnitCheckCollisionAgainstOtherUnits(TYPE_COLLISION_BLOCK* cb, TYPE_UNIT* ptrUnitArray, TYPE_UNIT* ptrCurrentUnit)
|
||||
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_UNIT *ptrOtherUnit = &ptrUnitArray[i];
|
||||
TYPE_COLLISION_BLOCK ocb = {.x = ptrOtherUnit->x,
|
||||
.y = ptrOtherUnit->y,
|
||||
.w = UnitGetWidthFromID(ptrOtherUnit->id),
|
||||
|
@ -317,46 +321,84 @@ void UnitHandler(TYPE_UNIT* unitArray, size_t sz)
|
|||
|
||||
for (i = 0; i < sz; i++)
|
||||
{
|
||||
TYPE_UNIT* ptrUnit = &unitArray[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 ( (ptrUnit->x - UnitSpeedTable[ptrUnit->id]) > ptrUnit->target_x)
|
||||
if ( (uint16_t)abs(x_dist) > (uint16_t)(abs(y_dist) << 2) ) /* Add some hysteresis so unit does not change constantly its direction */
|
||||
{
|
||||
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];
|
||||
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
|
||||
{
|
||||
bMoving = false;
|
||||
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,
|
||||
|
@ -366,33 +408,22 @@ void UnitHandler(TYPE_UNIT* unitArray, size_t sz)
|
|||
|
||||
if (UnitCheckCollisionAgainstOtherUnits(&cu, unitArray, ptrUnit) == true)
|
||||
{
|
||||
uint32_t dist = 0;
|
||||
uint32_t dist2 = 0;
|
||||
|
||||
switch (ptrUnit->dir)
|
||||
{
|
||||
case DIRECTION_LEFT:
|
||||
// Fall through
|
||||
case DIRECTION_RIGHT:
|
||||
dist = SystemGetHyp(abs(ptrUnit->x - ptrUnit->target_x), abs((ptrUnit->y + y_d) - ptrUnit->target_y));
|
||||
dist2 = SystemGetHyp(abs(ptrUnit->x - ptrUnit->target_x), abs((ptrUnit->y - y_d) - ptrUnit->target_y));
|
||||
|
||||
y_d = dist < dist2? x_d: -x_d;
|
||||
|
||||
ptrUnit->dir = y_d? DIRECTION_DOWN: DIRECTION_UP;
|
||||
|
||||
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:
|
||||
dist = SystemGetHyp(abs((ptrUnit->x - x_d) - ptrUnit->target_x), abs(ptrUnit->y - ptrUnit->target_y));
|
||||
dist2 = SystemGetHyp(abs((ptrUnit->x + x_d) - ptrUnit->target_x), abs(ptrUnit->y - ptrUnit->target_y));
|
||||
|
||||
x_d = dist < dist2? -y_d: -x_d;
|
||||
ptrUnit->dir = x_d? DIRECTION_RIGHT: DIRECTION_LEFT;
|
||||
x_d = y_d;
|
||||
y_d = 0;
|
||||
ptrUnit->dir = x_d > 0? DIRECTION_RIGHT: DIRECTION_LEFT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -410,7 +441,7 @@ void UnitHandler(TYPE_UNIT* unitArray, size_t sz)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t UnitGetAvailableActions(TYPE_UNIT* ptrUnit)
|
||||
uint8_t UnitGetAvailableActions(TYPE_UNIT *ptrUnit)
|
||||
{
|
||||
return UnitActionsTable[ptrUnit->id];
|
||||
}
|
||||
|
|
9
Unit.h
9
Unit.h
|
@ -100,17 +100,18 @@ void UnitHandler(TYPE_UNIT* unitArray, size_t sz);
|
|||
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);
|
||||
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 UnitDrawShadow(TYPE_UNIT *ptrUnit, TYPE_CAMERA *ptrCamera);
|
||||
|
||||
// Movement
|
||||
void UnitMoveTo(TYPE_UNIT* ptrUnit, uint16_t x, uint16_t y);
|
||||
void UnitMoveTo(TYPE_UNIT *ptrUnit, uint16_t x, uint16_t y);
|
||||
|
||||
// Collision cheking
|
||||
bool UnitCheckCollisionAgainstOtherUnits(TYPE_COLLISION_BLOCK* cb, TYPE_UNIT* ptrUnitArray, TYPE_UNIT* ptrCurrentUnit);
|
||||
bool UnitCheckCollisionAgainstOtherUnits(TYPE_COLLISION_BLOCK* cb, TYPE_UNIT *ptrUnitArray, TYPE_UNIT* ptrCurrentUnit);
|
||||
|
||||
// Selection index
|
||||
const char* UnitGetActionString(UNIT_ACTION action);
|
||||
|
|
Loading…
Reference in New Issue