- [+] 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)) {
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)) {
specificcheckok = B_FALSE;
}

173
data.c
View File

@ -183,6 +183,7 @@ void initcommands(void) {
//addcommand(CMD_DROP, 'd', "Drop an item.");
addcommand(CMD_DROPMULTI, 'd', "Drop one or more items.");
addcommand(CMD_EAT, 'e', "Eat something.");
addcommand(CMD_INTERACT, 'I', "Interact with adjacent objects.");
addcommand(CMD_MAGIC, 'm', "Use magic or abilities.");
addcommand(CMD_MEMMAGIC, 'M', "Memorise a hotkey for magic or abilities.");
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_SHORTSWORD, 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);
// stats
@ -1455,7 +1457,7 @@ void initjobs(void) {
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, 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);
// monster job flags
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, 7, F_DETECTAURAS, 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);
// monster job flags
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, 7, F_DETECTAURAS, 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);
// monster job flags
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, 7, F_DETECTAURAS, 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);
// monster job flags
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_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);
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_DUNGEON, 100, RR_COMMON, 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);
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_CAVE, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL);
// 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);
@ -6505,6 +6507,7 @@ void initobjects(void) {
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);
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_VALUE, 2000, NA, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
@ -7414,6 +7417,7 @@ void initobjects(void) {
// furniture
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_IMPASSABLE, SZ_MIN, SZ_LARGE, 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_NOPICKUP, B_TRUE, NA, NA, NULL);
@ -7443,6 +7447,8 @@ void initobjects(void) {
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);
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_GLYPH, C_WOOD, '\\', 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_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);
addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_UNCOMMON, 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_OPERABLE, 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_FOOD, NA, NULL);
@ -15983,7 +16004,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 5, 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_IQ, IQ_ANIMAL, 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)) {
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)) {
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);
}
addraceclassflags(r->flags, r->raceclass->id, r->id);
// fill in missing alignments
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_MASTER, "^gAttacking will no longer drain your stamina.^n", B_TRUE);
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_NOVICE, "^gYou can now cook corpses before consumption.^n", 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 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
#define D_ALWAYSFAIL -99
#define D_BADFEELING 120
// how many blood splashes you need before you
// can fill a flask with it.
@ -484,6 +485,7 @@ enum CELLCONDITION {
CC_KNOWN,
CC_IDENTIFIED,
CC_MINAR, // arg
CC_MAXAR, // arg
CC_MINDR, // arg
CC_MAXDR, // arg
CC_MAXSIZE, // arg is max size
@ -2345,6 +2347,7 @@ enum OBTYPE {
OT_CANDELABRUM,
OT_COFFIN,
OT_FIREPLACE,
OT_WARDROBE,
OT_WEAPONRACK,
OT_WOODENTABLE,
OT_WOODENBARREL,
@ -2859,6 +2862,8 @@ enum FLAG {
// player killed, and has not yet been touched.
F_UNTOUCHED, // this obejct has not yet been picked up by anyone
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_DEAD, // object will be removed. v0 = lfid who killed it
F_ONEPERCELL, // only one of these objects can exist per cell
@ -3188,6 +3193,9 @@ enum FLAG {
// v0 = base pct chance
// v1 = extra pct chance every 5 levels
// 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
// v0 = base pct chance
// v1 = extra pct chance every 5 levels
@ -3239,8 +3247,11 @@ enum FLAG {
F_LOCKED,// door is locked
// v1 is difficulty to disarm
// 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.
// v1 = have we tried this door yet?
F_JAMMED, // is this door/container jammed?
// 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
// to find it.
// NA means 'can never find this'
@ -4666,6 +4677,7 @@ enum COMMAND {
CMD_INFOARMOUR,
CMD_INFOKNOWLEDGE,
CMD_INFOPLAYER,
CMD_INTERACT,
CMD_INV,
CMD_LOOKAROUND,
CMD_LOOKHERE,

View File

@ -73,6 +73,7 @@ Flags can be:
entertext:xxx // show xxx when a non-blind player enters
goesin:xxx // can only randomly appear in habitat xxx
// (can appear multiple times)
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) {
case 'a':
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;
}
if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname);
if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break;
}
if (lf == lf2) {
// 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 {
if (!cansee(lf, lf2)) {
turntoface(lf, lf2->cell);
@ -4534,11 +4534,11 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
break;
case 'c':
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;
}
if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname);
if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break;
}
// 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...
killflagsofid(lf->flags, F_TARGETLF);
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;
}
if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname);
if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break;
}
aigoto(lf, targc, MR_OTHER, NULL, DEF_AIFOLLOWTIME);
break;
case 'i':
if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname);
if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break;
}
if (askforinfo(lf, 2)) {
@ -4790,25 +4790,25 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
case 'j':
// charisma check to see if they'll join you.
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;
}
if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname);
if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break;
}
recruit(lf);
break;
case 'k': // trade Knowledge
if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname);
if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break;
}
tradeknowledge(lf);
break;
case 'm': // mercy
if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname);
if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break;
}
if (islowhp(player) &&
@ -4878,11 +4878,11 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
*/
case 'r':
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;
}
if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname);
if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break;
}
f = isresting(lf);
@ -4904,7 +4904,7 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
return;
case 't':
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;
}
// ask whtehr to give/take
@ -4936,7 +4936,7 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
break;
case 'x':
if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname);
if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break;
}
if (askforinfo(lf, 4)) {
@ -4949,22 +4949,22 @@ void docommslf(lifeform_t *lf, char ch, lifeform_t *lf2, cell_t *targc) {
break;
case '<':
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;
}
if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname);
if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break;
}
setfollowdistance(lf, 1, 3);
break;
case '>':
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;
}
if (lfhasflag(lf, F_PHANTASM)) {
msg("%s doesn't respond.", lfname);
if (cansee(player, lf)) msg("%s doesn't respond.", lfname);
break;
}
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);
}
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)) {
msg("Cancelled.");
return;
@ -5536,7 +5536,7 @@ int dowear(obpile_t *op) {
CC_NONE);
o = askobject(op, "Wear what", "You have nothing to wear!", NULL, '\0', &cs, B_FALSE);
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)) {
msg("Cancelled.");
return B_TRUE;
@ -5562,7 +5562,7 @@ int doweild(obpile_t *op) {
CC_NONE);
o = askobject(op, "Weild what", "You have nothing to weild.", &count, 'w', &cs, B_TRUE);
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)) {
msg("Cancelled.");
return B_TRUE;
@ -7563,6 +7563,13 @@ char *makedesc_ob(object_t *o, char *retbuf) {
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 ((o->type->id == OT_SPELLBOOK) || (o->type->id == OT_GRIMOIRE)) {
@ -9037,6 +9044,63 @@ void dohelp(char helpmode) {
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) {
object_t *o;
char buf[BUFLEN];
@ -9092,7 +9156,7 @@ void doquaff(obpile_t *op) {
}
if (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)) {
msg("Cancelled.");
return;
@ -10889,6 +10953,9 @@ void handleinput(void) {
case CMD_INFOARMOUR: // display armour
showlfarmour(player);
break;
case CMD_INTERACT: // interact with adjacent objects
dointeract();
break;
case CMD_LOOKHERE: // look at what's here
dolook(player->cell, B_TRUE);
break;
@ -13671,7 +13738,7 @@ void showlfstats(lifeform_t *lf, int showall) {
f = hasflag_real(lf->flags, F_FEARLESS, B_TRUE, NULL, FROMRACE);
if (f) {
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);

1
io.h
View File

@ -62,6 +62,7 @@ void doexplain(char *question);
void dofinaloblist(obpile_t *op);
void dofire(void);
void dohelp(char helpmode);
void dointeract(void);
void doinventory(obpile_t *op);
void doknowledgelist(void);
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)) {
msg("%s starts casting a spell.", lfname);
} else {
msg("%s casts a spell.", lfname);
}
}
} else { // player can't see them
@ -5018,6 +5019,7 @@ int eat(lifeform_t *lf, object_t *o) {
}
// limit nutrition
//if (nutrition > (HUNGERCONST/2)) nutrition = (HUNGERCONST/2);
nutrition /= 2;
rawmeat = B_TRUE;
}
@ -5173,12 +5175,12 @@ int eat(lifeform_t *lf, object_t *o) {
char dambuf[BUFLEN];
snprintf(dambuf, BUFLEN, "a bad %s",noprefix(obname));
if (hasflag(corpserace->flags, F_AVIAN)) {
checkdiff = 100;
checkdiff = 120;
ptid = P_FOODBAD;
timemin = 30;
timemax = 50;
} else {
checkdiff = 65;
checkdiff = 85;
if (onein(3)) {
ptid = P_FOOD;
} 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 *a,*temp;
int count = 0;
@ -15788,7 +15929,7 @@ lifeform_t *makezombie(object_t *o, int power, char *description, lifeform_t *ma
flag_t *f;
race_t *r;
lifeform_t *lf;
cell_t *where;
cell_t *where,*origwhere;
char obname[BUFLEN];
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]);
if (!r) return NULL;
where = getoblocation(o);
origwhere = getoblocation(o);
where = origwhere;
getobname(o, obname, 1);
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_DTVULN);
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);
addflag(lf->flags, F_NOSTAIRS, B_TRUE, NA, NA, NULL);
addraceclassflags(lf->flags, RC_UNDEAD, R_NONE);
if (hasflag(o->flags, F_HEADLESS)) {
// remove the head
@ -15885,7 +16022,7 @@ lifeform_t *makezombie(object_t *o, int power, char *description, lifeform_t *ma
removeob(o,o->amt);
// redraw & announce
if (haslos(player, where)) {
if (haslos(player, where) || haslos(player, origwhere)) {
needredraw = B_TRUE;
drawscreen();
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);
// higher roll is better
roll = rnd(1,100);
//roll = rnd(1,50);
//roll = rnd(1,100);
roll = rnd(1,50);
// debugging for new skillcheck code
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);
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);
void addraceclassflags(flagpile_t *fp, enum RACECLASS rcid, enum RACE rid);
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 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;
f->val[1] = B_TRUE;
} else {
// known - try to force it
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
}
openit = unjam(lf, o);
} // end if jammedknown
} // end if jammed

197
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 MATERIAL wantdiffmat = MT_NOTHING;
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
map_t *targetmap = 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 trapchance = 0;
int lockchance = 0;
int jamchance = 0;
flag_t *retflag[MAXCANDIDATES];
int nretflags = 0;
@ -829,7 +830,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
p += strlen("locked ");
donesomething = B_TRUE;
} else if (strstarts(p, "jammed ")) {
doorflag[ndoorflags++] = F_JAMMED;
//doorflag[ndoorflags++] = F_JAMMED;
jamchance = 100;
p += strlen("jammed ");
donesomething = B_TRUE;
} 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?
if ((oc->id == OC_ARMOUR) && strstr(p, "armour")) {
limit(&minar, 1, NA);
if (oc->id == OC_ARMOUR) {
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 (mindr != NA) {
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;
ok = B_TRUE;
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:
val[0] = getdoorsecretdiff(obloc->map->depth);
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);
}
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%
if (!trapchance) {
f = hasflag(o->flags, F_CANBETRAPPED);
@ -4639,6 +4654,10 @@ lifeform_t *getobcreatedby(object_t *o) {
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'
//
// 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);
}
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
// (via its flagpile)
skill_t *getobskill(flagpile_t *fp) {
@ -9828,6 +9861,17 @@ int obmeetscondition(object_t *o, enum CELLCONDITION cond, int arg, int value) {
}
}
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:
f = hasflag(o->flags, F_DAM);
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 ok = B_FALSE;
int check = B_FALSE;
int n;
skill_t *sk = NULL;
flag_t *f;
assert(ot);
@ -9981,6 +10026,17 @@ int otmeetscondition(objecttype_t *ot, enum CELLCONDITION cond, int arg, int val
}
}
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:
f = hasflag(ot->flags, F_DAM);
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 (isplayer(lf)) { // only player can loot.
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)) {
msg("The %s seems to be locked.", noprefix(obname));
return B_TRUE;
@ -10572,6 +10642,8 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
}
} else {
snprintf(buf, BUFLEN, "Looting %s. Will you:",obname);
addflagifneeded(o->flags, F_BEENOPENED, B_TRUE, NA, NA, NULL);
initprompt(&prompt, buf);
if (countobs(lf->pack, B_FALSE)) {
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];
getobname(o, obname, 1);
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));
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);
if (ch == 'y') {
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));
donesomething = B_TRUE;
}
@ -13358,6 +13430,18 @@ int readsomething(lifeform_t *lf, object_t *o) {
char ch = 'a';
enum SPELLSCHOOL school;
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) {
f = hasflag(o->flags, F_LINKSCHOOL);
school = f->val[0];
@ -13366,7 +13450,6 @@ int readsomething(lifeform_t *lf, object_t *o) {
if (!slev) {
if (isplayer(lf)) {
msg("You cannot comprehend the contents of this book.");
maketried(o->type->id, NULL);
}
return B_FALSE;
}
@ -13385,23 +13468,11 @@ int readsomething(lifeform_t *lf, object_t *o) {
if (!found) {
if (isplayer(lf)) {
msg("You cannot comprehend the contents of this book.");
maketried(o->type->id, NULL);
}
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.
initprompt(&prompt, "Which spell will you try to learn?");
for (oo = o->contents->first ;oo ; oo = oo->next) {
@ -16935,6 +17006,76 @@ int uncurseob(object_t *o, int *seen) {
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
// out of charges.
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 getobbonus(object_t *o, int onlyknown);
lifeform_t *getobcreatedby(object_t *o);
int getobjamdiff(int depth);
int getoboffermod(object_t *o, lifeform_t *lf, char *why);
int getobpoints(object_t *o);
void getobs(obpile_t *op, condset_t *cs, object_t **retob, int *nretobs);
skill_t *getobskill(flagpile_t *fp);
enum LFSIZE getobsize(object_t *o);
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 turnon(lifeform_t *lf, object_t *o);
int uncurseob(object_t *o, int *seen);
int unjam(lifeform_t *lf, object_t *o);
int usecharge(object_t *o);
int usecharges(object_t *o, int amt);
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) {
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);
cooktime += getactspeed(user);
ncooked++;
break;
} else {
preparecorpse(user, corpse);
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];
int nposs = 0;
if (isplayer(caster)) {
msg("A burst of fireworks explodes around you!");
msg("^wA burst of fireworks explodes around you!");
} 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) {
if (target == caster) continue;
@ -8223,6 +8228,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
object_t *o,*oo;
cell_t *c;
condset_t cs;
int jamamt = 1;
o = hasobwithflag(targcell->obpile, F_DOOR);
if (!o) {
@ -8241,7 +8247,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
}
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)) {
char buf[BUFLEN];
@ -11374,6 +11382,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
getlfname(target, targname);
msg("^%c%s looks very lethargic!", getlfcol(target, CC_BAD), targname);
}
// cancels rage
killflagsofid(target->flags, F_RAGE);
modstamina(target, -amttolose);
} else if (spellid == OT_S_REFRACTION) {
flag_t *f;

View File

@ -971,7 +971,7 @@ int handleline(vault_t *v, char *line) {
error = B_TRUE;
}
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;
}
if (!error) {
@ -1302,7 +1302,8 @@ int handleline(vault_t *v, char *line) {
addflag(v->flags, F_VAULTSCATTER, thingtype, pct, NA, buf);
ok = B_TRUE;
} 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")) {
char *p;