2481 lines
74 KiB
C
2481 lines
74 KiB
C
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "ai.h"
|
|
#include "attack.h"
|
|
#include "defs.h"
|
|
#include "flag.h"
|
|
#include "god.h"
|
|
#include "io.h"
|
|
#include "lf.h"
|
|
#include "map.h"
|
|
#include "move.h"
|
|
#include "nexus.h"
|
|
#include "objects.h"
|
|
#include "spell.h"
|
|
#include "text.h"
|
|
|
|
extern int statdirty;
|
|
|
|
extern WINDOW *mainwin;
|
|
|
|
extern map_t *firstmap;
|
|
extern map_t *heaven;
|
|
extern race_t *firstrace, *lastrace;
|
|
extern raceclass_t *firstraceclass, *lastraceclass;
|
|
extern job_t *firstjob, *lastjob;
|
|
extern skill_t *firstskill, *lastskill;
|
|
extern objecttype_t *objecttype;
|
|
extern lifeform_t *player;
|
|
|
|
lifeform_t *godlf[MAXGODS];
|
|
int ngodlfs = 0;
|
|
|
|
void angergod(enum RACE rid, int amt, enum GODANGERREASON why) {
|
|
lifeform_t *god;
|
|
int piety;
|
|
char buf[BUFLEN];
|
|
enum PIETYLEV plev;
|
|
int dosay = B_FALSE;
|
|
|
|
if (lfhasflag(player, F_WINNER)) return;
|
|
|
|
god = findgod(rid);
|
|
|
|
modpiety(rid, -amt);
|
|
piety = getpiety(rid);
|
|
plev = getpietylev(rid, NULL, NULL);
|
|
|
|
// if you have never prayed to this god before, finish now.
|
|
if (!lfhasflag(god, F_PIETY)) {
|
|
return;
|
|
}
|
|
|
|
// if you HAVE prayed to this god before, something bad will probably happen.
|
|
|
|
switch (why) {
|
|
case GA_ATTACKALLY:
|
|
godsay(rid, B_TRUE, "How dare you attack an ally!"); break;
|
|
case GA_ATTACKHELPLESS:
|
|
godsay(rid, B_TRUE, "You would attack one who is helpless?"); break;
|
|
case GA_ATTACKOBJECT:
|
|
if (rid == R_GODTHIEVES) {
|
|
godsay(rid, B_TRUE, "What are you, a common thug?"); break;
|
|
} else if (rid == R_GODNATURE) {
|
|
godsay(rid, B_TRUE, "You dare destroy my creations?"); break;
|
|
} else {
|
|
godsay(rid, B_TRUE, "You dare desecrate my symbols?"); break;
|
|
}
|
|
case GA_ASSAULT:
|
|
if (rid == R_GODDEATH) {
|
|
godsay(rid, B_TRUE, "You dare attack one of my servants?"); break;
|
|
} else {
|
|
godsay(rid, B_TRUE, "You dare attack an innocent?"); break;
|
|
}
|
|
case GA_COWARD:
|
|
godsay(rid, B_TRUE, "Coward!"); break;
|
|
case GA_EAT:
|
|
godsay(rid, B_TRUE, "That is NOT acceptable for consumption!"); break;
|
|
case GA_GODSTONE:
|
|
switch (god->race->id) {
|
|
case R_GODPURITY: sprintf(buf, "That is not yours to touch, mortal!"); break;
|
|
case R_GODTHIEVES: sprintf(buf, "You dare to steal MY property?"); break;
|
|
case R_GODDEATH: sprintf(buf, "A fleshling thinks they can challenge the lord of death?"); break;
|
|
case R_GODFIRE: sprintf(buf, "THIIIEEEFFF!"); break;
|
|
case R_GODLIFE: sprintf(buf, "NO! You have stolen the very essense of life!"); break;
|
|
case R_GODMERCY: sprintf(buf, "NO!"); break;
|
|
case R_GODNATURE: sprintf(buf, "You threaten the destruction of everything!"); break;
|
|
case R_GODBATTLE: sprintf(buf, "Knave! Your theft constitutes a declaration of war!"); break;
|
|
case R_GODMAGIC: sprintf(buf, "One does not comprehend the danger of One's find!"); break;
|
|
default: break;
|
|
}
|
|
godsay(rid, B_TRUE, buf);
|
|
break;
|
|
case GA_HERESY:
|
|
if (rid == R_GODFIRE) {
|
|
godsay(rid, B_TRUE, "HERESY!");
|
|
} else if (rid == R_GODMAGIC) {
|
|
godsay(rid, B_TRUE, "One's mundanity is offensive!");
|
|
} else {
|
|
godsay(rid, B_TRUE, "Heresy!");
|
|
}
|
|
break;
|
|
case GA_MERCY:
|
|
godsay(rid, B_TRUE, "You allowed my sacrifice to escape!"); break;
|
|
case GA_MONEY:
|
|
godsay(rid, B_TRUE, "Where is your sense of greed?!"); break;
|
|
case GA_MURDER:
|
|
godsay(rid, B_TRUE, "You have taken a life!"); break;
|
|
case GA_PRAY: dosay = B_TRUE; break;
|
|
case GA_POISON:
|
|
godsay(rid, B_TRUE, "I do not condone the use of poison!"); break;
|
|
case GA_RACE:
|
|
godsay(rid, B_TRUE, "Your form offends me!"); break;
|
|
case GA_SPELL:
|
|
if (rid == R_GODBATTLE) {
|
|
godsay(rid, B_TRUE, "A true warrior does not resort to magic!"); break;
|
|
} else if (rid == R_GODFIRE) {
|
|
godsay(rid, B_TRUE, "NO COLD MAGIC!"); break;
|
|
} else if (rid == R_GODDEATH) {
|
|
godsay(rid, B_TRUE, "The stink of your vile magic offends me!"); break;
|
|
} else if (rid == R_GODLIFE) {
|
|
godsay(rid, B_TRUE, "I will not tolerate such evil magics!"); break;
|
|
} else {
|
|
godsay(rid, B_TRUE, "Your magic offends me!"); break;
|
|
}
|
|
}
|
|
|
|
// announce
|
|
switch (plev) {
|
|
case PL_ENRAGED:
|
|
godsay(rid,dosay, "Witness the wrath of a god!");
|
|
break;
|
|
case PL_FURIOUS:
|
|
godsay(rid,dosay, "You go too far, mortal!");
|
|
break;
|
|
case PL_ANGRY:
|
|
godsay(rid,dosay, "You have angered me, mortal!");
|
|
break;
|
|
case PL_INDIFFERENT: // ie. not angry yet...
|
|
godsay(rid, dosay, "You are testing my patience, mortal!");
|
|
break;
|
|
default: // ie. still happy
|
|
break;
|
|
}
|
|
|
|
// bad stuff
|
|
if (piety <= 0) {
|
|
void *poss[MAXCANDIDATES];
|
|
object_t *o;
|
|
flag_t *f;
|
|
int isflag[MAXCANDIDATES];
|
|
int nposs = 0;
|
|
enum ATTRIB a;
|
|
// lose at least one god gift
|
|
for (o = player->pack->first ; o ; o = o->next) {
|
|
if (hasflagval(o->flags, F_GODGIFT, rid, NA, NA, NULL)) {
|
|
poss[nposs] = o;
|
|
isflag[nposs] = B_FALSE;
|
|
nposs++;
|
|
}
|
|
}
|
|
|
|
for (f = player->flags->first ; f ; f = f->next) {
|
|
if ((f->lifetime == FROMGODGIFT) && (f->obfrom == god->race->id)) {
|
|
poss[nposs] = f;
|
|
isflag[nposs] = B_TRUE;
|
|
nposs++;
|
|
}
|
|
}
|
|
if (nposs) {
|
|
int sel;
|
|
msg("\"You are unworthy of my gifts, mortal!\"");
|
|
sel = rnd(0,nposs-1);
|
|
if (isflag[sel]) {
|
|
killflag((flag_t *)poss[sel]);
|
|
} else {
|
|
obdie((object_t *)poss[sel]);
|
|
}
|
|
}
|
|
|
|
// then...
|
|
if (plev == PL_ANGRY) {
|
|
int i,n;
|
|
flag_t *retflag[MAXCANDIDATES];
|
|
int nretflags;
|
|
lifeform_t *l;
|
|
// minor bad stuff
|
|
switch (rid) {
|
|
case R_GODBATTLE:
|
|
// rust your armour
|
|
for (o = player->pack->first ; o ; o = o->next) {
|
|
if (isarmour(o) && (o->type->material->id == MT_METAL)) {
|
|
poss[nposs++] = o;
|
|
}
|
|
}
|
|
if (nposs) {
|
|
o = poss[rnd(0,nposs-1)];
|
|
msg("\"Let your armour reflect your actions!\"");
|
|
makewet(o, R_TRUSTY);
|
|
} else {
|
|
o = getweapon(player);
|
|
if (o) {
|
|
msg("\"Let your weapon reflect your actions!\"");
|
|
makeduller(o, 2);
|
|
}
|
|
}
|
|
break;
|
|
case R_GODDEATH:
|
|
castspell(god, OT_S_PAIN, player, NULL, player->cell, NULL, NULL);
|
|
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell, NULL, NULL);
|
|
// all undead in sight become hostile
|
|
for (l = player->cell->map->lf ; l ; l = l->next) {
|
|
if (!isplayer(l) && isundead(l) && cansee(l, player)) {
|
|
if (getallegiance(l) != AL_HOSTILE) {
|
|
aiattack(l, player, PERMENANT);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case R_GODFIRE:
|
|
msg("\"Fire will burn away your sins!\"");
|
|
dospelleffects(NULL, OT_S_FLAMEPILLAR, 4, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
|
|
break;
|
|
case R_GODLIFE:
|
|
msg("\"Your body shall be slow to recover from wounds...\"");
|
|
// life spells will fail
|
|
break;
|
|
case R_GODMAGIC:
|
|
msg("\"You can live without my gifts for a while...\"");
|
|
losemp(player, player->mp);
|
|
// get random spell
|
|
getflags(player->flags, retflag, &nretflags, F_CANCAST, F_NONE);
|
|
nposs = 0;
|
|
for (i = 0; i < nretflags; i++) {
|
|
if (retflag[i]->lifetime != FROMJOB) {
|
|
poss[nposs++] = retflag[i];
|
|
}
|
|
}
|
|
if (nposs) {
|
|
f = poss[rnd(0,nposs-1)];
|
|
killflag(f);
|
|
}
|
|
break;
|
|
case R_GODNATURE:
|
|
msg("\"You have transgressed against nature!\"");
|
|
dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
|
|
// note: you will also rot food on touch until god is appeased.
|
|
// see touch().
|
|
break;
|
|
case R_GODMERCY:
|
|
// lower one attribute
|
|
msg("\"Be glad that I am feeling merciful, mortal!\"");
|
|
a = rnd(0,MAXATTS-1);
|
|
modattr(player, a, -1);
|
|
break;
|
|
case R_GODPURITY:
|
|
// remove blessings
|
|
nposs = 0;
|
|
for (o = player->pack->first ; o ; o = o->next) {
|
|
if (isblessed(o)) {
|
|
poss[nposs++] = o;
|
|
}
|
|
}
|
|
if (nposs) {
|
|
msg("\"Your actions do not befit the bearer of blessed objects!\"");
|
|
n = rnd(1,3);
|
|
if (nposs < n) n = nposs;
|
|
for (i = 0; i < n; i++) {
|
|
o = (object_t *)poss[rnd(0,nposs-1)];
|
|
while (!isblessed(o)) {
|
|
// pick again...
|
|
o = (object_t *)poss[rnd(0,nposs-1)];
|
|
}
|
|
curseob(o);
|
|
}
|
|
} else {
|
|
// don't have any blessed objects.
|
|
msg("\"Perhaps you need some time without material wealth...\"");
|
|
dospelleffects(NULL, OT_S_GUSTOFWIND, 10, NULL, NULL, player->cell, B_UNCURSED, NULL, B_TRUE);
|
|
}
|
|
break;
|
|
case R_GODTHIEVES:
|
|
// take a random object
|
|
msg("\"Yoink!\"");
|
|
castspell(god, OT_S_CONFISCATE, player, NULL, player->cell, NULL, NULL);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else if (plev == PL_FURIOUS) {
|
|
object_t *o;
|
|
lifeform_t *l;
|
|
int n,i,nretcells;
|
|
cell_t *retcell[MAXRETCELLS];
|
|
int rollagain = B_TRUE;
|
|
// major bad stuff
|
|
switch (god->race->id) {
|
|
case R_GODBATTLE:
|
|
switch (rnd(1,3)) {
|
|
case 1: // bad weapon
|
|
msg("\"A fool deserves a fool's weapon!\"");
|
|
// forcibly drop player's weapon
|
|
o = getweapon(player);
|
|
if (o) {
|
|
killflagsofid(o->flags, F_EQUIPPED);
|
|
drop(o, o->amt);
|
|
}
|
|
o = addob(player->pack, "cursed -1 stick");
|
|
if (o) {
|
|
identify(o);
|
|
weild(player, o);
|
|
}
|
|
break;
|
|
case 2: // bad armour
|
|
msg("\"A fool deserves a fool's armour!\"");
|
|
// remove all player's armour
|
|
dospelleffects(god, OT_S_INSTANTDISROBE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
|
|
// give them cursed armour
|
|
o = addob(player->pack, "cursed -5 cotton shirt");
|
|
if (o) {
|
|
resizeobject(o, getlfsize(player));
|
|
identify(o);
|
|
wear(player, o);
|
|
}
|
|
break;
|
|
case 3: // summon monsters
|
|
msg("\"Fight for your life, knave!\"");
|
|
summonlfs(player, player->cell, R_NONE, RC_HUMANOID, SZ_HUMAN, AL_NONE, 8, PERMENANT, B_FALSE);
|
|
break;
|
|
}
|
|
break;
|
|
case R_GODDEATH:
|
|
castspell(god, OT_S_PAIN, player, NULL, player->cell, NULL, NULL);
|
|
castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell, NULL, NULL);
|
|
// all undead in sight become hostile
|
|
for (l = player->cell->map->lf ; l ; l = l->next) {
|
|
if (!isplayer(l) && isundead(l) && cansee(l, player)) {
|
|
if (getallegiance(l) != AL_HOSTILE) {
|
|
aiattack(l, player, PERMENANT);
|
|
}
|
|
}
|
|
}
|
|
switch (rnd(1,2)) {
|
|
case 1:
|
|
msg("\"This will teach you some humility, mortal!\"");
|
|
if (getattr(player, A_IQ) > getattr(player, A_STR)) {
|
|
castspell(god, OT_S_FEEBLEMIND, player, NULL, player->cell, NULL, NULL);
|
|
} else {
|
|
castspell(god, OT_S_WEAKEN, player, NULL, player->cell, NULL, NULL);
|
|
}
|
|
break;
|
|
case 2:
|
|
// summon undead
|
|
msg("\"Destroy him, my pets!\"");
|
|
summonlfs(god, player->cell, R_NONE, RC_UNDEAD, SZ_ANY, AL_EVIL, 3, PERMENANT, B_FALSE);
|
|
break;
|
|
}
|
|
break;
|
|
case R_GODFIRE:
|
|
msg("\"Burn, infidel!\"");
|
|
dospelleffects(NULL, OT_S_FLAMEPILLAR, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
|
|
getradiuscells(player->cell, 1, DT_COMPASS, B_FALSE, LOF_WALLSTOP, B_FALSE, retcell, &nretcells, 0);
|
|
for (i = 0; i < nretcells; i++) {
|
|
if (!retcell[i]->type->solid) {
|
|
addobfast(retcell[i]->obpile, OT_FIRELARGE);
|
|
}
|
|
}
|
|
break;
|
|
case R_GODLIFE:
|
|
msg("\"I withdraw my gifts from you!\"");
|
|
// lower max hp by 10
|
|
player->maxhp -= 10;
|
|
limit(&(player->maxhp), 1, NA);
|
|
if (player->hp > player->maxhp) player->hp = player->maxhp;
|
|
statdirty = B_TRUE;
|
|
// player can now never heal
|
|
break;
|
|
case R_GODTHIEVES:
|
|
o = getweapon(player);
|
|
msg("\"Allow me to lighten your load a little...\"");
|
|
if (o) { // take player's weapon
|
|
castspell(god, OT_S_CONFISCATE, player, o, player->cell, NULL, NULL);
|
|
} else { // take 3 objects
|
|
int i;
|
|
for (i = 0; i < 3; i++) {
|
|
castspell(god, OT_S_CONFISCATE, player, NULL, player->cell, NULL, NULL);
|
|
}
|
|
}
|
|
break;
|
|
case R_GODMAGIC:
|
|
rollagain = B_TRUE;
|
|
while (rollagain) {
|
|
flag_t *retflag[MAXCANDIDATES];
|
|
int nretflags;
|
|
rollagain = B_FALSE;
|
|
switch (rnd(1,3)) {
|
|
case 1: // lose all spells
|
|
msg("\"I forbid you my gifts!\"");
|
|
nposs = 0;
|
|
getflags(player->flags, retflag, &nretflags, F_CANCAST, F_NONE);
|
|
nposs = 0;
|
|
for (i = 0; i < nretflags; i++) {
|
|
if (retflag[i]->lifetime != FROMJOB) {
|
|
killflag(retflag[i]);
|
|
}
|
|
}
|
|
break;
|
|
case 2: // spells usually fail
|
|
msg("\"You will find my gifts far less reliable in future!\"");
|
|
addtempflag(player->flags, F_MISCASTCHANCE, 85, NA, NA, NULL, 200);
|
|
break;
|
|
case 3: // become a newt
|
|
if (ispolymorphed(player)) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
msg("\"Maybe this will teach you some humility!\"");
|
|
setrace(player, R_NEWT, B_TRUE); // ie. don't set origrace!
|
|
}
|
|
break;
|
|
}
|
|
} // end while rollagain
|
|
break;
|
|
case R_GODMERCY:
|
|
msg("\"Even my mercy has its limits!\"");
|
|
// age
|
|
age(player, 15);
|
|
// lower every attribute by one
|
|
for (a = 0; a < MAXATTS; a++) {
|
|
modattr(player, a, -1);
|
|
}
|
|
|
|
break;
|
|
case R_GODNATURE:
|
|
msg("\"You have violated the cardinal laws of nature!\"");
|
|
dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
|
|
switch (rnd(1,3)) {
|
|
case 1:
|
|
dospelleffects(NULL, OT_S_CLOUDKILL, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
|
|
break;
|
|
case 2:
|
|
dospelleffects(NULL, OT_S_HAILSTORM, 10, NULL, NULL, player->cell, B_BLESSED, NULL, B_TRUE);
|
|
break;
|
|
case 3:
|
|
msg("\"Destroy him, my pets!\"");
|
|
summonlfs(god, player->cell, R_SAWGRASS, RC_ANY, SZ_ANY, AL_GOOD, 8, PERMENANT, B_FALSE);
|
|
break;
|
|
}
|
|
break;
|
|
case R_GODPURITY:
|
|
switch (rnd(1,2)) {
|
|
case 1:
|
|
// break objects
|
|
msg("\"Time for a lesson in materialism!\"");
|
|
nposs = 0;
|
|
for (o = player->pack->first ; o ; o = o->next) {
|
|
if (hasflag(o->flags, F_DAMAGABLE) && !hasflag(o->flags, F_DEAD)) {
|
|
poss[nposs++] = o;
|
|
}
|
|
}
|
|
n = rnd(1,3);
|
|
if (nposs < n) n = nposs;
|
|
for (i = 0; i < n; i++) {
|
|
char obname[BUFLEN];
|
|
o = (object_t *)poss[rnd(0,nposs-1)];
|
|
// damage it
|
|
getobname(o, obname, o->amt);
|
|
msg("Your %s %s struck by divine force!", OB1(o, "is", "are"), noprefix(obname));
|
|
takedamage(o, roll("2d4"), DT_DIRECT);
|
|
}
|
|
break;
|
|
case 2:
|
|
// summon holy creautes
|
|
msg("\"Destroy him, my pets!\"");
|
|
summonlfs(god, player->cell, R_NONE, RC_ANY, SZ_ANY, AL_GOOD, 3, PERMENANT, B_FALSE);
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
} else if (plev == PL_ENRAGED) {
|
|
// god attacks!
|
|
godappears(god->race->id, NULL);
|
|
aiattack(god, player, PERMENANT);
|
|
}
|
|
}
|
|
}
|
|
|
|
// anger the god if you are worshippin them.
|
|
void angergodmaybe(enum RACE rid, int amt, enum GODANGERREASON why) {
|
|
lifeform_t *god;
|
|
|
|
if (lfhasflag(player, F_WINNER)) return;
|
|
|
|
god = findgod(rid);
|
|
if (lfhasflag(god, F_PRAYEDTO)) {
|
|
angergod(rid, amt, why);
|
|
}
|
|
}
|
|
|
|
void dooffer(void) {
|
|
object_t *o, *nexto;
|
|
lifeform_t *god;
|
|
flag_t *retflag[MAXCANDIDATES];
|
|
int nretflags,pietyplus = 0;
|
|
char splatterob[BUFLEN];
|
|
strcpy(splatterob, "");
|
|
|
|
if (lfhasflag(player, F_RAGE)) {
|
|
msg("You are too enraged to offer a sacrifice!");
|
|
return;
|
|
}
|
|
|
|
// which god?
|
|
god = askgod("To whom will you sacrifice?", B_TRUE);
|
|
if (!god) {
|
|
msg("Cancelled.");
|
|
return;
|
|
}
|
|
getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBWITHFLAG, F_SACRIFICEOBBLESSED, F_NONE);
|
|
if (nretflags == 0) {
|
|
msg("%s does not accept sacrifices.", god->race->name);
|
|
return;
|
|
}
|
|
// anything here to offer?
|
|
for (o = player->cell->obpile->first ; o ; o = nexto) {
|
|
int i;
|
|
nexto = o->next;
|
|
// does the god want this?
|
|
getflags(god->flags, retflag, &nretflags, F_SACRIFICEOB, F_SACRIFICEOBCLASS, F_SACRIFICEOBWITHFLAG, F_SACRIFICEOBBLESSED, F_NONE);
|
|
for (i = 0; i < nretflags; i++) {
|
|
int ok = B_FALSE;
|
|
int thispiety = 0;
|
|
flag_t *f;
|
|
f = retflag[i];
|
|
if ((f->id == F_SACRIFICEOB) && (f->val[0] == o->type->id)) {
|
|
int validcorpse = B_FALSE;
|
|
if (f->val[1] == NA) {
|
|
validcorpse = B_TRUE;
|
|
} else {
|
|
flag_t *ff;
|
|
ff = hasflag(o->flags, F_CORPSEOF);
|
|
if (ff) {
|
|
race_t *r;
|
|
r = findrace(ff->val[0]);
|
|
if (r->raceclass->id == f->val[1]) {
|
|
validcorpse = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// special case - amberon only accepts evil corpses
|
|
if (validcorpse && (god->race->id == R_GODPURITY) && (o->type->id == OT_CORPSE)) {
|
|
flag_t *ff;
|
|
ff = hasflag(o->flags, F_ALIGNMENT);
|
|
if (!ff || (ff->val[0] != AL_EVIL)) {
|
|
validcorpse = B_FALSE;
|
|
}
|
|
}
|
|
|
|
if (validcorpse) {
|
|
ok = B_TRUE;
|
|
thispiety = f->val[2];
|
|
}
|
|
} else if ((f->id == F_SACRIFICEOBCLASS) && (f->val[0] == o->type->obclass->id)) {
|
|
ok = B_TRUE;
|
|
thispiety = f->val[2];
|
|
} else if ((f->id == F_SACRIFICEOBWITHFLAG) && hasflag(o->flags, f->val[0])) {
|
|
ok = B_TRUE;
|
|
thispiety = f->val[2];
|
|
} else if ((f->id == F_SACRIFICEOBBLESSED) && (f->val[0] == o->blessed) && (o->blessknown == B_TRUE)) {
|
|
ok = B_TRUE;
|
|
thispiety = f->val[2];
|
|
}
|
|
if (ok) {
|
|
char *p;
|
|
char obname[BUFLEN];
|
|
|
|
// override piety sometimes
|
|
if (god->race->id == R_GODTHIEVES) {
|
|
// 100 value = 1 piety.
|
|
// NOTE: this could be exploited by constantly sacrificing
|
|
// 1 gold at a time!
|
|
if ((o->type->id == OT_GOLD) || hasflag(o->flags, F_GEM)) {
|
|
thispiety = (getobvalue(o) / 100) + 1;
|
|
}
|
|
}
|
|
|
|
if (haslos(player, player->cell)) {
|
|
getobname(o, obname, ALL);
|
|
p = strdup(f->text);
|
|
p = strrep(p, "OB", obname, NULL);
|
|
if (o->amt == 1) {
|
|
p = strrep(p, "IS", "is", NULL);
|
|
p = strrep(p, "#S", "s", NULL);
|
|
} else {
|
|
p = strrep(p, "IS", "are", NULL);
|
|
p = strrep(p, "#S", "", NULL);
|
|
}
|
|
msg("%s", p);
|
|
free(p);
|
|
}
|
|
removeob(o, ALL);
|
|
pietyplus += thispiety;
|
|
// special effect
|
|
if (god->race->id == R_GODBATTLE) {
|
|
strcpy(splatterob, "splash of blood");
|
|
}
|
|
break;
|
|
}
|
|
} // end for each f_sacrificexxx flag
|
|
} // end foreach ob
|
|
|
|
|
|
if (pietyplus) {
|
|
pleasegod(god->race->id, pietyplus);
|
|
if (strlen(splatterob)) {
|
|
addob(player->cell->obpile, splatterob);
|
|
addobsinradius(player->cell, 1, DT_COMPASS, splatterob, B_TRUE, NULL);
|
|
}
|
|
if (god->race->id == R_GODFIRE) {
|
|
dospelleffects(player, OT_S_FLAMEBURST, 1, NULL, NULL, player->cell, B_UNCURSED, NULL, B_FALSE);
|
|
}
|
|
} else {
|
|
nothinghappens();
|
|
}
|
|
taketime(player, getactspeed(player));
|
|
}
|
|
|
|
|
|
lifeform_t *findgod(enum RACE rid) {
|
|
lifeform_t *lf;
|
|
// search heaven first
|
|
for (lf = heaven->lf ; lf ; lf = lf->next) {
|
|
if (lf->race->id == rid) return lf;
|
|
}
|
|
// now search other maps
|
|
lf = findlfunique(rid);
|
|
return lf;
|
|
}
|
|
|
|
enum RACE getopposinggod(enum RACE rid) {
|
|
switch (rid) {
|
|
//case R_GODPURITY: return R_GODCHAOS;
|
|
//case R_GODCHAOS: return R_GODPURITY;
|
|
case R_GODDEATH: return R_GODLIFE;
|
|
case R_GODLIFE: return R_GODDEATH;
|
|
|
|
case R_GODMERCY: return R_GODTHIEVES;
|
|
case R_GODTHIEVES: return R_GODMERCY;
|
|
|
|
case R_GODBATTLE: return R_GODMAGIC;
|
|
case R_GODMAGIC: return R_GODBATTLE;
|
|
|
|
case R_GODNATURE: return R_GODFIRE;
|
|
case R_GODFIRE: return R_GODNATURE;
|
|
default: break;
|
|
}
|
|
return R_NONE;
|
|
}
|
|
|
|
enum OBTYPE getopposinggodstone(enum RACE rid) {
|
|
objecttype_t *ot;
|
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
|
if (ot->obclass->id != OC_GODSTONE) continue;
|
|
if (hasflagval(ot->flags, F_LINKGOD, getopposinggod(rid), NA, NA, NULL)) return ot->id;
|
|
}
|
|
return OT_NONE;
|
|
}
|
|
|
|
int getpiety(enum RACE rid) {
|
|
lifeform_t *god;
|
|
flag_t *f;
|
|
god = findgod(rid);
|
|
f = lfhasflag(god, F_PIETY);
|
|
if (f) {
|
|
return f->val[0];
|
|
} else {
|
|
// ie. haven't prayed to them before.
|
|
return 100;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// return the highest piety value which will result in the given level.
|
|
int getpietycutoff(enum PIETYLEV pl) {
|
|
switch (pl) {
|
|
case PL_ENRAGED: return -200;
|
|
case PL_FURIOUS: return -100;
|
|
case PL_ANGRY: return -1;
|
|
case PL_TOLERATED: return 99;
|
|
case PL_INDIFFERENT: return 199;
|
|
case PL_PLEASED: return 299;
|
|
case PL_DELIGHTED: return 399;
|
|
case PL_ECSTATIC: return 1000;
|
|
}
|
|
// default
|
|
return 0;
|
|
}
|
|
|
|
enum PIETYLEV getpietylev(enum RACE rid, enum COLOUR *col, char *happiness) {
|
|
int piety;
|
|
/// figure out piety bracket
|
|
// min = -200
|
|
// max = 400
|
|
// range = 600
|
|
piety = getpiety(rid);
|
|
if (piety <= -200) { // -200 - -100
|
|
if (col) *col = C_ORANGE;
|
|
if (happiness) strcpy(happiness, "Enraged");
|
|
return PL_ENRAGED;
|
|
} else if (piety <= -100) { // -199 - -100
|
|
if (col) *col = C_RED;
|
|
if (happiness) strcpy(happiness, "Furious");
|
|
return PL_FURIOUS;
|
|
} else if (piety < 0) { // -99 - 0
|
|
if (col) *col = C_YELLOW;
|
|
if (happiness) strcpy(happiness, "Angry");
|
|
return PL_ANGRY;
|
|
} else if (piety <= 99) { // 0 - 99
|
|
if (col) *col = C_BROWN;
|
|
if (happiness) strcpy(happiness, "Tolerated");
|
|
return PL_TOLERATED;
|
|
} else if (piety <= 199) { // 100 - 199
|
|
if (col) *col = C_GREY;
|
|
if (happiness) strcpy(happiness, "Neutral");
|
|
return PL_INDIFFERENT;
|
|
} else if (piety <= 299) { // 200 - 299
|
|
if (col) *col = C_GREEN;
|
|
if (happiness) strcpy(happiness, "Pleased");
|
|
return PL_PLEASED;
|
|
} else if (piety <= 399) { // 300 - 399
|
|
if (col) *col = C_BOLDGREEN;
|
|
if (happiness) strcpy(happiness, "Delighted");
|
|
return PL_DELIGHTED;
|
|
} else { // 400+
|
|
if (col) *col = C_BOLDCYAN;
|
|
if (happiness) strcpy(happiness, "Ecstatic");
|
|
return PL_ECSTATIC;
|
|
}
|
|
return PL_INDIFFERENT;
|
|
}
|
|
|
|
int getprayedgods(lifeform_t **retgod, int *nretgods) {
|
|
int i;
|
|
*nretgods = 0;
|
|
for (i = 0; i < ngodlfs; i++) {
|
|
if (lfhasflag(godlf[i], F_PRAYEDTO)) {
|
|
retgod[*nretgods] = godlf[i];
|
|
(*nretgods)++;
|
|
}
|
|
}
|
|
return *nretgods;
|
|
}
|
|
|
|
lifeform_t *getrandomgod(void) {
|
|
if (ngodlfs == 0) {
|
|
return NULL;
|
|
}
|
|
return godlf[rnd(0,ngodlfs-1)];
|
|
}
|
|
|
|
// get a random god which player has prayed to
|
|
lifeform_t *getrandomprayedgod(void) {
|
|
int nposs;
|
|
lifeform_t *poss[MAXGODS];
|
|
|
|
getprayedgods(poss, &nposs);
|
|
if (nposs == 0) {
|
|
return NULL;
|
|
}
|
|
return poss[rnd(0,nposs-1)];
|
|
}
|
|
|
|
enum OBTYPE getrelatedgodstone(enum RACE rid) {
|
|
objecttype_t *ot;
|
|
for (ot = objecttype ; ot ; ot = ot->next) {
|
|
if (ot->obclass->id != OC_GODSTONE) continue;
|
|
if (hasflagval(ot->flags, F_LINKGOD, rid, NA, NA, NULL)) return ot->id;
|
|
}
|
|
return OT_NONE;
|
|
}
|
|
|
|
|
|
lifeform_t *godappears(enum RACE rid, cell_t *where) {
|
|
lifeform_t *god;
|
|
char killedname[BUFLEN],godname[BUFLEN];
|
|
god = findgod(rid);
|
|
real_getlfname(god, godname, B_FALSE, B_FALSE);
|
|
strcpy(killedname, "");
|
|
if (!where) {
|
|
// somewhere next to the player.
|
|
where = real_getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, player);
|
|
if (!where) {
|
|
where = getrandomadjcell(player->cell, B_FALSE, B_NOEXPAND);
|
|
}
|
|
}
|
|
|
|
// now see if anyone is there.
|
|
if (where->lf) {
|
|
// kill them.
|
|
getlfname(where->lf, killedname);
|
|
killlf(where->lf);
|
|
if (where->type->solid) {
|
|
setcelltype(where, where->habitat->emptycelltype);
|
|
}
|
|
teleportto(god, where, B_TRUE);
|
|
if (haslos(player, where) && strlen(killedname)) {
|
|
msg("%s transforms into %s!", killedname, godname);
|
|
}
|
|
|
|
} else {
|
|
teleportto(god, where, B_TRUE);
|
|
}
|
|
|
|
return god;
|
|
}
|
|
|
|
void god_usepoison_response(void) {
|
|
int i;
|
|
flag_t *f;
|
|
for (i = 0; i < ngodlfs; i++) {
|
|
if (godlf[i]) {
|
|
f = lfhasflag(godlf[i], F_GODPOISON);
|
|
if (f) {
|
|
if (f->val[0]) {
|
|
pleasegodmaybe(godlf[i]->race->id, f->val[1]);
|
|
} else {
|
|
angergodmaybe(godlf[i]->race->id, f->val[1], GA_POISON);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int godblocked(enum RACE rid) {
|
|
lifeform_t *opposegod,*god;
|
|
enum RACE opposeid;
|
|
god = findgod(rid);
|
|
// forcibly blocked?
|
|
if (lfhasflag(god, F_GODBLOCKED)) {
|
|
return B_TRUE;
|
|
}
|
|
// already prayed to the opposing god?
|
|
opposeid = getopposinggod(rid);
|
|
opposegod = findgod(opposeid);
|
|
if (opposegod && lfhasflag(opposegod, F_PRAYEDTO)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
// maybe get a gift
|
|
int godgiftmaybe(enum RACE rid, int fromtemple) {
|
|
lifeform_t *god;
|
|
int piety,gotgift = B_FALSE;
|
|
enum PIETYLEV plev;
|
|
int chance;
|
|
god = findgod(rid);
|
|
piety = getpiety(rid);
|
|
plev = getpietylev(rid, NULL, NULL);
|
|
|
|
if (fromtemple) {
|
|
chance = 100;
|
|
} else if (plev >= PL_PLEASED) { // ie. >= 200
|
|
// ie. 200 -> 4%
|
|
// ie. 500 -> 10%
|
|
chance = piety / 50;
|
|
} else {
|
|
chance = 0;
|
|
}
|
|
|
|
if (pctchance(chance)) { // if this is true, you get a gift.
|
|
char obtogive[BUFLEN];
|
|
int rollagain = B_TRUE;
|
|
enum SPELLSCHOOL school;
|
|
gotgift = B_TRUE;
|
|
|
|
killflagsofid(player->flags, F_ASLEEP);
|
|
|
|
|
|
switch (god->race->id) {
|
|
case R_GODPURITY:
|
|
godsay(god->race->id, B_TRUE, "I bestow a gift upon you, mortal!");
|
|
break;
|
|
case R_GODTHIEVES:
|
|
godsay(god->race->id, B_TRUE, "Loyalty has its rewards...");
|
|
break;
|
|
case R_GODDEATH:
|
|
godsay(god->race->id, B_TRUE, "Your service has impressed me...");
|
|
break;
|
|
case R_GODFIRE:
|
|
godsay(god->race->id, B_TRUE, "DESTROY IN MY NAME!");
|
|
break;
|
|
case R_GODLIFE:
|
|
godsay(god->race->id, B_TRUE, "Use this gift to spread the joy of life!");
|
|
break;
|
|
case R_GODMERCY:
|
|
godsay(god->race->id, B_TRUE, "As you have shown mercy, so shall you receive it!");
|
|
break;
|
|
case R_GODNATURE:
|
|
godsay(god->race->id, B_TRUE, "Harvest nature's bounty!");
|
|
break;
|
|
case R_GODBATTLE:
|
|
godsay(god->race->id, B_TRUE, "Gather up the spoils of battle!");
|
|
break;
|
|
case R_GODMAGIC:
|
|
godsay(god->race->id, B_TRUE, "One has earned a reward!");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
strcpy(obtogive, "");
|
|
switch (god->race->id) {
|
|
case R_GODBATTLE:
|
|
while (rollagain) {
|
|
rollagain = B_FALSE;
|
|
switch (rnd(1,2)) {
|
|
case 1:
|
|
snprintf(obtogive, BUFLEN, "excellent appropriate branded weapon");
|
|
break;
|
|
case 2:
|
|
snprintf(obtogive, BUFLEN, "excellent appropriate branded armour");
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case R_GODDEATH:
|
|
while (rollagain) {
|
|
flag_t *f;
|
|
object_t *wep;
|
|
rollagain = B_FALSE;
|
|
switch (rnd(1,6)) {
|
|
case 1:
|
|
if (lfhasflag(player, F_SEEINDARK)) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
msg("\"Henceforth the night shall be your ally!\"");
|
|
f = addtempflag(player->flags, F_SEEINDARK, 4, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
break;
|
|
case 2:
|
|
snprintf(obtogive, BUFLEN, "cursed branded weapon");
|
|
break;
|
|
case 3: // poison your weapon
|
|
wep = getweapon(player);
|
|
if (wep && canbepoisoned(wep->type->id)) {
|
|
applyobmod(wep, findobmod(OM_POISONED));
|
|
msg("A layer of venom covers your weapon!");
|
|
} else {
|
|
rollagain = B_TRUE;
|
|
}
|
|
break;
|
|
case 4: // resistant/immune to necrotic
|
|
if (lfhasflagval(player, F_DTRESIST, DT_NECROTIC, NA, NA, NULL)) {
|
|
if (lfhasflagval(player, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL)) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
f = addtempflag(player->flags, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
} else {
|
|
f = addtempflag(player->flags, F_DTRESIST, DT_NECROTIC, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
break;
|
|
case 5: // become a vampire
|
|
if (player->race->id == R_VAMPIRE) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
int orighp;
|
|
int origatt[MAXATTS];
|
|
enum ATTRIB a;
|
|
msg("\"Go forth and kill in my name!\"");
|
|
msg("You transform into a vampire!");
|
|
// special polymorph - we won't change some stats.
|
|
orighp = player->maxhp;
|
|
for (a = 0; a < MAXATTS; a++) {
|
|
origatt[a] = player->att[a];
|
|
}
|
|
|
|
// change the race.
|
|
setrace(player, R_VAMPIRE, B_FALSE); // ie. don't set origrace!
|
|
|
|
// restore stats
|
|
player->maxhp = orighp;
|
|
player->hp = orighp;
|
|
for (a = 0; a < MAXATTS; a++) {
|
|
player->att[a] = origatt[a];
|
|
}
|
|
statdirty = B_TRUE;
|
|
drawscreen();
|
|
}
|
|
break;
|
|
case 6: // necromancy spells
|
|
if (!getskill(player, SK_SS_DEATH)) {
|
|
giveskill(player, SK_SS_DEATH);
|
|
} else {
|
|
snprintf(obtogive, BUFLEN, "spellbook of necromancy");
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case R_GODFIRE:
|
|
while (rollagain) {
|
|
object_t *wep;
|
|
wep = getweapon(player);
|
|
rollagain = B_FALSE;
|
|
switch (rnd(1,3)) {
|
|
case 1: // weapon gains burning
|
|
if (wep) {
|
|
if (!hasobmod(wep, findobmod(OM_FLAMING))) {
|
|
applyobmod(wep, findobmod(OM_FLAMING));
|
|
} else if (!hasflag(wep->flags, F_HASBRAND)) {
|
|
char obname[BUFLEN];
|
|
// already burning. gains pyromania
|
|
addflag(wep->flags, F_FLAMESTRIKE, B_TRUE, NA, NA, NULL);
|
|
getobname(wep, obname, 1);
|
|
msg("Your %s glows with a brilliant heat!", noprefix(obname));
|
|
} else { // already has pyromania.
|
|
rollagain = B_TRUE;
|
|
}
|
|
} else {
|
|
rollagain = B_TRUE;
|
|
}
|
|
break;
|
|
case 2: // fire resist/immune
|
|
if (lfhasflagval(player, F_DTRESIST, DT_FIRE, NA, NA, NULL)) {
|
|
if (lfhasflagval(player, F_DTIMMUNE, DT_FIRE, NA, NA, NULL)) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
flag_t *f;
|
|
f = addtempflag(player->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
} else {
|
|
flag_t *f;
|
|
f = addtempflag(player->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
break;
|
|
case 3: // fire-related spellbook, or fire magic skill
|
|
if (getskill(player, SK_SS_FIRE)) {
|
|
snprintf(obtogive, BUFLEN, "spellbook of Fire Magic");
|
|
} else {
|
|
flag_t *f;
|
|
f = giveskill(player, SK_SS_FIRE);
|
|
if (f) {
|
|
f->obfrom = god->race->id;
|
|
} else {
|
|
rollagain = B_TRUE;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case R_GODLIFE:
|
|
while (rollagain) {
|
|
object_t *wep;
|
|
flag_t *f;
|
|
wep = getweapon(player);
|
|
rollagain = B_FALSE;
|
|
switch (rnd(1,4)) {
|
|
case 1: // regeneration
|
|
if (lfhasflag(player, F_REGENERATES)) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
f = addtempflag(player->flags, F_REGENERATES, 1, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
break;
|
|
case 2: // learn first aid skill
|
|
f = giveskill(player, SK_FIRSTAID);
|
|
if (f) {
|
|
f->obfrom = god->race->id;
|
|
} else {
|
|
rollagain = B_TRUE;
|
|
}
|
|
break;
|
|
case 3: // life-related spellbook, or life magic skill
|
|
if (getskill(player, SK_SS_LIFE)) {
|
|
snprintf(obtogive, BUFLEN, "spellbook of Life Magic");
|
|
} else {
|
|
flag_t *f;
|
|
f = giveskill(player, SK_SS_LIFE);
|
|
if (f) {
|
|
f->obfrom = god->race->id;
|
|
} else {
|
|
rollagain = B_TRUE;
|
|
}
|
|
}
|
|
break;
|
|
case 4: // increase max hp
|
|
player->maxhp += rollhitdice(player, B_TRUE);
|
|
statdirty = B_TRUE;
|
|
msg("\"I have increased your tolerance to injury!\"");
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case R_GODMAGIC:
|
|
while (rollagain) {
|
|
rollagain = B_FALSE;
|
|
switch (rnd(1,3)) {
|
|
case 1: // spellbook for a known school
|
|
school = getrandomspellschool(player, B_TRUE);
|
|
if (school == SS_NONE) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
snprintf(obtogive, BUFLEN, "spellbook of %s", getschoolname(school));
|
|
}
|
|
break;
|
|
case 2: // manual for an unknown spell school
|
|
school = getrandomspellschool(player, B_FALSE);
|
|
if (school == SS_NONE) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
enum SKILL skid;
|
|
skill_t *sk;
|
|
skid = getschoolskill(school);
|
|
sk = findskill(skid);
|
|
snprintf(obtogive, BUFLEN, "manual of %s", sk->name);
|
|
}
|
|
break;
|
|
case 3:
|
|
msg("\"I grant you additional magical reserves!\"");
|
|
player->maxmp += rnd(2,4);
|
|
statdirty = B_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case R_GODMERCY:
|
|
while (rollagain) {
|
|
flag_t *f;
|
|
rollagain = B_FALSE;
|
|
switch (rnd(1,3)) {
|
|
case 1:
|
|
snprintf(obtogive, BUFLEN, "3-4 potions of restoration");
|
|
break;
|
|
case 2:
|
|
if (hasob(player->pack, OT_RING_MIRACLES)) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
snprintf(obtogive, BUFLEN, "ring of miracles");
|
|
}
|
|
break;
|
|
case 3: // sixth sense
|
|
if (lfhasflag(player, F_SIXTHSENSE)) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
f = addtempflag(player->flags, F_SIXTHSENSE, B_TRUE, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case R_GODNATURE:
|
|
while (rollagain) {
|
|
flag_t *f;
|
|
object_t *o;
|
|
objecttype_t *ot;
|
|
rollagain = B_FALSE;
|
|
switch (rnd(1,6)) {
|
|
case 1: // resist/immune poison
|
|
if (lfhasflag(player, F_DISEASEIMMUNE)) {
|
|
if (lfhasflagval(player, F_DTIMMUNE, DT_POISON, NA, NA, NULL)) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
f = addtempflag(player->flags, F_DTIMMUNE, DT_POISON, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
} else {
|
|
f = addtempflag(player->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
break;
|
|
case 2: // resist/immune cold
|
|
if (lfhasflagval(player, F_DTRESIST, DT_COLD, NA, NA, NULL)) {
|
|
if (lfhasflagval(player, F_DTIMMUNE, DT_COLD, NA, NA, NULL)) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
f = addtempflag(player->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
} else {
|
|
f = addtempflag(player->flags, F_DTRESIST, DT_COLD, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
break;
|
|
case 3:
|
|
// good ranged weapon
|
|
if (getskill(player, SK_RANGED)) {
|
|
char obname[BUFLEN];
|
|
if (real_getrandomob(NULL, obname, 25, NA, getlfsize(player),
|
|
SK_RANGED, B_TRUE, OC_WEAPON, OC_NONE, DT_NONE)) {
|
|
snprintf(obtogive, BUFLEN, "excellent %s", obname);
|
|
} else {
|
|
rollagain = B_TRUE;
|
|
}
|
|
} else {
|
|
rollagain = B_TRUE;
|
|
}
|
|
break;
|
|
case 4: // ammo
|
|
o = getfirearm(player);
|
|
if (o) {
|
|
ot = getrandomammofor(o);
|
|
snprintf(obtogive, BUFLEN, "%d excellent %s", rnd(20,30), ot->name);
|
|
} else {
|
|
rollagain = B_TRUE;
|
|
}
|
|
break;
|
|
case 5: // calm animals ability
|
|
if (lfhasflagval(player, F_CANWILL, OT_S_CALMANIMALS, NA, NA, NULL)) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
f = addtempflag(player->flags, F_CANWILL, OT_S_CALMANIMALS, NA, NA, "pw:10;", FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
break;
|
|
case 6:
|
|
if (lfhasflagval(player, F_CANWILL, OT_S_SHAPESHIFT, NA, NA, "pw:1;race:hawk;")) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
f = addtempflag(player->flags, F_CANWILL, OT_S_SHAPESHIFT, 50, 50, "pw:1;race:hawk;", FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case R_GODPURITY:
|
|
if (!hasob(player->pack, OT_POT_RESTORATION)) {
|
|
snprintf(obtogive, BUFLEN, "2-3 blessed potions of restoration");
|
|
} else {
|
|
while (rollagain) {
|
|
flag_t *f;
|
|
rollagain = B_FALSE;
|
|
switch (rnd(1,3)) {
|
|
case 1:
|
|
snprintf(obtogive, BUFLEN, "2-3 blessed potions of water");
|
|
break;
|
|
case 2:
|
|
snprintf(obtogive, BUFLEN, "wand of turn undead");
|
|
break;
|
|
case 3: // holy aura
|
|
if (lfhasflag(player, F_HOLYAURA)) {
|
|
rollagain = B_TRUE;
|
|
} else {
|
|
f = addtempflag(player->flags, F_PRODUCESLIGHT, 3, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
f = addtempflag(player->flags, F_HOLYAURA, NA, NA, NA, NULL, FROMGODGIFT);
|
|
f->obfrom = god->race->id;
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case R_GODTHIEVES:
|
|
while (rollagain) {
|
|
object_t *wep;
|
|
rollagain = B_FALSE;
|
|
wep = getweapon(player);
|
|
if (wep && !hasflag(wep->flags, F_HASBRAND)) {
|
|
char obname[BUFLEN];
|
|
getobname(wep,obname,1);
|
|
// announce
|
|
msg("Your %s vibrates, and you suddenly thirst for vengeance!", noprefix(obname));
|
|
addflag(wep->flags, F_REVENGE, B_TRUE, NA, NA, NULL);
|
|
} else {
|
|
switch (rnd(1,7)) {
|
|
case 1:
|
|
if (getskill(player, SK_TECHUSAGE) >= gettechlevel(OT_LOCKHACKER)) {
|
|
snprintf(obtogive, BUFLEN, "lock hacker");
|
|
} else {
|
|
snprintf(obtogive, BUFLEN, "3-6 blessed lockpicks");
|
|
}
|
|
break;
|
|
case 2:
|
|
if (onein(6)) {
|
|
snprintf(obtogive, BUFLEN, "large bag of holding");
|
|
} else {
|
|
snprintf(obtogive, BUFLEN, "bag of holding");
|
|
}
|
|
break;
|
|
case 3:
|
|
snprintf(obtogive, BUFLEN, "safebox");
|
|
break;
|
|
case 4:
|
|
snprintf(obtogive, BUFLEN, "wand of opening");
|
|
break;
|
|
case 5:
|
|
snprintf(obtogive, BUFLEN, "wand of invisibility");
|
|
break;
|
|
case 6:
|
|
snprintf(obtogive, BUFLEN, "3-6 potions of invisibility");
|
|
break;
|
|
case 7:
|
|
snprintf(obtogive, BUFLEN, "leather boots of stealth");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
} // end switch
|
|
|
|
if (strlen(obtogive)) {
|
|
object_t *o;
|
|
o = addob(player->cell->obpile, obtogive);
|
|
if (o) {
|
|
char buf[BUFLEN];
|
|
addflag(o->flags, F_GODGIFT, god->race->id, NA, NA, NULL);
|
|
if (haslos(player, player->cell)) {
|
|
getobname(o, buf, o->amt);
|
|
msg("%s appear%s!", buf, OBS1(o));
|
|
} else {
|
|
msg("You hear something hitting the ground.");
|
|
}
|
|
}
|
|
}
|
|
|
|
// since you got a gift, lower piety a little.
|
|
//setpiety(rid, 101);
|
|
if (!fromtemple) {
|
|
modpiety(rid, -50);
|
|
}
|
|
} // end if (pctchance enough to get a gift)
|
|
return gotgift;
|
|
}
|
|
|
|
int godisangry(enum RACE rid) {
|
|
if (getpiety(rid) < 0) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
int godprayedto(enum RACE rid) {
|
|
lifeform_t *god;
|
|
god = findgod(rid);
|
|
if (hasflag(god->flags, F_PRAYEDTO)) {
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|
|
|
|
void godsay(enum RACE rid, int says, char *format, ...) {
|
|
lifeform_t *god;
|
|
char godname[BUFLEN], buf[BUFLEN];
|
|
char voiceverb[BUFLEN];
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
vsnprintf( buf, BUFLEN, format, args );
|
|
va_end(args);
|
|
|
|
god = findgod(rid);
|
|
real_getlfname(god, godname, B_FALSE, B_FALSE);
|
|
|
|
switch (rid) {
|
|
case R_GODBATTLE:
|
|
strcpy(voiceverb, "rings out from the heavens");
|
|
break;
|
|
case R_GODDEATH:
|
|
strcpy(voiceverb, "grates against your mind");
|
|
break;
|
|
case R_GODFIRE:
|
|
strcpy(voiceverb, "burns into your mind");
|
|
break;
|
|
case R_GODLIFE:
|
|
strcpy(voiceverb, "chimes out from the heavens");
|
|
break;
|
|
case R_GODMAGIC:
|
|
strcpy(voiceverb, "enters your thoughts");
|
|
break;
|
|
case R_GODMERCY:
|
|
strcpy(voiceverb, "washes over you");
|
|
break;
|
|
case R_GODNATURE:
|
|
if (godisangry(rid)) {
|
|
strcpy(voiceverb, "arrives with a buffeting wind");
|
|
} else {
|
|
strcpy(voiceverb, "arrives with a gentle breeze");
|
|
}
|
|
break;
|
|
case R_GODTHIEVES:
|
|
strcpy(voiceverb, "whispers in your ear");
|
|
break;
|
|
case R_GODPURITY:
|
|
default:
|
|
strcpy(voiceverb, "booms out from the heavens");
|
|
break;
|
|
}
|
|
|
|
if (says) {
|
|
msg("%s%s voice %s:", godname, getpossessive(godname), voiceverb); more();
|
|
}
|
|
msg("\"%s\"", buf);
|
|
}
|
|
|
|
void godstone_pickup_effects(lifeform_t *god, lifeform_t *opposegod, object_t *o) {
|
|
int x,y;
|
|
// opposing god appears
|
|
godappears(opposegod->race->id, NULL);
|
|
|
|
msg("%s says:", opposegod->race->name); more();
|
|
|
|
cls();
|
|
wmove(mainwin, 0, 0);
|
|
// tells you you can become the new god of xxx
|
|
// or give the stone to them, for a reward
|
|
//tells you about the portal on the surface
|
|
switch (opposegod->race->id) {
|
|
case R_GODBATTLE:
|
|
wprintw(mainwin, "\"Soldier. What you have just appropriated is the legendary\n");
|
|
wprintw(mainwin, "Godstone of Magic. As you well know, the existence of magic\n");
|
|
wprintw(mainwin, "has unfairly changed the outcome of many a battle. It causes\n");
|
|
wprintw(mainwin, "even the most hardened veteran to tremble in the face of the\n");
|
|
wprintw(mainwin, "weak and infirm. This goes against everything that is proper.\n");
|
|
wprintw(mainwin, "Now that the Godstone has been captured, there is a singular\n");
|
|
wprintw(mainwin, "opportunity to end this travesty.\n\n");
|
|
wprintw(mainwin, "Claim the stone in the name of armies everywhere, stand before\n");
|
|
wprintw(mainwin, "the Goddess of Magic, and issue your challenge. Strike her down,\n");
|
|
wprintw(mainwin, "and with her strike down the imbalances of magic itself!\n\n");
|
|
wprintw(mainwin, "Do not take any chances. If for any reason the success of your\n");
|
|
wprintw(mainwin, "primary mission should become uncertain, your contingency plan is\n");
|
|
wprintw(mainwin, "to immediately escort the stone safely to me. Such a dangerous\n");
|
|
wprintw(mainwin, "weapon must not fall into the hands of enemies, and only in\n");
|
|
wprintw(mainwin, "my possession can we be sure of its safety.\n\n");
|
|
wprintw(mainwin, "Your first waypoint is the portal atop the dungeon. This will\n");
|
|
wprintw(mainwin, "to the Realm of Gods, where both of your objectives can be\n");
|
|
wprintw(mainwin, "achieved.\"\n");
|
|
break;
|
|
case R_GODDEATH:
|
|
wprintw(mainwin, "\"Heh, heh, heh.\n\n");
|
|
wprintw(mainwin, "You, mortal, have just found the Godstone of Life.\n");
|
|
wprintw(mainwin, "It is the source of all Glorana's power... and could also be used to murder\n");
|
|
wprintw(mainwin, "her and take that power... if one had sufficient courage.\n\n");
|
|
wprintw(mainwin, "As you are a mere fleshling however, I will offer you a deal. Simply\n");
|
|
wprintw(mainwin, "deliver the Godstone to me, and in return I will forgo my claim on your\n");
|
|
wprintw(mainwin, "life. Your flesh will never wither. Your strength will never fade.\n");
|
|
wprintw(mainwin, "Death will never claim you.\n\n");
|
|
wprintw(mainwin, "Whatever your choice, travel to the surface and you will find a portal\n");
|
|
wprintw(mainwin, "to the Realm of Gods. Enter through, and claim your prize!\"\n\n");
|
|
break;
|
|
case R_GODFIRE:
|
|
wprintw(mainwin, "\"NATURE STONE!!!!\n\n");
|
|
wprintw(mainwin, "YOU WILL BRING IT! YOU WILL BRING IT AND KLIKIRAK WILL DESTROY!\n");
|
|
wprintw(mainwin, "OR... STONE KILL EKRUB. YES! YOU WILL USE. YOU FIND\n");
|
|
wprintw(mainwin, "HER. YOU USE STONE. STONE HELP BURN NATURE GODDESS!\n\n");
|
|
wprintw(mainwin, "YOU GO UPWARD. UPWARD GOES TO FOREST. PORTAL IN FOREST.\n");
|
|
wprintw(mainwin, "PORTAL TO TREE WOMAN. YOU KILL TREE WOMAN. OR YOU FIND KLIKIRAK,");
|
|
wprintw(mainwin, "YOU GIVE STONE TO KLIKIRAK.\n\n");
|
|
wprintw(mainwin, "YES. YES. YYYEESSS!!\"\n");
|
|
break;
|
|
case R_GODLIFE:
|
|
wprintw(mainwin, "\"BEWARE, CHILD! That is the Godstone of Death!\n\n");
|
|
wprintw(mainwin, "But wait... you seem unaffected by its power. Common wisdom\n");
|
|
wprintw(mainwin, "holds that the stone destroys all who touch it. Since this is\n");
|
|
wprintw(mainwin, "clearly untrue however... could it be that Hecta has fooled us\n");
|
|
wprintw(mainwin, "all? That the God of Death does indeed possess a weakness?\"\n\n");
|
|
wprintw(mainwin, "Lumara's pulsating form wavers for a moment, seemingly unsure.\n\n");
|
|
wprintw(mainwin, "\"It must be. And if this stone is truly the source of Hecta's\n");
|
|
wprintw(mainwin, "power, then destroying it... that would mean and end to death!\n");
|
|
wprintw(mainwin, "Life could last forever - all could be immortal, rathern just\n");
|
|
wprintw(mainwin, "a select few! It must be done - if you can bring me the\n");
|
|
wprintw(mainwin, "Godstone it will take but a few moments and the meaning of life\n");
|
|
wprintw(mainwin, "will be forever altered. Hecta will likely try to stop you.\n");
|
|
wprintw(mainwin, "Avoid him if you can... but should that not prove possible, the\n");
|
|
wprintw(mainwin, "the stone should at least grant you a slim chance of survival.\n");
|
|
wprintw(mainwin, "It might even be powerful enough for you to triumph...\n\n");
|
|
wprintw(mainwin, "But let us not dwell on that. Find the portal to my realm on\n");
|
|
wprintw(mainwin, "the surface, and take the first step towards eternal life!\"\n");
|
|
break;
|
|
case R_GODMAGIC:
|
|
wprintw(mainwin, "\"One has made a monumental discovery!\n\n");
|
|
wprintw(mainwin, "One my now comprehend, but the level of magic within the cosmos\n");
|
|
wprintw(mainwin, "has been waning. One's find is the source of this - an artifact\n");
|
|
wprintw(mainwin, "so imbued with the essense of physical conflict that its very\n");
|
|
wprintw(mainwin, "existence has disrupted the energies of imagination so vital to magic.\n");
|
|
wprintw(mainwin, "While One's path is of course One's own to decide, I would counsel you\n");
|
|
wprintw(mainwin, "to consider two alternative courses of action.\n\n");
|
|
wprintw(mainwin, "If you are able to bring the stone before me, the universe could be\n");
|
|
wprintw(mainwin, "forever enlightened. I could unlock infinite magical potential within\n");
|
|
wprintw(mainwin, "every living being, from the tiniest insect to the very stars themselves.\n\n");
|
|
wprintw(mainwin, "If One craves danger and adventure, One could also use the stone to confront\n");
|
|
wprintw(mainwin, "the God of Battle himself. Its power may just be sufficient to best the\n");
|
|
wprintw(mainwin, "Battlelord, and doing so would open the doors for One's own ascension.\n\n");
|
|
wprintw(mainwin, "One should consider these words wisely, and make One's choice.\"\n");
|
|
break;
|
|
case R_GODMERCY:
|
|
wprintw(mainwin, "\"HALT! By touching the Godstone of Vengeance, you have commited a\n");
|
|
wprintw(mainwin, "unspeakable sin! By rights your action should condemn you for\n");
|
|
wprintw(mainwin, "eternity. However...\"\n\n");
|
|
wprintw(mainwin, "Yumi's grave expression softens.\n\n");
|
|
wprintw(mainwin, "\"I embody mercy, and all sins can be forgiven. In this case, the road\n");
|
|
wprintw(mainwin, "to your redemption is tied with the deed itself. Bring the stone to me.\n");
|
|
wprintw(mainwin, "Perform this penance and not only will you be forgiven, but you will ensure\n");
|
|
wprintw(mainwin, "that your mistake is never again repeated for all eternity. The God of\n");
|
|
wprintw(mainwin, "Revenge will be neutralised, his influence ended.\n\n");
|
|
wprintw(mainwin, "Mercy however, extends even to the divine. I would not doom Felix to a\n");
|
|
wprintw(mainwin, "life of misery, his very essence ripped away. Should you possess the\n");
|
|
wprintw(mainwin, "power, the Godstone could be used to grant Felix the peaceful sleep\n");
|
|
wprintw(mainwin, "of death. For a tormented soul such as his, this would truly be a mercy.\n\n");
|
|
wprintw(mainwin, "Either way, your atonement begins now. Travel up to the surface, and enter\n");
|
|
wprintw(mainwin, "the magic portal. Complete your task in the Realm of Gods and all will be\n");
|
|
wprintw(mainwin, "forgiven.\"\n");
|
|
break;
|
|
case R_GODNATURE:
|
|
wprintw(mainwin, "\"%s! You hold the Godstone of Rage!\n\n", toupper(player->race->name[0]), (player->race->name + 1));
|
|
wprintw(mainwin, "Long have I sought this ancient artifact - it is from this stone that the\n");
|
|
wprintw(mainwin, "insane God of Fire draws his destructive power.\n");
|
|
wprintw(mainwin, "If you can just deliver this stone to me, Klikirak's reign could be ended!\n\n");
|
|
wprintw(mainwin, "Or even better...\"\n\n");
|
|
wprintw(mainwin, "Ekrub pauses for a moment.\n\n");
|
|
wprintw(mainwin, "As a being of creation I cannot affect the Fire God directly, but with the");
|
|
wprintw(mainwin, "power of the stone, you could. If you can confront and defeat him, I vow");
|
|
wprintw(mainwin, "to support you.\n\n");
|
|
wprintw(mainwin, "Within my forest on the surface, there is a portal to the Realm of Gods.");
|
|
wprintw(mainwin, "Use it, and bring the Godstone!\"\n");
|
|
break;
|
|
case R_GODTHIEVES:
|
|
wprintw(mainwin, "\"Oho, what have you there? That stone, my friend, is none other than\n");
|
|
wprintw(mainwin, "the Godstone of Mercy itself! Oh sure, there are those rumours of\n");
|
|
wprintw(mainwin, "its protective powers, but what people don't know is that it's also\n");
|
|
wprintw(mainwin, "the direct source of power for Yumi, the Mercy Goddess.\n");
|
|
wprintw(mainwin, "Now, were someone to hold that stone... well, they'd be in prime\n");
|
|
wprintw(mainwin, "position to give the high and might lady of forgiveness a taste of\n");
|
|
wprintw(mainwin, "good old fashioned Revenge.\n\n");
|
|
wprintw(mainwin, "Of course you don't need to bother with all that. Just bring the stone\n");
|
|
wprintw(mainwin, "to me and I'll do the rest. There's a portal up on the surface, all\n");
|
|
wprintw(mainwin, "you need to do is step through, track me down, and hand over that little\n");
|
|
wprintw(mainwin, "trinket. Piece of cake!\"\n");
|
|
break;
|
|
case R_GODPURITY:
|
|
wprintw(mainwin, "\"Mortal! You hold an ancient artifact of immense power!\n");
|
|
wprintw(mainwin, "In your hands is the accursed Godstone of Chaos. For\n");
|
|
wprintw(mainwin, "centuries I have tracked this vile object, but somehow\n");
|
|
wprintw(mainwin, "the energies of the mortal world are keeping it from me.\n\n");
|
|
wprintw(mainwin, "This single stone is the source of all impurity in the universe.\n");
|
|
wprintw(mainwin, "Now all you need to do is deliver it to me, and it can be\n");
|
|
wprintw(mainwin, "unmade. In fact with the Godstone possessed by another,\n");
|
|
wprintw(mainwin, "the Chaos God's power may well have been waned far enough\n");
|
|
wprintw(mainwin, "for him to be confronted directly.\n\n");
|
|
wprintw(mainwin, "Travel to the Realm of Gods mortal, and come to me with the\n");
|
|
wprintw(mainwin, "stone. If you find and destroy the Chaos god on the way, all");
|
|
wprintw(mainwin, "the better. Chaos and impurity MUST be ended!\"\n");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
getyx(mainwin, y, x);
|
|
centre(mainwin,C_WHITE, y, "[Press any key]");
|
|
getch();
|
|
|
|
restoregamewindows();
|
|
|
|
// identify the godstone
|
|
identify(o);
|
|
|
|
// make sure related god's anger will trigger one bad effect.
|
|
if (!godprayedto(god->race->id)) {
|
|
addflag(god->flags, F_PRAYEDTO, B_TRUE, NA, NA, NULL);
|
|
}
|
|
// related god screams and gets furios/enraged at you.
|
|
// (you lose prayedto if you have it?)
|
|
if (getpietylev(god->race->id, NULL, NULL) == PL_FURIOUS) {
|
|
// becomes enraged
|
|
setpiety(god->race->id, getpietycutoff(PL_ENRAGED));
|
|
} else {
|
|
// becomes furious
|
|
setpiety(god->race->id, getpietycutoff(PL_FURIOUS));
|
|
}
|
|
angergod(god->race->id, 0, GA_GODSTONE);
|
|
|
|
killflagsofid(god->flags, F_PRAYEDTO);
|
|
addflag(god->flags, F_GODBLOCKED, B_TRUE, NA, NA, NULL);
|
|
}
|
|
|
|
void modpiety(enum RACE rid, int amt) {
|
|
lifeform_t *god;
|
|
flag_t *f;
|
|
|
|
|
|
god = findgod(rid);
|
|
if (godblocked(god->race->id)) return;
|
|
|
|
f = lfhasflag(god, F_PIETY);
|
|
if (!f) return;
|
|
f->val[0] += amt;
|
|
|
|
limit(&f->val[0], PIETY_MIN, PIETY_MAX);
|
|
}
|
|
|
|
void pleasegod(enum RACE rid, int amt) {
|
|
lifeform_t *lf;
|
|
char lfname[BUFLEN];
|
|
lf = findgod(rid);
|
|
real_getlfname(lf, lfname, B_FALSE, B_FALSE);
|
|
|
|
modpiety(rid, amt);
|
|
|
|
// announce
|
|
if (hasflag(lf->flags, F_PRAYEDTO)) {
|
|
if (!isasleep(player)) {
|
|
switch (rid) {
|
|
case R_GODBATTLE:
|
|
msg("You feel triumphant.");
|
|
break;
|
|
case R_GODDEATH:
|
|
msg("You feel a thrill of unholy ecstasy.");
|
|
break;
|
|
case R_GODFIRE:
|
|
msg("A searing heat runs through your blood.");
|
|
break;
|
|
case R_GODLIFE:
|
|
if (isdeaf(player)) {
|
|
msg("You have a feeling of holiness.");
|
|
} else {
|
|
msg("You hear a distance choir singing.");
|
|
}
|
|
break;
|
|
case R_GODMAGIC:
|
|
msg("You feel Lumara's presense nearby.");
|
|
break;
|
|
case R_GODNATURE:
|
|
msg("You feel in tune with nature.");
|
|
break;
|
|
case R_GODMERCY:
|
|
msg("You feel a sense of serenity.");
|
|
break;
|
|
case R_GODPURITY:
|
|
msg("You feel righteous.");
|
|
break;
|
|
case R_GODTHIEVES:
|
|
msg("You feel a guilty pleasure.");
|
|
break;
|
|
default:
|
|
msg("You feel like %s approves of your actions.", lfname);
|
|
break;
|
|
}
|
|
}
|
|
godgiftmaybe(rid, B_FALSE);
|
|
}
|
|
}
|
|
|
|
void pleasegodmaybe(enum RACE rid, int amt) {
|
|
enum PIETYLEV modplev;
|
|
int chance;
|
|
|
|
if (lfhasflag(player, F_WINNER)) return;
|
|
|
|
modplev = abs(getpietylev(rid, NULL, NULL));
|
|
|
|
// the angrier or more happy the god gets, the harder it
|
|
// is to please them.
|
|
// ie. INDIFFERENT = 1 in 1 (always)
|
|
// ie. PLEASED/TOLERATED = 1 in 2
|
|
// ie. DELIGHTED/ANGRY = 1 in 3
|
|
// ie. ECSTATIC/FURIOUS = 1 in 4
|
|
// ie. ENRAGED = 1 in 5
|
|
chance = modplev + 1;
|
|
if (onein(chance)) {
|
|
pleasegod(rid, amt);
|
|
}
|
|
}
|
|
|
|
int prayto(lifeform_t *lf, lifeform_t *god) {
|
|
int piety,i,x,y;
|
|
char assisttext[BUFLEN];
|
|
enum PIETYLEV plev;
|
|
int newgod;
|
|
|
|
taketime(lf, getactspeed(lf));
|
|
|
|
if (godblocked(god->race->id)) {
|
|
msg("%s ignores you.", god->race->name);
|
|
return B_TRUE;
|
|
}
|
|
|
|
if (lfhasflagval(god, F_HATESRACECLASS, lf->race->raceclass->id, NA, NA, NULL) ||
|
|
lfhasflagval(god, F_HATESRACE, lf->race->id, NA, NA, NULL)) {
|
|
angergod(god->race->id, 50, GA_RACE);
|
|
return B_TRUE;
|
|
}
|
|
|
|
// this will return 100 if we haven't prayed to this
|
|
// god before
|
|
piety = getpiety(god->race->id);
|
|
|
|
// remember that we have now prayed to this god.
|
|
// ie. player is expected to follow the god's rules.
|
|
if (!hasflag(god->flags, F_PRAYEDTO)) {
|
|
addflag(god->flags, F_PRAYEDTO, B_TRUE, NA, NA, NULL);
|
|
newgod = B_TRUE;
|
|
}
|
|
|
|
if (godisangry(god->race->id)) {
|
|
// get even more angry
|
|
angergod(god->race->id, PIETYPRAYLOSS, GA_PRAY);
|
|
return B_FALSE;
|
|
}
|
|
|
|
if (piety <= 99) {
|
|
// piety between 0 and 99 = ignored
|
|
//godsay(god->race->id, "Stop pestering me!");
|
|
msg("%s doesn't respond.", god->race->name);
|
|
angergod(god->race->id, 0, GA_PRAY);
|
|
modpiety(god->race->id, -30);
|
|
return B_FALSE;
|
|
}
|
|
|
|
// if we get here, piety is >= 100.
|
|
// you get some help...
|
|
plev = getpietylev(god->race->id, NULL, NULL);
|
|
switch (god->race->id) {
|
|
case R_GODBATTLE:
|
|
strcpy(assisttext, "Message received, soldier!");
|
|
break;
|
|
case R_GODTHIEVES:
|
|
strcpy(assisttext, "What mischief have you gotten yourself into, then?");
|
|
break;
|
|
case R_GODDEATH:
|
|
strcpy(assisttext, "You desire a favour, fleshling?");
|
|
break;
|
|
case R_GODFIRE:
|
|
switch (rnd(1,2)) {
|
|
case 1: strcpy(assisttext, "BURN!"); break;
|
|
case 2: strcpy(assisttext, "DESTROY!"); break;
|
|
}
|
|
break;
|
|
case R_GODLIFE:
|
|
strcpy(assisttext, "You prayer is answered!");
|
|
break;
|
|
case R_GODMERCY:
|
|
strcpy(assisttext, "I hear your prayer, child.");
|
|
break;
|
|
case R_GODNATURE:
|
|
strcpy(assisttext, "Nature hears your call!");
|
|
break;
|
|
case R_GODMAGIC:
|
|
strcpy(assisttext, "One calls upon the eldritch powers...");
|
|
break;
|
|
case R_GODPURITY:
|
|
default:
|
|
strcpy(assisttext, "You appear in need of assistance, mortal!");
|
|
break;
|
|
}
|
|
godsay(god->race->id, B_TRUE, assisttext);
|
|
|
|
switch (god->race->id) {
|
|
lifeform_t *l;
|
|
int donesomething = B_FALSE,n;
|
|
cell_t *c;
|
|
object_t *o;
|
|
case R_GODBATTLE:
|
|
if (isinbattle(player, B_TRUE)) {
|
|
int redo = B_TRUE;
|
|
object_t *o;
|
|
|
|
if (getstamina(player) <= pctof(25, getmaxstamina(player))) {
|
|
setstamina(player, getmaxstamina(player));
|
|
msg("\"Time for your second wind!\"");
|
|
}
|
|
|
|
while (redo) {
|
|
redo = B_FALSE;
|
|
switch (rnd(1,4)) {
|
|
case 1: // bless weapon
|
|
msg("\"Fight in my name!\"");
|
|
o = getweapon(player);
|
|
if (o && !isblessed(o)) {
|
|
blessob(o);
|
|
} else {
|
|
redo = B_TRUE;
|
|
}
|
|
break;
|
|
case 2: // bezerk
|
|
if (lfhasflag(player, F_RAGE)) {
|
|
redo = B_TRUE;
|
|
} else {
|
|
msg("\"Rage like a badger!\"");
|
|
player->stamina = getmaxstamina(player);
|
|
abilityeffects(player, OT_A_RAGE, player->cell, player, NULL);
|
|
}
|
|
break;
|
|
case 3: //
|
|
msg("\"I will guide your blade!\"");
|
|
dospelleffects(god, OT_S_TRUESTRIKE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
|
|
break;
|
|
case 4: //
|
|
msg("\"Your blows will be as lightning!\"");
|
|
dospelleffects(god, OT_S_HASTE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
|
|
break;
|
|
} // end switch
|
|
}// end while redo
|
|
} else {
|
|
// not in battle...
|
|
int done = B_FALSE;
|
|
object_t *o,*wep;
|
|
wep = getweapon(player);
|
|
|
|
if (uncurse_one_equipped(lf, "\"Be free of your curse!\"")){
|
|
done = B_TRUE;
|
|
}
|
|
|
|
if (!done) {
|
|
// try to repair armour or undull weapons
|
|
i = 0;
|
|
for (o = lf->pack->first ; o ; o = o->next) {
|
|
if (isequipped(o)) {
|
|
if (isdamaged(o) || (getobbonus(o, B_FALSE) < 0)) {
|
|
dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
if (i) {
|
|
msg("\"Keep fighting, warrior!\"");
|
|
done = B_TRUE;
|
|
}
|
|
}
|
|
if (!done) {
|
|
int redo = B_TRUE;
|
|
while (redo) {
|
|
redo = B_FALSE;
|
|
switch (rnd(1,2)) {
|
|
case 1: // detect life
|
|
msg("\"Seek out battle in my name!\"");
|
|
dospelleffects(god, OT_S_DETECTLIFE, 10, lf, NULL, lf->cell, B_BLESSED, NULL, B_TRUE);
|
|
break;
|
|
case 2: // bless weapon
|
|
msg("\"Fight in my name!\"");
|
|
o = getweapon(player);
|
|
if (o && !isblessed(o)) {
|
|
blessob(o);
|
|
} else {
|
|
redo = B_TRUE;
|
|
}
|
|
break;
|
|
} // end switch
|
|
}// end while redo
|
|
}
|
|
}
|
|
break;
|
|
case R_GODPURITY:
|
|
msg("\"Witness the holy radiance of purity!\"");
|
|
c = getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND);
|
|
if (c) {
|
|
dospelleffects(god, OT_S_LIGHT, 10, NULL, NULL, c, B_BLESSED, NULL, B_TRUE);
|
|
}
|
|
// uncurse ALL equipped obs
|
|
for (o = lf->pack->first ; o ; o = o->next) {
|
|
if (iscursed(o) && isequipped(o)) {
|
|
blessob(o);
|
|
}
|
|
}
|
|
|
|
// cure poison
|
|
if (ispoisoned(lf)) {
|
|
dospelleffects(god, OT_S_CUREPOISON, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
|
|
}
|
|
|
|
if (isinbattle(lf, B_TRUE)) {
|
|
int i,nretflags;
|
|
flag_t *retflag[MAXCANDIDATES];
|
|
// smite evil
|
|
for (l = lf->cell->map->lf ; l ; l = l->next) {
|
|
if (getalignment(l) == AL_EVIL) {
|
|
if (haslof(lf->cell, l->cell, LOF_WALLSTOP, NULL)) {
|
|
// smite them
|
|
castspell(god, OT_S_SMITEEVIL, l, NULL, l->cell, NULL, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
// turn undead TODO: move this to 'life' god
|
|
castspell(god, OT_S_TURNUNDEAD, lf, NULL, NULL, NULL, NULL);
|
|
|
|
// remove all temporary bad status effects
|
|
getflags(player->flags, retflag, &nretflags, F_BLIND, F_CONFUSED, F_DEAF, F_CAFFEINATED, F_DRUNK, F_FROZEN,
|
|
F_GRABBEDBY, F_NAUSEATED, F_PAIN, F_POISONED, F_SLOWACT, F_SLOWMOVE, F_SLOWACTMOVE, F_NONE);
|
|
for (i = 0; i < nretflags; i++) {
|
|
if (istransitoryflag(retflag[i])) {
|
|
killflag(retflag[i]);
|
|
}
|
|
}
|
|
} else {
|
|
object_t *wep;
|
|
flag_t *f;
|
|
int donesomething = B_FALSE;
|
|
|
|
// restore original lifeform shape
|
|
if (!donesomething) {
|
|
f = lfhasflag(lf, F_ORIGRACE);
|
|
if (f) {
|
|
setrace(lf, f->val[0], B_TRUE);
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
|
|
// restore to original lifeform size
|
|
if (!donesomething) {
|
|
f = hasflag(lf->race->flags, F_SIZE);
|
|
if (f && (getlfsize(lf) != f->val[0])) {
|
|
resizelf(lf, f->val[0]);
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
|
|
// purify your food
|
|
if (!donesomething) {
|
|
if (!dospelleffects(god, OT_S_PURIFYFOOD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE)) {
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
|
|
// bless your weapon
|
|
if (!donesomething) {
|
|
wep = getweapon(player);
|
|
if (wep && !isblessed(wep)) {
|
|
blessob(wep);
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
|
|
// bless 1-3 random obs
|
|
if (!donesomething) {
|
|
int nposs = 0, n;
|
|
object_t *o,*poss[MAXCANDIDATES];
|
|
nposs = 0;
|
|
n = rnd(1,3); // num to bless
|
|
for (o = player->pack->first ; o ; o = o->next) {
|
|
if (!isblessed(o) && !hasflag(o->flags, F_NOBLESS)) {
|
|
poss[nposs++] = o;
|
|
}
|
|
}
|
|
if (nposs < n) n = nposs;
|
|
for (i = 0; i < n; i++) {
|
|
o = poss[rnd(0,nposs-1)];
|
|
while (isblessed(o)) {
|
|
o = poss[rnd(0,nposs-1)];
|
|
}
|
|
blessob(o);
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case R_GODDEATH:
|
|
msg("\"Behold, the power of death!\"");
|
|
c = NULL;
|
|
n = OT_NONE;
|
|
switch (rnd(0,1)) {
|
|
case 0: n = OT_S_FLAYFLESH; break;
|
|
case 1: n = OT_S_HECTASSERVANT;
|
|
c = getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND);
|
|
break;
|
|
}
|
|
if (n == OT_S_HECTASSERVANT) {
|
|
if (c) {
|
|
castspell(god, n, player, NULL, c, NULL, NULL);
|
|
n = OT_NONE;
|
|
} else {
|
|
n = OT_S_DRAINLIFE;
|
|
}
|
|
}
|
|
|
|
if (n != OT_NONE) {
|
|
// kill first lifeform in sight.
|
|
for (i = 1; i < lf->nlos; i++) {
|
|
lifeform_t *who;
|
|
who = lf->los[i]->lf;
|
|
if (who && !areallies(lf, who)) {
|
|
if (isundead(who)) {
|
|
makepeaceful(who, god);
|
|
} else if (gettr(who) <= 5) {
|
|
// instakill
|
|
who->lastdamtype = DT_NECROTIC;
|
|
setlastdam(who, "Hecta's finger of death.");
|
|
who->hp = 0;
|
|
} else {
|
|
//castspell(god, n, who, NULL, who->cell, NULL, NULL);
|
|
dospelleffects(god, n, 20, who, NULL, who->cell, B_UNCURSED, NULL, B_FALSE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
dospelleffects(god, OT_S_ANIMATEDEAD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
|
|
break;
|
|
case R_GODFIRE:
|
|
// restore frozen weapons
|
|
o = getweapon(player);
|
|
if (o && (o->material->id == MT_ICE) && (o->material != o->type->material)) {
|
|
changemat(o, o->type->material->id);
|
|
}
|
|
// set all nearby non-cosmetic objects on fire
|
|
i = 0;
|
|
for (y = 0; y < player->cell->map->h; y++) {
|
|
for (x = 0; x < player->cell->map->w; x++) {
|
|
cell_t *c;
|
|
c = getcellat(player->cell->map, x, y);
|
|
if (c && cellhaslos(c, player->cell)) {
|
|
if (c->lf && (c->lf != player)) {
|
|
dospelleffects(NULL, OT_S_FLAMEPILLAR, 10, NULL, NULL,
|
|
c, B_BLESSED, NULL, B_TRUE);
|
|
} else if (countnoncosmeticobs(c->obpile, B_FALSE, B_FALSE)) {
|
|
addobfast(c->obpile, OT_FIRESMALL);
|
|
i++;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
if (i) {
|
|
msg("Nearby objects erupt in flames!"); more();
|
|
}
|
|
break;
|
|
case R_GODLIFE:
|
|
if (ispoisoned(lf)) {
|
|
castspell(god, OT_S_CUREPOISON, player, NULL, player->cell, NULL, NULL);
|
|
donesomething = B_TRUE;
|
|
}
|
|
if (gethungerlevel(gethungerval(player)) >= H_PECKISH) {
|
|
dospelleffects(NULL, OT_S_SATEHUNGER, 10, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE);
|
|
donesomething = B_TRUE;
|
|
}
|
|
if (lf->mp < (getmaxmp(lf)/2)) {
|
|
gainmp(lf, getmaxmp(lf)/2);
|
|
donesomething = B_TRUE;
|
|
}
|
|
if (lfhasflag(lf, F_INJURY)) {
|
|
castspell(god, OT_S_HEALINGMAJ, player, NULL, player->cell, NULL, NULL);
|
|
donesomething = B_TRUE;
|
|
}
|
|
if (lf->hp < lf->maxhp) {
|
|
gainhp(lf, lf->maxhp);
|
|
donesomething = B_TRUE;
|
|
statdirty = B_TRUE;
|
|
}
|
|
if (isinbattle(lf, B_TRUE)) {
|
|
if (plev >= PL_INDIFFERENT) {
|
|
dospelleffects(NULL, OT_S_HEAVENARM, plev+1, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE);
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
// will bless player's water if nothing else done.
|
|
if (!donesomething && (plev >= PL_PLEASED)) {
|
|
object_t *o;
|
|
for (o = player->pack->first ; o ; o = o->next) {
|
|
if (o->type->id == OT_POT_WATER) {
|
|
if (!isblessed(o)) {
|
|
blessob(o);
|
|
} else if (!o->blessknown) {
|
|
dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (donesomething) {
|
|
msg("\"Rejoice in life!\"");
|
|
}
|
|
break;
|
|
case R_GODTHIEVES:
|
|
if (isinbattle(lf, B_TRUE)) {
|
|
lifeform_t *l;
|
|
int donesomething = B_FALSE;
|
|
if (islowhp(lf)) {
|
|
// teleport away
|
|
msg("\"Nothing like a quick getaway!\"");
|
|
dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
|
|
donesomething = B_TRUE;
|
|
} else {
|
|
int redo = B_TRUE;
|
|
while (redo) {
|
|
redo = B_FALSE;
|
|
switch (rnd(1,2)) {
|
|
case 1:
|
|
// steal from your enemies
|
|
for (l = lf->cell->map->lf ; l ; l = l->next) {
|
|
if ((l != lf) && areenemies(l, lf) && cansee(l, lf)) {
|
|
object_t *wep;
|
|
// confiscate their weapon
|
|
wep = getweapon(l);
|
|
if (wep) {
|
|
if (!donesomething) {
|
|
msg("\"I'll take that...\"");
|
|
donesomething = B_TRUE;
|
|
}
|
|
castspell(god, OT_S_CONFISCATE, l, wep, l->cell, NULL, NULL);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
if (lfhasflag(lf, F_INVISIBLE)) {
|
|
redo = B_TRUE;
|
|
} else {
|
|
// invisibility
|
|
msg("\"Can't hurt what you can't see...\"");
|
|
addtempflag(lf->flags, F_INVISIBLE, B_TRUE, NA, NA, NULL, 20);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!donesomething) {
|
|
// teleport away
|
|
msg("\"Nothing like a quick getaway!\"");
|
|
dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
|
|
}
|
|
} else {
|
|
int redo = B_TRUE;
|
|
object_t *possob[MAXPILEOBS];
|
|
int npossob,i,first;
|
|
object_t *o;
|
|
// unlock doors
|
|
first = B_TRUE;
|
|
for (i = 0; i < player->nlos; i++) {
|
|
cell_t *c;
|
|
object_t *o;
|
|
c = player->los[i];
|
|
for (o = c->obpile->first ; o ; o = o->next) {
|
|
if (killflagsofid(o->flags, F_LOCKED) || killflagsofid(o->flags, F_SECRET)) {
|
|
if (first) {
|
|
msg("\"Access granted!\"");
|
|
first = B_FALSE;
|
|
}
|
|
noise(c, NULL, NC_OTHER, SV_TALK, "the click of a lock.", NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
// uncurse one equipped ob
|
|
if (uncurse_one_equipped(lf, "\"Curses, schmurses!\"")){
|
|
redo = B_FALSE;
|
|
}
|
|
|
|
while (redo) {
|
|
redo = B_FALSE;
|
|
switch (rnd(1,2)) {
|
|
case 1:
|
|
msg("\"Allow me to reveal your surroundings...\"");
|
|
dospelleffects(god, OT_S_MAPPING, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
|
|
dospelleffects(god, OT_S_REVEALHIDDEN, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
|
|
break;
|
|
case 2: // identify objects
|
|
npossob = 0;
|
|
for (o = lf->pack->first ; o ; o = o->next) {
|
|
if (!isknown(o)) {
|
|
possob[npossob++] = o;
|
|
}
|
|
}
|
|
if (npossob) {
|
|
char oldname[BUFLEN],newname[BUFLEN];
|
|
o = possob[rnd(0,npossob-1)];
|
|
getobname(o,oldname,o->amt);
|
|
identify(o);
|
|
getobname(o,newname,o->amt);
|
|
msg("\"%s %s you are carrying %s %s!\"",
|
|
(o->amt == 1) ? "That" : "Those",
|
|
noprefix(oldname),
|
|
(o->amt == 1) ? "is" : "are",
|
|
newname);
|
|
} else {
|
|
redo = B_TRUE;
|
|
}
|
|
break;
|
|
} // end switch
|
|
}// end while redo
|
|
}
|
|
break;
|
|
case R_GODMAGIC:
|
|
if (player->mp <= (getmaxmp(player)/2)) {
|
|
gainmp(lf, getmaxmp(lf));
|
|
msg("\"One's magical reserves have been filled!\"");
|
|
} else {
|
|
object_t *toid[MAXPILEOBS],*touncurse[MAXPILEOBS];
|
|
int idnum = 0, uncursenum = 0;
|
|
int done = B_FALSE;
|
|
|
|
// uncurse one equipped ob
|
|
if (uncurse_one_equipped(lf, "\"One's curse is lifted.\"")){
|
|
done = B_TRUE;
|
|
}
|
|
|
|
if (!done) {
|
|
// any unid'd scrolls/books?
|
|
for (o = player->pack->first ; o ; o = o->next) {
|
|
if ((o->type->obclass->id == OC_SCROLL) || (o->type->obclass->id == OC_BOOK)) {
|
|
if (!isknown(o)) {
|
|
toid[idnum++] = o;
|
|
}
|
|
if (isequipped(o) && iscursed(o)) {
|
|
touncurse[uncursenum++] = o;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (idnum) {
|
|
msg("\"One is granted the favour of knowledge!\"");
|
|
o = toid[rnd(0,idnum-1)];
|
|
dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE);
|
|
} else if (uncursenum) {
|
|
msg("\"One is granted the favour of redemption!\"");
|
|
o = touncurse[rnd(0,uncursenum-1)];
|
|
uncurseob(o, NULL);
|
|
} else {
|
|
// just regain mana.
|
|
gainmp(lf, getmaxmp(lf));
|
|
msg("\"One's magical reserves have been filled!\"");
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case R_GODMERCY:
|
|
if (isinbattle(lf, B_TRUE)) {
|
|
lifeform_t *l;
|
|
int donesomething = B_FALSE;
|
|
int preventstoning = B_FALSE;
|
|
int preventparalysis = B_FALSE;
|
|
|
|
// if something nearby could stone/petrify you, confer temporary immunity.
|
|
for (l = lf->cell->map->lf ; l ; l = l->next) {
|
|
if ((l != lf) && areenemies(l, lf) && cansee(l, lf)) {
|
|
obpile_t *op = NULL;
|
|
int nweps = 0;
|
|
object_t *wep[MAXCANDIDATES];
|
|
flag_t *damflag[MAXCANDIDATES];
|
|
int lastweaponidx;
|
|
if (l->race->id == R_COCKATRICE) {
|
|
preventstoning = B_TRUE;
|
|
}
|
|
getweapons(l, wep, damflag, &lastweaponidx, &op, &nweps);
|
|
for (i = 0; i < nweps; i++) {
|
|
if (hasflagval(wep[i]->flags, F_HITCONFER, F_PARALYZED, NA, NA, NULL)) {
|
|
preventparalysis = B_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (op) killobpile(op);
|
|
}
|
|
}
|
|
if (preventstoning || preventparalysis) {
|
|
addtempflag(player->flags, F_DTIMMUNE, DT_PETRIFY, NA, NA, NULL, rnd(40,50));
|
|
donesomething = B_TRUE;
|
|
}
|
|
|
|
|
|
// sleep on all enemies
|
|
if (!donesomething) {
|
|
for (l = lf->cell->map->lf ; l ; l = l->next) {
|
|
if ((l != lf) && areenemies(l, lf) && cansee(l, lf)) {
|
|
castspell(god, OT_S_SLEEP, l, NULL, l->cell, NULL, NULL);
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (ispoisoned(lf)) {
|
|
msg("\"Let thy body be purged of toxins.\"");
|
|
castspell(god, OT_S_CUREPOISON, player, NULL, player->cell, NULL, NULL);
|
|
donesomething = B_TRUE;
|
|
}
|
|
if (gethungerlevel(gethungerval(player)) >= H_PECKISH) {
|
|
msg("\"Let thy stomach be satisfied.\"");
|
|
castspell(god, OT_S_SATEHUNGER, player, NULL, player->cell, NULL, NULL);
|
|
donesomething = B_TRUE;
|
|
}
|
|
if (islowhp(lf)) {
|
|
msg("\"Let thy wounds be healed.\"");
|
|
castspell(god, OT_S_HEALINGMAJ, player, NULL, player->cell, NULL, NULL);
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
|
|
// uncurse one equipped ob
|
|
uncurse_one_equipped(lf, "\"Let thy curse be ended!\"");
|
|
break;
|
|
case R_GODNATURE:
|
|
if (isinbattle(lf, B_TRUE)) {
|
|
lifeform_t *l;
|
|
int donesomething = B_FALSE;
|
|
int redo = B_TRUE;
|
|
while (redo) {
|
|
redo = B_FALSE;
|
|
switch (rnd(1,3)) {
|
|
case 1:
|
|
msg("\"My children will bind your enemies!\"");
|
|
// entangle your enemies
|
|
for (l = lf->cell->map->lf ; l ; l = l->next) {
|
|
if ((l != lf) && areenemies(l, lf) && cansee(l, player)) {
|
|
dospelleffects(NULL, OT_S_ENTANGLE, 10, NULL, NULL, l->cell, B_BLESSED, NULL, B_TRUE);
|
|
}
|
|
}
|
|
break;
|
|
case 2: // summon plants
|
|
msg("\"My children will aid you!\"");
|
|
summonlfs(player, player->cell, R_NONE, RC_PLANT, SZ_ANY, AL_NONE, 5, PERMENANT, B_TRUE);
|
|
break;
|
|
case 3: // lightning
|
|
msg("\"The powers of the sky will smite your foes!\"");
|
|
for (l = lf->cell->map->lf ; l ; l = l->next) {
|
|
if ((l != lf) && areenemies(l, lf) && cansee(l, player)) {
|
|
dospelleffects(god, OT_S_CALLLIGHTNING, 10, NULL, NULL, l->cell, B_BLESSED, NULL, B_TRUE);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// fighting a dragon?
|
|
for (i = 0; i < lf->nlos; i++) {
|
|
if (lf->los[i]->lf && (getraceclass(lf->los[i]->lf) == RC_DRAGON)) {
|
|
godappears(god->race->id, NULL);
|
|
aiattack(god, lf->los[i]->lf, PERMENANT);
|
|
donesomething = B_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
} else {// not in battle
|
|
int donesomething = B_FALSE;
|
|
flag_t *f;
|
|
|
|
// fix any poison potions
|
|
dospelleffects(god, OT_S_PURIFYFOOD, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
|
|
|
|
if (ispoisoned(lf)) {
|
|
msg("\"I will cure your poison...\"");
|
|
castspell(god, OT_S_CUREPOISON, player, NULL, player->cell, NULL, NULL);
|
|
donesomething = B_TRUE;
|
|
}
|
|
if (!donesomething && (gethungerlevel(gethungerval(player)) >= H_PECKISH)) {
|
|
msg("\"I will cure your hunger...\"");
|
|
castspell(god, OT_S_SATEHUNGER, player, NULL, player->cell, NULL, NULL);
|
|
donesomething = B_TRUE;
|
|
}
|
|
if (!donesomething && islowhp(lf)) {
|
|
msg("\"I will heal your injuries...\"");
|
|
castspell(god, OT_S_HEALINGMAJ, player, NULL, player->cell, NULL, NULL);
|
|
donesomething = B_TRUE;
|
|
}
|
|
if (!donesomething) { // out of ammo?
|
|
object_t *gun;
|
|
gun = getfirearm(lf);
|
|
if (gun && !getammo(gun) && !getrandomammo(lf)) {
|
|
objecttype_t *ot;
|
|
ot = getrandomammofor(gun);
|
|
if (ot) {
|
|
char obtogive[BUFLEN],ammoname[BUFLEN];
|
|
char gunname[BUFLEN];
|
|
object_t *ammo;
|
|
f = hasflag(gun->flags, F_AMMOCAPACITY);
|
|
snprintf(obtogive, BUFLEN, "%d %s of seeking", f->val[0], ot->name);
|
|
ammo = addob(gun->contents, obtogive);
|
|
identify(ammo);
|
|
getobname(ammo, ammoname, ammo->amt);
|
|
getobname(gun, gunname, 1);
|
|
msg("%s appear%s in your %s!", ammoname, OBS1(ammo), noprefix(gunname));
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
}
|
|
if (!donesomething) { // mend one random armour
|
|
object_t *poss[MAXCANDIDATES];
|
|
int nposs = 0;
|
|
for (o = lf->pack->first ; o ; o = o->next) {
|
|
if (isequipped(o) && isarmour(o) && isdamaged(o)) {
|
|
poss[nposs++] = o;
|
|
}
|
|
}
|
|
if (nposs) {
|
|
o = poss[rnd(0,nposs-1)];
|
|
dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE);
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
if (!donesomething) { // bless armour
|
|
object_t *poss[MAXCANDIDATES];
|
|
int nposs = 0;
|
|
for (o = lf->pack->first ; o ; o = o->next) {
|
|
if (isequipped(o) && isarmour(o) && (o->blessed == B_UNCURSED)) {
|
|
poss[nposs++] = o;
|
|
}
|
|
}
|
|
if (nposs) {
|
|
o = poss[rnd(0,nposs-1)];
|
|
msg("\"Nature's power will protect you...\"");
|
|
blessob(o);
|
|
}
|
|
donesomething = B_TRUE;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
|
|
// new god effects
|
|
if (newgod) {
|
|
switch (god->race->id) {
|
|
case R_GODTHIEVES:
|
|
makelearnable(lf, SK_THIEVERY);
|
|
makelearnable(lf, SK_LOCKPICKING);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if (god->race->id == R_GODNATURE) {
|
|
addob(lf->cell->obpile, "flower");
|
|
if (haslos(player, lf->cell)) {
|
|
msg("A beautiful flower grows from the ground.");
|
|
}
|
|
}
|
|
|
|
|
|
if (!godgiftmaybe(god->race->id, B_FALSE)) {
|
|
// if you didn't get a gift, lower piety for this god
|
|
modpiety(god->race->id, -PIETYPRAYLOSS);
|
|
}
|
|
|
|
// lower piety for other related gods
|
|
for (i = 0; i < ngodlfs; i++) {
|
|
if (godlf[i] != god) {
|
|
modpiety(godlf[i]->race->id, -25);
|
|
}
|
|
}
|
|
|
|
return B_FALSE;
|
|
}
|
|
|
|
|
|
void setpiety(enum RACE rid, int amt) {
|
|
lifeform_t *god;
|
|
flag_t *f;
|
|
god = findgod(rid);
|
|
f = lfhasflag(god, F_PIETY);
|
|
if (!f) return;
|
|
f->val[0] = amt;
|
|
limit(&f->val[0], PIETY_MIN, PIETY_MAX);
|
|
}
|
|
|
|
// uncurse one equipped ob
|
|
// returns true if we do somethign
|
|
int uncurse_one_equipped(lifeform_t *lf, char *text) {
|
|
object_t *possob[MAXPILEOBS],*o;
|
|
int npossob;
|
|
npossob = 0;
|
|
for (o = lf->pack->first ; o ; o = o->next) {
|
|
if (iscursed(o) && isequipped(o)) {
|
|
possob[npossob++] = o;
|
|
}
|
|
}
|
|
if (npossob) {
|
|
o = possob[rnd(0,npossob-1)];
|
|
if (text) {
|
|
msg(text);
|
|
}
|
|
blessob(o);
|
|
return B_TRUE;
|
|
}
|
|
return B_FALSE;
|
|
}
|