/**
* @file character.c
* @ingroup character
*
* Character based code
*
* @author Geoff Davis <geoff@circlemudsquared.org>
* @author Greg Buxton <greg@circlemudsquared.org>
*
* @par Copyright:
* Copyright (C) 2006 Geoff Davis <geoff@circlemudsquared.org><br>
* Greg Buxton <greg@circlemudsquared.org>
*
* @par
* Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University<br>
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.
*
* @par
* All rights reserved. See license.doc for complete information.
*
* @package cs
* @version 1.0
*/
#define __CHARACTER_C__
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
#include "character.h"
#include "db.h"
#include "main.h"
#include "dao.h"
/*
* Here for now
*/
const char *auth_types[] = {
/* 0 */ "none",
/* 1 */ "guest",
/* 2 */ "player",
/* 3 */ "wizard",
/* 4 */ "owner",
"\n"
};
const char *genders[] = {
/* 00 */ "Neuter",
/* 01 */ "Male",
/* 02 */ "Female",
"\n"
};
const char *pc_class_types[] = {
"Magic User",
"Cleric",
"Thief",
"Warrior",
"\n"
};
const char *npc_class_types[] = {
"Normal",
"Undead",
"\n"
};
/* Saving Throw Types */
const char *save_types[] = {
/* 00 */ "paralyzation",
/* 01 */ "rod",
/* 02 */ "petrification",
/* 03 */ "breath",
/* 04 */ "spell"
};
/**
* Convert a charPlayerData_t to it's DAO representation
*
* @param parentDao the container DAO to contain the item's DAO
* @param cpData the charPlayerData_t to be converted
* @param isPlayer TRUE if being called for a Player, FALSE if being called for a Mobile
* @return none
*/
void charPlayerData_toDao(daoData_t *parentDao, struct char_player_data *cpData, bool isPlayer) {
if (parentDao == NULL) {
log("charPlayerData_toDao(): invalid 'parentDao' daoData_t.");
} else if (cpData == NULL) {
log("charPlayerData_toDao(): invalid 'cpData' struct char_player_data.");
} else {
/* Declare some working DAO pointers */
daoData_t *cpDao = NULL;
/* Declare some temporary buffer space. */
char temp[MAX_STRING_LENGTH] = {'\0'};
cpDao = dao_newChild(parentDao, "playerData");
if (isPlayer) {
/* Save PC specific data */
dao_newScalar(cpDao, "password", "%s", cpData->passwd);
dao_newScalar(cpDao, "age", "%ld", cpData->time);
sprinttype(cpData->chclass, pc_class_types, temp, sizeof(temp));
if (cpData->name && *(cpData->name) != '\0') {
dao_newScalar(cpDao, "name", "%s", cpData->name);
}
} else {
/* Save Mob specific data */
sprinttype(cpData->chclass, npc_class_types, temp, sizeof(temp));
if (cpData->short_descr && *(cpData->short_descr) != '\0') {
dao_newScalar(cpDao, "shortDescription", "%s", cpData->short_descr);
}
if (cpData->name && *(cpData->name) != '\0') {
dao_newScalar(cpDao, "keywords", "%s", cpData->name);
}
}
dao_newScalar(cpDao, "class", "%s", temp);
/* Data in common to both PCs and NPCs */
if (cpData->long_descr && *(cpData->long_descr) != '\0') {
dao_newScalar(cpDao, "longDescription", "%s", cpData->long_descr);
}
if (cpData->description && *(cpData->description) != '\0') {
dao_newScalar(cpDao, "description", "%s", cpData->description);
}
if (cpData->title && *(cpData->title) != '\0') {
dao_newScalar(cpDao, "title", "%s", cpData->title);
}
dao_newScalar(cpDao, "level", "%d", cpData->level);
sprinttype(cpData->sex, genders, temp, sizeof(temp));
dao_newScalar(cpDao, "sex", "%s", temp);
sprinttype(cpData->auth, auth_types, temp, sizeof(temp));
dao_newScalar(cpDao, "auth", "%s", temp);
dao_newScalar(cpDao, "homeTown", "%d", cpData->hometown);
dao_newScalar(cpDao, "weight", "%d", cpData->weight);
dao_newScalar(cpDao, "height", "%d", cpData->height);
}
}
/**
* Convert a charAbilities_t to it's DAO representation
*
* @param parentDao the container DAO to contain the item's DAO
* @param caData the charAbilities_t to be converted
* @return none
*/
void charAbilities_toDao(daoData_t *parentDao, struct char_ability_data *caData) {
if (parentDao == NULL) {
log("charAbilities_toDao(): invalid 'parentDao' daoData_t.");
} else if (caData == NULL) {
log("charAbilities_toDao(): invalid 'caData' struct char_ability_data.");
} else {
dao_newScalar(parentDao, "strength", "%d", caData->str);
dao_newScalar(parentDao, "strengthAdd", "%d", caData->str_add);
dao_newScalar(parentDao, "intelligence", "%d", caData->intel);
dao_newScalar(parentDao, "wisdom", "%d", caData->wis);
dao_newScalar(parentDao, "dexterity", "%d", caData->dex);
dao_newScalar(parentDao, "constitution", "%d", caData->con);
dao_newScalar(parentDao, "charisma", "%d", caData->cha);
}
}
/**
* Convert a charPointData_t to it's DAO representation
*
* @param parentDao the container DAO to contain the item's DAO
* @param cpData the charPointData_t to be converted
* @return none
*/
void charPointData_toDao(daoData_t *parentDao, struct char_point_data *cpData, bool isPlayer) {
if (parentDao == NULL) {
log("charPointData_toDao(): invalid 'parentDao' daoData_t.");
} else if (cpData == NULL) {
log("charPointData_toDao(): invalid 'cpData' struct char_point_data.");
} else {
/* Declare a DAO pointer */
daoData_t *subContainerDao = NULL;
if (isPlayer == TRUE) {
/* Save points for a Player */
subContainerDao = dao_newChild(parentDao, "hitPoints");
dao_newScalar(subContainerDao, "current", "%d", cpData->hit);
dao_newScalar(subContainerDao, "maximum", "%d", cpData->max_hit);
subContainerDao = NULL;
subContainerDao = dao_newChild(parentDao, "manaPoints");
dao_newScalar(subContainerDao, "current", "%d", cpData->mana);
dao_newScalar(subContainerDao, "maximum", "%d", cpData->max_mana);
subContainerDao = NULL;
subContainerDao = dao_newChild(parentDao, "movePoints");
dao_newScalar(subContainerDao, "current", "%d", cpData->move);
dao_newScalar(subContainerDao, "maximum", "%d", cpData->max_move);
subContainerDao = NULL;
} else {
/* Save points for a Mobile Prototype. No currents, just maxes so we can trim things down */
if (cpData->max_hit == 0) {
subContainerDao = dao_newChild(parentDao, "hitPoints");
dao_newScalar(subContainerDao, "diceNumber", "%d", cpData->hit);
dao_newScalar(subContainerDao, "diceSize", "%d", cpData->mana);
dao_newScalar(subContainerDao, "diceAdd", "%d", cpData->move);
subContainerDao = NULL;
} else {
dao_newScalar(parentDao, "hitPoints", "%d", cpData->hit);
dao_newScalar(parentDao, "manaPoints", "%d", cpData->mana);
dao_newScalar(parentDao, "maxHitPoints", "%d", cpData->max_hit);
}
dao_newScalar(parentDao, "maxManaPoints", "%d", cpData->max_mana);
dao_newScalar(parentDao, "maxMovePoints", "%d", cpData->max_move);
}
/* Common data between players and mobiles */
subContainerDao = dao_newChild(parentDao, "gold");
dao_newScalar(subContainerDao, "inHand", "%d", cpData->gold);
dao_newScalar(subContainerDao, "inBank", "%d", cpData->bank_gold);
subContainerDao = NULL;
dao_newScalar(parentDao, "armor", "%d", cpData->armor);
dao_newScalar(parentDao, "experience", "%d", cpData->exp);
dao_newScalar(parentDao, "hitRoll", "%d", cpData->hitroll);
dao_newScalar(parentDao, "damRoll", "%d", cpData->damroll);
}
}
/**
* Convert a playerSpecials_t to it's DAO representation
*
* @param parentDao the container DAO to contain the item's DAO
* @param psData the playerSpecials_t to be converted
* @return none
*/
void playerSpecials_toDao(daoData_t *parentDao, struct player_special_data *psData) {
if (parentDao == NULL) {
log("playerSpecials_toDao(): invalid 'parentDao' daoData_t.");
} else if (psData == NULL) {
log("playerSpecials_toDao(): invalid 'psData' struct player_special_data.");
} else {
/* Declare a DAO pointer */
daoData_t *subContainerDao = NULL;
subContainerDao = dao_newChild(parentDao, "poofs");
dao_newScalar(parentDao, "in", "%s", psData->poofin);
dao_newScalar(parentDao, "out", "%s", psData->poofout);
subContainerDao = NULL;
/* Now for the savedPlayerSpecials */
subContainerDao = dao_newChild(parentDao, "savedPlayerSpecials");
savedPlayerSpecials_toDao(subContainerDao, &(psData->saved));
subContainerDao = NULL;
/* Aliases */
subContainerDao = dao_newChild(parentDao, "aliases");
subContainerDao = NULL;
}
}
/**
* Convert a savedPlayerSpecials_t to it's DAO representation
*
* @param parentDao the container DAO to contain the item's DAO
* @param psData the savedPlayerSpecials_t to be converted
* @return none
*/
void savedPlayerSpecials_toDao(daoData_t *parentDao, struct player_special_data_saved *psData) {
if (parentDao == NULL) {
log("savedPlayerSpecials_toDao(): invalid 'parentDao' daoData_t.");
} else if (psData == NULL) {
log("savedPlayerSpecials_toDao(): invalid 'psData' struct player_special_data_saved.");
} else {
/* Declare a DAO pointer */
daoData_t *subContainerDao = NULL;
/* Declare an iterator variable. */
register int i = 0;
/* Declare some temporary buffer space. */
char temp[MAX_STRING_LENGTH] = {'\0'};
if (psData->wimp_level > 0) {
dao_newScalar(parentDao, "wimpLevel", "%d", psData->wimp_level);
}
if (psData->freeze_auth > AUTH_NONE) {
sprinttype(psData->freeze_auth, auth_types, temp, sizeof(temp));
dao_newScalar(parentDao, "freezeAuth", "%s", temp);
}
if (psData->invis_auth > AUTH_NONE) {
sprinttype(psData->invis_auth, auth_types, temp, sizeof(temp));
dao_newScalar(parentDao, "invisAuth", "%s", temp);
}
dao_newScalar(parentDao, "loadRoom", "%d", psData->load_room);
dao_newScalar(parentDao, "badPWAttempts", "%d", psData->bad_pws);
dao_newScalar(parentDao, "spellsToLearn", "%d", psData->spells_to_learn);
subContainerDao = dao_newChild(parentDao, "skills");
for (i = 0; i <= MAX_SKILLS; i++) {
if (psData->skills[i] > 0) {
snprintf(temp, sizeof(temp), "%d", i);
dao_newScalar(subContainerDao, temp, "%d", psData->skills[i]);
}
}
subContainerDao = NULL;
/* Saving these for now, but it doesn't appear they're actually used anywhere */
subContainerDao = dao_newChild(parentDao, "talks");
for (i = 0; i <= MAX_TONGUE; i++) {
snprintf(temp, sizeof(temp), "%d", i);
if (psData->talks[i]) {
dao_newScalar(subContainerDao, temp, "%s", "Yes");
} else {
dao_newScalar(subContainerDao, temp, "%s", "No");
}
}
subContainerDao = NULL;
if (psData->pref != 0UL) {
subContainerDao = dao_newChild(parentDao, "preferences");
dao_newScalar(subContainerDao, "brief", YESNO(IS_SET(psData->pref, PRF_BRIEF)));
dao_newScalar(subContainerDao, "compact", YESNO(IS_SET(psData->pref, PRF_COMPACT)));
dao_newScalar(subContainerDao, "deaf", YESNO(IS_SET(psData->pref, PRF_DEAF)));
dao_newScalar(subContainerDao, "noTell", YESNO(IS_SET(psData->pref, PRF_NOTELL)));
dao_newScalar(subContainerDao, "displayHP", YESNO(IS_SET(psData->pref, PRF_DISPHP)));
dao_newScalar(subContainerDao, "displayMana", YESNO(IS_SET(psData->pref, PRF_DISPMANA)));
dao_newScalar(subContainerDao, "displayMove", YESNO(IS_SET(psData->pref, PRF_DISPMOVE)));
dao_newScalar(subContainerDao, "autoExit", YESNO(IS_SET(psData->pref, PRF_AUTOEXIT)));
dao_newScalar(subContainerDao, "noHassle", YESNO(IS_SET(psData->pref, PRF_NOHASSLE)));
dao_newScalar(subContainerDao, "quest", YESNO(IS_SET(psData->pref, PRF_QUEST)));
dao_newScalar(subContainerDao, "summon", YESNO(IS_SET(psData->pref, PRF_SUMMONABLE)));
dao_newScalar(subContainerDao, "noRepeat", YESNO(IS_SET(psData->pref, PRF_NOREPEAT)));
dao_newScalar(subContainerDao, "holyLight", YESNO(IS_SET(psData->pref, PRF_HOLYLIGHT)));
dao_newScalar(subContainerDao, "color1", YESNO(IS_SET(psData->pref, PRF_COLOR_1)));
dao_newScalar(subContainerDao, "color2", YESNO(IS_SET(psData->pref, PRF_COLOR_2)));
dao_newScalar(subContainerDao, "noWiznet", YESNO(IS_SET(psData->pref, PRF_NOWIZ)));
dao_newScalar(subContainerDao, "log1", YESNO(IS_SET(psData->pref, PRF_LOG1)));
dao_newScalar(subContainerDao, "log2", YESNO(IS_SET(psData->pref, PRF_LOG2)));
dao_newScalar(subContainerDao, "noAuction", YESNO(IS_SET(psData->pref, PRF_NOAUCT)));
dao_newScalar(subContainerDao, "noGossip", YESNO(IS_SET(psData->pref, PRF_NOGOSS)));
dao_newScalar(subContainerDao, "noGrats", YESNO(IS_SET(psData->pref, PRF_NOGRATZ)));
dao_newScalar(subContainerDao, "roomFlags", YESNO(IS_SET(psData->pref, PRF_ROOMFLAGS)));
dao_newScalar(subContainerDao, "displayAuto", YESNO(IS_SET(psData->pref, PRF_DISPAUTO)));
subContainerDao = NULL;
}
subContainerDao = dao_newChild(parentDao, "conditions");
dao_newScalar(subContainerDao, "drunk", "%d", psData->conditions[DRUNK]);
dao_newScalar(subContainerDao, "hunger", "%d", psData->conditions[FULL]);
dao_newScalar(subContainerDao, "thirst", "%d", psData->conditions[THIRST]);
subContainerDao = NULL;
}
}
/**
* Convert a savedCharSpecials_t to it's DAO representation
*
* @param parentDao the container DAO to contain the item's DAO
* @param csData the savedCharSpecials_t to be converted
* @param isPlayer TRUE if being called for a Player, FALSE if being called for a Mobile
* @return none
*/
void savedCharSpecials_toDao(daoData_t *parentDao, struct char_special_data_saved *csData, bool isPlayer) {
if (parentDao == NULL) {
log("savedCharSpecials_toDao(): invalid 'parentDao' daoData_t.");
} else if (csData == NULL) {
log("savedCharSpecials_toDao(): invalid 'csData' struct char_special_data_saved.");
} else {
/* Declare a DAO pointer */
daoData_t *subContainerDao = NULL;
/* Declare an iterator variable. */
register int i = 0;
/* Declare some temporary buffer space. */
char temp[MAX_STRING_LENGTH] = {'\0'};
if (isPlayer) {
/* PC Data */
dao_newScalar(parentDao, "idnum", "%d", csData->idnum);
subContainerDao = dao_newChild(parentDao, "playerFlags");
dao_newScalar(subContainerDao, "killer", YESNO(IS_SET(csData->act, PLR_KILLER)));
dao_newScalar(subContainerDao, "thief", YESNO(IS_SET(csData->act, PLR_THIEF)));
dao_newScalar(subContainerDao, "frozen", YESNO(IS_SET(csData->act, PLR_FROZEN)));
dao_newScalar(subContainerDao, "wiriting", YESNO(IS_SET(csData->act, PLR_WRITING)));
dao_newScalar(subContainerDao, "mailing", YESNO(IS_SET(csData->act, PLR_MAILING)));
dao_newScalar(subContainerDao, "crash", YESNO(IS_SET(csData->act, PLR_CRASH)));
dao_newScalar(subContainerDao, "siteOK", YESNO(IS_SET(csData->act, PLR_SITEOK)));
dao_newScalar(subContainerDao, "noShout", YESNO(IS_SET(csData->act, PLR_NOSHOUT)));
dao_newScalar(subContainerDao, "noTitle", YESNO(IS_SET(csData->act, PLR_NOTITLE)));
dao_newScalar(subContainerDao, "deleted", YESNO(IS_SET(csData->act, PLR_DELETED)));
dao_newScalar(subContainerDao, "loadRoom", YESNO(IS_SET(csData->act, PLR_LOADROOM)));
dao_newScalar(subContainerDao, "noWizlist", YESNO(IS_SET(csData->act, PLR_NOWIZLIST)));
dao_newScalar(subContainerDao, "noDelete", YESNO(IS_SET(csData->act, PLR_NODELETE)));
dao_newScalar(subContainerDao, "invisStart", YESNO(IS_SET(csData->act, PLR_INVSTART)));
dao_newScalar(subContainerDao, "cryoSaved", YESNO(IS_SET(csData->act, PLR_CRYO)));
dao_newScalar(subContainerDao, "Dead", YESNO(IS_SET(csData->act, PLR_NOTDEADYET)));
subContainerDao = NULL;
} else {
/* NPC Data */
subContainerDao = dao_newChild(parentDao, "mobileFlags");
dao_newScalar(subContainerDao, "spec", YESNO(IS_SET(csData->act, MOB_SPEC)));
dao_newScalar(subContainerDao, "sentinel", YESNO(IS_SET(csData->act, MOB_SENTINEL)));
dao_newScalar(subContainerDao, "scavenger", YESNO(IS_SET(csData->act, MOB_SCAVENGER)));
dao_newScalar(subContainerDao, "isNPC", YESNO(IS_SET(csData->act, MOB_ISNPC)));
dao_newScalar(subContainerDao, "aware", YESNO(IS_SET(csData->act, MOB_AWARE)));
dao_newScalar(subContainerDao, "aggressive", YESNO(IS_SET(csData->act, MOB_AGGRESSIVE)));
dao_newScalar(subContainerDao, "stayZone", YESNO(IS_SET(csData->act, MOB_STAY_ZONE)));
dao_newScalar(subContainerDao, "wimpy", YESNO(IS_SET(csData->act, MOB_WIMPY)));
dao_newScalar(subContainerDao, "aggroEvil", YESNO(IS_SET(csData->act, MOB_AGGR_EVIL)));
dao_newScalar(subContainerDao, "aggroGood", YESNO(IS_SET(csData->act, MOB_AGGR_GOOD)));
dao_newScalar(subContainerDao, "aggroNeutral", YESNO(IS_SET(csData->act, MOB_AGGR_NEUTRAL)));
dao_newScalar(subContainerDao, "memory", YESNO(IS_SET(csData->act, MOB_MEMORY)));
dao_newScalar(subContainerDao, "helper", YESNO(IS_SET(csData->act, MOB_HELPER)));
dao_newScalar(subContainerDao, "noCharm", YESNO(IS_SET(csData->act, MOB_NOCHARM)));
dao_newScalar(subContainerDao, "noSummon", YESNO(IS_SET(csData->act, MOB_NOSUMMON)));
dao_newScalar(subContainerDao, "noSleep", YESNO(IS_SET(csData->act, MOB_NOSLEEP)));
dao_newScalar(subContainerDao, "noBash", YESNO(IS_SET(csData->act, MOB_NOBASH)));
dao_newScalar(subContainerDao, "noBlind", YESNO(IS_SET(csData->act, MOB_NOBLIND)));
dao_newScalar(subContainerDao, "Dead", YESNO(IS_SET(csData->act, MOB_NOTDEADYET)));
subContainerDao = NULL;
}
dao_newScalar(parentDao, "alignment", "%d", csData->alignment);
subContainerDao = dao_newChild(parentDao, "savingThrows");
for (i = 0; i < 5; i++) {
snprintf(temp, sizeof(temp), "%s", save_types[i]);
dao_newScalar(subContainerDao, temp, "%d", csData->apply_saving_throw[i]);
}
subContainerDao = NULL;
}
}