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)
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

View File

@ -4,6 +4,7 @@
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include <pthread.h>
#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)
{

View File

@ -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

View File

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

View File

@ -7,6 +7,7 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <ncurses.h>
#include <pthread.h>
@ -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);
}

View File

@ -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