/****************************************************************************
* [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | *
* -----------------------------------------------------------| \\._.// *
* SmaugWiz (C) 1998 by Russ Pillsbury (Windows NT version) | (0...0) *
* -----------------------------------------------------------| ).:.( *
* SMAUG (C) 1994, 1995, 1996 by Derek Snider | {o o} *
* -----------------------------------------------------------| / ' ' \ *
* SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, |~'~.VxvxV.~'~*
* Scryn, Swordbearer, Rennard, Tricops, and Gorog. | *
* ------------------------------------------------------------------------ *
* Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik Staerfeldt, Tom Madsen, and Katja Nyboe. *
* ------------------------------------------------------------------------ *
* Deity handling module *
****************************************************************************/
// Put together by Rennard for Realms of Despair. Brap on...
#include "stdafx.h"
#include "smaug.h"
#include "Smaugx.h"
#include "mobiles.h"
#include "objects.h"
#include "rooms.h"
#include "races.h"
#include "deity.h"
#include "class.h"
#include "SmaugWizDoc.h"
#include "SmaugFiles.h"
#include "descriptor.h"
#include "character.h"
#include "sysdata.h"
CDeityData *first_deity;
CDeityData *last_deity;
// local routines
BOOL load_deity_file (const char *fname);
void write_deity_list ();
// Get pointer to deity structure from deity name
CDeityData *get_deity (const char* name)
{
CDeityData *deity;
for (deity = first_deity; deity; deity = deity->GetNext ())
if (!str_cmp (name, deity->GetName ()))
return deity;
return NULL;
}
void write_deity_list ()
{
CDeityData *tdeity;
FILE *fp;
fclose (fpReserve);
fp = fopen (FileTable.GetName (SM_DEITY_LIST), "w");
if (!fp)
bug ("FATAL: cannot open deity.lst for writing!\n\r", 0);
else {
for (tdeity = first_deity; tdeity; tdeity = tdeity->GetNext ())
fprintf (fp, "%s\n", tdeity->GetName ());
fprintf (fp, "$\n");
fclose (fp);
}
fpReserve = fopen (FileTable.GetName (SM_NULL_FILE), "r");
}
// Save a deity's data to its data file
void save_deity (CDeityData *deity)
{
FILE *fp;
if (!deity) {
bug ("save_deity: null deity pointer!", 0);
return;
}
if (! deity->IsValidName ()) {
bug ("save_deity: Deity has no name", 0);
return;
}
fclose (fpReserve);
if (! (fp = fopen (FileTable.MakeDeityName (deity->GetName ()), "w"))) {
bug ("save_deity: fopen", 0);
perror (deity->GetName ());
} else {
fprintf (fp, "#DEITY\n");
// Note: Filename is not needed since the deity name is used as
// the filename in SmaugWiz, but left in for compatibility.
fprintf (fp, "Filename %s~\n", deity->GetName ());
fprintf (fp, "Name %s~\n", deity->GetName ());
fprintf (fp, "Description %s~\n", deity->description);
fprintf (fp, "Alignment %d\n", deity->alignment);
fprintf (fp, "Worshippers %d\n", deity->worshippers);
fprintf (fp, "Flee %d\n", deity->flee);
fprintf (fp, "Flee_npcrace %d\n", deity->flee_npcrace);
fprintf (fp, "Flee_npcfoe %d\n", deity->flee_npcfoe);
fprintf (fp, "Kill %d\n", deity->kill);
fprintf (fp, "Kill_npcrace %d\n", deity->kill_npcrace);
fprintf (fp, "Kill_npcfoe %d\n", deity->kill_npcfoe);
fprintf (fp, "Kill_magic %d\n", deity->kill_magic);
fprintf (fp, "Sac %d\n", deity->sac);
fprintf (fp, "Bury_corpse %d\n", deity->bury_corpse);
fprintf (fp, "Aid_spell %d\n", deity->aid_spell);
fprintf (fp, "Aid %d\n", deity->aid);
fprintf (fp, "Steal %d\n", deity->steal);
fprintf (fp, "Backstab %d\n", deity->backstab);
fprintf (fp, "Die %d\n", deity->die);
fprintf (fp, "Die_npcrace %d\n", deity->die_npcrace);
fprintf (fp, "Die_npcfoe %d\n", deity->die_npcfoe);
fprintf (fp, "Spell_aid %d\n", deity->spell_aid);
fprintf (fp, "Dig_corpse %d\n", deity->dig_corpse);
fprintf (fp, "Scorpse %d\n", deity->scorpse);
fprintf (fp, "Savatar %d\n", deity->savatar);
fprintf (fp, "Sdeityobj %d\n", deity->sdeityobj);
fprintf (fp, "Srecall %d\n", deity->srecall);
fprintf (fp, "Race %d\n", deity->GetRace ());
fprintf (fp, "Class %d\n", deity->GetClass ());
fprintf (fp, "Element %d\n", deity->element);
fprintf (fp, "Sex %d\n", deity->sex);
fprintf (fp, "Avatar %d\n", deity->avatar);
fprintf (fp, "Deityobj %d\n", deity->deityobj);
fprintf (fp, "Affected %s\n",
NCCP deity->m_Affected.PrintVector ());
fprintf (fp, "Npcrace %d\n", deity->npcrace);
fprintf (fp, "Npcfoe %d\n", deity->npcfoe);
fprintf (fp, "Suscept %d\n", deity->suscept);
fprintf (fp, "End\n\n");
fprintf (fp, "#END\n");
fclose (fp);
}
fpReserve = fopen (FileTable.GetName (SM_NULL_FILE), "r");
}
#if defined (KEY)
#undef KEY
#endif
#define KEY(literal,field,value) \
if (!str_cmp (word, literal)) { \
field = value; \
fMatch = TRUE; \
break; \
}
// Read in actual deity data
void CDeityData::Read (FILE *fp)
{
char buf [MAX_STRING_LENGTH];
char *word, *pLine;
BOOL fMatch;
for (;;) {
fMatch = FALSE;
if (! feof (fp)) {
pLine = fread_line (fp);
word = ParseWord (pLine);
}
else word = "End";
switch (UPPER (word [0])) {
case '*':
fMatch = TRUE;
break;
case 'A':
if (! str_cmp (word, "Affected")) {
m_Affected.Parse (pLine);
fMatch = TRUE;
break;
}
KEY ("Aid", aid, ParseNumber (pLine));
KEY ("Aid_spell", aid_spell, ParseNumber (pLine));
KEY ("Alignment", alignment, ParseNumber (pLine));
KEY ("Avatar", avatar, ParseNumber (pLine));
break;
case 'B':
KEY ("Backstab", backstab, ParseNumber (pLine));
KEY ("Bury_corpse", bury_corpse, ParseNumber (pLine));
break;
case 'C':
KEY ("Class", m_Class, ParseNumber (pLine));
break;
case 'D':
KEY ("Deityobj", deityobj, ParseNumber (pLine));
KEY ("Description", description, ParseString (pLine, fp));
KEY ("Die", die, ParseNumber (pLine));
KEY ("Die_npcrace", die_npcrace, ParseNumber (pLine));
KEY ("Die_npcfoe", die_npcfoe, ParseNumber (pLine));
KEY ("Dig_corpse", dig_corpse, ParseNumber (pLine));
break;
case 'E':
if (!str_cmp (word, "End")) {
if (!GetName ())
SetName (STRALLOC (""));
if (!description)
description = STRALLOC ("");
return;
}
KEY ("Element", element, ParseNumber (pLine));
break;
case 'F':
// Filename not used for SmaugWiz, discard it.
if (! str_cmp (word, "Filename")) {
fMatch = TRUE;
}
// KEY ("Filename", filename, ParseStringNohash (pLine, fp));
KEY ("Flee", flee, ParseNumber (pLine));
KEY ("Flee_npcrace",flee_npcrace, ParseNumber (pLine));
KEY ("Flee_npcfoe", flee_npcfoe, ParseNumber (pLine));
break;
case 'K':
KEY ("Kill", kill, ParseNumber (pLine));
KEY ("Kill_npcrace",kill_npcrace, ParseNumber (pLine));
KEY ("Kill_npcfoe", kill_npcfoe, ParseNumber (pLine));
KEY ("Kill_magic", kill_magic, ParseNumber (pLine));
break;
case 'N':
KEY ("Name", m_pName, ParseString (pLine, fp));
KEY ("Npcfoe", npcfoe, ParseNumber (pLine));
KEY ("Npcrace", npcrace, ParseNumber (pLine));
break;
case 'R':
KEY ("Race", m_Race, ParseNumber (pLine));
break;
case 'S':
KEY ("Sac", sac, ParseNumber (pLine));
KEY ("Savatar", savatar, ParseNumber (pLine));
KEY ("Scorpse", scorpse, ParseNumber (pLine));
KEY ("Sdeityobj", sdeityobj, ParseNumber (pLine));
KEY ("Srecall", srecall, ParseNumber (pLine));
KEY ("Sex", sex, ParseNumber (pLine));
KEY ("Spell_aid", spell_aid, ParseNumber (pLine));
KEY ("Steal", steal, ParseNumber (pLine));
KEY ("Suscept", suscept, ParseNumber (pLine));
break;
case 'W':
KEY ("Worshippers", worshippers, ParseNumber (pLine));
break;
}
if (!fMatch) {
sprintf (buf, "CDeityData::Read: no match: %s", word);
bug (buf, 0);
}
}
}
// Load a deity file
BOOL load_deity_file (const char *fname)
{
CDeityData *deity;
FILE *fp;
BOOL found;
char *pLine;
found = FALSE;
if ((fp = fopen (FileTable.MakeDeityName (fname), "r"))) {
for (;;) {
char letter;
char *word;
pLine = fread_line (fp);
letter = *pLine++;
if (letter == '*')
continue;
if (letter != '#') {
bug ("Load_deity_file: # not found.");
break;
}
word = ParseWord (pLine);
if (! str_cmp (word, "DEITY")) {
deity = new CDeityData;
deity->Read (fp);
LINK (deity, first_deity, last_deity);
found = TRUE;
break;
} else {
bug ("Load_deity_file: bad section: %s.", word);
break;
}
}
fclose (fp);
}
return found;
}
// Load in all the deity files
void load_deities ()
{
FILE *fp;
char *pFname, *pLine;
first_deity = NULL;
last_deity = NULL;
gpDoc->LogString ("Loading deities...", LOG_BOOT);
if (! (fp = fopen (FileTable.GetName (SM_DEITY_LIST), "r"))) {
perror (FileTable.GetName (SM_DEITY_LIST));
ThrowSmaugException (SE_DEITY);
}
while (! feof (fp)) {
pLine = fread_line (fp);
pFname = ParseWord (pLine);
if (pFname [0] == '$') then break;
gpDoc->LogString (pFname, LOG_BOOT);
if (! load_deity_file (pFname))
bug ("Cannot load deity file: %s", pFname);
}
fclose (fp);
}
void do_setdeity (CCharacter *ch, char *argument)
{
char arg1 [MAX_INPUT_LENGTH];
char arg2 [MAX_INPUT_LENGTH];
char arg3 [MAX_INPUT_LENGTH];
CDeityData *deity;
int value;
if (ch->IsNpc ()) {
ch->SendText ("Huh?\n\r");
return;
}
switch (ch->GetSubstate ()) {
default:
break;
case SUB_RESTRICTED:
ch->SendText ("You cannot do this while in another command.\n\r");
return;
case SUB_DEITYDESC:
deity = (CDeityData *) ch->dest_buf;
STRFREE (deity->description);
deity->description = ch->GetEditBuffer ();
ch->StopEditing ();
save_deity (deity);
ch->SetSubstate (ch->tempnum);
return;
}
argument = one_argument (argument, arg1);
argument = one_argument (argument, arg2);
if (arg1[0] == '\0') {
ch->SendText ("Usage: setdeity <deity> <field> <toggle>\n\r");
ch->SendText ("\n\rField being one of:\n\r");
ch->SendText ("filename name description type alignment worshippers npcfoe\n\r");
ch->SendText ("deityobj race npcrace class element avatar sex affected suscept\n\r");
ch->SendText ("\n\rFavor adjustments:\n\r");
ch->SendText ("flee flee_npcrace kill kill_npcrace kill_magic\n\r");
ch->SendText ("die die_npcrace dig_corpse bury_corpse spell_aid\n\r");
ch->SendText ("steal backstab aid aid_spell sac kill_npcfoe\n\r");
ch->SendText ("die_npcfoe flee_npcfoe\n\r");
ch->SendText ("\n\rFavor requirements for supplicate:\n\r");
ch->SendText ("scorpse savatar sdeityobj srecall\n\r");
return;
}
deity = get_deity (arg1);
if (!deity) {
ch->SendText ("No such deity.\n\r");
return;
}
if (!strcmp (arg2, "name")) {
STRFREE (deity->GetName ());
deity->SetName (STRALLOC (argument));
save_deity (deity);
write_deity_list ();
ch->SendText ("Done.\n\r");
return;
}
if (! strcmp (arg2, "description")) {
if (ch->GetSubstate () == SUB_REPEATCMD)
ch->tempnum = SUB_REPEATCMD;
else
ch->tempnum = SUB_NONE;
ch->SetSubstate (SUB_DEITYDESC);
ch->dest_buf = deity;
start_editing (ch, deity->description);
return;
}
if (!strcmp (arg2, "alignment")) {
deity->alignment = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "flee")) {
deity->flee = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "flee_npcrace")) {
deity->flee_npcrace = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "flee_npcfoe")) {
deity->flee_npcfoe = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "kill")) {
deity->kill = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "kill_npcrace")) {
deity->kill_npcrace = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "kill_npcfoe")) {
deity->kill_npcfoe = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "kill_magic")) {
deity->kill_magic = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "sac")) {
deity->sac = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "bury_corpse")) {
deity->bury_corpse = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "aid_spell")) {
deity->aid_spell = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "aid")) {
deity->aid = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "steal")) {
deity->steal = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "backstab")) {
deity->backstab = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "die")) {
deity->die = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "die_npcrace")) {
deity->die_npcrace = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "die_npcfoe")) {
deity->die_npcfoe = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "spell_aid")) {
deity->spell_aid = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "dig_corpse")) {
deity->dig_corpse = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "scorpse")) {
deity->scorpse = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "savatar")) {
deity->savatar = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "sdeityobj")) {
deity->sdeityobj = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "srecall")) {
deity->srecall = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "worshippers")) {
deity->worshippers = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "deityobj")) {
deity->deityobj = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "race")) {
CRaceData *pRace = RaceTable.Find (argument);
if (pRace)
deity->SetRace (pRace->GetRace ());
else
deity->SetRace (-1);
save_deity (deity);
ch->SendTextf ("Deity race set to %s.\n\r",
deity->GetRace () == -1 ? "all" : argument);
return;
}
if (!strcmp (arg2, "npcrace")) {
value = RaceTable.GetNpcRace (argument);
if (value < 0) value = atoi (argument);
if ((value < 0) || (value >= MAX_NPC_RACE)) {
ch->SendText ("Invalid npc race.\n\r");
return;
}
deity->npcrace = value;
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "npcfoe")) {
value = RaceTable.GetNpcRace (argument);
if (value < 0) value = atoi (argument);
if ((value < 0) || (value >= MAX_NPC_RACE)) {
ch->SendText ("Invalid npc race.\n\r");
return;
}
deity->npcfoe = value;
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "class")) {
deity->SetClass (atoi (argument));
if ((deity->GetClass () < 0) || (deity->GetClass () >= ClassTable.GetCount ()))
deity->SetClass (-1);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "suscept")) {
BOOL fMatch = FALSE;
while (argument[0] != '\0') {
argument = one_argument (argument, arg3);
if (!str_cmp (arg3, "none")) {
fMatch = TRUE;
deity->suscept = 0;
} else {
value = get_risflag (arg3);
if (value < 0 || value > 31)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else {
TOGGLE_BIT (deity->suscept, 1 << value);
fMatch = TRUE;
}
}
}
if (fMatch) ch->SendTextf ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "element")) {
BOOL fMatch = FALSE;
while (argument[0] != '\0') {
argument = one_argument (argument, arg3);
if (!str_cmp (arg3, "none")) {
fMatch = TRUE;
deity->element = 0;
} else {
value = get_risflag (arg3);
if (value < 0 || value > 31)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else {
TOGGLE_BIT (deity->element, 1 << value);
fMatch = TRUE;
}
}
}
if (fMatch) ch->SendTextf ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "avatar")) {
deity->avatar = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "sex")) {
deity->sex = atoi (argument);
ch->SendText ("Done.\n\r");
save_deity (deity);
return;
}
if (!strcmp (arg2, "affected")) {
BOOL fMatch = FALSE;
while (argument[0] != '\0') {
argument = one_argument (argument, arg3);
if (!str_cmp (arg3, "none")) {
fMatch = TRUE;
deity->m_Affected.Empty ();
} else {
value = get_aflag (arg3);
if (value < 0 || value > 31)
ch->SendTextf ("Unknown flag: %s\n\r", arg3);
else {
deity->ToggleAffected (value);
fMatch = TRUE;
}
}
}
if (fMatch) ch->SendTextf ("Done.\n\r");
save_deity (deity);
return;
}
do_setdeity (ch, "");
}
void do_showdeity (CCharacter *ch, char *argument)
{
CDeityData *deity;
if (ch->IsNpc ()) {
ch->SendText ("Huh?\n\r");
return;
}
if (argument [0] == '\0') {
ch->SendText ("Usage: showdeity <deity>\n\r");
return;
}
deity = get_deity (argument);
if (! deity) {
ch->SendText ("No such deity.\n\r");
return;
}
ch->SendTextf ("Deity: %s\n\rDescription:\n\r%s\n\r", deity->GetName (),
deity->description);
ch->SendTextf ("Alignment: %-6dNpcrace: %-9sNpcfoe: %s\n\r",
deity->alignment,
RaceTable.GetNpcRaceName (deity->npcrace),
RaceTable.GetNpcRaceName (deity->npcfoe));
ch->SendTextf ("Race: %-11sClass: %-11sSex: %s\n\r",
deity->GetRace () == -1 ?
"all" : RaceTable.GetNpcRaceName (deity->GetRace ()),
deity->GetClass () == -1 ?
"all" : ClassTable.GetNpcClassName (deity->GetClass ()),
deity->sex == -1 ? "all" :
deity->sex == SEX_MALE ? "male" :
deity->sex == SEX_FEMALE ? "female" : "neutral");
ch->SendTextf ("Object: %-9dAvatar: %-10dWorshippers: %d\n\r",
deity->deityobj, deity->avatar, deity->worshippers);
ch->SendTextf ("\n\rAffected: %s\n\r",
NCCP deity->m_Affected.PrintString ());
ch->SendTextf ("Suscept: %s\n\r", flag_string (deity->suscept, ris_flags));
ch->SendTextf ("Element: %s\n\r", flag_string (deity->element, ris_flags));
ch->SendTextf ("\n\rFlee: %-11dFlee_npcrace: %-4dKill_npcrace: "
"%-4dKill: %d\n\r", deity->flee, deity->flee_npcrace,
deity->kill_npcrace, deity->kill);
ch->SendTextf ("Kill_magic: %-5dSac: %-13dBury_corpse: %-5dAid_spell: "
"%d\n\r", deity->kill_magic, deity->sac, deity->bury_corpse,
deity->aid_spell);
ch->SendTextf ("Aid: %-12dSteal: %-11dBackstab: %-8dDie: %d\n\r",
deity->aid, deity->steal, deity->backstab, deity->die);
ch->SendTextf ("Die_npcrace: %-4dDig_corpse: %-6dSpell_aid: %-7dKill_npcfoe: %d\n\r",
deity->die_npcrace, deity->dig_corpse, deity->spell_aid, deity->kill_npcfoe);
ch->SendTextf ("Die_npcfoe: %-5dFlee_npcfoe: %d\n\r",
deity->die_npcfoe, deity->flee_npcfoe);
ch->SendTextf ("\n\rScorpse: %-8dSavatar: %-9dSdeityobj: %-7d"
"Srecall: %d\n\r", deity->scorpse, deity->savatar,
deity->sdeityobj, deity->srecall);
}
void do_makedeity (CCharacter *ch, char *argument)
{
if (!argument || argument[0] == '\0') {
ch->SendText ("Usage: makedeity <deity name>\n\r");
return;
}
CDeityData *deity = new CDeityData;
LINK (deity, first_deity, last_deity);
deity->SetName (STRALLOC (argument));
deity->description = STRALLOC ("");
save_deity (deity);
write_deity_list ();
}
void do_devote (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
CDeityData *deity;
if (ch->IsNpc ()) {
ch->SendText ("Huh?\n\r");
return;
}
if (ch->GetLevel () < 10) {
ch->SendText ("You are not yet prepared for such devotion.\n\r");
return;
}
argument = one_argument (argument, arg);
if (arg [0] == '\0') {
ch->SendText ("Devote yourself to which deity?\n\r");
return;
}
if (! str_cmp (arg, "none")) {
CAffectData af;
if (! ch->GetPcData ()->deity) {
ch->SendText ("You have already chosen to worship no deities.\n\r");
return;
}
--ch->GetPcData ()->deity->worshippers;
ch->GetPcData ()->favor = -2500;
ch->SetMentalState (-80);
ch->SendText ("A terrible curse afflicts you as you forsake a deity!\n\r");
ch->ClrAffectBits (ch->GetPcData ()->deity->m_Affected);
ch->ClrResist (ch->GetPcData ()->deity->element);
ch->ClrSusceptible (ch->GetPcData ()->deity->suscept);
affect_strip (ch, gsn_blindness);
af.type = gsn_blindness;
af.location = APPLY_HITROLL;
af.modifier = -4;
af.duration = (short) (50 * DUR_CONV);
af.bitvector = AFF_BLIND;
affect_to_char (ch, &af);
save_deity (ch->GetPcData ()->deity);
ch->SendText ("You cease to worship any deity.\n\r");
ch->GetPcData ()->deity = NULL;
STRFREE (ch->GetPcData ()->GetDeityName ());
ch->GetPcData ()->SetDeityName (STRALLOC (""));
save_char_obj (ch);
return;
}
deity = get_deity (arg);
if (! deity) {
ch->SendText ("No such deity holds weight on this world.\n\r");
return;
}
if (ch->GetPcData ()->deity) {
ch->SendText ("You are already devoted to a deity.\n\r");
return;
}
if ((deity->GetClass () != -1)
&& (deity->GetClass () != ch->GetClass ())) {
ch->SendText (
"That deity will not accept your worship due to your class.\n\r");
return;
}
if ((deity->sex != -1) && (deity->sex != ch->GetSex ())) {
ch->SendText ("That deity will not accept worshippers of your sex.\n\r");
return;
}
if ((deity->GetRace () != -1) && (deity->GetRace () != ch->GetRace ())) {
ch->SendText ("That deity will not accept worshippers of your race.\n\r");
return;
}
STRFREE (ch->GetPcData ()->GetDeityName ());
ch->GetPcData ()->SetDeityName (QUICKLINK (deity->GetName ()));
ch->GetPcData ()->deity = deity;
ch->SetAffectBits (ch->GetPcData ()->deity->m_Affected);
ch->SetResist (ch->GetPcData ()->deity->element);
ch->SetSusceptible (ch->GetPcData ()->deity->suscept);
act (AT_MAGIC, "Body and soul, you devote yourself to $t!",
ch, ch->GetPcData ()->GetDeityName (), NULL, TO_CHAR);
++ch->GetPcData ()->deity->worshippers;
save_deity (ch->GetPcData ()->deity);
save_char_obj (ch);
}
void do_deities (CCharacter *ch, char *argument)
{
CDeityData *deity;
int count = 0;
if (argument[0] == '\0')
{
set_char_color (AT_NOTE, ch);
ch->SendText ("For detailed information on a deity, try deities <deity>.\n\r");
ch->SendText ("\n\rDeity Worshippers\n\r");
for (deity = first_deity; deity; deity = deity->GetNext ())
{
ch->SendTextf ("%-14s %19d\n\r", deity->GetName (), deity->worshippers);
count++;
}
if (!count)
{
ch->SendText ("There are no deities on this world.\n\r");
return;
}
return;
}
deity = get_deity (argument);
if (!deity)
{
ch->SendText ("That deity does not exist.\n\r");
return;
}
set_char_color (AT_NOTE, ch);
ch->SendTextf ("Deity: %s\n\rDescription:\n\r%s", deity->GetName (), deity->description);
return;
}
void do_supplicate (CCharacter *ch, char *argument)
{
char arg [MAX_INPUT_LENGTH];
one_argument (argument, arg);
if (ch->IsNpc () || !ch->GetPcData ()->deity) {
ch->SendText ("You have no deity to supplicate to.\n\r");
return;
}
if (arg [0] == '\0') {
ch->SendText ("Supplicate for what?\n\r");
return;
}
if (!str_cmp (arg, "corpse") && ! ch->IsPkiller ()) {
char buf2 [MAX_STRING_LENGTH];
char buf3 [MAX_STRING_LENGTH];
CObjData *obj;
if (ch->GetPcData ()->favor < ch->GetPcData ()->deity->scorpse) {
ch->SendText ("You are not favored enough for a corpse retrieval.\n\r");
return;
}
sprintf (buf3, " ");
sprintf (buf2, "the corpse of %s", ch->GetName ());
BOOL bFound = FALSE;
CObjIndexData &Idx = *OIdxTable.Find (OBJ_VNUM_CORPSE_PC);
if (! &Idx)
bug ("do_supplicate: No object index for OBJ_VNUM_CORPSE_PC.");
else {
POSITION pos = Idx.m_ObjList.GetHeadPosition ();
while (pos) {
obj = Idx.m_ObjList.GetNext (pos);
if (obj->in_room && ! str_cmp (buf2, obj->GetShortDescr ())) {
bFound = TRUE;
act (AT_MAGIC, "Your corpse appears suddenly, surrounded "
"by a divine presence...", ch, NULL, NULL, TO_CHAR);
act (AT_MAGIC, "$n's corpse appears suddenly, surrounded "
"by a divine force...", ch, NULL, NULL, TO_ROOM);
obj_from_room (obj);
obj = obj_to_room (obj, ch->GetInRoom ());
ch->GetPcData ()->favor -= ch->GetPcData ()->deity->scorpse;
}
}
}
if (! bFound) {
ch->SendText ("No corpse of yours litters the world...\n\r");
return;
}
return;
}
if (! str_cmp (arg, "avatar")) {
CMobIndexData *pMobIndex;
CCharacter *victim;
if (ch->GetPcData ()->favor < ch->GetPcData ()->deity->savatar) {
ch->SendText ("You are not favored enough for that.\n\r");
return;
}
if (ch->GetPcData ()->deity->avatar < 1) {
ch->SendText ("Your deity does not have an avatar to summon.\n\r");
return;
}
pMobIndex = MobTable.GetMob (ch->GetPcData ()->deity->avatar);
victim = create_mobile (pMobIndex);
victim->SendToRoom (ch->GetInRoom ());
act (AT_MAGIC, "$n summons a powerful avatar!", ch, NULL, NULL, TO_ROOM);
act (AT_MAGIC, "You summon a powerful avatar!", ch, NULL, NULL, TO_CHAR);
ch->GetPcData ()->favor -= ch->GetPcData ()->deity->savatar;
return;
}
if (! str_cmp (arg, "object")) {
CObjData *obj;
CObjIndexData *pObjIndex;
if (ch->GetPcData ()->favor < ch->GetPcData ()->deity->sdeityobj) {
ch->SendText ("You are not favored enough for that.\n\r");
return;
}
if (ch->GetPcData ()->deity->deityobj < 1) {
ch->SendText ("Your deity does not have a sigil of worship.\n\r");
return;
}
pObjIndex = OIdxTable.GetObj (ch->GetPcData ()->deity->deityobj);
obj = create_object (pObjIndex, ch->GetLevel ());
if (obj->CanWear (ITEM_TAKE))
obj = obj_to_char (obj, ch);
else
obj = obj_to_room (obj, ch->GetInRoom ());
act (AT_MAGIC, "$n weaves $p from divine matter!", ch, obj, NULL, TO_ROOM);
act (AT_MAGIC, "You weave $p from divine matter!", ch, obj, NULL, TO_CHAR);
ch->GetPcData ()->favor -= ch->GetPcData ()->deity->sdeityobj;
return;
}
if (! str_cmp (arg, "recall")) {
CRoomIndexData *location;
if (ch->GetPcData ()->favor < ch->GetPcData ()->deity->srecall) {
ch->SendText (
"You do not have enough favor for such a supplication.\n\r");
return;
}
if (ch->GetInRoom () == RoomTable.GetRoom (SysData.m_RoomHell)) {
ch->SendText ("You have been forsaken!\n\r");
return;
}
location = NULL;
if (! ch->IsNpc () && ch->GetPcData ()->GetClan ())
location = RoomTable.GetRoom (ch->GetPcData ()->GetClan ()->recall);
if (!ch->IsNpc () && !location && ch->GetLevel () >= 5
&& ch->IsPkiller ())
location = RoomTable.GetRoom (3009);
if (! location)
location = RoomTable.GetRoom (SysData.m_RoomTemple);
if (! location) {
ch->SendText ("You are completely lost.\n\r");
return;
}
act (AT_MAGIC, "$n disappears in a column of divine power.", ch,
NULL, NULL, TO_ROOM);
ch->RemoveFromRoom ();
ch->SendToRoom (location);
if (ch->mount) {
ch->mount->RemoveFromRoom ();
ch->mount->SendToRoom (location);
}
act (AT_MAGIC, "$n appears in the room from a column of divine mist.",
ch, NULL, NULL, TO_ROOM);
do_look (ch, "auto");
ch->GetPcData ()->favor -= ch->GetPcData ()->deity->srecall;
return;
}
ch->SendText ("You cannot supplicate for that.\n\r");
}
// Internal function to adjust favor.
// Fields are:
// 0 = flee 5 = sac 10 = backstab
// 1 = flee_npcrace 6 = bury_corpse 11 = die
// 2 = kill 7 = aid_spell 12 = die_npcrace
// 3 = kill_npcrace 8 = aid 13 = spell_aid
// 4 = kill_magic 9 = steal 14 = dig_corpse
// 15 = die_npcfoe 16 = flee_npcfoe 17 = kill_npcfoe
void adjust_favor (CCharacter *ch, int field, int mod)
{
if (ch->IsNpc () || !ch->GetPcData ()->deity)
return;
CDeityData &Di = *ch->GetPcData ()->deity;
short &Favor = ch->GetPcData ()->favor;
if ((ch->GetAlignment () - Di.alignment > 650
|| ch->GetAlignment () - Di.alignment < -650)
&& Di.alignment != 0) {
Favor -= 2;
Favor = URANGE (-1000, Favor, 1000);
return;
}
if (mod < 1) then mod = 1;
switch (field) {
case 0: Favor += number_fuzzy (Di.flee / mod); break;
case 1: Favor += number_fuzzy (Di.flee_npcrace / mod); break;
case 2: Favor += number_fuzzy (Di.kill / mod); break;
case 3: Favor += number_fuzzy (Di.kill_npcrace / mod); break;
case 4: Favor += number_fuzzy (Di.kill_magic / mod); break;
case 5: Favor += number_fuzzy (Di.sac / mod); break;
case 6: Favor += number_fuzzy (Di.bury_corpse / mod); break;
case 7: Favor += number_fuzzy (Di.aid_spell / mod); break;
case 8: Favor += number_fuzzy (Di.aid / mod); break;
case 9: Favor += number_fuzzy (Di.steal / mod); break;
case 10: Favor += number_fuzzy (Di.backstab / mod); break;
case 11: Favor += number_fuzzy (Di.die / mod); break;
case 12: Favor += number_fuzzy (Di.die_npcrace / mod); break;
case 13: Favor += number_fuzzy (Di.spell_aid / mod); break;
case 14: Favor += number_fuzzy (Di.dig_corpse / mod); break;
case 15: Favor += number_fuzzy (Di.die_npcfoe / mod); break;
case 16: Favor += number_fuzzy (Di.flee_npcfoe / mod); break;
case 17: Favor += number_fuzzy (Di.kill_npcfoe / mod); break;
}
Favor = URANGE (-1000, Favor, 1000);
}