- [+] change cooking skill - make it determien the size of the corpse

you are able to cook.
- [+] then greatly increase chances of getting sick from raw meat.
- [+] and decrease nutrition for raw meat again
- [+] wizard classes should get random spells on level up
- [+] Interact (with adjacent things)
    - [+] add new command
    - [+] bookshelf
    - [+] wardrobes (contain clothes)
    - [+] open barrels
    - [+] computers
- [+] only show "it currently contains..." for containers which you
      have opened.
    - [+] F_BEENOPENED.
- [+] some barrels are randomly jammed
- [+] change jam to be strength check.
- [+] change skillcheck roll - now only 1-50
- [+] monsters shouldn't cast lethargy if you're already exhasted
- [+] lethargy should cancel rage.
- [+] change spellbooks - always id them but you might not be able to
      read them.
new vaults:
- [+] goblin nest
- [+] orc fort
This commit is contained in:
Rob Pearce 2012-12-23 22:02:52 +00:00
parent 67d6d4b30b
commit 60914f4842
14 changed files with 489 additions and 264 deletions

5
ai.c
View File

@ -3148,6 +3148,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
if ((ot->id == OT_A_IRONFIST) && getweapon(lf)) { if ((ot->id == OT_A_IRONFIST) && getweapon(lf)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
if (ot->id == OT_S_LETHARGY) {
if (getstamina(victim) <= 0) {
specificcheckok = B_FALSE;
}
}
if ((ot->id == OT_S_PARALYZE) && lfhasflag(victim, F_PARALYZED)) { if ((ot->id == OT_S_PARALYZE) && lfhasflag(victim, F_PARALYZED)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }

173
data.c
View File

@ -183,6 +183,7 @@ void initcommands(void) {
//addcommand(CMD_DROP, 'd', "Drop an item."); //addcommand(CMD_DROP, 'd', "Drop an item.");
addcommand(CMD_DROPMULTI, 'd', "Drop one or more items."); addcommand(CMD_DROPMULTI, 'd', "Drop one or more items.");
addcommand(CMD_EAT, 'e', "Eat something."); addcommand(CMD_EAT, 'e', "Eat something.");
addcommand(CMD_INTERACT, 'I', "Interact with adjacent objects.");
addcommand(CMD_MAGIC, 'm', "Use magic or abilities."); addcommand(CMD_MAGIC, 'm', "Use magic or abilities.");
addcommand(CMD_MEMMAGIC, 'M', "Memorise a hotkey for magic or abilities."); addcommand(CMD_MEMMAGIC, 'M', "Memorise a hotkey for magic or abilities.");
addcommand(CMD_OFFER, 'O', "Offer a sacrifice to the gods."); addcommand(CMD_OFFER, 'O', "Offer a sacrifice to the gods.");
@ -1137,6 +1138,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_SELECTWEAPON, OT_LONGSWORD, NA, NA, NULL); addflag(lastjob->flags, F_SELECTWEAPON, OT_LONGSWORD, NA, NA, NULL);
addflag(lastjob->flags, F_SELECTWEAPON, OT_SHORTSWORD, NA, NA, NULL); addflag(lastjob->flags, F_SELECTWEAPON, OT_SHORTSWORD, NA, NA, NULL);
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
addflag(lastjob->flags, F_LEVSPELLSCHOOLFROMX, 103, SS_NONE, 3, NULL); // new spell every 3 level
addjob(J_PALADIN, "Paladin", "Paladins are holy warriors dedicated to the Goddess of Life. They gain powerful abilities and have access to healing magics, but these powers are dependant upon their goddess' approval. Paladins must take holy vows to only ever use battle equipiment which has first been blessed.", JC_FIGHTERMAGE); addjob(J_PALADIN, "Paladin", "Paladins are holy warriors dedicated to the Goddess of Life. They gain powerful abilities and have access to healing magics, but these powers are dependant upon their goddess' approval. Paladins must take holy vows to only ever use battle equipiment which has first been blessed.", JC_FIGHTERMAGE);
// stats // stats
@ -1455,7 +1457,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL);
addflag(lastjob->flags, F_LEVFLAG, 7, F_DETECTAURAS, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 7, F_DETECTAURAS, B_TRUE, NULL);
addflag(lastjob->flags, F_LEVFLAG, 10, F_CONTROL, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 10, F_CONTROL, B_TRUE, NULL);
//addflag(lastjob->flags, F_LEVSPELLSCHOOL, 101, SS_NONE, B_TRUE, NULL); // new spell every 1 level addflag(lastjob->flags, F_LEVSPELLSCHOOLFROMX, 104, SS_FIRE, 3, NULL); // new spell every 4 levels
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
// monster job flags // monster job flags
addflag(lastjob->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastjob->flags, F_CASTCHANCE, 30, NA, NA, NULL);
@ -1513,7 +1515,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL);
addflag(lastjob->flags, F_LEVFLAG, 7, F_DETECTAURAS, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 7, F_DETECTAURAS, B_TRUE, NULL);
addflag(lastjob->flags, F_LEVFLAG, 10, F_CONTROL, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 10, F_CONTROL, B_TRUE, NULL);
//addflag(lastjob->flags, F_LEVSPELLSCHOOL, 101, SS_NONE, B_TRUE, NULL); // new spell every 1 level addflag(lastjob->flags, F_LEVSPELLSCHOOLFROMX, 104, SS_COLD, 3, NULL); // new spell every 4 levels
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
// monster job flags // monster job flags
addflag(lastjob->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastjob->flags, F_CASTCHANCE, 30, NA, NA, NULL);
@ -1571,7 +1573,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL);
addflag(lastjob->flags, F_LEVFLAG, 7, F_DETECTAURAS, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 7, F_DETECTAURAS, B_TRUE, NULL);
addflag(lastjob->flags, F_LEVFLAG, 10, F_CONTROL, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 10, F_CONTROL, B_TRUE, NULL);
//addflag(lastjob->flags, F_LEVSPELLSCHOOL, 101, SS_NONE, B_TRUE, NULL); // new spell every 1 level addflag(lastjob->flags, F_LEVSPELLSCHOOLFROMX, 104, SS_DEATH, 3, NULL); // new spell every 4 levels
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
// monster job flags // monster job flags
addflag(lastjob->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastjob->flags, F_CASTCHANCE, 30, NA, NA, NULL);
@ -1629,7 +1631,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL);
addflag(lastjob->flags, F_LEVFLAG, 7, F_DETECTAURAS, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 7, F_DETECTAURAS, B_TRUE, NULL);
addflag(lastjob->flags, F_LEVFLAG, 10, F_CONTROL, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 10, F_CONTROL, B_TRUE, NULL);
//addflag(lastjob->flags, F_LEVSPELLSCHOOL, 101, SS_NONE, B_TRUE, NULL); // new spell every 1 level addflag(lastjob->flags, F_LEVSPELLSCHOOLFROMX, 104, SS_WILD, 3, NULL); // new spell every 4 levels
addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL);
// monster job flags // monster job flags
addflag(lastjob->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastjob->flags, F_CASTCHANCE, 30, NA, NA, NULL);
@ -6033,14 +6035,14 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL);
addot(OT_SPELLBOOK, "spellbook", "Spellbooks contain a selection of spells from a single school.", MT_PAPER, 1.5, OC_BOOK, SZ_SMALL); addot(OT_SPELLBOOK, "spellbook", "Spellbooks contain a selection of spells from a single school.", MT_PAPER, 1.5, OC_BOOK, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_UNCOMMON, NULL);
addot(OT_GRIMOIRE, "grimoire", "Grimoires contain spells from a variety of schools.", MT_PAPER, 2, OC_BOOK, SZ_SMALL); addot(OT_GRIMOIRE, "grimoire", "Grimoires contain spells from a variety of schools.", MT_PAPER, 2, OC_BOOK, SZ_SMALL);
addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NO_A, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL);
// wands // wands
addot(OT_WAND_CREATEFOOD, "wand of culinary abundance", "A limited-use magical wand which casts the imbued spell.", MT_DRAGONWOOD, 0.5, OC_WAND, SZ_SMALL); addot(OT_WAND_CREATEFOOD, "wand of culinary abundance", "A limited-use magical wand which casts the imbued spell.", MT_DRAGONWOOD, 0.5, OC_WAND, SZ_SMALL);
@ -6505,6 +6507,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EDIBLE, B_TRUE, 10, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 10, NA, "");
addot(OT_COMPUTER, "computer", "A complex technological device. In theory it is usable by most but without the correct skill your mileage may vary...", MT_METAL, 500, OC_TECH, SZ_LARGE); addot(OT_COMPUTER, "computer", "A complex technological device. In theory it is usable by most but without the correct skill your mileage may vary...", MT_METAL, 500, OC_TECH, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_BLUE, '[', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, '[', NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastot->flags, F_VALUE, 2000, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 2000, NA, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
@ -7414,6 +7417,7 @@ void initobjects(void) {
// furniture // furniture
addot(OT_ARMOURRACK, "armour rack", "An upright metal rack made for armour storage.", MT_METAL, 150, OC_FURNITURE, SZ_HUMAN); addot(OT_ARMOURRACK, "armour rack", "An upright metal rack made for armour storage.", MT_METAL, 150, OC_FURNITURE, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_METAL, '\\', NA, NULL); addflag(lastot->flags, F_GLYPH, C_METAL, '\\', 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_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
@ -7443,6 +7447,8 @@ void initobjects(void) {
addflag(lastot->flags, F_SHRINKSTO, OT_SHRUB, VT_OB, NA, NULL); addflag(lastot->flags, F_SHRINKSTO, OT_SHRUB, VT_OB, NA, NULL);
addot(OT_BOOKSHELF, "bookshelf", "A set of wooden shelves, sized for book storage.", MT_WOOD, 150, OC_FURNITURE, SZ_HUMAN); addot(OT_BOOKSHELF, "bookshelf", "A set of wooden shelves, sized for book storage.", MT_WOOD, 150, OC_FURNITURE, SZ_HUMAN);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
addflag(lastot->flags, F_CRUSHABLE, SZ_HUGE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_GLYPH, C_WOOD, '\\', NA, NULL); addflag(lastot->flags, F_GLYPH, C_WOOD, '\\', NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
@ -7514,6 +7520,20 @@ void initobjects(void) {
addflag(lastot->flags, F_GROWSTO, OT_FIRELARGE, VT_OB, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_FIRELARGE, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, NA, VT_OB, NA, "red-hot helmet"); addflag(lastot->flags, F_SHRINKSTO, NA, VT_OB, NA, "red-hot helmet");
addot(OT_WARDROBE, "wardrobe", "An upright enclosed shelving unit for clothes storage.", MT_WOOD, 80, OC_FURNITURE, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_WOOD, '\\', NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CONTAINER, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_STARTOB, 80, NA, NA, "random clothing");
addflag(lastot->flags, F_STARTOB, 60, NA, NA, "random clothing");
addflag(lastot->flags, F_STARTOB, 50, NA, NA, "good clothing");
addflag(lastot->flags, F_STARTOB, 50, NA, NA, "great clothing");
addot(OT_WEAPONRACK, "weapon rack", "A large matel frame, made to store weapons.", MT_METAL, 150, OC_FURNITURE, SZ_HUMAN); addot(OT_WEAPONRACK, "weapon rack", "A large matel frame, made to store weapons.", MT_METAL, 150, OC_FURNITURE, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_METAL, '\\', NA, NULL); addflag(lastot->flags, F_GLYPH, C_METAL, '\\', NA, NULL);
@ -7538,6 +7558,7 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 12, 12, NA, NULL); addflag(lastot->flags, F_OBHP, 12, 12, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, 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_CANBEJAMMED, 50, NA, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL); addflag(lastot->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL); addflag(lastot->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL); addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
@ -15983,7 +16004,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL); addflag(lastrace->flags, F_TR, 7, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
@ -20599,138 +20620,8 @@ void initrace(void) {
if (hasflag(r->flags, F_PLAYABLE)) { if (hasflag(r->flags, F_PLAYABLE)) {
r->known = B_TRUE; r->known = B_TRUE;
} }
if (r->raceclass->id == RC_AQUATIC) {
addflag(r->flags, F_HASSKILL, SK_SWIMMING, PR_MASTER, NA, NULL);
addflag(r->flags, F_AQUATIC, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DTIMMUNE, DT_WATER, NA, NA, NULL);
} else if (r->raceclass->id == RC_DEMON) {
addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_MATVULN, MT_SILVER, 200, 6, NULL);
addflag(r->flags, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_SEEINVIS, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL);
} else if (r->raceclass->id == RC_INSECT) {
addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
} else if (r->raceclass->id == RC_DRAGON) {
// wyrms hate hydras
if (r->id != R_HYDRA) {
addflag(r->flags, F_HATESRACE, R_HYDRA, NA, NA, NULL);
}
} else if (r->raceclass->id == RC_GOD) {
addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_PIETY, 100, NA, NA, NULL);
addflag(r->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_MORALE, 30, NA, NA, NULL);
addflag(r->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL);
addflag(r->flags, F_DTIMMUNE, DT_POISON, NA, NA, NULL);
addflag(r->flags, F_DTIMMUNE, DT_POISONGAS, NA, NA, NULL);
addflag(r->flags, F_FLEEONHPPCT, 20, NA, NA, NULL);
addflag(r->flags, F_RESISTMAG, 15, NA, NA, NULL);
addflag(r->flags, F_MEDITATES, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_SEEINDARK, 10, NA, NA, NULL);
addflag(r->flags, F_SEEINVIS, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_CANWILL, OT_S_PLANESHIFT, NA, NA, "pw:1;");
addflag(r->flags, F_FILLPOT, OT_POT_AMBROSIA, NA, NA, NULL);
addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_GIFTTIMER, 0, 50, NA, NULL);
addflag(r->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL);
} else if (r->raceclass->id == RC_MAGIC) {
addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL);
} else if (r->raceclass->id == RC_PLANT) {
addflag(r->flags, F_NOKO, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_GETKILLEDVERB, NA, NA, NA, "destroy");
addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DTRESIST, DT_BASH, NA, NA, NULL);
addflag(r->flags, F_DTVULN, DT_FIRE, NA, NA, NULL);
addflag(r->flags, F_DTVULN, DT_COLD, NA, NA, NULL);
addflag(r->flags, F_DTVULN, DT_DECAY, NA, NA, NULL);
addflag(r->flags, F_FLAMMABLE, PERMENANT, NA, NA, NULL);
addflag(r->flags, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DAYBOOST, 10, NA, NA, NULL);
addflag(r->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
} else if (r->raceclass->id == RC_SLIME) {
addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOTAKECRITS, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_TREMORSENSE, 5, NA, NA, NULL);
} else if (r->raceclass->id == RC_ROBOT) {
addflag(r->flags, F_NOKO, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_GETKILLEDVERB, NA, NA, NA, "destroy");
addflag(r->flags, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL);
addflag(r->flags, F_DTVULN, DT_WATER, NA, NA, NULL);
addflag(r->flags, F_CORPSETYPE, NA, NA, NA, "unstable power core");
addflag(r->flags, F_MORALE, 30, NA, NA, NULL);
addflag(r->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_BLOODOB, NA, NA, NA, "puddle of oil");
addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOSMELL, B_TRUE, NA, NA, NULL);
if (!hasflagval(r->flags, F_NOISETEXT, N_WALK, NA, NA, NULL)) { addraceclassflags(r->flags, r->raceclass->id, r->id);
addflag(r->flags, F_NOISETEXT, N_WALK, 2, NA, "^whirring");
}
if (!hasflagval(r->flags, F_NOISETEXT, N_GETANGRY, NA, NA, NULL)) {
addflag(r->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "beeps^a beep");
}
// will probably also be immune to fire/cold because they are metal
} else if (r->raceclass->id == RC_UNDEAD) {
addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addflag(r->flags, F_DTIMMUNE, DT_POISON, NA, NA, NULL);
addflag(r->flags, F_DTIMMUNE, DT_POISONGAS, NA, NA, NULL);
addflag(r->flags, F_DTIMMUNE, DT_DECAY, NA, NA, NULL);
addflag(r->flags, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL);
addflag(r->flags, F_NOTAKECRITS, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NORESTHEAL, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL);
// +/- 15 accuracy during day/night
addflag(r->flags, F_NIGHTBOOST, 15, NA, NA, NULL);
addflag(r->flags, F_DAYBOOST, -15, NA, NA, NULL);
switch (r->id) {
case R_SKELETONFIRE:
f = hasflagval(r->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
if (f) killflag(f);
break;
case R_MUMMYG:
break;
default:
addflag(r->flags, F_DTVULN, DT_HOLY, NA, NA, NULL);
break;
}
addflag(r->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
}
// fill in missing alignments // fill in missing alignments
if (!hasflag(r->flags, F_ALIGNMENT)) { if (!hasflag(r->flags, F_ALIGNMENT)) {
@ -20825,8 +20716,8 @@ void initskills(void) {
addskilldesc(SK_COMBAT, PR_EXPERT, "^gSecond wind restores stamina after defeating enemies.^n", B_TRUE); addskilldesc(SK_COMBAT, PR_EXPERT, "^gSecond wind restores stamina after defeating enemies.^n", B_TRUE);
addskilldesc(SK_COMBAT, PR_MASTER, "^gAttacking will no longer drain your stamina.^n", B_TRUE); addskilldesc(SK_COMBAT, PR_MASTER, "^gAttacking will no longer drain your stamina.^n", B_TRUE);
addskill(SK_COOKING, "Cooking", "Your ability to combine foods into nutritious meals.", 50); addskill(SK_COOKING, "Cooking", "Your ability to combine foods into nutritious meals.", 50);
addskilldesc(SK_COOKING, PR_INEPT, " - This skill determines the size of corpse which you can cook.", B_FALSE);
addskilldesc(SK_COOKING, PR_INEPT, " - Note: when cooking, all ingredients must already be recognised.", B_FALSE); addskilldesc(SK_COOKING, PR_INEPT, " - Note: when cooking, all ingredients must already be recognised.", B_FALSE);
addskilldesc(SK_COOKING, PR_NOVICE, "^gYou can now cook corpses before consumption.^n", B_TRUE);
addskillabil(SK_COOKING, PR_NOVICE, OT_A_COOK, NA, NULL, B_TRUE); addskillabil(SK_COOKING, PR_NOVICE, OT_A_COOK, NA, NULL, B_TRUE);
addskilldesc(SK_COOKING, PR_BEGINNER, "^gYou now recognise bad food.^n", B_TRUE); addskilldesc(SK_COOKING, PR_BEGINNER, "^gYou now recognise bad food.^n", B_TRUE);
addskilldesc(SK_COOKING, PR_BEGINNER, "^gYou can now cook recipes using up to 2 ingredients.^n", B_TRUE); addskilldesc(SK_COOKING, PR_BEGINNER, "^gYou can now cook recipes using up to 2 ingredients.^n", B_TRUE);

Binary file not shown.

16
defs.h
View File

@ -24,6 +24,7 @@
// skill check difficulty // skill check difficulty
#define D_ALWAYSFAIL -99 #define D_ALWAYSFAIL -99
#define D_BADFEELING 120
// how many blood splashes you need before you // how many blood splashes you need before you
// can fill a flask with it. // can fill a flask with it.
@ -484,6 +485,7 @@ enum CELLCONDITION {
CC_KNOWN, CC_KNOWN,
CC_IDENTIFIED, CC_IDENTIFIED,
CC_MINAR, // arg CC_MINAR, // arg
CC_MAXAR, // arg
CC_MINDR, // arg CC_MINDR, // arg
CC_MAXDR, // arg CC_MAXDR, // arg
CC_MAXSIZE, // arg is max size CC_MAXSIZE, // arg is max size
@ -2345,6 +2347,7 @@ enum OBTYPE {
OT_CANDELABRUM, OT_CANDELABRUM,
OT_COFFIN, OT_COFFIN,
OT_FIREPLACE, OT_FIREPLACE,
OT_WARDROBE,
OT_WEAPONRACK, OT_WEAPONRACK,
OT_WOODENTABLE, OT_WOODENTABLE,
OT_WOODENBARREL, OT_WOODENBARREL,
@ -2859,6 +2862,8 @@ enum FLAG {
// player killed, and has not yet been touched. // player killed, and has not yet been touched.
F_UNTOUCHED, // this obejct has not yet been picked up by anyone F_UNTOUCHED, // this obejct has not yet been picked up by anyone
F_BEINGUSED, // this object is currently being used F_BEINGUSED, // this object is currently being used
F_BEENOPENED, // this container has been opened by
// the player.
F_BRANDCHANCE, // this object has v0% extra chance of being branded F_BRANDCHANCE, // this object has v0% extra chance of being branded
F_DEAD, // object will be removed. v0 = lfid who killed it F_DEAD, // object will be removed. v0 = lfid who killed it
F_ONEPERCELL, // only one of these objects can exist per cell F_ONEPERCELL, // only one of these objects can exist per cell
@ -3188,6 +3193,9 @@ enum FLAG {
// v0 = base pct chance // v0 = base pct chance
// v1 = extra pct chance every 5 levels // v1 = extra pct chance every 5 levels
// v2 = max trap chance // v2 = max trap chance
F_CANBEJAMMED, // this object might start off jammed
// v0 = base pct chance
// v1 = extra pct chance every 5 levels
F_CANBELOCKED, // this object might start off locked F_CANBELOCKED, // this object might start off locked
// v0 = base pct chance // v0 = base pct chance
// v1 = extra pct chance every 5 levels // v1 = extra pct chance every 5 levels
@ -3239,8 +3247,11 @@ enum FLAG {
F_LOCKED,// door is locked F_LOCKED,// door is locked
// v1 is difficulty to disarm // v1 is difficulty to disarm
// if v2 is set, this objcet can't be magically unlocked. // if v2 is set, this objcet can't be magically unlocked.
F_JAMMED, // is this door jammed? v0 is # turns it'll take to open it. F_JAMMED, // is this door/container jammed?
// v1 = have we tried this door yet? // v0 is # turns it'll take to open it.
// v1 = have we tried this door/ob yet?
// (ie do we know it's jammed)
// v2 = unjam difficulty
F_SECRET, // this object is secret. v0 is sc_search difficulty F_SECRET, // this object is secret. v0 is sc_search difficulty
// to find it. // to find it.
// NA means 'can never find this' // NA means 'can never find this'
@ -4666,6 +4677,7 @@ enum COMMAND {
CMD_INFOARMOUR, CMD_INFOARMOUR,
CMD_INFOKNOWLEDGE, CMD_INFOKNOWLEDGE,
CMD_INFOPLAYER, CMD_INFOPLAYER,
CMD_INTERACT,
CMD_INV, CMD_INV,
CMD_LOOKAROUND, CMD_LOOKAROUND,
CMD_LOOKHERE, CMD_LOOKHERE,

View File

@ -73,6 +73,7 @@ Flags can be:
entertext:xxx // show xxx when a non-blind player enters entertext:xxx // show xxx when a non-blind player enters
goesin:xxx // can only randomly appear in habitat xxx goesin:xxx // can only randomly appear in habitat xxx
// (can appear multiple times)
usehabitat:xxx // cells in this vault have habitat=xxx usehabitat:xxx // cells in this vault have habitat=xxx

117
io.c
View File

@ -4505,17 +4505,17 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
switch (ch) { switch (ch) {
case 'a': case 'a':
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
if (lf == lf2) { if (lf == lf2) {
// won't attack itself // won't attack itself
msg("%s looks confused at your command.", lfname); if (cansee(player, lf)) msg("%s looks confused at your command.", lfname);
} else { } else {
if (!cansee(lf, lf2)) { if (!cansee(lf, lf2)) {
turntoface(lf, lf2->cell); turntoface(lf, lf2->cell);
@ -4534,11 +4534,11 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
break; break;
case 'c': case 'c':
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
// find adjacent cell // find adjacent cell
@ -4768,18 +4768,18 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
// stop attacking all current targets first... // stop attacking all current targets first...
killflagsofid(lf->flags, F_TARGETLF); killflagsofid(lf->flags, F_TARGETLF);
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
aigoto(lf, targc, MR_OTHER, NULL, DEF_AIFOLLOWTIME); aigoto(lf, targc, MR_OTHER, NULL, DEF_AIFOLLOWTIME);
break; break;
case 'i': case 'i':
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
if (askforinfo(lf, 2)) { if (askforinfo(lf, 2)) {
@ -4790,25 +4790,25 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
case 'j': case 'j':
// charisma check to see if they'll join you. // charisma check to see if they'll join you.
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
recruit(lf); recruit(lf);
break; break;
case 'k': // trade Knowledge case 'k': // trade Knowledge
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
tradeknowledge(lf); tradeknowledge(lf);
break; break;
case 'm': // mercy case 'm': // mercy
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
if (islowhp(player) && if (islowhp(player) &&
@ -4878,11 +4878,11 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
*/ */
case 'r': case 'r':
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
f = isresting(lf); f = isresting(lf);
@ -4904,7 +4904,7 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
return; return;
case 't': case 't':
if (lfhasflag(lf, F_PHANTASM) || lfhasflag(lf, F_SUMMONEDBY)) { if (lfhasflag(lf, F_PHANTASM) || lfhasflag(lf, F_SUMMONEDBY)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
// ask whtehr to give/take // ask whtehr to give/take
@ -4936,7 +4936,7 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
break; break;
case 'x': case 'x':
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
if (askforinfo(lf, 4)) { if (askforinfo(lf, 4)) {
@ -4949,22 +4949,22 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
break; break;
case '<': case '<':
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
setfollowdistance(lf, 1, 3); setfollowdistance(lf, 1, 3);
break; break;
case '>': case '>':
if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) { if (lfhasflag(lf, F_RAGE) || !canhear(lf, player->cell, SV_SHOUT, NULL)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname); if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break; break;
} }
setfollowdistance(lf, 3, 5); setfollowdistance(lf, 3, 5);
@ -5518,7 +5518,7 @@ void doeat(obpile_t *op) {
eatob = askobject(op, "Eat what", "You have nothing to eat!", NULL, 'e', &cs, B_FALSE); eatob = askobject(op, "Eat what", "You have nothing to eat!", NULL, 'e', &cs, B_FALSE);
} }
if (eatob) { if (eatob) {
if (isunknownbadobject(eatob) && skillcheck(player, A_WIS, 120, 0)) { if (isunknownbadobject(eatob) && skillcheck(player, A_WIS, D_BADFEELING, 0)) {
if (!confirm_badfeeling(eatob)) { if (!confirm_badfeeling(eatob)) {
msg("Cancelled."); msg("Cancelled.");
return; return;
@ -5536,7 +5536,7 @@ int dowear(obpile_t *op) {
CC_NONE); CC_NONE);
o = askobject(op, "Wear what", "You have nothing to wear!", NULL, '\0', &cs, B_FALSE); o = askobject(op, "Wear what", "You have nothing to wear!", NULL, '\0', &cs, B_FALSE);
if (o) { if (o) {
if (isunknownbadobject(o) && skillcheck(player, A_WIS, 120, 0)) { if (isunknownbadobject(o) && skillcheck(player, A_WIS, D_BADFEELING, 0)) {
if (!confirm_badfeeling(o)) { if (!confirm_badfeeling(o)) {
msg("Cancelled."); msg("Cancelled.");
return B_TRUE; return B_TRUE;
@ -5562,7 +5562,7 @@ int doweild(obpile_t *op) {
CC_NONE); CC_NONE);
o = askobject(op, "Weild what", "You have nothing to weild.", &count, 'w', &cs, B_TRUE); o = askobject(op, "Weild what", "You have nothing to weild.", &count, 'w', &cs, B_TRUE);
if (o) { if (o) {
if (isunknownbadobject(o) && skillcheck(player, A_WIS, 120, 0)) { if (isunknownbadobject(o) && skillcheck(player, A_WIS, D_BADFEELING, 0)) {
if (!confirm_badfeeling(o)) { if (!confirm_badfeeling(o)) {
msg("Cancelled."); msg("Cancelled.");
return B_TRUE; return B_TRUE;
@ -7563,6 +7563,13 @@ char *makedesc_ob(object_t *o, char *retbuf) {
showcontents = B_FALSE; showcontents = B_FALSE;
} }
} }
if (hasflag(o->flags, F_CONTAINER)) {
// only show contents of containers if you are holding them
// and you have previously opened it.
if (!hasflag(o->flags, F_BEENOPENED) || (o->pile->owner == player)) {
showcontents = B_FALSE;
}
}
if (showcontents) { if (showcontents) {
if ((o->type->id == OT_SPELLBOOK) || (o->type->id == OT_GRIMOIRE)) { if ((o->type->id == OT_SPELLBOOK) || (o->type->id == OT_GRIMOIRE)) {
@ -9037,6 +9044,63 @@ void dohelp(char helpmode) {
restoregamewindows(); restoregamewindows();
} }
void dointeract(void) {
cell_t *c;
object_t *o;
char ch = 'a';
int dir;
object_t *ob[(MAXPILEOBS*8)+1];
condset_t cs;
int nobs,n;
dir = askdir("Interact in which direction (- to cancel)", B_TRUE, B_TRUE);
if ((dir == D_MYSELF) || (dir == D_NONE)) {
msg("Cancelled.");
return;
}
c = getcellindir(player->cell, dir);
if (!c) {
msg("Cancelled.");
return;
}
// init prompt
initprompt(&prompt, "Interact with what?");
prompt.maycancel = B_TRUE;
// get adjacent cells
// anything operable and impasssble?
initcondv(&cs, CC_HASFLAG, B_TRUE, F_IMPASSABLE,
CC_OPERABLE, B_TRUE, NA,
CC_NONE);
getobs(c->obpile, &cs, ob, &nobs);
for (n = 0; n < nobs; n++) {
char obname[BUFLEN];
getobname(ob[n], obname, ob[n]->amt);
addchoice(&prompt, ch, obname, NULL, ob[n], NULL);
if (ch == 'z') ch = 'A';
else ch++;
}
o = NULL;
if (!prompt.nchoices) {
msg("There is nothing there to interact with!");
return;
} else if (prompt.nchoices == 1) {
o = (object_t *)prompt.choice[0].data;
} else {
getchoice(&prompt);
o = (object_t *)prompt.result;
}
if (!o) {
msg("Cancelled.");
return;
}
operate(player, o, NULL);
}
void doinventory(obpile_t *op) { void doinventory(obpile_t *op) {
object_t *o; object_t *o;
char buf[BUFLEN]; char buf[BUFLEN];
@ -9092,7 +9156,7 @@ void doquaff(obpile_t *op) {
} }
if (liquid) { if (liquid) {
if (candrink(player, liquid)) { if (candrink(player, liquid)) {
if (isunknownbadobject(liquid) && skillcheck(player, A_WIS, 120, 0)) { if (isunknownbadobject(liquid) && skillcheck(player, A_WIS, D_BADFEELING, 0)) {
if (!confirm_badfeeling(liquid)) { if (!confirm_badfeeling(liquid)) {
msg("Cancelled."); msg("Cancelled.");
return; return;
@ -10889,6 +10953,9 @@ void handleinput(void) {
case CMD_INFOARMOUR: // display armour case CMD_INFOARMOUR: // display armour
showlfarmour(player); showlfarmour(player);
break; break;
case CMD_INTERACT: // interact with adjacent objects
dointeract();
break;
case CMD_LOOKHERE: // look at what's here case CMD_LOOKHERE: // look at what's here
dolook(player->cell, B_TRUE); dolook(player->cell, B_TRUE);
break; break;
@ -13671,7 +13738,7 @@ void showlfstats(lifeform_t *lf, int showall) {
f = hasflag_real(lf->flags, F_FEARLESS, B_TRUE, NULL, FROMRACE); f = hasflag_real(lf->flags, F_FEARLESS, B_TRUE, NULL, FROMRACE);
if (f) { if (f) {
getflagsourcetext(f,source); getflagsourcetext(f,source);
wrapprint(mainwin, &y, &x, 0, "%s %s immune to the effects of fear.%s", you(lf), is(lf)); wrapprint(mainwin, &y, &x, 0, "%s %s immune to the effects of fear.%s", you(lf), is(lf), source);
} }
f = hasflag_real(lf->flags, F_FASTMETAB, B_TRUE, NULL, FROMRACE); f = hasflag_real(lf->flags, F_FASTMETAB, B_TRUE, NULL, FROMRACE);

1
io.h
View File

@ -62,6 +62,7 @@ void doexplain(char *question);
void dofinaloblist(obpile_t *op); void dofinaloblist(obpile_t *op);
void dofire(void); void dofire(void);
void dohelp(char helpmode); void dohelp(char helpmode);
void dointeract(void);
void doinventory(obpile_t *op); void doinventory(obpile_t *op);
void doknowledgelist(void); void doknowledgelist(void);
void dolook(cell_t *where, int onpurpose); void dolook(cell_t *where, int onpurpose);

165
lf.c
View File

@ -2162,6 +2162,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
if (hasflag(sp->flags, F_CASTINGTIME)) { if (hasflag(sp->flags, F_CASTINGTIME)) {
msg("%s starts casting a spell.", lfname); msg("%s starts casting a spell.", lfname);
} else { } else {
msg("%s casts a spell.", lfname);
} }
} }
} else { // player can't see them } else { // player can't see them
@ -5018,6 +5019,7 @@ int eat(lifeform_t *lf, object_t *o) {
} }
// limit nutrition // limit nutrition
//if (nutrition > (HUNGERCONST/2)) nutrition = (HUNGERCONST/2); //if (nutrition > (HUNGERCONST/2)) nutrition = (HUNGERCONST/2);
nutrition /= 2;
rawmeat = B_TRUE; rawmeat = B_TRUE;
} }
@ -5173,12 +5175,12 @@ int eat(lifeform_t *lf, object_t *o) {
char dambuf[BUFLEN]; char dambuf[BUFLEN];
snprintf(dambuf, BUFLEN, "a bad %s",noprefix(obname)); snprintf(dambuf, BUFLEN, "a bad %s",noprefix(obname));
if (hasflag(corpserace->flags, F_AVIAN)) { if (hasflag(corpserace->flags, F_AVIAN)) {
checkdiff = 100; checkdiff = 120;
ptid = P_FOODBAD; ptid = P_FOODBAD;
timemin = 30; timemin = 30;
timemax = 50; timemax = 50;
} else { } else {
checkdiff = 65; checkdiff = 85;
if (onein(3)) { if (onein(3)) {
ptid = P_FOOD; ptid = P_FOOD;
} else { } else {
@ -15436,6 +15438,145 @@ void addskillabil(enum SKILL id, enum SKILLLEVEL lev, enum OBTYPE abilid, int ti
} }
// rid is optional, can be R_NONE
void addraceclassflags(flagpile_t *fp, enum RACECLASS rcid, enum RACE rid) {
flag_t *f;
if (rcid == RC_AQUATIC) {
addflag(fp, F_HASSKILL, SK_SWIMMING, PR_MASTER, NA, NULL);
addflag(fp, F_AQUATIC, B_TRUE, NA, NA, NULL);
addflag(fp, F_BREATHWATER, B_TRUE, NA, NA, NULL);
addflag(fp, F_DTIMMUNE, DT_WATER, NA, NA, NULL);
} else if (rcid == RC_DEMON) {
addflag(fp, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(fp, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(fp, F_MATVULN, MT_SILVER, 200, 6, NULL);
addflag(fp, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(fp, F_SEEINVIS, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOSTAM, B_TRUE, NA, NA, NULL);
} else if (rcid == RC_INSECT) {
addflag(fp, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(fp, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
} else if (rcid == RC_DRAGON) {
// wyrms hate hydras
if (rid != R_HYDRA) {
addflag(fp, F_HATESRACE, R_HYDRA, NA, NA, NULL);
}
} else if (rcid == RC_GOD) {
addflag(fp, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(fp, F_PIETY, 100, NA, NA, NULL);
addflag(fp, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(fp, F_MORALE, 30, NA, NA, NULL);
addflag(fp, F_BREATHWATER, B_TRUE, NA, NA, NULL);
addflag(fp, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(fp, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL);
addflag(fp, F_DTIMMUNE, DT_POISON, NA, NA, NULL);
addflag(fp, F_DTIMMUNE, DT_POISONGAS, NA, NA, NULL);
addflag(fp, F_FLEEONHPPCT, 20, NA, NA, NULL);
addflag(fp, F_RESISTMAG, 15, NA, NA, NULL);
addflag(fp, F_MEDITATES, B_TRUE, NA, NA, NULL);
addflag(fp, F_SEEINDARK, 10, NA, NA, NULL);
addflag(fp, F_SEEINVIS, B_TRUE, NA, NA, NULL);
addflag(fp, F_CANWILL, OT_S_PLANESHIFT, NA, NA, "pw:1;");
addflag(fp, F_FILLPOT, OT_POT_AMBROSIA, NA, NA, NULL);
addflag(fp, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(fp, F_GIFTTIMER, 0, 50, NA, NULL);
addflag(fp, F_NONAUSEA, B_TRUE, NA, NA, NULL);
} else if (rcid == RC_MAGIC) {
addflag(fp, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(fp, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(fp, F_NONAUSEA, B_TRUE, NA, NA, NULL);
} else if (rcid == RC_PLANT) {
addflag(fp, F_NOKO, B_TRUE, NA, NA, NULL);
addflag(fp, F_GETKILLEDVERB, NA, NA, NA, "destroy");
addflag(fp, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(fp, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(fp, F_DTRESIST, DT_BASH, NA, NA, NULL);
addflag(fp, F_DTVULN, DT_FIRE, NA, NA, NULL);
addflag(fp, F_DTVULN, DT_COLD, NA, NA, NULL);
addflag(fp, F_DTVULN, DT_DECAY, NA, NA, NULL);
addflag(fp, F_FLAMMABLE, PERMENANT, NA, NA, NULL);
addflag(fp, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(fp, F_DAYBOOST, 10, NA, NA, NULL);
addflag(fp, F_NONAUSEA, B_TRUE, NA, NA, NULL);
addflag(fp, F_AWARENESS, B_TRUE, NA, NA, NULL);
} else if (rcid == RC_SLIME) {
addflag(fp, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(fp, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(fp, F_NONAUSEA, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOTAKECRITS, B_TRUE, NA, NA, NULL);
addflag(fp, F_TREMORSENSE, 5, NA, NA, NULL);
} else if (rcid == RC_ROBOT) {
addflag(fp, F_NOKO, B_TRUE, NA, NA, NULL);
addflag(fp, F_GETKILLEDVERB, NA, NA, NA, "destroy");
addflag(fp, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(fp, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(fp, F_BREATHWATER, B_TRUE, NA, NA, NULL);
addflag(fp, F_DTVULN, DT_ELECTRIC, NA, NA, NULL);
addflag(fp, F_DTVULN, DT_WATER, NA, NA, NULL);
addflag(fp, F_CORPSETYPE, NA, NA, NA, "unstable power core");
addflag(fp, F_MORALE, 30, NA, NA, NULL);
addflag(fp, F_SEEINDARK, B_TRUE, NA, NA, NULL);
addflag(fp, F_BLOODOB, NA, NA, NA, "puddle of oil");
addflag(fp, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOSMELL, B_TRUE, NA, NA, NULL);
if (!hasflagval(fp, F_NOISETEXT, N_WALK, NA, NA, NULL)) {
addflag(fp, F_NOISETEXT, N_WALK, 2, NA, "^whirring");
}
if (!hasflagval(fp, F_NOISETEXT, N_GETANGRY, NA, NA, NULL)) {
addflag(fp, F_NOISETEXT, N_GETANGRY, 3, NA, "beeps^a beep");
}
// will probably also be immune to fire/cold because they are metal
} else if (rcid == RC_UNDEAD) {
addflag(fp, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);
addflag(fp, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addflag(fp, F_DTIMMUNE, DT_POISON, NA, NA, NULL);
addflag(fp, F_DTIMMUNE, DT_POISONGAS, NA, NA, NULL);
addflag(fp, F_DTIMMUNE, DT_DECAY, NA, NA, NULL);
addflag(fp, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL);
addflag(fp, F_NOTAKECRITS, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOBREATH, B_TRUE, NA, NA, NULL);
addflag(fp, F_NORESTHEAL, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOSTAM, B_TRUE, NA, NA, NULL);
addflag(fp, F_NONAUSEA, B_TRUE, NA, NA, NULL);
// +/- 15 accuracy during day/night
addflag(fp, F_NIGHTBOOST, 15, NA, NA, NULL);
addflag(fp, F_DAYBOOST, -15, NA, NA, NULL);
switch (rid) {
case R_SKELETONFIRE:
f = hasflagval(fp, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
if (f) killflag(f);
break;
case R_MUMMYG:
break;
default:
addflag(fp, F_DTVULN, DT_HOLY, NA, NA, NULL);
break;
}
addflag(fp, F_SEEINDARK, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOTALK, B_TRUE, NA, NA, NULL);
addflag(fp, F_NOSTAIRS, B_TRUE, NA, NA, NULL);
}
}
skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime) { skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime) {
skill_t *a,*temp; skill_t *a,*temp;
int count = 0; int count = 0;
@ -15788,7 +15929,7 @@ lifeform_t *makezombie(object_t *o, int power, char *description, lifeform_t *ma
flag_t *f; flag_t *f;
race_t *r; race_t *r;
lifeform_t *lf; lifeform_t *lf;
cell_t *where; cell_t *where,*origwhere;
char obname[BUFLEN]; char obname[BUFLEN];
if (o->type->id != OT_CORPSE) return NULL; if (o->type->id != OT_CORPSE) return NULL;
@ -15799,7 +15940,9 @@ lifeform_t *makezombie(object_t *o, int power, char *description, lifeform_t *ma
r = findrace(f->val[0]); r = findrace(f->val[0]);
if (!r) return NULL; if (!r) return NULL;
where = getoblocation(o); origwhere = getoblocation(o);
where = origwhere;
getobname(o, obname, 1); getobname(o, obname, 1);
if (!cellwalkable(NULL, where, NULL)) { if (!cellwalkable(NULL, where, NULL)) {
@ -15818,14 +15961,8 @@ lifeform_t *makezombie(object_t *o, int power, char *description, lifeform_t *ma
killflagsofid(lf->flags, F_DTIMMUNE); killflagsofid(lf->flags, F_DTIMMUNE);
killflagsofid(lf->flags, F_DTVULN); killflagsofid(lf->flags, F_DTVULN);
killflagsofid(lf->flags, F_DTRESIST); killflagsofid(lf->flags, F_DTRESIST);
addflag(lf->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addflag(lf->flags, F_DTIMMUNE, DT_POISONGAS, NA, NA, NULL);
addflag(lf->flags, F_DTIMMUNE, DT_DECAY, NA, NA, NULL);
addflag(lf->flags, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL);
addflag(lf->flags, F_DTVULN, DT_HOLY, NA, NA, NULL);
addflag(lf->flags, F_NOTALK, B_TRUE, NA, NA, NULL); addraceclassflags(lf->flags, RC_UNDEAD, R_NONE);
addflag(lf->flags, F_NOSTAIRS, B_TRUE, NA, NA, NULL);
if (hasflag(o->flags, F_HEADLESS)) { if (hasflag(o->flags, F_HEADLESS)) {
// remove the head // remove the head
@ -15885,7 +16022,7 @@ lifeform_t *makezombie(object_t *o, int power, char *description, lifeform_t *ma
removeob(o,o->amt); removeob(o,o->amt);
// redraw & announce // redraw & announce
if (haslos(player, where)) { if (haslos(player, where) || haslos(player, origwhere)) {
needredraw = B_TRUE; needredraw = B_TRUE;
drawscreen(); drawscreen();
msg("^W%s %s!", obname, description); msg("^W%s %s!", obname, description);
@ -22344,8 +22481,8 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
//pct = getskillcheckchance(lf, ct, diff, mod); //pct = getskillcheckchance(lf, ct, diff, mod);
// higher roll is better // higher roll is better
roll = rnd(1,100); //roll = rnd(1,100);
//roll = rnd(1,50); roll = rnd(1,50);
// debugging for new skillcheck code // debugging for new skillcheck code
if (lfhasflag(lf, F_DEBUG)) dblog("%s initial roll=%d",dbtag,roll); if (lfhasflag(lf, F_DEBUG)) dblog("%s initial roll=%d",dbtag,roll);

1
lf.h
View File

@ -8,6 +8,7 @@ poisontype_t *addpoisontype(enum POISONTYPE id, char *name, char *desc, char *co
job_t *addjob(enum JOB id, char *name, char *desc, enum JOBCATEGORY category); job_t *addjob(enum JOB id, char *name, char *desc, enum JOBCATEGORY category);
race_t *addrace(enum RACE id, char *name, float weight, int glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc); race_t *addrace(enum RACE id, char *name, float weight, int glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc);
raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill); raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill);
void addraceclassflags(flagpile_t *fp, enum RACECLASS rcid, enum RACE rid);
skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime); skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime);
void addskillabil(enum SKILL id, enum SKILLLEVEL lev, enum OBTYPE abilid, int timeout, char *text, int announce); void addskillabil(enum SKILL id, enum SKILLLEVEL lev, enum OBTYPE abilid, int timeout, char *text, int announce);
void addskilldesc(enum SKILL id, enum SKILLLEVEL lev, char *text, int wantmsg); void addskilldesc(enum SKILL id, enum SKILLLEVEL lev, char *text, int wantmsg);

48
move.c
View File

@ -2190,53 +2190,7 @@ int opendoor(lifeform_t *lf, object_t *o) {
openit = B_FALSE; openit = B_FALSE;
f->val[1] = B_TRUE; f->val[1] = B_TRUE;
} else { } else {
// known - try to force it openit = unjam(lf, o);
int amt = 0;
amt = getattr(lf, A_STR) - 10;
limit(&amt, 0, NA);
// loosen a bit
if (amt > 0) {
f->val[0] -= amt;
}
if (isplayer(lf)) {
if (amt > 0) {
if (f->val[0] > 0) {
msg("The %s moves slightly but remains jammed.", noprefix(obname));
}
// ... otherwise we'll announce later that we forced the door
// successfully
} else {
msg("You cannot budge the jammed %s.", noprefix(obname));
}
} else {
// ai chasing someone and not strong enough to unjam the door?
if ((amt == 0) && willattackdoors(lf)) {
attackcell(lf, doorcell, B_TRUE);
return B_FALSE;
} else {
// try to force it
if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s tries to open %s, but fails.", lfname, obname);
} else if (haslos(player, doorcell)) {
msg("Something tries to open %s.", obname);
} else {
char noisebuf[BUFLEN];
sprintf(noisebuf, "%s jiggling against its hinges.", obname);
noise(doorcell, NULL, NC_OTHER, SV_SHOUT, noisebuf, NULL);
}
}
}
if (f->val[0] <= 0) {
killflag(f);
f = NULL;
openit = B_TRUE;
} else {
openit = B_FALSE; // don't open the door
}
} // end if jammedknown } // end if jammedknown
} // end if jammed } // end if jammed

199
objects.c
View File

@ -505,7 +505,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
enum LFSIZE wantarmsize = SZ_ANY; enum LFSIZE wantarmsize = SZ_ANY;
enum MATERIAL wantdiffmat = MT_NOTHING; enum MATERIAL wantdiffmat = MT_NOTHING;
int wantoriginal = B_FALSE; int wantoriginal = B_FALSE;
int minar = NA; // minimum AR for armour int minar = NA,maxar = NA; // minimum AR for armour
int mindr = NA,maxdr = NA; // minimum DR for weapons int mindr = NA,maxdr = NA; // minimum DR for weapons
map_t *targetmap = NULL; // for portals map_t *targetmap = NULL; // for portals
cell_t *targetcell = NULL; // for portals cell_t *targetcell = NULL; // for portals
@ -519,6 +519,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
int ndoorflags = 0; int ndoorflags = 0;
int trapchance = 0; int trapchance = 0;
int lockchance = 0; int lockchance = 0;
int jamchance = 0;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags = 0; int nretflags = 0;
@ -829,7 +830,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
p += strlen("locked "); p += strlen("locked ");
donesomething = B_TRUE; donesomething = B_TRUE;
} else if (strstarts(p, "jammed ")) { } else if (strstarts(p, "jammed ")) {
doorflag[ndoorflags++] = F_JAMMED; //doorflag[ndoorflags++] = F_JAMMED;
jamchance = 100;
p += strlen("jammed "); p += strlen("jammed ");
donesomething = B_TRUE; donesomething = B_TRUE;
} else if (strstarts(p, "secret ")) { } else if (strstarts(p, "secret ")) {
@ -1152,13 +1154,22 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
} }
// want actual armour as opposed to clothing? // want actual armour as opposed to clothing?
if ((oc->id == OC_ARMOUR) && strstr(p, "armour")) { if (oc->id == OC_ARMOUR) {
limit(&minar, 1, NA); if (strstr(p, "armour")) {
} limit(&minar, 1, NA);
} else if (strstr(p, "clothing")) {
minar = NA;
maxar = 0;
addcond(&cs, CC_HASFLAG, B_FALSE, F_SHIELD);
}
if (minar != NA) {
addcond(&cs, CC_MINAR, B_TRUE, minar);
}
if (maxar != NA) {
addcond(&cs, CC_MAXAR, B_TRUE, maxar);
}
}
if ((minar != NA) && (oc->id == OC_ARMOUR)) {
addcond(&cs, CC_MINAR, B_TRUE, minar);
}
if (oc->id == OC_WEAPON) { if (oc->id == OC_WEAPON) {
if (mindr != NA) { if (mindr != NA) {
addcond(&cs, CC_MINDR, B_TRUE, mindr); addcond(&cs, CC_MINDR, B_TRUE, mindr);
@ -1671,12 +1682,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
val[2] = NA; val[2] = NA;
ok = B_TRUE; ok = B_TRUE;
break; break;
case F_JAMMED:
val[0] = rnd(1,obloc->map->depth+5);
val[1] = B_FALSE; // not known yet
val[2] = NA;
ok = B_TRUE;
break;
case F_SECRET: case F_SECRET:
val[0] = getdoorsecretdiff(obloc->map->depth); val[0] = getdoorsecretdiff(obloc->map->depth);
val[1] = NA; val[1] = NA;
@ -2332,6 +2337,16 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
addflag(o->flags, F_LOCKED, B_TRUE, getdoorlockdiff(obloc->map->depth), NA, NULL); addflag(o->flags, F_LOCKED, B_TRUE, getdoorlockdiff(obloc->map->depth), NA, NULL);
} }
if (!jamchance) {
f = hasflag(o->flags, F_CANBEJAMMED);
if (f) {
jamchance = f->val[0] + (f->val[1] * (obloc->map->depth/5));
}
}
if (jamchance && pctchance(jamchance)) {
addflag(o->flags, F_JAMMED, 1, B_FALSE, getobjamdiff(obloc->map->depth), NULL);
}
// trapped? l1=10%, l5=20%, l10=30%, l15=40%, l20+=60% // trapped? l1=10%, l5=20%, l10=30%, l15=40%, l20+=60%
if (!trapchance) { if (!trapchance) {
f = hasflag(o->flags, F_CANBETRAPPED); f = hasflag(o->flags, F_CANBETRAPPED);
@ -4639,6 +4654,10 @@ lifeform_t *getobcreatedby(object_t *o) {
return creator; return creator;
} }
int getobjamdiff(int depth) {
return 100 + rnd(1,100);
}
// returns the amount to adjust a skillcheck roll if you give object 'o' to lifeform 'lf' // returns the amount to adjust a skillcheck roll if you give object 'o' to lifeform 'lf'
// //
// if 'why' is provided, it will be populated with the reason the monster wants it. // if 'why' is provided, it will be populated with the reason the monster wants it.
@ -4672,6 +4691,20 @@ int getobpoints(object_t *o) {
return getobvalue(o); return getobvalue(o);
} }
void getobs(obpile_t *op, condset_t *cs, object_t **ob, int *nobs) {
object_t *o;
*nobs = 0;
if (!op) return;
for (o = op->first ; o ; o = o->next) {
if (obmeets(o, cs)) {
ob[*nobs] = o;
(*nobs)++;
}
}
}
// returns the skill associated with this object // returns the skill associated with this object
// (via its flagpile) // (via its flagpile)
skill_t *getobskill(flagpile_t *fp) { skill_t *getobskill(flagpile_t *fp) {
@ -9828,6 +9861,17 @@ int obmeetscondition(object_t *o, enum CELLCONDITION cond, int arg, int value) {
} }
} }
break; break;
case CC_MAXAR:
f = hasflag(o->flags, F_ARMOURRATING);
if (f) {
n = f->val[0];
} else {
n = 0;
}
if (n <= arg) {
check = B_TRUE;
}
break;
case CC_MINDR: case CC_MINDR:
f = hasflag(o->flags, F_DAM); f = hasflag(o->flags, F_DAM);
if (f) { if (f) {
@ -9939,6 +9983,7 @@ int otmeets(objecttype_t *ot, condset_t *cs) {
int otmeetscondition(objecttype_t *ot, enum CELLCONDITION cond, int arg, int value) { int otmeetscondition(objecttype_t *ot, enum CELLCONDITION cond, int arg, int value) {
int ok = B_FALSE; int ok = B_FALSE;
int check = B_FALSE; int check = B_FALSE;
int n;
skill_t *sk = NULL; skill_t *sk = NULL;
flag_t *f; flag_t *f;
assert(ot); assert(ot);
@ -9981,6 +10026,17 @@ int otmeetscondition(objecttype_t *ot, enum CELLCONDITION cond, int arg, int val
} }
} }
break; break;
case CC_MAXAR:
f = hasflag(ot->flags, F_ARMOURRATING);
if (f) {
n = f->val[0];
} else {
n = 0;
}
if (n <= arg) {
check = B_TRUE;
}
break;
case CC_MINDR: case CC_MINDR:
f = hasflag(ot->flags, F_DAM); f = hasflag(ot->flags, F_DAM);
if (f) { if (f) {
@ -10533,6 +10589,20 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
if (hasflag(o->flags, F_CONTAINER) && !hasflag(o->flags, F_SHOP)) { // loot it if (hasflag(o->flags, F_CONTAINER) && !hasflag(o->flags, F_SHOP)) { // loot it
if (isplayer(lf)) { // only player can loot. if (isplayer(lf)) { // only player can loot.
char ch; char ch;
f = hasflag(o->flags, F_JAMMED);
if (f) {
int openit = B_FALSE;
if (f->val[1] != B_TRUE) { // not known yet
msg("The %s seems to be jammed.", noprefix(obname));
f->val[1] = B_TRUE;
} else {
// try to force
openit = unjam(lf, o);
}
if (!openit) {
return B_TRUE;
}
}
if (hasflag(o->flags, F_LOCKED)) { if (hasflag(o->flags, F_LOCKED)) {
msg("The %s seems to be locked.", noprefix(obname)); msg("The %s seems to be locked.", noprefix(obname));
return B_TRUE; return B_TRUE;
@ -10572,6 +10642,8 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
} }
} else { } else {
snprintf(buf, BUFLEN, "Looting %s. Will you:",obname); snprintf(buf, BUFLEN, "Looting %s. Will you:",obname);
addflagifneeded(o->flags, F_BEENOPENED, B_TRUE, NA, NA, NULL);
initprompt(&prompt, buf); initprompt(&prompt, buf);
if (countobs(lf->pack, B_FALSE)) { if (countobs(lf->pack, B_FALSE)) {
snprintf(buf, BUFLEN, "Put items in %s",obname); snprintf(buf, BUFLEN, "Put items in %s",obname);
@ -11616,7 +11688,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
char obname[BUFLEN]; char obname[BUFLEN];
getobname(o, obname, 1); getobname(o, obname, 1);
msg("You stick your gum into the hinges of %s.", obname); msg("You stick your gum into the hinges of %s.", obname);
addflag(o->flags, F_JAMMED, rnd(5,10), B_TRUE, NA, NULL); addflag(o->flags, F_JAMMED, 1, B_TRUE, 100, NULL);
taketime(lf, getactspeed(lf)); taketime(lf, getactspeed(lf));
donesomething = B_TRUE; donesomething = B_TRUE;
} }
@ -11661,7 +11733,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
ch = askchar(buf, "yn", "y", B_TRUE, B_FALSE); ch = askchar(buf, "yn", "y", B_TRUE, B_FALSE);
if (ch == 'y') { if (ch == 'y') {
msg("You tighten the hinges on %s.", obname); msg("You tighten the hinges on %s.", obname);
addflag(o->flags, F_JAMMED, rnd(5,10), B_TRUE, NA, NULL); addflag(o->flags, F_JAMMED, 2, B_TRUE, 150, NULL);
taketime(lf, getactspeed(lf)); taketime(lf, getactspeed(lf));
donesomething = B_TRUE; donesomething = B_TRUE;
} }
@ -13358,6 +13430,18 @@ int readsomething(lifeform_t *lf, object_t *o) {
char ch = 'a'; char ch = 'a';
enum SPELLSCHOOL school; enum SPELLSCHOOL school;
enum SKILLLEVEL slev; enum SKILLLEVEL slev;
maketried(o->type->id, NULL);
// identify right away.
if (isplayer(lf) && !isknown(o)) {
identify(o);
o->blessknown = B_TRUE;
real_getobname(o, obname, 1, B_NOPREMODS, B_CONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOUSED, B_NOSHOWALL);
// tell the player
msg("This is %s!",obname);
more();
drawmsg();
}
if (o->type->id == OT_SPELLBOOK) { if (o->type->id == OT_SPELLBOOK) {
f = hasflag(o->flags, F_LINKSCHOOL); f = hasflag(o->flags, F_LINKSCHOOL);
school = f->val[0]; school = f->val[0];
@ -13366,7 +13450,6 @@ int readsomething(lifeform_t *lf, object_t *o) {
if (!slev) { if (!slev) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You cannot comprehend the contents of this book."); msg("You cannot comprehend the contents of this book.");
maketried(o->type->id, NULL);
} }
return B_FALSE; return B_FALSE;
} }
@ -13385,23 +13468,11 @@ int readsomething(lifeform_t *lf, object_t *o) {
if (!found) { if (!found) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You cannot comprehend the contents of this book."); msg("You cannot comprehend the contents of this book.");
maketried(o->type->id, NULL);
} }
return B_FALSE; return B_FALSE;
} }
} }
// player now knows what it is - id it!
if (isplayer(lf) && !isknown(o)) {
identify(o);
o->blessknown = B_TRUE;
real_getobname(o, obname, 1, B_NOPREMODS, B_CONDITION, B_NOBLINDADJUST, B_BLESSINGS, B_NOUSED, B_NOSHOWALL);
// tell the player
msg("This is %s!",obname);
more();
drawmsg();
}
// we are skilled in the right school. now ask which spell to learn. // we are skilled in the right school. now ask which spell to learn.
initprompt(&prompt, "Which spell will you try to learn?"); initprompt(&prompt, "Which spell will you try to learn?");
for (oo = o->contents->first ;oo ; oo = oo->next) { for (oo = o->contents->first ;oo ; oo = oo->next) {
@ -16935,6 +17006,76 @@ int uncurseob(object_t *o, int *seen) {
return B_FALSE; return B_FALSE;
} }
// try to unjam a door/container
//
// returns TRUE if the unjam was successful
int unjam(lifeform_t *lf, object_t *o) {
char obname[BUFLEN];
int openit = B_FALSE;
int amt = 0;
flag_t *f;
cell_t *c;
c = getoblocation(o);
f = hasflag(o->flags, F_JAMMED);
if (!f) {
return B_TRUE;
}
getobname(o, obname, 1);
if (skillcheck(lf, SC_STR, f->val[2], 0)) {
amt = 1;
}
// loosen a bit
if (amt > 0) {
f->val[0] -= amt;
}
if (isplayer(lf)) {
if (amt > 0) {
if (f->val[0] > 0) {
msg("The %s moves slightly but remains jammed.", noprefix(obname));
}
// otherwise we opened it! unjammed doors will be announced seperately.
if (!isdoor(o, NULL)) {
msg("You force %s open!",obname);
}
} else {
msg("You cannot budge the jammed %s.", noprefix(obname));
}
} else {
// ai chasing someone and not strong enough to unjam the door?
if (isdoor(o, NULL) && (amt == 0) && willattackdoors(lf)) {
attackcell(lf, c, B_TRUE);
return B_FALSE;
} else {
// try to force it
if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s tries to open %s, but fails.", lfname, obname);
} else if (haslos(player, c)) {
msg("Something tries to open %s.", obname);
} else {
if (isdoor(o, NULL)) {
char noisebuf[BUFLEN];
sprintf(noisebuf, "%s jiggling against its hinges.", obname);
noise(c, NULL, NC_OTHER, SV_SHOUT, noisebuf, NULL);
}
}
}
}
if (f->val[0] <= 0) {
killflag(f);
f = NULL;
openit = B_TRUE;
} else {
openit = B_FALSE; // don't open the door
}
return openit;
}
// returns charges remaining, -1 if object doesn't have the flag or is // returns charges remaining, -1 if object doesn't have the flag or is
// out of charges. // out of charges.
int usecharge(object_t *o) { int usecharge(object_t *o) {

View File

@ -93,8 +93,10 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob
int getobaccuracy(object_t *wep, lifeform_t *weilder, int forthrow); int getobaccuracy(object_t *wep, lifeform_t *weilder, int forthrow);
int getobbonus(object_t *o, int onlyknown); int getobbonus(object_t *o, int onlyknown);
lifeform_t *getobcreatedby(object_t *o); lifeform_t *getobcreatedby(object_t *o);
int getobjamdiff(int depth);
int getoboffermod(object_t *o, lifeform_t *lf, char *why); int getoboffermod(object_t *o, lifeform_t *lf, char *why);
int getobpoints(object_t *o); int getobpoints(object_t *o);
void getobs(obpile_t *op, condset_t *cs, object_t **retob, int *nretobs);
skill_t *getobskill(flagpile_t *fp); skill_t *getobskill(flagpile_t *fp);
enum LFSIZE getobsize(object_t *o); enum LFSIZE getobsize(object_t *o);
int getobspellpower(object_t *o, lifeform_t *lf); int getobspellpower(object_t *o, lifeform_t *lf);
@ -312,6 +314,7 @@ int trytokillobs(obpile_t *op);
void turnoff(lifeform_t *lf, object_t *o); void turnoff(lifeform_t *lf, object_t *o);
void turnon(lifeform_t *lf, object_t *o); void turnon(lifeform_t *lf, object_t *o);
int uncurseob(object_t *o, int *seen); int uncurseob(object_t *o, int *seen);
int unjam(lifeform_t *lf, object_t *o);
int usecharge(object_t *o); int usecharge(object_t *o);
int usecharges(object_t *o, int amt); int usecharges(object_t *o, int amt);
int usefountaincharge(object_t *o, flag_t *drinkflag); int usefountaincharge(object_t *o, flag_t *drinkflag);

19
spell.c
View File

@ -881,10 +881,15 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (corpse) { if (corpse) {
getobname(corpse, obname, o->amt); getobname(corpse, obname, o->amt);
if (isimmuneto(corpse->flags, DT_FIRE, B_FALSE)) { if (getobsize(corpse) > (getskill(user, SK_COOKING)+1)) {
msg("%s is too large for you to cook at the moment.", obname);
ncooked++;
break;
} else if (isimmuneto(corpse->flags, DT_FIRE, B_FALSE)) {
msg("^wYou attempt to cook %s, but it won't heat up.^n", obname); msg("^wYou attempt to cook %s, but it won't heat up.^n", obname);
cooktime += getactspeed(user); cooktime += getactspeed(user);
ncooked++; ncooked++;
break;
} else { } else {
preparecorpse(user, corpse); preparecorpse(user, corpse);
if (isresistantto(corpse->flags, DT_FIRE, B_FALSE)) { if (isresistantto(corpse->flags, DT_FIRE, B_FALSE)) {
@ -7085,9 +7090,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
lifeform_t *poss[MAXCANDIDATES]; lifeform_t *poss[MAXCANDIDATES];
int nposs = 0; int nposs = 0;
if (isplayer(caster)) { if (isplayer(caster)) {
msg("A burst of fireworks explodes around you!"); msg("^wA burst of fireworks explodes around you!");
} else if (cansee(player, caster)) { } else if (cansee(player, caster)) {
msg("A burst of fireworks explodes around %s!", castername); msg("^wA burst of fireworks explodes around %s!", castername);
} }
for (target = caster->cell->map->lf ; target ; target = target->next) { for (target = caster->cell->map->lf ; target ; target = target->next) {
if (target == caster) continue; if (target == caster) continue;
@ -8223,6 +8228,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
object_t *o,*oo; object_t *o,*oo;
cell_t *c; cell_t *c;
condset_t cs; condset_t cs;
int jamamt = 1;
o = hasobwithflag(targcell->obpile, F_DOOR); o = hasobwithflag(targcell->obpile, F_DOOR);
if (!o) { if (!o) {
@ -8241,7 +8247,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
closedoor(NULL, o); closedoor(NULL, o);
addflag(o->flags, F_JAMMED, power*2, haslos(player, targcell) ? B_TRUE : B_FALSE, NA, NULL); jamamt = power/2;
limit(&jamamt, 1, NA);
addflag(o->flags, F_JAMMED, jamamt, haslos(player, targcell) ? B_TRUE : B_FALSE, 150 + (power*10), NULL);
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
char buf[BUFLEN]; char buf[BUFLEN];
@ -11374,6 +11382,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
getlfname(target, targname); getlfname(target, targname);
msg("^%c%s looks very lethargic!", getlfcol(target, CC_BAD), targname); msg("^%c%s looks very lethargic!", getlfcol(target, CC_BAD), targname);
} }
// cancels rage
killflagsofid(target->flags, F_RAGE);
modstamina(target, -amttolose); modstamina(target, -amttolose);
} else if (spellid == OT_S_REFRACTION) { } else if (spellid == OT_S_REFRACTION) {
flag_t *f; flag_t *f;

View File

@ -971,7 +971,7 @@ int handleline(vault_t *v, char *line) {
error = B_TRUE; error = B_TRUE;
} }
if ((tt2 != VT_NONE) && !real_vaultthingok(tt2,what2, &hasfire)) { if ((tt2 != VT_NONE) && !real_vaultthingok(tt2,what2, &hasfire)) {
dblog("invalid legend alternative definition: '%s'", line); dblog("invalid legend alternative definition: '%s' (what2='%s')", line,what2);
error = B_TRUE; error = B_TRUE;
} }
if (!error) { if (!error) {
@ -1302,7 +1302,8 @@ int handleline(vault_t *v, char *line) {
addflag(v->flags, F_VAULTSCATTER, thingtype, pct, NA, buf); addflag(v->flags, F_VAULTSCATTER, thingtype, pct, NA, buf);
ok = B_TRUE; ok = B_TRUE;
} else { } else {
dblog("invalid scatter() definition: '%s'", line); dblog("invalid scatter() definition: '%s' (thing='%s',min-max=%d-%d,pct=%d)" ,
line, thingname,countmin,countmax,pct);
} }
} else if (strstarts(line, "autodoors")) { } else if (strstarts(line, "autodoors")) {
char *p; char *p;