- [+] 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)
|
// 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);
|
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);
|
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);
|
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_RARITY, H_DUNGEON, 100, NA, NULL);
|
||||||
addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, 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);
|
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);
|
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);
|
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);
|
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_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, 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
|
// 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);
|
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);
|
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_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
|
||||||
addflag(lastot->flags, F_NEEDSGRAB, B_TRUE, 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);
|
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);
|
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);
|
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_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_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 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_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);
|
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);
|
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);
|
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_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 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_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, "^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);
|
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);
|
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?
|
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_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);
|
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);
|
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);
|
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_AMBROSIA,
|
||||||
OT_POT_BLOOD,
|
OT_POT_BLOOD,
|
||||||
OT_POT_BLOODC,
|
OT_POT_BLOODC,
|
||||||
|
OT_POT_CANINETRACKING,
|
||||||
OT_POT_COFFEE,
|
OT_POT_COFFEE,
|
||||||
OT_POT_COMPETENCE,
|
OT_POT_COMPETENCE,
|
||||||
OT_POT_ELEMENTIMMUNE,
|
OT_POT_ELEMENTIMMUNE,
|
||||||
|
@ -1072,7 +1073,6 @@ enum OBTYPE {
|
||||||
OT_GRAPHPAPER,
|
OT_GRAPHPAPER,
|
||||||
OT_SCR_AWARENESS,
|
OT_SCR_AWARENESS,
|
||||||
OT_SCR_NOTHING,
|
OT_SCR_NOTHING,
|
||||||
OT_SCR_CANINETRACKING,
|
|
||||||
OT_SCR_CREATEMONSTER,
|
OT_SCR_CREATEMONSTER,
|
||||||
OT_SCR_DETECTAURA,
|
OT_SCR_DETECTAURA,
|
||||||
OT_SCR_DETECTLIFE,
|
OT_SCR_DETECTLIFE,
|
||||||
|
@ -1260,6 +1260,7 @@ enum OBTYPE {
|
||||||
OT_S_BLINKASS,
|
OT_S_BLINKASS,
|
||||||
OT_S_DISPERSAL,
|
OT_S_DISPERSAL,
|
||||||
OT_S_GATE,
|
OT_S_GATE,
|
||||||
|
OT_S_INSTANTDISROBE,
|
||||||
OT_S_PLANESHIFT,
|
OT_S_PLANESHIFT,
|
||||||
OT_S_SUCK,
|
OT_S_SUCK,
|
||||||
OT_S_TELEPORT,
|
OT_S_TELEPORT,
|
||||||
|
@ -1284,6 +1285,7 @@ enum OBTYPE {
|
||||||
OT_A_LEVELUP,
|
OT_A_LEVELUP,
|
||||||
// abilities
|
// abilities
|
||||||
OT_A_AIMEDSTRIKE,
|
OT_A_AIMEDSTRIKE,
|
||||||
|
OT_A_CHECKSTAIRS,
|
||||||
OT_A_COOK,
|
OT_A_COOK,
|
||||||
OT_A_DARKWALK,
|
OT_A_DARKWALK,
|
||||||
OT_A_DISARM,
|
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));
|
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
|
} // end if fullyeaten
|
||||||
|
|
||||||
// take time
|
// take time
|
||||||
|
@ -5673,6 +5673,130 @@ int getnightvisrange(lifeform_t *lf) {
|
||||||
return range;
|
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) {
|
char *getlfconditionname(enum LFCONDITION cond) {
|
||||||
switch (cond) {
|
switch (cond) {
|
||||||
case C_CRITICAL:
|
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 all conferred flags now known, object is known
|
||||||
if (flagsfound && (flagsknown == flagsfound)) {
|
if (flagsfound && (flagsknown == flagsfound)) {
|
||||||
|
if (isplayer(lf) || cansee(player, lf)) {
|
||||||
makeknown(o->type->id);
|
makeknown(o->type->id);
|
||||||
// in some cases, identify the object fully
|
// in some cases, identify the object fully
|
||||||
// (ie. make +xxx bonuses known too)
|
// (ie. make +xxx bonuses known too)
|
||||||
if (isplayer(lf)) {
|
|
||||||
if (hasflag(o->flags, F_IDWHENUSED)) {
|
if (hasflag(o->flags, F_IDWHENUSED)) {
|
||||||
identify(o);
|
identify(o);
|
||||||
}
|
}
|
||||||
|
@ -7633,7 +7757,6 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
||||||
makeknown(OT_MUSHROOMTOAD);
|
makeknown(OT_MUSHROOMTOAD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (id == SK_LORE_ARCANA) {
|
} else if (id == SK_LORE_ARCANA) {
|
||||||
if (f->val[1] == PR_ADEPT) {
|
if (f->val[1] == PR_ADEPT) {
|
||||||
newf = hasflagval(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL);
|
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;
|
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) {
|
} else if (id == SK_PERCEPTION) {
|
||||||
if ((f->val[1] == PR_ADEPT) || (f->val[1] == PR_MASTER)) {
|
if ((f->val[1] == PR_ADEPT) || (f->val[1] == PR_MASTER)) {
|
||||||
// our FOV gets wider
|
// our FOV gets wider
|
||||||
|
@ -7659,6 +7789,7 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
|
||||||
newf->lifetime = FROMSKILL;
|
newf->lifetime = FROMSKILL;
|
||||||
}
|
}
|
||||||
} else if (id == SK_TECHUSAGE) {
|
} else if (id == SK_TECHUSAGE) {
|
||||||
|
if (isplayer(lf)) {
|
||||||
objecttype_t *ot;
|
objecttype_t *ot;
|
||||||
// automatically make known all tech <= our skill level
|
// automatically make known all tech <= our skill level
|
||||||
for (ot = objecttype ; ot ; ot = ot->next) {
|
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) {
|
} else if (id == SK_TWOWEAPON) {
|
||||||
if (f->val[1] == PR_EXPERT) {
|
if (f->val[1] == PR_EXPERT) {
|
||||||
addflag(lf->flags, F_CANWILL, OT_A_FLURRY, 3, 3, "pw:1;");
|
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++;
|
sk->nskilldesc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addtrail(lifeform_t *lf, int dir) {
|
object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int doscents) {
|
||||||
object_t *footprint, *scent;
|
object_t *footprint, *scent,*retob = NULL;
|
||||||
flag_t *fpflag;
|
flag_t *fpflag;
|
||||||
|
|
||||||
// no tracks at all?
|
// no tracks at all?
|
||||||
if (lf->cell->type->solid) {
|
if (where->type->solid) {
|
||||||
return;
|
return NULL;
|
||||||
} else if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) {
|
} else if (hasobwithflag(where->obpile, F_DEEPWATER)) {
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// footprints first
|
// footprints first
|
||||||
|
if (doprints) {
|
||||||
if (!isairborne(lf) && !lfhasflag(lf, F_NONCORPOREAL)) {
|
if (!isairborne(lf) && !lfhasflag(lf, F_NONCORPOREAL)) {
|
||||||
int fpdir;
|
int fpdir;
|
||||||
if (getskill(lf, SK_PERCEPTION) >= PR_EXPERT) {
|
if (getskill(lf, SK_PERCEPTION) >= PR_EXPERT) {
|
||||||
// no footprints!
|
// no footprints!
|
||||||
return;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
fpdir = dir;
|
fpdir = dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
footprint = hastrailof(lf->cell->obpile, lf, OT_FOOTPRINT, &fpflag, NULL);
|
footprint = hastrailof(where->obpile, lf, OT_FOOTPRINT, &fpflag, NULL);
|
||||||
if (footprint) {
|
if (footprint) {
|
||||||
assert(fpflag);
|
assert(fpflag);
|
||||||
fpflag->lifetime = getfootprinttime(lf);
|
fpflag->lifetime = getfootprinttime(lf);
|
||||||
|
@ -9620,22 +9753,28 @@ void addtrail(lifeform_t *lf, int dir) {
|
||||||
} else {
|
} else {
|
||||||
char buf[BUFLENTINY];
|
char buf[BUFLENTINY];
|
||||||
snprintf(buf, BUFLENTINY, "%d", lf->id);
|
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));
|
addtempflag(footprint->flags, F_TRAIL, lf->race->id, fpdir, S_SIGHT, buf, getfootprinttime(lf));
|
||||||
}
|
}
|
||||||
|
retob = footprint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now smell
|
// 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) {
|
if (scent) {
|
||||||
assert(fpflag);
|
assert(fpflag);
|
||||||
fpflag->lifetime = TM_SCENT;
|
fpflag->lifetime = TM_SCENT;
|
||||||
} else {
|
} else {
|
||||||
char buf[BUFLENTINY];
|
char buf[BUFLENTINY];
|
||||||
snprintf(buf, BUFLENTINY, "%d", lf->id);
|
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);
|
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) {
|
void adjustspeedforwater(lifeform_t *lf, int *speed) {
|
||||||
|
@ -10789,96 +10928,15 @@ int makenauseated(lifeform_t *lf, int amt, int howlong) {
|
||||||
return B_FALSE;
|
return B_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void makenoise(lifeform_t *lf, enum NOISETYPE nid) {
|
void makenoise(lifeform_t *lf, enum NOISETYPE nid) {
|
||||||
flag_t *retflag[MAXCANDIDATES],*nflag[MAXCANDIDATES];
|
int volume = 1;
|
||||||
int nretflags, volume = 1, i,nnflags = 0;
|
char hear[BUFLEN], see[BUFLEN];
|
||||||
char *verb = NULL, *noun = NULL;
|
|
||||||
|
|
||||||
if (lfhasflag(lf, F_FROZEN)) {
|
if (!getnoisedetails(lf, nid, hear, see, &volume)) {
|
||||||
// can't make noise if frozen!
|
// success
|
||||||
return;
|
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) {
|
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) {
|
} else if (orig == 0) {
|
||||||
msg("You feel less exhausted now.");
|
msg("You feel less exhausted now.");
|
||||||
}
|
}
|
||||||
} else if (cansee(player, lf)) {
|
}
|
||||||
|
/*else if (cansee(player, lf)) {
|
||||||
if (getstamina(lf) == 0) {
|
if (getstamina(lf) == 0) {
|
||||||
char lfname[BUFLEN];
|
char lfname[BUFLEN];
|
||||||
getlfname(lf, lfname);
|
getlfname(lf, lfname);
|
||||||
msg("%s looks exhausted.", lfname);
|
msg("%s looks exhausted.", lfname);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getstamina(lf) == 0) {
|
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
|
// if validchars is set, we will populate it with a list of valid
|
||||||
// choice letters for asking the player how to rest.
|
// choice letters for asking the player how to rest.
|
||||||
int needstorest(lifeform_t *lf, char *validchars) {
|
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");
|
strcat(realseetext, "something");
|
||||||
}
|
}
|
||||||
msg("%s %s.", lfname, realseetext);
|
msg("%s %s.", lfname, realseetext);
|
||||||
|
if ((realseetext[0] == '\0') || !strlen(realseetext)) {
|
||||||
|
dblog("xxx");
|
||||||
|
}
|
||||||
rv = B_TRUE;
|
rv = B_TRUE;
|
||||||
}
|
}
|
||||||
} else if (text && !isdeaf(l) && ((nclass != NC_MOVEMENT) || !lfhasflag(l, F_DONELISTEN))) {
|
} 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?
|
// do stairs go somewhere? generate new maps if required.
|
||||||
newcell = getstairdestination(o);
|
newcell = getstairdestination(o, &madenewmap);
|
||||||
if (!newcell) {
|
if (newcell) {
|
||||||
|
newmap = newcell->map;
|
||||||
|
} else {
|
||||||
if (isportal) {
|
if (isportal) {
|
||||||
// unconnected portal
|
// unconnected portal
|
||||||
if (isplayer(lf)) msg("This portal doesn't seem to go anywhere.");
|
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
|
// check noone is in the way
|
||||||
if (newcell->lf) {
|
if (movelfsoutofway(newcell)) {
|
||||||
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 {
|
|
||||||
// TODO: handle this differently - ie always allow the player
|
// TODO: handle this differently - ie always allow the player
|
||||||
// go there?
|
// go there?
|
||||||
if (isplayer(lf)) msg("The stairs seem to be blocked.");
|
if (isplayer(lf)) msg("The stairs seem to be blocked.");
|
||||||
return B_TRUE;
|
return B_TRUE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// announce
|
// announce
|
||||||
if (isplayer(lf)) {
|
if (isplayer(lf)) {
|
||||||
announcearrival(lf, newcell->map);
|
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);
|
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);
|
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 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 adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype);
|
||||||
void adjustspeedforwater(lifeform_t *lf, int *speed);
|
void adjustspeedforwater(lifeform_t *lf, int *speed);
|
||||||
void age(lifeform_t *lf, int pct);
|
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 getmiscastchance(lifeform_t *lf);
|
||||||
int getmorale(lifeform_t *lf);
|
int getmorale(lifeform_t *lf);
|
||||||
int getnightvisrange(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);
|
char *getlfconditionname(enum LFCONDITION cond);
|
||||||
object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp);
|
object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp);
|
||||||
int getowing(lifeform_t *buyer, int shopid, int *retnitems);
|
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);
|
float modifybystat(float num, lifeform_t *lf, enum ATTRIB att);
|
||||||
void modmorale(lifeform_t *lf, int howmuch);
|
void modmorale(lifeform_t *lf, int howmuch);
|
||||||
void modstamina(lifeform_t *lf, float howmuch);
|
void modstamina(lifeform_t *lf, float howmuch);
|
||||||
|
int movecausesnoise(lifeform_t *lf);
|
||||||
int needstorest(lifeform_t *lf, char *validchars);
|
int needstorest(lifeform_t *lf, char *validchars);
|
||||||
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, char *text, char *seetext);
|
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nt, int volume, char *text, char *seetext);
|
||||||
enum NOISECLASS noisetypetoclass(enum NOISETYPE nt);
|
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;
|
object_t *o;
|
||||||
c = getcellat(map, x, y);
|
c = getcellat(map, x, y);
|
||||||
o = hasobwithflag(c->obpile, F_CLIMBABLE);
|
o = hasobwithflag(c->obpile, F_CLIMBABLE);
|
||||||
if (o && !getstairdestination(o)) {
|
if (o && !getstairdestination(o, NULL)) {
|
||||||
// this will join these stairs to existing ones on
|
// this will join these stairs to existing ones on
|
||||||
// existing adjacent maps
|
// existing adjacent maps
|
||||||
if (!linkstairs(o, NULL)) {
|
if (!linkstairs(o, NULL)) {
|
||||||
if (db) {
|
if (db) {
|
||||||
cell_t *dst;
|
cell_t *dst;
|
||||||
dst = getstairdestination(o);
|
dst = getstairdestination(o, NULL);
|
||||||
dblog(" linked '%s' to map %s",o->type->name, dst->map->name);
|
dblog(" linked '%s' to map %s",o->type->name, dst->map->name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -4077,7 +4077,7 @@ map_t *findsurfaceexitmap(map_t *m) {
|
||||||
for (o = c->obpile->first ; o ; o = o->next) {
|
for (o = c->obpile->first ; o ; o = o->next) {
|
||||||
if (hasflagval(o->flags, F_CLIMBABLE, D_UP, NA, NA, NULL)) {
|
if (hasflagval(o->flags, F_CLIMBABLE, D_UP, NA, NA, NULL)) {
|
||||||
cell_t *newc;
|
cell_t *newc;
|
||||||
newc = getstairdestination(o);
|
newc = getstairdestination(o, NULL);
|
||||||
if (newc) {
|
if (newc) {
|
||||||
return newc->map;
|
return newc->map;
|
||||||
}
|
}
|
||||||
|
@ -4554,7 +4554,8 @@ int getslipperyness(cell_t *c, object_t **slipob) {
|
||||||
return totalslip;
|
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;
|
flag_t *f;
|
||||||
cell_t *newcell = NULL;
|
cell_t *newcell = NULL;
|
||||||
|
|
||||||
|
@ -4585,6 +4586,55 @@ cell_t *getstairdestination(object_t *o) {
|
||||||
newcell = getcellat(newmap, newx, newy);
|
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;
|
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);
|
cell_t *getrandomroomcell(map_t *map, int roomid);
|
||||||
void getroomcells(map_t *m, int roomid, cell_t **retcell, int *ncells);
|
void getroomcells(map_t *m, int roomid, cell_t **retcell, int *ncells);
|
||||||
int getslipperyness(cell_t *c, object_t **slipob);
|
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 *hasenterableobject(cell_t *c);
|
||||||
object_t *hascloseddoor(cell_t *c);
|
object_t *hascloseddoor(cell_t *c);
|
||||||
lifeform_t *haslf(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;
|
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
|
// basically this is a warpper for 'movelf' which
|
||||||
// does other game things like telling the player
|
// does other game things like telling the player
|
||||||
// what is here.
|
// what is here.
|
||||||
|
@ -1466,7 +1482,6 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
||||||
|
|
||||||
// make some noise
|
// make some noise
|
||||||
// (stealth check to avoid this)
|
// (stealth check to avoid this)
|
||||||
if (!lfhasflag(lf, F_SILENTMOVE) && !lfhasflag(lf, F_SNEAK)) {
|
|
||||||
if (!skillcheck(lf, SC_STEALTH, 20, 0)) {
|
if (!skillcheck(lf, SC_STEALTH, 20, 0)) {
|
||||||
if (isairborne(lf)) {
|
if (isairborne(lf)) {
|
||||||
makenoise(lf, N_FLY);
|
makenoise(lf, N_FLY);
|
||||||
|
@ -1474,7 +1489,6 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) {
|
||||||
makenoise(lf, N_WALK);
|
makenoise(lf, N_WALK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// slip on blood in new cell?
|
// slip on blood in new cell?
|
||||||
if (!isairborne(lf) && !isswimming(lf)) {
|
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);
|
killflagsofid(lf->flags, F_LASTDIR);
|
||||||
addflag(lf->flags, F_LASTDIR, dir, NA, NA, NULL);
|
addflag(lf->flags, F_LASTDIR, dir, NA, NA, NULL);
|
||||||
|
|
||||||
// add footprints in our current cell.
|
// add footprints/scents in our current cell.
|
||||||
addtrail(lf, dir);
|
addtrail(lf, lf->cell, dir, B_TRUE, B_TRUE);
|
||||||
|
|
||||||
// do your pets see you move?
|
// do your pets see you move?
|
||||||
if (isplayer(lf) && (gamemode == GM_GAMESTARTED)) {
|
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 moveclear(lifeform_t *lf, int dir, enum ERROR *error);
|
||||||
int moveeffects(lifeform_t *lf);
|
int moveeffects(lifeform_t *lf);
|
||||||
int movelf(lifeform_t *lf, cell_t *newcell);
|
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 moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg);
|
||||||
int movetowards(lifeform_t *lf, cell_t *dst, int dirtype, int strafe);
|
int movetowards(lifeform_t *lf, cell_t *dst, int dirtype, int strafe);
|
||||||
int move_will_hurt(lifeform_t *lf);
|
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;
|
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) {
|
enum SKILLLEVEL gettechlevel(enum OBTYPE oid) {
|
||||||
flag_t *f;
|
flag_t *f;
|
||||||
objecttype_t *ot;
|
objecttype_t *ot;
|
||||||
|
@ -6442,6 +6451,14 @@ void makeknown(enum OBTYPE otid) {
|
||||||
flag_t *retflag[MAXCANDIDATES];
|
flag_t *retflag[MAXCANDIDATES];
|
||||||
int nretflags = 0;
|
int nretflags = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
objecttype_t *ot;
|
||||||
|
ot = findot(otid);
|
||||||
|
if (ot && (ot->obclass->id == OC_TECH)) {
|
||||||
|
dblog("xxx");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (player) {
|
if (player) {
|
||||||
// if player is holding an object of that type with F_CONFER.. IFKNOWN... and isn't known...
|
// 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.
|
// 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);
|
pit = hasobwithflagval(dst->where->obpile, F_PIT, D_DOWN, NA, NA, NULL);
|
||||||
if (pit) {
|
if (pit) {
|
||||||
cell_t *newcell;
|
cell_t *newcell;
|
||||||
newcell = getstairdestination(pit);
|
newcell = getstairdestination(pit, NULL);
|
||||||
if (newcell) {
|
if (newcell) {
|
||||||
if (haslos(player, dst->where)) {
|
if (haslos(player, dst->where)) {
|
||||||
char obname[BUFLEN];
|
char obname[BUFLEN];
|
||||||
|
@ -7092,7 +7109,7 @@ int obsfallthrough(cell_t *c, object_t *pit) {
|
||||||
char obname[BUFLEN],downholename[BUFLEN],upholename[BUFLEN];
|
char obname[BUFLEN],downholename[BUFLEN],upholename[BUFLEN];
|
||||||
int nfallen = 0;
|
int nfallen = 0;
|
||||||
|
|
||||||
belowcell = getstairdestination(pit);
|
belowcell = getstairdestination(pit, NULL);
|
||||||
if (!belowcell) return 0;
|
if (!belowcell) return 0;
|
||||||
|
|
||||||
uphole = hasobwithflagval(belowcell->obpile, F_PIT, D_UP, NA, NA, NULL);
|
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;
|
break;
|
||||||
|
case OT_POT_CANINETRACKING:
|
||||||
|
dospelleffects(lf, OT_S_CANINETRACKING, 5, lf, NULL, lf->cell, potblessed, seen, B_TRUE);
|
||||||
|
break;
|
||||||
case OT_POT_COFFEE:
|
case OT_POT_COFFEE:
|
||||||
if (isplayer(lf)) {
|
if (isplayer(lf)) {
|
||||||
msg("This tastes like coffee.");
|
msg("This tastes like coffee.");
|
||||||
|
|
|
@ -130,6 +130,7 @@ char *getschoolname(enum SPELLSCHOOL sch);
|
||||||
char *getschoolnameshort(enum SPELLSCHOOL sch);
|
char *getschoolnameshort(enum SPELLSCHOOL sch);
|
||||||
int getshatterdam(object_t *o);
|
int getshatterdam(object_t *o);
|
||||||
float getshopprice(object_t *o, lifeform_t *buyer);
|
float getshopprice(object_t *o, lifeform_t *buyer);
|
||||||
|
int getstairdirection(object_t *o);
|
||||||
enum SKILLLEVEL gettechlevel(enum OBTYPE oid);
|
enum SKILLLEVEL gettechlevel(enum OBTYPE oid);
|
||||||
int getthrowdam(object_t *o);
|
int getthrowdam(object_t *o);
|
||||||
char *gettopobname(cell_t *c, char *retbuf);
|
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 knowledge_t *knowledge;
|
||||||
|
|
||||||
extern int needredraw;
|
extern int needredraw;
|
||||||
|
extern int noredraw;
|
||||||
|
|
||||||
extern prompt_t prompt;
|
extern prompt_t prompt;
|
||||||
|
|
||||||
|
@ -215,6 +216,344 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
|
||||||
// attack
|
// attack
|
||||||
attackcell(user, targcell, B_TRUE);
|
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) {
|
} else if (abilid == OT_A_COOK) {
|
||||||
object_t *water,*o;
|
object_t *water,*o;
|
||||||
race_t *r = NULL;
|
race_t *r = NULL;
|
||||||
|
@ -5975,6 +6314,63 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
||||||
} else {
|
} else {
|
||||||
// monsters can't cast
|
// 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) {
|
} else if (spellid == OT_S_INVISIBILITY) {
|
||||||
int howlong = 30;
|
int howlong = 30;
|
||||||
int willannounce = B_FALSE;
|
int willannounce = B_FALSE;
|
||||||
|
|
Loading…
Reference in New Issue