From d9497679cb8a3bd906400f13cd08bdb54876dee1 Mon Sep 17 00:00:00 2001 From: Barry Kane Date: Sun, 30 Oct 2022 12:58:39 +0000 Subject: [PATCH] Implemented Skill Checks. - Implemented skillCheck. - Allowed for the in-game testing of skillCheck via /try. - Slightly reorganized the Makefile. - Tweaked the logoString to display correctly. - Edited the client and server to generate gprof data when in debug builds. --- Makefile | 8 ++-- src/gamelogic.c | 93 ++++++++++++++++++++++++++++++++++-- src/gamelogic.h | 2 +- src/playerdata.h | 2 +- src/server/SilverMUDServer.c | 20 +++++--- src/texteffects.h | 22 ++++----- 6 files changed, 120 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 926ebf0..90805f5 100644 --- a/Makefile +++ b/Makefile @@ -14,16 +14,16 @@ SilverMUDServer: $(serverobj) gcc -o $@ $^ $(SERVERLDFLAGS) SilverMUDClientDebug: $(clientobj) - gcc $^ $(CLIENTLDFLAGS) -o $@ + gcc -pg $^ $(CLIENTLDFLAGS) -o $@ SilverMUDServerDebug: $(serverobj) - gcc $^ $(SERVERLDFLAGS) -o $@ + gcc -pg $^ $(SERVERLDFLAGS) -o $@ .PHONY: clean clean: rm -f $(clientobj) $(serverobj) SilverMUDClient SilverMUDServer SilverMUDClientDebug SilverMUDServerDebug -all: SilverMUDClient SilverMUDServer +all: clean SilverMUDClient SilverMUDServer all: CFLAGS += -Wall -Wextra -Ofast -debug: CFLAGS += -Wall -ggdb -Wextra -Og -pg +debug: CFLAGS += -Wall -Wextra -pg -ggdb -Og debug: clean SilverMUDClientDebug SilverMUDServerDebug diff --git a/src/gamelogic.c b/src/gamelogic.c index 97041a9..112291f 100644 --- a/src/gamelogic.c +++ b/src/gamelogic.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "constants.h" #include "gamelogic.h" #include "playerdata.h" @@ -18,9 +19,8 @@ void * gameLogicLoop(void * parameters) { gameLogicParameters * threadParameters = parameters; inputMessage * currentInput = NULL; - bool keepRunning = true; commandQueue * commandQueue = createCommandQueue(); - while(keepRunning) + while(true) { // Evaluate remaining commands: if(commandQueue->currentLength != 0) @@ -74,7 +74,7 @@ void * gameLogicLoop(void * parameters) dequeueInputMessage(threadParameters->inputQueue); } } - return NULL; + pthread_exit(NULL); } // Create a commandQueue: @@ -311,7 +311,9 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue) } default: { - strcpy(tryMessage->messageContent, "Not at the moment, mate.\n"); + sprintf(tryMessage->messageContent,"%d", + skillCheck(currentCommand->caller, 10, currentCommand->arguments, strlen(currentCommand->arguments), + parameters->globalSkillList)); break; } } @@ -645,11 +647,14 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue) // Run a stat check: outcome statCheck(playerInfo * player, int chance, coreStat statToCheck) { + // Calculate the chance: if(chance > 100 || chance < 0) { return ERROR; } chance = 100 - chance; + + // Calculate the modifier: int modifier = 0; switch(statToCheck) { @@ -708,6 +713,86 @@ outcome statCheck(playerInfo * player, int chance, coreStat statToCheck) } } +// Run a skill check: +outcome skillCheck(playerInfo * player, int chance, char * skillName, size_t skillNameLength, skillList * globalSkillList) +{ + // Calculate the chance: + if(chance > 100 || chance < 0) + { + return ERROR; + } + chance = 100 - chance; + + // Check if the player has the given skill: + bool playerHasSkill = false; + skillNode * currentPlayerNode = player->skills->head; + while(currentPlayerNode != NULL) + { + if(strncmp(skillName, currentPlayerNode->skill->skillName, skillNameLength) == 0) + { + playerHasSkill = true; + break; + } + currentPlayerNode = currentPlayerNode->next; + } + + // If the player doesn't have the skill, check if it's in the game and is trained: + bool trainedSkill = false; + if(!playerHasSkill) + { + skillNode * currentNode = globalSkillList->head; + while(strncmp(skillName, currentNode->skill->skillName, 32) != 0) + { + if(currentNode->next == NULL) + { + fprintf(stderr, "Skill doesn't exist in skill list.\n"); + return ERROR; + } + currentNode = currentNode->next; + } + if(currentNode->skill->trainedSkill == true) + { + trainedSkill = true; + } + } + + // Calculate the modifier: + int modifier = 0; + if(trainedSkill) + { + modifier = -100; + } + else + { + modifier = currentPlayerNode->skill->skillPoints * 4; + } + + // Attempt the check: + int attempt = (random() % 100) + modifier; + if(attempt >= chance) + { + if(attempt >= 98) + { + return CRITICAL_SUCCESS; + } + else + { + return SUCCESS; + } + } + else + { + if(attempt <= 2) + { + return CRITICAL_FAILURE; + } + else + { + return FAILURE; + } + } +} + // Move a player to a different area given a path in the area: int movePlayerToArea(playerInfo * player, char * requestedPath) { diff --git a/src/gamelogic.h b/src/gamelogic.h index b73d2a4..7660063 100644 --- a/src/gamelogic.h +++ b/src/gamelogic.h @@ -90,6 +90,6 @@ typedef enum outcome outcome statCheck(playerInfo * player, int chance, coreStat statToCheck); // Run a skill check: -// outcome skillCheck(playerInfo * player, int chance, char * skillToCheck, int skillNameLength); +outcome skillCheck(playerInfo * player, int chance, char * skillName, size_t skillNameLength, skillList * globalSkillList); #endif diff --git a/src/playerdata.h b/src/playerdata.h index 9f78742..01564b2 100644 --- a/src/playerdata.h +++ b/src/playerdata.h @@ -49,7 +49,7 @@ typedef struct skillList skillNode * head; int skillCount; } skillList; - +\ typedef struct playerInfo { char playerName[32]; diff --git a/src/server/SilverMUDServer.c b/src/server/SilverMUDServer.c index f11772b..7ba6083 100644 --- a/src/server/SilverMUDServer.c +++ b/src/server/SilverMUDServer.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -24,11 +25,14 @@ #include "../inputoutput.h" typedef struct sockaddr sockaddr; - -int main() +void sigintHandler(int signal) +{ + exit(EXIT_SUCCESS); +} + +int main(int argc, char ** argv) { time_t currentTime; - bool keepRunning = true; int socketFileDesc, connectionFileDesc, length, clientsAmount, socketCheck, activityCheck, returnVal; fd_set connectedClients; @@ -40,7 +44,10 @@ int main() struct sockaddr_in serverAddress, clientAddress; inputMessageQueue * inputQueue = createInputMessageQueue(); outputMessageQueue * outputQueue = createOutputMessageQueue(); - + + // Set the handler for SIGINT: + signal(2, sigintHandler); + // -==[ TEST GAME-STATE INITIALIZATION ]==- // Initialize test areas: areaNode * areas = createAreaList(createArea("Login Area", "Please login with the /join command.")); @@ -182,7 +189,7 @@ int main() slowPrint("=====\n", 5000); struct timeval timeout = {0, 500}; - while(keepRunning) + while(true) { // Clear the set of file descriptors angad add the master socket: FD_ZERO(&connectedClients); @@ -325,6 +332,7 @@ int main() dequeueOutputMessage(outputQueue); } } - return 0; + pthread_cancel(gameLogicThread); + exit(EXIT_SUCCESS); } diff --git a/src/texteffects.h b/src/texteffects.h index 3531e77..060c99c 100644 --- a/src/texteffects.h +++ b/src/texteffects.h @@ -20,17 +20,17 @@ void bruteforcePrintNcurses(char * stringToPrint, int delay, WINDOW * window, bo // A string containing an ASCII art version of the Silverkin Industries logo. char * logostring = " ///////\n" - " //////////////////////////////////////////\n" - " ///////////////////////////////////////////////////////////\n" - " ////////// ////////////////////////////\n" - " ### # # # # ##### ### # # # # # /////////////////\n" - " ## # # # # ## # # ### # ## # //////////////\n" - " ## # # # # # ### # # # # # # /////////\n" - " ### # ### # ##### # # # # # # # ///////\n" - " # ## # ##### # # ### ### ### # ##### ### ////// \n" - " # # # # # # # # ## # # # # ## ## ////\n" - " # # # # # # # # ## # ### # # ## //\n" - " # # ### ##### ##### ### # # # # #### ### /\n"; + " //////////////////////////////////////////\n" + " ///////////////////////////////////////////////////////////\n" + " ////////// ////////////////////////////\n" + " ### # # # # ##### ### # # # # # /////////////////\n" + " ## # # # # ## # # ### # ## # //////////////\n" + " ## # # # # # ### # # # # # # /////////\n" + " ### # ### # ##### # # # # # # # ///////\n" + " # ## # ##### # # ### ### ### # ##### ### //////\n" + " # # # # # # # # ## # # # # ## ## ////\n" + " # # # # # # # # ## # ### # # ## //\n" + " # # ### ##### ##### ### # # # # #### ### /\n"; void wrapString(char * stringToWrap, int stringLength, int screenWidth); #endif