diff options
Diffstat (limited to 'Player.cpp')
| -rw-r--r-- | Player.cpp | 761 |
1 files changed, 19 insertions, 742 deletions
@@ -1,762 +1,39 @@ /* ************************************** - * Includes * + * Includes * * **************************************/ #include "Player.h" -#include "Pad.h" -#include "Unit.h" -#include "Gameplay.h" +#include <string.h> /* ************************************** - * Defines * + * Defines * * **************************************/ -#define ACCEPT_UNIT_BUILDING_OPTIONS_FRAMES 5 -#define MAX_SELECTION_DIST 400 -#define NO_SELECTION -1 - /* ************************************** - * Local variables * + * Structs and enums * * **************************************/ -Player::Player(void) -{ -} - -Player::~Player(void) -{ - -} - -void Player::Init(void) -{ - enum - { - DEFAULT_WOOD = 1000, - DEFAULT_GOLD = 1000, - DEFAULT_FOOD = 1000 - }; - - uint8_t i; - - unit_i = 0; - - selectedUnitCandidate = NO_SELECTION; - - CameraInit(&Camera); - UnitInit(); - - for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) - { - memset(&units[i], 0, sizeof(TYPE_UNIT)); - } - - TYPE_COLLISION_BLOCK cb; - - Resources.Wood = DEFAULT_WOOD; - Resources.Gold = DEFAULT_GOLD; - Resources.Food = DEFAULT_FOOD; - - cb.x = SystemRand(0, 24); - cb.y = SystemRand(0, 24); - - createUnit(TOWN_CENTER, cb); - - 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; - - createUnit(PEASANT, cb); -} - -void Player::showHealth(uint8_t hp) -{ - enum - { - HP_TEXT_X = 4, - HP_TEXT_Y = Y_SCREEN_RESOLUTION - 4, - }; - - char str[8]; - - str[0] = 'H'; - str[1] = 'P'; - str[2] = '='; - - GfxFillRectangle(0, Y_SCREEN_RESOLUTION - 5, X_SCREEN_RESOLUTION, 8, GFX_WHITE); - - Systemitoa(&str[3], sizeof(str) - 3, hp); - - GfxPrintTextFont(str, font3x3, HP_TEXT_X, HP_TEXT_Y); -} - -void Player::DrawHandler(void) -{ - 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]; - - if (u->alive == false) - { - continue; - } - - bool selected = false; - - if (selectedUnitCandidate != NO_SELECTION) - { - selected = (i == selectedUnitCandidate); - } - - UnitDraw(u, &Camera, selected); - - if ( (u->selected != false) && (bAnyoneSelected == false) ) - { - bAnyoneSelected = true; - } - } - - if (human != false) - { - MenuDrawHandler(); - } -} - -void Player::MenuDrawHandler(void) -{ - ActionsMenu(); - - ShowResources(); -} - -void Player::ShowResources(void) -{ - char str[8]; - size_t i; - - str[1] = '='; - - gb.display.setColor(GFX_GRAY); - gb.display.fillRect(0, 0, X_SCREEN_RESOLUTION, 8); - - str[0] = 'W'; - - Systemitoa(&str[2], 6, Resources.Wood); - - GfxPrintTextFont(str, font3x3, 8, 1); - - str[0] = 'G'; - - Systemitoa(&str[2], 6, Resources.Gold); - - GfxPrintTextFont(str, font3x3, 2, 5); - - str[0] = 'F'; - - Systemitoa(&str[2], 6, Resources.Food); - - GfxPrintTextFont(str, font3x3, 42, 1); - - i = Systemitoa(str, 3, getAliveUnits()); - - str[i++] = '/'; - - Systemitoa(&str[i], sizeof(str) - i, PLAYER_MAX_UNITS_BUILDINGS); - - GfxPrintTextFont(str, font3x3, 42, 5); -} - - -bool Player::checkNewBuildingPosition(TYPE_COLLISION_BLOCK * cb) -{ - uint8_t i; - TYPE_COLLISION_BLOCK bldgCB; - bool success; - static uint8_t max_tries = 0; - - for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) - { - TYPE_UNIT *ptrUnit = &units[i]; - success = false; - - if (ptrUnit->building == false) - { - continue; - } - - bldgCB.x = ptrUnit->x; - bldgCB.y = ptrUnit->y; - bldgCB.w = UnitGetWidthFromID(ptrUnit->id); - bldgCB.h = UnitGetHeightFromID(ptrUnit->id); - - if (SystemCollisionCheck(cb, &bldgCB) != false) - { - success = false; - } - else - { - success = true; - } - - if (success == false) - { - cb->x = SystemRand(0, 128); - cb->y = SystemRand(0, 128); - - if (++max_tries < 16) - { - if (checkNewBuildingPosition(cb) == false) - { - return false; - } - else - { - return true; - } - } - else - { - return false; - } - } - } - - max_tries = 0; - return true; -} - -uint8_t Player::getAliveUnits(void) -{ - uint8_t ret = 0; - - for (uint8_t i = 0; i < unit_i; i++) - { - if (units[i].alive != false) - { - ret++; - } - } - - return ret; -} - -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 (getAliveUnits() < PLAYER_MAX_UNITS_BUILDINGS) - { - for (uint8_t i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) - { - if (units[i].alive == 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; - ptrNewUnit->building = (id > MAX_UNIT_ID); - - /* Substract resources from player */ - Resources.Wood -= res.Wood; - Resources.Gold -= res.Gold; - Resources.Food -= res.Food; - return; - } - } - } - else - { - GfxPrintText_Flash(F("Popul. limit")); - } -} - -TYPE_COLLISION_BLOCK Player::GetCursorPos(void) -{ - enum - { - MOUSE_W = 8, - MOUSE_H = 8 - }; - - 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 = MOUSE_W; - cb.h = MOUSE_H; - - return cb; -} - -void Player::UnitBuildingSelection(void) -{ - enum - { - X_MAX_ALLOWED_DISTANCE = X_SCREEN_RESOLUTION >> 1, - Y_MAX_ALLOWED_DISTANCE = Y_SCREEN_RESOLUTION >> 1 - }; - - uint16_t i; - uint32_t nearest_unit_dist = 0xFFFFFFFF; // Set maximum value - uint32_t dist = nearest_unit_dist; - - 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 != false) ) - { - continue; - } - - TYPE_COLLISION_BLOCK cursor_cb = GetCursorPos(); - TYPE_COLLISION_BLOCK u_cb = {u->x, u->y, UnitGetWidthFromID(u->id), UnitGetHeightFromID(u->id) }; - - 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); - - if (dist < nearest_unit_dist) - { - nearest_unit_dist = dist; - nearest_unit = (int8_t)i; - } - } - - selectedUnitCandidate = nearest_unit; -} - -void Player::ActionsMenu(void) -{ - enum - { - 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) - { - 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) -{ - CameraSetLock(&Camera, showActionsMenu); - - CameraHandler(&Camera); - - UnitBuildingSelection(); - - UnitHandler(units, sizeof(units) / sizeof(units[0])); - - ButtonHandler(); -} - -void Player::ButtonHandler(void) -{ - if (PadButtonPressed(PAD_A) != false) - { - ButtonAPressed(); - } - else if (PadButtonReleased(PAD_A) != false) - { - ButtonAReleased(); - } - else if (PadButtonPressed(PAD_B) != false) - { - ButtonBPressed(); - } - else if (PadButtonReleased(PAD_B) != false) - { - ButtonBReleased(); - } - else if (PadButtonReleased(PAD_LEFT) != false) - { - ButtonLeftReleased(); - } - else if (PadButtonReleased(PAD_RIGHT) != false) - { - ButtonRightReleased(); - } -} - -void Player::ButtonAPressed(void) -{ - // Only increase progress bar when any unit has been previously selected - if (anyUnitSelected != false) - { - 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 != false) - { - uint8_t i = 0; - - for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) - { - TYPE_UNIT *ptrUnit = &units[i]; - - if (ptrUnit->selected != false) - { - showActionsMenu_counterLevel1 = 0; - - switch (showActionsMenu_index) - { - case ACTION_CREATE_PEASANT: - ActionCreateUnit(ptrUnit, PEASANT); - break; - - case ACTION_CREATE_SOLDIER: - ActionCreateUnit(ptrUnit, SOLDIER); - break; - - case ACTION_BUILD_BARRACKS: - ActionCreateBuilding(BARRACKS); - break; - - case ACTION_BUILD_TOWER_CENTER: - ActionCreateBuilding(TOWN_CENTER); - break; - - default: - break; - } - - break; - } - } - } - - showActionsMenu = (showActionsMenu_counter < ACCEPT_UNIT_BUILDING_OPTIONS_FRAMES)? false: true; -} - -void Player::ActionCreateUnit(TYPE_UNIT *ptrUnit, TYPE_UNIT_ID unit) -{ - enum - { - MAX_RETRIES = 16 - }; - - uint8_t retries = 0; - - do - { - uint8_t w = UnitGetWidthFromID(ptrUnit->id); - uint8_t h = UnitGetHeightFromID(ptrUnit->id); - uint8_t new_pos_x = ptrUnit->x + SystemRand(0, 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, - .w = UnitGetWidthFromID(unit), - .h = UnitGetHeightFromID(unit)}; - - if (UnitCheckCollisionAgainstOtherUnits(&cb, units, NULL) == false) - { - createUnit(unit, cb); - return; - } - - }while (++retries < MAX_RETRIES); +/* ************************************** + * Local variables * + * **************************************/ - /* Will only get here if we could not create the new unit */ - GfxPrintText_Flash(F("Could not create unit")); -} +/* ************************************** + * Functions definition * + * **************************************/ -void Player::ActionCreateBuilding(TYPE_UNIT_ID bldg) +/*****************************************************************//** + * + * \brief Constructor for Player class. + * + *********************************************************************/ +Player::Player(const char* const strPlayerName) { - TYPE_COLLISION_BLOCK cb = GetCursorPos(); - - cb.w = UnitGetWidthFromID(bldg); - cb.w = UnitGetHeightFromID(bldg); - - if (UnitCheckCollisionAgainstOtherUnits(&cb, units, NULL) == false) + if (strPlayerName != NULL) { - createUnit(bldg, cb); + strncpy(_name, strPlayerName, MAX_NAME_LENGTH); } else { - GfxPrintText_Flash(F("Cannot build here")); - } -} - -void Player::ButtonBPressed(void) -{ - enum - { - CANCEL_SELECTION_FRAMES = 5 - }; - - if (anyUnitSelected != false) - { - if (unselectUnits_counter < CANCEL_SELECTION_FRAMES) - { - unselectUnits_counter++; - } - else - { - if (anyUnitSelected != false) - { - 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 != false) - { - ptrUnit->selected = false; - } - } - - /* Reset accumulated counter and flags */ - unselectUnits_counter = 0; - anyUnitSelected = false; - showActionsMenu = false; - showActionsMenu_counter = 0; - } - } - } -} - -void Player::ButtonBReleased(void) -{ - if (anyUnitSelected != false) - { - 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 != false) - { - if (showActionsMenu == false) - { - UnitMoveTo(ptrUnit, cursor.x, cursor.y); - } - else - { - showActionsMenu = false; - showActionsMenu_counter = 0; - } - } - } - } - - /* Reset accumulated counter */ - unselectUnits_counter = 0; -} - - -void Player::ButtonLeftReleased(void) -{ - if (showActionsMenu != false) - { - uint8_t i; - - for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) - { - TYPE_UNIT *ptrUnit = &units[i]; - - if (ptrUnit->selected != false) - { - /* We need to iterate over all available actions - * for current unit. */ - uint8_t availableActions = UnitGetAvailableActions(ptrUnit); - - 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 != false) - { - uint8_t i; - - for (i = 0; i < PLAYER_MAX_UNITS_BUILDINGS; i++) - { - TYPE_UNIT *ptrUnit = &units[i]; - - if (ptrUnit->selected != false) - { - /* We need to iterate over all available actions - * for current unit. */ - uint8_t availableActions = UnitGetAvailableActions(ptrUnit); - - 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; - } - } - } - } + /* Undefined player name. */ } } |
