- [+] 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:
parent
d063040341
commit
db0b726088
14
ai.c
14
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
82
attack.c
82
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;
|
||||
|
|
10
data.c
10
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.");
|
||||
|
|
5
defs.h
5
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
|
||||
|
||||
|
|
38
io.c
38
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;
|
||||
|
|
42
lf.c
42
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 {
|
||||
|
|
1
lf.h
1
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);
|
||||
|
|
4
move.c
4
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;
|
||||
}
|
||||
|
|
4
nexus.c
4
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;
|
||||
|
|
134
objects.c
134
objects.c
|
@ -1,6 +1,7 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.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 *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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue