- [+] corpses should inherit lf vulnerabilities/immunities

- [+] change bloodsplatter for full leeches to no longer use fireat code
    - [+] was a bug - wasn't handling NA for speed in F_DIESPLATTER
    - [+] change fireat code to not announce "xxx flies through the
          air" for platters
- [+] fix it so that things flying through the air (via fragments())
      can hit people.
- [+] when calling fragments(), don't announce every single "a shard
      flies at xxx"
    - [+] fireat() needs "announcethrow"
- [+] stop running when adjacent to any monster (evne peaceful)
- [+] monsters should always turn to face their attackers, even if they
      aren't adjacent.
- [+] multiple ring types are getting the same hiddenname:
    - [+] Rings
             ring of strength          (flourite ring)
             ring of stench           (flourite ring)
    - [+] validateobs now checks for this.
    - [+] nearly everything seems to have 2 entries.
    - [+] maybe also put a check inside addhiddenname!
    - [+] addhiddenname no longer triggering dupes.
- [+] bug: planeshift not working when cast by enemies.
- [+] bug: skillxp being boosted by massive amounts sometimes
    - [+]  Exp Level: 15 (32150 XP, -1581 for next)
    - [+] bug in getlfaccuracy - returning 9937 and boosting xpval by
          massive amounts!
- [+] motel bug:
    - [+] How many hours will you pay for (you have $1073)? 4 hours
          ($440)
          You start resting (in your motel room)...  You finish resting.
          You wake up.
          "Sleep well!"
    - [+] say"sleep well" BEFORE sleeping!
- [+] for some reason i'm gaining massive amounts of skill points!
    - [+] killed  giant ant, got 3 points???
    - [+] pointsforsp not going up fast enough, especially at high
          levles (13+)
    - [+] was a bug in getlfaccuracy
- [+] yumi should only check attacking helpless on your FIRST attack.
    - [+] if you have subsequent ones, they're ok since you can't
          control them!
- [+] don't please or anger gods when fighting gods
This commit is contained in:
Rob Pearce 2012-01-15 23:18:20 +00:00
parent d063040341
commit db0b726088
12 changed files with 234 additions and 108 deletions

14
ai.c
View File

@ -968,11 +968,15 @@ int ai_healing(lifeform_t *lf) {
// don't have or can't use our healing items // don't have or can't use our healing items
// no enemies in sight? // no enemies in sight?
if (safetorest(lf)) { if (safetorest(lf)) {
// if it's "night time" for us, sleep forever. // gods will only sleep/meditate if they are in the realm of gods
// otehrwise just sleep until we're healed if (isgod(lf) && (lf->cell->habitat->id != H_HEAVEN)) {
if (!gotosleep(lf, issleepingtimefor(lf) ? B_TRUE : B_FALSE)) { } else {
taketime(lf, getactspeed(lf)); // to make sure our turn ends // if it's "night time" for us, sleep forever.
return B_TRUE; // success // otehrwise just sleep until we're healed
if (!gotosleep(lf, issleepingtimefor(lf) ? B_TRUE : B_FALSE)) {
taketime(lf, getactspeed(lf)); // to make sure our turn ends
return B_TRUE; // success
}
} }
} }
} }

View File

@ -483,45 +483,47 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
// god effects... // god effects...
if ((attacktype == AT_LF) && isplayer(lf) && attacktarget) { if ((attacktype == AT_LF) && isplayer(lf) && attacktarget) {
if (attackedfriend) { if (!isgod(attacktarget)) {
angergodmaybe(R_GODMERCY, 100, GA_ATTACKALLY); if (attackedfriend) {
angergodmaybe(R_GODPURITY, 100, GA_ATTACKALLY); angergodmaybe(R_GODMERCY, 100, GA_ATTACKALLY);
switch (getalignment(attacktarget)) { angergodmaybe(R_GODPURITY, 100, GA_ATTACKALLY);
case AL_EVIL: switch (getalignment(attacktarget)) {
angergodmaybe(R_GODDEATH, 20, GA_ATTACKALLY); // even more case AL_EVIL:
break; angergodmaybe(R_GODDEATH, 20, GA_ATTACKALLY); // even more
case AL_GOOD: break;
angergodmaybe(R_GODPURITY, 20, GA_ATTACKALLY); // even more case AL_GOOD:
break; angergodmaybe(R_GODPURITY, 20, GA_ATTACKALLY); // even more
default: break;
break; default:
break;
}
} else if (attackedpeaceful) {
angergodmaybe(R_GODMERCY, 50, GA_ASSAULT);
angergodmaybe(R_GODPURITY, 50, GA_ASSAULT);
switch (getalignment(attacktarget)) {
case AL_EVIL:
angergodmaybe(R_GODDEATH, 20, GA_ASSAULT); // even more
break;
case AL_GOOD:
angergodmaybe(R_GODPURITY, 20, GA_ASSAULT); // even more
break;
default:
break;
}
} else if (attackedhelpless) {
angergodmaybe(R_GODMERCY, 50, GA_ATTACKHELPLESS);
angergodmaybe(R_GODPURITY, 50, GA_ATTACKHELPLESS);
if (getalignment(attacktarget) != AL_EVIL) {
pleasegodmaybe(R_GODTHIEVES, 5);
pleasegodmaybe(R_GODDEATH, 10);
}
}
if (lfhasflag(lf, F_USEDPOISON)) {
killflagsofid(lf->flags, F_USEDPOISON);
angergodmaybe(R_GODPURITY, 100, GA_POISON);
angergodmaybe(R_GODMERCY, 25, GA_POISON);
pleasegodmaybe(R_GODDEATH, 3);
} }
} else if (attackedpeaceful) {
angergodmaybe(R_GODMERCY, 50, GA_ASSAULT);
angergodmaybe(R_GODPURITY, 50, GA_ASSAULT);
switch (getalignment(attacktarget)) {
case AL_EVIL:
angergodmaybe(R_GODDEATH, 20, GA_ASSAULT); // even more
break;
case AL_GOOD:
angergodmaybe(R_GODPURITY, 20, GA_ASSAULT); // even more
break;
default:
break;
}
} else if (attackedhelpless) {
angergodmaybe(R_GODMERCY, 50, GA_ATTACKHELPLESS);
angergodmaybe(R_GODPURITY, 50, GA_ATTACKHELPLESS);
if (getalignment(attacktarget) != AL_EVIL) {
pleasegodmaybe(R_GODTHIEVES, 5);
pleasegodmaybe(R_GODDEATH, 10);
}
}
if (lfhasflag(lf, F_USEDPOISON)) {
killflagsofid(lf->flags, F_USEDPOISON);
angergodmaybe(R_GODPURITY, 100, GA_POISON);
angergodmaybe(R_GODMERCY, 25, GA_POISON);
pleasegodmaybe(R_GODDEATH, 3);
} }
} }
@ -1557,7 +1559,7 @@ int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag) {
setcelltype(c, c->map->habitat->emptycelltype); setcelltype(c, c->map->habitat->emptycelltype);
// announce // announce
if (haslos(player, c)) { if (haslos(player, c)) {
msg("%s %s!", cellname, shattered ? "shatters" : "is destroyed"); msg("%s %s!", cellname, willshatter(cellmat) ? "shatters" : "is destroyed");
} }
// shatter? // shatter?
if (willshatter(cellmat)) { if (willshatter(cellmat)) {
@ -1565,7 +1567,7 @@ int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag) {
shattered = B_TRUE; shattered = B_TRUE;
noise(c, NULL, NC_OTHER, SV_CAR, "something shattering.", NULL); noise(c, NULL, NC_OTHER, SV_CAR, "something shattering.", NULL);
if (getshardobname(cellmat, what)) { if (getshardobname(cellmat, what)) {
fragments(c, what, 0, 3); // TODO: use speed so shards will hit lfs fragments(c, what, 3, 3);
} }
} }
break; break;

10
data.c
View File

@ -928,7 +928,7 @@ void initobjects(void) {
for (i = 0; strlen(ringadjective[i]) ; i++) { for (i = 0; strlen(ringadjective[i]) ; i++) {
char buf2[BUFLEN]; char buf2[BUFLEN];
snprintf(buf2, BUFLEN, "%s %s",ringadjective[i], buf); snprintf(buf2, BUFLEN, "%s %s",ringadjective[i], buf);
addhiddenname(OC_RING, buf); addhiddenname(OC_RING, buf2);
} }
} }
@ -943,8 +943,6 @@ void initobjects(void) {
} }
} }
shufflehiddennames();
// object modifiers - flags can be either known or not, depending on if it's obvious // object modifiers - flags can be either known or not, depending on if it's obvious
addobmod(OM_BLOODSTAINED,"bloodstained"); addobmod(OM_BLOODSTAINED,"bloodstained");
@ -1286,6 +1284,10 @@ void initobjects(void) {
addoc(OC_ABILITY, "Abilities", "A special ability", '&', C_GREY, RR_NEVER); // this is a "virtual" object class addoc(OC_ABILITY, "Abilities", "A special ability", '&', C_GREY, RR_NEVER); // this is a "virtual" object class
// shuffle hidden names and ensure no duplicates
shufflehiddennames();
validatehiddennames();
// object types // object types
// dungeon features // dungeon features
@ -2557,6 +2559,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_SMITEGOOD, "smite good", "Instantly deals 1-^bpower*2^n damage to good creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SMITEGOOD, "smite good", "Instantly deals 1-^bpower*2^n damage to good creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
@ -2632,6 +2635,7 @@ void initobjects(void) {
addot(OT_S_HECTASSERVANT, "hecta's hand", "Summons an enormous skeletal hand to drag foes to their doom. BEWARE: the hand will attack anything living, including the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_HECTASSERVANT, "hecta's hand", "Summons an enormous skeletal hand to drag foes to their doom. BEWARE: the hand will attack anything living, including the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
// l6 // l6
addot(OT_S_POSSESSION, "possession", "Completely possess an enemy, moving your consciousness into their body.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_POSSESSION, "possession", "Completely possess an enemy, moving your consciousness into their body.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines its resistability."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines its resistability.");

5
defs.h
View File

@ -2955,6 +2955,11 @@ enum FLAG {
F_RUNNING, // are we running? (shift+dir) F_RUNNING, // are we running? (shift+dir)
// v0 is last dir moved. // v0 is last dir moved.
// v1 is whether we have turned yet. // v1 is whether we have turned yet.
// v2 = what walls to our left and right are:
// 0 = l+r cells clear
// 1 = l cell walled, r cell clear
// 2 = l cell clear, r cell walled
// 3 = l+r cells walled
// nutrition // nutrition
F_HUNGER, // val0 = hunger, higher = hungrier F_HUNGER, // val0 = hunger, higher = hungrier

38
io.c
View File

@ -1294,6 +1294,8 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
} else { } else {
if (f->val[1] == ST_ASLEEP) { if (f->val[1] == ST_ASLEEP) {
msg("%s fall%s asleep.",lfname, isplayer(lf) ? "" : "s"); msg("%s fall%s asleep.",lfname, isplayer(lf) ? "" : "s");
} else if (f->val[1] == ST_MEDITATING) {
msg("%s enter%s a trance.",lfname, isplayer(lf) ? "" : "s");
} else { } else {
msg("%s lose%s consciousness.",lfname, isplayer(lf) ? "" : "s"); msg("%s lose%s consciousness.",lfname, isplayer(lf) ? "" : "s");
} }
@ -3723,7 +3725,7 @@ void docomms(lifeform_t *lf) {
} }
// TODO: allow you to ask this of allies, but only on the level they started on. // TODO: allow you to ask this of allies, but only on the level they started on.
if (!areallies(player, lf)) { if (!areallies(player, lf) && !isgod(lf)) {
if (ispeaceful(lf) && cantalk(lf)) { if (ispeaceful(lf) && cantalk(lf)) {
addchoice(&prompt, 'i', "What can you tell me about this area?", NULL, NULL, NULL); addchoice(&prompt, 'i', "What can you tell me about this area?", NULL, NULL, NULL);
addchoice(&prompt, 'x', "Any dangers nearby that I should look out for?", NULL, NULL, NULL); addchoice(&prompt, 'x', "Any dangers nearby that I should look out for?", NULL, NULL, NULL);
@ -3735,7 +3737,7 @@ void docomms(lifeform_t *lf) {
} }
// if you are allies, use 'trade items' instead // if you are allies, use 'trade items' instead
if (isadjacent(lf->cell, player->cell) && !areallies(player,lf)) { if (isadjacent(lf->cell, player->cell) && !areallies(player,lf) && !isgod(lf)) {
addchoice(&prompt, 'd', "(donate an item)", NULL, NULL, NULL); addchoice(&prompt, 'd', "(donate an item)", NULL, NULL, NULL);
} }
@ -8637,11 +8639,13 @@ void handleinput(void) {
if (f) { if (f) {
int rundir = D_NONE; int rundir = D_NONE;
int lastdir; int lastdir;
int ihaveturned; int ihaveturned,walls;
int stopnow = B_FALSE; int stopnow = B_FALSE;
int i;
object_t *o; object_t *o;
lastdir = f->val[0]; lastdir = f->val[0];
ihaveturned = f->val[1]; ihaveturned = f->val[1];
walls = f->val[2];
// certain objects in the current cell will stop us from running. // certain objects in the current cell will stop us from running.
for (o = player->cell->obpile->first ; o ; o = o->next) { for (o = player->cell->obpile->first ; o ; o = o->next) {
@ -8651,6 +8655,24 @@ void handleinput(void) {
} }
} }
for (i = 0; i < player->nlos; i++) {
lifeform_t *thislf;
thislf = player->los[i]->lf;
if (thislf && !isplayer(thislf) && !areallies(player, thislf) && cansee(player, thislf)) {
if (areenemies(player, player->los[i]->lf)) {
// visible hostile monsters stop us
stopnow = B_TRUE;
break;
} else if (getcelldist(player->cell, player->los[i]) <= 1) {
// any non-ally lf in adjacent cells should stop us
stopnow = B_TRUE;
break;
}
}
}
// adjacent doors stop us.
if (countadjcellswithflag(player->cell, F_DOOR, DT_COMPASS)) { if (countadjcellswithflag(player->cell, F_DOOR, DT_COMPASS)) {
stopnow = B_TRUE; stopnow = B_TRUE;
} }
@ -8662,8 +8684,14 @@ void handleinput(void) {
// something here? // something here?
if (stopnow) { if (stopnow) {
} else if (!ihaveturned && moveclear(player, lastdir, NULL)) { } else if (!ihaveturned && moveclear(player, lastdir, NULL)) {
// go the same dir if we can. // haven't turned yet?
rundir = lastdir; // if walls to our l+r have changed...
if (getleftrightwalls(player) != walls) {
stopnow = B_TRUE;
} else {
// otherwise go the same dir if we can.
rundir = lastdir;
}
} else { } else {
int dir; int dir;
int poss[MAXDIR_COMPASS],nposs; int poss[MAXDIR_COMPASS],nposs;

42
lf.c
View File

@ -1627,7 +1627,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
needtovalidate = B_TRUE; needtovalidate = B_TRUE;
} else if (targcell) { } else if (targcell) {
targettype = TT_NONE; targettype = TT_NONE;
needtovalidate = B_TRUE; needtovalidate = B_FALSE;
} }
if (needtovalidate) { if (needtovalidate) {
@ -1664,7 +1664,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
power += countplantsinsight(lf); power += countplantsinsight(lf);
limit(&power, NA, 10); limit(&power, NA, 10);
} }
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 20 + power, 0)) { if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 20 + power, 0) && !isgod(lf)) {
if (power > 1) { if (power > 1) {
// half strength // half strength
power /= 2; power /= 2;
@ -2680,6 +2680,12 @@ void die(lifeform_t *lf) {
flag_t *f; flag_t *f;
f = lfhasflag(lf, F_DIESPLATTER); f = lfhasflag(lf, F_DIESPLATTER);
if (f) { if (f) {
int speed,howfar;
howfar = f->val[0];
speed = f->val[1];
if (speed < 0) speed = 0;
if (howfar < 0) howfar = UNLIMITED;
fragments(corpsecell, f->text, f->val[1], f->val[0]); fragments(corpsecell, f->text, f->val[1], f->val[0]);
} }
} }
@ -4155,10 +4161,12 @@ void fightback(lifeform_t *lf, lifeform_t *attacker) {
// turn to face our attacker // turn to face our attacker
if (!lfhasflag(lf, F_STUNNED) && !isdead(lf)) { if (!lfhasflag(lf, F_STUNNED) && !isdead(lf)) {
if (isadjacent(lf->cell, attacker->cell)) { if (!isfleeing(lf)) {
//if (isadjacent(lf->cell, attacker->cell)) {
turntoface(lf, attacker->cell); turntoface(lf, attacker->cell);
//}
aiattack(lf, attacker, aigetchasetime(lf));
} }
aiattack(lf, attacker, aigetchasetime(lf));
} }
// any nearby monsters which will help out? // any nearby monsters which will help out?
@ -6099,6 +6107,26 @@ int getlastdir(lifeform_t *lf) {
return D_NONE; return D_NONE;
} }
int getleftrightwalls(lifeform_t *lf) {
cell_t *rightcell,*leftcell;
int rightdir,leftdir;
int walls = 0;
// remember walls to left and right
leftdir = lf->facing - 1;
if (leftdir < DC_N) leftdir = DC_NW;
rightdir = lf->facing + 1;
if (rightdir > DC_NW) rightdir = DC_N;
leftcell = getcellindir(lf->cell, leftdir);
rightcell = getcellindir(lf->cell, rightdir);
if (!leftcell || (leftcell && leftcell->type->solid)) {
walls += 1;
}
if (!rightcell || (rightcell && rightcell->type->solid)) {
walls += 2;
}
return walls;
}
int getlfaccuracy(lifeform_t *lf, object_t *wep) { int getlfaccuracy(lifeform_t *lf, object_t *wep) {
flag_t *f; flag_t *f;
object_t *o; object_t *o;
@ -6197,7 +6225,11 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) {
f = lfhasflag(lf, F_DRUNK); f = lfhasflag(lf, F_DRUNK);
if (f) { if (f) {
int amt; int amt;
amt = (f->lifetime/TM_DRUNKTIME)+1; int time;
time = f->lifetime;
if (time < 0) time = 70; // ie permenant
limit(&time, NA, 70);
amt = (time/TM_DRUNKTIME)+1;
if (hasjob(lf, J_PIRATE)) { if (hasjob(lf, J_PIRATE)) {
acc += (10*amt); acc += (10*amt);
} else { } else {

1
lf.h
View File

@ -161,6 +161,7 @@ char *gethungername(lifeform_t *lf, enum HUNGER hunger, char *buf);
int gethungerval(lifeform_t *lf); int gethungerval(lifeform_t *lf);
job_t *getjob(lifeform_t *lf); job_t *getjob(lifeform_t *lf);
int getlastdir(lifeform_t *lf); int getlastdir(lifeform_t *lf);
int getleftrightwalls(lifeform_t *lf);
int getlfaccuracy(lifeform_t *lf, object_t *wep); int getlfaccuracy(lifeform_t *lf, object_t *wep);
char getlfcol(lifeform_t *lf, enum MSGCHARCOL cc); char getlfcol(lifeform_t *lf, enum MSGCHARCOL cc);
enum LFCONDITION getlfcondition(lifeform_t *lf); enum LFCONDITION getlfcondition(lifeform_t *lf);

4
move.c
View File

@ -2099,8 +2099,8 @@ int tryrun(lifeform_t *lf, int dir) {
} }
rv = trymove(lf, dir, B_TRUE, B_TRUE); rv = trymove(lf, dir, B_TRUE, B_TRUE);
if (!rv && willrun) { if (!rv && willrun) {
// successful move // successful move - start running.
addflag(lf->flags, F_RUNNING, dir, B_FALSE, NA, NULL); addflag(lf->flags, F_RUNNING, dir, B_FALSE, getleftrightwalls(lf), NULL);
} }
return rv; return rv;
} }

View File

@ -1131,6 +1131,7 @@ int init(void) {
initoptions(); initoptions();
initcommands(); initcommands();
initobjects(); initobjects();
validatehiddennames();
initskills(); initskills();
initjobs(); initjobs();
initrace(); initrace();
@ -1142,6 +1143,9 @@ int init(void) {
// create the dungeon layout // create the dungeon layout
initmap(); initmap();
validatehiddennames();
gamemode = GM_VALIDATION; gamemode = GM_VALIDATION;
if (validateobs()) { if (validateobs()) {
return B_TRUE; return B_TRUE;

134
objects.c
View File

@ -1,6 +1,7 @@
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <math.h> #include <math.h>
#include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -305,6 +306,9 @@ object_t *addemptyob(obpile_t *where, object_t *o) {
hiddenname_t *addhiddenname(enum OBCLASS obclass, char *text) { hiddenname_t *addhiddenname(enum OBCLASS obclass, char *text) {
hiddenname_t *a; hiddenname_t *a;
// make sure it doesn't already exist
assert(counthiddennames(obclass, text) == 0);
// add to the end of the list // add to the end of the list
if (firsthiddenname == NULL) { if (firsthiddenname == NULL) {
firsthiddenname = malloc(sizeof(hiddenname_t)); firsthiddenname = malloc(sizeof(hiddenname_t));
@ -2753,6 +2757,17 @@ void copyobprops(object_t *dst, object_t *src) {
} }
int counthiddennames(enum OBCLASS ocid, char *text) {
int count = 0;
hiddenname_t *hn;
for (hn = firsthiddenname ; hn ; hn = hn->next) {
if ((hn->obclass == ocid) && streq(hn->text, text)) {
count++;
}
}
return count;
}
int countmoney(obpile_t *op) { int countmoney(obpile_t *op) {
object_t *o; object_t *o;
int amt = 0; int amt = 0;
@ -3366,8 +3381,7 @@ recipe_t *findrecipefor(enum OBTYPE result) {
void fragments(cell_t *centre, char *what, int speed, int howfar) { void fragments(cell_t *centre, char *what, int speed, int howfar) {
cell_t *c,*dst; cell_t *c,*dst;
int n; int n,dir;
int dir;
for (dir = DC_N; dir <= DC_NW; dir++) { for (dir = DC_N; dir <= DC_NW; dir++) {
int wantdist = 0; int wantdist = 0;
@ -3392,20 +3406,24 @@ void fragments(cell_t *centre, char *what, int speed, int howfar) {
} }
} }
limit(&maxdist, NA, howfar);
// pick random distance // pick random distance
if (maxdist == 0) { if (maxdist == 0) {
wantdist = 0; wantdist = 0;
} else { } else {
/*
int realmax; int realmax;
if (howfar > maxdist) { if (howfar > maxdist) {
realmax = (maxdist-1); realmax = (maxdist-1);
} else { } else {
realmax = howfar-1; realmax = howfar-1;
} }
if (realmax < 1) { */
if (maxdist < 1) {
wantdist = 0; wantdist = 0;
} else { } else {
wantdist = rnd(1,realmax); wantdist = rnd(1,maxdist);
} }
} }
// go that far // go that far
@ -3424,7 +3442,7 @@ void fragments(cell_t *centre, char *what, int speed, int howfar) {
// add object then fire it // add object then fire it
o = addob(centre->obpile, what); o = addob(centre->obpile, what);
if (o) { if (o) {
fireat(NULL, o, o->amt, dst, speed, NULL); real_fireat(NULL, o, o->amt, dst, speed, NULL, B_FALSE);
} }
} else { } else {
// add object // add object
@ -11109,7 +11127,6 @@ void shufflehiddennames(void) {
hiddenname_t *a, *temp; hiddenname_t *a, *temp;
int shuffleamt = 500; int shuffleamt = 500;
total = 0; total = 0;
for (a = firsthiddenname ; a ; a = a->next) { for (a = firsthiddenname ; a ; a = a->next) {
total++; total++;
@ -11489,8 +11506,12 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
return damtaken; return damtaken;
} }
// throw speed/2 is the damage multiplier
int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm) { int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm) {
return real_fireat(thrower, o, amt, where, speed, firearm, B_TRUE);
}
// throw speed/2 is the damage multiplier
int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm, int announcethrow) {
char throwername[BUFLEN]; char throwername[BUFLEN];
char throwernamea[BUFLEN]; char throwernamea[BUFLEN];
char realthrowername[BUFLEN]; char realthrowername[BUFLEN];
@ -11653,48 +11674,49 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
} }
// announce it ("xx throws xx" "at yy") // announce it ("xx throws xx" "at yy")
if (thrower && isplayer(thrower)) { if (announcethrow) {
// player is throwing something if (thrower && isplayer(thrower)) {
if (!firearm) { // player is throwing something
if (target && !hasflag(o->flags, F_POWDER)) { if (!firearm) {
msg("You %s %s %s %s.", throwverbpres, obname, willcatch ? "to" : "at", targetname); if (target && !hasflag(o->flags, F_POWDER)) {
} else { msg("You %s %s %s %s.", throwverbpres, obname, willcatch ? "to" : "at", targetname);
msg("You %s %s.",throwverbpres, obname); } else {
msg("You %s %s.",throwverbpres, obname);
}
} }
} } else if (thrower && haslos(player, srcloc) && (srcloc == thrower->cell)) {
} else if (thrower && haslos(player, srcloc) && (srcloc == thrower->cell)) { char throwstring[BUFLEN];
char throwstring[BUFLEN];
// a monster is throwing something // a monster is throwing something
snprintf(throwstring, BUFLEN, "%s %ss %s", throwername, throwverbpres, snprintf(throwstring, BUFLEN, "%s %ss %s", throwername, throwverbpres,
obname); obname);
if (target && haslos(player, where) && !hasflag(o->flags, F_POWDER)) { if (target && haslos(player, where) && !hasflag(o->flags, F_POWDER)) {
strcat(throwstring, willcatch ? " to " : " at "); strcat(throwstring, willcatch ? " to " : " at ");
strcat(throwstring, targetname); strcat(throwstring, targetname);
} }
strcat(throwstring, "."); strcat(throwstring, ".");
msg("%s", throwstring); msg("%s", throwstring);
} else if (seen) { } else if (seen) {
char throwstring[BUFLEN]; char throwstring[BUFLEN];
// an object is moving on its own // an object is moving on its own
if (o->pile->owner && cansee(player, o->pile->owner)) { if (o->pile->owner && cansee(player, o->pile->owner)) {
char ownername[BUFLEN]; char ownername[BUFLEN];
getlfname(o->pile->owner, ownername); getlfname(o->pile->owner, ownername);
snprintf(throwstring, BUFLEN, "%s%s %s %s through the air", ownername, getpossessive(ownername), snprintf(throwstring, BUFLEN, "%s%s %s %s through the air", ownername, getpossessive(ownername),
noprefix(obname), (amt == 1) ? "flies" : "fly"); noprefix(obname), (amt == 1) ? "flies" : "fly");
} else { } else {
snprintf(throwstring, BUFLEN, "%s %s through the air", obname, (amt == 1) ? "flies" : "fly"); snprintf(throwstring, BUFLEN, "%s %s through the air", obname, (amt == 1) ? "flies" : "fly");
}
if (target && haslos(player, where)) {
strcat(throwstring, " toward ");
strcat(throwstring, targetname);
}
strcat(throwstring, ".");
msg("%s", throwstring);
} }
if (target && haslos(player, where)) {
strcat(throwstring, " toward ");
strcat(throwstring, targetname);
}
strcat(throwstring, ".");
msg("%s", throwstring);
} }
//taketime(thrower, SPEED_THROW); //taketime(thrower, SPEED_THROW);
// some obejcts will die when thrown. // some obejcts will die when thrown.
@ -13156,14 +13178,36 @@ int usecharges(object_t *o, int amt) {
return -1; return -1;
} }
int validatehiddennames(void) {
objectclass_t *oc;
hiddenname_t *hn;
int goterror = B_FALSE;
// check hidden names for duplicates
for (oc = objectclass ; oc ; oc = oc->next) {
for (hn = firsthiddenname ; hn ; hn = hn->next) {
if (hn->obclass == oc->id) {
int count;
count = counthiddennames(oc->id, hn->text);
if (count > 1) {
printf("Error - duplicate hiddenname found for class %s, text '%s'. (%d found)\n", oc->name, hn->text, count);
goterror = B_TRUE;
}
}
}
}
if (goterror) {
raise(SIGINT);
}
return goterror;
}
int validateobs(void) { int validateobs(void) {
objecttype_t *ot; objecttype_t *ot;
flag_t *f;
int foundspells = B_FALSE; int foundspells = B_FALSE;
int goterror = B_FALSE; int goterror = B_FALSE;
flag_t *f;
for (ot = objecttype ; ot ; ot = ot->next) { for (ot = objecttype ; ot ; ot = ot->next) {
// fix up glyphs // fix up glyphs
f = hasflag(ot->flags, F_GLYPH); f = hasflag(ot->flags, F_GLYPH);
if (f) { if (f) {

View File

@ -39,6 +39,7 @@ int getcritprotection(object_t *o);
int checkobnames(char *haystack, char *needle); int checkobnames(char *haystack, char *needle);
void colourmatchob(object_t *o, lifeform_t *lf); void colourmatchob(object_t *o, lifeform_t *lf);
void copyobprops(object_t *dst, object_t *src); void copyobprops(object_t *dst, object_t *src);
int counthiddennames(enum OBCLASS ocid, char *text);
int countmoney(obpile_t *op); int countmoney(obpile_t *op);
int countnames(char **list); int countnames(char **list);
int countobs(obpile_t *op, int onlyifknown); int countobs(obpile_t *op, int onlyifknown);
@ -265,8 +266,8 @@ object_t *splitob(object_t *o);
int takedamage(object_t *o, int howmuch, int damtype); int takedamage(object_t *o, int howmuch, int damtype);
int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce); int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce);
int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm); int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm);
int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm, int announcethrow);
void timeeffectsob(object_t *o); void timeeffectsob(object_t *o);
//void trapeffects(object_t *trapob, enum OBTYPE oid, lifeform_t *lf);
void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c); void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c);
void turnoff(lifeform_t *lf, object_t *o); void turnoff(lifeform_t *lf, object_t *o);
void turnon(lifeform_t *lf, object_t *o); void turnon(lifeform_t *lf, object_t *o);
@ -274,6 +275,7 @@ int uncurseob(object_t *o, int *seen);
int usecharge(object_t *o); int usecharge(object_t *o);
int usecharges(object_t *o, int amt); int usecharges(object_t *o, int amt);
int usefountaincharge(object_t *o, flag_t *drinkflag); int usefountaincharge(object_t *o, flag_t *drinkflag);
int validatehiddennames(void);
int validateobs(void); int validateobs(void);
int wepdullable(object_t *o); int wepdullable(object_t *o);
int willshatter(enum MATERIAL mat); int willshatter(enum MATERIAL mat);

View File

@ -7053,8 +7053,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (cansee(player, target)) { if (cansee(player, target)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
// alwyas go realm of gods
m = findregionmap(RG_HEAVEN, 1); m = heaven;
} }
if (m) { if (m) {
int ntries = 0; int ntries = 0;