server-1.12/common/holy.c

230 lines
7.8 KiB
C

/*
* static char *rcsid_holy_c =
* "$Id: holy.c 11578 2009-02-23 22:02:27Z lalo $";
*/
/*
CrossFire, A Multiplayer game for X-windows
Copyright (C) 2006 Mark Wedel & Crossfire Development Team
Copyright (C) 1992 Frank Tore Johansen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The authors can be reached via e-mail at crossfire-devel@real-time.com
*/
/**
* @file holy.c
* God-related common functions.
*/
#include <stdlib.h>
#include <global.h>
#include <living.h>
#include <spells.h>
static void add_god_to_list(archetype *god_arch);
/**
* Initializes a god structure.
*
* @note
* Will never return NULL.
*/
static godlink *init_godslist(void) {
godlink *gl = (godlink *)malloc(sizeof(godlink));
if (gl == NULL)
fatal(OUT_OF_MEMORY);
gl->name = NULL; /* how to describe the god to the player */
gl->arch = NULL; /* pointer to the archetype of this god */
gl->id = 0; /* id of the god */
gl->next = NULL; /* next god in this linked list */
return gl;
}
/**
* This takes a look at all of the archetypes to find
* the objects which correspond to the GODS (type GOD)
*/
void init_gods(void) {
archetype *at = NULL;
LOG(llevDebug, "Initializing gods...\n");
for (at = first_archetype; at != NULL; at = at->next)
if (at->clone.type == GOD)
add_god_to_list(at);
LOG(llevDebug, "done.\n");
}
/**
* Adds specified god to linked list, gives it an id.
*
* @param god_arch
* God to add. If NULL, will log an error.
*/
static void add_god_to_list(archetype *god_arch) {
godlink *god;
if (!god_arch) {
LOG(llevError, "ERROR: Tried to add null god to list!\n");
return;
}
god = init_godslist();
god->arch = god_arch;
god->name = add_string(god_arch->clone.name);
if (!first_god)
god->id = 1;
else {
god->id = first_god->id+1;
god->next = first_god;
}
first_god = god;
#ifdef DEBUG_GODS
LOG(llevDebug, "Adding god %s (%d) to list\n", god->name, god->id);
#endif
}
/**
* Returns a random god.
*
* @return
* a random god, or NULL if no god was found.
*/
godlink *get_rand_god(void) {
godlink *god = first_god;
int i;
if (god)
for (i = RANDOM()%(god->id)+1; god; god = god->next)
if (god->id == i)
break;
if (!god)
LOG(llevError, "get_rand_god(): can't find a random god!\n");
return god;
}
/**
* Returns a pointer to the object
* We need to be VERY careful about using this, as we
* are returning a pointer to the CLONE object. -b.t.
*
* @param godlnk
* god to get object.
*/
const object *pntr_to_god_obj(godlink *godlnk) {
if (godlnk && godlnk->arch)
return &godlnk->arch->clone;
return NULL;
}
/**
* Frees all god information.
*/
void free_all_god(void) {
godlink *god, *godnext;
LOG(llevDebug, "Freeing god information\n");
for (god = first_god; god; god = godnext) {
godnext = god->next;
if (god->name)
free_string(god->name);
free(god);
}
first_god = NULL;
}
/**
* Prints all gods to stderr.
*
* @todo
* use LOG instead of fprintf().
*/
void dump_gods(void) {
godlink *glist;
fprintf(stderr, "\n");
for (glist = first_god; glist; glist = glist->next) {
const object *god = pntr_to_god_obj(glist);
char tmpbuf[HUGE_BUF];
int tmpvar, gifts = 0;
fprintf(stderr, "GOD: %s\n", god->name);
fprintf(stderr, " avatar stats:\n");
fprintf(stderr, " S:%d C:%d D:%d I:%d W:%d P:%d\n", god->stats.Str, god->stats.Con, god->stats.Dex, god->stats.Int, god->stats.Wis, god->stats.Pow);
fprintf(stderr, " lvl:%d speed:%4.2f\n", god->level, god->speed);
fprintf(stderr, " wc:%d ac:%d hp:%d dam:%d\n", god->stats.wc, god->stats.ac, god->stats.hp, god->stats.dam);
fprintf(stderr, " enemy: %s\n", god->title ? god->title : "NONE");
if (god->other_arch) {
object *serv = &god->other_arch->clone;
fprintf(stderr, " servant stats: (%s)\n", god->other_arch->name);
fprintf(stderr, " S:%d C:%d D:%d I:%d W:%d P:%d\n", serv->stats.Str, serv->stats.Con, serv->stats.Dex, serv->stats.Int, serv->stats.Wis, serv->stats.Pow);
fprintf(stderr, " lvl:%d speed:%4.2f\n", serv->level, serv->speed);
fprintf(stderr, " wc:%d ac:%d hp:%d dam:%d\n", serv->stats.wc, serv->stats.ac, serv->stats.hp, serv->stats.dam);
} else
fprintf(stderr, " servant: NONE\n");
fprintf(stderr, " aligned_race(s): %s\n", god->race);
fprintf(stderr, " enemy_race(s): %s\n", (god->slaying ? god->slaying : "none"));
describe_resistance(god, 1, tmpbuf, HUGE_BUF);
fprintf(stderr, "%s", tmpbuf);
snprintf(tmpbuf, sizeof(tmpbuf), " attacktype:");
if ((tmpvar = god->attacktype)) {
strcat(tmpbuf, "\n ");
DESCRIBE_ABILITY(tmpbuf, tmpvar, "Attacks");
}
strcat(tmpbuf, "\n aura:");
strcat(tmpbuf, "\n paths:");
if ((tmpvar = god->path_attuned)) {
strcat(tmpbuf, "\n ");
DESCRIBE_PATH(tmpbuf, tmpvar, "Attuned");
}
if ((tmpvar = god->path_repelled)) {
strcat(tmpbuf, "\n ");
DESCRIBE_PATH(tmpbuf, tmpvar, "Repelled");
}
if ((tmpvar = god->path_denied)) {
strcat(tmpbuf, "\n ");
DESCRIBE_PATH(tmpbuf, tmpvar, "Denied");
}
fprintf(stderr, "%s\n", tmpbuf);
fprintf(stderr, " Desc: %s", god->msg ? god->msg : "---\n");
fprintf(stderr, " Priest gifts/limitations: ");
if (!QUERY_FLAG(god, FLAG_USE_WEAPON)) { gifts = 1; fprintf(stderr, "\n weapon use is forbidden"); }
if (!QUERY_FLAG(god, FLAG_USE_ARMOUR)) { gifts = 1; fprintf(stderr, "\n no armour may be worn"); }
if (QUERY_FLAG(god, FLAG_UNDEAD)) { gifts = 1; fprintf(stderr, "\n is undead"); }
if (QUERY_FLAG(god, FLAG_SEE_IN_DARK)) { gifts = 1; fprintf(stderr, "\n has infravision "); }
if (QUERY_FLAG(god, FLAG_XRAYS)) { gifts = 1; fprintf(stderr, "\n has X-ray vision"); }
if (QUERY_FLAG(god, FLAG_REFL_MISSILE)) { gifts = 1; fprintf(stderr, "\n reflect missiles"); }
if (QUERY_FLAG(god, FLAG_REFL_SPELL)) { gifts = 1; fprintf(stderr, "\n reflect spells"); }
if (QUERY_FLAG(god, FLAG_STEALTH)) { gifts = 1; fprintf(stderr, "\n is stealthy"); }
if (QUERY_FLAG(god, FLAG_MAKE_INVIS)) { gifts = 1; fprintf(stderr, "\n is (permanently) invisible"); }
if (QUERY_FLAG(god, FLAG_BLIND)) { gifts = 1; fprintf(stderr, "\n is blind"); }
if (god->last_heal) { gifts = 1; fprintf(stderr, "\n hp regenerate at %d", god->last_heal); }
if (god->last_sp) { gifts = 1; fprintf(stderr, "\n sp regenerate at %d", god->last_sp); }
if (god->last_eat) { gifts = 1; fprintf(stderr, "\n digestion is %s (%d)", god->last_eat < 0 ? "slowed" : "faster", god->last_eat); }
if (god->last_grace) { gifts = 1; fprintf(stderr, "\n grace regenerates at %d", god->last_grace); }
if (god->stats.luck) { gifts = 1; fprintf(stderr, "\n luck is %d", god->stats.luck); }
if (!gifts) fprintf(stderr, "NONE");
fprintf(stderr, "\n\n");
}
}