From db0b7260885b92ed5a3af870400c22f62b3aa94d Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Sun, 15 Jan 2012 23:18:20 +0000 Subject: [PATCH] - [+] 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 --- ai.c | 14 ++++-- attack.c | 82 +++++++++++++++++---------------- data.c | 10 ++-- defs.h | 5 ++ io.c | 38 ++++++++++++++-- lf.c | 42 +++++++++++++++-- lf.h | 1 + move.c | 4 +- nexus.c | 4 ++ objects.c | 134 ++++++++++++++++++++++++++++++++++++------------------ objects.h | 4 +- spell.c | 4 +- 12 files changed, 234 insertions(+), 108 deletions(-) diff --git a/ai.c b/ai.c index 4f990c2..a8ecd95 100644 --- a/ai.c +++ b/ai.c @@ -968,11 +968,15 @@ int ai_healing(lifeform_t *lf) { // don't have or can't use our healing items // no enemies in sight? if (safetorest(lf)) { - // if it's "night time" for us, sleep forever. - // 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 + // gods will only sleep/meditate if they are in the realm of gods + if (isgod(lf) && (lf->cell->habitat->id != H_HEAVEN)) { + } else { + // if it's "night time" for us, sleep forever. + // 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 + } } } } diff --git a/attack.c b/attack.c index 5eb2ceb..12b67ba 100644 --- a/attack.c +++ b/attack.c @@ -483,45 +483,47 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { // god effects... if ((attacktype == AT_LF) && isplayer(lf) && attacktarget) { - if (attackedfriend) { - angergodmaybe(R_GODMERCY, 100, GA_ATTACKALLY); - angergodmaybe(R_GODPURITY, 100, GA_ATTACKALLY); - switch (getalignment(attacktarget)) { - case AL_EVIL: - angergodmaybe(R_GODDEATH, 20, GA_ATTACKALLY); // even more - break; - case AL_GOOD: - angergodmaybe(R_GODPURITY, 20, GA_ATTACKALLY); // even more - break; - default: - break; + if (!isgod(attacktarget)) { + if (attackedfriend) { + angergodmaybe(R_GODMERCY, 100, GA_ATTACKALLY); + angergodmaybe(R_GODPURITY, 100, GA_ATTACKALLY); + switch (getalignment(attacktarget)) { + case AL_EVIL: + angergodmaybe(R_GODDEATH, 20, GA_ATTACKALLY); // even more + break; + case AL_GOOD: + angergodmaybe(R_GODPURITY, 20, GA_ATTACKALLY); // even more + 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); // announce if (haslos(player, c)) { - msg("%s %s!", cellname, shattered ? "shatters" : "is destroyed"); + msg("%s %s!", cellname, willshatter(cellmat) ? "shatters" : "is destroyed"); } // shatter? if (willshatter(cellmat)) { @@ -1565,7 +1567,7 @@ int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag) { shattered = B_TRUE; noise(c, NULL, NC_OTHER, SV_CAR, "something shattering.", NULL); if (getshardobname(cellmat, what)) { - fragments(c, what, 0, 3); // TODO: use speed so shards will hit lfs + fragments(c, what, 3, 3); } } break; diff --git a/data.c b/data.c index 750c52d..2ccee55 100644 --- a/data.c +++ b/data.c @@ -928,7 +928,7 @@ void initobjects(void) { for (i = 0; strlen(ringadjective[i]) ; i++) { char buf2[BUFLEN]; 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 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 + // shuffle hidden names and ensure no duplicates + shufflehiddennames(); + validatehiddennames(); + // object types // dungeon features @@ -2557,6 +2559,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLLEVEL, 2, 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_AICASTTOATTACK, ST_VICTIM, NA, 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); 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); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); // l6 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."); diff --git a/defs.h b/defs.h index 1d6b71c..5e6bc08 100644 --- a/defs.h +++ b/defs.h @@ -2955,6 +2955,11 @@ enum FLAG { F_RUNNING, // are we running? (shift+dir) // v0 is last dir moved. // 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 F_HUNGER, // val0 = hunger, higher = hungrier diff --git a/io.c b/io.c index 7df43e1..d2a1191 100644 --- a/io.c +++ b/io.c @@ -1294,6 +1294,8 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { } else { if (f->val[1] == ST_ASLEEP) { 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 { 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. - if (!areallies(player, lf)) { + if (!areallies(player, lf) && !isgod(lf)) { if (ispeaceful(lf) && cantalk(lf)) { 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); @@ -3735,7 +3737,7 @@ void docomms(lifeform_t *lf) { } // 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); } @@ -8637,11 +8639,13 @@ void handleinput(void) { if (f) { int rundir = D_NONE; int lastdir; - int ihaveturned; + int ihaveturned,walls; int stopnow = B_FALSE; + int i; object_t *o; lastdir = f->val[0]; ihaveturned = f->val[1]; + walls = f->val[2]; // certain objects in the current cell will stop us from running. 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)) { stopnow = B_TRUE; } @@ -8662,8 +8684,14 @@ void handleinput(void) { // something here? if (stopnow) { } else if (!ihaveturned && moveclear(player, lastdir, NULL)) { - // go the same dir if we can. - rundir = lastdir; + // haven't turned yet? + // 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 { int dir; int poss[MAXDIR_COMPASS],nposs; diff --git a/lf.c b/lf.c index 32b9aaf..89737b5 100644 --- a/lf.c +++ b/lf.c @@ -1627,7 +1627,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar needtovalidate = B_TRUE; } else if (targcell) { targettype = TT_NONE; - needtovalidate = B_TRUE; + needtovalidate = B_FALSE; } if (needtovalidate) { @@ -1664,7 +1664,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar power += countplantsinsight(lf); 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) { // half strength power /= 2; @@ -2680,6 +2680,12 @@ void die(lifeform_t *lf) { flag_t *f; f = lfhasflag(lf, F_DIESPLATTER); 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]); } } @@ -4155,10 +4161,12 @@ void fightback(lifeform_t *lf, lifeform_t *attacker) { // turn to face our attacker 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); + //} + aiattack(lf, attacker, aigetchasetime(lf)); } - aiattack(lf, attacker, aigetchasetime(lf)); } // any nearby monsters which will help out? @@ -6099,6 +6107,26 @@ int getlastdir(lifeform_t *lf) { 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) { flag_t *f; object_t *o; @@ -6197,7 +6225,11 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) { f = lfhasflag(lf, F_DRUNK); if (f) { 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)) { acc += (10*amt); } else { diff --git a/lf.h b/lf.h index af398ee..cb7f5ea 100644 --- a/lf.h +++ b/lf.h @@ -161,6 +161,7 @@ char *gethungername(lifeform_t *lf, enum HUNGER hunger, char *buf); int gethungerval(lifeform_t *lf); job_t *getjob(lifeform_t *lf); int getlastdir(lifeform_t *lf); +int getleftrightwalls(lifeform_t *lf); int getlfaccuracy(lifeform_t *lf, object_t *wep); char getlfcol(lifeform_t *lf, enum MSGCHARCOL cc); enum LFCONDITION getlfcondition(lifeform_t *lf); diff --git a/move.c b/move.c index 543d787..e904e34 100644 --- a/move.c +++ b/move.c @@ -2099,8 +2099,8 @@ int tryrun(lifeform_t *lf, int dir) { } rv = trymove(lf, dir, B_TRUE, B_TRUE); if (!rv && willrun) { - // successful move - addflag(lf->flags, F_RUNNING, dir, B_FALSE, NA, NULL); + // successful move - start running. + addflag(lf->flags, F_RUNNING, dir, B_FALSE, getleftrightwalls(lf), NULL); } return rv; } diff --git a/nexus.c b/nexus.c index c7f8040..8398994 100644 --- a/nexus.c +++ b/nexus.c @@ -1131,6 +1131,7 @@ int init(void) { initoptions(); initcommands(); initobjects(); + validatehiddennames(); initskills(); initjobs(); initrace(); @@ -1142,6 +1143,9 @@ int init(void) { // create the dungeon layout initmap(); + validatehiddennames(); + + gamemode = GM_VALIDATION; if (validateobs()) { return B_TRUE; diff --git a/objects.c b/objects.c index 5cad980..9f3ab89 100644 --- a/objects.c +++ b/objects.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -305,6 +306,9 @@ object_t *addemptyob(obpile_t *where, object_t *o) { hiddenname_t *addhiddenname(enum OBCLASS obclass, char *text) { hiddenname_t *a; + // make sure it doesn't already exist + assert(counthiddennames(obclass, text) == 0); + // add to the end of the list if (firsthiddenname == NULL) { 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) { object_t *o; int amt = 0; @@ -3366,8 +3381,7 @@ recipe_t *findrecipefor(enum OBTYPE result) { void fragments(cell_t *centre, char *what, int speed, int howfar) { cell_t *c,*dst; - int n; - int dir; + int n,dir; for (dir = DC_N; dir <= DC_NW; dir++) { 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 if (maxdist == 0) { wantdist = 0; } else { + /* int realmax; if (howfar > maxdist) { realmax = (maxdist-1); } else { realmax = howfar-1; } - if (realmax < 1) { + */ + if (maxdist < 1) { wantdist = 0; } else { - wantdist = rnd(1,realmax); + wantdist = rnd(1,maxdist); } } // go that far @@ -3424,7 +3442,7 @@ void fragments(cell_t *centre, char *what, int speed, int howfar) { // add object then fire it o = addob(centre->obpile, what); if (o) { - fireat(NULL, o, o->amt, dst, speed, NULL); + real_fireat(NULL, o, o->amt, dst, speed, NULL, B_FALSE); } } else { // add object @@ -11109,7 +11127,6 @@ void shufflehiddennames(void) { hiddenname_t *a, *temp; int shuffleamt = 500; - total = 0; for (a = firsthiddenname ; a ; a = a->next) { total++; @@ -11489,8 +11506,12 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) { 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) { + 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 throwernamea[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") - if (thrower && isplayer(thrower)) { - // player is throwing something - if (!firearm) { - if (target && !hasflag(o->flags, F_POWDER)) { - msg("You %s %s %s %s.", throwverbpres, obname, willcatch ? "to" : "at", targetname); - } else { - msg("You %s %s.",throwverbpres, obname); + if (announcethrow) { + if (thrower && isplayer(thrower)) { + // player is throwing something + if (!firearm) { + if (target && !hasflag(o->flags, F_POWDER)) { + msg("You %s %s %s %s.", throwverbpres, obname, willcatch ? "to" : "at", targetname); + } else { + msg("You %s %s.",throwverbpres, obname); + } } - } - } else if (thrower && haslos(player, srcloc) && (srcloc == thrower->cell)) { - char throwstring[BUFLEN]; + } else if (thrower && haslos(player, srcloc) && (srcloc == thrower->cell)) { + char throwstring[BUFLEN]; - // a monster is throwing something - snprintf(throwstring, BUFLEN, "%s %ss %s", throwername, throwverbpres, - obname); + // a monster is throwing something + snprintf(throwstring, BUFLEN, "%s %ss %s", throwername, throwverbpres, + obname); - if (target && haslos(player, where) && !hasflag(o->flags, F_POWDER)) { - strcat(throwstring, willcatch ? " to " : " at "); - strcat(throwstring, targetname); - } - strcat(throwstring, "."); - msg("%s", throwstring); - } else if (seen) { - char throwstring[BUFLEN]; - // an object is moving on its own - if (o->pile->owner && cansee(player, o->pile->owner)) { - char ownername[BUFLEN]; - getlfname(o->pile->owner, ownername); - snprintf(throwstring, BUFLEN, "%s%s %s %s through the air", ownername, getpossessive(ownername), - noprefix(obname), (amt == 1) ? "flies" : "fly"); - } else { - snprintf(throwstring, BUFLEN, "%s %s through the air", obname, (amt == 1) ? "flies" : "fly"); + if (target && haslos(player, where) && !hasflag(o->flags, F_POWDER)) { + strcat(throwstring, willcatch ? " to " : " at "); + strcat(throwstring, targetname); + } + strcat(throwstring, "."); + msg("%s", throwstring); + } else if (seen) { + char throwstring[BUFLEN]; + // an object is moving on its own + if (o->pile->owner && cansee(player, o->pile->owner)) { + char ownername[BUFLEN]; + getlfname(o->pile->owner, ownername); + snprintf(throwstring, BUFLEN, "%s%s %s %s through the air", ownername, getpossessive(ownername), + noprefix(obname), (amt == 1) ? "flies" : "fly"); + } else { + 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); // some obejcts will die when thrown. @@ -13156,14 +13178,36 @@ int usecharges(object_t *o, int amt) { 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) { objecttype_t *ot; + flag_t *f; int foundspells = B_FALSE; int goterror = B_FALSE; - flag_t *f; for (ot = objecttype ; ot ; ot = ot->next) { - // fix up glyphs f = hasflag(ot->flags, F_GLYPH); if (f) { diff --git a/objects.h b/objects.h index 310f383..660ffe6 100644 --- a/objects.h +++ b/objects.h @@ -39,6 +39,7 @@ int getcritprotection(object_t *o); int checkobnames(char *haystack, char *needle); void colourmatchob(object_t *o, lifeform_t *lf); void copyobprops(object_t *dst, object_t *src); +int counthiddennames(enum OBCLASS ocid, char *text); int countmoney(obpile_t *op); int countnames(char **list); 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 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 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 trapeffects(object_t *trapob, enum OBTYPE oid, lifeform_t *lf); void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c); void turnoff(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 usecharges(object_t *o, int amt); int usefountaincharge(object_t *o, flag_t *drinkflag); +int validatehiddennames(void); int validateobs(void); int wepdullable(object_t *o); int willshatter(enum MATERIAL mat); diff --git a/spell.c b/spell.c index 9e191f0..453b889 100644 --- a/spell.c +++ b/spell.c @@ -7053,8 +7053,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (cansee(player, target)) { if (seenbyplayer) *seenbyplayer = B_TRUE; } - - m = findregionmap(RG_HEAVEN, 1); + // alwyas go realm of gods + m = heaven; } if (m) { int ntries = 0;