- [+] don't show 'the xxx look exhausted' for monsters
- [+] The giant blowfly (null). - [+] instant disrobe spell - tleports armour to the side - [+] why did a monk recognise a grenade? bug in conferobjectflags. - [+] adept nature lore should identify bad mushrooms too - [+] draining/vampiric brand - gives hp to user. - [+] ways to check stairs before travelling - [+] make getstairdestination() be the place where new maps are generated - [+] move getnoisedetails into new function - [+] ability to listen down stairs with adept listen skill - [+] atomatically trigger walknoise for all lfs within los of stairs, and you always pass the check. - [+] at expert listn you get names - [+] otherwise just get 'slithering' etc - [+] test...... - [+] "check stairs" ability ??? - [+] this then prompts for various methods - [+] smell down stairs with enhancesmell - [+] say "you see xxx scent" for all lfs within los of other end - [+] use perception to check stairs - [+] say "you see xxx footprints" for all lfs within los of other end - [+] ability to peek down stairs with adept stealth skill? - [+] temporarily put you there - [+] precaclc los with awareness in all directions from there - [+] show view - [+] wait for key - [+] move you back, remove temporary awareness - [+] add help for these skills
This commit is contained in:
parent
0d663e81b3
commit
a297a3c180
19
data.c
19
data.c
|
@ -1589,6 +1589,9 @@ 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, SZ_TINY);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
addot(OT_POT_CANINETRACKING, "potion of canine tracking", "Mimics the effects of a 'canine tracking' spell.", MT_GLASS, 1, OC_POTION, SZ_TINY);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
|
||||
|
||||
addot(OT_POT_HEALINGMIN, "potion of minor healing", "Restores 1-10 health to whoever drinks it.", MT_GLASS, 1, OC_POTION, SZ_TINY);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||
addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL);
|
||||
|
@ -1690,10 +1693,6 @@ void initobjects(void) {
|
|||
addot(OT_SCR_AWARENESS, "scroll of awareness", "Mimics the effects of a 'heightened awareness' spell.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
|
||||
|
||||
addot(OT_SCR_CANINETRACKING, "scroll of canine tracking", "Mimics the effects of a 'canine tracking' spell.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
|
||||
addflag(lastot->flags, F_LINKSPELL, OT_S_CANINETRACKING, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
|
||||
|
||||
addot(OT_SCR_REMOVECURSE, "scroll of remove curse", "Removes curses from all weilded equipment.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
|
||||
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
|
||||
|
||||
|
@ -2876,6 +2875,13 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
addot(OT_S_INSTANTDISROBE, "instant disrobe", "Transports 1-3 pieces of the target's armour to the air next to them.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines number of items affected.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 8, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
|
||||
// l4
|
||||
addot(OT_S_BLINKASS, "assassin blink", "Teleports the caster behind an enemy, ready for a sneak attack.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
|
||||
|
@ -3007,6 +3013,8 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_NEEDSGRAB, B_TRUE, NA, NA, NULL);
|
||||
addot(OT_A_CHECKSTAIRS, "check stairs", "Attempt to determine what lies on the other end of a staircase.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_COOK, "cook", "Combine food and water into a healthy meals.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||
addot(OT_A_DARKWALK, "darkwalk", "Step between the shadows.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
|
||||
|
@ -8664,6 +8672,7 @@ void initskills(void) {
|
|||
addskilldesc(SK_LISTEN, PR_NOVICE, "^gYou now gauge the distance of sounds.^n", B_TRUE);
|
||||
addskilldesc(SK_LISTEN, PR_BEGINNER, "^gYou now more accurately gauge the distance of sounds.^n", B_TRUE);
|
||||
addskilldesc(SK_LISTEN, PR_ADEPT, "^gYou can now determine the direction sounds are coming from.^n", B_TRUE);
|
||||
addskilldesc(SK_LISTEN, PR_ADEPT, "^gYou can now listen at staircases before descending.^n", B_TRUE);
|
||||
addskilldesc(SK_LISTEN, PR_EXPERT, "^gYou can now identify monsters based on sound.^n", B_TRUE);
|
||||
addskilldesc(SK_LISTEN, PR_MASTER, "^gYou can now locate monsters based on sound.^n", B_TRUE);
|
||||
addskill(SK_LOCKPICKING, "Lockpicking", "Enhances your ability to pick locks.", 50);
|
||||
|
@ -8707,6 +8716,7 @@ void initskills(void) {
|
|||
addskill(SK_PERCEPTION, "Perception", "Your ability to notice hidden details, from simple footprints to sinister traps.", 50);
|
||||
addskilldesc(SK_PERCEPTION, PR_INEPT, "- At higher levels this skill will also let you obscure your own tracks.", B_TRUE);
|
||||
addskilldesc(SK_PERCEPTION, PR_NOVICE, "^gYou can now see footprints.^n", B_TRUE);
|
||||
addskilldesc(SK_PERCEPTION, PR_NOVICE, "^gYou can now check for trails on staircases before descending.^n", B_TRUE);
|
||||
addskilldesc(SK_PERCEPTION, PR_BEGINNER, "^gYou can now determine how recently footprints were made.^n", B_TRUE);
|
||||
addskilldesc(SK_PERCEPTION, PR_ADEPT, "^gYou can now identify creatures from their footprints.^n", B_TRUE);
|
||||
addskilldesc(SK_PERCEPTION, PR_ADEPT, "^gYour field of vision is now wider.^n", B_TRUE);
|
||||
|
@ -8715,6 +8725,7 @@ void initskills(void) {
|
|||
addskilldesc(SK_PERCEPTION, PR_MASTER, "^gYou now have perception of your blind spots.^n", B_TRUE);
|
||||
addskill(SK_STEALTH, "Stealth", "Affects your ability to move silently.", 0); // untrainable?
|
||||
addskilldesc(SK_STEALTH, PR_BEGINNER, "^gYou gain the 'hide' ability.^n", B_FALSE);
|
||||
addskilldesc(SK_STEALTH, PR_SKILLED, "^gYou can now peek down staircases.^n", B_TRUE);
|
||||
addskilldesc(SK_STEALTH, PR_EXPERT, "^gYou can now hide even when monsters are nearby.^n", B_TRUE);
|
||||
addskill(SK_SWIMMING, "Swimming", "Allows you to safely swim through deep water.", 50);
|
||||
addskilldesc(SK_SWIMMING, PR_NOVICE, "^gYou can now swim.^n", B_TRUE);
|
||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
4
defs.h
4
defs.h
|
@ -1044,6 +1044,7 @@ enum OBTYPE {
|
|||
OT_POT_AMBROSIA,
|
||||
OT_POT_BLOOD,
|
||||
OT_POT_BLOODC,
|
||||
OT_POT_CANINETRACKING,
|
||||
OT_POT_COFFEE,
|
||||
OT_POT_COMPETENCE,
|
||||
OT_POT_ELEMENTIMMUNE,
|
||||
|
@ -1072,7 +1073,6 @@ enum OBTYPE {
|
|||
OT_GRAPHPAPER,
|
||||
OT_SCR_AWARENESS,
|
||||
OT_SCR_NOTHING,
|
||||
OT_SCR_CANINETRACKING,
|
||||
OT_SCR_CREATEMONSTER,
|
||||
OT_SCR_DETECTAURA,
|
||||
OT_SCR_DETECTLIFE,
|
||||
|
@ -1260,6 +1260,7 @@ enum OBTYPE {
|
|||
OT_S_BLINKASS,
|
||||
OT_S_DISPERSAL,
|
||||
OT_S_GATE,
|
||||
OT_S_INSTANTDISROBE,
|
||||
OT_S_PLANESHIFT,
|
||||
OT_S_SUCK,
|
||||
OT_S_TELEPORT,
|
||||
|
@ -1284,6 +1285,7 @@ enum OBTYPE {
|
|||
OT_A_LEVELUP,
|
||||
// abilities
|
||||
OT_A_AIMEDSTRIKE,
|
||||
OT_A_CHECKSTAIRS,
|
||||
OT_A_COOK,
|
||||
OT_A_DARKWALK,
|
||||
OT_A_DISARM,
|
||||
|
|
313
lf.c
313
lf.c
|
@ -2902,7 +2902,7 @@ int eat(lifeform_t *lf, object_t *o) {
|
|||
addtempflag(lf->flags, F_SEEINDARK, 3, NA, NA, NULL, rnd(20,40));
|
||||
}
|
||||
|
||||
makeknown(o->type->id);
|
||||
if (isplayer(lf)) makeknown(o->type->id);
|
||||
} // end if fullyeaten
|
||||
|
||||
// take time
|
||||
|
@ -5673,6 +5673,130 @@ int getnightvisrange(lifeform_t *lf) {
|
|||
return range;
|
||||
}
|
||||
|
||||
// populates heartext, seetext and volume
|
||||
int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, char *heartext,char *seetext, int *volume) {
|
||||
flag_t *retflag[MAXCANDIDATES],*nflag[MAXCANDIDATES];
|
||||
int nretflags, i,nnflags = 0;
|
||||
|
||||
// deafults
|
||||
if (volume) *volume = 0;
|
||||
if (heartext) strcpy(heartext, "");
|
||||
if (seetext) strcpy(seetext, "");
|
||||
|
||||
if (lfhasflag(lf, F_FROZEN)) {
|
||||
// can't make noise if frozen!
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if ((nid == N_WALK) || nid == (N_FLY)) {
|
||||
if (!movecausesnoise(lf)) {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
getflags(lf->flags, retflag, &nretflags, F_NOISETEXT, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
if (retflag[i]->val[0] == nid) {
|
||||
nflag[nnflags++] = retflag[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (nnflags) {
|
||||
flag_t *f;
|
||||
char verb[BUFLEN], noun[BUFLEN];
|
||||
f = nflag[rnd(0,nnflags-1)];
|
||||
|
||||
if (volume) *volume = f->val[1];
|
||||
|
||||
if (f->text[0] == '^') {
|
||||
strcpy(verb, "");
|
||||
//noun = strtok_r(f->text, "^", &dummy);
|
||||
strcpy(noun, f->text + 1);
|
||||
} else {
|
||||
char *p;
|
||||
p = readuntil(verb, f->text, '^');
|
||||
readuntil(noun, p, '^'); // ie eol
|
||||
//verb = strtok_r(f->text, "^", &dummy);
|
||||
//noun = strtok_r(NULL, "^", &dummy);
|
||||
}
|
||||
|
||||
if (heartext) {
|
||||
if (strlen(noun)) {
|
||||
snprintf(heartext, BUFLEN, "%s.",noun);
|
||||
}
|
||||
}
|
||||
if (seetext) {
|
||||
if (strlen(verb)) {
|
||||
strcpy(seetext, verb);
|
||||
}
|
||||
}
|
||||
if (nid == N_WALK) {
|
||||
*volume += getarmournoise(lf);
|
||||
}
|
||||
return B_FALSE;
|
||||
} else {
|
||||
// some defaults
|
||||
if (nid == N_WALK) {
|
||||
enum LFSIZE sz;
|
||||
char movetext[BUFLEN];
|
||||
strcpy(movetext, "");
|
||||
sz = getlfsize(lf);
|
||||
switch (sz) {
|
||||
case SZ_MINI:
|
||||
case SZ_TINY:
|
||||
if (volume) *volume = 0;
|
||||
break;
|
||||
case SZ_SMALL:
|
||||
if (volume) *volume = 1;
|
||||
strcpy(movetext, "light footsteps.");
|
||||
break;
|
||||
case SZ_MEDIUM:
|
||||
case SZ_HUMAN:
|
||||
if (volume) *volume = 2;
|
||||
strcpy(movetext, "footsteps.");
|
||||
break;
|
||||
case SZ_LARGE:
|
||||
if (volume) *volume = 3;
|
||||
strcpy(movetext, "heavy footsteps.");
|
||||
break;
|
||||
case SZ_HUGE:
|
||||
if (volume) *volume = 4;
|
||||
strcpy(movetext, "heavy footsteps.");
|
||||
break;
|
||||
case SZ_ENORMOUS:
|
||||
if (volume) *volume = 5;
|
||||
strcpy(movetext, "very heavy footsteps.");
|
||||
break;
|
||||
case SZ_MAX:
|
||||
if (volume) *volume = 6;
|
||||
strcpy(movetext, "extremely loud thumping.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (strlen(movetext)) {
|
||||
if (volume) *volume += getarmournoise(lf);
|
||||
if (heartext) strcpy(heartext, movetext);
|
||||
return B_FALSE;
|
||||
}
|
||||
} else if (nid == N_SONICBOLT) {
|
||||
|
||||
if (volume) *volume = 5;
|
||||
if (heartext) strcpy(heartext, "a ear-splitting burst of sound!");
|
||||
if (seetext) strcpy(seetext, "emits an ear-splitting burst of sound!");
|
||||
return B_FALSE;
|
||||
} else if (nid == N_WARCRY) {
|
||||
if (volume) *volume = 4;
|
||||
if (heartext) strcpy(heartext, "a blood-curdling war cry!");
|
||||
if (seetext) strcpy(seetext, "shouts a blood-curdling war-cry!");
|
||||
return B_FALSE;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
char *getlfconditionname(enum LFCONDITION cond) {
|
||||
switch (cond) {
|
||||
case C_CRITICAL:
|
||||
|
@ -7521,10 +7645,10 @@ void giveobflags(lifeform_t *lf, object_t *o, enum FLAG whattype) {
|
|||
|
||||
// if all conferred flags now known, object is known
|
||||
if (flagsfound && (flagsknown == flagsfound)) {
|
||||
if (isplayer(lf) || cansee(player, lf)) {
|
||||
makeknown(o->type->id);
|
||||
// in some cases, identify the object fully
|
||||
// (ie. make +xxx bonuses known too)
|
||||
if (isplayer(lf)) {
|
||||
if (hasflag(o->flags, F_IDWHENUSED)) {
|
||||
identify(o);
|
||||
}
|
||||
|
@ -7633,7 +7757,6 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
makeknown(OT_MUSHROOMTOAD);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (id == SK_LORE_ARCANA) {
|
||||
if (f->val[1] == PR_ADEPT) {
|
||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL);
|
||||
|
@ -7642,6 +7765,13 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
newf->lifetime = FROMSKILL;
|
||||
}
|
||||
}
|
||||
} else if (id == SK_LORE_NATURE) {
|
||||
if (f->val[1] == PR_ADEPT) {
|
||||
if (isplayer(lf)) {
|
||||
makeknown(OT_MUSHROOMSHI);
|
||||
makeknown(OT_MUSHROOMTOAD);
|
||||
}
|
||||
}
|
||||
} else if (id == SK_PERCEPTION) {
|
||||
if ((f->val[1] == PR_ADEPT) || (f->val[1] == PR_MASTER)) {
|
||||
// our FOV gets wider
|
||||
|
@ -7659,6 +7789,7 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
newf->lifetime = FROMSKILL;
|
||||
}
|
||||
} else if (id == SK_TECHUSAGE) {
|
||||
if (isplayer(lf)) {
|
||||
objecttype_t *ot;
|
||||
// automatically make known all tech <= our skill level
|
||||
for (ot = objecttype ; ot ; ot = ot->next) {
|
||||
|
@ -7683,6 +7814,7 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (id == SK_TWOWEAPON) {
|
||||
if (f->val[1] == PR_EXPERT) {
|
||||
addflag(lf->flags, F_CANWILL, OT_A_FLURRY, 3, 3, "pw:1;");
|
||||
|
@ -9591,28 +9723,29 @@ void addskilldesc(enum SKILL id, enum SKILLLEVEL lev, char *text, int wantmsg) {
|
|||
sk->nskilldesc++;
|
||||
}
|
||||
|
||||
void addtrail(lifeform_t *lf, int dir) {
|
||||
object_t *footprint, *scent;
|
||||
object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int doscents) {
|
||||
object_t *footprint, *scent,*retob = NULL;
|
||||
flag_t *fpflag;
|
||||
|
||||
// no tracks at all?
|
||||
if (lf->cell->type->solid) {
|
||||
return;
|
||||
} else if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) {
|
||||
return;
|
||||
if (where->type->solid) {
|
||||
return NULL;
|
||||
} else if (hasobwithflag(where->obpile, F_DEEPWATER)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// footprints first
|
||||
if (doprints) {
|
||||
if (!isairborne(lf) && !lfhasflag(lf, F_NONCORPOREAL)) {
|
||||
int fpdir;
|
||||
if (getskill(lf, SK_PERCEPTION) >= PR_EXPERT) {
|
||||
// no footprints!
|
||||
return;
|
||||
return NULL;
|
||||
} else {
|
||||
fpdir = dir;
|
||||
}
|
||||
|
||||
footprint = hastrailof(lf->cell->obpile, lf, OT_FOOTPRINT, &fpflag, NULL);
|
||||
footprint = hastrailof(where->obpile, lf, OT_FOOTPRINT, &fpflag, NULL);
|
||||
if (footprint) {
|
||||
assert(fpflag);
|
||||
fpflag->lifetime = getfootprinttime(lf);
|
||||
|
@ -9620,22 +9753,28 @@ void addtrail(lifeform_t *lf, int dir) {
|
|||
} else {
|
||||
char buf[BUFLENTINY];
|
||||
snprintf(buf, BUFLENTINY, "%d", lf->id);
|
||||
footprint = addobfast(lf->cell->obpile, OT_FOOTPRINT);
|
||||
footprint = addobfast(where->obpile, OT_FOOTPRINT);
|
||||
addtempflag(footprint->flags, F_TRAIL, lf->race->id, fpdir, S_SIGHT, buf, getfootprinttime(lf));
|
||||
}
|
||||
retob = footprint;
|
||||
}
|
||||
}
|
||||
|
||||
// now smell
|
||||
scent = hastrailof(lf->cell->obpile, lf, OT_SCENT, &fpflag, NULL);
|
||||
if (doscents) {
|
||||
scent = hastrailof(where->obpile, lf, OT_SCENT, &fpflag, NULL);
|
||||
if (scent) {
|
||||
assert(fpflag);
|
||||
fpflag->lifetime = TM_SCENT;
|
||||
} else {
|
||||
char buf[BUFLENTINY];
|
||||
snprintf(buf, BUFLENTINY, "%d", lf->id);
|
||||
scent = addobfast(lf->cell->obpile, OT_SCENT);
|
||||
scent = addobfast(where->obpile, OT_SCENT);
|
||||
addtempflag(scent->flags, F_TRAIL, lf->race->id, dir, S_SMELL, buf, TM_SCENT);
|
||||
}
|
||||
retob = scent;
|
||||
}
|
||||
return retob;
|
||||
}
|
||||
|
||||
void adjustspeedforwater(lifeform_t *lf, int *speed) {
|
||||
|
@ -10789,96 +10928,15 @@ int makenauseated(lifeform_t *lf, int amt, int howlong) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
void makenoise(lifeform_t *lf, enum NOISETYPE nid) {
|
||||
flag_t *retflag[MAXCANDIDATES],*nflag[MAXCANDIDATES];
|
||||
int nretflags, volume = 1, i,nnflags = 0;
|
||||
char *verb = NULL, *noun = NULL;
|
||||
int volume = 1;
|
||||
char hear[BUFLEN], see[BUFLEN];
|
||||
|
||||
if (lfhasflag(lf, F_FROZEN)) {
|
||||
// can't make noise if frozen!
|
||||
return;
|
||||
if (!getnoisedetails(lf, nid, hear, see, &volume)) {
|
||||
// success
|
||||
noise(lf->cell, lf, noisetypetoclass(nid), volume, strlen(hear) ? hear : NULL, strlen(see) ? see : NULL);
|
||||
}
|
||||
|
||||
|
||||
getflags(lf->flags, retflag, &nretflags, F_NOISETEXT, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
if (retflag[i]->val[0] == nid) {
|
||||
nflag[nnflags++] = retflag[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (nnflags) {
|
||||
flag_t *f;
|
||||
char *dummy;
|
||||
char noisetext[BUFLEN];
|
||||
f = nflag[rnd(0,nnflags-1)];
|
||||
|
||||
volume = f->val[1];
|
||||
|
||||
if (f->text[0] == '^') {
|
||||
verb = NULL;
|
||||
noun = strtok_r(f->text, "^", &dummy);
|
||||
} else {
|
||||
verb = strtok_r(f->text, "^", &dummy);
|
||||
noun = strtok_r(NULL, "^", &dummy);
|
||||
}
|
||||
|
||||
snprintf(noisetext, BUFLEN, "%s.",noun);
|
||||
if (nid == N_WALK) {
|
||||
volume += getarmournoise(lf);
|
||||
}
|
||||
noise(lf->cell, lf, noisetypetoclass(nid), volume, noisetext, verb);
|
||||
} else {
|
||||
// some defaults
|
||||
if (nid == N_WALK) {
|
||||
enum LFSIZE sz;
|
||||
char movetext[BUFLEN];
|
||||
strcpy(movetext, "");
|
||||
sz = getlfsize(lf);
|
||||
switch (sz) {
|
||||
case SZ_MINI:
|
||||
case SZ_TINY:
|
||||
volume = 0;
|
||||
break;
|
||||
case SZ_SMALL:
|
||||
volume = 1;
|
||||
strcpy(movetext, "light footsteps.");
|
||||
break;
|
||||
case SZ_MEDIUM:
|
||||
case SZ_HUMAN:
|
||||
volume = 2;
|
||||
strcpy(movetext, "footsteps.");
|
||||
break;
|
||||
case SZ_LARGE:
|
||||
volume = 3;
|
||||
strcpy(movetext, "heavy footsteps.");
|
||||
break;
|
||||
case SZ_HUGE:
|
||||
volume = 4;
|
||||
strcpy(movetext, "heavy footsteps.");
|
||||
break;
|
||||
case SZ_ENORMOUS:
|
||||
volume = 5;
|
||||
strcpy(movetext, "very heavy footsteps.");
|
||||
break;
|
||||
case SZ_MAX:
|
||||
volume = 6;
|
||||
strcpy(movetext, "extremely loud thumping.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
volume += getarmournoise(lf);
|
||||
if (strlen(movetext)) {
|
||||
noise(lf->cell, lf, noisetypetoclass(nid), volume, movetext, NULL);
|
||||
}
|
||||
} else if (nid == N_SONICBOLT) {
|
||||
noise(lf->cell, lf, NC_OTHER, 5, "a ear-splitting burst of sound!", "emits an ear-splitting burst of sound!");
|
||||
} else if (nid == N_WARCRY) {
|
||||
noise(lf->cell, lf, NC_OTHER, 4, "a blood-curdling war cry!", "shouts a blood-curdling war-cry!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void mayusespellschool(flagpile_t *fp, enum SPELLSCHOOL ss, enum FLAG how) {
|
||||
|
@ -11203,13 +11261,14 @@ void modstamina(lifeform_t *lf, float howmuch) {
|
|||
} else if (orig == 0) {
|
||||
msg("You feel less exhausted now.");
|
||||
}
|
||||
} else if (cansee(player, lf)) {
|
||||
}
|
||||
/*else if (cansee(player, lf)) {
|
||||
if (getstamina(lf) == 0) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(lf, lfname);
|
||||
msg("%s looks exhausted.", lfname);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
if (getstamina(lf) == 0) {
|
||||
|
@ -11217,6 +11276,14 @@ void modstamina(lifeform_t *lf, float howmuch) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int movecausesnoise(lifeform_t *lf) {
|
||||
if (lfhasflag(lf, F_SILENTMOVE) || lfhasflag(lf, F_SNEAK)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// if validchars is set, we will populate it with a list of valid
|
||||
// choice letters for asking the player how to rest.
|
||||
int needstorest(lifeform_t *lf, char *validchars) {
|
||||
|
@ -11310,6 +11377,9 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
strcat(realseetext, "something");
|
||||
}
|
||||
msg("%s %s.", lfname, realseetext);
|
||||
if ((realseetext[0] == '\0') || !strlen(realseetext)) {
|
||||
dblog("xxx");
|
||||
}
|
||||
rv = B_TRUE;
|
||||
}
|
||||
} else if (text && !isdeaf(l) && ((nclass != NC_MOVEMENT) || !lfhasflag(l, F_DONELISTEN))) {
|
||||
|
@ -15061,31 +15131,14 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
}
|
||||
}
|
||||
|
||||
// do stairs go somewhere?
|
||||
newcell = getstairdestination(o);
|
||||
if (!newcell) {
|
||||
// do stairs go somewhere? generate new maps if required.
|
||||
newcell = getstairdestination(o, &madenewmap);
|
||||
if (newcell) {
|
||||
newmap = newcell->map;
|
||||
} else {
|
||||
if (isportal) {
|
||||
// unconnected portal
|
||||
if (isplayer(lf)) msg("This portal doesn't seem to go anywhere.");
|
||||
} else {
|
||||
// is there already a level of the correct depth?
|
||||
newmap = findregionmap(newregion->id, newdepth);
|
||||
if (newmap) {
|
||||
dblog("ERROR - unlinked stairs!\n");
|
||||
msg("ERROR - unlinked stairs!\n");
|
||||
} else {
|
||||
// generate a new map! this will fill in the destination of our stairs
|
||||
newmap = addmap();
|
||||
// first map of a newly created region?
|
||||
if (newregion->id != curmap->region->id) {
|
||||
newdepth = 1;
|
||||
}
|
||||
createmap(newmap, newdepth, newregion, curmap, dir, o);
|
||||
// at this point, stairs should have a destination (map creation will
|
||||
// fill it in)
|
||||
newcell = getstairdestination(o);
|
||||
madenewmap = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15112,20 +15165,12 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose) {
|
|||
}
|
||||
|
||||
// check noone is in the way
|
||||
if (newcell->lf) {
|
||||
cell_t *c;
|
||||
// if they are, find somewhere to move them.
|
||||
c = getrandomadjcell(newcell, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
if (c) {
|
||||
// move them there
|
||||
movelf(newcell->lf, c);
|
||||
} else {
|
||||
if (movelfsoutofway(newcell)) {
|
||||
// TODO: handle this differently - ie always allow the player
|
||||
// go there?
|
||||
if (isplayer(lf)) msg("The stairs seem to be blocked.");
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
// announce
|
||||
if (isplayer(lf)) {
|
||||
announcearrival(lf, newcell->map);
|
||||
|
|
4
lf.h
4
lf.h
|
@ -7,7 +7,7 @@ race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcol
|
|||
raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill);
|
||||
skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime);
|
||||
void addskilldesc(enum SKILL id, enum SKILLLEVEL lev, char *text, int wantmsg);
|
||||
void addtrail(lifeform_t *lf, int dir);
|
||||
object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int doscents);
|
||||
void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype);
|
||||
void adjustspeedforwater(lifeform_t *lf, int *speed);
|
||||
void age(lifeform_t *lf, int pct);
|
||||
|
@ -153,6 +153,7 @@ int getminions(lifeform_t *lf, lifeform_t **minion, int *nminions);
|
|||
int getmiscastchance(lifeform_t *lf);
|
||||
int getmorale(lifeform_t *lf);
|
||||
int getnightvisrange(lifeform_t *lf);
|
||||
int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, char *heartext,char *seetext, int *volume);
|
||||
char *getlfconditionname(enum LFCONDITION cond);
|
||||
object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp);
|
||||
int getowing(lifeform_t *buyer, int shopid, int *retnitems);
|
||||
|
@ -318,6 +319,7 @@ void modhunger(lifeform_t *lf, int amt);
|
|||
float modifybystat(float num, lifeform_t *lf, enum ATTRIB att);
|
||||
void modmorale(lifeform_t *lf, int howmuch);
|
||||
void modstamina(lifeform_t *lf, float howmuch);
|
||||
int movecausesnoise(lifeform_t *lf);
|
||||
int needstorest(lifeform_t *lf, char *validchars);
|
||||
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, char *text, char *seetext);
|
||||
enum NOISECLASS noisetypetoclass(enum NOISETYPE nt);
|
||||
|
|
58
map.c
58
map.c
|
@ -2782,13 +2782,13 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
object_t *o;
|
||||
c = getcellat(map, x, y);
|
||||
o = hasobwithflag(c->obpile, F_CLIMBABLE);
|
||||
if (o && !getstairdestination(o)) {
|
||||
if (o && !getstairdestination(o, NULL)) {
|
||||
// this will join these stairs to existing ones on
|
||||
// existing adjacent maps
|
||||
if (!linkstairs(o, NULL)) {
|
||||
if (db) {
|
||||
cell_t *dst;
|
||||
dst = getstairdestination(o);
|
||||
dst = getstairdestination(o, NULL);
|
||||
dblog(" linked '%s' to map %s",o->type->name, dst->map->name);
|
||||
}
|
||||
} else {
|
||||
|
@ -4077,7 +4077,7 @@ map_t *findsurfaceexitmap(map_t *m) {
|
|||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (hasflagval(o->flags, F_CLIMBABLE, D_UP, NA, NA, NULL)) {
|
||||
cell_t *newc;
|
||||
newc = getstairdestination(o);
|
||||
newc = getstairdestination(o, NULL);
|
||||
if (newc) {
|
||||
return newc->map;
|
||||
}
|
||||
|
@ -4554,7 +4554,8 @@ int getslipperyness(cell_t *c, object_t **slipob) {
|
|||
return totalslip;
|
||||
}
|
||||
|
||||
cell_t *getstairdestination(object_t *o) {
|
||||
// if madenewmap is passed, then we'll try to make a new map for stairs with no endpoint
|
||||
cell_t *getstairdestination(object_t *o, int *madenewmap) {
|
||||
flag_t *f;
|
||||
cell_t *newcell = NULL;
|
||||
|
||||
|
@ -4585,6 +4586,55 @@ cell_t *getstairdestination(object_t *o) {
|
|||
newcell = getcellat(newmap, newx, newy);
|
||||
}
|
||||
}
|
||||
|
||||
if (!newcell && madenewmap) {
|
||||
cell_t *obcell = NULL;
|
||||
map_t *newmap,*curmap;
|
||||
region_t *newregion = NULL;
|
||||
int dir,newdepth;
|
||||
|
||||
obcell = getoblocation(o);
|
||||
curmap = obcell->map;
|
||||
|
||||
f = hasflag(o->flags, F_CLIMBABLE);
|
||||
if (!f) return NULL;
|
||||
|
||||
dir = getstairdirection(o);
|
||||
if ((dir != D_UP) && (dir != D_DOWN)) {
|
||||
// ie this is a portal
|
||||
return NULL;
|
||||
} else {
|
||||
if (dir == D_UP) newdepth = curmap->depth - 1;
|
||||
else newdepth = curmap->depth + 1;
|
||||
if (f->val[1] == NA) {
|
||||
// use same region
|
||||
newregion = obcell->map->region;
|
||||
} else {
|
||||
newregion = findregion(f->val[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// is there already a level of the correct depth?
|
||||
newmap = findregionmap(newregion->id, newdepth);
|
||||
if (newmap) {
|
||||
dblog("ERROR - unlinked stairs!\n");
|
||||
msg("ERROR - unlinked stairs!\n");
|
||||
return NULL;
|
||||
} else {
|
||||
// generate a new map! this will fill in the destination of our stairs
|
||||
newmap = addmap();
|
||||
// first map of a newly created region?
|
||||
if (newregion->id != curmap->region->id) {
|
||||
newdepth = 1;
|
||||
}
|
||||
createmap(newmap, newdepth, newregion, curmap, dir, o);
|
||||
// at this point, stairs should have a destination (map creation will
|
||||
// fill it in)
|
||||
newcell = getstairdestination(o, NULL); // recursive call
|
||||
*madenewmap = B_TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
return newcell;
|
||||
}
|
||||
|
||||
|
|
2
map.h
2
map.h
|
@ -95,7 +95,7 @@ int getrandomdirexcept(int dirtype, int exception);
|
|||
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);
|
||||
cell_t *getstairdestination(object_t *o, int *madenewmap);
|
||||
object_t *hasenterableobject(cell_t *c);
|
||||
object_t *hascloseddoor(cell_t *c);
|
||||
lifeform_t *haslf(cell_t *c);
|
||||
|
|
22
move.c
22
move.c
|
@ -1363,6 +1363,22 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
|
|||
return didmsg;
|
||||
}
|
||||
|
||||
int movelfsoutofway(cell_t *newcell) {
|
||||
// anyone in the way?
|
||||
if (newcell->lf) {
|
||||
cell_t *c;
|
||||
// if they are, find somewhere to move them.
|
||||
c = getrandomadjcell(newcell, WE_WALKABLE, B_ALLOWEXPAND);
|
||||
if (c) {
|
||||
// move them there
|
||||
movelf(newcell->lf, c);
|
||||
} else {
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// basically this is a warpper for 'movelf' which
|
||||
// does other game things like telling the player
|
||||
// what is here.
|
||||
|
@ -1466,7 +1482,6 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
|
||||
// make some noise
|
||||
// (stealth check to avoid this)
|
||||
if (!lfhasflag(lf, F_SILENTMOVE) && !lfhasflag(lf, F_SNEAK)) {
|
||||
if (!skillcheck(lf, SC_STEALTH, 20, 0)) {
|
||||
if (isairborne(lf)) {
|
||||
makenoise(lf, N_FLY);
|
||||
|
@ -1474,7 +1489,6 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
|||
makenoise(lf, N_WALK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// slip on blood in new cell?
|
||||
if (!isairborne(lf) && !isswimming(lf)) {
|
||||
|
@ -2373,8 +2387,8 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
|
|||
killflagsofid(lf->flags, F_LASTDIR);
|
||||
addflag(lf->flags, F_LASTDIR, dir, NA, NA, NULL);
|
||||
|
||||
// add footprints in our current cell.
|
||||
addtrail(lf, dir);
|
||||
// add footprints/scents in our current cell.
|
||||
addtrail(lf, lf->cell, dir, B_TRUE, B_TRUE);
|
||||
|
||||
// do your pets see you move?
|
||||
if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) {
|
||||
|
|
1
move.h
1
move.h
|
@ -18,6 +18,7 @@ int moveawayfrom(lifeform_t *lf, cell_t *dst, int dirtype, int keepinlof, int st
|
|||
int moveclear(lifeform_t *lf, int dir, enum ERROR *error);
|
||||
int moveeffects(lifeform_t *lf);
|
||||
int movelf(lifeform_t *lf, cell_t *newcell);
|
||||
int movelfsoutofway(cell_t *newcell);
|
||||
int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg);
|
||||
int movetowards(lifeform_t *lf, cell_t *dst, int dirtype, int strafe);
|
||||
int move_will_hurt(lifeform_t *lf);
|
||||
|
|
24
objects.c
24
objects.c
|
@ -5287,6 +5287,15 @@ float getshopprice(object_t *o, lifeform_t *buyer) {
|
|||
return val;
|
||||
}
|
||||
|
||||
int getstairdirection(object_t *o) {
|
||||
flag_t *f;
|
||||
f = hasflag(o->flags, F_CLIMBABLE);
|
||||
if ((f->val[0] == D_UP) || (f->val[0] == D_DOWN)) {
|
||||
return f->val[0];
|
||||
}
|
||||
return D_NONE;
|
||||
}
|
||||
|
||||
enum SKILLLEVEL gettechlevel(enum OBTYPE oid) {
|
||||
flag_t *f;
|
||||
objecttype_t *ot;
|
||||
|
@ -6442,6 +6451,14 @@ void makeknown(enum OBTYPE otid) {
|
|||
flag_t *retflag[MAXCANDIDATES];
|
||||
int nretflags = 0;
|
||||
|
||||
/*
|
||||
objecttype_t *ot;
|
||||
ot = findot(otid);
|
||||
if (ot && (ot->obclass->id == OC_TECH)) {
|
||||
dblog("xxx");
|
||||
}
|
||||
*/
|
||||
|
||||
if (player) {
|
||||
// if player is holding an object of that type with F_CONFER.. IFKNOWN... and isn't known...
|
||||
// then by making the object known, we also need to give them the flag.
|
||||
|
@ -6597,7 +6614,7 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
|
|||
pit = hasobwithflagval(dst->where->obpile, F_PIT, D_DOWN, NA, NA, NULL);
|
||||
if (pit) {
|
||||
cell_t *newcell;
|
||||
newcell = getstairdestination(pit);
|
||||
newcell = getstairdestination(pit, NULL);
|
||||
if (newcell) {
|
||||
if (haslos(player, dst->where)) {
|
||||
char obname[BUFLEN];
|
||||
|
@ -7092,7 +7109,7 @@ int obsfallthrough(cell_t *c, object_t *pit) {
|
|||
char obname[BUFLEN],downholename[BUFLEN],upholename[BUFLEN];
|
||||
int nfallen = 0;
|
||||
|
||||
belowcell = getstairdestination(pit);
|
||||
belowcell = getstairdestination(pit, NULL);
|
||||
if (!belowcell) return 0;
|
||||
|
||||
uphole = hasobwithflagval(belowcell->obpile, F_PIT, D_UP, NA, NA, NULL);
|
||||
|
@ -8492,6 +8509,9 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
}
|
||||
}
|
||||
break;
|
||||
case OT_POT_CANINETRACKING:
|
||||
dospelleffects(lf, OT_S_CANINETRACKING, 5, lf, NULL, lf->cell, potblessed, seen, B_TRUE);
|
||||
break;
|
||||
case OT_POT_COFFEE:
|
||||
if (isplayer(lf)) {
|
||||
msg("This tastes like coffee.");
|
||||
|
|
|
@ -130,6 +130,7 @@ char *getschoolname(enum SPELLSCHOOL sch);
|
|||
char *getschoolnameshort(enum SPELLSCHOOL sch);
|
||||
int getshatterdam(object_t *o);
|
||||
float getshopprice(object_t *o, lifeform_t *buyer);
|
||||
int getstairdirection(object_t *o);
|
||||
enum SKILLLEVEL gettechlevel(enum OBTYPE oid);
|
||||
int getthrowdam(object_t *o);
|
||||
char *gettopobname(cell_t *c, char *retbuf);
|
||||
|
|
396
spell.c
396
spell.c
|
@ -25,6 +25,7 @@ extern region_t *firstregion;
|
|||
extern knowledge_t *knowledge;
|
||||
|
||||
extern int needredraw;
|
||||
extern int noredraw;
|
||||
|
||||
extern prompt_t prompt;
|
||||
|
||||
|
@ -215,6 +216,344 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
|||
// attack
|
||||
attackcell(user, targcell, B_TRUE);
|
||||
}
|
||||
} else if (abilid == OT_A_CHECKSTAIRS) {
|
||||
char obname[BUFLEN], buf[BUFLEN],ch;
|
||||
int madenewmap = B_TRUE;
|
||||
cell_t *origcell = NULL;
|
||||
lifeform_t *inway = NULL;
|
||||
cell_t *c;
|
||||
object_t *stairs;
|
||||
int stairdir;
|
||||
|
||||
if (!isplayer(user)) {
|
||||
return B_FALSE;
|
||||
}
|
||||
// are there stairs here?
|
||||
stairs = hasobwithflag(user->cell->obpile, F_CLIMBABLE);
|
||||
if (!stairs) {
|
||||
msg("There are no stairs here!");
|
||||
return B_TRUE;
|
||||
}
|
||||
stairdir = getstairdirection(stairs);
|
||||
|
||||
if ((stairdir != D_UP) && (stairdir != D_DOWN)) {
|
||||
// slightly different message from above, for debugging
|
||||
msg("There are no stairs here to check!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// how can we check the stairs?
|
||||
getobname(stairs, obname, 1);
|
||||
sprintf(buf, "How will you check %s", obname);
|
||||
initprompt(&prompt, buf);
|
||||
if ((getskill(user, SK_LISTEN) >= PR_ADEPT) && !isdeaf(user)) {
|
||||
addchoice(&prompt, 'l', "Listen for sounds", NULL, NULL, NULL);
|
||||
}
|
||||
if ((getskill(user, SK_PERCEPTION)) && !isblind(user)) {
|
||||
addchoice(&prompt, 'f', "Check for footprints", NULL, NULL, NULL);
|
||||
}
|
||||
if (getskill(user, SK_STEALTH) >= PR_SKILLED) {
|
||||
addchoice(&prompt, 'p', "Peek at the other end", NULL, NULL, NULL);
|
||||
}
|
||||
if (lfhasflag(user, F_ENHANCESMELL)) {
|
||||
addchoice(&prompt, 's', "Sniff for scents", NULL, NULL, NULL);
|
||||
}
|
||||
addchoice(&prompt, '-', "(cancel)", NULL, NULL, NULL);
|
||||
prompt.maycancel = B_TRUE;
|
||||
if (prompt.nchoices == 1) {
|
||||
msg("You have no way to check %s.", obname);
|
||||
return B_TRUE;
|
||||
}
|
||||
ch = getchoice(&prompt);
|
||||
|
||||
if ((ch == '-') || (ch == '\0')) {
|
||||
msg("Cancelled.");
|
||||
return B_TRUE;
|
||||
}
|
||||
c = getstairdestination(stairs, &madenewmap);
|
||||
if (!c) {
|
||||
msg("These stairs don't seem to go anywhere!");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
noredraw = B_TRUE;
|
||||
|
||||
// move any lfs at the other end out of the way.
|
||||
if (movelfsoutofway(c)) {
|
||||
// can't move them? ie. no adj cells.
|
||||
inway = c->lf;
|
||||
}
|
||||
|
||||
if (!inway) {
|
||||
// temporarily put the player at the other end
|
||||
// purposely not using movelf() because we don't
|
||||
// want to trigger map enter effects.
|
||||
origcell = user->cell;
|
||||
origcell->lf = NULL;
|
||||
user->cell = c;
|
||||
c->lf = user;
|
||||
}
|
||||
|
||||
// now actually do the check
|
||||
if (ch == 'l') {
|
||||
lifeform_t *lf;
|
||||
enum SKILLLEVEL slev;
|
||||
char *movetext[MAXCANDIDATES],thismovetext[BUFLEN];
|
||||
int nposs = 0,n,movetextcount[MAXCANDIDATES],found,vol;
|
||||
|
||||
slev = getskill(user, SK_LISTEN);
|
||||
|
||||
msg("You listen at %s...",obname);
|
||||
more();
|
||||
|
||||
if (inway) {
|
||||
// just get the lf in the way
|
||||
if (getnoisedetails(inway, N_WALK, thismovetext, NULL, &vol)) {
|
||||
// doesn't make noise
|
||||
nposs = 0;
|
||||
} else {
|
||||
if (slev >= PR_EXPERT) {
|
||||
// overwrite name
|
||||
real_getlfnamea(inway, thismovetext, B_FALSE);
|
||||
}
|
||||
movetext[0] = strdup(thismovetext);
|
||||
movetextcount[0] = 1;
|
||||
nposs = 1;
|
||||
}
|
||||
} else {
|
||||
// get all lfs within hearing of the other end
|
||||
for (lf = c->map->lf ; lf ; lf = lf->next) {
|
||||
if (lf == user) continue;
|
||||
// get movement text
|
||||
if (getnoisedetails(lf, N_WALK, thismovetext, NULL, &vol)) continue;
|
||||
if (slev >= PR_EXPERT) {
|
||||
// overwrite name
|
||||
real_getlfnamea(lf, thismovetext, B_FALSE);
|
||||
}
|
||||
if (canhear(user, lf->cell, vol)) {
|
||||
// already have this text?
|
||||
found = B_FALSE;
|
||||
for (n = 0; n < nposs; n++) {
|
||||
if (streq(movetext[n], thismovetext)) {
|
||||
movetextcount[n]++;
|
||||
found = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
movetext[nposs] = strdup(thismovetext);
|
||||
movetextcount[nposs] = 1;
|
||||
nposs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// announce
|
||||
if (nposs) {
|
||||
for (n = 0; n < nposs; n++) {
|
||||
char amttext[BUFLEN];
|
||||
if (slev >= PR_EXPERT) { // we're hearing monster names
|
||||
if (movetextcount[n] == 1) {
|
||||
strcpy(amttext, "");
|
||||
} else if (movetextcount[n] <= 3) {
|
||||
strcpy(amttext, "some ");
|
||||
} else {
|
||||
strcpy(amttext, "lots of ");
|
||||
}
|
||||
} else { // we're hearing monster sounds
|
||||
strcpy(amttext, "");
|
||||
}
|
||||
|
||||
if (slev >= PR_EXPERT) {
|
||||
char *newtext;
|
||||
if (movetextcount[n] > 1) {
|
||||
newtext = makeplural(movetext[n]);
|
||||
msg("You can hear %s%s.", amttext, noprefix(newtext));
|
||||
free(newtext);
|
||||
} else {
|
||||
msg("You can hear %s.", movetext[n]);
|
||||
}
|
||||
} else {
|
||||
msg("You can hear %s%s", amttext, movetext[n]);
|
||||
}
|
||||
// free this mem
|
||||
free(movetext[n]);
|
||||
}
|
||||
} else {
|
||||
msg("You don't hear anything unusual.");
|
||||
}
|
||||
} else if (ch == 's') { // smell
|
||||
lifeform_t *lf;
|
||||
race_t *smellrace[MAXCANDIDATES];
|
||||
int nposs = 0,n,smellcount[MAXCANDIDATES], range = 0;
|
||||
|
||||
msg("You sniff %s...",obname);
|
||||
more();
|
||||
|
||||
f = lfhasflag(user, F_ENHANCESMELL);
|
||||
if (f) {
|
||||
range = f->val[0];
|
||||
}
|
||||
|
||||
if (range) {
|
||||
// list everyone you can smell.
|
||||
if (inway) {
|
||||
// just smell the lf in the way
|
||||
if (issmellablelf(inway)) {
|
||||
smellrace[0] = inway->race;
|
||||
smellcount[0] = 1;
|
||||
nposs = 1;
|
||||
} else {
|
||||
nposs = 0;
|
||||
}
|
||||
} else {
|
||||
// get all lfs you can smell from the other end
|
||||
for (lf = c->map->lf ; lf ; lf = lf->next) {
|
||||
int found;
|
||||
if (lf == user) continue;
|
||||
if (getcelldist(lf->cell, c) <= range) {
|
||||
// already have this one?
|
||||
found = B_FALSE;
|
||||
for (n = 0; n < nposs; n++) {
|
||||
if (smellrace[n] == lf->race) {
|
||||
smellcount[n]++;
|
||||
found = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
smellrace[nposs] = lf->race;
|
||||
smellcount[nposs] = 1;
|
||||
nposs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// announce
|
||||
if (nposs) {
|
||||
for (n = 0; n < nposs; n++) {
|
||||
char amttext[BUFLEN];
|
||||
char *newtext;
|
||||
if (smellcount[n] == 1) {
|
||||
strcpy(amttext, "");
|
||||
} else if (smellcount[n] <= 3) {
|
||||
strcpy(amttext, "some ");
|
||||
} else {
|
||||
strcpy(amttext, "lots of ");
|
||||
}
|
||||
|
||||
if (smellcount[n] > 1) {
|
||||
newtext = makeplural(smellrace[n]->name);
|
||||
msg("You can smell %s%s.", amttext, newtext);
|
||||
free(newtext);
|
||||
} else {
|
||||
msg("You can smell %s %s.", needan(smellrace[n]->name) ? "an" : "a", smellrace[n]->name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msg("You don't smell anything unusual.");
|
||||
}
|
||||
} else if (ch == 'f') { // footprints
|
||||
lifeform_t *lf;
|
||||
object_t *trailob;
|
||||
char *fpname[MAXCANDIDATES],thisfpname[BUFLEN];
|
||||
int nposs = 0,n,fpcount[MAXCANDIDATES];
|
||||
|
||||
msg("You inspect %s...",obname);
|
||||
more();
|
||||
|
||||
if (inway) {
|
||||
// just do footprints for the lf in the way
|
||||
trailob = addtrail(inway, c, inway->facing, B_TRUE, B_FALSE);
|
||||
if (trailob) {
|
||||
getobname(trailob, thisfpname, 1);
|
||||
fpname[0] = strdup(thisfpname);
|
||||
fpcount[0] = 1;
|
||||
nposs = 1;
|
||||
killob(trailob);
|
||||
} else {
|
||||
nposs = 0;
|
||||
}
|
||||
} else {
|
||||
// get all lfs which make trails from the other end
|
||||
for (lf = c->map->lf ; lf ; lf = lf->next) {
|
||||
if (lf == user) continue;
|
||||
// within lof of stairs?
|
||||
if (haslof(lf->cell, c, LOF_WALLSTOP, NULL)) {
|
||||
trailob = addtrail(lf, c, lf->facing, B_TRUE, B_FALSE);
|
||||
if (trailob) {
|
||||
if (canseeob(user, trailob)) {
|
||||
int found = B_FALSE;
|
||||
// already a trail like this?
|
||||
getobname(trailob, thisfpname, 1);
|
||||
for (n = 0; n < nposs; n++) {
|
||||
if (streq(fpname[n], thisfpname)) {
|
||||
fpcount[n]++;
|
||||
found = B_TRUE;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
fpname[nposs] = strdup(thisfpname);
|
||||
fpcount[nposs] = 1;
|
||||
nposs++;
|
||||
}
|
||||
}
|
||||
killob(trailob);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// announce
|
||||
if (nposs) {
|
||||
for (n = 0; n < nposs; n++) {
|
||||
char amttext[BUFLEN];
|
||||
if (fpcount[n] == 1) {
|
||||
strcpy(amttext, "");
|
||||
} else if (fpcount[n] <= 3) {
|
||||
strcpy(amttext, "several ");
|
||||
} else { // 4+
|
||||
strcpy(amttext, "lots of ");
|
||||
}
|
||||
msg("You find %s%s.", amttext, fpname[n]);
|
||||
}
|
||||
} else {
|
||||
msg("You don't find any unusual tracks.");
|
||||
}
|
||||
} else if (ch == 'p') { // peek
|
||||
flag_t *awareness;
|
||||
msg("You peek %s the stairs...", getdirname(stairdir)); more();
|
||||
// process light sources for the other end (otherwise new
|
||||
// maps will be dark by default and you might not see anything)
|
||||
calclight(c->map);
|
||||
// prevent announcement of the flag we're about to give
|
||||
user->born = B_FALSE;
|
||||
// temporarily give the player 360degree sight
|
||||
awareness = addflag(user->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
|
||||
noredraw = B_FALSE; // allow redraws
|
||||
setlosdirty(user); // this will redraw the screen
|
||||
askcoords("Peek (ESC when done)->", "Peek (ESC when done)->", TT_NONE, user, UNLIMITED, LOF_DONTNEED, B_FALSE);
|
||||
killflag(awareness);
|
||||
user->born = B_TRUE;
|
||||
} else {
|
||||
msg("Not implemented yet.");
|
||||
} // end ways of checking
|
||||
|
||||
if (!inway) {
|
||||
// move user back
|
||||
user->cell->lf = NULL;
|
||||
user->cell = origcell;
|
||||
origcell->lf = user;
|
||||
}
|
||||
noredraw = B_FALSE;
|
||||
|
||||
if (ch == 'p') {
|
||||
// if we peeked, then we have to redraw now.
|
||||
setlosdirty(user);
|
||||
msg("You return to your original position.");
|
||||
}
|
||||
|
||||
taketime(user, getactspeed(user)*2);
|
||||
} else if (abilid == OT_A_COOK) {
|
||||
object_t *water,*o;
|
||||
race_t *r = NULL;
|
||||
|
@ -5975,6 +6314,63 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
} else {
|
||||
// monsters can't cast
|
||||
}
|
||||
} else if (spellid == OT_S_INSTANTDISROBE) {
|
||||
cell_t *newcell = NULL;
|
||||
int howmany = (power / 4)+1,ndone = 0;
|
||||
int i,announcethump = B_FALSE;
|
||||
object_t *o;
|
||||
target = targcell->lf;
|
||||
if (!target) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// find cell next to caster
|
||||
newcell = getrandomadjcell(targcell, WE_WALKABLE, B_NOEXPAND);
|
||||
if (!newcell) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
for (i = 0; i < howmany; i++) {
|
||||
// pick armour
|
||||
o = getrandomarmour(target);
|
||||
if (o) {
|
||||
char obname[BUFLEN];
|
||||
// move it
|
||||
ndone++;
|
||||
moveob(o, newcell->obpile, o->amt);
|
||||
if (isplayer(target)) {
|
||||
getobname(o, obname, o->amt);
|
||||
if (haslos(player, newcell)) {
|
||||
msg("Your %s suddenly appears next to you!", noprefix(obname));
|
||||
} else {
|
||||
msg("Your %s suddenly vanishes!", noprefix(obname));
|
||||
|
||||
announcethump = B_TRUE;
|
||||
}
|
||||
} else if (cansee(player, target)) {
|
||||
char lfname[BUFLEN];
|
||||
getlfname(target, lfname);
|
||||
if (haslos(player, newcell)) {
|
||||
msg("%s%s %s suddenly appears next to it!", lfname, getpossessive(lfname),
|
||||
noprefix(buf));
|
||||
} else {
|
||||
msg("%s%s %s suddenly vanishes!", lfname, getpossessive(lfname),
|
||||
noprefix(buf));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ndone) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
if (announcethump && !isdeaf(player)) {
|
||||
msg("You hear something hitting the ground next to you.");
|
||||
}
|
||||
} else if (spellid == OT_S_INVISIBILITY) {
|
||||
int howlong = 30;
|
||||
int willannounce = B_FALSE;
|
||||
|
|
Loading…
Reference in New Issue