|
|
@ -1,5 +1,7 @@ |
|
|
|
#include <iostream> |
|
|
|
|
|
|
|
#include <map> |
|
|
|
|
|
|
|
#include "graphics/graphics.hpp" |
|
|
|
#include "input/input.hpp" |
|
|
|
|
|
|
@ -8,6 +10,8 @@ |
|
|
|
#include "Entity.hpp" |
|
|
|
#include "Levels.hpp" |
|
|
|
|
|
|
|
static int TurnCounter = 0; |
|
|
|
|
|
|
|
static std::vector<std::string> GameLog; |
|
|
|
|
|
|
|
// @Callback: CustomLogOutputFunc
|
|
|
@ -42,8 +46,22 @@ void ConsoleAndGameLogOutput(const gv::Logging::Record& record) |
|
|
|
|
|
|
|
if (IsInfo) |
|
|
|
{ |
|
|
|
static int lastTurnLog = 0; |
|
|
|
|
|
|
|
std::string gameLogAction(buffer); |
|
|
|
GameLog.push_back(gameLogAction); |
|
|
|
|
|
|
|
// Append logs to the same line if they occur on the same turn
|
|
|
|
if (lastTurnLog == TurnCounter && !GameLog.empty() && gameLogAction != GameLog.back()) |
|
|
|
{ |
|
|
|
std::string& currentTurnLog = GameLog.back(); |
|
|
|
currentTurnLog += ". "; |
|
|
|
currentTurnLog += gameLogAction; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
GameLog.push_back(gameLogAction); |
|
|
|
lastTurnLog = TurnCounter; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -68,16 +86,71 @@ void initializeDisplayText(text& text) |
|
|
|
std::cout << "err: cannot load default text font\n"; |
|
|
|
} |
|
|
|
|
|
|
|
struct GameInput |
|
|
|
{ |
|
|
|
inputManager& inp; |
|
|
|
std::map<inputCode::keyCode, bool> keyTapStates; |
|
|
|
|
|
|
|
GameInput(inputManager& newInput) : inp(newInput) |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
bool Tapped(inputCode::keyCode key) |
|
|
|
{ |
|
|
|
bool isPressed = inp.isPressed(key); |
|
|
|
|
|
|
|
std::map<inputCode::keyCode, bool>::iterator findIt = keyTapStates.find(key); |
|
|
|
if (findIt != keyTapStates.end()) |
|
|
|
{ |
|
|
|
if (isPressed) |
|
|
|
{ |
|
|
|
if (findIt->second) |
|
|
|
{ |
|
|
|
// Wasn't tapped this frame
|
|
|
|
return false; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
findIt->second = true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
findIt->second = false; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
keyTapStates[key] = true; |
|
|
|
return isPressed; |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
void SetTextColor(text& text, RLColor& color) |
|
|
|
{ |
|
|
|
text.setColor(color.r, color.g, color.b, color.a); |
|
|
|
} |
|
|
|
|
|
|
|
int main(int argc, char const* argv[]) |
|
|
|
{ |
|
|
|
const int WindowWidth = 2500; |
|
|
|
const int WindowHeight = 1600; |
|
|
|
|
|
|
|
const int TileTextHeight = 32; |
|
|
|
const int TileTextWidth = TileTextHeight / 2; |
|
|
|
const int ViewTileRightMargin = 2; |
|
|
|
|
|
|
|
const int SidebarTileWidth = 30; |
|
|
|
|
|
|
|
const int ViewTileRightMargin = SidebarTileWidth + 1; |
|
|
|
const int ViewTileBottomMargin = 2; |
|
|
|
const int ViewTileWidth = (WindowWidth / TileTextWidth) - ViewTileRightMargin; |
|
|
|
const int ViewTileHeight = (WindowHeight / TileTextHeight) - ViewTileBottomMargin; |
|
|
|
|
|
|
|
const int SidebarStartX = (ViewTileWidth + 1) * TileTextWidth; |
|
|
|
const int SidebarStartY = 0 * TileTextHeight; |
|
|
|
|
|
|
|
const int LogX = 10; |
|
|
|
const int LogY = ViewTileHeight * TileTextHeight; |
|
|
|
|
|
|
@ -90,6 +163,7 @@ int main(int argc, char const* argv[]) |
|
|
|
initializeWindow(win); |
|
|
|
|
|
|
|
inputManager inp(&win); |
|
|
|
GameInput gameInp(inp); |
|
|
|
|
|
|
|
text displayText; |
|
|
|
initializeDisplayText(displayText); |
|
|
@ -104,35 +178,104 @@ int main(int argc, char const* argv[]) |
|
|
|
player.X = ViewTileWidth / 2; |
|
|
|
player.Y = ViewTileHeight / 2; |
|
|
|
|
|
|
|
RLEntity lookModeCursor; |
|
|
|
|
|
|
|
RLMap testMap(ViewTileWidth, ViewTileHeight); |
|
|
|
createTestMap(testMap); |
|
|
|
// createTestMap(testMap);
|
|
|
|
createTestMap2(testMap); |
|
|
|
|
|
|
|
RLEntity skeleton; |
|
|
|
skeleton.X = (ViewTileWidth / 2) + 3; |
|
|
|
skeleton.Y = ViewTileHeight / 2; |
|
|
|
skeleton.Speed = 1; |
|
|
|
skeleton.Type = SKELETON_TYPE; |
|
|
|
skeleton.Color = {ENEMY_COLOR_NORMAL}; |
|
|
|
skeleton.Description = "a skeleton"; |
|
|
|
skeleton.Stats["HP"] = {"Health", PLAYER_STARTING_MAX_HEALTH, PLAYER_STARTING_MAX_HEALTH}; |
|
|
|
|
|
|
|
std::vector<RLEntity> npcs{skeleton}; |
|
|
|
|
|
|
|
int camXOffset = 0; |
|
|
|
int camYOffset = 0; |
|
|
|
|
|
|
|
while (!win.shouldClose() && !inp.isPressed(inputCode::Return) && |
|
|
|
!inp.isPressed(inputCode::Escape)) |
|
|
|
bool lookMode = false; |
|
|
|
|
|
|
|
while (!win.shouldClose() && !inp.isPressed(inputCode::Return)) |
|
|
|
{ |
|
|
|
bool playerTurnPerformed = false; |
|
|
|
|
|
|
|
//
|
|
|
|
// Input
|
|
|
|
//
|
|
|
|
|
|
|
|
// Player movement
|
|
|
|
if (inp.isPressed(inputCode::Up)) |
|
|
|
// Escape exits modes or closes the game
|
|
|
|
if (gameInp.Tapped(inputCode::Escape)) |
|
|
|
{ |
|
|
|
player.Y -= 1; |
|
|
|
if (lookMode) |
|
|
|
lookMode = false; |
|
|
|
else |
|
|
|
// Close the game
|
|
|
|
break; |
|
|
|
} |
|
|
|
if (inp.isPressed(inputCode::Down)) |
|
|
|
|
|
|
|
// Look mode
|
|
|
|
if (gameInp.Tapped(inputCode::L)) |
|
|
|
{ |
|
|
|
player.Y += 1; |
|
|
|
// Entering look mode; set the cursor to the player's position
|
|
|
|
if (!lookMode) |
|
|
|
{ |
|
|
|
lookModeCursor.X = player.X; |
|
|
|
lookModeCursor.Y = player.Y; |
|
|
|
} |
|
|
|
lookMode = !lookMode; |
|
|
|
} |
|
|
|
if (inp.isPressed(inputCode::Left)) |
|
|
|
|
|
|
|
// Directional navigation
|
|
|
|
int deltaX = 0; |
|
|
|
int deltaY = 0; |
|
|
|
if (gameInp.Tapped(inputCode::Up)) |
|
|
|
deltaY -= 1; |
|
|
|
if (gameInp.Tapped(inputCode::Down)) |
|
|
|
deltaY += 1; |
|
|
|
if (gameInp.Tapped(inputCode::Left)) |
|
|
|
deltaX -= 1; |
|
|
|
if (gameInp.Tapped(inputCode::Right)) |
|
|
|
deltaX += 1; |
|
|
|
|
|
|
|
if (lookMode) |
|
|
|
{ |
|
|
|
player.X -= 1; |
|
|
|
if (deltaX || deltaY) |
|
|
|
{ |
|
|
|
lookModeCursor.X += deltaX; |
|
|
|
lookModeCursor.Y += deltaY; |
|
|
|
} |
|
|
|
} |
|
|
|
if (inp.isPressed(inputCode::Right)) |
|
|
|
else |
|
|
|
{ |
|
|
|
player.X += 1; |
|
|
|
// Player movement
|
|
|
|
if (canMoveTo(player, deltaX, deltaY, testMap)) |
|
|
|
{ |
|
|
|
player.X += deltaX; |
|
|
|
player.Y += deltaY; |
|
|
|
|
|
|
|
// Decide whether we need to make this a turn
|
|
|
|
if (abs(deltaX) >= player.Speed || abs(deltaY) >= player.Speed) |
|
|
|
{ |
|
|
|
playerTurnPerformed = true; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
LOGI << "You bump into a wall"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//
|
|
|
|
// Turn update
|
|
|
|
//
|
|
|
|
if (playerTurnPerformed) |
|
|
|
{ |
|
|
|
TurnCounter++; |
|
|
|
} |
|
|
|
|
|
|
|
//
|
|
|
@ -149,16 +292,28 @@ int main(int argc, char const* argv[]) |
|
|
|
static std::string buffer = ""; |
|
|
|
buffer.clear(); |
|
|
|
|
|
|
|
if (player.X == tileX && player.Y == tileY) |
|
|
|
bool shouldDrawTile = true; |
|
|
|
for (RLEntity& npc : npcs) |
|
|
|
{ |
|
|
|
if (npc.X == tileX && npc.Y == tileY) |
|
|
|
{ |
|
|
|
buffer += npc.Type; |
|
|
|
SetTextColor(displayText, npc.Color); |
|
|
|
|
|
|
|
shouldDrawTile = false; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (buffer.empty() && player.X == tileX && player.Y == tileY) |
|
|
|
{ |
|
|
|
buffer += player.Type; |
|
|
|
displayText.setColor(PLAYER_COLOR_NORMAL); |
|
|
|
SetTextColor(displayText, player.Color); |
|
|
|
} |
|
|
|
else |
|
|
|
else if (buffer.empty()) |
|
|
|
{ |
|
|
|
buffer += currentTile.Type; |
|
|
|
displayText.setColor(currentTile.Color.r, currentTile.Color.g, |
|
|
|
currentTile.Color.b, currentTile.Color.a); |
|
|
|
SetTextColor(displayText, currentTile.Color); |
|
|
|
} |
|
|
|
|
|
|
|
displayText.setText(buffer); |
|
|
@ -167,10 +322,88 @@ int main(int argc, char const* argv[]) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Draw look mode cursor
|
|
|
|
if (lookMode) |
|
|
|
{ |
|
|
|
static std::string lookModeCursorText(LOOK_MODE_CURSOR); |
|
|
|
displayText.setText(lookModeCursorText); |
|
|
|
displayText.setColor(LOOK_CURSOR_COLOR); |
|
|
|
displayText.setPosition(TileTextWidth * lookModeCursor.X, |
|
|
|
TileTextHeight * lookModeCursor.Y); |
|
|
|
win.draw(&displayText); |
|
|
|
} |
|
|
|
|
|
|
|
//
|
|
|
|
// Draw sidebar
|
|
|
|
//
|
|
|
|
{ |
|
|
|
int currentRowY = SidebarStartY; |
|
|
|
displayText.setColor(LOG_COLOR_NORMAL); |
|
|
|
displayText.setText("Stats"); |
|
|
|
displayText.setPosition(SidebarStartX, SidebarStartY); |
|
|
|
win.draw(&displayText); |
|
|
|
currentRowY += TileTextHeight * 2; |
|
|
|
|
|
|
|
for (std::pair<const std::string, RLCombatStat>& stat : player.Stats) |
|
|
|
{ |
|
|
|
std::string statName(stat.second.Name); |
|
|
|
std::string statValue(std::to_string(stat.second.Value)); |
|
|
|
std::string statText(statName); |
|
|
|
// Add justify spaces
|
|
|
|
for (unsigned int i = 0; |
|
|
|
i < SidebarTileWidth - (statName.size() + statValue.size()) - 1; i++) |
|
|
|
statText += ' '; |
|
|
|
statText += statValue; |
|
|
|
|
|
|
|
displayText.setPosition(SidebarStartX, currentRowY); |
|
|
|
displayText.setText(statText); |
|
|
|
win.draw(&displayText); |
|
|
|
currentRowY += TileTextHeight; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//
|
|
|
|
// Draw log
|
|
|
|
// Draw log/status
|
|
|
|
//
|
|
|
|
if (GameLog.size()) |
|
|
|
if (lookMode) |
|
|
|
{ |
|
|
|
std::string description; |
|
|
|
RLTile& lookTile = testMap.At(lookModeCursor.X, lookModeCursor.Y); |
|
|
|
std::string tileDescription = GetTileDescription(lookTile); |
|
|
|
std::string npcDescription; |
|
|
|
for (RLEntity& npc : npcs) |
|
|
|
{ |
|
|
|
if (npc.X == lookModeCursor.X && npc.Y == lookModeCursor.Y) |
|
|
|
{ |
|
|
|
npcDescription += npc.Description; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!tileDescription.empty() || !npcDescription.empty()) |
|
|
|
{ |
|
|
|
if (player.SamePos(lookModeCursor)) |
|
|
|
description += "You are standing on "; |
|
|
|
else if (description.empty()) |
|
|
|
description += "You see "; |
|
|
|
|
|
|
|
if (!npcDescription.empty()) |
|
|
|
{ |
|
|
|
description += npcDescription; |
|
|
|
description += " standing on "; |
|
|
|
description += tileDescription; |
|
|
|
} |
|
|
|
else |
|
|
|
description += tileDescription; |
|
|
|
} |
|
|
|
|
|
|
|
displayText.setText(description); |
|
|
|
displayText.setColor(LOG_COLOR_NORMAL); |
|
|
|
displayText.setPosition(LogX, LogY); |
|
|
|
|
|
|
|
win.draw(&displayText); |
|
|
|
} |
|
|
|
else if (GameLog.size()) |
|
|
|
{ |
|
|
|
displayText.setText(GameLog.back()); |
|
|
|
displayText.setColor(LOG_COLOR_NORMAL); |
|
|
|