Commit 7fae6973 authored by Timothy LAIRD's avatar Timothy LAIRD

missions; rules tab

parent ae7fe2e6
......@@ -18,7 +18,7 @@ include_directories(${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/src)
include_directories( ${PROJECT_SOURCE_DIR}/dpd/include )
link_directories( ${PROJECT_SOURCE_DIR}/dpd )
add_executable(risk src/main-viewer.c src/networld.c src/controlpanel.c src/entity.c src/player.c src/random-map.c src/graphical-aspect.c src/window-manager.c src/menu-button.c src/main-menu.c src/int-input.c src/options-menu.c)
add_executable(risk src/main-viewer.c src/networld.c src/controlpanel.c src/entity.c src/player.c src/random-map.c src/graphical-aspect.c src/window-manager.c src/menu-button.c src/main-menu.c src/int-input.c src/options-menu.c src/mission.c)
target_link_libraries(risk raylib pthread dl rt X11 m)
......
......@@ -57,7 +57,7 @@ void Panel_drawMainMenu(Panel * self, Main_Menu * menu){
DrawText("RISK", (self->screenWidth*35)/100 , (self->screenHeight*10)/100 , (self->screenWidth*10)/100,BLACK);
//Draw each button
for(int index = 0; index < menu->buttonCount; index++){
Menu_Button_draw(menu->buttons[index], &font, self->screenWidth, self->screenHeight);
Menu_Button_draw(menu->buttons[index], &font, self->screenWidth, self->screenHeight, RED, (self->screenHeight*4)/100, (self->screenWidth/75), true);
}
ClearBackground(RAYWHITE);
UnloadFont(font);
......@@ -82,6 +82,33 @@ void Panel_drawOptionsMenu(Panel * self, Options_Menu * menu){
EndDrawing();
}
void Panel_drawRules(Panel * self, Main_Menu * rules){
Font font = GetFontDefault();
BeginDrawing();
DrawText("RULES", (self->screenWidth*40)/100 , (self->screenHeight*15)/100 , (self->screenWidth*5)/100,BLACK);
Menu_Button_draw(rules->buttons[0], &font, self->screenWidth, self->screenHeight, GREEN, (self->screenHeight*4)/100, (self->screenWidth/400), true);
Menu_Button_draw(rules->buttons[1], &font, self->screenWidth, self->screenHeight, BLACK, self->screenHeight/40, (self->screenWidth/400), true);
ClearBackground(RAYWHITE);
UnloadFont(font);
EndDrawing();
}
void Panel_drawWin(Panel * self, Player * player){
BeginDrawing();
Font font = GetFontDefault();
DrawText("VICTORY", (self->screenWidth*35)/100 , (self->screenHeight*15)/100 , (self->screenWidth*5)/100,BLACK);
char * victoryText = malloc(50*sizeof(char));
sprintf(victoryText, "Player %d has completed his mission and won the game", player->ID);
DrawText(victoryText, (self->screenWidth*20)/100, (self->screenHeight*45)/100, (self->screenWidth*2)/100, BLACK);
UnloadFont(font);
ClearBackground(RAYWHITE);
EndDrawing();
}
void Panel_drawGame(Panel * self)
{
//BeginDrawing();
......
......@@ -4,6 +4,7 @@
#include "networld.h"
#include "main-menu.h"
#include "options-menu.h"
#include "player.h"
// Tools
void printVector2( Vector2 v );
......@@ -45,6 +46,12 @@ void Panel_drawMainMenu(Panel * self, Main_Menu * menu);
//Rendering the options menu
void Panel_drawOptionsMenu(Panel * self, Options_Menu * menu);
//Rendering the rules menu
void Panel_drawRules(Panel * self, Main_Menu * rules);
//Rendering the victory screen
void Panel_drawWin(Panel * self, Player * player);
// Control
void Panel_control(Panel * self);
void Panel_controlCamera(Panel * self);
......
......@@ -246,8 +246,6 @@ void diceRolling(Player * attacker, Player * defender, Node * originNode, Node *
}
for(int i = 0 ; i < defendersCount + 1 ; i++){
positionDiceDefender[i] = (Vector2){1000 + (i)*150, screenHeight - 500};
printf("position dice defender %d x : %f \n", i , positionDiceDefender[i].x);
printf("position dice defender %d y : %f \n", i , positionDiceDefender[i].y);
}
// Main game loop
......
......@@ -16,13 +16,52 @@ Main_Menu * Main_Menu_init(const int screenWidth, const int screenHeight){
Rectangle optionsBtn = {(screenWidth*32)/100, (screenHeight*45)/100, (screenWidth*30)/100, (screenHeight*5)/100};
Rectangle smallOptionsBtn = {3 + (screenWidth*32/100), 3 + (screenHeight*45/100), (screenWidth*30/100) - 6, (screenHeight*5/100) - 6};
Rectangle optionsTextBox = {smallOptionsBtn.x + smallOptionsBtn.width/4, smallOptionsBtn.y, smallOptionsBtn.width, smallOptionsBtn.height};
Menu_Button * optionsMenu = Menu_Button_init(optionsBtn, smallOptionsBtn,optionsTextBox, "OPTIONS", options);
self->buttonCount = 2;
//Init of the rules btn
Rectangle rulesBtn = {(screenWidth*32)/100, (screenHeight*55)/100, (screenWidth*30)/100, (screenHeight*5)/100};
Rectangle smallRulesBtn = {3 + (screenWidth*32/100), 3 + (screenHeight*55/100), (screenWidth*30/100) - 6, (screenHeight*5/100) - 6};
Rectangle rulesTextBox = {smallRulesBtn.x + smallRulesBtn.width*4/13, smallRulesBtn.y, smallRulesBtn.width, smallRulesBtn.height};
Menu_Button * rulesMenu = Menu_Button_init(rulesBtn, smallRulesBtn,rulesTextBox, "RULES", rules);
//Init of the exit btn
Rectangle exitBtn = {0, (screenHeight*95)/100, (screenWidth*10)/100, (screenHeight*10)/100};
Rectangle smallerExitBtn = {3, 3 +(screenHeight*95)/100, -6 + (screenWidth*10)/100, -6 + (screenHeight*10)/100};
Rectangle exitTextBox = {smallerExitBtn.x + smallerExitBtn.width/10, smallerExitBtn.y, smallerExitBtn.width, smallerExitBtn.height};
Menu_Button * terminateBtn = Menu_Button_init(exitBtn, smallerExitBtn, exitTextBox, "EXIT", exitRoute);
self->buttonCount = 4;
self->buttons = malloc(sizeof(Menu_Button) * self->buttonCount);
self->buttons[game_ui] = playGame;
self->buttons[options] = optionsMenu;
self->buttons[rules] = rulesMenu;
self->buttons[exitRoute] = terminateBtn;
return self;
}
Main_Menu * Rules_Menu_init(const int screenWidth, const int screenHeight){
Main_Menu * self = malloc(sizeof(Main_Menu));
//Init of the return btn
Rectangle returnBtn = {0, (screenHeight*95)/100, (screenWidth*15)/100, (screenHeight*10)/100};
Rectangle smallerReturnBtn = {3, 3 +(screenHeight*95)/100, -6 + (screenWidth*15)/100, -6 + (screenHeight*10)/100};
Rectangle returnTextBox = {smallerReturnBtn.x + smallerReturnBtn.width/7, smallerReturnBtn.y, smallerReturnBtn.width, smallerReturnBtn.height};
Menu_Button * rulesMenu = Menu_Button_init(returnBtn, smallerReturnBtn, returnTextBox, "Main Menu", main_menu);
//Init of the rules text box
Rectangle rulesBox = {(screenWidth*25)/100, (screenHeight*30)/100, (screenWidth*50)/100, (screenHeight*60)/100};
Rectangle smallerRulesBox = {3 + (screenWidth*25)/100, 3 +(screenHeight*30)/100, -6 + (screenWidth*50)/100, -6 + (screenHeight*60)/100};
Rectangle rulesTextBox = {5 + (screenWidth*25)/100, 5 +(screenHeight*30)/100, -10 + (screenWidth*50)/100, -10 + (screenHeight*60)/100};
Menu_Button * rulesText = Menu_Button_init(rulesBox, smallerRulesBox, rulesTextBox,
"This game is an adapted and computerized version of the board game Risk.\nEach player will be given a set of territories (nodes) and a mission to win the game.\nSuccessively, each player will play their turns which happens in 2 phases :\n-\tThe recruitment phase, in which a player is given reinforcements to place on his node, and move existing soldiers, although any given nodes needs at least 1 soldier at all times.\n-\tThe attack phase, in which a player may attack neighboring nodes that he doesnt own. He will have to engage up to 3 soldiers in a fight, which resolves in throwing one die per soldier engage. The outcome will be determined by the head to head comparison of the results from the attacker and the defender.\nA player wins by accomplishing their mission.",
rules);
self->buttonCount = 2;
self->buttons = malloc(sizeof(Menu_Button) * self->buttonCount);
self->buttons[0] = rulesMenu;
self->buttons[1] = rulesText;
return self;
}
......
......@@ -20,6 +20,14 @@ typedef struct Str_Main_Menu Main_Menu;
*/
Main_Menu * Main_Menu_init(const int screenWidth, const int screenHeight);
/**
* @brief Initialise a new Main_Menu object for the rules menu
* @param screenWidth the width of the screen
* @param screenHeight the height of the screen
* @return A pointer to the new Main_Menu
*/
Main_Menu * Rules_Menu_init(const int screenWidth, const int screenHeight);
/**
* @brief Detect if any buttons have been clicked
* @param self the Main_Menu context
......
......@@ -19,6 +19,7 @@
#include "window-manager.h"
#include "main-menu.h"
#include "options-menu.h"
#include "mission.h"
// Program attributes
//-------------------
......@@ -26,11 +27,11 @@ const int screenWidth = 1700;
const int screenHeight = 800;
const int targetFPS = 60;
void game_update(NetWorld * world, Player * players, Font font, Panel * panel);
int game_update(NetWorld * world, Player * players, Mission * missions, Font font, Panel * panel);
// Game attributes
//-----------------
bool game_end;
bool game_end = false;
int main(int nbArg, char ** arg)
{
......@@ -38,7 +39,7 @@ int main(int nbArg, char ** arg)
int playerCount = 3;
NetWorld * world = malloc(sizeof(NetWorld));
Player * players = malloc(sizeof(Player));
Mission * missions = malloc(sizeof(Mission));
// Game Initialization
//--------------------
Panel * panel= Panel_new();
......@@ -55,13 +56,19 @@ int main(int nbArg, char ** arg)
//UI elements
Main_Menu * menu = Main_Menu_init(screenWidth, screenHeight);
Main_Menu * rulesMenu = Rules_Menu_init(screenWidth, screenHeight);
Options_Menu * optionsMenu = Options_Menu_init(&playerCount, &nodeCount, screenWidth, screenHeight);
Window_Manager * manager = Window_Manager_new(panel, menu, optionsMenu);
Window_Manager * manager = Window_Manager_new(panel, menu, rulesMenu, optionsMenu);
Rectangle gameReturnBtn = {0,0, (screenWidth*13)/100, (screenHeight*5)/100};
Rectangle smallerGameReturnBtn = {3,3, -6 +(screenWidth*13)/100, -6 +(screenHeight*5)/100};
Menu_Button* gameReturn = Menu_Button_init(gameReturnBtn, smallerGameReturnBtn, smallerGameReturnBtn, "Main Menu", main_menu);
while (!game_end && !WindowShouldClose()) // Detect window close button or ESC key
{
DrawFPS(10, 10);
Window_Manager_display(manager);
DrawFPS(screenWidth - 100,screenHeight - 50);
Window_Manager_display(manager, world, players);
Vector2 mousePos;
switch (manager->display)
{
case main_menu:
......@@ -72,26 +79,35 @@ int main(int nbArg, char ** arg)
//Initialising a new game with inputted parameters
*world = *NetWorld_new(nodeCount, playerCount);
Random_map(world);
Color colors[] = {BLACK, RED, BLUE, GREEN, PURPLE, PINK, YELLOW};
Color colors[] = {BLACK, RED, BLUE, BROWN, PURPLE, PINK, YELLOW};
players = Player_newArray(playerCount, colors);
missions = Mission_newArray(playerCount, world);
//Distribute nodes to players evenly
for(int index = 0; index < world->size; index++){
Player_add_Node(&(players[index % playerCount]), &(world->nodes[index]));
}
world->currentPlayer = playerCount - 1;
game_end = false;
world->currentPlayer = 0;
Player_start_turn(&(players[world->currentPlayer]));
}
}
break;
case game_ui:
Panel_control(panel);
mousePos = GetMousePosition();
Menu_Button_draw(gameReturn, &gameFont, screenWidth, screenHeight, RED, (screenHeight*4)/100, (screenWidth/400), true);
if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && CheckCollisionPointRec(mousePos, gameReturn->button)){
manager->display = gameReturn->displayOnClick;
}
//Draw the hitboxes for each node
for(int index = 0; index < world->size; index++){
Vector2 screenPosition= Panel_pixelFromPosition(panel, &(world->nodes[index]).position);
world->nodes[index].collisionHitbox.x = screenPosition.x - 24;
world->nodes[index].collisionHitbox.y = screenPosition.y - 24;
}
game_update(world, players, gameFont, panel);
world->winner = game_update(world, players, missions, gameFont, panel);
if(world->hasWinner){
manager->display = win;
}
break;
case options:
//Activate/Deactivate inputs on click and detect click on the save btn
......@@ -121,6 +137,21 @@ int main(int nbArg, char ** arg)
}
}
break;
case rules:
if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)){
Vector2 mousePos = GetMousePosition();
manager->display = Main_Menu_detect_click(rulesMenu, &mousePos);
}
break;
case win:
Menu_Button_draw(gameReturn, &gameFont, screenWidth, screenHeight, RED, (screenHeight*4)/100, (screenWidth/400), true);
mousePos = GetMousePosition();
if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON) && CheckCollisionPointRec(mousePos, gameReturn->button)){
manager->display = gameReturn->displayOnClick;
}
break;
case exitRoute:
game_end = true;
default:
break;
}
......@@ -131,7 +162,9 @@ int main(int nbArg, char ** arg)
NetWorld_delete(world);
Player_delete(players);
Mission_delete(missions);
Main_Menu_delete(menu);
Main_Menu_delete(rulesMenu);
Options_Menu_delete(optionsMenu);
Window_Manager_delete(manager);
UnloadFont(gameFont);
......@@ -140,15 +173,21 @@ int main(int nbArg, char ** arg)
return 0;
}
void game_update(NetWorld * world, Player * players, Font font, Panel * panel)
int game_update(NetWorld * world, Player * players, Mission * missions, Font font, Panel * panel)
{
//Game frame init
int winner = 0;
Vector2 mousePosition = GetMousePosition();
Player * currentPlayer = &(players[world->currentPlayer]);
Graphic_ShowPlayerInfo(currentPlayer, screenWidth, screenHeight, font);
Graphic_WhoseTurnIsIt(currentPlayer, screenWidth, screenHeight, font);
int playerCount = world->playerCount;
Rectangle missionDisplay = {screenWidth*30/100, screenHeight*95/100, screenWidth*40/100, screenHeight*10/100};
Rectangle missionTextBox = {missionDisplay.x + missionDisplay.width/5, missionDisplay.y, missionDisplay.width, missionDisplay.height};
DrawTextRec(font, missions[currentPlayer->ID].displayText, missionTextBox, (screenHeight*4)/100, (screenWidth/400), true, BLACK);
switch(currentPlayer->turnPhase){
case recruitment:
Graphic_RecrutementPhase(currentPlayer, screenWidth, screenHeight, font);
......@@ -218,11 +257,20 @@ void game_update(NetWorld * world, Player * players, Font font, Panel * panel)
}
break;
case init :
//Check on missions
for(int i = 0; i < world->playerCount; i++){
if(Mission_check(&missions[i], world, players)){
world->hasWinner = true;
winner = i;
}
}
//Switch turns
Player_end_turn(currentPlayer);
world->currentPlayer = (world->currentPlayer + 1) % playerCount;
Player_start_turn(&(players[world->currentPlayer]));
break;
default:;
default:
break;
}
return winner;
}
......@@ -12,10 +12,10 @@ Menu_Button * Menu_Button_init(Rectangle button, Rectangle smallerButton, Rectan
return self;
}
void Menu_Button_draw(Menu_Button * self, Font * font, const int screenWidth, const int screenHeight){
DrawRectangleRec(self->button, RED);
void Menu_Button_draw(Menu_Button * self, Font * font, const int screenWidth, const int screenHeight, Color colour,int fontSize, int spacing, bool wordWrap){
DrawRectangleRec(self->button, colour);
DrawRectangleRec(self->smallerButton, WHITE);
DrawTextRec(*font, self->displayText, self->textBox, (screenHeight*4)/100, (screenWidth/75), true, BLACK);
DrawTextRec(*font, self->displayText, self->textBox, fontSize, spacing, wordWrap, BLACK);
}
void Menu_Button_delete(Menu_Button * self){
......
......@@ -3,7 +3,7 @@
#include "raylib.h"
enum displays {game_ui, options, load_save, main_menu};
enum displays {game_ui, options, rules, exitRoute, main_menu, win};
typedef enum displays Display;
struct Str_Menu_Button{
......@@ -38,7 +38,7 @@ Menu_Button * Menu_Button_init(Rectangle button, Rectangle smallerButton, Rectan
* @param screenWidth Width of the screen
* @param screenHeight Height of the screen
*/
void Menu_Button_draw(Menu_Button * self, Font * font, const int screenWidth, const int screenHeight);
void Menu_Button_draw(Menu_Button * self, Font * font, const int screenWidth, const int screenHeight, Color colour, int fontSize, int spacing, bool wordWrap);
/**
* @brief Void a Menu_button
......
#include "mission.h"
#include <stdlib.h>
#include <stdio.h>
bool Player_conquer_threshold(NetWorld * world, Player * players, const int playerID, const int threshold){
return players[playerID].nodeCount >= threshold;
}
bool Player_eliminated(NetWorld * world, Player * players, const int playerID, const int targetPlayer){
return players[targetPlayer].nodeCount == 0;
}
Mission * Mission_init(const int playerID, NetWorld * world){
Mission * self = malloc(sizeof(Mission));
char* displayText = malloc(sizeof(char)*50);
self->playerID = playerID;
switch(rand()%2){
case 0:
self->mission = &Player_conquer_threshold;
self->target = world->size/2 + ((rand()%(world->size/5)) + (world->size/10));
sprintf(displayText, "\tConquer %d nodes", self->target);
self->displayText = displayText;
break;
case 1:
self->mission = &Player_eliminated;
self->target = rand()%world->playerCount;
while(self->target == self->playerID){
self->target = rand()%world->playerCount;
}
sprintf(displayText, "Eliminate Player %d", self->target);
self->displayText = displayText;
break;
}
return self;
}
Mission * Mission_newArray(const int playerCount, NetWorld * world){
Mission * missionArray = malloc(sizeof(Mission) * playerCount);
for(int i = 0; i < playerCount; i++){
missionArray[i] = *Mission_init(i, world);
}
return missionArray;
}
bool Mission_check(Mission * self, NetWorld * world, Player * players){
return self->mission(world, players, self->playerID, self->target);
}
void Mission_delete(Mission * self){
free(self);
}
\ No newline at end of file
#ifndef MISSION_H
#define MISSION_H
#include "networld.h"
#include "player.h"
struct Str_Mission{
bool (*mission)(NetWorld*, Player*, const int, const int);
int playerID;
int target;
char* displayText;
};
typedef struct Str_Mission Mission;
Mission * Mission_init(const int playerID, NetWorld * world);
bool Mission_check(Mission * self, NetWorld * world, Player * players);
void Mission_delete(Mission * self);
Mission * Mission_newArray(const int playerCount, NetWorld * world);
#endif
\ No newline at end of file
......@@ -210,6 +210,8 @@ NetWorld * NetWorld_new(int size, int playerCount)
p->nodes= Node_newArray( p->size );
p->currentPlayer = -1;
p->playerCount = playerCount;
p->hasWinner = false;
p->winner = 0;
return p;
}
......
......@@ -243,6 +243,10 @@ struct Str_NetWorld {
int currentPlayer;
//! Total Player count;
int playerCount;
//! Does the game have a winner
bool hasWinner;
//! ID of the game's winner
int winner;
};
typedef struct Str_NetWorld NetWorld;
......
......@@ -3,11 +3,12 @@
#include <stdlib.h>
#include <stdio.h>
Window_Manager * Window_Manager_new(Panel * panel, Main_Menu * menu, Options_Menu * optionsMenu){
Window_Manager * Window_Manager_new(Panel * panel, Main_Menu * menu, Main_Menu * rules, Options_Menu * optionsMenu){
Window_Manager * self = malloc(sizeof(Window_Manager));
self->panel = panel;
self->display = (Display) main_menu;
self->menu = menu;
self->rules = rules;
self->options = optionsMenu;
return self;
}
......@@ -16,7 +17,7 @@ void Window_Manager_delete(Window_Manager * manager){
free(manager);
}
void Window_Manager_display(Window_Manager * self){
void Window_Manager_display(Window_Manager * self, NetWorld * world, Player * players){
switch(self->display){
case main_menu:
Panel_drawMainMenu(self->panel, self->menu);
......@@ -27,7 +28,11 @@ void Window_Manager_display(Window_Manager * self){
case game_ui:
Panel_drawGame(self->panel);
break;
case load_save:
case rules:
Panel_drawRules(self->panel, self->rules);
break;
case win:
Panel_drawWin(self->panel, &players[world->winner]);
break;
default:
break;
......
......@@ -11,6 +11,8 @@ struct Str_Window_Manager{
Panel * panel;
//! Reference to the main menu context
Main_Menu * menu;
//! Reference to the rules menu context
Main_Menu * rules;
//! Reference to the options context
Options_Menu * options;
};
......@@ -23,7 +25,7 @@ typedef struct Str_Window_Manager Window_Manager;
* @param menu Reference to the main menu context
* @param optionsMenu Reference to the options menu context
*/
Window_Manager * Window_Manager_new(Panel * panel, Main_Menu * menu, Options_Menu * optionsMenu);
Window_Manager * Window_Manager_new(Panel * panel, Main_Menu * menu, Main_Menu * rules, Options_Menu * optionsMenu);
/**
......@@ -36,6 +38,6 @@ void Window_Manager_delete(Window_Manager * manager);
* @brief Displays the appropriate frame
* @param self The manager context
*/
void Window_Manager_display(Window_Manager * self);
void Window_Manager_display(Window_Manager * self, NetWorld * world, Player * players);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment