* [+] darkmantle DARKNES isn't working! (but it does work if i cast it)
* [+] "you arrive at level 2" "it is pitch black" - but it isn't - [+] make detect magic find more things * [+] make some objects harder to identify? from easy->hard * [+] magic item usage skill - [+] with 'R', ask "heal mp, hp or both?" - [+] make dt_fire damage evaporate water. - [+] make ring of sight increase nightvis and nomal visrange slightly too - [+] FIX seeindark to give RANGE. * [+] BUG: monster moved on top of me! * [+] boost spells * [+] more boost spells - [+] modify accuracy based on size difference. * [+] ooze should hurt objects it steps on * [+] resist magic save - [+] potion of blood - [+] ability to fill a potion with blood / water - [+] better potion -> splash code. - [+] stop stoning when you polymorph - [+] can't stone incorporeal or gaseos things - [+] cockatrice blood - [+] cockatrice - [+] when being stoned, give 1 turn's grace - [+] gain/lose text for "CANWILL" - [+] things killed by poison gas should have tainted corpses - [+] make troglodyte corpses poisonous * [+] smallteeth vs teeth - [+] fix hitconfer code
This commit is contained in:
parent
cc969bb800
commit
4edc66af47
32
ai.c
32
ai.c
|
@ -618,7 +618,7 @@ void aimove(lifeform_t *lf) {
|
|||
|
||||
// need to heal?
|
||||
if ((lf->hp < lf->maxhp) ||
|
||||
((lf->mp < lf->maxmp) && lfhasflag(lf, F_RESTHEALMPAMT)) ) {
|
||||
((lf->mp < getmaxmp(lf)) && lfhasflag(lf, F_RESTHEALMPAMT)) ) {
|
||||
if (lf->hp < (lf->maxhp/2)) {
|
||||
if (!useitemwithflag(lf, F_AIHEALITEM)) {
|
||||
return;
|
||||
|
@ -700,20 +700,34 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
strcpy(why, "spell too powerful");
|
||||
} else if (reason == E_NOTREADY) {
|
||||
strcpy(why, "abil not ready");
|
||||
} else if (reason == E_NEEDGRAB) {
|
||||
strcpy(why, "needs grab");
|
||||
} else {
|
||||
strcpy(why, "unknown reason");
|
||||
}
|
||||
if (db) {
|
||||
if (ot) {
|
||||
dblog(".oO { can't cast %s right now (%s) (mpcost=%d, i have %d) }",
|
||||
ot ? ot->name : "?unkownspell?", why,
|
||||
getmpcost(ot->id), lf->mp);
|
||||
getmpcost(lf, ot->id), lf->mp);
|
||||
} else {
|
||||
dblog(".oO { can't cast ?unknownspell? right now }");
|
||||
}
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// boost spell already active?
|
||||
if (hasflag(ot->flags, F_ONGOING)) {
|
||||
if (lfhasflagval(lf, F_BOOSTSPELL, ot->id, NA, NA, NULL)) {
|
||||
if (db) {
|
||||
dblog(".oO { can't cast %s - it is already active.", ot ? ot->name : "?unkownspell?");
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
f = hasflag(ot->flags, purpose);
|
||||
if (f) {
|
||||
int range;
|
||||
|
@ -817,12 +831,26 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
if ((ot->id == OT_S_HEALINGMIN) && (lf->hp >= lf->maxhp)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_PARALYZE) && lfhasflag(victim, F_PARALYZED)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_SLEEP) && lfhasflag(victim, F_ASLEEP)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_SLOW) && lfhasflag(victim, F_SLOWACT)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_A_SPRINT) && lfhasflag(lf, F_SPRINTING)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_WEAKEN)) {
|
||||
flag_t *lff;
|
||||
for (lff = lf->flags->first; lff ; lff = lff->next) {
|
||||
if ((lff->id == F_ATTRMOD) && (lff->val[0] == A_STR) && (lff->obfrom == OT_S_WEAKEN)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return B_TRUE;
|
||||
}
|
||||
|
|
189
attack.c
189
attack.c
|
@ -103,6 +103,14 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
aidb = B_TRUE;
|
||||
}
|
||||
|
||||
moveeffects(lf);
|
||||
|
||||
if (isdead(lf)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// get names
|
||||
getlfname(lf, attackername);
|
||||
|
||||
|
@ -273,7 +281,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
if (fatal) {
|
||||
verb = getkillverb(victim, damtype[i], dam[i], victim->maxhp);
|
||||
} else {
|
||||
verb = getattackverb(damtype[i], dam[i], victim->maxhp);
|
||||
verb = getattackverb(lf, wep, damtype[i], dam[i], victim->maxhp);
|
||||
}
|
||||
warn("You %s %s%s%s",
|
||||
verb,
|
||||
|
@ -304,7 +312,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
strcpy(withwep, "");
|
||||
}
|
||||
|
||||
strcpy(attackverb, getattackverb(damtype[i],dam[i],victim->maxhp));
|
||||
strcpy(attackverb, getattackverb(lf, wep, damtype[i],dam[i],victim->maxhp));
|
||||
if ((dam[i] == 0) && (damtype[i] != DT_TOUCH)) {
|
||||
strcpy(nodamstr, " but does no damage");
|
||||
} else {
|
||||
|
@ -354,7 +362,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
} // end foreach damtype
|
||||
|
||||
// special weapon effects
|
||||
wepeffects(wep, victim->cell);
|
||||
if (dam[0]) {
|
||||
wepeffects(wep->flags, victim->cell);
|
||||
}
|
||||
|
||||
if (!isdead(victim)) {
|
||||
if (unarmedflag) {
|
||||
|
@ -404,6 +414,32 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
|
|||
}
|
||||
}
|
||||
|
||||
// confer flags from attacker?
|
||||
if (dam[0]) {
|
||||
wepeffects(lf->flags, victim->cell);
|
||||
}
|
||||
|
||||
// special lifeform-based effects
|
||||
if ((lf->race->id == R_COCKATRICE) && dam[0]) {
|
||||
// first saving throw...
|
||||
if (skillcheck(victim, SC_CON, 25, 0)) {
|
||||
// slowed
|
||||
addtempflag(victim->flags, F_SLOWMOVE, 15, NA, NA, NULL, 2);
|
||||
addtempflag(victim->flags, F_SLOWACT, 15, NA, NA, NULL, 2);
|
||||
} else {
|
||||
// second saving throw...
|
||||
if (skillcheck(victim, SC_CON, 25, 0)) {
|
||||
// paralyzed
|
||||
addtempflag(victim->flags, F_PARALYZED, B_TRUE, NA, NA, NULL, 5);
|
||||
} else {
|
||||
if (!lfhasflag(lf, F_BEINGSTONED)) {
|
||||
// stoned!
|
||||
addflag(victim->flags, F_BEINGSTONED, 2, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else { // miss!
|
||||
if (aidb) dblog(".oO { i missed! }");
|
||||
|
@ -477,6 +513,8 @@ int attackob(lifeform_t *lf, object_t *o) {
|
|||
//int aidb = B_TRUE;
|
||||
int maxhp;
|
||||
|
||||
moveeffects(lf);
|
||||
if (isdead(lf)) return B_TRUE;
|
||||
|
||||
// get names
|
||||
getlfname(lf, attackername);
|
||||
|
@ -546,7 +584,7 @@ int attackob(lifeform_t *lf, object_t *o) {
|
|||
} else {
|
||||
strcpy(extradambuf, "");
|
||||
}
|
||||
msg("You %s %s.", getattackverb(damtype[i], dam[i], maxhp),
|
||||
msg("You %s %s.", getattackverb(lf, wep, damtype[i], dam[i], maxhp),
|
||||
obname, extradambuf);
|
||||
} else if (cansee(player, lf)) {
|
||||
char withwep[BUFLEN];
|
||||
|
@ -558,7 +596,7 @@ int attackob(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
|
||||
msg("%s %ss %s%s.", attackername,
|
||||
getattackverb(damtype[i],dam[i],maxhp), obname,withwep);
|
||||
getattackverb(lf, wep, damtype[i],dam[i],maxhp), obname,withwep);
|
||||
} else {
|
||||
youhear(lf->cell, "sounds of fighting");
|
||||
}
|
||||
|
@ -579,7 +617,9 @@ int attackob(lifeform_t *lf, object_t *o) {
|
|||
} // end foreach damtype
|
||||
|
||||
// special weapon effects
|
||||
wepeffects(wep, obloc);
|
||||
if (dam[0]) {
|
||||
wepeffects(wep->flags, obloc);
|
||||
}
|
||||
|
||||
if (unarmedflag) {
|
||||
// touch effects
|
||||
|
@ -624,10 +664,27 @@ int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE d
|
|||
|
||||
|
||||
// returns a const char *
|
||||
char *getattackverb(enum DAMTYPE damtype, int dam, int maxhp) {
|
||||
char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp) {
|
||||
float pct;
|
||||
enum LFSIZE ownersize = SZ_HUMAN;
|
||||
|
||||
if (lf) {
|
||||
ownersize = getlfsize(lf);
|
||||
}
|
||||
|
||||
pct = (int)(((float) dam / (float) maxhp) * 100.0);
|
||||
if (damtype == DT_BASH) {
|
||||
|
||||
if (wep) {
|
||||
flag_t *f;
|
||||
f = hasflag(wep->flags, F_ATTACKVERB);
|
||||
if (f) {
|
||||
return f->text;
|
||||
}
|
||||
}
|
||||
|
||||
if (damtype == DT_ACID) {
|
||||
return "burn";
|
||||
} else if (damtype == DT_BASH) {
|
||||
if (pct <= 5) {
|
||||
return "whack";
|
||||
} else if (pct <= 20) {
|
||||
|
@ -640,6 +697,13 @@ char *getattackverb(enum DAMTYPE damtype, int dam, int maxhp) {
|
|||
return "pummel";
|
||||
}
|
||||
} else if (damtype == DT_BITE) {
|
||||
if (lf && (ownersize <= SZ_SMALL)) {
|
||||
if (pct <= 5) {
|
||||
return "nip";
|
||||
} else if (pct <= 30) {
|
||||
return "bite";
|
||||
}
|
||||
} else {
|
||||
if (pct <= 5) {
|
||||
return "gnaw";
|
||||
} else if (pct <= 30) {
|
||||
|
@ -647,6 +711,7 @@ char *getattackverb(enum DAMTYPE damtype, int dam, int maxhp) {
|
|||
} else {
|
||||
return "savage";
|
||||
}
|
||||
}
|
||||
} else if (damtype == DT_CLAW) {
|
||||
if (pct <= 5) {
|
||||
return "scratch";
|
||||
|
@ -1088,6 +1153,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical) {
|
|||
object_t *wep;
|
||||
obpile_t *op = NULL;
|
||||
int gothit;
|
||||
enum LFSIZE szlf,szvictim;
|
||||
|
||||
if (critical) {
|
||||
*critical = 0;
|
||||
|
@ -1100,6 +1166,19 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical) {
|
|||
ev = getevasion(victim);
|
||||
acc -= ev;
|
||||
|
||||
// size difference
|
||||
szlf = getlfsize(lf);
|
||||
szvictim = getlfsize(victim);
|
||||
if (szvictim < szlf) {
|
||||
// if defender is smaller...
|
||||
// -7% per size difference
|
||||
acc -= (7 * (szlf - szvictim));
|
||||
} else if (szvictim > szlf) {
|
||||
// if defender is bigger...
|
||||
// +7% per size difference
|
||||
acc += (7 * (szvictim - szlf));
|
||||
}
|
||||
|
||||
// modify if we can't see the victim
|
||||
if (!cansee(lf, victim)) {
|
||||
acc -= 50;
|
||||
|
@ -1134,16 +1213,19 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical) {
|
|||
return gothit;
|
||||
}
|
||||
|
||||
void wepeffects(object_t *wep, cell_t *where) {
|
||||
void wepeffects(flagpile_t *fp, cell_t *where) {
|
||||
flag_t *f;
|
||||
lifeform_t *victim;
|
||||
lifeform_t *owner;
|
||||
|
||||
owner = wep->pile->owner;
|
||||
victim = where->lf;
|
||||
object_t *wep;
|
||||
|
||||
if (!where) return;
|
||||
for (f = wep->flags->first ; f ; f = f->next) {
|
||||
|
||||
wep = fp->ob;
|
||||
owner = fp->owner;
|
||||
victim = where->lf;
|
||||
|
||||
for (f = fp->first ; f ; f = f->next) {
|
||||
if (f->id == F_FLAMESTRIKE) {
|
||||
if (!hasob(where->obpile, OT_FIRESMALL)) {
|
||||
// ignite!
|
||||
|
@ -1154,36 +1236,6 @@ void wepeffects(object_t *wep, cell_t *where) {
|
|||
f->known = B_KNOWN;
|
||||
}
|
||||
}
|
||||
} else if ((f->id == F_HITCONFER) && victim && !isdead(victim)) {
|
||||
enum FLAG fid;
|
||||
int val0,val1;
|
||||
int min,max,howlong;
|
||||
fid = f->val[0];
|
||||
if (!lfhasflag(victim, fid)) {
|
||||
val0 = f->val[1];
|
||||
val1 = f->val[2];
|
||||
if (f->text) {
|
||||
char loctext[BUFLEN];
|
||||
char *word, *dummy;
|
||||
strcpy(loctext,f->text);
|
||||
word = strtok_r(loctext, "-", &dummy);
|
||||
if (word) {
|
||||
min = atoi(word);
|
||||
word = strtok_r(NULL, "-", &dummy);
|
||||
if (word) {
|
||||
max = atoi(word);
|
||||
howlong = rnd(min,max);
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
addtempflag(victim->flags, fid, val0, val1, NA, NULL, howlong);
|
||||
}
|
||||
} else if ((f->id == F_REVENGE) && victim && !isdead(victim)) {
|
||||
lifeform_t *owner;
|
||||
owner = wep->pile->owner;
|
||||
|
@ -1230,6 +1282,57 @@ void wepeffects(object_t *wep, cell_t *where) {
|
|||
dir = getdirtowards(owner->cell, victim->cell, victim, B_FALSE);
|
||||
knockback(victim, dir , 2, owner);
|
||||
f->known = B_TRUE;
|
||||
} else if ((f->id == F_HITCONFER) && victim ) {
|
||||
enum FLAG fid;
|
||||
int min,max,howlong;
|
||||
fid = f->val[0];
|
||||
if (!lfhasflag(victim, fid)) {
|
||||
int passedcheck = B_FALSE;
|
||||
if (!f->val[1] == NA) {
|
||||
int scdiff;
|
||||
if (f->val[2] == NA) {
|
||||
scdiff = 20; // default
|
||||
} else {
|
||||
scdiff = f->val[2];
|
||||
}
|
||||
if (skillcheck(victim, f->val[1], scdiff, 0)) {
|
||||
passedcheck = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!passedcheck) {
|
||||
int val0;
|
||||
val0 = f->val[1];
|
||||
if (f->text) {
|
||||
char loctext[BUFLEN];
|
||||
char *word, *dummy;
|
||||
strcpy(loctext,f->text);
|
||||
word = strtok_r(loctext, "-", &dummy);
|
||||
if (word) {
|
||||
min = atoi(word);
|
||||
word = strtok_r(NULL, "-", &dummy);
|
||||
if (word) {
|
||||
max = atoi(word);
|
||||
howlong = rnd(min,max);
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
} else {
|
||||
howlong = PERMENANT;
|
||||
}
|
||||
|
||||
addtempflag(victim->flags, fid, val0, NA, NA, NULL, howlong);
|
||||
} // end if passedcheck
|
||||
} // end (if victim doesn't already have the flag)
|
||||
|
||||
// was this from a poisoned weapon? if so the poison vanishes
|
||||
if ((f->val[0] == F_POISONED) && (f->lifetime == FROMOBMOD)) {
|
||||
killflag(f);
|
||||
}
|
||||
} // end if (fid == hitconfer)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
5
attack.h
5
attack.h
|
@ -5,8 +5,9 @@ void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *
|
|||
int attackcell(lifeform_t *lf, cell_t *c);
|
||||
int attacklf(lifeform_t *lf, lifeform_t *victim);
|
||||
int attackob(lifeform_t *lf, object_t *o);
|
||||
void confereffects(flagpile_t *fp, lifeform_t *victim);
|
||||
int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype);
|
||||
char *getattackverb(enum DAMTYPE damtype, int dam, int maxhp);
|
||||
char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam, int maxhp);
|
||||
object_t *getattackwep(lifeform_t *lf, obpile_t **unarmedpile, flag_t **unarmedflag);
|
||||
enum DAMTYPE getdamtype(object_t *wep);
|
||||
int getextradam(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam);
|
||||
|
@ -19,4 +20,4 @@ int getdamrollfromflag(flag_t *f);
|
|||
float getstrdammod(lifeform_t *lf);
|
||||
obpile_t *getunarmedweapon(lifeform_t *lf, flag_t **uflag);
|
||||
int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical);
|
||||
void wepeffects(object_t *wep, cell_t *where);
|
||||
void wepeffects(flagpile_t *fp, cell_t *where);
|
||||
|
|
82
defs.h
82
defs.h
|
@ -45,6 +45,9 @@ enum CHECKTYPE {
|
|||
SC_SLIP,
|
||||
SC_MORALE,
|
||||
SC_OPENLOCKS,
|
||||
SC_POISON,
|
||||
SC_RESISTMAG,
|
||||
SC_WILL,
|
||||
};
|
||||
|
||||
enum BURDENED {
|
||||
|
@ -86,6 +89,7 @@ enum LFCONDITION {
|
|||
#define FROMBLESSING (-9866)
|
||||
#define FROMBRAND (-9865)
|
||||
#define FROMOBMOD (-9864)
|
||||
#define FROMSPELL (-9863)
|
||||
|
||||
|
||||
#define IFKNOWN (-9772) // used by f_xxconfer. only confer a flag if item is known.
|
||||
|
@ -367,9 +371,11 @@ enum DAMTYPE {
|
|||
DT_LIGHT = 21,
|
||||
DT_CRUSH = 22,
|
||||
DT_FALL = 23,
|
||||
DT_NONE = 24, // for direclty dealt damage, not really any type
|
||||
DT_PETRIFY = 24,
|
||||
DT_POISON = 25,
|
||||
DT_NONE = 26, // for direclty dealt damage, not really any type
|
||||
};
|
||||
#define MAXDAMTYPE 25
|
||||
#define MAXDAMTYPE 27
|
||||
|
||||
// Object Classes
|
||||
enum OBCLASS {
|
||||
|
@ -423,7 +429,9 @@ enum RACE {
|
|||
R_NONE, R_RANDOM,
|
||||
R_HUMAN,
|
||||
// monsters
|
||||
R_BEHOLDER,
|
||||
R_BUGBEAR,
|
||||
R_COCKATRICE,
|
||||
R_DARKMANTLE,
|
||||
R_EYEBAT,
|
||||
R_GIANTHILL,
|
||||
|
@ -456,9 +464,13 @@ enum RACE {
|
|||
R_TROLL,
|
||||
R_XAT,
|
||||
// small animals
|
||||
R_ANT,
|
||||
R_ANTS,
|
||||
R_BAT,
|
||||
R_HAWK,
|
||||
R_NEWT,
|
||||
R_RAT,
|
||||
R_SNAKE,
|
||||
R_WOLF,
|
||||
// insects
|
||||
R_BUTTERFLY,
|
||||
|
@ -518,6 +530,7 @@ enum MATERIAL {
|
|||
MT_GAS = 20,
|
||||
MT_SLIME = 21,
|
||||
MT_WAX = 22,
|
||||
MT_ACID = 23,
|
||||
};
|
||||
|
||||
// Object Types
|
||||
|
@ -572,6 +585,8 @@ enum OBTYPE {
|
|||
OT_POT_ACID,
|
||||
OT_POT_ACROBATICS,
|
||||
OT_POT_AMBROSIA,
|
||||
OT_POT_BLOOD,
|
||||
OT_POT_BLOODC,
|
||||
OT_POT_COMPETENCE,
|
||||
OT_POT_ELEMENTENDURE,
|
||||
OT_POT_ELEMENTIMMUNE,
|
||||
|
@ -614,8 +629,10 @@ enum OBTYPE {
|
|||
OT_MAN_ATHLETICS,
|
||||
OT_MAN_FIRSTAID,
|
||||
OT_MAN_LOCKPICKING,
|
||||
OT_MAN_MAGITEMUSAGE,
|
||||
OT_MAN_RESEARCH,
|
||||
OT_MAN_SPELLCASTING,
|
||||
OT_MAN_TECHUSAGE,
|
||||
// manuals of weaponry
|
||||
OT_MAN_AXES,
|
||||
OT_MAN_CLUBS,
|
||||
|
@ -638,12 +655,12 @@ enum OBTYPE {
|
|||
OT_MAN_SS_SUMMONING,
|
||||
OT_MAN_SS_TRANSLOCATION,
|
||||
OT_MAN_SS_WILD,
|
||||
OT_MAN_TECHUSAGE,
|
||||
// SPELLBOOKS
|
||||
// allomancy can't be learned from books
|
||||
// -- death
|
||||
OT_SB_ANIMATEDEAD,
|
||||
OT_SB_PAIN,
|
||||
OT_SB_PARALYZE,
|
||||
OT_SB_INFINITEDEATH,
|
||||
OT_SB_WEAKEN,
|
||||
OT_SB_BLINDNESS,
|
||||
|
@ -653,6 +670,7 @@ enum OBTYPE {
|
|||
OT_SB_IDENTIFY,
|
||||
OT_SB_MAPPING,
|
||||
// -- elemental - air
|
||||
OT_SB_AIRBLAST,
|
||||
OT_SB_CLOUDKILL,
|
||||
// -- elemental - fire
|
||||
OT_SB_SPARK,
|
||||
|
@ -665,16 +683,20 @@ enum OBTYPE {
|
|||
OT_SB_CONECOLD,
|
||||
OT_SB_FREEZEOB,
|
||||
// -- gravity
|
||||
OT_SB_GRAVLOWER,
|
||||
OT_SB_GRAVBOOST,
|
||||
OT_SB_HASTE,
|
||||
OT_SB_FLIGHT,
|
||||
OT_SB_SLOW,
|
||||
OT_SB_LEVITATION,
|
||||
// -- life
|
||||
OT_SB_HEALING,
|
||||
OT_SB_HEALINGMIN,
|
||||
OT_SB_TURNUNDEAD,
|
||||
// -- mental
|
||||
// -- mental / psionic
|
||||
OT_SB_MINDSCAN,
|
||||
OT_SB_TELEKINESIS,
|
||||
OT_SB_PSYARMOUR,
|
||||
// -- modification
|
||||
OT_SB_GASEOUSFORM,
|
||||
OT_SB_KNOCK,
|
||||
|
@ -705,6 +727,7 @@ enum OBTYPE {
|
|||
// -- death
|
||||
OT_S_ANIMATEDEAD,
|
||||
OT_S_PAIN,
|
||||
OT_S_PARALYZE,
|
||||
OT_S_INFINITEDEATH,
|
||||
OT_S_WEAKEN,
|
||||
OT_S_BLINDNESS,
|
||||
|
@ -715,6 +738,7 @@ enum OBTYPE {
|
|||
OT_S_IDENTIFY,
|
||||
OT_S_MAPPING,
|
||||
// -- elemental - air
|
||||
OT_S_AIRBLAST,
|
||||
OT_S_CLOUDKILL,
|
||||
// -- elemental - fire
|
||||
OT_S_SPARK,
|
||||
|
@ -727,17 +751,21 @@ enum OBTYPE {
|
|||
OT_S_CONECOLD,
|
||||
OT_S_FREEZEOB,
|
||||
// -- gravity
|
||||
OT_S_GRAVLOWER,
|
||||
OT_S_GRAVBOOST,
|
||||
OT_S_HASTE,
|
||||
OT_S_SLOW,
|
||||
OT_S_LEVITATION,
|
||||
OT_S_FLIGHT,
|
||||
// -- life
|
||||
OT_S_HEALING,
|
||||
OT_S_HEALINGMIN,
|
||||
OT_S_TURNUNDEAD,
|
||||
// -- mental
|
||||
// -- mental / psionic
|
||||
OT_S_MINDSCAN,
|
||||
OT_S_SLEEP,
|
||||
OT_S_TELEKINESIS,
|
||||
OT_S_PSYARMOUR,
|
||||
// -- modification
|
||||
OT_S_ENCHANT,
|
||||
OT_S_GASEOUSFORM,
|
||||
|
@ -776,6 +804,7 @@ enum OBTYPE {
|
|||
OT_A_EMPLOY,
|
||||
OT_A_HEAVYBLOW,
|
||||
OT_A_INSPECT,
|
||||
OT_A_STINGACID, // need to define dam in f_canwill
|
||||
// wands
|
||||
OT_WAND_COLD,
|
||||
OT_WAND_DETONATION,
|
||||
|
@ -826,11 +855,14 @@ enum OBTYPE {
|
|||
OT_ICESHEET,
|
||||
OT_PUDDLEWATER,
|
||||
OT_PUDDLEWATERL,
|
||||
OT_ACIDPUDDLE,
|
||||
OT_ACIDPOOL,
|
||||
OT_SLIMEPOOL,
|
||||
OT_VOMITPOOL,
|
||||
OT_BLOODSTAIN,
|
||||
OT_BLOODSPLASH,
|
||||
OT_BLOODPOOL,
|
||||
OT_BLOODCSPLASH,
|
||||
OT_MELTEDWAX,
|
||||
OT_SOGGYPAPER,
|
||||
OT_FLESHCHUNK,
|
||||
|
@ -839,6 +871,8 @@ enum OBTYPE {
|
|||
OT_FIREMED,
|
||||
OT_FIRESMALL,
|
||||
OT_MAGICBARRIER,
|
||||
OT_STEAMCLOUD,
|
||||
OT_STEAMPUFF,
|
||||
OT_SMOKECLOUD,
|
||||
OT_SMOKEPUFF,
|
||||
OT_POISONCLOUD,
|
||||
|
@ -899,8 +933,10 @@ enum OBTYPE {
|
|||
// animal weapons
|
||||
OT_CLAWS,
|
||||
OT_FISTS,
|
||||
OT_STING,
|
||||
OT_TAIL,
|
||||
OT_TEETH,
|
||||
OT_TEETHSM,
|
||||
OT_TENTACLE,
|
||||
OT_ZAPPER,
|
||||
// monster weapons
|
||||
|
@ -1052,8 +1088,7 @@ enum FLAG {
|
|||
F_ACTIVATECONFER, // gives flag v0+v1 when activated. v2 specifies if it must be id'd.
|
||||
|
||||
F_HITCONFER, // hitting with this gives flagid=v0
|
||||
// with flagval0 = val1
|
||||
// with flagval1 = val2
|
||||
// unless you pass a val1 skillcheck, diff val2
|
||||
// with timeleft = text ("min-max")
|
||||
F_ACTIVATED, // val0 = is this object turned on?
|
||||
F_GRENADE, // this obkejct will drain charge when activated, then die
|
||||
|
@ -1114,8 +1149,10 @@ enum FLAG {
|
|||
F_MASTERWORK, // weps do higher damager, armour protects better
|
||||
F_SHODDY, // weps do less damage, armour protects less.
|
||||
// weapon flags
|
||||
F_ATTACKVERB, // text=verb for attacking. ie. "hit" "slash" "sting" etc
|
||||
F_OBATTACKDELAY, // how long weapon takes to attack
|
||||
F_USESSKILL, // weapon needs skill sk_v0
|
||||
F_CANHAVEOBMOD, // weapon can have obmod om_v0 applied
|
||||
F_DAMTYPE, // val0 = damage type
|
||||
F_DAM, // val0 = ndice, val1 = nsidesondie, val2 = mod
|
||||
F_MISSILEDAM, // val0 = dam if it hits (without speed multiplier)
|
||||
|
@ -1149,6 +1186,8 @@ enum FLAG {
|
|||
F_NOOBDAMTEXT, // don't anounce damage to this object
|
||||
F_NOOBDIETEXT, // don't anounce destruction of this object
|
||||
F_NODIECONVERTTEXT, // don't anounce when this object changes
|
||||
// misc flags
|
||||
F_LINKOB, // val0 = linked object id
|
||||
// scroll flags
|
||||
F_LINKSPELL, // val0 = spell this scroll will cast when read
|
||||
// v1 = spell power
|
||||
|
@ -1158,12 +1197,15 @@ enum FLAG {
|
|||
F_HASHIDDENNAME, // whether this object class has a hidden name
|
||||
F_IDENTIFIED, // whether this object is fully identified
|
||||
// bad flags
|
||||
F_WALKDAM, // val0 = dam per sec, val1 = damtype
|
||||
F_WALKDAM, // val0 = damtype, text = dam per sec
|
||||
// abilities
|
||||
F_NEEDSGRAB, // this ability needs to to grab someone first.
|
||||
// magic
|
||||
F_SPELLSCHOOL, // val0 = SPELLSCHOOL enum
|
||||
F_SPELLLEVEL, // val0 = difficulty level of spell
|
||||
F_MAXPOWER, // val0 = max power of this spell (1-10)
|
||||
F_MPCOST, // v0=mp cost of spell. if missing, mpcost if splev^2
|
||||
F_ONGOING, // this spell has an ongoing cost
|
||||
//F_SPELLLETTER, // text[0] = letter to cast this spell
|
||||
F_AICASTTOFLEE, // AI can cast this spell to help flee
|
||||
// v0 is who to target
|
||||
|
@ -1205,8 +1247,9 @@ enum FLAG {
|
|||
F_GUNTARGET, // current projectile weapon target
|
||||
F_CASTINGSPELL, // set while the player is casting a spell
|
||||
// v0 is spell id
|
||||
// ABILITY FLAGS
|
||||
// ABILITY/SPELL FLAGS
|
||||
F_FAILEDINSPECT, // lf has failed an inspect check for item id v0
|
||||
F_BOOSTSPELL, // v0 is active boost spell
|
||||
// MONSTER AI FLAGS
|
||||
F_XPVAL, // force xp val for killing this lf to v0
|
||||
F_HOSTILE, // lf will attack the player if in sight
|
||||
|
@ -1260,6 +1303,7 @@ enum FLAG {
|
|||
F_NOPACK, // this race cannot hold objects
|
||||
F_NOSPELLS, // this race cannot cast spells
|
||||
F_INDUCEFEAR, // causes fear when you attack it
|
||||
F_POISONOUS, // lf's corpse will be poisonous
|
||||
F_AUTOCREATEOB, // produces obtype 'text' wherever it walks, v0=radius
|
||||
// (only if ob of that type not already there)
|
||||
F_PACKATTACK, // deal v0 extra damage of type v1 if there are
|
||||
|
@ -1267,13 +1311,17 @@ enum FLAG {
|
|||
// to the victim
|
||||
F_PHALANX, // gain v0 AR if v2 or more adj monsters matching f->text
|
||||
// INTRINSICS
|
||||
F_ARBOOST,// armour is magically boosted
|
||||
F_ASLEEP, // is asleep
|
||||
F_BEINGSTONED,// turn to stone when v0 drops to zero. (drops 1/turn)
|
||||
F_BLIND, // cannot see anything
|
||||
F_CANCAST, // can cast the spell val0 (need MP)
|
||||
F_CANWILL, // can cast the spell val0 without using MP
|
||||
// v1 is counter untiluse
|
||||
// v2 is what you need to use it
|
||||
// ie. when v1 == v2, ability is ready.
|
||||
// text is other options, semicolon seperated:
|
||||
// pw:xx; cast the spell at power xx
|
||||
F_DETECTAURAS, // autodetect bless/curse
|
||||
F_DETECTLIFE, // autodetect nearby lifeforms in orthogonal dist v0
|
||||
F_DETECTMAGIC, // autodetect magic/special objects
|
||||
|
@ -1282,7 +1330,7 @@ enum FLAG {
|
|||
F_FLYING, // lf is flying
|
||||
F_FASTACT, // modifier for action speed
|
||||
F_FASTMOVE, // modifier for move speed
|
||||
F_FOODPOISONED, // has food poisoning
|
||||
F_POISONED, // has food poisoning
|
||||
F_FREEZINGTOUCH,// next thing touched turns to ice!
|
||||
F_GRABBEDBY,// you've been grabbed by lf id v0
|
||||
F_GRABBING, // you are grabbing lf id v0
|
||||
|
@ -1292,7 +1340,7 @@ enum FLAG {
|
|||
F_QUICKBITE, // deals v0 d d1 + d2 damage when you hit a bleeding victim
|
||||
// (bypasses armour)
|
||||
F_GRAVBOOSTED,// cannot walk or throw stuff
|
||||
F_PAIN, // take damage if you walk
|
||||
F_PAIN, // take damage if you walk. v0=damtype,text is damage (xdy+z).
|
||||
F_PARALYZED,// cannot do anything
|
||||
F_FROZEN, // made of ice
|
||||
F_LEVITATING, // like flying but uncontrolled
|
||||
|
@ -1302,7 +1350,7 @@ enum FLAG {
|
|||
F_OMNIPOTENT, // knows extra info
|
||||
F_PHOTOMEM, // you don't forget your surroundings
|
||||
F_REGENERATES, // regenerate HP at val0 per turn
|
||||
F_RESISTMAG, // immune to most magic effects
|
||||
F_RESISTMAG, // immunity to magic effects. v0=amt (1-20)
|
||||
F_MPREGEN, // regenerate MP at val0 per turn
|
||||
F_SEEINDARK, // nightvis range is val0
|
||||
F_SEEINVIS, // can see invisible things
|
||||
|
@ -1329,12 +1377,14 @@ enum FLAG {
|
|||
// damage (x y-sided dice + z)
|
||||
F_EVASION, // % chance of evading an attack
|
||||
|
||||
// healing
|
||||
// healing/resting/training
|
||||
F_STATGAINREADY, // ready to increase str/int etc. v2 is how many times
|
||||
// we can do it.
|
||||
F_RESTING, // are we resting? cleared on any action other than rest.
|
||||
// v2 = if not, NA it is the training counter.
|
||||
// when it hits 0, you finish trainign.
|
||||
F_RESTUNTILHP, // resting until we have full hp
|
||||
F_RESTUNTILMP, // resting until we have full mp
|
||||
//
|
||||
F_RUNNING, // are we running?
|
||||
// nutrition
|
||||
|
@ -1476,6 +1526,7 @@ enum ERROR {
|
|||
E_CANTMOVE = 34,
|
||||
E_NOTKNOWN = 35,
|
||||
E_TOOPOWERFUL = 36,
|
||||
E_NEEDGRAB = 37,
|
||||
};
|
||||
|
||||
|
||||
|
@ -1547,6 +1598,7 @@ typedef struct cell_s {
|
|||
struct obpile_s *obpile;
|
||||
enum LIGHTLEV lit;
|
||||
enum LIGHTLEV origlit;
|
||||
int origlittimer;
|
||||
int littimer;
|
||||
|
||||
char *writing;
|
||||
|
@ -1680,8 +1732,10 @@ enum SKILL {
|
|||
SK_ATHLETICS,
|
||||
SK_FIRSTAID,
|
||||
SK_LOCKPICKING,
|
||||
SK_MAGITEMUSAGE,
|
||||
SK_RESEARCH,
|
||||
SK_SPELLCASTING,
|
||||
SK_TECHUSAGE,
|
||||
// weaponry
|
||||
SK_AXES,
|
||||
SK_CLUBS,
|
||||
|
@ -1704,7 +1758,6 @@ enum SKILL {
|
|||
SK_SS_SUMMONING,
|
||||
SK_SS_TRANSLOCATION,
|
||||
SK_SS_WILD,
|
||||
SK_TECHUSAGE,
|
||||
};
|
||||
#define MAXSKILLS 31
|
||||
|
||||
|
@ -1794,6 +1847,7 @@ enum OBMOD {
|
|||
OM_FROZEN,
|
||||
OM_HEADLESS,
|
||||
OM_MASTERWORK,
|
||||
OM_POISONED,
|
||||
OM_SHODDY,
|
||||
};
|
||||
#define MAXOBMODS 4
|
||||
|
|
|
@ -5,7 +5,8 @@ objects.c:
|
|||
add an addmaterial() line
|
||||
update adjustdammaterial() as required
|
||||
update getmaterialvalue()
|
||||
update issolidmat()
|
||||
update getmaterialstate()
|
||||
update ismetal()
|
||||
update willshatter()
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
defs.h:
|
||||
add the OT_xxx enum
|
||||
(optional) add a scroll to do the same effect
|
||||
(optional) add a potion to do the same effect
|
||||
(optional) add a scroll to do the same effect - not for boosts though
|
||||
(optional) add a potion to do the same effect - not for boosts though
|
||||
|
||||
objects.c:
|
||||
define the spell
|
||||
remember to have spelllevle
|
||||
remember to have spelllevel
|
||||
(optional) add a scroll to do the same effect, use F_LINKSPELL
|
||||
(optional) add a potion to do the same effect
|
||||
(optional) add a spellbook to learn it
|
||||
|
@ -22,4 +22,5 @@ spell.c:
|
|||
ai.c
|
||||
update aigetspelltarget();
|
||||
update aigetattackspell();
|
||||
update aispellok();
|
||||
|
||||
|
|
40
flag.c
40
flag.c
|
@ -6,6 +6,7 @@
|
|||
#include "io.h"
|
||||
#include "lf.h"
|
||||
#include "objects.h"
|
||||
#include "spell.h"
|
||||
#include "text.h"
|
||||
|
||||
extern enum GAMEMODE gamemode;
|
||||
|
@ -31,6 +32,10 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
known = B_KNOWN;
|
||||
}
|
||||
|
||||
if ((id == F_POISONED) && isimmuneto(fp, DT_POISON)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// certain flags stack...
|
||||
if (flagstacks(id)) {
|
||||
f = hasflag(fp, id);
|
||||
|
@ -151,6 +156,20 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3,
|
|||
}
|
||||
}
|
||||
|
||||
// special effects
|
||||
if (f->pile->owner) {
|
||||
switch (f->id) {
|
||||
case F_ASLEEP:
|
||||
stopallspells(f->pile->owner);
|
||||
break;
|
||||
case F_NONCORPOREAL:
|
||||
killflagsofid(f->pile->owner->flags, F_BEINGSTONED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((gamemode == GM_GAMESTARTED) && doredraw) {
|
||||
statdirty = B_TRUE;
|
||||
needredraw = B_TRUE;
|
||||
|
@ -192,20 +211,20 @@ int flagstacks(enum FLAG fid) {
|
|||
}
|
||||
|
||||
flag_t *hasflag(flagpile_t *fp, int id) {
|
||||
return hasflag_real(fp, id, NA);
|
||||
return hasflag_real(fp, id, NA, NULL);
|
||||
}
|
||||
|
||||
flag_t *hasflagknown(flagpile_t *fp, int id) {
|
||||
return hasflag_real(fp, id, B_TRUE);
|
||||
return hasflag_real(fp, id, B_TRUE, NULL);
|
||||
}
|
||||
|
||||
flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown) {
|
||||
flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception) {
|
||||
flag_t *f;
|
||||
lifeform_t *owner;
|
||||
owner = fp->owner;
|
||||
|
||||
for (f = fp->first ; f ; f = f->next) {
|
||||
if (f->id == id) {
|
||||
if ((f->id == id) && (f != exception)) {
|
||||
int valid = B_TRUE;
|
||||
if ((wantknown != NA) && (f->known != wantknown)) valid = B_FALSE;
|
||||
if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) {
|
||||
|
@ -453,6 +472,19 @@ void timeeffectsflag(flag_t *f) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (f->id == F_BEINGSTONED) {
|
||||
f->val[0]--;
|
||||
if (f->val[0] == 0) {
|
||||
if (!stone(f->pile->owner)) {
|
||||
// lf turned to stone!
|
||||
return;
|
||||
} else {
|
||||
// stoning failed. stop being stoned.
|
||||
killflag(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2) {
|
||||
|
|
2
flag.h
2
flag.h
|
@ -10,7 +10,7 @@ void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
|
|||
int flagstacks(enum FLAG fid);
|
||||
flag_t *hasflag(flagpile_t *fp, int id);
|
||||
flag_t *hasflagknown(flagpile_t *fp, int id);
|
||||
flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown);
|
||||
flag_t *hasflag_real(flagpile_t *fp, int id, int wantknown, flag_t *exception);
|
||||
flag_t *hasflagval(flagpile_t *fp, int id, int val1, int val2, int val3, char *text);
|
||||
flag_t *hasflagvalknown(flagpile_t *fp, int id, int val1, int val2, int val3, char *text);
|
||||
flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown);
|
||||
|
|
285
io.c
285
io.c
|
@ -664,10 +664,18 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_ARBOOST:
|
||||
msg("A magical shield appears around %s!",lfname);
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_ASLEEP:
|
||||
msg("%s fall%s asleep.",lfname, isplayer(lf) ? "" : "s");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_BEINGSTONED:
|
||||
msg("%s begin%s to turn to stone!",lfname, isplayer(lf) ? "" : "s");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_BLIND:
|
||||
if (isplayer(lf)) {
|
||||
msg("%s cannot see!",lfname);
|
||||
|
@ -685,6 +693,15 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case F_CANWILL:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
objecttype_t *ot;
|
||||
ot = findot(f->val[0]);
|
||||
if (ot) {
|
||||
msg("You have learned the ability '%s'.", ot->name);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case F_DTIMMUNE:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You feel immune to %s!", getdamnamenoun(f->val[0]));
|
||||
|
@ -703,18 +720,6 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_CANWILL:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
switch (f->val[0]) {
|
||||
case OT_A_JUMP:
|
||||
msg("You feel like you could leap a tall building in a single bound!");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case F_DETECTAURAS:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You feel aware of spiritual auras around you.");
|
||||
|
@ -777,7 +782,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
cansee(player, lf2) ? buf : "something");
|
||||
}
|
||||
break;
|
||||
case F_FOODPOISONED:
|
||||
case F_POISONED:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You feel very sick.");
|
||||
donesomething = B_TRUE;
|
||||
|
@ -862,7 +867,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
break;
|
||||
case F_RESISTMAG:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You feel immune to magic.");
|
||||
msg("You feel %simmune to magic.", hasflag_real(lf->flags, F_RESISTMAG, NA, f) ? "more " : "");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -993,16 +998,24 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_ARBOOST:
|
||||
msg("%s%s magical shield vanishes.",lfname,getpossessive(lfname));
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_ASLEEP:
|
||||
msg("%s wake%s up.",lfname, isplayer(lf) ? "" : "s");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_BEINGSTONED:
|
||||
msg("The fragments of stone around %s%s body drop%s away.",lfname, getpossessive(lfname), isplayer(lf) ? "" : "s");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_BLIND:
|
||||
msg("%s can see again.",lfname);
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_CANCAST:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
objecttype_t *ot;
|
||||
ot = findot(f->val[0]);
|
||||
if (ot) {
|
||||
|
@ -1011,6 +1024,16 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case F_CANWILL:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
objecttype_t *ot;
|
||||
ot = findot(f->val[0]);
|
||||
if (ot) {
|
||||
msg("You can no longer use the ability '%s'.", ot->name);
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case F_DTIMMUNE:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("You are no longer immune to %s.", getdamnamenoun(f->val[0]));
|
||||
|
@ -1041,24 +1064,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s stop%s fleeing.", lfname, isplayer(lf) ? "" : "s");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FOODPOISONED:
|
||||
case F_POISONED:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("You feel less sick now.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_CANWILL:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
switch (f->val[0]) {
|
||||
case OT_A_JUMP:
|
||||
msg("You no longer feel so good at jumping.");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case F_DODGES:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("You can no longer dodge attacks.");
|
||||
|
@ -1154,8 +1165,10 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_PAIN:
|
||||
msg("%s skin returns to normal.",lfname, getpossessive(lfname));
|
||||
if (isplayer(lf)) { // don't konw if it expires for monsters
|
||||
msg("Your skin stops hurting.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_PARALYZED:
|
||||
if (isplayer(lf)) { // don't konw if it expires for monsters
|
||||
|
@ -1181,7 +1194,11 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
break;
|
||||
case F_RESISTMAG:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
if (hasflag_real(lf->flags, F_RESISTMAG, NA, f)) {
|
||||
msg("You feel less immune to magic.");
|
||||
} else {
|
||||
msg("You are no longer immune to magic.");
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -2217,6 +2234,13 @@ void describeob(object_t *o) {
|
|||
y++;
|
||||
}
|
||||
|
||||
for (f = o->flags->first ; f ; f = f->next) {
|
||||
if ((f->id == F_HITCONFER) && (f->val[0] == F_POISONED) && (f->lifetime == FROMOBMOD)) {
|
||||
mvwprintw(mainwin, y, 0, "It has been coated with poison.");
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now special flags...
|
||||
y++;
|
||||
|
@ -2373,7 +2397,8 @@ void describeob(object_t *o) {
|
|||
mvwprintw(mainwin, y, 0, "%s allows you to regenerate health%s.", buf,buf2); y++;
|
||||
break;
|
||||
case F_RESISTMAG:
|
||||
mvwprintw(mainwin, y, 0, "%s grants you immunity from magic.", buf); y++;
|
||||
mvwprintw(mainwin, y, 0, "%s grants you %s immunity to magic.", buf,
|
||||
(f->val[0] >= 10) ? "strong" : "minor"); y++;
|
||||
break;
|
||||
case F_SEEINVIS:
|
||||
mvwprintw(mainwin, y, 0, "%s allows you to see invisible things.", buf); y++;
|
||||
|
@ -2424,6 +2449,14 @@ void describeob(object_t *o) {
|
|||
}
|
||||
|
||||
y++;
|
||||
|
||||
// skill type?
|
||||
f = hasflag(o->flags, F_USESSKILL);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It falls into the '%s' category of weapons.",getskillname(f->val[0]));
|
||||
y++;
|
||||
}
|
||||
|
||||
if (hasflag(o->flags, F_NOBLESS)) {
|
||||
mvwprintw(mainwin, y, 0, "%s cannot be blessed or cursed.", (o->amt == 1) ? "It" : "They" );
|
||||
y++;
|
||||
|
@ -2484,9 +2517,13 @@ void describespell(objecttype_t *ot) {
|
|||
y++;
|
||||
}
|
||||
|
||||
i = getmpcost(ot->id);
|
||||
i = getmpcost(NULL, ot->id);
|
||||
if (i > 0) {
|
||||
if (hasflag(ot->flags, F_ONGOING)) {
|
||||
mvwprintw(mainwin, y, 0, "It takes %d MP to keep active - this is an ongoing cost.",i);
|
||||
} else {
|
||||
mvwprintw(mainwin, y, 0, "It costs %d MP to cast.",i);
|
||||
}
|
||||
y++;
|
||||
}
|
||||
|
||||
|
@ -2983,6 +3020,7 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2)
|
|||
int mpcost[MAXCANDIDATES];
|
||||
char mpdesc[MAXCANDIDATES][BUFLEN];
|
||||
int validspell[MAXCANDIDATES];
|
||||
int deactspell[MAXCANDIDATES];
|
||||
int nposs = 0;
|
||||
int i,n;
|
||||
enum SPELLSCHOOL lastschool;
|
||||
|
@ -2997,6 +3035,7 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2)
|
|||
if (f) {
|
||||
if (hasflagval(ot->flags, F_SPELLSCHOOL, i, NA, NA, NULL)) {
|
||||
poss[nposs] = ot->id;
|
||||
deactspell[nposs] = B_FALSE; // default
|
||||
mpcost[nposs] = -1;
|
||||
if (f->val[2] == NA) {
|
||||
sprintf(mpdesc[nposs], "(ready)");
|
||||
|
@ -3028,7 +3067,7 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2)
|
|||
if (lfhasflagval(lf, F_CANCAST, ot->id, NA, NA, NULL)) {
|
||||
int cost;
|
||||
int found = B_FALSE;
|
||||
cost = getmpcost(ot->id);
|
||||
cost = getmpcost(lf, ot->id);
|
||||
for (n = 0; n < nposs; n++) {
|
||||
if (poss[n] == ot->id) {
|
||||
found = B_TRUE;
|
||||
|
@ -3040,10 +3079,22 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2)
|
|||
// add to list
|
||||
poss[nposs] = ot->id;
|
||||
mpcost[nposs] = cost;
|
||||
deactspell[nposs] = B_FALSE; // default
|
||||
power = getspellpower(lf, ot->id);
|
||||
if (power > 0) {
|
||||
sprintf(mpdesc[nposs], "(%d MP)", mpcost[nposs]);
|
||||
if (lf->mp >= cost) {
|
||||
|
||||
if (lfhasflagval(lf, F_BOOSTSPELL, ot->id, NA, NA, NULL)) {
|
||||
cost = 0;
|
||||
mpcost[nposs] = 0;
|
||||
strcpy(mpdesc[nposs], "(Deactivate, at will)");
|
||||
deactspell[nposs] = B_TRUE;
|
||||
} else {
|
||||
int ongoing = B_FALSE;
|
||||
if (hasflag(ot->flags, F_ONGOING)) ongoing = B_TRUE;
|
||||
sprintf(mpdesc[nposs], "(%d MP%s)", mpcost[nposs],
|
||||
ongoing ? ", ongoing" : "");
|
||||
}
|
||||
if (lf->mp >= mpcost[nposs]) {
|
||||
validspell[nposs] = B_TRUE;
|
||||
} else {
|
||||
validspell[nposs] = B_FALSE;
|
||||
|
@ -3090,6 +3141,10 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2)
|
|||
}
|
||||
|
||||
getspellname(ot->id, player, buf2);
|
||||
if (deactspell[i]) {
|
||||
strcat(buf2, "/deact");
|
||||
}
|
||||
|
||||
|
||||
if (validspell[i]) {
|
||||
strcpy(costbuf, "");
|
||||
|
@ -3609,22 +3664,49 @@ void dorest(void) {
|
|||
}
|
||||
// if not training, only rest if we need to.
|
||||
if (!willtrain) {
|
||||
if (player->hp >= player->maxhp) {
|
||||
char norestmsg[BUFLEN];
|
||||
strcpy(norestmsg, "");
|
||||
if (player->maxmp > 0) {
|
||||
if (player->mp >= player->maxmp) {
|
||||
// no need to rest
|
||||
strcpy(norestmsg, "Not resting - already at full health and mana.");
|
||||
char validchars[BUFLEN];
|
||||
char ques[BUFLEN];
|
||||
char ch;
|
||||
strcpy(validchars, "");
|
||||
if (player->hp < player->maxhp) {
|
||||
strcat(validchars, "h");
|
||||
}
|
||||
if ((getmaxmp(player) > 0) && (player->mp < getmaxmp(player))) {
|
||||
strcat(validchars, "m");
|
||||
}
|
||||
|
||||
if (strchr(validchars, 'h') && strchr(validchars, 'm')) {
|
||||
strcat(validchars, "b");
|
||||
strcpy(ques, "Rest until full HP, Mana, Both or none");
|
||||
ch = askchar(ques, validchars, "b", B_TRUE);
|
||||
if (ch == 'b') {
|
||||
addflag(player->flags, F_RESTUNTILHP, B_TRUE, NA, NA, NULL);
|
||||
addflag(player->flags, F_RESTUNTILMP, B_TRUE, NA, NA, NULL);
|
||||
} else if (ch == 'h') {
|
||||
addflag(player->flags, F_RESTUNTILHP, B_TRUE, NA, NA, NULL);
|
||||
} else if (ch == 'm') {
|
||||
addflag(player->flags, F_RESTUNTILMP, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
} else if (strchr(validchars, 'h')) {
|
||||
strcpy(ques, "Rest until full HP");
|
||||
ch = askchar(ques, "yn", "y", B_TRUE);
|
||||
if (ch == 'y') {
|
||||
addflag(player->flags, F_RESTUNTILHP, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
} else if (strchr(validchars, 'm')) {
|
||||
strcpy(ques, "Rest until full Mana");
|
||||
ch = askchar(ques, "yn", "y", B_TRUE);
|
||||
if (ch == 'y') {
|
||||
addflag(player->flags, F_RESTUNTILMP, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
} else {
|
||||
// no need to rest
|
||||
strcpy(norestmsg, "Not resting - already at full health.");
|
||||
}
|
||||
if (strlen(norestmsg)) {
|
||||
msg(norestmsg);
|
||||
msg("You don't need to rest at the moment.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lfhasflag(player, F_RESTUNTILHP) && !lfhasflag(player, F_RESTUNTILMP)) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
startresting(player, willtrain);
|
||||
|
@ -4225,8 +4307,10 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
|
|||
|
||||
|
||||
// display prompt question
|
||||
sprintf(promptstr, "%s %s %s",
|
||||
prompt->q[prompt->whichq], prompt->maycancel ? "[ESC=cancel, '=next page] " : "",
|
||||
sprintf(promptstr, "%s [%s%s] %s",
|
||||
prompt->q[prompt->whichq],
|
||||
prompt->maycancel ? "ESC," : "",
|
||||
showall ? "'=next page,?=toggle" : "?=list",
|
||||
inpstring);
|
||||
mvwprintw(mainwin, 0, 0, "%s", promptstr);
|
||||
wclrtoeol(mainwin);
|
||||
|
@ -4853,6 +4937,7 @@ void drawstatus(void) {
|
|||
char buf2[BUFLEN];
|
||||
char waitbuf[BUFLEN];
|
||||
char pname[BUFLEN];
|
||||
char maxmpstr[BUFLEN];
|
||||
flag_t *f;
|
||||
int str,dex,iq,con;
|
||||
long xpleft;
|
||||
|
@ -4902,8 +4987,8 @@ void drawstatus(void) {
|
|||
}
|
||||
|
||||
// show certain flags
|
||||
if (lfhasflag(player, F_FOODPOISONED)) {
|
||||
strcat(buf, " Sick");
|
||||
if (lfhasflag(player, F_POISONED)) {
|
||||
strcat(buf, " Poisoned");
|
||||
}
|
||||
|
||||
mvwprintw(statwin, 0, 0, buf);
|
||||
|
@ -4954,9 +5039,16 @@ void drawstatus(void) {
|
|||
iq = getattr(player, A_IQ);
|
||||
con = getattr(player, A_CON);
|
||||
//redraw();
|
||||
sprintf(buf, "HP:%d/%d MP:%d/%d $:%d St:%d%c Dx:%d%c Iq:%d%c Cn:%d%c DLev:%d",
|
||||
|
||||
if (getmaxmp(player) == player->maxmp) {
|
||||
strcpy(maxmpstr, "");
|
||||
} else {
|
||||
sprintf(maxmpstr, "(%d)",player->maxmp);
|
||||
}
|
||||
|
||||
sprintf(buf, "HP:%d/%d MP:%d/%d%s $:%d St:%d%c Dx:%d%c Iq:%d%c Cn:%d%c DLev:%d",
|
||||
player->hp,player->maxhp,
|
||||
player->mp, player->maxmp,
|
||||
player->mp, getmaxmp(player), maxmpstr,
|
||||
countmoney(player),
|
||||
str, (str == player->baseatt[A_STR]) ? ' ' : '*',
|
||||
dex, (dex == player->baseatt[A_DEX]) ? ' ' : '*',
|
||||
|
@ -5227,8 +5319,16 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
}
|
||||
if (showall) {
|
||||
char maxmpstr[BUFLEN];
|
||||
|
||||
if (getmaxmp(lf) == lf->maxmp) {
|
||||
strcpy(maxmpstr, "");
|
||||
} else {
|
||||
sprintf(maxmpstr, "(%d)",lf->maxmp);
|
||||
}
|
||||
|
||||
mvwprintw(mainwin, y, 0, ftext, "Mana");
|
||||
wprintw(mainwin, "%d / %d", lf->mp , lf->maxmp); y++;
|
||||
wprintw(mainwin, "%d / %d%s", lf->mp , lf->maxmp,maxmpstr); y++;
|
||||
}
|
||||
if (showall) {
|
||||
mvwprintw(mainwin, y, 0, ftext, "Exp Level");
|
||||
|
@ -5697,6 +5797,11 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, "%s %s sleeping.", you(lf), isplayer(lf) ? "are" : "is");
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_BEINGSTONED);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s being turning to stone.", you(lf), isplayer(lf) ? "are" : "is");
|
||||
y++;
|
||||
}
|
||||
|
||||
f = lfhasknownflag(lf, F_FLYING);
|
||||
if (f && (f->known)) {
|
||||
|
@ -5776,13 +5881,29 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
f = lfhasknownflagval(lf, F_CANWILL, ot->id, NA, NA, NULL);
|
||||
if (f && (f->known)) {
|
||||
char expirebuf[BUFLEN];
|
||||
char eb2[BUFLEN];
|
||||
int needgrab = B_FALSE;
|
||||
|
||||
if (f->val[2] == NA) {
|
||||
sprintf(expirebuf, " (at will)");
|
||||
sprintf(expirebuf, "at will");
|
||||
} else {
|
||||
sprintf(expirebuf, " (every %d turn%s)",f->val[2],
|
||||
sprintf(expirebuf, "every %d turn%s",f->val[2],
|
||||
(f->val[2] == 1) ? "" : "s");
|
||||
}
|
||||
sprintf(buf, "%-12s%s%s", ot->name, ot->desc, expirebuf);
|
||||
|
||||
// extra options?
|
||||
texttospellopts(f->text, NULL, NULL, &needgrab);
|
||||
if (needgrab) {
|
||||
strcat(expirebuf, ",after grab");
|
||||
}
|
||||
|
||||
|
||||
if (strlen(expirebuf)) {
|
||||
sprintf(eb2,"(%s)",expirebuf);
|
||||
} else {
|
||||
strcpy(eb2, "");
|
||||
}
|
||||
sprintf(buf, "%-12s%s%s", ot->name, ot->desc, eb2);
|
||||
mvwprintw(mainwin, y, 0, buf);
|
||||
if (downline(&y, h, "ABILITIES", NULL, prompt, cmdchars, &ch)) {
|
||||
exitnow = B_TRUE;
|
||||
|
@ -5798,10 +5919,11 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
centre(mainwin, y, "SKILLS"); y += 2;
|
||||
for (f = lf->flags->first ; f ; f = f->next) {
|
||||
if (f->id == F_HASSKILL) {
|
||||
mvwprintw(mainwin, y, 0, "%c %s %s%s",
|
||||
mvwprintw(mainwin, y, 0, "%c %s (%s%s)",
|
||||
ismaxedskill(lf, f->val[0]) ? '*' : '-',
|
||||
getskilllevelname(f->val[1]), getskillname(f->val[0]),
|
||||
ismaxedskill(lf, f->val[0]) ? " (max)" : "");
|
||||
getskillname(f->val[0]),
|
||||
getskilllevelname(f->val[1]),
|
||||
ismaxedskill(lf, f->val[0]) ? "/MAX" : "");
|
||||
if (downline(&y, h, "SKILLS", NULL, prompt, cmdchars, &ch)) {
|
||||
exitnow = B_TRUE;
|
||||
break;
|
||||
|
@ -5837,12 +5959,28 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
char mpbuf[BUFLEN];
|
||||
int power;
|
||||
int mpcost;
|
||||
mpcost = getmpcost(ot->id);
|
||||
if (f->id == F_CANWILL) {
|
||||
mpcost = 0;
|
||||
|
||||
if (f->val[2] == NA) {
|
||||
sprintf(mpbuf, "At will");
|
||||
} else {
|
||||
sprintf(mpbuf, "At will, every %d turn%s",f->val[2],
|
||||
(f->val[2] == 1) ? "" : "s");
|
||||
}
|
||||
} else {
|
||||
|
||||
mpcost = getmpcost(lf, ot->id);
|
||||
if (mpcost) {
|
||||
if (hasflag(ot->flags, F_ONGOING)) {
|
||||
sprintf(mpbuf, "%d MP ongoing", mpcost);
|
||||
} else {
|
||||
sprintf(mpbuf, "%d MP", mpcost);
|
||||
}
|
||||
} else {
|
||||
sprintf(mpbuf, "At will");
|
||||
}
|
||||
}
|
||||
|
||||
power = getspellpower(lf, ot->id);
|
||||
|
||||
|
@ -5895,6 +6033,13 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
f = lfhasknownflag(lf, F_ARBOOST);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s protected by a magical shield.", you(lf), isplayer(lf) ? "are" : "is");
|
||||
y++;
|
||||
}
|
||||
|
||||
f = lfhasknownflag(lf, F_NOPACK);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s cannot carry objects.", you(lf));
|
||||
|
@ -5934,9 +6079,9 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, "%s receive enhanced knowledge about the world.", you(lf));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_FOODPOISONED);
|
||||
f = lfhasknownflag(lf, F_POISONED);
|
||||
if (f && (f->known)) {
|
||||
sprintf(buf, "%s have food poisoning.", you(lf));
|
||||
sprintf(buf, "%s %s poisoned.", you(lf), isplayer(lf) ? "are" : "is");
|
||||
if (lfhasflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT)) {
|
||||
char buf2[BUFLEN];
|
||||
sprintf(buf2, " [%d left]", f->lifetime);
|
||||
|
@ -6041,7 +6186,21 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
f = lfhasknownflag(lf, F_RESISTMAG);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "Magic does not affect %s.", you(lf));
|
||||
int mr;
|
||||
char adjective[BUFLEN];
|
||||
mr = getmr(lf);
|
||||
if (mr <= 5) {
|
||||
strcpy(adjective, "slightly");
|
||||
} else if (mr <= 10) {
|
||||
strcpy(adjective, "quite");
|
||||
} else if (mr <= 15) {
|
||||
strcpy(adjective, "very");
|
||||
} else if (mr <= 20) {
|
||||
strcpy(adjective, "extremely");
|
||||
} else { // ie. 21 upwards
|
||||
strcpy(adjective, "incredibly");
|
||||
}
|
||||
mvwprintw(mainwin, y, 0, "%s %s %s resistant to magic.", you(lf), isplayer(lf) ? "are" : "is", adjective);
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_TIRED);
|
||||
|
|
5
lf.h
5
lf.h
|
@ -78,7 +78,9 @@ char getlfglyph(lifeform_t *lf);
|
|||
enum MATERIAL getlfmaterial(lifeform_t *lf);
|
||||
float getmaxcarryweight(lifeform_t *lf);
|
||||
float getmaxliftweight(lifeform_t *lf);
|
||||
int getmaxmp(lifeform_t *lf);
|
||||
float getmaxpushweight(lifeform_t *lf);
|
||||
int getmr(lifeform_t *lf);
|
||||
int getvisrange(lifeform_t *lf);
|
||||
int getmovespeed(lifeform_t *lf);
|
||||
char *getmoveverb(lifeform_t *lf);
|
||||
|
@ -115,15 +117,16 @@ void givestartobs(lifeform_t *lf, flagpile_t *fp);
|
|||
void givestartskills(lifeform_t *lf, flagpile_t *fp);
|
||||
map_t *gotolev(lifeform_t *lf, int depth, object_t *fromstairs);
|
||||
job_t *hasjob(lifeform_t *lf, enum JOB job);
|
||||
int lfcanbestoned(lifeform_t *lf);
|
||||
flag_t *lfhasflag(lifeform_t *lf, enum FLAG fid);
|
||||
flag_t *lfhasflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text);
|
||||
flag_t *lfhasknownflag(lifeform_t *lf, enum FLAG fid);
|
||||
flag_t *lfhasknownflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text);
|
||||
int lockpick(lifeform_t *lf, object_t *target, object_t *device);
|
||||
void loseobflags(lifeform_t *lf, object_t *o, int kind);
|
||||
int hasbp(lifeform_t *lf, enum BODYPART bp);
|
||||
int haslof(lifeform_t *viewer, cell_t *dest);
|
||||
int haslos(lifeform_t *viewer, cell_t *dest);
|
||||
int hasmr(lifeform_t *lf);
|
||||
void initjobs(void);
|
||||
void initrace(void);
|
||||
void initskills(void);
|
||||
|
|
5
map.c
5
map.c
|
@ -34,6 +34,7 @@ cell_t *addcell(map_t *m, int x, int y) {
|
|||
cell->lit = L_NOTLIT;
|
||||
cell->origlit = L_NOTLIT;
|
||||
cell->littimer = 0;
|
||||
cell->origlittimer = 0;
|
||||
cell->writing = NULL;
|
||||
cell->known = B_FALSE;
|
||||
return cell;
|
||||
|
@ -2092,8 +2093,10 @@ void makelit(cell_t *c, enum LIGHTLEV how, int howlong) {
|
|||
}
|
||||
}
|
||||
if (howlong > 0) {
|
||||
c->littimer = howlong;
|
||||
// TODO: use a stack here instead
|
||||
c->origlit = c->lit;
|
||||
c->origlittimer = c->littimer;
|
||||
c->littimer = howlong;
|
||||
}
|
||||
c->lit = how;
|
||||
}
|
||||
|
|
53
move.c
53
move.c
|
@ -459,6 +459,28 @@ int moveawayfrom(lifeform_t *lf, cell_t *dst ) {
|
|||
}
|
||||
|
||||
|
||||
void moveeffects(lifeform_t *lf) {
|
||||
flag_t *f;
|
||||
|
||||
if (isbleeding(lf)) {
|
||||
if (rnd(1,2) == 1) {
|
||||
bleed(lf);
|
||||
}
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_PAIN);
|
||||
if (f) {
|
||||
if (isplayer(lf)) {
|
||||
msg("Your body is wracked with pain!");
|
||||
} else if (cansee(player, lf)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s convulses in pain!",lfname);
|
||||
}
|
||||
losehp(lf, roll(f->text), f->val[0], NULL, "extreme pain");
|
||||
}
|
||||
if (isdead(lf)) return;
|
||||
}
|
||||
|
||||
|
||||
// returns TRUE if something happened
|
||||
|
@ -468,9 +490,14 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
lifeform_t *l;
|
||||
int didmsg = B_FALSE;
|
||||
flag_t *f;
|
||||
int changedlev = B_FALSE;
|
||||
|
||||
getlfname(lf, lfname);
|
||||
|
||||
if (newcell->map != lf->cell->map) {
|
||||
changedlev = B_TRUE;
|
||||
}
|
||||
|
||||
// update current cell
|
||||
lf->cell->lf = NULL;
|
||||
|
||||
|
@ -491,20 +518,13 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
// update new cell
|
||||
newcell->lf = lf;
|
||||
|
||||
if (isbleeding(lf)) {
|
||||
if (rnd(1,2) == 1) {
|
||||
bleed(lf);
|
||||
}
|
||||
}
|
||||
if (lfhasflag(lf, F_PAIN)) {
|
||||
losehp(lf, rolldie(2,4)+2, DT_DIRECT, NULL, "extreme pain");
|
||||
if (isplayer(lf)) {
|
||||
msg("Your body is wracked with pain!");
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s convulses in pain!",lfname);
|
||||
}
|
||||
// update light
|
||||
if (changedlev && isplayer(lf)) {
|
||||
calclight(lf->cell->map);
|
||||
}
|
||||
|
||||
moveeffects(lf);
|
||||
|
||||
// remove grabs
|
||||
f = lfhasflag(lf, F_GRABBING);
|
||||
if (f) {
|
||||
|
@ -617,6 +637,8 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
|||
dontclearmsg = B_TRUE;
|
||||
}
|
||||
|
||||
assert(!newcell->lf);
|
||||
|
||||
getlfname(lf, lfname);
|
||||
|
||||
// is current cell dark?
|
||||
|
@ -870,7 +892,8 @@ int closedoor(lifeform_t *lf, object_t *o) {
|
|||
if (lf && isplayer(lf)) {
|
||||
char inwayname[BUFLEN];
|
||||
getobname(oo, inwayname, oo->amt);
|
||||
msg("%s is in the way!", haslos(lf, cell) ? inwayname : "Something");
|
||||
msg("%s %s in the way!", haslos(lf, cell) ? inwayname : "Something",
|
||||
(haslos(lf,cell) && (oo->amt > 1)) ? "are" : "is" );
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
@ -1029,6 +1052,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
}
|
||||
|
||||
// slipping on blood before moving?
|
||||
if (!isairborne(lf)) {
|
||||
slip = getslipperyness(lf->cell, &slipob);
|
||||
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
|
||||
slipon(lf, slipob);
|
||||
|
@ -1036,6 +1060,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
reason = E_OK;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// move to new cell
|
||||
reason = E_OK;
|
||||
|
@ -1043,6 +1068,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
taketime(lf, getmovespeed(lf));
|
||||
|
||||
// slip on blood in new cell?
|
||||
if (!isairborne(lf)) {
|
||||
slip = getslipperyness(cell, &slipob);
|
||||
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
|
||||
slipon(lf, slipob);
|
||||
|
@ -1050,6 +1076,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
reason = E_OK;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
object_t *inway;
|
||||
int door, dooropen;
|
||||
|
|
1
move.h
1
move.h
|
@ -12,6 +12,7 @@ int getdiraway(cell_t *src, cell_t *dst, int wantcheck);
|
|||
int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck);
|
||||
int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher);
|
||||
int moveawayfrom(lifeform_t *lf, cell_t *dst);
|
||||
void moveeffects(lifeform_t *lf);
|
||||
int movelf(lifeform_t *lf, cell_t *newcell);
|
||||
int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose);
|
||||
int movetowards(lifeform_t *lf, cell_t *dst);
|
||||
|
|
18
nexus.c
18
nexus.c
|
@ -120,6 +120,10 @@ int main(int argc, char **argv) {
|
|||
// find staircase
|
||||
where = findobinmap(firstmap, OT_STAIRSUP);
|
||||
assert(where);
|
||||
// make sure no lifeforms are there
|
||||
if (where->lf) {
|
||||
killlf(where->lf);
|
||||
}
|
||||
// add player
|
||||
real_addlf(where, R_HUMAN, 1, C_PLAYER); // this will assign 'player'
|
||||
|
||||
|
@ -583,6 +587,16 @@ int rnd(int min, int max) {
|
|||
res = (rand() % (max - min + 1)) + min;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int roll(char *string) {
|
||||
int ndice,nsides,bonus;
|
||||
int roll;
|
||||
texttodice(string, &ndice,&nsides,&bonus);
|
||||
roll = rolldie(ndice, nsides) + bonus;
|
||||
return roll;
|
||||
}
|
||||
|
||||
// get a random number
|
||||
int rolldie(int ndice, int sides) {
|
||||
int i;
|
||||
|
@ -883,10 +897,6 @@ void timeeffectsworld(map_t *map) {
|
|||
// now handle effects on lifeforms and/or their objects
|
||||
for (l = map->lf ; l ; l = l->next) {
|
||||
timeeffectslf(l);
|
||||
for (o = l->pack->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
timeeffectsob(o);
|
||||
}
|
||||
}
|
||||
|
||||
//dblog("AFTER SORT AND ADJUST.....");
|
||||
|
|
1
nexus.h
1
nexus.h
|
@ -15,6 +15,7 @@ int isplayerturn(void);
|
|||
int limit(int *what, int min, int max);
|
||||
float pctof(float pct, float num);
|
||||
int rnd(int min, int max);
|
||||
int roll(char *string);
|
||||
int rolldie(int ndice, int sides);
|
||||
int rollhitdice(lifeform_t *lf);
|
||||
int rollmpdice(lifeform_t *lf);
|
||||
|
|
|
@ -21,6 +21,7 @@ void appendinscription(object_t *o, char *text);
|
|||
void applyobmod(object_t *o, obmod_t *om);
|
||||
int blessob(object_t *o);
|
||||
void brightflash(cell_t *centre, int range, lifeform_t *immunelf);
|
||||
int canbepoisoned(enum OBTYPE oid);
|
||||
object_t *canstackob(obpile_t *op, object_t *match);
|
||||
object_t *canstacknewot(obpile_t *op, objecttype_t *match);
|
||||
int changemat(object_t *o, enum MATERIAL mat);
|
||||
|
@ -140,6 +141,7 @@ void killob(object_t *o);
|
|||
void killobpile(obpile_t *o);
|
||||
void killoc(objectclass_t *oc);
|
||||
void killot(objecttype_t *ot);
|
||||
int knockbackob(object_t *o, int dir, int howfar, int power, lifeform_t *pusher);
|
||||
lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level);
|
||||
void makeduller(object_t *o, int howmuch);
|
||||
void makeknown(enum OBTYPE otid);
|
||||
|
@ -170,7 +172,7 @@ void setinscription(object_t *o, char *text);
|
|||
void shufflehiddennames(void);
|
||||
object_t *splitob(object_t *o);
|
||||
int takedamage(object_t *o, unsigned int howmuch, int damtype);
|
||||
int fireat(lifeform_t *thrower, object_t *o, cell_t *where, int speed, object_t *firearm);
|
||||
int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm);
|
||||
void timeeffectsob(object_t *o);
|
||||
void turnoff(lifeform_t *lf, object_t *o);
|
||||
void turnon(lifeform_t *lf, object_t *o);
|
||||
|
|
504
spell.c
504
spell.c
|
@ -25,17 +25,55 @@ extern WINDOW *msgwin;
|
|||
|
||||
extern job_t *firstjob;
|
||||
|
||||
int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifeform_t *target) {
|
||||
int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifeform_t *target, flag_t *cwflag) {
|
||||
char username[BUFLEN];
|
||||
char killername[BUFLEN];
|
||||
char targetname[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
int power = 0,needgrab = B_FALSE;
|
||||
char damstr[BUFLEN];
|
||||
objecttype_t *ot;
|
||||
|
||||
flag_t *f;
|
||||
|
||||
getlfname(user, username);
|
||||
real_getlfname(user,killername, B_FALSE);
|
||||
|
||||
// defaults
|
||||
strcpy(damstr,"");
|
||||
power = 0;
|
||||
needgrab = B_FALSE;
|
||||
|
||||
if (cwflag && strlen(cwflag->text)) {
|
||||
texttospellopts(cwflag->text, &power, damstr, &needgrab);
|
||||
}
|
||||
|
||||
// get more options from ablity itself...
|
||||
ot = findot(abilid);
|
||||
if (ot) {
|
||||
if (hasflag(ot->flags, F_NEEDSGRAB)) {
|
||||
needgrab = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (needgrab) {
|
||||
// target is whoever we are grabbing
|
||||
f = lfhasflag(user, F_GRABBING);
|
||||
if (f) {
|
||||
target = findlf(NULL, f->val[0]);
|
||||
} else {
|
||||
if (isplayer(user)) msg("You need to grab someone first!");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
if (target) {
|
||||
getlfname(target, targetname);
|
||||
}
|
||||
|
||||
|
||||
if (abilid == OT_A_GRAB) {
|
||||
char dirch;
|
||||
flag_t *f;
|
||||
char targetname[BUFLEN];
|
||||
|
||||
f = lfhasflag(user, F_GRABBING);
|
||||
if (f) {
|
||||
|
@ -81,12 +119,13 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
} else {
|
||||
addflag(user->flags, F_GRABBING, target->id, NA, NA, NULL);
|
||||
addflag(target->flags, F_GRABBEDBY, user->id, NA, NA, NULL);
|
||||
// damage?
|
||||
if (strlen(damstr)) {
|
||||
losehp(target, roll(damstr), DT_CRUSH, user, killername);
|
||||
}
|
||||
}
|
||||
taketime(user, getactspeed(user));
|
||||
} else if (abilid == OT_A_CRUSH) {
|
||||
flag_t *f;
|
||||
lifeform_t *grabee;
|
||||
char gbname[BUFLEN];
|
||||
int dam = 0;
|
||||
|
||||
if (isimmobile(user)) {
|
||||
|
@ -94,42 +133,39 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
// shouldn't be able to happen!
|
||||
/*
|
||||
f = lfhasflag(user, F_GRABBING);
|
||||
if (!f) {
|
||||
if (isplayer(user)) msg("You need to hold someone before using this ability.");
|
||||
return B_TRUE;
|
||||
}
|
||||
grabee = findlf(NULL, f->val[0]);
|
||||
|
||||
assert(grabee);
|
||||
getlfname(grabee, gbname);
|
||||
*/
|
||||
|
||||
// announce
|
||||
if (cansee(player, grabee)) {
|
||||
msg("%s squeeze%s %s tightly!", username, isplayer(user) ? "" : "s", gbname);
|
||||
if (cansee(player, target)) {
|
||||
msg("%s squeeze%s %s tightly!", username, isplayer(user) ? "" : "s", targetname);
|
||||
}
|
||||
|
||||
// victim gets a skilcheck to avoid damage...
|
||||
if (skillcheckvs(grabee, SC_STR, 0, user, SC_STR, 1)) {
|
||||
if (cansee(player, grabee)) {
|
||||
if (skillcheckvs(target, SC_STR, 0, user, SC_STR, 1)) {
|
||||
if (cansee(player, target)) {
|
||||
// broke free
|
||||
killflagsofid(grabee->flags, F_GRABBEDBY);
|
||||
killflagsofid(target->flags, F_GRABBEDBY);
|
||||
killflagsofid(user->flags, F_GRABBING);
|
||||
}
|
||||
} else {
|
||||
char killername[BUFLEN];
|
||||
int str;
|
||||
// determine damage baesd on crusher's strength
|
||||
str = getattr(user, A_STR);
|
||||
dam = modifybystat((str/2), user, A_STR);
|
||||
|
||||
// announce
|
||||
if (cansee(player, grabee)) {
|
||||
msg("%s %s being crushed!", gbname, isplayer(grabee) ? "are" : "is");
|
||||
if (cansee(player, target)) {
|
||||
msg("%s %s being crushed!", targetname, isplayer(target) ? "are" : "is");
|
||||
}
|
||||
|
||||
real_getlfname(user,killername, B_FALSE);
|
||||
losehp(grabee, dam, DT_CRUSH, user, killername);
|
||||
losehp(target, dam, DT_CRUSH, user, killername);
|
||||
}
|
||||
taketime(user, getactspeed(user));
|
||||
} else if (abilid == OT_A_JUMP) {
|
||||
|
@ -276,6 +312,20 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
}
|
||||
|
||||
addtempflag(user->flags, F_SPRINTING, B_TRUE, NA, NA, NULL, howlong);
|
||||
} else if (abilid == OT_A_STINGACID) {
|
||||
validateabillf(user, abilid, &target);
|
||||
if (!target) return B_TRUE;
|
||||
getlfname(target, targetname);
|
||||
|
||||
if (cansee(player, target)) {
|
||||
msg("%s inject%s acid into %s!", username,
|
||||
isplayer(user) ? "" : "s",
|
||||
targetname);
|
||||
}
|
||||
losehp(target, roll(damstr), DT_ACID, user, killername);
|
||||
// cause ongoing pain for 2 turns
|
||||
addtempflag(target->flags, F_PAIN, DT_ACID, NA, NA, damstr, 2);
|
||||
taketime(user, getactspeed(user));
|
||||
} else if (abilid == OT_A_LEARN) {
|
||||
skill_t *sk;
|
||||
char ch = 'a';
|
||||
|
@ -405,18 +455,12 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
if (!isplayer(user)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
if (isplayer(user)) {
|
||||
if (!haslos(user, user->cell)) {
|
||||
msg("You can't inspect anything, since you can't see!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// blind?
|
||||
if (isblind(user)) {
|
||||
msg("You must be able to see before you can inspect something.");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// ask what to inspect
|
||||
o = askobject(user->pack, "Inspect which object", NULL, AO_NOTKNOWN);
|
||||
if (!o) {
|
||||
|
@ -429,6 +473,18 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
// can only inspect certain types of things
|
||||
switch (o->type->obclass->id) {
|
||||
case OC_SCROLL:
|
||||
case OC_BOOK:
|
||||
case OC_WAND:
|
||||
case OC_RING:
|
||||
break;
|
||||
default:
|
||||
msg("This doesn't seem to be a standard kind of item.");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// failed this already?
|
||||
if (lfhasflagval(user, F_FAILEDINSPECT, o->type->id, NA, NA, NULL)) {
|
||||
msg("You won't be able to recognise this until you are more experienced.");
|
||||
|
@ -442,6 +498,20 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
rarity = 0;
|
||||
}
|
||||
difficulty = 25 + ((100 - rarity) / 5);
|
||||
switch (o->type->obclass->id) {
|
||||
case OC_SCROLL:
|
||||
difficulty += 2; break;
|
||||
case OC_BOOK:
|
||||
difficulty += 4; break;
|
||||
case OC_WAND:
|
||||
difficulty += 6; break;
|
||||
case OC_RING:
|
||||
difficulty += 8; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
slev = getskill(user, SK_RESEARCH);
|
||||
switch (slev) {
|
||||
case PR_INEPT:
|
||||
|
@ -482,6 +552,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
char buf[BUFLEN];
|
||||
char castername[BUFLEN];
|
||||
int rv = B_FALSE;
|
||||
objecttype_t *sp;
|
||||
|
||||
sp = findot(spellid);
|
||||
|
||||
getlfname(caster, castername);
|
||||
|
||||
|
@ -501,6 +574,17 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
|
||||
if (hasflag(sp->flags, F_ONGOING)) {
|
||||
if (lfhasflagval(caster, F_BOOSTSPELL, spellid, NA, NA, NULL)) {
|
||||
// cancel it.
|
||||
stopspell(caster, spellid);
|
||||
return B_FALSE;
|
||||
} else {
|
||||
addflag(caster->flags, F_BOOSTSPELL, spellid, NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// switch based on spell effects...
|
||||
if (spellid == OT_S_ABSORBMETAL) {
|
||||
int i;
|
||||
float totalmass = 0;
|
||||
|
@ -517,7 +601,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
totalmass = 0;
|
||||
|
||||
// destroy WORN metal objects by the caster (not CARRIED ones)
|
||||
if (!hasmr(caster)) {
|
||||
for (o = caster->pack->first ; o ; o = o->next) {
|
||||
if (isequipped(o) && ismetal(o->material->id)) {
|
||||
takedamage(o, 9999, DT_DIRECT);
|
||||
|
@ -528,7 +611,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
// destroy objects right away
|
||||
removedeadobs(caster->pack);
|
||||
}
|
||||
|
||||
// handle cell under the caster
|
||||
for (o = caster->cell->obpile->first ; o ; o = o->next) {
|
||||
|
@ -556,7 +638,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
// destroy objects right away
|
||||
removedeadobs(targcell->obpile);
|
||||
if (targcell->lf && !hasmr(targcell->lf)) {
|
||||
|
||||
|
||||
if (targcell->lf && !skillcheck(targcell->lf, SC_RESISTMAG, 20 + power, 0)) {
|
||||
// destroy only WORN metal objects, not CARRIED ones
|
||||
for (o = targcell->lf->pack->first ; o ; o = o->next) {
|
||||
if (isequipped(o) && ismetal(o->material->id)) {
|
||||
|
@ -572,11 +656,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
|
||||
if (totalmass > 0) {
|
||||
if (hasmr(caster)) {
|
||||
if (isplayer(caster)) {
|
||||
msg("You feel a surge of magic, but it quickly dampens.");
|
||||
}
|
||||
} else {
|
||||
float max;
|
||||
// heal 1 mp per kilo
|
||||
howmuch = floor(totalmass);
|
||||
|
@ -587,10 +666,30 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (howmuch > max) howmuch = max;
|
||||
|
||||
gainmp(caster, howmuch);
|
||||
}
|
||||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_AIRBLAST) {
|
||||
int dir;
|
||||
object_t *o,*nexto;
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER, B_TRUE, spellid, power)) return B_TRUE;
|
||||
target = targcell->lf;
|
||||
|
||||
if (cansee(player, caster)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
msg("%s emit%s a powerful blast of air!", castername, isplayer(caster) ? "" : "s");
|
||||
}
|
||||
|
||||
dir = getdirtowards(caster->cell, targcell, target, B_FALSE);
|
||||
// lfs
|
||||
if (target) {
|
||||
knockback(target, dir, power, caster);
|
||||
}
|
||||
// objects
|
||||
for (o = targcell->obpile->first ;o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
if (!hasflag(o->flags, F_NOPICKUP)) knockbackob(o, dir, power, power, caster);
|
||||
}
|
||||
} else if (spellid == OT_S_ANIMATEDEAD) {
|
||||
int i;
|
||||
object_t *o,*nexto;
|
||||
|
@ -669,7 +768,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (hasmr(target) || skillcheck(target, A_IQ, 24, -power)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
failed = B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -694,12 +793,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_BLINK) {
|
||||
if (hasmr(caster)) {
|
||||
if (isplayer(caster)) {
|
||||
msg("You feel a momentary tug.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (!caster->nlos) {
|
||||
if (!caster->nlos) {
|
||||
// can't see anywhere
|
||||
fizzle(caster);
|
||||
} else {
|
||||
|
@ -1034,7 +1128,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
target = targcell->lf;
|
||||
|
||||
if (targcell->lf) {
|
||||
if (hasmr(targcell->lf)) {
|
||||
if (skillcheck(targcell->lf, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(targcell->lf)) {
|
||||
msg("You flicker.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -1345,17 +1439,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else {
|
||||
// monsters can't id things!
|
||||
}
|
||||
} else if (spellid == OT_S_FLIGHT) {
|
||||
flag_t *f;
|
||||
// always targetted at caster
|
||||
targcell = caster->cell;
|
||||
target = caster;
|
||||
|
||||
f = addtempflag(caster->flags, F_FLYING, B_TRUE, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_FREEZEOB) {
|
||||
object_t *o;
|
||||
|
||||
if (targob) {
|
||||
o = targob;
|
||||
} else {
|
||||
if (hasmr(caster)) {
|
||||
if (isplayer(caster)) {
|
||||
msg("Your hands feel cold for a second.");
|
||||
}
|
||||
return B_FALSE;
|
||||
} else {
|
||||
// rings?
|
||||
o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_RIGHTHAND, NA, NA, NULL);
|
||||
|
@ -1392,7 +1488,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!o) {
|
||||
fizzle(caster);
|
||||
|
@ -1453,7 +1548,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else if (spellid == OT_S_GASEOUSFORM) {
|
||||
target = caster;
|
||||
if (hasmr(target)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You feel momentarily insubstantial.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -1483,7 +1578,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
||||
if (hasmr(target)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target) || haslos(player, target->cell)) {
|
||||
getlfname(target, buf);
|
||||
msg("%s blur%s for a moment.",buf, isplayer(target) ? "" : "s");
|
||||
|
@ -1499,15 +1594,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
flag_t *f;
|
||||
target = caster;
|
||||
|
||||
if (hasmr(target)) {
|
||||
if (isplayer(target) || haslos(player, target->cell)) {
|
||||
getlfname(target, buf);
|
||||
msg("%s %s briefly healthier.",buf, isplayer(target) ? "feel" : "looks");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// cure certain bad effects
|
||||
if (killflagsofid(target->flags, F_PAIN)) {
|
||||
donesomething = B_TRUE;
|
||||
|
@ -1539,7 +1625,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
f = lfhasflag(target, F_FOODPOISONED);
|
||||
f = lfhasflag(target, F_POISONED);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
donesomething = B_TRUE;
|
||||
|
@ -1555,14 +1641,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int donesomething = B_FALSE;
|
||||
flag_t *f;
|
||||
target = caster;
|
||||
if (hasmr(target)) {
|
||||
if (isplayer(target) || haslos(player, target->cell)) {
|
||||
getlfname(target, buf);
|
||||
msg("%s %s briefly healthier.",buf, isplayer(target) ? "feel" : "looks");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// cure bad effects instead of healing
|
||||
if (killflagsofid(target->flags, F_PAIN)) {
|
||||
|
@ -1592,7 +1670,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
f = lfhasflag(target, F_FOODPOISONED);
|
||||
f = lfhasflag(target, F_POISONED);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
donesomething = B_TRUE;
|
||||
|
@ -1654,7 +1732,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
for (l = caster->cell->map->lf ; l ; l = l->next) {
|
||||
if (l != caster) {
|
||||
|
||||
if (hasmr(l)) {
|
||||
if (skillcheck(l, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(l)) {
|
||||
msg("Luckily, the evil doesn't seem to harm you.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -1776,7 +1854,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
totalmass = 0;
|
||||
|
||||
// destroy WORN metal objects by the caster (not CARRIED ones)
|
||||
if (!hasmr(caster)) {
|
||||
for (o = caster->pack->first ; o ; o = o->next) {
|
||||
if (isequipped(o) && ismetal(o->material->id)) {
|
||||
takedamage(o, 9999, DT_DIRECT);
|
||||
|
@ -1787,7 +1864,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
// destroy objects right away
|
||||
removedeadobs(caster->pack);
|
||||
}
|
||||
|
||||
// handle cell under the caster
|
||||
for (o = caster->cell->obpile->first ; o ; o = o->next) {
|
||||
|
@ -1815,7 +1891,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
// destroy objects right away
|
||||
removedeadobs(targcell->obpile);
|
||||
if (targcell->lf && !hasmr(targcell->lf)) {
|
||||
if (targcell->lf && !skillcheck(targcell->lf, SC_RESISTMAG, 20 + power, 0)) {
|
||||
// destroy only WORN metal objects, not CARRIED ones
|
||||
for (o = targcell->lf->pack->first ; o ; o = o->next) {
|
||||
if (isequipped(o) && ismetal(o->material->id)) {
|
||||
|
@ -1831,16 +1907,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
|
||||
if (totalmass > 0) {
|
||||
if (hasmr(caster)) {
|
||||
if (isplayer(caster)) {
|
||||
msg("You feel momentarily healthier, but the feeling passes.");
|
||||
}
|
||||
} else {
|
||||
// heal 2 hp per kilo
|
||||
howmuch = floor(totalmass) * 2;
|
||||
howmuch *= (power/3); // modify for power
|
||||
gainhp(caster, howmuch);
|
||||
}
|
||||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
|
@ -1884,7 +1954,41 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
// 4 is the same as ST_TITANIC strength
|
||||
// 10 = gun speed
|
||||
fireat(caster, targob, targcell, 8 + (power / 2) , NULL);
|
||||
fireat(caster, targob, 1, targcell, 8 + (power / 2) , NULL);
|
||||
} else if (spellid == OT_S_PARALYZE) {
|
||||
int howlong;
|
||||
int saved = B_FALSE;
|
||||
if (!validatespelllf(caster, &target)) return B_TRUE;
|
||||
|
||||
if (lfhasflag(target, F_PARALYZED)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
saved = B_TRUE;
|
||||
} else if (skillcheck(target, SC_STR, 20 + power, 0)) {
|
||||
saved = B_TRUE;
|
||||
}
|
||||
|
||||
if (saved) {
|
||||
if (isplayer(target)) {
|
||||
msg("You stiffen momentarily.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else if (haslos(player, target->cell)) {
|
||||
getlfname(target, buf);
|
||||
msg("%s stiffens momentarily.", buf);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
howlong = power*2;
|
||||
|
||||
addtempflag(target->flags, F_PARALYZED, B_TRUE, NA, NA, NULL, howlong);
|
||||
if (isplayer(target) || haslos(player, target->cell)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_PAIN) {
|
||||
int failed = B_FALSE;
|
||||
// ask for target
|
||||
|
@ -1896,8 +2000,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
|
||||
// make this a constitution skill check ?
|
||||
//if (hasmr(target) || skillcheck(caster, A_IQ, -5)) {
|
||||
if (hasmr(target)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
failed = B_TRUE;
|
||||
} else if (skillcheck(target, SC_CON, 20 + power, 0)) {
|
||||
failed = B_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1916,7 +2021,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else {
|
||||
int howlong = 7;
|
||||
howlong = getspellduration(3,5,blessed) + (power/2);
|
||||
addtempflag(target->flags, F_PAIN, B_TRUE, NA, NA, NULL, howlong);
|
||||
addtempflag(target->flags, F_PAIN, DT_MAGIC, NA, NA, "2d4+2", howlong);
|
||||
}
|
||||
} else {
|
||||
fizzle(caster);
|
||||
|
@ -1924,27 +2029,41 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else if (spellid == OT_S_PETRIFY) {
|
||||
if (!validatespelllf(caster, &target)) return B_TRUE;
|
||||
|
||||
// some thigns can't be stoned
|
||||
if (!lfcanbestoned(target)) {
|
||||
fizzle(caster);
|
||||
return B_FALSE;
|
||||
} else if (lfhasflag(target, F_BEINGSTONED)) {
|
||||
fizzle(caster);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// savingthrow
|
||||
if (hasmr(target) || skillcheck(target, SC_IQ, 30, -power)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0) || skillcheck(target, SC_CON, 30 + power, 0)) {
|
||||
if (haslos(player, target->cell)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(target, lfname);
|
||||
msg("%s glows grey momentarily.", lfname);
|
||||
msg("%s glow%s grey momentarily.", lfname, isplayer(target) ? "" : "s");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!stone(target)) {
|
||||
// successful
|
||||
if (haslos(player, target->cell)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
// failed!
|
||||
fizzle(caster);
|
||||
}
|
||||
addflag(target->flags, F_BEINGSTONED, 2, NA, NA, NULL);
|
||||
} else if (spellid == OT_S_PSYARMOUR) {
|
||||
flag_t *f;
|
||||
// always targetted at caster
|
||||
targcell = caster->cell;
|
||||
target = caster;
|
||||
|
||||
f = addtempflag(caster->flags, F_ARBOOST, power*3, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_PULLMETAL) {
|
||||
int donesomething = B_FALSE;
|
||||
if (!validatespellcell(caster, &targcell,TT_OBJECT, B_TRUE, spellid, power)) return B_TRUE;
|
||||
|
||||
if (targcell->lf) {
|
||||
|
@ -1954,12 +2073,17 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
float metalweight = 0;
|
||||
object_t *wep;
|
||||
|
||||
donesomething = B_FALSE;
|
||||
|
||||
// if they are weilding a metal weapon...
|
||||
wep = getweapon(targcell->lf);
|
||||
if (wep && ismetal(wep->material->id)) {
|
||||
if (wep && ismetal(wep->material->id) && !lfhasflag(caster, F_NOPACK)) {
|
||||
// pull their weapon from them
|
||||
pullobto(wep, caster);
|
||||
} else {
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// if they're wearing metal...
|
||||
for (o = targcell->lf->pack->first ; o ; o = o->next) {
|
||||
if (ismetal(o->material->id)) {
|
||||
|
@ -1973,11 +2097,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
if (gotmetal) {
|
||||
donesomething = B_TRUE;
|
||||
// include the target lf's weight since we will be pulling on them
|
||||
target = targcell->lf;
|
||||
metalweight += getlfweight(target, B_WITHOBS);
|
||||
|
||||
if (hasmr(target)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
failed = B_TRUE;
|
||||
} else if (getobpileweight(caster->pack) + metalweight <= getmaxcarryweight(caster)) {
|
||||
// they get pulled towards caster
|
||||
|
@ -2000,9 +2125,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
|
||||
if (!donesomething) {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (targcell->obpile->first) { // no lifeform there
|
||||
targob = NULL;
|
||||
|
@ -2052,16 +2178,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
if ((newdepth < min) || (newdepth > max)) {
|
||||
fizzle(caster);
|
||||
} else if (hasmr(caster)) {
|
||||
if (isplayer(caster)) {
|
||||
msg("You see a flicker nearby.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else if (cansee(player, caster)) {
|
||||
getlfname(caster, buf);
|
||||
msg("You see a flicker near %s.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
} else {
|
||||
map_t *newmap;
|
||||
cell_t *newcell,*srccell;
|
||||
|
@ -2185,7 +2301,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
addtempflag(target->flags, F_INVISIBLE, B_TRUE, NA, NA, NULL, howlong);
|
||||
if (willannounce) {
|
||||
msg("%s vanishes!",targname);
|
||||
msg("%s flicker%s then vanishes!",targname, isplayer(target) ? "" : "s");
|
||||
}
|
||||
} else if (spellid == OT_S_KNOCK) {
|
||||
object_t *o;
|
||||
|
@ -2204,17 +2320,17 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
takedamage(o, 999, DT_DIRECT);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (targcell->lf && (targcell->lf != caster)) {
|
||||
int dir;
|
||||
target = targcell->lf;
|
||||
dir = getdirtowards(caster->cell, targcell, target, B_FALSE);
|
||||
if (cansee(caster, target)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
knockback(target, dir, 2, caster);
|
||||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_LEVITATION) {
|
||||
flag_t *f;
|
||||
// always targetted at caster
|
||||
targcell = caster->cell;
|
||||
target = caster;
|
||||
|
||||
f = addtempflag(caster->flags, F_LEVITATING, B_TRUE, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_LIGHT) {
|
||||
lifeform_t *l;
|
||||
|
||||
|
@ -2294,7 +2410,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (target) {
|
||||
int howlong = 15;
|
||||
|
||||
if (hasmr(target)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You feel momentarily heavier.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -2307,10 +2423,18 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_GRAVLOWER) {
|
||||
flag_t *f;
|
||||
// always targetted at caster
|
||||
targcell = caster->cell;
|
||||
target = caster;
|
||||
|
||||
f = addtempflag(caster->flags, F_DTIMMUNE, DT_FALL, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
} else if (spellid == OT_S_PASSWALL) {
|
||||
int howlong = 7;
|
||||
target = caster;
|
||||
if (hasmr(target)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You feel momentarily insubstantial.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -2339,7 +2463,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (hasmr(target)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You feel momentarily different.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -2408,7 +2532,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int howlong;
|
||||
if (!validatespelllf(caster, &target)) return B_TRUE;
|
||||
|
||||
if (hasmr(target)) {
|
||||
if (lfhasflag(target, F_ASLEEP)) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You yawn.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -2419,7 +2548,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
howlong = getspellduration(5,15,blessed) + (power/2);
|
||||
howlong = getspellduration(5,10,blessed) + (power/2);
|
||||
addtempflag(target->flags, F_ASLEEP, B_TRUE, NA, NA, NULL, howlong);
|
||||
if (isplayer(target) || haslos(player, target->cell)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -2428,7 +2557,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
int howlong = 15;
|
||||
if (!validatespelllf(caster, &target)) return B_TRUE;
|
||||
|
||||
if (hasmr(target)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You feel momentarily slower.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -2472,7 +2601,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// target is always the caster
|
||||
target = caster;
|
||||
|
||||
if (hasmr(target)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You flicker.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -2598,7 +2727,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else {
|
||||
// otherwise throw it there - but speed is based on
|
||||
// caster's INTELLIGENCE, not strength like normal.
|
||||
fireat(caster, targob, targcell, getthrowspeed(getattr(caster, A_IQ)), NULL);
|
||||
fireat(caster, targob, targob->amt, targcell, power, NULL);
|
||||
// note that we use fireat() rather than throwat() to avoid
|
||||
// calling taketime() twice.
|
||||
}
|
||||
|
@ -2633,13 +2762,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// ask for target
|
||||
if (!validatespelllf(caster, &target)) return B_TRUE;
|
||||
|
||||
if (hasmr(target)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You feel momentarily weaker.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else if (haslos(player, target->cell)) {
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (cansee(player, target)) {
|
||||
getlfname(target, buf);
|
||||
msg("%s looks momentarily weaker.", buf);
|
||||
msg("%s %s momentarily weaker.", buf, isplayer(target) ? "feel" : "looks");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
|
@ -2647,8 +2773,24 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
if (target) {
|
||||
int howlong = 15;
|
||||
howlong = getspellduration(10,20,blessed) + power;
|
||||
addtempflag(target->flags, F_ATTRMOD, A_STR, -6, NA, NULL, howlong);
|
||||
flag_t *f;
|
||||
|
||||
// already weakaned?
|
||||
for (f = target->flags->first; f ; f = f->next) {
|
||||
if ((f->id == F_ATTRMOD) && (f->val[0] == A_STR) && (f->obfrom == OT_S_WEAKEN)) {
|
||||
if (cansee(player, target)) {
|
||||
getlfname(target, buf);
|
||||
msg("%s %s momentarily weaker.", buf, isplayer(target) ? "feel" : "looks");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
howlong = getspellduration(5,10,blessed) + power;
|
||||
f = addtempflag(target->flags, F_ATTRMOD, A_STR, -power, NA, NULL, howlong);
|
||||
f->obfrom = OT_S_WEAKEN;
|
||||
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else {
|
||||
fizzle(caster);
|
||||
|
@ -2851,11 +2993,22 @@ char *getspellname(enum OBTYPE spellid, lifeform_t *lf, char *buf) {
|
|||
}
|
||||
|
||||
int getspellpower(lifeform_t *lf, enum OBTYPE spellid) {
|
||||
int power;
|
||||
int power = 0;
|
||||
int statmod;
|
||||
int spelllev;
|
||||
int skill;
|
||||
int max = 10;
|
||||
flag_t *f;
|
||||
|
||||
// first: can we WILL this to occur? if so, we might have a set
|
||||
// spellpower
|
||||
f = lfhasflagval(lf, F_CANWILL, spellid, NA, NA, NULL);
|
||||
if (f && strlen(f->text)) {
|
||||
texttospellopts(f->text, &power, NULL, NULL);
|
||||
if (power > 0) {
|
||||
return power;
|
||||
}
|
||||
}
|
||||
|
||||
// statmod is -1 to 1
|
||||
statmod = getstatmod(lf, A_IQ);
|
||||
|
@ -2922,6 +3075,7 @@ int getspellrange(enum OBTYPE spellid, int power) {
|
|||
|
||||
switch (spellid) {
|
||||
case OT_S_BURNINGWAVE:
|
||||
// base range for this spell is 3
|
||||
range += (power/3);
|
||||
default:
|
||||
break;
|
||||
|
@ -2979,6 +3133,78 @@ void pullobto(object_t *o, lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void stopallspells(lifeform_t *lf) {
|
||||
flag_t *f,*nextf;
|
||||
|
||||
for (f = lf->flags->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
if (f->id == F_BOOSTSPELL) {
|
||||
stopspell(lf, f->val[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stopspell(lifeform_t *caster, enum OBTYPE spellid) {
|
||||
flag_t *f,*nextf;
|
||||
|
||||
for (f = caster->flags->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
if ((f->id == F_BOOSTSPELL) && (f->val[0] == spellid)) {
|
||||
killflag(f);
|
||||
} else if ((f->lifetime == FROMSPELL) && (f->obfrom == spellid)) {
|
||||
killflag(f);
|
||||
}
|
||||
}
|
||||
// remove any other specific effects based on spell type.
|
||||
}
|
||||
|
||||
lifeform_t *validateabillf(lifeform_t *user, enum OBTYPE aid, lifeform_t **target) {
|
||||
objecttype_t *ot;
|
||||
int maxrange;
|
||||
flag_t *f;
|
||||
|
||||
if (*target) {
|
||||
return *target;
|
||||
}
|
||||
ot = findot(aid);
|
||||
f = hasflag(ot->flags, F_RANGE);
|
||||
if (f) {
|
||||
maxrange = f->val[0];
|
||||
} else {
|
||||
maxrange = UNLIMITED;
|
||||
}
|
||||
|
||||
|
||||
// ask for a target lifeform
|
||||
if (isplayer(user)) {
|
||||
cell_t *where;
|
||||
char buf[BUFLEN];
|
||||
sprintf(buf, "Where will you target your %s?",ot->name);
|
||||
where = askcoords(buf, TT_MONSTER);
|
||||
if (where) {
|
||||
if (!haslf(where)) {
|
||||
msg("There is nobody there!");
|
||||
return NULL;
|
||||
}
|
||||
if (maxrange != UNLIMITED) {
|
||||
if (getcelldist(user->cell,where) > maxrange) {
|
||||
msg("That location is out of range!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
*target = haslf(where);
|
||||
} else {
|
||||
msg("Cancelled.");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
// TODO: fill in monster code?
|
||||
return NULL;
|
||||
}
|
||||
return *target;
|
||||
}
|
||||
|
||||
cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, int needlof, enum OBTYPE spellid, int power) {
|
||||
int maxrange = UNLIMITED;
|
||||
int done = B_FALSE;
|
||||
|
@ -3089,7 +3315,7 @@ int getiqreq(enum OBTYPE oid) {
|
|||
}
|
||||
*/
|
||||
|
||||
int getmpcost(enum OBTYPE oid) {
|
||||
int getmpcost(lifeform_t *lf, enum OBTYPE oid) {
|
||||
flag_t *f;
|
||||
objecttype_t *ot;
|
||||
int cost = 0;
|
||||
|
@ -3097,6 +3323,16 @@ int getmpcost(enum OBTYPE oid) {
|
|||
if (!ot) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lf) {
|
||||
if (lfhasflagval(lf, F_BOOSTSPELL, oid, NA, NA, NULL)) {
|
||||
return 0; // ie. deactivating it
|
||||
}
|
||||
if (lfhasflagval(lf, F_CANWILL, oid, NA, NA, NULL)) {
|
||||
return 0; // ie. deactivating it
|
||||
}
|
||||
}
|
||||
|
||||
f = hasflag(ot->flags, F_MPCOST);
|
||||
if (f) {
|
||||
cost = f->val[0];
|
||||
|
|
7
spell.h
7
spell.h
|
@ -2,11 +2,11 @@
|
|||
#define __SPELLS_H
|
||||
#include "defs.h"
|
||||
|
||||
int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifeform_t *target);
|
||||
int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifeform_t *target, flag_t *cwflag);
|
||||
int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_t *target, object_t *targob, cell_t *targcell, int blessed, int *seenbyplayer);
|
||||
void fizzle(lifeform_t *caster);
|
||||
//int getiqreq(enum OBTYPE oid);
|
||||
int getmpcost(enum OBTYPE oid);
|
||||
int getmpcost(lifeform_t *lf, enum OBTYPE oid);
|
||||
enum SKILL getschoolskill(enum SPELLSCHOOL ss);
|
||||
int getspellduration(int min,int max,int blessed);
|
||||
int getspelllevel(enum OBTYPE spellid);
|
||||
|
@ -16,6 +16,9 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid);
|
|||
enum SPELLSCHOOL getspellschool(enum OBTYPE spellid);
|
||||
int getspellrange(enum OBTYPE spellid, int power);
|
||||
void pullobto(object_t *o, lifeform_t *lf);
|
||||
void stopspell(lifeform_t *caster, enum OBTYPE spellid);
|
||||
void stopallspells(lifeform_t *lf);
|
||||
lifeform_t *validateabillf(lifeform_t *user, enum OBTYPE aid, lifeform_t **target);
|
||||
cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, int needlof, enum OBTYPE spellid, int power);
|
||||
lifeform_t *validatespelllf(lifeform_t *caster, lifeform_t **lf);
|
||||
#endif
|
||||
|
|
55
text.c
55
text.c
|
@ -444,6 +444,61 @@ int texttodice(char *text, int *ndice, int *nsides, int *bonus) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
void texttospellopts(char *text, int *power, char *damstr, int *needgrab) {
|
||||
char *p;
|
||||
int n;
|
||||
char *argname[] = {
|
||||
"pw:",
|
||||
"dam:",
|
||||
"needgrab:",
|
||||
NULL,
|
||||
};
|
||||
void *argval[] = {
|
||||
power,
|
||||
damstr,
|
||||
needgrab,
|
||||
NULL,
|
||||
};
|
||||
char argtype[] = {
|
||||
'i',
|
||||
's',
|
||||
'b',
|
||||
'\0',
|
||||
};
|
||||
|
||||
// defaults
|
||||
if (power) *power = 0;
|
||||
if (damstr) strcpy(damstr, "");
|
||||
if (needgrab) *needgrab = B_FALSE;
|
||||
|
||||
// for each arg
|
||||
for (n = 0; argname[n]; n++) {
|
||||
// search for it in text...
|
||||
for (p = text ; *p ; p++) {
|
||||
if (!strncmp(p, argname[n], strlen(argname[n])) ) {
|
||||
char localval[BUFLEN];
|
||||
char *valfull;
|
||||
|
||||
strcpy(localval, p + strlen(argname[n]));
|
||||
valfull = strtok(localval, ";");
|
||||
if (valfull) {
|
||||
if (argval[n]) {
|
||||
if (argtype[n] == 'i') {
|
||||
*((int *)argval[n]) = atoi(valfull);
|
||||
} else if (argtype[n] == 'b') {
|
||||
*((int *)argval[n]) = atoi(valfull) ? B_TRUE : B_FALSE;
|
||||
} else if (argtype[n] == 's') {
|
||||
strcpy((char *)argval[n], valfull);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *you(lifeform_t *lf) {
|
||||
if (isplayer(lf)) {
|
||||
return "You";
|
||||
|
|
1
text.h
1
text.h
|
@ -18,6 +18,7 @@ char *strrep(char *text, char *oldtok, char *newtok, int *rv);
|
|||
char *dostrrep(char* in, char** out, char* oldtok, char* newtok, int *rv);
|
||||
int strpixmatch(char *haystack, char *needle);
|
||||
int texttodice(char *text, int *ndice, int *nsides, int *bonus);
|
||||
void texttospellopts(char *text, int *power, char *damstr, int *needgrab);
|
||||
char *you(lifeform_t *lf);
|
||||
char *you_l(lifeform_t *lf);
|
||||
char *your(lifeform_t *lf);
|
||||
|
|
Loading…
Reference in New Issue