diff options
| author | XaviDCR92 <xavi.dcr@gmail.com> | 2017-09-08 18:39:22 +0200 |
|---|---|---|
| committer | XaviDCR92 <xavi.dcr@gmail.com> | 2017-09-08 18:39:22 +0200 |
| commit | 786dccd2bc0946d48b8a2758ef2c607678bc8dd9 (patch) | |
| tree | 47952d77e5646a993671134b50c16f32ebe35b1c /Player.cpp | |
| parent | 72d350a37aa67936361ac8a374472b7e0227da61 (diff) | |
Removed Building and GameStructures modules. Restructured SW for Unit and Player, still a lot TODO
Diffstat (limited to 'Player.cpp')
| -rw-r--r-- | Player.cpp | 757 |
1 files changed, 396 insertions, 361 deletions
@@ -1,17 +1,19 @@ /* ************************************** * Includes * * **************************************/ - + #include "Player.h" - +#include "Pad.h" +#include <limits.h> + /* ************************************** * Defines * * **************************************/ - -#define CANCEL_SELECTION_NO_FRAMES 5 + #define ACCEPT_UNIT_BUILDING_OPTIONS_FRAMES 5 #define MAX_SELECTION_DIST 400 - +#define NO_SELECTION -1 + /* ************************************** * Local variables * * **************************************/ @@ -22,55 +24,50 @@ Player::Player(void) Player::~Player(void) { - + } void Player::Init(void) { uint8_t i; - + unit_i = 0; - bldg_i = 0; - - selectedUnit = NULL; - selectedBuilding = NULL; - + + selectedUnitCandidate = NO_SELECTION; + CameraInit(&Camera); - BuildingInit(); UnitInit(); - - for(i = 0; i < PLAYER_MAX_BUILDINGS; i++) - { - memset(&buildings[i], 0, sizeof(TYPE_BUILDING)); - } - - for(i = 0; i < PLAYER_MAX_UNITS; i++) + + for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) { memset(&units[i], 0, sizeof(TYPE_UNIT)); } - - TYPE_COLLISION_BLOCK cl; - + + TYPE_COLLISION_BLOCK cb; + Resources.Wood = 25; Resources.Gold = 50; Resources.Food = 75; - - cl.x = SystemRand(0, 20); - cl.y = SystemRand(0, 20); - cl.w = BuildingGetWidthFromID(BARRACKS); - cl.h = BuildingGetHeightFromID(BARRACKS); - - if(createBuilding(BARRACKS, cl) == false) + + cb.x = SystemRand(0, 20); + cb.y = SystemRand(0, 20); + + if (createUnit(BARRACKS, cb) == false) { GfxPrintText_Flash(F("Failed to create building!")); } - - cl.x = SystemRand(48, 56); - cl.y = SystemRand(48, 56); - cl.w = UnitGetWidthFromID(PEASANT); - cl.h = UnitGetHeightFromID(PEASANT); - - if(createUnit(PEASANT, cl) == false) + + cb.x = SystemRand(48, 56); + cb.y = SystemRand(48, 56); + cb.w = UnitGetWidthFromID(PEASANT); + cb.h = UnitGetHeightFromID(PEASANT); + + showActionsMenu_counter = 0; + showActionsMenu_index = 0; + showActionsMenu = false; + anyUnitSelected = false; + + if (createUnit(PEASANT, cb) == false) { GfxPrintText_Flash(F("Failed to create unit!")); } @@ -78,68 +75,71 @@ void Player::Init(void) void Player::showHealth(uint8_t hp) { + enum + { + HP_TEXT_X = 4, + HP_TEXT_Y = Y_SCREEN_RESOLUTION - 4, + }; + char str[8]; - + GfxFillRectangle(0, Y_SCREEN_RESOLUTION - 5, X_SCREEN_RESOLUTION, 8, GFX_WHITE); - snprintf(str, 8, "HP=%u", hp); + snprintf(str, sizeof(str), "HP=%u", hp); - GfxPrintTextFont(str, font3x3, 4, Y_SCREEN_RESOLUTION - 4); + GfxPrintTextFont(str, font3x3, HP_TEXT_X, HP_TEXT_Y); } 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; - + //GfxRenderTiles(&Camera); - - for(i = 0; i < PLAYER_MAX_BUILDINGS; i++) - { - TYPE_BUILDING * b = &buildings[i]; - - if(b->built == false) - { - continue; - } - - bool selected = (b == selectedBuilding); - BuildingDraw(&Camera, b, selected); - - if( (b->selected == true) && (bAnyoneSelected == false) ) - { - bAnyoneSelected = true; - - showHealth(b->hp); - BuildingSelectedOptions(b); - } - } - - for(i = 0; i < PLAYER_MAX_UNITS; i++) + + for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) { - TYPE_UNIT * u = &units[i]; - - if(u->alive == false) + TYPE_UNIT* u = &units[i]; + + if (u->alive == false) { continue; } - - bool selected = (u == selectedUnit); - UnitDraw(&Camera, u, selected); - - if( (u->selected == true) && (bAnyoneSelected == false) ) + + bool selected = false; + + if (selectedUnitCandidate != NO_SELECTION) + { + selected = (i == selectedUnitCandidate); + } + + UnitDraw(u, &Camera, selected); + + if ( (u->selected == true) && (bAnyoneSelected == false) ) { bAnyoneSelected = true; - + showHealth(u->hp); - UnitSelectedOptions(u); } } - - if(progress_bar != 0) - { - GfxDrawRectangle(X_SCREEN_RESOLUTION - 16, Y_SCREEN_RESOLUTION - 4, progress_bar, 2, GFX_BLACK); - } + + if (bAnyoneSelected == true) + { + 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); + } + } } bool Player::checkNewBuildingPosition(TYPE_COLLISION_BLOCK * cb) @@ -148,22 +148,23 @@ bool Player::checkNewBuildingPosition(TYPE_COLLISION_BLOCK * cb) TYPE_COLLISION_BLOCK bldgCB; bool success; static uint8_t max_tries = 0; - - for(i = 0; i < PLAYER_MAX_BUILDINGS; i++) + + for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) { + TYPE_UNIT* ptrUnit = &units[i]; success = false; - - if(buildings[i].built == false) + + if (ptrUnit->building == false) { continue; } - - bldgCB.x = buildings[i].x; - bldgCB.y = buildings[i].y; - bldgCB.w = BuildingGetWidthFromID(buildings[i].id); - bldgCB.h = BuildingGetHeightFromID(buildings[i].id); - - if(SystemCollisionCheck(*cb, bldgCB) == true) + + bldgCB.x = ptrUnit->x; + bldgCB.y = ptrUnit->y; + bldgCB.w = UnitGetWidthFromID(ptrUnit->id); + bldgCB.h = UnitGetHeightFromID(ptrUnit->id); + + if (SystemCollisionCheck(*cb, bldgCB) == true) { success = false; } @@ -171,15 +172,15 @@ bool Player::checkNewBuildingPosition(TYPE_COLLISION_BLOCK * cb) { success = true; } - - if(success == false) + + if (success == false) { cb->x = SystemRand(0, 128); cb->y = SystemRand(0, 128); - - if(++max_tries < 16) - { - if(checkNewBuildingPosition(cb) == false) + + if (++max_tries < 16) + { + if (checkNewBuildingPosition(cb) == false) { return false; } @@ -194,332 +195,366 @@ bool Player::checkNewBuildingPosition(TYPE_COLLISION_BLOCK * cb) } } } - + max_tries = 0; return true; } -bool Player::createBuilding(TYPE_BUILDING_ID id, TYPE_COLLISION_BLOCK cb) +bool Player::createUnit(TYPE_UNIT_ID id, TYPE_COLLISION_BLOCK cb) { - if(checkNewBuildingPosition(&cb) == false) + if (unit_i < PLAYER_MAX_UNITS_BUILDINGS) { - return false; - } + TYPE_UNIT* ptrNewUnit = &units[unit_i]; + ptrNewUnit->id = id; + ptrNewUnit->x = cb.x; + ptrNewUnit->y = cb.y; + ptrNewUnit->hp = UnitGetHpFromID(id); + ptrNewUnit->alive = true; - if(bldg_i < PLAYER_MAX_BUILDINGS) - { - buildings[bldg_i].id = id; - buildings[bldg_i].x = cb.x; - buildings[bldg_i].y = cb.y; - buildings[bldg_i].hp = BuildingGetHpFromID(id); - buildings[bldg_i].built = true; - - bldg_i++; - - return true; - } - else - { - return false; - } - - return false; -} + ptrNewUnit->building = (id > MAX_UNIT_ID); -bool Player::createUnit(uint8_t id, TYPE_COLLISION_BLOCK cb) -{ - if(unit_i < PLAYER_MAX_UNITS) - { - units[unit_i].id = id; - units[unit_i].x = cb.x; - units[unit_i].y = cb.y; - units[unit_i].hp = UnitGetHpFromID(id); - units[unit_i].alive = true; - unit_i++; - + return true; } else { return false; } - + return false; } TYPE_COLLISION_BLOCK Player::GetCursorPos(void) { TYPE_COLLISION_BLOCK cb; - + cb.x = (X_SCREEN_RESOLUTION >> 1) - 4 - Camera.X_Offset; cb.y = (Y_SCREEN_RESOLUTION >> 1) - 4 - Camera.Y_Offset; cb.w = 8; cb.h = 8; - + return cb; } void Player::UnitBuildingSelection(void) { uint16_t i; - TYPE_UNIT * nearest_unit = NULL; uint32_t nearest_unit_dist = 0xFFFFFFFF; // Set maximum value uint32_t dist; - - for(i = 0; i < PLAYER_MAX_UNITS; i++) + + int8_t nearest_unit = NO_SELECTION; + + for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) { - TYPE_UNIT * u = &units[i]; - - if( (u->alive == false) || (u->selected == true) ) + TYPE_UNIT* u = &units[i]; + + if ( (u->alive == false) || (u->selected == true) ) { continue; } - + 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 - cursor_cb.x); - uint16_t dist_y = (u_cb.y - cursor_cb.y); - + + 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); + dist = (dist_x * dist_x) + (dist_y * dist_y); - - if(dist < nearest_unit_dist) + + if (dist < nearest_unit_dist) { nearest_unit_dist = dist; - nearest_unit = u; + nearest_unit = (int8_t)i; } } - - TYPE_BUILDING * nearest_building = NULL; - uint32_t nearest_building_dist = 0xFFFFFFFF; // Set maximum value - - for(i = 0; i < PLAYER_MAX_BUILDINGS; i++) - { - TYPE_BUILDING * b = &buildings[i]; - - if( (b->built == false) || (b->selected == true) ) - { - continue; - } - - TYPE_COLLISION_BLOCK cursor_cb = GetCursorPos(); - TYPE_COLLISION_BLOCK u_cb = {b->x, b->y, BuildingGetWidthFromID(b->id), BuildingGetHeightFromID(b->id) }; - - uint16_t dist_x = (u_cb.x + (u_cb.w >> 1) - cursor_cb.x + 4); - uint16_t dist_y = (u_cb.y + (u_cb.h >> 1) - cursor_cb.y + 4); - - dist = (dist_x * dist_x) + (dist_y * dist_y); - - if(dist < nearest_building_dist) - { - nearest_building_dist = dist; - nearest_building = b; - } - } - - if(nearest_building_dist <= nearest_unit_dist) - { - selectedUnit = NULL; - selectedBuilding = nearest_building; - } - else - { - selectedUnit = nearest_unit; - selectedBuilding = NULL; - } - - if( (nearest_unit_dist > MAX_SELECTION_DIST) - && - (nearest_building_dist > MAX_SELECTION_DIST) ) - { - selectedUnit = NULL; - selectedBuilding = NULL; - } - - /*char buf[8]; - - snprintf(buf, 8, "%lu", nearest_building_dist); - - GfxPrintText(buf, X_SCREEN_RESOLUTION - 32, 16); - - snprintf(buf, 8, "%lu", nearest_unit_dist); - - GfxPrintText(buf, X_SCREEN_RESOLUTION - 32, 24);*/ + + selectedUnitCandidate = nearest_unit; } -void Player::BuildingUnitActions(void) +void Player::ActionsMenu(void) { - const char* pActionStr = NULL; - - for(uint8_t i = 0; i < PLAYER_MAX_BUILDINGS; i++) - { - if(buildings[i].selected == true) - { - BuildingSelectedOptions(selectedBuilding); - break; - } - } - - if(pActionStr == NULL) - { - for(uint8_t i = 0; i < PLAYER_MAX_UNITS; i++) - { - if(units[i].selected == true) - { - pActionStr = UnitSelectedOptions(selectedUnit); - break; - } - } - } - - if(pActionStr != NULL) - { - GfxPrintTextFont(pActionStr, font3x3, 48, Y_SCREEN_RESOLUTION - 4); - } + if (showActionsMenu == true) + { + for (uint8_t i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) + { + TYPE_UNIT* ptrUnit = &units[i]; + + if (ptrUnit->selected == true) + { + uint8_t availableActions = UnitGetAvailableActions(ptrUnit); + + if (!(availableActions & (1 << showActionsMenu_index) ) ) + { + IncreaseShowActionsMenuIndex(); + } + + UNIT_ACTION action = (UNIT_ACTION) (showActionsMenu_index); + + const char* str = UnitGetActionString(action); + + GfxPrintText(str, 40, Y_SCREEN_RESOLUTION - 4); + + break; + } + + } + } + } void Player::Handler(void) -{ +{ + CameraSetLock(&Camera, showActionsMenu); + CameraHandler(&Camera); - + UnitBuildingSelection(); - - for(uint8_t i = 0; i < PLAYER_MAX_UNITS; i++) + + for (uint8_t i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) { - TYPE_UNIT * ptrUnit = &units[i]; - + TYPE_UNIT* ptrUnit = &units[i]; + UnitHandler(ptrUnit); } + ActionsMenu(); + ButtonHandler(); - - BuildingUnitActions(); - + GfxShowResources(&Resources); } void Player::ButtonHandler(void) { - static bool bCancelSelection = false; - - if(PadButtonPressed(PAD_A) == true) - { - if(progress_bar < ACCEPT_UNIT_BUILDING_OPTIONS_FRAMES) - { - progress_bar++; - } - } - - if(PadButtonReleased(PAD_A) == true) - { - /*TYPE_COLLISION_BLOCK cl; - - cl.x = SystemRand(0, 32); - cl.y = SystemRand(0, 32); - cl.w = BuildingGetWidthFromID(BARRACKS); - cl.h = BuildingGetHeightFromID(BARRACKS); - - if(createBuilding(BARRACKS, cl) == false) - { - GfxPrintText_Flash(F("Failed!")); - } - else - { - GfxPrintText_Flash(F("Building built!\0")); - }*/ - - for(uint8_t i = 0; i < PLAYER_MAX_UNITS; i++) - { - TYPE_UNIT * u = &units[i]; - - if(selectedUnit == u) - { - u->selected = true; - } - } - - for(uint8_t i = 0; i < PLAYER_MAX_BUILDINGS; i++) - { - TYPE_BUILDING * b = &buildings[i]; - - if(selectedBuilding == b) - { - b->selected = true; - } - } - } - else if(PadButtonPressedFrames(PAD_A, ACCEPT_UNIT_BUILDING_OPTIONS_FRAMES) == true) - { - for(uint8_t i = 0; i < PLAYER_MAX_UNITS; i++) - { - TYPE_UNIT* u = &units[i]; - - if(u->selected == true) - { - UnitAcceptAction(u); - break; - } - } - } - else if( (PadButtonPressedFrames(PAD_B, CANCEL_SELECTION_NO_FRAMES) == true) - && - (bCancelSelection == false) ) - { - for(uint8_t i = 0; i < PLAYER_MAX_UNITS; i++) - { - TYPE_UNIT * u = &units[i]; - - u->selected = false; - } - - for(uint8_t i = 0; i < PLAYER_MAX_BUILDINGS; i++) - { - TYPE_BUILDING * b = &buildings[i]; - - b->selected = false; - } - - selectedUnit = NULL; - selectedBuilding = NULL; - - bCancelSelection = true; - showUnitBuildingOptions = true; - } - else - { - // Button A is not pressed. Reset progress bar. - progress_bar = 0; - } + if (PadButtonPressed(PAD_A) == true) + { + ButtonAPressed(); + } + else if (PadButtonReleased(PAD_A) == true) + { + ButtonAReleased(); + } + else if (PadButtonPressed(PAD_B) == true) + { + ButtonBPressed(); + } + else if (PadButtonReleased(PAD_B) == true) + { + ButtonBReleased(); + } + else if (PadButtonReleased(PAD_LEFT) == true) + { + ButtonLeftReleased(); + } + else if (PadButtonReleased(PAD_RIGHT) == true) + { + ButtonRightReleased(); + } - if( (PadButtonReleased(PAD_B) == true) - && - (bCancelSelection == false) ) - { - if(showUnitBuildingOptions == false) - { - TYPE_COLLISION_BLOCK cursor = GetCursorPos(); - - for(uint8_t i = 0; i < PLAYER_MAX_UNITS; i++) - { - TYPE_UNIT * u = &units[i]; - - if(u->selected == true) - { - UnitMoveTo(u, cursor.x, cursor.y); - } - } - } - else - { - showUnitBuildingOptions = false; - } - } - else if( (PadButtonReleased(PAD_B) == true) - && - (bCancelSelection == true) ) - { - bCancelSelection = false; - UnitResetMenuLevel(); - } + +} + +void Player::ButtonAPressed(void) +{ + // Only increase progress bar when any unit has been previously selected + if (anyUnitSelected == true) + { + if (showActionsMenu == false) + { + if (showActionsMenu_counter < ACCEPT_UNIT_BUILDING_OPTIONS_FRAMES) + { + showActionsMenu_counter++; + } + } + } +} + + +void Player::ButtonAReleased(void) +{ + if (showActionsMenu_counter < ACCEPT_UNIT_BUILDING_OPTIONS_FRAMES) + { + if (selectedUnitCandidate != NO_SELECTION) + { + // When actions menu is not active, select unit if + // a candidate is present + TYPE_UNIT* ptrUnit = &units[selectedUnitCandidate]; + + ptrUnit->selected = true; + anyUnitSelected = true; + showActionsMenu_index = 0; + } + + showActionsMenu_counter = 0; + } + else if (showActionsMenu == true) + { + uint8_t i = 0; + + for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) + { + TYPE_UNIT* ptrUnit = &units[i]; + + if (ptrUnit->selected == true) + { + if (showActionsMenu_index == ACTION_CREATE_UNIT) + { + uint8_t w = UnitGetWidthFromID(ptrUnit->id); + uint8_t h = UnitGetHeightFromID(ptrUnit->id); + uint8_t new_pos_x = ptrUnit->x + SystemRand(w, w + (w >> 1)); + uint8_t new_pos_y = ptrUnit->y + SystemRand(h, h + (h >> 1)); + TYPE_COLLISION_BLOCK cb = {.x = new_pos_x, .y = new_pos_y}; + + createUnit(PEASANT, cb); + + break; + } + } + } + } + + showActionsMenu = (showActionsMenu_counter < ACCEPT_UNIT_BUILDING_OPTIONS_FRAMES)? false: true; +} + +void Player::ButtonBPressed(void) +{ + enum + { + CANCEL_SELECTION_FRAMES = 5 + }; + + if (anyUnitSelected == true) + { + if (unselectUnits_counter < CANCEL_SELECTION_FRAMES) + { + unselectUnits_counter++; + } + else + { + if (anyUnitSelected == true) + { + uint8_t i; + + // Cancel selection of all units + for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) + { + TYPE_UNIT* ptrUnit = &units[i]; + + if (ptrUnit->selected == true) + { + ptrUnit->selected = false; + } + } + + // Reset accumulated counter and flags + unselectUnits_counter = 0; + anyUnitSelected = false; + showActionsMenu = false; + showActionsMenu_counter = 0; + } + } + } +} + +void Player::ButtonBReleased(void) +{ + if (anyUnitSelected == true) + { + TYPE_COLLISION_BLOCK cursor = GetCursorPos(); + uint8_t i; + + for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) + { + TYPE_UNIT* ptrUnit = &units[i]; + + if (ptrUnit->selected == true) + { + UnitMoveTo(ptrUnit, cursor.x, cursor.y); + } + } + } + + // Reset accumulated counter + unselectUnits_counter = 0; +} + + +void Player::ButtonLeftReleased(void) +{ + if (showActionsMenu == true) + { + uint8_t i; + + for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) + { + TYPE_UNIT* ptrUnit = &units[i]; + + if (ptrUnit->selected == true) + { + // We need to iterate over all available actions + // for current unit. + uint8_t availableActions = UnitGetAvailableActions(ptrUnit); + + DEBUG_VAR(availableActions); + + for (uint8_t j = showActionsMenu_index - 1; j != showActionsMenu_index ; j--) + { + if (j > (sizeof(uint8_t) << 3)) + { + // Maximum index: 7 + j = (sizeof(uint8_t) << 3) - 1; + } + + if (availableActions & (1 << j)) + { + showActionsMenu_index = j; + break; + } + + } + } + } + } +} + +void Player::ButtonRightReleased(void) +{ + IncreaseShowActionsMenuIndex(); +} + +void Player::IncreaseShowActionsMenuIndex(void) +{ + if (showActionsMenu == true) + { + uint8_t i; + + for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) + { + TYPE_UNIT* ptrUnit = &units[i]; + + if (ptrUnit->selected == true) + { + // We need to iterate over all available actions + // for current unit. + uint8_t availableActions = UnitGetAvailableActions(ptrUnit); + + DEBUG_VAR(availableActions); + + for (uint8_t j = showActionsMenu_index + 1; j != showActionsMenu_index ; j++) + { + if (j >= (sizeof(uint8_t) << 3) ) + { + j = 0; + } + + if (availableActions & (1 << j)) + { + showActionsMenu_index = j; + break; + } + } + } + } + } } |
