Updated the evaluateNextCommand to use a hash instead of strncmp

- Added hashCommand.
- Refactored evaluateNextCommand to use hashCommand to jump to the correct functionality with a switch.
This commit is contained in:
Barry Kane 2023-02-19 00:32:03 +00:00
parent e6a13ed2ac
commit afedf15c63
2 changed files with 406 additions and 358 deletions

View File

@ -108,7 +108,7 @@ void queueMessagedCommand(queue * queue, inputMessage * messageToQueue)
// Copy the command and arguments to the new commandEvent: // Copy the command and arguments to the new commandEvent:
memcpy(newCommand->command, &messageToQueue->content->messageContent[1], 16); memcpy(newCommand->command, &messageToQueue->content->messageContent[1], 16);
memcpy(newCommand->arguments, &messageToQueue->content->messageContent[strlen(newCommand->command) + 2], memcpy(newCommand->arguments, &messageToQueue->content->messageContent[strlen(newCommand->command) + 2],
MAX - (strlen(newCommand->command) + 2)); MAX - (strlen(newCommand->command) + 2));
// Ensure the arguments are safe to parse, without adding newlines: // Ensure the arguments are safe to parse, without adding newlines:
userNameSanatize(newCommand->command, 16); userNameSanatize(newCommand->command, 16);
@ -158,226 +158,349 @@ int evaluateNextCommand(gameLogicParameters * parameters, queue * queue)
{ {
return -1; return -1;
} }
// Try command: Attempt to use a stat or skill on an object:
if (strncmp(currentCommand->command, "try", 3) == 0) // Hash the command and execute the relevant functionality:
switch (hashCommand(currentCommand->command, strlen(currentCommand->command)))
{ {
userMessage * tryMessage = malloc(sizeof(userMessage)); // Look command: Returns the description of the current area and paths:
tryMessage->senderName[0] = '\0'; case 5626697:
// Temporary message until we can implement objects, events, and challenges.
strcpy(tryMessage->messageContent, "The try command is currently not implemented. Implement it if you want to use it.\n");
// Allocate an outputMessage for the queue:
outputMessage * tryOutputMessage = createTargetedOutputMessage(tryMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, tryOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage:
free(tryMessage);
}
// Exit command: Sends an "empty" exit message to disconnect a client:
if (strncmp(currentCommand->command, "exit", 4) == 0)
{
// Allocate a userMessage containing null characters as the first char in both fields:
userMessage * exitMessage = malloc(sizeof(userMessage));
exitMessage->senderName[0] = '\0';
exitMessage->messageContent[0] = '\0';
// Allocate an outputMessage for the queue:
outputMessage * exitOutputMessage = createTargetedOutputMessage(exitMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, exitOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage
free(exitMessage);
}
// Move command: Moves the caller to a different area given a path name or number:
if (strncmp(currentCommand->command, "move", 4) == 0)
{
char requestedPath[32];
if (strlen(currentCommand->arguments) > 0 && currentCommand->caller->currentArea != getFromList(parameters->areaList, 0)->area)
{ {
memcpy(requestedPath, currentCommand->arguments, 32); char formattedString[64];
userNameSanatize(requestedPath, 32); userMessage * lookMessage = calloc(1, sizeof(userMessage));
requestedPath[31] = '\0'; lookMessage->senderName[0] = '\0';
if (movePlayerToArea(currentCommand->caller, requestedPath) == 0) strncat(lookMessage->messageContent, currentCommand->caller->currentArea->areaName, 33);
{ strncat(lookMessage->messageContent, "\n", 2);
// Call the look command after moving. It's fine to unlock, because the loop won't strncat(lookMessage->messageContent, currentCommand->caller->currentArea->areaDescription, MAX - 35);
// continue until the command is queued:
queue->lock = false;
queueCommand(queue, "look", "", 5, 0, currentCommand->caller);
queue->lock = true;
}
}
}
// Look command: Returns the description of the current area and paths: // Allocate an outputMessage for the queue:
if (strncmp(currentCommand->command, "look", 4) == 0) outputMessage * lookOutputMessage = createTargetedOutputMessage(lookMessage, &currentCommand->caller, 1);
{
char formattedString[64];
userMessage * lookMessage = calloc(1, sizeof(userMessage));
lookMessage->senderName[0] = '\0';
strncat(lookMessage->messageContent, currentCommand->caller->currentArea->areaName, 33);
strncat(lookMessage->messageContent, "\n", 2);
strncat(lookMessage->messageContent, currentCommand->caller->currentArea->areaDescription, MAX - 35);
// Allocate an outputMessage for the queue:
outputMessage * lookOutputMessage = createTargetedOutputMessage(lookMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, lookOutputMessage, OUTPUT_MESSAGE);
//queueTargetedOutputMessage(parameters->outputQueue, lookMessage, &currentCommand->caller, 1);
bzero(lookMessage, sizeof(userMessage));
// Loop through the paths and send the appropriate amount of messages:
int charCount = 13;
strncat(lookMessage->messageContent, "You can go:", 13);
if (currentCommand->caller->currentArea->pathList->itemCount > 0)
{
for(size_t index = 0; index < currentCommand->caller->currentArea->pathList->itemCount; index++)
{
if ((charCount + 64) >= MAX)
{
lookOutputMessage = createTargetedOutputMessage(lookMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, lookOutputMessage, OUTPUT_MESSAGE);
bzero(lookMessage, sizeof(userMessage));
charCount = 0;
}
snprintf(formattedString, 64, "\n\t%ld. %s", index + 1,
getFromList(currentCommand->caller->currentArea->pathList, index)->path->pathName);
strncat(lookMessage->messageContent, formattedString, 64);
charCount += 64;
}
// Allocate another outputMessage for the queue:
lookOutputMessage = createTargetedOutputMessage(lookMessage, &currentCommand->caller, 1);
// Queue the outputMessage: // Queue the outputMessage:
pushQueue(parameters->outputQueue, lookOutputMessage, OUTPUT_MESSAGE); pushQueue(parameters->outputQueue, lookOutputMessage, OUTPUT_MESSAGE);
}
free(lookMessage); //queueTargetedOutputMessage(parameters->outputQueue, lookMessage, &currentCommand->caller, 1);
} bzero(lookMessage, sizeof(userMessage));
// Join command: Allows the player to join the game given a name:
// TODO: Implement login/character creation. Will be a while: // Loop through the paths and send the appropriate amount of messages:
if (strncmp(currentCommand->command, "join", 4) == 0) int charCount = 13;
{ strncat(lookMessage->messageContent, "You can go:", 13);
if (currentCommand->caller->currentArea == getFromList(parameters->areaList, 0)->area)
{ if (currentCommand->caller->currentArea->pathList->itemCount > 0)
bool validName = true;
for(int index = 0; index < *parameters->playerCount; index++)
{ {
if (currentCommand->arguments[0] == '\0') for(size_t index = 0; index < currentCommand->caller->currentArea->pathList->itemCount; index++)
{ {
validName = false; if ((charCount + 64) >= MAX)
{
lookOutputMessage = createTargetedOutputMessage(lookMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, lookOutputMessage, OUTPUT_MESSAGE);
bzero(lookMessage, sizeof(userMessage));
charCount = 0;
}
snprintf(formattedString, 64, "\n\t%ld. %s", index + 1,
getFromList(currentCommand->caller->currentArea->pathList, index)->path->pathName);
strncat(lookMessage->messageContent, formattedString, 64);
charCount += 64;
} }
if (strncmp(currentCommand->arguments, parameters->connectedPlayers[index].playerName, 16) == 0) // Allocate another outputMessage for the queue:
lookOutputMessage = createTargetedOutputMessage(lookMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, lookOutputMessage, OUTPUT_MESSAGE);
}
free(lookMessage);
break;
}
// Stat command: Displays the current character's sheet.
case 5987604:
{
char * formattedString = calloc(121, sizeof(char));
userMessage * statMessage = calloc(1, sizeof(userMessage));
statMessage->senderName[0] = '\0';
// Basic status: Name, level, location.
snprintf(formattedString, 120, "%s, Level %d | %s\n", currentCommand->caller->playerName,
currentCommand->caller->stats->level, currentCommand->caller->currentArea->areaName);
strncat(statMessage->messageContent, formattedString, 120);
// Current stats: Health and WISED.
snprintf(formattedString, 120,
"Health: %d/%d\nStats:\n\tWits: %2d | Intellect: %2d | Strength: %2d | Endurance: %2d | Dexerity: %2d \n",
currentCommand->caller->stats->currentHealth, currentCommand->caller->stats->maxHealth,
currentCommand->caller->stats->wits, currentCommand->caller->stats->intellect,
currentCommand->caller->stats->strength, currentCommand->caller->stats->endurance,
currentCommand->caller->stats->dexerity);
strncat(statMessage->messageContent, formattedString, 120);
// Levelling stats: Current XP, and spec points.
if (currentCommand->caller->stats->specPoints > 0 || currentCommand->caller->stats->skillPoints > 0)
{
snprintf(formattedString, 120, "Current Experience: %ld | Spec Points Available: %d | Skill Points Available: %d",
currentCommand->caller->stats->experience, currentCommand->caller->stats->specPoints, currentCommand->caller->stats->skillPoints);
}
else
{
snprintf(formattedString, 120, "Current Experience: %ld", currentCommand->caller->stats->experience);
}
strncat(statMessage->messageContent, formattedString, 120);
// Allocate an outputMessage for the queue:
outputMessage * statOutputMessage = createTargetedOutputMessage(statMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, statOutputMessage, OUTPUT_MESSAGE);
bzero(statMessage->messageContent, sizeof(char) * MAX);
if (currentCommand->caller->skills->head != NULL)
{
size_t skillIndex = 0;
int charCount = 0;
bool addNewline = false;
playerSkill * skill;
while (skillIndex < currentCommand->caller->skills->itemCount)
{ {
validName = false; skill = getFromList(currentCommand->caller->skills, skillIndex)->skill;
skillIndex++;
snprintf(formattedString, 120, "| %2d | %31s ", skill->skillPoints, skill->skillName);
charCount += 43;
strncat(statMessage->messageContent, formattedString, 120);
if ((charCount + 43) >= MAX)
{
// Allocate an outputMessage for the queue:
statOutputMessage = createTargetedOutputMessage(statMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, statOutputMessage, OUTPUT_MESSAGE);
bzero(statMessage, sizeof(userMessage));
charCount = 0;
break;
}
else if (addNewline)
{
strncat(statMessage->messageContent, "|\n", 3);
charCount++;
addNewline = false;
}
else
{
addNewline = true;
}
}
// Allocate an outputMessage for the queue:
statOutputMessage = createTargetedOutputMessage(statMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, statOutputMessage, OUTPUT_MESSAGE);
}
free(statMessage);
free(formattedString);
break;
}
// Spec command: Assign spec points to stats:
case 5982259:
{
userMessage * specMessage = calloc(1, sizeof(userMessage));
specMessage->senderName[0] = '\0';
char * formattedString = calloc(121, sizeof(char));
if (currentCommand->caller->stats->specPoints > 0)
{
int selectedAmount = 0;
strtok(currentCommand->arguments, " ");
selectedAmount = atoi(&currentCommand->arguments[strlen(currentCommand->arguments) + 1]);
coreStat selectedStat = getCoreStatFromString(currentCommand->arguments, 16);
if (selectedAmount > 0 && (currentCommand->caller->stats->specPoints - selectedAmount) >= 0)
{
switch (selectedStat)
{
case WITS:
{
currentCommand->caller->stats->wits += selectedAmount;
strncat(specMessage->messageContent, "Increased wits.", 16);
currentCommand->caller->stats->specPoints -= selectedAmount;
break;
}
case INTELLECT:
{
currentCommand->caller->stats->intellect += selectedAmount;
strncat(specMessage->messageContent, "Increased intellect.", 21);
currentCommand->caller->stats->specPoints -= selectedAmount;
break;
}
case STRENGTH:
{
currentCommand->caller->stats->strength += selectedAmount;
strncat(specMessage->messageContent, "Increased strength.", 20);
currentCommand->caller->stats->specPoints -= selectedAmount;
break;
}
case ENDURANCE:
{
currentCommand->caller->stats->endurance += selectedAmount;
strncat(specMessage->messageContent, "Increased endurance.", 21);
currentCommand->caller->stats->specPoints -= selectedAmount;
break;
}
case DEXERITY:
{
currentCommand->caller->stats->dexerity += selectedAmount;
strncat(specMessage->messageContent, "Increased dexerity.", 21);
currentCommand->caller->stats->specPoints -= selectedAmount;
break;
}
case INVALID:
{
strncat(specMessage->messageContent, "Invalid stat.", 21);
}
}
}
else
{
strncat(specMessage->messageContent, "You have entered an invalid amount of spec points.", 51);
} }
} }
if (validName) else
{ {
strncpy(currentCommand->caller->playerName, currentCommand->arguments, 16); strncat(specMessage->messageContent, "You have no spec points available.", 35);
currentCommand->caller->currentArea = getFromList(parameters->areaList, 1)->area;
// Call the look command after joining. It's fine to unlock, because the loop won't
// continue until the command is queued:
queue->lock = false;
queueCommand(queue, "look", "", 5, 0, currentCommand->caller);
queue->lock = true;
} }
// Allocate an outputMessage for the queue:
outputMessage * specOutputMessage = createTargetedOutputMessage(specMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, specOutputMessage, OUTPUT_MESSAGE);
// Show the new stat sheet:
queue->lock = false;
queueCommand(queue, "stat", "", 5, 0, currentCommand->caller);
queue->lock = true;
// Free the finished message:
free(specMessage);
free(formattedString);
break;
} }
}
// Talk command: Allows the player to begin a chat session with another player:
if (strncmp(currentCommand->command, "talk", 4) == 0)
{
userMessage * talkMessage = malloc(sizeof(userMessage));
talkMessage->senderName[0] = '\0';
// Temporary message until we can implement objects, events, and challenges. // Try command: Attempt to use a stat or skill on an object:
strcpy(talkMessage->messageContent, "The talk command is currently not implemented. Implement it if you want to use it.\n"); case 163143:
// Allocate an outputMessage for the queue:
outputMessage * talkOutputMessage = createTargetedOutputMessage(talkMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, talkOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage:
free(talkMessage);
}
// Stat command: Displays the current character's sheet.
if (strncmp(currentCommand->command, "stat", 4) == 0)
{
char * formattedString = calloc(121, sizeof(char));
userMessage * statMessage = calloc(1, sizeof(userMessage));
statMessage->senderName[0] = '\0';
// Basic status: Name, level, location.
snprintf(formattedString, 120, "%s, Level %d | %s\n", currentCommand->caller->playerName,
currentCommand->caller->stats->level, currentCommand->caller->currentArea->areaName);
strncat(statMessage->messageContent, formattedString, 120);
// Current stats: Health and WISED.
snprintf(formattedString, 120,
"Health: %d/%d\nStats:\n\tWits: %2d | Intellect: %2d | Strength: %2d | Endurance: %2d | Dexerity: %2d \n",
currentCommand->caller->stats->currentHealth, currentCommand->caller->stats->maxHealth,
currentCommand->caller->stats->wits, currentCommand->caller->stats->intellect,
currentCommand->caller->stats->strength, currentCommand->caller->stats->endurance,
currentCommand->caller->stats->dexerity);
strncat(statMessage->messageContent, formattedString, 120);
// Levelling stats: Current XP, and spec points.
if (currentCommand->caller->stats->specPoints > 0 || currentCommand->caller->stats->skillPoints > 0)
{ {
snprintf(formattedString, 120, "Current Experience: %ld | Spec Points Available: %d | Skill Points Available: %d", // Allocate the userMessage to send:
currentCommand->caller->stats->experience, currentCommand->caller->stats->specPoints, currentCommand->caller->stats->skillPoints); userMessage * tryMessage = malloc(sizeof(userMessage));
tryMessage->senderName[0] = '\0';
// Temporary message until we can implement objects, events, and challenges.
strcpy(tryMessage->messageContent, "The try command is currently not implemented. Implement it if you want to use it.\n");
// Allocate an outputMessage for the queue:
outputMessage * tryOutputMessage = createTargetedOutputMessage(tryMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, tryOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage:
free(tryMessage);
break;
} }
else
// Move command: Moves the caller to a different area given a path name or number:
case 5677603:
{ {
snprintf(formattedString, 120, "Current Experience: %ld", currentCommand->caller->stats->experience); char requestedPath[32];
if (strlen(currentCommand->arguments) > 0 && currentCommand->caller->currentArea != getFromList(parameters->areaList, 0)->area)
{
memcpy(requestedPath, currentCommand->arguments, 32);
userNameSanatize(requestedPath, 32);
requestedPath[31] = '\0';
if (movePlayerToArea(currentCommand->caller, requestedPath) == 0)
{
// Call the look command after moving. It's fine to unlock, because the loop won't
// continue until the command is queued:
queue->lock = false;
queueCommand(queue, "look", "", 5, 0, currentCommand->caller);
queue->lock = true;
}
}
break;
} }
strncat(statMessage->messageContent, formattedString, 120);
// Allocate an outputMessage for the queue: // Skill command: Allows you to put skill points into skills:
outputMessage * statOutputMessage = createTargetedOutputMessage(statMessage, &currentCommand->caller, 1); case 221096235:
// Queue the outputMessage:
pushQueue(parameters->outputQueue, statOutputMessage, OUTPUT_MESSAGE);
bzero(statMessage->messageContent, sizeof(char) * MAX);
if (currentCommand->caller->skills->head != NULL)
{ {
size_t skillIndex = 0; userMessage * skillMessage = calloc(1, sizeof(userMessage));
skillMessage->senderName[0] = '\0';
if ((currentCommand->caller->stats->skillPoints - 1) >= 0)
{
int returnValue = takeSkill(parameters->globalSkillList, currentCommand->arguments,
strlen(currentCommand->arguments), currentCommand->caller);
switch(returnValue)
{
case -1:
{
strcpy(skillMessage->messageContent, "Not a valid skill.");
break;
}
case 0:
{
strcpy(skillMessage->messageContent, "Took ");
strcat(skillMessage->messageContent, currentCommand->arguments);
strcat(skillMessage->messageContent, ".");
currentCommand->caller->stats->skillPoints--;
break;
}
}
}
else
{
strcpy(skillMessage->messageContent, "You don't have enough skill points to take this skill.\n");
}
// Allocate an outputMessage for the queue:
outputMessage * skillOutputMessage = createTargetedOutputMessage(skillMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, skillOutputMessage, OUTPUT_MESSAGE);
free(skillMessage);
break;
}
// Listskills commands: List all available skills on the server:
case 2395990522:
{
userMessage * listMessage = calloc(1, sizeof(userMessage));
char * formattedString = calloc(121, sizeof(char));
int charCount = 0; int charCount = 0;
size_t skillIndex = 0;
bool addNewline = false; bool addNewline = false;
playerSkill * skill; playerSkill * currentSkill;
while (skillIndex < currentCommand->caller->skills->itemCount) while (skillIndex < parameters->globalSkillList->itemCount)
{ {
skill = getFromList(currentCommand->caller->skills, skillIndex)->skill; currentSkill = getFromList(parameters->globalSkillList, skillIndex)->skill;
skillIndex++; snprintf(formattedString, 120, "| %-31s ", currentSkill->skillName);
snprintf(formattedString, 120, "| %2d | %31s ", skill->skillPoints, skill->skillName);
charCount += 43; charCount += 43;
strncat(statMessage->messageContent, formattedString, 120); strncat(listMessage->messageContent, formattedString, 120);
if ((charCount + 43) >= MAX) if ((charCount + 46) >= MAX)
{ {
// Allocate an outputMessage for the queue: // Allocate an outputMessage for the queue:
statOutputMessage = createTargetedOutputMessage(statMessage, &currentCommand->caller, 1); outputMessage * listOutputMessage = createTargetedOutputMessage(listMessage, &currentCommand->caller, 1);
// Queue the outputMessage: // Queue the outputMessage:
pushQueue(parameters->outputQueue, statOutputMessage, OUTPUT_MESSAGE); pushQueue(parameters->outputQueue, listOutputMessage, OUTPUT_MESSAGE);
bzero(statMessage, sizeof(userMessage));
bzero(listMessage, sizeof(userMessage));
charCount = 0; charCount = 0;
break; addNewline = false;
} }
else if (addNewline) else if (addNewline)
{ {
strncat(statMessage->messageContent, "|\n", 3); strncat(listMessage->messageContent, "|\n", 3);
charCount++; charCount++;
addNewline = false; addNewline = false;
} }
@ -385,183 +508,92 @@ int evaluateNextCommand(gameLogicParameters * parameters, queue * queue)
{ {
addNewline = true; addNewline = true;
} }
skillIndex++;
} }
// Allocate an outputMessage for the queue: // Allocate an outputMessage for the queue:
statOutputMessage = createTargetedOutputMessage(statMessage, &currentCommand->caller, 1); outputMessage * listOutputMessage = createTargetedOutputMessage(listMessage, &currentCommand->caller, 1);
// Queue the outputMessage: // Queue the outputMessage:
pushQueue(parameters->outputQueue, statOutputMessage, OUTPUT_MESSAGE); pushQueue(parameters->outputQueue, listOutputMessage, OUTPUT_MESSAGE);
free(listMessage);
free(formattedString);
break;
} }
free(statMessage);
free(formattedString);
}
// Spec command: Assign spec points to stats: // Talk command: Allows the player to begin a chat session with another player:
if (strncmp(currentCommand->command, "spec", 4) == 0) case 601264:
{
userMessage * specMessage = calloc(1, sizeof(userMessage));
specMessage->senderName[0] = '\0';
char * formattedString = calloc(121, sizeof(char));
if (currentCommand->caller->stats->specPoints > 0)
{ {
int selectedAmount = 0; userMessage * talkMessage = malloc(sizeof(userMessage));
strtok(currentCommand->arguments, " "); talkMessage->senderName[0] = '\0';
selectedAmount = atoi(&currentCommand->arguments[strlen(currentCommand->arguments) + 1]);
coreStat selectedStat = getCoreStatFromString(currentCommand->arguments, 16); // Temporary message until we can implement objects, events, and challenges.
if (selectedAmount > 0 && (currentCommand->caller->stats->specPoints - selectedAmount) >= 0) strcpy(talkMessage->messageContent, "The talk command is currently not implemented. Implement it if you want to use it.\n");
// Allocate an outputMessage for the queue:
outputMessage * talkOutputMessage = createTargetedOutputMessage(talkMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, talkOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage:
free(talkMessage);
break;
}
// Exit command: Sends an "empty" exit message to disconnect a client:
case 5284234:
{
// Allocate a userMessage containing null characters as the first char in both fields:
userMessage * exitMessage = malloc(sizeof(userMessage));
exitMessage->senderName[0] = '\0';
exitMessage->messageContent[0] = '\0';
// Allocate an outputMessage for the queue:
outputMessage * exitOutputMessage = createTargetedOutputMessage(exitMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, exitOutputMessage, OUTPUT_MESSAGE);
// Free the userMessage
free(exitMessage);
break;
}
// Join command: Allows the player to join the game given a name:
// TODO: Implement login/character creation. Will be a while:
case 5525172:
{
if (currentCommand->caller->currentArea == getFromList(parameters->areaList, 0)->area)
{ {
switch (selectedStat) bool validName = true;
for(int index = 0; index < *parameters->playerCount; index++)
{ {
case WITS: if (currentCommand->arguments[0] == '\0')
{ {
currentCommand->caller->stats->wits += selectedAmount; validName = false;
strncat(specMessage->messageContent, "Increased wits.", 16);
currentCommand->caller->stats->specPoints -= selectedAmount;
break;
} }
case INTELLECT: if (strncmp(currentCommand->arguments, parameters->connectedPlayers[index].playerName, 16) == 0)
{ {
currentCommand->caller->stats->intellect += selectedAmount; validName = false;
strncat(specMessage->messageContent, "Increased intellect.", 21);
currentCommand->caller->stats->specPoints -= selectedAmount;
break;
}
case STRENGTH:
{
currentCommand->caller->stats->strength += selectedAmount;
strncat(specMessage->messageContent, "Increased strength.", 20);
currentCommand->caller->stats->specPoints -= selectedAmount;
break;
}
case ENDURANCE:
{
currentCommand->caller->stats->endurance += selectedAmount;
strncat(specMessage->messageContent, "Increased endurance.", 21);
currentCommand->caller->stats->specPoints -= selectedAmount;
break;
}
case DEXERITY:
{
currentCommand->caller->stats->dexerity += selectedAmount;
strncat(specMessage->messageContent, "Increased dexerity.", 21);
currentCommand->caller->stats->specPoints -= selectedAmount;
break;
}
case INVALID:
{
strncat(specMessage->messageContent, "Invalid stat.", 21);
} }
} }
} if (validName)
else
{
strncat(specMessage->messageContent, "You have entered an invalid amount of spec points.", 51);
}
}
else
{
strncat(specMessage->messageContent, "You have no spec points available.", 35);
}
// Allocate an outputMessage for the queue:
outputMessage * specOutputMessage = createTargetedOutputMessage(specMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, specOutputMessage, OUTPUT_MESSAGE);
// Show the new stat sheet:
queue->lock = false;
queueCommand(queue, "stat", "", 5, 0, currentCommand->caller);
queue->lock = true;
// Free the finished message:
free(specMessage);
free(formattedString);
}
if (strncmp(currentCommand->command, "skill", 5) == 0)
{
userMessage * skillMessage = calloc(1, sizeof(userMessage));
skillMessage->senderName[0] = '\0';
if ((currentCommand->caller->stats->skillPoints - 1) >= 0)
{
int returnValue = takeSkill(parameters->globalSkillList, currentCommand->arguments,
strlen(currentCommand->arguments), currentCommand->caller);
switch(returnValue)
{
case -1:
{ {
strcpy(skillMessage->messageContent, "Not a valid skill."); strncpy(currentCommand->caller->playerName, currentCommand->arguments, 16);
break; currentCommand->caller->currentArea = getFromList(parameters->areaList, 1)->area;
} // Call the look command after joining. It's fine to unlock, because the loop won't
case 0: // continue until the command is queued:
{ queue->lock = false;
strcpy(skillMessage->messageContent, "Took "); queueCommand(queue, "look", "", 5, 0, currentCommand->caller);
strcat(skillMessage->messageContent, currentCommand->arguments); queue->lock = true;
strcat(skillMessage->messageContent, ".");
currentCommand->caller->stats->skillPoints--;
break;
} }
} }
break;
} }
else
{
strcpy(skillMessage->messageContent, "You don't have enough skill points to take this skill.\n");
}
// Allocate an outputMessage for the queue:
outputMessage * skillOutputMessage = createTargetedOutputMessage(skillMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, skillOutputMessage, OUTPUT_MESSAGE);
free(skillMessage);
} }
if (strncmp(currentCommand->command, "listskills", 10) == 0)
{
userMessage * listMessage = calloc(1, sizeof(userMessage));
char * formattedString = calloc(121, sizeof(char));
int charCount = 0;
size_t skillIndex = 0;
bool addNewline = false;
playerSkill * currentSkill;
while (skillIndex < parameters->globalSkillList->itemCount)
{
currentSkill = getFromList(parameters->globalSkillList, skillIndex)->skill;
snprintf(formattedString, 120, "| %-31s ", currentSkill->skillName);
charCount += 43;
strncat(listMessage->messageContent, formattedString, 120);
if ((charCount + 46) >= MAX)
{
// Allocate an outputMessage for the queue:
outputMessage * listOutputMessage = createTargetedOutputMessage(listMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, listOutputMessage, OUTPUT_MESSAGE);
bzero(listMessage, sizeof(userMessage));
charCount = 0;
addNewline = false;
}
else if (addNewline)
{
strncat(listMessage->messageContent, "|\n", 3);
charCount++;
addNewline = false;
}
else
{
addNewline = true;
}
skillIndex++;
}
// Allocate an outputMessage for the queue:
outputMessage * listOutputMessage = createTargetedOutputMessage(listMessage, &currentCommand->caller, 1);
// Queue the outputMessage:
pushQueue(parameters->outputQueue, listOutputMessage, OUTPUT_MESSAGE);
free(listMessage);
free(formattedString);
}
// Remove the current command and unlock the queue: // Remove the current command and unlock the queue:
currentCommand = NULL; currentCommand = NULL;
queue->lock = false; queue->lock = false;
@ -719,7 +751,7 @@ int movePlayerToArea(playerInfo * player, char * requestedPath)
if (selected != 0 && !(selected > player->currentArea->pathList->itemCount)) if (selected != 0 && !(selected > player->currentArea->pathList->itemCount))
{ {
if (getFromList(player->currentArea->pathList, selected - 1)->path != NULL && if (getFromList(player->currentArea->pathList, selected - 1)->path != NULL &&
getFromList(player->currentArea->pathList, selected - 1)->path->areaToJoin != NULL) getFromList(player->currentArea->pathList, selected - 1)->path->areaToJoin != NULL)
{ {
player->currentArea = getFromList(player->currentArea->pathList, selected - 1)->path->areaToJoin; player->currentArea = getFromList(player->currentArea->pathList, selected - 1)->path->areaToJoin;
return 0; return 0;
@ -734,12 +766,25 @@ int movePlayerToArea(playerInfo * player, char * requestedPath)
for (size_t index = 0; index < player->currentArea->pathList->itemCount; index++) for (size_t index = 0; index < player->currentArea->pathList->itemCount; index++)
{ {
if (strncmp(getFromList(player->currentArea->pathList, index)->path->pathName, if (strncmp(getFromList(player->currentArea->pathList, index)->path->pathName,
requestedPath, 32) == 0) requestedPath, 32) == 0)
{ {
printf("%s: %s\n", player->playerName, getFromList(player->currentArea->pathList, index)->path->pathName);
player->currentArea = getFromList(player->currentArea->pathList, index)->path->areaToJoin; player->currentArea = getFromList(player->currentArea->pathList, index)->path->areaToJoin;
return 0; return 0;
} }
} }
return 1; return 1;
} }
// A hash function for distinguishing commands for the game logic handler:
unsigned int hashCommand(char * command, unsigned int commandLength)
{
unsigned int hash = 0;
char * currentCharacter = command;
for (unsigned int index = 0; index < commandLength && *currentCharacter != '\0'; currentCharacter++)
{
hash = 37 * hash + *currentCharacter;
}
return hash;
}

View File

@ -55,6 +55,9 @@ int evaluateNextCommand(gameLogicParameters * parameters, queue * queue);
void queueCommand(queue * queue, char * command, char * arguments, int commandLength, int argumentsLength, void queueCommand(queue * queue, char * command, char * arguments, int commandLength, int argumentsLength,
playerInfo * callingPlayer); playerInfo * callingPlayer);
// A hash function for distinguishing commands for the game logic handler:
unsigned int hashCommand(char * command, unsigned int commandLength);
// ============================ // ============================
// -=[ Gameplay Primitives ]=-: // -=[ Gameplay Primitives ]=-:
// ============================ // ============================