diff --git a/attack.c b/attack.c index 74999f7..9d600e1 100644 --- a/attack.c +++ b/attack.c @@ -1712,7 +1712,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) { } else { // if a trap didn't go off, you might break the lock f = hasflag(o->flags, F_LOCKED); - if (f) { + if (f && (damtype[i] == DT_BASH)) { int difficulty; int unlockit = B_FALSE; difficulty = f->val[0]; diff --git a/data.c b/data.c index 45b5d1a..dcf7de1 100644 --- a/data.c +++ b/data.c @@ -4562,7 +4562,7 @@ void initobjects(void) { addflag(lastot->flags, F_MAXPOWER, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); // l2 - addot(OT_S_ENERGYBOLT, "energy bolt", "Fires a medium-sized bolt of wild magic, dealing 1d4 damage per power level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_ENERGYBOLT, "energy bolt", "Fires a medium-sized bolt of wild magic, dealing 2d4 damage per power level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); @@ -4599,7 +4599,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the amount of charges restored."); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); - addot(OT_S_SPIKEVOLLEY, "spike volley", "Fires a volley of iron spikes, dealing 3 damage plus 1d3 per spell power.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_SPIKEVOLLEY, "spike volley", "Fires a volley of iron spikes, dealing 3d4 damage per spell power.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); @@ -5247,7 +5247,6 @@ void initobjects(void) { addot(OT_CREDITCARD, "credit card", "A rectangular plastic card.", MT_PLASTIC, 0.01, OC_TECH, SZ_TINY); addflag(lastot->flags, F_RARITY, H_ALL, 90, NA, NULL); addflag(lastot->flags, F_RNDCHARGES, 75, 500, NA, NULL); - addflag(lastot->flags, F_STACKABLE, B_FALSE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_PICKLOCKS, 2, NA, NA, NULL); addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL); @@ -9071,6 +9070,7 @@ void initrace(void) { addflag(lastrace->flags, F_LEVABIL, 7, OT_S_FLIGHT, NA, NULL); addflag(lastrace->flags, F_LEVABIL, 10, OT_S_FIREBALL, 80, "pw:10;"); addflag(lastrace->flags, F_STARTSKILL, SK_LORE_DRAGONS, PR_SKILLED, NA, NULL); + addflag(lastrace->flags, F_CANLEARN, SK_LORE_DRAGONS, PR_MASTER, NA, NULL); // no limit // penalties addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_LEARNBOOST, -30, NA, NA, NULL); @@ -11435,7 +11435,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 90, NA, NA, NULL); // will nearly always use its spikes first. - addflag(lastrace->flags, F_CANWILL, OT_S_SPIKEVOLLEY, 30, 30, "pw:4;range:4;"); + addflag(lastrace->flags, F_CANWILL, OT_S_SPIKEVOLLEY, 30, 30, "pw:2;range:4;"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_SPIKEVOLLEY, NA, B_APPENDYOU, "aims its tail"); addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); @@ -16357,6 +16357,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); + addflag(lastrace->flags, F_FOLLOWTIME, 0, NA, NA, NULL); addrace(R_SKELETON, "skeleton", 20, 'Z', C_GREY, MT_BONE, RC_UNDEAD, "A walking set of bones, animated through the use of necromancy. Due to their lack of soft flesh, they have little to fear from edged weapons."); setbodytype(lastrace, BT_HUMANOID); @@ -16399,6 +16400,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_FOLLOWTIME, 0, NA, NA, NULL); addrace(R_SKELETONFIRE, "fire skeleton", 20, 'Z', C_RED, MT_BONE, RC_UNDEAD, "A walking set of flaming bones, imbued with the power of fire. They have all the advantages of normal skeletons but tend to burn victims with their flame rather than use weapons."); setbodytype(lastrace, BT_HUMANOID); @@ -16469,6 +16471,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_FOLLOWTIME, 10, NA, NA, NULL); addrace(R_WRAITHBOG, "bog wraith", 20, 'Z', C_BROWN, MT_PLANT, RC_UNDEAD, "Bog wraiths take the form of vaguely humanoid blobs of putrid mud."); setbodytype(lastrace, BT_HUMANOID); @@ -16707,6 +16710,7 @@ void initrace(void) { addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "shouts^a shout"); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_FOLLOWTIME, 50, NA, NA, NULL); addrace(R_MUMMY, "mummy", 54, 'M', C_GREY, MT_FLESH, RC_UNDEAD, "A rotting humanoid figure clad in bandages."); @@ -16739,6 +16743,7 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_FOLLOWTIME, 30, NA, NA, NULL); addrace(R_MUMMYG, "mummy king", 54, 'M', C_MAGENTA, MT_FLESH, RC_UNDEAD, "A hugely muscled rotting figure, wearing priestly garments."); setbodytype(lastrace, BT_HUMANOID); @@ -16779,6 +16784,7 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_FOLLOWTIME, 50, NA, NA, NULL); addrace(R_REVENANT, "revenant", 60, 'Z', C_BOLDBLUE, MT_FLESH, RC_UNDEAD, "A powerful zombie which retains full memory of its former life and abilities."); setbodytype(lastrace, BT_HUMANOID); @@ -16811,6 +16817,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTJOB, 25, J_WARRIOR, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 100, J_WIZARD, SJ_RANDOM, NULL); addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_REVENANT, "rises from the dead!"); + addflag(lastrace->flags, F_FOLLOWTIME, 40, NA, NA, NULL); addrace(R_VAMPIRE, "vampire", 75, 'V', C_BLUE, MT_FLESH, RC_UNDEAD, "Blood-drinking creatures of the night, vampires have pale white skin and prominent fangs protuding from their mouthes. They are said to be near immortal, able to survive even seemingly fatal attacks by converting themselves to a gaseous form."); setbodytype(lastrace, BT_HUMANOID); @@ -16857,6 +16864,7 @@ void initrace(void) { // special: flee from garlic addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_FOLLOWTIME, 50, NA, NA, NULL); addrace(R_WEREBEAR, "werebear", 90, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Stout, well-muscled humans with large, thick beards."); setbodytype(lastrace, BT_HUMANOID); @@ -17388,7 +17396,7 @@ void initskills(void) { 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 the depth and direction of footprints.^n", B_TRUE); addskilldesc(SK_PERCEPTION, PR_BEGINNER, "^gYou now have perception of your blind spots.^n", B_TRUE); - addskilldesc(SK_PERCEPTION, PR_BEGINNER, "^gYou can now recognise the quality of items.^n", B_TRUE); + addskilldesc(SK_PERCEPTION, PR_BEGINNER, "^gYou can now recognise the quality of all items.^n", B_TRUE); addskilldesc(SK_PERCEPTION, PR_ADEPT, "^gYour field of vision is now wider.^n", B_TRUE); addskilldesc(SK_PERCEPTION, PR_EXPERT, "^gYou can now move without leaving footprints.^n", B_TRUE); addskilldesc(SK_PERCEPTION, PR_MASTER, "^gYou field of vision now extends behind you.^n", B_TRUE); diff --git a/data/hiscores.db b/data/hiscores.db index 3943bdb..aa23ba8 100644 Binary files a/data/hiscores.db and b/data/hiscores.db differ diff --git a/defs.h b/defs.h index 2768c36..620246b 100644 --- a/defs.h +++ b/defs.h @@ -24,7 +24,7 @@ #define TEXT_WARN_NOXP_GOODVSPEACEFUL "Warning: Only Evil players gain XP for peaceful kills." // Defaults -#define DEF_AIFOLLOWTIME (50) // if target lf is out of view +#define DEF_AIFOLLOWTIME (20) // if target lf is out of view #define DEF_BURNTIMEMIN (3) #define DEF_BURNTIMEMAX (6) @@ -373,8 +373,10 @@ enum TRADEINFOTYPE { }; enum SHOPACTION { + SA_NONE, SA_BUY, SA_SELL, + SA_DONATE, SA_ID, }; diff --git a/god.c b/god.c index 9fecfa1..46c0399 100644 --- a/god.c +++ b/god.c @@ -1136,7 +1136,7 @@ int godgiftmaybe(enum RACE rid, int fromtemple) { break; case 3: msg("\"I grant you additional magical reserves!\""); - player->maxmp += rnd(2,4); + player->maxmp += rnd(4,6); statdirty = B_TRUE; break; } @@ -2232,9 +2232,14 @@ int prayto(lifeform_t *lf, lifeform_t *god) { o = touncurse[rnd(0,uncursenum-1)]; uncurseob(o, NULL); } else { - // just regain mana. - gainmp(lf, getmaxmp(lf)); - msg("\"One's magical reserves have been filled!\""); + if (lf->mp < getmaxmp(lf)) { + // just regain mana. + gainmp(lf, getmaxmp(lf)); + msg("\"One's magical reserves have been filled!\""); + } else { + lf->maxmp++; + msg("\"One's magical capacity has been increased!\""); + } } } } diff --git a/io.c b/io.c index 01c7234..803cd2a 100644 --- a/io.c +++ b/io.c @@ -1127,10 +1127,10 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t tempob = addob(c->obpile, obname); } // show objects - o = doaskobject(c->obpile, "Describe which object", NULL, NULL, B_TRUE, B_FALSE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE); + o = doaskobject(c->obpile, "Describe which object", NULL, NULL, B_TRUE, B_FALSE, B_FALSE, '\0', NULL, SA_NONE, MT_NOTHING, AO_NONE, F_NONE); while (o) { describeob(o); - o = doaskobject(c->obpile, "Describe which object",NULL, NULL, B_FALSE, B_FALSE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE); + o = doaskobject(c->obpile, "Describe which object",NULL, NULL, B_FALSE, B_FALSE, B_FALSE, '\0', NULL, SA_NONE, MT_NOTHING, AO_NONE, F_NONE); } if (tempob) killob(tempob); } @@ -2910,11 +2910,11 @@ object_t *askobject(obpile_t *op, char *prompt, char *noobtext, int *count, char if (op->owner && isplayer(op->owner)) { showlong = B_FALSE; } - return doaskobject(op, prompt, noobtext, count, showlong, B_TRUE, B_FALSE, action, NULL, MT_NOTHING, opts, F_NONE); + return doaskobject(op, prompt, noobtext, count, showlong, B_TRUE, B_FALSE, action, NULL, SA_NONE, MT_NOTHING, opts, F_NONE); } object_t *askobjectwithflag(obpile_t *op, char *prompt, char *noobtext, int *count, char action, long opts, enum FLAG withflag) { - return doaskobject(op, prompt, noobtext, count, B_TRUE, B_TRUE, B_FALSE, action, NULL, MT_NOTHING, opts, withflag, F_NONE); + return doaskobject(op, prompt, noobtext, count, B_TRUE, B_TRUE, B_FALSE, action, NULL, SA_NONE, MT_NOTHING, opts, withflag, F_NONE); } int contains(enum OBCLASS *array, int nargs, enum OBCLASS want) { @@ -2927,7 +2927,7 @@ int contains(enum OBCLASS *array, int nargs, enum OBCLASS want) { return B_FALSE; } -void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup, int showpoints, object_t *sellshop) { +void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup, int showpoints, object_t *sellshop, enum SHOPACTION sellaction) { int lastclass = OC_NULL; int i; int useobletters = B_TRUE; @@ -2985,7 +2985,7 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi char pricebuf[BUFLEN]; int markdownpct; for (n = 0; n < nsellflags; n++) { - if (obmatchessellflag(mylist[i], sellflag[n], SA_SELL)) { + if (obmatchessellflag(mylist[i], sellflag[n], sellaction)) { curflag = sellflag[n]; break; } @@ -3052,7 +3052,7 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi // F_NONE // // If you pass "sellshop", DONT also pass F_xxx. -object_t *doaskobject(obpile_t *op, char *prompt, char *noobtext, int *count, int showlong, int forpickup, int showpoints, char action, object_t *sellshop, int wantmaterial, long opts, ...) { +object_t *doaskobject(obpile_t *op, char *prompt, char *noobtext, int *count, int showlong, int forpickup, int showpoints, char action, object_t *sellshop, enum SHOPACTION sellaction, int wantmaterial, long opts, ...) { int c,i; char defchar = '\0'; static char defaults[52] = {'\0'}; @@ -3211,7 +3211,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, char *noobtext, int *count, in // list the objects y = 2; - listobs(mainwin, mylist, NULL, NULL, firstob, &i, lastline, &y, useobletters ? NULL : myletters , forpickup, showpoints, sellshop); + listobs(mainwin, mylist, NULL, NULL, firstob, &i, lastline, &y, useobletters ? NULL : myletters , forpickup, showpoints, sellshop, sellaction); } if (mylist[i] == NULL) { @@ -3449,7 +3449,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) { // list the objects y = 2; - listobs(mainwin, mylist, selected, selcount, firstob, &i, lastline, &y, useobletters ? NULL : myletters , B_TRUE, B_FALSE, NULL); + listobs(mainwin, mylist, selected, selcount, firstob, &i, lastline, &y, useobletters ? NULL : myletters , B_TRUE, B_FALSE, NULL, SA_NONE); if (mylist[i] == NULL) { nextpage = -1; @@ -8214,12 +8214,12 @@ void doexplain(char *question) { void dofinaloblist(obpile_t *op) { object_t *o; - o = doaskobject(op, "Your final possessions were", NULL, NULL, B_TRUE, B_FALSE, B_TRUE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE); + o = doaskobject(op, "Your final possessions were", NULL, NULL, B_TRUE, B_FALSE, B_TRUE, '\0', NULL, SA_NONE, MT_NOTHING, AO_NONE, F_NONE); while (o) { // describe it describeob(o); // ask for another one - o = doaskobject(op, "Your final possessions were",NULL, NULL, B_TRUE, B_FALSE, B_TRUE,'\0', NULL, MT_NOTHING, AO_NONE, F_NONE); + o = doaskobject(op, "Your final possessions were",NULL, NULL, B_TRUE, B_FALSE, B_TRUE,'\0', NULL, SA_NONE, MT_NOTHING, AO_NONE, F_NONE); } real_clearmsg(B_TRUE); } @@ -8373,7 +8373,7 @@ void doinventory(obpile_t *op) { maxweight = getmaxcarryweight(player); pct = (packweight / maxweight) * 100; snprintf(buf, BUFLEN, "Inventory (%0.0f/%0.0f kg, %0.0f%%)", packweight, maxweight, pct); - o = doaskobject(op, buf, NULL, NULL, B_TRUE, B_TRUE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE); + o = doaskobject(op, buf, NULL, NULL, B_TRUE, B_TRUE, B_FALSE, '\0', NULL, SA_NONE, MT_NOTHING, AO_NONE, F_NONE); while (o) { // describe it describeob(o); @@ -8962,6 +8962,14 @@ void drawlevelfor(lifeform_t *lf) { } } +int haschoice(prompt_t *p, char ch) { + int i; + for (i = 0; i < p->nchoices; i++) { + if (p->choice[i].ch == ch) return B_TRUE; + } + return B_FALSE; +} + void doheading(WINDOW *win, int *y, int x, char *what) { int len,i; char *underline; @@ -13131,41 +13139,43 @@ void showlfstats(lifeform_t *lf, int showall) { getflags(lf->flags, retflag, &nretflags, F_EXTRADAM, F_NONE); for (i = 0; i < nretflags; i++) { - int ndice,nsides,bonus; - char dicebuf[BUFLEN]; - char mmbuf[BUFLEN]; - char damtypebuf[BUFLEN]; - int min = 0,max = 0; - f = retflag[i]; - texttodice(f->text, &ndice,&nsides,&bonus); - - if ((f->lifetime == FROMOBEQUIP) || - (f->lifetime == FROMOBHOLD) || - (f->lifetime == FROMOBACTIVATE) ) { - object_t *obfrom; - obfrom = findobbyid(lf->pack, f->obfrom); - if (obfrom) { - int bonusdam; - sumflags(obfrom->flags, F_BONUS, &bonusdam, NULL, NULL); - bonus += bonusdam; + if (showall || f->known) { + int ndice,nsides,bonus; + char dicebuf[BUFLEN]; + char mmbuf[BUFLEN]; + char damtypebuf[BUFLEN]; + int min = 0,max = 0; + f = retflag[i]; + texttodice(f->text, &ndice,&nsides,&bonus); + + if ((f->lifetime == FROMOBEQUIP) || + (f->lifetime == FROMOBHOLD) || + (f->lifetime == FROMOBACTIVATE) ) { + object_t *obfrom; + obfrom = findobbyid(lf->pack, f->obfrom); + if (obfrom) { + int bonusdam; + sumflags(obfrom->flags, F_BONUS, &bonusdam, NULL, NULL); + bonus += bonusdam; + } } - } - if (f->val[0] == NA) { - strcpy(damtypebuf, "damage"); - } else { - snprintf(damtypebuf, BUFLEN, "%s damage", getdamname(f->val[0])); - } + if (f->val[0] == NA) { + strcpy(damtypebuf, "damage"); + } else { + snprintf(damtypebuf, BUFLEN, "%s damage", getdamname(f->val[0])); + } - dicetotext(ndice, nsides, bonus, &min, &max, dicebuf, mmbuf); - if (strcmp(dicebuf, mmbuf)) { - mvwprintw(mainwin, y, 0, "%s deal%s %s (%s) extra %s each hit.", you(lf), - isplayer(lf) ? "" : "s", dicebuf, mmbuf, damtypebuf); - } else { - mvwprintw(mainwin, y, 0, "%s deal%s %s extra %s each hit.", you(lf), - isplayer(lf) ? "" : "s", dicebuf, damtypebuf); + dicetotext(ndice, nsides, bonus, &min, &max, dicebuf, mmbuf); + if (strcmp(dicebuf, mmbuf)) { + mvwprintw(mainwin, y, 0, "%s deal%s %s (%s) extra %s each hit.", you(lf), + isplayer(lf) ? "" : "s", dicebuf, mmbuf, damtypebuf); + } else { + mvwprintw(mainwin, y, 0, "%s deal%s %s extra %s each hit.", you(lf), + isplayer(lf) ? "" : "s", dicebuf, damtypebuf); + } + y++; } - y++; } sumflags(lf->flags, F_EXTRALUCK, &luckmod, NULL, NULL); diff --git a/io.h b/io.h index 1bc3bbe..2cd1ecf 100644 --- a/io.h +++ b/io.h @@ -22,7 +22,7 @@ int confirm_injury_action(enum BODYPART bp, enum DAMTYPE dt, char *actionname); lifeform_t *askgod(char *prompt, int onlyprayed); object_t *askobject(obpile_t *op, char *title, char *noobtext, int *count, char action, long opts); object_t *askobjectwithflag(obpile_t *op, char *title, char *noobtext,int *count, char action, long opts, enum FLAG withflag); -object_t *doaskobject(obpile_t *op, char *prompt, char *noobtext, int *count, int showlong, int forpickup, int showpoints, char action, object_t *sellshop, int wantmaterial, long opts, ...); +object_t *doaskobject(obpile_t *op, char *prompt, char *noobtext, int *count, int showlong, int forpickup, int showpoints, char action, object_t *sellshop, enum SHOPACTION sellaction, int wantmaterial, long opts, ...); int askobjectmulti(obpile_t *op, char *prompt, long opts); char askchar(char *prompt, char *validchars, char *def, int showchars, int maycancel); cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail); @@ -103,12 +103,13 @@ int getkey(int escseqok); enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev); void handle_ctrl_y(int arg); void handleinput(void); +int haschoice(prompt_t *p, char ch); void doheading(WINDOW *win, int *y, int x, char *what); void doheadingsmall(WINDOW *win, int y, int x, char *format, char *heading); void initgfx(void); void initprompt(prompt_t *p, char *q1); int keycodetokey(int keycode, int escseqok); -void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup, int showpoints, object_t *sellshop); +void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup, int showpoints, object_t *sellshop, enum SHOPACTION sellaction); char *makedesc_god(lifeform_t *god, char *retbuf); char *makedesc_job(job_t *j, char *retbuf); char *makedesc_ob(object_t *o, char *retbuf); diff --git a/lf.c b/lf.c index c6bced0..684b681 100644 --- a/lf.c +++ b/lf.c @@ -5876,9 +5876,10 @@ int flee(lifeform_t *lf) { // a certain time period (ie. f->lifetime == PERMENANT), we can now stop fleeing. if (f->lifetime == PERMENANT) { // player let something flee? - if (isplayer(thisone)) { + if (isplayer(thisone) && !haslos(thisone, lf->cell)) { // purposely not using cansee pleasegodmaybe(R_GODMERCY, 5); - if ((lf->lastdamlf == player->id) || cansee(player, lf)) { + //if ((lf->lastdamlf == player->id) || cansee(player, lf)) { + if (lf->lastdamlf == player->id) { // ie. only if the player saw them run away, or has already // attacked them. angergodmaybe(R_GODDEATH, 10, GA_MERCY); @@ -10263,10 +10264,9 @@ void givejob(lifeform_t *lf, enum JOB jobid) { // - hpmod ones // - skills which we already have f_noskill for. for (f = j->flags->first ; f ; f = f->next) { - int ignorethis = B_FALSE; - int val[3]; - int id; + int val[3],id,ignorethis = B_FALSE; char *text; + flag_t *f2; id = f->id; val[0] = f->val[0]; @@ -10305,6 +10305,11 @@ void givejob(lifeform_t *lf, enum JOB jobid) { break; case F_CANLEARN: if (lfhasflagval(lf, F_NOSKILL, f->val[0], NA, NA, NULL)) ignorethis = B_TRUE; + if (!ignorethis && (f->val[1] != NA)) { + // already have a better limit? + f2 = lfhasflagval(lf, F_NOSKILL, f->val[0], NA, NA, NULL); + if (f2 && (f2->val[1] != NA) && (f2->val[1] > f->val[1])) ignorethis = B_TRUE; + } break; default: break; @@ -18475,6 +18480,10 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) { } else if ((f->condition == FC_IFPLAYER) && !isplayer(lf)) { ignorethis = B_TRUE; } + // don't change hostility when polymorphing + if (frompolymorph) { + if (f->id == F_HOSTILE) ignorethis = B_TRUE; + } if (!ignorethis) { //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging addflag_real(lf->flags, f->id, f->val[0], f->val[1], f->val[2], f->text, FROMRACE, f->known, -1); diff --git a/nexus.c b/nexus.c index cacbb5a..d2360c0 100644 --- a/nexus.c +++ b/nexus.c @@ -432,6 +432,7 @@ int main(int argc, char **argv) { // changes for anything within los/lof of player's starting pos: // - don't want any mosnters starting here + // - don't want any impassable objects other than doors // - don't want any locked doors slev = getskill(player, SK_CARTOGRAPHY); for (y = 0; y < player->cell->map->h; y++) { @@ -444,7 +445,12 @@ int main(int argc, char **argv) { } for (o = c->obpile->first ; o ; o = nexto) { nexto = o->next; - killflagsofid(o->flags, F_LOCKED); + if (hasflag(o->flags, F_IMPASSABLE) && !hasflag(o->flags, F_DOOR)) { + killob(o); + continue; + } else { + killflagsofid(o->flags, F_LOCKED); + } } } } diff --git a/objects.c b/objects.c index 92bef94..5b7fe13 100644 --- a/objects.c +++ b/objects.c @@ -680,6 +680,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum donesomething = B_TRUE; while (donesomething) { int n; + material_t *mat = NULL; donesomething = B_FALSE; // water flags @@ -803,9 +804,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum p += strlen("lit "); donesomething = B_TRUE; // different materials - } else if (strstarts(p, "silver ")) { - wantdiffmat = MT_SILVER; - p += strlen("silver "); + } else if (((mat = strmatchesmaterial(p)) != NULL) && !strstr(p, "gold coin")) { + wantdiffmat = mat->id; + p += strlen(mat->name); + p++; // go past the space donesomething = B_TRUE; // rarity } else if (strstarts(p, "frequent ")) { @@ -7493,6 +7495,7 @@ int isplainob(object_t *o) { if (o->inscription) return B_FALSE; if (o->blessed != B_UNCURSED) return B_FALSE; if (isblessknown(o)) return B_FALSE; + if (isdamaged(o)) return B_FALSE; return B_TRUE; } @@ -9132,6 +9135,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { f = hasflag(o->flags, F_OPERNEEDTARGET); if (f && !where) { int ttype = TT_NONE,range = UNLIMITED; + flag_t *f2; // don't give hints about the object if (isknown(o)) { ttype = f->val[0]; @@ -9147,9 +9151,9 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { // default to needing lof ltype = LOF_NEED; } else { - f = hasflag(o->flags, F_LINKSPELL); - if (f) { - ltype = getspellloftype(f->val[0]); + f2 = hasflag(o->flags, F_LINKSPELL); + if (f2) { + ltype = getspellloftype(f2->val[0]); } else { ltype = LOF_NEED; } @@ -9331,10 +9335,15 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { snprintf(buf, BUFLEN, "Take items out of %s",obname); addchoice(&prompt, 'o', buf, NULL, NULL, NULL); } - snprintf(buf, BUFLEN, "Both"); - addchoice(&prompt, 'b', buf, NULL, NULL, NULL); - snprintf(buf, BUFLEN, "Neither"); - addchoice(&prompt, 'n', buf, NULL, NULL, NULL); + if (haschoice(&prompt, 'i') && haschoice(&prompt, 'o')) { + snprintf(buf, BUFLEN, "Both"); + addchoice(&prompt, 'b', buf, NULL, NULL, NULL); + snprintf(buf, BUFLEN, "Neither"); + addchoice(&prompt, 'n', buf, NULL, NULL, NULL); + } else { + snprintf(buf, BUFLEN, "Do nothing"); + addchoice(&prompt, 'n', buf, NULL, NULL, NULL); + } prompt.maycancel = B_TRUE; ch = getchoice(&prompt); switch (ch) { @@ -14663,7 +14672,7 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c) { if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards } else if (oid == OT_TRAPGAS) { // can't be dodged - dospelleffects(NULL, OT_S_CLOUDKILL, 3, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL); + dospelleffects(NULL, OT_S_CLOUDKILL, 1, NULL, NULL, c, B_UNCURSED, NULL, B_TRUE, NULL); if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards } else if (oid == OT_TRAPMINE) { // can't be dodged diff --git a/shops.c b/shops.c index 0bd2076..e1287c1 100644 --- a/shops.c +++ b/shops.c @@ -434,7 +434,7 @@ enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *topte default: wantflag = F_NONE; wantoc = OC_NONE; break; } */ - o = doaskobject(lf->pack, "What will you donate?", NULL, &count, B_TRUE, B_FALSE, B_FALSE, '\0', vm, MT_NOTHING, AO_NONE, F_NONE); + o = doaskobject(lf->pack, "What will you donate?", NULL, &count, B_TRUE, B_FALSE, B_FALSE, '\0', vm, SA_DONATE, MT_NOTHING, AO_NONE, F_NONE); // validate it if (o) { @@ -485,13 +485,13 @@ enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *topte if (f) { lifeform_t *god = NULL; god = findgod(f->val[0]); - msg("%s appreciates your kind donation.", god->race->name); + msg("\"%s appreciates your kind donation.\"", god->race->name); modpiety(god->race->id, (goldgiven/2)); } else { - msg("We appreciate your kind donation."); + msg("\"We appreciate your kind donation.\""); } } else { - msg("Thanks!"); more(); + msg("\"Thanks!\""); more(); } f = hasflag(vm->flags, F_SHOPDONATED); @@ -1232,7 +1232,7 @@ enum SHOPRETURN shopsell(lifeform_t *lf, object_t *vm, int starty, char *toptext // ask what to sell sprintf(buf, "What will you sell (you have $%d)?", countmoney(lf->pack)); - o = doaskobject(player->pack, buf, NULL, &count, B_TRUE, B_FALSE, B_FALSE, '\0', vm, MT_NOTHING, AO_NONE, F_NONE); + o = doaskobject(player->pack, buf, NULL, &count, B_TRUE, B_FALSE, B_FALSE, '\0', vm, SA_SELL, MT_NOTHING, AO_NONE, F_NONE); if (!o) { return SR_BACK; } diff --git a/spell.c b/spell.c index 161142b..1f80713 100644 --- a/spell.c +++ b/spell.c @@ -1385,9 +1385,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } } else if (cansee(player, user)) { if (victim && !dodged) { - msg("%s drops from the air and lands nearby!", username); - } else { msg("%s drops from the air onto %s!", username,victimname); + } else { + msg("%s drops from the air and lands nearby!", username); } } @@ -3798,7 +3798,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ // needs: // object = which object to convert if (!targob && isplayer(caster)) { - targob = doaskobject(caster->pack, "Convert which object to gold", NULL, NULL, B_FALSE, B_FALSE, B_FALSE, '\0', NULL, MT_METAL, AO_NONE, F_NONE); + targob = doaskobject(caster->pack, "Convert which object to gold", NULL, NULL, B_FALSE, B_FALSE, B_FALSE, '\0', NULL, SA_NONE, MT_METAL, AO_NONE, F_NONE); } if (!targob) { fizzle(caster); @@ -4813,7 +4813,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); return B_TRUE; } - radius = (power/4)+1; + radius = (power/3); addobburst(targcell, radius, DT_COMPASS, "puff of poison gas", caster, LOF_WALLSTOP); @@ -6410,7 +6410,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ msg("%s bolts of energy hit %s.",numbuf, lfname); } } - losehp(target, rolldie(power,4), DT_MAGIC, caster, "an energy bolt"); + losehp(target, rolldie(power*2,4), DT_MAGIC, caster, "an energy bolt"); } } else if ((spellid == OT_S_FIREBALL) || (spellid == OT_S_METEOR)) { int failed = B_FALSE; @@ -7677,7 +7677,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ msg("%s spikes of mana hit %s.",numbuf, lfname); } } - losehp(target, rolldie(power,2), DT_MAGIC, caster, "a mana spike"); + losehp(target, rolldie(power,4), DT_MAGIC, caster, "a mana spike"); } } else if (spellid == OT_S_MAGSHIELD) { object_t *o,*nexto; @@ -8049,7 +8049,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int seen; if (targcell->obpile->first) { - targob = doaskobject(targcell->obpile, "Target which object", NULL, NULL, B_TRUE, B_FALSE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE); + targob = doaskobject(targcell->obpile, "Target which object", NULL, NULL, B_TRUE, B_FALSE, B_FALSE, '\0', NULL, SA_NONE, MT_NOTHING, AO_NONE, F_NONE); } if (!targob) { @@ -8138,7 +8138,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int seen; if (targcell->obpile->first) { - targob = doaskobject(targcell->obpile, "Target which object", NULL, NULL, B_TRUE, B_FALSE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE); + targob = doaskobject(targcell->obpile, "Target which object", NULL, NULL, B_TRUE, B_FALSE, B_FALSE, '\0', NULL, SA_NONE, MT_NOTHING, AO_NONE, F_NONE); } strcpy(obtocreate, ""); @@ -11026,7 +11026,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (f) { // should always be true char dambuf[BUFLEN]; free(f->text); - sprintf(dambuf, "%dd3", power); + sprintf(dambuf, "%dd4", power*3); f->text = strdup(dambuf); } real_fireat(caster, o, 1, targcell, 6, NULL, B_FALSE, OT_S_SPIKEVOLLEY, NULL); diff --git a/text.c b/text.c index 618f838..9e44f4b 100644 --- a/text.c +++ b/text.c @@ -22,6 +22,8 @@ extern lifeform_t *player; extern enum GAMEMODE gamemode; extern enum WINGAMETYPE wintype; +extern material_t *material,*lastmaterial; + int needan(char *text) { if (isvowel(tolower(text[0]))) { return B_TRUE; @@ -2220,6 +2222,16 @@ char *strends(char *a, char *suffix) { return NULL; } +material_t *strmatchesmaterial(char *p) { + material_t *m; + char searchfor[BUFLEN]; + for (m = material ; m ; m = m->next) { + sprintf(searchfor, "%s ", m->name); + if (strstarts(p, searchfor)) return m; + } + return NULL; +} + char *strcasestarts(char *a, char *prefix) { if (!a || !prefix) return NULL; diff --git a/text.h b/text.h index 39ef9d6..a7248bf 100644 --- a/text.h +++ b/text.h @@ -66,6 +66,7 @@ char *dostrrep(char* in, char** out, char* oldtok, char* newtok, int *rv); int streq(char *a, char *b); char *strends(char *a, char *suffix); char *strcasestarts(char *a, char *prefix); +material_t *strmatchesmaterial(char *p); char *strstarts(char *a, char *prefix); int strlen_without_colours(char *buf); int strpixmatch(char *haystack, char *needle);