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.
This commit is contained in:
Barry Kane 2022-10-30 12:58:39 +00:00
parent f2dd83857f
commit d9497679cb
6 changed files with 120 additions and 27 deletions

View File

@ -14,16 +14,16 @@ SilverMUDServer: $(serverobj)
gcc -o $@ $^ $(SERVERLDFLAGS) gcc -o $@ $^ $(SERVERLDFLAGS)
SilverMUDClientDebug: $(clientobj) SilverMUDClientDebug: $(clientobj)
gcc $^ $(CLIENTLDFLAGS) -o $@ gcc -pg $^ $(CLIENTLDFLAGS) -o $@
SilverMUDServerDebug: $(serverobj) SilverMUDServerDebug: $(serverobj)
gcc $^ $(SERVERLDFLAGS) -o $@ gcc -pg $^ $(SERVERLDFLAGS) -o $@
.PHONY: clean .PHONY: clean
clean: clean:
rm -f $(clientobj) $(serverobj) SilverMUDClient SilverMUDServer SilverMUDClientDebug SilverMUDServerDebug rm -f $(clientobj) $(serverobj) SilverMUDClient SilverMUDServer SilverMUDClientDebug SilverMUDServerDebug
all: SilverMUDClient SilverMUDServer all: clean SilverMUDClient SilverMUDServer
all: CFLAGS += -Wall -Wextra -Ofast all: CFLAGS += -Wall -Wextra -Ofast
debug: CFLAGS += -Wall -ggdb -Wextra -Og -pg debug: CFLAGS += -Wall -Wextra -pg -ggdb -Og
debug: clean SilverMUDClientDebug SilverMUDServerDebug debug: clean SilverMUDClientDebug SilverMUDServerDebug

View File

@ -4,6 +4,7 @@
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <pthread.h>
#include "constants.h" #include "constants.h"
#include "gamelogic.h" #include "gamelogic.h"
#include "playerdata.h" #include "playerdata.h"
@ -18,9 +19,8 @@ void * gameLogicLoop(void * parameters)
{ {
gameLogicParameters * threadParameters = parameters; gameLogicParameters * threadParameters = parameters;
inputMessage * currentInput = NULL; inputMessage * currentInput = NULL;
bool keepRunning = true;
commandQueue * commandQueue = createCommandQueue(); commandQueue * commandQueue = createCommandQueue();
while(keepRunning) while(true)
{ {
// Evaluate remaining commands: // Evaluate remaining commands:
if(commandQueue->currentLength != 0) if(commandQueue->currentLength != 0)
@ -74,7 +74,7 @@ void * gameLogicLoop(void * parameters)
dequeueInputMessage(threadParameters->inputQueue); dequeueInputMessage(threadParameters->inputQueue);
} }
} }
return NULL; pthread_exit(NULL);
} }
// Create a commandQueue: // Create a commandQueue:
@ -311,7 +311,9 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
} }
default: 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; break;
} }
} }
@ -645,11 +647,14 @@ int evaluateNextCommand(gameLogicParameters * parameters, commandQueue * queue)
// Run a stat check: // Run a stat check:
outcome statCheck(playerInfo * player, int chance, coreStat statToCheck) outcome statCheck(playerInfo * player, int chance, coreStat statToCheck)
{ {
// Calculate the chance:
if(chance > 100 || chance < 0) if(chance > 100 || chance < 0)
{ {
return ERROR; return ERROR;
} }
chance = 100 - chance; chance = 100 - chance;
// Calculate the modifier:
int modifier = 0; int modifier = 0;
switch(statToCheck) 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: // Move a player to a different area given a path in the area:
int movePlayerToArea(playerInfo * player, char * requestedPath) int movePlayerToArea(playerInfo * player, char * requestedPath)
{ {

View File

@ -90,6 +90,6 @@ typedef enum outcome
outcome statCheck(playerInfo * player, int chance, coreStat statToCheck); outcome statCheck(playerInfo * player, int chance, coreStat statToCheck);
// Run a skill check: // 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 #endif

View File

@ -49,7 +49,7 @@ typedef struct skillList
skillNode * head; skillNode * head;
int skillCount; int skillCount;
} skillList; } skillList;
\
typedef struct playerInfo typedef struct playerInfo
{ {
char playerName[32]; char playerName[32];

View File

@ -7,6 +7,7 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <ncurses.h> #include <ncurses.h>
#include <pthread.h> #include <pthread.h>
@ -24,11 +25,14 @@
#include "../inputoutput.h" #include "../inputoutput.h"
typedef struct sockaddr sockaddr; typedef struct sockaddr sockaddr;
void sigintHandler(int signal)
{
exit(EXIT_SUCCESS);
}
int main() int main(int argc, char ** argv)
{ {
time_t currentTime; time_t currentTime;
bool keepRunning = true;
int socketFileDesc, connectionFileDesc, length, clientsAmount, int socketFileDesc, connectionFileDesc, length, clientsAmount,
socketCheck, activityCheck, returnVal; socketCheck, activityCheck, returnVal;
fd_set connectedClients; fd_set connectedClients;
@ -41,6 +45,9 @@ int main()
inputMessageQueue * inputQueue = createInputMessageQueue(); inputMessageQueue * inputQueue = createInputMessageQueue();
outputMessageQueue * outputQueue = createOutputMessageQueue(); outputMessageQueue * outputQueue = createOutputMessageQueue();
// Set the handler for SIGINT:
signal(2, sigintHandler);
// -==[ TEST GAME-STATE INITIALIZATION ]==- // -==[ TEST GAME-STATE INITIALIZATION ]==-
// Initialize test areas: // Initialize test areas:
areaNode * areas = createAreaList(createArea("Login Area", "Please login with the /join command.")); areaNode * areas = createAreaList(createArea("Login Area", "Please login with the /join command."));
@ -182,7 +189,7 @@ int main()
slowPrint("=====\n", 5000); slowPrint("=====\n", 5000);
struct timeval timeout = {0, 500}; struct timeval timeout = {0, 500};
while(keepRunning) while(true)
{ {
// Clear the set of file descriptors angad add the master socket: // Clear the set of file descriptors angad add the master socket:
FD_ZERO(&connectedClients); FD_ZERO(&connectedClients);
@ -325,6 +332,7 @@ int main()
dequeueOutputMessage(outputQueue); dequeueOutputMessage(outputQueue);
} }
} }
return 0; pthread_cancel(gameLogicThread);
exit(EXIT_SUCCESS);
} }

View File

@ -27,7 +27,7 @@ char * logostring =
" ## # # # # ## # # ### # ## # //////////////\n" " ## # # # # ## # # ### # ## # //////////////\n"
" ## # # # # # ### # # # # # # /////////\n" " ## # # # # # ### # # # # # # /////////\n"
" ### # ### # ##### # # # # # # # ///////\n" " ### # ### # ##### # # # # # # # ///////\n"
" # ## # ##### # # ### ### ### # ##### ### ////// \n" " # ## # ##### # # ### ### ### # ##### ### //////\n"
" # # # # # # # # ## # # # # ## ## ////\n" " # # # # # # # # ## # # # # ## ## ////\n"
" # # # # # # # # ## # ### # # ## //\n" " # # # # # # # # ## # ### # # ## //\n"
" # # ### ##### ##### ### # # # # #### ### /\n"; " # # ### ##### ##### ### # # # # #### ### /\n";