- [+] bug: shouldn't be able to pay with gems without beginner

psychology
- [+] plauge rat should have poison corpse
- [+] bjorn should only get mad when you flee from armed foes.
- [+] Strengths: should include poisonous bite at beginner level, not
      adept.
- [+] show behaviour flags in description
    - [+] territorial (insane)
    - [+] fleeondam (timid)
    - [+] noflee (drugged)
    - [+] followtime (detemrined / lazy)
    - [+] muscled/scrawny
- [+] should be able to pay potion stores to id stuff.
    - [+] update make_basic_shop
    - [+] use shopacceptsflag
    - [+] id function...
- [+] bug: scroll of wishing, Protection. keeps giving me 'sun hat.
    - [+] limit possible body parts to certain ones.
- [+] when wearing armour of the spider, you should never get exhausted
      from climbing
- [+] show "Threat Assessment" text on @@
- [+] only warn about pentagrams with gtaverage iq
* [+] new playable race: Wyrmspawn
This commit is contained in:
Rob Pearce 2012-05-22 06:10:49 +00:00
parent 1605501866
commit cd9b6cd40a
13 changed files with 338 additions and 83 deletions

2
ai.c
View File

@ -1991,7 +1991,7 @@ int aipickupok(lifeform_t *lf, object_t *o) {
*/ */
if (isedible(o)) { if (isedible(o)) {
if (caneat(lf, o) && !isinbattle(lf, B_FALSE)) { if (caneat(lf, o) && !isinbattle(lf, B_NODISTANT, B_FALSE)) {
ok = B_TRUE; ok = B_TRUE;
} }
} else if (canpickup(lf, o, 1)) { } else if (canpickup(lf, o, 1)) {

69
data.c
View File

@ -1814,7 +1814,9 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_VERYRARE, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
make_basic_shop(lastot->flags); addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_HASHIDDENNAME, NA, OC_SCROLL, NULL);
addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_HASHIDDENNAME, NA, OC_BOOK, NULL);
make_basic_shop(lastot->flags, B_ALLOWID);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
f = addflag(lastot->flags, F_STARTOBCLASS, 100, OC_BOOK, RANDOM, NULL); f = addflag(lastot->flags, F_STARTOBCLASS, 100, OC_BOOK, RANDOM, NULL);
addcondition(f, FC_NOCONDITION, 33); addcondition(f, FC_NOCONDITION, 33);
@ -1824,7 +1826,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
make_basic_shop(lastot->flags); make_basic_shop(lastot->flags, B_NOID);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
addflag(lastot->flags, F_STARTOBCLASS, 100, OC_FOOD, RANDOM, NULL); addflag(lastot->flags, F_STARTOBCLASS, 100, OC_FOOD, RANDOM, NULL);
} }
@ -1832,7 +1834,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
make_basic_shop(lastot->flags); make_basic_shop(lastot->flags, B_NOID);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 100, RANDOM, NA, NULL);
} }
@ -1840,7 +1842,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
make_basic_shop(lastot->flags); make_basic_shop(lastot->flags, B_NOID);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
f = addflag(lastot->flags, F_STARTOBCLASS, 100, OC_TOOLS, RANDOM, NULL); f = addflag(lastot->flags, F_STARTOBCLASS, 100, OC_TOOLS, RANDOM, NULL);
addcondition(f, FC_NOCONDITION, 50); addcondition(f, FC_NOCONDITION, 50);
@ -1849,8 +1851,9 @@ void initobjects(void) {
addot(OT_SHOPPOTION, "potion store", "A small kiosk dealing in liqour and potions.", MT_METAL, 500, OC_BUILDING, SZ_LARGE); addot(OT_SHOPPOTION, "potion store", "A small kiosk dealing in liqour and potions.", MT_METAL, 500, OC_BUILDING, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_DRINKABLE, NA, OC_POTION, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
make_basic_shop(lastot->flags); make_basic_shop(lastot->flags, B_ALLOWID);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
addflag(lastot->flags, F_STARTOBCLASS, 100, OC_POTION, RANDOM, NULL); addflag(lastot->flags, F_STARTOBCLASS, 100, OC_POTION, RANDOM, NULL);
} }
@ -1859,9 +1862,11 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_VERYRARE, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_GEM, 75, NA, NULL); addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_GEM, 75, NA, NULL);
addflag(lastot->flags, F_SHOPACCEPTSFLAG, F_HASHIDDENNAME, NA, OC_RING, NULL); // ID only, not sell.
addflag(lastot->flags, F_SHOPMENU, 0, MA_GOTOMENU, SM_PURCHASEITEMS, "a:buy something"); addflag(lastot->flags, F_SHOPMENU, 0, MA_GOTOMENU, SM_PURCHASEITEMS, "a:buy something");
addflag(lastot->flags, F_SHOPMENU, 1, MA_GOTOMENU, SM_SELLITEMS, "b:sell gems"); addflag(lastot->flags, F_SHOPMENU, 1, MA_GOTOMENU, SM_SELLITEMS, "b:sell gems");
addflag(lastot->flags, F_SHOPMENU, 2, MA_QUIT, NA, "q:leave"); addflag(lastot->flags, F_SHOPMENU, 2, MA_GOTOMENU, SM_ID, "i:inspect items");
addflag(lastot->flags, F_SHOPMENU, 3, MA_QUIT, NA, "q:leave");
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "a cash register chiming."); addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "a cash register chiming.");
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
if (onein(3)) { if (onein(3)) {
@ -9034,6 +9039,43 @@ void initrace(void) {
addflag(lastrace->flags, F_TAMABLE, 25, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 25, NA, NA, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, "gne"); addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, "gne");
addrace(R_WYRMSPAWN, "wyrmspawn", 150, '@', C_MAGENTA, MT_FLESH, RC_HUMANOID, "In the rare occasion that a wyrm mates with a human, the result is a wyrmspawn - half-human, half-wyrm. Their scaled skin protects against slashing damage, and those who live long enough gain powerful breath weapons. On the other hand, their innate ego precludes the worship of any god and limits their rate of learning.");
setbodytype(lastrace, BT_HUMANOID);
addbodypart(lastrace, BP_WINGS, NULL);
addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 1, 4, NA, NULL);
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 4, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 65, OC_WEAPON, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_SCROLL, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_SCROLL, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_SCROLL, NA, NULL);
addflag(lastrace->flags, F_STARTJOB, 75, J_RANDOM, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "roars^a roars");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOFLEE, NA, NA, NA, NULL);
// bonuses
addflag(lastrace->flags, F_DTRESIST, DT_SLASH, NA, NA, NULL);
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);
// penalties
addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_LEARNBOOST, -30, NA, NA, NULL);
addflag(lastrace->flags, F_NOPRAY, NA, NA, NA, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, "ne");
// robots // robots
@ -9507,7 +9549,7 @@ void initrace(void) {
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "prolonged peace"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "prolonged peace");
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "the use of poison"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "the use of poison");
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "the use of magic"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "the use of magic");
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "cowardice"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "fleeing from armed foes");
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "dishonourable combat"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "dishonourable combat");
// sacrifices // sacrifices
addflag(lastrace->flags, F_SACRIFICEOBWITHFLAG, F_BATTLESPOILS, NA, 3, "OB explode#S into a shower of blood!"); addflag(lastrace->flags, F_SACRIFICEOBWITHFLAG, F_BATTLESPOILS, NA, 3, "OB explode#S into a shower of blood!");
@ -14284,7 +14326,7 @@ void initrace(void) {
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:4;"); addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:2;");
addflag(lastrace->flags, F_CANWILL, OT_A_SUCKBLOOD, NA, NA, "dam:0d1+4;"); addflag(lastrace->flags, F_CANWILL, OT_A_SUCKBLOOD, NA, NA, "dam:0d1+4;");
addflag(lastrace->flags, F_WANTS, OT_BLOODSPLASH, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_BLOODSPLASH, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_WANTS, OT_BLOODPOOL, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_BLOODPOOL, B_COVETS, NA, NULL);
@ -14464,6 +14506,7 @@ void initrace(void) {
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "scuttle"); addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "scuttle");
addflag(lastrace->flags, F_POISONCORPSE, B_TRUE, NA, NA, NULL);
addrace(R_ROC, "roc", 1, 'A', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Rocs are unbelievably gargantuan birds or prey, large enough to carry a fully-grown elephant. They are generally peaceful, but deadly once provoked."); // 'A' for Avian addrace(R_ROC, "roc", 1, 'A', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Rocs are unbelievably gargantuan birds or prey, large enough to carry a fully-grown elephant. They are generally peaceful, but deadly once provoked."); // 'A' for Avian
setbodytype(lastrace, BT_BIRD); setbodytype(lastrace, BT_BIRD);
@ -17644,9 +17687,13 @@ void killcommand(command_t *cmd) {
} }
} }
void make_basic_shop(flagpile_t *fp) { void make_basic_shop(flagpile_t *fp, int includeid) {
addflag(fp, F_SHOPMENU, 0, MA_GOTOMENU, SM_PURCHASEITEMS, "a:buy something"); int idx = 0;
addflag(fp, F_SHOPMENU, 1, MA_QUIT, NA, "q:leave"); addflag(fp, F_SHOPMENU, idx++, MA_GOTOMENU, SM_PURCHASEITEMS, "a:buy something");
if (includeid) {
addflag(fp, F_SHOPMENU, idx++, MA_GOTOMENU, SM_ID, "i:inspect items");
}
addflag(fp, F_SHOPMENU, idx++, MA_QUIT, NA, "q:leave");
addflag(fp, F_MAKESNOISE, 33, 3, NA, "a cash register chiming."); addflag(fp, F_MAKESNOISE, 33, 3, NA, "a cash register chiming.");
} }

2
data.h
View File

@ -14,5 +14,5 @@ void initskills(void);
void killbehaviour(behaviour_t *b); void killbehaviour(behaviour_t *b);
void killcommand(command_t *cmd); void killcommand(command_t *cmd);
void killoption(option_t *o); void killoption(option_t *o);
void make_basic_shop(flagpile_t *fp); void make_basic_shop(flagpile_t *fp, int includeid);
void sortcommands(void); void sortcommands(void);

Binary file not shown.

20
defs.h
View File

@ -78,6 +78,13 @@
#define B_TRUE (-1) #define B_TRUE (-1)
#define B_MAYBE (-2) #define B_MAYBE (-2)
#define B_ALLOWID (-1)
#define B_NOID (0)
#define B_ONLYIFARMED (-1)
#define B_INCLUDEDISTANT (-1)
#define B_NODISTANT (0)
#define B_MAYCHASE (-1) #define B_MAYCHASE (-1)
#define B_ONLYEXTERNAL (-1) #define B_ONLYEXTERNAL (-1)
#define B_FORCE (-2) #define B_FORCE (-2)
@ -368,6 +375,7 @@ enum TRADEINFOTYPE {
enum SHOPACTION { enum SHOPACTION {
SA_BUY, SA_BUY,
SA_SELL, SA_SELL,
SA_ID,
}; };
/////////////////////////////////////// ///////////////////////////////////////
@ -997,6 +1005,7 @@ enum RACE {
R_ELF, R_ELF,
R_HUMAN, R_HUMAN,
R_MAMMOAN, R_MAMMOAN,
R_WYRMSPAWN,
// robots // robots
R_ANDROID, R_ANDROID,
R_BOTRIOT, R_BOTRIOT,
@ -2688,8 +2697,9 @@ enum FLAG {
F_BANNEDLF, // lfid v0 is not allowed to enter this shop F_BANNEDLF, // lfid v0 is not allowed to enter this shop
F_SHOP, // this object is a shop F_SHOP, // this object is a shop
F_SHOPDONATED, // v0 = how much gold worth you have donated F_SHOPDONATED, // v0 = how much gold worth you have donated
F_SHOPACCEPTSFLAG, // v0 = can sell items with flag v0 to this shop, for F_SHOPACCEPTSFLAG, // v0 = can sell/id items with flag v0 to this shop, for
// v1 percent of full value. // v1 percent of full value you can sell for
// NA means 'you can't sell it' (ie. id only)
// v2 = must be this objectclass (or NA) // v2 = must be this objectclass (or NA)
F_SHOPMENU, // defines a menu for interaction with a shop F_SHOPMENU, // defines a menu for interaction with a shop
// v0 = (menuid*100) + itemorder // v0 = (menuid*100) + itemorder
@ -3244,6 +3254,7 @@ enum FLAG {
F_FLEEONDAM, // lf will run away instead of counterattacking F_FLEEONDAM, // lf will run away instead of counterattacking
F_FLEEONHPPCT, // lf will run away if its hp drop to v0% or lower F_FLEEONHPPCT, // lf will run away if its hp drop to v0% or lower
F_NOFLEE, // lf will not run away F_NOFLEE, // lf will not run away
F_NOPRAY, // lf cannor pray
F_ATTACKRANGE, // v0/v1 = min/max celldist to stay away F_ATTACKRANGE, // v0/v1 = min/max celldist to stay away
// from f_targetlf (ie. lf we are attacking) // from f_targetlf (ie. lf we are attacking)
F_FOLLOWRANGE, // v0/v1 = min/max celldist to stay away F_FOLLOWRANGE, // v0/v1 = min/max celldist to stay away
@ -3565,7 +3576,8 @@ enum FLAG {
F_RISEASGHOST, // become a ghost when you die. F_RISEASGHOST, // become a ghost when you die.
F_SEEINDARK, // nightvis range is val0 F_SEEINDARK, // nightvis range is val0
F_SEEINVIS, // can see invisible things F_SEEINVIS, // can see invisible things
F_SPIDERCLIMB, // lf can climb at 100% success rate F_SPIDERCLIMB, // lf can climb at 100% success rate, and climbing
// does not drain their stamina.
F_SILENTMOVE, // lf makes no noise when walking/flying F_SILENTMOVE, // lf makes no noise when walking/flying
F_SIXTHSENSE, // warned about nearby enemies. v0 = power. F_SIXTHSENSE, // warned about nearby enemies. v0 = power.
F_STABILITY, // doesn't slip over F_STABILITY, // doesn't slip over
@ -4717,6 +4729,8 @@ enum SHOPMENU {
// weapon/armour shops // weapon/armour shops
SM_RESIZE = -9, SM_RESIZE = -9,
SM_REPAIR = -10, SM_REPAIR = -10,
// various shops
SM_ID = -11,
}; };
enum SHOPRETURN { enum SHOPRETURN {

12
god.c
View File

@ -1779,7 +1779,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
cell_t *c; cell_t *c;
object_t *o; object_t *o;
case R_GODBATTLE: case R_GODBATTLE:
if (isinbattle(player, B_TRUE)) { if (isinbattle(player, B_INCLUDEDISTANT, B_FALSE)) {
int redo = B_TRUE; int redo = B_TRUE;
object_t *o; object_t *o;
@ -1886,7 +1886,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
dospelleffects(god, OT_S_CUREPOISON, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL); dospelleffects(god, OT_S_CUREPOISON, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE, NULL);
} }
if (isinbattle(lf, B_TRUE)) { if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
int i,nretflags; int i,nretflags;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
// smite evil // smite evil
@ -2064,7 +2064,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
donesomething = B_TRUE; donesomething = B_TRUE;
statdirty = B_TRUE; statdirty = B_TRUE;
} }
if (isinbattle(lf, B_TRUE)) { if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
if (plev >= PL_INDIFFERENT) { if (plev >= PL_INDIFFERENT) {
dospelleffects(NULL, OT_S_HEAVENARM, plev+1, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE, NULL); dospelleffects(NULL, OT_S_HEAVENARM, plev+1, player, NULL, player->cell, B_UNCURSED, NULL, B_FALSE, NULL);
donesomething = B_TRUE; donesomething = B_TRUE;
@ -2088,7 +2088,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
} }
break; break;
case R_GODTHIEVES: case R_GODTHIEVES:
if (isinbattle(lf, B_TRUE)) { if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
lifeform_t *l; lifeform_t *l;
int donesomething = B_FALSE; int donesomething = B_FALSE;
if (islowhp(lf)) { if (islowhp(lf)) {
@ -2240,7 +2240,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
} }
break; break;
case R_GODMERCY: case R_GODMERCY:
if (isinbattle(lf, B_TRUE)) { if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
lifeform_t *l; lifeform_t *l;
int donesomething = B_FALSE; int donesomething = B_FALSE;
int preventstoning = B_FALSE; int preventstoning = B_FALSE;
@ -2304,7 +2304,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
uncurse_one_equipped(lf, "\"Let thy curse be ended!\""); uncurse_one_equipped(lf, "\"Let thy curse be ended!\"");
break; break;
case R_GODNATURE: case R_GODNATURE:
if (isinbattle(lf, B_TRUE)) { if (isinbattle(lf, B_INCLUDEDISTANT, B_FALSE)) {
lifeform_t *l; lifeform_t *l;
int donesomething = B_FALSE; int donesomething = B_FALSE;
int redo = B_TRUE; int redo = B_TRUE;

93
io.c
View File

@ -2985,7 +2985,7 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi
char pricebuf[BUFLEN]; char pricebuf[BUFLEN];
int markdownpct; int markdownpct;
for (n = 0; n < nsellflags; n++) { for (n = 0; n < nsellflags; n++) {
if (obmatchessellflag(mylist[i], sellflag[n])) { if (obmatchessellflag(mylist[i], sellflag[n], SA_SELL)) {
curflag = sellflag[n]; curflag = sellflag[n];
break; break;
} }
@ -7272,7 +7272,7 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
case F_FLYING: if (lorelev >= PR_NOVICE) sprintf(buf, "Can fly at will"); break; case F_FLYING: if (lorelev >= PR_NOVICE) sprintf(buf, "Can fly at will"); break;
case F_HEAVYBLOW: if (lorelev >= PR_ADEPT) sprintf(buf, "Attacks will knock enemies backwards"); break; case F_HEAVYBLOW: if (lorelev >= PR_ADEPT) sprintf(buf, "Attacks will knock enemies backwards"); break;
case F_HITCONFER: case F_HITCONFER:
if (lorelev >= PR_ADEPT) { if (lorelev >= PR_BEGINNER) {
if (f->val[0] == F_POISONED) { if (f->val[0] == F_POISONED) {
poisontype_t *pt; poisontype_t *pt;
pt = findpoisontype(f->val[1]); pt = findpoisontype(f->val[1]);
@ -7281,6 +7281,11 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
} }
break; break;
case F_HUMANOID: if (!forplayersel) sprintf(buf, "Can use weapons and armour."); break; case F_HUMANOID: if (!forplayersel) sprintf(buf, "Can use weapons and armour."); break;
case F_LEARNBOOST:
if ((lorelev >= PR_BEGINNER) && (f->val[0] >= 0)) {
sprintf(buf, "Gains XP %d%% faster.", f->val[0]);
}
break;
case F_LEVITATING: if (lorelev >= PR_NOVICE) sprintf(buf, "Can levitate at will"); break; case F_LEVITATING: if (lorelev >= PR_NOVICE) sprintf(buf, "Can levitate at will"); break;
case F_MEDITATES: if (lorelev >= PR_ADEPT) sprintf(buf, "Meditates to retain awareness while sleeping."); break; case F_MEDITATES: if (lorelev >= PR_ADEPT) sprintf(buf, "Meditates to retain awareness while sleeping."); break;
case F_MPMOD: if (f->val[0] > 0) sprintf(buf, "+%d Mana", f->val[0]); break; case F_MPMOD: if (f->val[0] > 0) sprintf(buf, "+%d Mana", f->val[0]); break;
@ -7374,6 +7379,11 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
} }
break; break;
case F_FASTMETAB: if (lorelev >= PR_BEGINNER) sprintf(buf, "Fast metabolism (needs to eat often)"); break; case F_FASTMETAB: if (lorelev >= PR_BEGINNER) sprintf(buf, "Fast metabolism (needs to eat often)"); break;
case F_LEARNBOOST:
if ((lorelev >= PR_BEGINNER) && (f->val[0] < 0)) {
sprintf(buf, "Gains XP %d%% slower.", abs(f->val[0]));
}
break;
case F_MATVULN: case F_MATVULN:
if (lorelev >= PR_ADEPT) { if (lorelev >= PR_ADEPT) {
mt = findmaterial(f->val[0]); mt = findmaterial(f->val[0]);
@ -7382,6 +7392,7 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel
break; break;
case F_MPMOD: if (f->val[0] < 0) sprintf(buf, "%d Mana", f->val[0]); break; case F_MPMOD: if (f->val[0] < 0) sprintf(buf, "%d Mana", f->val[0]); break;
case F_NEEDSWATER: if (lorelev >= PR_NOVICE) sprintf(buf, "Will suffocate without water"); break; case F_NEEDSWATER: if (lorelev >= PR_NOVICE) sprintf(buf, "Will suffocate without water"); break;
case F_NOPRAY: if (lorelev >= PR_BEGINNER) sprintf(buf, "Cannot worship gods."); break;
case F_NOSMELL: if ((lorelev >= PR_NOVICE) ) sprintf(buf, "No sense of smell."); break; case F_NOSMELL: if ((lorelev >= PR_NOVICE) ) sprintf(buf, "No sense of smell."); break;
case F_NOCTURNAL: if ((lorelev >= PR_BEGINNER) && !forplayersel) sprintf(buf, "Sleeps during the day."); break; case F_NOCTURNAL: if ((lorelev >= PR_BEGINNER) && !forplayersel) sprintf(buf, "Sleeps during the day."); break;
case F_NOSPELLS: if (lorelev >= PR_NOVICE) sprintf(buf, "Cannot use magic."); break; case F_NOSPELLS: if (lorelev >= PR_NOVICE) sprintf(buf, "Cannot use magic."); break;
@ -11210,6 +11221,7 @@ void showlfarmour(lifeform_t *lf) {
void showlfstats(lifeform_t *lf, int showall) { void showlfstats(lifeform_t *lf, int showall) {
int y = 0, y2 = 0, x2 = 40; int y = 0, y2 = 0, x2 = 40;
int starty;
int x; int x;
int arating, evasion; int arating, evasion;
int acc; int acc;
@ -11294,11 +11306,13 @@ void showlfstats(lifeform_t *lf, int showall) {
y = 0; y = 0;
ch = '\0'; ch = '\0';
if (mode == '@') { if (mode == '@') {
wattron(mainwin, A_UNDERLINE);
if (isplayer(lf)) { if (isplayer(lf)) {
centre(mainwin, C_WHITE, 0, "CHARACTER DETAILS"); centre(mainwin, C_WHITE, 0, "CHARACTER DETAILS");
} else{ } else{
centre(mainwin, C_WHITE, 0, "MONSTER DETAILS"); centre(mainwin, C_WHITE, 0, "MONSTER DETAILS");
} }
wattroff(mainwin, A_UNDERLINE);
x = 0; x = 0;
centre(mainwin, C_MAGENTA, 1, "[Press ? for a full description]"); centre(mainwin, C_MAGENTA, 1, "[Press ? for a full description]");
@ -11794,6 +11808,12 @@ void showlfstats(lifeform_t *lf, int showall) {
y = y2 + 1; y = y2 + 1;
} }
wattron(mainwin, A_UNDERLINE);
centre(mainwin, C_WHITE, y, "THREAT ASSESSMENT");
wattroff(mainwin, A_UNDERLINE);
y++;
starty = y;
/* /*
if (!isplayer(lf)) { if (!isplayer(lf)) {
char *descbuf = NULL; char *descbuf = NULL;
@ -11852,6 +11872,49 @@ void showlfstats(lifeform_t *lf, int showall) {
// extra info from lore? // extra info from lore?
if (lorelev >= PR_SKILLED) { if (lorelev >= PR_SKILLED) {
int hitstokillyou,hitstokillit; int hitstokillyou,hitstokillit;
// append behaviour text
f = lfhasflag(lf, F_BEHAVIOUR);
if (f) {
behaviour_t *b;
b = findbehaviour(f->val[0]);
if (b) {
char bhtext[BUFLEN];
switch (b->id) {
case BH_INSANE:
sprintf(bhtext, "It is insane, and will attack anyone who comes close. ");
break;
case BH_TIMID:
sprintf(bhtext, "It is timid, and will flee upon taking damage. ");
break;
case BH_DRUGGED:
sprintf(bhtext, "It is drugged, and will never flee. ");
break;
case BH_DETERMINED:
sprintf(bhtext, "It is determined, and will chase you for longer. ");
break;
case BH_LAZY:
sprintf(bhtext, "It is lazy, and won't chase you very far. ");
break;
case BH_MUSCLED:
sprintf(bhtext, "It is muscled, and has extra hit points. ");
break;
case BH_SCRAWNY:
sprintf(bhtext, "It is scrawy, and has lowered hit points. ");
break;
default:
strcpy(bhtext, "");
break;
}
if (strlen(bhtext)) {
setcol(mainwin, lorecol);
wrapprint(mainwin, &y, &x, 0, "%s", bhtext);
unsetcol(mainwin, lorecol);
}
}
}
hitstokillit = gethitstokill(player, lf, B_TRUE, B_TRUE); hitstokillit = gethitstokill(player, lf, B_TRUE, B_TRUE);
hitstokillyou = gethitstokill(lf, player, B_TRUE, B_TRUE); hitstokillyou = gethitstokill(lf, player, B_TRUE, B_TRUE);
if (hitstokillit == hitstokillyou) { if (hitstokillit == hitstokillyou) {
@ -11952,10 +12015,6 @@ void showlfstats(lifeform_t *lf, int showall) {
if (f && (f->known)) { if (f && (f->known)) {
wrapprint(mainwin, &y, &x, 0, "%s %s climbing on a wall. ", you(lf), is(lf)); wrapprint(mainwin, &y, &x, 0, "%s %s climbing on a wall. ", you(lf), is(lf));
} }
f = lfhasknownflag(lf, F_FASTMETAB);
if (f && (f->known)) {
wrapprint(mainwin, &y, &x, 0, "%s metabolic rate has been increased. ", your(lf), getpossessive(you(lf)));
}
f = lfhasknownflag(lf, F_FEIGNINGDEATH); f = lfhasknownflag(lf, F_FEIGNINGDEATH);
if (f && (f->known)) { if (f && (f->known)) {
wrapprint(mainwin, &y, &x, 0, "%s %s pretending to be dead. ", you(lf), is(lf)); wrapprint(mainwin, &y, &x, 0, "%s %s pretending to be dead. ", you(lf), is(lf));
@ -12143,8 +12202,14 @@ void showlfstats(lifeform_t *lf, int showall) {
mt = findmaterial(getlfmaterial(lf)); mt = findmaterial(getlfmaterial(lf));
wrapprint(mainwin, &y, &x, 0, "%s %s made out of %s. ",you(lf), is(lf), mt->name); wrapprint(mainwin, &y, &x, 0, "%s %s made out of %s. ",you(lf), is(lf), mt->name);
} }
if (y == starty) {
wrapprint(mainwin, &y, &x, 0, "Nothing obvious.");
}
} else if (mode == 'a') { } else if (mode == 'a') {
wattron(mainwin, A_UNDERLINE);
centre(mainwin, C_WHITE, 0, "ABILITIES"); centre(mainwin, C_WHITE, 0, "ABILITIES");
wattroff(mainwin, A_UNDERLINE);
y = 2; y = 2;
for (ot = objecttype ; ot ; ot = ot->next) { for (ot = objecttype ; ot ; ot = ot->next) {
@ -12204,7 +12269,9 @@ void showlfstats(lifeform_t *lf, int showall) {
skill_t *sk; skill_t *sk;
int finished = B_FALSE,dounknown; int finished = B_FALSE,dounknown;
wattron(mainwin, A_UNDERLINE);
centre(mainwin, C_WHITE, 0, "SKILLS"); centre(mainwin, C_WHITE, 0, "SKILLS");
wattroff(mainwin, A_UNDERLINE);
y = 2; y = 2;
@ -12321,7 +12388,9 @@ void showlfstats(lifeform_t *lf, int showall) {
snprintf(subheading, BUFLEN, " %-4s%-26s%-15s%-13s%s","Lv","Spell", "School", "Power", "Cost"); snprintf(subheading, BUFLEN, " %-4s%-26s%-15s%-13s%s","Lv","Spell", "School", "Power", "Cost");
wattron(mainwin, A_UNDERLINE);
centre(mainwin, C_WHITE, y, "MAGIC"); y += 2; centre(mainwin, C_WHITE, y, "MAGIC"); y += 2;
wattroff(mainwin, A_UNDERLINE);
doheading(mainwin, &y, 0, subheading); doheading(mainwin, &y, 0, subheading);
// show spells monster can cast using mp // show spells monster can cast using mp
for (lev = 0; (lev <= 9) && !exitnow; lev++) { for (lev = 0; (lev <= 9) && !exitnow; lev++) {
@ -12403,7 +12472,9 @@ void showlfstats(lifeform_t *lf, int showall) {
enum LFSIZE racesize,cursize; enum LFSIZE racesize,cursize;
x = 0; // override x = 0; // override
// down a line. // down a line.
wattron(mainwin, A_UNDERLINE);
centre(mainwin, C_WHITE, y, "EFFECTS"); centre(mainwin, C_WHITE, y, "EFFECTS");
wattroff(mainwin, A_UNDERLINE);
y += 2; y += 2;
@ -12662,6 +12733,12 @@ void showlfstats(lifeform_t *lf, int showall) {
mvwprintw(mainwin, y, 0, "%s %s %s resistant to magic.", you(lf), is(lf), adjective); mvwprintw(mainwin, y, 0, "%s %s %s resistant to magic.", you(lf), is(lf), adjective);
y++; y++;
} }
f = hasflag_real(lf->flags, F_FASTMETAB, B_TRUE, NULL, FROMRACE);
if (f) {
wrapprint(mainwin, &y, &x, 0, "%s metabolic rate has been increased. ", your(lf), getpossessive(you(lf)));
}
f = hasflag_real(lf->flags, F_TREMORSENSE, B_TRUE, NULL, FROMRACE); f = hasflag_real(lf->flags, F_TREMORSENSE, B_TRUE, NULL, FROMRACE);
if (f) { if (f) {
mvwprintw(mainwin, y, 0, "%s can 'see' by sensing vibrations around %s.", you(lf), you(lf)); mvwprintw(mainwin, y, 0, "%s can 'see' by sensing vibrations around %s.", you(lf), you(lf));
@ -13294,11 +13371,13 @@ void showlfstats(lifeform_t *lf, int showall) {
} else if (mode == 'i') { } else if (mode == 'i') {
object_t *o; object_t *o;
cls(); cls();
wattron(mainwin, A_UNDERLINE);
if (lf == player) { // mindscanning it if (lf == player) { // mindscanning it
centre(mainwin, C_WHITE, 0, "INVENTORY"); centre(mainwin, C_WHITE, 0, "INVENTORY");
} else { // not mindscanning } else { // not mindscanning
centre(mainwin, C_WHITE, 0, "INVENTORY (equipped items only)"); centre(mainwin, C_WHITE, 0, "INVENTORY (equipped items only)");
} }
wattroff(mainwin, A_UNDERLINE);
y = 2; y = 2;
if ((lf == player) && lfhasflag(lf, F_NOPACK)) { if ((lf == player) && lfhasflag(lf, F_NOPACK)) {
@ -13336,7 +13415,9 @@ void showlfstats(lifeform_t *lf, int showall) {
int i; int i;
char line[BUFLEN]; char line[BUFLEN];
cls(); cls();
wattron(mainwin, A_UNDERLINE);
centre(mainwin, C_WHITE, 0, "GODS"); centre(mainwin, C_WHITE, 0, "GODS");
wattroff(mainwin, A_UNDERLINE);
y = 2; y = 2;
snprintf(line, BUFLEN, "%-30s Prayed? %-22s %s","God","Piety", "Happiness"); snprintf(line, BUFLEN, "%-30s Prayed? %-22s %s","God","Piety", "Happiness");

14
lf.c
View File

@ -13104,13 +13104,15 @@ flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt, int onlytemp) {
} }
int isinbattle(lifeform_t *lf, int includedistant) { int isinbattle(lifeform_t *lf, int includedistant, int onlyarmed) {
if (includedistant) { if (includedistant) {
lifeform_t *l; lifeform_t *l;
for (l = lf->cell->map->lf ; l ;l = l->next) { for (l = lf->cell->map->lf ; l ;l = l->next) {
if ((l != lf) && areenemies(l, lf) && cansee(lf, l)) { if ((l != lf) && areenemies(l, lf) && cansee(lf, l)) {
if (!lfhasflag(l, F_DOESNTMOVE)) { if (!lfhasflag(l, F_DOESNTMOVE)) {
return B_TRUE; if (!onlyarmed || getweapon(l)) {
return B_TRUE;
}
} }
} }
} }
@ -13121,7 +13123,9 @@ int isinbattle(lifeform_t *lf, int includedistant) {
c = getcellindir(lf->cell, dir); c = getcellindir(lf->cell, dir);
if (c && c->lf && areenemies(lf, c->lf) && cansee(lf, c->lf)) { if (c && c->lf && areenemies(lf, c->lf) && cansee(lf, c->lf)) {
if (!lfhasflag(c->lf, F_DOESNTMOVE)) { if (!lfhasflag(c->lf, F_DOESNTMOVE)) {
return B_TRUE; if (!onlyarmed || getweapon(c->lf)) {
return B_TRUE;
}
} }
} }
} }
@ -19971,7 +19975,7 @@ void startlfturn(lifeform_t *lf) {
// they are hiding, and you haven't spotted them yet // they are hiding, and you haven't spotted them yet
f = ishidingfrom(l, lf); f = ishidingfrom(l, lf);
if (f && !isinbattle(lf, B_FALSE)) { if (f && !isinbattle(lf, B_NODISTANT, B_FALSE)) {
// can you see their cell? // can you see their cell?
if (!lfhasflag(lf, F_TRAINING) && haslos(lf, l->cell)) { if (!lfhasflag(lf, F_TRAINING) && haslos(lf, l->cell)) {
int bonus = 0; int bonus = 0;
@ -19995,7 +19999,7 @@ void startlfturn(lifeform_t *lf) {
} }
// secret doors, traps, etc? // secret doors, traps, etc?
if (isplayer(lf) && !isinbattle(lf, B_TRUE) && !isblind(lf) && !lfhasflag(lf, F_TRAINING)) { if (isplayer(lf) && !isinbattle(lf, B_INCLUDEDISTANT, B_FALSE) && !isblind(lf) && !lfhasflag(lf, F_TRAINING)) {
for (i = 0; i < lf->nlos; i++) { for (i = 0; i < lf->nlos; i++) {
if (!lf->los[i]->lf || (lf->los[i]->lf == lf)) { if (!lf->los[i]->lf || (lf->los[i]->lf == lf)) {
object_t *o; object_t *o;

2
lf.h
View File

@ -338,7 +338,7 @@ flag_t *ishidingfrom(lifeform_t *hider, lifeform_t *seeker);
int ishirable(lifeform_t *lf); int ishirable(lifeform_t *lf);
int isimmobile(lifeform_t *lf); int isimmobile(lifeform_t *lf);
flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt, int onlytemp); flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt, int onlytemp);
int isinbattle(lifeform_t *lf, int includedistant); int isinbattle(lifeform_t *lf, int includedistant, int onlyarmed);
int isingunrange(lifeform_t *lf, cell_t *where); int isingunrange(lifeform_t *lf, cell_t *where);
int isliving(lifeform_t *lf); int isliving(lifeform_t *lf);
int isloreskill(enum SKILL skid); int isloreskill(enum SKILL skid);

22
move.c
View File

@ -139,7 +139,7 @@ int canswapwith(lifeform_t *lf, lifeform_t *lf2) {
} }
if (isplayer(lf) && !areenemies(lf, lf2)) { if (isplayer(lf) && !areenemies(lf, lf2)) {
if (isknownpeaceful(lf2)) { if (isknownpeaceful(lf2)) {
// player can swap with peaceful lgs // player can swap with peaceful lfs
// if they are a lot smaller // if they are a lot smaller
if (getlfsize(lf) - getlfsize(lf2) >= 2) { if (getlfsize(lf) - getlfsize(lf2) >= 2) {
return B_TRUE; return B_TRUE;
@ -198,8 +198,9 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
return B_TRUE; return B_TRUE;
} }
if (o->type->id == OT_PENTAGRAM) { if (o->type->id == OT_PENTAGRAM) {
// this is only dangerous for the player // this is only dangerous for the player, and only if they have
if (isplayer(lf)) { // above average wisdom
if (isplayer(lf) && (wis >= AT_GTAVERAGE)) {
object_t *oo; object_t *oo;
// any blessed objects in your pack? // any blessed objects in your pack?
for (oo = lf->pack->first ; oo ; oo = oo->next) { for (oo = lf->pack->first ; oo ; oo = oo->next) {
@ -2335,7 +2336,9 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int onpurpose, int *didmsg) {
reason = E_OK; reason = E_OK;
return B_TRUE; return B_TRUE;
} }
modstamina(lf, -1); if (!lfhasflag(lf, F_SPIDERCLIMB)) {
modstamina(lf, -1);
}
} }
} }
} }
@ -2778,9 +2781,14 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
int reldir; int reldir;
int srcmoney = 0; int srcmoney = 0;
int prebattle = B_FALSE; int prebattle = B_FALSE;
int prebattlearmed = B_FALSE;
flag_t *f; flag_t *f;
// are we next to an enemy who we can see? // are we next to an enemy who we can see?
prebattle = isinbattle(lf, B_FALSE); prebattle = isinbattle(lf, B_NODISTANT, B_FALSE);
if (isplayer(lf)) {
// only care about this for players
prebattlearmed = isinbattle(lf, B_NODISTANT, B_ONLYIFARMED);
}
howlong = getmovespeed(lf); howlong = getmovespeed(lf);
@ -2809,7 +2817,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
} }
// check for fleeing... // check for fleeing...
if (isplayer(lf) && !isdead(lf)) { if (isplayer(lf) && !isdead(lf)) {
if (prebattle && !isinbattle(lf, B_FALSE) && onpurpose) { if (prebattlearmed && !isinbattle(lf, B_NODISTANT, B_ONLYIFARMED) && onpurpose) {
angergodmaybe(R_GODBATTLE, 5, GA_COWARD); angergodmaybe(R_GODBATTLE, 5, GA_COWARD);
} }
} }
@ -3317,7 +3325,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
// check for fleeing... // check for fleeing...
if (isplayer(lf) && !isdead(lf)) { if (isplayer(lf) && !isdead(lf)) {
if (prebattle && !isinbattle(lf, B_FALSE) && onpurpose) { if (prebattlearmed && !isinbattle(lf, B_NODISTANT, B_ONLYIFARMED) && onpurpose) {
angergodmaybe(R_GODBATTLE, 10, GA_COWARD); angergodmaybe(R_GODBATTLE, 10, GA_COWARD);
} }
} }

110
shops.c
View File

@ -20,6 +20,7 @@
#define DEF_REMCURSECOST 60 #define DEF_REMCURSECOST 60
#define DEF_BLESSCOST 50 #define DEF_BLESSCOST 50
#define DEF_IDCOST 50
#define DEF_SURCHARGE 15 #define DEF_SURCHARGE 15
#define DEF_RESIZECOST 80 #define DEF_RESIZECOST 80
#define DEF_REPAIRCOSTPERHP 2 #define DEF_REPAIRCOSTPERHP 2
@ -118,10 +119,13 @@ int getshopblessprice(object_t *o, object_t *shop) {
return cost; return cost;
} }
int obmatchessellflag(object_t *o, flag_t *f) { int obmatchessellflag(object_t *o, flag_t *f, enum SHOPACTION action) {
if ((f->val[0] == F_NONE) || hasflag(o->flags, f->val[0])) { if ((f->val[0] == F_NONE) || hasflag(o->flags, f->val[0])) {
if ((f->val[2] == NA) || (o->type->obclass->id == f->val[2])) { if ((f->val[2] == NA) || (o->type->obclass->id == f->val[2])) {
return B_TRUE; if ((action == SA_SELL) && (f->val[1] == NA)) {
} else {
return B_TRUE;
}
} }
} }
return B_FALSE; return B_FALSE;
@ -217,6 +221,9 @@ void shop(lifeform_t *lf, object_t *vm) {
} else if (curmenu == SM_DONATE) { } else if (curmenu == SM_DONATE) {
shopfunc = shopdonate; shopfunc = shopdonate;
shoparg = &ngiven; shoparg = &ngiven;
} else if (curmenu == SM_ID) {
shopfunc = shopid;
shoparg = &ngiven;
} else if (curmenu == SM_REST) { } else if (curmenu == SM_REST) {
shopfunc = shoprest; shopfunc = shoprest;
shoparg = &ngiven; shoparg = &ngiven;
@ -629,6 +636,84 @@ enum SHOPRETURN shopbless(lifeform_t *lf, object_t *vm, int starty, char *toptex
return SR_CONTINUE; return SR_CONTINUE;
} }
enum SHOPRETURN shopid(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *nid) {
flag_t *sellflag[MAXCANDIDATES];
char buf[BUFLEN],obname[BUFLEN];
int nsellflags;
object_t *o;
int y,ch,i;
int cost = DEF_IDCOST;
y = starty;
cost = applyshoppricemod(DEF_IDCOST,lf, vm, SA_ID);
*nid = 0;
mvwprintw(mainwin, y, 0, "We can help inspect your items for a small fee."); y += 2;
mvwprintw(mainwin, y, 0, "For just $%d per item we can reveal their general purpose,", cost); y++;
mvwprintw(mainwin, y, 0, "however please note that we are unable to detect magical"); y++;
mvwprintw(mainwin, y, 0, "enchantments or blessings.", cost); y += 2;
mvwprintw(mainwin, y, 0, "Identify items [y/n]? ", countmoney(lf->pack));
ch = getch();
if (ch != 'y') {
return SR_BACK;
}
getflags(vm->flags, sellflag, &nsellflags, F_SHOPACCEPTSFLAG, F_NONE);
// ask what to sell
sprintf(buf, "What would you like to inspect (you have $%d)?", countmoney(lf->pack));
initprompt(&prompt, buf);
prompt.maycancel = B_TRUE;
for (o = player->pack->first ; o ; o = o->next) {
int ok = B_FALSE;
for (i = 0; i < nsellflags; i++) {
if (obmatchessellflag(o, sellflag[i], SA_ID)) {
if (!isknown(o)) {
ok = B_TRUE;
break;
}
}
}
if (ok) {
char costbuf[BUFLEN];
getobname(o, buf, o->amt);
sprintf(costbuf, "%-60s($%d)", buf, cost);
addchoice(&prompt, o->letter, costbuf, costbuf, o, NULL);
}
}
addchoice(&prompt, '-', "(nothing)", NULL, NULL, NULL);
ch = getchoice(&prompt);
o = (object_t *)prompt.result;
if (!o) {
return SR_BACK;
}
// confirm
getobname(o, obname, o->amt);
if (countmoney(player->pack) < cost) {
msg("You cannot afford the $%d inspection fee.", cost);
more();
} else {
// pay.
msg("You hand over $%d.", cost); more();
givemoney(player, NULL, cost);
// id it.
makeknown(o->type->id);
// get name again
getobname(o, obname, o->amt);
// tell the player
msg("\"%s %s.\"",(o->amt == 1) ? "That is" : "Those are", obname);
more();
}
return SR_CONTINUE;
}
enum SHOPRETURN shopmiracle(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *ndonated) { enum SHOPRETURN shopmiracle(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *ndonated) {
char ch; char ch;
@ -788,16 +873,19 @@ enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *top
// only list gold if you have enough // only list gold if you have enough
if (getobvalue(oo) >= value) valid = B_TRUE; if (getobvalue(oo) >= value) valid = B_TRUE;
strcpy(fullname, moneyname); strcpy(fullname, moneyname);
} else if ((slev >= PR_BEGINNER) && hasflag(oo->flags, F_GEM)) { } else if (hasflag(oo->flags, F_GEM)) {
// only list gems which are worth enough // gems are only valid if our psychology skill is high
int thisval; // enough to convince the shopkeeper to accept them.
thisval = applyshoppricemod(getobvalue(oo), player, vm, SA_SELL); if (slev >= PR_BEGINNER) {
if (thisval >= value) { int thisval;
valid = B_TRUE; thisval = applyshoppricemod(getobvalue(oo), player, vm, SA_SELL);
sprintf(fullname, "%s (worth $%d)", moneyname, thisval); if (thisval >= value) {
valid = B_TRUE;
sprintf(fullname, "%s (worth $%d)", moneyname, thisval);
}
} }
} else { } else {
// always list cards // always list anything else (credit cards)
valid = B_TRUE; valid = B_TRUE;
strcpy(fullname, moneyname); strcpy(fullname, moneyname);
} }
@ -1165,7 +1253,7 @@ enum SHOPRETURN shopsell(lifeform_t *lf, object_t *vm, int starty, char *toptext
// get matching sell flag // get matching sell flag
curflag = NULL; curflag = NULL;
for (i = 0; i < nsellflags; i++) { for (i = 0; i < nsellflags; i++) {
if (obmatchessellflag(o, sellflag[i])) { if (obmatchessellflag(o, sellflag[i], SA_SELL)) {
curflag = sellflag[i]; curflag = sellflag[i];
break; break;
} }

View File

@ -4,12 +4,13 @@ int apply_shopob_restrictions(char *buf);
float applyshoppricemod(float origprice, lifeform_t *lf, object_t *shop, enum SHOPACTION action); float applyshoppricemod(float origprice, lifeform_t *lf, object_t *shop, enum SHOPACTION action);
int canafford(lifeform_t *lf, int amt); int canafford(lifeform_t *lf, int amt);
int getshopblessprice(object_t *o, object_t *shop); int getshopblessprice(object_t *o, object_t *shop);
int obmatchessellflag(object_t *o, flag_t *f); int obmatchessellflag(object_t *o, flag_t *f, enum SHOPACTION action);
void shop(lifeform_t *lf, object_t *vm); void shop(lifeform_t *lf, object_t *vm);
enum SHOPRETURN shopabsolve(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *ndonated); enum SHOPRETURN shopabsolve(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *ndonated);
enum SHOPRETURN shopbless(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *ndonated); enum SHOPRETURN shopbless(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *ndonated);
enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased); enum SHOPRETURN shopdonate(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased);
enum SHOPRETURN shopdetectcurse(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased); enum SHOPRETURN shopdetectcurse(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased);
enum SHOPRETURN shopid(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *nid);
enum SHOPRETURN shopmiracle(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased); enum SHOPRETURN shopmiracle(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased);
enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased); enum SHOPRETURN shoppurchase(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased);
enum SHOPRETURN shoprepair(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased); enum SHOPRETURN shoprepair(lifeform_t *lf, object_t *vm, int starty, char *toptext, int *npurchased);

72
spell.c
View File

@ -2600,6 +2600,13 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} else if (abilid == OT_A_PRAY) { } else if (abilid == OT_A_PRAY) {
lifeform_t *god; lifeform_t *god;
if (!isplayer(user)) return B_FALSE; if (!isplayer(user)) return B_FALSE;
if (lfhasflag(player, F_NOPRAY)) {
if (isplayer(user)) {
msg("Your pride prevents you from worshipping another being.");
}
return B_TRUE;
}
// ask for which god // ask for which god
initprompt(&prompt, "To whom will you pray?"); initprompt(&prompt, "To whom will you pray?");
@ -12445,50 +12452,55 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (ch == 'a') { // wealth (gold, bad: goldtouch) if (ch == 'a') { // wealth (gold, bad: goldtouch)
snprintf(buf, BUFLEN, "1000-2000 gold coins"); snprintf(buf, BUFLEN, "1000-2000 gold coins");
} else if (ch == 'b') { // power (weapons, bad: battery) } else if (ch == 'b') { // power (weapons, bad: battery)
skill_t *sk,*poss[MAXSKILLS]; if (blessed == B_CURSED) {
int nposs = 0; snprintf(buf, BUFLEN, "battery");
// get a list of all valid weapon skills } else {
for (sk = firstskill ; sk ; sk = sk->next) { skill_t *sk,*poss[MAXSKILLS];
if (isweaponskill(sk->id) && getskill(target, sk->id)) { int nposs = 0;
poss[nposs++] = sk; // get a list of all valid weapon skills
} for (sk = firstskill ; sk ; sk = sk->next) {
} if (isweaponskill(sk->id) && getskill(target, sk->id)) {
if (nposs) { poss[nposs++] = sk;
int nweps = 0;
objecttype_t *ot;
// pick a random one
sk = poss[rnd(0,nposs-1)];
// find all associated weapons
for (ot = objecttype ; ot ; ot = ot->next) {
if (hasflagval(ot->flags, F_USESSKILL, sk->id, NA, NA, NULL)) {
nweps++;
} }
} }
if (nweps) { if (nposs) {
int sel,n = 0; int nweps = 0;
sel = rnd(0,nweps-1); objecttype_t *ot;
// pick a random one
sk = poss[rnd(0,nposs-1)];
// find all associated weapons
for (ot = objecttype ; ot ; ot = ot->next) { for (ot = objecttype ; ot ; ot = ot->next) {
if (hasflagval(ot->flags, F_USESSKILL, sk->id, NA, NA, NULL)) { if (hasflagval(ot->flags, F_USESSKILL, sk->id, NA, NA, NULL)) {
if (n == sel) break; nweps++;
n++;
} }
} }
snprintf(buf, BUFLEN, "excellent branded %s", ot->name); if (nweps) {
int sel,n = 0;
sel = rnd(0,nweps-1);
for (ot = objecttype ; ot ; ot = ot->next) {
if (hasflagval(ot->flags, F_USESSKILL, sk->id, NA, NA, NULL)) {
if (n == sel) break;
n++;
}
}
snprintf(buf, BUFLEN, "excellent branded %s", ot->name);
} else {
snprintf(buf, BUFLEN, "stick");
}
} else { } else {
snprintf(buf, BUFLEN, "stick"); snprintf(buf, BUFLEN, "stick");
} }
} else {
snprintf(buf, BUFLEN, "stick");
} }
} else if (ch == 'c') { // protection. bad: turn to stone } else if (ch == 'c') { // protection. bad: turn to stone
enum BODYPART bp,poss[MAXBODYPARTS]; enum BODYPART bp,poss[MAXBODYPARTS];
int nposs = 0; int nposs = 0;
// get a list of all valid body parts // get a list of all valid body parts
for (bp = 0; bp <= MAXBODYPARTS; bp++) { if (hasbp(target, BP_HEAD)) poss[nposs++] = BP_HEAD;
if (!lfhasflagval(target, F_NOBODYPART, bp, NA, NA, NULL)) { if (hasbp(target, BP_SHOULDERS)) poss[nposs++] = BP_SHOULDERS;
poss[nposs++] = bp; if (hasbp(target, BP_BODY)) poss[nposs++] = BP_BODY;
} if (hasbp(target, BP_LEGS)) poss[nposs++] = BP_LEGS;
} if (hasbp(target, BP_FEET)) poss[nposs++] = BP_FEET;
if (hasbp(target, BP_HANDS)) poss[nposs++] = BP_HANDS;
if (nposs) { if (nposs) {
int narms = 0; int narms = 0;
objecttype_t *ot; objecttype_t *ot;