* [+] 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
42
ai.c
42
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 (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);
|
||||
} else {
|
||||
dblog(".oO { can't cast ?unknownspell? right now }");
|
||||
if (db) {
|
||||
if (ot) {
|
||||
dblog(".oO { can't cast %s right now (%s) (mpcost=%d, i have %d) }",
|
||||
ot ? ot->name : "?unkownspell?", why,
|
||||
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;
|
||||
}
|
||||
|
|
201
attack.c
201
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,12 +697,20 @@ char *getattackverb(enum DAMTYPE damtype, int dam, int maxhp) {
|
|||
return "pummel";
|
||||
}
|
||||
} else if (damtype == DT_BITE) {
|
||||
if (pct <= 5) {
|
||||
return "gnaw";
|
||||
} else if (pct <= 30) {
|
||||
return "bite";
|
||||
if (lf && (ownersize <= SZ_SMALL)) {
|
||||
if (pct <= 5) {
|
||||
return "nip";
|
||||
} else if (pct <= 30) {
|
||||
return "bite";
|
||||
}
|
||||
} else {
|
||||
return "savage";
|
||||
if (pct <= 5) {
|
||||
return "gnaw";
|
||||
} else if (pct <= 30) {
|
||||
return "bite";
|
||||
} else {
|
||||
return "savage";
|
||||
}
|
||||
}
|
||||
} else if (damtype == DT_CLAW) {
|
||||
if (pct <= 5) {
|
||||
|
@ -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);
|
||||
|
|
84
defs.h
84
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
|
||||
// magic
|
||||
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);
|
||||
|
|
305
io.c
305
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));
|
||||
donesomething = B_TRUE;
|
||||
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
|
||||
msg("You are no longer immune to magic.");
|
||||
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) {
|
||||
mvwprintw(mainwin, y, 0, "It costs %d MP to cast.",i);
|
||||
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,23 +3664,50 @@ 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.");
|
||||
}
|
||||
} else {
|
||||
// no need to rest
|
||||
strcpy(norestmsg, "Not resting - already at full health.");
|
||||
}
|
||||
if (strlen(norestmsg)) {
|
||||
msg(norestmsg);
|
||||
return;
|
||||
}
|
||||
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 {
|
||||
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);
|
||||
// do the first one right away
|
||||
|
@ -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,11 +5959,27 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
char mpbuf[BUFLEN];
|
||||
int power;
|
||||
int mpcost;
|
||||
mpcost = getmpcost(ot->id);
|
||||
if (mpcost) {
|
||||
sprintf(mpbuf, "%d MP", mpcost);
|
||||
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 {
|
||||
sprintf(mpbuf, "At will");
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
81
move.c
81
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,13 +1052,15 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
}
|
||||
|
||||
// slipping on blood before moving?
|
||||
slip = getslipperyness(lf->cell, &slipob);
|
||||
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
|
||||
slipon(lf, slipob);
|
||||
// don't move
|
||||
reason = E_OK;
|
||||
return B_FALSE;
|
||||
}
|
||||
if (!isairborne(lf)) {
|
||||
slip = getslipperyness(lf->cell, &slipob);
|
||||
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
|
||||
slipon(lf, slipob);
|
||||
// don't move
|
||||
reason = E_OK;
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// move to new cell
|
||||
reason = E_OK;
|
||||
|
@ -1043,13 +1068,15 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
taketime(lf, getmovespeed(lf));
|
||||
|
||||
// slip on blood in new cell?
|
||||
slip = getslipperyness(cell, &slipob);
|
||||
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
|
||||
slipon(lf, slipob);
|
||||
// don't move
|
||||
reason = E_OK;
|
||||
return B_FALSE;
|
||||
}
|
||||
if (!isairborne(lf)) {
|
||||
slip = getslipperyness(cell, &slipob);
|
||||
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
|
||||
slipon(lf, slipob);
|
||||
// don't move
|
||||
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);
|
||||
|
|
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