Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 40 additions & 37 deletions src/Client/Phases/ActionPhase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ namespace TheTraitor {
ActionPhase::ActionPhase(sf::RenderWindow& window, sf::Font& font, const std::vector<sf::Texture>& avatarTextures, std::string executableFolderPath)
: window(window), font(font), avatarTextures(avatarTextures),
viewData{ false, ActionType::TradePact, CountryType(NONE), GamePhase(NONE), "", "", "", 0, false },
actionMenu({ 310, (float)window.getSize().y - 40 }),
eventLogMenu({ (float)window.getSize().x - 870, 300 }),
actionMenu({ 310, 1080 - 40 }),
eventLogMenu({ 1920 - 870, 300 }),
eventLogString(""),
eventLogMenuLabel(font, "Event Log"),
eventLogLabel(font, eventLogString, 20),
infoMenu({ 480, (float)window.getSize().y - 40 }),
infoMenu({ 480, 1080 - 40 }),
topBar({ 1050, 120 }),
roundLabel(font, "Round 1"),
phaseLabel(font, "Action Phase"),
timerLabel(font, "01:02"),
playerInfo({ {font, font, font, font}}),
playerInfo({ {font, font, font, font} }),
economyIconTexture(executableFolderPath + "/assets/icons/icons8-cash-64.png"),
healthIconTexture(executableFolderPath + "/assets/icons/icons8-medical-kit-64.png"),
educationIconTexture(executableFolderPath + "/assets/icons/icons8-book-64.png"),
Expand Down Expand Up @@ -96,17 +96,17 @@ namespace TheTraitor {
buttonIndex++;
}

eventLogMenu.setPosition({ 350, (float)window.getSize().y - 320 });
eventLogMenu.setPosition({ 350, 1080 - 320 });
eventLogMenu.setFillColor(sf::Color::Black);
eventLogMenu.setOutlineThickness(5);
eventLogMenu.setOutlineColor(sf::Color::White);


eventLogMenuLabel.setPosition({ 370, (float)window.getSize().y - 300 });
eventLogLabel.setPosition({ 370, (float)window.getSize().y - 250 });
eventLogMenuLabel.setPosition({ 370, 1080 - 300 });
eventLogLabel.setPosition({ 370, 1080 - 250 });


infoMenu.setPosition({ (float)window.getSize().x - 500, 20 });
infoMenu.setPosition({ 1920 - 500, 20 });
infoMenu.setFillColor(sf::Color::Black);
infoMenu.setOutlineThickness(5);
infoMenu.setOutlineColor(sf::Color::White);
Expand Down Expand Up @@ -212,11 +212,12 @@ namespace TheTraitor {
if (player.getRole()->getName() == "Traitor") {
isTraitor = true;
cachedIsTraitor = true;
} else {
}
else {
isTraitor = false;
cachedIsTraitor = false;
}

if (player.getCountry()->isDestroyed()) {
isLocalPlayerDestroyed = true;
}
Expand Down Expand Up @@ -290,7 +291,8 @@ namespace TheTraitor {
// Logic to visually fade buttons if not allowed
if (!isActionAllowed(type)) {
btn.setDisabled(true);
} else {
}
else {
btn.setDisabled(false);
}

Expand All @@ -299,7 +301,7 @@ namespace TheTraitor {
type == ActionType::SpreadPlague)) {
btn.setShapeOutlineColor(sf::Color(255, 255, 255, 128));
btn.setLabelFillColor(sf::Color(255, 255, 255, 128));

// Ensure innocent secret buttons are disabled (logic covered by isActionAllowed too)
btn.setDisabled(true);
}
Expand Down Expand Up @@ -332,14 +334,14 @@ namespace TheTraitor {

// Highlight player info if country is hovered or selected
sf::RectangleShape highlightRect;
highlightRect.setPosition({ (float)window.getSize().x - 500, (float)posY - 10 });
highlightRect.setPosition({ 1920 - 500, (float)posY - 10 });
highlightRect.setSize({ 480, 190 });
highlightRect.setFillColor(sf::Color::Transparent);

CountryType type = player.getCountry()->getType();
int typeIndex = static_cast<int>(type);
bool isTarget = false;

// Cache local player country type
if (isLocal) {
cachedLocalPlayerCountryType = type;
Expand All @@ -348,29 +350,30 @@ namespace TheTraitor {
if (type != CountryType::NONE && typeIndex >= 0 && typeIndex < 5) {
sf::Color currentColor = (*allCountries[typeIndex].second)[0].color;
if (currentColor == countrySelectedColor) {
highlightRect.setFillColor(sf::Color(150, 0, 50, 128));
highlightRect.setFillColor(sf::Color(150, 0, 50, 128));
isTarget = true;
} else if (currentColor == countryHoverColor) {
}
else if (currentColor == countryHoverColor) {
highlightRect.setFillColor(sf::Color(0, 150, 50, 128));
}
}
window.draw(highlightRect);

name.setString(displayName);
name.setCharacterSize(30);
name.setPosition({ (float)window.getSize().x - 480, (float)posY });
economyIconSprite.setPosition({ (float)window.getSize().x - 480, (float)posY + 80 });
name.setPosition({ 1920 - 480, (float)posY });
economyIconSprite.setPosition({ 1920 - 480, (float)posY + 80 });
economy.setString(std::to_string(player.getCountry()->getEconomy()));
economy.setCharacterSize(25);
economy.setPosition({ (float)window.getSize().x - 400, (float)posY + 110 });
healthIconSprite.setPosition({ (float)window.getSize().x - 360, (float)posY + 80 });
economy.setPosition({ 1920 - 400, (float)posY + 110 });
healthIconSprite.setPosition({ 1920 - 360, (float)posY + 80 });
health.setString(std::to_string(player.getCountry()->getHealth()));
health.setCharacterSize(25);
health.setPosition({ (float)window.getSize().x - 280, (float)posY + 110 });
educationIconSprite.setPosition({ (float)window.getSize().x - 240, (float)posY + 90 });
health.setPosition({ 1920 - 280, (float)posY + 110 });
educationIconSprite.setPosition({ 1920 - 240, (float)posY + 90 });
education.setString(std::to_string(player.getCountry()->getEducation()));
education.setCharacterSize(25);
education.setPosition({ (float)window.getSize().x - 160, (float)posY + 110 });
education.setPosition({ 1920 - 160, (float)posY + 110 });

// Draw Avatar in Action Phase
int avatarID = player.getAvatarID();
Expand All @@ -382,7 +385,7 @@ namespace TheTraitor {
avatarSprite.setScale({ size / texSize.x, size / texSize.y });
}
// Position to the right of the name (Fixed column)
avatarSprite.setPosition({ (float)window.getSize().x - 120.0f, (float)posY + 80.0f });
avatarSprite.setPosition({ 1920 - 120.0f, (float)posY + 80.0f });
window.draw(avatarSprite);
}

Expand All @@ -403,7 +406,7 @@ namespace TheTraitor {
// But we need to make sure we only show effects if SOME country is selected.
// However, if isTarget is true, then a country IS selected (this one).
// We also need to know if ANY country is selected to show Local Player effects.

bool anyCountrySelected = false;
for (const auto& cPair : allCountries) {
if ((*cPair.second)[0].color == countrySelectedColor) {
Expand All @@ -419,19 +422,19 @@ namespace TheTraitor {
if (isLocal) value += effect.playerEffect;
// If this is target player, add target effect
if (isTarget) value += effect.targetEffect;

// Only draw if non-zero AND if the stat type matches
// Effects should be below "related stats".

if (value != 0) {
std::string valStr = (value > 0 ? "+" : "") + std::to_string(value);
effectText.setString(valStr);
effectText.setFillColor(value > 0 ? sf::Color::Green : sf::Color::Red);

float xPos = 0;
if (effect.statType == CountryStatType::Economy) xPos = (float)window.getSize().x - 400;
else if (effect.statType == CountryStatType::Health) xPos = (float)window.getSize().x - 280;
else if (effect.statType == CountryStatType::Education) xPos = (float)window.getSize().x - 160;
if (effect.statType == CountryStatType::Economy) xPos = 1920 - 400;
else if (effect.statType == CountryStatType::Health) xPos = 1920 - 280;
else if (effect.statType == CountryStatType::Education) xPos = 1920 - 160;

effectText.setPosition({ xPos, (float)(posY - 200) + 135 }); // posY was incremented already
window.draw(effectText);
Expand Down Expand Up @@ -468,7 +471,7 @@ namespace TheTraitor {
isHovered = button.isMouseOver(position);

button.updateHoverEffect(isHovered);

if (isHovered) {
isActionHovered = true;
hoveredAction = actionType;
Expand Down Expand Up @@ -504,18 +507,18 @@ namespace TheTraitor {
// 2. Self-Targeting Validation
if (targetType == cachedLocalPlayerCountryType) {
// Logic: Only Traitor can self-target with specific secret actions

bool isTraitorSelfTargetAllowed = false;
if (cachedIsTraitor && (actionType == ActionType::SpreadPlague ||
actionType == ActionType::DestroySchool ||
actionType == ActionType::SabotageFactory)) {
actionType == ActionType::DestroySchool ||
actionType == ActionType::SabotageFactory)) {
isTraitorSelfTargetAllowed = true;
}

if (!isTraitorSelfTargetAllowed) {
// Invalid self-target. Do NOT consume action. Do NOT send packet.
viewData.isActionRequested = false;
return viewData;
return viewData;
}
}

Expand All @@ -536,7 +539,7 @@ namespace TheTraitor {
if (isPointInPolygon(*countryPair.first, position - countriesOffset)) {
sf::Color fillColor = (inputData.isMouseClicked && canInteract) ? countrySelectedColor : countryHoverColor;
if ((*countryPair.second)[0].color == countrySelectedColor) fillColor = countryHoverColor;

// Destroyed Override
if (isDestroyed) fillColor = countryDestroyedColor;

Expand Down
6 changes: 3 additions & 3 deletions src/Client/Phases/DiscussionPhase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace TheTraitor {
DiscussionPhase::DiscussionPhase(sf::RenderWindow& window, sf::Font& font, const std::vector<sf::Texture>& avatarTextures, std::string executableFolderPath)
: window(window), font(font), avatarTextures(avatarTextures),
viewData{ false, ActionType::TradePact, CountryType(NONE), GamePhase(NONE), "", "", "", 0, false },
readyButton(sf::Vector2f(window.getSize().x / 2 - 100, window.getSize().y - 100), sf::Vector2f(200, 60), sf::Vector2f(10, 10), "Ready", font, window, 30, sf::Color::Black, sf::Color::White, 5, sf::Color(100,100,100), sf::Color::White),
readyButton(sf::Vector2f(1920 / 2 - 100, 1080 - 100), sf::Vector2f(200, 60), sf::Vector2f(10, 10), "Ready", font, window, 30, sf::Color::Black, sf::Color::White, 5, sf::Color(100,100,100), sf::Color::White),
isReady(false),
titleLabel(font, "Discussion Phase", 40),
timerLabel(font, "00:00", 30),
Expand All @@ -23,7 +23,7 @@ namespace TheTraitor {
titleLabel.setPosition({ 50, 30 });
titleLabel.setStyle(sf::Text::Bold);

timerLabel.setPosition({ (float)window.getSize().x - 150, 30 });
timerLabel.setPosition({ 1920 - 150, 30 });
}

void DiscussionPhase::render(const GameState& gameState, int localPlayerID, float elapsedTime, int roundCounter) {
Expand Down Expand Up @@ -56,7 +56,7 @@ namespace TheTraitor {
}

// We put them in a column on the right side, similar to Action Phase but maybe simpler
float rightColumnX = (float)window.getSize().x - 550;
float rightColumnX = 1920 - 550;

// Name
name.setString(displayName);
Expand Down
20 changes: 10 additions & 10 deletions src/Client/Phases/GameoverPhase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace TheTraitor {
totalRoundsLabel(font),
totalTimeLabel(font),
traitorInfoLabel(font),
quitGameButton(sf::Vector2f(window.getSize().x / 2.0f - 100, window.getSize().y / 2.0f + 150),
quitGameButton(sf::Vector2f(1920 / 2.0f - 100, 1080 / 2.0f + 150),
sf::Vector2f(200, 60),
sf::Vector2f(45, 15),
"Quit Game",
Expand All @@ -26,15 +26,15 @@ namespace TheTraitor {
{
title.setFillColor(sf::Color::Red);
title.setPosition(sf::Vector2f(
window.getSize().x / 2.0f - title.getGlobalBounds().size.x / 2.0f,
window.getSize().y / 2.0f - 200));
1920 / 2.0f - title.getGlobalBounds().size.x / 2.0f,
1080 / 2.0f - 200));
}

void GameoverPhase::render(const GameState& gameState, int localPlayerID, float elapsedTime, int roundCounter) {
int totalTimeSeconds = static_cast<int>(elapsedTime);

// Background overlay
sf::RectangleShape overlay(sf::Vector2f((float)window.getSize().x, (float)window.getSize().y));
sf::RectangleShape overlay(sf::Vector2f(1920, 1080));
overlay.setFillColor(sf::Color(0, 0, 0, 200));
window.draw(overlay);

Expand All @@ -45,17 +45,17 @@ namespace TheTraitor {
totalRoundsLabel.setCharacterSize(30);
totalRoundsLabel.setFillColor(sf::Color::White);
totalRoundsLabel.setPosition(sf::Vector2f(
window.getSize().x / 2.0f - totalRoundsLabel.getGlobalBounds().size.x / 2.0f,
window.getSize().y / 2.0f - 50));
1920 / 2.0f - totalRoundsLabel.getGlobalBounds().size.x / 2.0f,
1080 / 2.0f - 50));
window.draw(totalRoundsLabel);

// Total time
totalTimeLabel.setString("Total Time: " + std::to_string(totalTimeSeconds / 60) + ":" + std::to_string(totalTimeSeconds % 60));
totalTimeLabel.setCharacterSize(30);
totalTimeLabel.setFillColor(sf::Color::White);
totalTimeLabel.setPosition(sf::Vector2f(
window.getSize().x / 2.0f - totalTimeLabel.getGlobalBounds().size.x / 2.0f,
window.getSize().y / 2.0f + 20));
1920 / 2.0f - totalTimeLabel.getGlobalBounds().size.x / 2.0f,
1080 / 2.0f + 20));
window.draw(totalTimeLabel);

std::string traitorName = "Unknown";
Expand All @@ -70,8 +70,8 @@ namespace TheTraitor {
traitorInfoLabel.setCharacterSize(30);
traitorInfoLabel.setFillColor(sf::Color::Red);
traitorInfoLabel.setPosition(sf::Vector2f(
window.getSize().x / 2.0f - traitorInfoLabel.getGlobalBounds().size.x / 2.0f,
window.getSize().y / 2.0f + 80));
1920 / 2.0f - traitorInfoLabel.getGlobalBounds().size.x / 2.0f,
1080 / 2.0f + 80));
window.draw(traitorInfoLabel);

quitGameButton.render();
Expand Down
2 changes: 1 addition & 1 deletion src/Client/Phases/MenuPhase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ namespace TheTraitor {
// Calculate total width to right-align
float totalGridWidth = cols * avatarDisplaySize + (cols - 1) * gap;

float startX = window.getSize().x - totalGridWidth - 150.0f;
float startX = 1920 - totalGridWidth - 150.0f;
float startY = 350.0f;

avatarSprites.reserve(avatarTextures.size());
Expand Down
20 changes: 10 additions & 10 deletions src/Client/Phases/WinPhase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace TheTraitor {
totalRoundsLabel(font),
totalTimeLabel(font),
traitorInfoLabel(font),
quitGameButton(sf::Vector2f(window.getSize().x / 2.0f - 100, window.getSize().y / 2.0f + 150),
quitGameButton(sf::Vector2f(1920 / 2.0f - 100, 1080 / 2.0f + 150),
sf::Vector2f(200, 60),
sf::Vector2f(45, 15),
"Quit Game",
Expand All @@ -26,14 +26,14 @@ namespace TheTraitor {
{
title.setFillColor(sf::Color::Green);
title.setPosition(sf::Vector2f(
window.getSize().x / 2.0f - title.getGlobalBounds().size.x / 2.0f,
window.getSize().y / 2.0f - 200));
1920 / 2.0f - title.getGlobalBounds().size.x / 2.0f,
1080 / 2.0f - 200));
}

void WinPhase::render(const GameState& gameState, int localPlayerID, float elapsedTime, int roundCounter) {
int totalTimeSeconds = static_cast<int>(elapsedTime);

sf::RectangleShape overlay(sf::Vector2f((float)window.getSize().x, (float)window.getSize().y));
sf::RectangleShape overlay(sf::Vector2f(1920, 1080));
overlay.setFillColor(sf::Color(0, 0, 0, 200));
window.draw(overlay);

Expand All @@ -43,16 +43,16 @@ namespace TheTraitor {
totalRoundsLabel.setCharacterSize(30);
totalRoundsLabel.setFillColor(sf::Color::White);
totalRoundsLabel.setPosition(sf::Vector2f(
window.getSize().x / 2.0f - totalRoundsLabel.getGlobalBounds().size.x / 2.0f,
window.getSize().y / 2.0f - 50));
1920 / 2.0f - totalRoundsLabel.getGlobalBounds().size.x / 2.0f,
1080 / 2.0f - 50));
window.draw(totalRoundsLabel);

totalTimeLabel.setString("Total Time: " + std::to_string(totalTimeSeconds / 60) + ":" + std::to_string(totalTimeSeconds % 60));
totalTimeLabel.setCharacterSize(30);
totalTimeLabel.setFillColor(sf::Color::White);
totalTimeLabel.setPosition(sf::Vector2f(
window.getSize().x / 2.0f - totalTimeLabel.getGlobalBounds().size.x / 2.0f,
window.getSize().y / 2.0f + 20));
1920 / 2.0f - totalTimeLabel.getGlobalBounds().size.x / 2.0f,
1080 / 2.0f + 20));
window.draw(totalTimeLabel);

std::string traitorName = "Unknown";
Expand All @@ -67,8 +67,8 @@ namespace TheTraitor {
traitorInfoLabel.setCharacterSize(30);
traitorInfoLabel.setFillColor(sf::Color::Red);
traitorInfoLabel.setPosition(sf::Vector2f(
window.getSize().x / 2.0f - traitorInfoLabel.getGlobalBounds().size.x / 2.0f,
window.getSize().y / 2.0f + 80));
1920 / 2.0f - traitorInfoLabel.getGlobalBounds().size.x / 2.0f,
1080 / 2.0f + 80));
window.draw(traitorInfoLabel);

quitGameButton.render();
Expand Down
2 changes: 1 addition & 1 deletion src/Server/GameHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace TheTraitor {

GameHost::GameHost() : serverIp(sf::IpAddress::LocalHost), serverPort(53000) {
GameHost::GameHost(unsigned short serverPort) : serverIp(sf::IpAddress::LocalHost), serverPort(serverPort) {
clientConnectionTimeout = 30; //seconds
isGameStarted = false;

Expand Down
2 changes: 1 addition & 1 deletion src/Server/GameHost.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace TheTraitor{
void updateGlobalGameState();

public:
GameHost();
GameHost(unsigned short serverPort);
void establishConnectionWithClients(GlobalGameState& state);
void receivePacket(sf::TcpSocket* socket);
void sendPacket(sf::TcpSocket* socket, sf::Packet& packet);
Expand Down
Loading