- [+] 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:
parent
ed98c0b735
commit
0a06d06374
18
ai.c
18
ai.c
|
@ -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;
|
||||
|
|
2
attack.c
2
attack.c
|
@ -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)) {
|
||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
17
defs.h
17
defs.h
|
@ -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
66
io.c
|
@ -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
8
io.h
|
@ -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
60
lf.c
|
@ -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
19
move.c
|
@ -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
1
move.h
|
@ -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);
|
||||
|
|
37
objects.c
37
objects.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
4
shops.c
4
shops.c
|
@ -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;
|
||||
}
|
||||
|
|
111
spell.c
111
spell.c
|
@ -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 (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 || !ismetal(targob->material->id) ) {
|
||||
|
||||
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;
|
||||
|
|
2
spell.h
2
spell.h
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue