* [+] 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:
Rob Pearce 2011-03-22 07:06:28 +00:00
parent cc969bb800
commit 4edc66af47
23 changed files with 2449 additions and 10349 deletions

42
ai.c
View File

@ -618,7 +618,7 @@ void aimove(lifeform_t *lf) {
// need to heal? // need to heal?
if ((lf->hp < lf->maxhp) || 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 (lf->hp < (lf->maxhp/2)) {
if (!useitemwithflag(lf, F_AIHEALITEM)) { if (!useitemwithflag(lf, F_AIHEALITEM)) {
return; return;
@ -700,20 +700,34 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
strcpy(why, "spell too powerful"); strcpy(why, "spell too powerful");
} else if (reason == E_NOTREADY) { } else if (reason == E_NOTREADY) {
strcpy(why, "abil not ready"); strcpy(why, "abil not ready");
} else if (reason == E_NEEDGRAB) {
strcpy(why, "needs grab");
} else { } else {
strcpy(why, "unknown reason"); strcpy(why, "unknown reason");
} }
if (ot) { if (db) {
dblog(".oO { can't cast %s right now (%s) (mpcost=%d, i have %d) }", if (ot) {
ot ? ot->name : "?unkownspell?", why, dblog(".oO { can't cast %s right now (%s) (mpcost=%d, i have %d) }",
getmpcost(ot->id), lf->mp); ot ? ot->name : "?unkownspell?", why,
} else { getmpcost(lf, ot->id), lf->mp);
dblog(".oO { can't cast ?unknownspell? right now }"); } else {
dblog(".oO { can't cast ?unknownspell? right now }");
}
} }
} }
return B_FALSE; 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); f = hasflag(ot->flags, purpose);
if (f) { if (f) {
int range; 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)) { if ((ot->id == OT_S_HEALINGMIN) && (lf->hp >= lf->maxhp)) {
return B_FALSE; 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)) { if ((ot->id == OT_S_SLOW) && lfhasflag(victim, F_SLOWACT)) {
return B_FALSE; return B_FALSE;
} }
if ((ot->id == OT_A_SPRINT) && lfhasflag(lf, F_SPRINTING)) { if ((ot->id == OT_A_SPRINT) && lfhasflag(lf, F_SPRINTING)) {
return B_FALSE; 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; return B_TRUE;
} }

201
attack.c
View File

@ -103,6 +103,14 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
aidb = B_TRUE; aidb = B_TRUE;
} }
moveeffects(lf);
if (isdead(lf)) {
return B_TRUE;
}
// get names // get names
getlfname(lf, attackername); getlfname(lf, attackername);
@ -273,7 +281,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
if (fatal) { if (fatal) {
verb = getkillverb(victim, damtype[i], dam[i], victim->maxhp); verb = getkillverb(victim, damtype[i], dam[i], victim->maxhp);
} else { } 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", warn("You %s %s%s%s",
verb, verb,
@ -304,7 +312,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
strcpy(withwep, ""); 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)) { if ((dam[i] == 0) && (damtype[i] != DT_TOUCH)) {
strcpy(nodamstr, " but does no damage"); strcpy(nodamstr, " but does no damage");
} else { } else {
@ -354,7 +362,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim) {
} // end foreach damtype } // end foreach damtype
// special weapon effects // special weapon effects
wepeffects(wep, victim->cell); if (dam[0]) {
wepeffects(wep->flags, victim->cell);
}
if (!isdead(victim)) { if (!isdead(victim)) {
if (unarmedflag) { 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! } else { // miss!
if (aidb) dblog(".oO { i missed! }"); if (aidb) dblog(".oO { i missed! }");
@ -477,6 +513,8 @@ int attackob(lifeform_t *lf, object_t *o) {
//int aidb = B_TRUE; //int aidb = B_TRUE;
int maxhp; int maxhp;
moveeffects(lf);
if (isdead(lf)) return B_TRUE;
// get names // get names
getlfname(lf, attackername); getlfname(lf, attackername);
@ -546,7 +584,7 @@ int attackob(lifeform_t *lf, object_t *o) {
} else { } else {
strcpy(extradambuf, ""); 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); obname, extradambuf);
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char withwep[BUFLEN]; char withwep[BUFLEN];
@ -558,7 +596,7 @@ int attackob(lifeform_t *lf, object_t *o) {
} }
msg("%s %ss %s%s.", attackername, 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 { } else {
youhear(lf->cell, "sounds of fighting"); youhear(lf->cell, "sounds of fighting");
} }
@ -579,7 +617,9 @@ int attackob(lifeform_t *lf, object_t *o) {
} // end foreach damtype } // end foreach damtype
// special weapon effects // special weapon effects
wepeffects(wep, obloc); if (dam[0]) {
wepeffects(wep->flags, obloc);
}
if (unarmedflag) { if (unarmedflag) {
// touch effects // touch effects
@ -624,10 +664,27 @@ int getarmourdamreduction(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE d
// returns a const char * // 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; float pct;
enum LFSIZE ownersize = SZ_HUMAN;
if (lf) {
ownersize = getlfsize(lf);
}
pct = (int)(((float) dam / (float) maxhp) * 100.0); 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) { if (pct <= 5) {
return "whack"; return "whack";
} else if (pct <= 20) { } else if (pct <= 20) {
@ -640,12 +697,20 @@ char *getattackverb(enum DAMTYPE damtype, int dam, int maxhp) {
return "pummel"; return "pummel";
} }
} else if (damtype == DT_BITE) { } else if (damtype == DT_BITE) {
if (pct <= 5) { if (lf && (ownersize <= SZ_SMALL)) {
return "gnaw"; if (pct <= 5) {
} else if (pct <= 30) { return "nip";
return "bite"; } else if (pct <= 30) {
return "bite";
}
} else { } else {
return "savage"; if (pct <= 5) {
return "gnaw";
} else if (pct <= 30) {
return "bite";
} else {
return "savage";
}
} }
} else if (damtype == DT_CLAW) { } else if (damtype == DT_CLAW) {
if (pct <= 5) { if (pct <= 5) {
@ -1088,6 +1153,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical) {
object_t *wep; object_t *wep;
obpile_t *op = NULL; obpile_t *op = NULL;
int gothit; int gothit;
enum LFSIZE szlf,szvictim;
if (critical) { if (critical) {
*critical = 0; *critical = 0;
@ -1100,6 +1166,19 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical) {
ev = getevasion(victim); ev = getevasion(victim);
acc -= ev; 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 // modify if we can't see the victim
if (!cansee(lf, victim)) { if (!cansee(lf, victim)) {
acc -= 50; acc -= 50;
@ -1134,16 +1213,19 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical) {
return gothit; return gothit;
} }
void wepeffects(object_t *wep, cell_t *where) { void wepeffects(flagpile_t *fp, cell_t *where) {
flag_t *f; flag_t *f;
lifeform_t *victim; lifeform_t *victim;
lifeform_t *owner; lifeform_t *owner;
object_t *wep;
owner = wep->pile->owner;
victim = where->lf;
if (!where) return; 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 (f->id == F_FLAMESTRIKE) {
if (!hasob(where->obpile, OT_FIRESMALL)) { if (!hasob(where->obpile, OT_FIRESMALL)) {
// ignite! // ignite!
@ -1154,36 +1236,6 @@ void wepeffects(object_t *wep, cell_t *where) {
f->known = B_KNOWN; 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)) { } else if ((f->id == F_REVENGE) && victim && !isdead(victim)) {
lifeform_t *owner; lifeform_t *owner;
owner = wep->pile->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); dir = getdirtowards(owner->cell, victim->cell, victim, B_FALSE);
knockback(victim, dir , 2, owner); knockback(victim, dir , 2, owner);
f->known = B_TRUE; 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)
} }
} }

View File

@ -5,8 +5,9 @@ void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *
int attackcell(lifeform_t *lf, cell_t *c); int attackcell(lifeform_t *lf, cell_t *c);
int attacklf(lifeform_t *lf, lifeform_t *victim); int attacklf(lifeform_t *lf, lifeform_t *victim);
int attackob(lifeform_t *lf, object_t *o); 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); 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); object_t *getattackwep(lifeform_t *lf, obpile_t **unarmedpile, flag_t **unarmedflag);
enum DAMTYPE getdamtype(object_t *wep); enum DAMTYPE getdamtype(object_t *wep);
int getextradam(object_t *wep, int *dam, enum DAMTYPE *damtype, int *ndam); 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); float getstrdammod(lifeform_t *lf);
obpile_t *getunarmedweapon(lifeform_t *lf, flag_t **uflag); obpile_t *getunarmedweapon(lifeform_t *lf, flag_t **uflag);
int rolltohit(lifeform_t *lf, lifeform_t *victim, int *critical); 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
View File

@ -45,6 +45,9 @@ enum CHECKTYPE {
SC_SLIP, SC_SLIP,
SC_MORALE, SC_MORALE,
SC_OPENLOCKS, SC_OPENLOCKS,
SC_POISON,
SC_RESISTMAG,
SC_WILL,
}; };
enum BURDENED { enum BURDENED {
@ -86,6 +89,7 @@ enum LFCONDITION {
#define FROMBLESSING (-9866) #define FROMBLESSING (-9866)
#define FROMBRAND (-9865) #define FROMBRAND (-9865)
#define FROMOBMOD (-9864) #define FROMOBMOD (-9864)
#define FROMSPELL (-9863)
#define IFKNOWN (-9772) // used by f_xxconfer. only confer a flag if item is known. #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_LIGHT = 21,
DT_CRUSH = 22, DT_CRUSH = 22,
DT_FALL = 23, 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 // Object Classes
enum OBCLASS { enum OBCLASS {
@ -423,7 +429,9 @@ enum RACE {
R_NONE, R_RANDOM, R_NONE, R_RANDOM,
R_HUMAN, R_HUMAN,
// monsters // monsters
R_BEHOLDER,
R_BUGBEAR, R_BUGBEAR,
R_COCKATRICE,
R_DARKMANTLE, R_DARKMANTLE,
R_EYEBAT, R_EYEBAT,
R_GIANTHILL, R_GIANTHILL,
@ -456,9 +464,13 @@ enum RACE {
R_TROLL, R_TROLL,
R_XAT, R_XAT,
// small animals // small animals
R_ANT,
R_ANTS,
R_BAT, R_BAT,
R_HAWK,
R_NEWT, R_NEWT,
R_RAT, R_RAT,
R_SNAKE,
R_WOLF, R_WOLF,
// insects // insects
R_BUTTERFLY, R_BUTTERFLY,
@ -518,6 +530,7 @@ enum MATERIAL {
MT_GAS = 20, MT_GAS = 20,
MT_SLIME = 21, MT_SLIME = 21,
MT_WAX = 22, MT_WAX = 22,
MT_ACID = 23,
}; };
// Object Types // Object Types
@ -572,6 +585,8 @@ enum OBTYPE {
OT_POT_ACID, OT_POT_ACID,
OT_POT_ACROBATICS, OT_POT_ACROBATICS,
OT_POT_AMBROSIA, OT_POT_AMBROSIA,
OT_POT_BLOOD,
OT_POT_BLOODC,
OT_POT_COMPETENCE, OT_POT_COMPETENCE,
OT_POT_ELEMENTENDURE, OT_POT_ELEMENTENDURE,
OT_POT_ELEMENTIMMUNE, OT_POT_ELEMENTIMMUNE,
@ -614,8 +629,10 @@ enum OBTYPE {
OT_MAN_ATHLETICS, OT_MAN_ATHLETICS,
OT_MAN_FIRSTAID, OT_MAN_FIRSTAID,
OT_MAN_LOCKPICKING, OT_MAN_LOCKPICKING,
OT_MAN_MAGITEMUSAGE,
OT_MAN_RESEARCH, OT_MAN_RESEARCH,
OT_MAN_SPELLCASTING, OT_MAN_SPELLCASTING,
OT_MAN_TECHUSAGE,
// manuals of weaponry // manuals of weaponry
OT_MAN_AXES, OT_MAN_AXES,
OT_MAN_CLUBS, OT_MAN_CLUBS,
@ -638,12 +655,12 @@ enum OBTYPE {
OT_MAN_SS_SUMMONING, OT_MAN_SS_SUMMONING,
OT_MAN_SS_TRANSLOCATION, OT_MAN_SS_TRANSLOCATION,
OT_MAN_SS_WILD, OT_MAN_SS_WILD,
OT_MAN_TECHUSAGE,
// SPELLBOOKS // SPELLBOOKS
// allomancy can't be learned from books // allomancy can't be learned from books
// -- death // -- death
OT_SB_ANIMATEDEAD, OT_SB_ANIMATEDEAD,
OT_SB_PAIN, OT_SB_PAIN,
OT_SB_PARALYZE,
OT_SB_INFINITEDEATH, OT_SB_INFINITEDEATH,
OT_SB_WEAKEN, OT_SB_WEAKEN,
OT_SB_BLINDNESS, OT_SB_BLINDNESS,
@ -653,6 +670,7 @@ enum OBTYPE {
OT_SB_IDENTIFY, OT_SB_IDENTIFY,
OT_SB_MAPPING, OT_SB_MAPPING,
// -- elemental - air // -- elemental - air
OT_SB_AIRBLAST,
OT_SB_CLOUDKILL, OT_SB_CLOUDKILL,
// -- elemental - fire // -- elemental - fire
OT_SB_SPARK, OT_SB_SPARK,
@ -665,16 +683,20 @@ enum OBTYPE {
OT_SB_CONECOLD, OT_SB_CONECOLD,
OT_SB_FREEZEOB, OT_SB_FREEZEOB,
// -- gravity // -- gravity
OT_SB_GRAVLOWER,
OT_SB_GRAVBOOST, OT_SB_GRAVBOOST,
OT_SB_HASTE, OT_SB_HASTE,
OT_SB_FLIGHT,
OT_SB_SLOW, OT_SB_SLOW,
OT_SB_LEVITATION,
// -- life // -- life
OT_SB_HEALING, OT_SB_HEALING,
OT_SB_HEALINGMIN, OT_SB_HEALINGMIN,
OT_SB_TURNUNDEAD, OT_SB_TURNUNDEAD,
// -- mental // -- mental / psionic
OT_SB_MINDSCAN, OT_SB_MINDSCAN,
OT_SB_TELEKINESIS, OT_SB_TELEKINESIS,
OT_SB_PSYARMOUR,
// -- modification // -- modification
OT_SB_GASEOUSFORM, OT_SB_GASEOUSFORM,
OT_SB_KNOCK, OT_SB_KNOCK,
@ -705,6 +727,7 @@ enum OBTYPE {
// -- death // -- death
OT_S_ANIMATEDEAD, OT_S_ANIMATEDEAD,
OT_S_PAIN, OT_S_PAIN,
OT_S_PARALYZE,
OT_S_INFINITEDEATH, OT_S_INFINITEDEATH,
OT_S_WEAKEN, OT_S_WEAKEN,
OT_S_BLINDNESS, OT_S_BLINDNESS,
@ -715,6 +738,7 @@ enum OBTYPE {
OT_S_IDENTIFY, OT_S_IDENTIFY,
OT_S_MAPPING, OT_S_MAPPING,
// -- elemental - air // -- elemental - air
OT_S_AIRBLAST,
OT_S_CLOUDKILL, OT_S_CLOUDKILL,
// -- elemental - fire // -- elemental - fire
OT_S_SPARK, OT_S_SPARK,
@ -727,17 +751,21 @@ enum OBTYPE {
OT_S_CONECOLD, OT_S_CONECOLD,
OT_S_FREEZEOB, OT_S_FREEZEOB,
// -- gravity // -- gravity
OT_S_GRAVLOWER,
OT_S_GRAVBOOST, OT_S_GRAVBOOST,
OT_S_HASTE, OT_S_HASTE,
OT_S_SLOW, OT_S_SLOW,
OT_S_LEVITATION,
OT_S_FLIGHT,
// -- life // -- life
OT_S_HEALING, OT_S_HEALING,
OT_S_HEALINGMIN, OT_S_HEALINGMIN,
OT_S_TURNUNDEAD, OT_S_TURNUNDEAD,
// -- mental // -- mental / psionic
OT_S_MINDSCAN, OT_S_MINDSCAN,
OT_S_SLEEP, OT_S_SLEEP,
OT_S_TELEKINESIS, OT_S_TELEKINESIS,
OT_S_PSYARMOUR,
// -- modification // -- modification
OT_S_ENCHANT, OT_S_ENCHANT,
OT_S_GASEOUSFORM, OT_S_GASEOUSFORM,
@ -776,6 +804,7 @@ enum OBTYPE {
OT_A_EMPLOY, OT_A_EMPLOY,
OT_A_HEAVYBLOW, OT_A_HEAVYBLOW,
OT_A_INSPECT, OT_A_INSPECT,
OT_A_STINGACID, // need to define dam in f_canwill
// wands // wands
OT_WAND_COLD, OT_WAND_COLD,
OT_WAND_DETONATION, OT_WAND_DETONATION,
@ -826,11 +855,14 @@ enum OBTYPE {
OT_ICESHEET, OT_ICESHEET,
OT_PUDDLEWATER, OT_PUDDLEWATER,
OT_PUDDLEWATERL, OT_PUDDLEWATERL,
OT_ACIDPUDDLE,
OT_ACIDPOOL,
OT_SLIMEPOOL, OT_SLIMEPOOL,
OT_VOMITPOOL, OT_VOMITPOOL,
OT_BLOODSTAIN, OT_BLOODSTAIN,
OT_BLOODSPLASH, OT_BLOODSPLASH,
OT_BLOODPOOL, OT_BLOODPOOL,
OT_BLOODCSPLASH,
OT_MELTEDWAX, OT_MELTEDWAX,
OT_SOGGYPAPER, OT_SOGGYPAPER,
OT_FLESHCHUNK, OT_FLESHCHUNK,
@ -839,6 +871,8 @@ enum OBTYPE {
OT_FIREMED, OT_FIREMED,
OT_FIRESMALL, OT_FIRESMALL,
OT_MAGICBARRIER, OT_MAGICBARRIER,
OT_STEAMCLOUD,
OT_STEAMPUFF,
OT_SMOKECLOUD, OT_SMOKECLOUD,
OT_SMOKEPUFF, OT_SMOKEPUFF,
OT_POISONCLOUD, OT_POISONCLOUD,
@ -899,8 +933,10 @@ enum OBTYPE {
// animal weapons // animal weapons
OT_CLAWS, OT_CLAWS,
OT_FISTS, OT_FISTS,
OT_STING,
OT_TAIL, OT_TAIL,
OT_TEETH, OT_TEETH,
OT_TEETHSM,
OT_TENTACLE, OT_TENTACLE,
OT_ZAPPER, OT_ZAPPER,
// monster weapons // 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_ACTIVATECONFER, // gives flag v0+v1 when activated. v2 specifies if it must be id'd.
F_HITCONFER, // hitting with this gives flagid=v0 F_HITCONFER, // hitting with this gives flagid=v0
// with flagval0 = val1 // unless you pass a val1 skillcheck, diff val2
// with flagval1 = val2
// with timeleft = text ("min-max") // with timeleft = text ("min-max")
F_ACTIVATED, // val0 = is this object turned on? F_ACTIVATED, // val0 = is this object turned on?
F_GRENADE, // this obkejct will drain charge when activated, then die 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_MASTERWORK, // weps do higher damager, armour protects better
F_SHODDY, // weps do less damage, armour protects less. F_SHODDY, // weps do less damage, armour protects less.
// weapon flags // weapon flags
F_ATTACKVERB, // text=verb for attacking. ie. "hit" "slash" "sting" etc
F_OBATTACKDELAY, // how long weapon takes to attack F_OBATTACKDELAY, // how long weapon takes to attack
F_USESSKILL, // weapon needs skill sk_v0 F_USESSKILL, // weapon needs skill sk_v0
F_CANHAVEOBMOD, // weapon can have obmod om_v0 applied
F_DAMTYPE, // val0 = damage type F_DAMTYPE, // val0 = damage type
F_DAM, // val0 = ndice, val1 = nsidesondie, val2 = mod F_DAM, // val0 = ndice, val1 = nsidesondie, val2 = mod
F_MISSILEDAM, // val0 = dam if it hits (without speed multiplier) 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_NOOBDAMTEXT, // don't anounce damage to this object
F_NOOBDIETEXT, // don't anounce destruction of this object F_NOOBDIETEXT, // don't anounce destruction of this object
F_NODIECONVERTTEXT, // don't anounce when this object changes F_NODIECONVERTTEXT, // don't anounce when this object changes
// misc flags
F_LINKOB, // val0 = linked object id
// scroll flags // scroll flags
F_LINKSPELL, // val0 = spell this scroll will cast when read F_LINKSPELL, // val0 = spell this scroll will cast when read
// v1 = spell power // v1 = spell power
@ -1158,12 +1197,15 @@ enum FLAG {
F_HASHIDDENNAME, // whether this object class has a hidden name F_HASHIDDENNAME, // whether this object class has a hidden name
F_IDENTIFIED, // whether this object is fully identified F_IDENTIFIED, // whether this object is fully identified
// bad flags // bad flags
F_WALKDAM, // val0 = dam per sec, val1 = damtype F_WALKDAM, // val0 = damtype, text = dam per sec
// magic // abilities
F_NEEDSGRAB, // this ability needs to to grab someone first.
// magic
F_SPELLSCHOOL, // val0 = SPELLSCHOOL enum F_SPELLSCHOOL, // val0 = SPELLSCHOOL enum
F_SPELLLEVEL, // val0 = difficulty level of spell F_SPELLLEVEL, // val0 = difficulty level of spell
F_MAXPOWER, // val0 = max power of this spell (1-10) F_MAXPOWER, // val0 = max power of this spell (1-10)
F_MPCOST, // v0=mp cost of spell. if missing, mpcost if splev^2 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_SPELLLETTER, // text[0] = letter to cast this spell
F_AICASTTOFLEE, // AI can cast this spell to help flee F_AICASTTOFLEE, // AI can cast this spell to help flee
// v0 is who to target // v0 is who to target
@ -1205,8 +1247,9 @@ enum FLAG {
F_GUNTARGET, // current projectile weapon target F_GUNTARGET, // current projectile weapon target
F_CASTINGSPELL, // set while the player is casting a spell F_CASTINGSPELL, // set while the player is casting a spell
// v0 is spell id // v0 is spell id
// ABILITY FLAGS // ABILITY/SPELL FLAGS
F_FAILEDINSPECT, // lf has failed an inspect check for item id v0 F_FAILEDINSPECT, // lf has failed an inspect check for item id v0
F_BOOSTSPELL, // v0 is active boost spell
// MONSTER AI FLAGS // MONSTER AI FLAGS
F_XPVAL, // force xp val for killing this lf to v0 F_XPVAL, // force xp val for killing this lf to v0
F_HOSTILE, // lf will attack the player if in sight F_HOSTILE, // lf will attack the player if in sight
@ -1260,6 +1303,7 @@ enum FLAG {
F_NOPACK, // this race cannot hold objects F_NOPACK, // this race cannot hold objects
F_NOSPELLS, // this race cannot cast spells F_NOSPELLS, // this race cannot cast spells
F_INDUCEFEAR, // causes fear when you attack it 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 F_AUTOCREATEOB, // produces obtype 'text' wherever it walks, v0=radius
// (only if ob of that type not already there) // (only if ob of that type not already there)
F_PACKATTACK, // deal v0 extra damage of type v1 if there are F_PACKATTACK, // deal v0 extra damage of type v1 if there are
@ -1267,13 +1311,17 @@ enum FLAG {
// to the victim // to the victim
F_PHALANX, // gain v0 AR if v2 or more adj monsters matching f->text F_PHALANX, // gain v0 AR if v2 or more adj monsters matching f->text
// INTRINSICS // INTRINSICS
F_ARBOOST,// armour is magically boosted
F_ASLEEP, // is asleep F_ASLEEP, // is asleep
F_BEINGSTONED,// turn to stone when v0 drops to zero. (drops 1/turn)
F_BLIND, // cannot see anything F_BLIND, // cannot see anything
F_CANCAST, // can cast the spell val0 (need MP) F_CANCAST, // can cast the spell val0 (need MP)
F_CANWILL, // can cast the spell val0 without using MP F_CANWILL, // can cast the spell val0 without using MP
// v1 is counter untiluse // v1 is counter untiluse
// v2 is what you need to use it // v2 is what you need to use it
// ie. when v1 == v2, ability is ready. // 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_DETECTAURAS, // autodetect bless/curse
F_DETECTLIFE, // autodetect nearby lifeforms in orthogonal dist v0 F_DETECTLIFE, // autodetect nearby lifeforms in orthogonal dist v0
F_DETECTMAGIC, // autodetect magic/special objects F_DETECTMAGIC, // autodetect magic/special objects
@ -1282,7 +1330,7 @@ enum FLAG {
F_FLYING, // lf is flying F_FLYING, // lf is flying
F_FASTACT, // modifier for action speed F_FASTACT, // modifier for action speed
F_FASTMOVE, // modifier for move 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_FREEZINGTOUCH,// next thing touched turns to ice!
F_GRABBEDBY,// you've been grabbed by lf id v0 F_GRABBEDBY,// you've been grabbed by lf id v0
F_GRABBING, // you are grabbing 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 F_QUICKBITE, // deals v0 d d1 + d2 damage when you hit a bleeding victim
// (bypasses armour) // (bypasses armour)
F_GRAVBOOSTED,// cannot walk or throw stuff 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_PARALYZED,// cannot do anything
F_FROZEN, // made of ice F_FROZEN, // made of ice
F_LEVITATING, // like flying but uncontrolled F_LEVITATING, // like flying but uncontrolled
@ -1302,7 +1350,7 @@ enum FLAG {
F_OMNIPOTENT, // knows extra info F_OMNIPOTENT, // knows extra info
F_PHOTOMEM, // you don't forget your surroundings F_PHOTOMEM, // you don't forget your surroundings
F_REGENERATES, // regenerate HP at val0 per turn 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_MPREGEN, // regenerate MP at val0 per turn
F_SEEINDARK, // nightvis range is val0 F_SEEINDARK, // nightvis range is val0
F_SEEINVIS, // can see invisible things F_SEEINVIS, // can see invisible things
@ -1329,12 +1377,14 @@ enum FLAG {
// damage (x y-sided dice + z) // damage (x y-sided dice + z)
F_EVASION, // % chance of evading an attack F_EVASION, // % chance of evading an attack
// healing // healing/resting/training
F_STATGAINREADY, // ready to increase str/int etc. v2 is how many times F_STATGAINREADY, // ready to increase str/int etc. v2 is how many times
// we can do it. // we can do it.
F_RESTING, // are we resting? cleared on any action other than rest. F_RESTING, // are we resting? cleared on any action other than rest.
// v2 = if not, NA it is the training counter. // v2 = if not, NA it is the training counter.
// when it hits 0, you finish trainign. // 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? F_RUNNING, // are we running?
// nutrition // nutrition
@ -1476,6 +1526,7 @@ enum ERROR {
E_CANTMOVE = 34, E_CANTMOVE = 34,
E_NOTKNOWN = 35, E_NOTKNOWN = 35,
E_TOOPOWERFUL = 36, E_TOOPOWERFUL = 36,
E_NEEDGRAB = 37,
}; };
@ -1547,6 +1598,7 @@ typedef struct cell_s {
struct obpile_s *obpile; struct obpile_s *obpile;
enum LIGHTLEV lit; enum LIGHTLEV lit;
enum LIGHTLEV origlit; enum LIGHTLEV origlit;
int origlittimer;
int littimer; int littimer;
char *writing; char *writing;
@ -1680,8 +1732,10 @@ enum SKILL {
SK_ATHLETICS, SK_ATHLETICS,
SK_FIRSTAID, SK_FIRSTAID,
SK_LOCKPICKING, SK_LOCKPICKING,
SK_MAGITEMUSAGE,
SK_RESEARCH, SK_RESEARCH,
SK_SPELLCASTING, SK_SPELLCASTING,
SK_TECHUSAGE,
// weaponry // weaponry
SK_AXES, SK_AXES,
SK_CLUBS, SK_CLUBS,
@ -1704,7 +1758,6 @@ enum SKILL {
SK_SS_SUMMONING, SK_SS_SUMMONING,
SK_SS_TRANSLOCATION, SK_SS_TRANSLOCATION,
SK_SS_WILD, SK_SS_WILD,
SK_TECHUSAGE,
}; };
#define MAXSKILLS 31 #define MAXSKILLS 31
@ -1794,6 +1847,7 @@ enum OBMOD {
OM_FROZEN, OM_FROZEN,
OM_HEADLESS, OM_HEADLESS,
OM_MASTERWORK, OM_MASTERWORK,
OM_POISONED,
OM_SHODDY, OM_SHODDY,
}; };
#define MAXOBMODS 4 #define MAXOBMODS 4

View File

@ -5,7 +5,8 @@ objects.c:
add an addmaterial() line add an addmaterial() line
update adjustdammaterial() as required update adjustdammaterial() as required
update getmaterialvalue() update getmaterialvalue()
update issolidmat() update getmaterialstate()
update ismetal() update ismetal()
update willshatter()

View File

@ -1,11 +1,11 @@
defs.h: defs.h:
add the OT_xxx enum add the OT_xxx enum
(optional) add a scroll 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 (optional) add a potion to do the same effect - not for boosts though
objects.c: objects.c:
define the spell 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 scroll to do the same effect, use F_LINKSPELL
(optional) add a potion to do the same effect (optional) add a potion to do the same effect
(optional) add a spellbook to learn it (optional) add a spellbook to learn it
@ -22,4 +22,5 @@ spell.c:
ai.c ai.c
update aigetspelltarget(); update aigetspelltarget();
update aigetattackspell(); update aigetattackspell();
update aispellok();

40
flag.c
View File

@ -6,6 +6,7 @@
#include "io.h" #include "io.h"
#include "lf.h" #include "lf.h"
#include "objects.h" #include "objects.h"
#include "spell.h"
#include "text.h" #include "text.h"
extern enum GAMEMODE gamemode; 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; known = B_KNOWN;
} }
if ((id == F_POISONED) && isimmuneto(fp, DT_POISON)) {
return NULL;
}
// certain flags stack... // certain flags stack...
if (flagstacks(id)) { if (flagstacks(id)) {
f = hasflag(fp, 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) { if ((gamemode == GM_GAMESTARTED) && doredraw) {
statdirty = B_TRUE; statdirty = B_TRUE;
needredraw = B_TRUE; needredraw = B_TRUE;
@ -192,20 +211,20 @@ int flagstacks(enum FLAG fid) {
} }
flag_t *hasflag(flagpile_t *fp, int id) { 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) { 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; flag_t *f;
lifeform_t *owner; lifeform_t *owner;
owner = fp->owner; owner = fp->owner;
for (f = fp->first ; f ; f = f->next) { for (f = fp->first ; f ; f = f->next) {
if (f->id == id) { if ((f->id == id) && (f != exception)) {
int valid = B_TRUE; int valid = B_TRUE;
if ((wantknown != NA) && (f->known != wantknown)) valid = B_FALSE; if ((wantknown != NA) && (f->known != wantknown)) valid = B_FALSE;
if (owner && (f->lifetime == FROMJOB) && !getjob(owner)) { 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) { void sumflags(flagpile_t *fp, int id, int *val0, int *val1, int *val2) {

2
flag.h
View File

@ -10,7 +10,7 @@ void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
int flagstacks(enum FLAG fid); int flagstacks(enum FLAG fid);
flag_t *hasflag(flagpile_t *fp, int id); flag_t *hasflag(flagpile_t *fp, int id);
flag_t *hasflagknown(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 *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 *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); flag_t *hasflagval_real(flagpile_t *fp, int id, int val1, int val2, int val3, char *text, int wantknown);

305
io.c
View File

@ -664,10 +664,18 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
} }
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_ARBOOST:
msg("A magical shield appears around %s!",lfname);
donesomething = B_TRUE;
break;
case F_ASLEEP: case F_ASLEEP:
msg("%s fall%s asleep.",lfname, isplayer(lf) ? "" : "s"); msg("%s fall%s asleep.",lfname, isplayer(lf) ? "" : "s");
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_BEINGSTONED:
msg("%s begin%s to turn to stone!",lfname, isplayer(lf) ? "" : "s");
donesomething = B_TRUE;
break;
case F_BLIND: case F_BLIND:
if (isplayer(lf)) { if (isplayer(lf)) {
msg("%s cannot see!",lfname); msg("%s cannot see!",lfname);
@ -685,6 +693,15 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
} }
} }
break; 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: case F_DTIMMUNE:
if (isplayer(lf)) { // don't know if monsters get it if (isplayer(lf)) { // don't know if monsters get it
msg("You feel immune to %s!", getdamnamenoun(f->val[0])); 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; donesomething = B_TRUE;
} }
break; 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: case F_DETECTAURAS:
if (isplayer(lf)) { // don't know if monsters get it if (isplayer(lf)) { // don't know if monsters get it
msg("You feel aware of spiritual auras around you."); 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"); cansee(player, lf2) ? buf : "something");
} }
break; break;
case F_FOODPOISONED: case F_POISONED:
if (isplayer(lf)) { // don't know if monsters get it if (isplayer(lf)) { // don't know if monsters get it
msg("You feel very sick."); msg("You feel very sick.");
donesomething = B_TRUE; donesomething = B_TRUE;
@ -862,7 +867,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
break; break;
case F_RESISTMAG: case F_RESISTMAG:
if (isplayer(lf)) { // don't know if monsters get it 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; donesomething = B_TRUE;
} }
break; break;
@ -993,16 +998,24 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
case F_ARBOOST:
msg("%s%s magical shield vanishes.",lfname,getpossessive(lfname));
donesomething = B_TRUE;
break;
case F_ASLEEP: case F_ASLEEP:
msg("%s wake%s up.",lfname, isplayer(lf) ? "" : "s"); msg("%s wake%s up.",lfname, isplayer(lf) ? "" : "s");
donesomething = B_TRUE; donesomething = B_TRUE;
break; 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: case F_BLIND:
msg("%s can see again.",lfname); msg("%s can see again.",lfname);
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_CANCAST: 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; objecttype_t *ot;
ot = findot(f->val[0]); ot = findot(f->val[0]);
if (ot) { if (ot) {
@ -1011,6 +1024,16 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
} }
} }
break; 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: case F_DTIMMUNE:
if (isplayer(lf)) { // don't know if monsters lose it if (isplayer(lf)) { // don't know if monsters lose it
msg("You are no longer immune to %s.", getdamnamenoun(f->val[0])); 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"); msg("%s stop%s fleeing.", lfname, isplayer(lf) ? "" : "s");
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_FOODPOISONED: case F_POISONED:
if (isplayer(lf)) { // don't know if monsters lose it if (isplayer(lf)) { // don't know if monsters lose it
msg("You feel less sick now."); msg("You feel less sick now.");
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; 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: case F_DODGES:
if (isplayer(lf)) { // don't know if monsters lose it if (isplayer(lf)) { // don't know if monsters lose it
msg("You can no longer dodge attacks."); msg("You can no longer dodge attacks.");
@ -1154,8 +1165,10 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_PAIN: case F_PAIN:
msg("%s skin returns to normal.",lfname, getpossessive(lfname)); if (isplayer(lf)) { // don't konw if it expires for monsters
donesomething = B_TRUE; msg("Your skin stops hurting.");
donesomething = B_TRUE;
}
break; break;
case F_PARALYZED: case F_PARALYZED:
if (isplayer(lf)) { // don't konw if it expires for monsters if (isplayer(lf)) { // don't konw if it expires for monsters
@ -1181,7 +1194,11 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
break; break;
case F_RESISTMAG: case F_RESISTMAG:
if (isplayer(lf)) { // don't know if monsters lose it 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; donesomething = B_TRUE;
} }
break; break;
@ -2217,6 +2234,13 @@ void describeob(object_t *o) {
y++; 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... // now special flags...
y++; y++;
@ -2373,7 +2397,8 @@ void describeob(object_t *o) {
mvwprintw(mainwin, y, 0, "%s allows you to regenerate health%s.", buf,buf2); y++; mvwprintw(mainwin, y, 0, "%s allows you to regenerate health%s.", buf,buf2); y++;
break; break;
case F_RESISTMAG: 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; break;
case F_SEEINVIS: case F_SEEINVIS:
mvwprintw(mainwin, y, 0, "%s allows you to see invisible things.", buf); y++; mvwprintw(mainwin, y, 0, "%s allows you to see invisible things.", buf); y++;
@ -2424,6 +2449,14 @@ void describeob(object_t *o) {
} }
y++; 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)) { if (hasflag(o->flags, F_NOBLESS)) {
mvwprintw(mainwin, y, 0, "%s cannot be blessed or cursed.", (o->amt == 1) ? "It" : "They" ); mvwprintw(mainwin, y, 0, "%s cannot be blessed or cursed.", (o->amt == 1) ? "It" : "They" );
y++; y++;
@ -2484,9 +2517,13 @@ void describespell(objecttype_t *ot) {
y++; y++;
} }
i = getmpcost(ot->id); i = getmpcost(NULL, ot->id);
if (i > 0) { 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++; y++;
} }
@ -2983,6 +3020,7 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2)
int mpcost[MAXCANDIDATES]; int mpcost[MAXCANDIDATES];
char mpdesc[MAXCANDIDATES][BUFLEN]; char mpdesc[MAXCANDIDATES][BUFLEN];
int validspell[MAXCANDIDATES]; int validspell[MAXCANDIDATES];
int deactspell[MAXCANDIDATES];
int nposs = 0; int nposs = 0;
int i,n; int i,n;
enum SPELLSCHOOL lastschool; enum SPELLSCHOOL lastschool;
@ -2997,6 +3035,7 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2)
if (f) { if (f) {
if (hasflagval(ot->flags, F_SPELLSCHOOL, i, NA, NA, NULL)) { if (hasflagval(ot->flags, F_SPELLSCHOOL, i, NA, NA, NULL)) {
poss[nposs] = ot->id; poss[nposs] = ot->id;
deactspell[nposs] = B_FALSE; // default
mpcost[nposs] = -1; mpcost[nposs] = -1;
if (f->val[2] == NA) { if (f->val[2] == NA) {
sprintf(mpdesc[nposs], "(ready)"); 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)) { if (lfhasflagval(lf, F_CANCAST, ot->id, NA, NA, NULL)) {
int cost; int cost;
int found = B_FALSE; int found = B_FALSE;
cost = getmpcost(ot->id); cost = getmpcost(lf, ot->id);
for (n = 0; n < nposs; n++) { for (n = 0; n < nposs; n++) {
if (poss[n] == ot->id) { if (poss[n] == ot->id) {
found = B_TRUE; found = B_TRUE;
@ -3040,10 +3079,22 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2)
// add to list // add to list
poss[nposs] = ot->id; poss[nposs] = ot->id;
mpcost[nposs] = cost; mpcost[nposs] = cost;
deactspell[nposs] = B_FALSE; // default
power = getspellpower(lf, ot->id); power = getspellpower(lf, ot->id);
if (power > 0) { 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; validspell[nposs] = B_TRUE;
} else { } else {
validspell[nposs] = B_FALSE; 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); getspellname(ot->id, player, buf2);
if (deactspell[i]) {
strcat(buf2, "/deact");
}
if (validspell[i]) { if (validspell[i]) {
strcpy(costbuf, ""); strcpy(costbuf, "");
@ -3609,23 +3664,50 @@ void dorest(void) {
} }
// if not training, only rest if we need to. // if not training, only rest if we need to.
if (!willtrain) { if (!willtrain) {
if (player->hp >= player->maxhp) { char validchars[BUFLEN];
char norestmsg[BUFLEN]; char ques[BUFLEN];
strcpy(norestmsg, ""); char ch;
if (player->maxmp > 0) { strcpy(validchars, "");
if (player->mp >= player->maxmp) { if (player->hp < player->maxhp) {
// no need to rest strcat(validchars, "h");
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;
}
} }
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); startresting(player, willtrain);
// do the first one right away // do the first one right away
@ -4225,8 +4307,10 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
// display prompt question // display prompt question
sprintf(promptstr, "%s %s %s", sprintf(promptstr, "%s [%s%s] %s",
prompt->q[prompt->whichq], prompt->maycancel ? "[ESC=cancel, '=next page] " : "", prompt->q[prompt->whichq],
prompt->maycancel ? "ESC," : "",
showall ? "'=next page,?=toggle" : "?=list",
inpstring); inpstring);
mvwprintw(mainwin, 0, 0, "%s", promptstr); mvwprintw(mainwin, 0, 0, "%s", promptstr);
wclrtoeol(mainwin); wclrtoeol(mainwin);
@ -4853,6 +4937,7 @@ void drawstatus(void) {
char buf2[BUFLEN]; char buf2[BUFLEN];
char waitbuf[BUFLEN]; char waitbuf[BUFLEN];
char pname[BUFLEN]; char pname[BUFLEN];
char maxmpstr[BUFLEN];
flag_t *f; flag_t *f;
int str,dex,iq,con; int str,dex,iq,con;
long xpleft; long xpleft;
@ -4902,8 +4987,8 @@ void drawstatus(void) {
} }
// show certain flags // show certain flags
if (lfhasflag(player, F_FOODPOISONED)) { if (lfhasflag(player, F_POISONED)) {
strcat(buf, " Sick"); strcat(buf, " Poisoned");
} }
mvwprintw(statwin, 0, 0, buf); mvwprintw(statwin, 0, 0, buf);
@ -4954,9 +5039,16 @@ void drawstatus(void) {
iq = getattr(player, A_IQ); iq = getattr(player, A_IQ);
con = getattr(player, A_CON); con = getattr(player, A_CON);
//redraw(); //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->hp,player->maxhp,
player->mp, player->maxmp, player->mp, getmaxmp(player), maxmpstr,
countmoney(player), countmoney(player),
str, (str == player->baseatt[A_STR]) ? ' ' : '*', str, (str == player->baseatt[A_STR]) ? ' ' : '*',
dex, (dex == player->baseatt[A_DEX]) ? ' ' : '*', dex, (dex == player->baseatt[A_DEX]) ? ' ' : '*',
@ -5227,8 +5319,16 @@ void showlfstats(lifeform_t *lf, int showall) {
} }
} }
if (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"); 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) { if (showall) {
mvwprintw(mainwin, y, 0, ftext, "Exp Level"); 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"); mvwprintw(mainwin, y, 0, "%s %s sleeping.", you(lf), isplayer(lf) ? "are" : "is");
y++; 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); f = lfhasknownflag(lf, F_FLYING);
if (f && (f->known)) { 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); f = lfhasknownflagval(lf, F_CANWILL, ot->id, NA, NA, NULL);
if (f && (f->known)) { if (f && (f->known)) {
char expirebuf[BUFLEN]; char expirebuf[BUFLEN];
char eb2[BUFLEN];
int needgrab = B_FALSE;
if (f->val[2] == NA) { if (f->val[2] == NA) {
sprintf(expirebuf, " (at will)"); sprintf(expirebuf, "at will");
} else { } else {
sprintf(expirebuf, " (every %d turn%s)",f->val[2], sprintf(expirebuf, "every %d turn%s",f->val[2],
(f->val[2] == 1) ? "" : "s"); (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); mvwprintw(mainwin, y, 0, buf);
if (downline(&y, h, "ABILITIES", NULL, prompt, cmdchars, &ch)) { if (downline(&y, h, "ABILITIES", NULL, prompt, cmdchars, &ch)) {
exitnow = B_TRUE; exitnow = B_TRUE;
@ -5798,10 +5919,11 @@ void showlfstats(lifeform_t *lf, int showall) {
centre(mainwin, y, "SKILLS"); y += 2; centre(mainwin, y, "SKILLS"); y += 2;
for (f = lf->flags->first ; f ; f = f->next) { for (f = lf->flags->first ; f ; f = f->next) {
if (f->id == F_HASSKILL) { 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]) ? '*' : '-', ismaxedskill(lf, f->val[0]) ? '*' : '-',
getskilllevelname(f->val[1]), getskillname(f->val[0]), getskillname(f->val[0]),
ismaxedskill(lf, f->val[0]) ? " (max)" : ""); getskilllevelname(f->val[1]),
ismaxedskill(lf, f->val[0]) ? "/MAX" : "");
if (downline(&y, h, "SKILLS", NULL, prompt, cmdchars, &ch)) { if (downline(&y, h, "SKILLS", NULL, prompt, cmdchars, &ch)) {
exitnow = B_TRUE; exitnow = B_TRUE;
break; break;
@ -5837,11 +5959,27 @@ void showlfstats(lifeform_t *lf, int showall) {
char mpbuf[BUFLEN]; char mpbuf[BUFLEN];
int power; int power;
int mpcost; int mpcost;
mpcost = getmpcost(ot->id); if (f->id == F_CANWILL) {
if (mpcost) { mpcost = 0;
sprintf(mpbuf, "%d MP", mpcost);
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 { } 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); power = getspellpower(lf, ot->id);
@ -5895,6 +6033,13 @@ void showlfstats(lifeform_t *lf, int showall) {
y++; 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); f = lfhasknownflag(lf, F_NOPACK);
if (f && (f->known)) { if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s cannot carry objects.", you(lf)); 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)); mvwprintw(mainwin, y, 0, "%s receive enhanced knowledge about the world.", you(lf));
y++; y++;
} }
f = lfhasknownflag(lf, F_FOODPOISONED); f = lfhasknownflag(lf, F_POISONED);
if (f && (f->known)) { 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)) { if (lfhasflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT)) {
char buf2[BUFLEN]; char buf2[BUFLEN];
sprintf(buf2, " [%d left]", f->lifetime); sprintf(buf2, " [%d left]", f->lifetime);
@ -6041,7 +6186,21 @@ void showlfstats(lifeform_t *lf, int showall) {
} }
f = lfhasknownflag(lf, F_RESISTMAG); f = lfhasknownflag(lf, F_RESISTMAG);
if (f) { 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++; y++;
} }
f = lfhasknownflag(lf, F_TIRED); f = lfhasknownflag(lf, F_TIRED);

615
lf.c

File diff suppressed because it is too large Load Diff

5
lf.h
View File

@ -78,7 +78,9 @@ char getlfglyph(lifeform_t *lf);
enum MATERIAL getlfmaterial(lifeform_t *lf); enum MATERIAL getlfmaterial(lifeform_t *lf);
float getmaxcarryweight(lifeform_t *lf); float getmaxcarryweight(lifeform_t *lf);
float getmaxliftweight(lifeform_t *lf); float getmaxliftweight(lifeform_t *lf);
int getmaxmp(lifeform_t *lf);
float getmaxpushweight(lifeform_t *lf); float getmaxpushweight(lifeform_t *lf);
int getmr(lifeform_t *lf);
int getvisrange(lifeform_t *lf); int getvisrange(lifeform_t *lf);
int getmovespeed(lifeform_t *lf); int getmovespeed(lifeform_t *lf);
char *getmoveverb(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); void givestartskills(lifeform_t *lf, flagpile_t *fp);
map_t *gotolev(lifeform_t *lf, int depth, object_t *fromstairs); map_t *gotolev(lifeform_t *lf, int depth, object_t *fromstairs);
job_t *hasjob(lifeform_t *lf, enum JOB job); 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 *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 *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 *lfhasknownflag(lifeform_t *lf, enum FLAG fid);
flag_t *lfhasknownflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text); 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); int lockpick(lifeform_t *lf, object_t *target, object_t *device);
void loseobflags(lifeform_t *lf, object_t *o, int kind); 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 haslof(lifeform_t *viewer, cell_t *dest);
int haslos(lifeform_t *viewer, cell_t *dest); int haslos(lifeform_t *viewer, cell_t *dest);
int hasmr(lifeform_t *lf);
void initjobs(void); void initjobs(void);
void initrace(void); void initrace(void);
void initskills(void); void initskills(void);

9975
log.txt

File diff suppressed because it is too large Load Diff

5
map.c
View File

@ -34,6 +34,7 @@ cell_t *addcell(map_t *m, int x, int y) {
cell->lit = L_NOTLIT; cell->lit = L_NOTLIT;
cell->origlit = L_NOTLIT; cell->origlit = L_NOTLIT;
cell->littimer = 0; cell->littimer = 0;
cell->origlittimer = 0;
cell->writing = NULL; cell->writing = NULL;
cell->known = B_FALSE; cell->known = B_FALSE;
return cell; return cell;
@ -2092,8 +2093,10 @@ void makelit(cell_t *c, enum LIGHTLEV how, int howlong) {
} }
} }
if (howlong > 0) { if (howlong > 0) {
c->littimer = howlong; // TODO: use a stack here instead
c->origlit = c->lit; c->origlit = c->lit;
c->origlittimer = c->littimer;
c->littimer = howlong;
} }
c->lit = how; c->lit = how;
} }

81
move.c
View File

@ -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 // returns TRUE if something happened
@ -468,9 +490,14 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
lifeform_t *l; lifeform_t *l;
int didmsg = B_FALSE; int didmsg = B_FALSE;
flag_t *f; flag_t *f;
int changedlev = B_FALSE;
getlfname(lf, lfname); getlfname(lf, lfname);
if (newcell->map != lf->cell->map) {
changedlev = B_TRUE;
}
// update current cell // update current cell
lf->cell->lf = NULL; lf->cell->lf = NULL;
@ -491,20 +518,13 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
// update new cell // update new cell
newcell->lf = lf; newcell->lf = lf;
if (isbleeding(lf)) { // update light
if (rnd(1,2) == 1) { if (changedlev && isplayer(lf)) {
bleed(lf); calclight(lf->cell->map);
}
}
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);
}
} }
moveeffects(lf);
// remove grabs // remove grabs
f = lfhasflag(lf, F_GRABBING); f = lfhasflag(lf, F_GRABBING);
if (f) { if (f) {
@ -617,6 +637,8 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose) {
dontclearmsg = B_TRUE; dontclearmsg = B_TRUE;
} }
assert(!newcell->lf);
getlfname(lf, lfname); getlfname(lf, lfname);
// is current cell dark? // is current cell dark?
@ -870,7 +892,8 @@ int closedoor(lifeform_t *lf, object_t *o) {
if (lf && isplayer(lf)) { if (lf && isplayer(lf)) {
char inwayname[BUFLEN]; char inwayname[BUFLEN];
getobname(oo, inwayname, oo->amt); 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; return B_TRUE;
} }
@ -1029,13 +1052,15 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
} }
// slipping on blood before moving? // slipping on blood before moving?
slip = getslipperyness(lf->cell, &slipob); if (!isairborne(lf)) {
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) { slip = getslipperyness(lf->cell, &slipob);
slipon(lf, slipob); if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
// don't move slipon(lf, slipob);
reason = E_OK; // don't move
return B_FALSE; reason = E_OK;
} return B_FALSE;
}
}
// move to new cell // move to new cell
reason = E_OK; reason = E_OK;
@ -1043,13 +1068,15 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
taketime(lf, getmovespeed(lf)); taketime(lf, getmovespeed(lf));
// slip on blood in new cell? // slip on blood in new cell?
slip = getslipperyness(cell, &slipob); if (!isairborne(lf)) {
if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) { slip = getslipperyness(cell, &slipob);
slipon(lf, slipob); if (slip && !skillcheck(lf, SC_SLIP, slip, 0)) {
// don't move slipon(lf, slipob);
reason = E_OK; // don't move
return B_FALSE; reason = E_OK;
} return B_FALSE;
}
}
} else { } else {
object_t *inway; object_t *inway;
int door, dooropen; int door, dooropen;

1
move.h
View File

@ -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 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 knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher);
int moveawayfrom(lifeform_t *lf, cell_t *dst); int moveawayfrom(lifeform_t *lf, cell_t *dst);
void moveeffects(lifeform_t *lf);
int movelf(lifeform_t *lf, cell_t *newcell); int movelf(lifeform_t *lf, cell_t *newcell);
int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose); int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose);
int movetowards(lifeform_t *lf, cell_t *dst); int movetowards(lifeform_t *lf, cell_t *dst);

18
nexus.c
View File

@ -120,6 +120,10 @@ int main(int argc, char **argv) {
// find staircase // find staircase
where = findobinmap(firstmap, OT_STAIRSUP); where = findobinmap(firstmap, OT_STAIRSUP);
assert(where); assert(where);
// make sure no lifeforms are there
if (where->lf) {
killlf(where->lf);
}
// add player // add player
real_addlf(where, R_HUMAN, 1, C_PLAYER); // this will assign '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; res = (rand() % (max - min + 1)) + min;
return res; 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 // get a random number
int rolldie(int ndice, int sides) { int rolldie(int ndice, int sides) {
int i; int i;
@ -883,10 +897,6 @@ void timeeffectsworld(map_t *map) {
// now handle effects on lifeforms and/or their objects // now handle effects on lifeforms and/or their objects
for (l = map->lf ; l ; l = l->next) { for (l = map->lf ; l ; l = l->next) {
timeeffectslf(l); timeeffectslf(l);
for (o = l->pack->first ; o ; o = nexto) {
nexto = o->next;
timeeffectsob(o);
}
} }
//dblog("AFTER SORT AND ADJUST....."); //dblog("AFTER SORT AND ADJUST.....");

View File

@ -15,6 +15,7 @@ int isplayerturn(void);
int limit(int *what, int min, int max); int limit(int *what, int min, int max);
float pctof(float pct, float num); float pctof(float pct, float num);
int rnd(int min, int max); int rnd(int min, int max);
int roll(char *string);
int rolldie(int ndice, int sides); int rolldie(int ndice, int sides);
int rollhitdice(lifeform_t *lf); int rollhitdice(lifeform_t *lf);
int rollmpdice(lifeform_t *lf); int rollmpdice(lifeform_t *lf);

653
objects.c

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@ void appendinscription(object_t *o, char *text);
void applyobmod(object_t *o, obmod_t *om); void applyobmod(object_t *o, obmod_t *om);
int blessob(object_t *o); int blessob(object_t *o);
void brightflash(cell_t *centre, int range, lifeform_t *immunelf); 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 *canstackob(obpile_t *op, object_t *match);
object_t *canstacknewot(obpile_t *op, objecttype_t *match); object_t *canstacknewot(obpile_t *op, objecttype_t *match);
int changemat(object_t *o, enum MATERIAL mat); int changemat(object_t *o, enum MATERIAL mat);
@ -140,6 +141,7 @@ void killob(object_t *o);
void killobpile(obpile_t *o); void killobpile(obpile_t *o);
void killoc(objectclass_t *oc); void killoc(objectclass_t *oc);
void killot(objecttype_t *ot); 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); lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level);
void makeduller(object_t *o, int howmuch); void makeduller(object_t *o, int howmuch);
void makeknown(enum OBTYPE otid); void makeknown(enum OBTYPE otid);
@ -170,7 +172,7 @@ void setinscription(object_t *o, char *text);
void shufflehiddennames(void); void shufflehiddennames(void);
object_t *splitob(object_t *o); object_t *splitob(object_t *o);
int takedamage(object_t *o, unsigned int howmuch, int damtype); 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 timeeffectsob(object_t *o);
void turnoff(lifeform_t *lf, object_t *o); void turnoff(lifeform_t *lf, object_t *o);
void turnon(lifeform_t *lf, object_t *o); void turnon(lifeform_t *lf, object_t *o);

688
spell.c

File diff suppressed because it is too large Load Diff

View File

@ -2,11 +2,11 @@
#define __SPELLS_H #define __SPELLS_H
#include "defs.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); 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); void fizzle(lifeform_t *caster);
//int getiqreq(enum OBTYPE oid); //int getiqreq(enum OBTYPE oid);
int getmpcost(enum OBTYPE oid); int getmpcost(lifeform_t *lf, enum OBTYPE oid);
enum SKILL getschoolskill(enum SPELLSCHOOL ss); enum SKILL getschoolskill(enum SPELLSCHOOL ss);
int getspellduration(int min,int max,int blessed); int getspellduration(int min,int max,int blessed);
int getspelllevel(enum OBTYPE spellid); int getspelllevel(enum OBTYPE spellid);
@ -16,6 +16,9 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid);
enum SPELLSCHOOL getspellschool(enum OBTYPE spellid); enum SPELLSCHOOL getspellschool(enum OBTYPE spellid);
int getspellrange(enum OBTYPE spellid, int power); int getspellrange(enum OBTYPE spellid, int power);
void pullobto(object_t *o, lifeform_t *lf); 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); 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); lifeform_t *validatespelllf(lifeform_t *caster, lifeform_t **lf);
#endif #endif

55
text.c
View File

@ -444,6 +444,61 @@ int texttodice(char *text, int *ndice, int *nsides, int *bonus) {
return B_FALSE; 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) { char *you(lifeform_t *lf) {
if (isplayer(lf)) { if (isplayer(lf)) {
return "You"; return "You";

1
text.h
View File

@ -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); char *dostrrep(char* in, char** out, char* oldtok, char* newtok, int *rv);
int strpixmatch(char *haystack, char *needle); int strpixmatch(char *haystack, char *needle);
int texttodice(char *text, int *ndice, int *nsides, int *bonus); 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(lifeform_t *lf);
char *you_l(lifeform_t *lf); char *you_l(lifeform_t *lf);
char *your(lifeform_t *lf); char *your(lifeform_t *lf);