- [+] dancing weapons should injerit object's size.

- [+] animals shouldn't be smart enough to avoid sharp objects on the
      grond.
    - [+] make all animals have wisdom = LOW
    - [+] make most undead have wisdom = VLOW
    - [+] make most undead have CHA = EXLOW
- [+] warn if races are missing any STARTATTs
- [+] warn if races have duplice sTARTATTS
- [+] reduce unyon hit points
- [+] drop monster hitdice sides to 6
- [+] change goblin colours
- [+] replace quickblade with uchigatana. dael 7-8 damage. very rare.
- [ ] apply correct rarity to weapons
- [+] balance katana now that i've modified blades!
    - [+] and add wakazashi.
- [+] add altdam bash to most swords
- [+] add f->text to altdam
- [+] add "noobstext" to askobject()
- [+] why did ninja start with 0 mp ?
- [+] if you read a manual for a skill yo ucan't learn, have some kind
      of message to say it didnt work
- [+] map shouldn't be magical
- [+] cloth should 'heat up' (it just catches on fire)
- [+] give A_FIT to all mosnters, for stamina when we polymorph into
      them!
- [+] fix bug where celldangerous() fails on a lifeform's own cell
- [+] reflexive dodging should also dodge dangerous objects which
      appear on top of you!
    - [+] do this in startlfturn(), before other effects!
- [+] air spell - refraction - boosts EV
- [+] move jolt to L2
- [+] don't announce initial damage taking object from perfect to
      battered.
- [+] propel missile
    - [+] doesnt anger lumara
    - [+] for monsters: aispellok true if we have an OC_MISISLE which
          we're strong enough to able to throw.
    - [+] minrange 2
This commit is contained in:
Rob Pearce 2012-03-20 10:26:33 +00:00
parent ed98c0b735
commit 0a06d06374
15 changed files with 778 additions and 184 deletions

18
ai.c
View File

@ -1573,7 +1573,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
if ( (spell != OT_NONE) && // found a valid spell/ability to use
// AND one of these:
((dist != 1) || // there is distance between us and target
(getspellrange(lf, st->id, 1) == 1) || // OR this works from adjacent
(getspellrange(lf, st->id, 1, NULL) == 1) || // OR this works from adjacent
(st->obclass->id == OC_ABILITY) || // OR this is an ability
!countinnateattacks(lf) || // OR we have no melee attack
(rnd(1,3) == 1)) // OR random chance of using anyway...
@ -2203,11 +2203,12 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
if (f) {
if (pctchance(castchance)) {
int range;
int range, minrange,dist;
dist = getcelldist(lf->cell, victim->cell);
switch (targettype) {
case ST_VICTIM:
range = getspellrange(lf, spellid, getspellpower(lf, spellid));
if ((range == UNLIMITED) || (getcelldist(lf->cell, victim->cell) <= range)) {
range = getspellrange(lf, spellid, getspellpower(lf, spellid), &minrange);
if (((range == UNLIMITED) || (dist <= range)) && (dist >= minrange)) {
if (db) {
dblog(".oO { spell possibility: %s }", ot ? ot->name : "?unkownspell?");
}
@ -2222,7 +2223,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
ok = B_TRUE;
break;
case ST_ADJVICTIM:
if (getcelldist(lf->cell,victim->cell) == 1) {
if (dist == 1) {
if (ot->id == OT_A_GRAB) {
if (lfhasflag(lf, F_GRABBING) || lfhasflag(lf, F_GRABBEDBY) ||
lfhasflag(victim, F_GRABBING) || lfhasflag(victim, F_GRABBEDBY)) {
@ -2245,7 +2246,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
}
break;
case ST_ADJSELF:
if (getcelldist(lf->cell,victim->cell) == 1) {
if (dist == 1) {
ok = B_TRUE;
}
break;
@ -2499,6 +2500,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
if ((ot->id == OT_S_PARALYZE) && lfhasflag(victim, F_PARALYZED)) {
specificcheckok = B_FALSE;
}
if (ot->id == OT_S_PROPELMISSILE) {
if (!getbestthrowmissile(lf, victim)) {
specificcheckok = B_FALSE;
}
}
if (ot->id == OT_A_SHIELDBASH) {
if (!getshield(lf, DT_ALL)) {
specificcheckok = B_FALSE;

View File

@ -1082,7 +1082,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
}
if (candodge) {
adj = getrandomadjcell(victim->cell, WE_WALKABLE, B_NOEXPAND);
adj = getdodgecell(victim);
if (adj) {
flag_t *f;
if (isplayer(victim) || cansee(player, victim)) {

615
data.c

File diff suppressed because it is too large Load Diff

Binary file not shown.

17
defs.h
View File

@ -386,7 +386,7 @@ enum SHOPACTION {
#define RANDOM (-2610)
#define AUTO (-7654)
#define HEAVYWEPKG (5)
#define HITDIESIDES (8)
#define HITDIESIDES (6)
// how quickly the game clock increments
@ -1521,6 +1521,8 @@ enum OBTYPE {
OT_S_GUSTOFWIND,
OT_S_HURRICANE,
OT_S_MIST,
OT_S_PROPELMISSILE,
OT_S_REFRACTION,
OT_S_SHATTER,
OT_S_TAILWIND,
OT_S_TORNADO,
@ -2057,9 +2059,7 @@ enum OBTYPE {
OT_KNIFE,
OT_MEATCLEAVER,
OT_ORNDAGGER,
OT_QUICKBLADE,
OT_RAPIER,
OT_SAI,
OT_SABRE,
OT_SHORTSWORD,
OT_STEAKKNIFE,
@ -2072,11 +2072,16 @@ enum OBTYPE {
OT_EPEE,
OT_FALCHION,
OT_GREATSWORD,
OT_KATANA,
OT_LONGSWORD,
OT_ORNSWORD,
OT_SCIMITAR,
OT_ZWEIHANDER,
// exotic
OT_KATANA,
OT_NUNCHAKU,
OT_SAI,
OT_UCHIGATANA,
OT_WAKAZASHI,
// polearms
OT_GLAIVE,
OT_GUISARME,
@ -2105,7 +2110,6 @@ enum OBTYPE {
OT_GREATCLUB,
OT_MACE,
OT_MORNINGSTAR,
OT_NUNCHAKU,
OT_SHILLELAGH,
OT_SPANNER,
OT_STICK,
@ -2664,7 +2668,8 @@ enum FLAG {
F_FIRESPEED, // how fast this weapon shoots projectiles
F_AMMOOB, // v0 = what object this weapon fires. can have multiple types.
F_AMMOCAPACITY, // v0 = max ammo that can be loaded
F_RANGE, // range of projectile firing weapon
F_RANGE, // v0 = range of projectile firing weapon or spell
// optional v1 = minrange (for spells only)
F_RELOADTURNS, // # actions it takes to reload this gun
// end gun flags
F_FLAMESTRIKE, // causes fires where you hit

66
io.c
View File

@ -542,10 +542,10 @@ char askchar(char *prompt, char *validchars, char *def, int showchars, int mayca
}
cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail) {
return real_askcoords(prompt, subprompt, targettype, srclf, maxrange, loftype, wanttrail, NULL, 0);
return real_askcoords(prompt, subprompt, targettype, srclf, 0, maxrange, loftype, wanttrail, NULL, 0);
}
cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail, cell_t **spectarg, int nspectargs) {
cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int minrange, int maxrange, enum LOFTYPE loftype, int wanttrail, cell_t **spectarg, int nspectargs) {
static int startlf = -1;
int finished = B_FALSE;
int moved = B_FALSE;
@ -1084,10 +1084,10 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
tempob = addob(c->obpile, obname);
}
// show objects
o = doaskobject(c->obpile, "Describe which object", NULL, B_TRUE, B_FALSE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
o = doaskobject(c->obpile, "Describe which object", NULL, NULL, B_TRUE, B_FALSE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
while (o) {
describeob(o);
o = doaskobject(c->obpile, "Describe which object", NULL, B_FALSE, B_FALSE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
o = doaskobject(c->obpile, "Describe which object",NULL, NULL, B_FALSE, B_FALSE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
}
if (tempob) killob(tempob);
}
@ -2795,16 +2795,16 @@ lifeform_t *askgod(char *prompttext, int onlyprayed) {
return lf;
}
object_t *askobject(obpile_t *op, char *prompt, int *count, char action, long opts) {
object_t *askobject(obpile_t *op, char *prompt, char *noobtext, int *count, char action, long opts) {
int showlong = B_TRUE;
if (op->owner && isplayer(op->owner)) {
showlong = B_FALSE;
}
return doaskobject(op, prompt, count, showlong, B_TRUE, B_FALSE, action, NULL, MT_NOTHING, opts, F_NONE);
return doaskobject(op, prompt, noobtext, count, showlong, B_TRUE, B_FALSE, action, NULL, MT_NOTHING, opts, F_NONE);
}
object_t *askobjectwithflag(obpile_t *op, char *prompt, int *count, char action, long opts, enum FLAG withflag) {
return doaskobject(op, prompt, count, B_TRUE, B_TRUE, B_FALSE, action, NULL, MT_NOTHING, opts, withflag, F_NONE);
object_t *askobjectwithflag(obpile_t *op, char *prompt, char *noobtext, int *count, char action, long opts, enum FLAG withflag) {
return doaskobject(op, prompt, noobtext, count, B_TRUE, B_TRUE, B_FALSE, action, NULL, MT_NOTHING, opts, withflag, F_NONE);
}
int contains(enum OBCLASS *array, int nargs, enum OBCLASS want) {
@ -2942,7 +2942,7 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi
// F_NONE
//
// If you pass "sellshop", DONT also pass F_xxx.
object_t *doaskobject(obpile_t *op, char *prompt, int *count, int showlong, int forpickup, int showpoints, char action, object_t *sellshop, int wantmaterial, long opts, ...) {
object_t *doaskobject(obpile_t *op, char *prompt, char *noobtext, int *count, int showlong, int forpickup, int showpoints, char action, object_t *sellshop, int wantmaterial, long opts, ...) {
int c,i;
char defchar = '\0';
static char defaults[52] = {'\0'};
@ -3078,6 +3078,12 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int showlong, int
}
mylist[i] = NULL;
// no objects?
if ((i == 0) && noobtext) {
msg("%s", noobtext);
return NULL;
}
// start displaying from the first one
firstob = 0;
nextpage = -1;
@ -4175,7 +4181,7 @@ void docomms(lifeform_t *lf) {
} else {
// ask what to give
snprintf(buf, BUFLEN, "What will you give to %s?",lfname);
o = askobject(player->pack, buf, &count, '\0', AO_NONE);
o = askobject(player->pack, buf, NULL, &count, '\0', AO_NONE);
}
if (o) {
if (o->type->id == OT_GOLD) {
@ -4746,7 +4752,7 @@ void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) {
if (wantmulti) {
askobjectmulti(op, buf, AO_NONE);
} else {
o = askobject(op, buf, &count, '\0', AO_NONE);
o = askobject(op, buf, NULL, &count, '\0', AO_NONE);
if (o) {
retobs[0] = o;
retobscount[0] = count;
@ -4881,7 +4887,7 @@ void doeat(obpile_t *op) {
return;
}
eatob = askobject(op, "Eat what", NULL, 'e', AO_EDIBLE);
eatob = askobject(op, "Eat what", "You have nothing to eat!", NULL, 'e', AO_EDIBLE);
}
if (eatob) {
if (isunknownbadobject(eatob) && skillcheck(player, A_WIS, 30, 0)) {
@ -4897,7 +4903,7 @@ void doeat(obpile_t *op) {
int dowear(obpile_t *op) {
object_t *o;
int rv;
o = askobject(op, "Wear what", NULL, '\0', AO_WEARABLE);
o = askobject(op, "Wear what", "You have nothing to wear!", NULL, '\0', AO_WEARABLE);
if (o) {
if (isunknownbadobject(o) && skillcheck(player, A_WIS, 30, 0)) {
if (!confirm_badfeeling(o)) {
@ -4919,7 +4925,7 @@ int doweild(obpile_t *op) {
object_t *o;
int count = ALL;
int rv;
o = askobject(op, "Weild what", &count, 'w', AO_WEILDABLE | AO_INCLUDENOTHING);
o = askobject(op, "Weild what", "You have nothing to weild.", &count, 'w', AO_WEILDABLE | AO_INCLUDENOTHING);
if (o) {
if (isunknownbadobject(o) && skillcheck(player, A_WIS, 30, 0)) {
if (!confirm_badfeeling(o)) {
@ -7283,7 +7289,7 @@ char *makedesc_skill(enum SKILL skid, char *retbuf, enum SKILLLEVEL levhilite) {
char *makedesc_spell(objecttype_t *ot, char *retbuf) {
char buf[BUFLEN];
flag_t *retflag[MAXCANDIDATES], *f;
int nretflags,i,power,range,stamcost;
int nretflags,i,power,range,stamcost,minrange;
strcpy(retbuf, "");
@ -7294,7 +7300,7 @@ char *makedesc_spell(objecttype_t *ot, char *retbuf) {
}
range = getspellrange(player, ot->id, power);
range = getspellrange(player, ot->id, power, &minrange);
snprintf(buf, BUFLEN, "%s\n", ot->desc);
strncat(retbuf, buf, BUFLEN);
@ -7408,7 +7414,13 @@ char *makedesc_spell(objecttype_t *ot, char *retbuf) {
strncat(retbuf, buf, BUFLEN);
if (range != UNLIMITED) {
sprintf(buf, "At this power, it has a range of %d cell%s.\n",range, (range == 1) ? "" : "s");
sprintf(buf, "At this power, it has a range of %d cell%s",range, (range == 1) ? "" : "s");
if (minrange != 0) {
char buf2[BUFLEN];
sprintf(buf2, " (minimum %d)", minrange);
strcat(buf, buf2);
}
strcat(buf, ".\n");
strncat(retbuf, buf, BUFLEN);
}
}
@ -7802,7 +7814,7 @@ void dooperate(obpile_t *op) {
}
// ask which object to read
o = askobject(op, "Operate what", NULL, 'o', AO_OPERABLE);
o = askobject(op, "Operate what", "You have nothing to operate.", NULL, 'o', AO_OPERABLE);
if (o) {
operate(player, o, NULL);
}
@ -7995,12 +8007,12 @@ void doexplain(char *question) {
void dofinaloblist(obpile_t *op) {
object_t *o;
o = doaskobject(op, "Your final possessions were", NULL, B_TRUE, B_FALSE, B_TRUE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
o = doaskobject(op, "Your final possessions were", NULL, NULL, B_TRUE, B_FALSE, B_TRUE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
while (o) {
// describe it
describeob(o);
// ask for another one
o = doaskobject(op, "Your final possessions were", NULL, B_TRUE, B_FALSE, B_TRUE,'\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
o = doaskobject(op, "Your final possessions were",NULL, NULL, B_TRUE, B_FALSE, B_TRUE,'\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
}
real_clearmsg(B_TRUE);
}
@ -8154,12 +8166,12 @@ void doinventory(obpile_t *op) {
maxweight = getmaxcarryweight(player);
pct = (packweight / maxweight) * 100;
snprintf(buf, BUFLEN, "Inventory (%0.0f/%0.0f kg, %0.0f%%)", packweight, maxweight, pct);
o = doaskobject(op, buf, NULL, B_TRUE, B_TRUE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
o = doaskobject(op, buf, NULL, NULL, B_TRUE, B_TRUE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
while (o) {
// describe it
describeob(o);
// ask for another one
o = askobject(op, buf, NULL, '\0', AO_NONE);
o = askobject(op, buf, NULL, NULL, '\0', AO_NONE);
}
real_clearmsg(B_TRUE);
}
@ -8193,7 +8205,7 @@ void doquaff(obpile_t *op) {
// ask which object to quaff
if (!liquid) {
liquid = askobjectwithflag(op, "Quaff what", NULL, 'q', AO_NONE, F_DRINKABLE);
liquid = askobjectwithflag(op, "Quaff what", "You have nothing drinkable.", NULL, 'q', AO_NONE, F_DRINKABLE);
}
if (liquid) {
if (canquaff(player, liquid)) {
@ -8275,7 +8287,7 @@ void dopour(obpile_t *op) {
object_t *o;
// ask which object to read
o = askobject(op, "Pour what", NULL, 'P', AO_POURABLE);
o = askobject(op, "Pour what", "You are not holding anything pourable.", NULL, 'P', AO_POURABLE);
if (o) {
if (ispourable(o)) {
pour(player, o);
@ -8304,7 +8316,7 @@ void doread(obpile_t *op) {
// ask which object to read
o = askobject(op, "Read what", NULL, 'r', AO_READABLE);
o = askobject(op, "Read what", "You have nothing to read.", NULL, 'r', AO_READABLE);
if (o) {
if (isreadable(o)) {
readsomething(player, o);
@ -8394,7 +8406,7 @@ int dotakeoff(obpile_t *op) {
int rv = B_TRUE;
// ask which object to read
o = askobject(op, "Take off what", NULL, 'T', AO_EQUIPPEDNONWEAPON );
o = askobject(op, "Take off what", "You are not wearing anything!", NULL, 'T', AO_EQUIPPEDNONWEAPON );
if (o) {
if (isarmour(o)) {
f = hasflag(o->flags, F_EQUIPPED);
@ -8425,7 +8437,7 @@ int dothrow(obpile_t *op, object_t *o) {
// ask which object to throw
if (!o) {
o = askobject(op, "Throw what", NULL, 't', AO_NONE);
o = askobject(op, "Throw what", "You have nothing to throw!", NULL, 't', AO_NONE);
}
if (o) {
int maxdist;

8
io.h
View File

@ -19,13 +19,13 @@ void announceobflagloss(object_t *o, flag_t *f);
int confirm_badfeeling(object_t *o);
int confirm_injury_action(enum BODYPART bp, enum DAMTYPE dt, char *actionname);
lifeform_t *askgod(char *prompt, int onlyprayed);
object_t *askobject(obpile_t *op, char *title, int *count, char action, long opts);
object_t *askobjectwithflag(obpile_t *op, char *title, int *count, char action, long opts, enum FLAG withflag);
object_t *doaskobject(obpile_t *op, char *title, int *count, int showlong, int forpickup, int showpoints, char action, object_t *sellshop, int wantmaterial, long opts, ...);
object_t *askobject(obpile_t *op, char *title, char *noobtext, int *count, char action, long opts);
object_t *askobjectwithflag(obpile_t *op, char *title, char *noobtext,int *count, char action, long opts, enum FLAG withflag);
object_t *doaskobject(obpile_t *op, char *prompt, char *noobtext, int *count, int showlong, int forpickup, int showpoints, char action, object_t *sellshop, int wantmaterial, long opts, ...);
int askobjectmulti(obpile_t *op, char *prompt, long opts);
char askchar(char *prompt, char *validchars, char *def, int showchars, int maycancel);
cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail);
cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail, cell_t **spectarg, int nspectargs);
cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int minrange, int maxrange, enum LOFTYPE loftype, int wanttrail, cell_t **spectarg, int nspectargs);
char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def);
vault_t *askvault(char *prompttext);
void centre(WINDOW *win, enum COLOUR col, int y, char *format, ... );

60
lf.c
View File

@ -68,6 +68,7 @@ extern lifeform_t *godlf[];
extern int ngodlfs;
extern enum ERROR reason;
extern void *rdata;
// for xplist
@ -4180,7 +4181,7 @@ int eat(lifeform_t *lf, object_t *o) {
ptid = P_FOOD;
}
// cannibulism ?
if (corpserace->id == lf->race->baseid) {
if (corpserace && (corpserace->id == lf->race->baseid)) {
ppower = 3;
}
poison(lf, rnd(20,40), ptid, ppower, dambuf, cf ? cf->val[0] : R_NONE);
@ -9951,6 +9952,9 @@ void givesubjob(lifeform_t *lf, enum SUBJOB sj) {
switch (sj) {
// mage types
case SJ_AIRMAGE:
o = addob(lf->pack, "15 blessed darts");
identify(o);
giveskilllev(lf, SK_THROWING, PR_NOVICE);
addflag(lf->flags, F_CANSEETHROUGHMAT, MT_GAS, NA, NA, NULL);
sb1 = addob(lf->pack, "spellbook of air magic");
if (!isplayer(lf)) {
@ -11529,7 +11533,7 @@ int lockpick(lifeform_t *lf, cell_t *targcell, object_t *target, object_t *devic
}
// ask which object to use
device = askobjectwithflag(lf->pack, "Lockpick using what", NULL, 'p', AO_NONE, F_PICKLOCKS);
device = askobjectwithflag(lf->pack, "Lockpick using what", NULL, NULL, 'p', AO_NONE, F_PICKLOCKS);
if (!device) {
msg("Cancelled.");
return B_TRUE;
@ -19093,6 +19097,35 @@ void startlfturn(lifeform_t *lf) {
if (isdead(lf)) return;
if (lfhasflag(lf, F_DODGES)) {
enum ERROR e;
if (celldangerous(lf, lf->cell, B_TRUE, &e)) {
cell_t *adj;
// autododge!
adj = getdodgecell(lf);
if (adj) {
char fromx[BUFLEN];
if ((e == E_AVOIDOB) && rdata) {
object_t *o;
o = (object_t *)rdata;
getobname(o, fromx, o->amt);
} else {
sprintf(fromx, "danger");
}
if (isplayer(lf)) {
msg("You reflexively dodge away from %s!", fromx);
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s reflexively dodges away from %s!", lfname, fromx);
}
f = addflag(lf->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
moveto(lf, adj, B_FALSE, B_FALSE);
killflag(f);
}
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// IMPORTANT: any potentially damaging effects have to go after here...
@ -21102,6 +21135,7 @@ int validateraces(void) {
for (r = firstrace ; r ; r = r->next) {
lifeform_t *lf;
int thishd;
enum ATTRIB a;
// add a fake lf
lf = addlf(&fakecell, r->id, 1);
@ -21113,6 +21147,19 @@ int validateraces(void) {
maxmonhitdice = thishd;
}
// all races must have fully defined stats
for (a = 0 ; a < MAXATTS; a++) {
if (!hasflagval(r->flags, F_STARTATT, a, NA, NA, NULL)) {
printf("ERROR in race '%s' - race has no f_startatt %s\n", r->name, getattrname(a));
goterror = B_TRUE;
}
}
// duplicate startatt flags?
if (countflagsofid(r->flags, F_STARTATT) != MAXATTS) {
printf("ERROR in race '%s' - duplicate f_startatt flags detected.\n", r->name);
goterror = B_TRUE;
}
if (!hasflag(r->flags, F_SIZE)) {
printf("ERROR in race '%s' - missing F_SIZE.\n", r->name);
@ -21183,15 +21230,6 @@ int validateraces(void) {
printf("ERROR in race '%s' - F_HITCONFER, but no HITCONFERVALS defined.\n", r->name);
goterror = B_TRUE;
}
} else if (f->id == F_PLAYABLE) {
// playable races must have fully defined stats
enum ATTRIB a;
for (a = 0 ; a < MAXATTS; a++) {
if (!hasflagval(r->flags, F_STARTATT, a, NA, NA, NULL)) {
printf("ERROR in race '%s' - race is f_playable but has no f_startatt %s\n", r->name, getattrname(a));
goterror = B_TRUE;
}
}
} else if (f->id == F_STARTATT) {
if (strlen(f->text) && (f->val[1] != NA)) {
printf("ERROR in race '%s' - F_STARTATT has both text range and val1.\n", r->name);

19
move.c
View File

@ -165,7 +165,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
// never dangerous if there's someone there, since we'll
// attack them instead of moving!
if (cell->lf) {
if (cell->lf && (cell->lf != lf)) {
return B_FALSE;
}
@ -780,6 +780,23 @@ int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, in
return bestdir;
}
cell_t *getdodgecell(lifeform_t *lf) {
int dir;
cell_t *c,*poss[8];
int nposs = 0;
for (dir = DC_N; dir <= DC_NW; dir++) {
c = getcellindir(lf->cell, dir);
if (c && cellwalkable(lf, c, NULL) && !celldangerous(lf, c, B_TRUE, NULL)) {
poss[nposs++] = c;
}
}
if (nposs) {
return poss[rnd(0,nposs-1)];
}
return NULL;
}
int getwalkoffdir(lifeform_t *lf, int dir) {
switch (dir) {
case DC_NE:

1
move.h
View File

@ -11,6 +11,7 @@ int diropposite(int dir);
int dorandommove(lifeform_t *lf, int badmovesok, int restonfail, int strafe);
int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype, int keepinlof);
int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype);
cell_t *getdodgecell(lifeform_t *lf);
int getwalkoffdir(lifeform_t *lf, int dir);
int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallcheckdiff, int wantannounce);
int makeorthogonal(int dir);

View File

@ -3715,7 +3715,7 @@ void fragments(cell_t *centre, char *what, int speed, int howfar) {
// add object then fire it
o = addob(centre->obpile, what);
if (o) {
real_fireat(NULL, o, o->amt, dst, speed, NULL, B_FALSE);
real_fireat(NULL, o, o->amt, dst, speed, NULL, B_FALSE, OT_NONE);
}
} else {
// add object
@ -6906,13 +6906,6 @@ int isheatable(object_t *o) {
return 0;
}
switch (o->material->id) {
case MT_PAPER:
case MT_LEATHER:
case MT_CLOTH:
case MT_SILK:
case MT_PLANT:
return 2;
case MT_BONE:
case MT_STONE:
case MT_RUBBER:
case MT_WAX:
@ -7030,6 +7023,7 @@ int ismagicalobtype(objecttype_t *ot) {
case OC_SCROLL:
switch (ot->id) {
case OT_SCR_NOTHING:
case OT_MAP:
// these scrolls are non-magical
break;
default:
@ -7690,6 +7684,13 @@ lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level) {
newlf->maxhp = f->val[1];
newlf->hp = newlf->maxhp;
}
f = hasflag(o->flags, F_SIZE);
if (f) {
flag_t *f2;
f2 = lfhasflag(newlf, F_SIZE);
if (f2) f2->val[0] = f->val[0];
else addflag(lf->flags, F_SIZE, f->val[0], NA, NA, NULL);
}
f = hasflag(o->flags, F_OBATTACKDELAY);
if (f) {
int origspeed;
@ -8991,7 +8992,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
return B_TRUE;
} else {
snprintf(buf, BUFLEN, "Load %s with what ammo",obname);
oo = askobject(lf->pack, buf, NULL, 'l', AO_SPECIFIED);
oo = askobject(lf->pack, buf, NULL, NULL, 'l', AO_SPECIFIED);
if (oo) {
if (isammofor(oo->type, o)) {
loadfirearm(lf, o, oo);
@ -9847,7 +9848,7 @@ int pour(lifeform_t *lf, object_t *o) {
} else {
snprintf(buf, BUFLEN, "Pour %s onto what", obname);
// tip onto another object
dst = askobject(lf->pack, buf, NULL, '\0', AO_NONE);
dst = askobject(lf->pack, buf, NULL, NULL, '\0', AO_NONE);
if (!dst) {
msg("Cancelled.");
return B_TRUE;
@ -10867,7 +10868,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
if (needsob && isplayer(lf) && !isknown(o)) {
flag_t *f2;
f2 = addflag(o->flags, F_BEINGUSED, B_TRUE, NA, NA, NULL);
targob = askobject(lf->pack, "Target which object", NULL, '\0', AO_NONE);
targob = askobject(lf->pack, "Target which object", NULL, NULL, '\0', AO_NONE);
killflag(f2);
if (targob) {
if (isplayer(lf)) {
@ -11272,7 +11273,10 @@ int readsomething(lifeform_t *lf, object_t *o) {
if (ismaxedskill(lf, f->val[0])) {
if (isplayer(lf)) msg("This manual is too advanced for you.");
} else {
giveskill(lf, f->val[0]);
if (!giveskill(lf, f->val[0])) {
// can't learn this skill. maybe you have f_noskill?
if (isplayer(lf)) msg("You are incapable of using this skill.");
}
}
}
if (isplayer(lf)) {
@ -12156,7 +12160,8 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
getobconditionname(o, postdamname);
// was it enough to change the status
if (!hasflag(o->flags, F_NOOBDAMTEXT) && strcmp(predamname, postdamname)) {
if (!hasflag(o->flags, F_NOOBDAMTEXT) && strcmp(predamname, postdamname) &&
!streq(postdamname, "battered")) {
// if it was melting, drop some water here
if (damtype == DT_MELT) {
if (hasflag(o->flags, F_EQUIPPED) ) {
@ -12202,11 +12207,11 @@ 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) {
return real_fireat(thrower, o, amt, where, speed, firearm, B_TRUE);
return real_fireat(thrower, o, amt, where, speed, firearm, B_TRUE, OT_NONE);
}
// 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) {
int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm, int announcethrow, enum OBTYPE fromspell) {
char throwername[BUFLEN];
char throwernamea[BUFLEN];
char realthrowername[BUFLEN];
@ -12984,7 +12989,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
msg("Your %s is now out of ammo.", noprefix(buf));
}
*/
if (thrower && isplayer(thrower)) {
if (!fromspell && thrower && isplayer(thrower)) {
angergodmaybe(R_GODMAGIC, 10, GA_HERESY);
}

View File

@ -278,7 +278,7 @@ 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);
int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm, int announcethrow, enum OBTYPE fromspell);
void timeeffectsob(object_t *o);
int touch_battle_spoils(object_t *o);
void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c);

View File

@ -427,7 +427,7 @@ enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *topte
default: wantflag = F_NONE; wantoc = OC_NONE; break;
}
*/
o = doaskobject(lf->pack, "What will you donate?", &count, B_TRUE, B_FALSE, B_FALSE, '\0', vm, MT_NOTHING, AO_NONE, F_NONE);
o = doaskobject(lf->pack, "What will you donate?", NULL, &count, B_TRUE, B_FALSE, B_FALSE, '\0', vm, MT_NOTHING, AO_NONE, F_NONE);
// validate it
if (o) {
@ -1123,7 +1123,7 @@ enum SHOPRETURN shopsell(lifeform_t *lf, object_t *vm, int starty, char *toptext
// ask what to sell
sprintf(buf, "What will you sell (you have $%d)?", countmoney(lf->pack));
o = doaskobject(player->pack, buf, &count, B_TRUE, B_FALSE, B_FALSE, '\0', vm, MT_NOTHING, AO_NONE, F_NONE);
o = doaskobject(player->pack, buf, NULL, &count, B_TRUE, B_FALSE, B_FALSE, '\0', vm, MT_NOTHING, AO_NONE, F_NONE);
if (!o) {
return SR_BACK;
}

113
spell.c
View File

@ -1740,7 +1740,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (targcell->obpile->first) {
// select object from cell...
o = askobject(targcell->obpile, "Snatch which object", NULL, '\0', AO_NONE);
o = askobject(targcell->obpile, "Snatch which object", NULL, NULL, '\0', AO_NONE);
} else {
if (isplayer(user)) msg("There is nothing there to snatch!");
return B_TRUE;
@ -2708,6 +2708,11 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
for (i = 0; i < nretflags; i++) {
f = retflag[i];
sprintf(buf, "%s, DR %d", getdamname(f->val[0]), f->val[1]);
if (strlen(f->text)) {
strcat(buf, "(");
strcat(buf, f->text);
strcat(buf, ")");
}
if (f->val[0] == curdt) {
strcat(buf, " (current)");
}
@ -3704,7 +3709,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// needs:
// object = which object to convert
if (!targob && isplayer(caster)) {
targob = doaskobject(caster->pack, "Convert which object to gold", NULL, B_FALSE, B_FALSE, B_FALSE, '\0', NULL, MT_METAL, AO_NONE, F_NONE);
targob = doaskobject(caster->pack, "Convert which object to gold", NULL, NULL, B_FALSE, B_FALSE, B_FALSE, '\0', NULL, MT_METAL, AO_NONE, F_NONE);
}
if (!targob) {
fizzle(caster);
@ -3899,7 +3904,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (targcell->obpile->first) {
// select object from cell...
targob = askobject(targcell->obpile, "Target which object", NULL, '\0', AO_NONE);
targob = askobject(targcell->obpile, "Target which object", NULL, NULL, '\0', AO_NONE);
if (!targob) {
failed = B_TRUE;
}
@ -4304,7 +4309,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (targcell->obpile->first) {
// select object from cell...
targob = askobject(targcell->obpile, "Target which object", NULL, '\0', AO_NONE);
targob = askobject(targcell->obpile, "Target which object", NULL, NULL, '\0', AO_NONE);
if (!targob) {
failed = B_TRUE;
}
@ -4416,7 +4421,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
int range;
int nsides = 6;
range = getspellrange(caster, spellid, power);
range = getspellrange(caster, spellid, power, NULL);
if (caster) {
// create a line of fire towards the target cell
@ -6267,7 +6272,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
o = targob;
} else {
// ask for an object
o = askobjectwithflag(caster->pack, "Enchant which object", NULL, '\0', AO_NONE, F_ENCHANTABLE);
o = askobjectwithflag(caster->pack, "Enchant which object", NULL, NULL, '\0', AO_NONE, F_ENCHANTABLE);
}
if (!o) {
fizzle(caster);
@ -7065,7 +7070,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
o = targob;
} else {
// ask for an object
o = askobject(caster->pack, "Identify which object", NULL, '\0', AO_NOTIDENTIFIED);
o = askobject(caster->pack, "Identify which object", "You have nothing which needs identifying.", NULL, '\0', AO_NOTIDENTIFIED);
}
if (!o) {
fizzle(caster);
@ -7567,7 +7572,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
int seen;
if (targcell->obpile->first) {
targob = doaskobject(targcell->obpile, "Target which object", NULL, B_TRUE, B_FALSE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
targob = doaskobject(targcell->obpile, "Target which object", NULL, NULL, B_TRUE, B_FALSE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
}
if (!targob) {
@ -7645,21 +7650,46 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else {
if (seen) msg("%s shudders for a moment.", obname);
}
} else if (spellid == OT_S_ACCELMETAL) {
} else if ((spellid == OT_S_ACCELMETAL) || (spellid == OT_S_PROPELMISSILE)) {
char oidbuf[BUFLEN];
char obname[BUFLEN];
flag_t *f;
if (!targob) {
// ask for an object
targob = askobject(caster->pack, "Accelerate which object", NULL, 't', AO_NONE);
}
if (!targob || !ismetal(targob->material->id) ) {
if (spellid == OT_S_ACCELMETAL) {
// TODO: handle ai casting
targob = askobject(caster->pack, "Accelerate which metal object", NULL, NULL, 't', AO_NONE);
} else { // ie. propel
if (isplayer(caster)) {
targob = askobject(caster->pack, "Propel which object", NULL, NULL, 't', AO_NONE);
} else {
lifeform_t *target;
target = gettargetlf(caster);
if (target) {
targob = getbestthrowmissile(caster, target);
} else {
fizzle(caster);
return B_TRUE;
}
}
}
}
if (!targob || ((spellid == OT_S_ACCELMETAL) && !ismetal(targob->material->id)) ) {
fizzle(caster);
return B_TRUE;
}
getobname(targob, obname, 1);
if ((spellid == OT_S_PROPELMISSILE) && (getmaxthrowrange(caster, targob) <= 0)) {
if (isplayer(caster)) {
msg("%s is too heavy for you to throw!");
}
return B_FALSE; // don't cost mana
}
if (isequipped(targob) && iscursed(targob)) {
char obname[BUFLEN];
getobname(targob, obname, 1);
msg("Your %s appears to be stuck to you!", noprefix(obname));
targob->blessknown = B_TRUE;
return B_TRUE;
@ -7671,8 +7701,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
killflagsofid(caster->flags, F_THROWING);
// 5 is the same as AT_VHIGH strength
// 10 = gun speed
fireat(caster, targob, 1, targcell, 8 + (power / 2) , NULL);
real_fireat(caster, targob, 1, targcell, 5, NULL, B_TRUE, spellid);
} else if (spellid == OT_S_PLANESHIFT) {
map_t *m;
target = caster;
@ -7770,7 +7799,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
setcellknown(poss[i], PR_EXPERT);
}
// then ask to select one
targcell = real_askcoords("Travel where?", "Plantwalk->", TT_SPECIFIED, player, UNLIMITED, LOF_DONTNEED, B_FALSE, poss, nposs);
targcell = real_askcoords("Travel where?", "Plantwalk->", TT_SPECIFIED, player, 0, UNLIMITED, LOF_DONTNEED, B_FALSE, poss, nposs);
if (!hasobofclass(targcell->obpile, OC_FLORA)) {
targcell = NULL;
}
@ -7967,7 +7996,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("Robots are immune to charming.");
break;
case E_ALREADYUSING:
msg("%s is already charmed by another!", targetname);
msg("%s is already charmed by another!", targname);
break;
default:
msg("You cannot possesss %s.", targname);
@ -8132,7 +8161,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (targcell->obpile->first) { // no lifeform there
targob = NULL;
// select object from cell...
targob = askobject(targcell->obpile, "Target which object", NULL, '\0', AO_NONE);
targob = askobject(targcell->obpile, "Target which object", NULL, NULL, '\0', AO_NONE);
if (targob) {
if (ismetal(targob->material->id)) {
@ -8879,7 +8908,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
o = targob;
} else {
// ask for an object
o = askobject(caster->pack, "Mend which object", NULL, '\0', AO_DAMAGED);
o = askobject(caster->pack, "Mend which object", NULL, NULL, '\0', AO_DAMAGED);
}
if (!o) {
fizzle(caster);
@ -9459,6 +9488,15 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("%s looks very lethargic!", targname);
}
modstamina(target, -amttolose);
} else if (spellid == OT_S_REFRACTION) {
flag_t *f;
f = addtempflag(caster->flags, F_EVASION, 15+(power*5), NA, NA, NULL, FROMSPELL);
f->obfrom = spellid;
if (isplayer(caster)) {
msg("Your body seems to shimmer and bend!");
} else if (cansee(player, caster)) {
msg("%s%s body seems to shimmer and bend!", castername, getpossessive(castername));
}
} else if (spellid == OT_S_REPELINSECTS) {
// just announce
if (isplayer(caster)) {
@ -9472,7 +9510,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (!targob) {
if (isplayer(caster)) {
// ask for an object
targob = askobjectwithflag(caster->pack, "Replenish which object", NULL, '\0', AO_NONE, F_REPLENISHABLE);
targob = askobjectwithflag(caster->pack, "Replenish which object", NULL, NULL, '\0', AO_NONE, F_REPLENISHABLE);
}
}
if (!targob) {
@ -9530,7 +9568,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
lifeform_t *newlf;
if (!targob) {
// select object from cell...
targob = askobjectwithflag(targcell->obpile, "Revive which corpse", NULL, '\0', AO_NONE, F_CORPSEOF);
targob = askobjectwithflag(targcell->obpile, "Revive which corpse", NULL, NULL, '\0', AO_NONE, F_CORPSEOF);
if (!targob) {
fizzle(caster);
return B_TRUE;
@ -10398,7 +10436,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// object = which potion to throw
// cell = where to throw the potion
if (!targob && isplayer(caster)) {
targob = askobjectwithflag(caster->pack, "Superheat which potion", NULL, 'q', AO_NONE, F_DRINKABLE);
targob = askobjectwithflag(caster->pack, "Superheat which potion", NULL, NULL, 'q', AO_NONE, F_DRINKABLE);
}
if (!targob) {
fizzle(caster);
@ -10671,7 +10709,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (where && haslos(caster, where)) {
if (where->obpile->first) {
// select object from cell...
targob = askobject(where->obpile, "Target which object", NULL, '\0', AO_NONE);
targob = askobject(where->obpile, "Target which object", NULL, NULL, '\0', AO_NONE);
if (!targob) {
failed = B_TRUE;
}
@ -10747,7 +10785,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// otherwise throw it there - but speed is based on
// caster's INTELLIGENCE, not strength like normal.
addflag(caster->flags, F_TKTHROW, A_IQ, SK_SS_MENTAL, NA, NULL);
fireat(caster, targob, targob->amt, targcell, power, NULL);
real_fireat(caster, targob, targob->amt, targcell, power, NULL, B_TRUE, spellid);
killflagsofid(caster->flags, F_TKTHROW);
// note that we use fireat() rather than throwat() to avoid
// calling taketime() twice.
@ -11851,7 +11889,7 @@ void fizzle(lifeform_t *caster) {
enum OBTYPE getfirstwizspell(enum SPELLSCHOOL school) {
enum OBTYPE firstspell = OT_S_MANASPIKE;
switch (school) {
case SS_AIR: firstspell = OT_S_JOLT; break;
case SS_AIR: firstspell = OT_S_PROPELMISSILE; break;
case SS_COLD: firstspell = OT_S_CHILL; break;
case SS_FIRE: firstspell = OT_S_SPARK; break;
case SS_DEATH: firstspell = OT_S_STENCH; break;
@ -12464,10 +12502,15 @@ enum SKILLLEVEL getspellskill(lifeform_t *lf, enum OBTYPE spellid) {
return slev;
}
int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power) {
int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power, int *minrange) {
objecttype_t *st;
int range = UNLIMITED;
// default
if (minrange) {
*minrange = 0;
}
// If we can _will_ this to occur then we might have a set
// range
if (lf) {
@ -12488,6 +12531,9 @@ int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power) {
f = hasflag(st->flags, F_RANGE);
if (f) {
range = f->val[0];
if (minrange && (f->val[1] != NA)) {
*minrange = f->val[1];
}
}
}
@ -13084,6 +13130,8 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e
objecttype_t *sp;
int needlos = B_TRUE;
enum LOFTYPE needlof = LOF_NEED;
int minrange = 0;
if (!caster) {
return *targcell;
@ -13105,7 +13153,7 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e
needlos = B_FALSE;
}
maxrange = getspellrange(caster, spellid, power);
maxrange = getspellrange(caster, spellid, power, &minrange);
if (*targcell) where = *targcell;
@ -13146,6 +13194,13 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e
}
where = NULL;
}
if (where && (getcelldist(caster->cell, where) < minrange)) {
// out of range
if (isplayer(caster) && !frompot) {
msg("Too close - min range is %d.",minrange); more();
}
where = NULL;
}
if (!frompot && where && where->lf && haslos(caster, where) && isplayer(caster) && areallies(caster, where->lf)) {
// warn before targetting yourself!
@ -13189,7 +13244,7 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e
snprintf(buf, BUFLEN, "Where will you target your %s [max range %d]?",sp->name, maxrange);
}
snprintf(buf2, BUFLEN, "%s->",sp->name);
where = askcoords(buf, buf2, targtype, caster, maxrange, needlof, needlof ? B_TRUE : B_FALSE);
where = real_askcoords(buf, buf2, targtype, caster, minrange, maxrange, needlof, needlof ? B_TRUE : B_FALSE, NULL, 0);
if (!where) {
char ques[BUFLEN];
int ch;

View File

@ -28,7 +28,7 @@ int getspellpowerstatmod(lifeform_t *lf, enum SPELLSCHOOL school, enum ATTRIB *a
enum SPELLSCHOOL getspellschool(enum OBTYPE spellid);
enum SPELLSCHOOL getspellschoolknown(lifeform_t *lf, enum OBTYPE spellid);
enum SKILLLEVEL getspellskill(lifeform_t *lf, enum OBTYPE spellid);
int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power);
int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power, int *minrange);
int getstamcost(lifeform_t *lf, enum OBTYPE oid);
char *getspelldesc(enum OBTYPE spellid, int power, char *buf);
int getworkablematerials(lifeform_t *lf, enum SKILL skid , enum MATERIAL *repairablemats, int *cutoffpct, int *nmats);