diff --git a/ai.c b/ai.c index 1646c30..4a7eed7 100644 --- a/ai.c +++ b/ai.c @@ -1452,9 +1452,11 @@ int ai_handle_emergencies(lifeform_t *lf, enum ATTRBRACKET iqb) { // flying monsters not flying? if (!isprone(lf)) { if (hasflag(lf->race->flags, F_NATURALFLIGHT) && !lfhasflag(lf, F_FLYING)) { - if (cancast(lf, OT_S_FLIGHT, NULL)) { - if (!castspell(lf, OT_S_FLIGHT, lf, NULL, lf->cell, NULL, NULL)) { - return B_TRUE; + if (cancast(lf, OT_A_FLY, NULL) && !isburdened(lf)) { + if (getstaminapct(lf) >= 80) { + if (!useability(lf, OT_A_FLY, lf, lf->cell)) { + return B_TRUE; + } } } } @@ -1464,6 +1466,14 @@ int ai_handle_emergencies(lifeform_t *lf, enum ATTRBRACKET iqb) { return B_TRUE; } } + + // flying and out of stamina? + if (isflyingwithwings(lf) && isexhausted(lf)) { + // stop flying. + if (!useability(lf, OT_A_FLY, lf, lf->cell)) { + return B_TRUE; + } + } return B_FALSE; } @@ -3099,7 +3109,7 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG if (lfhasflag(lf, F_SPRINTING) || !getstamina(lf) || (getstamina(lf) <= (getmaxstamina(lf)/2))) { specificcheckok = B_FALSE; } - if (isairborne(lf)) { + if (isairborne(lf, NULL)) { specificcheckok = B_FALSE; } } @@ -3148,13 +3158,13 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG } if (ot->id == OT_A_TRIPLF) { - if (isairborne(victim)) { + if (isairborne(victim, NULL)) { specificcheckok = B_FALSE; } } if ((ot->id == OT_A_TUMBLE) || (ot->id == OT_A_JUMP)) { - if (lfhasflag(lf, F_GRABBING) || lfhasflag(lf, F_GRABBEDBY) || isairborne(lf)) { + if (lfhasflag(lf, F_GRABBING) || lfhasflag(lf, F_GRABBEDBY) || isairborne(lf, NULL)) { specificcheckok = B_FALSE; } } diff --git a/attack.c b/attack.c index 2f7d187..b564cdb 100644 --- a/attack.c +++ b/attack.c @@ -33,10 +33,10 @@ int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damty int damtaken = 0; // first of all, only apply some of the damage - dam /= 2; - if (dam == 0) { - return 0; - } + //dam /= 2; + //if (dam == 0) { +// return 0; +// } // special case - missiles always hit flak jacket if (damtype == DT_PROJECTILE) { @@ -193,6 +193,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { int attackedfriend = B_FALSE; int attackedpeaceful = B_FALSE; enum SKILLLEVEL slev; + int dostamloss = B_TRUE; // warn if attacking will cause injury if (!force && isplayer(lf) && haslos(lf, c)) { @@ -256,7 +257,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { } attackedpeaceful = B_TRUE; // non-evil players get no xp for attacking peaceful lfs - if ((isplayer(lf) || areallies(player, lf)) && (getalignment(lf) != AL_EVIL)) { + if ((isplayer(lf) || areallies(player, lf)) && (getalignment(player) != AL_EVIL)) { killflagsofid(c->lf->flags, F_XPVAL); addflag(c->lf->flags, F_XPVAL, 0, NA, NA, NULL); real_warnabout(TEXT_WARN_NOXP_GOODVSPEACEFUL, PERMENANT, B_FALSE); @@ -812,13 +813,21 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { } } - //if (isplayer(lf)) { + dostamloss = B_TRUE; // default + slev = getskill(lf, SK_COMBAT); - if (slev != PR_MASTER) { - if (!pctchance(slev * 10)) { - // lose a bit of stamina - modstamina(lf, -getattackstamloss(lf)); - } + if (slev == PR_MASTER) { + dostamloss = B_FALSE; + } else if (lfhasflagval(lf, F_LASTATTACKHIT, B_FALSE, NA, NA, NULL) && + (getskill(lf, SK_ATHLETICS) >= PR_BEGINNER)) { + // missed, and we have balance via athletics skill + dostamloss = B_FALSE; + } else if (pctchance(slev * 10)) { + dostamloss = B_FALSE; + } + if (dostamloss) { + // lose a bit of stamina + modstamina(lf, -getattackstamloss(lf)); } //} @@ -1222,6 +1231,11 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) if (ndam > 0) { flag_t *f; + // hit! + + killflagsofid(lf->flags, F_LASTATTACKHIT); + addflag(lf->flags, F_LASTATTACKHIT, B_TRUE, NA, NA, NULL); + for (i = 0; i < ndam; i++) { int damreducedbyarmour = 0; int backstab = B_FALSE; @@ -1285,8 +1299,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) // damaged during the call to criticalhit() later on. if ((dam[i] > 0) && !backstab && !critical && ismeleedam(damtype[i])) { // modify for defender's armour + // first figure out how much to reduce the damage by. damreducedbyarmour = getarmourdamreduction(victim, wep, dam[i], damtype[i]); - + // now actually reduce the damage amount applyarmourdamreduction(victim, wep, damreducedbyarmour, &dam[i], damtype[i]); } @@ -1590,21 +1605,19 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) { wepeffects(wep->flags, victim->cell, damflag, dam[0], isunarmed); } - if (isunarmed) { - f = lfhasflag(lf, F_FREEZINGTOUCH); - if (f) { - int diff; - diff = f->val[2]*20; - if (isimmuneto(victim->flags, DT_COLD, B_FALSE) || skillcheck(victim, SC_RESISTMAG, diff, 0)) { - if (isplayer(victim)) { - msg("You feel mildly chilly."); - } - } else { - // victim turns to ice for a while! - freezelf(victim, lf, f->val[1]); - } - killflag(f); + f = lfhasflag(lf, F_FREEZINGTOUCH); + if (f) { + int diff; + diff = f->val[2]*20; + if (isimmuneto(victim->flags, DT_COLD, B_FALSE) || skillcheck(victim, SC_RESISTMAG, diff, 0)) { + if (isplayer(victim)) { + msg("You feel mildly chilly."); + } + } else { + // victim turns to ice for a while! + freezelf(victim, lf, f->val[1]); } + killflag(f); } // critical hit effects @@ -1696,6 +1709,8 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) } } else { // miss! if (aidb) dblog(".oO { i missed! }"); + killflagsofid(lf->flags, F_LASTATTACKHIT); + addflag(lf->flags, F_LASTATTACKHIT, B_FALSE, NA, NA, NULL); // announce it if (weppassthrough) { if (cansee(player, lf)) { @@ -1995,13 +2010,14 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) { // still not dead? more checks if (!isdeadob(o)) { + object_t *oo; f = hasflag(o->flags, F_TRAPPED); if (f && pctchance(75)) { doobtraps(o, lf); } else { // if a trap didn't go off, you might break the lock f = hasflag(o->flags, F_LOCKED); - if (f && (damtype[i] == DT_BASH)) { + if (f && (damtype[0] == DT_BASH)) { int difficulty; int unlockit = B_FALSE; difficulty = f->val[1]; @@ -2021,7 +2037,18 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) { } } } - + + // objects inside might smash + for (oo = o->contents->first ;oo ; oo = oo->next) { + if (willshatter(oo->material->id) && onein(2)) { + if (isplayer(lf)) { + // since the sound won't work. + msg("You hear shattering glass from inside %s.", obname); + } + // damstring should never be used... + shatter(oo, B_FALSE, "shattering damage", lf); + } + } } return B_FALSE; } @@ -3025,6 +3052,7 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical, } else { int myroll; int reachpenalty = 0; + int vicheight = 0; // actually roll... baseacc = getlfaccuracy(lf, wep); acc = baseacc; @@ -3079,7 +3107,14 @@ int rolltohit(lifeform_t *lf, lifeform_t *victim, object_t *wep, int *critical, } acc -= ev; - if (db) dblog("%s: minus victim's evaion (%d) -> %d", lfname, ev, acc); + if (db) dblog("%s: minus victim's evasion (%d) -> %d", lfname, ev, acc); + + // modify if victim is flying and we're not + if (isairborne(victim,&vicheight)) { + if (!isairborne(lf, NULL)) { + acc -= (5 * vicheight); + } + } // modify if we can't see the victim if (!cansee(lf, victim)) { diff --git a/data.c b/data.c index 0e66696..fdacfc4 100644 --- a/data.c +++ b/data.c @@ -1921,7 +1921,7 @@ void initobjects(void) { addbrand(BR_FEEBLENESS, "of feebleness", BP_WAIST, B_CURSED, 80); addflag_real(lastbrand->flags, F_EQUIPCONFER, F_ATTRSET, A_STR, 15, NULL, PERMENANT, B_UNKNOWN, -1); addbrand(BR_FLIGHT, "of the eagle", BP_WAIST, B_UNCURSED, 0); - addflag_real(lastbrand->flags, F_EQUIPCONFER, F_FLYING, B_TRUE, NA, NULL, PERMENANT, B_UNKNOWN, -1); + addflag_real(lastbrand->flags, F_EQUIPCONFER, F_FLYING, SZ_HUMAN, NA, NULL, PERMENANT, B_UNKNOWN, -1); addbrand(BR_SPEED, "of swiftness", BP_WAIST, B_UNCURSED, 0); addflag_real(lastbrand->flags, F_EQUIPCONFER, F_FASTACT, 5, NA, NULL, PERMENANT, B_UNKNOWN, -1); @@ -2180,10 +2180,10 @@ void initobjects(void) { // object types // dungeon features - addot(OT_DOORWOOD, "wooden door", "A sturdy wooden door.", MT_WOOD, 150, OC_DFEATURE, SZ_LARGE); + addot(OT_DOORWOOD, "wooden door", "A sturdy wooden door.", MT_WOOD, 160, OC_DFEATURE, SZ_LARGE); // GLYPH here is a special case in getglyph addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL); - addflag(lastot->flags, F_DOORFALLOB, NA, NA, NA, "plank of wood"); + addflag(lastot->flags, F_DOORFALLOB, NA, NA, NA, "4-5 planks of wood"); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, B_TRUE, NA, NULL); addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL); @@ -2201,7 +2201,7 @@ void initobjects(void) { addflag(lastot->flags, F_GROWSTO, CT_WALLWOOD, VT_CELL, NA, NULL); addflag(lastot->flags, F_SHRINKSTO, OT_BED, VT_OB, NA, NULL); - addot(OT_DOORIRON, "iron door", "A strong iron door.", MT_METAL, 300, OC_DFEATURE, SZ_LARGE); + addot(OT_DOORIRON, "iron door", "A strong iron door.", MT_METAL, 290, OC_DFEATURE, SZ_LARGE); // GLYPH here is a special case in getglyph addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_DOORFALLOB, NA, NA, NA, "sheet of metal"); @@ -2272,7 +2272,7 @@ void initobjects(void) { addot(OT_GATEWOOD, "wooden gate", "A gate comprised of a series of wooden slats.", MT_WOOD, 200, OC_DFEATURE, SZ_LARGE); addflag(lastot->flags, F_GLYPH, C_GREY, '+', NA, NULL); addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL); - addflag(lastot->flags, F_DOORFALLOB, NA, NA, NA, "plank of wood"); + addflag(lastot->flags, F_DOORFALLOB, NA, NA, NA, "4-5 planks of wood"); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ATTACKABLE, B_TRUE, NA, NA, NULL); @@ -3301,6 +3301,8 @@ void initobjects(void) { addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_GROWSTO, CT_WALLTREE, VT_CELL, NA, NULL); addflag(lastot->flags, F_SHRINKSTO, OT_STUMP, VT_OB, NA, NULL); + addflag(lastot->flags, F_BREAKOB, DT_CHOP, NA, NA, "stump"); + addflag(lastot->flags, F_BREAKOB, DT_CHOP, NA, NA, "20-40 shards of wood"); // food addot(OT_APPLE, "apple", "A crunchy apple.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); @@ -4308,7 +4310,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); - addot(OT_S_FLIGHT, "fly", "Allows the caster to fly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addot(OT_S_FLIGHT, "enchanted flight", "Allows the caster to fly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); @@ -4544,7 +4546,8 @@ void initobjects(void) { addot(OT_S_FREEZEOB, "freezing touch", "Changes the next thing touched into solid ice. The effect is permenant for inanimate objects, but will wear off on living creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); - addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, 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_NORANDOM, B_TRUE, NA, NA, NULL); addot(OT_S_ICECRUST, "ice crust", "Encrusts your weapon with a layer of sharp ice.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how long the enchantment will remain."); @@ -5618,6 +5621,9 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addot(OT_A_FEIGNDEATH, "feign death", "Pretend to be dead.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addot(OT_A_FLY, "fly", "Use your wings to fly in the air.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addflag(lastot->flags, F_STAMCOST, 2, NA, NA, NULL); addot(OT_A_FLIP, "flip", "Flip your opponent over your head.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_STAMCOST, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); @@ -5993,12 +5999,23 @@ void initobjects(void) { addflag(lastot->flags, F_VALUE, 75, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); + addot(OT_PEACEPIPES, "pipes of peace", "A set of enchanted pipes, capable of calming any nearby foes.", MT_METAL, 0.5, OC_TOOLS, SZ_TINY); + addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL); + addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_VERYRARE, NULL); + addflag(lastot->flags, F_VALUE, 500, NA, NA, NULL); + addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OPERUSECHARGE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_RNDCHARGES, 5, 10, NA, NULL); + addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "set of panpipes"); + addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL); + addot(OT_PICKAXE, "pickaxe", "A heavy tool for breaking rock.", MT_METAL, 8, OC_TOOLS, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastot->flags, F_VALUE, 75, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HELPSDIG, 10, NA, NA, NULL); + addflag(lastot->flags, F_OPERSOUND, SV_SHOUT, NA, NA, "the sound of digging"); addot(OT_ROPE, "nylon rope", "A long length of strong rope.", MT_CLOTH, 5, OC_TOOLS, SZ_MEDIUM); addflag(lastot->flags, F_GLYPH, C_BROWN, ']', NA, NULL); @@ -6144,6 +6161,7 @@ void initobjects(void) { addflag(lastot->flags, F_VALUE, 45, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HELPSDIG, 5, NA, NA, NULL); + addflag(lastot->flags, F_OPERSOUND, SV_SHOUT, NA, NA, "the sound of digging"); addot(OT_TORCH, "torch", "A metre-long wooden rod with a flammable end.", MT_WOOD, 2, OC_TOOLS, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 85, NA, NULL); @@ -6230,6 +6248,7 @@ void initobjects(void) { addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL); + addot(OT_POCKETWATCH, "pocket watch", "A portable timekeeping device made to be carried in a pocket.", MT_METAL, 0.1, OC_TECH, SZ_TINY); addflag(lastot->flags, F_RARITY, H_ALL, 90, NA, NULL); addflag(lastot->flags, F_VALUE, 25, NA, NA, NULL); @@ -6408,12 +6427,15 @@ void initobjects(void) { addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); - addot(OT_JACKHAMMER, "jackhammer", "A heavy power tool for quickly digging into hard rock.", MT_METAL, 15, OC_TOOLS, SZ_MEDIUM); + addot(OT_JACKHAMMER, "jackhammer", "A heavy power tool for quickly digging into hard rock.", MT_METAL, 15, OC_TECH, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HELPSDIG, 25, NA, NA, NULL); + addflag(lastot->flags, F_TECHLEVEL, PR_BEGINNER, NA, NA, NULL); + addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OPERSOUND, SV_CAR, NA, NA, "the roar of a jackhammer"); addot(OT_MOTIONSCANNER, "motion scanner", "Small scanning device which detects nearby lifeforms.", MT_METAL, 1.5, OC_TECH, SZ_TINY); addflag(lastot->flags, F_RARITY, H_ALL, 70, RR_RARE, NULL); @@ -6604,7 +6626,7 @@ void initobjects(void) { addflag(lastot->flags, F_OPERONOFF, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_RNDCHARGES, 10, 30, NA, NULL); addflag(lastot->flags, F_REFILLWITH, OT_POT_OIL, NA, NA, NULL); - addflag(lastot->flags, F_ACTIVATECONFER, F_FLYING, B_TRUE, NA, NULL); + addflag(lastot->flags, F_ACTIVATECONFER, F_FLYING, SZ_HUGE, NA, NULL); addflag(lastot->flags, F_ACTIVATECONFER, F_PRODUCESLIGHT, 3, NA, NULL); addflag(lastot->flags, F_TECHLEVEL, PR_SKILLED, NA, NA, NULL); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, NULL); @@ -6980,7 +7002,7 @@ void initobjects(void) { addflag(lastot->flags, F_PURIFIESTO, OT_PUDDLEWATERL, NA, NA, NULL); addflag(lastot->flags, F_FILLPOT, OT_POT_BLOOD, NA, NA, NULL); - addot(OT_WOODPLANK, "plank of wood", "A large plank of heavy wood.", MT_WOOD, 150, OC_MISC, SZ_MEDIUM); + addot(OT_WOODPLANK, "plank of wood", "A large plank of heavy wood.", MT_WOOD, 25, OC_MISC, SZ_MEDIUM); addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '_', NA, NULL); @@ -6990,8 +7012,31 @@ void initobjects(void) { addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_DOORWOOD, VT_OB, NA, NULL); addflag(lastot->flags, F_SHRINKSTO, OT_STICK, VT_OB, NA, NULL); + addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL); + addflag(lastot->flags, F_ACCURACY, 60, NA, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); + addflag(lastot->flags, F_OBATTACKDELAY, 110, NA, NA, NULL); - addot(OT_METALSHEET, "sheet of metal", "A large sheet of thick wood.", MT_WOOD, 150, OC_MISC, SZ_LARGE); + + addot(OT_WOODSHARD, "shard of wood", "A small shard of wood.", MT_WOOD, 4, OC_MISC, SZ_MEDIUM); + addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); + addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_GLYPH, C_BROWN, ',', NA, NULL); + addflag(lastot->flags, F_DTCONVERT, DT_FIRE, NA, NA, "pile of ash"); + addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL); + addflag(lastot->flags, F_DTVULN, DT_BASH, NA, NA, NULL); + addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); + addflag(lastot->flags, F_GROWSTO, OT_WOODPLANK, VT_OB, NA, NULL); + addflag(lastot->flags, F_SHRINKSTO, OT_ASH, VT_OB, NA, NULL); + addflag(lastot->flags, F_OBATTACKDELAY, 80, NA, NA, NULL); + addflag(lastot->flags, F_DAM, DT_PIERCE, 3, NA, NULL); + addflag(lastot->flags, F_ACCURACY, 777770, NA, NA, NULL); + addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_OBHP, 2, 2, NA, NULL); + addflag(lastot->flags, F_USESSKILL, SK_SHORTBLADES, NA, NA, NULL); + + addot(OT_METALSHEET, "sheet of metal", "A large sheet of heavy metal.", MT_WOOD, 150, OC_MISC, SZ_LARGE); addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, '_', NA, NULL); @@ -7160,7 +7205,7 @@ void initobjects(void) { addflag(lastot->flags, F_GROWSTO, OT_DOORWOOD, VT_OB, NA, NULL); addflag(lastot->flags, F_SHRINKSTO, OT_WOODENSTOOL, VT_OB, NA, NULL); - addot(OT_WOODENSTOOL, "wooden footstool", "A small, wooden footstool.", MT_WOOD, 5, OC_FURNITURE, SZ_MEDIUM); + addot(OT_WOODENSTOOL, "wooden footstool", "A small, wooden footstool.", MT_WOOD, 20, OC_FURNITURE, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_ALL, 83, RR_COMMON, NULL); addflag(lastot->flags, F_GLYPH, NA, '\\', NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); @@ -8866,6 +8911,7 @@ void initobjects(void) { addflag(lastot->flags, F_CANBEDIFFMAT, MT_SILVER, 10, NA, NULL); addflag(lastot->flags, F_CANBEDIFFMAT, MT_BONE, 10, NA, NULL); addflag(lastot->flags, F_ATTREQ, A_AGI, NA, 65, "10"); + addot(OT_BASELARD, "baselard", "A heavy dagger designed for punching through armour.", MT_METAL, 1, OC_WEAPON, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 90, RR_UNCOMMON, NULL); @@ -9465,6 +9511,7 @@ void initobjects(void) { addflag(lastot->flags, F_HELPSDISARM, 5, NA, NA, NULL); addflag(lastot->flags, F_HELPSREPAIR, MT_METAL, 2, 15, NULL); addflag(lastot->flags, F_USESSKILL, SK_CLUBS, NA, NA, NULL); + addflag(lastot->flags, F_OPERSOUND, SV_SHOUT, NA, NA, "a metallic clanging"); addot(OT_SHILLELAGH, "shillelagh", "An small cudgel with a strap, lightweight yet surprisingly effective. Irish in origin.", MT_WOOD, 2, OC_WEAPON, SZ_MEDIUM); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, NA, NULL); @@ -10165,18 +10212,20 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CHA, AT_RANDOM, NA, NULL); // bonuses addbonustext(lastrace->flags, F_BONDESC, "Unarmed claw attack (damage rating 4)"); + addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, "pw:1;"); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, "pw:1;"); addflag(lastrace->flags, F_VISRANGEMOD, 1, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL); - addflag(lastrace->flags, F_FLIGHTEVASION, 20, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); // penalties addbonustext(lastrace->flags, F_PENDESC, "Low hit points."); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 1, 3, 4, NULL); // other special stuff - addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "screechs^a screech"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^flapping wings"); + addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, SV_SHOUT, NA, "screechs^a screech"); addflag(lastrace->flags, F_TR, 2, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL); @@ -10567,10 +10616,12 @@ void initrace(void) { addflag(lastrace->flags, F_NOFLEE, NA, NA, NA, NULL); // bonuses addflag(lastrace->flags, F_DTRESIST, DT_SLASH, NA, NA, NULL); - addflag(lastrace->flags, F_LEVABIL, 7, OT_S_FLIGHT, NA, NULL); + addflag(lastrace->flags, F_LEVSKILL, 7, SK_FLIGHT, NA, NULL); + addflag(lastrace->flags, F_LEVABIL, 7, OT_A_FLY, NA, NULL); addflag(lastrace->flags, F_LEVABIL, 10, OT_S_FIREBALL, 80, "pw:10;"); addflag(lastrace->flags, F_STARTSKILL, SK_LORE_DRAGONS, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_CANLEARN, SK_LORE_DRAGONS, PR_MASTER, NA, NULL); // no limit + addflag(lastrace->flags, F_CANLEARN, SK_FLIGHT, NA, NA, NULL); // penalties addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_LEARNBOOST, -30, NA, NA, NULL); @@ -11027,6 +11078,7 @@ void initrace(void) { addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "Mortal! Your actions have impressed me."); addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "I offer you a place in my service."); addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "appears in a flash of power!"); + addflag(lastrace->flags, F_GODDECLINE, NA, NA, NA, "So be it."); addrace(R_GODBATTLE, "Bjorn", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Bjorn the Battlelord is the god of honourable combat. He appears as a heavily built, bearded warrior clad in well-used armour."); setbodytype(lastrace, BT_HUMANOID); @@ -11108,6 +11160,7 @@ void initrace(void) { addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "Your actions have proved worthy of notice."); addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "Join me in my eternal battle!"); addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "appears in a shower of blood!"); + addflag(lastrace->flags, F_GODDECLINE, NA, NA, NA, "Coward!"); addrace(R_GODNATURE, "Ekrub", 200, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Ekrub is goddess of nature and creation. She appears as a female figure dressed in farming clothes. Ekrub has a burning hatred of all dragonkind, who she views as abhorrent due to their destructive nature."); setbodytype(lastrace, BT_HUMANOID); @@ -11188,6 +11241,7 @@ void initrace(void) { addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "You have demonstrated an affinity for creation."); addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "Nature would welcome your continued worship."); addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "coalesces out of twisting air currents!"); + addflag(lastrace->flags, F_GODDECLINE, NA, NA, NA, "Your choice is disappointing."); addrace(R_GODTHIEVES, "Felix", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Felix is the god of Thieves, Revenge and Greed. 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."); setbodytype(lastrace, BT_HUMANOID); @@ -11238,6 +11292,7 @@ void initrace(void) { addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "giving away or discarding money"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "opening locked objects through force"); // sacrifices (piety val will be overridden with value) + addflag(lastrace->flags, F_GODPOISON, B_TRUE, 3, NA, NULL); addflag(lastrace->flags, F_SACRIFICEOBCLASS, OC_MONEY, NA, 2, "OB IS consumed in a swirl of shadowy blackness."); addflag(lastrace->flags, F_SACRIFICEOBWITHFLAG, F_GEM, NA, 2, "OB IS consumed in a swirl of shadowy blackness."); addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "teleporting you out of danger"); @@ -11261,6 +11316,7 @@ void initrace(void) { addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "Some would denounce your greed... but others would welcome it."); addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "We could work together, you and I. What say you?"); addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "steps out of the shadows."); + addflag(lastrace->flags, F_GODDECLINE, NA, NA, NA, "You will come to your senses soon enough..."); addrace(R_GODLIFE, "Glorana", 2, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Glorana is the goddess of life. She appears as a pulsating orb of holy energy."); addbodypart(lastrace, BP_BODY, "life energy"); @@ -11327,6 +11383,7 @@ void initrace(void) { addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "Well met, my child! I am Glorana, protector of all that is living."); addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "I would gladly welcome you to into my service, should you accept."); addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "appears in a shaft of holy light."); + addflag(lastrace->flags, F_GODDECLINE, NA, NA, NA, "I will, of course, respect your decision."); 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."); setbodytype(lastrace, BT_HUMANOID); @@ -11393,6 +11450,7 @@ void initrace(void) { addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "I bring you an offer, murderous fleshling."); addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "Great power in life, in return for eternal service in death."); addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "rises up from the underworld!"); + addflag(lastrace->flags, F_GODDECLINE, NA, NA, NA, "Foolish mortal!"); addrace(R_GODFIRE, "Klikirak", 2, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Klikirak is the burning god of Fire and Destruction. He is visible only as a raging inferno of fire, destroying anything in his path."); addbodypart(lastrace, BP_BODY, "flames"); @@ -11447,6 +11505,7 @@ void initrace(void) { addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "YOU BURN/DESTROY... I BURN/DESTROY..."); addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "WE BURN/DESTROY TOGETHER! YES?"); addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "appears in a burst of white-hot fire!"); + addflag(lastrace->flags, F_GODDECLINE, NA, NA, NA, "BURN ALONE THEN!"); addrace(R_GODMAGIC, "Lumara", 55, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Lumara is the goddess of magic. She appears as a slender elderly woman, her expression wise with age."); setbodytype(lastrace, BT_HUMANOID); @@ -11514,6 +11573,7 @@ void initrace(void) { addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "One walks the path of magic... but One has far to go."); addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "Become my student, and experience the full spectrum of arcane knowledge."); addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "appears in a swirl of multicoloured lights!"); + addflag(lastrace->flags, F_GODDECLINE, NA, NA, NA, "One will find arcane learning a difficult task on One's own."); addrace(R_GODMERCY, "Yumi", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Yumi is the goddess of Mercy and Forgiveness. She has a calm, serene face and wears simple clothing."); setbodytype(lastrace, BT_HUMANOID); @@ -11578,6 +11638,7 @@ void initrace(void) { addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "Such mercy as you have shown is rarely seen in your kind."); addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "Would you consider a position as my disciple?"); addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "fades slowly into view."); + addflag(lastrace->flags, F_GODDECLINE, NA, NA, NA, "I understand."); // monsters 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."); @@ -11710,13 +11771,15 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 4, BP_HEAD, NULL); // lion head addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 3, BP_HEAD2, NULL); // dragon head addflag(lastrace->flags, F_HASATTACK, OT_HORN, 5, BP_HEAD3, NULL); // goat horns addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); // front lion claws addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); // front lion claws + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_SHOUT, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, SV_CAR, NA, "roars^a roar"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, SV_SHOUT, NA, "bleats^an angry bleating"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); @@ -11803,7 +11866,7 @@ void initrace(void) { addflag(lastrace->flags, F_DTIMMUNE, DT_PETRIFY, B_TRUE, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL); addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTIMMUNE, DT_PETRIFY, NA, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_DTIMMUNE, DT_PETRIFY, NA, "50"); // special attack handled in attack.c 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."); @@ -11871,7 +11934,7 @@ void initrace(void) { addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_NIGHTVISRANGEMOD, 1, NA, "75"); + addflag(lastrace->flags, F_EATMUTATE, F_NIGHTVISRANGEMOD, 1, NA, "75"); addrace(R_DRYAD, "dryad", 65, 'p', C_BROWN, MT_WOOD, RC_MAGIC, "Dryads are gentle forest spirits. These peaceful creatures prefer the tranquility of nature, and will avoid fighting if possible."); setbodytype(lastrace, BT_HUMANOID); @@ -11944,6 +12007,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "silk shirt"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "riding trousers"); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_SHOUT, NA, "^whirling air"); addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "whirlwind"); @@ -11957,6 +12021,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_TWOWEAPON, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_AIR, PR_EXPERT, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_HATESRACE, R_EFREETI, NA, NA, NULL); addrace(R_EFREETI, "efreeti", 65, 'Y', C_RED, MT_FLESH, RC_MAGIC, "Efreeti are evil, fire-based cousins of genies. They resemble richly dressed humans surrounded by crackling flames."); setbodytype(lastrace, BT_HUMANOID); @@ -11985,6 +12050,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "medium fire"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_SHOUT, NA, "^roaring flames"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); addflag(lastrace->flags, F_CANCAST, OT_S_WALLOFFIRE, 10, 10, "pw:5;"); addflag(lastrace->flags, F_CANCAST, OT_S_FLAMEPILLAR, NA, NA, "pw:7;"); @@ -11994,6 +12060,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTSKILL, SK_TWOWEAPON, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_FIRE, PR_EXPERT, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); + addflag(lastrace->flags, F_HATESRACE, R_DJINNI, NA, NA, NULL); 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."); addbodypart(lastrace, BP_BODY, NULL); @@ -12064,7 +12131,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_STUN, NA, B_APPENDYOU, "gazes"); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_VISRANGEMOD, 1, NA, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_VISRANGEMOD, 1, NA, "50"); addrace(R_TREANTYOUNG, "treant youngling", 500, 'T', C_BROWN, MT_WOOD, RC_HUMANOID, "Treants are huge living trees, with humanoid facial features visible on their trunks."); setbodytype(lastrace, BT_HUMANOID); @@ -12213,7 +12280,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOB, 90, NA, NA, "25-100 gold dollars"); addflag(lastrace->flags, F_STARTOB, 70, NA, NA, "1-2 boulders"); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_ATTRMOD, A_STR, 5, "50"); f = addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great club"); addcondition(f, FC_NOCONDITION, 70); @@ -12276,8 +12343,8 @@ void initrace(void) { 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); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "50"); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_FIRE, NA, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_ATTRMOD, A_STR, 5, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_FIRE, NA, "50"); addflag(lastrace->flags, F_FILLPOT, OT_POT_ELEMENTIMMUNE, BLOODFORPOT, NA, NULL); addrace(R_GIANTFIREFC, "flame giant firemaster", 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."); @@ -12320,8 +12387,8 @@ void initrace(void) { 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); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "50"); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_FIRE, NA, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_ATTRMOD, A_STR, 5, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_FIRE, NA, "50"); addflag(lastrace->flags, F_FILLPOT, OT_POT_ELEMENTIMMUNE, BLOODFORPOT, NA, NULL); @@ -12709,12 +12776,14 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_BEAK, 14, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_SHOUT, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "screeches^a screeches"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL); @@ -12750,14 +12819,16 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_HITDICE, 3, 3, NA, NULL); addflag(lastrace->flags, F_TR, 5, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_BEAK, 10, NA, NULL); addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_SHOUT, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 4, NA, "screams in pain^screams of pain"); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, ""); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); @@ -12998,7 +13069,7 @@ void initrace(void) { addflag(lastrace->flags, F_DODGES, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EXTRALUCK, 10, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_EXTRALUCK, 5, NA, NULL); + addflag(lastrace->flags, F_EATMUTATE, F_EXTRALUCK, 5, NA, NULL); addrace(R_LESHY, "leshy", 35, 'h', C_GREEN, MT_PLANT, RC_HUMANOID, "Human-like figures with leaves (and the occasional fruit) covering their bodies."); setbodytype(lastrace, BT_HUMANOID); @@ -13086,8 +13157,9 @@ void initrace(void) { addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, 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_SPELLSPEED, SP_SLOW, NA, NA, NULL); @@ -13095,6 +13167,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "gestures"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "bloodstained dagger"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^buzzing"); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_BACKSTAB, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); @@ -13123,15 +13196,17 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 90, NA, NA, NULL); // will nearly always use its spikes first. addflag(lastrace->flags, F_CANWILL, OT_S_SPIKEVOLLEY, 30, 30, "pw:2;range:4;"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_SPIKEVOLLEY, NA, B_APPENDYOU, "aims its tail"); addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_SHOUT, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screams in pain^screams of pain"); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); @@ -13584,7 +13659,7 @@ void initrace(void) { addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "80"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_COLD, NA, "80"); addrace(R_PEGASUS, "pegasus", 500, 'u', C_CYAN, MT_FLESH, RC_ANIMAL, "A legendary white, winged horse."); setbodytype(lastrace, BT_QUADRAPED); @@ -13604,8 +13679,8 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL); addflag(lastrace->flags, F_TR, 6, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_HOOF, 8, NA, NULL); @@ -13615,12 +13690,14 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, NULL); addflag(lastrace->flags, F_SWOOPRANGE, 4, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_SMITEEVIL, NA, NA, "pw:8;"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_SHOUT, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 4, NA, "screams in pain^screams of pain"); addflag(lastrace->flags, F_RESISTMAG, 5, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 15, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL); addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_EQUINE, B_TRUE, NA, NA, NULL); addrace(R_PIXIE, "pixie", 5, 'n', C_MAGENTA, MT_FLESH, RC_MAGIC, "A small magical woodland creature, flying around on moth-like wings."); @@ -13642,8 +13719,9 @@ void initrace(void) { addflag(lastrace->flags, F_TR, 2, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^buzzing wings"); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, 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_RNDSPELLCOUNT, 2, NA, NA, NULL); @@ -13654,6 +13732,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOB, 80, NA, NA, "1-2 arrows"); addflag(lastrace->flags, F_STARTOB, 60, NA, NA, "cap"); addflag(lastrace->flags, F_STARTOB, 60, NA, NA, "leather shoes"); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_RANGED, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); @@ -14026,7 +14105,7 @@ void initrace(void) { addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_COLD, NA, "50"); addrace(R_OOZEGREY, "sizzling slime", 10, 'j', C_GREEN, MT_SLIME, RC_SLIME, "Exactly what it sounds like - a small lump of green ooze. Green, acidic ooze."); @@ -14146,8 +14225,8 @@ void initrace(void) { addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 15, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, 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_SPELLSPEED, SP_SLOW, NA, NA, NULL); @@ -14160,13 +14239,15 @@ void initrace(void) { addflag(lastrace->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_WATER, NA, NA, "1d6"); addflag(lastrace->flags, F_DTVULN, DT_COLD, NA, NA, NULL); - addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^crackling flames"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^crackling flames"); + addflag(lastrace->flags, F_NOISETEXT, N_WALK, SV_TALK, NA, "^crackling flames"); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, 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_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_FIRE, NA, "25"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_FIRE, NA, "25"); addflag(lastrace->flags, F_WANTSOBFLAG, F_GEM, B_COVETS, NA, NULL); addflag(lastrace->flags, F_FILLPOT, OT_POT_ELEMENTIMMUNE, BLOODFORPOT, NA, NULL); @@ -14189,8 +14270,8 @@ void initrace(void) { addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 15, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, 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_SPELLSPEED, SP_SLOW, NA, NA, NULL); @@ -14200,6 +14281,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "gestures"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_DEATH, 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); @@ -14226,8 +14308,9 @@ void initrace(void) { addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 15, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^buzzing wings"); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, 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_SPELLSPEED, SP_SLOW, NA, NA, NULL); @@ -14240,12 +14323,13 @@ void initrace(void) { addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_ELECTRIC, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, 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_CASTCHANCE, 30, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "25"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_COLD, NA, "25"); addflag(lastrace->flags, F_WANTSOBFLAG, F_GEM, B_COVETS, NA, NULL); addflag(lastrace->flags, F_FILLPOT, OT_POT_ELEMENTIMMUNE, BLOODFORPOT, NA, NULL); @@ -14268,8 +14352,9 @@ void initrace(void) { addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 15, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^buzzing wings"); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, 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_CANCAST, OT_S_SMITEGOOD, NA, NA, "pw:1;"); @@ -14278,6 +14363,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "gestures"); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_WILD, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL); @@ -14400,7 +14486,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLLSNOW, "comes to life!"); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_COLD, NA, "50"); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;"); @@ -14650,7 +14736,7 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, 6, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_ELECTRIC, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_ELECTRIC, NA, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_ELECTRIC, NA, "50"); 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."); setbodytype(lastrace, BT_FISH); addflag(lastrace->flags, F_NEEDSWATER, B_TRUE, NA, NA, NULL); @@ -14909,7 +14995,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "5-10 peanuts"); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "5-10 peanuts"); addflag(lastrace->flags, F_WILLTHROW, OT_NUT, NA, NA, NULL); - addflag(lastrace->flags, F_STARTSKILL, SK_THROWING, PR_SKILLED, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_THROWING, PR_EXPERT, NA, NULL); addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOPRINTS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); @@ -14987,9 +15073,9 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 1, NA, 4, NULL); addflag(lastrace->flags, F_TR, 1, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 1, NA, NULL); @@ -14997,7 +15083,7 @@ void initrace(void) { addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 2, NA, NA, NULL); - addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^flapping wings"); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); 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."); setbodytype(lastrace, BT_BIRD); @@ -15016,9 +15102,9 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL); addflag(lastrace->flags, F_TR, 2, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 1, NA, NULL); @@ -15028,7 +15114,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANWILL, OT_A_SONICBOLT, 3, 3, "pw:5;dam:1d4;"); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); - addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^flapping wings"); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_EATCONFER, F_MUTABLE, B_TRUE, NA, "100"); addrace(R_BATBRAIN, "brain bat", 6, 'B', C_RED, MT_FLESH, RC_ANIMAL, "Rare bats, said to exhibit strange psionic behaviour."); @@ -15046,14 +15132,15 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 2, NA, NULL); addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); - addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^flapping wings"); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_STUN, 3, 3, "pw:3;"); addflag(lastrace->flags, F_CANCAST, OT_S_DISORIENT, 3, 3, "pw:3;"); addflag(lastrace->flags, F_CANCAST, OT_S_PSIBLAST, 3, 3, "pw:1;"); @@ -15076,9 +15163,9 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL); @@ -15088,7 +15175,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_MATVULN, MT_SILVER, 200, NA, NULL); - addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^flapping wings"); 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); @@ -15295,7 +15382,7 @@ void initrace(void) { addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;"); addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_CANSEETHROUGHMAT, MT_GAS, NA, "80"); + addflag(lastrace->flags, F_EATMUTATE, F_CANSEETHROUGHMAT, MT_GAS, NA, "80"); addflag(lastrace->flags, F_FELINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACEWITHFLAG, F_CANINE, NA, NA, NULL); @@ -15555,7 +15642,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, NULL); addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_FLOOD, F_AICASTTOATTACK, ST_SELF, "100"); addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "hop"); - addflag(lastrace->flags, F_EATCONFER, F_BREATHWATER, B_TRUE, NA, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_BREATHWATER, B_TRUE, NA, "50"); addrace(R_CHICKEN, "chicken", 0.5, 'c', C_BROWN, MT_FLESH, RC_ANIMAL, "A common farm-yard chicken."); @@ -15798,15 +15885,16 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 7, NA, NA, NULL); addflag(lastrace->flags, F_TR, 7, NA, NA, NULL); addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 6, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); @@ -15832,14 +15920,14 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL); addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 2, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 2, NA, NULL); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL); @@ -15847,6 +15935,7 @@ void initrace(void) { addflag(lastrace->flags, F_CASTCHANCE, 70, NA, NA, NULL); addflag(lastrace->flags, F_SWOOPRANGE, 2, NA, NA, NULL); addflag(lastrace->flags, F_LEVRACE, 4, R_HAWK, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_TOOCLOSE, 2, NA, "screeches threateningly^a loud screech"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); @@ -15871,13 +15960,13 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL); addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 3, NA, NULL); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, NULL); @@ -15885,6 +15974,7 @@ void initrace(void) { addflag(lastrace->flags, F_SWOOPRANGE, 3, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_LEVRACE, 8, R_HAWKBLOOD, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_TOOCLOSE, 2, NA, "screeches threateningly^a loud screech"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); @@ -15907,19 +15997,20 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL); addflag(lastrace->flags, F_TR, 5, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 7, NA, NULL); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 70, NA, NA, NULL); addflag(lastrace->flags, F_SWOOPRANGE, 5, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_TOOCLOSE, 2, NA, "screeches threateningly^a loud screech"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); @@ -15940,13 +16031,13 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 7, NA, NA, NULL); addflag(lastrace->flags, F_TR, 8, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 11, NA, NULL); addflag(lastrace->flags, F_EXTRADAM, DT_COLD, NA, NA, "1d6"); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, NULL); @@ -15955,12 +16046,13 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "screeches"); 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_FLY, SV_TALK, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_TOOCLOSE, 2, NA, "screeches threateningly^a loud screech"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, B_TRUE, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "20"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_COLD, NA, "20"); addflag(lastrace->flags, F_FILLPOT, OT_POT_ELEMENTIMMUNE, BLOODFORPOT, NA, NULL); addrace(R_ELEPHANT, "elephant", 4000, 'Q', C_GREY, MT_LEATHER, RC_ANIMAL, "A massive grey mammal with a long trunk and sharp tusks."); @@ -16048,12 +16140,12 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 10, NA, NA, NULL); addflag(lastrace->flags, F_TR, 9, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 14, NA, NULL); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, NULL); @@ -16061,11 +16153,12 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "screeches"); addflag(lastrace->flags, F_MORALE, 13, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_SHOUT, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 3, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DTRESIST, DT_COLD, B_TRUE, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "20"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_COLD, NA, "20"); 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."); addbodypart(lastrace, BP_BODY, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); @@ -16300,23 +16393,24 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 18, NA, NA, NULL); addflag(lastrace->flags, F_TR, 15, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 18, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 18, NA, NULL); - addflag(lastrace->flags, F_FLIGHTEVASION, 15, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SWOOP, NA, NA, NULL); addflag(lastrace->flags, F_SWOOPRANGE, 8, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "screeches"); addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_CAR, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 5, NA, "screeches in pain^screeches of pain"); addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_CANWILL, OT_S_FLIGHT, NA, "90"); + addflag(lastrace->flags, F_EATMUTATE, F_CANWILL, OT_S_FLIGHT, NA, "90"); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACE, R_DWARF, NA, NA, NULL); @@ -16424,7 +16518,7 @@ void initrace(void) { addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_POISON, NA, "10"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_POISON, NA, "10"); addrace(R_SNAKECARPET, "carpet snake", 3, 's', C_GREY, MT_FLESH, RC_ANIMAL, "Non-venemous (but not quite harmless) snakes."); setbodytype(lastrace, BT_SNAKE); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); @@ -16521,7 +16615,7 @@ void initrace(void) { addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_POISON, NA, "15"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_POISON, NA, "15"); addrace(R_SNAKECOBRAGOLDEN, "golden cobra", 3, 's', C_YELLOW, MT_FLESH, RC_ANIMAL, "Golden cobras spit a blindness-inducing venom at their enemies."); setbodytype(lastrace, BT_SNAKE); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL); @@ -16557,7 +16651,7 @@ void initrace(void) { addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_POISON, NA, "15"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_POISON, NA, "15"); 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."); setbodytype(lastrace, BT_SNAKE); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); @@ -16698,7 +16792,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOMELEVOB, 5, 10, NA, "20-30 webs"); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, ""); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_POISON, NA, "15"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_POISON, NA, "15"); addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "creep"); addflag(lastrace->flags, F_FILLPOT, OT_POT_POISON, BLOODFORPOT, NA, NULL); addrace(R_SPIDERREDBACK, "giant redback", 5, 'S', C_RED, MT_FLESH, RC_ANIMAL, "A version of a giant spider with a highly painful bite."); @@ -16738,7 +16832,7 @@ void initrace(void) { addflag(lastrace->flags, F_HOMELEVOB, 5, 10, NA, "10-20 webs"); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, ""); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_POISON, NA, "10"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_POISON, NA, "10"); addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "creep"); addflag(lastrace->flags, F_FILLPOT, OT_POT_POISON, BLOODFORPOT, NA, NULL); addrace(R_SPIDERTOMB, "tomb spider", 5, 'S', C_BLUE, MT_FLESH, RC_ANIMAL, "Tomb spiders are truly nightmarish beings. Their skin can absorb light itself, and they can boost their own life force by consuming the flesh of their victims."); @@ -16948,7 +17042,7 @@ void initrace(void) { addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "25"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_COLD, NA, "25"); addrace(R_CRYSTALCUR, "crystal cur", 60, 'd', C_WHITE, MT_CRYSTAL, RC_ANIMAL, "Crystal Curs are magical hounds, imbued with magical defenses by over-protective owners."); setbodytype(lastrace, BT_QUADRAPED); @@ -17054,9 +17148,9 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 5, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_SKILLED, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 10, NA, NA, NULL); addflag(lastrace->flags, F_TR, 10, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 12, NA, NA, NULL); @@ -17070,6 +17164,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_CAR, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 5, NA, "roars^a roar"); addflag(lastrace->flags, F_STARTSKILL, SK_LORE_DRAGONS, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_LISTEN, PR_ADEPT, NA, NULL); @@ -17091,9 +17186,9 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_SKILLED, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 28, NA, NA, NULL); addflag(lastrace->flags, F_TR, 16, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 18, NA, NA, NULL); @@ -17109,6 +17204,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_CAR, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roar"); addflag(lastrace->flags, F_ATTACKRANGE, 2, 5, NA, NULL); // maintain distance addflag(lastrace->flags, F_FLEEONHPPCT, 15, NA, NA, NULL); @@ -17131,7 +17227,7 @@ void initrace(void) { addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_ELECTRIC, NA, "100"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_ELECTRIC, NA, "100"); addrace(R_DRAGONBLUEY, "blue wyrmling", 150, 'w', C_CYAN, MT_FLESH, RC_DRAGON, "Blue wyrms are massive reptilian creatures who can (and will) consume almost any living creature."); setbodytype(lastrace, BT_HUMANOID); @@ -17143,8 +17239,8 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 13, NA, NA, NULL); addflag(lastrace->flags, F_TR, 10, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 12, NA, NA, NULL); @@ -17160,9 +17256,11 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_CAR, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 5, NA, "roars^a roar"); addflag(lastrace->flags, F_ATTACKRANGE, 2, 5, NA, NULL); // maintain distance addflag(lastrace->flags, F_DTIMMUNE, DT_ELECTRIC, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_AIR, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_LORE_DRAGONS, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_LISTEN, PR_ADEPT, NA, NULL); @@ -17183,8 +17281,8 @@ void initrace(void) { addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_ELECTRIC, NA, "50"); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "25"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_ELECTRIC, NA, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_ATTRMOD, A_STR, 5, "25"); addrace(R_DRAGONBLUEA, "ancient blue wyrm", 600, 'W', C_CYAN, MT_FLESH, RC_DRAGON, "Blue wyrms are massive reptilian creatures who can (and will) consume almost any living creature."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_WINGS, NULL); @@ -17195,9 +17293,9 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 15, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_EXPERT, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 40, NA, NA, NULL); addflag(lastrace->flags, F_TR, 19, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 24, NA, NA, NULL); @@ -17213,6 +17311,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_CAR, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 5, NA, "roars^a roar"); addflag(lastrace->flags, F_FLEEONHPPCT, 15, NA, NA, NULL); addflag(lastrace->flags, F_ATTACKRANGE, 2, 5, NA, NULL); // maintain distance @@ -17242,8 +17341,8 @@ void initrace(void) { addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_ELECTRIC, NA, "100"); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "100"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_ELECTRIC, NA, "100"); + addflag(lastrace->flags, F_EATMUTATE, F_ATTRMOD, A_STR, 5, "100"); addrace(R_DRAGONRED, "red wyrm", 400, 'W', C_RED, MT_FLESH, RC_DRAGON, "Red wyrms are massive evil reptilians who thrive on destruction, especially by means of fire."); @@ -17256,9 +17355,9 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_SKILLED, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 30, NA, NA, NULL); addflag(lastrace->flags, F_TR, 17, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 18, NA, NA, NULL); @@ -17272,6 +17371,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_CAR, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roar"); addflag(lastrace->flags, F_FLEEONHPPCT, 15, NA, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL); @@ -17297,8 +17397,8 @@ void initrace(void) { addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_FIRE, NA, "100"); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_FIRE, NA, "100"); + addflag(lastrace->flags, F_EATMUTATE, F_ATTRMOD, A_STR, 5, "50"); addrace(R_DRAGONREDY, "red wyrmling", 150, 'w', C_RED, MT_FLESH, RC_DRAGON, "Red wyrms are massive evil reptilians who thrive on destruction, especially by means of fire."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_WINGS, NULL); @@ -17309,8 +17409,8 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 15, NA, NA, NULL); addflag(lastrace->flags, F_TR, 10, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 12, NA, NA, NULL); @@ -17324,9 +17424,11 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_CAR, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 5, NA, "roars^a roar"); addflag(lastrace->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_FIRE, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_LORE_DRAGONS, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_LISTEN, PR_ADEPT, NA, NULL); @@ -17345,8 +17447,8 @@ void initrace(void) { addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_FIRE, NA, "50"); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "25"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_FIRE, NA, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_ATTRMOD, A_STR, 5, "25"); addrace(R_DRAGONREDA, "ancient red wyrm", 600, 'W', C_RED, MT_FLESH, RC_DRAGON, "Red wyrms are massive evil reptilians who thrive on destruction, especially by means of fire."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_WINGS, NULL); @@ -17357,9 +17459,9 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 15, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_EXPERT, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 45, NA, NA, NULL); addflag(lastrace->flags, F_TR, 20, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 24, NA, NA, NULL); @@ -17373,6 +17475,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_CAR, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 5, NA, "roars^a roar"); addflag(lastrace->flags, F_FLEEONHPPCT, 15, NA, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL); @@ -17400,8 +17503,8 @@ void initrace(void) { addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_FIRE, NA, "100"); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "100"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_FIRE, NA, "100"); + addflag(lastrace->flags, F_EATMUTATE, F_ATTRMOD, A_STR, 5, "100"); addrace(R_DRAGONWHITE, "white wyrm", 400, 'W', C_WHITE, MT_FLESH, RC_DRAGON, "Although white wyrms are smaller than other varieties, their icy breath still makes them a formidable threat."); setbodytype(lastrace, BT_HUMANOID); @@ -17413,9 +17516,9 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_SKILLED, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 22, NA, NA, NULL); addflag(lastrace->flags, F_TR, 15, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 10, NA, NA, NULL); @@ -17430,6 +17533,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_CAR, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roar"); addflag(lastrace->flags, F_FLEEONHPPCT, 15, NA, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); @@ -17453,8 +17557,8 @@ void initrace(void) { addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "100"); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_COLD, NA, "100"); + addflag(lastrace->flags, F_EATMUTATE, F_ATTRMOD, A_STR, 5, "50"); addrace(R_DRAGONWHITEY, "white wyrmling", 150, 'w', C_WHITE, MT_FLESH, RC_DRAGON, "Although white wyrms are smaller than other varieties, their icy breath still makes them a formidable threat."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_WINGS, NULL); @@ -17465,8 +17569,8 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 10, NA, NA, NULL); addflag(lastrace->flags, F_TR, 10, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 7, NA, NA, NULL); @@ -17481,9 +17585,11 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_CAR, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 5, NA, "roars^a roar"); addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SS_COLD, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_LORE_DRAGONS, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_LISTEN, PR_ADEPT, NA, NULL); @@ -17499,8 +17605,8 @@ void initrace(void) { addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "50"); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "25"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_COLD, NA, "50"); + addflag(lastrace->flags, F_EATMUTATE, F_ATTRMOD, A_STR, 5, "25"); addrace(R_DRAGONWHITEA, "ancient white wyrm", 600, 'W', C_WHITE, MT_FLESH, RC_DRAGON, "Although white wyrms are smaller than other varieties, their icy breath still makes them a formidable threat."); setbodytype(lastrace, BT_HUMANOID); addbodypart(lastrace, BP_WINGS, NULL); @@ -17511,9 +17617,9 @@ void initrace(void) { addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 15, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_EXPERT, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 32, NA, NA, NULL); addflag(lastrace->flags, F_TR, 18, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 16, NA, NA, NULL); @@ -17528,6 +17634,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_CAR, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 5, NA, "roars^a roar"); addflag(lastrace->flags, F_FLEEONHPPCT, 15, NA, NA, NULL); addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); @@ -17554,8 +17661,8 @@ void initrace(void) { addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "100"); - addflag(lastrace->flags, F_EATCONFER, F_ATTRMOD, A_STR, 5, "100"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_COLD, NA, "100"); + addflag(lastrace->flags, F_EATMUTATE, F_ATTRMOD, A_STR, 5, "100"); // end dragons / wyrms // insects @@ -17627,9 +17734,10 @@ void initrace(void) { addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_TINY, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_FLIGHTEVASION, 50, NA, NA, NULL); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_WHISPER, NA, "^flapping wings"); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_MASTER, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 0, NA, 1, NULL); addflag(lastrace->flags, F_TR, 0, NA, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); @@ -17655,18 +17763,18 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HITDICE, 0, NA, 1, NULL); addflag(lastrace->flags, F_TR, 1, NA, NA, NULL); - addflag(lastrace->flags, F_FLIGHTEVASION, 10, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 1, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "buzzes angrily^an angry buzzing"); - addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^buzzing"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^buzzing wings"); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_CORPSE, B_COVETS, NA, NULL); @@ -17691,18 +17799,18 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL); addflag(lastrace->flags, F_TR, 1, NA, NA, NULL); - addflag(lastrace->flags, F_FLIGHTEVASION, 5, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 1, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "buzzes angrily^an angry buzzing"); - addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^buzzing"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^buzzing wings"); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_CORPSE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); @@ -17724,17 +17832,18 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL); addflag(lastrace->flags, F_TR, 1, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 2, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 1, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "buzzes angrily^an angry buzzing"); - addflag(lastrace->flags, F_NOISETEXT, N_FLY, 2, NA, "^buzzing"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^buzzing wings"); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); @@ -17820,7 +17929,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "flares its flames^crackling flames"); addflag(lastrace->flags, F_DAMAGEGROUNDOBS, 2, DT_FIRE, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_FIRE, NA, "10"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_FIRE, NA, "10"); addrace(R_GLOWBUG, "glowbug", 1, 'i', C_WHITE, MT_FLESH, RC_INSECT, "Glowbugs are tiny flying creatures, magically producing light from their bodies."); setbodytype(lastrace, BT_BIRD); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); @@ -17834,14 +17943,14 @@ void initrace(void) { addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_HITDICE, 1, NA, 4, NULL); addflag(lastrace->flags, F_TR, 1, NA, NA, NULL); - addflag(lastrace->flags, F_FLIGHTEVASION, 15, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, 1, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_S_FLASH, 15, 15, "pw:4;"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "pulses"); @@ -17849,12 +17958,12 @@ void initrace(void) { addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_PRODUCESLIGHT, 3, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); - addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^buzzing"); + addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^buzzing wings"); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_PRODUCESLIGHT, 3, NA, "100"); + addflag(lastrace->flags, F_EATMUTATE, F_PRODUCESLIGHT, 3, NA, "100"); addrace(R_STINKBUG, "stinkbeetle", 1, 'x', C_MAGENTA, MT_FLESH, RC_INSECT, "A dog-sized beetle with tough scales. Emits a foul odour upon death."); setbodytype(lastrace, BT_QUADRAPED); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); @@ -18411,7 +18520,7 @@ void initrace(void) { addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_POISONCORPSE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_POISON, NA, "15"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_POISON, NA, "15"); addrace(R_WRAITHICE, "ice wraith", 20, 'Z', C_CYAN, MT_ICE, RC_UNDEAD, "Ice wraiths look like frozen humanoid forms, often garbed in threadbare clothing."); setbodytype(lastrace, BT_HUMANOID); @@ -18446,7 +18555,7 @@ void initrace(void) { addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SPRINT, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); - addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "15"); + addflag(lastrace->flags, F_EATMUTATE, F_DTRESIST, DT_COLD, NA, "15"); addrace(R_BANSHEE, "banshee", 50, 'p', C_BLUE, MT_FLESH, RC_UNDEAD, "A floating phantom, with wild unbrushed hair."); setbodytype(lastrace, BT_HUMANOID); @@ -18540,7 +18649,6 @@ void initrace(void) { addflag(lastrace->flags, F_XRAYVIS, 3, NA, 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_NATURALFLIGHT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_INDUCEFEAR, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_INVISIBILITY, 40, 40, "pw:1;"); addflag(lastrace->flags, F_LIFEOB, OT_CORPSE, 5, 4, NULL); @@ -18915,8 +19023,8 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, ""); - addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL); - addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); + addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL); addflag(lastrace->flags, F_TR, 1, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 300, NA, NA, NULL); @@ -18930,6 +19038,7 @@ void initrace(void) { addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_MASTER, NA, NULL); // special: fully heal if our origrace is a vampire, and we are resting over a coffin addrace(R_HECTASSERVANT, "skeletal hand", 20, 'Z', C_MAGENTA, MT_BONE, RC_UNDEAD, "An enormous skeletal hand."); addbodypart(lastrace, BP_WEAPON, NULL); @@ -18976,7 +19085,7 @@ void initrace(void) { addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); addflag(lastrace->flags, F_TR, 8, NA, NA, NULL); - addflag(lastrace->flags, F_FLIGHTEVASION, 30, NA, NA, NULL); + addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL); addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); @@ -19058,6 +19167,9 @@ void initrace(void) { addflag(r->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(r->flags, F_SEEINVIS, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); + } else if (r->raceclass->id == RC_INSECT) { + addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); } else if (r->raceclass->id == RC_DRAGON) { // wyrms hate hydras if (r->id != R_HYDRA) { @@ -19080,10 +19192,12 @@ void initrace(void) { addflag(r->flags, F_SEEINVIS, B_TRUE, NA, NA, NULL); addflag(r->flags, F_CANWILL, OT_S_PLANESHIFT, NA, NA, "pw:1;"); addflag(r->flags, F_FILLPOT, OT_POT_AMBROSIA, NA, NA, NULL); + addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); addflag(r->flags, F_GIFTTIMER, 0, 50, NA, NULL); } else if (r->raceclass->id == RC_MAGIC) { addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL); addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); } else if (r->raceclass->id == RC_PLANT) { addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL); addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); @@ -19094,6 +19208,7 @@ void initrace(void) { addflag(r->flags, F_FLAMMABLE, PERMENANT, NA, NA, NULL); addflag(r->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL); addflag(r->flags, F_DAYBOOST, 10, NA, NA, NULL); } else if (r->raceclass->id == RC_SLIME) { @@ -19101,6 +19216,7 @@ void initrace(void) { addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); } else if (r->raceclass->id == RC_ROBOT) { addflag(r->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL); @@ -19114,6 +19230,7 @@ void initrace(void) { addflag(r->flags, F_MORALE, 30, NA, NA, NULL); addflag(r->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); addflag(r->flags, F_BLOODOB, NA, NA, NA, "puddle of oil"); + addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); if (!hasflagval(r->flags, F_NOISETEXT, N_WALK, NA, NA, NULL)) { addflag(r->flags, F_NOISETEXT, N_WALK, 2, NA, "^whirring"); @@ -19192,6 +19309,7 @@ void initskills(void) { addskilldesc(SK_ARMOUR, PR_MASTER, "^gReduces armour penalties by 60%.^n", B_FALSE); addskill(SK_ATHLETICS, "Athletics", "Grants various athletic abilities and increases Stamina.", 50); addskillabil(SK_ATHLETICS, PR_NOVICE, OT_A_SPRINT, NA, NULL, B_TRUE); + addskilldesc(SK_ATHLETICS, PR_BEGINNER, "^gYour exceptional balance means that missed attacks no longer consume stamina.^n", B_FALSE); addskillabil(SK_ATHLETICS, PR_ADEPT, OT_A_TUMBLE, NA, NULL, B_TRUE); addskillabil(SK_ATHLETICS, PR_EXPERT, OT_A_JUMP, NA, NULL, B_TRUE); addskill(SK_BACKSTAB, "Backstabbing", "Lets you inflict massive damage when unseen and using a piercing weapon.", 50); @@ -19276,6 +19394,14 @@ void initskills(void) { addskilldesc(SK_FIRSTAID, PR_SKILLED, "+8 hit points per level.", B_FALSE); addskilldesc(SK_FIRSTAID, PR_EXPERT, "+10 hit points per level.", B_FALSE); addskilldesc(SK_FIRSTAID, PR_MASTER, "+12 hit points per level.", B_FALSE); + addskill(SK_FLIGHT, "Flight", "Determines your natural ability to fly (normally via wings).", 0); // untrainable + addskilldesc(SK_FIRSTAID, PR_INEPT, "- Each rank grants +5 evasion versus non-flying opponents.", B_FALSE); + addskilldesc(SK_FIRSTAID, PR_NOVICE, "You can hover low over the ground.", B_FALSE); + addskilldesc(SK_FIRSTAID, PR_BEGINNER, "You can fly a metre above the ground.", B_FALSE); + addskilldesc(SK_FIRSTAID, PR_ADEPT, "You can fly two metres above the ground.", B_FALSE); + addskilldesc(SK_FIRSTAID, PR_SKILLED, "You can fly three metres above the ground.", B_FALSE); + addskilldesc(SK_FIRSTAID, PR_EXPERT, "You can fly four metres above the ground.", B_FALSE); + addskilldesc(SK_FIRSTAID, PR_MASTER, "You can fly five metres above the ground.", B_FALSE); addskill(SK_LISTEN, "Listen", "How good you are at hearing and interpreting sounds.", 200); addskilldesc(SK_LISTEN, PR_NOVICE, "^gYou now gauge the distance of sounds.^n", B_TRUE); addskilldesc(SK_LISTEN, PR_BEGINNER, "^gYou can now determine the direction sounds are coming from.^n", B_TRUE); @@ -19389,8 +19515,8 @@ void initskills(void) { addskilldesc(SK_ENGINEERING, PR_BEGINNER, "You can now detect hollow spaces.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_BEGINNER, "You can now identify trap types.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_ADEPT, "You can now create barricades and basic traps.", B_TRUE); + addskilldesc(SK_ENGINEERING, PR_ADEPT, "You can now dismantle doors as well as obstacles.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_SKILLED, "You now automatically detect traps.", B_TRUE); - addskilldesc(SK_ENGINEERING, PR_SKILLED, "You can now dismantle doors as well as obstacles.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_EXPERT, "You can now create advanced traps.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_MASTER, "You are now immune to most trap effects.", B_TRUE); addskill(SK_THROWING, "Throwing", "Your accuracy when throwing objects at things.", 50); @@ -19420,11 +19546,11 @@ void initskills(void) { free(lastskill->shortname); lastskill->shortname = strdup("Lore:Chem"); addskilldesc(SK_LORE_CHEMISTRY, PR_NOVICE, "^gYou can attempt to identify potions with the 'inspect' ability.^n", B_FALSE); addskillabil(SK_LORE_CHEMISTRY, PR_NOVICE, OT_A_INSPECT, NA, NULL, B_FALSE); - addskilldesc(SK_LORE_CHEMISTRY, PR_NOVICE, "^gYou can now mix venom sacs into potions to create poison.", B_TRUE); - addskilldesc(SK_LORE_CHEMISTRY, PR_BEGINNER, "^gYou can now recognise very common potions.", B_TRUE); - addskilldesc(SK_LORE_CHEMISTRY, PR_ADEPT, "^gYou can now recognise common potions.", B_TRUE); - addskilldesc(SK_LORE_CHEMISTRY, PR_EXPERT, "^gYou can now recognise uncommon potions.", B_TRUE); - addskilldesc(SK_LORE_CHEMISTRY, PR_MASTER, "^gYou can now recognise rare potions.", B_TRUE); + addskilldesc(SK_LORE_CHEMISTRY, PR_NOVICE, "^gYou can now mix venom sacs into potions to create poison.^n", B_TRUE); + addskilldesc(SK_LORE_CHEMISTRY, PR_BEGINNER, "^gYou can now recognise very common potions.^n", B_TRUE); + addskilldesc(SK_LORE_CHEMISTRY, PR_ADEPT, "^gYou can now recognise common potions.^n", B_TRUE); + addskilldesc(SK_LORE_CHEMISTRY, PR_EXPERT, "^gYou can now recognise uncommon potions.^n", B_TRUE); + addskilldesc(SK_LORE_CHEMISTRY, PR_MASTER, "^gYou can now recognise rare potions.^n", B_TRUE); addskill(SK_LORE_DEMONS, "Lore:Demonology", "Determines your knowledge about demons.", 5); free(lastskill->shortname); lastskill->shortname = strdup("Lore:Demons"); addskillabil(SK_LORE_DEMONS, PR_NOVICE, OT_S_EXORCISE, NA, NULL, B_TRUE); @@ -19661,6 +19787,7 @@ void inittext(void) { addplural("scroll","scrolls", B_TRUE); addplural("splash","splashes", B_TRUE); addplural("set","sets", B_TRUE); + addplural("shard","shards", B_TRUE); addplural("sheet","sheets", B_TRUE); addplural("sprig","sprigs", B_TRUE); addplural("suit","suits", B_TRUE); diff --git a/data/hiscores.db b/data/hiscores.db index c86d086..a0794f0 100644 Binary files a/data/hiscores.db and b/data/hiscores.db differ diff --git a/defs.h b/defs.h index 375dd4a..610130b 100644 --- a/defs.h +++ b/defs.h @@ -568,6 +568,7 @@ enum SHOPACTION { #define FROMPOISON (-9862) #define FROMLYCANTHROPY (-9861) #define FROMGAMESTART (-9860) +#define FROMABIL (-9859) #define IMPOSSIBLE (9999) @@ -746,6 +747,7 @@ enum SKILL { SK_COOKING, SK_EVASION, SK_FIRSTAID, + SK_FLIGHT, SK_LISTEN, SK_LOCKPICKING, SK_METALWORK, @@ -795,7 +797,7 @@ enum SKILL { SK_SS_TRANSLOCATION, SK_SS_WILD, }; -#define MAXSKILLS 56 +#define MAXSKILLS 57 // proficiency levels enum SKILLLEVEL { @@ -2004,6 +2006,7 @@ enum OBTYPE { OT_A_FEIGNDEATH, OT_A_FLIP, OT_A_FLURRY, + OT_A_FLY, OT_A_FULLSHIELD, OT_A_GRAB, OT_A_CHARGE, @@ -2081,6 +2084,7 @@ enum OBTYPE { OT_LANTERNOIL, OT_LOCKPICK, OT_PANPIPES, + OT_PEACEPIPES, OT_PICKAXE, OT_ROPE, OT_SACK, @@ -2182,6 +2186,7 @@ enum OBTYPE { OT_FLESHCHUNK, OT_TUSK, OT_WOODPLANK, + OT_WOODSHARD, OT_METALSHEET, // trail objects OT_FOOTPRINT, @@ -2787,6 +2792,10 @@ enum FLAG { // v0 = radius to scatter new object in // (0 or NA means just convert the object) // v1 = dirtype for radius + F_BREAKOB, // if killed by damtype v0, change to + // object 'text'. + // IMPORTANT: can only have up to 2 of these per + // damage type. F_NOBLESS, // can't be blessed or cursed F_NOQUALITY, // can't be masterwork / shoddy F_NOSTEAL, // this object can't be stolen, blown away, etc. @@ -2883,6 +2892,7 @@ enum FLAG { F_CHARGEOUTMSG, // text = msg when charges are gone F_HELPSCLIMB, // object gives v0 bonus to sc_climb checks. F_HELPSDIG, // object can dig. does v0 dam to cells. + // also makes noise 'text' at volume v1 F_HELPSDISARM, // object gives v0 bonus to disarm trap checks. F_HELPSREPAIR, // object gives v1 bonus to repairing obejcts // made of material v0. Also decreases the @@ -2918,6 +2928,8 @@ enum FLAG { F_DRINKABLE, // you can drink this. val1 = nutrition. 100 = a meal // -1 means "nutrition is weight x abs(val1)" // if v2=DONTKILL, this object does NOT die when drunk. + F_OPERSOUND, // v0 = volume of sound when operating this + // text = noise F_OPERABLE, // can operate? F_OPERWITHOUTHANDS, // can operate without having hands or being // humanoid @@ -3230,6 +3242,8 @@ enum FLAG { // with vals v1,v2,text. // OR // eating this object gives it. + F_EATMUTATE, // same as eatconfer, but only works if you have + // f_mutable. // player only flags F_AICONTROLLED, // player will be controlled by the computer F_DONEBURNMSG, // tells the game not to say 'the {celltype} burns!' @@ -3282,6 +3296,7 @@ enum FLAG { // power. if not given, power comes from depth. F_NOSMELL, // lf can't smell. not affected by stench, and // can't get enhancesmell. + F_NOSTAM, // this lf has infinite stamina F_NOTALK, // override ability to talk F_NOGIVECRITS, // monsters can't take critical hits F_NOTAKECRITS, // monsters can't take critical hits @@ -3290,7 +3305,6 @@ enum FLAG { // v0 = max time allowed to rest before checkout // v1 = total time rested // text = obid of hotel - F_FLIGHTEVASION,// +v0 evasion if flying F_SWIMEVASION, // +v0 evasion if swimming F_ALIGNMENT, // v0 = al_good, al_neutral, al_evil. default neutral. // if al_none is selected for the player, they @@ -3537,6 +3551,10 @@ enum FLAG { // eg: text=="st" means they know of shops+traps F_NOJOBTEXT, // this lf's name is 'a xxx', not 'a xxx wizard' etc F_LASTDIR, // this is the last direction we moved. + F_LASTATTACKHIT, // did our last attack hit or miss? + // v0 = B_TRUE = hit + // v0 = B_FALSE = miss + //F_OWNERLASTDIR, // for pets, this it the last dir our owner moved // when we could see them. F_ISPRISONER, // this lf wants to escape to the surface @@ -3677,6 +3695,7 @@ enum FLAG { F_GODGIFTTEXT, // text = what the god says when you get a gift F_GODASK1, // text = how the god asks you to join them F_GODASK2, // text = how the god asks you to join them (2nd line) + F_GODDECLINE, // text = what the god says if you decline offer to join F_GODTEXTAPPEAR, // text = godname ->xxxxx<- (when they teleport in) F_GODOF, // text = what this lf is the god of. use capitals. F_GODLIKES, // text = something this god likes (ie. incs piety) @@ -3876,7 +3895,7 @@ enum FLAG { // lower chance of rare monsters F_EXTRAMP, // lf has +v0 % extra maxmp F_FEIGNINGDEATH, // lf is pretending to be dead - F_FLYING, // lf is flying + F_FLYING, // lf is flying. v0 = feet height F_FASTACT, // modifier for action speed F_FASTMETAB, // hunger counter increases faster, poison cures faster. // v0 is multiplier. @@ -4016,6 +4035,7 @@ enum FLAG { F_EATING, // lf is eating obid v0 F_DIGGING, // v0/v1 = cell where lf is digging. // v2 is how much to dig per turn. + // text = obid of tool we are using to dig. F_REPAIRING, // text = obid of held item we are repairing. F_TRAINING, // are we training? cleared on any action other than rest. // v0 = current training amount @@ -4556,6 +4576,7 @@ typedef struct habitat_s { int randvaultpct; // % chance that a room will be a vault //int maxvisrange; enum OBTYPE upstairtype, downstairtype; + int stairsinrooms; enum CELLTYPE emptycelltype,solidcelltype; struct habitat_s *next, *prev; } habitat_t; diff --git a/god.c b/god.c index 6132033..ea929c3 100644 --- a/god.c +++ b/god.c @@ -536,17 +536,24 @@ void askforworship(enum RACE rid) { say(god, getflagtext(god->flags, F_GODASK1), SV_TALK); more(); msg("\"%s\"", getflagtext(god->flags, F_GODASK2)); more(); - yn = askchar("Will you accept", "yn", "n", B_TRUE, B_FALSE); - if (yn == 'y') { - // should never be true, but check just in case... - if (!godprayedto(rid)) { - addflag(god->flags, F_PRAYEDTO, B_TRUE, NA, NA, NULL); + yn = '?'; + while (yn == '?') { + yn = askchar("Will you accept", "yn?", "n", B_TRUE, B_FALSE); + if (yn == '?') { + describegod(god); + } else if (yn == 'y') { + // should never be true, but check just in case... + if (!godprayedto(rid)) { + addflag(god->flags, F_PRAYEDTO, B_TRUE, NA, NA, NULL); + } + // always get a gift, but announce it first. + say(god, getflagtext(god->flags, F_GODGIFTTEXT), SV_TALK); more(); + godgiftmaybe(rid, B_TRUE, B_FALSE); + // increment piety so that it doesn't remain around the border. + modpiety(rid, PIETYPRAYLOSS); + } else { // ie. no + msg("\"%s\"", getflagtext(god->flags, F_GODDECLINE)); more(); } - // always get a gift, but announce it first. - say(god, getflagtext(god->flags, F_GODGIFTTEXT), SV_TALK); more(); - godgiftmaybe(rid, B_TRUE, B_FALSE); - // increment piety so that it doesn't remain around the border. - modpiety(rid, PIETYPRAYLOSS); } } @@ -1550,10 +1557,12 @@ int godgiftmaybe(enum RACE rid, int fromtemple, int announce) { wep = getweapon(player); if (wep && !hasflag(wep->flags, F_HASBRAND)) { char obname[BUFLEN]; + flag_t *f; getobname(wep,obname,1); // announce msg("Your %s vibrates, and you suddenly thirst for vengeance!", noprefix(obname)); - addflag(wep->flags, F_REVENGE, B_TRUE, NA, NA, NULL); + f = addflag(wep->flags, F_REVENGE, B_TRUE, NA, NA, NULL); + f->known = B_TRUE; } else { switch (rnd(1,7)) { case 1: diff --git a/io.c b/io.c index a1b08ce..836f718 100644 --- a/io.c +++ b/io.c @@ -742,6 +742,7 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t object_t *wep,*o; char extrainfo[BIGBUFLEN]; enum SKILLLEVEL lorelev; + int height = 0; lorelev = getlorelevel(player, c->lf->race->raceclass->id); strcpy(extrainfo, ""); getlfnamea(c->lf, buf); @@ -819,10 +820,12 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t // prevent showing 'prone' and 'asleep' if (strlen(extrainfo)) strcat(extrainfo, ", "); strcat(extrainfo, "prone"); - } else if (isairborne(c->lf)) { + } else if (isairborne(c->lf, &height)) { if (strlen(extrainfo)) strcat(extrainfo, ", "); if (lfhasflag(c->lf, F_FLYING)) { - strcat(extrainfo, "flying"); + char fbuf[BUFLEN]; + sprintf(fbuf, "flying:%d",height); + strcat(extrainfo, fbuf); } else if (lfhasflag(c->lf, F_LEVITATING)) { strcat(extrainfo, "levitating"); } else { @@ -1693,6 +1696,14 @@ int announceflaggain(lifeform_t *lf, flag_t *f) { donesomething = B_TRUE; } break; + case F_FREEZINGTOUCH: + if (isplayer(lf)) { // don't know if monsters get it + msg("Your hands begin to glow blue!"); + } else { + msg("%s%s hands begin to glow blue!", lfname, getpossessive(lfname)); + } + donesomething = B_TRUE; + break; case F_FULLSHIELD: o = hasobid(lf->pack, atol(f->text)); assert(o); @@ -2539,6 +2550,14 @@ int announceflagloss(lifeform_t *lf, flag_t *f) { msg("^%c%s %s less sick now.^n", getlfcol(lf, CC_VGOOD), lfname, isplayer(lf) ? "feel" : "looks"); donesomething = B_TRUE; break; + case F_FREEZINGTOUCH: + if (isplayer(lf)) { + msg("Your hands are no longer glowing blue."); + } else { + msg("%s%s hands are no longer glowing blue.", lfname, getpossessive(lfname)); + } + donesomething = B_TRUE; + break; case F_FULLSHIELD: msg("%s %s no longer fully shielded.", lfname, isplayer(lf) ? "are" : "is"); donesomething = B_TRUE; @@ -3292,7 +3311,7 @@ void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int fi long points; points = getobpoints(mylist[i]); if (points > 0) { - snprintf(pointsbuf, BUFLEN, " [%ld points]", points); + snprintf(pointsbuf, BUFLEN, " [%ld point%s]", points, (points == 1) ? "" : "s"); } } @@ -7725,7 +7744,6 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel break; case F_ENHANCESMELL: if (lorelev >= PR_BEGINNER) sprintf(buf, "Enhanced sense of smell (range %d)", f->val[0]); break; case F_FEARLESS: if (lorelev >= PR_BEGINNER) sprintf(buf, "Fearless"); break; - case F_FLIGHTEVASION: if (lorelev >= PR_BEGINNER) sprintf(buf, "%d%% evasion while flying", f->val[0]); break; case F_FLYING: if (lorelev >= PR_NOVICE) sprintf(buf, "Can fly at will"); break; case F_HEAVYBLOW: if (lorelev >= PR_ADEPT) sprintf(buf, "Attacks will knock enemies backwards"); break; case F_HITCONFER: @@ -11071,6 +11089,7 @@ void drawstatus(void) { enum ATTRIB a; int myatt[MAXATTS]; int xpleft; + int height; curs_set(0); wclear(statwin); @@ -11213,10 +11232,10 @@ void drawstatus(void) { unsetcol(statwin, C_BOLDBLUE); } - if (isairborne(player)) { + if (isairborne(player, &height)) { if (lfhasflag(player, F_FLYING)) { setcol(statwin, C_BOLDBLUE); - wprintw(statwin, " Fly"); + wprintw(statwin, " Fly:%d",height); unsetcol(statwin, C_BOLDBLUE); } else if (lfhasflag(player, F_LEVITATING)) { setcol(statwin, C_BOLDBLUE); diff --git a/lf.c b/lf.c index e3f9bbc..290ffea 100644 --- a/lf.c +++ b/lf.c @@ -660,6 +660,7 @@ int canbuild(lifeform_t *lf, objecttype_t *ot, char *needtext, enum OBTYPE *need return B_FALSE; } +// can lf cast spell/use ability 'oid' int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) { int castable = B_FALSE; flag_t *f; @@ -1236,8 +1237,8 @@ int canreach(lifeform_t *lf, lifeform_t *victim, int *reachpenalty) { // harder to hit flying/levitating enemies, or ones climbing // (ie they are higher than you) - lffootheight = getlfheight(lf); - victimfootheight = getlfheight(victim); + lffootheight = getfeetheight(lf); + victimfootheight = getfeetheight(victim); diff = victimfootheight - (getlfsize(lf) + lffootheight); @@ -1298,7 +1299,7 @@ int canreachbp(lifeform_t *lf, lifeform_t *victim, enum BODYPART bp) { // your reach is defined as anywhere between your feet and just over your // head. flying creatures have more leeway. - if (isairborne(lf)) { + if (isairborne(lf, NULL)) { topthresh = 3; bottomthresh = 2; } else { @@ -1343,7 +1344,7 @@ int cansee_real(lifeform_t *viewer, lifeform_t *viewee, int uselos) { } dist = getcelldist(viewer->cell, viewee->cell); f = lfhasflag(viewer, F_TREMORSENSE); - if (f && !isairborne(viewee) && !isairborne(viewer)) { + if (f && !isairborne(viewee, NULL) && !isairborne(viewer, NULL)) { if (f->val[0] > 0) { tremordist = f->val[0]; } else { @@ -1441,7 +1442,7 @@ int cansee_real(lifeform_t *viewer, lifeform_t *viewee, int uselos) { } // viewee underwater and more than 1 cell away? if ((getobdepth(o, viewee) >= DP_HEAD) && (dist > 1)) { - if (!isairborne(viewee)) { + if (!isairborne(viewee, NULL)) { return B_FALSE; } } @@ -2071,7 +2072,8 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar if (targlf && (f->val[2] == B_APPENDYOU)) { char targname[BUFLEN]; if (targlf == lf) { - strcpy(targname, "itself"); + strcpy(targname, it(lf)); + strcat(targname, "self"); } else { getlfname(targlf, targname); } @@ -2506,7 +2508,7 @@ int checkfordrowning(lifeform_t *lf, object_t *o) { flag_t *f; enum SKILLLEVEL slev; - if (isairborne(lf)) { + if (isairborne(lf, NULL)) { return B_FALSE; } @@ -2725,6 +2727,7 @@ void copycorpseflags(flagpile_t *dst, flagpile_t *src) { int continuedigging(lifeform_t *lf) { cell_t *c; flag_t *f = NULL; + object_t *digob = NULL; int digpower; int stopnow = B_FALSE; @@ -2736,6 +2739,18 @@ int continuedigging(lifeform_t *lf) { if (!f) { stopnow = B_TRUE; } + + if (!stopnow && strlen(f->text)) { + long obid; + // do we still ahve the object we were using to dig? + obid = atol(f->text); + + digob = hasobid(lf->pack, obid); + if (!digob) { + stopnow = B_TRUE; + } + } + if (!stopnow) { c = getcellat(lf->cell->map, f->val[0], f->val[1]); if (!c) { @@ -2748,6 +2763,8 @@ int continuedigging(lifeform_t *lf) { return B_TRUE; } + if (digob) makeopersound(lf->cell,digob); + digpower = f->val[2]; c->hp -= digpower; if (c->hp <= 0) { @@ -2867,6 +2884,8 @@ int continuerepairing(lifeform_t *lf, flag_t *repairflag) { } + if (helpob) makeopersound(lf->cell,helpob); + // take some time. taketime(lf, getactspeed(lf)); @@ -4353,8 +4372,16 @@ int digcell(lifeform_t *lf, cell_t *c, object_t *o) { if (c->type->solid) { turntoface(lf, c); if (isdiggable(c)) { + char digoid[BUFLEN]; // start digging! - addflag(lf->flags, F_DIGGING, c->x, c->y, digpower, NULL); + if (o) { + sprintf(digoid, "%ld",o->id); + } else { + strcpy(digoid,""); + } + + addflag(lf->flags, F_DIGGING, c->x, c->y, digpower, digoid); + if (isplayer(lf)) { msg("You start digging into %s %s.", needan(c->type->name) ? "an" : "a", c->type->name); needredraw = B_TRUE; @@ -4491,7 +4518,7 @@ int digup(lifeform_t *lf, object_t *o) { // if digging with an object, you must be able to reach the roof if (o) { - if (!isairborne(lf)) { + if (!isairborne(lf, NULL)) { if (isplayer(lf)) { msg("You can't reach the roof!"); } @@ -4984,6 +5011,9 @@ int eat(lifeform_t *lf, object_t *o) { if (fullyeaten) { // special cases if (!hasflag(o->flags, F_TAINTED)) { + flag_t *mutable = NULL; + flag_t *retflag[MAXCANDIDATES]; + int nretflags,i; if (hasflagval(o->flags, F_CORPSEOF, R_NEWT, NA, NA, NULL)) { // think "eye of newt" gainmp(lf, 2); @@ -5005,65 +5035,63 @@ int eat(lifeform_t *lf, object_t *o) { } // most eat effects only happen if you have f_MUTABLE. - if (lfhasflag(lf, F_MUTABLE)) { - flag_t *retflag[MAXCANDIDATES]; - int nretflags,i; - getflags(o->flags, retflag, &nretflags, F_EATCONFER, F_NONE); - for (i = 0; i < nretflags; i++) { - f = retflag[i]; - if (f->val[0] != F_MUTABLE) { - int chance; - int luckmod = 0; - chance = atoi(f->text); - sumflags(lf->flags, F_EXTRALUCK, &luckmod, NULL, NULL); - chance += (luckmod*5); - limit(&chance, 0, 100); - if (pctchance(chance)) { - enum FLAG fid; - int val[2]; - fid = f->val[0]; - val[0] = f->val[1]; - val[1] = f->val[2]; - // already got this? + mutable = lfhasflag(lf, F_MUTABLE); + + getflags(o->flags, retflag, &nretflags, F_EATCONFER, F_EATMUTATE, F_NONE); + for (i = 0; i < nretflags; i++) { + int chance; + int luckmod = 0; + f = retflag[i]; + if ((f->id == F_EATMUTATE) && !mutable) continue; + + chance = atoi(f->text); + sumflags(lf->flags, F_EXTRALUCK, &luckmod, NULL, NULL); + chance += (luckmod*5); + limit(&chance, 0, 100); + if (pctchance(chance)) { + enum FLAG fid; + int val[2]; + fid = f->val[0]; + val[0] = f->val[1]; + val[1] = f->val[2]; + // already got this? + if (lfhasflag(lf, fid)) { + int changed = B_FALSE; + // sometimes improve it + switch (fid) { + case F_DTRESIST: fid = F_DTIMMUNE; changed = B_TRUE; break; + case F_SEEINDARK: + case F_PRODUCESLIGHT: + break; // can have multiple. + default: fid = F_NONE; break; + } + // still got the new one? + if (changed && (fid != F_NONE)) { if (lfhasflag(lf, fid)) { - int changed = B_FALSE; - // sometimes improve it - switch (fid) { - case F_DTRESIST: fid = F_DTIMMUNE; changed = B_TRUE; break; - case F_SEEINDARK: - case F_PRODUCESLIGHT: - break; // can have multiple. - default: fid = F_NONE; break; - } - // still got the new one? - if (changed && (fid != F_NONE)) { - if (lfhasflag(lf, fid)) { - fid = F_NONE; - } - } - } - if (fid != F_NONE) { - // lose half your max hp! - losehp_real(lf, (lf->maxhp/2), DT_DIRECT, NULL, - "the shock of mutation", - B_NODAMADJUST, o, B_NORETALIATE, NULL, B_DAMEFFECTS, - BP_NONE); - if (isplayer(lf)) { - msg("^%cYou convulse in agony as your body mutates!", - getlfcol(lf, CC_BAD)); - } else if (cansee(player, lf)) { - msg("^%c%s convulses in agony as its body mutates!", - getlfcol(lf, CC_BAD), lfname); - } - // still alive? you gain the ability! - if (!isdead(lf)) { - addflag(lf->flags, fid, val[0], val[1], NA, NULL); - } + fid = F_NONE; } - } // end if pctchance - } // end if v0 not f_mutable - } // end foreach f_eatconfer flag - } // end if lf has f_mutable + } + } + if (fid != F_NONE) { + // lose half your max hp! + losehp_real(lf, (lf->maxhp/2), DT_DIRECT, NULL, + "the shock of mutation", + B_NODAMADJUST, o, B_NORETALIATE, NULL, B_DAMEFFECTS, + BP_NONE); + if (isplayer(lf)) { + msg("^%cYou convulse in agony as your body mutates!", + getlfcol(lf, CC_BAD)); + } else if (cansee(player, lf)) { + msg("^%c%s convulses in agony as its body mutates!", + getlfcol(lf, CC_BAD), lfname); + } + // still alive? you gain the ability! + if (!isdead(lf)) { + addflag(lf->flags, fid, val[0], val[1], NA, NULL); + } + } + } // end if pctchance + } // end foreach f_eatconfer flag } // end if !tainted // special cases for object types @@ -5903,7 +5931,7 @@ int fall(lifeform_t *lf, lifeform_t *fromlf, int announce) { if (isdead(lf)) return B_TRUE; if (isprone(lf)) return B_TRUE; - if (!isairborne(lf)) { + if (!isairborne(lf, NULL)) { if ((lfhasflag(lf, F_STABILITY) || !hasbp(lf, BP_FEET))) { return B_TRUE; } @@ -7833,10 +7861,10 @@ int getevasion(lifeform_t *lf) { } // flightevasion creatures get extra evasion while flying - f = lfhasflag(lf, F_FLIGHTEVASION); - if (f && (isairborne(lf) == F_FLYING)) { - ev += f->val[0]; - } + //f = lfhasflag(lf, F_FLIGHTEVASION); + //if (f && (isairborne(lf) == F_FLYING)) { +// ev += f->val[0]; +// } ////////////////////////////////////////////////// // now negative modifiers @@ -8677,32 +8705,27 @@ enum LFCONDITION getlfcondition(lifeform_t *lf) { // returns a value representing 'lf's height off the ground. // higher value means higher -int getlfheight(lifeform_t *lf) { +int getfeetheight(lifeform_t *lf) { int height = 0; - switch (isairborne(lf)) { - case F_FLYING: - height += SZ_HUMAN; - break; - case F_LEVITATING: - height += SZ_MEDIUM; - break; - default: - // climbing a wall? - if (isclimbing(lf)) { - if (height < SZ_LARGE) height = SZ_LARGE; - } else { - object_t *o; - // is lf climbing on top of something, or on a wall? - o = hasobwithflag(lf->cell->obpile, F_CLIMBOBSTACLE); - if (o) { - flag_t *f; - f = hasflag(o->flags, F_IMPASSABLE); - if (f && (f->val[0] > 0)) { - height += f->val[0]; - } - } - } - break; + int temph; + if (isairborne(lf, &temph)) { + height += temph; + } else { + // climbing a wall? + if (isclimbing(lf)) { + if (height < SZ_LARGE) height = SZ_LARGE; + } else { + object_t *o; + // is lf climbing on top of something, or on a wall? + o = hasobwithflag(lf->cell->obpile, F_CLIMBOBSTACLE); + if (o) { + flag_t *f; + f = hasflag(o->flags, F_IMPASSABLE); + if (f && (f->val[0] > 0)) { + height += f->val[0]; + } + } + } } return height; } @@ -8728,16 +8751,6 @@ int getlistendetectrange(lifeform_t *lf) { return 0; } -int getfeetheight(lifeform_t *lf) { - int howmuch = 0; - switch (isairborne(lf)) { - case F_FLYING: howmuch = SZ_HUMAN; break; - case F_LEVITATING: howmuch = SZ_SMALL; break; - default: break; - } - return howmuch; -} - int getmasterid(lifeform_t *lf) { flag_t *f; f = lfhasflag(lf, F_PETOF); @@ -8813,6 +8826,19 @@ int getmorale(lifeform_t *lf) { return gettr(lf); } +int getnaturalflightheight(lifeform_t *lf) { + switch (getskill(lf, SK_FLIGHT)) { + case PR_NOVICE: return SZ_SMALL; + case PR_BEGINNER: return SZ_MEDIUM; + case PR_ADEPT: return SZ_HUMAN; + case PR_SKILLED: return SZ_LARGE; + case PR_EXPERT: return SZ_HUGE; + case PR_MASTER: return SZ_ENORMOUS; + default: break; + } + return 0; +} + int getnextshortcut(lifeform_t *lf) { flag_t *retflag[MAXCANDIDATES]; int nretflags,i,min = 0; @@ -9523,7 +9549,7 @@ int getmovespeed(lifeform_t *lf) { } else if (f->id == F_HIDING) { speed += 10; } else if (f->id == F_INJURY) { - if (!isairborne(lf)) { + if (!isairborne(lf, NULL)) { switch (f->val[0]) { case IJ_LEGBROKEN: case IJ_HAMSTRUNG: @@ -9533,7 +9559,7 @@ int getmovespeed(lifeform_t *lf) { } } } else if (f->id == F_SPRINTING) { - if (!isairborne(lf)) { + if (!isairborne(lf, NULL)) { speed -= 10; } } @@ -10103,11 +10129,21 @@ int getstamina(lifeform_t *lf) { return (int)floor(lf->stamina); } +int getstaminapct(lifeform_t *lf) { + float max; + max = getmaxstamina(lf); + if ((max == 0) || lfhasflag(lf, F_NOSTAM)) return 100; + return ((float)lf->stamina / max) * 100.0; +} + float getstamregen(lifeform_t *lf) { float regenrate = STAMREGEN; flag_t *retflag[MAXCANDIDATES]; int nretflags,i; + // flying with wings? + if (isflyingwithwings(lf)) return 0; + if (lfhasflag(lf, F_TRAINING)) { // don't regain stamina while training! return 0; @@ -10122,9 +10158,11 @@ float getstamregen(lifeform_t *lf) { } } - getflags(lf->flags, retflag, &nretflags, F_STAMREGEN, F_NONE); + getflags(lf->flags, retflag, &nretflags, F_STAMREGEN, F_FLYING, F_NONE); for (i = 0; i < nretflags; i++) { - regenrate += atof(retflag[i]->text); + if (retflag[i]->id == F_STAMREGEN) { + regenrate += atof(retflag[i]->text); + } } limitf(®enrate, 0, NA); @@ -11823,6 +11861,17 @@ flag_t *giveskill(lifeform_t *lf, enum SKILL id) { } } + if (id == SK_FLIGHT) { + flag_t *f; + int h; + // adjust flight height if we're already flying. + h = getnaturalflightheight(lf); + f = lfhasflag(lf, F_FLYING); + if (f && (f->val[0] < h)) { + f->val[0] = h; + } + } + if (id == SK_ARMOUR) { if ((gamemode == GM_GAMESTARTED) && isplayer(lf)) { if (isplayer(lf)) pleasegodmaybe(R_GODBATTLE, 5); @@ -13784,13 +13833,23 @@ int haslos_fast(lifeform_t *viewer, cell_t *dest) { return B_FALSE; } -enum FLAG isairborne(lifeform_t *lf) { +enum FLAG isairborne(lifeform_t *lf, int *height) { + flag_t *f; + + if (height) *height = 0; + if (!lf) return B_FALSE; - if (lfhasflag(lf, F_FLYING)) { + f = lfhasflag(lf, F_FLYING); + if (f) { + if (height) *height = f->val[0]; return F_FLYING; - } else if (lfhasflag(lf, F_LEVITATING)) { + } + if (lfhasflag(lf, F_LEVITATING)) { + if (height) *height = SZ_MEDIUM; return F_LEVITATING; - } else if (lfhasflag(lf, F_ICESLIDE)) { + } + if (lfhasflag(lf, F_ICESLIDE)) { + if (height) *height = SZ_MEDIUM; return F_LEVITATING; } return F_NONE; @@ -14037,6 +14096,18 @@ flag_t *isfleeingfrom(lifeform_t *lf, lifeform_t *runfrom) { return lfhasflagval(lf, F_FLEEFROM, runfrom->id, NA, NA, NULL); } +int isflyingwithwings(lifeform_t *lf) { + flag_t *retflag[MAXCANDIDATES]; + int nretflags,i; + getflags(lf->flags, retflag, &nretflags, F_FLYING, F_NONE); + for (i = 0; i < nretflags; i++) { + if (retflag[i]->lifetime == FROMABIL) { + return B_TRUE; + } + } + return B_FALSE; +} + int isfreebp(lifeform_t *lf, enum BODYPART bp) { if (hasobwithflagval(lf->pack, F_EQUIPPED, bp, NA, NA, NULL)) return B_FALSE; @@ -14882,7 +14953,7 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos // footprints first if (doprints) { - if (!isairborne(lf) && !lfhasflag(lf, F_NONCORPOREAL)) { + if (!isairborne(lf, NULL) && !lfhasflag(lf, F_NONCORPOREAL)) { int fpdir; if (getskill(lf, SK_PERCEPTION) >= PR_EXPERT) { // no footprints! @@ -14926,7 +14997,7 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos void adjustspeedforwater(lifeform_t *lf, int *speed) { object_t *o; flag_t *f; - if (!isairborne(lf)) { + if (!isairborne(lf, NULL)) { for (o = lf->cell->obpile->first ; o ; o = o->next) { f = hasflag(o->flags, F_DEEPWATER); if (f) { @@ -15862,7 +15933,7 @@ int isswimming(lifeform_t *lf) { if (gamemode != GM_GAMESTARTED) { return B_FALSE; } - if (!isairborne(lf) && (getcellwaterdepth(lf->cell, lf) >= DP_WAIST) && + if (!isairborne(lf, NULL) && (getcellwaterdepth(lf->cell, lf) >= DP_WAIST) && getskill(lf, SK_SWIMMING)) { return B_TRUE; } @@ -16640,7 +16711,7 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr noise(lf->cell, NULL, NC_OTHER, SV_CAR, "arcing electricity", NULL); for (i = 0 ; i < nretcells; i++) { if (retcell[i]->lf && (retcell[i]->lf != lf)) { - if (!isairborne(retcell[i]->lf)) { + if (!isairborne(retcell[i]->lf, NULL)) { losehp_real(retcell[i]->lf, dam, DT_ELECTRIC, fromlf, "an electric shock", B_TRUE, NULL, B_FALSE, NULL, B_FALSE, BP_NONE); } } @@ -17488,16 +17559,8 @@ void modstamina(lifeform_t *lf, float howmuch) { if (howmuch == 0) return; - // some raceclasses have infinite stamina - switch (getraceclass(lf)) { - case RC_PLANT: - case RC_ROBOT: - case RC_GOD: - case RC_MAGIC: - case RC_SLIME: - case RC_DEMON: - return; - default: break; + if (lfhasflag(lf, F_NOSTAM)) { + return; } if (isundead(lf)) return; @@ -17643,14 +17706,19 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, int dist; int difficulty; int lbonus; + int myvol; int nwalls = 0; - flag_t *f; + flag_t *sleepflag; if (l == noisemaker) continue; // ie. if this lf is in the process of swapping places if (!l->cell) continue; + sleepflag = lfhasflag(l, F_ASLEEP); + // can't hear while unconscious + if (sleepflag && (sleepflag->val[1] == ST_KO)) continue; + dist = getcelldist(l->cell, c); // listen check difficulty is based on sound distance vs max hearing distance @@ -17666,19 +17734,23 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, difficulty = (int) ( ((float) dist / ((float)gethearingrange(l) + volume)) * 75); } + if (sleepflag) { + myvol = volume - 1; + } else { + myvol = volume; + } + limit(&myvol, 0, NA); + // listen bonus is based on sound volume - lbonus = volume; - f = lfhasflag(l, F_ASLEEP); - if (f) { - // can't hear while unconscious - if (f->val[1] == ST_KO) continue; - lbonus -= 6; + lbonus = myvol; + if (sleepflag) { + lbonus -= 5; limit(&lbonus, 0, NA); } // skillcheck to hear this if ( (isplayer(l) && haslos(l, c)) || // only player can "hear by seeing" - (canhear(l, c, volume, &nwalls) && (alwayshear || skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) ) { + (canhear(l, c, myvol, &nwalls) && (alwayshear || skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) ) { flag_t *f; // announce? if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) { @@ -17824,8 +17896,8 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, practice(l, SK_LISTEN, 1); } // migraine? - if ((volume > 1) && lfhasflagval(l, F_POISONED, P_MIGRAINE, NA, NA, NULL)) { - losehp(l, (volume-1), DT_SONIC, NULL, "a migraine"); + if ((myvol > 1) && lfhasflagval(l, F_POISONED, P_MIGRAINE, NA, NA, NULL)) { + losehp(l, (myvol-1), DT_SONIC, NULL, "a migraine"); if (isplayer(l)) { msg("Your head explodes in pain at the sound!"); } @@ -17837,7 +17909,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, f = lfhasflag(l, F_ASLEEP); if (f && (f->val[1] != ST_KO)) { if (f->lifetime > 0) { // ie. temporary - timeeffectsflag(f, volume + rnd(1,3)); + timeeffectsflag(f, myvol + rnd(1,3)); } else if (f->lifetime == PERMENANT) { if (f->val[2] == NA) { // ie asleep rather than 'resting' @@ -17850,7 +17922,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, } else { // ie resting on purpose via 'R' // only wake up if the sound if very close - if (volume >= getcelldist(c, l->cell)) { + if (myvol >= getcelldist(c, l->cell)) { // wake up! if (isplayer(l)) { char wakenoise[BUFLEN]; @@ -17906,7 +17978,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, } if (targlf && (targlf->cell)) { // ie. not swapping places if (getcelldist(l->cell, c) < getcelldist(l->cell, targlf->cell)) { - if ((volume >= 4) && onein(2)) { + if ((myvol >= 4) && onein(2)) { willrespond = B_TRUE; } } @@ -17953,7 +18025,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, } else { int chasetime; // if NOT within lof, go and investigate - chasetime = volume * 10; + chasetime = myvol * 10; aigoto(l, c, MR_SOUND, NULL, chasetime); } } @@ -19181,7 +19253,7 @@ int startresting(lifeform_t *lf, int willtrain) { // player can't rest while in the air, unless you're in a motel room if (isplayer(lf)) { - if (isairborne(lf) && !lfhasflag(lf, F_RESTINGINMOTEL)) { + if (isairborne(lf, NULL) && !lfhasflag(lf, F_RESTINGINMOTEL)) { msg("You can't %s while airborne!", willtrain ? "train" : "rest"); return B_TRUE; } @@ -20548,7 +20620,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) { //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging - if (lfhasflag(lf, F_NATURALFLIGHT) && !isairborne(lf)) { + if (lfhasflag(lf, F_NATURALFLIGHT) && !isairborne(lf, NULL)) { if (cancast(lf, OT_S_FLIGHT, NULL)) { notime = B_TRUE; castspell(lf, OT_S_FLIGHT, lf, NULL, lf->cell, NULL, NULL); @@ -21401,7 +21473,7 @@ int slipon(lifeform_t *lf, object_t *o) { char obname[BUFLEN]; char lfname[BUFLEN]; - if (lfhasflag(lf, F_NONCORPOREAL) || isairborne(lf)) { + if (lfhasflag(lf, F_NONCORPOREAL) || isairborne(lf, NULL)) { return B_TRUE; } @@ -21542,6 +21614,7 @@ void startlfturn(lifeform_t *lf) { int movedlastturn = B_FALSE; object_t *bloodamu = NULL; enum TIMEPHASE tp; + enum FLAG inair = F_NONE; tp = gettimephase(); map = lf->cell->map; @@ -21627,11 +21700,11 @@ void startlfturn(lifeform_t *lf) { killflagsofid(lf->flags, F_DONELISTEN); killflagsofid(lf->flags, F_DONEBURNMSG); killflagsofid(lf->flags, F_NOSWAP); + killflagsofid(lf->flags, F_LASTATTACKHIT); movedlastturn = 0; movedlastturn += killflagsofid(lf->flags, F_HASBEENMOVED); movedlastturn += killflagsofid(lf->flags, F_MOVED); - // if we didn't turn lsat move, kill our turncounter if (!killflagsofid(lf->flags, F_TURNED)) { lf->turncounter = 0; @@ -22467,8 +22540,13 @@ void startlfturn(lifeform_t *lf) { } // if you are stunned and flying, you fall - if (isairborne(lf) && lfhasflag(lf, F_STUNNED)) { - fall_from_air(lf); + inair = isairborne(lf, NULL); + if (inair) { + if (lfhasflag(lf, F_STUNNED)) { + fall_from_air(lf); + } else if (isburdened(lf)) { + fall_from_air(lf); + } } getflags(lf->flags, retflag, &nretflags, F_POISONED, F_NONE); @@ -22848,7 +22926,7 @@ void startlfturn(lifeform_t *lf) { for (i = 0; i < nretflags; i++) { f = retflag[i]; if (f->id == F_WALKDAMBP) { - if (!isairborne(lf)) { + if (!isairborne(lf, NULL)) { object_t *armour; int dam; enum BODYPART bp; @@ -23677,7 +23755,7 @@ void timeeffectslf(lifeform_t *lf) { while (o && donesomething) { int willfall = B_FALSE; donesomething = B_FALSE; - if ((dir == D_DOWN) && !isairborne(lf)) { + if ((dir == D_DOWN) && !isairborne(lf, NULL)) { object_t *amu; willfall = B_TRUE; @@ -24061,7 +24139,7 @@ int real_touch(lifeform_t *lf, object_t *o, int onpurpose) { if (isplayer(lf)) { msg("^bOw! You burn your hands on %s.",obname); } else if (cansee(player, lf)) { - msg("%s burns itself on %s.",lfname, obname); + msg("%s burns %sself on %s.",lfname, it(lf), obname); } snprintf(buf, BUFLEN, "touching %s",obname); if (f->id == F_ONFIRE) { @@ -24553,7 +24631,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) { // if we just climbed up through a hole, and are not flying, we want to // end up adjacent to the hole in the ground. otherwise we'll just fall // straight back down! - if (hasflag(o->flags, F_PIT) && (dir == D_UP) && !isairborne(lf)) { + if (hasflag(o->flags, F_PIT) && (dir == D_UP) && !isairborne(lf, NULL)) { cell_t *noholecell; noholecell = real_getrandomadjcell(newcell, &ccwalkable, B_ALLOWEXPAND, LOF_NEED, NULL, NULL ); if (noholecell) { @@ -24585,7 +24663,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) { moveto(lf, newcell, onpurpose, B_TRUE); // take time - if ((dir == D_UP) && !isairborne(lf)) { + if ((dir == D_UP) && !isairborne(lf, NULL)) { stopsprinting(lf); // you can sprint down stairs, but not up if (onpurpose) taketime(lf, getmovespeed(lf)*2); // takes longer to climb } else { @@ -24602,7 +24680,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) { stopsprinting(adjally[n]); movelf(adjally[n], c, B_TRUE); climbtime = getmovespeed(adjally[n]); - if ((dir == D_UP) && !isairborne(adjally[n])) { + if ((dir == D_UP) && !isairborne(adjally[n], NULL)) { climbtime *= 2; } if (onpurpose) taketime(adjally[n], climbtime); @@ -24809,7 +24887,13 @@ int validateraces(void) { if (!hasflag(r->flags, F_TR)) { printf("ERROR in race '%s' - missing F_TR (threat level).\n", r->name); goterror = B_TRUE; + } + if (hasflagval(r->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL)) { + if (!getskill(lf,SK_FLIGHT)) { + printf("ERROR in race '%s' - has flight but no flight skill.\n", r->name); + goterror = B_TRUE; + } } if (hasflag(r->flags, F_CANCAST) && !hasflag(r->flags, F_CASTWITHOUTIQ)) { diff --git a/lf.h b/lf.h index 7e4e2ed..a6d93fc 100644 --- a/lf.h +++ b/lf.h @@ -207,14 +207,14 @@ int getleftrightwalls(lifeform_t *lf); int getlfaccuracy(lifeform_t *lf, object_t *wep); char getlfcol(lifeform_t *lf, enum MSGCHARCOL cc); enum LFCONDITION getlfcondition(lifeform_t *lf); -int getlfheight(lifeform_t *lf); -int getlistendetectrange(lifeform_t *lf); int getfeetheight(lifeform_t *lf); +int getlistendetectrange(lifeform_t *lf); int getmasterid(lifeform_t *lf); enum SKILLLEVEL getmaxskilllevel(lifeform_t *lf, enum SKILL skid); int getminions(lifeform_t *lf, lifeform_t **minion, int *nminions); int getmiscastchance(lifeform_t *lf); int getmorale(lifeform_t *lf); +int getnaturalflightheight(lifeform_t *lf); int getnextshortcut(lifeform_t *lf); int getnightvisrange(lifeform_t *lf); int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, flag_t *noiseflag, char *heartext,char *seetext, int *volume, flag_t **returnedflag); @@ -259,6 +259,7 @@ int getallshields(lifeform_t *lf, enum DAMTYPE damtype, object_t **retob, int *c int getshieldblockmod(lifeform_t *lf, object_t *o); int getspellspeed(lifeform_t *lf); int getstamina(lifeform_t *lf); +int getstaminapct(lifeform_t *lf); float getstamregen(lifeform_t *lf); char *getplayername(char *buf); char *getplayernamefull(char *buf); @@ -348,7 +349,7 @@ int haslos(lifeform_t *viewer, cell_t *dest); //int haslosdark(lifeform_t *viewer, cell_t *dest); int haslos_fast(lifeform_t *viewer, cell_t *dest); void interrupt(lifeform_t *lf); -enum FLAG isairborne(lifeform_t *lf); +enum FLAG isairborne(lifeform_t *lf, int *height); int isaquatic(lifeform_t *lf); flag_t *isasleep(lifeform_t *lf); int isbehind(lifeform_t *lf, lifeform_t *otherlf); @@ -362,6 +363,7 @@ int isdeaf(lifeform_t *lf); object_t *isdualweilding(lifeform_t *lf); flag_t *isfleeing(lifeform_t *lf); flag_t *isfleeingfrom(lifeform_t *lf, lifeform_t *runfrom); +int isflyingwithwings(lifeform_t *lf); int isfreebp(lifeform_t *lf, enum BODYPART bp); int isfriendly(lifeform_t *lf); int isfullyhealed(lifeform_t *lf); diff --git a/map.c b/map.c index 424d04e..255fe0d 100644 --- a/map.c +++ b/map.c @@ -98,7 +98,7 @@ cell_t *addcell(map_t *m, int x, int y) { return cell; } -habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell, int thingchance, int obchance, int vaultchance, int maxvisrange, enum OBTYPE upstairtype, enum OBTYPE downstairtype) { +habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell, int thingchance, int obchance, int vaultchance, int maxvisrange, enum OBTYPE upstairtype, enum OBTYPE downstairtype, int stairsinrooms) { habitat_t *a; // add to the end of the list if (firsthabitat == NULL) { @@ -126,6 +126,7 @@ habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum //a->maxvisrange = maxvisrange; a->upstairtype = upstairtype; a->downstairtype = downstairtype; + a->stairsinrooms = stairsinrooms; return a; } @@ -3089,6 +3090,10 @@ int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int if (cell->lf && isplayer(cell->lf)) { valid = B_FALSE; continue; } + // - overlap a cell with an important object + if (hasobwithflag(cell->obpile, F_IMPORTANT)) { + valid = B_FALSE; continue; + } /* // - overlap the inside of an existing room if (cellwalkable(NULL, cell, NULL) && isroom(cell)) { @@ -5051,7 +5056,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex for (x = 0; x < map->w; x++) { cell_t *c; c = getcellat(map, x, y); - if (c) { + if (c && !hasobwithflag(c->obpile, F_IMPORTANT)) { // add random obs, but not in vaults if (isempty(c)) { if (!getcellvault(c) || (c->habitat->id == H_HEAVEN)) { @@ -7079,8 +7084,10 @@ int finalisemap(map_t *map, object_t *entryob, int exitdir) { initcondv(&okforstairs, CC_EMPTY, B_TRUE, NA, CC_OKFORSTAIRS, B_TRUE, NA, - CC_ISROOM, B_TRUE, NA, CC_NONE); + if (map->habitat->stairsinrooms) { + addcond(&okforstairs, CC_ISROOM, B_TRUE, NA); + } // make sure this map has sufficient up/down staircases as defined by its // region type. @@ -7403,9 +7410,10 @@ void finalisemonster(lifeform_t *lf, lifeform_t *leader, flagpile_t *wantflags, killflagsofid(lf->flags, F_HIDING); } else { if (hasflag(lf->race->flags, F_NATURALFLIGHT) && !lfhasflag(lf, F_FLYING)) { - if (cancast(lf, OT_S_FLIGHT, NULL)) { + if (cancast(lf, OT_A_FLY, NULL) && !isburdened(lf)) { notime = B_TRUE; - castspell(lf, OT_S_FLIGHT, lf, NULL, lf->cell, NULL, NULL); + //castspell(lf, OT_S_FLIGHT, lf, NULL, lf->cell, NULL, NULL); + useability(lf, OT_A_FLY, lf, lf->cell); notime = B_FALSE; } } @@ -8447,19 +8455,19 @@ object_t *hastrailof(obpile_t *op, lifeform_t *lf, enum OBTYPE oid, flag_t **tfl void initmap(void) { // habitats - // thingchance, obchance, vaultchance, maxvisrange, upstiartype, downstairtype - addhabitat(H_DUNGEON, "dungeon", CT_CORRIDOR, CT_WALL, 5, 60, 30, 6, OT_STAIRSUP, OT_STAIRSDOWN); - addhabitat(H_CAVE, "cave", CT_DIRT, CT_WALLDIRT, 10, 45, 20, 6, OT_TUNNELUP, OT_TUNNELDOWN); - addhabitat(H_FOREST, "forest", CT_GRASS, CT_WALLTREE, 5, 75, 0, MAXVISRANGE, OT_TREEUP, OT_TREEDOWN); - addhabitat(H_HEAVEN, "heaven", CT_CORRIDOR, CT_WALLGLASS, 5, 0, 0, MAXVISRANGE, OT_NONE, OT_NONE); - addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5, OT_NONE, OT_NONE); - addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 5, 70, 0, MAXVISRANGE, OT_NONE, OT_NONE); - addhabitat(H_SEWER, "sewer", CT_MOSSROCK, CT_WALL, 10, 50, 0, MAXVISRANGE, OT_GRATINGROOF, OT_NONE); - addhabitat(H_STOMACH, "stomach", CT_FLOORFLESH, CT_WALLFLESH, 5, 80, 0, MAXVISRANGE, OT_NONE, OT_NONE); - addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 5, 50, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN); - addhabitat(H_BYHUT, "babayaga's hut", CT_FLOORWOOD, CT_WALLDWOOD, 0, 0, 0, MAXVISRANGE, OT_BYHUTDOOR, OT_NONE); - addhabitat(H_ANTNEST, "ant nest", CT_DIRT, CT_WALLDIRT, 10, 40, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN); - addhabitat(H_MASTERVAULTS, "master vaults", CT_FLOORDURANITE, CT_WALLDURANITE, 10, 0, 0, MAXVISRANGE, OT_VSTAIRSUP, OT_VSTAIRSDOWN); + // thingchance, obchance, vaultchance, maxvisrange, upstiartype, downstairtype, stairs_in_rooms + addhabitat(H_DUNGEON, "dungeon", CT_CORRIDOR, CT_WALL, 5, 60, 30, 6, OT_STAIRSUP, OT_STAIRSDOWN, B_TRUE); + addhabitat(H_CAVE, "cave", CT_DIRT, CT_WALLDIRT, 10, 45, 20, 6, OT_TUNNELUP, OT_TUNNELDOWN, B_FALSE); + addhabitat(H_FOREST, "forest", CT_GRASS, CT_WALLTREE, 5, 75, 0, MAXVISRANGE, OT_TREEUP, OT_TREEDOWN, B_FALSE); + addhabitat(H_HEAVEN, "heaven", CT_CORRIDOR, CT_WALLGLASS, 5, 0, 0, MAXVISRANGE, OT_NONE, OT_NONE, B_FALSE); + addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5, OT_NONE, OT_NONE, B_FALSE); + addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 5, 70, 0, MAXVISRANGE, OT_NONE, OT_NONE, B_FALSE); + addhabitat(H_SEWER, "sewer", CT_MOSSROCK, CT_WALL, 10, 50, 0, MAXVISRANGE, OT_GRATINGROOF, OT_NONE, B_FALSE); + addhabitat(H_STOMACH, "stomach", CT_FLOORFLESH, CT_WALLFLESH, 5, 80, 0, MAXVISRANGE, OT_NONE, OT_NONE, B_FALSE); + addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 5, 50, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN, B_FALSE); + addhabitat(H_BYHUT, "babayaga's hut", CT_FLOORWOOD, CT_WALLDWOOD, 0, 0, 0, MAXVISRANGE, OT_BYHUTDOOR, OT_NONE, B_FALSE); + addhabitat(H_ANTNEST, "ant nest", CT_DIRT, CT_WALLDIRT, 10, 40, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN, B_FALSE); + addhabitat(H_MASTERVAULTS, "master vaults", CT_FLOORDURANITE, CT_WALLDURANITE, 10, 0, 0, MAXVISRANGE, OT_VSTAIRSUP, OT_VSTAIRSDOWN, B_FALSE); // cell types - solid // floorheight, hp, volmod, absorbant @@ -9779,15 +9787,24 @@ int remove_deadends(map_t *m, int howmuch) { cell_t *c; c = m->cell[n]; if (!c->room) { + int exits; + exits = countcellexits(c, DT_ORTH); //if ((countcellexits(c, DT_ORTH) == 1) || // (countcellexits(c, DT_COMPASS) == 1)) { - if (countcellexits(c, DT_ORTH) == 1) { + if (exits == 1) { // erase this cell clearcell(c); setcelltype(c, solidcell); setcellreason(c, "dead-end removed."); count++; thiscount++; + } else if (exits == 0) { + // erase this cell + clearcell(c); + setcelltype(c, solidcell); + setcellreason(c, "zero-exit deadend removed."); + count++; + thiscount++; } } } @@ -10253,7 +10270,7 @@ void updateknowncells(void) { // you don't remember cells when you're flying, unless you // have a magic map or photographic memory. - if (isairborne(player) && !lfhasflag(player, F_PHOTOMEM)) { + if (isairborne(player, NULL) && !lfhasflag(player, F_PHOTOMEM)) { return; } if (lfhasflag(player, F_RAGE)) { diff --git a/map.h b/map.h index c841cb2..0ecdf02 100644 --- a/map.h +++ b/map.h @@ -1,7 +1,7 @@ #include "defs.h" cell_t *addcell(map_t *map, int x, int y); -habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell, int thingchance, int obchance, int vaultchance, int maxvisrange, enum OBTYPE upstairtype, enum OBTYPE downstairtype); +habitat_t *addhabitat(enum HABITAT id, char *name, enum CELLTYPE emptycell, enum CELLTYPE solidcell, int thingchance, int obchance, int vaultchance, int maxvisrange, enum OBTYPE upstairtype, enum OBTYPE downstairtype, int stairsinrooms); void addhomeobs(lifeform_t *lf, int dolevelobs); map_t *addmap(void); lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok, int amt, int autogen, int *nadded); diff --git a/move.c b/move.c index e529ee0..cb47a19 100644 --- a/move.c +++ b/move.c @@ -227,7 +227,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err } f = hasflag(o->flags, F_PIT); if (f && (f->val[0] == D_DOWN)) { - if (!isairborne(lf)) { + if (!isairborne(lf, NULL)) { if (error) { *error = E_AVOIDOB; rdata = o; @@ -238,7 +238,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err f = hasflag(o->flags, F_DEEPWATER); if (f) { // non swimming creature in water? - if (!isairborne(lf) && !lfhasflag(lf, F_AQUATIC)) { + if (!isairborne(lf, NULL) && !lfhasflag(lf, F_AQUATIC)) { if ((getobdepth(o, lf) >= DP_HEAD)) { if (getskill(lf, SK_SWIMMING) - isburdened(lf) <= 0) { if (error) { @@ -925,7 +925,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc msg("%s stagger%s %s but hold%s %s %s.",lfname,isplayer(lf) ? "" : "s", getreldirname(getrelativedir(lf, dir)), isplayer(lf) ? "" : "s", isplayer(lf) ? "your" : "its", - isairborne(lf) ? "position" : "ground"); + isairborne(lf, NULL) ? "position" : "ground"); } return B_TRUE; } @@ -1404,7 +1404,7 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) { } // check ground objects - flying = isairborne(lf); + flying = isairborne(lf, NULL); if (flying == F_NONE) { for (o = newcell->obpile->first ; o ; o = nexto ) { nexto = o->next; @@ -1471,6 +1471,7 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) { if (!lfhasflag(lf, F_CAREFULMOVE)) { if (cancrush(lf, o)) { + int maxhp; // crush it getobname(o, obname, 1); @@ -1495,9 +1496,16 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) { didmsg = B_TRUE; } // kill object which is being crushed. - removeob(o, o->amt); + //removeob(o, o->amt); + getobhp(o, &maxhp); + if (maxhp) { + takedamage(o, maxhp, DT_CRUSH, lf); + } else { + removeob(o, ALL); + } if (isplayer(lf)) { angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT); + pleasegodmaybe(R_GODFIRE, 2); } continue; } @@ -1717,7 +1725,7 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) { for (i = 0; i < nretflags; i++) { f = retflag[i]; // will we cause damage to ground objects ? - if (!isairborne(lf) || (f->val[2] == B_TRUE)) { + if (!isairborne(lf, NULL) || (f->val[2] == B_TRUE)) { damageallobs(NULL, lf->cell->obpile, f->val[0], f->val[1], lf); } } @@ -1859,14 +1867,14 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) { // (stealth check to avoid this) willmakenoise = B_TRUE; if (lfhasflag(lf, F_HIDING)) { - if (skillcheck(lf, SC_STEALTH, 70, isairborne(lf) ? 25 : 0)) { + if (skillcheck(lf, SC_STEALTH, 70, isairborne(lf, NULL) ? 10 : 0)) { willmakenoise = B_FALSE; } } // swapping places? if (willmakenoise) { - if (isairborne(lf)) { + if (isairborne(lf, NULL)) { makenoise(lf, N_FLY); } else { makenoise(lf, N_WALK); @@ -1874,7 +1882,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) { } // slip on blood in new cell? - if (!isairborne(lf) && !isswimming(lf)) { + if (!isairborne(lf, NULL) && !isswimming(lf)) { int slip; object_t *slipob; @@ -1892,7 +1900,7 @@ int moveto(lifeform_t *lf, cell_t *newcell, int onpurpose, int dontclearmsg) { nexto = o->next; f = hasflag(o->flags, F_TRAP); if (f) { - if (strstr(f->text, "ground") && isairborne(lf)) { + if (strstr(f->text, "ground") && isairborne(lf, NULL)) { // nothing happens } else { triggertrap(lf, NULL, o, lf->cell); @@ -1957,7 +1965,7 @@ int move_will_hurt(lifeform_t *lf) { if (f->id == F_INJURY) { switch (f->val[0]) { case IJ_LEGBLEED: - if (!isairborne(lf)) return B_TRUE; + if (!isairborne(lf, NULL)) return B_TRUE; break; case IJ_WINGBLEED: getflags(lf->flags, retflag2, &nretflags2, F_FLYING, F_NONE); @@ -1973,7 +1981,7 @@ int move_will_hurt(lifeform_t *lf) { } } - if (hasbleedinginjury(lf, BP_LEGS) && !isairborne(lf)) { + if (hasbleedinginjury(lf, BP_LEGS) && !isairborne(lf, NULL)) { return B_TRUE; } return B_FALSE; @@ -2430,7 +2438,7 @@ int pullnextto(lifeform_t *lf, cell_t *c) { char buf[BUFLEN]; getlfname(lf, buf); msg("%s %s pulled %s!", buf, is(lf), - isairborne(lf) ? "through the air" : + isairborne(lf, NULL) ? "through the air" : "along the ground"); } movelf(lf, dst, B_FALSE); @@ -2561,7 +2569,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int onpurpose, int *didmsg) { if (o->type->id == OT_WEB) { - if (isairborne(lf)) { + if (isairborne(lf, NULL)) { checkmod -= 5; } if (lf->race->raceclass->id == RC_INSECT) { @@ -2636,7 +2644,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int onpurpose, int *didmsg) { // slipping on something before moving? if (!attacking && onpurpose) { - if (!isairborne(lf)) { + if (!isairborne(lf, NULL)) { int slip; object_t *slipob; @@ -2665,7 +2673,7 @@ int initiatemove(lifeform_t *lf, cell_t *cell, int onpurpose, int *didmsg) { for (o = cell->obpile->first ; o ; o = nexto) { nexto = o->next; if (!isplayer(lf)) { - if ((o->blessed == B_CURSED) && (getraceclass(lf) == RC_ANIMAL) && !isairborne(lf)) { + if ((o->blessed == B_CURSED) && (getraceclass(lf) == RC_ANIMAL) && !isairborne(lf, NULL)) { if (cansee(player, lf)) { char lfname[BUFLEN]; getlfname(lf,lfname); diff --git a/objects.c b/objects.c index 422f295..9dcc4cc 100644 --- a/objects.c +++ b/objects.c @@ -4162,6 +4162,143 @@ object_t *getbestcontainer(obpile_t *op) { return poss2[rnd(0,nposs2-1)]; } +// returns TRUE if an break obejct was found. +int getbreakob(object_t *o, char *bigobname, char *smallobname) { + enum MATERIAL mid; + enum DAMTYPE dt; + enum OBTYPE bigoid = OT_NONE,smalloid = OT_NONE; + objecttype_t *big = NULL,*small = NULL; + flag_t *f; + int nsmall = 0,nbig = 0; + double weight; + char bigadj[BUFLEN],smalladj[BUFLEN]; + flag_t *retflag[MAXCANDIDATES]; + int nretflags = 0,i; + int found = B_FALSE; + + mid = o->material->id; + dt = oblastdamtype(o); + + // name to return. + strcpy(bigobname, ""); + strcpy(smallobname, ""); + + + // flag overrides code below + found = 0; + getflags(o->flags, retflag, &nretflags, F_BREAKOB, F_NONE); + for (i = 0; i < nretflags; i++) { + f = retflag[i]; + if (f && (f->val[0] == dt)) { + if (found == 0) { + strcpy(bigobname, f->text); + } else if (found == 1) { + strcpy(smallobname, f->text); + } else { + msg("ERROR - too many F_BREAKOB flags in %s",o->type->name); + dblog("ERROR - too many F_BREAKOB flags in %s",o->type->name); + } + found++; + } + } + if (found) { + return B_TRUE; + } + + // adjectives + strcpy(bigadj, ""); + strcpy(smalladj, ""); + switch (mid) { + case MT_WOOD: + if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) { + bigoid = OT_WOODPLANK; + smalloid = OT_WOODSHARD; + } else { + switch (dt) { + case DT_FIRE: + case DT_HEAT: + case DT_ACID: + bigoid = OT_ASH; + smalloid = OT_ASH; + break; + default: break; + } + } + break; + case MT_GLASS: + if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) { + bigoid = OT_BROKENGLASS; + smalloid = OT_BROKENGLASS; + break; + } else { + switch (dt) { + case DT_FIRE: + case DT_HEAT: + case DT_ACID: + bigoid = OT_ASH; + smalloid = OT_ASH; + break; + default: break; + } + } + break; + case MT_ICE: + if (ismeleedam(dt) || (dt == DT_EXPLOSIVE)) { + bigoid = OT_ICECHUNK; + smalloid = OT_ICECHUNK; + break; + } else { + switch (dt) { + case DT_FIRE: + case DT_HEAT: + bigoid = OT_PUDDLEWATERL; + smalloid = OT_PUDDLEWATER; + break; + default: break; + } + } + break; + case MT_FLESH: + switch (dt) { + case DT_FIRE: + bigoid = OT_ASH; + smalloid = OT_ASH; + break; + default: break; + } + break; + default: break; + } + + big = findot(bigoid); + small = findot(smalloid); + + // now find out how many big obejcts make up the wight. + // NOTE: purposesly not using getobweight() here since + // we don't case about whther it is in water, etc. + weight = getobweight(o); + if (big) { + nbig = weight / big->weight; + weight -= (nbig*big->weight); + } + if (small){ + nsmall = weight / small->weight; + weight -= (nsmall*small->weight); + } + + if (nbig) { + sprintf(bigobname, "%d %s",nbig,big->name); + } + if (nsmall) { + sprintf(smallobname, "%d %s",nsmall,small->name); + } + + if (strlen(bigobname) || strlen(smallobname)) { + return B_TRUE; + } + return B_FALSE; +} + // returns -1 if object doesn't have the flag int getchargeinfo(object_t *o, int *cur, int *max) { flag_t *f; @@ -7677,7 +7814,7 @@ int isimpassableob(object_t *o, lifeform_t *lf, enum LFSIZE forcesize) { if ((lfsize >= blockmin) && (lfsize <= blockmax)) { // exception - if you're flying over it - if (getlfheight(lf) >= blockmax) { + if (getfeetheight(lf) >= blockmax) { } else { return B_TRUE; } @@ -7735,6 +7872,7 @@ int ismagicalobtype(objecttype_t *ot) { case OT_SHILLELAGH: case OT_WIZARDSTAFF: case OT_ARMOURTHORN: + case OT_PEACEPIPES: return B_TRUE; default: break; } @@ -8544,6 +8682,14 @@ void makeknownobclass(enum OBCLASS ocid, enum RARITY rrlev) { } } +void makeopersound(cell_t *c, object_t *o) { + flag_t *df; + df = hasflag(o->flags, F_OPERSOUND); + if (df) { + noise(c, NULL, NC_OTHER, df->val[0], df->text, NULL); + } +} + void maketemporary(object_t *o, int howlong, char *obdietext) { addflag(o->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(o->flags, F_OBHP, howlong, howlong, NA, NULL); @@ -9204,6 +9350,17 @@ void obdie(object_t *o) { snprintf(bonestr, BUFLEN, "%d-%d bones",minbones,maxbones); addob(o->pile, bonestr); } + } else { + char bigbreak[BUFLEN],smallbreak[BUFLEN]; + // maybe create broken object based on material + getbreakob(o, bigbreak, smallbreak); + + if (strlen(smallbreak)) { + addob(loc->obpile, smallbreak); + } + if (strlen(bigbreak)) { + addob(loc->obpile, bigbreak); + } } } @@ -9227,6 +9384,13 @@ void obdie(object_t *o) { magicwoods_angry(killer); } + if (killer && isplayer(killer)) { + if (oblastdamtype(o) == DT_FIRE) { + pleasegodmaybe(R_GODFIRE, 5); + } else { + pleasegodmaybe(R_GODFIRE, 2); + } + } killob(o); } @@ -9430,7 +9594,7 @@ flag_t *obrestrictsmovement(object_t *o, lifeform_t *lf) { if (lf) { if ((o->type->id == OT_WEB) && (lf->race->baseid == R_SPIDER)) { } else if ((o->type->id == OT_VINE) && hasjob(lf, J_DRUID)) { - } else if (isairborne(lf) && (f->val[2] != B_TRUE)) { + } else if (isairborne(lf, NULL) && (f->val[2] != B_TRUE)) { } else { return f; } @@ -10816,8 +10980,30 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { if (isplayer(lf)) { msg("You play a few notes on your panpipes."); } else { - noise(lf->cell, lf, NC_OTHER, SV_CAR, "the sound of panpipes.", "plays a tune on its panpipes."); + char nbuf[BUFLEN]; + sprintf(nbuf, "plays a tune on %ss panpipes.", it(lf)); + noise(lf->cell, lf, NC_OTHER, SV_SHOUT, "the sound of panpipes.", nbuf); } + } else if (o->type->id == OT_PEACEPIPES) { + lifeform_t *l; + if (isplayer(lf)) { + msg("You play an enchanting melody on your panpipes!"); + } else { + char nbuf[BUFLEN]; + sprintf(nbuf, "plays a calming melody on %ss panpipes.", it(lf)); + noise(lf->cell, lf, NC_OTHER, SV_SHOUT, "an eerily calming melody.", nbuf); + } + for (l = lf->cell->map->lf ; l ; l = l->next) { + if (l == lf) continue; + if (iscursed(o)) { + // enrage + enrage(l, DEF_RAGETIME*2); + } else { + // calm + makepeaceful(l, lf); + } + } + makeknown(o->type->id); } else if (hasflag(o->flags, F_HELPSDIG)) { int ch,dir; cell_t *c; @@ -11873,7 +12059,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE // remove damaging objects underneath if (killobswithflag(lf->cell->obpile, F_WALKDAM, B_FALSE)) { if (haslos(player, lf->cell)) { - msg("Some nearby objecst disappear!"); + msg("Some nearby objects disappear!"); } } @@ -13030,7 +13216,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) { } // announce - if (haslos(player, where)) { + if (haslos(player, where) && !o->pile->parentob) { char prefix[BUFLEN]; if (o->pile->owner) { @@ -13049,7 +13235,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) { noise(where, NULL, NC_OTHER, SV_SHOUT, "shattering glass.", NULL); } - if (target) { + if (target && !o->pile->parentob) { shatterdam = getshatterdam(o); if (shatterdam && !isdead(target)) { // extra glass damage @@ -13067,7 +13253,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) { numshards = getnumshards(o); // place glass shards snprintf(buf, BUFLEN, "%d pieces of broken glass",numshards); - addob(where->obpile, buf); + addob(o->pile, buf); } else if (o->material->id == MT_ICE) { int numshards; numshards = getnumshards(o) / 15; @@ -13075,7 +13261,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) { // ice snprintf(buf, BUFLEN, "%d chunks of ice",numshards); - addob(where->obpile, buf); + addob(o->pile, buf); } // potion effects (only if you hit)? @@ -13197,7 +13383,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) { } //TODO: holy water blesses everything? // everything here takes water damage - for (oo = where->obpile->first ; oo ; oo = nextoo) { + for (oo = o->pile->first ; oo ; oo = nextoo) { nextoo = oo->next; takedamage(oo, 0, DT_WATER, fromlf); } @@ -13641,22 +13827,6 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce, lif meat->weight = o->weight; copyflag(meat->flags, o->flags, F_CORPSEOF); } - // fire turns things to ash - addob(o->pile, "pile of ash"); - } else if (damtype == DT_BASH) { - if (o->material->id == MT_GLASS) { // bashing damage breaks glass - int nshards; - char buf[BUFLEN]; - nshards = getnumshards(o); - snprintf(buf, BUFLEN, "%d pieces of broken glass", nshards); - addob(o->pile, buf); - } else if (o->material->id == MT_ICE) { // bashing breaks ice - int nshards; - char buf[BUFLEN]; - nshards = getnumshards(o) / 15; - snprintf(buf, BUFLEN, "%d chunks of ice", nshards); - addob(o->pile, buf); - } } // object dies! @@ -14445,7 +14615,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp // will the missile trip them over? f = hasflag(o->flags, F_TANGLEMISSILE); if (f) { - if (isairborne(target) || !skillcheck(target, SC_SLIP, f->val[0], 0)) { + if (isairborne(target, NULL) || !skillcheck(target, SC_SLIP, f->val[0], 0)) { willtangle = B_TRUE; } } @@ -14587,6 +14757,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp shatter(newob, youhit, dambuf, thrower); if (thrower && isplayer(thrower)) { angergodmaybe(R_GODNATURE, 10, GA_ATTACKOBJECT); + pleasegodmaybe(R_GODFIRE, 1); } } else if (hasflag(newob->flags, F_MISSILEALWAYSDIES)) { killob(newob); @@ -15207,9 +15378,11 @@ void timeeffectsob(object_t *o) { } else { damtype = f->val[1]; } - // special case - corpses don't decay when on ice + // special case - corpses don't decay when on ice or on fire. if (o->type->id == OT_CORPSE) { - if (hasobofmaterial(o->pile, MT_ICE)) { + if (hasflag(o->flags, F_ONFIRE)) { + doit = B_FALSE; + } else if (hasobofmaterial(o->pile, MT_ICE)) { doit = B_FALSE; } } diff --git a/objects.h b/objects.h index aef49bf..2695065 100644 --- a/objects.h +++ b/objects.h @@ -72,6 +72,7 @@ void genhiddennames(void); enum LFSIZE getarmoursize(object_t *o); enum RARITY getavgrarity(flagpile_t *fp); object_t *getbestcontainer(obpile_t *op); +int getbreakob(object_t *o, char *bigobname, char *smallobname); int getchargeinfo(object_t *o, int *cur, int *max); int getcharges(object_t *o); enum SKILL getclassloreskill(enum OBCLASS oc); @@ -247,6 +248,7 @@ int makeduller(object_t *o, int howmuch); void makehot(object_t *o, int howmuch, int howlong); void makeknown(enum OBTYPE otid); void makeknownobclass(enum OBCLASS ocid, enum RARITY rrlev); +void makeopersound(cell_t *c, object_t *o); void maketemporary(object_t *o, int howlong, char *obdietext); void maketried(enum OBTYPE otid, char *triedon); void makewet(object_t *o, int amt); diff --git a/spell.c b/spell.c index 761e123..1911865 100644 --- a/spell.c +++ b/spell.c @@ -131,7 +131,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } else if (isstuck(user)) { if (isplayer(user)) msg("You can't build anything while stuck!"); return B_TRUE; - } else if (isairborne(user)) { + } else if (isairborne(user, NULL)) { if (isplayer(user)) msg("You can't build anything while airborne!"); return B_TRUE; } @@ -1214,7 +1214,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef msg("There is nothing to dismantle there."); return B_TRUE; } else if (!o) { - if (slev >= PR_SKILLED) { + if (slev >= PR_ADEPT) { // you can dismantle doors too... o = hasdoor(c); } @@ -1258,6 +1258,36 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef addflag(target->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL); target->hp = 0; killallobs(target->pack); + } else if (abilid == OT_A_FLY) { + flag_t *retflag[MAXCANDIDATES],*f; + int nretflags,i; + + // already flying? stop. + getflags(user->flags, retflag, &nretflags, F_FLYING, F_NONE); + for (i = 0; i < nretflags; i++) { + f = retflag[i]; + if (f->lifetime == FROMABIL) { + killflag(f); + taketime(user, getactspeed(user)); + return B_FALSE; + } + } + + if (isimmobile(user)) { + if (isplayer(user)) msg("You can't move!"); + return B_TRUE; + } else if (isstuck(user)) { + if (isplayer(user)) msg("You can't start flying while stuck!"); + return B_TRUE; + } else if (isburdened(user)) { + if (isplayer(user)) msg("You can't flying while burdened!"); + return B_TRUE; + } + + // start flying + addtempflag(user->flags, F_FLYING, getnaturalflightheight(user), NA, NA, NULL, FROMABIL); + taketime(user, getactspeed(user)); + } else if (abilid == OT_A_FEIGNDEATH) { lifeform_t *lf; if (hasflag(user->flags, F_FEIGNINGDEATH)) { @@ -1580,7 +1610,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { if (isplayer(user)) msg("You can't jump while swimming!"); return B_TRUE; - } else if (isairborne(user)) { + } else if (isairborne(user, NULL)) { if (isplayer(user)) msg("You can't jump while airbourne!"); return B_TRUE; } else if (hasflag(user->flags, F_GRAVBOOSTED)) { @@ -2174,7 +2204,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef return B_TRUE; } - if (isairborne(user)) { + if (isairborne(user, NULL)) { if (isplayer(user)) msg("You can't sprint while airborne!"); return B_TRUE; } @@ -2707,7 +2737,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef if (isplayer(user)) msg("There is nobody there to trip!"); return B_TRUE; } - if (isairborne(target)) { + if (isairborne(target, NULL)) { if (isplayer(user)) msg("You can't trip someone in the air!"); return B_TRUE; } @@ -2757,7 +2787,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { if (isplayer(user)) msg("You can't tumble while swimming!"); return B_TRUE; - } else if (isairborne(user)) { + } else if (isairborne(user, NULL)) { if (isplayer(user)) msg("You can't tumble while airbourne!"); return B_TRUE; } else if (lfhasflag(user, F_GRABBING)) { @@ -6164,7 +6194,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (cansee(player, c2->lf)) { char lfname[BUFLEN]; getlfname(c2->lf, lfname); - msg("%s %s showered with debris!", lfname, isplayer(c2->lf) ? "are" : "is"); + msg("^%c%s %s showered with debris!", + getlfcol(c2->lf, CC_BAD), + lfname, isplayer(c2->lf) ? "are" : "is"); } losehp(c2->lf, dam, DT_PROJECTILE, NULL, "flying debris"); } @@ -7428,131 +7460,27 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_FLIGHT) { flag_t *f; + int height; // always targetted at caster targcell = caster->cell; target = caster; - f = addtempflag(caster->flags, F_FLYING, B_TRUE, NA, NA, NULL, FROMSPELL); + height = (power/2)+1; + limit(&height, SZ_MEDIUM, NA); + + f = addtempflag(caster->flags, F_FLYING, height, NA, NA, NULL, FROMSPELL); f->obfrom = spellid; } else if (spellid == OT_S_FREEZEOB) { - object_t *o; - - if (targob) { - o = targob; - } else { - // rings? - o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_RIGHTFINGER, NA, NA, NULL); - if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_LEFTFINGER, NA, NA, NULL); - // gloves? - if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_HANDS, NA, NA, NULL); - // weapon? - if (!o) o = hasobwithflagval(caster->pack, F_EQUIPPED, BP_WEAPON, NA, NA, NULL); - if (o) { - // at high power, warn... - if (isplayer(caster) && (power > 5)) { - char obname[BUFLEN]; - char ch; - getobname(o, obname, o->amt); - msg("%s %s start%s glowing bright blue!", - (o->pile->owner == caster) ? "Your" : "", - (o->pile->owner == caster) ? noprefix(obname) : obname, - OBS1(o)); - more(); - 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; - } - } - } else { - // next thing touched - addflag(caster->flags, F_FREEZINGTOUCH, 1, power, 10+power, NULL); - if (isplayer(caster)) { - msg("Your hands begin to glow blue!"); - if (seenbyplayer) *seenbyplayer = B_TRUE; - } else if (cansee(player, caster)) { - getlfname(caster, buf); - msg("%s's hands begin to glow blue!", buf); - if (seenbyplayer) *seenbyplayer = B_TRUE; - } - return B_FALSE; - } - } - - if (!o) { - if (isplayer(caster)) { - msg("Your hands feel freezing cold for a moment."); - } + if (lfhasflag(caster, F_FREEZINGTOUCH)) { fizzle(caster); return B_TRUE; } - - // object will turn to ice immediately... - if (o->material->id == MT_ICE) { // already made of ice? - cell_t *loc; - flag_t *f; - loc = getoblocation(o); - // announce - if (haslos(player, loc)) { - char obname[BUFLEN]; - getobname(o, obname, o->amt); - msg("%s %s freeze%s some more.", - (o->pile->owner == caster) ? "Your" : "", - (o->pile->owner == caster) ? noprefix(obname) : obname, - OBS1(o)); - } - // restore it - f = hasflag(o->flags, F_OBHP); - if (f) { - f->val[0] = f->val[1]; - } - return B_TRUE; - } else { - int rv; - getobname(o, buf, o->amt); - if (isimmuneto(o->flags, DT_COLD, B_FALSE)) { - rv = E_NOEFFECT; - } else { - rv = changemat(o, MT_ICE); - } - if (rv) { - if (rv == E_NOEFFECT) { - if (o->pile->owner) { - if (isplayer(o->pile->owner)) { - msg("Your %s glows blue for a moment.",noprefix(buf)); - if (seenbyplayer) *seenbyplayer = B_TRUE; - } else if (haslos(player, o->pile->owner->cell)) { - char buf2[BUFLEN]; - getlfname(o->pile->owner, buf2); - msg("%s%s %s glows blue for a moment.", noprefix(buf2),getpossessive(buf2), buf); - if (seenbyplayer) *seenbyplayer = B_TRUE; - } - } else if (haslos(player, o->pile->where)) { - msg("%s glows blue for a moment.", buf); - if (seenbyplayer) *seenbyplayer = B_TRUE; - } - } else { - if (isplayer(caster)) { - nothinghappens(); - } - } - return B_TRUE; - } else { - if (o->pile->owner) { - if (isplayer(o->pile->owner)) { - msg("Your %s turn%s to ice!",noprefix(buf), OBS1(o)); - if (seenbyplayer) *seenbyplayer = B_TRUE; - } else if (haslos(player, o->pile->owner->cell)) { - getlfname(o->pile->owner, buf); - msg("A small cloud of vapour rises up from %s.", buf); - if (seenbyplayer) *seenbyplayer = B_TRUE; - } - } else if (haslos(player, o->pile->where)) { - msg("%s turns to ice!", buf); - if (seenbyplayer) *seenbyplayer = B_TRUE; - } - } + if (isplayer(caster) || cansee(player, caster)) { + if (seenbyplayer) *seenbyplayer = B_TRUE; } + // next thing touched + addflag(caster->flags, F_FREEZINGTOUCH, 1, power, 10+power, NULL); + return B_FALSE; } else if (spellid == OT_S_FROSTBITE) { char lfname[BUFLEN]; int exposedlimbs,dam; @@ -14737,7 +14665,7 @@ void pullobto(object_t *o, lifeform_t *lf) { } // can we pick up the object? - if (hasflag(o->flags, F_NOPICKUP) || hasflag(o->flags, F_IMPASSABLE) || !canpickup(lf, o, ALL)) { + if (hasflag(o->flags, F_NOPICKUP) || isimpassableob(o, lf, getlfsize(lf)) || !canpickup(lf, o, ALL)) { char buf[BUFLEN]; int dir; cell_t *obloc,*newcell; diff --git a/text.c b/text.c index 1489078..f56148f 100644 --- a/text.c +++ b/text.c @@ -1191,6 +1191,10 @@ char *getflagsourcetext(flag_t *f) { return " (god gift)"; case FROMGODPIETY: return " (piety bonus)"; + case FROMSPELL: + return " (from spell)"; + case FROMABIL: + return " (from ability)"; default: break; } return "";