diff --git a/ai.c b/ai.c index 675f507..2c57301 100644 --- a/ai.c +++ b/ai.c @@ -666,7 +666,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) { if (getschool(spell) == SS_ABILITY) { spellfailed = useability(lf, spell, spelllf, spellcell); } else { - spellfailed = castspell(lf, spell, spelllf, spellob, spellcell); + spellfailed = castspell(lf, spell, spelllf, spellob, spellcell, NULL, NULL); } } if (spellfailed) { @@ -1161,7 +1161,7 @@ void aiturn(lifeform_t *lf) { // hurt gods planeshift away if (lf->race->raceclass->id == RC_GOD) { if (gethppct(lf) <= 10) { - if (!castspell(lf, OT_S_PLANESHIFT, lf, NULL, lf->cell)) { + if (!castspell(lf, OT_S_PLANESHIFT, lf, NULL, lf->cell, NULL, NULL)) { return; } } @@ -1500,7 +1500,7 @@ void aiturn(lifeform_t *lf) { if (lf->race->raceclass->id == RC_GOD) { if (onein(6)) { // gods will planeshift away - if (!castspell(lf, OT_S_PLANESHIFT, lf, NULL, lf->cell)) { + if (!castspell(lf, OT_S_PLANESHIFT, lf, NULL, lf->cell, NULL, NULL)) { return; } } @@ -1976,7 +1976,7 @@ object_t *hasbetterarmour(lifeform_t *lf, obpile_t *op) { bp = f->val[0]; // is it better than what we have in that position? curarm = getarmour(lf, bp); - if (isbetterwepthan(o, curarm)) { + if (isbetterwepthan(o, curarm, lf)) { return o; } } @@ -1989,7 +1989,7 @@ object_t *hasbetterweapon(lifeform_t *lf, obpile_t *op) { bestwep = getbestweapon(lf); for (o = op->first ; o ; o = o->next) { - if (isweapon(o) && isbetterwepthan(o, bestwep) && canweild(lf, o)) { + if (isweapon(o) && isbetterwepthan(o, bestwep, lf) && canweild(lf, o)) { return o; } } @@ -2152,7 +2152,7 @@ int lookforobs(lifeform_t *lf) { if (gothere) { // cast a spell? if (cancast(lf, OT_S_CALLWIND, NULL) && haslof(lf->cell, c, LOF_NEED, NULL)) { - if (!castspell(lf, OT_S_CALLWIND, NULL, o, c)) { + if (!castspell(lf, OT_S_CALLWIND, NULL, o, c, NULL, NULL)) { // successful return B_TRUE; } diff --git a/attack.c b/attack.c index 1b682b9..618fcbc 100644 --- a/attack.c +++ b/attack.c @@ -199,7 +199,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { snprintf(buf, BUFLEN, "Really attack the allied %s?",noprefix(victimname)); break; } - ch = askchar(buf, "yn","n", B_TRUE); + ch = askchar(buf, "yn","n", B_TRUE, B_FALSE); if (ch == 'n') { // cancel. return B_TRUE; @@ -220,6 +220,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { } killflagsofid(c->lf->flags, F_PRONE); // still counts as a move! + if (isplayer(lf)) addflag(lf->flags, F_MOVED, B_TRUE, NA, NA, NULL); taketime(lf, getmovespeed(lf)); return B_FALSE; } @@ -247,7 +248,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { real_getobname(o, obname, o->amt, B_FALSE, B_FALSE, B_TRUE, B_FALSE, B_FALSE); getobname(priwep, wepname, priwep->amt); snprintf(buf, BUFLEN, "Attacking %s might damage your %s. Proceed?", obname, noprefix(wepname)); - ch = askchar(buf, "yn","n", B_TRUE); + ch = askchar(buf, "yn","n", B_TRUE, B_FALSE); if (ch == 'n') { // cancel. return B_TRUE; @@ -360,6 +361,9 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { } } + if (maxattacks) { + if (isplayer(lf)) addflag(lf->flags, F_MOVED, B_TRUE, NA, NA, NULL); + } attacksdone = 0; while (attacksdone < maxattacks) { @@ -383,7 +387,12 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { if (isbehind(lf, victim)) { msg("You attack %s from behind!", vname); } else { - msg("You attack the helpless %s!", vname); + char *vn; + // strip "the" from "the xxx" + vn = strdup(vname); + vn = strrep(vn, "the ", "", NULL); + msg("You attack the helpless %s!", vn); + free(vn); } } } @@ -714,6 +723,15 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) dam[0] = (int)((float)dam[0] * getstrdammod(lf)); } + // modify for injuries + getflags(lf->flags, retflag, &nretflags, F_INJURY, F_NONE); + for (i = 0; i < nretflags; i++) { + switch (retflag[i]->val[0]) { + case IJ_TORSOBRUISEDBAD: dam[0] = pctof(90, dam[0]); break; + } + } + + // modify for size modifyforsize(&dam[0], lf, victim, 5, M_PCT); @@ -1954,7 +1972,7 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d } } - if ((damtype == DT_BASH) && lfhasflag(victim, F_FROZEN)) { + if ((damtype == DT_BASH) && ismadeofice(victim)) { return "shatter"; } @@ -1968,7 +1986,13 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d if (pct >= 70) { if (damtype == DT_PIERCE) return "impale"; - if (damtype == DT_BASH) return "flatten"; + if (damtype == DT_BASH) { + if (isunconscious(victim)) { + return "kill"; + } else { + return "flatten"; + } + } if (damtype == DT_BITE) return "gore"; if (damtype == DT_SLASH) { if (lfhasflagval(victim, F_NOBODYPART, BP_HEAD, NA, NA, NULL)) { @@ -2285,7 +2309,12 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical) } if (lfhasflag(lf, F_AIMEDSTRIKE)) { - acc -= 50; + acc -= 40; + } + + // easier to hit things which have grabbed you + if (lfhasflagval(lf, F_GRABBEDBY, victim->id, NA, NA, NULL)) { + acc += 30; } // harder to hit flying/levitating enemies, unless you are diff --git a/data.c b/data.c index c064d29..06107c5 100644 --- a/data.c +++ b/data.c @@ -135,7 +135,6 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 blessed potions of experience"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "ring of miracles"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "ring of control"); - addflag(lastjob->flags, F_STARTSKILL, SK_SPELLCASTING, PR_MASTER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_ARCANA, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_DEATH, PR_MASTER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_TRANSLOCATION, PR_MASTER, NA, NULL); @@ -169,7 +168,6 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_SKILLED, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LOCKPICKING, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SPELLCASTING, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_NOVICE, NA, NULL); @@ -236,6 +234,7 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_FIRSTAID, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_RANGED, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL); @@ -354,31 +353,34 @@ void initjobs(void) { // 20: tower of iron will // 21: planeshift addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); - addjob(J_MECHANIC, "Mechanic", "Mechanics, while highly paid, are not generally very suited for adventuring. Their spanner and metal-working skills might come in handy though."); + addjob(J_MECHANIC, "Mechanic", "Mechanics, while great at negotiating high hourly rates, are not generally very suited for adventuring. Their spanner and metal-working skills might come in handy though."); // stats + addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 1, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_CHA, -4, NA, NULL); // initial objects addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "spanner"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "80 gold coins"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "pair of safety goggles"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "overalls"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cap"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3-5 mushrooms"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "80 gold coins"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "block of chocolate"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 potions of oil"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "rubber boots"); // initial skills - addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_METALWORK, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_SPEECH, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_TECHUSAGE, PR_BEGINNER, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_ADEPT, NA, NULL); // learnable akills + addflag(lastjob->flags, F_CANLEARN, SK_CARTOGRAPHY, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, NA, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SPELLCASTING, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_PERCEPTION, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SWIMMING, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_THROWING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SS_ALLOMANCY, PR_ADEPT, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SS_FIRE, PR_ADEPT, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SS_COLD, PR_ADEPT, NA, NULL); // abilities - addflag(lastjob->flags, F_EVASION, 30, NA, NA, NULL); addflag(lastjob->flags, F_OBESE, B_TRUE, NA, NA, NULL); - addflag(lastjob->flags, F_CANWILL, OT_A_JUMP, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); addjob(J_PRINCE, "Prince", "Princes have lived a life of leisure and privilege. Their time is generally spent either hunting (making them quite fit and skilled with a bow) or reading (giving them knowledge about the world around them). As they normally travel with a pack of bodyguards though, their weapons are more for show than actually useful."); // stats @@ -497,7 +499,6 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_THROWING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_TWOWEAPON, PR_EXPERT, NA, NULL); - addflag(lastjob->flags, F_CANLEARN, SK_SPELLCASTING, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SS_DIVINATION, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SS_GRAVITY, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SS_MODIFICATION, PR_BEGINNER, NA, NULL); @@ -560,13 +561,14 @@ void initjobs(void) { addflag(lastjob->flags, F_LEVABIL, 10, OT_A_HURRICANESTRIKE, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); - addjob(J_WIZARD, "Wizard", "Wizards specialise in Arcane lore, using their magic to create awe-inspiring effects on the world around them."); + addjob(J_WIZARD, "Wizard", "Specialising in Arcane lore, high level wizards use their magic to create awe-inspiring effects on the world around them, raining death upon their enemies with eldritch wizardries. Not much is known about low level wizards, as they tend to get mauled to death by newts due to their lack of combat skills."); // stats addflag(lastjob->flags, F_JOBATTRMOD, A_STR, -4, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_IQ, 4, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_CON, -3, NA, NULL); // initial objects - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "knife"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "wizard staff"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "wizard hat"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "robe"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 potions of magic"); // monster wizards sometimes start with a random book @@ -576,16 +578,15 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_LORE_ARCANA, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_UNDEAD, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_DEMONS, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SPELLCASTING, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CHANNELING, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_STAVES, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_SS_WILD, PR_NOVICE, NA, NULL); // learnable skills addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SHORTBLADES, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SPEECH, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_STAVES, PR_ADEPT, NA, NULL); // limit addflag(lastjob->flags, F_CANLEARN, SK_SS_AIR, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SS_DEATH, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SS_DIVINATION, NA, NA, NULL); @@ -596,9 +597,11 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_SS_MODIFICATION, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SS_SUMMONING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SS_TRANSLOCATION, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_WILD, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LORE_DEMONS, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LORE_UNDEAD, NA, NA, NULL); // abilities + addflag(lastjob->flags, F_NEEDOBFORSPELLS, OT_WIZARDSTAFF, NA, NA, NULL); addflag(lastjob->flags, F_MAXHPMOD, 50, NA, NA, NULL); // low hp addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL); addflag(lastjob->flags, F_RESTHEALTIME, 6, NA, NA, NULL); // wizard heals slowly, but regenerates mp @@ -864,6 +867,9 @@ void initobjects(void) { addflag(lastmaterial->flags, F_MATCONVERT, MT_FIRE, NA, NA, "lump of melted wax"); addflag(lastmaterial->flags, F_MATCONVERTTEXT, MT_FIRE, NA, NA, "melts"); addflag(lastmaterial->flags, F_MATCONVERTTEXTPL, MT_FIRE, NA, NA, "melt"); + addmaterial(MT_DRAGONWOOD, "dragonwood", 3); + addflag(lastmaterial->flags, F_HARDNESS, 5, NA, NA, NULL); + addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL); addmaterial(MT_RUBBER, "rubber", 4); addmaterial(MT_LEATHER, "leather", 4); addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL); @@ -1514,11 +1520,19 @@ void initobjects(void) { addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL); - addot(OT_MUSHROOM, "mushroom", "A large brown mushroom.", MT_FOOD, 0.2, OC_FOOD, SZ_TINY); + addot(OT_MUSHROOMSHI, "shiitake mushroom", "A large brown mushroom.", MT_FOOD, 0.2, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_EDIBLE, B_TRUE, 60, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); + addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "mushroom"); + addot(OT_MUSHROOMTOAD, "toadstool", "A poisonous variety of mushroom.", MT_FOOD, 0.2, OC_FOOD, SZ_TINY); + addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, NULL); + addflag(lastot->flags, F_TAINTED, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); + addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL); + addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); + addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "mushroom"); addot(OT_BREADSTALE, "loaf of stale bread", "A small loaf of old, stale bread.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "%"); addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, ""); @@ -2022,7 +2036,7 @@ void initobjects(void) { // elemental - air /////////////////// // l1 - addot(OT_S_MIST, "pea soup", "Hides the caster from view with a thick cloud of mist.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_MIST, "pea soup", "Envelops the area directly ahead of the caster with a thick cloud of mist.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how long the mist will last."); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); @@ -2039,7 +2053,7 @@ void initobjects(void) { addot(OT_S_JOLT, "jolt", "Jolts an adjacent enemy with a short pulse of electricity, dealing 1-^bpower^n damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); - addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); + addflag(lastot->flags, F_MAXPOWER, 10, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); @@ -2110,7 +2124,7 @@ void initobjects(void) { addot(OT_S_SPARK, "spark", "Creates a tiny spark of flame, dealing 1-3 fire damage to creatures and objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); - addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT|TT_MONSTER, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); @@ -2121,7 +2135,6 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); - addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_FIREDART, "flame dart", "Fires a medium-sized dart of fire, dealing 1d6+^bpower^n fire damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2493,12 +2506,11 @@ void initobjects(void) { // gravity /////////////////// // l1 - addot(OT_S_TRUESTRIKE, "weapon attraction", "Gives the target unerring accuracy, making their attacks always hit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_TRUESTRIKE, "weapon attraction", "Gives the target unerring accuracy, making their attacks always hit and negating strength penalties.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the amount of strikes before it expires."); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); - addflag(lastot->flags, F_TARGETTEDSPELL, TT_PLAYER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL); // l2 @@ -2522,7 +2534,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_ADJSELF, NA, NA, NULL); // l4 - addot(OT_S_GRAVBOOST, "boost gravity", "Greatly increases gravity around the target, stopping them from moving.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_GRAVBOOST, "boost gravity", "Greatly increases gravity around the target, preventing them from moving.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long its effects will last."); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); @@ -3220,7 +3232,7 @@ void initobjects(void) { addflag(lastot->flags, F_CHARGEOUTMSG, B_TRUE, NA, NA, "goes out"); addot(OT_FRIDGE, "refrigerator", "An insulated household appliance, made for storing food.", MT_METAL, 120, OC_TOOLS, SZ_HUMAN); - addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); + addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GLYPH, C_WHITE, NA, NA, "]"); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); @@ -3991,7 +4003,7 @@ void initobjects(void) { addot(OT_DUSTCLOUD, "large dust cloud", "A very thick cloud of dust particles.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_BROWN, NA, NA, "}"); addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL); - addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "small dust cloud"); + addflag(lastot->flags, F_DIECONVERT, 1, NA, NA, "small dust cloud"); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); @@ -4018,7 +4030,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_WALKDAM,DT_FIRE, NA, NA, "2d4+4"); + addflag(lastot->flags, F_WALKDAM,DT_FIRE, NA, NA, "8d4"); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 3, NA, NA, NULL); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); @@ -4029,7 +4041,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_WALKDAM, DT_FIRE, NA, NA, "2d4"); + addflag(lastot->flags, F_WALKDAM, DT_FIRE, NA, NA, "4d4"); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); @@ -4039,7 +4051,7 @@ void initobjects(void) { addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_WALKDAM, DT_FIRE, NA, NA, "1d4"); + addflag(lastot->flags, F_WALKDAM, DT_FIRE, NA, NA, "2d4"); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 1, NA, NA, NULL); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); @@ -4047,7 +4059,7 @@ void initobjects(void) { addot(OT_STEAMCLOUD, "cloud of steam", "A thick cloud of scalding steam.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "}"); addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL); - addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puff of steam"); + addflag(lastot->flags, F_DIECONVERT, 1, NA, NA, "puff of steam"); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); @@ -4100,7 +4112,7 @@ void initobjects(void) { addot(OT_SMOKECLOUD, "cloud of smoke", "A thick cloud of black smoke.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addflag(lastot->flags, F_GLYPH, NA, NA, NA, "}"); addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL); - addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puff of smoke"); + addflag(lastot->flags, F_DIECONVERT, 1, NA, NA, "puff of smoke"); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); @@ -4123,7 +4135,7 @@ void initobjects(void) { addot(OT_POISONCLOUD, "cloud of poison gas", "A thick cloud of poisonous gas.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_GREEN, NA, NA, "}"); addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "thins out a little"); - addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "puff of gas"); + addflag(lastot->flags, F_DIECONVERT, 1, NA, NA, "puff of gas"); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); @@ -4449,6 +4461,13 @@ void initobjects(void) { addflag(lastot->flags, F_ARMOURRATING, 2, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL); addflag(lastot->flags, F_SCARY, 4, NA, NA, NULL); + addot(OT_POINTYHAT, "wizard hat", "A foot-long brimmed conical hat, inscribed with strange symbols.", MT_CLOTH, 1, OC_ARMOUR, SZ_SMALL); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); + addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 1, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); + addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pointy hat"); // armour - ears addot(OT_EARPLUGS, "set of earplugs", "A pair of cloth plugs designed to give the wearer a peaceful night's sleep. ", MT_CLOTH, 0.01, OC_ARMOUR, SZ_SMALL); @@ -4779,7 +4798,7 @@ void initobjects(void) { addot(OT_BULLET, "bullet", "A regular gun bullet.", MT_METAL, 0.1, OC_MISSILE, SZ_MINI); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); - addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, ""); + addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); @@ -4789,7 +4808,7 @@ void initobjects(void) { addot(OT_RUBBERBULLET, "rubber bullet", "A rubber gun bullet - does not do much damage.", MT_RUBBER, 0.05, OC_MISSILE, SZ_MINI); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); - addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, ""); + addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); @@ -5093,6 +5112,14 @@ void initobjects(void) { addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 8, NA, NA, NULL); + addot(OT_WIZARDSTAFF, "wizard staff", "A twisted branch of wood.", MT_DRAGONWOOD, 4, OC_WEAPON, SZ_HUMAN); + addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); + addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d4"); + addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); + addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_STAVES, NA, NA, NULL); + addflag(lastot->flags, F_RODSHAPED, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "twisted branch"); // clubs (bashing) addot(OT_CLUB, "club", "A heavy, blunt wooden instrument to hit things with.", MT_WOOD, 8, OC_WEAPON, SZ_MEDIUM); @@ -5153,7 +5180,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "It makes metalwork easier."); addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, NA, NA, "1d4"); - addflag(lastot->flags, F_ACCURACY, 65, NA, NA, NULL); + addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERNEEDDIR, B_TRUE, NA, NA, "Use your spanner in which direction"); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); @@ -5324,7 +5351,7 @@ void initrace(void) { addraceclass(RC_UNDEAD, "undead", "the undead", SK_LORE_UNDEAD); // unique monsters - addrace(R_JAILER, "jailer", 110, '@', C_MAGENTA, MT_FLESH, RC_HUMANOID); + addrace(R_JAILER, "jailer", 110, '@', C_MAGENTA, MT_FLESH, RC_HUMANOID, "Jailers are generally known for their surplus of brawn and utter lack of brains. This one is no different."); addflag(lastrace->flags, F_NAME, NA, NA, NA, "Jimbo"); addflag(lastrace->flags, F_UNIQUE, NA, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, NA, NA, NA, NULL); @@ -5358,7 +5385,7 @@ void initrace(void) { // races / monsters // playable races - addrace(R_HUMAN, "human", 75, '@', C_GREY, MT_FLESH, RC_HUMANOID); + addrace(R_HUMAN, "human", 75, '@', C_GREY, MT_FLESH, RC_HUMANOID, "Your average example of the Homo Sapiens species."); addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL); @@ -5379,7 +5406,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); - addrace(R_AVIAD, "aviad", 60, 'h', C_WHITE, MT_FLESH, RC_HUMANOID); + addrace(R_AVIAD, "aviad", 60, 'h', C_WHITE, MT_FLESH, RC_HUMANOID, "A bipedal bird-like race. Aviads are human-sized but have more delicate bones and are covered in feathers. They have sharp talons in place of fingernails, and large feathered wings sprouting from their backs. While capable of flight from birth, their feathers make them vulnerable to fire and lightning based attacks."); // stats addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); @@ -5410,7 +5437,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); - addrace(R_CYBORG, "cyborg", 150, 'R', C_GREY, MT_FLESH, RC_HUMANOID); + addrace(R_CYBORG, "cyborg", 150, 'R', C_GREY, MT_FLESH, RC_HUMANOID, "A cyborg is a human with cybernetic implants grafted throughout their body. In most cases their body has been completely reconstructed from metal, with a thin later of skin outside to maintain a human appearance. Cyborgs are exceptionaly good with technology due to their computer-enhanced brain, but completely unable to use magic (for much the same reason)."); // stats addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); @@ -5454,7 +5481,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "bleeps^a bleep"); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addrace(R_DWARF, "dwarf", 60, 'h', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_DWARF, "dwarf", 60, 'h', C_BROWN, MT_FLESH, RC_HUMANOID, "Dwarves are short, hardy creatures who generally spend their entire lives mining underground. As such they have great fitness and enhanced low-light vision, but generally lack great reasoning skills and magical ability."); addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LTAVERAGE, NA, NULL); @@ -5468,19 +5495,22 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+3"); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); - addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); addflag(lastrace->flags, F_STARTJOB, 75, J_RANDOM, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); + // bonuses + addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL); + // penalties + addflag(lastrace->flags, F_MPMOD, -3, NA, NA, NULL); - addrace(R_ELF, "elf", 60, '@', C_GREEN, MT_FLESH, RC_HUMANOID); + addrace(R_ELF, "elf", 60, '@', C_GREEN, MT_FLESH, RC_HUMANOID, "Elves are slender, graceful beings around human-sized but far nimbler. They have high intelligence and magical affinity, but a lack of physical strength. Elves meditate instead of sleeping, thus maintaining basic awareness."); addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CON, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); @@ -5508,10 +5538,10 @@ void initrace(void) { // bonuses addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL); addflag(lastrace->flags, F_MEDITATES, B_TRUE, NA, NA, NULL); - + addflag(lastrace->flags, F_MPMOD, 3, NA, NA, NULL); // human monsters... - addrace(R_BANDITLDR, "bandit leader", 75, '@', C_GREY, MT_FLESH, RC_HUMANOID); + addrace(R_BANDITLDR, "bandit leader", 75, '@', C_GREY, MT_FLESH, RC_HUMANOID, "Like a regular bandit, but bigger and stronger. Enough so to bully their followers into submission anyway."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); @@ -5536,7 +5566,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MINIONS, 100, 1, 3, "bandit"); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); - addrace(R_BANDIT, "bandit", 75, '@', C_GREY, MT_FLESH, RC_HUMANOID); + addrace(R_BANDIT, "bandit", 75, '@', C_GREY, MT_FLESH, RC_HUMANOID, "Bandits prey on travellers, demanding cash in exchange for not beating them to a pulp."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); @@ -5562,7 +5592,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTJOB, 15, J_WIZARD, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 50, J_ROGUE, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); - addrace(R_BEGGAR, "beggar", 50, '@', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_BEGGAR, "beggar", 50, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Beggar roam the streets of towns, pleading for any spare cash."); addflag(lastrace->flags, F_RARITY, H_VILLAGE, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); @@ -5576,7 +5606,7 @@ void initrace(void) { addflag(lastrace->flags, F_RANDOMTALK, SP_BEG, SV_WHISPER, SV_TALK, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); - addrace(R_DRUNK, "drunkard", 90, '@', C_GREY, MT_FLESH, RC_HUMANOID); + addrace(R_DRUNK, "drunkard", 90, '@', C_GREY, MT_FLESH, RC_HUMANOID, "A humon who has become hopelessly addicated to alcohol. They exist in a permenant state of inebriation."); addflag(lastrace->flags, F_RARITY, H_VILLAGE, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); @@ -5597,7 +5627,7 @@ void initrace(void) { addcondition(f, FC_NOCONDITION, 30); addaltval(f, F_DRUNK, 3, NA, NA, NULL); - addrace(R_PRISONER, "prisoner", 60, '@', C_GREY, MT_FLESH, RC_HUMANOID); + addrace(R_PRISONER, "prisoner", 60, '@', C_GREY, MT_FLESH, RC_HUMANOID, "Somebody who has been improsioned."); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_VARLEVEL, NA, NA, NA, NULL); @@ -5614,7 +5644,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); - addrace(R_TOWNGUARD, "town guard", 100, '@', C_GREY, MT_FLESH, RC_HUMANOID); + addrace(R_TOWNGUARD, "town guard", 100, '@', C_GREY, MT_FLESH, RC_HUMANOID, "A surly guard employed to uphold the laws of a town."); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, NA, NA, "12-18"); addflag(lastrace->flags, F_STARTASLEEPPCT, 0, NA, NA, NULL); @@ -5642,7 +5672,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); // gods - kep sorted alphabetically - addrace(R_GODPURITY, "Amberon", 90, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD); + addrace(R_GODPURITY, "Amberon", 90, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Amberon appears as a shining statuesque humanoid with gold-hued skin. He represents Purity, Law and Justice."); addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, NA, NA, "20"); addflag(lastrace->flags, F_STARTATT, A_AGI, NA, NA, "10"); @@ -5661,7 +5691,6 @@ void initrace(void) { addflag(lastrace->flags, F_WANTSOBFLAG, F_RARITY, NA, NA, NULL); // ie. everything addflag(lastrace->flags, F_STARTSKILL, SK_SS_LIFE, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_FIRSTAID, PR_SKILLED, NA, NULL); - addflag(lastrace->flags, F_STARTSKILL, SK_SPELLCASTING, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, B_APPENDYOU, "gestures imperiously"); // god abilities @@ -5690,10 +5719,10 @@ void initrace(void) { addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "eating pets"); - addrace(R_GODTHIEVES, "Felix", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD); + addrace(R_GODTHIEVES, "Felix", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Felix is the god of Thieves, Greed and Trickery. He generally appears as an overweight glutton carrying his contraband loot around in huge sacks. Despite this, he is amazingly agile and is said to be able to steal one's soul right out of their body."); addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, NA, NA, "20"); - addflag(lastrace->flags, F_STARTATT, A_AGI, NA, NA, "10"); + addflag(lastrace->flags, F_STARTATT, A_STR, NA, NA, "15"); + addflag(lastrace->flags, F_STARTATT, A_AGI, NA, NA, "20"); addflag(lastrace->flags, F_STARTATT, A_WIS, NA, NA, "9"); addflag(lastrace->flags, F_STARTATT, A_IQ, NA, NA, "10"); addflag(lastrace->flags, F_STARTATT, A_CON, NA, NA, "8"); @@ -5706,6 +5735,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "+5 dagger of sharpness"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "blessed ring of hunger"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "10 huge bags of holding"); + addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "10 huge bags of holding"); //addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_RARITY, NA, NA, NULL); // ie. everything addflag(lastrace->flags, F_STARTSKILL, SK_THIEVERY, PR_MASTER, NA, NULL); @@ -5735,7 +5765,7 @@ void initrace(void) { addflag(lastrace->flags, F_SACRIFICEOBCLASS, OC_MONEY, NA, 2, "OB IS consumed in a swirl of shadowy blackness"); - addrace(R_GODDEATH, "Hecta", 100, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD); + addrace(R_GODDEATH, "Hecta", 100, '@', C_BOLDMAGENTA, MT_BONE, RC_GOD, "The skeletal god of death is garbed in a cloak made of pure shadow. and weilds an enormous scythe."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, NA, NA, "16"); addflag(lastrace->flags, F_STARTATT, A_AGI, NA, NA, "20"); @@ -5752,8 +5782,8 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "cloak of shadows"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "bone helmet"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "10-20 bones"); + addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "+15 scythe of sharpness"); //addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); - addflag(lastrace->flags, F_STARTSKILL, SK_SPELLCASTING, PR_EXPERT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_DEATH, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "extends a skeletal finger"); @@ -5780,7 +5810,7 @@ void initrace(void) { // sacrifices addflag(lastrace->flags, F_SACRIFICEOB, OT_CORPSE, NA, 2, "Bony claws rise up and drag OB underground."); - addrace(R_GODMERCY, "Yumi", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD); + addrace(R_GODMERCY, "Yumi", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Yumi is the goddess of Mercy and Healing. She has a calm, serene face and wears simple clothing."); addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL); addflag(lastrace->flags, F_FLEEONHPPCT, 95, NA, NA, ""); addflag(lastrace->flags, F_STARTATT, A_STR, NA, NA, "10"); @@ -5794,13 +5824,15 @@ void initrace(void) { addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "50d4"); addflag(lastrace->flags, F_UNIQUE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "1d2"); + addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "cotton shirt of health"); + addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "cloth trousers "); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "blessed longsword of mercy"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "10 blessed vials of ambrosia"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "2 rings of regeneration"); addflag(lastrace->flags, F_STARTSKILL, SK_FIRSTAID, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_LONGBLADES, PR_ADEPT, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "raises her hand"); + addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "raises her palms"); // god abilities addflag(lastrace->flags, F_GODOF, B_FEMALE, NA, NA, "Mercy"); addflag(lastrace->flags, F_FLEEONHPPCT, 10, NA, NA, NULL); @@ -5824,7 +5856,7 @@ void initrace(void) { // monsters - addrace(R_BEHOLDER, "beholder", 5, 'e', C_MAGENTA, MT_FLESH, RC_MAGIC); + addrace(R_BEHOLDER, "beholder", 5, 'e', C_MAGENTA, MT_FLESH, RC_MAGIC, "A floating orb of flesh with a large mouth, single central eye, and numerous smaller eyestalks."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -5851,14 +5883,13 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL); - addflag(lastrace->flags, F_STARTSKILL, SK_SPELLCASTING, PR_EXPERT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_EXPERT, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_BODYPARTNAME, BP_EYES, NA, NA, "eyestalks"); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); - addrace(R_BUGBEAR, "bugbear", 120, 'G', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_BUGBEAR, "bugbear", 120, 'G', C_BROWN, MT_FLESH, RC_HUMANOID, "A huge goblinoid creature, similar to a hobgoblin but larger again, with a temperament to match."); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); @@ -5885,7 +5916,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); - addrace(R_COCKATRICE, "cockatrice", 5, 'c', C_YELLOW, MT_FLESH, RC_MAGIC); + addrace(R_COCKATRICE, "cockatrice", 5, 'c', C_YELLOW, MT_FLESH, RC_MAGIC, "A small two-legged dragon with a rooster's head. Its touch is said to petrify the flesh of living creatures."); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); @@ -5907,7 +5938,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); // special attack handled in attack.c - addrace(R_CREEPINGCLAW, "creeping claw", 3, 'x', C_YELLOW, MT_FLESH, RC_MAGIC); + addrace(R_CREEPINGCLAW, "creeping claw", 3, 'x', C_YELLOW, MT_FLESH, RC_MAGIC, "A disembodied hand, animated by magic. Its favourite pastime is to leap onto unsuspecting victims and crush the life out of them."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); @@ -5934,7 +5965,7 @@ void initrace(void) { addflag(lastrace->flags, F_CASTCHANCE, 70, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_DARKMANTLE, "darkmantle", 70, 'U', C_BLUE, MT_FLESH, RC_MAGIC); + addrace(R_DARKMANTLE, "darklurk", 70, 'U', C_BLUE, MT_FLESH, RC_MAGIC, "A floating squid-like creature, rarely seen due to its ability to cloak itself in a magical darkness. They use their huge tentacles to grab then crush their unsuspecting prey."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_STARTHIDDENPCT, 80, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -5968,7 +5999,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); - addrace(R_EYEBAT, "eyebat", 5, 'e', C_BLUE, MT_FLESH, RC_MAGIC); + addrace(R_EYEBAT, "eyebat", 5, 'e', C_BLUE, MT_FLESH, RC_MAGIC, "A smaller cousin to the beholder, an eyebat is a single oversized eyeball suspended between bat-like wings."); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -5988,15 +6019,15 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); + addflag(lastrace->flags, F_NOBODYPART, BP_BODY, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEGS, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL); - addflag(lastrace->flags, F_STARTSKILL, SK_SPELLCASTING, PR_EXPERT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings"); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); - addrace(R_GIANTHILL, "hill giant", 160, 'H', C_GREY, MT_FLESH, RC_HUMANOID); + addrace(R_GIANTHILL, "mountain giant", 160, 'H', C_GREY, MT_FLESH, RC_HUMANOID, "Enormous humanoids who dwell in the mountains, using their grat strength to leap between valleys and pelt their prey with enormous boulders."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL); @@ -6030,7 +6061,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); - addrace(R_GIANTFIRE, "fire giant", 160, 'H', C_RED, MT_FLESH, RC_HUMANOID); + addrace(R_GIANTFIRE, "flame giant", 160, 'H', C_RED, MT_FLESH, RC_HUMANOID, "Fire giants are cousins to hill giants who dwell on active vulcanoes. Their constant proximity to intense heat has led them to evolve a natural resistance to fire"); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -6059,11 +6090,12 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "bellows^a bellow"); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); - addrace(R_GIANTFIREFC, "fire giant forgecaller", 160, 'H', C_RED, MT_FLESH, RC_HUMANOID); + addrace(R_GIANTFIREFC, "flame giant shaman", 160, 'H', C_RED, MT_FLESH, RC_HUMANOID, "A subspecies of flame giant who have developed the ability to command the primal volcanic fires around them."); lastrace->baseid = R_GIANTFIRE; addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "fire giant corpse"); @@ -6093,14 +6125,13 @@ void initrace(void) { addflag(lastrace->flags, F_CANCAST, OT_S_FIREDART, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_FLAMEPILLAR, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_S_FLAMEBURST, 4, 4, "pw:4;"); - addflag(lastrace->flags, F_STARTSKILL, SK_SPELLCASTING, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_FIRE, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 15, NA, NA, NULL); - addrace(R_GIANTFIRETITAN, "fire titan", 160, 'H', C_RED, MT_FLESH, RC_HUMANOID); + addrace(R_GIANTFIRETITAN, "flame titan", 160, 'H', C_RED, MT_FLESH, RC_HUMANOID, "The ultimate evolutionary form of a flame giant. Flame titans tower over even the largest of regular giants and can generate massive amounts of raging flame at will."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -6134,7 +6165,7 @@ void initrace(void) { // TODO: storm giant // TODO: storm titan - addrace(R_GNOLL, "gnoll", 130, 'h', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_GNOLL, "gnoll", 130, 'h', C_BROWN, MT_FLESH, RC_HUMANOID, "Gnolls are doglike warriors - the gladiators of the kobold race. They are highly organised and often travel in packs."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "gnoll corpse"); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -6151,6 +6182,8 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d6+4"); + addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "spear"); + addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "shield"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-40 gold coins"); addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL); @@ -6165,7 +6198,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); - addrace(R_GNOLLHM, "gnoll huntmaster", 130, 'h', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_GNOLLHM, "gnoll hunter", 130, 'h', C_BROWN, MT_FLESH, RC_HUMANOID, "Hunters are gnolls tasked with obtaining food, but can also turn their ranged skills to combat."); lastrace->baseid = R_GNOLL; addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "gnoll corpse"); @@ -6200,41 +6233,8 @@ void initrace(void) { addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 12, NA, NA, NULL); - addrace(R_GNOLLMR, "gnoll marauder", 130, 'h', C_BROWN, MT_FLESH, RC_HUMANOID); - lastrace->baseid = R_GNOLL; - addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); - addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "gnoll corpse"); - addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_RARITY, H_DUNGEON, 65, NA, NULL); - addflag(lastrace->flags, F_RARITY, H_FOREST, 65, NA, NULL); - addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "10d4"); - addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); - addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); - addflag(lastrace->flags, F_EVASION, 0, NA, NA, NULL); - addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); - addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); - addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d4+2"); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour"); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "spear"); - addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "buckler"); - addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); - addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL); - addflag(lastrace->flags, F_QUICKBITE, 1, 6, 2, NULL); - addflag(lastrace->flags, F_PACKATTACK, 3, NA, 2, NULL); - addflag(lastrace->flags, F_MINIONS, 75, 1, 2, "gnoll"); - addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); - addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws"); - addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw"); - addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); - addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 12, NA, NA, NULL); - addrace(R_GOBLIN, "goblin", 20, 'g', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_GOBLIN, "goblin", 25, 'g', C_BROWN, MT_FLESH, RC_HUMANOID, "Small humanoids with flat faces, broad noses, pointed ears, and small, sharp fangs."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_FEIGNDEATH, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -6265,7 +6265,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); - addrace(R_GOBLINWAR, "goblin warrior", 30, 'g', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_GOBLINWAR, "goblin warrior", 30, 'g', C_BROWN, MT_FLESH, RC_HUMANOID, "Goblin Warriors are uncommon goblins with sufficient mental control to ungergo formal combat training (rather than just hack away mindlessly at their foes)."); lastrace->baseid = R_GOBLIN; addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "goblin corpse"); @@ -6295,7 +6295,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); - addrace(R_GOBLINSHOOTER, "goblin sharpshooter", 20, 'g', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_GOBLINSHOOTER, "goblin archer", 20, 'g', C_BROWN, MT_FLESH, RC_HUMANOID, "Deformed goblins born without claws become archers for their communities, pelting their enemies from afar with barrages of arrows."); lastrace->baseid = R_GOBLIN; addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "goblin corpse"); @@ -6328,7 +6328,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); - addrace(R_GOBLINHEXER, "goblin hexer", 20, 'g', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_GOBLINHEXER, "goblin shaman", 20, 'g', C_BROWN, MT_FLESH, RC_HUMANOID, "When a goblin develops an affinity for magic, they become known as shamans. Shamans aim to weaken their foes with hexs, providing easy kills for their comrades."); lastrace->baseid = R_GOBLIN; addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "goblin corpse"); @@ -6352,7 +6352,6 @@ void initrace(void) { addflag(lastrace->flags, F_PACKATTACK, 2, DT_SLASH, 3, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_BLINDNESS, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_PAIN, NA, NA, NULL); - addflag(lastrace->flags, F_STARTSKILL, SK_SPELLCASTING, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MINIONS, 90, 1, 2, "goblin"); @@ -6360,7 +6359,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); - addrace(R_HOBGOBLIN, "hobgoblin", 90, 'g', C_GREEN, MT_FLESH, RC_HUMANOID); + addrace(R_HOBGOBLIN, "hobgoblin", 90, 'g', C_GREEN, MT_FLESH, RC_HUMANOID, "A larger, stronger, smarter and more menacing form of a goblin."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 73, NA, NULL); @@ -6393,7 +6392,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); - addrace(R_HOBGOBLINWAR, "hobgoblin warrior", 90, 'g', C_GREEN, MT_FLESH, RC_HUMANOID); + addrace(R_HOBGOBLINWAR, "hobgoblin elite", 90, 'g', C_GREEN, MT_FLESH, RC_HUMANOID, "An exceptional hobgoblin commander who has achieved command of its own unit."); lastrace->baseid = R_HOBGOBLIN; addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -6431,7 +6430,7 @@ void initrace(void) { // TODO: hobgoblin archer // TODO: hobgoblin warcaster - addrace(R_KOBOLD, "kobold", 18, 'k', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_KOBOLD, "kobold", 18, 'k', C_BROWN, MT_FLESH, RC_HUMANOID, "An evil humanoid race with doglike features, kobolds are known for their cowardace and prefer to attack from a distance if at all possible."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 95, NA, NULL); @@ -6457,9 +6456,10 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_FLEEONHPPCT, 30, NA, NA, ""); addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); - addrace(R_TROGLODYTE, "troglodyte", 20, 'z', C_GREY, MT_FLESH, RC_HUMANOID); + addrace(R_TROGLODYTE, "troglodyte", 20, 'z', C_GREY, MT_FLESH, RC_HUMANOID, "Troglodytes are smaller, stunted lizardmen who at outcast at birth. They linger on the outskirts of society, scavenging garbage and living in their own filth."); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_POISONOUS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -6486,7 +6486,7 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); - addrace(R_LEPRECHAUN, "leprechaun", 35, 'n', C_GREEN, MT_FLESH, RC_HUMANOID); + addrace(R_LEPRECHAUN, "leprechaun", 35, 'n', C_GREEN, MT_FLESH, RC_HUMANOID, "Leprechauns are tiny Irish humans, with a love for gold and practical jokes. Known for their supernatural luck."); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL); @@ -6509,7 +6509,7 @@ void initrace(void) { addflag(lastrace->flags, F_EXTRALUCK, 2, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); - addrace(R_LIZARDMAN, "lizardman", 100, 'z', C_GREEN, MT_FLESH, RC_HUMANOID); + addrace(R_LIZARDMAN, "lizardman", 100, 'z', C_GREEN, MT_LEATHER, RC_HUMANOID, "Lizardmen are as they sound - a cross between a human and a lizard. Their leathery skin helps protect them from pummeling blows, and their tails give them enhanced stability."); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); @@ -6533,10 +6533,11 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_S_POISONBOLT, 5, 5, "pw:5;"); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_STABILITY, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); - - addrace(R_MINOTAUR, "minotaur", 130, 'H', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_MINOTAUR, "minotaur", 130, 'H', C_BROWN, MT_FLESH, RC_HUMANOID, "Legendary creatures with the head of a bull, with a strength and temperament to match."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); @@ -6567,7 +6568,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOARMOURON, BP_HEAD, NA, NA, NULL); - addrace(R_OGRE, "ogre", 160, 'O', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_OGRE, "ogre", 160, 'O', C_BROWN, MT_FLESH, RC_HUMANOID, "Large, cruel, monstrous and hideous humanoid monsters. Ogres have a raging temper and hunger for flesh."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); @@ -6597,37 +6598,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL); - addrace(R_OGRESAVAGE, "ogre savage", 160, 'O', C_BROWN, MT_FLESH, RC_HUMANOID); - lastrace->baseid = R_OGRE; - addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); - addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); - addflag(lastrace->flags, F_RARITY, H_DUNGEON, 45, NA, NULL); - addflag(lastrace->flags, F_RARITY, H_FOREST, 55, NA, NULL); - addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "13d4+8"); - addflag(lastrace->flags, F_ARMOURRATING, 11, NA, NA, NULL); - addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); - addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "3d4"); - addflag(lastrace->flags, F_HASATTACK, OT_FISTS, NA, NA, "3d4"); - addflag(lastrace->flags, F_STARTATT, A_IQ, AT_VLOW, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL); - addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); - addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); - addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); - f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "blessed great club"); - addcondition(f, FC_NOCONDITION, 80); - addaltval(f, F_STARTOB, 100, NA, NA, "great club"); - addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "leather armour"); - addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-70 gold coins"); - addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); - addflag(lastrace->flags, F_MINIONS, 50, 1, 5, "orc"); - addflag(lastrace->flags, F_MINIONS, 50, 1, 3, "orc warrior"); - addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); - - addrace(R_OGREWARHULK, "ogre warhulk", 160, 'O', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_OGREWARHULK, "warhulk", 160, 'O', C_BROWN, MT_FLESH, RC_HUMANOID, "Warhulks are huge ogres, even angrier than their comrades."); lastrace->baseid = R_OGRE; addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -6658,7 +6629,7 @@ void initrace(void) { addflag(lastrace->flags, F_MINIONS, 25, 1, 2, "orc warrior"); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); - addrace(R_ORC, "orc", 90, 'o', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_ORC, "orc", 90, 'o', C_BROWN, MT_FLESH, RC_HUMANOID, "Orcs are fierce humanoid monsters with green skin and grotesque features."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); @@ -6689,42 +6660,9 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_STARTJOB, 25, J_WARRIOR, NA, NULL); - addrace(R_ORCWARRIOR, "orc warrior", 90, 'o', C_BROWN, MT_FLESH, RC_HUMANOID); - lastrace->baseid = R_ORC; - addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); - addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); - addflag(lastrace->flags, F_RARITY, H_FOREST, 75, NA, NULL); - addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4"); - addflag(lastrace->flags, F_EVASION, 5, NA, NA, NULL); - addflag(lastrace->flags, F_ARMOURRATING, 10, NA, NA, NULL); - addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); - addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); - addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "5d4"); - f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "battleaxe"); - addcondition(f, FC_NOCONDITION, 70); - addaltval(f, F_STARTOBDT, 50, DT_CHOP, NA, NULL); - addflag(lastrace->flags, F_STARTOBCLASS, 30, OC_POTION, NA, NULL); - addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour"); - addflag(lastrace->flags, F_STARTOB, 75, NA, NA, "buckler"); - addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "bone helmet"); - addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "1-50 gold coins"); - addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL); - addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); - addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); - addflag(lastrace->flags, F_SEEINDARK, 2, NA, NA, NULL); - //addflag(lastrace->flags, F_STARTJOB, 20, J_WIZARD, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_A_SPRINT, NA, NA, NULL); - addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); - addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_MORALE, 12, NA, NA, NULL); - - addrace(R_ORK, "ork", 90, 'o', C_BROWN, MT_FLESH, RC_HUMANOID); + addrace(R_ORK, "ork", 90, 'o', C_BROWN, MT_FLESH, RC_HUMANOID, "Orcs who have become fascinated with technology tend to become shunned by their peers, and have taken the name 'Orks' for themselves."); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "orc corpse"); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); @@ -6754,7 +6692,7 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); - addrace(R_PEGASUS, "pegasus", 130, 'Q', C_GREY, MT_FLESH, RC_MAGIC); + addrace(R_PEGASUS, "pegasus", 130, 'Q', C_GREY, MT_FLESH, RC_MAGIC, "A legendary white, winged horse."); addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 57, NA, ""); addflag(lastrace->flags, F_RARITY, H_FOREST, 57, NA, NULL); @@ -6782,7 +6720,7 @@ void initrace(void) { addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); - addrace(R_POLTERGEIST, "poltergeist", 50, 'p', C_GREEN, MT_FLESH, RC_UNDEAD); // sPirit + addrace(R_POLTERGEIST, "poltergeist", 50, 'p', C_GREEN, MT_FLESH, RC_UNDEAD, "An evil ghostly spirit who telekinetically throws objects at its enemies."); // sPirit addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); @@ -6810,7 +6748,7 @@ void initrace(void) { addflag(lastrace->flags, F_XPMULTIPLY, 2, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); - addrace(R_SATYR, "satyr", 80, 'h', C_GREEN, MT_FLESH, RC_HUMANOID); + addrace(R_SATYR, "satyr", 80, 'h', C_GREEN, MT_FLESH, RC_HUMANOID, "A goat-like humanoid equipped with a set of magical panpipes."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); @@ -6834,7 +6772,6 @@ void initrace(void) { addflag(lastrace->flags, F_CANCAST, OT_S_CHARM, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_FEAR, NA, NA, NULL); - addflag(lastrace->flags, F_STARTSKILL, SK_SPELLCASTING, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_MENTAL, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_HIDE, NA, NA, NULL); @@ -6843,10 +6780,10 @@ void initrace(void) { addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); - addrace(R_SHADOWCAT, "shadowcat", 5, 'f', C_BLUE, MT_FLESH, RC_MAGIC); + addrace(R_SHADOWCAT, "shadowcat", 5, 'f', C_BLUE, MT_FLESH, RC_MAGIC, "A huge, feral black cat, surrounded by clouds of black smoke."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, 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_HITDICE, NA, NA, NA, "3d4+3"); @@ -6863,7 +6800,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw"); addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); - addrace(R_OOZEGREY, "grey ooze", 10, 'j', C_GREY, MT_SLIME, RC_SLIME); + addrace(R_OOZEGREY, "grey ooze", 10, 'j', C_GREY, MT_SLIME, RC_SLIME, "Exactly what it sounds like - a small lump of grey ooze. Grey, acidic ooze."); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "pool of slime"); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); @@ -6893,7 +6830,7 @@ void initrace(void) { addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, 5, NA, NA, NULL); - addrace(R_SPRITEFIRE, "fire sprite", 5, 'n', C_RED, MT_FIRE, RC_MAGIC); + addrace(R_SPRITEFIRE, "fire sprite", 5, 'n', C_RED, MT_FIRE, RC_MAGIC, "A small magical creature surrounded by crackling flames."); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "small fire"); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); @@ -6911,14 +6848,13 @@ void initrace(void) { addflag(lastrace->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^crackling flames"); - addflag(lastrace->flags, F_STARTSKILL, SK_SPELLCASTING, PR_NOVICE, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_FIRE, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); - addrace(R_SPRITEICE, "ice sprite", 5, 'n', C_WHITE, MT_ICE, RC_MAGIC); + addrace(R_SPRITEICE, "ice sprite", 5, 'n', C_WHITE, MT_ICE, RC_MAGIC, "A small magical creature surrounded by freezing ice."); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "sheet of ice"); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); @@ -6936,15 +6872,13 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, B_APPENDYOU, "gestures"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d3"); addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); - addflag(lastrace->flags, F_STARTSKILL, SK_SPELLCASTING, PR_NOVICE, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_COLD, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); - - addrace(R_TROLL, "troll", 100, 't', C_GREEN, MT_FLESH, RC_HUMANOID); + addrace(R_TROLL, "troll", 100, 't', C_GREEN, MT_FLESH, RC_HUMANOID, "A savage, hairy green monster. Trolls are extremely muscular, move abnormally quickly and regenerate."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); @@ -6965,7 +6899,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); - addrace(R_XAT, "xat", 2, 'x', C_BROWN, MT_FLESH, RC_ANIMAL); + addrace(R_XAT, "xat", 2, 'x', C_BROWN, MT_FLESH, RC_ANIMAL, "Xats are wild pigs with the claws of a dog."); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); @@ -6986,7 +6920,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); // fish - addrace(R_CRAB, "giant crab", 150, ';', C_ORANGE, MT_FLESH, RC_AQUATIC); + addrace(R_CRAB, "giant crab", 150, ';', C_ORANGE, MT_FLESH, RC_AQUATIC, "A massive orange crab with sharp pincers."); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); @@ -7011,7 +6945,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOARMOURON, BP_FEET, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); - addrace(R_MERLOCH, "merloch", 250, 'm', C_ORANGE, MT_FLESH, RC_AQUATIC); + addrace(R_MERLOCH, "merloch", 250, 'm', C_ORANGE, MT_FLESH, RC_AQUATIC, "Merlochs are bipedal, fishlike beings. Equally at home in the water or on land, they use their sonic scream to disable foes."); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); @@ -7040,7 +6974,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOARMOURON, BP_FEET, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); - addrace(R_PIRANHA, "piranha", 0.5, ';', C_GREEN, MT_FLESH, RC_AQUATIC); + addrace(R_PIRANHA, "piranha", 0.5, ';', C_GREEN, MT_FLESH, RC_AQUATIC, "A vicious, flesh-eating fish"); addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7061,7 +6995,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d2"); addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); - addrace(R_PIRANHAKING, "king piranha", 1, ';', C_GREEN, MT_FLESH, RC_AQUATIC); + addrace(R_PIRANHAKING, "king piranha", 1, ';', C_GREEN, MT_FLESH, RC_AQUATIC, "A larger version of a standard piranha. King piranhas can leap through the air."); addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7083,7 +7017,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d6"); addflag(lastrace->flags, F_CANWILL, OT_A_CHARGE, NA, NA, "range:5;"); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); - addrace(R_EELELEC, "electric eel", 120, ';', C_CYAN, MT_FLESH, RC_AQUATIC); + addrace(R_EELELEC, "electric eel", 120, ';', C_CYAN, MT_FLESH, RC_AQUATIC, "A sliippery eel charged with electricity."); addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7104,7 +7038,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, NA, NA, "1d6"); addflag(lastrace->flags, F_DTIMMUNE, DT_ELECTRIC, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); - addrace(R_EELGIANT, "giant eel", 150, ';', C_BLUE, MT_FLESH, RC_AQUATIC); + addrace(R_EELGIANT, "giant eel", 150, ';', C_BLUE, MT_FLESH, RC_AQUATIC, "A very long, slippery eel. They tend to catch and crush their prey."); addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7126,7 +7060,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d6;"); addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); // plants - addrace(R_CACTUS, "cactus", 30, 'F', C_YELLOW, MT_PLANT, RC_PLANT); + addrace(R_CACTUS, "cactus", 30, 'F', C_YELLOW, MT_PLANT, RC_PLANT, "A wide upright plant coated with sharp spines. Said to sprout delicious fruit."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7150,7 +7084,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); - addrace(R_DREAMFUNGUS, "dreamfungus", 0.5, 'F', C_MAGENTA, MT_METAL, RC_PLANT); + addrace(R_DREAMFUNGUS, "dreamfungus", 0.5, 'F', C_MAGENTA, MT_PLANT, RC_PLANT, "A spotty purple mold which releases speed-inducing spores on the slightest contact."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL); @@ -7174,7 +7108,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOBODYPART, BP_RIGHTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_LEFTFINGER, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); - addrace(R_SAWGRASS, "sawgrass", 1, 'F', C_GREY, MT_METAL, RC_PLANT); + addrace(R_SAWGRASS, "sawgrass", 1, 'F', C_GREY, MT_METAL, RC_PLANT, "Razor sharp metallic grass with serrated edges. This plant sense vibrations in the air around it and slashes out with its sharp fronds."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7203,7 +7137,7 @@ void initrace(void) { // end plants // animals - addrace(R_BAT, "giant bat", 3, 'B', C_BROWN, MT_FLESH, RC_ANIMAL); + addrace(R_BAT, "giant bat", 3, 'B', C_BROWN, MT_FLESH, RC_ANIMAL, "A larger (and more savage) version of your average household bat."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7226,7 +7160,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings"); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); - addrace(R_BATMUTATED, "mutated bat", 3, 'B', C_MAGENTA, MT_FLESH, RC_ANIMAL); + addrace(R_BATMUTATED, "mutated bat", 3, 'B', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Bats exposed to toxic radiation become mutated, and their sonic navigation skills turn deadly."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7250,7 +7184,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings"); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_BATVAMPIRE, "vampire bat", 6, 'B', C_BLUE, MT_FLESH, RC_ANIMAL); + addrace(R_BATVAMPIRE, "vampire bat", 6, 'B', C_BLUE, MT_FLESH, RC_ANIMAL, "Bats which suck the blood of their victims."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7276,7 +7210,7 @@ void initrace(void) { addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); - addrace(R_BEAR, "black bear", 150, 'q', C_BLUE, MT_FLESH, RC_ANIMAL); + addrace(R_BEAR, "black bear", 150, 'q', C_BLUE, MT_FLESH, RC_ANIMAL, "A medium sized omnivore bear."); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); @@ -7292,6 +7226,7 @@ void initrace(void) { addflag(lastrace->flags, F_MAXATTACKS, 3, 3, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); + addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roars"); addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL); @@ -7302,7 +7237,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw"); addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); - addrace(R_BEARGRIZZLY, "grizzly bear", 200, 'q', C_YELLOW, MT_FLESH, RC_ANIMAL); + addrace(R_BEARGRIZZLY, "grizzly bear", 200, 'q', C_YELLOW, MT_FLESH, RC_ANIMAL, "A large angry bear."); lastrace->baseid = R_BEAR; addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); @@ -7331,7 +7266,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw"); addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); - addrace(R_BEARCUB, "bear cub", 60, 'q', C_BROWN, MT_FLESH, RC_ANIMAL); + addrace(R_BEARCUB, "bear cub", 60, 'q', C_BROWN, MT_FLESH, RC_ANIMAL, "Cute little baby bears. Still dangerous though."); lastrace->baseid = R_BEAR; addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); @@ -7355,7 +7290,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw"); addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); - addrace(R_ANT, "giant ant", 20, 'a', C_BROWN, MT_FLESH, RC_ANIMAL); + addrace(R_ANT, "giant ant", 20, 'a', C_BROWN, MT_FLESH, RC_ANIMAL, "Giant ants are enormous (for an ant, anyway), and keen to take avenge their smaller ancestors who were crushed by small children."); lastrace->baseid = R_ANT; addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); @@ -7378,7 +7313,7 @@ void initrace(void) { addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); - addrace(R_ANTS, "giant soldier ant", 25, 'a', C_BROWN, MT_FLESH, RC_ANIMAL); + addrace(R_ANTS, "giant soldier ant", 25, 'a', C_BROWN, MT_FLESH, RC_ANIMAL, "The fighter of the giant ant family. Giant soldier ants are equipped with a powerful acidic stinger."); lastrace->baseid = R_ANT; addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); @@ -7403,7 +7338,7 @@ void initrace(void) { addflag(lastrace->flags, F_MINIONS, 50, 1, 3, "giant worker ant"); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 12, NA, NA, NULL); - addrace(R_ANTLION, "giant antlion", 30, 'a', C_YELLOW, MT_FLESH, RC_ANIMAL); + addrace(R_ANTLION, "giant antlion", 30, 'a', C_YELLOW, MT_FLESH, RC_ANIMAL, "Antlions are mammoth giant ants with the head of a lion."); lastrace->baseid = R_ANT; addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); @@ -7428,7 +7363,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roars"); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL); - addrace(R_CHICKEN, "chicken", 0.5, 'c', C_BROWN, MT_FLESH, RC_ANIMAL); + addrace(R_CHICKEN, "chicken", 0.5, 'c', C_BROWN, MT_FLESH, RC_ANIMAL, "A common farm-yard chicken."); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); @@ -7448,7 +7383,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^clucking"); addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); addflag(lastrace->flags, F_TIMID, B_TRUE, NA, NA, NULL); - addrace(R_DOG, "dog", 35, 'd', C_BROWN, MT_FLESH, RC_ANIMAL); + addrace(R_DOG, "dog", 35, 'd', C_BROWN, MT_FLESH, RC_ANIMAL, "A medium-sized canine."); addflag(lastrace->flags, F_RNDHOSTILE, 10, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); @@ -7475,7 +7410,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); - addrace(R_DOGBLINK, "blink dog", 35, 'd', C_BLUE, MT_FLESH, RC_ANIMAL); + addrace(R_DOGBLINK, "blink dog", 35, 'd', C_BLUE, MT_FLESH, RC_ANIMAL, "Magical canines who can teleport small distances at will."); addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 2, 4, NA, ""); @@ -7503,7 +7438,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw"); addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_MORALE, 2, NA, NA, NULL); - addrace(R_DOGDEATH, "death hound", 40, 'd', C_MAGENTA, MT_FLESH, RC_ANIMAL); + addrace(R_DOGDEATH, "death hound", 40, 'd', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Possessed evil canines who thrive on death and destruction."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 2, 6, NA, ""); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7534,7 +7469,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw"); addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_MORALE, 15, NA, NA, NULL); - addrace(R_DOGWAR, "war hound", 40, 'd', C_BROWN, MT_FLESH, RC_ANIMAL); + addrace(R_DOGWAR, "war hound", 40, 'd', C_BROWN, MT_FLESH, RC_ANIMAL, "Canines bred for war."); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 1, 4, NA, ""); addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); @@ -7561,7 +7496,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); - addrace(R_HAWKYOUNG, "young hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL); // 'A' for Avian + addrace(R_HAWKYOUNG, "young hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL, "A young baby hawk."); // 'A' for Avian lastrace->baseid = R_HAWK; addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7590,7 +7525,7 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); - addrace(R_HAWK, "hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL); // 'A' for Avian + addrace(R_HAWK, "hawk", 1, 'A', C_GREY, MT_FLESH, RC_ANIMAL, "A large bird of prey."); // 'A' for Avian lastrace->baseid = R_HAWK; addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7619,7 +7554,7 @@ void initrace(void) { addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL); - addrace(R_HAWKBLOOD, "blood hawk", 1, 'A', C_RED, MT_FLESH, RC_ANIMAL); // 'A' for Avian + addrace(R_HAWKBLOOD, "blood hawk", 1, 'A', C_RED, MT_FLESH, RC_ANIMAL, "A stronger version of a hawk."); // 'A' for Avian lastrace->baseid = R_HAWK; addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7645,7 +7580,7 @@ void initrace(void) { addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); - addrace(R_HAWKFROST, "frost hawk", 1, 'A', C_CYAN, MT_FLESH, RC_ANIMAL); // 'A' for Avian + addrace(R_HAWKFROST, "frost hawk", 1, 'A', C_CYAN, MT_FLESH, RC_ANIMAL, "A hark imbued with the power of ice. Frost hawks can release a powerufl blast of freezing air when threatened."); // 'A' for Avian addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -7672,7 +7607,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); - addrace(R_LEECH, "giant leech", 10, 'j', C_MAGENTA, MT_FLESH, RC_ANIMAL); + addrace(R_LEECH, "giant leech", 10, 'j', C_MAGENTA, MT_FLESH, RC_ANIMAL, "A boneless blood-sucking creature. Quite dangerous until it eats it becomes satiated with blood, at which point it will slither off and fall asleep."); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -7697,7 +7632,7 @@ void initrace(void) { addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); - addrace(R_NEWT, "giant newt", 4, ':', C_BROWN, MT_FLESH, RC_ANIMAL); + addrace(R_NEWT, "giant newt", 4, ':', C_BROWN, MT_FLESH, RC_ANIMAL, "An abnormally large example of the lizard family."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7718,7 +7653,7 @@ void initrace(void) { addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); - addrace(R_PORCUPINE, "giant porcupine", 10, 'r', C_GREY, MT_FLESH, RC_ANIMAL); + addrace(R_PORCUPINE, "giant porcupine", 10, 'r', C_GREY, MT_FLESH, RC_ANIMAL, "A large four legged creature covered with sharp spines."); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACE, R_ANT, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -7737,7 +7672,7 @@ void initrace(void) { addflag(lastrace->flags, F_RETALIATE, 1, 4, DT_PIERCE, "sharp spines"); addflag(lastrace->flags, F_CORPSEFLAG, F_SHARP, 1, 4, NULL); addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); - addrace(R_RAT, "giant rat", 3, 'r', C_BROWN, MT_FLESH, RC_ANIMAL); + addrace(R_RAT, "giant rat", 3, 'r', C_BROWN, MT_FLESH, RC_ANIMAL, "A rodent of unusual size."); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -7761,7 +7696,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw"); addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); - addrace(R_SNAKE, "brown snake", 3, 's', C_BROWN, MT_FLESH, RC_ANIMAL); + addrace(R_SNAKE, "brown snake", 3, 's', C_BROWN, MT_FLESH, RC_ANIMAL, "Common venomous snakes."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7789,7 +7724,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_SNAKECARPET, "carpet snake", 3, 's', C_GREY, MT_FLESH, RC_ANIMAL); + addrace(R_SNAKECARPET, "carpet snake", 3, 's', C_GREY, MT_FLESH, RC_ANIMAL, "Non-venemous (but not quite harmless) snakes."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7814,7 +7749,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_SNAKETREE, "tree snake", 3, 's', C_GREEN, MT_FLESH, RC_ANIMAL); + addrace(R_SNAKETREE, "tree snake", 3, 's', C_GREEN, MT_FLESH, RC_ANIMAL, "Non-venomous snakes which leap at their prey."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7841,7 +7776,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_SNAKECOBRABLACK, "black cobra", 3, 's', C_BLUE, MT_FLESH, RC_ANIMAL); + addrace(R_SNAKECOBRABLACK, "black cobra", 3, 's', C_BLUE, MT_FLESH, RC_ANIMAL, "Black cobras can spit globs of venom at their prey."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7869,7 +7804,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_SNAKECOBRAGOLDEN, "golden cobra", 3, 's', C_YELLOW, MT_FLESH, RC_ANIMAL); + addrace(R_SNAKECOBRAGOLDEN, "golden cobra", 3, 's', C_YELLOW, MT_FLESH, RC_ANIMAL, "Golden cobras spit a blindness-inducing venom at their enemies."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7898,7 +7833,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_SNAKECONSTRICTOR, "constrictor", 3, 's', C_MAGENTA, MT_FLESH, RC_ANIMAL); + addrace(R_SNAKECONSTRICTOR, "constrictor", 3, 's', C_MAGENTA, MT_FLESH, RC_ANIMAL, "A huge snake which coils around its victims then crushes them to death."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_COLDBLOOD, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -7926,7 +7861,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_SNAKEWATER, "water snake", 3, 's', C_BLUE, MT_FLESH, RC_ANIMAL); + addrace(R_SNAKEWATER, "water snake", 3, 's', C_BLUE, MT_FLESH, RC_ANIMAL, "Aquatic snakes who can nevertheless exist quite happily on land. Non-venomous."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL); @@ -7954,7 +7889,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_SPIDER, "giant spider", 5, 'S', C_GREY, MT_FLESH, RC_ANIMAL); + addrace(R_SPIDER, "giant spider", 5, 'S', C_GREY, MT_FLESH, RC_ANIMAL, "An eight legged beast who is the central feature in many nightmares."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); @@ -7981,7 +7916,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_BODY, NA, NA, "abdomen"); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_SPIDERFUNNELWEB, "giant funnelweb", 5, 'S', C_MAGENTA, MT_FLESH, RC_ANIMAL); + addrace(R_SPIDERFUNNELWEB, "giant funnelweb", 5, 'S', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Like a giant spider... but extremely venomous."); lastrace->baseid = R_SPIDER; addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -8011,7 +7946,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_BODY, NA, NA, "abdomen"); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_SPIDERREDBACK, "giant redback", 5, 'S', C_RED, MT_FLESH, RC_ANIMAL); + addrace(R_SPIDERREDBACK, "giant redback", 5, 'S', C_RED, MT_FLESH, RC_ANIMAL, "A version of a giant spider with a highly painful bite."); lastrace->baseid = R_SPIDER; addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -8041,7 +7976,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_BODY, NA, NA, "abdomen"); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_WOLFYOUNG, "young wolf", 10, 'd', C_GREY, MT_FLESH, RC_ANIMAL); + addrace(R_WOLFYOUNG, "young wolf", 10, 'd', C_GREY, MT_FLESH, RC_ANIMAL, "Immature wolves."); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL); @@ -8065,7 +8000,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right foreclaw"); addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left foreclaw"); addflag(lastrace->flags, F_MORALE, 3, NA, NA, NULL); - addrace(R_WOLF, "wolf", 25, 'd', C_GREY, MT_FLESH, RC_ANIMAL); + addrace(R_WOLF, "wolf", 25, 'd', C_GREY, MT_FLESH, RC_ANIMAL, "Highly intelligent members of the canine family."); addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); @@ -8091,7 +8026,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 7, NA, NA, NULL); // insects - addrace(R_BUTTERFLY, "butterfly", 0.01, 'i', C_YELLOW, MT_FLESH, RC_ANIMAL); + addrace(R_BUTTERFLY, "butterfly", 0.01, 'i', C_YELLOW, MT_FLESH, RC_ANIMAL, "A harmless, colourful butterfly."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -8113,12 +8048,11 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_TIMID, B_TRUE, NA, NA, NULL); - addrace(R_GIANTFLY, "giant fly", 1, 'i', C_GREY, MT_FLESH, RC_INSECT); + addrace(R_GIANTFLY, "giant fly", 1, 'i', C_GREY, MT_FLESH, RC_INSECT, "Giant flies buzz around the places, feeding on corpses. Usually no more than a nuisance."); lastrace->baseid = R_GIANTFLY; addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); - addflag(lastrace->flags, F_NUMAPPEAR, 3, 3, NA, ""); addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); @@ -8141,21 +8075,20 @@ void initrace(void) { addflag(lastrace->flags, F_ATTACKRANGE, 1, 2, NA, NULL); // just buzz around addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); - addrace(R_GIANTBLOWFLY, "giant blowfly", 2, 'i', C_GREY, MT_FLESH, RC_INSECT); + addrace(R_GIANTBLOWFLY, "giant blowfly", 2, 'i', C_GREY, MT_FLESH, RC_INSECT, "Large, more solid versions of giant flies. These can actually cause damage, albeit rarely."); lastrace->baseid = R_GIANTFLY; addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "giant fly corpse"); - addflag(lastrace->flags, F_NUMAPPEAR, 1, 2, NA, ""); addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); - addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+1"); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); + addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+3"); addflag(lastrace->flags, F_EVASION, 5, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL); - addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d1"); + addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3-2"); addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); @@ -8170,7 +8103,7 @@ void initrace(void) { addflag(lastrace->flags, F_ATTACKRANGE, 1, 2, NA, NULL); // just buzz around addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); - addrace(R_STIRGE, "mosquitoid", 10, 'i', C_BROWN, MT_FLESH, RC_INSECT); + addrace(R_STIRGE, "mosquitoid", 10, 'i', C_BROWN, MT_FLESH, RC_INSECT, "Mosquitoids look like giant mosquiteos but are equipped with human-like arms, with clawed hands."); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -8199,7 +8132,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); - addrace(R_CENTIPEDE, "giant centipede", 3, 'w', C_GREEN, MT_FLESH, RC_INSECT); + addrace(R_CENTIPEDE, "giant centipede", 3, 'w', C_GREEN, MT_FLESH, RC_INSECT, "Giant centipedes are long, many-legged creatures with a poisonous bite."); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -8222,7 +8155,7 @@ void initrace(void) { addflag(lastrace->flags, F_TREMORSENSE, 3, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addrace(R_GLOWBUG, "glowbug", 1, 'i', C_WHITE, MT_FLESH, RC_INSECT); + addrace(R_GLOWBUG, "glowbug", 1, 'i', C_WHITE, MT_FLESH, RC_INSECT, "Glowbugs are tiny flying creatures, magically producing light from their bodies."); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, ""); @@ -8250,7 +8183,7 @@ void initrace(void) { addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); // demons - addrace(R_DRETCH, "dretch", 30, '&', C_BROWN, MT_FLESH, RC_DEMON); + addrace(R_DRETCH, "dretch", 30, '&', C_BROWN, MT_FLESH, RC_DEMON, "An ape-like creature with extended forearms ending in clawed hands. They stand about 4 feet tall and weigh 60 pounds."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); @@ -8273,7 +8206,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "narrows its eyes"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "roars^an other-wordly roar"); - addrace(R_LURKINGHORROR, "lurking horror", 100, 'U', C_MAGENTA, MT_FLESH, RC_DEMON); + addrace(R_LURKINGHORROR, "lurking horror", 100, 'U', C_MAGENTA, MT_FLESH, RC_DEMON, "A creeping, seething mass of pulsating flesh. A multitide of misshapen eyes and limbs protude from the writhing ooze in all directions. The very sight of this creature inspires a sense of cold dread."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -8299,7 +8232,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); - addrace(R_QUASIT, "quasit", 4, '&', C_BROWN, MT_FLESH, RC_DEMON); + addrace(R_QUASIT, "quasit", 4, '&', C_BROWN, MT_FLESH, RC_DEMON, "A tiny, bald humanoid with small spiked horns running down the middle of its scalp, leathery bat-like wings and of course sharp claws.."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); @@ -8326,7 +8259,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "screechs^an other-wordly screech"); // undead - addrace(R_ZOMBIE, "zombie", 50, 'Z', C_BLUE, MT_FLESH, RC_UNDEAD); + addrace(R_ZOMBIE, "zombie", 50, 'Z', C_BLUE, MT_FLESH, RC_UNDEAD, "The re-animated corpse of a once living entity, zombies seek to consume the brains of living creatures in an attempt to regain their soul."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CON, NA, NA, "6"); @@ -8355,7 +8288,7 @@ void initrace(void) { addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); - addrace(R_SKELETON, "skeleton", 20, 'Z', C_GREY, MT_BONE, RC_UNDEAD); + addrace(R_SKELETON, "skeleton", 20, 'Z', C_GREY, MT_BONE, RC_UNDEAD, "A walking set of bones, animated through the use of necromancy. Due to their lack of soft flesh, they have little to fear from edged weapons."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "5-20 bones"); @@ -8390,7 +8323,7 @@ void initrace(void) { addflag(lastrace->flags, F_BODYPARTNAME, BP_RIGHTFINGER, NA, NA, "right phalange"); addflag(lastrace->flags, F_BODYPARTNAME, BP_LEFTFINGER, NA, NA, "left phalange"); - addrace(R_GHAST, "ghast", 50, 'Z', C_MAGENTA, MT_FLESH, RC_UNDEAD); + addrace(R_GHAST, "ghast", 50, 'Z', C_MAGENTA, MT_FLESH, RC_UNDEAD, "A more slender and ghost-like form of ghoul. Ghasts are cunning and deadly, and possess a paralyzing touch."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); @@ -8412,7 +8345,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws"); - addrace(R_GHOST, "ghost", 50, 'p', C_BLUE, MT_MAGIC, RC_UNDEAD); // p for sPirit + addrace(R_GHOST, "ghost", 50, 'p', C_BLUE, MT_MAGIC, RC_UNDEAD, "Wispy spirits formed when a soul refuses to depart the earthly realm after death, ghosts exist part way between dimensions. The sight of a ghost can cause fear in all who behold it, and their ethereal nature makes them immune to most attacks."); // p for sPirit addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); @@ -8435,7 +8368,7 @@ void initrace(void) { // special: ghosts gain canwill->possession if they are near // their previous corpse. use f_mycorpse->oid for this. - addrace(R_GHOUL, "ghoul", 50, 'Z', C_GREEN, MT_FLESH, RC_UNDEAD); + addrace(R_GHOUL, "ghoul", 50, 'Z', C_GREEN, MT_FLESH, RC_UNDEAD, "Ghouls are monstrous, undead humanoids who feed on flesh and reek of carrion. Their bodies are grey and hairless, their teeth fanged, and their nails sharped into deadly claws."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); @@ -8443,6 +8376,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); + addflag(lastrace->flags, F_STENCH, 3, 1, NA, NULL); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+2"); addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); @@ -8457,7 +8391,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_BODYPARTNAME, BP_HANDS, NA, NA, "claws"); - addrace(R_VAMPIRE, "vampire", 75, 'V', C_BLUE, MT_FLESH, RC_UNDEAD); + addrace(R_VAMPIRE, "vampire", 75, 'V', C_BLUE, MT_FLESH, RC_UNDEAD, "Blood-drinking creatures of the night, vampires have pale white skin and prominent fangs protuding from their mouthes. They are said to be near immortal, able to survive even seemingly fatal attacks by converting themselves to a gaseous form."); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_EXHIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_VHIGH, NA, NULL); @@ -8494,7 +8428,6 @@ void initrace(void) { addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "pile of ash"); addflag(lastrace->flags, F_SPELLCASTTEXT, NA, NA, NA, "gestures"); addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "hisses angrily^an angry hiss"); - // special: change to gas cloud with 1 hp on death, if not asleep // special: flee from garlic // TODO: can shapeshift to bat @@ -8502,7 +8435,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); // special monsters - addrace(R_GASCLOUD, "cloud of gas", 0.1, '}', C_GREY, MT_GAS, RC_OTHER); + addrace(R_GASCLOUD, "cloud of gas", 0.1, '}', C_GREY, MT_GAS, RC_OTHER, "A large cloud of gas which seems to move with a life of its own..."); addflag(lastrace->flags, F_MOVESPEED, SP_ULTRAFAST, NA, NA, ""); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); @@ -8530,7 +8463,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); // special: fully heal if our origrace is a vampire, and we are resting over a coffin - addrace(R_DANCINGWEAPON, "dancing weapon", 0, ')', C_GREY, MT_METAL, RC_OTHER); + addrace(R_DANCINGWEAPON, "dancing weapon", 0, ')', C_GREY, MT_METAL, RC_OTHER, "A magically animated weapon."); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_FLYING, B_TRUE, NA, NA, ""); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4"); @@ -8554,7 +8487,7 @@ void initrace(void) { addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); - addrace(R_FLOATINGDISC, "floating disc", 0, '_', C_BOLDGREEN, MT_METAL, RC_OTHER); + addrace(R_FLOATINGDISC, "floating disc", 0, '_', C_BOLDGREEN, MT_METAL, RC_OTHER, "A magically created disc of energy which floats in the air."); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_LEVITATING, B_TRUE, NA, NA, ""); @@ -8735,8 +8668,6 @@ void initskills(void) { addskilldesc(SK_SPEECH, PR_SKILLED, "^gShop item prices are reduced by 20%.^n", B_FALSE); addskilldesc(SK_SPEECH, PR_EXPERT, "^gShop item prices are reduced by 25%.^n", B_FALSE); addskilldesc(SK_SPEECH, PR_MASTER, "^gShop item prices are reduced by 30%.^n", B_FALSE); - addskill(SK_SPELLCASTING, "Sorcery", "Increases the power of spells from all schools except Allomancy, Enviromancy and Psionics.", 50); - addskilldesc(SK_SPELLCASTING, PR_SKILLED, "^gYou gain the 'study scrolls' ability.^n", B_FALSE); addskill(SK_PERCEPTION, "Perception", "Your ability to notice hidden details, from simple footprints to sinister traps.", 50); addskilldesc(SK_PERCEPTION, PR_INEPT, "- At higher levels this skill will also let you obscure your own tracks.", B_TRUE); addskilldesc(SK_PERCEPTION, PR_NOVICE, "^gYou can now see footprints.^n", B_TRUE); @@ -8765,12 +8696,12 @@ void initskills(void) { addskilldesc(SK_THIEVERY, PR_EXPERT, "gYou can now steal multiple items.", B_TRUE); addskilldesc(SK_THIEVERY, PR_MASTER, "gYou can now steal equipped items.", B_TRUE); addskill(SK_THROWING, "Throwing", "Your accuracy when throwing objects at things.", 50); - addskilldesc(SK_RANGED, PR_NOVICE, "^gYou suffer a -20% accuracy penalty when throwing items.^n", B_FALSE); - addskilldesc(SK_RANGED, PR_BEGINNER, "^gYou suffer a -10% accuracy penalty when throwing items.^n", B_FALSE); - addskilldesc(SK_RANGED, PR_ADEPT, "^gYou no longer suffer a accuracy penalty when throwing items.^n", B_FALSE); - addskilldesc(SK_RANGED, PR_SKILLED, "^gYou gain a +10% accuracy bonus when throwing items.^n", B_FALSE); - addskilldesc(SK_RANGED, PR_EXPERT, "^gYou gain a +20% accuracy bonus when throwing items.^n", B_FALSE); - addskilldesc(SK_RANGED, PR_MASTER, "^gYou gain a +30% accuracy bonus when throwing items.^n", B_FALSE); + addskilldesc(SK_THROWING, PR_NOVICE, "^gYou suffer a -20% accuracy penalty when throwing items.^n", B_FALSE); + addskilldesc(SK_THROWING, PR_BEGINNER, "^gYou suffer a -10% accuracy penalty when throwing items.^n", B_FALSE); + addskilldesc(SK_THROWING, PR_ADEPT, "^gYou no longer suffer a accuracy penalty when throwing items.^n", B_FALSE); + addskilldesc(SK_THROWING, PR_SKILLED, "^gYou gain a +10% accuracy bonus when throwing items.^n", B_FALSE); + addskilldesc(SK_THROWING, PR_EXPERT, "^gYou gain a +20% accuracy bonus when throwing items.^n", B_FALSE); + addskilldesc(SK_THROWING, PR_MASTER, "^gYou gain a +30% accuracy bonus when throwing items.^n", B_FALSE); addskill(SK_TRAPS, "Traps", "Affects your ability to locate and disarm traps.", 25); addskilldesc(SK_TRAPS, PR_NOVICE, "^gYou gain the 'disarm traps' ability.^n", B_FALSE); addskill(SK_TWOWEAPON, "Dual Weilding", "Allows you to weild two melee weapons at once.", 50); @@ -8782,37 +8713,38 @@ void initskills(void) { // knowledge addskill(SK_LORE_ARCANA, "Lore:Arcana", "Allows you a chance of recognising magical objects and creatures.", 0); addskilldesc(SK_LORE_ARCANA, PR_NOVICE, "^gYou can attempt to identify objects with the 'inspect' ability.^n", B_FALSE); + addskilldesc(SK_LORE_ARCANA, PR_ADEPT, "^gYou gain the 'study scrolls' ability.", B_FALSE); addskill(SK_LORE_DEMONS, "Lore:Demonology", "Determines your knowledge about demons.", 0); addskilldesc(SK_LORE_DEMONS, PR_INEPT, "At each skill level, more information about related creatures will be shown.", B_FALSE); addskilldesc(SK_LORE_DEMONS, PR_INEPT, "Each level also gives +10% damage and accuracy against related creatures.", B_FALSE); addskilldesc(SK_LORE_DEMONS, PR_NOVICE, "^gExact attributes, armour rating and evasion are revealed.^n", B_FALSE); addskilldesc(SK_LORE_DEMONS, PR_BEGINNER, "^gExact attack damage is now revealed.^n", B_FALSE); - addskilldesc(SK_LORE_DEMONS, PR_ADEPT, "^gExact remaining hit points and stamina are now shown.^n", B_FALSE); - addskilldesc(SK_LORE_DEMONS, PR_SKILLED, "^gAn approximate threat level is calculated.^n", B_FALSE); + addskilldesc(SK_LORE_DEMONS, PR_ADEPT, "^gExact remaining hit points and stamina are shown and an approximate threat level is calculated.^n", B_FALSE); + addskilldesc(SK_LORE_DEMONS, PR_SKILLED, "^gExact turns to kill are shown.", B_FALSE); addskilldesc(SK_LORE_DEMONS, PR_MASTER, "^gYou can view complete information about skills, magic and abilities.^n", B_FALSE); addskill(SK_LORE_HUMANOID, "Lore:Humanoid", "Determines your knowledge about humanoid (bipedal) creatures.", 0); addskilldesc(SK_LORE_HUMANOID, PR_INEPT, "At each skill level, more information about related creatures will be shown.", B_FALSE); addskilldesc(SK_LORE_HUMANOID, PR_INEPT, "Each level also gives +10% damage and accuracy against related creatures.", B_FALSE); addskilldesc(SK_LORE_HUMANOID, PR_NOVICE, "^gExact attributes, armour rating and evasion are revealed.^n", B_FALSE); addskilldesc(SK_LORE_HUMANOID, PR_BEGINNER, "^gExact attack damage is now revealed.^n", B_FALSE); - addskilldesc(SK_LORE_HUMANOID, PR_ADEPT, "^gExact remaining hit points and stamina are now shown.^n", B_FALSE); - addskilldesc(SK_LORE_HUMANOID, PR_SKILLED, "^gAn approximate threat level is calculated.^n", B_FALSE); + addskilldesc(SK_LORE_HUMANOID, PR_ADEPT, "^gExact remaining hit points and stamina are shown and an approximate threat level is calculated.^n", B_FALSE); + addskilldesc(SK_LORE_HUMANOID, PR_SKILLED, "^gExact turns to kill are shown.", B_FALSE); addskilldesc(SK_LORE_HUMANOID, PR_MASTER, "^gYou can view complete information about skills, magic and abilities.^n", B_FALSE); addskill(SK_LORE_NATURE, "Lore:Nature", "Determines your knowledge of plants, animals and insects.", 0); addskilldesc(SK_LORE_NATURE, PR_INEPT, "At each skill level, more information about related creatures will be shown.", B_FALSE); addskilldesc(SK_LORE_NATURE, PR_INEPT, "Each level also gives +10% damage and accuracy against related creatures.", B_FALSE); addskilldesc(SK_LORE_NATURE, PR_NOVICE, "^gExact attributes, armour rating and evasion are revealed.^n", B_FALSE); addskilldesc(SK_LORE_NATURE, PR_BEGINNER, "^gExact attack damage is now revealed.^n", B_FALSE); - addskilldesc(SK_LORE_NATURE, PR_ADEPT, "^gExact remaining hit points and stamina are now shown.^n", B_FALSE); - addskilldesc(SK_LORE_NATURE, PR_SKILLED, "^gAn approximate threat level is calculated.^n", B_FALSE); + addskilldesc(SK_LORE_NATURE, PR_ADEPT, "^gExact remaining hit points and stamina are shown and an approximate threat level is calculated.^n", B_FALSE); + addskilldesc(SK_LORE_NATURE, PR_SKILLED, "^gExact turns to kill are shown.", B_FALSE); addskilldesc(SK_LORE_NATURE, PR_MASTER, "^gYou can view complete information about skills, magic and abilities.^n", B_FALSE); addskill(SK_LORE_UNDEAD, "Lore:Undead", "Determines your knowledge of the undead.", 0); addskilldesc(SK_LORE_UNDEAD, PR_INEPT, "At each skill level, more information about related creatures will be shown.", B_FALSE); addskilldesc(SK_LORE_UNDEAD, PR_INEPT, "Each level also gives +10% damage and accuracy against related creatures.", B_FALSE); addskilldesc(SK_LORE_UNDEAD, PR_NOVICE, "^gExact attributes, armour rating and evasion are revealed.^n", B_FALSE); addskilldesc(SK_LORE_UNDEAD, PR_BEGINNER, "^gExact attack damage is now revealed.^n", B_FALSE); - addskilldesc(SK_LORE_UNDEAD, PR_ADEPT, "^gExact remaining hit points and stamina are now shown.^n", B_FALSE); - addskilldesc(SK_LORE_UNDEAD, PR_SKILLED, "^gAn approximate threat level is calculated.^n", B_FALSE); + addskilldesc(SK_LORE_UNDEAD, PR_ADEPT, "^gExact hit points and stamina are shown, and an approximate threat level is calculated.^n", B_FALSE); + addskilldesc(SK_LORE_UNDEAD, PR_SKILLED, "^gExact turns to kill are shown.", B_FALSE); addskilldesc(SK_LORE_UNDEAD, PR_MASTER, "^gYou can view complete information about skills, magic and abilities.^n", B_FALSE); @@ -8851,84 +8783,84 @@ void initskills(void) { addskilldesc(SK_SS_NATURE, PR_SKILLED, "Allows you to cast Nature spells up to level 4.", B_FALSE); addskilldesc(SK_SS_NATURE, PR_EXPERT, "Allows you to cast Nature spells up to level 5.", B_FALSE); addskilldesc(SK_SS_NATURE, PR_MASTER, "Allows you to cast Nature spells up to level 6.", B_FALSE); - addskill(SK_SS_AIR, "Magic:Air Magic", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_AIR, "Sorcery:Air Magic", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_AIR, PR_NOVICE, "Allows you to cast Air Magic spells up to level 1.", B_FALSE); addskilldesc(SK_SS_AIR, PR_BEGINNER, "Allows you to cast Air Magic spells up to level 2.", B_FALSE); addskilldesc(SK_SS_AIR, PR_ADEPT, "Allows you to cast Air Magic spells up to level 3.", B_FALSE); addskilldesc(SK_SS_AIR, PR_SKILLED, "Allows you to cast Air Magic spells up to level 4.", B_FALSE); addskilldesc(SK_SS_AIR, PR_EXPERT, "Allows you to cast Air Magic spells up to level 5.", B_FALSE); addskilldesc(SK_SS_AIR, PR_MASTER, "Allows you to cast Air Magic spells up to level 6.", B_FALSE); - addskill(SK_SS_DEATH, "Magic:Necromancy", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_DEATH, "Sorcery:Necromancy", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_DEATH, PR_NOVICE, "Allows you to cast Necromancy spells up to level 1.", B_FALSE); addskilldesc(SK_SS_DEATH, PR_BEGINNER, "Allows you to cast Necromancy spells up to level 2.", B_FALSE); addskilldesc(SK_SS_DEATH, PR_ADEPT, "Allows you to cast Necromancy spells up to level 3.", B_FALSE); addskilldesc(SK_SS_DEATH, PR_SKILLED, "Allows you to cast Necromancy spells up to level 4.", B_FALSE); addskilldesc(SK_SS_DEATH, PR_EXPERT, "Allows you to cast Necromancy spells up to level 5.", B_FALSE); addskilldesc(SK_SS_DEATH, PR_MASTER, "Allows you to cast Necromancy spells up to level 6.", B_FALSE); - addskill(SK_SS_DIVINATION, "Magic:Divination", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_DIVINATION, "Sorcery:Divination", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_DIVINATION, PR_NOVICE, "Allows you to cast Divination spells up to level 1.", B_FALSE); addskilldesc(SK_SS_DIVINATION, PR_BEGINNER, "Allows you to cast Divination spells up to level 2.", B_FALSE); addskilldesc(SK_SS_DIVINATION, PR_ADEPT, "Allows you to cast Divination spells up to level 3.", B_FALSE); addskilldesc(SK_SS_DIVINATION, PR_SKILLED, "Allows you to cast Divination spells up to level 4.", B_FALSE); addskilldesc(SK_SS_DIVINATION, PR_EXPERT, "Allows you to cast Divination spells up to level 5.", B_FALSE); addskilldesc(SK_SS_DIVINATION, PR_MASTER, "Allows you to cast Divination spells up to level 6.", B_FALSE); - addskill(SK_SS_ENCHANTMENT, "Magic:Enchantment", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_ENCHANTMENT, "Sorcery:Enchantment", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_ENCHANTMENT, PR_NOVICE, "Allows you to cast Enchantment spells up to level 1.", B_FALSE); addskilldesc(SK_SS_ENCHANTMENT, PR_BEGINNER, "Allows you to cast Enchantment spells up to level 2.", B_FALSE); addskilldesc(SK_SS_ENCHANTMENT, PR_ADEPT, "Allows you to cast Enchantment spells up to level 3.", B_FALSE); addskilldesc(SK_SS_ENCHANTMENT, PR_SKILLED, "Allows you to cast Enchantment spells up to level 4.", B_FALSE); addskilldesc(SK_SS_ENCHANTMENT, PR_EXPERT, "Allows you to cast Enchantment spells up to level 5.", B_FALSE); addskilldesc(SK_SS_ENCHANTMENT, PR_MASTER, "Allows you to cast Enchantment spells up to level 6.", B_FALSE); - addskill(SK_SS_FIRE, "Magic:Fire Magic", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_FIRE, "Sorcery:Fire Magic", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_FIRE, PR_NOVICE, "Allows you to cast Fire Magic spells up to level 1.", B_FALSE); addskilldesc(SK_SS_FIRE, PR_BEGINNER, "Allows you to cast Fire Magic spells up to level 2.", B_FALSE); addskilldesc(SK_SS_FIRE, PR_ADEPT, "Allows you to cast Fire Magic spells up to level 3.", B_FALSE); addskilldesc(SK_SS_FIRE, PR_SKILLED, "Allows you to cast Fire Magic spells up to level 4.", B_FALSE); addskilldesc(SK_SS_FIRE, PR_EXPERT, "Allows you to cast Fire Magic spells up to level 5.", B_FALSE); addskilldesc(SK_SS_FIRE, PR_MASTER, "Allows you to cast Fire Magic spells up to level 6.", B_FALSE); - addskill(SK_SS_COLD, "Magic:Cold Magic", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_COLD, "Sorcery:Cold Magic", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_COLD, PR_NOVICE, "Allows you to cast Cold Magic spells up to level 1.", B_FALSE); addskilldesc(SK_SS_COLD, PR_BEGINNER, "Allows you to cast Cold Magic spells up to level 2.", B_FALSE); addskilldesc(SK_SS_COLD, PR_ADEPT, "Allows you to cast Cold Magic spells up to level 3.", B_FALSE); addskilldesc(SK_SS_COLD, PR_SKILLED, "Allows you to cast Cold Magic spells up to level 4.", B_FALSE); addskilldesc(SK_SS_COLD, PR_EXPERT, "Allows you to cast Cold Magic spells up to level 5.", B_FALSE); addskilldesc(SK_SS_COLD, PR_MASTER, "Allows you to cast Cold Magic spells up to level 6.", B_FALSE); - addskill(SK_SS_GRAVITY, "Magic:Gravitation Magic", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_GRAVITY, "Sorcery:Gravitation Magic", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_GRAVITY, PR_NOVICE, "Allows you to cast Gravitation Magic spells up to level 1.", B_FALSE); addskilldesc(SK_SS_GRAVITY, PR_BEGINNER, "Allows you to cast Gravitation Magic spells up to level 2.", B_FALSE); addskilldesc(SK_SS_GRAVITY, PR_ADEPT, "Allows you to cast Gravitation Magic spells up to level 3.", B_FALSE); addskilldesc(SK_SS_GRAVITY, PR_SKILLED, "Allows you to cast Gravitation Magic spells up to level 4.", B_FALSE); addskilldesc(SK_SS_GRAVITY, PR_EXPERT, "Allows you to cast Gravitation Magic spells up to level 5.", B_FALSE); addskilldesc(SK_SS_GRAVITY, PR_MASTER, "Allows you to cast Gravitation Magic spells up to level 6.", B_FALSE); - addskill(SK_SS_LIFE, "Magic:Life Magic", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_LIFE, "Sorcery:Life Magic", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_LIFE, PR_NOVICE, "Allows you to cast Life Magic spells up to level 1.", B_FALSE); addskilldesc(SK_SS_LIFE, PR_BEGINNER, "Allows you to cast Life Magic spells up to level 2.", B_FALSE); addskilldesc(SK_SS_LIFE, PR_ADEPT, "Allows you to cast Life Magic spells up to level 3.", B_FALSE); addskilldesc(SK_SS_LIFE, PR_SKILLED, "Allows you to cast Life Magic spells up to level 4.", B_FALSE); addskilldesc(SK_SS_LIFE, PR_EXPERT, "Allows you to cast Life Magic spells up to level 5.", B_FALSE); addskilldesc(SK_SS_LIFE, PR_MASTER, "Allows you to cast Life Magic spells up to level 6.", B_FALSE); - addskill(SK_SS_MODIFICATION, "Magic:Modification", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_MODIFICATION, "Sorcery:Modification", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_MODIFICATION, PR_NOVICE, "Allows you to cast Modification spells up to level 1.", B_FALSE); addskilldesc(SK_SS_MODIFICATION, PR_BEGINNER, "Allows you to cast Modification spells up to level 2.", B_FALSE); addskilldesc(SK_SS_MODIFICATION, PR_ADEPT, "Allows you to cast Modification spells up to level 3.", B_FALSE); addskilldesc(SK_SS_MODIFICATION, PR_SKILLED, "Allows you to cast Modification spells up to level 4.", B_FALSE); addskilldesc(SK_SS_MODIFICATION, PR_EXPERT, "Allows you to cast Modification spells up to level 5.", B_FALSE); addskilldesc(SK_SS_MODIFICATION, PR_MASTER, "Allows you to cast Modification spells up to level 6.", B_FALSE); - addskill(SK_SS_SUMMONING, "Magic:Summoning", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_SUMMONING, "Sorcery:Summoning", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_SUMMONING, PR_NOVICE, "Allows you to cast Summoning spells up to level 1.", B_FALSE); addskilldesc(SK_SS_SUMMONING, PR_BEGINNER, "Allows you to cast Summoning spells up to level 2.", B_FALSE); addskilldesc(SK_SS_SUMMONING, PR_ADEPT, "Allows you to cast Summoning spells up to level 3.", B_FALSE); addskilldesc(SK_SS_SUMMONING, PR_SKILLED, "Allows you to cast Summoning spells up to level 4.", B_FALSE); addskilldesc(SK_SS_SUMMONING, PR_EXPERT, "Allows you to cast Summoning spells up to level 5.", B_FALSE); addskilldesc(SK_SS_SUMMONING, PR_MASTER, "Allows you to cast Summoning spells up to level 6.", B_FALSE); - addskill(SK_SS_TRANSLOCATION, "Magic:Translocation", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_TRANSLOCATION, "Sorcery:Translocation", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_TRANSLOCATION, PR_NOVICE, "Allows you to cast Translocation spells up to level 1.", B_FALSE); addskilldesc(SK_SS_TRANSLOCATION, PR_BEGINNER, "Allows you to cast Translocation spells up to level 2.", B_FALSE); addskilldesc(SK_SS_TRANSLOCATION, PR_ADEPT, "Allows you to cast Translocation spells up to level 3.", B_FALSE); addskilldesc(SK_SS_TRANSLOCATION, PR_SKILLED, "Allows you to cast Translocation spells up to level 4.", B_FALSE); addskilldesc(SK_SS_TRANSLOCATION, PR_EXPERT, "Allows you to cast Translocation spells up to level 5.", B_FALSE); addskilldesc(SK_SS_TRANSLOCATION, PR_MASTER, "Allows you to cast Translocation spells up to level 6.", B_FALSE); - addskill(SK_SS_WILD, "Magic:Wild Magic", "Boosts casting of spells from this school.", 50); + addskill(SK_SS_WILD, "Sorcery:Wild Magic", "Boosts casting of spells from this school.", 50); addskilldesc(SK_SS_WILD, PR_NOVICE, "Allows you to cast Wild Magic spells up to level 1.", B_FALSE); addskilldesc(SK_SS_WILD, PR_BEGINNER, "Allows you to cast Wild Magic spells up to level 2.", B_FALSE); addskilldesc(SK_SS_WILD, PR_ADEPT, "Allows you to cast Wild Magic spells up to level 3.", B_FALSE); diff --git a/data/hiscores.db b/data/hiscores.db index b5e3935..5fe5e39 100644 Binary files a/data/hiscores.db and b/data/hiscores.db differ diff --git a/defs.h b/defs.h index e493466..04bd3bc 100644 --- a/defs.h +++ b/defs.h @@ -436,7 +436,6 @@ enum SKILL { SK_SEWING, SK_SHIELDS, SK_SPEECH, - SK_SPELLCASTING, SK_STEALTH, SK_SWIMMING, SK_TECHUSAGE, @@ -475,7 +474,7 @@ enum SKILL { SK_SS_TRANSLOCATION, SK_SS_WILD, }; -#define MAXSKILLS 53 +#define MAXSKILLS 52 // proficiency levels enum SKILLLEVEL { @@ -801,7 +800,6 @@ enum RACE { R_GIANTFIRETITAN, R_GNOLL, R_GNOLLHM, - R_GNOLLMR, R_GOBLIN, R_GOBLINWAR, R_GOBLINSHOOTER, @@ -813,7 +811,6 @@ enum RACE { R_LIZARDMAN, R_MINOTAUR, R_OGRE, - R_OGRESAVAGE, R_OGREWARHULK, R_OOZEGREY, R_ORC, @@ -954,6 +951,7 @@ enum MATERIAL { MT_PLANT = 26, MT_WIRE = 27, MT_SILVER = 28, + MT_DRAGONWOOD = 29, }; // Object Types @@ -1019,7 +1017,8 @@ enum OBTYPE { OT_BANANA, OT_BANANASKIN, // not really food OT_APPLE, - OT_MUSHROOM, + OT_MUSHROOMSHI, + OT_MUSHROOMTOAD, OT_BREADSTALE, OT_CHEESE, OT_STEW, @@ -1474,6 +1473,7 @@ enum OBTYPE { // armour - head OT_SUNHAT, OT_PIRATEHAT, + OT_POINTYHAT, OT_CAP, OT_HELM, OT_GASMASK, @@ -1577,6 +1577,7 @@ enum OBTYPE { OT_BAMBOOSTAFF, OT_IRONSTAFF, OT_BLADEDSTAFF, + OT_WIZARDSTAFF, // clubs OT_CLUB, OT_FLAIL, @@ -1799,7 +1800,9 @@ enum FLAG { F_OBDIETEXT, // text when the object dies F_DIECONVERTTEXT, // text when the object converts. eg. "melts" F_DIECONVERTTEXTPL, // text when the object converts, if there are more than 1. eg. "melt" - F_DIECONVERT, // val0 = what this turns into when dying + F_DIECONVERT, // text = what this turns into when dying + // v0 = radius to scatter new object in (0 or NA means + // just convert the object) F_NOBLESS, // can't be blessed or cursed F_NOQUALITY, // can't be masterwork / shoddy F_CORPSEOF, // this is a corpse of montype val0. @@ -2024,6 +2027,7 @@ enum FLAG { F_MANUALOF, // val0 = spellschool this book trains // ob identification flags F_HASHIDDENNAME, // whether this object class has a hidden name + // text is the name if you don't know what it is F_IDENTIFIED, // whether this object is fully identified F_KNOWNBAD, // you know this object is somehow bad // bad flags @@ -2311,6 +2315,7 @@ enum FLAG { // v0=slot (0-9) // text=spell text // for monsters + F_MPMOD, // this race gains/loses v0 mp each level F_DOESNTMOVE, // this race doesn't move (but can still attack) F_AQUATIC, // this race can attack normally in water and suffers no // movement penalties @@ -2598,8 +2603,12 @@ enum INJURY { IJ_LEGBROKEN, IJ_LEGBRUISE, IJ_NOSEBROKEN, + IJ_RIBBROKEN, // can be from explosive too IJ_RIBCRACKED, // can be from explosive too IJ_SHOULDERDISLOCATED, + IJ_TORSOBRUISED, + IJ_TORSOBRUISEDBAD, + IJ_WINDED, IJ_WINDPIPECRUSHED, // slashing IJ_ARTERYPIERCE, @@ -3003,6 +3012,7 @@ typedef struct race_s { struct raceclass_s *raceclass; struct material_s *material; char *name; + char *desc; struct glyph_s glyph; float weight; struct flagpile_s *flags; diff --git a/doc/add_material.txt b/doc/add_material.txt index 9f8ca87..68aa151 100644 --- a/doc/add_material.txt +++ b/doc/add_material.txt @@ -1,8 +1,10 @@ defs.h: define the MT_* enum -objects.c: +data.c: add an addmaterial() line + +objects.c: update adjustdammaterial() as required update getmaterialvalue() update getmaterialstate() diff --git a/god.c b/god.c index 3ea5845..6087500 100644 --- a/god.c +++ b/god.c @@ -101,8 +101,8 @@ void angergod(enum RACE rid, int amt) { // minor bad stuff switch (rid) { case R_GODDEATH: - castspell(god, OT_S_PAIN, player, NULL, player->cell); - castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell); + castspell(god, OT_S_PAIN, player, NULL, player->cell, NULL, NULL); + castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell, NULL, NULL); // all undead in sight become hostile for (l = player->cell->map->lf ; l ; l = l->next) { if (!isplayer(l) && isundead(l) && cansee(l, player)) { @@ -115,7 +115,7 @@ void angergod(enum RACE rid, int amt) { case R_GODTHIEVES: // take a random object msg("\"Yoink!\""); - castspell(god, OT_S_CONFISCATE, player, NULL, player->cell); + castspell(god, OT_S_CONFISCATE, player, NULL, player->cell, NULL, NULL); break; case R_GODMERCY: // lower one attribute @@ -153,8 +153,8 @@ void angergod(enum RACE rid, int amt) { // major bad stuff switch (god->race->id) { case R_GODDEATH: - castspell(god, OT_S_PAIN, player, NULL, player->cell); - castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell); + castspell(god, OT_S_PAIN, player, NULL, player->cell, NULL, NULL); + castspell(god, OT_S_DRAINLIFE, player, NULL, player->cell, NULL, NULL); // all undead in sight become hostile for (l = player->cell->map->lf ; l ; l = l->next) { if (!isplayer(l) && isundead(l) && cansee(l, player)) { @@ -167,9 +167,9 @@ void angergod(enum RACE rid, int amt) { case 1: msg("\"This will teach you some humility, mortal!\""); if (getattr(player, A_IQ) > getattr(player, A_STR)) { - castspell(god, OT_S_FEEBLEMIND, player, NULL, player->cell); + castspell(god, OT_S_FEEBLEMIND, player, NULL, player->cell, NULL, NULL); } else { - castspell(god, OT_S_WEAKEN, player, NULL, player->cell); + castspell(god, OT_S_WEAKEN, player, NULL, player->cell, NULL, NULL); } break; case 2: @@ -183,11 +183,11 @@ void angergod(enum RACE rid, int amt) { o = getweapon(player); msg("\"Allow me to lighten your load a little...\""); if (o) { // take player's weapon - castspell(god, OT_S_CONFISCATE, player, o, player->cell); + castspell(god, OT_S_CONFISCATE, player, o, player->cell, NULL, NULL); } else { // take 3 objects int i; for (i = 0; i < 3; i++) { - castspell(god, OT_S_CONFISCATE, player, NULL, player->cell); + castspell(god, OT_S_CONFISCATE, player, NULL, player->cell, NULL, NULL); } } break; @@ -809,12 +809,12 @@ int prayto(lifeform_t *lf, lifeform_t *god) { if (getalignment(l) == AL_EVIL) { if (haslof(lf->cell, l->cell, LOF_WALLSTOP, NULL)) { // smite them - castspell(god, OT_S_SMITEEVIL, l, NULL, l->cell); + castspell(god, OT_S_SMITEEVIL, l, NULL, l->cell, NULL, NULL); } } } // turn undead - castspell(god, OT_S_TURNUNDEAD, lf, NULL, NULL); + castspell(god, OT_S_TURNUNDEAD, lf, NULL, NULL, NULL, NULL); break; case R_GODDEATH: @@ -824,7 +824,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { if (isundead(l)) { makepeaceful(l); } else { - castspell(god, OT_S_PAIN, l, NULL, l->cell); + castspell(god, OT_S_PAIN, l, NULL, l->cell, NULL, NULL); } } } @@ -851,7 +851,7 @@ int prayto(lifeform_t *lf, lifeform_t *god) { msg("\"I'll take that...\""); donesomething = B_TRUE; } - castspell(god, OT_S_CONFISCATE, l, wep, l->cell); + castspell(god, OT_S_CONFISCATE, l, wep, l->cell, NULL, NULL); } } } @@ -888,17 +888,17 @@ int prayto(lifeform_t *lf, lifeform_t *god) { case R_GODMERCY: if (ispoisoned(lf)) { msg("\"Let thy body be purged of toxins.\""); - castspell(god, OT_S_CUREPOISON, player, NULL, player->cell); + castspell(god, OT_S_CUREPOISON, player, NULL, player->cell, NULL, NULL); donesomething = B_TRUE; } if (gethungerlevel(gethungerval(player)) >= H_PECKISH) { msg("\"Let thy stomach be satisfied.\""); - castspell(god, OT_S_SATEHUNGER, player, NULL, player->cell); + castspell(god, OT_S_SATEHUNGER, player, NULL, player->cell, NULL, NULL); donesomething = B_TRUE; } if (isbleeding(lf) || !donesomething) { msg("\"Let thy wounds be healed.\""); - castspell(god, OT_S_HEALINGMAJ, player, NULL, player->cell); + castspell(god, OT_S_HEALINGMAJ, player, NULL, player->cell, NULL, NULL); donesomething = B_TRUE; } break; diff --git a/io.c b/io.c index 6562ab9..2852f13 100644 --- a/io.c +++ b/io.c @@ -33,6 +33,8 @@ int hascolour = B_TRUE; int noredraw = B_FALSE; +int escok = B_TRUE; + extern int needredraw; extern int numdraws; @@ -48,6 +50,8 @@ extern void (*precalclos)(lifeform_t *); extern lifeform_t *godlf[]; extern int ngodlfs; +extern race_t *firstrace; + extern prompt_t prompt; extern object_t *retobs[MAXPILEOBS+1]; @@ -463,7 +467,7 @@ void animsky(cell_t *src, char ch, int colour) { needredraw = B_TRUE; } -char askchar(char *prompt, char *validchars, char *def, int showchars) { +char askchar(char *prompt, char *validchars, char *def, int showchars, int maycancel) { char buf[BUFLEN]; char msghistbuf[BUFLEN]; char *p; @@ -501,8 +505,11 @@ char askchar(char *prompt, char *validchars, char *def, int showchars) { curs_set(1); valid = B_FALSE; while (!valid) { - ch = getkey(); - if (strchr(validchars, ch)) { + ch = getkey(B_FALSE); + if ((ch == 27) && maycancel) { + ch = '\0'; + valid = B_TRUE; + } else if (strchr(validchars, ch)) { valid = B_TRUE; } else if ((ch == 10) && def) { // enter = default valid = B_TRUE; @@ -513,7 +520,7 @@ char askchar(char *prompt, char *validchars, char *def, int showchars) { curs_set(0); // update messaage history - sprintf(msghistbuf, "%s%c", buf, ch); + sprintf(msghistbuf, "%s%c", buf, (ch == '\0') ? '-' : '\0'); addmsghist(msghistbuf); clearmsg(); @@ -2343,7 +2350,7 @@ void announceobflagloss(object_t *o, flag_t *f) { int confirm_badfeeling(object_t *o) { char ch; - ch = askchar("You have a bad feeling about this. Continue?", "yn", "n", B_TRUE); + ch = askchar("You have a bad feeling about this. Continue?", "yn", "n", B_TRUE, B_FALSE); if (ch == 'y') return B_TRUE; if (o && !hasflag(o->flags, F_KNOWNBAD)) { addflag(o->flags, F_KNOWNBAD, B_TRUE, NA, NA, NULL); @@ -2359,7 +2366,7 @@ int confirm_injury_action(enum BODYPART bp, enum DAMTYPE dt, char *actionname) { if (hasbleedinginjury(player, bp) && willbleedfrom(player, bp)) { snprintf(ques, BUFLEN, "Your %s injury will cause damage if you %s - continue?", getinjuredbpname(bp), actionname); - ch = askchar(ques, "yn","n", B_TRUE); + ch = askchar(ques, "yn","n", B_TRUE, B_FALSE); if (ch == 'n') { return B_FALSE; } @@ -2641,7 +2648,7 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int break; } // otherwise look for shift key etc.. - ch = keycodetokey(ch); + ch = keycodetokey(ch, B_TRUE); // then handle input if (ch == ' ') { // next page if (nextpage == -1) { // go to first page @@ -2649,6 +2656,8 @@ object_t *doaskobject(obpile_t *op, char *prompt, int *count, int forpickup, int } else { firstob = nextpage; } + } else if ((ch == '\\') && (gamemode == GM_GAMESTARTED)) { + doknowledgelist(); } else if (isalpha(ch) || (ch == '$')) { object_t *o; // describe that object @@ -2856,7 +2865,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) { break; } // otherwise look for shift key etc.. - ch = keycodetokey(ch); + ch = keycodetokey(ch, B_TRUE); // then handle input if (ch == ' ') { // next page if (nextpage == -1) { // go to first page @@ -3211,7 +3220,36 @@ void describeob(object_t *o) { restoregamewindows(); } -void describeskill(enum SKILL skid) { +void describerace(enum RACE rid) { + char buf[BUFLEN]; + char *buf2; + race_t *r; + cls(); + r = findrace(rid); + if (!r) return; + + // title + snprintf(buf, BUFLEN, "Race::%s",r->name); + wattron(mainwin, A_BOLD); + mvwprintw(mainwin, 0, 0, "%s", buf); + wattroff(mainwin, A_BOLD); + + wmove(mainwin, 2, 0); + + buf2 = malloc(HUGEBUFLEN * sizeof(char)); + makedesc_race(rid, buf2); + textwithcol(mainwin, buf2); + free(buf2); + + wrefresh(mainwin); + + // wait for key + getch(); + real_clearmsg(B_TRUE); + restoregamewindows(); +} + +void describeskill(enum SKILL skid, enum SKILLLEVEL levhilite) { char buf[BUFLEN]; char *buf2; skill_t *sk; @@ -3228,7 +3266,7 @@ void describeskill(enum SKILL skid) { wmove(mainwin, 2, 0); buf2 = malloc(HUGEBUFLEN * sizeof(char)); - makedesc_skill(skid, buf2); + makedesc_skill(skid, buf2, levhilite); textwithcol(mainwin, buf2); free(buf2); @@ -3272,7 +3310,7 @@ void doattackcell(char dirch) { cell_t *c; if (dirch == '\0') { - dirch = askchar("Attack in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + dirch = askchar("Attack in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); } @@ -3332,7 +3370,7 @@ void doclose(void) { } else if (adjdoors == 1) { dir = forcedir; } else { - ch = askchar("Close door in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE); + ch = askchar("Close door in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE); dir = chartodir(ch); } @@ -3499,7 +3537,7 @@ void docomms(lifeform_t *lf) { say(lf, "Behold mortal! It is I, Yumi!", SV_SHOUT); say(lf, "For your selfless act, I grant you a wish.", SV_TALK); // grant a wish. - castspell(lf, OT_S_WISHLIMITED, player, NULL, NULL); + castspell(lf, OT_S_WISHLIMITED, player, NULL, NULL, NULL, NULL); say(lf, "Until next time, mortal!", SV_TALK); unsummon(lf, B_TRUE); } else if (i <= 20) { // identify @@ -3617,7 +3655,7 @@ void docomms(lifeform_t *lf) { char buf2[BUFLEN]; char ch2; snprintf(buf2, BUFLEN, "Pay $%d to identify %s?",(int)DEF_SHOPIDENTPRICE, buf); - ch2 = askchar(buf2, "yn","n", B_TRUE); + ch2 = askchar(buf2, "yn","n", B_TRUE, B_FALSE); if (ch2 == 'y') { if (givemoney(player, lf, DEF_SHOPIDENTPRICE)) { angeramt += 25; @@ -3771,7 +3809,7 @@ void dodrop(obpile_t *op, int wantmulti, obpile_t *dst) { char buf2[BUFLEN]; // take it off first - this takes time. snprintf(buf2, BUFLEN, "Remove %s",buf); - ch = askchar(buf2, "yn","y", B_TRUE); + ch = askchar(buf2, "yn","y", B_TRUE, B_FALSE); if (ch == 'y') { if (takeoff(player, o)) { // failed to take it off - can't drop it. @@ -3850,7 +3888,7 @@ void doeat(obpile_t *op) { (o->amt == 1) ? "is" : "are", obname, (o->amt == 1) ? "it" : "one"); - ch = askchar(buf, "yn","n", B_TRUE); + ch = askchar(buf, "yn","n", B_TRUE, B_FALSE); if (ch == 'y') { eatob = o; break; @@ -3949,7 +3987,7 @@ void dovendingmachine(lifeform_t *lf, object_t *vm) { // confirm getobname(o, obname, o->amt); snprintf(buf, BUFLEN, "Buy %s for $%d?",obname, getobvalue(o)); - answer = askchar(buf, "yn","n", B_TRUE); + answer = askchar(buf, "yn","n", B_TRUE, B_FALSE); if (answer == 'y') { int shopamt; givemoney(player, NULL, getobvalue(o)); @@ -5319,7 +5357,21 @@ char *makedesc_ob(object_t *o, char *retbuf) { return retbuf; } -char *makedesc_skill(enum SKILL skid, char *retbuf) { +char *makedesc_race(enum RACE rid, char *retbuf) { + race_t *r; + char buf[HUGEBUFLEN]; + + strcpy(retbuf, ""); + + r = findrace(rid); + + snprintf(buf, HUGEBUFLEN, "%s\n\n", r->desc); + strncat(retbuf, buf, HUGEBUFLEN); + + return retbuf; +} + +char *makedesc_skill(enum SKILL skid, char *retbuf, enum SKILLLEVEL levhilite) { skill_t *sk; enum SKILLLEVEL slev; char buf[BUFLEN]; @@ -5340,7 +5392,13 @@ char *makedesc_skill(enum SKILL skid, char *retbuf) { if (slev == PR_INEPT) { snprintf(buf, BUFLEN, "%s\n",sk->skilldesctext[i]); } else { - snprintf(buf, BUFLEN, "At %s level: %s\n",getskilllevelname(sk->skilldesclev[i]), sk->skilldesctext[i]); + int hilitethis = B_FALSE; + if ((levhilite != PR_INEPT) && (slev == levhilite)) { + hilitethis = B_TRUE; + } + snprintf(buf, BUFLEN, "%sAt %s level%s: %s\n",hilitethis ? "^W" : "", + getskilllevelname(sk->skilldesclev[i]), sk->skilldesctext[i], + hilitethis ? "^n" : ""); } strncat(retbuf, buf, HUGEBUFLEN); } @@ -5693,7 +5751,7 @@ void domagic(enum OBTYPE spellid, int cellx, int celly) { // should always work... if (ot->obclass->id == OC_SPELL) { - castspell(player, spellid, targlf, NULL, targcell); + castspell(player, spellid, targlf, NULL, targcell, NULL, NULL); } else { useability(player, spellid, targlf, targcell); } @@ -5716,7 +5774,10 @@ void domemmagic(void) { msg("You don't have any spells or abilities!"); return; } - ch = askchar("Memorise in which slot (1-9)", "1234567890","", B_FALSE); + ch = askchar("Memorise in which slot (0-9, n to cancel)", "1234567890n","", B_FALSE, B_TRUE); + if (!isdigit(ch)) { + return; + } slot = ch - '0'; getchoicestr(&prompt, B_FALSE, B_FALSE); @@ -5768,7 +5829,7 @@ void dooperate(obpile_t *op) { (o->amt == 1) ? "is" : "are", obname, verb, (o->amt == 1) ? "it" : "one"); - ch = askchar(buf, "yn","n", B_TRUE); + ch = askchar(buf, "yn","n", B_TRUE, B_FALSE); if (ch == 'y') { operate(player, o, NULL); return; @@ -5943,6 +6004,7 @@ void dohelp(char helpmode) { if (helpmode == '?') { initprompt(&prompt, "What would you like help with (ESC when done)?"); addchoice(&prompt, '?', "Keyboard Commands", NULL, NULL, NULL); + addchoice(&prompt, 'r', "Race Descriptions", NULL, NULL, NULL); addchoice(&prompt, 's', "Skill Descriptions", NULL, NULL, NULL); addchoice(&prompt, 'g', "God Descriptions", NULL, NULL, NULL); addchoice(&prompt, '-', "(done)", NULL, NULL, NULL); @@ -5974,6 +6036,24 @@ void dohelp(char helpmode) { centre(mainwin,C_WHITE, h-1, "[Press any key]"); getch(); done = B_TRUE; + } else if (helpmode == 'r') { + race_t *r; + centre(mainwin,C_WHITE, 0, "RACE REFERENCE"); + y = 2; + + initprompt(&prompt, "Describe which race (ESC when done)?"); + for (r = firstrace ; r ; r = r->next) { + addchoice(&prompt, 'a', r->name, NULL, r, r->desc); + } + addchoice(&prompt, '\0', "(done)", NULL, NULL, NULL); + prompt.maycancel = B_TRUE; + ch = getchoicestr(&prompt, B_FALSE, B_TRUE); + if (!ch) { + done = B_TRUE; + } else { + r = (race_t *)prompt.result; + describerace(r->id); + } } else if (helpmode == 's') { skill_t *sk; centre(mainwin,C_WHITE, 0, "SKILL REFERENCE"); @@ -5990,7 +6070,7 @@ void dohelp(char helpmode) { done = B_TRUE; } else { sk = (skill_t *)prompt.result; - describeskill(sk->id); + describeskill(sk->id, PR_INEPT); } } else if (helpmode == 'g') { lifeform_t *god; @@ -6048,7 +6128,7 @@ void doquaff(obpile_t *op) { (o->amt == 1) ? "is" : "are", obname, drink, (o->amt == 1) ? "it" : "one"); - ch = askchar(buf, "yn","n", B_TRUE); + ch = askchar(buf, "yn","n", B_TRUE, B_FALSE); if (ch == 'y') { liquid = o; break; @@ -6095,7 +6175,7 @@ void dolockpick(obpile_t *op) { } // ask direction - ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE); + ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE); dir = chartodir(ch); if (dir == D_NONE) { clearmsg(); @@ -6200,7 +6280,7 @@ void dopour(obpile_t *op) { void doquit(void) { char ch; - ch = askchar("Really quit", "yn","n", B_TRUE); + ch = askchar("Really quit", "yn","n", B_TRUE, B_FALSE); if (ch == 'y') { addflag(player->flags, F_NOSCORE, B_TRUE, NA, NA, NULL); setlastdam(player, "quitting"); @@ -6237,43 +6317,15 @@ void dorest(void) { if (check_rest_ok(player)) return; if (needstorest(player, validchars)) { - /* - if (strchr(validchars, 'h') && strchr(validchars, 'm')) { - - strcat(validchars, "bn"); - strcpy(ques, "Rest until full Health, Mana, Both, or none"); - ch = askchar(ques, validchars, "b", B_TRUE); - if (ch == 'b') { - addflag(player->flags, F_RESTUNTILHP, B_TRUE, NA, NA, NULL); - addflag(player->flags, F_RESTUNTILMP, B_TRUE, NA, NA, NULL); - } else if (ch == 'h') { - addflag(player->flags, F_RESTUNTILHP, B_TRUE, NA, NA, NULL); - } else if (ch == 'm') { - addflag(player->flags, F_RESTUNTILMP, B_TRUE, NA, NA, NULL); - } - } else if (strchr(validchars, 'h')) { - strcpy(ques, "Rest until full Health"); - ch = askchar(ques, "yn", "y", B_TRUE); - if (ch == 'y') { - addflag(player->flags, F_RESTUNTILHP, B_TRUE, NA, NA, NULL); - } - } else if (strchr(validchars, 'm')) { - strcpy(ques, "Rest until full Mana"); - ch = askchar(ques, "yn", "y", B_TRUE); - if (ch == 'y') { - addflag(player->flags, F_RESTUNTILMP, B_TRUE, NA, NA, NULL); - } - } - */ strcpy(ques, "Rest"); - ch = askchar(ques, "yn", "y", B_TRUE); + ch = askchar(ques, "yn", "y", B_TRUE, B_FALSE); if (ch == 'y') { addflag(player->flags, F_RESTUNTILBETTER, B_TRUE, NA, NA, NULL); } } else { if (countnearbyhurtallies(player)) { strcpy(ques, "Rest until nearby allies are healed?"); - ch = askchar(ques, "yn", "y", B_TRUE); + ch = askchar(ques, "yn", "y", B_TRUE, B_FALSE); if (ch == 'y') { addflag(player->flags, F_RESTUNTILALLIES, B_TRUE, NA, NA, NULL); } @@ -6390,7 +6442,7 @@ void dothrow(obpile_t *op) { if (!haslof(player->cell, where, LOF_WALLSTOP, &newwhere)) { if (newwhere && (newwhere != player->cell)) { char ch; - ch = askchar("Your line of fire is blocked - really throw here", "yn", "y", B_TRUE); + ch = askchar("Your line of fire is blocked - really throw here", "yn", "y", B_TRUE, B_FALSE); if (ch == 'y') { // update destination cell. where = newwhere; @@ -6695,8 +6747,9 @@ void initgfx(void) { noecho(); - //cbreak(); - raw(); + // TODO: change back to raw mode, or make this a switch + cbreak(); + //raw(); nodelay(mainwin, FALSE); getmaxyx(mainwin, SCREENH, SCREENW); @@ -6901,6 +6954,8 @@ char getchoice(prompt_t *prompt) { prompt->result = NULL; sel = -1; break; + } else if ((ch == '\\') && (gamemode == GM_GAMESTARTED)) { + doknowledgelist(); } else if (ch == ' ') { if (nextpage == -1) { first = 0; @@ -7177,6 +7232,8 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) { } else if ((ch == 27) && (prompt->maycancel)) { // ESC - cancel sel = -1; break; + } else if ((ch == '\\') && (gamemode == GM_GAMESTARTED)) { + doknowledgelist(); } else if (ch == '\'') { if (nextpage == -1) { first = 0; @@ -7261,7 +7318,7 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) { return prompt->choice[i].ch; } -int getkey(void) { +int getkey(int escseqok) { int key_code=0; key_code = getch(); @@ -7282,7 +7339,7 @@ int getkey(void) { raw(); } - return keycodetokey(key_code); + return keycodetokey(key_code, escseqok); } enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev) { @@ -7424,7 +7481,7 @@ void handleinput(void) { } } else { gettinginput = B_TRUE; - ch = getkey(); + ch = getkey(B_TRUE); gettinginput = B_FALSE; } gotcmd = B_TRUE; @@ -7761,13 +7818,20 @@ void initprompt(prompt_t *p, char *q1) { } } -int keycodetokey(int keycode) { +// if escseqok is true, then process escape sequences by +// reading 3 more chars +int keycodetokey(int keycode, int escseqok) { int keystroke = 0; if (keycode == -1) return -1; - if (keycode == 27) { // an esc sequence + if (escseqok && (keycode == 27)) { // an esc sequence + timeout(0); // don't block keycode=getch(); + timeout(-1); // resume blocking + if (keycode == ERR) { + return 27; // ESC + } keystroke=keycode; keycode=getch(); keystroke=keystroke | (keycode<<8); @@ -8575,9 +8639,11 @@ void showlfstats(lifeform_t *lf, int showall) { char actbuf[BUFLEN],movebuf[BUFLEN]; int h; char buf[BUFLEN],buf2[BUFLEN]; + char *descbuf = NULL; job_t *j; flag_t *f; - char *ftext= "%13s: "; + //char *ftext= "%13s: "; + char *ftext= "%11s: "; long xpneeded; object_t *o; object_t *w[2]; @@ -8623,14 +8689,27 @@ void showlfstats(lifeform_t *lf, int showall) { showall = B_TRUE; } - if (showall) { + if (isplayer(lf) || showall) { snprintf(promptstr, BUFLEN, "^h[^W@^n=stats ^WS^nkills ^WA^nbils ^WM^nagic ^WE^nffects %s%s^W?^n=help ^WESC^n=quit^h]", isplayer(lf) ? "^WG^nods " : "", isplayer(lf) ? "" : "^WI^ntems " ); snprintf(cmdchars, BUFLEN, "@asme%s%s",isplayer(lf) ? "g" : "", isplayer(lf) ? "" : "i"); } else { - snprintf(promptstr, BUFLEN, "^h[^W@^n=stats ^WE^nffects %s ^WESC^n=quit]", isplayer(lf) ? "" : "^WI^ntems "); - snprintf(cmdchars, BUFLEN, "@ie"); + snprintf(cmdchars, BUFLEN, "@e?"); + // can always see stats & effects + snprintf(promptstr, BUFLEN, "^h[^W@^n=stats ^WE^nffects "); + if (!isplayer(lf)) { + snprintf(buf, BUFLEN, "^WI^ntems "); + strcat(promptstr, buf); + strcat(cmdchars, "i"); + } + if ((lorelev >= PR_ADEPT) || (getskill(player, SK_LORE_ARCANA) >= PR_ADEPT)) { + snprintf(buf, BUFLEN, "^M^agic "); + strcat(promptstr, buf); + strcat(cmdchars, "m"); + } + snprintf(buf, BUFLEN, "^W?^n=help ^WESC^n=quit]"); + strcat(promptstr, buf); } while (!done) { @@ -8679,16 +8758,20 @@ void showlfstats(lifeform_t *lf, int showall) { // size - doheadingsmall(mainwin, y, 0, ftext, "Size"); - wprintw(mainwin, "%-20s", getsizetext(getlfsize(lf))); y++; - - if (showall) { float w; w = getlfweight(lf, B_NOOBS); - doheadingsmall(mainwin, y, 0, ftext, "Weight"); + doheadingsmall(mainwin, y, 0, ftext, "Size/Weight"); getweighttext(w, buf, B_FALSE); - wprintw(mainwin, buf, w); y++; + wprintw(mainwin, "%s (%s)", getsizetext(getlfsize(lf)), buf); y++; + } else { + doheadingsmall(mainwin, y, 0, ftext, "Size"); + wprintw(mainwin, "%-20s", getsizetext(getlfsize(lf))); y++; + } + + + if (showall) { + doheadingsmall(mainwin, y, 0, ftext, "Weight"); } @@ -8764,7 +8847,6 @@ void showlfstats(lifeform_t *lf, int showall) { y++; } } - y++; // skip line for (i = 0; i < MAXATTS; i++) { int val; @@ -8869,9 +8951,11 @@ void showlfstats(lifeform_t *lf, int showall) { // get first innate attack weapon. op = addobpile(NULL, NULL, NULL); f = hasflag(lf->flags, F_HASATTACK); - w[0] = addobfast(op, f->val[0]); - if (w[0]) { - nweps = 1; + if (f) { + w[0] = addobfast(op, f->val[0]); + if (w[0]) { + nweps = 1; + } } } @@ -8937,21 +9021,14 @@ void showlfstats(lifeform_t *lf, int showall) { } } // end for each weapon - if (op) { + if (op) { killobpile(op); + op = NULL; } // skip a line y2++; - /* - if (showall) { - mvwprintw(mainwin, y2, x2, ftext, "Attack Dmg"); - wprintw(mainwin, "%-20s", buf); y2++; - } - */ - - // unarmed attacks op = addobpile(NULL, NULL, NULL); for (f = lf->flags->first ; f ; f = f->next) { @@ -8992,7 +9069,6 @@ void showlfstats(lifeform_t *lf, int showall) { } // end if o } // end if fid == hasattack } // end for each flag - // no attacks at all? if ((nweps == 0) && !op->first) { @@ -9004,7 +9080,10 @@ void showlfstats(lifeform_t *lf, int showall) { // skip line y2++; - killobpile(op); + if (op) { + killobpile(op); + op = NULL; + } // ARMOUR STUFF if (showall || (lorelev >= PR_NOVICE)) { @@ -9015,13 +9094,6 @@ void showlfstats(lifeform_t *lf, int showall) { //max = pctof(75, arating); doheadingsmall(mainwin, y2, x2, ftext, "Armour Rating"); - /* - if (arating > 0) { - wprintw(mainwin, "%d (-%0.0f%% dmg)", arating, getdamreducepct(arating)); y2++; - } else { - wprintw(mainwin, "%d", arating); y2++; - } - */ if (lorelev >= PR_NOVICE) setcol(mainwin, lorecol); getarrange(arating, &min, &max); if (max <= 0) { @@ -9056,7 +9128,6 @@ void showlfstats(lifeform_t *lf, int showall) { y2++; // skip line - if (showall) { f = hasflag(lf->flags, F_HUNGER); if (f) { @@ -9090,13 +9161,6 @@ void showlfstats(lifeform_t *lf, int showall) { unsetcol(mainwin, col); wprintw(mainwin, "]"); y2++; - /* - if (showall) { - wprintw(mainwin, "%-14s (%d)", buf, f->val[0]); y++; - } else { - wprintw(mainwin, "%-14s", buf); y++; - } - */ } } @@ -9106,6 +9170,16 @@ void showlfstats(lifeform_t *lf, int showall) { y = y2 + 1; } + if (!isplayer(lf)) { + int dummy; + // description first. + descbuf = malloc(HUGEBUFLEN * sizeof(char)); + makedesc_race(lf->race->id, descbuf); + mvwprintw(mainwin, y, 0, "%s", descbuf); + free(descbuf); + + getyx(mainwin, y, dummy); + } // knowledge? if (lf != player) { char knowstring[BUFLEN]; @@ -9146,36 +9220,45 @@ void showlfstats(lifeform_t *lf, int showall) { } // extra info from lore? - if (lorelev >= PR_ADEPT) { + if (lorelev >= PR_SKILLED) { int hitstokillyou,hitstokillit; - hitstokillit = gethitstokill(player, lf); - hitstokillyou = gethitstokill(lf, player); - if (hitstokillit || hitstokillyou) { - if (hitstokillit == hitstokillyou) { + hitstokillit = gethitstokill(player, lf, B_TRUE, B_TRUE); + hitstokillyou = gethitstokill(lf, player, B_TRUE, B_TRUE); + if (hitstokillit == hitstokillyou) { + if (hitstokillit) { setcol(mainwin, lorecol); - mvwprintw(mainwin, y, 0, "You could both kill each other in %d hit%s.", hitstokillit, + wrapprint(mainwin, &y, &x, "You could both kill each other in %d hit%s.", hitstokillit, (hitstokillit == 1) ? "" : "s"); unsetcol(mainwin, lorecol); - y++; } else { - if (hitstokillit) { - setcol(mainwin, lorecol); - mvwprintw(mainwin, y, 0, "You could kill it in %d hit%s.", hitstokillit, - (hitstokillit == 1) ? "" : "s"); - unsetcol(mainwin, lorecol); - y++; - } - if (hitstokillyou) { - setcol(mainwin, lorecol); - mvwprintw(mainwin, y, 0, "It could kill you in %d hit%s.", hitstokillyou, - (hitstokillyou == 1) ? "" : "s"); - unsetcol(mainwin, lorecol); - y++; - } + setcol(mainwin, lorecol); + wrapprint(mainwin, &y, &x, "Neither of you would be able to kill the other."); + unsetcol(mainwin, lorecol); + } + } else { + if (hitstokillit) { + setcol(mainwin, lorecol); + wrapprint(mainwin, &y, &x, "You could kill it in %d hit%s.", hitstokillit, + (hitstokillit == 1) ? "" : "s"); + unsetcol(mainwin, lorecol); + } else { + setcol(mainwin, lorecol); + wrapprint(mainwin, &y, &x, "You would never be able to kill it."); + unsetcol(mainwin, lorecol); + } + if (hitstokillyou) { + setcol(mainwin, lorecol); + wrapprint(mainwin, &y, &x, "It could kill you in %d hit%s.", hitstokillyou, + (hitstokillyou == 1) ? "" : "s"); + unsetcol(mainwin, lorecol); + } else { + setcol(mainwin, lorecol); + wrapprint(mainwin, &y, &x, "It would never be able to kill you."); + unsetcol(mainwin, lorecol); } } } - if (lorelev >= PR_SKILLED) { + if (lorelev >= PR_ADEPT) { float rating; // get threat rating rating = comparelfs(player, lf); @@ -9191,14 +9274,14 @@ void showlfstats(lifeform_t *lf, int showall) { } else if (rating >= 0.5) { snprintf(buf, BUFLEN, "It would be challenging to defeat."); } else if (rating >= 0.25) { - snprintf(buf, BUFLEN, "It would present a formidable opponent."); + snprintf(buf, BUFLEN, "It would make a formidable opponent."); } else if (rating >= 0.125) { snprintf(buf, BUFLEN, "It is very dangerous to you."); } else { snprintf(buf, BUFLEN, "It is EXTREMELY dangerous to you."); } //mvwprintw(mainwin, y, 0, "Threat rating: %0.1f",comparelfs(player, lf)); - mvwprintw(mainwin, y, 0, "%s", buf); + wrapprint(mainwin, &y, &x, "%s", buf); unsetcol(mainwin, lorecol); y++; } @@ -9812,6 +9895,17 @@ void showlfstats(lifeform_t *lf, int showall) { y++; } + getflags(lf->flags, retflag, &nretflags, F_CANSEETHROUGHMAT, F_NONE); + for (i = 0; i < nretflags; i++) { + material_t *m; + f = retflag[i]; + m = findmaterial(f->val[0]); + if (m) { + mvwprintw(mainwin, y, 0, "%s can see through %s.", you(lf), m->name); + y++; + } + } + // material vulnerbilities getflags(lf->flags, retflag, &nretflags, F_MATVULN, F_NONE); for (i = 0; i < nretflags; i++) { @@ -10238,7 +10332,7 @@ void showlfstats(lifeform_t *lf, int showall) { } f = lfhasflag(lf, F_GRAVLESSENED); if (f && (f->known)) { - mvwprintw(mainwin, y, 0, "Gravity is lessened around %s.", you_l(lf)); + mvwprintw(mainwin, y, 0, "Gravity is lessened around %s, preventing fall damage and increasing flight speed.", you_l(lf)); y++; } f = lfhasknownflag(lf, F_DODGES); @@ -10248,7 +10342,7 @@ void showlfstats(lifeform_t *lf, int showall) { } f = lfhasknownflag(lf, F_INVULNERABLE); if (f && (f->known)) { - mvwprintw(mainwin, y, 0, "%s are protected from all physical harm.", you(lf)); + mvwprintw(mainwin, y, 0, "%s %s protected from all physical harm.", you(lf), is(lf)); y++; } f = lfhasflag(lf, F_MAGSHIELD); @@ -10455,6 +10549,8 @@ void showlfstats(lifeform_t *lf, int showall) { dohelp('g'); } else if (mode == 's') { // help on skills dohelp('s'); + } else if (mode == '@') { // help on current race + describerace(lf->race->id); } break; default: @@ -10630,7 +10726,7 @@ void wrapprint(WINDOW *win, int *y, int *x, char *format, ... ) { } wmove(win, *y, *x); textwithcol(win, buf); - (*x) += strlen(buf); + //(*x) += strlen(buf); getyx(win, *y, *x); } diff --git a/io.h b/io.h index 441d4ba..f79b0ed 100644 --- a/io.h +++ b/io.h @@ -23,7 +23,7 @@ object_t *askobject(obpile_t *op, char *title, int *count, long opts); object_t *askobjectwithflag(obpile_t *op, char *title, int *count, long opts, enum FLAG withflag); object_t *doaskobject(obpile_t *op, char *title, int *count, int forpickup, int showpoints, long opts, ...); int askobjectmulti(obpile_t *op, char *prompt, long opts); -char askchar(char *prompt, char *validchars, char *def, int showchars); +char askchar(char *prompt, char *validchars, char *def, int showchars, int maycancel); cell_t *askcoords(char *prompt, char *subprompt, int targettype, lifeform_t *srclf, int maxrange, enum LOFTYPE loftype, int wanttrail); char *askstring(char *prompt, char punc, char *retbuf, int retbuflen, char *def); vault_t *askvault(char *prompttext); @@ -38,7 +38,8 @@ void cls(void); int contains(enum OBCLASS *array, int nargs, enum OBCLASS want); void describegod(lifeform_t *god); void describeob(object_t *o); -void describeskill(enum SKILL skid); +void describerace(enum RACE rid); +void describeskill(enum SKILL skid, enum SKILLLEVEL levhilite); void describespell(objecttype_t *ot); void doattackcell(char dirch); void doclose(void); @@ -87,7 +88,7 @@ void dumpspells(void); enum COLOUR getattrcolour(enum ATTRBRACKET brack); char getchoice(prompt_t *prompt); char getchoicestr(prompt_t *prompt, int useshortcuts, int showlallatstart); -int getkey(void); +int getkey(int escseqok); enum COLOUR getskilllevelcolour(enum SKILLLEVEL slev); void handle_ctrl_y(int arg); void handleinput(void); @@ -95,11 +96,12 @@ void doheading(WINDOW *win, int *y, int x, char *what); void doheadingsmall(WINDOW *win, int y, int x, char *format, char *heading); void initgfx(void); void initprompt(prompt_t *p, char *q1); -int keycodetokey(int keycode); +int keycodetokey(int keycode, int escseqok); void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup, int showpoints); char *makedesc_god(lifeform_t *god, char *retbuf); char *makedesc_ob(object_t *o, char *retbuf); -char *makedesc_skill(enum SKILL skid, char *retbuf); +char *makedesc_race(enum RACE rid, char *retbuf); +char *makedesc_skill(enum SKILL skid, char *retbuf, enum SKILLLEVEL levhilite); char *makedesc_spell(objecttype_t *ot, char *retbuf); void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2, enum SPELLSCHOOL wantschool, int wantunknown, int wantlowmp, int wanttoohard,int mpcutoff); void more(void); diff --git a/lf.c b/lf.c index 7ac2c23..0cddd8e 100644 --- a/lf.c +++ b/lf.c @@ -26,6 +26,7 @@ extern FILE *logfile; extern void (*precalclos)(lifeform_t *); extern int noredraw; +extern int enteringmap; extern map_t *firstmap; extern race_t *firstrace, *lastrace; @@ -286,12 +287,11 @@ int calcxp(lifeform_t *lf) { if (db) dblog("calcxp: calculating xpval for %s",lf->race->name); - f = lfhasflag(lf, F_XPVAL); + f = lfhasflag(lf, F_XPMULTIPLY); if (f) { multiplier = f->val[0]; } - f = lfhasflag(lf, F_XPVAL); if (f) { if (db) dblog("calcxp: got F_XPVAL, forcing result to %d\n",f->val[0]); @@ -309,9 +309,7 @@ int calcxp(lifeform_t *lf) { // -- hitdice f = lfhasflag(lf, F_HITDICE); if (f) { - int ndice,nsides,bonus; - texttodice(f->text, &ndice,&nsides,&bonus); - maxhdroll = ndice * nsides + bonus; + maxhdroll = roll(f->text); } else { maxhdroll = 4; } @@ -442,9 +440,6 @@ int calcxp(lifeform_t *lf) { if (db) dblog("calcxp: F_XPMOD is %d",f->val[0]); } - - - if (multiplier > 1) { xpval *= multiplier; if (db) dblog("calcxp: mulitplier takes val to %0.1f",xpval); @@ -1216,7 +1211,7 @@ int cantakeoff(lifeform_t *lf, object_t *o) { return B_TRUE; } -int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell) { +int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell, object_t *fromob, int *seen) { int rv; int needtovalidate = B_FALSE; int targettype; @@ -1224,82 +1219,90 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar flag_t *f,*willflag; int power; objecttype_t *sp; - // check whether we _can_ cast it. - // do we have this spell/ability? - // enough mp? etc - if (!cancast(lf, sid, &cost)) { - if (isplayer(lf)) { - // announce - switch (reason) { - case E_TOOPOWERFUL: - msg("That spell is too powerful for you to cast."); - break; - case E_NOMP: - msg("You don't have enough mana to cast that."); - break; - case E_LOWIQ: - msg("You are not smart enough to cast spells."); - break; - case E_PRONE: - msg("You can't cast spells while prone."); - break; - case E_SWIMMING: - msg("You can't cast spells while swimming."); - break; - case E_STUNNED: - msg("You can't cast spells while stunned."); - break; - default: - msg("For some reason, you can't cast that."); - break; - } - } - return B_TRUE; - } - willflag = lfhasflagval(lf, F_CANWILL, sid, NA, NA, NULL); - - // special case - if (!willflag) { - f = lfhasflag(lf, F_NEEDOBFORSPELLS); - if (f && !hasob(lf->pack, f->val[0])) { - objecttype_t *ot; - ot = findot(f->val[0]); + if (fromob) { + power = getobspellpower(fromob, lf); + } else { + power = getspellpower(lf, sid); + // check whether we _can_ cast it. + // do we have this spell/ability? + // enough mp? etc + if (!cancast(lf, sid, &cost)) { if (isplayer(lf)) { - msg("You can't cast spells without %s %s.",needan(ot->name) ? "an" : "a", ot->name); + // announce + switch (reason) { + case E_TOOPOWERFUL: + msg("That spell is too powerful for you to cast."); + break; + case E_NOMP: + msg("You don't have enough mana to cast that."); + break; + case E_LOWIQ: + msg("You are not smart enough to cast spells."); + break; + case E_PRONE: + msg("You can't cast spells while prone."); + break; + case E_SWIMMING: + msg("You can't cast spells while swimming."); + break; + case E_STUNNED: + msg("You can't cast spells while stunned."); + break; + default: + msg("For some reason, you can't cast that."); + break; + } } return B_TRUE; } - } - power = getspellpower(lf, sid); + willflag = lfhasflagval(lf, F_CANWILL, sid, NA, NA, NULL); + + // special case + if (!willflag) { + f = lfhasflag(lf, F_NEEDOBFORSPELLS); + if (f && !hasob(lf->pack, f->val[0])) { + objecttype_t *ot; + ot = findot(f->val[0]); + if (isplayer(lf)) { + msg("You can't cast spells without %s %s.",needan(ot->name) ? "an" : "a", ot->name); + } + return B_TRUE; + } + } + + power = getspellpower(lf, sid); + } sp = findot(sid); - if (isplayer(lf) && (power > 1) && hasflag(sp->flags, F_VARPOWER)) { - if (!hasactivespell(lf, sp->id)) { - int max; - char buf[BUFLEN],desc[BUFLEN]; - int i; - char ch; - // ask what power - max = power; - snprintf(buf, BUFLEN, "Cast %s at what power level?", sp->name); - initprompt(&prompt, buf); - for (i = 1; i <= max; i++) { - snprintf(buf, BUFLEN, "Power %s (%d MP)", roman(i), getmpcost(lf, sid) * i); - getvarpowerspelldesc(sp->id, i, desc); - if (strlen(desc)) { - strcat(buf, "\t"); - strcat(buf, desc); + if (!fromob) { + if (isplayer(lf) && (power > 1) && hasflag(sp->flags, F_VARPOWER)) { + if (!hasactivespell(lf, sp->id)) { + int max; + char buf[BUFLEN],desc[BUFLEN]; + int i; + char ch; + // ask what power + max = power; + snprintf(buf, BUFLEN, "Cast %s at what power level?", sp->name); + initprompt(&prompt, buf); + for (i = 1; i <= max; i++) { + snprintf(buf, BUFLEN, "Power %s (%d MP)", roman(i), getmpcost(lf, sid) * i); + getvarpowerspelldesc(sp->id, i, desc); + if (strlen(desc)) { + strcat(buf, "\t"); + strcat(buf, desc); + } + addchoice(&prompt, '0' + i, buf, buf, NULL, NULL); } - addchoice(&prompt, '0' + i, buf, buf, NULL, NULL); - } - ch = getchoice(&prompt); - power = ch - '0'; + ch = getchoice(&prompt); + power = ch - '0'; - // modify cost - cost *= i; + // modify cost + cost *= i; + } } } @@ -1317,44 +1320,51 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar if (isplayer(lf)) msg("Cancelled."); return B_TRUE; } + + if (fromob && !targcell) { + return B_TRUE; + } } // stop hiding killflagsofid(lf->flags, F_HIDING); // take time taketime(lf, getspellspeed(lf)); - // lose mp - losemp(lf, cost); - // spell fails? - // miscast chance? - if (isplayer(lf) && !hasjob(lf, J_GOD)) { - if (pctchance(getmiscastchance(lf))) { - msg("^WYour cumbersome armour makes you miscast your spell!"); - return B_FALSE; + if (!fromob) { + // lose mp + losemp(lf, cost); + + // spell fails? + // miscast chance? + if (isplayer(lf) && !hasjob(lf, J_GOD)) { + if (pctchance(getmiscastchance(lf))) { + msg("^WYour cumbersome armour makes you miscast your spell!"); + return B_FALSE; + } + } + + // adjust power? + if (hasjob(lf, J_DRUID)) { + power += countplantsinsight(lf); + limit(&power, NA, 10); } - } + if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 20 + power, 0)) { + if (power > 1) { + // half strength + power /= 2; + if (power <= 1) power = 1; - // adjust power? - if (hasjob(lf, J_DRUID)) { - power += countplantsinsight(lf); - limit(&power, NA, 10); - } - if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 20 + power, 0)) { - if (power > 1) { - // half strength - power /= 2; - if (power <= 1) power = 1; - - if (isplayer(lf)) { - msg("^wYour magic resistance lowers your spell's power."); + if (isplayer(lf)) { + msg("^wYour magic resistance lowers your spell's power."); + } } } } // announce - if (!isplayer(lf)) { + if (!isplayer(lf) && !fromob) { if (cansee(player, lf)) { char lfname[BUFLEN]; char whattosay[BUFLEN]; @@ -1393,19 +1403,21 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar } } - // willing this spell? reset counter! - // do this _before_ casting the spell, - // in case the spell causes us to lose - // the f_canwill flag (eg. polymorph) - if (willflag) { - if (willflag->val[2] != NA) { - willflag->val[1] = -1; + if (!fromob) { + // willing this spell? reset counter! + // do this _before_ casting the spell, + // in case the spell causes us to lose + // the f_canwill flag (eg. polymorph) + if (willflag) { + if (willflag->val[2] != NA) { + willflag->val[1] = -1; + } } } // cast the spell f = hasflag(sp->flags, F_CASTINGTIME); - if (f) { + if (f && !fromob) { int castingtime; char tempbuf[BUFLEN]; char castingbuf[BUFLEN]; @@ -1444,7 +1456,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar } } else { // instant cast addflag(lf->flags, F_CASTINGSPELL, sid, NA, NA, NULL); - rv = dospelleffects(lf, sid, power, targlf, targob, targcell, B_UNCURSED, NULL, B_FALSE); + rv = dospelleffects(lf, sid, power, targlf, targob, targcell, B_UNCURSED, seen, B_FALSE); f = lfhasflag(lf, F_CASTINGSPELL); if (f) { killflag(f); @@ -1453,11 +1465,17 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar // successful cast? if (!rv) { - // TODO: charge mp - - practice(lf, SK_SPELLCASTING, 1); + enum SPELLSCHOOL school; + school = getspellschoolknown(lf, sid); + if (school != SS_NONE) { + enum SKILL skid; + skid = getschoolskill(school); + if (skid != SK_NONE) { + practice(lf, skid, 1); + } + } if (isplayer(lf)) { - switch (getschool(sid)) { + switch (school) { case SS_DEATH: pleasegodmaybe(R_GODDEATH, getspelllevel(sid)); angergodmaybe(R_GODPURITY, getspelllevel(sid)*5); @@ -1559,6 +1577,29 @@ int celltransparentfor(lifeform_t *lf, cell_t *c, int *xray, int *rangemod) { return B_TRUE; } +int checkburdened(lifeform_t *lf, int preburdened) { + int postburdened; + + postburdened = isburdened(lf); + if (postburdened != preburdened) { + if (postburdened) { + if (preburdened == BR_NONE) { + msg("^wThe weight of your possessions is burdening you!"); + statdirty = B_TRUE; + } else if (postburdened > preburdened) { + msg("^wThe weight of your possessions is burdening you even more!"); + } else { // ie. postburdened < preburdened + msg("^wThe weight of your possessions is burdening you a little less now."); + } + } else { // not burdened + msg("^wYour possessions are no longer weighing you down."); + statdirty = B_TRUE; + } + return B_TRUE; + } + return B_FALSE; +} + // returns TRUE if something happened. int checkfordrowning(lifeform_t *lf, object_t *o) { int depth,i; @@ -1681,30 +1722,22 @@ int check_rest_ok(lifeform_t *lf) { // < 0 = harder // > 0 = easier float comparelfs(lifeform_t *lf1, lifeform_t *lf2) { - float avgdam[2]; - lifeform_t *lf[2]; - float avgturnstokill[2]; - int i; + float turnstokill1, turnstokill2; float ratio; - lf[0] = lf1; - lf[1] = lf2; - for (i = 0; i < 2; i++) { - float otherevasion; - // get avg damage - avgdam[i] = getavgdam(lf[i], B_FALSE); - // mod this by other lf's evasion - otherevasion = ((float)getevasion(lf[1-i])); - avgdam[i] -= pctof(otherevasion, avgdam[i]); - // divide other lf's hit points by this lf's avg dam - if (avgdam[i] == 0) { - avgturnstokill[1-i] = 9999; - } else { - avgturnstokill[1-i] = (float)lf[1-i]->hp / avgdam[i]; - } - } + turnstokill1 = gethitstokill(lf1, lf2, B_TRUE, B_TRUE); // #turns for lf1 to kill lf2 + turnstokill2 = gethitstokill(lf2, lf1, B_TRUE, B_TRUE); // #turns for lf2 to kill lf1 - // compare avgturnstokill values - ratio = (avgturnstokill[0] / avgturnstokill[1]); + if (turnstokill1 == 0) { + // lf1 can never kill lf2 + ratio = -1; + } else if (turnstokill2 == 0) { + // lf2 can never kill lf1 + ratio = 5; + } else { + // compare avgturnstokill values + // if turns to kill lf2 is lower, ratio will be positive. + ratio = (turnstokill2 / turnstokill1); + } return ratio; } @@ -1924,7 +1957,7 @@ void die(lifeform_t *lf) { if (isplayer(lf) && hasjob(lf, J_GOD)) { char ch; msg("^BYou die..."); more(); - ch = askchar("Die", "yn", "n", B_TRUE); + ch = askchar("Die", "yn", "n", B_TRUE, B_FALSE); if (ch == 'n') { lf->hp = lf->maxhp; msg("Not dying."); @@ -1957,7 +1990,7 @@ void die(lifeform_t *lf) { if (lf->race->id == R_GLOWBUG) { // final spell... - castspell(lf, OT_S_FLASH, NULL, NULL, lf->cell); + castspell(lf, OT_S_FLASH, NULL, NULL, lf->cell, NULL, NULL); } // revert to your original form first. @@ -2857,6 +2890,8 @@ int eat(lifeform_t *lf, object_t *o) { killtransitoryflags(lf->flags, F_BLIND); addtempflag(lf->flags, F_SEEINDARK, 3, NA, NA, NULL, rnd(20,40)); } + + makeknown(o->type->id); } // end if fullyeaten // take time @@ -2886,7 +2921,7 @@ int eat(lifeform_t *lf, object_t *o) { if (isplayer(lf) && (posthlev != H_STUFFED)) { int ch; more(); - ch = askchar("Stop eating?","yn","y", B_TRUE); + ch = askchar("Stop eating?","yn","y", B_TRUE, B_FALSE); if (ch == 'y') { stopeating = B_TRUE; } @@ -2963,6 +2998,8 @@ void enhanceskills(lifeform_t *lf) { float hpratio,mpratio; enum SKILLLEVEL slev; int gainedxplev = B_FALSE; + flag_t *retflag[MAXCANDIDATES]; + int nretflags; if (lf->newlevel != lf->level) { lf->level = lf->newlevel; @@ -2987,7 +3024,7 @@ void enhanceskills(lifeform_t *lf) { } else { mpratio = ((float)lf->mp / (float)lf->maxmp); } - lf->maxmp += rollmpdice(lf); + lf->maxmp += rollmpdice(lf, B_FALSE); lf->mp = mpratio * (float)lf->maxmp; } @@ -3012,7 +3049,7 @@ void enhanceskills(lifeform_t *lf) { if (isplayer(lf)) { char ch; more(); - ch = askchar("Increase your Strength, Agility, Fitness, IQ or Wisdom?", "safiw",NULL, B_TRUE); + ch = askchar("Increase your Strength, Agility, Fitness, IQ or Wisdom?", "safiw",NULL, B_TRUE, B_FALSE); switch (ch) { case 's': att = A_STR; break; case 'a': att = A_AGI; break; @@ -3071,17 +3108,17 @@ void enhanceskills(lifeform_t *lf) { char buf[BUFLEN]; if (skillstoenhance) { snprintf(buf, BUFLEN, "(E)nhance skills, (L)earn skills, or (N)either (%d points left)?",lf->skillpoints); - eorl = askchar(buf,"eln","e", B_TRUE); + eorl = askchar(buf,"eln","e", B_TRUE, B_FALSE); } else { snprintf(buf, BUFLEN,"Learn a new skill (%d points left)?",lf->skillpoints); - ch = askchar(buf,"yn","y", B_TRUE); + ch = askchar(buf,"yn","y", B_TRUE, B_FALSE); if (ch == 'y') eorl = 'l'; else eorl = 'n'; } } else if (skillstoenhance) { char buf[BUFLEN]; snprintf(buf, BUFLEN,"Enhance your current skills (%d points left)?",lf->skillpoints); - ch = askchar(buf,"yn","y", B_TRUE); + ch = askchar(buf,"yn","y", B_TRUE, B_FALSE); if (ch == 'y') eorl = 'e'; else eorl = 'n'; } else { @@ -3094,15 +3131,17 @@ void enhanceskills(lifeform_t *lf) { // any skills to get? if (skillstoenhance) { char ques[BUFLEN],ques2[BUFLEN]; - int done = B_FALSE; + int done = B_FALSE,i; snprintf(ques, BUFLEN, "Enhance which skill (%d points left)?", lf->skillpoints); snprintf(ques2, BUFLEN, "Describe which skill?"); initprompt(&prompt, ques); addpromptq(&prompt, ques2); ch = 'a'; - for (f = lf->flags->first ; f ; f = f->next) { - if ((f->id == F_HASSKILL) && (f->val[1] != PR_MASTER)) { + getflags(lf->flags, retflag, &nretflags, F_HASSKILL, F_NONE); + for (i = 0;i < nretflags; i++) { + f = retflag[i]; + if (!ismaxedskill(lf, f->val[0])) { int cost; cost = getskilllevcost(f->val[1] + 1); if (lf->skillpoints >= cost) { @@ -3110,7 +3149,7 @@ void enhanceskills(lifeform_t *lf) { char buf2[HUGEBUFLEN]; snprintf(buf, BUFLEN, "%s -> %s (cost:%d points)", getskillname(f->val[0]), getskilllevelname(f->val[1] + 1), cost); - makedesc_skill(f->val[0], buf2); + makedesc_skill(f->val[0], buf2, f->val[1]+1); addchoice(&prompt, ch++, getskillname(f->val[0]), buf, f, buf2); } } @@ -3128,7 +3167,7 @@ void enhanceskills(lifeform_t *lf) { giveskill(lf, whichsk); done = B_TRUE; } else { // ie. describing a skill - describeskill(whichsk); + describeskill(whichsk, f->val[1]+1); } } else { done = B_TRUE; @@ -3158,7 +3197,7 @@ void enhanceskills(lifeform_t *lf) { char buf[BUFLEN]; char buf2[HUGEBUFLEN]; snprintf(buf, BUFLEN, "%-18s(%s)", getskillname(sk->id), getskilldesc(sk->id)); - makedesc_skill(sk->id, buf2); + makedesc_skill(sk->id, buf2, PR_NOVICE); addchoice(&prompt, ch++, getskillname(sk->id), buf, sk, buf2); } } @@ -3172,7 +3211,7 @@ void enhanceskills(lifeform_t *lf) { player->skillpoints -= newskillcost; done = B_TRUE; } else { - describeskill(sk->id); + describeskill(sk->id, PR_NOVICE); } } else { done = B_TRUE; @@ -3397,9 +3436,11 @@ int fall(lifeform_t *lf, lifeform_t *fromlf, int announce) { return B_TRUE; } } + if (lfhasflag(lf, F_GRAVLESSENED)) return B_TRUE; getlfname(lf,lfname); + if (announce) { if (isplayer(lf) || cansee(player, lf)) { if (fromlf) { @@ -3438,6 +3479,7 @@ int fallasleep(lifeform_t *lf, enum SLEEPTYPE how, int howlong) { loseconcentration(lf); interrupt(lf); + killtransitoryflags(lf->flags, F_FLYING); killflagsofid(lf->flags, F_RAGE); killflagsofid(lf->flags, F_TRAINING); @@ -3753,7 +3795,7 @@ int flee(lifeform_t *lf) { } } else { if (db) dblog("%s - casting %s to flee", sp->name); - if (!castspell(lf, spell, targlf, targob, targcell)) { + if (!castspell(lf, spell, targlf, targob, targcell, NULL, NULL)) { if (db) dblog("%s - success.", lfname); return B_TRUE; } @@ -4945,7 +4987,7 @@ object_t *getbestweapon(lifeform_t *lf) { if (ot) { o = addobfast(op, ot->id); - if (isweapon(o) && !isfirearm(o) && canweild(lf, o) && isbetterwepthan(o, bestwep)) { + if (isweapon(o) && !isfirearm(o) && canweild(lf, o) && isbetterwepthan(o, bestwep, lf)) { bestwep = o; // inherit damage from hasattack flag if (strlen(retflag[i]->text)) { @@ -4967,7 +5009,7 @@ object_t *getbestweapon(lifeform_t *lf) { for (o = lf->pack->first ; o ; o = o->next) { // if it does damage and we can weild it... if (isweapon(o) && !isfirearm(o) && canweild(lf, o)) { - if (isbetterwepthan(o, bestwep)) { + if (isbetterwepthan(o, bestwep, lf)) { bestwep = o; } } @@ -5182,7 +5224,7 @@ int gethitdicerace(race_t *r) { return 1; } -int gethitstokill(lifeform_t *lf, lifeform_t *victim) { +int gethitstokill(lifeform_t *lf, lifeform_t *victim, int useevasion, int usearmour) { object_t *wep[MAXCANDIDATES]; flag_t *damflag[MAXCANDIDATES]; obpile_t *op = NULL; @@ -5191,8 +5233,29 @@ int gethitstokill(lifeform_t *lf, lifeform_t *victim) { if (nweps) { int maxdam; getdamrange(damflag[0], NULL, &maxdam); - hitstokill = victim->hp / maxdam; - limit(&hitstokill, 1, NA); + + // modify by victim's evasion? + if (useevasion) { + float ev; + ev = ((float)getevasion(victim)); + maxdam -= pctof(ev, maxdam); + } + + // modify by victim's armour? + if (usearmour) { + int ar,aravg,amin,amax; + ar = getarmourrating(victim, NULL, NULL, NULL); + getarrange(ar, &amin, &amax); + aravg = (int)(((float)amin + (float)amax) / 2.0); + maxdam -= aravg; + } + + if (maxdam >= 1) { + hitstokill = victim->hp / maxdam; + limit(&hitstokill, 1, NA); + } else { + hitstokill = 0; // ie you'll never kill it. + } } if (op) killobpile(op); return hitstokill; @@ -5362,12 +5425,16 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) { } else if (f->id == F_ARMOURPENALTY) { acc -= adjustarmourpenalty(lf, f->val[0]); } else if (f->id == F_INJURY) { - if (f->val[0] == IJ_EYELIDSCRAPED) { - acc -= 20; - } else if (f->val[0] == IJ_FINGERBROKEN) { - acc -= 10; - } else if (f->val[0] == IJ_SHOULDERDISLOCATED) { - acc -= 20; + switch (f->val[0]) { + case IJ_FINGERBROKEN: + case IJ_TORSOBRUISED: + acc -= 10; break; + case IJ_EYELIDSCRAPED: + case IJ_TORSOBRUISEDBAD: + case IJ_SHOULDERDISLOCATED: + acc -= 20; break; + case IJ_RIBBROKEN: + acc -= 30; break; } } } @@ -5501,8 +5568,12 @@ enum SKILLLEVEL getmaxskilllevel(lifeform_t *lf, enum SKILL skid) { flag_t *f; enum SKILLLEVEL maxlev = PR_MASTER; f = lfhasflagval(lf, F_CANLEARN, skid, NA, NA, NULL); - if (f && (f->val[1] != NA)) { - maxlev = f->val[1]; + if (f) { + if (f->val[1] == NA) { + maxlev = PR_MASTER; + } else { + maxlev = f->val[1]; + } } return maxlev; } @@ -5799,9 +5870,11 @@ float getmaxcarryweight(lifeform_t *lf) { max = getlfweight(lf, B_NOOBS) * mod; - if (lfhasflagval(lf, F_INJURY, IJ_RIBCRACKED, NA, NA, NULL)) { + if (lfhasflagval(lf, F_INJURY, IJ_RIBBROKEN, NA, NA, NULL)) { max /= 2; - } + } else if (lfhasflagval(lf, F_INJURY, IJ_RIBCRACKED, NA, NA, NULL)) { + max /= 2; + } limitf(&max, 0, NA); return max; @@ -7267,10 +7340,9 @@ void givejob(lifeform_t *lf, enum JOB jobid) { if (rollmp) { f = hasflag(lf->flags, F_MPDICE); if (f) { - lf->maxmp = f->val[0] * 4; - if (f->val[1] != NA) lf->maxmp += f->val[1]; + lf->maxmp = rollmpdice(lf, B_TRUE); for (i = 0; i < lf->level-1; i++) { - lf->maxmp += rollmpdice(lf); + lf->maxmp += rollmpdice(lf, B_FALSE); } lf->mp = lf->maxmp; } @@ -7480,7 +7552,9 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) { newf->lifetime = FROMSKILL; } } else if (id == SK_COOKING) { - makeknown(OT_POT_WATER); + if (isplayer(lf)) { + makeknown(OT_POT_WATER); + } } else if (id == SK_LORE_ARCANA) { newf = hasflagval(lf->flags, F_CANWILL, OT_A_INSPECT, NA, NA, NULL); if (!newf) { @@ -7529,9 +7603,24 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) { newf->lifetime = FROMSKILL; } } else if (id == SK_COOKING) { - if (f->val[1] == PR_ADEPT) { + if (f->val[1] == PR_BEGINNER) { newf = addflag(lf->flags, F_CANWILL, OT_A_COOK, NA, NA, NULL); newf->lifetime = FROMSKILL; + } + if (f->val[1] == PR_ADEPT) { + if (isplayer(lf)) { + makeknown(OT_MUSHROOMSHI); + makeknown(OT_MUSHROOMTOAD); + } + } + + } else if (id == SK_LORE_ARCANA) { + if (f->val[1] == PR_ADEPT) { + newf = hasflagval(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL); + if (!newf) { + newf = addflag(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL); + newf->lifetime = FROMSKILL; + } } } else if (id == SK_PERCEPTION) { if ((f->val[1] == PR_ADEPT) || (f->val[1] == PR_MASTER)) { @@ -7544,14 +7633,6 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) { newf = addflag(lf->flags, F_CANWILL, OT_A_SHIELDBASH, NA, NA, NULL); newf->lifetime = FROMSKILL; } - } else if (id == SK_SPELLCASTING) { - if (f->val[1] == PR_SKILLED) { - newf = hasflagval(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL); - if (!newf) { - newf = addflag(lf->flags, F_CANWILL, OT_A_STUDYSCROLL, NA, NA, NULL); - newf->lifetime = FROMSKILL; - } - } } else if (id == SK_STEALTH) { if (f->val[1] == PR_BEGINNER) { newf = addflag(lf->flags, F_CANWILL, OT_A_HIDE, NA, NA, NULL); @@ -7994,13 +8075,26 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) { if (damtype == DT_BASH) { switch (where) { - case BP_BODY: inj = IJ_RIBCRACKED; desc = strdup("ribs are cracked^carrying capacity halved"); break; + case BP_BODY: + switch (rnd(1,5)) { + case 1: + inj = IJ_RIBCRACKED; desc = strdup("ribs are cracked^carrying capacity halved"); break; + case 2: + inj = IJ_RIBBROKEN; desc = strdup("ribs are broken^carrying capacity halved, -6 accuracy"); break; + case 3: + inj = IJ_TORSOBRUISED; desc = strdup("torso is bruised^-2 accuracy"); break; + case 4: + inj = IJ_TORSOBRUISEDBAD; desc = strdup("torso is badly bruised^-4 accuracy, -10% dam"); break; + case 5: + inj = IJ_WINDED; desc = strdup("stomach is winded^-1 Fitness"); howlong = rnd(3,5); break; + } + break; case BP_HANDS: switch (rnd(1,2)) { case 1: - inj = IJ_FINGERBROKEN; desc = strdup("finger is broken^-10% accuracy"); break; + inj = IJ_FINGERBROKEN; desc = strdup("finger is broken^-2 accuracy"); break; case 2: - inj = IJ_SHOULDERDISLOCATED; desc = strdup("shoulder is dislocated^-20% accuracy, cannot weild heavy weapons"); break; + inj = IJ_SHOULDERDISLOCATED; desc = strdup("shoulder is dislocated^-4 accuracy, cannot weild heavy weapons"); break; } break; case BP_HEAD: @@ -8129,13 +8223,15 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) { } else if (damtype == DT_EXPLOSIVE) { switch (where) { case BP_BODY: - switch (rnd(1,2)) { + switch (rnd(1,3)) { case 1: // collapsed lung inj = IJ_LUNGCOLLAPSED; desc = strdup("lungs have collapsed^lose all stamina points"); case 2: inj = IJ_RIBCRACKED; desc = strdup("ribs are cracked^carrying capacity halved"); break; break; + case 3: + inj = IJ_RIBBROKEN; desc = strdup("ribs are broken^carrying capacity halved, -6 accuracy"); break; } break; case BP_HANDS: @@ -8214,6 +8310,10 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) { wep = getweapon(lf); if (wep) drop(wep, wep->amt); break; + case IJ_WINDED: + lf->stamina = 0; + if (isplayer(lf)) statdirty = B_TRUE; + break; default: break; } @@ -9061,6 +9161,12 @@ int isloreskill(enum SKILL skid) { return B_FALSE; } +int ismadeofice(lifeform_t *lf) { + if (lf->material->id == MT_ICE) return B_TRUE; + if (lfhasflag(lf, F_FROZEN)) return B_TRUE; + return B_FALSE; +} + int ismaxedskill(lifeform_t *lf, enum SKILL skid) { if (getskill(lf, skid) >= getmaxskilllevel(lf, skid)) { return B_TRUE; @@ -9357,7 +9463,7 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) { -race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass) { +race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc) { race_t *a; assert(!findrace(id)); @@ -9385,6 +9491,7 @@ race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcol a->material = findmaterial(mat); assert(a->material); a->name = strdup(name); + a->desc = strdup(desc); a->weight = weight; a->glyph.ch = glyph; a->glyph.colour = glyphcolour; @@ -9578,7 +9685,7 @@ void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype) { return; } - if ((damtype == DT_BASH) && lfhasflag(lf, F_FROZEN)) { + if ((damtype == DT_BASH) && ismadeofice(lf)) { (*amt) *= 2; } @@ -9589,6 +9696,10 @@ void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype) { (*amt) = pctof(150, *amt); } + if ((damtype == DT_FALL) && lfhasflag(lf, F_GRAVLESSENED)) { + *amt = 0; + } + if (isresistantto(lf->flags, damtype)) { (*amt) /= 2; } @@ -9896,30 +10007,28 @@ void autoskill(lifeform_t *lf) { slev = PR_ADEPT; } - if (!hasjob(lf, J_WIZARD)) { - for (o = lf->pack->first ; o ; o = o->next) { - if (isweapon(o) && canweild(lf, o)) { - sk = getobskill(o); - if (sk && !getskill(lf, sk->id)) { - giveskilllev(lf, sk->id, slev); - } - nweps++; + for (o = lf->pack->first ; o ; o = o->next) { + if (isweapon(o) && canweild(lf, o)) { + sk = getobskill(o); + if (sk && !getskill(lf, sk->id)) { + giveskilllev(lf, sk->id, slev); } - if (isfirearm(o) && canweild(lf, o)) { - giveskilllev(lf, SK_RANGED, slev); - } - if (isarmour(o) && canwear(lf, o, BP_NONE)) { - flag_t *f; - // evasion penalty? - f = hasflag(o->flags, F_EVASION); - if (f && (f->val[0] < 0)) { - giveskilllev(lf, SK_ARMOUR, slev); - } - } - if (isshield(o) && canwear(lf, o, BP_NONE)) { - giveskilllev(lf, SK_SHIELDS, slev); + nweps++; + } + if (isfirearm(o) && canweild(lf, o)) { + giveskilllev(lf, SK_RANGED, slev); + } + if (isarmour(o) && canwear(lf, o, BP_NONE)) { + flag_t *f; + // evasion penalty? + f = hasflag(o->flags, F_EVASION); + if (f && (f->val[0] < 0)) { + giveskilllev(lf, SK_ARMOUR, slev); } } + if (isshield(o) && canwear(lf, o, BP_NONE)) { + giveskilllev(lf, SK_SHIELDS, slev); + } } // monsters must get unarmed skill! @@ -10394,9 +10503,9 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml // bashing damage sometimes ko's if (!ko) { if (damtype == DT_BASH) { - int hpleft; - hpleft = lf->hp - amt; - if ((hpleft >= -5) && (hpleft <= 0)) { + int hpleftafterdam; + hpleftafterdam = lf->hp - amt; + if ((lf->hp > 1) && (hpleftafterdam >= -5) && (hpleftafterdam <= 0)) { if (onein(2)) { ko = B_TRUE; amt = lf->hp - 1; // ie end up at 1hp @@ -10956,6 +11065,10 @@ void modhunger(lifeform_t *lf, int amt) { sumflags(lf->flags, F_SLOWMETAB, &tempmult, NULL, NULL); multiplier -= tempmult; + if (lfhasflagval(lf, F_ASLEEP, ST_MEDITATING, NA, NA, NULL)) { + multiplier -= 2; + } + if (multiplier > 0) { amt *= multiplier; } else if (multiplier < 0) { @@ -11311,7 +11424,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, // still asleep? f = lfhasflag(l, F_ASLEEP); - if (f && (f->val[1] != ST_KO) && cansee(player, l)) { + if (f && (f->val[1] == ST_ASLEEP) && cansee(player, l)) { char lfname[BUFLEN]; getlfname(l, lfname); msg("%s stir%s in %s slumber...", lfname, @@ -11451,7 +11564,7 @@ int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground, int want if (isplayer(lf) && !isburdened(lf) && willburden(lf, what, howmany)) { char ch,buf[BUFLEN]; snprintf(buf, BUFLEN, "Picking up %s will burden you. Continue", obname); - ch = askchar(buf, "yn","n", B_TRUE); + ch = askchar(buf, "yn","n", B_TRUE, B_FALSE); if (ch != 'y') { msg("Cancelled."); return B_TRUE; @@ -11824,6 +11937,7 @@ int push(lifeform_t *lf, object_t *o, int dir) { } touch(lf, o); + if (isplayer(lf)) addflag(lf->flags, F_MOVED, B_TRUE, NA, NA, NULL); return B_FALSE; @@ -11889,7 +12003,7 @@ int recruit(lifeform_t *lf) { } else { char ch; snprintf(buf, BUFLEN, "Pay $%d to hire %s", askingprice, lfname); - ch = askchar(buf, "yn","n", B_TRUE); + ch = askchar(buf, "yn","n", B_TRUE, B_FALSE); if (ch == 'y') { dohire = B_TRUE; } @@ -12781,11 +12895,13 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r char mbuf[BUFLEN]; flag_t *f; + /* if (lfhasflag(lf, F_DEBUG)) { //if (ct != SC_STEALTH) { // dont show debug info for stealth checks db = B_TRUE; //} } + */ switch (ct) { case SC_STR: @@ -12821,7 +12937,7 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r attrib = getskill(lf, SK_ATHLETICS); break; case SC_LEARNMAGIC: - attrib = (getattr(lf, A_IQ) / 2) + (getskill(lf, SK_SPELLCASTING)/2) + lf->level; + attrib = (getattr(lf, A_IQ) / 2) + lf->level; break; case SC_MORALE: // based on morale, level/hitdice and size. attrib = getmorale(lf) + gethitdice(lf); @@ -13401,7 +13517,7 @@ void startlfturn(lifeform_t *lf) { } if (f->val[2] >= 7) { char ch; - ch = askchar("Turn to face the threat", "yn","y", B_TRUE); + ch = askchar("Turn to face the threat", "yn","y", B_TRUE, B_FALSE); if (ch == 'y') { turntoface(lf, retcell[i]); } @@ -13603,19 +13719,24 @@ void startlfturn(lifeform_t *lf) { // secret doors, traps, etc? if (isplayer(lf) && !isinbattle(lf) && !isblind(lf) && !lfhasflag(lf, F_TRAINING)) { for (i = 0; i < lf->nlos; i++) { - if (!lf->los[i]->lf) { + if (!lf->los[i]->lf || (lf->los[i]->lf == lf)) { object_t *o; + int multiplier; + multiplier = getcelldist(lf->cell, lf->los[i]); + limit(&multiplier, 1, NA); for (o = lf->los[i]->obpile->first; o ; o = o->next) { flag_t *f; int mod = 0; - + // object which IS secret (ie a trap or secret door) f = hasflag(o->flags, F_SECRET); if (f && (f->val[0] != NA)) { + int diff; if (hasflag(o->flags, F_TRAP)) { mod += (getskill(lf, SK_TRAPS)*2); } + diff = f->val[0] * multiplier; - if (skillcheck(lf, SC_SEARCH, f->val[0], mod)) { + if (skillcheck(lf, SC_SEARCH, diff, mod)) { char obname[BUFLEN]; // reveal it getobname(o, obname, o->amt); @@ -13631,18 +13752,17 @@ void startlfturn(lifeform_t *lf) { } } } + // object which CONTAINS something secret (ie. trapped door/chest) f = hasflag(o->flags, F_TRAPPED); if (f && (f->val[2] != B_TRUE) && !hasflag(o->flags, F_SECRET)) { objecttype_t *ot; flag_t *trapflag; int diff; - // find trap type ot = findot(f->val[0]); trapflag = hasflag(ot->flags, F_TRAP); assert(trapflag); - diff = trapflag->val[0]; - + diff = trapflag->val[0] * multiplier; mod += getskill(lf, SK_TRAPS); if (skillcheck(lf, SC_SEARCH, diff, mod)) { char obname[BUFLEN]; @@ -14324,10 +14444,15 @@ void taketime(lifeform_t *lf, long howlong) { map = lf->cell->map; if (gamemode == GM_GAMESTARTED) { - if (map != player->cell->map) { + if (!enteringmap && (map != player->cell->map)) { // lfs not on the player's map don't take time. // this avoids the assertion below failing when // (for example) a monster falls through a pit. + // + // the exception is when we're simulating turns for + // monsters on the destination level when a player + // walks up/down stairs. in this case, "enteringmap" + // will be set. return; } if (db && cansee(player, lf)) { @@ -14674,7 +14799,6 @@ void unsummon(lifeform_t *lf, int vanishobs) { } int unweild(lifeform_t *lf, object_t *o) { - flag_t *f; char obname[BUFLEN]; char buf[BUFLEN]; @@ -14705,7 +14829,6 @@ int unweild(lifeform_t *lf, object_t *o) { } // remove the equipped flag - f = hasflag(o->flags, F_EQUIPPED); killflagsofid(o->flags, F_EQUIPPED); // unweilding doesn't take any time @@ -15391,7 +15514,7 @@ int rest(lifeform_t *lf, int onpurpose) { if (lf->mp < getmaxmp(lf)) { // pass a skill check to regain mp - if (skillcheck(lf, SC_IQ, difficulty, getskill(lf, SK_SPELLCASTING))) { + if (skillcheck(lf, SC_IQ, difficulty, (lf->level/2))) { gainmp(lf, mpheal); } } @@ -15618,7 +15741,7 @@ int wear(lifeform_t *lf, object_t *o) { // take offending item off first - this takes extra time. snprintf(buf2, BUFLEN, "Remove your %s",noprefix(buf)); while (!ch) { - ch = askchar(buf2, "yn?","y", B_TRUE); + ch = askchar(buf2, "yn?","y", B_TRUE, B_FALSE); if (ch == '?') { describeob(o); ch = '\0'; @@ -15865,7 +15988,7 @@ int weild(lifeform_t *lf, object_t *o) { if (isplayer(lf)) { char buf2[BUFLEN]; snprintf(buf2, BUFLEN, "Weild %s in your left hand?",buf); - ch = askchar(buf2, "yn","y", B_TRUE); + ch = askchar(buf2, "yn","y", B_TRUE, B_FALSE); } else { if (getweaponskill(lf, o)) ch = 'y'; else ch = 'n'; @@ -15903,7 +16026,7 @@ int weild(lifeform_t *lf, object_t *o) { // prompt before taking it off. snprintf(buf2, BUFLEN, "Remove your %s",noprefix(inwayname)); while (!ch) { - ch = askchar(buf2, "yn?","y", B_TRUE); + ch = askchar(buf2, "yn?","y", B_TRUE, B_FALSE); if (ch == '?') { describeob(o); ch = '\0'; @@ -15958,7 +16081,7 @@ int weild(lifeform_t *lf, object_t *o) { // prompt before taking it off. getobname(oo, inwayname, oo->amt); snprintf(buf2, BUFLEN, "Remove your %s",noprefix(inwayname)); - ch = askchar(buf2, "yn","y", B_TRUE); + ch = askchar(buf2, "yn","y", B_TRUE, B_FALSE); } } else { ch = 'y'; diff --git a/lf.h b/lf.h index 311b053..8ae0fef 100644 --- a/lf.h +++ b/lf.h @@ -3,7 +3,7 @@ lifeform_t *addlf(cell_t *cell, enum RACE rid, int level); lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller); job_t *addjob(enum JOB id, char *name, char *desc); -race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass); +race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass, char *desc); raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill); skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime); void addskilldesc(enum SKILL id, enum SKILLLEVEL lev, char *text, int wantmsg); @@ -46,9 +46,10 @@ int canuseweapons(lifeform_t *lf); int canwear(lifeform_t *lf, object_t *o, enum BODYPART where); int canweild(lifeform_t *lf, object_t *o); int cantakeoff(lifeform_t *lf, object_t *o); -int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell); +int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell, object_t *fromob, int *seen); int celllitfor(lifeform_t *lf, cell_t *c, int maxvisrange, int nightvisrange); int celltransparentfor(lifeform_t *lf, cell_t *c, int *xray, int *rangemod); +int checkburdened(lifeform_t *lf, int preburdened); int checkfordrowning(lifeform_t *lf, object_t *o); int check_rest_ok(lifeform_t *lf); //void checkxp(enum RACE rid); @@ -136,7 +137,7 @@ int gethearingrange(lifeform_t *lf); int gethidemodifier(lifeform_t *lf); int gethitdice(lifeform_t *lf); int gethitdicerace(race_t *r); -int gethitstokill(lifeform_t *lf, lifeform_t *victim); +int gethitstokill(lifeform_t *lf, lifeform_t *victim, int useevasion, int usearmour); int gethppct(lifeform_t *lf); enum COLOUR gethungercol(enum HUNGER hlev); enum HUNGER gethungerlevel(int hunger); @@ -273,6 +274,7 @@ flag_t *isimmuneto(flagpile_t *fp, enum DAMTYPE dt); int isinbattle(lifeform_t *lf); int isingunrange(lifeform_t *lf, cell_t *where); int isloreskill(enum SKILL skid); +int ismadeofice(lifeform_t *lf); int ismaxedskill(lifeform_t *lf, enum SKILL skid); int ispeaceful(lifeform_t *lf); int ispetof(lifeform_t *lf, lifeform_t *owner); diff --git a/map.c b/map.c index 37996e4..cb0ffc9 100644 --- a/map.c +++ b/map.c @@ -16,6 +16,8 @@ #include "text.h" #include "vault.h" +int enteringmap = B_FALSE; + extern habitat_t *firsthabitat,*lasthabitat; extern job_t *firstjob; extern map_t *firstmap,*lastmap; @@ -5226,12 +5228,16 @@ void mapentereffects(map_t *m) { // monsters on the new level now get a bunch of turns to simulate them moving about when the player wasn't there. if (m->lastplayervisit != -1) { int nturns; + + enteringmap = B_TRUE; + nturns = (curtime - m->lastplayervisit) / TICK_INTERVAL; limit(&nturns, NA, 20); //nturns *= countlfs(m); for (i = 0; i < nturns; i++) { donextturn(m); } + enteringmap = B_FALSE; } } diff --git a/move.c b/move.c index 26c846f..9769eb1 100644 --- a/move.c +++ b/move.c @@ -1008,19 +1008,6 @@ int movelf(lifeform_t *lf, cell_t *newcell) { } } - // remember current cell + room id - prespeed = getmovespeed(lf); - preroom = lf->cell->room; - v = getcellvault(lf->cell); - if (v && hasflag(v->flags, F_VAULTISSHOP)) { - preshop = getroomid(lf->cell); - } - - // getting out of water? - if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) { - prewater = B_TRUE; - } - // special effects when the player moves to a new map if (changedlev && isplayer(lf)) { object_t *o; @@ -1039,6 +1026,18 @@ int movelf(lifeform_t *lf, cell_t *newcell) { if (o) killob(o); } + // remember current cell + room id + prespeed = getmovespeed(lf); + preroom = lf->cell->room; + v = getcellvault(lf->cell); + if (v && hasflag(v->flags, F_VAULTISSHOP)) { + preshop = getroomid(lf->cell); + } + + // getting out of water? + if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) { + prewater = B_TRUE; + } // move out... lf->cell->lf = NULL; @@ -1203,7 +1202,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) { msg("%s crushes %s.",lfname, obname); didmsg = B_TRUE; } - // kill object + // kill object which is being crushed. removeob(o, o->amt); continue; } @@ -1373,6 +1372,12 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) { int didmsg; int predark = B_FALSE,postdark = B_FALSE; + // for the player, moving means that we don't regenerate stamina. + // this is the equivilant of losing the same amount of stamina which we + // would regenerate, only it avoids constantly redrawing the status + // bar every single move. + if (isplayer(lf)) addflag(lf->flags, F_MOVED, B_TRUE, NA, NA, NULL); + if (!onpurpose || !isplayer(lf)) { dontclearmsg = B_TRUE; } @@ -1609,7 +1614,7 @@ int opendoor(lifeform_t *lf, object_t *o) { if (getattrbracket(getattr(lf, A_WIS), A_WIS, NULL) >= AT_AVERAGE) { char ch; snprintf(buf, BUFLEN,"Really open %s?", obname); - ch = askchar(buf,"yn","n", B_TRUE); + ch = askchar(buf,"yn","n", B_TRUE, B_FALSE); if (ch != 'y') { msg("Cancelled."); return B_TRUE; @@ -1625,7 +1630,7 @@ int opendoor(lifeform_t *lf, object_t *o) { char ch; snprintf(buf, BUFLEN,"%s running water behind %s. Really open it?", haslos(lf, pastdoorcell) ? "There is" : "You can hear", obname); - ch = askchar(buf,"yn","n", B_TRUE); + ch = askchar(buf,"yn","n", B_TRUE, B_FALSE); if (ch != 'y') { msg("Cancelled."); return B_TRUE; @@ -1847,7 +1852,7 @@ int trysneak(lifeform_t *lf, int dir) { char ques[BUFLEN]; char ch; snprintf(ques, BUFLEN, "Carefully %s in which direction (- to cancel)", getmoveverb(lf)); - ch = askchar(ques, "yuhjklbn.-","-", B_FALSE); + ch = askchar(ques, "yuhjklbn.-","-", B_FALSE, B_TRUE); dir = chartodir(ch); if (dir == D_NONE) return B_TRUE; } else { @@ -1952,7 +1957,12 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int *didmsg) { if (!attacking) { if (lfhasflag(lf, F_GRAVBOOSTED)) { // make a saving throw to move - if (!skillcheck(lf, SC_STR, 25, 0)) { + if (skillcheck(lf, SC_STR, 25, 0)) { + if (isplayer(lf)) { + msg("You manage to %s despite the strong gravity.", isprone(lf) ? "stand" : "move"); + if (didmsg) *didmsg = B_TRUE; + } + } else { if (isplayer(lf)) { msg("You try to %s but are unable to %s!", isprone(lf) ? "stand" : "move", @@ -2173,9 +2183,10 @@ void swapplaces(lifeform_t *lf1, lifeform_t *lf2, int changedir, int onpurpose) setfacing(lf1, tempfacing); } - // remember that we just swapped + // remember that we just swapped, and this counts as a move if (!isplayer(lf1)) { addflag(lf1->flags, F_NOSWAP, B_TRUE, NA, NA, NULL); + if (isplayer(lf1)) addflag(lf1->flags, F_MOVED, B_TRUE, NA, NA, NULL); } } @@ -2330,7 +2341,7 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) { } else { snprintf(ques, BUFLEN, "Really %s there?", getmoveverb(lf)); } - ch = askchar(ques, "yn","n", B_TRUE); + ch = askchar(ques, "yn","n", B_TRUE, B_FALSE); if (ch != 'y') { return B_TRUE; } @@ -2355,13 +2366,6 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) { return B_TRUE; } - // for the player, moving means that we don't regenerate stamina. - // this is the equivilant of losing the same amount of stamina which we - // would regenerate, only it avoids constantly redrawing the status - // bar every single move. - if (isplayer(lf)) { - addflag(lf->flags, F_MOVED, B_TRUE, NA, NA, NULL); - } reason = E_OK; @@ -2528,7 +2532,10 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) { if (isplayer(lf)) { if (cell->known) { // try to open it - opendoor(lf, inway); + if (!opendoor(lf, inway)) { + // opening a door counts as a successful move. + reason = E_OK; + } } else { msg("Ouch! You %s into a door.", getmoveverb(lf)); setcellknown(cell, B_FALSE); diff --git a/nexus.c b/nexus.c index b2e891d..37187f6 100644 --- a/nexus.c +++ b/nexus.c @@ -60,6 +60,8 @@ glyph_t playerglyph,tempglyph; double startticks,lastticks; struct timeval starttv, tv,newtv; +extern int enteringmap; + // maintains unique lifeform ID numbers long nextlfid = 0; @@ -201,7 +203,7 @@ int main(int argc, char **argv) { ch = 'a'; for (r = firstrace ; r ; r = r->next) { if (hasflag(r->flags, F_PLAYABLE)) { - addchoice(&prompt, ch++, r->name, NULL, r, NULL); + addchoice(&prompt, ch++, r->name, NULL, r, r->desc); } } startrace = NULL; @@ -285,12 +287,14 @@ int main(int argc, char **argv) { addchoice(&prompt, 'a', getskillname(SK_SS_AIR), NULL, findskill(SK_SS_AIR), NULL); addchoice(&prompt, 'c', getskillname(SK_SS_COLD), NULL, findskill(SK_SS_COLD), NULL); addchoice(&prompt, 'f', getskillname(SK_SS_FIRE), NULL, findskill(SK_SS_FIRE), NULL); + addchoice(&prompt, 'w', getskillname(SK_SS_WILD), NULL, findskill(SK_SS_WILD), NULL); getchoice(&prompt); sk = (skill_t *) prompt.result; giveskilllev(player, sk->id, PR_BEGINNER); switch (sk->id) { case SK_SS_AIR: addflag(player->flags, F_CANCAST, OT_S_MIST, NA, NA, NULL); + addflag(player->flags, F_CANSEETHROUGHMAT, MT_GAS, NA, NA, NULL); break; case SK_SS_COLD: addflag(player->flags, F_CANCAST, OT_S_CHILL, NA, NA, NULL); @@ -298,11 +302,15 @@ int main(int argc, char **argv) { case SK_SS_FIRE: addflag(player->flags, F_CANCAST, OT_S_SPARK, NA, NA, NULL); break; + case SK_SS_WILD: + addflag(player->flags, F_CANCAST, OT_S_MANASPIKE, NA, NA, NULL); + break; default: break; } initprompt(&prompt, "Select your secondary spell school:"); addchoice(&prompt, 'd', getskillname(SK_SS_DIVINATION), NULL, findskill(SK_SS_DIVINATION), NULL); + addchoice(&prompt, 'g', getskillname(SK_SS_GRAVITY), NULL, findskill(SK_SS_GRAVITY), NULL); addchoice(&prompt, 'm', getskillname(SK_SS_MODIFICATION), NULL, findskill(SK_SS_MODIFICATION), NULL); addchoice(&prompt, 's', getskillname(SK_SS_SUMMONING), NULL, findskill(SK_SS_SUMMONING), NULL); addchoice(&prompt, 't', getskillname(SK_SS_TRANSLOCATION), NULL, findskill(SK_SS_TRANSLOCATION), NULL); @@ -313,6 +321,9 @@ int main(int argc, char **argv) { case SK_SS_DIVINATION: addflag(player->flags, F_CANCAST, OT_S_SIXTHSENSE, NA, NA, NULL); break; + case SK_SS_GRAVITY: + addflag(player->flags, F_CANCAST, OT_S_TRUESTRIKE, NA, NA, NULL); + break; case SK_SS_MODIFICATION: addflag(player->flags, F_CANCAST, OT_S_HOLDPORTAL, NA, NA, NULL); break; @@ -377,8 +388,11 @@ int main(int argc, char **argv) { // start game - this will cause debug messages to now // go to the log file instead of stdout. + timeleft = 0; // reset game timer + enteringmap = B_FALSE; // no time passes for lfs on a different map to the player. + // calculate initial light calclight(player->cell->map); // pre-calc line-of-sight for player @@ -1215,16 +1229,18 @@ int rollhitdice(lifeform_t *lf) { // modify for fitness/con myroll = pctof(mod, myroll); - limit(&myroll, 1, NA); if (db) dblog(" -> modified to: %d",myroll); + + limit(&myroll, 1, NA); return myroll; } -int rollmpdice(lifeform_t *lf) { +int rollmpdice(lifeform_t *lf, int wantmax) { flag_t *f; - int ndice, plus; - int roll; + int ndice, plus,roll,i; float mod; + flag_t *retflag[MAXCANDIDATES]; + int nretflags; f = hasflag(lf->flags, F_MPDICE); if (f) { @@ -1234,11 +1250,23 @@ int rollmpdice(lifeform_t *lf) { } else { return 0; } - mod = 100 + getstatmod(lf, A_IQ) + (getskill(lf, SK_SPELLCASTING)/2); - roll = rolldie(ndice, 4) + plus; + mod = 100 + getstatmod(lf, A_IQ); + if (wantmax) { + roll = (ndice * 4) + plus; + } else { + roll = rolldie(ndice, 4) + plus; + } roll = pctof(mod, roll); + + // modify via racial flags + getflags(lf->flags, retflag, &nretflags, F_MPMOD, F_NONE); + for (i = 0; i < nretflags; i++) { + roll += retflag[i]->val[0]; + } + + limit(&roll, 0, NA); return roll; } diff --git a/nexus.h b/nexus.h index 0b2763c..3e13d2c 100644 --- a/nexus.h +++ b/nexus.h @@ -28,7 +28,7 @@ int rnd(int min, int max); int roll(char *string); int rolldie(int ndice, int sides); int rollhitdice(lifeform_t *lf); -int rollmpdice(lifeform_t *lf); +int rollmpdice(lifeform_t *lf, int wantmax); //void sortlf(map_t *map); void timeeffectsworld(map_t *map, int updategametime); void usage(char *progname); diff --git a/objects.c b/objects.c index 67f0611..8c805fd 100644 --- a/objects.c +++ b/objects.c @@ -1555,15 +1555,30 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes } } - // apply cost to shop items if (o->pile->where) { vault_t *v; v = getcellvault(o->pile->where); + // apply cost to shop items if (v && hasflag(v->flags, F_VAULTISSHOP)) { if (canpickup(NULL, o, 1)) { addflag(o->flags, F_SHOPITEM, getobvalue(o), getroomid(o->pile->where), NA, NULL); } } + // blood will stain things on the ground + if (o->material->id == MT_BLOOD) { + object_t *poss[MAXPILEOBS],*oo; + int nposs = 0; + // bloodstain one piece of armour + for (oo = o->pile->first ; oo ; oo = oo->next) { + if ((oo != o) && isarmour(oo)) { + poss[nposs++] = oo; + } + } + if (nposs) { + oo = poss[rnd(0,nposs-1)]; + applyobmod(oo, findobmod(OM_BLOODSTAINED)); + } + } } @@ -1774,6 +1789,20 @@ void adjustdammaterial(unsigned int *dam, enum DAMTYPE damtype, enum MATERIAL ma *dam = 0; return; } + } else if (mat == MT_DRAGONWOOD) { + switch (damtype) { + case DT_FIRE: + case DT_MELT: + case DT_DECAY: + case DT_COLD: + case DT_ELECTRIC: + case DT_HOLY: + case DT_WATER: + *dam = 0; + return; + default: + break; + } } // adjust based on damage type @@ -1991,6 +2020,10 @@ void appendinscription(object_t *o, char *text) { void applyobmod(object_t *o, obmod_t *om) { flag_t *f; + if (hasobmod(o, om)) { + return; + } + if ((om->id == OM_MASTERWORK) || (om->id == OM_SHODDY)) { if (hasflag(o->flags, F_NOQUALITY)) { return; @@ -2516,6 +2549,91 @@ void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype) { } } +// returns TRUE if something happened +int doobdieconvert(object_t *o, int wantannounce) { + flag_t *f; + f = hasflag(o->flags, F_DIECONVERT); + if (f) { + flag_t *f2; + object_t *newob; + char desc[BUFLEN]; + if (wantannounce && !hasflag(o->flags, F_NODIECONVERTTEXT)) { + char obname[BUFLEN]; + // announce the change + real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE); + + strcpy(desc, ""); + + f2 = NULL; + if (o->amt > 1) { + f2 = hasflag(o->flags, F_DIECONVERTTEXTPL); + } + if (!f2) { + f2 = hasflag(o->flags, F_DIECONVERTTEXT); + } + if (f2) { + snprintf(desc, BUFLEN, "%s", f2->text); + } else if (oblastdamtype(o) == DT_DECAY) { + // don't announce devay death while traning + if (!lfhasflag(player, F_TRAINING)) { + snprintf(desc, BUFLEN, "%s completed rotted away", (o->amt == 1) ? "has" : "have"); + } + } else { + snprintf(desc, BUFLEN, "%s destroyed", (o->amt == 1) ? "is" : "are"); + } + if (strstr(o->type->name, "stain") || (o->type->id == OT_ROASTMEAT)) { + assert(0 == 1); + } + + if (strlen(desc)) { + if (o->pile->owner) { + if (isplayer(o->pile->owner)) { + msg("Your %s %s!",noprefix(obname), desc); + } else if (cansee(player, o->pile->owner)) { + // don't announce decay death unless we are holding it + if (oblastdamtype(o) != DT_DECAY) { + char monname[BUFLEN]; + getlfname(o->pile->owner, monname); + msg("%s's %s %s!",monname, noprefix(obname), desc); + } + } + } else if (haslos(player, o->pile->where)) { + // don't announce decay death unless we are holding it + if (oblastdamtype(o) != DT_DECAY) { + capitalise(obname); + msg("%s %s.",obname, desc); + } + } + } // end if desc != "" + } + + // change into something else + newob = addob(o->pile, f->text); + // only set amt if text wasn't "x-y somethings" + if (newob && !strchr(f->text, '-')) { + newob->amt = o->amt; + } + if (f->val[0] > 0) { + cell_t *centre; + centre = getoblocation(o); + if (centre) { + cell_t *cell[MAXCANDIDATES]; + int ncells,i; + getradiuscells(centre, f->val[0], DT_COMPASS, B_FALSE, LOF_WALLSTOP, B_FALSE, cell, &ncells, B_FALSE); + for (i = 0; i < ncells; i++) { + newob = addob(cell[i]->obpile, f->text); + if (newob && !strchr(f->text, '-')) { + newob->amt = o->amt; + } + } + } + } + return B_TRUE; + } + return B_FALSE; +} + + int doobtraps(object_t *o, lifeform_t *lf) { flag_t *f; f = hasflag(o->flags, F_TRAPPED); @@ -3705,6 +3823,7 @@ int getmaterialvalue(enum MATERIAL mat) { case MT_SILVER: return 6; case MT_GOLD: + case MT_DRAGONWOOD: return 7; } // default @@ -5523,7 +5642,7 @@ int isbetterarmourthan(object_t *a, object_t *b) { } // compare weapons using max damage -int isbetterwepthan(object_t *a, object_t *b) { +int isbetterwepthan(object_t *a, object_t *b, lifeform_t *owner) { //flag_t *f; int dama,damb; float acca,accb; @@ -5559,15 +5678,15 @@ int isbetterwepthan(object_t *a, object_t *b) { } // modify with accuracy - acca = getobaccuracy(a, a->pile->owner); - accb = getobaccuracy(b, b->pile->owner); + acca = getobaccuracy(a, owner); + accb = getobaccuracy(b, owner); if (db) { msg("PREACC:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb); } - dama = (int)((float)dama * (acca/100)); - damb = (int)((float)damb * (accb/100)); + dama = pctof(acca, dama); + damb = pctof(accb, damb); if (db) { msg("POST:a=%s:%d(acc %d), b=%s:%d(acc %d)",namea,dama,(int)acca, nameb, damb,(int)accb); @@ -5836,8 +5955,11 @@ int ismagical(object_t *o) { if (hasflag(o->flags, F_ENCHANTABLE) && hasflag(o->flags, F_BONUS)) { return B_TRUE; } - if (o->type->id == OT_SHILLELAGH) { - return B_TRUE; + switch (o->type->id) { + case OT_SHILLELAGH: + case OT_WIZARDSTAFF: + return B_TRUE; + default: break; } return B_FALSE; @@ -6605,13 +6727,7 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) { // did this make us burdened? if (isplayer(dst->owner)) { - if (isburdened(dst->owner) != preburdened) { - if (preburdened == BR_NONE) { - msg("^wThe weight of your possessions is burdening you!"); - } else { - msg("^wThe weight of your possessions is burdening you even more!"); - } - } + checkburdened(dst->owner, preburdened); } // in case you picked up money, something which changes your AR, etc @@ -6708,70 +6824,8 @@ void obdie(object_t *o) { char obname[BUFLEN]; flag_t *f; - f = hasflag(o->flags, F_DIECONVERT); - if (f) { - flag_t *f2; - object_t *newob; - char desc[BUFLEN]; - if (!hasflag(o->flags, F_NODIECONVERTTEXT)) { - // announce the change - real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE); - - strcpy(desc, ""); - - f2 = NULL; - if (o->amt > 1) { - f2 = hasflag(o->flags, F_DIECONVERTTEXTPL); - } - if (!f2) { - f2 = hasflag(o->flags, F_DIECONVERTTEXT); - } - if (f2) { - snprintf(desc, BUFLEN, "%s", f2->text); - } else if (oblastdamtype(o) == DT_DECAY) { - // don't announce devay death while traning - if (!lfhasflag(player, F_TRAINING)) { - snprintf(desc, BUFLEN, "%s completed rotted away", (o->amt == 1) ? "has" : "have"); - } - } else { - snprintf(desc, BUFLEN, "%s destroyed", (o->amt == 1) ? "is" : "are"); - } - if (strstr(o->type->name, "stain") || (o->type->id == OT_ROASTMEAT)) { - assert(0 == 1); - } - - - if (strlen(desc)) { - if (o->pile->owner) { - if (isplayer(o->pile->owner)) { - msg("Your %s %s!",noprefix(obname), desc); - } else if (cansee(player, o->pile->owner)) { - // don't announce decay death unless we are holding it - if (oblastdamtype(o) != DT_DECAY) { - char monname[BUFLEN]; - getlfname(o->pile->owner, monname); - msg("%s's %s %s!",monname, noprefix(obname), desc); - } - } - } else if (haslos(player, o->pile->where)) { - // don't announce decay death unless we are holding it - if (oblastdamtype(o) != DT_DECAY) { - capitalise(obname); - msg("%s %s.",obname, desc); - } - } - } // end if desc != "" - } - - // change into something else - newob = addob(o->pile, f->text); - if (newob) { - // only set amt if text wasn't "x-y somethings" - if (!strchr(f->text, '-')) { - newob->amt = o->amt; - } - } - } else { + // handle object conversion + if (!doobdieconvert(o, B_TRUE)) { char desc[BUFLEN]; real_getobname(o, obname, o->amt, B_TRUE, B_FALSE, B_TRUE, B_TRUE, B_FALSE); @@ -7129,7 +7183,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { if (getattrbracket(getattr(lf, A_WIS), A_WIS, NULL) >= AT_AVERAGE) { char ch; snprintf(buf, BUFLEN,"Really operate %s?", obname); - ch = askchar(buf,"yn","n", B_TRUE); + ch = askchar(buf,"yn","n", B_TRUE, B_FALSE); if (ch != 'y') { msg("Cancelled."); return B_TRUE; @@ -7216,8 +7270,8 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { char ch; int dir; // ask direction - ch = askchar(f->text, "yuhjklbn-","-", B_FALSE); - if (ch == '-') { + ch = askchar(f->text, "yuhjklbn-","-", B_FALSE, B_TRUE); + if ((ch == '-') || !ch) { msg("Cancelled."); return B_TRUE; } else { @@ -7551,7 +7605,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { object_t *newob; getobname(oo, liquidname, 1); snprintf(ques, BUFLEN, "Fill your %s from %s?", noprefix(obname), liquidname); - ch = askchar(ques, "yn", "y", B_TRUE); + ch = askchar(ques, "yn", "y", B_TRUE, B_FALSE); if (ch == 'y') { char newobname[BUFLEN]; if (oo->type->id == OT_FOUNTAIN) { @@ -7702,7 +7756,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { char ch; int dir; // ask direction - ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE); + ch = askchar("Lockpick in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE); dir = chartodir(ch); if (dir == D_NONE) { clearmsg(); @@ -7729,7 +7783,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { char ch; int dir; // ask direction - ch = askchar("Manipulate lock in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE); + ch = askchar("Manipulate lock in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE); dir = chartodir(ch); if (dir == D_NONE) { clearmsg(); @@ -7783,8 +7837,8 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { } else if (o->type->id == OT_PICKAXE) { int ch,dir; cell_t *c; - ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn><-","-", B_FALSE); - if (ch == '-') { + ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn><-","-", B_FALSE, B_TRUE); + if ((ch == '-') || !ch) { // cancel clearmsg(); return B_TRUE; @@ -7821,7 +7875,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { if (!isopen) { // ie. if closed. f = hasflag(o->flags, F_JAMMED); if (f) { - ch = askchar("The hinges seem jammed. Loosen them", "yn", "y", B_TRUE); + ch = askchar("The hinges seem jammed. Loosen them", "yn", "y", B_TRUE, B_FALSE); if (ch == 'y') { char obname[BUFLEN]; getobname(o, obname, 1); @@ -7834,7 +7888,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { char obname[BUFLEN]; getobname(o, obname, 1); snprintf(buf, BUFLEN, "Tighten the hinges on %s",obname); - ch = askchar(buf, "yn", "y", B_TRUE); + 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(1,10), NA, NA, NULL); @@ -7987,7 +8041,7 @@ int pour(lifeform_t *lf, object_t *o) { door = hasobwithflag(c->obpile, F_DOOR); if (door) { snprintf(buf, BUFLEN, "Pour %s onto the door to the %s", obname, getdirname(d)); - ch = askchar(buf, "yn", "n", B_TRUE); + ch = askchar(buf, "yn", "n", B_TRUE, B_FALSE); if (ch == 'y') { // finished asking where to pour doneask = B_TRUE; @@ -8002,7 +8056,7 @@ int pour(lifeform_t *lf, object_t *o) { if (!doneask) { // tip onto what? snprintf(buf, BUFLEN, "Pour %s onto the ground", obname); - ch = askchar(buf, "yn", "y", B_TRUE); + ch = askchar(buf, "yn", "y", B_TRUE, B_FALSE); if (ch == 'y') { dst = NULL; } else { @@ -8160,17 +8214,13 @@ int pour(lifeform_t *lf, object_t *o) { takedamage(dst, 0, DT_WATER); } } else { - flag_t *f; // pour onto ground if (isplayer(lf)) { msg("You pour %s onto the ground.", obname); } else if (haslos(player, lf->cell)) { msg("%s pours %s onto the ground.", lfname, obname); } - f = hasflag(o->flags, F_DIECONVERT); - if (f) { - addob(lf->cell->obpile, f->text); - } else { + if (!doobdieconvert(o, B_FALSE)) { if (haslos(player, lf->cell)) { msg("The contents evaporate."); } @@ -8936,9 +8986,7 @@ int readsomething(lifeform_t *lf, object_t *o) { f = hasflag(o->flags, F_LINKSPELL); if (f) { int seen = B_FALSE; - int power; - - power = getobspellpower(o, lf); + int noeffect = B_FALSE; // for unidentified scrolls which target an object, // let player select ANY object (even if it won't @@ -8948,12 +8996,21 @@ int readsomething(lifeform_t *lf, object_t *o) { f2 = addflag(o->flags, F_BEINGUSED, B_TRUE, NA, NA, NULL); targob = askobject(lf->pack, "Target which object", NULL, AO_NONE); killflag(f2); + if (!targob) { + noeffect = B_TRUE; + } } - - dospelleffects(lf, f->val[0], power, NULL, targob, NULL, o->blessed, &seen, B_FALSE); - if (seen) { - // id the scroll now - makeknown(o->type->id); o->blessknown = B_TRUE; + + if (!noeffect) { + castspell(lf, f->val[0], NULL, targob, NULL, o, &seen); + + /* + dospelleffects(lf, f->val[0], power, NULL, targob, NULL, o->blessed, &seen, B_FALSE); + */ + if (seen) { + // id the scroll now + makeknown(o->type->id); o->blessknown = B_TRUE; + } } // removeob one of the object @@ -9325,18 +9382,31 @@ void removedeadobs(obpile_t *op) { // returns the amount left int removeob(object_t *o,int howmany) { + int preburdened = B_FALSE; + int rv = 0; + lifeform_t *owner; + + owner = o->pile->owner; + if (owner) { + preburdened = isburdened(o->pile->owner); + } + if (howmany == ALL) { howmany = o->amt; } if (howmany >= o->amt) { killob(o); - return 0; + rv = 0; } else { o->amt -= howmany; + rv = o->amt; } - return o->amt; + // did this make us burdened? + if (owner && isplayer(owner)) checkburdened(owner, preburdened); + + return rv; } void rrtorarity(enum RARITY r, int *minr, int *maxr) { diff --git a/objects.h b/objects.h index cf0c886..03ce164 100644 --- a/objects.h +++ b/objects.h @@ -43,6 +43,7 @@ int countobsoftype(obpile_t *op, enum OBTYPE oid); int countnoncosmeticobs(obpile_t *op, int onlyifknown); int curseob(object_t *o); void damageallobs(object_t *srcob, obpile_t *op, int howmuch, int damtype); +int doobdieconvert(object_t *o, int wantannounce); int doobtraps(object_t *o, lifeform_t *lf); void dumpobrarity(void); void explodeob(object_t *o, flag_t *f, int bigness); @@ -151,7 +152,7 @@ int isammofor(objecttype_t *ammo, object_t *gun); int isbadfood(object_t *o); int isunknownbadobject(object_t *o); int isbetterarmourthan(object_t *a, object_t *b); -int isbetterwepthan(object_t *a, object_t *b); +int isbetterwepthan(object_t *a, object_t *b, lifeform_t *owner); int isblessed(object_t *o); int isblessknown(object_t *o); int iscorpse(object_t *o); diff --git a/spell.c b/spell.c index 3e6c15d..18eefd1 100644 --- a/spell.c +++ b/spell.c @@ -330,8 +330,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // ask for direction if (!targcell) { int dirch; - dirch = askchar("Disarm trap in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); - if (dirch == '-') { + dirch = askchar("Disarm trap in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); + if ((dirch == '-') || !dirch) { if (isplayer(user)) msg("Cancelled."); return B_TRUE ; } @@ -482,7 +482,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // ask for direction if (!targcell) { char dirch; - dirch = askchar("Flip from which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + dirch = askchar("Flip from which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); if (dirch == '.') { if (isplayer(user)) msg("You can't flip yourself!"); return B_TRUE; @@ -580,7 +580,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef if (targcell) { dir = getdirtowards(user->cell, targcell, NULL, B_FALSE, DT_ORTH); } else { - dirch = askchar("Flurry in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE); + dirch = askchar("Flurry in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE); dir = chartodir(dirch); if (dir == D_NONE) { if (isplayer(user)) msg("Cancelled."); @@ -629,7 +629,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // ask for direction if (!targcell) { - dirch = askchar("Grab in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + dirch = askchar("Grab in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); if (dirch == '.') { if (isplayer(user)) msg("You can't grab yourself!"); return B_TRUE; @@ -1055,7 +1055,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // ask for direction if (!targcell) { - dirch = askchar("Shield bash in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + dirch = askchar("Shield bash in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); if (dirch == '.') { // yourself! targcell = user->cell; @@ -1147,7 +1147,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef if (isplayer(user)) { int dir,dirch; - dirch = askchar("Sprint in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + dirch = askchar("Sprint in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); if (dirch == '.') { msg("Cancelled."); return B_TRUE; @@ -1419,7 +1419,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef dir = getdirtowards(user->cell, targcell, NULL, B_FALSE, DT_ORTH); } else { char dirch; - dirch = askchar("Tumble in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + dirch = askchar("Tumble in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); dir = chartodir(dirch); if (dir == D_NONE) { if (isplayer(user)) msg("Cancelled."); @@ -1613,9 +1613,13 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef ch = 'a'; for (sk = firstskill ; sk ; sk = sk->next) { char buf2[HUGEBUFLEN]; - snprintf(buf, BUFLEN, "%s (%s)",getskillname(sk->id), getskilldesc(sk->id)); - makedesc_skill(sk->id, buf2); - addchoice(&prompt, ch++, getskillname(sk->id), buf, sk, buf2); + enum SKILLLEVEL curlev; + curlev = getskill(user, sk->id); + if (curlev != PR_MASTER) { + snprintf(buf, BUFLEN, "%s (%s)",getskillname(sk->id), getskilldesc(sk->id)); + makedesc_skill(sk->id, buf2, curlev+1); + addchoice(&prompt, ch++, getskillname(sk->id), buf, sk, buf2); + } } getchoicestr(&prompt, B_FALSE, B_TRUE); sk = (skill_t *)prompt.result; @@ -1680,7 +1684,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // ask for direction if (!targcell) { - dirch = askchar("Aimed strike in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + dirch = askchar("Aimed strike in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); if (dirch == '.') { // yourself! targcell = user->cell; @@ -1752,7 +1756,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef while (!c) { char ques[BUFLEN]; snprintf(ques, BUFLEN,"%s combination in which direction (- to cancel)", nhits ? "Continue" : "Start"); - dirch = askchar("%s combination in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE); + dirch = askchar(ques, "yuhjklbn-","-", B_FALSE, B_TRUE); if (dirch == '-') { break; } else { @@ -1827,7 +1831,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef if (where && where->lf) { char ch; enum ATTRIB att; - ch = askchar("Enhance which stat (n for none)?", "sacin",NULL, B_TRUE); + ch = askchar("Enhance which stat (n for none)?", "sacin",NULL, B_TRUE, B_FALSE); switch (ch) { case 's': att = A_STR; break; case 'a': att = A_AGI; break; @@ -1879,7 +1883,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // ask for direction if (!targcell) { - dirch = askchar("Heavy blow in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + dirch = askchar("Heavy blow in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); if (dirch == '.') { // yourself! targcell = user->cell; @@ -1924,7 +1928,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // ask for direction if (!targcell) { - dirch = askchar("Quivering Palm in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + dirch = askchar("Quivering Palm in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); if (dirch == '.') { // yourself! targcell = user->cell; @@ -1968,7 +1972,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef if (isroom(user->cell) && hasobwithflagval(user->cell->obpile, F_SHOPITEM, NA, getroomid(user->cell), NA, NULL)) { // stealing from a shop char yn; - yn = askchar("Steal something from this shop?", "yn","n", B_TRUE); + yn = askchar("Steal something from this shop?", "yn","n", B_TRUE, B_FALSE); if (yn == 'y') { object_t *o; flag_t *f; @@ -2017,7 +2021,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // ask for direction if (!targcell) { int dir; - dirch = askchar("Steal in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE); + dirch = askchar("Steal in which direction (- to cancel)", "yuhjklbn-","-", B_FALSE, B_TRUE); dir = chartodir(dirch); if (dir == D_NONE) { if (isplayer(user)) msg("Cancelled."); @@ -2481,7 +2485,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ dir = getdirtowards(caster->cell, targcell, target, B_FALSE, DT_COMPASS); } else { int dirch; - dirch = askchar("Airblast in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + dirch = askchar("Airblast in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); if ((dirch == '.') || (dirch == '-')) { fizzle(caster); return B_TRUE; @@ -2700,25 +2704,21 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f->obfrom = spellid; } else if (spellid == OT_S_BLADEBURN) { object_t *wep; - enum DAMTYPE dt; + if (!targcell) { + targcell = caster->cell; + } target = targcell->lf; if (!target) { fizzle(caster); return B_FALSE; } - // does caster have a bladed weapon? + // does caster have a weapon? wep = getweapon(target); if (!wep) { fizzle(caster); return B_FALSE; } - dt = getdamtype(wep); - if ((dt != DT_PIERCE) && (dt != DT_SLASH) && (dt != DT_CHOP)) { - fizzle(caster); - return B_FALSE; - } - if (isplayer(target)) { if (seenbyplayer) *seenbyplayer = B_TRUE; } else if (cansee(player, target)) { @@ -3169,10 +3169,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } radius = (power/4)+1; - addobburst(targcell, radius, DT_COMPASS, "cloud of poison gas", caster, LOF_WALLSTOP); + addobburst(targcell, radius, DT_COMPASS, "puff of poison gas", caster, LOF_WALLSTOP); if (haslos(player, targcell)) { - msg("A cloud of poison gas appears!"); + msg("A puff of poison gas appears!"); if (seenbyplayer) *seenbyplayer = B_TRUE; } } else if (spellid == OT_S_CHARM) { @@ -3534,7 +3534,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ msg("BAM! A vault has appeared nearby."); more(); needredraw = B_TRUE; - ch = askchar("Teleport to the new vault", "yn","y", B_TRUE); + ch = askchar("Teleport to the new vault", "yn","y", B_TRUE, B_FALSE); if (ch == 'y') { int x,y; // find it @@ -3740,8 +3740,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else { // don't need line of fire OR sight! //if (!validatespellcell(caster, &targcell, TT_NONE, spellid, power, frompot)) return B_TRUE; - ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn.-<>","-", B_FALSE); - if ((ch == '.') || (ch == '-')) { + ch = askchar("Dig in which direction (- to cancel)", "yuhjklbn.-<>","-", B_FALSE, B_TRUE); + if ((ch == '.') || (ch == '-') || !ch) { fizzle(caster); return B_TRUE; } else if (ch == '<') { @@ -4689,7 +4689,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ (o->pile->owner == caster) ? noprefix(obname) : obname, (o->amt == 1) ? "s" : ""); more(); - ch = askchar("Abort your spell?", "yn","y", B_TRUE); + ch = askchar("Abort your spell?", "yn","y", B_TRUE, B_FALSE); if (ch == 'y') { msg("You release your spell into the air."); return B_FALSE; @@ -5666,7 +5666,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ char ch; snprintf(buf, BUFLEN, "You may be stuck in %s%s body - proceed?", targname, getpossessive(targname)); - ch = askchar(buf, "yn", "n", B_TRUE); + ch = askchar(buf, "yn", "n", B_TRUE, B_FALSE); if (ch != 'y') { cancel = B_TRUE; } @@ -7636,11 +7636,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ return B_FALSE; } else if (!c->known) { // confirm - ch = askchar("Are you sure to want to teleport into the unknown?", "yn", "n", B_TRUE); + ch = askchar("Are you sure to want to teleport into the unknown?", "yn", "n", B_TRUE, B_FALSE); if (ch != 'y') c = NULL; } else if (c->type->solid) { // confirm - ch = askchar("Are you sure to want to teleport into solid rock?", "yn", "n", B_TRUE); + ch = askchar("Are you sure to want to teleport into solid rock?", "yn", "n", B_TRUE, B_FALSE); if (ch != 'y') c = NULL; } } @@ -7654,8 +7654,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int xmax,ymax; // semicontrolled // ask for dir - dirch = askchar("Teleport in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); - if ((dirch == '.') || (dirch == '-')) { + dirch = askchar("Teleport in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE, B_TRUE); + if ((dirch == '.') || (dirch == '-') || !dirch) { fizzle(caster); return B_TRUE; } else { @@ -7891,12 +7891,17 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f = addtempflag(target->flags, F_RETALIATE, 1, 4, DT_PIERCE, "sharp thorns", FROMSPELL); f->obfrom = spellid; } else if (spellid == OT_S_TRUESTRIKE) { + flag_t *f; + if (!targcell) targcell = caster->cell; target = targcell->lf; if (!target) { fizzle(caster); return B_FALSE; } - addflag(caster->flags, F_TRUESTRIKE, power, NA, NA, NULL); + f = addtempflag(caster->flags, F_TRUESTRIKE, power, NA, NA, NULL, FROMSPELL); + f->obfrom = spellid; + f = addtempflag(caster->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL, FROMSPELL); + f->obfrom = spellid; } else if (spellid == OT_S_TURNUNDEAD) { int i; lifeform_t *lf; @@ -8023,6 +8028,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (o) { if (canweild(target, o)) { flag_t *f; + object_t *oldwep; + // unweild current weapon + + oldwep = getweapon(target); + if (oldwep) { + if (iscursed(oldwep)) setblessed(oldwep, B_UNCURSED); + unweild(target, oldwep); + } // announce if (isplayer(target)) { msg("A blade of pure energy forms in your hands!"); @@ -8231,7 +8244,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else { dam = roll("1d6"); } - takedamage(o, dam, DT_DIRECT); + takedamage(o, dam, DT_DECAY); if (haslos(player, targcell)) { if (seenbyplayer) *seenbyplayer = B_TRUE; } @@ -8506,7 +8519,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ enum SPELLSCHOOL school; skill_t *poss2[MAXSKILLS],*sk; int nposs2 = 0; - giveskill(target, SK_SPELLCASTING); for (school = SS_AIR; school < SS_LAST; school++) { sk = findskill(getschoolskill(school)); poss2[nposs2++] = sk; @@ -8635,6 +8647,7 @@ objecttype_t *findspelln(char *buf) { } void fizzle(lifeform_t *caster) { + if (!caster) return; if (isplayer(caster)) { if (lfhasflag(caster, F_CASTINGSPELL)) { msg("Your spell fizzles."); @@ -8905,10 +8918,9 @@ char *getspellname(enum OBTYPE spellid, lifeform_t *lf, char *buf) { int getspellpower(lifeform_t *lf, enum OBTYPE spellid) { int power = 0; int spelllev; - enum SKILLLEVEL spellcastskill,schoolskill; + enum SKILLLEVEL schoolskill; enum SPELLSCHOOL school; int db = B_FALSE; - int usesorcery = B_FALSE; flag_t *f; if (db) { @@ -8937,7 +8949,6 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) { // get spell details school = getspellschoolknown(lf, spellid); schoolskill = getskill(lf, getschoolskill(school)); - spellcastskill = getskill(lf, SK_SPELLCASTING); spelllev = getspelllevel(spellid); // for most spell schools, your skill in the school determines which @@ -8948,9 +8959,7 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) { int maxspelllevel = MAXSPELLLEV; if (hasjob(lf, J_DRUID) && (school == SS_NATURE)) { } else if ((school == SS_ALLOMANCY) || (school == SS_MENTAL)) { - // dont need spellcasting skill for mental/allomancy } else { - usesorcery = B_TRUE; switch (schoolskill) { case PR_INEPT: maxspelllevel = 0; break; case PR_NOVICE: maxspelllevel = 1; break; @@ -8975,23 +8984,9 @@ int getspellpower(lifeform_t *lf, enum OBTYPE spellid) { // HOW POWERFUL IS THIS SPELL? //////////////////////////////////// if (isplayer(lf)) { - if (hasjob(lf, J_DRUID) && (school == SS_NATURE)) { - // always okay - usesorcery = B_FALSE; - } else if ((school == SS_ALLOMANCY) || (school == SS_MENTAL)) { - // dont need spellcasting skill for mental/allomancy - usesorcery = B_FALSE; - } else { - usesorcery = B_TRUE; - } - power = 1; // base power of 1. - // plus either your hitdice/3 OR your sorcery skill - if (usesorcery) { - power += spellcastskill; - } else { - power += (gethitdice(lf)/3); - } + // plus your hitdice/3 + power += (gethitdice(lf)/3); // plus intelligence modifier if (school == SS_MENTAL) { @@ -9581,7 +9576,7 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e if (isplayer(caster) && !frompot) { // warn! int ch; - ch = askchar("Your have no clear line of fire - really target here?","yn","n", B_TRUE); + ch = askchar("Your have no clear line of fire - really target here?","yn","n", B_TRUE, B_FALSE); if (ch == 'y') { where = newwhere; } else { @@ -9619,7 +9614,7 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e getlfname(where->lf, lfname); snprintf(ques, BUFLEN, "Really target %s", lfname); } - ch = askchar(ques,"yn","n", B_TRUE); + ch = askchar(ques,"yn","n", B_TRUE, B_FALSE); if (ch != 'y') { where = NULL; } @@ -9649,7 +9644,7 @@ cell_t *validatespellcell(lifeform_t *caster, cell_t **targcell, int targtype, e char ques[BUFLEN]; int ch; snprintf(ques, BUFLEN, "Abandon your %s?", (sp->obclass->id == OC_SPELL) ? "spell" : "ability"); - ch = askchar(ques,"yn","n", B_TRUE); + ch = askchar(ques,"yn","n", B_TRUE, B_FALSE); if (ch == 'y') { return NULL; } diff --git a/text.c b/text.c index 52a100c..78f075c 100644 --- a/text.c +++ b/text.c @@ -158,11 +158,15 @@ char *getaccuracyname(int accpct) { if (accpct >= 200) { return "incredible"; } else if (accpct >= 150) { - return "very good"; + return "excellent"; + } else if (accpct >= 120) { + return "great"; } else if (accpct >= 100) { return "good"; - } else if (accpct >= 70) { + } else if (accpct >= 80) { return "average"; + } else if (accpct >= 70) { + return "mediocre"; } else if (accpct >= 50) { return "poor"; } else if (accpct >= 30) { @@ -174,6 +178,10 @@ char *getaccuracyname(int accpct) { } } +int getaccuracymodnum(int accpctmod) { + return accpctmod / 5; +} + int getaccuracynum(int accpct) { int num; num = (accpct - 100) / 5; // @@ -211,7 +219,7 @@ char *getattrname(enum ATTRIB att) { case A_AGI: return "agility"; case A_IQ: - return "intelligence"; + return "intellect"; case A_STR: return "strength"; case A_WIS: diff --git a/text.h b/text.h index 47f09d7..cdbc31b 100644 --- a/text.h +++ b/text.h @@ -7,6 +7,7 @@ enum COLOUR chartocol(char ch); char *dicetotext(int ndice, int nsides, int bonus, int *min, int *max, char *dicebuf, char *minmaxbuf); int flip(int ch); char *getaccuracyname(int accpct); +int getaccuracymodnum(int accmodpct); int getaccuracynum(int accpct); char *getattrabbrev(enum ATTRIB att); char *getattrname(enum ATTRIB att);