- [+] young hawk moving very slowly? was healing.
- [+] make monsters heal faster when resting - [+] make pet rest when you do - [+] allow 'R' to heal allies - [+] F_RESTUNTILALLIES - [+] mindless/animal mosnters won't throw things - [+] announceflag for attrset not working * [+] feeblemind spell - reduces intelligence to ANIMAL. - [+] ai: if we are carrying too much, drop something (non-weapons/armour first) - [+] teleport spell should teleport any adjacent allies too. * [+] new 'C'hat commands: * [+] change 'resist elements' potion to 'rum' * [+] notify when pet is low on hp - [+] why could a pirate use a biuckler? * [+] genericise usage of canhaveobmod! - [+] armour mod: blooodstained. adds scary. - [+] CRASH when you have two weapons and catch a glowbug in your flask. * [+] potion of restoration onto frozen axe: - [+] slow spell repeated message: The brown snake looks sluggish. The brown snake is now moving slower. - [+] make you only hear one thing each turn ? - [+] always draw impassable objects on top - [+] special ash - [+] exploding powder - explode in radius 1 around player (including player) - [+] concealing powder - create smoke cloud radius 3 around player - [+] redo levelup logic. - [+] trigger LevUp when you have 'newskillready' - [+] announce when you gain level. - [+] can't gain more experience when LevUp! - [+] only update maxhp/mp from new level after you train - [+] diety can't use abilities. fixed. * [+] when i exit from@S output, statbar isn't redrawn * [+] make SKILLS page show which skills you can learn. - [+] In @s, downline isn't showing the title on the second page of SKILLS... - [+] show POWER in @M spells page - [+] ###--- - [+] show cost RANGE in @M for varpower ones - [+] need getspellcosttext(spellid, power, buf) function - [+] 25-62MP - [+] leftover rubbish chars at end of ---- in doheading() - [+] mosnters should follow you up/down stairs * [+] different poison types - [+] implement tremorsense (like darkvision butrun can't be blinded etc) * [+] implement HIDE ability * [+] Thief job - [+] if you walk into a room and every cell is lit, reveal it all. - [+] auto-learn jump ability with high athletics skill * [+] secret doors - [+] items to spot secret doors - [+] gem of seeing - [+] ENHANCESEARCH - [+] F_SEEINVIS - [+] spell: "reveal hidden" - [+] shows secret doors - [+] removes invisibility - [+] wand of detect hidden - [+] ... casts the spell
This commit is contained in:
parent
c32f93294c
commit
4f54fc0ef9
297
ai.c
297
ai.c
|
@ -70,8 +70,6 @@ void aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
|
|||
// no longer a pet
|
||||
f = lfhasflagval(lf, F_PETOF, victim->id, NA, NA, NULL);
|
||||
if (f) killflag(f);
|
||||
f = lfhasflagval(lf, F_ALLYOF, victim->id, NA, NA, NULL);
|
||||
if (f) killflag(f);
|
||||
}
|
||||
|
||||
enum OBTYPE aigetattackspell(lifeform_t *lf, lifeform_t *victim) {
|
||||
|
@ -277,7 +275,78 @@ void aigoto(lifeform_t *lf, cell_t *c, int timelimit) {
|
|||
}
|
||||
}
|
||||
|
||||
void aimove(lifeform_t *lf) {
|
||||
void aimovetotargetcell(lifeform_t *lf, flag_t *f) {
|
||||
int x,y;
|
||||
cell_t *c;
|
||||
int db = B_FALSE;
|
||||
|
||||
if (lfhasflag(lf, F_DEBUG)) {
|
||||
db = B_TRUE;
|
||||
}
|
||||
|
||||
x = f->val[0];
|
||||
y = f->val[1];
|
||||
if (db) dblog(".oO { walking from %d,%d towards f_targetcell (%d,%d) ... }", lf->cell->x, lf->cell->y, x, y);
|
||||
c = getcellat(lf->cell->map, x, y);
|
||||
if (c) {
|
||||
// target cell adjacent and something in the way?
|
||||
if (movetowards(lf, c, DT_ORTH)) {
|
||||
// couldn't move towards it for some reason.
|
||||
// so stop trying.
|
||||
if (db) dblog(".oO { couldn't walk towards f_targetcell. abandoning it. }");
|
||||
killflag(f);
|
||||
// remember NOT to target this one.
|
||||
lf->ignorecell = c;
|
||||
} else {
|
||||
if (db) dblog(".oO { successfully walked towards f_targetcell. arrived at %d,%d }",lf->cell->x, lf->cell->y);
|
||||
// moved towards it.
|
||||
// reset lifetime
|
||||
f->lifetime = AI_FOLLOWTIME;
|
||||
|
||||
// are we there yet?
|
||||
if (lf->cell == c) {
|
||||
if (db) dblog(".oO { arrived at f_targetcell. removing. }");
|
||||
killflag(f);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (db) dblog(".oO { f_targetcell doesn't exist. abandoning. }");
|
||||
// destination doesn't exist!
|
||||
killflag(f);
|
||||
// remember NOT to target this one.
|
||||
lf->ignorecell = c;
|
||||
}
|
||||
}
|
||||
|
||||
int aipickup(lifeform_t *lf, object_t *o) {
|
||||
if (isedible(o)) {
|
||||
return eat(lf, o);
|
||||
} else {
|
||||
return pickup(lf, o, o->amt, B_TRUE);
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int aiobok(lifeform_t *lf, object_t *o, lifeform_t *target) {
|
||||
switch (o->type->id) {
|
||||
case OT_POT_INVIS:
|
||||
case OT_WAND_INVIS:
|
||||
if (lfhasflag(target, F_INVISIBLE)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
break;
|
||||
case OT_POT_INVULN:
|
||||
if (lfhasflag(target, F_INVULNERABLE)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
void aiturn(lifeform_t *lf) {
|
||||
int db = B_FALSE;
|
||||
object_t *curwep,*bestwep, *o;
|
||||
int icanattack = B_FALSE;
|
||||
|
@ -288,8 +357,10 @@ void aimove(lifeform_t *lf) {
|
|||
// lifeform_t *fleefrom = NULL;
|
||||
lifeform_t *target;
|
||||
enum BODYPART bp;
|
||||
int x,y;
|
||||
cell_t *c;
|
||||
lifeform_t *master = NULL;
|
||||
enum IQBRACKET iqb;
|
||||
|
||||
|
||||
/*
|
||||
if (wantdb && haslos(player, lf->cell)) {
|
||||
|
@ -320,8 +391,68 @@ void aimove(lifeform_t *lf) {
|
|||
}
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////
|
||||
// info gathering
|
||||
///////////////////////////////////////////
|
||||
// remember our intelligence
|
||||
iqb = getiqname(getattr(lf, A_IQ), NULL);
|
||||
|
||||
|
||||
// are we a pet?
|
||||
mf = lfhasflagval(lf, F_PETOF, NA, NA, NA, NULL);
|
||||
if (mf && (getallegiance(lf) == AL_FRIENDLY)) {
|
||||
master = findlf(lf->cell->map, mf->val[0]);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// housekeeping - weapon changes, drop/pickup,
|
||||
// use items, etc
|
||||
///////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// healing
|
||||
///////////////////////////////////////////////
|
||||
|
||||
// need to heal?
|
||||
if (lf->hp < (lf->maxhp/2)) {
|
||||
if (!useitemwithflag(lf, F_AIHEALITEM)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// burdened?
|
||||
if (isburdened(lf)) {
|
||||
object_t *o,*heaviest = NULL;
|
||||
float hevweight = 0;
|
||||
|
||||
if (db) dblog(".oO { i am burdened }");
|
||||
|
||||
// drop our heaviest non-equipped object
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
if (!isequipped(o)) {
|
||||
float thisweight;
|
||||
thisweight = getobweight(o);
|
||||
if (thisweight > hevweight) {
|
||||
hevweight = thisweight;
|
||||
heaviest = o;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (heaviest) {
|
||||
if (db) {
|
||||
char obname[BUFLEN];
|
||||
getobname(o, obname, ALL);
|
||||
dblog(".oO { i will drop %s to lower my burden }", obname);
|
||||
}
|
||||
if (!drop(heaviest, ALL)) {
|
||||
return;
|
||||
}
|
||||
if (db) dblog(".oO { drop failed! }");
|
||||
}
|
||||
if (db) dblog(".oO { couldn't drop anything }");
|
||||
}
|
||||
|
||||
// do we have a better weapon we could use?
|
||||
curwep = getweapon(lf);
|
||||
bestwep = getbestweapon(lf);
|
||||
|
@ -382,6 +513,10 @@ void aimove(lifeform_t *lf) {
|
|||
if (db) dblog(".oO { found covetted object. returning. }");
|
||||
return;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// attacks
|
||||
///////////////////////////////////////////////
|
||||
|
||||
// do we already have a target we are attacking?
|
||||
f = hasflag(lf->flags, F_TARGET);
|
||||
|
@ -490,7 +625,10 @@ void aimove(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// if not adjacent, check for guns, wands, throwing
|
||||
if (goingtomove && (getcelldist(lf->cell, target->cell) > 1) && haslof(lf->cell, target->cell, LOF_NEED, NULL)) {
|
||||
if (goingtomove && // if we are still planning on moving
|
||||
(getcelldist(lf->cell, target->cell) > 1) && // and we're not adjacent to target
|
||||
haslof(lf->cell, target->cell, LOF_NEED, NULL) && // and we have line of fire to them
|
||||
(iqb > IQ_ANIMAL) ) { // and we are smarter than an animal
|
||||
// can we attack by firing a weapon?
|
||||
gun = getfirearm(lf);
|
||||
if (goingtomove && gun && getammo(lf)) {
|
||||
|
@ -602,45 +740,22 @@ void aimove(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// movement
|
||||
///////////////////////////////////////////////
|
||||
|
||||
// do we have a target cell?
|
||||
f = hasflag(lf->flags, F_TARGETCELL);
|
||||
if (f) {
|
||||
// if so, move towards it
|
||||
x = f->val[0];
|
||||
y = f->val[1];
|
||||
if (db) dblog(".oO { walking from %d,%d towards f_targetcell (%d,%d) ... }", lf->cell->x, lf->cell->y, x, y);
|
||||
c = getcellat(lf->cell->map, x, y);
|
||||
if (c) {
|
||||
// target cell adjacent and something in the way?
|
||||
if (movetowards(lf, c, DT_ORTH)) {
|
||||
// couldn't move towards it for some reason.
|
||||
// so stop trying.
|
||||
if (db) dblog(".oO { couldn't walk towards f_targetcell. abandoning it. }");
|
||||
killflag(f);
|
||||
// remember NOT to target this one.
|
||||
lf->ignorecell = c;
|
||||
} else {
|
||||
if (db) dblog(".oO { successfully walked towards f_targetcell. arrived at %d,%d }",lf->cell->x, lf->cell->y);
|
||||
// moved towards it.
|
||||
// reset lifetime
|
||||
f->lifetime = AI_FOLLOWTIME;
|
||||
|
||||
// are we there yet?
|
||||
if (lf->cell == c) {
|
||||
if (db) dblog(".oO { arrived at f_targetcell. removing. }");
|
||||
killflag(f);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (db) dblog(".oO { f_targetcell doesn't exist. abandoning. }");
|
||||
// destination doesn't exist!
|
||||
killflag(f);
|
||||
// remember NOT to target this one.
|
||||
lf->ignorecell = c;
|
||||
}
|
||||
aimovetotargetcell(lf, f);
|
||||
return;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// look for something to do (objects, things
|
||||
// to attack, etc)
|
||||
///////////////////////////////////////////////
|
||||
|
||||
// look for any object which we want
|
||||
if (db) dblog(".oO { looking for any ob which i want. }");
|
||||
if (lookforobs(lf, B_ANY)) {
|
||||
|
@ -708,23 +823,13 @@ void aimove(lifeform_t *lf) {
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
// need to heal?
|
||||
if ((lf->hp < lf->maxhp) ||
|
||||
((lf->mp < getmaxmp(lf)) && lfhasflag(lf, F_RESTHEALMPAMT)) ) {
|
||||
if (lf->hp < (lf->maxhp/2)) {
|
||||
if (!useitemwithflag(lf, F_AIHEALITEM)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (db) dblog(".oO { resting }");
|
||||
rest(lf, B_TRUE);
|
||||
}
|
||||
///////////////////////////////////////////////
|
||||
// training
|
||||
///////////////////////////////////////////////
|
||||
|
||||
// need to train skills?
|
||||
if (lf->skillpoints || getattpoints(lf)) {
|
||||
if (canrest(lf)) {
|
||||
if (readytotrain(lf)) {
|
||||
if (safetorest(lf)) {
|
||||
// special case - monsters don't need to actually rest to gain
|
||||
// skills, although they DO still need to wait until the player
|
||||
// is out of sight.
|
||||
|
@ -732,20 +837,23 @@ void aimove(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
// just try to move in a random direction
|
||||
mf = lfhasflagval(lf, F_PETOF, NA, NA, NA, NULL);
|
||||
if (!mf) {
|
||||
mf = lfhasflagval(lf, F_ALLYOF, NA, NA, NA, NULL);
|
||||
}
|
||||
if (mf && (getallegiance(lf) == AL_FRIENDLY)) {
|
||||
// pet movement - note that pets will only rest if their
|
||||
// master is resting. the normal rest code underneath this section
|
||||
// will never be called.
|
||||
if (master) {
|
||||
lifeform_t *master;
|
||||
master = findlf(lf->cell->map, mf->val[0]);
|
||||
if (master && cansee(lf, master)) {
|
||||
// can see my master - either move towards them or randomly
|
||||
// can see my master
|
||||
if (lfhasflag(master, F_RESTING)) {
|
||||
// rest as well.
|
||||
rest(lf, B_TRUE);
|
||||
return;
|
||||
}
|
||||
// - either move towards them or randomly
|
||||
if (isadjacent(lf->cell, master->cell)) {
|
||||
if (db) dblog(".oO { i can see my master - moving randomly }");
|
||||
dorandommove(lf, B_NOBADMOVES);
|
||||
return;
|
||||
} else {
|
||||
// move towards master if not adjacent
|
||||
if (db) dblog(".oO { i can see my master - moving towards them }");
|
||||
|
@ -753,63 +861,43 @@ void aimove(lifeform_t *lf) {
|
|||
// failed
|
||||
if (db) dblog(".oO { failed. moving randomly }");
|
||||
dorandommove(lf, B_NOBADMOVES);
|
||||
return;
|
||||
} else {
|
||||
// success
|
||||
if (db) dblog(".oO { success. }");
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// try to move towards master's last known loc
|
||||
if (mf->val[1] != NA) {
|
||||
if (db) dblog(".oO { cannot see my master - adding F_TARGETCELL for last known loc }");
|
||||
addflag(lf->flags, F_TARGETCELL, mf->val[1], mf->val[2], NA, NULL);
|
||||
f = addflag(lf->flags, F_TARGETCELL, mf->val[1], mf->val[2], NA, NULL);
|
||||
aimovetotargetcell(lf, f);
|
||||
} else {
|
||||
if (db) dblog(".oO { cannot see my master and dont have a last known location. randommove. }");
|
||||
dorandommove(lf, B_NOBADMOVES);
|
||||
return;
|
||||
}
|
||||
// exit the function without moving - next time we will do a move due to f_targetcell code.
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (db) dblog(".oO { default - moving randomly }");
|
||||
dorandommove(lf, B_NOBADMOVES);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// resting / healing
|
||||
///////////////////////////////////////////////
|
||||
|
||||
// need to heal?
|
||||
if (needstorest(lf, NULL) && safetorest(lf)) {
|
||||
if (db) dblog(".oO { resting to heal }");
|
||||
rest(lf, B_TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
// if we get this far, just wait
|
||||
rest(lf, B_TRUE);
|
||||
|
||||
// DEFAULT - try to move in a random direction
|
||||
if (db) dblog(".oO { default - moving randomly }");
|
||||
dorandommove(lf, B_NOBADMOVES); // this function will call rest() if we cant move
|
||||
}
|
||||
|
||||
int aipickup(lifeform_t *lf, object_t *o) {
|
||||
if (isedible(o)) {
|
||||
return eat(lf, o);
|
||||
} else {
|
||||
return pickup(lf, o, o->amt, B_TRUE);
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int aiobok(lifeform_t *lf, object_t *o, lifeform_t *target) {
|
||||
switch (o->type->id) {
|
||||
case OT_POT_INVIS:
|
||||
case OT_WAND_INVIS:
|
||||
if (lfhasflag(target, F_INVISIBLE)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
break;
|
||||
case OT_POT_INVULN:
|
||||
if (lfhasflag(target, F_INVULNERABLE)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// is the spell 'spellid' okay for AI lifeform 'lf' to cast at 'victim', for given purpose.
|
||||
// purpose could be F_AICASTTOFLEE or F_ATCASTTOATTACK
|
||||
|
@ -983,9 +1071,16 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
specificcheckok = B_FALSE;
|
||||
}
|
||||
}
|
||||
if ((ot->id == OT_S_HASTE) && lfhasflag(lf, F_FASTACT)) {
|
||||
if ((ot->id == OT_S_HASTE) && (lfhasflag(victim, F_FASTACT) || lfhasflag(victim, F_FASTACTMOVE)) ) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if (ot->id == OT_A_HIDE) {
|
||||
if (lfhasflag(victim, F_HIDING)) {
|
||||
specificcheckok = B_FALSE;
|
||||
} else if (!safetorest(victim)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
}
|
||||
if ((ot->id == OT_S_INVISIBILITY) && lfhasflag(victim, F_INVISIBLE)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
|
@ -1004,7 +1099,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
|
|||
if ((ot->id == OT_S_SLEEP) && lfhasflag(victim, F_ASLEEP)) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_S_SLOW) && lfhasflag(victim, F_SLOWACT)) {
|
||||
if ((ot->id == OT_S_SLOW) && (lfhasflag(victim, F_SLOWACT) || lfhasflag(victim, F_SLOWACTMOVE)) ) {
|
||||
specificcheckok = B_FALSE;
|
||||
}
|
||||
if ((ot->id == OT_A_SPRINT) && lfhasflag(lf, F_SPRINTING)) {
|
||||
|
@ -1249,3 +1344,5 @@ int useitemwithflag(lifeform_t *lf, enum FLAG whichflag) {
|
|||
// failed to use an item
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
3
ai.h
3
ai.h
|
@ -6,10 +6,11 @@ enum OBTYPE aigetfleespell(lifeform_t *lf);
|
|||
void aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose);
|
||||
object_t * aigetwand(lifeform_t *lf, enum FLAG purpose);
|
||||
void aigoto(lifeform_t *lf, cell_t *c, int timelimit);
|
||||
void aimove(lifeform_t *lf);
|
||||
void aimovetotargetcell(lifeform_t *lf, flag_t *f);
|
||||
int aipickup(lifeform_t *lf, object_t *o);
|
||||
int aiobok(lifeform_t *lf, object_t *o, lifeform_t *target);
|
||||
int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG purpose);
|
||||
void aiturn(lifeform_t *lf);
|
||||
object_t *hasbetterarmour(lifeform_t *lf, obpile_t *op);
|
||||
object_t *hasbetterweapon(lifeform_t *lf, obpile_t *op);
|
||||
int lookforobs(lifeform_t *lf, int covetsonly);
|
||||
|
|
33
attack.c
33
attack.c
|
@ -254,10 +254,10 @@ int attackcell(lifeform_t *lf, cell_t *c) {
|
|||
if (validwep[i]) {
|
||||
if (attacktype == AT_LF) {
|
||||
if (!isdead((lifeform_t *)attacktarget)) {
|
||||
attacklf(lf, (lifeform_t *)attacktarget, wep[i], damflag[i]);
|
||||
if (attacklf(lf, (lifeform_t *)attacktarget, wep[i], damflag[i])) break;
|
||||
}
|
||||
} else if (attacktype == AT_OB) {
|
||||
attackob(lf, (object_t *)attacktarget, wep[i], damflag[i]);
|
||||
if (attackob(lf, (object_t *)attacktarget, wep[i], damflag[i])) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -350,7 +350,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
msg("%s drops to the ground.", buf);
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
// stop all further attacks
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -644,8 +645,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
// 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);
|
||||
addtempflag(victim->flags, F_SLOWACTMOVE, 15, NA, NA, NULL, 2);
|
||||
} else {
|
||||
// second saving throw...
|
||||
if (skillcheck(victim, SC_CON, 25, 0)) {
|
||||
|
@ -713,7 +713,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
// induction of fear?
|
||||
if (!isdead(victim)) {
|
||||
if (lfhasflag(victim, F_INDUCEFEAR)) {
|
||||
scare(lf, victim, rnd(2,3));
|
||||
if (cansee(lf, victim)) {
|
||||
scare(lf, victim, rnd(2,3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1670,6 +1672,9 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
|
|||
if (fid == F_POISONED) {
|
||||
// need to fill in the name of what poisoned us
|
||||
char frombuf[BUFLEN];
|
||||
flag_t *typeflag;
|
||||
enum POISONTYPE ptype;
|
||||
int ppower;
|
||||
if (wep) {
|
||||
if (owner) {
|
||||
char lfname[BUFLEN];
|
||||
|
@ -1687,7 +1692,21 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
|
|||
} else {
|
||||
strcpy(frombuf, "something unknown");
|
||||
}
|
||||
poison(victim, howlong, frombuf);
|
||||
typeflag = hasflag(f->pile, F_HITPOISONTYPE);
|
||||
if (typeflag) {
|
||||
ptype = typeflag->val[0];
|
||||
if (typeflag->val[1] == NA) {
|
||||
ppower = 1;
|
||||
} else {
|
||||
ppower = typeflag->val[1];
|
||||
}
|
||||
} else {
|
||||
// should never happen.
|
||||
ptype = P_VENOM;
|
||||
ppower = 1;
|
||||
}
|
||||
|
||||
poison(victim, howlong, ptype, ppower, frombuf);
|
||||
} else {
|
||||
addtempflag(victim->flags, fid, NA, NA, NA, NULL, howlong);
|
||||
}
|
||||
|
|
78
defs.h
78
defs.h
|
@ -7,9 +7,12 @@
|
|||
#define PRACTICETIME 50 // #attempts it takes to learn new skill
|
||||
|
||||
#define WETTIME 10 // how long it takes for things to dry
|
||||
#define DRUNKTIME 10 // how long it takes for alcohol to wear off
|
||||
|
||||
/*
|
||||
#define POISONDAMCHANCE 33 // chance of vomitting when poisoned
|
||||
#define POISONDAM 2 // damage taken from vomiting when poisoned
|
||||
*/
|
||||
|
||||
// ncurses colours
|
||||
enum COLOUR {
|
||||
|
@ -76,6 +79,7 @@ enum CHECKTYPE {
|
|||
SC_OPENLOCKS,
|
||||
SC_POISON,
|
||||
SC_RESISTMAG,
|
||||
SC_SEARCH,
|
||||
SC_STEALTH,
|
||||
SC_WILL,
|
||||
};
|
||||
|
@ -120,7 +124,9 @@ enum LFCONDITION {
|
|||
#define FROMBRAND (-9865)
|
||||
#define FROMOBMOD (-9864)
|
||||
#define FROMSPELL (-9863)
|
||||
#define FROMPOISON (-9862)
|
||||
|
||||
#define LEVABILITYDONE (-8000)
|
||||
|
||||
#define IFKNOWN (-9772) // used by f_xxconfer. only confer a flag if item is known.
|
||||
#define IFACTIVE (-9771) // used by f_prodeuceslight. only does so if object is activated
|
||||
|
@ -521,6 +527,7 @@ enum RACE {
|
|||
R_WOLF,
|
||||
// insects
|
||||
R_BUTTERFLY,
|
||||
R_CENTIPEDE,
|
||||
R_GLOWBUG,
|
||||
R_GIANTFLY,
|
||||
R_GIANTBLOWFLY,
|
||||
|
@ -545,6 +552,7 @@ enum JOB {
|
|||
J_PIRATE,
|
||||
J_PLUMBER,
|
||||
J_PRINCE,
|
||||
J_ROGUE,
|
||||
J_WIZARD,
|
||||
};
|
||||
|
||||
|
@ -601,6 +609,8 @@ enum OBTYPE {
|
|||
OT_GOLD,
|
||||
OT_STONE,
|
||||
OT_ASH,
|
||||
OT_ASHEXPLODE,
|
||||
OT_ASHCONCEAL,
|
||||
OT_GEMOFSEEING,
|
||||
// food
|
||||
OT_BERRY,
|
||||
|
@ -639,7 +649,6 @@ enum OBTYPE {
|
|||
OT_POT_BLOOD,
|
||||
OT_POT_BLOODC,
|
||||
OT_POT_COMPETENCE,
|
||||
OT_POT_ELEMENTENDURE,
|
||||
OT_POT_ELEMENTIMMUNE,
|
||||
OT_POT_ETHEREALNESS,
|
||||
OT_POT_EXPERIENCE,
|
||||
|
@ -653,6 +662,7 @@ enum OBTYPE {
|
|||
OT_POT_POISON,
|
||||
OT_POT_POLYMORPH,
|
||||
OT_POT_RESTORATION,
|
||||
OT_POT_RUM,
|
||||
OT_POT_SANCTUARY,
|
||||
OT_POT_SPEED,
|
||||
OT_POT_WATER,
|
||||
|
@ -690,6 +700,7 @@ enum OBTYPE {
|
|||
OT_MAN_RESEARCH,
|
||||
OT_MAN_SHIELDS,
|
||||
OT_MAN_SPELLCASTING,
|
||||
OT_MAN_SPOTHIDDEN,
|
||||
OT_MAN_STEALTH,
|
||||
OT_MAN_TECHUSAGE,
|
||||
// manuals of weaponry
|
||||
|
@ -705,6 +716,7 @@ enum OBTYPE {
|
|||
OT_MAN_SS_AIR,
|
||||
OT_MAN_SS_DEATH,
|
||||
OT_MAN_SS_DIVINATION,
|
||||
OT_MAN_SS_EARTH,
|
||||
OT_MAN_SS_FIRE,
|
||||
OT_MAN_SS_ICE,
|
||||
OT_MAN_SS_GRAVITY,
|
||||
|
@ -724,11 +736,13 @@ enum OBTYPE {
|
|||
OT_SB_POISONBOLT,
|
||||
OT_SB_INFINITEDEATH,
|
||||
OT_SB_WEAKEN,
|
||||
OT_SB_FEEBLEMIND,
|
||||
OT_SB_BLINDNESS,
|
||||
// -- divination
|
||||
OT_SB_DETECTAURA,
|
||||
OT_SB_DETECTLIFE,
|
||||
OT_SB_DETECTOBS,
|
||||
OT_SB_REVEALHIDDEN,
|
||||
OT_SB_IDENTIFY,
|
||||
OT_SB_MAPPING,
|
||||
// -- elemental - air
|
||||
|
@ -799,6 +813,7 @@ enum OBTYPE {
|
|||
OT_S_PARALYZE,
|
||||
OT_S_INFINITEDEATH,
|
||||
OT_S_WEAKEN,
|
||||
OT_S_FEEBLEMIND,
|
||||
OT_S_BLINDNESS,
|
||||
OT_S_POISONBOLT,
|
||||
OT_S_POSSESSION,
|
||||
|
@ -807,6 +822,7 @@ enum OBTYPE {
|
|||
OT_S_DETECTLIFE,
|
||||
OT_S_DETECTOBS,
|
||||
OT_S_DETECTMAGIC,
|
||||
OT_S_REVEALHIDDEN,
|
||||
OT_S_IDENTIFY,
|
||||
OT_S_MAPPING,
|
||||
// -- elemental - air
|
||||
|
@ -885,6 +901,7 @@ enum OBTYPE {
|
|||
OT_A_SWOOP,
|
||||
OT_A_EMPLOY,
|
||||
OT_A_HEAVYBLOW,
|
||||
OT_A_HIDE,
|
||||
OT_A_INSPECT,
|
||||
OT_A_HURRICANESTRIKE,
|
||||
OT_A_POLYREVERT,
|
||||
|
@ -903,6 +920,7 @@ enum OBTYPE {
|
|||
OT_WAND_KNOCK,
|
||||
OT_WAND_LIGHT,
|
||||
OT_WAND_POLYMORPH,
|
||||
OT_WAND_REVEALHIDDEN,
|
||||
OT_WAND_SLOW,
|
||||
OT_WAND_WEAKNESS,
|
||||
OT_WAND_WONDER,
|
||||
|
@ -1159,6 +1177,13 @@ enum ALLEGIENCE {
|
|||
AL_FRIENDLY, // will help you fight
|
||||
};
|
||||
|
||||
enum POISONTYPE {
|
||||
P_FOOD,
|
||||
P_GAS,
|
||||
P_VENOM,
|
||||
P_WEAKNESS,
|
||||
};
|
||||
|
||||
enum FLAG {
|
||||
F_NONE, // dummy flag
|
||||
// object flags
|
||||
|
@ -1216,12 +1241,15 @@ enum FLAG {
|
|||
F_HITCONFER, // hitting with this gives flagid=v0
|
||||
// unless you pass a val1 skillcheck, diff val2
|
||||
// with timeleft = text ("min-max")
|
||||
F_HITPOISONTYPE, // used when you have f_hitconfer->f_poisoned.
|
||||
// v0 is type of poison.
|
||||
// v1 is power (NA means 1)
|
||||
F_ACTIVATED, // val0 = is this object turned on?
|
||||
F_GRENADE, // this obkejct will drain charge when activated, then die
|
||||
F_EXPLODEONDEATH, // explodes when it dies, deals val0 vamage.
|
||||
F_EXPLODEONDEATH, // explodes when it dies, deals TEXT damage.
|
||||
// val1 = BIG means hit surrounding cells
|
||||
// val2 = ifactivated, only explodes if activated.
|
||||
F_EXPLODEONDAM, // explodes when it is damaged, deals val0 vamage.
|
||||
F_EXPLODEONDAM, // explodes when it is damaged, deals TEXT damage.
|
||||
// val1 = BIG means hit surrounding cells
|
||||
// val2 = ifactivated, only explodes if activated.
|
||||
F_FLASHONDEATH, // produce a bright flash when it dies,v0=range
|
||||
|
@ -1257,6 +1285,8 @@ enum FLAG {
|
|||
F_OPEN, // is this door open?
|
||||
F_LOCKED,// door is locked
|
||||
F_JAMMED, // is this door jammed?
|
||||
F_SECRETDOOR, // this door is secret. v0 is sc_search difficulty
|
||||
// to find it.
|
||||
// stairs / teleporters / portals
|
||||
F_CLIMBABLE, // this is a stiarcase, v0 = up/down/in
|
||||
// also use this for portals
|
||||
|
@ -1270,6 +1300,8 @@ enum FLAG {
|
|||
// ob interaction flags
|
||||
F_HARD, // object is hard (ie. punching it will hurt!)
|
||||
F_SHARP, // does damage when you step on it. v0/1 are min/max dam
|
||||
F_SCARY, // gives other lfs a penalty to morale checks against you,
|
||||
// v0 = penalty amt.
|
||||
F_SLIPPERY, // you might slip when stepping on it. v0 is amt
|
||||
F_SLIPMOVE, // if someone slips on this, it will move to an adj cell
|
||||
F_FLAMMABLE, // object will catch alight if burnt (ie fire damage)
|
||||
|
@ -1295,6 +1327,7 @@ enum FLAG {
|
|||
F_OBATTACKDELAY, // how long weapon takes to attack
|
||||
F_USESSKILL, // weapon needs skill sk_v0
|
||||
F_CANHAVEOBMOD, // weapon can have obmod om_v0 applied
|
||||
// optional: v1 is chance of randomly having it
|
||||
F_ATTREQ, // requires attrib v0 to be at least bracket v1
|
||||
//F_DAMTYPE, // val0 = damage type
|
||||
//F_DAM, // val0 = ndice, val1 = nsidesondie, val2 = mod
|
||||
|
@ -1372,6 +1405,7 @@ enum FLAG {
|
|||
// using their strength
|
||||
// player only flags
|
||||
F_DONEDARKMSG, // tells the game not to say 'it is very dark here'
|
||||
F_DONELISTEN, // supress further 'you hear xx' messages this turn.
|
||||
// lifeform flags / lf flags
|
||||
F_DEBUG, // debugging enabled
|
||||
F_ACCURACYMOD, // modify your accuracy by val0
|
||||
|
@ -1415,17 +1449,11 @@ enum FLAG {
|
|||
// MONSTER AI FLAGS
|
||||
F_XPVAL, // force xp val for killing this lf to v0
|
||||
// ...OR if applied to an ability...
|
||||
// monsters with this abil are worth
|
||||
// monsters with this abil/spell are worth
|
||||
// v0 more xp.
|
||||
F_XPMULTIPLY, // multiply xp val for killing this lf by v0
|
||||
F_PETOF, // this lf is a pet of lfid v0
|
||||
// v1/2 = last known location of my owner.
|
||||
F_ALLYOF, // this lf is a ally of lfid v0
|
||||
// v1/2 = last known location of my owner.
|
||||
// difference between this an 'petof' will be that
|
||||
// you don't get alignment penalties etc for your
|
||||
// ally dying.
|
||||
|
||||
F_HOSTILE, // lf will attack the player if in sight
|
||||
F_FRIENDLY, // lf will attack all non-players if in sight
|
||||
F_WANTS, // lf will try to pick up object type val0. if
|
||||
|
@ -1491,6 +1519,7 @@ enum FLAG {
|
|||
// to the victim
|
||||
F_PHALANX, // gain v0 AR if v2 or more adj monsters matching f->text
|
||||
F_MORALE, // gain +v0 in morale checks.
|
||||
F_SPOTTED, // you have spotted hiding lf id v0
|
||||
// INTRINSICS
|
||||
F_MAGICARMOUR,// armour is magically boosted. f->text is the description
|
||||
// ie 'magic armour', 'force field'
|
||||
|
@ -1518,6 +1547,8 @@ enum FLAG {
|
|||
F_DETECTMAGIC, // autodetect magic/special objects
|
||||
F_DETECTMETAL, // autodetect nearby metal
|
||||
F_DETECTOBS, // autodetect nearby obs in orthog dist v0
|
||||
F_DRUNK, // v1 is drunknness - 1-5.
|
||||
F_ENHANCESEARCH, // gives v0 bonus on search checks.
|
||||
F_EXTRADAM, // do 'text' extra damage of damtype v0 when you hit
|
||||
// if v1 is TRUE, also deal extra damage based on
|
||||
// the flagpile's F_BONUS flag.
|
||||
|
@ -1527,11 +1558,15 @@ enum FLAG {
|
|||
F_FLYING, // lf is flying
|
||||
F_FASTACT, // modifier for action speed
|
||||
F_FASTMOVE, // modifier for move speed
|
||||
F_POISONED, // has food poisoning. text = what from.eg'a bad egg'
|
||||
F_FASTACTMOVE, // modifier for action and move speed
|
||||
F_POISONED, // has poisoning. v0 = poison type,
|
||||
// v1 = power
|
||||
// text = what from.eg'a bad egg'
|
||||
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
|
||||
F_HEAVYBLOW, // next attack is a heavy blow
|
||||
F_HIDING, // lifeform is hiding. v0 is modifier to stealth checks.
|
||||
F_INVISIBLE, // lifeform is invisible
|
||||
F_INVULNERABLE,// immune to most damage
|
||||
F_QUICKBITE, // deals v0 d d1 + d2 damage when you hit a bleeding victim
|
||||
|
@ -1551,8 +1586,8 @@ enum FLAG {
|
|||
F_MPREGEN, // regenerate MP at val0 per turn
|
||||
F_RISEASGHOST, // become a ghost when you die.
|
||||
F_SEEINDARK, // nightvis range is val0
|
||||
F_TREMORSENSE, // doesn't need eyes to see, can see in dark with v0
|
||||
F_SEEINVIS, // can see invisible things
|
||||
F_SEEWITHOUTEYES, // doesn't need eyes to see
|
||||
F_STABILITY, // doesn't slip over
|
||||
F_STENCH, // creatures within v0 gain f_nauseated = v1
|
||||
F_PRODUCESLIGHT, // produces light of val0 radius.
|
||||
|
@ -1561,6 +1596,7 @@ enum FLAG {
|
|||
// is activated!
|
||||
F_SLOWACT, // modifier for action speed
|
||||
F_SLOWMOVE, // modifier for move speed
|
||||
F_SLOWACTMOVE, // modifier for move and action speed
|
||||
F_XRAYVIS, //val0=num of walls we can see through
|
||||
F_CANSEETHROUGHMAT, //val0=kind of material you can see through
|
||||
F_SPRINTING, // v0=true: you are sprinting. false=you are tired
|
||||
|
@ -1580,6 +1616,7 @@ enum FLAG {
|
|||
F_EVASION, // % chance of evading an attack
|
||||
|
||||
// healing/resting/training
|
||||
F_HASNEWLEVEL, // we have a new xp lev, but haven't trained yet.
|
||||
F_STATGAINREADY, // ready to increase str/int etc. v2 is how many times
|
||||
// we can do it.
|
||||
F_INTERRUPTED, // somethign interrupted our rest. stop!
|
||||
|
@ -1588,6 +1625,7 @@ enum FLAG {
|
|||
// when it hits 0, you finish trainign.
|
||||
F_RESTUNTILHP, // resting until we have full hp
|
||||
F_RESTUNTILMP, // resting until we have full mp
|
||||
F_RESTUNTILALLIES, // resting until allies have full hp
|
||||
//
|
||||
F_RUNNING, // are we running?
|
||||
// nutrition
|
||||
|
@ -1606,6 +1644,10 @@ enum FLAG {
|
|||
// v2 = how often you can do it (or NA for unlimited)
|
||||
// text = options
|
||||
F_LEVSPELL, // at level v0, this job gains f_cancast v1.
|
||||
F_LEVSPELLSCHOOL, // at level v0, this job gains f_cancast for a spell
|
||||
// of their choice from school v1. if v1 is SS_NONE, they can
|
||||
// pick form any school they are skilled in.
|
||||
// if v0 is >100, this triggers every (v0-100) levels.
|
||||
F_LEVFLAG, // at level v0, this job gains flagid v1, flagval0=v2,
|
||||
// flagtext = text
|
||||
|
||||
|
@ -1752,6 +1794,9 @@ enum ERROR {
|
|||
// charm failure reasons
|
||||
// LOWIQ = 42
|
||||
E_UNDEAD = 46,
|
||||
E_DRUNK = 47,
|
||||
//
|
||||
E_NOBP = 48,
|
||||
};
|
||||
|
||||
|
||||
|
@ -1881,6 +1926,7 @@ typedef struct lifeform_s {
|
|||
int controller;
|
||||
struct race_s *race;
|
||||
int level;
|
||||
int newlevel;
|
||||
long xp;
|
||||
int skillpoints;
|
||||
int hp,maxhp;
|
||||
|
@ -1964,9 +2010,9 @@ typedef struct material_s {
|
|||
} material_t;
|
||||
|
||||
|
||||
#define SK_NONE -1
|
||||
enum SKILL {
|
||||
SK_ARMOUR,
|
||||
SK_NONE = 0,
|
||||
SK_ARMOUR = 1,
|
||||
SK_ATHLETICS,
|
||||
SK_BACKSTAB,
|
||||
SK_FIRSTAID,
|
||||
|
@ -1976,6 +2022,7 @@ enum SKILL {
|
|||
SK_RESEARCH,
|
||||
SK_SHIELDS,
|
||||
SK_SPELLCASTING,
|
||||
SK_SPOTHIDDEN,
|
||||
SK_STEALTH,
|
||||
SK_TECHUSAGE,
|
||||
// weaponry
|
||||
|
@ -2002,7 +2049,7 @@ enum SKILL {
|
|||
SK_SS_TRANSLOCATION,
|
||||
SK_SS_WILD,
|
||||
};
|
||||
#define MAXSKILLS 33
|
||||
#define MAXSKILLS 35
|
||||
|
||||
// proficiency levels
|
||||
enum SKILLLEVEL {
|
||||
|
@ -2100,6 +2147,7 @@ enum RUSTINESS {
|
|||
};
|
||||
|
||||
enum OBMOD {
|
||||
OM_BLOODSTAINED,
|
||||
OM_FLAMING,
|
||||
OM_FROZEN,
|
||||
OM_HEADLESS,
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
defs.h:
|
||||
Add flag F_LEVxxx
|
||||
|
||||
lf.c:
|
||||
Update enhanceskills()
|
||||
Update refreshlevelabilities()
|
||||
Update levelabilityready()
|
|
@ -0,0 +1,9 @@
|
|||
defs.h:
|
||||
add enum POISONTYPE
|
||||
|
||||
lf.c:
|
||||
update getpoisondam()
|
||||
update getpoisondamchance()
|
||||
update getpoisonverb()
|
||||
update getpoisonname()
|
||||
update poison()
|
|
@ -20,7 +20,6 @@ spell.c:
|
|||
blindness if the effect is vision-based
|
||||
|
||||
ai.c
|
||||
update aigetspelltarget();
|
||||
update aigetattackspell();
|
||||
update aigetspelltarget(); (if we have target ST_SPECIAL)
|
||||
update aispellok();
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ defs.h:
|
|||
|
||||
objects.c:
|
||||
update getschoolname
|
||||
update getschoolnameshort
|
||||
|
||||
spell.c:
|
||||
update getschoolskill to return the skill for this school
|
||||
|
|
1
flag.c
1
flag.c
|
@ -200,6 +200,7 @@ int flagcausesredraw(lifeform_t *lf, enum FLAG fid) {
|
|||
case F_DETECTLIFE:
|
||||
case F_DETECTOBS:
|
||||
case F_FASTMOVE:
|
||||
case F_HIDING:
|
||||
case F_INVISIBLE:
|
||||
case F_SEEINDARK:
|
||||
case F_SEEINVIS:
|
||||
|
|
497
io.c
497
io.c
|
@ -248,7 +248,7 @@ void animradial(cell_t *src, int radius, char ch, int colour) {
|
|||
for (y = src->y - radius ; y <= src->y + radius ; y++) {
|
||||
for (x = src->x - radius ; x <= src->x + radius ; x++) {
|
||||
c = getcellat(src->map, x, y);
|
||||
if (c && haslos(player, c) && (getcelldistorth(src, c) <= i)) {
|
||||
if (c && haslos(player, c) && (getcelldist(src, c) <= i)) {
|
||||
// draw char & cursor at its current pos...
|
||||
//mvwprintw(gamewin, c->y - viewy, c->x - viewx, "%c", ch);
|
||||
drawglyph(&gl, c->x - viewx, c->y - viewy);
|
||||
|
@ -287,7 +287,7 @@ void animradialorth(cell_t *src, int radius, char ch,int colour) {
|
|||
for (y = src->y - radius ; y <= src->y + radius ; y++) {
|
||||
for (x = src->x - radius ; x <= src->x + radius ; x++) {
|
||||
c = getcellat(src->map, x, y);
|
||||
if (c && haslos(player, c) && (getcelldist(src, c) <= i)) {
|
||||
if (c && haslos(player, c) && (getcelldistorth(src, c) <= i)) {
|
||||
// draw char & cursor at its current pos...
|
||||
//mvwprintw(gamewin, c->y - viewy, c->x - viewx, "%c", ch);
|
||||
drawglyph(&gl, c->x - viewx, c->y - viewy);
|
||||
|
@ -386,8 +386,13 @@ cell_t *askcoords(char *prompt, int targettype) {
|
|||
valid = B_TRUE;
|
||||
} else if ((targettype & TT_OBJECT) && hasobject(c)) {
|
||||
valid = B_TRUE;
|
||||
} else if ((targettype & TT_DOOR) && hasobwithflag(c->obpile, F_DOOR)) {
|
||||
valid = B_TRUE;
|
||||
}
|
||||
if (targettype & TT_DOOR) {
|
||||
object_t *o;
|
||||
o = hasobwithflag(c->obpile, F_DOOR);
|
||||
if (o && !hasflag(o->flags, F_SECRETDOOR)) {
|
||||
valid = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
|
@ -402,7 +407,6 @@ cell_t *askcoords(char *prompt, int targettype) {
|
|||
|
||||
|
||||
// start prompting
|
||||
|
||||
if (curtarget == -1) {
|
||||
c = player->cell;
|
||||
} else {
|
||||
|
@ -453,10 +457,12 @@ cell_t *askcoords(char *prompt, int targettype) {
|
|||
case AL_FRIENDLY:
|
||||
if (!isplayer(c->lf)) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
if (lfhasflagval(c->lf, F_ALLYOF, player->id, NA, NA, NULL)) {
|
||||
strcat(extrainfo, "ally");
|
||||
} else if (lfhasflagval(c->lf, F_PETOF, player->id, NA, NA, NULL)) {
|
||||
strcat(extrainfo, "pet");
|
||||
if (lfhasflagval(c->lf, F_PETOF, player->id, NA, NA, NULL)) {
|
||||
if (lfhasflag(c->lf, F_ANIMAL)) {
|
||||
strcat(extrainfo, "pet");
|
||||
} else {
|
||||
strcat(extrainfo, "ally");
|
||||
}
|
||||
} else {
|
||||
strcat(extrainfo, "friendly");
|
||||
}
|
||||
|
@ -474,6 +480,10 @@ cell_t *askcoords(char *prompt, int targettype) {
|
|||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "fleeing");
|
||||
}
|
||||
if (lfhasflag(c->lf, F_RESTING)) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "resting");
|
||||
}
|
||||
if (lfhasflag(c->lf, F_ASLEEP)) {
|
||||
if (strlen(extrainfo)) strcat(extrainfo, ", ");
|
||||
strcat(extrainfo, "asleep");
|
||||
|
@ -726,9 +736,9 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_ATTRSET:
|
||||
if (f->val[1] != getattr(lf, f->val[0])) {
|
||||
if (f->val[1] != real_getattr(lf, f->val[0], B_TRUE)) {
|
||||
int myatt;
|
||||
myatt = getattr(lf, f->val[0]);
|
||||
myatt = real_getattr(lf, f->val[0], B_TRUE);
|
||||
switch (f->val[0]) {
|
||||
case A_STR:
|
||||
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] < myatt) ? "weak" : "strong");
|
||||
|
@ -864,6 +874,16 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_HIDING:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
if (f->val[0] < 0) {
|
||||
msg("You are now trying to hide.");
|
||||
} else {
|
||||
msg("You are now hiding.");
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_INVISIBLE:
|
||||
if (isplayer(lf)) {
|
||||
if (lfhasflag(player, F_SEEINVIS)) {
|
||||
|
@ -905,6 +925,16 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s %s very sick.", lfname, isplayer(lf) ? "feel" : "looks");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_ENHANCESEARCH:
|
||||
if (isplayer(lf)) {
|
||||
msg("You feel very perceptive!");
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_DRUNK:
|
||||
msg("%s %s tipsy.", lfname, isplayer(lf) ? "feel" : "looks");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_EXTRADAM:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You feel more dangerous!");
|
||||
|
@ -931,6 +961,10 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s %s faster.",lfname, isplayer(lf) ? "feel yourself moving" : "is now moving");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FASTACTMOVE:
|
||||
msg("%s %s",lfname, isplayer(lf) ? "feel faster and quicker!" : "looks faster and quicker.");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FLYING:
|
||||
msg("%s begin%s to fly!",lfname, isplayer(lf) ? "" : "s");
|
||||
donesomething = B_TRUE;
|
||||
|
@ -1034,6 +1068,10 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s %s slower.",lfname, isplayer(lf) ? "feel yourself moving" : "is now moving");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_SLOWACTMOVE:
|
||||
msg("%s %s",lfname, isplayer(lf) ? "feel slow and sluggish." : "looks slow and sluggish.");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_SPRINTING:
|
||||
msg("%s %s sprinting!",lfname, isplayer(lf) ? "start" : "starts");
|
||||
donesomething = B_TRUE;
|
||||
|
@ -1046,6 +1084,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s looks exhausted.",lfname);
|
||||
}
|
||||
break;
|
||||
case F_TREMORSENSE:
|
||||
if (isplayer(lf)) { // don't know if monsters get it
|
||||
msg("You can 'see' by sensing vibrations around you.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_WINDSHIELD:
|
||||
if (isplayer(lf)) {
|
||||
msg("You are surrounded by a whirling cyclone!");
|
||||
|
@ -1134,9 +1178,9 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_ATTRSET:
|
||||
if (f->val[1] != getattr(lf, f->val[0])) {
|
||||
if (f->val[1] != real_getattr(lf, f->val[0], B_TRUE)) {
|
||||
int myatt;
|
||||
myatt = getattr(lf, f->val[0]);
|
||||
myatt = real_getattr(lf, f->val[0], B_TRUE);
|
||||
switch (f->val[0]) {
|
||||
case A_STR:
|
||||
msg("%s %s %s!",lfname, isplayer(lf) ? "feel" : "seems", (f->val[1] > myatt) ? "less strong" : "less weak");
|
||||
|
@ -1223,6 +1267,16 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_ENHANCESEARCH:
|
||||
if (isplayer(lf)) {
|
||||
msg("You no longer feel so perceptive!");
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_DRUNK:
|
||||
msg("%s %s more steady now.", lfname, isplayer(lf) ? "feel" : "looks");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_EXTRADAM:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("You no longer feel more dangerous.");
|
||||
|
@ -1249,6 +1303,10 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s %s slower.",lfname, isplayer(lf) ? "feel yourself moving" : "is now moving");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FASTACTMOVE:
|
||||
msg("%s %s",lfname, isplayer(lf) ? "slow down back to normal speed." : "slows down to its normal speed.");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_FLEEFROM:
|
||||
msg("%s stop%s fleeing.", lfname, isplayer(lf) ? "" : "s");
|
||||
donesomething = B_TRUE;
|
||||
|
@ -1266,6 +1324,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_HIDING:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("You are no longer hidden.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_INVISIBLE:
|
||||
if (isplayer(lf)) {
|
||||
msg("Your are no longer invisible.");
|
||||
|
@ -1431,6 +1495,10 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
msg("%s %s faster.",lfname, isplayer(lf) ? "feel yourself moving" : "is now moving");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_SLOWACTMOVE:
|
||||
msg("%s %s",lfname, isplayer(lf) ? "speed back up." : "speeds back up.");
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_SPRINTING:
|
||||
if (f->val[0]) {
|
||||
if (isplayer(lf)) { // don't know if monsters lose it (but you'll see them get exhausted)
|
||||
|
@ -1453,6 +1521,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
|
|||
}
|
||||
donesomething = B_TRUE;
|
||||
break;
|
||||
case F_TREMORSENSE:
|
||||
if (isplayer(lf)) { // don't know if monsters lose it
|
||||
msg("You no longer sense vibrations around you.");
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case F_WINDSHIELD:
|
||||
if (isplayer(lf) || cansee(player, lf)) {
|
||||
msg("%s%s cyclonic shield vanishes.", lfname, getpossessive(lfname));
|
||||
|
@ -2133,12 +2207,15 @@ void centre(WINDOW *win, int y, char *format, ... ) {
|
|||
int w;
|
||||
char buf[BUFLEN];
|
||||
va_list args;
|
||||
int startx;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf( buf, format, args );
|
||||
va_end(args);
|
||||
|
||||
w = getmaxx(win);
|
||||
startx = (w/2) - (strlen(buf)/2);
|
||||
if (startx < 0) startx = 0;
|
||||
mvwprintw(win, y, (w/2) - (strlen(buf)/2), buf);
|
||||
}
|
||||
|
||||
|
@ -2425,14 +2502,18 @@ void describeob(object_t *o) {
|
|||
y++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
f = hasflag(o->flags, F_PICKLOCKS);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "You can use it to pick locks.");
|
||||
y++;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_SCARY);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "It may unnerve others when worn.");
|
||||
y++;
|
||||
}
|
||||
|
||||
// immunities
|
||||
for (i = 0; i < MAXDAMTYPE; i++) {
|
||||
if (isimmuneto(o->flags, i)) {
|
||||
|
@ -2508,7 +2589,6 @@ void describeob(object_t *o) {
|
|||
|
||||
|
||||
// if known, show what it confers
|
||||
y++;
|
||||
for (f = o->flags->first ; f ; f = f->next) {
|
||||
if ((f->id == F_HOLDCONFER) || (f->id == F_EQUIPCONFER) || (f->id == F_ACTIVATECONFER)) {
|
||||
if (obknown) {
|
||||
|
@ -2549,6 +2629,12 @@ void describeob(object_t *o) {
|
|||
case F_DETECTMETAL:
|
||||
mvwprintw(mainwin, y, 0, "%s will detect nearby metal.", buf); y++;
|
||||
break;
|
||||
case F_ENHANCESEARCH:
|
||||
mvwprintw(mainwin, y, 0, "%s enhances your searching ability.", buf); y++;
|
||||
break;
|
||||
case F_DRUNK:
|
||||
mvwprintw(mainwin, y, 0, "%s makes you tipsy.", buf); y++;
|
||||
break;
|
||||
case F_EXTRAINFO:
|
||||
mvwprintw(mainwin, y, 0, "%s provides enhanced knowledge to you.", buf); y++;
|
||||
break;
|
||||
|
@ -2668,6 +2754,9 @@ void describeob(object_t *o) {
|
|||
case F_SLOWMOVE:
|
||||
mvwprintw(mainwin, y, 0, "%s will slow down your movement.", buf); y++;
|
||||
break;
|
||||
case F_TREMORSENSE:
|
||||
mvwprintw(mainwin, y, 0, "%s allows you to 'see' by sensing vibrations around you.", buf); y++;
|
||||
break;
|
||||
case F_WINDSHIELD:
|
||||
mvwprintw(mainwin, y, 0, "%s will surround you with a cyclonic shield.", buf); y++;
|
||||
break;
|
||||
|
@ -2712,7 +2801,8 @@ void describeob(object_t *o) {
|
|||
// 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]));
|
||||
mvwprintw(mainwin, y, 0, "It falls into the '%s' category (your skill: %s).",getskillname(f->val[0]),
|
||||
getskilllevelname(getskill(player, f->val[0])) );
|
||||
y++;
|
||||
}
|
||||
|
||||
|
@ -2907,7 +2997,7 @@ void docomms(void) {
|
|||
initprompt(&prompt, buf);
|
||||
prompt.maycancel = B_TRUE;
|
||||
// are they friendly?
|
||||
if (areallies(player, lf)) {
|
||||
if (ispetof(lf, player)) {
|
||||
addchoice(&prompt, 'a', "Attack something", NULL, NULL);
|
||||
if (!isadjacent(lf->cell, player->cell)) {
|
||||
addchoice(&prompt, 'c', "Come here", NULL, NULL);
|
||||
|
@ -2915,6 +3005,11 @@ void docomms(void) {
|
|||
if (isadjacent(lf->cell, player->cell) && !lfhasflag(lf, F_NOPACK)) {
|
||||
addchoice(&prompt, 't', "Trade items with me", NULL, NULL);
|
||||
}
|
||||
if (lfhasflag(lf, F_RESTING)) {
|
||||
addchoice(&prompt, 'r', "Stop resting.", NULL, NULL);
|
||||
} else {
|
||||
addchoice(&prompt, 'r', "Rest until you are healed.", NULL, NULL);
|
||||
}
|
||||
} else {
|
||||
addchoice(&prompt, 'y', "Yeeeeeaaaargh!", NULL, NULL);
|
||||
}
|
||||
|
@ -2937,8 +3032,12 @@ void docomms(void) {
|
|||
return;
|
||||
}
|
||||
getlfname(lf2, lfname2);
|
||||
msg("You say \"Attack %s!\" to %s.",lfname2, lfname);
|
||||
aiattack(lf, lf2, AI_FOLLOWTIME);
|
||||
msg("You say \"Attack %s!\" to %s.",isplayer(lf2) ? "me" : lfname2, lfname);
|
||||
if (isplayer(lf)) {
|
||||
msg("%s looks confused at your command.", lfname);
|
||||
} else {
|
||||
aiattack(lf, lf2, AI_FOLLOWTIME);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
msg("You say \"Come here!\" to %s.",lfname);
|
||||
|
@ -2951,6 +3050,22 @@ void docomms(void) {
|
|||
case 'n':
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
case 'r':
|
||||
if (lfhasflag(lf, F_RESTING)) {
|
||||
stopresting(lf);
|
||||
} else {
|
||||
if (needstorest(lf, NULL)) {
|
||||
if (safetorest(lf)) {
|
||||
addflag(lf->flags, F_RESTUNTILHP, B_TRUE, NA, NA, NULL);
|
||||
startresting(lf, B_FALSE);
|
||||
} else {
|
||||
msg("%s is too nervous to rest (perhaps there are monsters nearby).", lfname);
|
||||
}
|
||||
} else {
|
||||
msg("%s doesn't need to rest at the moment.", lfname);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 't':
|
||||
// ask whtehr to give/take
|
||||
initprompt(&prompt, "How will you trade?");
|
||||
|
@ -3420,7 +3535,9 @@ void dolook(cell_t *where) {
|
|||
}
|
||||
}
|
||||
|
||||
void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2) {
|
||||
// if wantunknown is set, lsit spells we DONT know.
|
||||
// otherwise list spells we DO know.
|
||||
void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2, enum SPELLSCHOOL wantschool, int wantunknown) {
|
||||
char ch;
|
||||
flag_t *f;
|
||||
char buf[BUFLEN];
|
||||
|
@ -3438,11 +3555,21 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2)
|
|||
|
||||
nposs = 0;
|
||||
for (i = SS_NONE+1; i < SS_LAST; i++) {
|
||||
// school doesn't match the one we're asking for?
|
||||
if ((wantschool != SS_NONE) && (i != wantschool)) {
|
||||
continue;
|
||||
}
|
||||
// we can't cast spells from this school?
|
||||
if (getschoolskill(i) != SK_NONE) {
|
||||
if (!getskill(lf, getschoolskill(i))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// get list of spells/abilities we can cast at will
|
||||
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||
if ((ot->obclass->id == OC_SPELL) || (ot->obclass->id == OC_ABILITY)) {
|
||||
f = lfhasflagval(lf, F_CANWILL, ot->id, NA, NA, NULL);
|
||||
if (f) {
|
||||
if (!wantunknown && f) {
|
||||
if (hasflagval(ot->flags, F_SPELLSCHOOL, i, NA, NA, NULL)) {
|
||||
poss[nposs] = ot->id;
|
||||
deactspell[nposs] = B_FALSE; // default
|
||||
|
@ -3470,11 +3597,12 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2)
|
|||
if (!lfhasflag(lf, F_NOSPELLS)) {
|
||||
// get list of spells we can cast using mp
|
||||
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||
if (ot->obclass->id == OC_SPELL) {
|
||||
if (hasflagval(ot->flags, F_SPELLSCHOOL, i, NA, NA, NULL)) {
|
||||
if (ot->obclass->id == OC_SPELL) { // is it a spell?
|
||||
if (hasflagval(ot->flags, F_SPELLSCHOOL, i, NA, NA, NULL)) { // from the current school?
|
||||
// not using 'cancast' here because we want to list spells
|
||||
// even if we don't have enough mp
|
||||
if (lfhasflagval(lf, F_CANCAST, ot->id, NA, NA, NULL)) {
|
||||
f = lfhasflagval(lf, F_CANCAST, ot->id, NA, NA, NULL);
|
||||
if ((f && !wantunknown) || (!f && wantunknown)) {
|
||||
int cost;
|
||||
int found = B_FALSE;
|
||||
cost = getmpcost(lf, ot->id);
|
||||
|
@ -3498,18 +3626,7 @@ void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2)
|
|||
strcpy(mpdesc[nposs], "(Deactivate, at will)");
|
||||
deactspell[nposs] = B_TRUE;
|
||||
} else {
|
||||
int ongoing = B_FALSE;
|
||||
if (hasflag(ot->flags, F_ONGOING)) ongoing = B_TRUE;
|
||||
|
||||
if (hasflag(ot->flags, F_VARPOWER)) {
|
||||
|
||||
sprintf(mpdesc[nposs], "(%d-%d MP%s)", mpcost[nposs],
|
||||
mpcost[nposs] * power,
|
||||
ongoing ? ", ongoing" : "");
|
||||
} else {
|
||||
sprintf(mpdesc[nposs], "(%d MP%s)", mpcost[nposs],
|
||||
ongoing ? ", ongoing" : "");
|
||||
}
|
||||
getspellcosttext(lf, ot->id, power, mpdesc[nposs]);
|
||||
}
|
||||
if (lf->mp >= mpcost[nposs]) {
|
||||
validspell[nposs] = B_TRUE;
|
||||
|
@ -3591,7 +3708,7 @@ void domagic(enum OBTYPE spellid, int cellx, int celly) {
|
|||
|
||||
// init the prompt if required.
|
||||
if (spellid == OT_NONE) {
|
||||
makespellchoicelist(&prompt, player, "Use which spell/ability:","Describe which spell/ability:");
|
||||
makespellchoicelist(&prompt, player, "Use which spell/ability:","Describe which spell/ability:", SS_NONE, B_FALSE);
|
||||
}
|
||||
|
||||
finished = B_FALSE;
|
||||
|
@ -3659,7 +3776,7 @@ void domemmagic(void) {
|
|||
char ch;
|
||||
int slot;
|
||||
objecttype_t *ot;
|
||||
makespellchoicelist(&prompt, player, "Memorise which spell/ability:","Describe which spell/ability");
|
||||
makespellchoicelist(&prompt, player, "Memorise which spell/ability:","Describe which spell/ability",SS_NONE, B_FALSE);
|
||||
if (prompt.nchoices <= 0) {
|
||||
msg("You don't have any spells or abilities!");
|
||||
return;
|
||||
|
@ -4091,9 +4208,9 @@ void doread(obpile_t *op) {
|
|||
|
||||
void dorest(void) {
|
||||
// can we rest?
|
||||
if (canrest(player)) {
|
||||
if (safetorest(player)) {
|
||||
int willtrain = B_FALSE;
|
||||
if (player->skillpoints || lfhasflag(player, F_STATGAINREADY)) {
|
||||
if (lfhasflag(player, F_HASNEWLEVEL)) {
|
||||
int ch;
|
||||
ch = askchar("Would you like to train your skills?","yn","y", B_TRUE);
|
||||
if (ch == 'y') {
|
||||
|
@ -4105,44 +4222,48 @@ void dorest(void) {
|
|||
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, "bn");
|
||||
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);
|
||||
if (needstorest(player, validchars)) {
|
||||
if (strchr(validchars, 'h') && strchr(validchars, 'm')) {
|
||||
strcat(validchars, "bn");
|
||||
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 (countnearbyallies(player)) {
|
||||
strcpy(ques, "Rest until nearby allies are healed?");
|
||||
ch = askchar(ques, "yn", "y", B_TRUE);
|
||||
if (ch == 'y') {
|
||||
addflag(player->flags, F_RESTUNTILALLIES, 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)) {
|
||||
if (!lfhasflag(player, F_RESTUNTILHP) &&
|
||||
!lfhasflag(player, F_RESTUNTILMP) &&
|
||||
!lfhasflag(player, F_RESTUNTILALLIES)) {
|
||||
msg("Cancelled.");
|
||||
return;
|
||||
}
|
||||
|
@ -4313,7 +4434,10 @@ void drawscannedcell(cell_t *cell, int x, int y) {
|
|||
int downline(int *y, int h, char *heading, char *subheading, char *bottomstring, char *cmdchars, char *retchar) {
|
||||
char headbuf[BUFLEN];
|
||||
int ch;
|
||||
sprintf(headbuf, "%s (continued)", heading);
|
||||
int w;
|
||||
w = getmaxx(mainwin);
|
||||
|
||||
snprintf(headbuf, w-1, "%s (continued)", heading);
|
||||
(*y)++;
|
||||
if (*y >= (h-3)) {
|
||||
centre(mainwin, h-2, MORESTRING);
|
||||
|
@ -4331,6 +4455,7 @@ int downline(int *y, int h, char *heading, char *subheading, char *bottomstring,
|
|||
|
||||
cls(); *y = 0;
|
||||
centre(mainwin, *y, headbuf);
|
||||
|
||||
*y += 2;
|
||||
wmove(mainwin, *y, 0);
|
||||
if (subheading) {
|
||||
|
@ -4478,7 +4603,8 @@ void doheading(WINDOW *win, int *y, int x, char *what) {
|
|||
char *buf;
|
||||
len = strlen(what) + 1;
|
||||
buf = malloc(len * sizeof(char));
|
||||
memset(buf, '-', (size_t)len);
|
||||
memset(buf, '-', (size_t)(len-1));
|
||||
buf[len] = '\0';
|
||||
mvwprintw(win, *y, x, what); (*y)++;
|
||||
mvwprintw(win, *y, x, buf); (*y)++;
|
||||
free(buf);
|
||||
|
@ -4552,6 +4678,9 @@ int drop(object_t *o, int count) {
|
|||
op = o->pile;
|
||||
assert(op->owner);
|
||||
|
||||
// in case we get burduned
|
||||
if (isplayer(op->owner)) statdirty = B_TRUE;
|
||||
|
||||
getobname(o, obname, count);
|
||||
|
||||
origid = o->type->id;
|
||||
|
@ -5491,12 +5620,12 @@ void drawstatus(void) {
|
|||
player->level);
|
||||
mvwprintw(statwin, 0, 0, buf);
|
||||
|
||||
if ((player->skillpoints == 0) && (getattpoints(player) == 0)) {
|
||||
wprintw(statwin, " Next:%ld",xpleft);
|
||||
} else {
|
||||
if (lfhasflag(player, F_HASNEWLEVEL)) {
|
||||
setcol(statwin, C_BOLDGREEN);
|
||||
wprintw(statwin, " LevUp",xpleft);
|
||||
unsetcol(statwin, C_BOLDGREEN);
|
||||
} else {
|
||||
wprintw(statwin, " Next:%ld",xpleft);
|
||||
}
|
||||
// blinded?
|
||||
if (isblind(player)) {
|
||||
|
@ -5581,10 +5710,24 @@ void drawstatus(void) {
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
// show certain flags
|
||||
if (lfhasflag(player, F_POISONED)) {
|
||||
f = isdrunk(player);
|
||||
if (f) {
|
||||
char dstring[BUFLEN];
|
||||
strcpy(dstring, getdrunktext(f));
|
||||
capitalise(dstring);
|
||||
setcol(statwin, C_BROWN);
|
||||
//wprintw(statwin, " %s(%d)", dstring,f->lifetime);
|
||||
wprintw(statwin, " %s", dstring);
|
||||
unsetcol(statwin, C_BROWN);
|
||||
}
|
||||
|
||||
f = ispoisoned(player);
|
||||
if (f) {
|
||||
// find highest amount of poison
|
||||
if (getskill(player, SK_FIRSTAID) >= PR_ADEPT) {
|
||||
if (poisonthreatenslife(player)) {
|
||||
if (poisonthreatenslife(player, f)) {
|
||||
setcol(statwin, C_GREEN);
|
||||
wprintw(statwin, " Poison(bad)");
|
||||
unsetcol(statwin, C_GREEN);
|
||||
|
@ -5622,6 +5765,18 @@ void drawstatus(void) {
|
|||
unsetcol(statwin, C_BROWN);
|
||||
}
|
||||
|
||||
// good effects
|
||||
f = lfhasflag(player, F_HIDING);
|
||||
if (f) {
|
||||
setcol(statwin, C_BLUE);
|
||||
if (f->val[0] < 0) {
|
||||
wprintw(statwin, " Hiding--");
|
||||
} else {
|
||||
wprintw(statwin, " Hiding");
|
||||
}
|
||||
unsetcol(statwin, C_BLUE);
|
||||
}
|
||||
|
||||
// construct waiting string
|
||||
strcpy(waitbuf, "");
|
||||
/*
|
||||
|
@ -5644,6 +5799,7 @@ void drawstatus(void) {
|
|||
wprintw(statwin, " (%s)",waitbuf);
|
||||
}
|
||||
|
||||
|
||||
// SECOND LINE
|
||||
|
||||
for (a = 0; a < MAXATTS; a++) {
|
||||
|
@ -5946,7 +6102,7 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
|
||||
if (showall) {
|
||||
sprintf(prompt, "[@=stats S=skills/abilities M=magic E=effects %sESC=quit]", isplayer(lf) ? "" : "I=items " );
|
||||
sprintf(cmdchars, "@ase%s",isplayer(lf) ? "" : "i");
|
||||
sprintf(cmdchars, "@asme%s",isplayer(lf) ? "" : "i");
|
||||
} else {
|
||||
sprintf(prompt, "%s", "[ESC=quit]");
|
||||
sprintf(cmdchars, "%s", "@");
|
||||
|
@ -6380,6 +6536,11 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, buf);
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_HIDING);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s hiding.", you(lf), isplayer(lf) ? "are" : "is");
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_INVISIBLE);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s invisible.", you(lf), isplayer(lf) ? "are" : "is");
|
||||
|
@ -6649,22 +6810,42 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
y++;
|
||||
|
||||
if (!exitnow) {
|
||||
if (hasflag(lf->flags, F_HASSKILL)) {
|
||||
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)",
|
||||
ismaxedskill(lf, f->val[0]) ? '*' : '-',
|
||||
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;
|
||||
}
|
||||
char skilltitle[BUFLEN];
|
||||
flag_t *known[MAXSKILLS], *available[MAXSKILLS];
|
||||
int numknown = 0, numavailable = 0;
|
||||
int n;
|
||||
|
||||
for (f = lf->flags->first ; f ; f = f->next) {
|
||||
if (f->id == F_HASSKILL) {
|
||||
known[numknown++] = f;
|
||||
} else if (f->id == F_CANLEARN) {
|
||||
if (!getskill(lf, f->val[0])) {
|
||||
available[numavailable++] = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//centre(mainwin, y, "SKILLS"); y ++;
|
||||
sprintf(skilltitle, "%-40s%-40s","AVAILABLE SKILLS", "KNOWN SKILLS");
|
||||
doheading(mainwin, &y, 0, skilltitle);
|
||||
for (n = 0; n < MAXOF(numknown,numavailable); n++) {
|
||||
if (n < numavailable) {
|
||||
mvwprintw(mainwin, y, 0, "- %s",
|
||||
getskillname(available[n]->val[0]) );
|
||||
}
|
||||
if (n < numknown) {
|
||||
mvwprintw(mainwin, y, 40, "%c %s (%s%s)",
|
||||
ismaxedskill(lf, known[n]->val[0]) ? '*' : '-',
|
||||
getskillname(known[n]->val[0]),
|
||||
getskilllevelname(known[n]->val[1]),
|
||||
ismaxedskill(lf, known[n]->val[0]) ? "/MAX" : "");
|
||||
}
|
||||
if (downline(&y, h, "SKILLS", skilltitle, prompt, cmdchars, &ch)) {
|
||||
exitnow = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (mode == 'm') {
|
||||
char subheading[BUFLEN];
|
||||
|
@ -6672,9 +6853,9 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
int anyfound;
|
||||
int exitnow = B_FALSE;
|
||||
|
||||
sprintf(subheading, " %-4s%-25s%-22s%s","Lv","Spell", "School", "Cost");
|
||||
sprintf(subheading, " %-4s%-26s%-15s%-13s%s","Lv","Spell", "School", "Power", "Cost");
|
||||
|
||||
centre(mainwin, y, "SPELLS"); y += 2;
|
||||
centre(mainwin, y, "MAGIC"); y += 2;
|
||||
doheading(mainwin, &y, 0, subheading);
|
||||
//if (!isplayer(lf)) {
|
||||
// show spells monster can cast using mp
|
||||
|
@ -6691,8 +6872,23 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
if (f && (f->known)) {
|
||||
char spellname[BUFLEN];
|
||||
char mpbuf[BUFLEN];
|
||||
char powerbuf[BUFLEN];
|
||||
int power;
|
||||
int mpcost;
|
||||
|
||||
// power
|
||||
power = getspellpower(lf, ot->id);
|
||||
sprintf(powerbuf, "[");
|
||||
for (i = 0; i < power; i++) {
|
||||
strcat(powerbuf, "#");
|
||||
}
|
||||
for (i = 0; i < (getspellmaxpower(ot->id) - power); i++) {
|
||||
strcat(powerbuf, "-");
|
||||
}
|
||||
strcat(powerbuf, "]");
|
||||
|
||||
|
||||
// mp cost
|
||||
if (f->id == F_CANWILL) {
|
||||
mpcost = 0;
|
||||
|
||||
|
@ -6703,26 +6899,20 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
(f->val[2] == 1) ? "" : "s");
|
||||
}
|
||||
} else {
|
||||
|
||||
mpcost = getmpcost(lf, ot->id);
|
||||
if (mpcost) {
|
||||
if (hasflag(ot->flags, F_ONGOING)) {
|
||||
sprintf(mpbuf, "%d MP ongoing", mpcost);
|
||||
} else {
|
||||
sprintf(mpbuf, "%d MP", mpcost);
|
||||
}
|
||||
getspellcosttext(lf, ot->id, power, mpbuf);
|
||||
} else {
|
||||
sprintf(mpbuf, "At will");
|
||||
}
|
||||
}
|
||||
|
||||
power = getspellpower(lf, ot->id);
|
||||
|
||||
getspellname(ot->id, lf, spellname);
|
||||
sprintf(buf, " %-4d%-25s%-22s%s",thislev, spellname, getschoolname(getspellschool(ot->id)), mpbuf);
|
||||
sprintf(buf, " %-4d%-26s%-15s%-13s%s",thislev, spellname, getschoolnameshort(getspellschool(ot->id)), powerbuf, mpbuf);
|
||||
mvwprintw(mainwin, y, 0, "%s\n", buf);
|
||||
anyfound = B_TRUE;
|
||||
if (downline(&y, h, "SPELLS", subheading, prompt, cmdchars, &ch)) {
|
||||
if (downline(&y, h, "MAGIC", subheading, prompt, cmdchars, &ch)) {
|
||||
exitnow = B_TRUE;
|
||||
break;
|
||||
}
|
||||
|
@ -6743,15 +6933,15 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
|
||||
// ready to gain a level?
|
||||
if (lfhasflag(lf, F_STATGAINREADY)) {
|
||||
mvwprintw(mainwin, y, 0, "%s are ready for training.", you(lf));
|
||||
mvwprintw(mainwin, y, 0, "%s are ready to train your attributes.", you(lf));
|
||||
y++;
|
||||
}
|
||||
if (lf->skillpoints >= 2) {
|
||||
if (lf->skillpoints) {
|
||||
mvwprintw(mainwin, y, 0, "%s are ready to learn a new skill.", you(lf));
|
||||
y++;
|
||||
} else if (lf->skillpoints) {
|
||||
mvwprintw(mainwin, y, 0, "%s are ready to enhance %s existing skills.", you(lf),
|
||||
isplayer(lf) ? "your" : "its");
|
||||
}
|
||||
if (levelabilityready(lf)) {
|
||||
mvwprintw(mainwin, y, 0, "%s are ready to learn a new job-based ability.", you(lf));
|
||||
y++;
|
||||
}
|
||||
|
||||
|
@ -6768,6 +6958,13 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
|
||||
|
||||
// show racial effects
|
||||
if (hasjob(lf, J_PIRATE)) {
|
||||
mvwprintw(mainwin, y, 0, "%s can hold %s liquor well.", you(lf), isplayer(lf) ? "your" : "its");
|
||||
y++;
|
||||
mvwprintw(mainwin, y, 0, "%s %s missing one eye.", you(lf), isplayer(lf) ? "are" : "is");
|
||||
y++;
|
||||
}
|
||||
|
||||
// show intrinsics
|
||||
f = lfhasknownflag(lf, F_ATTRSET);
|
||||
|
@ -6853,7 +7050,18 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, "%s automatically detect nearby objects.", you(lf));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_ENHANCESEARCH);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s searching ability is enhanced.", you(lf), isplayer(lf) ? "Your" : "Its");
|
||||
y++;
|
||||
}
|
||||
|
||||
f = lfhasknownflag(lf, F_DRUNK);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s %s.", you(lf),
|
||||
isplayer(lf) ? "are" : "is", getdrunktext(f));
|
||||
y++;
|
||||
}
|
||||
|
||||
// extra dam - can have it multiple times
|
||||
for (f = lf->flags->first ; f; f = f->next) {
|
||||
|
@ -6913,27 +7121,30 @@ 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_POISONED);
|
||||
if (f && (f->known)) {
|
||||
int knownfatal = B_FALSE;
|
||||
for (f = lf->flags->first ; f ; f = f->next ){
|
||||
if (f->known && (f->id == F_POISONED)) {
|
||||
int knownfatal = B_FALSE;
|
||||
|
||||
if (getskill(player, SK_FIRSTAID) >= PR_ADEPT) {
|
||||
if (poisonthreatenslife(lf)) {
|
||||
knownfatal = B_TRUE;
|
||||
if (getskill(player, SK_FIRSTAID) >= PR_ADEPT) {
|
||||
if (poisonthreatenslife(lf, f)) {
|
||||
knownfatal = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(buf, "%s %s poisoned%s.", you(lf), isplayer(lf) ? "are" : "is",
|
||||
knownfatal ? ", potentially fatally" : "");
|
||||
if (lfhasflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT) ||
|
||||
(getskill(player, SK_FIRSTAID) >= PR_ADEPT) ) {
|
||||
char buf2[BUFLEN];
|
||||
sprintf(buf2, " [max %d turns left]", f->lifetime);
|
||||
strcat(buf, buf2);
|
||||
sprintf(buf, "%s %s sick with %s%s.", you(lf), isplayer(lf) ? "are" : "is",
|
||||
getpoisonname(f->val[0]),
|
||||
knownfatal ? ", potentially fatally" : "");
|
||||
if (lfhasflag(lf, F_EXTRAINFO) || lfhasflag(lf, F_OMNIPOTENT) ||
|
||||
(getskill(player, SK_FIRSTAID) >= PR_ADEPT) ) {
|
||||
char buf2[BUFLEN];
|
||||
sprintf(buf2, " [max %d turns left]", f->lifetime);
|
||||
strcat(buf, buf2);
|
||||
}
|
||||
mvwprintw(mainwin, y, 0, buf);
|
||||
y++;
|
||||
}
|
||||
mvwprintw(mainwin, y, 0, buf);
|
||||
y++;
|
||||
}
|
||||
|
||||
f = lfhasflag(lf, F_NAUSEATED);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s nauseated.", you(lf), isplayer(lf) ? "are" : "is");
|
||||
|
@ -6999,7 +7210,11 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
|
||||
f = lfhasflag(lf, F_PAIN);
|
||||
if (f && (f->known)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s in extreme pain, and movement will cause %s damage.", you(lf), isplayer(lf) ? "are" : "is", isplayer(lf) ? "you" : "it");
|
||||
if (isdrunk(lf)) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s in extreme pain, somewhat mitigated by %s inebriation.", you(lf), isplayer(lf) ? "are" : "is", isplayer(lf) ? "your" : "its");
|
||||
} else {
|
||||
mvwprintw(mainwin, y, 0, "%s %s in extreme pain, and movement will cause %s damage.", you(lf), isplayer(lf) ? "are" : "is", isplayer(lf) ? "you" : "it");
|
||||
}
|
||||
y++;
|
||||
}
|
||||
|
||||
|
@ -7047,6 +7262,11 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
mvwprintw(mainwin, y, 0, "%s %s %s resistant to magic.", you(lf), isplayer(lf) ? "are" : "is", adjective);
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_TREMORSENSE);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s can 'see' by sensing vibrations around you.", you(lf));
|
||||
y++;
|
||||
}
|
||||
f = lfhasknownflag(lf, F_WINDSHIELD);
|
||||
if (f) {
|
||||
mvwprintw(mainwin, y, 0, "%s %s protected from missiles by a cyclonic shield", you(lf), isplayer(lf) ? "are" : "is");
|
||||
|
@ -7105,8 +7325,16 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
cls();
|
||||
centre(mainwin, 0, "INVENTORY");
|
||||
y = 2;
|
||||
if (countobs(lf->pack)) {
|
||||
mvwprintw(mainwin, y, 0, "It is carrying:");
|
||||
if (lfhasflag(lf, F_NOPACK)) {
|
||||
mvwprintw(mainwin, y, 0, "It cannot carry anything.");
|
||||
} else if (countobs(lf->pack)) {
|
||||
char invtitle[BUFLEN];
|
||||
float packweight,maxweight,pct;
|
||||
packweight = getobpileweight(lf->pack);
|
||||
maxweight = getmaxcarryweight(lf);
|
||||
pct = (packweight / maxweight) * 100;
|
||||
sprintf(invtitle, "It is carrying: (%0.0f/%0.0f kg, %0.0f%%)", packweight, maxweight, pct);
|
||||
mvwprintw(mainwin, y, 0, "%s", invtitle);
|
||||
y += 2;
|
||||
for (o = lf->pack->first ; o ; o = o->next) {
|
||||
getobname(o, buf,o->amt);
|
||||
|
@ -7148,7 +7376,14 @@ void showlfstats(lifeform_t *lf, int showall) {
|
|||
}
|
||||
} // end while !done
|
||||
|
||||
statdirty = B_TRUE;
|
||||
needredraw = B_TRUE;
|
||||
|
||||
cls(); wrefresh(mainwin);
|
||||
drawscreen();
|
||||
wrefresh(gamewin);
|
||||
wrefresh(statwin);
|
||||
|
||||
real_clearmsg(B_TRUE);
|
||||
//redraw();
|
||||
}
|
||||
|
|
2
io.h
2
io.h
|
@ -80,7 +80,7 @@ void initgfx(void);
|
|||
void initprompt(prompt_t *p, char *q1);
|
||||
int keycodetokey(int keycode);
|
||||
void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters);
|
||||
void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2);
|
||||
void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2, enum SPELLSCHOOL wantschool, int wantunknown);
|
||||
void more(void);
|
||||
void warn(char *format, ... );
|
||||
void msg(char *format, ... );
|
||||
|
|
19
lf.h
19
lf.h
|
@ -24,7 +24,6 @@ int canpickup(lifeform_t *lf, object_t *o, int amt);
|
|||
int canpolymorphto(enum RACE rid);
|
||||
int canpush(lifeform_t *lf, object_t *o, int dir);
|
||||
int canquaff(lifeform_t *lf, object_t *o);
|
||||
int canrest(lifeform_t *lf);
|
||||
int cansee(lifeform_t *viewer, lifeform_t *viewee);
|
||||
int canwear(lifeform_t *lf, object_t *o, enum BODYPART where);
|
||||
int canweild(lifeform_t *lf, object_t *o);
|
||||
|
@ -32,6 +31,7 @@ int cantakeoff(lifeform_t *lf, object_t *o);
|
|||
int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell);
|
||||
void checkxp(enum RACE rid);
|
||||
int countmoney(lifeform_t *lf);
|
||||
int countnearbyallies(lifeform_t *lf);
|
||||
void debug(lifeform_t *lf);
|
||||
void die(lifeform_t *lf);
|
||||
void dumplf(void);
|
||||
|
@ -64,6 +64,7 @@ int getarmourrating(lifeform_t *lf);
|
|||
int getattackspeed(lifeform_t *lf);
|
||||
int getattpoints(lifeform_t *lf);
|
||||
int getattr(lifeform_t *lf, enum ATTRIB attr);
|
||||
int real_getattr(lifeform_t *lf, enum ATTRIB attr, int ignoreattrset);
|
||||
int getevasion(lifeform_t *lf);
|
||||
object_t *getbestthrowmissile(lifeform_t *lf);
|
||||
object_t *getbestweapon(lifeform_t *lf);
|
||||
|
@ -109,6 +110,9 @@ float getlfweight(lifeform_t *lf, int withobs);
|
|||
int getspellspeed(lifeform_t *lf);
|
||||
char *getplayername(char *buf);
|
||||
char *getplayernamefull(char *buf);
|
||||
int getpoisondamchance(enum POISONTYPE ptype);
|
||||
char *getpoisondamverb(enum POISONTYPE ptype);
|
||||
char *getpoisonname(enum POISONTYPE ptype);
|
||||
int getracerarity(enum RACE rid);
|
||||
object_t *getrandomarmour(lifeform_t *lf);
|
||||
//int getrandommonlevel(int depth);
|
||||
|
@ -157,6 +161,7 @@ int isblind(lifeform_t *lf);
|
|||
enum BURDENED isburdened(lifeform_t *lf);
|
||||
int ischarmable(lifeform_t *lf);
|
||||
int isdead(lifeform_t *lf);
|
||||
flag_t *isdrunk(lifeform_t *lf);
|
||||
int isfleeing(lifeform_t *lf);
|
||||
int isfreebp(lifeform_t *lf, enum BODYPART bp);
|
||||
int isfriendly(lifeform_t *lf);
|
||||
|
@ -166,13 +171,16 @@ flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt);
|
|||
int isingunrange(lifeform_t *lf, cell_t *where);
|
||||
int ismaxedskill(lifeform_t *lf, enum SKILL skid);
|
||||
int ispeaceful(lifeform_t *lf);
|
||||
int ispetof(lifeform_t *lf, lifeform_t *owner);
|
||||
int isplayer(lifeform_t *lf);
|
||||
flag_t *ispoisoned(lifeform_t *lf);
|
||||
int ispolymorphed(lifeform_t *lf);
|
||||
flag_t *isresistantto(flagpile_t *fp, enum DAMTYPE dt);
|
||||
flag_t *isvulnto(flagpile_t *fp, enum DAMTYPE dt);
|
||||
void killjob(job_t *job);
|
||||
void killlf(lifeform_t *lf);
|
||||
void killrace(race_t *race);
|
||||
flag_t *levelabilityready(lifeform_t *lf);
|
||||
void loseconcentration(lifeform_t *lf);
|
||||
int losehp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc);
|
||||
int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam);
|
||||
|
@ -185,14 +193,17 @@ void mayusespellschool(flagpile_t *fp, enum SPELLSCHOOL ss, enum FLAG how);
|
|||
int modattr(lifeform_t *lf, enum ATTRIB attr, int amt);
|
||||
void modhunger(lifeform_t *lf, int amt);
|
||||
float modifybystat(float num, lifeform_t *lf, enum ATTRIB att);
|
||||
int needstorest(lifeform_t *lf, char *validchars);
|
||||
void noise(cell_t *c, lifeform_t *noisemaker, char *text, char *seetext);
|
||||
void outfitlf(lifeform_t *lf);
|
||||
int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground);
|
||||
void poison(lifeform_t *lf, int howlong, char *fromwhat);
|
||||
int poisonthreatenslife(lifeform_t *lf);
|
||||
void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat);
|
||||
int poisonthreatenslife(lifeform_t *lf, flag_t *f);
|
||||
void practice(lifeform_t *lf, enum SKILL skid);
|
||||
void precalclos(lifeform_t *lf);
|
||||
int push(lifeform_t *lf, object_t *o, int dir);
|
||||
int readytotrain(lifeform_t *lf);
|
||||
void refreshlevelabilities(lifeform_t *lf);
|
||||
void relinklf(lifeform_t *src, map_t *dst);
|
||||
int rest(lifeform_t *lf, int onpurpose);
|
||||
void startresting(lifeform_t *lf, int willtrain);
|
||||
|
@ -201,6 +212,7 @@ int rolldex(enum DEXBRACKET bracket);
|
|||
int rolliq(enum IQBRACKET bracket);
|
||||
int rollstr(enum STRBRACKET bracket);
|
||||
int rollstat(lifeform_t *lf, enum ATTRIB attr);
|
||||
int safetorest(lifeform_t *lf);
|
||||
int scare(lifeform_t *lf, lifeform_t *scarer, int howlong);
|
||||
int setammo(lifeform_t *lf, object_t *o);
|
||||
void setattr(lifeform_t *lf, enum ATTRIB attr, int val);
|
||||
|
@ -224,6 +236,7 @@ int throwat(lifeform_t *thrower, object_t *o, cell_t *where);
|
|||
void timeeffectslf(lifeform_t *lf);
|
||||
void turneffectslf(lifeform_t *lf);
|
||||
int touch(lifeform_t *lf, object_t *o);
|
||||
void unpoison(lifeform_t *lf);
|
||||
int unweild(lifeform_t *lf, object_t *o);
|
||||
int useability(lifeform_t *lf, enum OBTYPE aid, lifeform_t *who, cell_t *where);
|
||||
int useringofmiracles(lifeform_t *lf, int charges);
|
||||
|
|
95
map.c
95
map.c
|
@ -14,6 +14,7 @@
|
|||
#include "text.h"
|
||||
|
||||
extern map_t *firstmap,*lastmap;
|
||||
extern celltype_t *firstcelltype, *lastcelltype;
|
||||
extern int viewx,viewy,vieww,viewh;
|
||||
extern lifeform_t *player;
|
||||
|
||||
|
@ -408,7 +409,12 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
|
|||
|
||||
// draw highest object in sort order
|
||||
o = gettopobject(c);
|
||||
if (o) {
|
||||
if (hasobwithflag(c->obpile, F_SECRETDOOR)) {
|
||||
celltype_t *ct;
|
||||
ct = findcelltype(getwallcelltype(c->map->habitat));
|
||||
*g = ct->glyph;
|
||||
} else if (o) {
|
||||
// return the object's glyph
|
||||
*g = *(getglyph(o));
|
||||
} else {
|
||||
// should never happen. if it does, just show the
|
||||
|
@ -468,10 +474,31 @@ enum CELLTYPE getemptycelltype(enum HABITAT hab) {
|
|||
return CT_CORRIDOR;
|
||||
}
|
||||
|
||||
enum CELLTYPE getwallcelltype(enum HABITAT hab) {
|
||||
switch (hab) {
|
||||
case H_DUNGEON:
|
||||
return CT_WALL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return CT_WALL;
|
||||
}
|
||||
|
||||
object_t *gettopobject(cell_t *where) {
|
||||
object_t *o;
|
||||
int c;
|
||||
// draw highest object in sort order
|
||||
// draw impassable objects first...
|
||||
o = hasobwithflag(where->obpile, F_IMPASSABLE);
|
||||
if (o) {
|
||||
// ignore secret doors
|
||||
if (issecretdoor(o)) {
|
||||
return NULL;
|
||||
} else {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise draw highest object in sort order
|
||||
c = 0;
|
||||
while (sortorder[c] != OC_NULL) {
|
||||
// check each object against this ob class
|
||||
|
@ -479,7 +506,11 @@ object_t *gettopobject(cell_t *where) {
|
|||
// appear first.
|
||||
for (o = where->obpile->last ; o ; o = o->prev) {
|
||||
if (o->type->obclass->id == sortorder[c]) {
|
||||
return o;
|
||||
if (issecretdoor(o)) {
|
||||
return NULL;
|
||||
} else {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
}
|
||||
c++;
|
||||
|
@ -1584,10 +1615,16 @@ printf("dump of map '%s' (%d x %d):\n",map->name, map->w, map->h);
|
|||
}
|
||||
}
|
||||
|
||||
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int wantannounce) {
|
||||
// dirtype of DT_COMPASS will give a square explosion
|
||||
// dirtype of DT_COMPASS will give a circular explosion
|
||||
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int dirtype, int wantannounce) {
|
||||
int x,y;
|
||||
|
||||
animradial(c, range, '}', C_RED);
|
||||
if (dirtype == DT_COMPASS) {
|
||||
animradial(c, range, '}', C_RED);
|
||||
} else { // ie. DT_ORTH
|
||||
animradialorth(c, range, '}', C_RED);
|
||||
}
|
||||
|
||||
if (haslos(player, c)) {
|
||||
if (wantannounce) {
|
||||
|
@ -1599,10 +1636,18 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
|
|||
|
||||
for (y = c->y - range ; y <= c->y + range ; y++) {
|
||||
for (x = c->x - range ; x <= c->x + range ; x++) {
|
||||
int inrange = B_FALSE;
|
||||
cell_t *cc;
|
||||
cc = getcellat(c->map, x,y);
|
||||
if (cc && (getcelldist(c, cc) <= range)) {
|
||||
explodesinglecell(cc, dam, killwalls, o, c);
|
||||
if (cc) {
|
||||
if ((dirtype == DT_COMPASS) && (getcelldist(c,cc) <= range)) {
|
||||
inrange = B_TRUE;
|
||||
} else if ((dirtype == DT_ORTH) && (getcelldistorth(c,cc) <= range)) {
|
||||
inrange = B_TRUE;
|
||||
}
|
||||
if (inrange && haslof(c, cc, LOF_WALLSTOP, NULL)) {
|
||||
explodesinglecell(cc, dam, killwalls, o, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1654,6 +1699,14 @@ void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *c
|
|||
}
|
||||
}
|
||||
|
||||
celltype_t *findcelltype(enum CELLTYPE cid) {
|
||||
celltype_t *ct;
|
||||
for (ct = firstcelltype ; ct ; ct = ct->next) {
|
||||
if (ct->id == cid) return ct;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
map_t *findmap(int mid) {
|
||||
map_t *m;
|
||||
for (m = firstmap ; m ; m = m->next) {
|
||||
|
@ -2011,6 +2064,20 @@ cell_t *getrandomroomcell(map_t *map, int roomid) {
|
|||
return c;
|
||||
}
|
||||
|
||||
// popuplates retcell[] with all cells from room
|
||||
void getroomcells(map_t *m, int roomid, cell_t **retcell, int *ncells) {
|
||||
int i;
|
||||
cell_t *c;
|
||||
*ncells = 0;
|
||||
for (i = 0; i < m->w*m->h; i++) {
|
||||
c = m->cell[i];
|
||||
if (c && (c->roomid == roomid)) {
|
||||
retcell[*ncells] = c;
|
||||
(*ncells)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns how slippery this cell is
|
||||
int getslipperyness(cell_t *c, object_t **slipob) {
|
||||
object_t *o;
|
||||
|
@ -2383,17 +2450,27 @@ void makedoor(cell_t *cell) {
|
|||
} else {
|
||||
int chance;
|
||||
// door is closed - lock it?
|
||||
chance = rolldie(1,6); // ie. 1 in 6
|
||||
|
||||
// ie. at dungeon lev 10, chance is 2 in 6
|
||||
// at dungeon lev 20, chance is 3 in 6
|
||||
// ...
|
||||
// at dungeon lev 50, chance is 5 in 6
|
||||
chance -= (m->depth / 10);
|
||||
chance = rolldie(1,6) - (m->depth / 10);
|
||||
|
||||
if (chance <= 1) {
|
||||
addflag(o->flags, F_LOCKED, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
|
||||
// make it secret?
|
||||
chance = rolldie(1,6) - (m->depth / 10);
|
||||
|
||||
// difficulty:
|
||||
// l1 = 20
|
||||
// l10 = 25
|
||||
// l20 = 30
|
||||
if (chance <= 1) {
|
||||
addflag(o->flags, F_SECRETDOOR, 20 + (m->depth / 2), NA, NA, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
5
map.h
5
map.h
|
@ -11,6 +11,7 @@ int getcelldist(cell_t *src, cell_t *dst);
|
|||
int getcelldistorth(cell_t *src, cell_t *dst);
|
||||
void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer);
|
||||
enum CELLTYPE getemptycelltype(enum HABITAT hab);
|
||||
enum CELLTYPE getwallcelltype(enum HABITAT hab);
|
||||
object_t *gettopobject(cell_t *where);
|
||||
void calclight(map_t *map);
|
||||
int calcroompos(map_t *map, int w, int h, int *bx, int *by);
|
||||
|
@ -23,7 +24,8 @@ int dirtox(int dt, int dir);
|
|||
int dirtoy(int dt, int dir);
|
||||
void dumpmap(map_t *map);
|
||||
void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *centre);
|
||||
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int wantannounce);
|
||||
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int dirtype, int wantannounce);
|
||||
celltype_t *findcelltype(enum CELLTYPE cid);
|
||||
map_t *findmap(int mid);
|
||||
map_t *findmapofdepth(int depth);
|
||||
object_t *findobidinmap(map_t *m, long id);
|
||||
|
@ -37,6 +39,7 @@ cell_t *getrandomcell(map_t *map);
|
|||
cell_t *getrandomcelloftype(map_t *map, int id);
|
||||
int getrandomdir(int dirtype);
|
||||
cell_t *getrandomroomcell(map_t *map, int roomid);
|
||||
void getroomcells(map_t *m, int roomid, cell_t **retcell, int *ncells);
|
||||
int getslipperyness(cell_t *c, object_t **slipob);
|
||||
cell_t *getstairdestination(object_t *o);
|
||||
object_t *hasenterableobject(cell_t *c);
|
||||
|
|
103
move.c
103
move.c
|
@ -121,13 +121,15 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
|
|||
for (o = cell->obpile->first ; o ; o = o->next) {
|
||||
f = hasflag(o->flags, F_WALKDAM);
|
||||
if (f) {
|
||||
// are we immune to this?
|
||||
if (!lfhasflagval(lf, F_DTIMMUNE, f->val[0], NA, NA, NULL)) {
|
||||
if (error) {
|
||||
*error = E_AVOIDOB;
|
||||
rdata = o;
|
||||
}
|
||||
return B_TRUE;
|
||||
if ((f->val[0] != DT_WATER) || isvulnto(lf->flags, DT_WATER)) {
|
||||
// are we immune to this?
|
||||
if (!lfhasflagval(lf, F_DTIMMUNE, f->val[0], NA, NA, NULL)) {
|
||||
if (error) {
|
||||
*error = E_AVOIDOB;
|
||||
rdata = o;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -203,7 +205,11 @@ int cellwalkable(lifeform_t *lf, cell_t *cell, enum ERROR *error) {
|
|||
rdata = o;
|
||||
if (error) {
|
||||
if (isdoor(o, NULL)) {
|
||||
*error = E_DOORINWAY;
|
||||
if (hasflag(o->flags, F_SECRETDOOR)) {
|
||||
*error = E_WALLINWAY;
|
||||
} else {
|
||||
*error = E_DOORINWAY;
|
||||
}
|
||||
} else {
|
||||
*error = E_OBINWAY;
|
||||
}
|
||||
|
@ -555,14 +561,16 @@ void moveeffects(lifeform_t *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);
|
||||
if (!isdrunk(lf)) {
|
||||
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");
|
||||
}
|
||||
losehp(lf, roll(f->text), f->val[0], NULL, "extreme pain");
|
||||
}
|
||||
|
||||
if (isdead(lf)) return;
|
||||
|
@ -577,6 +585,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
int didmsg = B_FALSE;
|
||||
flag_t *f;
|
||||
int changedlev = B_FALSE;
|
||||
int preroom = -1, postroom = -1;
|
||||
|
||||
getlfname(lf, lfname);
|
||||
|
||||
|
@ -584,8 +593,9 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
changedlev = B_TRUE;
|
||||
}
|
||||
|
||||
// update current cell
|
||||
// update current cell + room id
|
||||
lf->cell->lf = NULL;
|
||||
preroom = lf->cell->roomid;
|
||||
|
||||
// if required, relink lifeform to new map
|
||||
if (newcell->map != lf->cell->map) {
|
||||
|
@ -601,6 +611,9 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
// nothing should be in new cell..
|
||||
assert(!newcell->lf);
|
||||
|
||||
// remember new room...
|
||||
postroom = lf->cell->roomid;
|
||||
|
||||
// update new cell
|
||||
newcell->lf = lf;
|
||||
|
||||
|
@ -611,6 +624,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
|
||||
moveeffects(lf);
|
||||
|
||||
killflagsofid(lf->flags, F_HIDING);
|
||||
|
||||
// remove grabs
|
||||
f = lfhasflag(lf, F_GRABBING);
|
||||
if (f) {
|
||||
|
@ -686,6 +701,37 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
// (but without a map you will then slowly forget it)
|
||||
if (isplayer(lf)) {
|
||||
updateknowncells();
|
||||
|
||||
// TODO: not sure about this next bit yet...
|
||||
// it definitely won't work for non-square rooms
|
||||
// or rooms with pillars. would be better to fix
|
||||
// haslos() code to handle looking along walls
|
||||
// instead.
|
||||
// if you walked into a new fully lit room, reveal it
|
||||
if ((postroom > 0) && (postroom != preroom)) {
|
||||
cell_t *c[MAXRETCELLS];
|
||||
int ncells;
|
||||
int i,alllit = B_TRUE,allknown = B_TRUE;
|
||||
|
||||
// is the whole room lit?
|
||||
getroomcells(lf->cell->map, postroom, c, &ncells);
|
||||
for (i = 0; i < ncells; i++) {
|
||||
if (!islit(c[i])) {
|
||||
alllit = B_FALSE;
|
||||
}
|
||||
if (!c[i]->known) {
|
||||
allknown = B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (alllit && !allknown) {
|
||||
// make the all known
|
||||
for (i = 0; i < ncells; i++) {
|
||||
c[i]->known = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// does anyone else see you?
|
||||
|
@ -707,7 +753,6 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
}
|
||||
} else {
|
||||
if (isplayer(lf) && areallies(lf, l)) {
|
||||
|
||||
// remember player's last known loc
|
||||
f = lfhasflag(l, F_PETOF);
|
||||
if (f) {
|
||||
|
@ -715,7 +760,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
f->val[2] = player->cell->y;
|
||||
}
|
||||
}
|
||||
dointerrupt = B_TRUE;
|
||||
//dointerrupt = B_TRUE;
|
||||
}
|
||||
if (dointerrupt) {
|
||||
interrupt(l);
|
||||
|
@ -752,6 +797,9 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose) {
|
|||
}
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_HIDING)) {
|
||||
dontclearmsg = B_TRUE;
|
||||
}
|
||||
// actually do the move
|
||||
didmsg = movelf(lf, newcell);
|
||||
|
||||
|
@ -1178,6 +1226,17 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
cell_t *cell;
|
||||
enum ERROR errcode;
|
||||
char buf[BUFLEN];
|
||||
flag_t *f;
|
||||
|
||||
f = isdrunk(lf);
|
||||
if (f) {
|
||||
if (!hasjob(lf, J_PIRATE)) {
|
||||
if (rnd(1,6) <= ((f->lifetime/DRUNKTIME)+1)) {
|
||||
// randomize move
|
||||
dir = rnd(DC_N, DC_NW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cell = getcellindir(lf->cell, dir);
|
||||
if (canandwillmove(lf, dir, &errcode)) {
|
||||
|
@ -1273,7 +1332,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose) {
|
|||
if (!haslos(lf, cell)) {
|
||||
if (isplayer(lf)) {
|
||||
// only take damage if we didn't know about this
|
||||
if (!cell->known) {
|
||||
if (!cell->known || isdrunk(lf)) {
|
||||
sprintf(buf, "%sing into a wall", getmoveverb(lf));
|
||||
losehp(lf, 1, DT_BASH, NULL, buf);
|
||||
// we now know there is a wall there.
|
||||
|
@ -1441,15 +1500,21 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
|
|||
enum IQBRACKET iq;
|
||||
object_t *o;
|
||||
char buf[BUFLEN];
|
||||
|
||||
//object_t *o;
|
||||
iq = getiqname(getattr(lf, A_IQ), NULL);
|
||||
|
||||
|
||||
// default
|
||||
if (error) {
|
||||
*error = E_OK;
|
||||
rdata = NULL;
|
||||
}
|
||||
|
||||
if (isdrunk(lf)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
cell = getcellindir(lf->cell, dir);
|
||||
if (celldangerous(lf, cell, B_TRUE, error)) {
|
||||
if (error) *error = E_WONT;
|
||||
|
|
31
nexus.c
31
nexus.c
|
@ -128,6 +128,7 @@ int main(int argc, char **argv) {
|
|||
job_t *j = NULL;
|
||||
char ch;
|
||||
cell_t *where;
|
||||
int dir;
|
||||
flag_t *f;
|
||||
|
||||
// read from input file if required
|
||||
|
@ -196,6 +197,15 @@ int main(int argc, char **argv) {
|
|||
// player needs hunger
|
||||
addflag(player->flags, F_HUNGER, 0, NA, NA, NULL);
|
||||
|
||||
// kill any other lifeforms around the caster, to make room for pets.
|
||||
for (dir = DC_N; dir <= DC_NW; dir++) {
|
||||
cell_t *c;
|
||||
c = getcellindir(player->cell, dir);
|
||||
if (c && c->lf) {
|
||||
killlf(c->lf);
|
||||
}
|
||||
}
|
||||
|
||||
// pet / npc / follower
|
||||
f = lfhasflag(player, F_HASPET);
|
||||
if (f) {
|
||||
|
@ -211,11 +221,7 @@ int main(int argc, char **argv) {
|
|||
pet = addlf(c, r->id, 1);
|
||||
makefriendly(pet, PERMENANT);
|
||||
// mark us as its master
|
||||
if (lfhasflag(pet, F_ANIMAL) || lfhasflag(pet, F_INSECT)) {
|
||||
addflag(pet->flags, F_PETOF, player->id, player->cell->x, player->cell->y, NULL);
|
||||
} else {
|
||||
addflag(pet->flags, F_ALLYOF, player->id, player->cell->x, player->cell->y, NULL);
|
||||
}
|
||||
addflag(pet->flags, F_PETOF, player->id, player->cell->x, player->cell->y, NULL);
|
||||
}
|
||||
|
||||
getplayernamefull(pname);
|
||||
|
@ -486,7 +492,7 @@ void donextturn(map_t *map) {
|
|||
handleinput();
|
||||
} else {
|
||||
// do ai move
|
||||
aimove(who);
|
||||
aiturn(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -515,17 +521,6 @@ void donextturn(map_t *map) {
|
|||
|
||||
}
|
||||
|
||||
celltype_t *findcelltype(int id) {
|
||||
celltype_t *ct;
|
||||
for (ct = firstcelltype; ct ; ct = ct->next) {
|
||||
if (ct->id == id) {
|
||||
return ct;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *getdirname(int dir) {
|
||||
switch (dir) {
|
||||
case D_N:
|
||||
|
@ -590,7 +585,7 @@ void getrarity(int depth, int *min, int *max, int range) {
|
|||
//*max = mid + range; if (*max > 100) *max = 100;
|
||||
*max = 100;
|
||||
|
||||
if (*min > 85) *min = 85;
|
||||
//if (*min > 85) *min = 85;
|
||||
if (*max < 25) *max = 25;
|
||||
}
|
||||
|
||||
|
|
1
nexus.h
1
nexus.h
|
@ -7,7 +7,6 @@ void checkendgame(void);
|
|||
void cleanup(void);
|
||||
void dobresnham(int d, int xinc1, int yinc1, int dinc1, int xinc2, int yinc2, int dinc2, int *xinc, int *yinc, int *dinc);
|
||||
void donextturn(map_t *map);
|
||||
celltype_t *findcelltype(int id);
|
||||
char *getdirname(int dir);
|
||||
enum COLOUR getpctcol(float num, float max);
|
||||
void getrarity(int depth, int *min, int *max, int range);
|
||||
|
|
439
objects.c
439
objects.c
|
@ -170,6 +170,8 @@ hiddennamewithcol_t colour[] = {
|
|||
|
||||
hiddennamewithcol_t gemtype[] = {
|
||||
{ "agate", C_MAGENTA, },
|
||||
{ "amethyst", C_MAGENTA, }, // should be purple
|
||||
{ "brass",C_BROWN },
|
||||
{ "bronze",C_BROWN },
|
||||
{ "copper",C_BROWN },
|
||||
{ "diamond",C_BOLDCYAN },
|
||||
|
@ -177,6 +179,7 @@ hiddennamewithcol_t gemtype[] = {
|
|||
{ "flourite",C_GREY },
|
||||
{ "garnet",C_ORANGE },
|
||||
{ "gold",C_YELLOW },
|
||||
{ "iridium",C_WHITE },
|
||||
{ "jade",C_GREEN },
|
||||
{ "lapis lazuli",C_BOLDBLUE },
|
||||
{ "malachite",C_BOLDCYAN },
|
||||
|
@ -185,7 +188,8 @@ hiddennamewithcol_t gemtype[] = {
|
|||
{ "pearl",C_WHITE },
|
||||
{ "quartz",C_GREY },
|
||||
{ "ruby",C_RED },
|
||||
{ "sapphire",C_CYAN },
|
||||
{ "sapphire",C_BLUE },
|
||||
{ "zinc",C_GREY },
|
||||
{ "",C_GREY },
|
||||
};
|
||||
|
||||
|
@ -1123,6 +1127,33 @@ obpile_t *addobpile(lifeform_t *owner, cell_t *where) {
|
|||
}
|
||||
|
||||
|
||||
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes) {
|
||||
int x,y;
|
||||
objecttype_t *ot;
|
||||
ot = findotn(name);
|
||||
if (!ot) return;
|
||||
|
||||
for (y = centre->y - radius ; y <= centre->y + radius; y++) {
|
||||
for (x = centre->x - radius ; x <= centre->x + radius; x++) {
|
||||
int valid = B_FALSE;
|
||||
cell_t *c;
|
||||
c = getcellat(centre->map, x, y);
|
||||
if (c && !c->type->solid && haslof(centre, c, LOF_WALLSTOP, NULL)) {
|
||||
if (allowdupes || !hasob(c->obpile, ot->id)) {
|
||||
if ((dirtype == DT_COMPASS) && (getcelldist(centre, c) <= radius)) {
|
||||
valid = B_TRUE;
|
||||
} else if ((dirtype == DT_ORTH) && (getcelldistorth(centre, c) <= radius)) {
|
||||
valid = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (valid) {
|
||||
addob(c->obpile, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
objecttype_t *addot(int id, char *name, char *description, int material, float weight, int obclassid) {
|
||||
objecttype_t *a, *ot;
|
||||
//flag_t *f;
|
||||
|
@ -1459,23 +1490,19 @@ void applyobmod(object_t *o, obmod_t *om) {
|
|||
}
|
||||
|
||||
// ...but they do melt!
|
||||
addflag(o->flags, F_OBHPDRAIN, 1, DT_MELT, NA, NULL);
|
||||
f = addtempflag(o->flags, F_OBHPDRAIN, 1, DT_MELT, NA, NULL, FROMOBMOD);
|
||||
|
||||
// it needs HP to melt
|
||||
if (!hasflag(o->flags, F_OBHP)) {
|
||||
if (!hasflag(o->flags, F_OBHP)) {
|
||||
int myhp;
|
||||
// give hp
|
||||
myhp = getobweight(o) * 20;
|
||||
if (myhp <= 0) myhp = 2;
|
||||
|
||||
// TODO: not sure about using FROMMAT here...
|
||||
// but i wnat restoration to still work.
|
||||
addtempflag(o->flags, F_OBHP, myhp, myhp, NA, NULL, FROMMAT);
|
||||
addtempflag(o->flags, F_OBHP, myhp, myhp, NA, NULL, FROMOBMOD);
|
||||
}
|
||||
if (!hasflag(o->flags, F_DAMAGABLE)) {
|
||||
// TODO: not sure about using FROMMAT here...
|
||||
// but i wnat restoration to still work.
|
||||
addtempflag(o->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL, FROMMAT);
|
||||
addtempflag(o->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL, FROMOBMOD);
|
||||
}
|
||||
}
|
||||
copyflags(o->flags, om->flags, FROMOBMOD);
|
||||
|
@ -1534,6 +1561,7 @@ void brightflash(cell_t *centre, int range, lifeform_t *immunelf) {
|
|||
// announce
|
||||
if (haslos(player, centre) && !isblind(player)) {
|
||||
msg("You see an intense flash of light!");
|
||||
more();
|
||||
}
|
||||
/*
|
||||
if (getcelldist(player->cell, centre) <= range) {
|
||||
|
@ -1690,13 +1718,10 @@ int changemat(object_t *o, enum MATERIAL mat) {
|
|||
|
||||
// it stops burning
|
||||
extinguish(o);
|
||||
|
||||
// it will melt...
|
||||
// note that it is frozen
|
||||
om = findobmod(OM_FROZEN);
|
||||
applyobmod(o, om);
|
||||
// make it melt
|
||||
//addtempflag(o->flags, F_OBHPDRAIN, 1, DT_MELT, NA, NULL, FROMMAT);
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -1873,7 +1898,7 @@ void explodeob(object_t *o, flag_t *f, int bigness) {
|
|||
int dam;
|
||||
char obname[BUFLEN];
|
||||
|
||||
dam = f->val[0];
|
||||
dam = roll(f->text);
|
||||
c = getoblocation(o);
|
||||
getobname(o, obname, o->amt);
|
||||
|
||||
|
@ -1889,7 +1914,7 @@ void explodeob(object_t *o, flag_t *f, int bigness) {
|
|||
} else if (haslos(player, c)) {
|
||||
msg("%s explode%s!", obname, (o->amt == 1) ? "s" : "");
|
||||
}
|
||||
explodecells(c, dam * o->amt, bigness ? B_TRUE : B_FALSE, o, bigness ? 1 : 0, B_FALSE);
|
||||
explodecells(c, dam * o->amt, bigness ? B_TRUE : B_FALSE, o, bigness ? 1 : 0, DT_COMPASS, B_FALSE);
|
||||
|
||||
// hurt everything!
|
||||
/*
|
||||
|
@ -3211,6 +3236,10 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
|
|||
}
|
||||
}
|
||||
|
||||
if (issecretdoor(o)) {
|
||||
strcat(buf, "secret ");
|
||||
}
|
||||
|
||||
// object name
|
||||
strcat(buf, pluralname);
|
||||
free(pluralname);
|
||||
|
@ -3443,6 +3472,9 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth
|
|||
int raritymin,raritymax;
|
||||
int depth;
|
||||
int done = B_FALSE;
|
||||
obmod_t *om;
|
||||
flag_t *omposs[MAXCANDIDATES];
|
||||
int noms = 0;
|
||||
|
||||
|
||||
if (forcedepth != NA) {
|
||||
|
@ -3593,29 +3625,24 @@ char *real_getrandomob(map_t *map, char *buf, int cond, int cval, int forcedepth
|
|||
strcat(cursestr, buf2);
|
||||
}
|
||||
|
||||
// weapons/armour have random chance of various obmods
|
||||
if ((ot->obclass->id == OC_WEAPON) ||
|
||||
(ot->obclass->id == OC_ARMOUR)) {
|
||||
obmod_t *om;
|
||||
// random chance of having an obmod
|
||||
for (om = firstobmod ; om ; om = om->next) {
|
||||
if (!hasflag(ot->flags, F_NOQUALITY)) {
|
||||
// 1 in 6 of masterwork
|
||||
if (rnd(1,6) == 1) {
|
||||
om = findobmod(OM_MASTERWORK);
|
||||
strcat(cursestr, om->prefix);
|
||||
} else if (rnd(1,3) == 1) { // 1 in 3 of shoddy
|
||||
om = findobmod(OM_SHODDY);
|
||||
strcat(cursestr, om->prefix);
|
||||
f = hasflagval(ot->flags, F_CANHAVEOBMOD, om->id, NA, NA, NULL);
|
||||
if (f && (f->val[1] != NA)) {
|
||||
omposs[noms] = f;
|
||||
noms++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (canbepoisoned(ot->id)) {
|
||||
// random chance of being poisoned
|
||||
if (rnd(1,6) == 1) {
|
||||
obmod_t *om;
|
||||
om = findobmod(OM_POISONED);
|
||||
strcat(cursestr, om->prefix);
|
||||
|
||||
if (noms) {
|
||||
// pick a random one to maybe apply
|
||||
f = omposs[rnd(0,noms-1)];
|
||||
if (rnd(1,100) <= f->val[1]) {
|
||||
om = findobmod(f->val[0]);
|
||||
if (om) {
|
||||
strcat(cursestr, om->prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3928,6 +3955,31 @@ char *getschoolname(enum SPELLSCHOOL sch) {
|
|||
return "unknown school";
|
||||
}
|
||||
|
||||
char *getschoolnameshort(enum SPELLSCHOOL sch) {
|
||||
switch (sch) {
|
||||
case SS_ABILITY: return "Abilities";
|
||||
case SS_ALLOMANCY: return "Allomancy";
|
||||
case SS_DIVINE: return "Divine Powers";
|
||||
case SS_WILD: return "Wild Magic";
|
||||
case SS_MENTAL: return "Psionic Powers";
|
||||
case SS_AIR: return "Air Magic";
|
||||
case SS_EARTH: return "Earth Magic";
|
||||
case SS_FIRE: return "Fire Magic";
|
||||
case SS_ICE: return "Ice Magic";
|
||||
case SS_MODIFICATION: return "Modification";
|
||||
case SS_DEATH: return "Necromancy";
|
||||
case SS_LIFE: return "Life Magic";
|
||||
case SS_DIVINATION: return "Divination";
|
||||
case SS_TRANSLOCATION: return "Translocation";
|
||||
case SS_SUMMONING: return "Summoning";
|
||||
case SS_GRAVITY: return "Gravitation";
|
||||
case SS_LAST: return "!invalid school!";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "unknown school";
|
||||
}
|
||||
|
||||
int getshatterdam(object_t *o) {
|
||||
int shatterdam = 0;
|
||||
if (willshatter(o->material->id)) {
|
||||
|
@ -4195,20 +4247,12 @@ void initobjects(void) {
|
|||
}
|
||||
}
|
||||
|
||||
addhiddenname(OC_WAND, "amethyst wand");
|
||||
addhiddenname(OC_WAND, "brass wand");
|
||||
addhiddenname(OC_WAND, "copper wand");
|
||||
addhiddenname(OC_WAND, "diamond wand");
|
||||
addhiddenname(OC_WAND, "emerald wand");
|
||||
addhiddenname(OC_WAND, "flourescent wand");
|
||||
addhiddenname(OC_WAND, "gold wand");
|
||||
addhiddenname(OC_WAND, "humming wand");
|
||||
addhiddenname(OC_WAND, "iridium wand");
|
||||
addhiddenname(OC_WAND, "luminous wand");
|
||||
addhiddenname(OC_WAND, "ruby wand");
|
||||
addhiddenname(OC_WAND, "zinc wand");
|
||||
addhiddenname(OC_WAND, "sapphire wand");
|
||||
addhiddenname(OC_WAND, "wooden wand");
|
||||
for (n = 0; strlen(gemtype[n].name); n++) {
|
||||
char buf[BUFLEN];
|
||||
// add it without an adjective
|
||||
sprintf(buf, "%s wand", gemtype[n].name);
|
||||
addhiddenname(OC_WAND, buf);
|
||||
}
|
||||
|
||||
for (n = 0; strlen(gemtype[n].name); n++) {
|
||||
char buf[BUFLEN];
|
||||
|
@ -4232,6 +4276,8 @@ void initobjects(void) {
|
|||
|
||||
|
||||
// object modifiers - flags can be either known or not, depending on if it's obvious
|
||||
addobmod(OM_BLOODSTAINED,"bloodstained");
|
||||
addflag_real(lastobmod->flags, F_SCARY, 2, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
||||
addobmod(OM_FLAMING,"flaming");
|
||||
addflag_real(lastobmod->flags, F_ONFIRE, B_TRUE, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
||||
addobmod(OM_FROZEN,"frozen");
|
||||
|
@ -4243,7 +4289,7 @@ void initobjects(void) {
|
|||
addobmod(OM_SHODDY,"shoddy");
|
||||
addflag_real(lastobmod->flags, F_SHODDY, B_TRUE, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
||||
addobmod(OM_POISONED,"poisoned");
|
||||
addflag_real(lastobmod->flags, F_HITCONFER, F_POISONED, SC_POISON, 25, "2-8", PERMENANT, B_KNOWN, -1);
|
||||
addflag_real(lastobmod->flags, F_HITCONFER, F_POISONED, SC_POISON, 25, "15-30", PERMENANT, B_KNOWN, -1);
|
||||
addobmod(OM_WET1,"damp");
|
||||
addflag_real(lastobmod->flags, F_WET, W_DAMP, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
|
||||
addobmod(OM_WET2,"wet");
|
||||
|
@ -4390,9 +4436,14 @@ void initobjects(void) {
|
|||
addoc(OC_WEAPON, "Weapons", "An instrument used for the purpose of causing harm or death.", ')', C_GREY);
|
||||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_MASTERWORK, 17, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_SHODDY, 34, NA, NULL);
|
||||
addoc(OC_ARMOUR, "Armour/Clothing", "Protective gear.", ']', C_GREY);
|
||||
addflag(lastobjectclass->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_MASTERWORK, 17, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_SHODDY, 34, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_CANHAVEOBMOD, OM_BLOODSTAINED, 17, NA, NULL);
|
||||
addoc(OC_MISSILE, "Missiles/Ammunition", "An instrument used for the purpose of causing harm or death.", ';', C_GREY);
|
||||
addflag(lastobjectclass->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastobjectclass->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4516,14 +4567,31 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_ASH, "pile of ash", "A pile of ash", MT_STONE, 0.1, OC_ROCK);
|
||||
addot(OT_ASH, "pile of ash", "A pile of ash.", MT_STONE, 0.1, OC_ROCK);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, "");
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_ASHEXPLODE, "pile of exploding powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_EXPLODEONDAM, NA, NA, NA, "1d6");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, "");
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash");
|
||||
addot(OT_ASHCONCEAL, "pile of concealing powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK);
|
||||
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ",");
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, "");
|
||||
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash");
|
||||
addot(OT_GEMOFSEEING, "gem of seeing", "Magically enhances your eyesight.", MT_STONE, 1, OC_ROCK);
|
||||
addflag(lastot->flags, F_HOLDCONFER, F_XRAYVIS, 2, NA, NULL);
|
||||
addflag(lastot->flags, F_HOLDCONFER, F_SEEINVIS, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_HOLDCONFER, F_ENHANCESEARCH, 20, NA, NULL);
|
||||
addflag(lastot->flags, F_HOLDCONFER, F_DETECTAURAS, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_HOLDCONFER, F_DETECTMAGIC, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
|
||||
|
@ -4597,17 +4665,19 @@ void initobjects(void) {
|
|||
// potions (sorted by rarity)
|
||||
addot(OT_POT_JUICE, "potion of fruit juice", "Tasty (but not very fresh) fruit juice!", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
addot(OT_POT_WATER, "potion of water", "Plain, regular water.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "small puddle of water");
|
||||
addot(OT_POT_HEALINGMIN, "potion of minor healing", "Restores 1-8 health to whoever drinks it.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_POT_WATER, "potion of water", "Plain, regular water.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "small puddle of water");
|
||||
addot(OT_POT_HEALING, "potion of healing", "Restores 10-20 health to whoever drinks it.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
|
||||
addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_POT_OIL, "potion of oil", "A bottle of cooking oil.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addot(OT_POT_RUM, "potion of rum", "String liqour which is sure to make you tipsy.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addot(OT_POT_RESTORATION, "potion of restoration", "Restores lost abilities to the drinker.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addot(OT_POT_SPEED, "potion of haste", "Temporarily increasees the drinker's speed.", MT_GLASS, 1, OC_POTION);
|
||||
|
@ -4619,8 +4689,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_POT_ACROBATICS, "potion of acrobatics", "Allows the drinker to leap large distances.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
addot(OT_POT_ELEMENTENDURE, "potion of endure elements", "Grants the imbiber temporary resistance to both fire and cold.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
addot(OT_POT_INVIS, "potion of invisibility", "Temporarily renders the drinker invisible.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
|
||||
|
@ -4636,7 +4704,6 @@ void initobjects(void) {
|
|||
addot(OT_POT_BLOOD, "potion of blood", "A small quantity of blood.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
||||
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "splash of blood");
|
||||
|
||||
addot(OT_POT_SANCTUARY, "potion of sanctuary", "Creates a temporary magical barrier abour the drinker.", MT_GLASS, 1, OC_POTION);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
|
||||
|
||||
|
@ -4814,10 +4881,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
// TODO: should be "castnearob ot_corpse"
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
addot(OT_S_WEAKEN, "weaken", "Temporarily lowers the target's muscle strength.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addot(OT_S_DRAINLIFE, "drain life", "Draws life force from the victim in order to heal the caster.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
|
@ -4827,10 +4890,19 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
// l4
|
||||
addot(OT_S_WEAKEN, "weaken", "Temporarily lowers the target's muscle strength.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addot(OT_S_PARALYZE, "paralyze", "Disables the target's muscles, leaving them unable to move.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
// l5
|
||||
addot(OT_S_FEEBLEMIND, "feeblemind", "Temporarily lowers the target's intelligence to that of an animal.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
// l7
|
||||
addot(OT_S_POSSESSION, "possession", "Completely possess an enemy, moving your consciousness into their body.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
|
||||
|
@ -4844,7 +4916,7 @@ void initobjects(void) {
|
|||
// divination
|
||||
///////////////////
|
||||
// l1
|
||||
addot(OT_S_DETECTLIFE, "detect life", "Senses life near the caster.", MT_NOTHING, 0, OC_SPELL);
|
||||
addot(OT_S_DETECTLIFE, "detect life", "Senses the size of creatures near the caster. At Power V, it will detect exact creature types.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
// l2
|
||||
|
@ -4862,6 +4934,10 @@ void initobjects(void) {
|
|||
addot(OT_S_DETECTMAGIC, "detect magic", "Allows the caster to detect magical enchantments.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
// l4
|
||||
addot(OT_S_REVEALHIDDEN, "reveal hidden", "Reveals hidden doors or invisible creatures in the caster's line of sight.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
// l8
|
||||
addot(OT_S_IDENTIFY, "identification", "Completely identifies any one item.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
|
||||
|
@ -5026,10 +5102,10 @@ void initobjects(void) {
|
|||
addot(OT_S_INSCRIBE, "inscribe", "Creates a magical inscription viewable to anyone standing nearby.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addot(OT_S_KNOCK, "knock", "Magically opens doors or other such barriers.", MT_NOTHING, 0, OC_SPELL);
|
||||
addot(OT_S_KNOCK, "knock", "Magically opens doors or other such barriers.\nAt Power VII, this spell will also knock back living creatures.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addot(OT_S_LIGHT, "light", "Creates a permenant light source centred on the caster.", MT_NOTHING, 0, OC_SPELL);
|
||||
addot(OT_S_LIGHT, "light", "Creates a temporary light source centred on the caster.\nAt Power III, you can control where the light appears.\nAt Power VIII, the light becomes permenant.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
|
@ -5043,6 +5119,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_XPVAL, 50, NA, NA, NULL);
|
||||
addot(OT_S_PASSWALL, "passwall", "Allows the caster to temporarily walk through walls.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
|
@ -5056,7 +5133,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addot(OT_S_POLYMORPH, "polymorph", "Transmutes the target into a new living race. Becomes controlled at high power.", MT_NOTHING, 0, OC_SPELL);
|
||||
addot(OT_S_POLYMORPH, "polymorph", "Transmutes the target into a new living race.\nBecomes semi-controlled at Power V, and fully-controlled at power VIII.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
|
||||
// l7
|
||||
|
@ -5069,7 +5146,7 @@ void initobjects(void) {
|
|||
// summoning
|
||||
///////////////////
|
||||
// l2
|
||||
addot(OT_S_CREATEMONSTER, "create monster", "Summons a (probably hostile) monster to a nearby location.", MT_NOTHING, 0, OC_SPELL);
|
||||
addot(OT_S_CREATEMONSTER, "create monster", "Summons a (probably hostile) monster to a nearby location.\nAt Power V you can control where the monster appears.\nAt Power VII, you can control the type of monster created.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
|
@ -5087,7 +5164,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
// l4
|
||||
addot(OT_S_TELEPORT, "teleportation", "Causes the caster to teleport to a new location within the same level. Becomes controlled at high power.", MT_NOTHING, 0, OC_SPELL);
|
||||
addot(OT_S_TELEPORT, "teleportation", "Teleports the caster (and Power-1 adjacent allies) to a new location within the same level.\nBecomes semi-controlled at Power V, and fully controlled at Power VII.", MT_NOTHING, 0, OC_SPELL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
||||
|
@ -5165,11 +5242,14 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
||||
addot(OT_A_JUMP, "jump", "You can leap large distances.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_HIDE, "hide", "You can hide in the shadows.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL);
|
||||
addot(OT_A_INSPECT, "inspect", "Try to identify an unknown object from your pack.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_HURRICANESTRIKE, "hurricane strike", "A sweeping attack aginst everything nearby.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
|
||||
addot(OT_A_INSPECT, "inspect", "Try to identify an unknown object from your pack.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_POLYREVERT, "revertform", "Revert to your original form.", MT_NOTHING, 0, OC_ABILITY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOANNOUNCE, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5209,6 +5289,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_MANUALOF, SK_SHIELDS, NA, NA, NULL);
|
||||
addot(OT_MAN_SPELLCASTING, "manual of spellcasting", "Teaches you the skill 'spellcasting'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_SPELLCASTING, NA, NA, NULL);
|
||||
addot(OT_MAN_SPOTHIDDEN, "manual of searching", "Teaches you the skill 'searching'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_SPOTHIDDEN, NA, NA, NULL);
|
||||
addot(OT_MAN_STEALTH, "manual of stealth", "Teaches you the skill 'stealth'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_STEALTH, NA, NA, NULL);
|
||||
addot(OT_MAN_TECHUSAGE, "manual of technology", "Teaches you the skill 'technology'.", MT_PAPER, 3, OC_BOOK);
|
||||
|
@ -5237,6 +5319,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_MANUALOF, SK_SS_DEATH, NA, NA, NULL);
|
||||
addot(OT_MAN_SS_DIVINATION, "manual of divination", "Teaches you the skill 'divination'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_SS_DIVINATION, NA, NA, NULL);
|
||||
addot(OT_MAN_SS_EARTH, "manual of earth magic", "Teaches you the skill 'earth magic'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_SS_EARTH, NA, NA, NULL);
|
||||
addot(OT_MAN_SS_FIRE, "manual of fire magic", "Teaches you the skill 'fire magic'.", MT_PAPER, 3, OC_BOOK);
|
||||
addflag(lastot->flags, F_MANUALOF, SK_SS_FIRE, NA, NA, NULL);
|
||||
addot(OT_MAN_SS_ICE, "manual of ice magic", "Teaches you the skill 'ice magic'.", MT_PAPER, 3, OC_BOOK);
|
||||
|
@ -5261,6 +5345,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_LINKSPELL, OT_S_ANIMATEDEAD, NA, NA, NULL);
|
||||
addot(OT_SB_DRAINLIFE, "spellbook of drain life", "Teaches the spell 'drain life'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_DRAINLIFE, NA, NA, NULL);
|
||||
addot(OT_SB_FEEBLEMIND, "spellbook of feeblemind", "Teaches the spell 'feeblemind'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_FEEBLEMIND, NA, NA, NULL);
|
||||
addot(OT_SB_PAIN, "spellbook of pain", "Teaches the spell 'pain'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_PAIN, NA, NA, NULL);
|
||||
addot(OT_SB_PARALYZE, "spellbook of paralyze", "Teaches the spell 'paralyze'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
|
@ -5282,6 +5368,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_LINKSPELL, OT_S_MAPPING, NA, NA, NULL);
|
||||
addot(OT_SB_DETECTAURA, "spellbook of detect aura", "Teaches the spell 'detect aura'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_DETECTAURA, NA, NA, NULL);
|
||||
addot(OT_SB_REVEALHIDDEN, "spellbook of reveal hidden", "Teaches the spell 'reveal hidden'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_REVEALHIDDEN, NA, NA, NULL);
|
||||
addot(OT_SB_IDENTIFY, "spellbook of identification", "Teaches the spell 'identification'.", MT_PAPER, 1.5, OC_BOOK);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_IDENTIFY, NA, NA, NULL);
|
||||
// elemental - air
|
||||
|
@ -5418,6 +5506,9 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_LIGHT, 3, NA, NULL);
|
||||
addflag(lastot->flags, F_OPERNEEDTARGET, TT_MONSTER, NA, NA, NULL);
|
||||
addot(OT_WAND_REVEALHIDDEN, "wand of reveal hidden", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_REVEALHIDDEN, NA, NA, NULL);
|
||||
addot(OT_WAND_SLOW, "wand of slowness", "A limited-use magical wand which casts the imbued spell.", MT_METAL, 0.5, OC_WAND);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_SLOW, NA, NA, NULL);
|
||||
|
@ -5510,7 +5601,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
|
||||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EXPLODEONDAM, 15, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EXPLODEONDAM, NA, NA, NA, "8d2");
|
||||
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6");
|
||||
addflag(lastot->flags, F_FLAMMABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5636,8 +5727,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EXPLODEONDEATH, 15, NA, B_IFACTIVATED, NULL);
|
||||
addflag(lastot->flags, F_EXPLODEONDAM, 10, NA, B_IFACTIVATED, NULL);
|
||||
addflag(lastot->flags, F_EXPLODEONDEATH, NA, NA, B_IFACTIVATED, "8d2");
|
||||
addflag(lastot->flags, F_EXPLODEONDAM, NA, NA, B_IFACTIVATED, "5d2");
|
||||
addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5652,7 +5743,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RECHARGEWHENOFF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EXPLODEONDEATH, 30, B_BIG, B_IFACTIVATED, NULL);
|
||||
addflag(lastot->flags, F_EXPLODEONDEATH, NA, B_BIG, B_IFACTIVATED, "15d2");
|
||||
addflag(lastot->flags, F_GRENADE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
|
@ -5678,6 +5769,7 @@ void initobjects(void) {
|
|||
addot(OT_INFOVISOR, "infovisor", "Sleek looking metal visor which displays info directly into the retina.", MT_METAL, 0.2, OC_TECH);
|
||||
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_EXTRAINFO, B_TRUE, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_ENHANCESEARCH, 10, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
|
||||
addflag(lastot->flags, F_TECHLEVEL, PR_SKILLED, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL);
|
||||
|
@ -6204,6 +6296,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 1, 1, NA, NULL);
|
||||
addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL);
|
||||
addot(OT_CAP, "cap", "Close-fitting headwear with a short shade visor at the front.", MT_CLOTH, 1, OC_ARMOUR);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 80, NA, NULL);
|
||||
addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL);
|
||||
|
@ -6243,6 +6336,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EVASION, 0, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
|
||||
addflag(lastot->flags, F_SCARY, 4, NA, NA, NULL);
|
||||
|
||||
|
||||
|
||||
|
@ -6259,6 +6353,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_ALL, 70, NA, NULL);
|
||||
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL);
|
||||
addot(OT_NVGOGGLES, "nightvis goggles", "Special goggles which allow the wear to see in the dark.", MT_METAL, 1.5, OC_ARMOUR);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 25, NA, NULL);
|
||||
addflag(lastot->flags, F_GOESON, BP_EYES, NA, NA, NULL);
|
||||
|
@ -6302,7 +6397,7 @@ void initobjects(void) {
|
|||
addot(OT_RING_SIGHT, "ring of sight", "Allows the caster to see the invisible, and in the dark.", MT_METAL, 0.1, OC_RING);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_SEEINVIS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_SEEINDARK, 5, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_SEEINDARK, 3, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, 1, NA, NULL);
|
||||
addot(OT_RING_MANA, "ring of mana", "Increases the wearer's MP pool.", MT_METAL, 0.1, OC_RING);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, NA, "");
|
||||
|
@ -6458,7 +6553,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_MISSILEDAM, 2, NA, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, "");
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
||||
|
||||
addot(OT_NANODART, "nanodart", "A metal dart with a laser-sharpened point.", MT_METAL, 0.5, OC_MISSILE);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
|
@ -6467,7 +6562,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ARMOURPIERCE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, "");
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
||||
|
||||
addot(OT_JAVELIN, "javelin", "A long, sharp missile weapon.", MT_METAL, 1.5, OC_MISSILE);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
|
@ -6476,7 +6571,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, "");
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, "");
|
||||
addflag(lastot->flags, F_OBHP, 3, 3, NA, "");
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
||||
|
||||
addot(OT_ARROW, "arrow", "A sharp wooden arrow.", MT_WOOD, 0.5, OC_MISSILE);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
|
@ -6485,14 +6580,14 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL);
|
||||
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
||||
|
||||
addot(OT_BOLT, "bolt", "A sharp metal spike, meant for firing from a crossbow.", MT_METAL, 1, OC_MISSILE);
|
||||
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, "");
|
||||
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
|
||||
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
|
||||
|
||||
|
||||
addot(OT_BULLET, "bullet", "A regular gun bullet.", MT_STONE, 0.1, OC_MISSILE);
|
||||
|
@ -6667,7 +6762,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ATTREQ, A_STR, ST_VWEAK, NA, NULL);
|
||||
|
||||
// polearms
|
||||
addot(OT_GLAIVE, "glaive", "A long pole with a sharpened head.", MT_METAL, 4, OC_WEAPON);
|
||||
addot(OT_GLAIVE, "glaive", "A single-edged blade attached to a long pole.", MT_METAL, 4, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 73, NA, NULL);
|
||||
addflag(lastot->flags, F_OBATTACKDELAY, 150, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_DAM, DT_SLASH, NA, NA, "1d7+3");
|
||||
|
@ -6675,7 +6770,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_USESSKILL, SK_POLEARMS, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ATTREQ, A_STR, ST_STRONG, NA, NULL);
|
||||
addot(OT_GUISARME, "guisarme", "A hooked polearm.", MT_METAL, 4, OC_WEAPON);
|
||||
addot(OT_GUISARME, "guisarme", "A hooked polearm, made by attaching a hook to a spear shaft.", MT_METAL, 4, OC_WEAPON);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
|
||||
addflag(lastot->flags, F_TRIPATTACK, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TWOHANDED, B_TRUE, NA, NA, NULL);
|
||||
|
@ -7209,6 +7304,7 @@ int ismagical(object_t *o) {
|
|||
case OT_POT_OIL:
|
||||
case OT_POT_WATER:
|
||||
case OT_POT_BLOOD:
|
||||
case OT_POT_RUM:
|
||||
case OT_POT_JUICE:
|
||||
// these potions are non-magical
|
||||
break;
|
||||
|
@ -7372,6 +7468,13 @@ int isrotting(object_t *o) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
flag_t *issecretdoor(object_t *o) {
|
||||
if (isdoor(o, NULL)) {
|
||||
return hasflag(o->flags, F_SECRETDOOR);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// returns the 'shield' flag
|
||||
flag_t *isshield(object_t *o) {
|
||||
return hasflag(o->flags, F_SHIELD);
|
||||
|
@ -8227,29 +8330,38 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
ttype = f->val[0];
|
||||
}
|
||||
|
||||
if (strlen(f->text) > 0) {
|
||||
where = askcoords(f->text, ttype);
|
||||
} else {
|
||||
sprintf(buf, "Where will you aim %s?",obname);
|
||||
where = askcoords(buf, ttype);
|
||||
if (!haslos(lf, where)) {
|
||||
// exception - wand of digging doesn't need los
|
||||
if (isknown(o) && (o->type->id == OT_WAND_DIGGING)) {
|
||||
} else {
|
||||
msg("You can't see there!");
|
||||
return B_TRUE;
|
||||
if (isplayer(lf)) {
|
||||
if (strlen(f->text) > 0) {
|
||||
where = askcoords(f->text, ttype);
|
||||
} else {
|
||||
sprintf(buf, "Where will you aim %s?",obname);
|
||||
where = askcoords(buf, ttype);
|
||||
if (!haslos(lf, where)) {
|
||||
// exception - wand of digging doesn't need los
|
||||
if (isknown(o) && (o->type->id == OT_WAND_DIGGING)) {
|
||||
} else {
|
||||
msg("You can't see there!");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
dblog("BUG - ai (%s, id %d) using wand (%s) without target.",
|
||||
lfname, lf->id, obname);
|
||||
where = NULL;
|
||||
}
|
||||
|
||||
if (!where) {
|
||||
// cancel.
|
||||
msg("Cancelled.");
|
||||
if (isplayer(lf)) msg("Cancelled.");
|
||||
return B_TRUE;
|
||||
} else {
|
||||
if (f->val[1] != NA) {
|
||||
cell_t *newwhere = NULL;
|
||||
if ((f->val[1] & TR_NEEDLOS) && !haslos(lf, where)) {
|
||||
msg("You can't see there!");
|
||||
if (isplayer(lf)) msg("You can't see there!");
|
||||
return B_TRUE;
|
||||
}
|
||||
if ((f->val[1] & TR_NEEDLOF) && !haslof(lf->cell, where, B_TRUE, &newwhere)) {
|
||||
|
@ -8257,7 +8369,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
|
|||
// update destination
|
||||
where = newwhere;
|
||||
} else {
|
||||
msg("You have no line of fire to there!");
|
||||
if (isplayer(lf)) msg("You have no line of fire to there!");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -8995,11 +9107,13 @@ int pour(lifeform_t *lf, object_t *o) {
|
|||
dst->blessknown = B_TRUE;
|
||||
// remove bonuses
|
||||
killflagsofid(dst->flags, F_BONUS);
|
||||
// remove temporary flags and modify some others
|
||||
// remove temporary flags, obmod flags and modify some others
|
||||
for (f = dst->flags->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
if (f->lifetime > 0) {
|
||||
killflag(f);
|
||||
} else if (f->lifetime == FROMOBMOD) {
|
||||
killflag(f);
|
||||
} else if (f->id == F_FROZEN) {
|
||||
killflag(f);
|
||||
} else if (f->id == F_ONFIRE) {
|
||||
|
@ -9009,11 +9123,12 @@ int pour(lifeform_t *lf, object_t *o) {
|
|||
} else if (f->id == F_OBHP) {
|
||||
f->val[0] = f->val[1];
|
||||
}
|
||||
}
|
||||
// restore hp
|
||||
|
||||
|
||||
if (!isknown(dst)) makeknown(dst->type->id);
|
||||
}
|
||||
|
||||
// we now know what the potion was
|
||||
if (!isknown(o)) makeknown(o->type->id);
|
||||
//if (!isknown(dst)) makeknown(dst->type->id);
|
||||
} else if (o->type->id == OT_POT_ACID) {
|
||||
// damage destinaiton
|
||||
msg("You pour %s onto %s.", obname,dstname);
|
||||
|
@ -9103,21 +9218,12 @@ void quaff(lifeform_t *lf, object_t *o) {
|
|||
willid = B_FALSE;
|
||||
if (playercansee) {
|
||||
switch (o->type->id) {
|
||||
enum ATTRIB a;
|
||||
case OT_POT_HEALING:
|
||||
case OT_POT_HEALINGMIN:
|
||||
if (lf->hp < lf->maxhp) {
|
||||
willid = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case OT_POT_RESTORATION:
|
||||
for (a = 0; a < (MAXATTS-1); a++) {
|
||||
if (getattr(lf,a) < lf->baseatt[a]) {
|
||||
willid = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
willid = B_TRUE;
|
||||
break;
|
||||
|
@ -9167,13 +9273,14 @@ void quaff(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
|
||||
void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE potblessed, int *seen) {
|
||||
char buf[BUFLEN];
|
||||
char lfname[BUFLEN];
|
||||
unsigned int dam;
|
||||
int i;
|
||||
int first,dir;
|
||||
int amt;
|
||||
int failed;
|
||||
int seenbyplayer;
|
||||
int hpheal,mpheal;
|
||||
flag_t *f;
|
||||
|
||||
if (isplayer(lf)) {
|
||||
|
@ -9188,6 +9295,8 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE potblessed, i
|
|||
*seen = seenbyplayer;
|
||||
}
|
||||
|
||||
getlfname(lf, lfname);
|
||||
|
||||
switch (oid) {
|
||||
case OT_POT_ACID:
|
||||
dam = rnd(5,10);
|
||||
|
@ -9195,9 +9304,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE potblessed, i
|
|||
if (isplayer(lf)) {
|
||||
msg("Your suffer massive internal burning!");
|
||||
} else if (cansee(player, lf)) {
|
||||
getlfname(lf, buf);
|
||||
capitalise(buf);
|
||||
msg("%s writhes in agony!", buf);
|
||||
msg("%s writhes in agony!", lfname);
|
||||
}
|
||||
break;
|
||||
case OT_POT_ACROBATICS:
|
||||
|
@ -9231,8 +9338,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE potblessed, i
|
|||
if (isplayer(lf)) {
|
||||
msg("You feel completely healed!");
|
||||
} else if (cansee(player, lf)) {
|
||||
getlfname(lf, buf);
|
||||
msg("%s looks completely healed!", buf);
|
||||
msg("%s looks completely healed!", lfname);
|
||||
}
|
||||
} else {
|
||||
if (isplayer(lf)) {
|
||||
|
@ -9283,22 +9389,27 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE potblessed, i
|
|||
if (seen) *seen = B_TRUE;
|
||||
}
|
||||
break;
|
||||
case OT_POT_ELEMENTENDURE:
|
||||
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You feel momentarily resistant to the elements.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OT_POT_RUM:
|
||||
// how long for?
|
||||
i = geteffecttime(15,25,potblessed);
|
||||
|
||||
f = lfhasflag(lf, F_DRUNK);
|
||||
if (f) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You feel more tipsy.");
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s looks more tipsy.", lfname);
|
||||
}
|
||||
f->lifetime += DRUNKTIME;
|
||||
} else {
|
||||
addtempflag(lf->flags, F_DRUNK, 1, NA, NA, NULL, DRUNKTIME);
|
||||
}
|
||||
/*
|
||||
if (!lfhasflagval(lf, F_DTRESIST, DT_FIRE, NA, NA, NULL)) {
|
||||
addtempflag(lf->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL, i);
|
||||
}
|
||||
if (!lfhasflagval(lf, F_DTRESIST, DT_COLD, NA, NA, NULL)) {
|
||||
addtempflag(lf->flags, F_DTRESIST, DT_COLD, NA, NA, NULL, i);
|
||||
}
|
||||
*/
|
||||
break;
|
||||
case OT_POT_ELEMENTIMMUNE:
|
||||
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 30, 0)) {
|
||||
|
@ -9389,7 +9500,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE potblessed, i
|
|||
}
|
||||
break;
|
||||
case OT_POT_POISON:
|
||||
poison(lf, rnd(10,20), "a potion of poison");
|
||||
poison(lf, rnd(10,20), P_FOOD, 1, "a potion of poison");
|
||||
break;
|
||||
case OT_POT_POLYMORPH:
|
||||
if (potblessed == B_BLESSED) {
|
||||
|
@ -9408,26 +9519,48 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE potblessed, i
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (getattr(lf,A_STR) < lf->baseatt[A_STR]) {
|
||||
setattr(lf, A_STR, lf->baseatt[A_STR]);
|
||||
if (isplayer(lf)) msg("Your strength is restored!");
|
||||
failed = B_FALSE;
|
||||
}
|
||||
if (getattr(lf,A_DEX) < lf->baseatt[A_DEX]) {
|
||||
setattr(lf, A_DEX, lf->baseatt[A_DEX]);
|
||||
if (isplayer(lf)) msg("Your dexterity is restored!");
|
||||
failed = B_FALSE;
|
||||
}
|
||||
if (getattr(lf,A_IQ) < lf->baseatt[A_IQ]) {
|
||||
setattr(lf, A_IQ, lf->baseatt[A_IQ]);
|
||||
if (isplayer(lf)) msg("Your intelligence is restored!");
|
||||
failed = B_FALSE;
|
||||
}
|
||||
|
||||
if (potblessed == B_BLESSED) {
|
||||
hpheal = lf->maxhp;
|
||||
mpheal = getmaxmp(lf);
|
||||
} else if (potblessed == B_CURSED) {
|
||||
hpheal = lf->maxhp / 3;
|
||||
mpheal = getmaxmp(lf) / 3;
|
||||
} else {
|
||||
hpheal = lf->maxhp / 2;
|
||||
mpheal = getmaxmp(lf) / 2;
|
||||
}
|
||||
|
||||
// blessed restores hp/mp to full
|
||||
if (lf->hp < hpheal) {
|
||||
gainhp(lf, hpheal - lf->hp);
|
||||
if (!isplayer(lf) && cansee(player, lf)) {
|
||||
msg("%s%s health has been restored!", lfname, getpossessive(lfname));
|
||||
}
|
||||
failed = B_FALSE;
|
||||
}
|
||||
if (lf->mp < mpheal) {
|
||||
gainmp(lf, mpheal - lf->mp);
|
||||
failed = B_FALSE;
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
if (isplayer(lf)) {
|
||||
msg("You feel momentarily restored.");
|
||||
}
|
||||
if (isplayer(lf)) msg("You feel momentarily restored.");
|
||||
} else {
|
||||
if (isplayer(lf)) msg("You feel restored!");
|
||||
}
|
||||
break;
|
||||
case OT_POT_SANCTUARY:
|
||||
|
@ -9475,8 +9608,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, enum BLESSTYPE potblessed, i
|
|||
if (isplayer(lf)) {
|
||||
msg("This tastes like water, but burns like acid!");
|
||||
} else if (cansee(player, lf)) {
|
||||
getlfname(lf, buf);
|
||||
msg("%s writhes in agony!", buf);
|
||||
msg("%s writhes in agony!", lfname);
|
||||
}
|
||||
losehp(lf, rnd(5,15), DT_HOLY, NULL, "drinking holy water");
|
||||
} else {
|
||||
|
@ -10344,8 +10476,38 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
|
||||
// some obejcts will die when thrown.
|
||||
if (hasflag(o->flags, F_POWDER)) {
|
||||
if (haslos(player, srcloc)) {
|
||||
msg("%s dispers%s into the air.", obname, (amt == 1) ? "es" : "e");
|
||||
// special cases first
|
||||
if (o->type->id == OT_ASHCONCEAL) {
|
||||
int radius;
|
||||
// make smoke
|
||||
if (haslos(player, srcloc)) {
|
||||
msg("%s dispers%s into a thick cloud of smoke!", obname,
|
||||
(amt == 1) ? "es" : "e",
|
||||
(amt == 1) ? "es" : "e" );
|
||||
|
||||
if (!isknown(o)) makeknown(o->type->id);
|
||||
}
|
||||
radius = o->amt * 2;
|
||||
if (radius > 10) radius = 10;
|
||||
addobsinradius(thrower->cell, radius, DT_COMPASS, "cloud of smoke", B_FALSE);
|
||||
} else if (o->type->id == OT_ASHEXPLODE) {
|
||||
char diebuf[BUFLEN];
|
||||
// explosion!
|
||||
sprintf(diebuf, "%dd6",o->amt);
|
||||
|
||||
if (haslos(player, srcloc)) {
|
||||
msg("%s dispers%s and explod%s!", obname,
|
||||
(amt == 1) ? "es" : "e",
|
||||
(amt == 1) ? "es" : "e" );
|
||||
|
||||
if (!isknown(o)) makeknown(o->type->id);
|
||||
}
|
||||
explodecells(thrower->cell, roll(diebuf), B_FALSE, o, 1, DT_COMPASS, B_FALSE);
|
||||
} else {
|
||||
if (haslos(player, srcloc)) {
|
||||
msg("%s dispers%s into the air.", obname, (amt == 1) ? "es" : "e");
|
||||
if (!isknown(o)) makeknown(o->type->id);
|
||||
}
|
||||
}
|
||||
removeob(o, amt);
|
||||
return B_FALSE;
|
||||
|
@ -10595,7 +10757,6 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case OT_POT_ELEMENTENDURE:
|
||||
case OT_POT_ELEMENTIMMUNE:
|
||||
case OT_POT_ETHEREALNESS:
|
||||
case OT_POT_GASEOUSFORM:
|
||||
|
@ -11263,6 +11424,16 @@ int validateobs(void) {
|
|||
goterror = B_TRUE;
|
||||
}
|
||||
}
|
||||
f = hasflag(ot->flags, F_EXPLODEONDAM);
|
||||
if (f && !strlen(f->text)) {
|
||||
printf("ERROR in object '%s' - F_EXPLODEONDAM does not have damage string.\n", ot->name);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
f = hasflag(ot->flags, F_EXPLODEONDEATH);
|
||||
if (f && !strlen(f->text)) {
|
||||
printf("ERROR in object '%s' - F_EXPLODEONDEATH does not have damage string.\n", ot->name);
|
||||
goterror = B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
for (sk = firstskill ; sk ; sk = sk->next) {
|
||||
|
|
|
@ -13,6 +13,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack);
|
|||
int addobburst(cell_t *where, int range, int dirtype, char *name, lifeform_t *fromlf);
|
||||
obmod_t *addobmod(enum OBMOD id, char *prefix);
|
||||
obpile_t *addobpile(lifeform_t *owner, cell_t *where);
|
||||
void addobsinradius(cell_t *centre, int radius, int dirtype, char *name, int allowdupes);
|
||||
objecttype_t *addot(int id, char *name, char *description, int material, float weight, int obclassid);
|
||||
void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL mat);
|
||||
void adjustdamob(object_t *o, unsigned int *dam, enum DAMTYPE damtype);
|
||||
|
@ -97,6 +98,7 @@ char *getrandomobwithclass(map_t *map, enum OBCLASS cid, char *buf);
|
|||
int getobrarity(object_t *o);
|
||||
enum SPELLSCHOOL getschool(enum OBTYPE sid);
|
||||
char *getschoolname(enum SPELLSCHOOL sch);
|
||||
char *getschoolnameshort(enum SPELLSCHOOL sch);
|
||||
int getshatterdam(object_t *o);
|
||||
enum SKILLLEVEL gettechlevel(object_t *o);
|
||||
int getthrowdam(object_t *o);
|
||||
|
@ -143,6 +145,7 @@ int ispourable(object_t *o);
|
|||
int ispushable(object_t *o);
|
||||
int isreadable(object_t *o);
|
||||
int isrotting(object_t *o);
|
||||
flag_t *issecretdoor(object_t *o);
|
||||
flag_t *isshield(object_t *o);
|
||||
int isthrownmissile(object_t *o);
|
||||
int istried(object_t *o);
|
||||
|
|
5
save.c
5
save.c
|
@ -142,7 +142,7 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
|
|||
int obcount;
|
||||
int mapid;
|
||||
map_t *m;
|
||||
int x,y,level;
|
||||
int x,y,level,newlevel;
|
||||
int db = B_TRUE;
|
||||
|
||||
if (db) dblog("--> Loading lifeform...\n");
|
||||
|
@ -153,6 +153,7 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
|
|||
fscanf(f, "map: %d\n",&mapid);
|
||||
fscanf(f, "pos: %d,%d\n",&x, &y);
|
||||
fscanf(f, "level: %d\n",&level);
|
||||
fscanf(f, "newlevel: %d\n",&newlevel);
|
||||
|
||||
// find the map
|
||||
m = findmap(mapid);
|
||||
|
@ -172,6 +173,7 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
|
|||
l->id = lfid;
|
||||
l->x = x;
|
||||
l->y = y;
|
||||
l->newlevel = newlevel;
|
||||
|
||||
// load rest of this lf
|
||||
fscanf(f, "str: %d/%d\n",&l->att[A_STR],&l->baseatt[A_STR]);
|
||||
|
@ -630,6 +632,7 @@ int savelf(FILE *f, lifeform_t *l) {
|
|||
fprintf(f, "map: %d\n",l->cell->map->id);
|
||||
fprintf(f, "pos: %d,%d\n",l->cell->x, l->cell->y);
|
||||
fprintf(f, "level: %d\n",l->level);
|
||||
fprintf(f, "newlevel: %d\n",l->newlevel);
|
||||
// liefform will be created after loading the above.
|
||||
fprintf(f, "str: %d/%d\n",l->att[A_STR],l->baseatt[A_STR]);
|
||||
fprintf(f, "dex: %d/%d\n",l->att[A_DEX],l->baseatt[A_DEX]);
|
||||
|
|
250
spell.c
250
spell.c
|
@ -650,6 +650,35 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
// remove temporary flags
|
||||
killflag(f);
|
||||
killflag(f2);
|
||||
} else if (abilid == OT_A_HIDE) {
|
||||
int penalty = 0;
|
||||
if (lfhasflag(user, F_HIDING)) {
|
||||
if (isplayer(user)) msg("You are already hiding!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (!safetorest(user)) {
|
||||
if (getskill(user, SK_STEALTH) == PR_EXPERT) {
|
||||
// can still hide, but with a penalty
|
||||
penalty = -4;
|
||||
} else if (getskill(user, SK_STEALTH) == PR_MASTER) {
|
||||
// can still hide, but with a penalty
|
||||
penalty = -2;
|
||||
} else {
|
||||
if (isplayer(user)) msg("You can't hide - there are monsters around!");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// no stealth skill?
|
||||
if (!getskill(user, SK_STEALTH)) {
|
||||
penalty = -5;
|
||||
}
|
||||
|
||||
// start hiding
|
||||
addflag(user->flags, F_HIDING, penalty, NA, NA, NULL);
|
||||
|
||||
taketime(user, getactspeed(user));
|
||||
} else if (abilid == OT_A_INSPECT) {
|
||||
object_t *o;
|
||||
int difficulty;
|
||||
|
@ -1087,6 +1116,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (!ischarmable(target)) {
|
||||
if (isplayer(caster)) {
|
||||
switch (reason) {
|
||||
case E_DRUNK:
|
||||
msg("%s%s mind is too alcohol-impaired for you to charm.",targetname,getpossessive(targetname));
|
||||
break;
|
||||
case E_LOWIQ:
|
||||
msg("%s%s intellect is too simple for you to charm.",targetname,getpossessive(targetname));
|
||||
break;
|
||||
|
@ -1101,12 +1133,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (getallegiance(caster) == AL_PEACEFUL) {
|
||||
fizzle(caster);
|
||||
return B_FALSE;
|
||||
}
|
||||
if (getallegiance(target) == getallegiance(caster)) {
|
||||
if (ispetof(target, caster)) {
|
||||
if (isplayer(caster)) {
|
||||
msg("%s is already allied with you!",targetname);
|
||||
}
|
||||
|
@ -1130,7 +1161,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
howlong = getspellduration(20,30,blessed) + (power*10);
|
||||
|
||||
//
|
||||
addtempflag(target->flags, F_CHARMEDBY, caster->id, NA, NA, NULL, howlong);
|
||||
addtempflag(target->flags, F_PETOF, caster->id, NA, NA, NULL, howlong);
|
||||
}
|
||||
} else if (spellid == OT_S_COLDBURST) {
|
||||
int range = 1;
|
||||
|
@ -1386,6 +1419,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
(numseen == 1) ? "s" : ""
|
||||
);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else {
|
||||
if (isplayer(caster)) nothinghappens();
|
||||
}
|
||||
} else if (spellid == OT_S_DETECTLIFE) {
|
||||
target = caster;
|
||||
|
@ -1431,7 +1466,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// don't need line of fire!
|
||||
if (!validatespellcell(caster, &targcell, TT_MONSTER|TT_DOOR, B_TRUE, LOF_DONTNEED, spellid, power)) return B_TRUE;
|
||||
|
||||
explodecells(targcell, 20, B_TRUE, NULL, power / 4, B_TRUE);
|
||||
explodecells(targcell, 20, B_TRUE, NULL, power / 4, DT_ORTH, B_TRUE);
|
||||
|
||||
if (haslos(player, targcell)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -1459,9 +1494,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
// announce
|
||||
if (totalmass < 10) {
|
||||
// little one
|
||||
explodecells(targcell, totalmass*5, B_FALSE, NULL, 0, B_TRUE);
|
||||
explodecells(targcell, totalmass*5, B_FALSE, NULL, 0, DT_COMPASS, B_TRUE);
|
||||
} else {
|
||||
explodecells(targcell, totalmass*5, B_TRUE, NULL, 1, B_TRUE);
|
||||
explodecells(targcell, totalmass*5, B_TRUE, NULL, 1, DT_COMPASS, B_TRUE);
|
||||
}
|
||||
} else {
|
||||
fizzle(caster);
|
||||
|
@ -1619,6 +1654,44 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_FEEBLEMIND) {
|
||||
// ask for target
|
||||
if (!validatespelllf(caster, &target)) return B_TRUE;
|
||||
|
||||
if ((getattr(target, A_IQ) <= 3) || skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (cansee(player, target)) {
|
||||
getlfname(target, buf);
|
||||
msg("%s %s momentarily foolish.", buf, isplayer(target) ? "feel" : "looks");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
if (target) {
|
||||
int howlong = 15;
|
||||
flag_t *f;
|
||||
|
||||
// already feebleminded?
|
||||
for (f = target->flags->first; f ; f = f->next) {
|
||||
if ((f->id == F_ATTRMOD) && (f->val[0] == A_IQ) && (f->obfrom == OT_S_FEEBLEMIND)) {
|
||||
if (cansee(player, target)) {
|
||||
getlfname(target, buf);
|
||||
msg("%s %s momentarily more foolish.", buf, isplayer(target) ? "feel" : "looks");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
howlong = getspellduration(5,10,blessed) + power;
|
||||
// always set to 3 (ie. animal)
|
||||
f = addtempflag(target->flags, F_ATTRSET, A_IQ, 3, NA, NULL, howlong);
|
||||
f->obfrom = OT_S_FEEBLEMIND;
|
||||
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else {
|
||||
fizzle(caster);
|
||||
}
|
||||
} else if (spellid == OT_S_FLASH) {
|
||||
if (isplayer(caster) || cansee(player, caster)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
|
@ -1900,7 +1973,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
char obname[BUFLEN];
|
||||
char ch;
|
||||
getobname(o, obname, o->amt);
|
||||
msg("Your %s start%s glowing bright blue!", obname, (o->amt == 1) ? "s" : "");
|
||||
msg("%s %s start%s glowing bright blue!",
|
||||
(o->pile->owner == caster) ? "Your" : "",
|
||||
(o->pile->owner == caster) ? noprefix(obname) : obname,
|
||||
(o->amt == 1) ? "s" : "");
|
||||
more();
|
||||
ch = askchar("Abort your spell?", "yn","y", B_TRUE);
|
||||
if (ch == 'y') {
|
||||
|
@ -1924,18 +2000,31 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
|
||||
if (!o) {
|
||||
if (isplayer(caster)) {
|
||||
msg("Your hands feel freezing cold for a moment.");
|
||||
}
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// object will turn to ice immediately...
|
||||
if (isplayer(caster)) {
|
||||
msg("Your hands feel freezing cold!");
|
||||
}
|
||||
|
||||
if (o->material->id == MT_ICE) { // already made of ice?
|
||||
if (isplayer(caster)) {
|
||||
nothinghappens();
|
||||
cell_t *loc;
|
||||
flag_t *f;
|
||||
loc = getoblocation(o);
|
||||
// announce
|
||||
if (haslos(caster, loc)) {
|
||||
char obname[BUFLEN];
|
||||
getobname(o, obname, o->amt);
|
||||
msg("%s %s freeze%s some more.",
|
||||
(o->pile->owner == caster) ? "Your" : "",
|
||||
(o->pile->owner == caster) ? noprefix(obname) : obname,
|
||||
(o->amt == 1) ? "s" : "");
|
||||
}
|
||||
// restore it
|
||||
f = hasflag(o->flags, F_OBHP);
|
||||
if (f) {
|
||||
f->val[0] = f->val[1];
|
||||
}
|
||||
return B_TRUE;
|
||||
} else {
|
||||
|
@ -2020,12 +2109,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else {
|
||||
howlong = getspellduration(5,25,blessed) + power;
|
||||
addtempflag(target->flags, F_FASTACT, 10, NA, NA, NULL, howlong);
|
||||
addtempflag(target->flags, F_FASTMOVE, 10, NA, NA, NULL, howlong);
|
||||
addtempflag(target->flags, F_FASTACTMOVE, 10, NA, NA, NULL, howlong);
|
||||
}
|
||||
} else if (spellid == OT_S_HEALING) {
|
||||
int donesomething = B_FALSE;
|
||||
flag_t *f;
|
||||
target = caster;
|
||||
|
||||
// cure certain bad effects
|
||||
|
@ -2059,9 +2146,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
f = lfhasflag(target, F_POISONED);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
if (killflagsofid(target->flags, F_POISONED)) {
|
||||
donesomething = B_TRUE;
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
@ -2073,7 +2158,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else if (spellid == OT_S_HEALINGMIN) {
|
||||
int donesomething = B_FALSE;
|
||||
flag_t *f;
|
||||
target = caster;
|
||||
|
||||
// cure bad effects instead of healing
|
||||
|
@ -2104,9 +2188,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
donesomething = B_TRUE;
|
||||
}
|
||||
f = lfhasflag(target, F_POISONED);
|
||||
if (f) {
|
||||
killflag(f);
|
||||
if (killflagsofid(target->flags, F_POISONED)) {
|
||||
donesomething = B_TRUE;
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
@ -2538,9 +2620,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (cansee(caster, target)) {
|
||||
msg("A glob of venom hits %s.",lfname);
|
||||
}
|
||||
losehp(target, rnd(1,4), DT_POISON, caster, "a glob of poison");
|
||||
if (!isimmuneto(target->flags, DT_POISON)) {
|
||||
addtempflag(target->flags, F_POISONED, NA, NA, NA, castername, power*3);
|
||||
poison(target, power*3, P_VENOM, power, "a glob of venom");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -2586,6 +2667,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (!ischarmable(target)) {
|
||||
if (isplayer(caster)) {
|
||||
switch (reason) {
|
||||
case E_DRUNK:
|
||||
msg("%s%s mind is too alcohol-impaired for you to possess.",targname,getpossessive(targname));
|
||||
break;
|
||||
case E_LOWIQ:
|
||||
msg("%s%s intellect is too simple for you to possess.",targname,getpossessive(targname));
|
||||
break;
|
||||
|
@ -2944,6 +3028,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
addtempflag(target->flags, F_INVISIBLE, B_TRUE, NA, NA, NULL, howlong);
|
||||
if (willannounce && !lfhasflag(player, F_SEEINVIS)) {
|
||||
msg("%s flicker%s then vanishes!",targname, isplayer(target) ? "" : "s");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_KNOCK) {
|
||||
object_t *o;
|
||||
|
@ -2983,6 +3068,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
f = addtempflag(caster->flags, F_LEVITATING, B_TRUE, NA, NA, NULL, FROMSPELL);
|
||||
f->obfrom = spellid;
|
||||
|
||||
if (cansee(player, target)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_LIGHT) {
|
||||
lifeform_t *l;
|
||||
|
||||
|
@ -3063,15 +3152,20 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (target) {
|
||||
int howlong = 15;
|
||||
|
||||
if (skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (lfhasflag(target, F_GRAVBOOSTED) || skillcheck(target, SC_RESISTMAG, 20 + power, 0)) {
|
||||
if (isplayer(target)) {
|
||||
msg("You feel momentarily heavier.");
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else if (cansee(player, target)) {
|
||||
char targname[BUFLEN];
|
||||
getlfname(target, targname);
|
||||
msg("%s looks momentarily heavier.", targname);
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
howlong = getspellduration(2,10,blessed) + (power/2);
|
||||
howlong = getspellduration(3,10,blessed) + (power/2);
|
||||
addtempflag(target->flags, F_GRAVBOOSTED, B_TRUE, NA, NA, NULL, howlong);
|
||||
} else {
|
||||
fizzle(caster);
|
||||
|
@ -3253,6 +3347,54 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_REVEALHIDDEN) {
|
||||
int i;
|
||||
int seen = B_FALSE;
|
||||
for (i = 0 ; i < caster->nlos; i++ ){
|
||||
targcell = caster->los[i];
|
||||
if (targcell) {
|
||||
object_t *o;
|
||||
if (isplayer(caster)) {
|
||||
// reveal secret doors
|
||||
for (o = targcell->obpile->first ; o ; o = o->next) {
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_SECRETDOOR);
|
||||
if (f) {
|
||||
char obname[BUFLEN];
|
||||
getobname(o, obname, o->amt);
|
||||
msg("%s is magically revealed!", obname);
|
||||
killflag(f);
|
||||
seen = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove invisibility
|
||||
if (targcell->lf) {
|
||||
flag_t *f, *nextf;
|
||||
for (f = targcell->lf->flags->first ; f ; f = nextf) {
|
||||
nextf = f->next;
|
||||
if (f->id == F_INVISIBLE) {
|
||||
if ((f->lifetime > 0) || (f->lifetime == PERMENANT)) {
|
||||
killflag(f);
|
||||
// player can see whoever just appeared, and the caster?
|
||||
if (cansee(player, targcell->lf) && cansee(player, caster)) {
|
||||
seen = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (seen) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
} else {
|
||||
if (isplayer(caster)) {
|
||||
nothinghappens();
|
||||
}
|
||||
}
|
||||
} else if (spellid == OT_S_SLEEP) {
|
||||
int howlong;
|
||||
if (!validatespelllf(caster, &target)) return B_TRUE;
|
||||
|
@ -3295,8 +3437,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
|
||||
howlong = rnd(5,25) + power;
|
||||
addtempflag(target->flags, F_SLOWACT, 10, NA, NA, NULL, howlong);
|
||||
addtempflag(target->flags, F_SLOWMOVE, 10, NA, NA, NULL, howlong);
|
||||
addtempflag(target->flags, F_SLOWACTMOVE, 10, NA, NA, NULL, howlong);
|
||||
if (isplayer(target) || haslos(player, target->cell)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
|
@ -3322,6 +3463,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
}
|
||||
} else if (spellid == OT_S_TELEPORT) {
|
||||
cell_t *c = NULL;
|
||||
lifeform_t *ally[8];
|
||||
int nallies = 0;
|
||||
|
||||
// target is always the caster
|
||||
target = caster;
|
||||
|
@ -3471,10 +3614,35 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
|
||||
targcell = c;
|
||||
|
||||
|
||||
// we can take up to 'power-1' allies with us.
|
||||
if (caster == target) {
|
||||
int dir;
|
||||
for (dir = DC_N; (dir <= DC_NW) && (nallies < power); dir++) {
|
||||
c = getcellindir(target->cell, dir);
|
||||
if (c && c->lf && areallies(c->lf, caster)) {
|
||||
ally[nallies] = c->lf;
|
||||
nallies++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isplayer(target) || haslos(player, target->cell)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
teleportto(target, targcell, B_TRUE);
|
||||
|
||||
// now do allies
|
||||
if (nallies) {
|
||||
int i;
|
||||
for (i = 0; i < nallies; i++) {
|
||||
c = getrandomadjcell(targcell, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
if (c) {
|
||||
teleportto(ally[i], c, B_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = B_FALSE;
|
||||
} else if (spellid == OT_S_TELEKINESIS) {
|
||||
cell_t *where;
|
||||
|
@ -3752,6 +3920,32 @@ enum SKILL getschoolskill(enum SPELLSCHOOL ss) {
|
|||
return SK_NONE;
|
||||
}
|
||||
|
||||
// returns "x MP" or "x-y MP", or "x-y MP, ongoing" ect
|
||||
char *getspellcosttext(lifeform_t *lf, enum OBTYPE spellid, int power, char *buf) {
|
||||
objecttype_t *ot;
|
||||
int ongoing = B_FALSE;
|
||||
int cost;
|
||||
|
||||
ot = findot(spellid);
|
||||
if (!ot) {
|
||||
strcpy(buf, "?invalidspellid?");
|
||||
return buf;
|
||||
}
|
||||
|
||||
cost = getmpcost(lf, spellid);
|
||||
|
||||
if (hasflag(ot->flags, F_ONGOING)) ongoing = B_TRUE;
|
||||
|
||||
if (hasflag(ot->flags, F_VARPOWER)) {
|
||||
sprintf(buf, "%d-%d MP%s", cost,
|
||||
cost * power, ongoing ? ", ongoing" : "");
|
||||
} else {
|
||||
sprintf(buf, "%d MP%s", cost, ongoing ? ", ongoing" : "");
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
// returns a number between min & max
|
||||
// if blessed, always the max
|
||||
// if cursed, always the min
|
||||
|
|
1
spell.h
1
spell.h
|
@ -8,6 +8,7 @@ void fizzle(lifeform_t *caster);
|
|||
//int getiqreq(enum OBTYPE oid);
|
||||
int getmpcost(lifeform_t *lf, enum OBTYPE oid);
|
||||
enum SKILL getschoolskill(enum SPELLSCHOOL ss);
|
||||
char *getspellcosttext(lifeform_t *lf, enum OBTYPE spellid, int power, char *buf);
|
||||
int getspellduration(int min,int max,int blessed);
|
||||
int getspelllevel(enum OBTYPE spellid);
|
||||
int getspellmaxpower(enum OBTYPE spellid);
|
||||
|
|
24
text.c
24
text.c
|
@ -24,6 +24,7 @@ char *capitalise(char *text) {
|
|||
return text;
|
||||
}
|
||||
|
||||
// capitalise all words
|
||||
char *capitaliseall(char *text) {
|
||||
if (strlen(text) > 0) {
|
||||
char *p;
|
||||
|
@ -128,6 +129,19 @@ char *getpossessive(char *text) {
|
|||
return "'s";
|
||||
}
|
||||
|
||||
char *getdrunktext(flag_t *drunkflag) {
|
||||
int bracket;
|
||||
bracket = (drunkflag->lifetime / DRUNKTIME) + 1;
|
||||
if (bracket == 1) {
|
||||
return "tipsy";
|
||||
} else if (bracket == 2) {
|
||||
return "drunk";
|
||||
} else {
|
||||
return "very drunk";
|
||||
}
|
||||
return "??drunk??";
|
||||
}
|
||||
|
||||
char *getsizetext(enum LFSIZE sz) {
|
||||
switch (sz) {
|
||||
case SZ_ENORMOUS:
|
||||
|
@ -289,6 +303,16 @@ char *makeplural(char *text) {
|
|||
return newtext;
|
||||
}
|
||||
|
||||
char *makeuppercase(char *text) {
|
||||
if (strlen(text) > 0) {
|
||||
char *p;
|
||||
for (p = text ; *p; p++) {
|
||||
*p = toupper(*p);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
int needses(char *text) {
|
||||
if (text[strlen(text)-1] == 's') {
|
||||
return B_TRUE;
|
||||
|
|
2
text.h
2
text.h
|
@ -7,12 +7,14 @@ char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dic
|
|||
char *getattrabbrev(enum ATTRIB att);
|
||||
char *getattrname(enum ATTRIB att);
|
||||
char *getpossessive(char *text);
|
||||
char *getdrunktext(flag_t *drunkflag);
|
||||
char *getsizetext(enum LFSIZE sz);
|
||||
char *gettimetext(char *retbuf);
|
||||
char *gettimetextfuzzy(char *retbuf, int wantpm);
|
||||
char *getweighttext(float weight, char *buf);
|
||||
int isvowel(char c);
|
||||
char *makeplural(char *text);
|
||||
char *makeuppercase(char *text);
|
||||
int needses(char *text);
|
||||
char *noprefix(char *obname);
|
||||
char *numtotext(int num, char *buf);
|
||||
|
|
Loading…
Reference in New Issue