PocketEmpires/HumanPlayer.cpp

187 lines
5.4 KiB
C++

/* *******************************************************************
* Includes
* ******************************************************************/
#include "HumanPlayer.h"
#include "System.h"
#include "Sprite.h"
#include "Cursor.h"
#include <Buttons.h>
#include <Gamebuino.h>
#include <stdint.h>
#include <string.h>
/* *******************************************************************
* Defines
* ******************************************************************/
/* *******************************************************************
* Types definition
* ******************************************************************/
/* *******************************************************************
* Global variables definition
* ******************************************************************/
/* *******************************************************************
* Local variables definition
* ******************************************************************/
/*****************************************************************//**
*
* \brief Bitmap data for idle UNIT_ID_PEASANT.
*
*********************************************************************/
static const PROGMEM uint8_t au8MouseSprData[] =
{
8,
8,
0xFC,
0x84,
0x88,
0x84,
0xA2,
0xD1,
0x0A,
0x04
};
/* *******************************************************************
* Local prototypes declaration
* ******************************************************************/
/* *******************************************************************
* Functions definition
* ******************************************************************/
/*****************************************************************//**
*
* \brief Constructor for HumanPlayer class.
*
*********************************************************************/
HumanPlayer::HumanPlayer(const char* const strPlayerName, const Camera& cam) :
Player(strPlayerName),
_eState(PLAYER_STATE_IDLE),
_cam(cam),
_cursor(cam),
_ABtnFrames(0),
_BBtnFrames(0)
{
_unitsMap[0].create(Unit::UNIT_ID_PEASANT, 16, 16);
}
/*****************************************************************//**
*
* \brief Periodical event handler that calls HumanPlayer subtasks.
*
*********************************************************************/
void HumanPlayer::handler(void)
{
/* Execute HumanPlayerBtn submodule. */
buttonHandler();
/* Execute parent class unit handler. */
Player::handleUnits();
drawHandler();
}
/*****************************************************************//**
*
* \brief This function draws all units and player UI.
*
*********************************************************************/
void HumanPlayer::drawHandler(void)
{
/* Execute base class Unit drawHandler. */
Player::drawUnits();
if (_eState == PLAYER_STATE_UNIT_MENU)
{
gb.display.setColor(BLACK);
gb.display.drawRect(0, 40, 84, 8);
}
/* Configure cursor sprite object. */
Sprite cursorSpr(au8MouseSprData, false, INVERT);
/* Transfer Cursor to Sprite coordinates. */
cursorSpr.setPos(_cursor.getScreenX(), _cursor.getScreenY());
/* Draw cursor sprite. */
cursorSpr.draw();
}
/*****************************************************************//**
*
* \brief This function looks for units nearby and selects them.
* If no units can be selected, player state remains
* unchanged.
*
* \return New player state.
*
* \see \ref tPlayerState.
*
*********************************************************************/
enum HumanPlayer::tPlayerState HumanPlayer::selectUnit(void)
{
for (size_t szUnit = 0; szUnit < MAX_UNITS; szUnit++)
{
/* Select Unit object from internal table. */
Unit& u = _unitsMap[szUnit];
if (u.isAlive())
{
if (not u.isSelected())
{
enum
{
/* Maximum distance, in pixels,
* between unit and cursor
* in order to select a unit. */
MAX_SELECTION_DISTANCE = 32
};
/* Extract Unit object X position. */
const uint16_t x = u.getX();
/* Extract Unit object Y position. */
const uint16_t y = u.getY();
/* Extract cursor X. */
const uint16_t cx = _cursor.getX();
/* Extract cursor Y. */
const uint16_t cy = _cursor.getY();
/* Calculate X distance between cursor and unit. */
const uint16_t x_dist = (uint16_t)abs((int)x - (int)cx);
/* Calculate Y distance between cursor and unit. */
const uint16_t y_dist = (uint16_t)abs((int)y - (int)cy);
if ((x_dist < MAX_SELECTION_DISTANCE)
&&
(y_dist < MAX_SELECTION_DISTANCE))
{
/* Select unit. */
u.setSelected(true);
/* Player has entered unit selection mode. */
return PLAYER_STATE_UNIT_SELECTED;
}
}
else
{
/* Unit is already selected. Continue. */
}
}
else
{
/* Unit is not alive. Continue. */
}
}
return PLAYER_STATE_IDLE;
}