added bazaar vault.

- [+] remove damage from jumping onto other lfs
- [+] when you jump in water or something lands in water: "you hear a
      splash"
- [+] tweaks to how evasion works.
- [+] The book crumbles to dust.  Your manual is no longer glowing.
      FIXED.
- [+] fix msghistbuf for askchar - not showing your choice.
- [+] in shops, show prices in red if you can't afford them.
- [+] retaliate should only work if you're still adjecent
- [+] show Ravenous in RED
- [+] no xp for rapid ivy clones
- [+] make weapon of impact only knockback 33% of the time (instead of
      always)
- [+] don't set F_NOSCORE when quitting.
- [+] some scrolls cost $1??
- [+] You see a masterwork shoddy club here.
    - [+] shouhldn't be able to have both!!!
- [+] change bleeding code.  lowhp doesn't mean bleeding.
    - [+] also change flee on bleed etc
This commit is contained in:
Rob Pearce 2011-12-09 00:37:02 +00:00
parent 089ce94751
commit 0f99007c2a
15 changed files with 275 additions and 107 deletions

2
ai.c
View File

@ -848,7 +848,7 @@ int ai_healing(lifeform_t *lf) {
if (!lfhasflag(lf, F_RAGE)) { if (!lfhasflag(lf, F_RAGE)) {
// feigning death with enemies in sight, and hurt? // feigning death with enemies in sight, and hurt?
if (lfhasflag(lf, F_FEIGNINGDEATH) && !safetorest(lf)) { if (lfhasflag(lf, F_FEIGNINGDEATH) && !safetorest(lf)) {
if (isbleeding(lf)) { if (islowhp(lf)) {
if (db) dblog(".oO { i am feigning death and bleeding (hp=%d/%d), skipping turn. }",lf->hp,lf->maxhp); if (db) dblog(".oO { i am feigning death and bleeding (hp=%d/%d), skipping turn. }",lf->hp,lf->maxhp);
// just wait... // just wait...
rest(lf, B_TRUE); rest(lf, B_TRUE);

View File

@ -920,7 +920,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (lfhasflag(victim, F_FEIGNINGDEATH)) { if (lfhasflag(victim, F_FEIGNINGDEATH)) {
killflagsofid(victim->flags, F_FEIGNINGDEATH); killflagsofid(victim->flags, F_FEIGNINGDEATH);
} else if (!fatal && !isplayer(victim) && cancast(victim, OT_A_FEIGNDEATH, NULL)) { } else if (!fatal && !isplayer(victim) && cancast(victim, OT_A_FEIGNDEATH, NULL)) {
if (onein(2) || isbleeding(victim)) { if (onein(2) || islowhp(victim)) {
// do it! // do it!
useability(victim, OT_A_FEIGNDEATH, lf, lf->cell); useability(victim, OT_A_FEIGNDEATH, lf, lf->cell);
feigneddeath = B_TRUE; feigneddeath = B_TRUE;
@ -1036,7 +1036,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
f = lfhasflag(lf, F_QUICKBITE); f = lfhasflag(lf, F_QUICKBITE);
if (f) { if (f) {
if (isbleeding(victim)) { if (islowhp(victim)) {
int dam; int dam;
char lfname[BUFLEN]; char lfname[BUFLEN];
dam = rolldie(f->val[0], f->val[1]) + f->val[2]; dam = rolldie(f->val[0], f->val[1]) + f->val[2];
@ -1126,7 +1126,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
getflags(victim->flags, retflag, &nretflags, F_RETALIATE, F_NONE); getflags(victim->flags, retflag, &nretflags, F_RETALIATE, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (f->id == F_RETALIATE) { if ((f->id == F_RETALIATE) && (getcelldist(victim->cell, lf->cell) == 1)) {
int rdam; int rdam;
char damstring[BUFLEN]; char damstring[BUFLEN];
rdam = rolldie(f->val[0], f->val[1]); rdam = rolldie(f->val[0], f->val[1]);
@ -2170,10 +2170,18 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
} }
} else if ((f->id == F_HEAVYBLOW) && victim && owner) { } else if ((f->id == F_HEAVYBLOW) && victim && owner) {
int dir; int dir;
// knock back victim int chance;
dir = getdirtowards(owner->cell, victim->cell, victim, B_FALSE, DT_COMPASS); // lifeform flag works all the time. object flag only works sometimes.
knockback(victim, dir , 2, owner, 30, B_TRUE); if (wep) chance = 33;
f->known = B_TRUE; else chance = 100;
if (pctchance(chance)) {
// knock back victim
dir = getdirtowards(owner->cell, victim->cell, victim, B_FALSE, DT_COMPASS);
knockback(victim, dir , 2, owner, 30, B_TRUE);
if (cansee(player, owner)) {
f->known = B_TRUE;
}
}
} else if ((f->id == F_HITCONFER) && victim ) { } else if ((f->id == F_HITCONFER) && victim ) {
// only works if we did damage // only works if we did damage
enum FLAG fid; enum FLAG fid;
@ -2265,7 +2273,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
if (wep && owner && victim) { if (wep && owner && victim) {
enum DRAINTYPE draintype = DR_NONE; enum DRAINTYPE draintype = DR_NONE;
if ((wep->type->id == OT_TEETH) && lfhasflag(owner, F_VAMPIRIC) && isbleeding(victim)) { if ((wep->type->id == OT_TEETH) && lfhasflag(owner, F_VAMPIRIC) && islowhp(victim)) {
draintype = DR_FROMBITE; draintype = DR_FROMBITE;
} else if (hasflag(wep->flags, F_VAMPIRIC)) { } else if (hasflag(wep->flags, F_VAMPIRIC)) {
draintype = DR_FROMWEP; draintype = DR_FROMWEP;

20
data.c
View File

@ -2141,7 +2141,7 @@ void initobjects(void) {
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "splash of cockatrice blood"); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "splash of cockatrice blood");
addflag(lastot->flags, F_VALUE, 35, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 35, NA, NA, NULL);
addot(OT_POT_COMPETENCE, "potion of competence", "Permemantly increases the drinker's strength, intelligence or dexterity.", MT_GLASS, 1, OC_POTION, SZ_TINY); addot(OT_POT_COMPETENCE, "potion of competence", "Permemantly increases the drinker's base attribites (Strength, IQ, etc).", MT_GLASS, 1, OC_POTION, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, NA, NULL);
addflag(lastot->flags, F_VALUE, 160, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 160, NA, NA, NULL);
@ -2185,9 +2185,11 @@ void initobjects(void) {
// scrolls // scrolls
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_VALUE, 50, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, 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_VALUE, 50, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_FREQUENT, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_FREQUENT, NULL);
addot(OT_SCR_IDENTIFY, "scroll of identify", "Completely identifies any one item.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addot(OT_SCR_IDENTIFY, "scroll of identify", "Completely identifies any one item.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
@ -2200,10 +2202,12 @@ void initobjects(void) {
addflag(lastot->flags, F_MAXPOWER, 4, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 4, NA, NA, NULL);
addot(OT_SCR_NOTHING, "scroll of nothing", "Looks like a magic scroll, but doesn't do anything.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addot(OT_SCR_NOTHING, "scroll of nothing", "Looks like a magic scroll, but doesn't do anything.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
addflag(lastot->flags, F_VALUE, 2, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 84, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 84, RR_UNCOMMON, NULL);
addot(OT_GRAPHPAPER, "magic map", "Paper containing a set of grid-lines, which automatically draws a map of its surroundings.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addot(OT_GRAPHPAPER, "magic map", "Paper containing a set of grid-lines, which automatically draws a map of its surroundings.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
addflag(lastot->flags, F_HOLDCONFER, F_PHOTOMEM, NA, IFKNOWN, NULL); addflag(lastot->flags, F_HOLDCONFER, F_PHOTOMEM, NA, IFKNOWN, NULL);
addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
addot(OT_MAP, "map", "A visual representation of the area.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addot(OT_MAP, "map", "A visual representation of the area.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
@ -2267,6 +2271,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, NULL);
addot(OT_SCR_PERMENANCE, "scroll of permenance", "Makes all effects on an object last forever.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addot(OT_SCR_PERMENANCE, "scroll of permenance", "Makes all effects on an object last forever.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
addflag(lastot->flags, F_VALUE, 400, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 50, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 50, RR_RARE, NULL);
addot(OT_SCR_TELEPORT, "scroll of teleportation", "Causes the caster to teleport to a random location within the same level.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addot(OT_SCR_TELEPORT, "scroll of teleportation", "Causes the caster to teleport to a random location within the same level.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
@ -2280,6 +2285,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ALL, 70, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 70, RR_UNCOMMON, NULL);
addot(OT_SCR_WISH, "scroll of wishing", "Grants the caster any item of their choice (with some limitations).", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addot(OT_SCR_WISH, "scroll of wishing", "Grants the caster any item of their choice (with some limitations).", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_VERYRARE, NULL);
addflag(lastot->flags, F_LINKSPELL, OT_S_WISHLIMITED, NA, NA, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_WISHLIMITED, NA, NA, NULL);
@ -3653,6 +3659,9 @@ void initobjects(void) {
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
addflag(lastot->flags, F_STAMCOST, 2, NA, NA, NULL); addflag(lastot->flags, F_STAMCOST, 2, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
addot(OT_A_SNATCH, "snatch", "Quickly grab a single item from an adjacent cell.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
addot(OT_A_SONICBOLT, "sonic bolt", "Emit a damaging burst of sound, targetted at a particular location.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addot(OT_A_SONICBOLT, "sonic bolt", "Emit a damaging burst of sound, targetted at a particular location.", 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);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
@ -4417,7 +4426,7 @@ void initobjects(void) {
addot(OT_ACIDSPLASH, "splash of acid", "A splash corrosive acid.", MT_ACID, 0, OC_MISC, SZ_SMALL); addot(OT_ACIDSPLASH, "splash of acid", "A splash corrosive acid.", MT_ACID, 0, OC_MISC, SZ_SMALL);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, NA, NA, NA, ","); addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates"); addflag(lastot->flags, F_OBDIETEXT, NA, NA, NA, "evaporates");
addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL);
@ -5478,7 +5487,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_CON, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_CON, 1, NULL); // '1' is randomized during generation
addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL);
addot(OT_RING_DEX, "ring of dexterity", "Increases the wearer's dexterity.", MT_METAL, 0.1, OC_RING, SZ_MINI); addot(OT_RING_DEX, "ring of agility", "Increases the wearer's agility.", MT_METAL, 0.1, OC_RING, SZ_MINI);
addflag(lastot->flags, F_RARITY, H_ALL, 70, RR_UNCOMMON, ""); addflag(lastot->flags, F_RARITY, H_ALL, 70, RR_UNCOMMON, "");
addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_AGI, 1, NULL); // '1' is randomized during generation addflag(lastot->flags, F_EQUIPCONFER, F_ATTRMOD, A_AGI, 1, NULL); // '1' is randomized during generation
addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL);
@ -6549,7 +6558,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good armour");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "armour"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "armour");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "dungeon exit orb"); //addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "dungeon exit orb");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "concealing powder"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "concealing powder");
addflag(lastrace->flags, F_FLEEONHPPCT, 40, NA, NA, NULL); addflag(lastrace->flags, F_FLEEONHPPCT, 40, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_POLEARMS, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_POLEARMS, PR_ADEPT, NA, NULL);
@ -8672,7 +8681,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d6;"); addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d6;");
addflag(lastrace->flags, F_CRITKNOCKDOWN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CRITKNOCKDOWN, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_BLEEDABIL, OT_A_RAGE, NA, NA, NULL); addflag(lastrace->flags, F_LOWHPABIL, OT_A_RAGE, NA, NA, NULL);
addflag(lastrace->flags, F_MINIONS, 25, 1, 2, "bear cub"); addflag(lastrace->flags, F_MINIONS, 25, 1, 2, "bear cub");
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
@ -10471,6 +10480,7 @@ void initskills(void) {
addskilldesc(SK_EVASION, PR_NOVICE, "^gIncreases your EV by 12%.^n", B_FALSE); addskilldesc(SK_EVASION, PR_NOVICE, "^gIncreases your EV by 12%.^n", B_FALSE);
addskilldesc(SK_EVASION, PR_BEGINNER, "^gIncreases your EV by 24%.^n", B_FALSE); addskilldesc(SK_EVASION, PR_BEGINNER, "^gIncreases your EV by 24%.^n", B_FALSE);
addskilldesc(SK_EVASION, PR_ADEPT, "^gIncreases your EV by 36%.^n", B_FALSE); addskilldesc(SK_EVASION, PR_ADEPT, "^gIncreases your EV by 36%.^n", B_FALSE);
addskilldesc(SK_EVASION, PR_ADEPT, "^gYou gain the 'snatch' ability.^n", B_FALSE);
addskilldesc(SK_EVASION, PR_SKILLED, "^gIncreases your EV by 48%.^n", B_FALSE); addskilldesc(SK_EVASION, PR_SKILLED, "^gIncreases your EV by 48%.^n", B_FALSE);
addskilldesc(SK_EVASION, PR_EXPERT, "^gIncreases your EV by 60%.^n", B_FALSE); addskilldesc(SK_EVASION, PR_EXPERT, "^gIncreases your EV by 60%.^n", B_FALSE);
addskilldesc(SK_EVASION, PR_MASTER, "^gIncreases your EV by 72%.^n", B_FALSE); addskilldesc(SK_EVASION, PR_MASTER, "^gIncreases your EV by 72%.^n", B_FALSE);

Binary file not shown.

3
defs.h
View File

@ -1437,6 +1437,7 @@ enum OBTYPE {
OT_A_REPAIR, OT_A_REPAIR,
OT_A_RESIZE, OT_A_RESIZE,
OT_A_SHIELDBASH, OT_A_SHIELDBASH,
OT_A_SNATCH,
OT_A_SONICBOLT, OT_A_SONICBOLT,
OT_A_SPRINT, OT_A_SPRINT,
OT_A_STUDYSCROLL, OT_A_STUDYSCROLL,
@ -2668,7 +2669,7 @@ enum FLAG {
F_CANCAST, // can cast the spell val0 (need MP) F_CANCAST, // can cast the spell val0 (need MP)
F_CANHEARLF, // you can hear lifeform id v0 (show their glyph) F_CANHEARLF, // you can hear lifeform id v0 (show their glyph)
// this flag does not get announced. // this flag does not get announced.
F_BLEEDABIL, // will automatically use the ability v0 when F_LOWHPABIL, // will automatically use the ability v0 when
// this lf starts bleeding. // this lf starts bleeding.
F_BREATHWATER, // can breath normally underwater F_BREATHWATER, // can breath normally underwater
F_CANWILL, // can cast the spell/ability val0 without using MP F_CANWILL, // can cast the spell/ability val0 without using MP

4
god.c
View File

@ -892,7 +892,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
if (isinbattle(lf)) { if (isinbattle(lf)) {
lifeform_t *l; lifeform_t *l;
int donesomething = B_FALSE; int donesomething = B_FALSE;
if (isbleeding(lf)) { if (islowhp(lf)) {
// teleport away // teleport away
msg("\"Nothing like a quick getaway!\""); msg("\"Nothing like a quick getaway!\"");
dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE); dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
@ -953,7 +953,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
castspell(god, OT_S_SATEHUNGER, player, NULL, player->cell, NULL, NULL); castspell(god, OT_S_SATEHUNGER, player, NULL, player->cell, NULL, NULL);
donesomething = B_TRUE; donesomething = B_TRUE;
} }
if (isbleeding(lf) || !donesomething) { if (islowhp(lf) || !donesomething) {
msg("\"Let thy wounds be healed.\""); msg("\"Let thy wounds be healed.\"");
castspell(god, OT_S_HEALINGMAJ, player, NULL, player->cell, NULL, NULL); castspell(god, OT_S_HEALINGMAJ, player, NULL, player->cell, NULL, NULL);
donesomething = B_TRUE; donesomething = B_TRUE;

31
io.c
View File

@ -522,7 +522,7 @@ char askchar(char *prompt, char *validchars, char *def, int showchars, int mayca
curs_set(0); curs_set(0);
// update messaage history // update messaage history
sprintf(msghistbuf, "%s%c", buf, (ch == '\0') ? '-' : '\0'); sprintf(msghistbuf, "%s%c", buf, (ch == '\0') ? '-' : ch);
addmsghist(msghistbuf); addmsghist(msghistbuf);
clearmsg(); clearmsg();
@ -3844,7 +3844,7 @@ void docomms(lifeform_t *lf) {
int mod = 0; int mod = 0;
int covets = B_FALSE; int covets = B_FALSE;
// healing object and they were bleeding? // healing object and they were bleeding?
if (isbleeding(lf) && hasflag(givenob->flags, F_AIHEALITEM)) { if ((islowhp(lf) || isbleeding(lf)) && hasflag(givenob->flags, F_AIHEALITEM)) {
if (aiobok(lf, givenob, lf)) { if (aiobok(lf, givenob, lf)) {
mod += 3; mod += 3;
} }
@ -5012,8 +5012,12 @@ char *makedesc_ob(object_t *o, char *retbuf) {
if (f) { if (f) {
int critprotchance; int critprotchance;
critprotchance = getcritprotection(o); critprotchance = getcritprotection(o);
snprintf(buf, BUFLEN, "It has a %d%% chance of preventing critical hits to your %s", if (critprotchance == 0) {
critprotchance, getbodypartname(player, f->val[0])); snprintf(buf, BUFLEN, "It will not protect your %s from critical hits", getbodypartname(player, f->val[0]));
} else {
snprintf(buf, BUFLEN, "It has a %d%% chance of preventing critical hits to your %s",
critprotchance, getbodypartname(player, f->val[0]));
}
if (compareob) { if (compareob) {
int diff,comparechance = 0; int diff,comparechance = 0;
@ -5696,10 +5700,10 @@ char *makedesc_ob(object_t *o, char *retbuf) {
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
if (usable && isweapon(o)) { if (usable && isweapon(o)) {
if (pctmod > 0) { if (pctmod > 0) {
sprintf(buf, "^%dYour high %s will increase your effectiveness with this weapon.^n", C_GREEN, getattrname(f->val[0])); sprintf(buf, "^%dYour high %s will increase your effectiveness with this weapon.^n\n", C_GREEN, getattrname(f->val[0]));
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
} else if (pctmod < 0) { } else if (pctmod < 0) {
sprintf(buf, "^%dYour low %s will decrease your effectiveness with this weapon.^n", C_BROWN, getattrname(f->val[0])); sprintf(buf, "^%dYour low %s will decrease your effectiveness with this weapon.^n\n", C_BROWN, getattrname(f->val[0]));
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
} }
} }
@ -7003,7 +7007,6 @@ void doquit(void) {
char ch; char ch;
ch = askchar("Really quit", "yn","n", B_TRUE, B_FALSE); ch = askchar("Really quit", "yn","n", B_TRUE, B_FALSE);
if (ch == 'y') { if (ch == 'y') {
addflag(player->flags, F_NOSCORE, B_TRUE, NA, NA, NULL);
setlastdam(player, "quitting"); setlastdam(player, "quitting");
player->alive = B_FALSE; player->alive = B_FALSE;
} }
@ -9214,18 +9217,16 @@ void drawstatus(void) {
if (hlev == H_NONE) { if (hlev == H_NONE) {
strcpy(buf2, ""); strcpy(buf2, "");
} else { } else {
gethungername(player, gethungerlevel(f->val[0]), buf2); gethungername(player, hlev, buf2);
capitalise(buf2); capitalise(buf2);
} }
} else { if (hlev == H_STARVING) setcol(statwin, C_RED);
strcpy(buf2, ""); else setcol(statwin, C_BROWN);
wprintw(statwin, " %s", buf2);
if (hlev == H_STARVING) unsetcol(statwin, C_RED);
else unsetcol(statwin, C_BROWN);
} }
if (strlen(buf2) > 0) {
setcol(statwin, C_BROWN);
wprintw(statwin, " %s", buf2);
unsetcol(statwin, C_BROWN);
}
// good effects // good effects
f = lfhasflag(player, F_HIDING); f = lfhasflag(player, F_HIDING);

110
lf.c
View File

@ -1124,7 +1124,9 @@ int cansee_real(lifeform_t *viewer, lifeform_t *viewee, int uselos) {
} }
// viewee underwater and more than 1 cell away? // viewee underwater and more than 1 cell away?
if ((getobdepth(o, viewee) >= DP_HEAD) && (dist > 1)) { if ((getobdepth(o, viewee) >= DP_HEAD) && (dist > 1)) {
return B_FALSE; if (!isairborne(viewee)) {
return B_FALSE;
}
} }
} }
@ -3361,13 +3363,13 @@ int eat(lifeform_t *lf, object_t *o) {
// end of turn effects // end of turn effects
void endlfturn(lifeform_t *lf) { void endlfturn(lifeform_t *lf) {
// lf will complain if in pain // lf will complain if in pain
if (isbleeding(lf) && onein(3) && !hasflag(lf->flags, F_ASLEEP)) { if (islowhp(lf) && onein(3) && !hasflag(lf->flags, F_ASLEEP)) {
// TODO: replace 4 // TODO: replace 4
if (ispetof(lf, player)) { if (ispetof(lf, player)) {
if (!canhear(player, lf->cell, 4)) { if (!canhear(player, lf->cell, 4)) {
char realname[BUFLEN]; char realname[BUFLEN];
real_getlfname(lf, realname, B_FALSE); real_getlfname(lf, realname, B_FALSE);
warn("You feel worried about your %s.", noprefix(realname)); warn("You feel worried about %s%s.", lfhasflag(lf, F_NAME) ? "" : "your ", noprefix(realname));
} else if (cantalk(lf)) { } else if (cantalk(lf)) {
sayphrase(lf, SP_ALLY_INPAIN, SV_SHOUT, NA, NULL); sayphrase(lf, SP_ALLY_INPAIN, SV_SHOUT, NA, NULL);
} else { } else {
@ -3769,7 +3771,7 @@ void enhanceskills(lifeform_t *lf) {
killflagsofid(lf->flags, F_HASNEWLEVEL); killflagsofid(lf->flags, F_HASNEWLEVEL);
// ready for another level? // ready for another level?
if (lf->xp >= getxpforlev(lf->level + 1)) { if (lf->xp >= getxpforlev(lf->level + 1)) {
gainlevel(lf); // this will increment 'newlevel' gainlevel(lf, B_FALSE); // this will increment 'newlevel'
} }
killwarningtext(TEXT_WARN_ATTACK_NOXP); killwarningtext(TEXT_WARN_ATTACK_NOXP);
@ -4343,7 +4345,7 @@ void gainhp(lifeform_t *lf, int amt) {
} }
} }
void gainlevel(lifeform_t *lf) { void gainlevel(lifeform_t *lf, int autotrain) {
flag_t *f; flag_t *f;
race_t *mybaserace; race_t *mybaserace;
//int skillready = B_FALSE; //int skillready = B_FALSE;
@ -4379,8 +4381,10 @@ void gainlevel(lifeform_t *lf) {
} }
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^GYou are ready to train a new experience level!"); if (!autotrain) {
more(); msg("^GYou are ready to train a new experience level!");
more();
}
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
//getlfname(lf, buf); //getlfname(lf, buf);
//msg("%s looks more confident!",buf); //msg("%s looks more confident!",buf);
@ -4407,6 +4411,10 @@ void gainlevel(lifeform_t *lf) {
statdirty = B_TRUE; statdirty = B_TRUE;
drawscreen(); drawscreen();
} }
if (autotrain) {
enhanceskills(lf);
}
} }
@ -4485,7 +4493,7 @@ void gainxp(lifeform_t *lf, long amt) {
if (doxp) { if (doxp) {
// ready for next level? can only go up ONE level. // ready for next level? can only go up ONE level.
if (lf->xp >= getxpforlev(lf->level + 1)) { if (lf->xp >= getxpforlev(lf->level + 1)) {
gainlevel(lf); // this will increment 'newlevel' gainlevel(lf, B_FALSE); // this will increment 'newlevel'
} }
} }
if (newskillpoints) { if (newskillpoints) {
@ -5294,17 +5302,14 @@ int getevasion(lifeform_t *lf) {
return 0; return 0;
} }
//////////////////////////////////////////////////
// positive modifiers first
//////////////////////////////////////////////////
// get natural evasion, adjustments for bulky armour/shield // get natural evasion, adjustments for bulky armour/shield
getflags(lf->flags, retflag, &nretflags, F_ARMOURPENALTY, F_EVASION, F_SHIELDPENALTY, F_NONE); getflags(lf->flags, retflag, &nretflags, F_EVASION, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; ev += (retflag[i]->val[0]);
if (f->id == F_ARMOURPENALTY) {
ev -= adjustarmourpenalty(lf, f->val[1]);
} else if (f->id == F_EVASION) {
ev += (f->val[0]);
} else if (f->id == F_SHIELDPENALTY) {
ev -= adjustshieldpenalty(lf, f->val[1]);
}
} }
// level based evasion // level based evasion
@ -5315,9 +5320,25 @@ int getevasion(lifeform_t *lf) {
ev += getattr(lf, A_AGI); ev += getattr(lf, A_AGI);
// apply skill based evasion modifier // apply skill based evasion modifier
skillpctmod = 100 + (getskill(lf, SK_EVASION)) * 12; skillpctmod = 100 + (getskill(lf, SK_EVASION) * 12);
ev = pctof(skillpctmod, ev); ev = pctof(skillpctmod, ev);
//////////////////////////////////////////////////
// now negative modifiers
//////////////////////////////////////////////////
// get adjustments for bulky armour/shield
getflags(lf->flags, retflag, &nretflags, F_ARMOURPENALTY, F_SHIELDPENALTY, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (f->id == F_ARMOURPENALTY) {
ev -= adjustarmourpenalty(lf, f->val[1]);
} else if (f->id == F_SHIELDPENALTY) {
ev -= adjustshieldpenalty(lf, f->val[1]);
}
}
// you are easier to hit if you're glowing // you are easier to hit if you're glowing
if (hasflag(lf->flags, F_PRODUCESLIGHT)) { if (hasflag(lf->flags, F_PRODUCESLIGHT)) {
ev -= 5; ev -= 5;
@ -8399,6 +8420,13 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) {
makeknown(OT_MUSHROOMTOAD); makeknown(OT_MUSHROOMTOAD);
} }
} }
} else if (id == SK_EVASION) {
if (f->val[1] == PR_ADEPT) {
if (isplayer(lf)) {
newf = addflag(lf->flags, F_CANWILL, OT_A_SNATCH, NA, NA, NULL);
newf->lifetime = FROMSKILL;
}
}
} 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);
@ -8788,6 +8816,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
// SPECIAL CASES // SPECIAL CASES
if (lf) { if (lf) {
/*
if (lf->race->id == R_JAILER) { if (lf->race->id == R_JAILER) {
regionoutline_t *ro; regionoutline_t *ro;
region_t *r; region_t *r;
@ -8808,6 +8837,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
} }
addflag(o->flags, F_MAPTO, rt->x, rt->y, OT_GATEWOOD, "a village"); addflag(o->flags, F_MAPTO, rt->x, rt->y, OT_GATEWOOD, "a village");
} }
*/
// make sure lf doesn't start off burdened! // make sure lf doesn't start off burdened!
while (isburdened(lf)) { while (isburdened(lf)) {
@ -9901,19 +9931,15 @@ int isbehind(lifeform_t *lf, lifeform_t *otherlf) {
return B_FALSE; return B_FALSE;
} }
// returns B_FALSE, B_TRUE, or B_FROMINJURY
int isbleeding(lifeform_t *lf) { int isbleeding(lifeform_t *lf) {
float hppct;
hppct = ((float)lf->hp / (float) lf->maxhp) * 100;
if (hppct <= 40) return B_TRUE;
if (lfhasflagval(lf, F_INJURY, NA, NA, DT_SLASH, NULL)) { if (lfhasflagval(lf, F_INJURY, NA, NA, DT_SLASH, NULL)) {
return B_FROMINJURY; //return B_FROMINJURY;
return B_TRUE;
} }
return B_FALSE; return B_FALSE;
} }
int isblind(lifeform_t *lf) { int isblind(lifeform_t *lf) {
flag_t *f; flag_t *f;
if (!lf) return B_FALSE; if (!lf) return B_FALSE;
@ -10241,6 +10267,14 @@ int isloreskill(enum SKILL skid) {
return B_FALSE; return B_FALSE;
} }
int islowhp(lifeform_t *lf) {
float hppct;
hppct = ((float)lf->hp / (float) lf->maxhp) * 100;
if (hppct <= 40) return B_TRUE;
return B_FALSE;
}
int isspellskill(enum SKILL skid) { int isspellskill(enum SKILL skid) {
switch (skid) { switch (skid) {
case SK_SS_ALLOMANCY: case SK_SS_ALLOMANCY:
@ -11638,11 +11672,13 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
char buf[BUFLEN]; char buf[BUFLEN];
char buf2[BUFLEN]; char buf2[BUFLEN];
char lfname[BUFLEN]; char lfname[BUFLEN];
int prebleed = B_FALSE,postbleed = B_FALSE,ko = B_FALSE; int prelowhp = B_FALSE,postlowhp = B_FALSE,ko = B_FALSE;
flag_t *f; flag_t *f;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags; int nretflags;
if (gamemode < GM_GAMESTARTED) return 0;
getlfname(lf, lfname); getlfname(lf, lfname);
if (isplayer(lf)) { if (isplayer(lf)) {
@ -11650,7 +11686,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
} }
if (isbleeding(lf)) { if (isbleeding(lf)) {
prebleed = B_TRUE; prelowhp = B_TRUE;
} }
// check for psychic armour etc // check for psychic armour etc
@ -11849,7 +11885,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
} }
if (isbleeding(lf)) { if (isbleeding(lf)) {
postbleed = B_TRUE; postlowhp = B_TRUE;
} }
////////////////////////////////////////// //////////////////////////////////////////
@ -11954,8 +11990,8 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
} }
// automatic onbleed abilities? // automatic onbleed abilities?
if (postbleed && !prebleed) { if (postlowhp && !prelowhp) {
f = lfhasflag(lf, F_BLEEDABIL); f = lfhasflag(lf, F_LOWHPABIL);
if (f) { if (f) {
flag_t *notime; flag_t *notime;
notime = addflag(lf->flags, F_NOTIME, B_TRUE, NA, NA, NULL); notime = addflag(lf->flags, F_NOTIME, B_TRUE, NA, NA, NULL);
@ -12576,6 +12612,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
// announce? // announce?
if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) { if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) {
// never say "you hear xxx" if you can see the lf that caused the noise. // never say "you hear xxx" if you can see the lf that caused the noise.
// or the cell which made the noise
if (noisemaker && cansee(l, noisemaker)) { if (noisemaker && cansee(l, noisemaker)) {
if (seetext) { if (seetext) {
char lfname[BUFLEN]; char lfname[BUFLEN];
@ -12599,6 +12636,11 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
} }
rv = B_TRUE; rv = B_TRUE;
} }
} else if (!noisemaker && haslos(player, c)) {
// you can see the cell which made the noise
if (seetext) {
msg("%s", seetext);
}
} else if (text && !isdeaf(l) && ((nclass != NC_MOVEMENT) || !lfhasflag(l, F_DONELISTEN))) { } else if (text && !isdeaf(l) && ((nclass != NC_MOVEMENT) || !lfhasflag(l, F_DONELISTEN))) {
// this means you can only hear one 'walk' sound per turn // this means you can only hear one 'walk' sound per turn
char textnopunc[BUFLEN]; char textnopunc[BUFLEN];
@ -12674,7 +12716,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
practice(l, SK_LISTEN, 1); practice(l, SK_LISTEN, 1);
} }
} }
} // end if !isplayer and not asleep } // end if isplayer and not asleep
// wake up a little // wake up a little
f = lfhasflag(l, F_ASLEEP); f = lfhasflag(l, F_ASLEEP);
@ -13918,7 +13960,7 @@ int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus) {
} }
// determine morale check penalty // determine morale check penalty
if (isbleeding(lf)) { if (isbleeding(lf) || islowhp(lf)) {
penalty += 5; penalty += 5;
} }
if (lfhasflag(lf, F_HUMANOID)) { if (lfhasflag(lf, F_HUMANOID)) {
@ -16725,7 +16767,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
getobname(o, obname, 1); getobname(o, obname, 1);
obcell = getoblocation(o); obcell = getoblocation(o);
if (initiatemove(lf, NULL, NULL)) { if (initiatemove(lf, NULL, onpurpose, NULL)) {
// failed? // failed?
return B_FALSE; return B_FALSE;
} }
@ -16908,7 +16950,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
cell_t *c; cell_t *c;
c = getrandomadjcell(newcell, WE_WALKABLE, B_ALLOWEXPAND); c = getrandomadjcell(newcell, WE_WALKABLE, B_ALLOWEXPAND);
if (c) { if (c) {
if (!initiatemove(adjally[n], NULL, NULL)) { if (!initiatemove(adjally[n], NULL, B_TRUE, NULL)) {
int climbtime; int climbtime;
stopsprinting(adjally[n]); stopsprinting(adjally[n]);
movelf(adjally[n], c); movelf(adjally[n], c);

3
lf.h
View File

@ -107,7 +107,7 @@ void fleefrom(lifeform_t *lf, lifeform_t *enemy, int howlong, int onpurpose);
int fovlist_contains(int *endx, int *endy, int nendcells, int x, int y); int fovlist_contains(int *endx, int *endy, int nendcells, int x, int y);
int freezelf(lifeform_t *freezee, lifeform_t *freezer, int howlong); int freezelf(lifeform_t *freezee, lifeform_t *freezer, int howlong);
void gainhp(lifeform_t *lf, int amt); void gainhp(lifeform_t *lf, int amt);
void gainlevel(lifeform_t *lf); void gainlevel(lifeform_t *lf, int autotrain);
void gainmp(lifeform_t *lf, int amt); void gainmp(lifeform_t *lf, int amt);
void gainxp(lifeform_t *lf, long amt); void gainxp(lifeform_t *lf, long amt);
void genxplist(void); void genxplist(void);
@ -292,6 +292,7 @@ flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt, int onlytemp);
int isinbattle(lifeform_t *lf); int isinbattle(lifeform_t *lf);
int isingunrange(lifeform_t *lf, cell_t *where); int isingunrange(lifeform_t *lf, cell_t *where);
int isloreskill(enum SKILL skid); int isloreskill(enum SKILL skid);
int islowhp(lifeform_t *lf);
int isspellskill(enum SKILL skid); int isspellskill(enum SKILL skid);
int ismadeofice(lifeform_t *lf); int ismadeofice(lifeform_t *lf);
int ismaxedskill(lifeform_t *lf, enum SKILL skid); int ismaxedskill(lifeform_t *lf, enum SKILL skid);

12
move.c
View File

@ -1252,6 +1252,8 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
// stop sprinting // stop sprinting
stopsprinting(lf); stopsprinting(lf);
noise(lf->cell, NULL, NC_OTHER, SV_TALK, "a splash.", NULL);
} }
} }
} }
@ -2110,7 +2112,7 @@ int pullnextto(lifeform_t *lf, cell_t *c) {
// cell can be null if you're using stairs. // cell can be null if you're using stairs.
// return true if something happened // return true if something happened
int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) { int initiatemove(lifeform_t *lf, cell_t *cell, int onpurpose, int *didmsg) {
object_t *o, *nexto; object_t *o, *nexto;
char buf[BUFLEN]; char buf[BUFLEN];
flag_t *f; flag_t *f;
@ -2315,7 +2317,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) {
// note however that if a monster is chasing a player (ie // note however that if a monster is chasing a player (ie
// has F_TARGET,player) then they will simply avoid the cursed // has F_TARGET,player) then they will simply avoid the cursed
// object rather than failing the movement. // object rather than failing the movement.
if (cell) { if (cell && onpurpose) {
for (o = cell->obpile->first ; o ; o = nexto) { for (o = cell->obpile->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
if (!isplayer(lf)) { if (!isplayer(lf)) {
@ -2602,7 +2604,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
if (moveok) { if (moveok) {
lifeform_t *alf; lifeform_t *alf;
if (initiatemove(lf, cell, &dontclearmsg)) { if (initiatemove(lf, cell, onpurpose, &dontclearmsg)) {
// failed? // failed?
return B_TRUE; return B_TRUE;
} }
@ -2868,7 +2870,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
} }
break; break;
case E_LFINWAY: case E_LFINWAY:
if (initiatemove(lf, cell, &dontclearmsg)) { if (initiatemove(lf, cell, onpurpose, &dontclearmsg)) {
// failed? // failed?
return B_TRUE; return B_TRUE;
} }
@ -3058,7 +3060,7 @@ int walkoffmap(lifeform_t *lf, int dir, int onpurpose) {
cell_t *c; cell_t *c;
c = getrandomadjcell(dst, WE_WALKABLE, B_ALLOWEXPAND); c = getrandomadjcell(dst, WE_WALKABLE, B_ALLOWEXPAND);
if (c) { if (c) {
if (!initiatemove(adjally[n], NULL, NULL)) { if (!initiatemove(adjally[n], NULL, B_TRUE, NULL)) {
movelf(adjally[n], c); movelf(adjally[n], c);
taketime(adjally[n], getmovespeed(adjally[n])); taketime(adjally[n], getmovespeed(adjally[n]));
} }

2
move.h
View File

@ -25,7 +25,7 @@ int move_will_hurt(lifeform_t *lf);
int opendoorat(lifeform_t *lf, cell_t *c); int opendoorat(lifeform_t *lf, cell_t *c);
int opendoor(lifeform_t *lf, object_t *o); int opendoor(lifeform_t *lf, object_t *o);
int pullnextto(lifeform_t *lf, cell_t *c); int pullnextto(lifeform_t *lf, cell_t *c);
int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg); int initiatemove(lifeform_t *lf, cell_t *cell, int onpurpose, int *didmsg);
int isorthogonal(int dir); int isorthogonal(int dir);
int ispossiblemove(lifeform_t *lf, int dir); int ispossiblemove(lifeform_t *lf, int dir);
void standup(lifeform_t *lf); void standup(lifeform_t *lf);

View File

@ -1224,14 +1224,18 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
if (o && (o->type->id == OT_FOUNTAIN)) { if (o && (o->type->id == OT_FOUNTAIN)) {
f = hasflag(o->flags, F_LINKOB); f = hasflag(o->flags, F_LINKOB);
if (where->where && (where->where->habitat->id != H_VILLAGE)) { if (where->where && (where->where->habitat->id != H_VILLAGE)) {
objecttype_t *ot; if (onein(3)) {
int min,max; objecttype_t *ot;
int min,max;
getrarityrange(where->where->map->depth, &min, &max, RARITYVARIANCEOB, B_FALSE);
// random potion type getrarityrange(where->where->map->depth, &min, &max, RARITYVARIANCEOB, B_FALSE);
ot = getrandomobofclass(OC_POTION, min, max); // random potion type
if (ot) { ot = getrandomobofclass(OC_POTION, min, max);
f->val[0] = ot->id; if (ot) {
f->val[0] = ot->id;
}
} else {
f->val[0] = OT_POT_WATER;
} }
} }
} }
@ -2193,8 +2197,13 @@ void applyobmod(object_t *o, obmod_t *om) {
return; return;
} }
if ((om->id == OM_MASTERWORK) || (om->id == OM_SHODDY)) { if (om->id == OM_MASTERWORK) {
if (hasflag(o->flags, F_NOQUALITY)) { if (hasflag(o->flags, F_NOQUALITY) || hasflag(o->flags, F_SHODDY)) {
return;
}
}
if (om->id == OM_SHODDY) {
if (hasflag(o->flags, F_NOQUALITY) || hasflag(o->flags, F_MASTERWORK)) {
return; return;
} }
} }
@ -7483,6 +7492,10 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
removeob(oo, oo->amt); removeob(oo, oo->amt);
} }
} }
if ((oo->type->id == OT_WATERDEEP) && (getmaterialstate(o->material->id) == MS_SOLID)) {
noise(dst->where, NULL, NC_OTHER, SV_TALK, "a splash.", "Splash!");
}
} }
} }
} }
@ -9407,14 +9420,14 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
} }
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You feel more experienced!"); msg("You feel more experienced!");
gainxp(lf, getxpforlev(lf->level+1) - lf->xp); // purposely not using gainxp
lf->xp = getxpforlev(lf->level+1);
} else { } else {
if (cansee(player, lf)) { if (cansee(player, lf)) {
msg("%s looks more experienced!", lfname); msg("%s looks more experienced!", lfname);
} }
gainlevel(lf);
enhanceskills(lf);
} }
gainlevel(lf, B_TRUE);
break; break;
case OT_POT_GASEOUSFORM: case OT_POT_GASEOUSFORM:
@ -10340,6 +10353,7 @@ int removeob(object_t *o,int howmany) {
} }
if (howmany >= o->amt) { if (howmany >= o->amt) {
o->dying = B_TRUE;
killob(o); killob(o);
rv = 0; rv = 0;
} else { } else {

14
shops.c
View File

@ -557,17 +557,25 @@ enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *top
// list objects for sale // list objects for sale
for (o = vm->contents->first ; o ; o = o->next) { for (o = vm->contents->first ; o ; o = o->next) {
char obname[BUFLEN]; char obname[BUFLEN];
// get the name of the object int thisprice;
getshopobname(o, obname, o->amt); getshopobname(o, obname, o->amt);
thisprice = (int)getshopprice(o, player);
snprintf(buf, BUFLEN, "%c - %s", o->letter, obname); snprintf(buf, BUFLEN, "%c - %s", o->letter, obname);
snprintf(buf2, BUFLEN, "%-60s$%d",buf,(int)getshopprice(o, player)); snprintf(buf2, BUFLEN, "^%d%-60s$%d",
mvwprintw(mainwin, y, 0, "%s", buf2); (countmoney(player->pack) >= thisprice) ? C_GREY : C_RED,
buf, thisprice);
wmove(mainwin, y, 0);
textwithcol(mainwin, buf2);
y++; y++;
} }
strcpy(choices, ""); strcpy(choices, "");
y++; y++;
wmove(mainwin, y, 0);
textwithcol(mainwin, "^n");
mvwprintw(mainwin, y, 0, "You have $%d.", countmoney(player->pack)); mvwprintw(mainwin, y, 0, "You have $%d.", countmoney(player->pack));
y++; y++;
y++; y++;

92
spell.c
View File

@ -1235,6 +1235,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
cell_t *origcell; cell_t *origcell;
int maxrange = 2; int maxrange = 2;
object_t *o; object_t *o;
int swapped = B_FALSE;
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
if (isplayer(user)) msg("You can't jump while swimming!"); if (isplayer(user)) msg("You can't jump while swimming!");
@ -1303,35 +1304,38 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
getlfname(victim,victimname); getlfname(victim,victimname);
// TODO: if jumper is smaller, move them out of the way instead
// move them out of the way // move them out of the way
c = getrandomadjcell(victim->cell, WE_EMPTY, B_NOEXPAND); c = getrandomadjcell(victim->cell, WE_EMPTY, B_NOEXPAND);
// nowhere to move? move to player's cell! // nowhere to move? move to where the lf jumped from!
if (!c) { if (c) {
c = user->cell; movelf(victim, c);
} } else {
movelf(victim, c); swapplaces(victim, user, B_TRUE, B_FALSE);
swapped = B_TRUE;
}
// see if you actually landed on them or they dodge... // see if you actually landed on them or they dodge...
acc = 100 - getevasion(victim); acc = 100 - (getevasion(victim)*2);
if (rnd(1,100) > acc) { if (rnd(1,100) > acc) {
// dodged! // dodged!
dodged = B_TRUE; dodged = B_TRUE;
} }
} }
movelf(user, targcell); if (!swapped) {
movelf(user, targcell);
}
// announce // announce
if (isplayer(user)) { if (isplayer(user)) {
if (victim && !dodged) { if (victim && !dodged) {
msg("You leap high in the air and land on %s!",victimname); msg("You leap high in the air onto %s!",victimname);
} else { } else {
msg("You leap high in the air!"); msg("You leap high in the air!");
} }
} else if (haslos(player, origcell)) { } else if (haslos(player, origcell)) {
if (cansee(player, user)) { if (cansee(player, user)) {
if (victim && !dodged) { if (victim && !dodged) {
msg("%s leaps high in the air and lands on %s!", username,victimname); msg("%s leaps high in the air onto %s!", username,victimname);
} else { } else {
msg("%s leaps high in the air and lands nearby!", username); msg("%s leaps high in the air and lands nearby!", username);
} }
@ -1342,7 +1346,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (victim && !dodged) { if (victim && !dodged) {
msg("%s drops from the air and lands nearby!", username); msg("%s drops from the air and lands nearby!", username);
} else { } else {
msg("%s drops from the air and lands on %s!", username,victimname); msg("%s drops from the air onto %s!", username,victimname);
} }
} }
@ -1350,6 +1354,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
for (o = targcell->obpile->first ; o ; o = o->next) { for (o = targcell->obpile->first ; o ; o = o->next) {
if ((o->material->id == MT_WATER) && (o->type->id != OT_PUDDLEWATER)) { if ((o->material->id == MT_WATER) && (o->type->id != OT_PUDDLEWATER)) {
addobburst(targcell, 1, DT_COMPASS, "small puddle of water", NULL, LOF_NEED); addobburst(targcell, 1, DT_COMPASS, "small puddle of water", NULL, LOF_NEED);
noise(targcell, NULL, NC_OTHER, SV_TALK, "a splash.", "Splash!");
break; break;
} }
} }
@ -1360,11 +1365,18 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
msg("%s dodges out of the way!", victimname); msg("%s dodges out of the way!", victimname);
} }
} else { } else {
int dam; /*
// they take damage based on the jumper's weight int dam = 0;
// 1hp per 15 kg int diff;
// TODO: make divisor be dependant on difference in lf size diff = getlfsize(user) - getlfsize(victim);
dam = getlfweight(user, B_WITHOBS) / 15; if (diff > 0) { // user was larger
// victim takes damage based on the jumper's weight
// 1hp per 25 kg
dam = getlfweight(user, B_WITHOBS) / 25;
} else {
// user was same size or smaller
dam = 0;
}
if (dam > 0) { if (dam > 0) {
if (lfhasflag(user, F_EXTRAINFO) || lfhasflag(user, F_OMNIPOTENT)) { if (lfhasflag(user, F_EXTRAINFO) || lfhasflag(user, F_OMNIPOTENT)) {
msg("[%s takes %d damage]",victimname,dam); msg("[%s takes %d damage]",victimname,dam);
@ -1372,6 +1384,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
snprintf(buf, BUFLEN, "a falling %s", user->race->name); snprintf(buf, BUFLEN, "a falling %s", user->race->name);
losehp(victim, dam, DT_BASH, user, buf); losehp(victim, dam, DT_BASH, user, buf);
} }
*/
// both victim and attacker wall
if (!isdead(victim)) fall(victim, NULL, B_TRUE);
fall(user, NULL, B_TRUE);
} }
} }
} else if (abilid == OT_A_RAGE) { } else if (abilid == OT_A_RAGE) {
@ -1683,6 +1699,41 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// shield gets damaged // shield gets damaged
takedamage(shield, roll("1d3"), DT_DIRECT); takedamage(shield, roll("1d3"), DT_DIRECT);
} else if (abilid == OT_A_SNATCH) {
object_t *o = NULL;
if (!targcell) {
int dirch;
// ask which dir
dirch = askchar("Snatch from which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE);
if ((dirch == '-') || !dirch) {
if (isplayer(user)) msg("Cancelled.");
return B_TRUE;
} else {
int dir;
dir = chartodir(dirch);
if (dir == D_NONE) {
if (isplayer(user)) msg("Cancelled.");
return B_TRUE;
} else {
targcell = getcellindir(user->cell, dir);
}
}
}
if (targcell->obpile->first) {
// select object from cell...
o = askobject(targcell->obpile, "Snatch which object", NULL, '\0', AO_NONE);
} else {
if (isplayer(user)) msg("There is nothing there to snatch!");
return B_TRUE;
}
if (!o) {
if (isplayer(user)) msg("Cancelled.");
return B_TRUE;
}
pickup(user, o, 1, B_TRUE, B_TRUE);
} else if (abilid == OT_A_SONICBOLT) { } else if (abilid == OT_A_SONICBOLT) {
int volume; int volume;
@ -2366,7 +2417,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
msg("Cancelled."); msg("Cancelled.");
} else { } else {
while (user->level < lev) { while (user->level < lev) {
gainlevel(user); gainlevel(user, B_TRUE);
} }
} }
} else if (abilid == OT_A_BLINDALL) { } else if (abilid == OT_A_BLINDALL) {
@ -3891,6 +3942,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} // end while narccells } // end while narccells
} else if (spellid == OT_S_CLONE) { } else if (spellid == OT_S_CLONE) {
lifeform_t *lf;
// duplicate the caster // duplicate the caster
targcell = getrandomadjcell(caster->cell, WE_WALKABLE, B_NOEXPAND); targcell = getrandomadjcell(caster->cell, WE_WALKABLE, B_NOEXPAND);
if (!targcell) { if (!targcell) {
@ -3900,7 +3952,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (isplayer(caster) || haslos(player, targcell)) { if (isplayer(caster) || haslos(player, targcell)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
addmonster(targcell, caster->race->id, NULL, B_FALSE, 1, B_FALSE, NULL); lf = addmonster(targcell, caster->race->id, NULL, B_FALSE, 1, B_FALSE, NULL);
if (lf) {
killflagsofid(lf->flags, F_XPVAL);
addflag(lf->flags, F_XPVAL, 0, NA, NA, NULL);
}
} else if (spellid == OT_S_CLOUDKILL) { } else if (spellid == OT_S_CLOUDKILL) {
int radius; int radius;

25
vaults/bazaar.vlt Normal file
View File

@ -0,0 +1,25 @@
@id:bazaar
@map
#####X#####
#..s._.s..#
#.._._._..#
X_________X
#.._._._..#
#..s._.s..#
#####X#####
@end
@legend
#:cell:rock floor
#:ob:wooden fence
_:cell:dirt
s:ob:random building
X:exit
@end
@flags
goesin:dungeon
mayrotate
rarity:vrare
@end