From ae01d1bbfac46c230d853bea23352927c3c5e91f Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Mon, 3 Dec 2012 05:12:29 +0000 Subject: [PATCH] - [+] add f_nostam to undead. - [+] add nonausea rather than nosmell sometimes. - [+] rats should eb able to smell, but not get nauseated. - [+] fix triumph pleasure for bjorn. must be no monsters within LOF... or within radius ? - [+] and make it very low piety gain. - [+] remember which level we got flags form - [+] flag_t -> fromlev - [+] announce this in getflagcourse - [+] undead qualities - [+] no criticals - [+] don't naturally heal - [+] don't breath - [+] drainlevel(fromlf) - [+] check for dtresist necrotic - [+] fitness saving throw (difficulty is 100 + fromlf's level*6) - [+] call loselevel() - [+] loselevel() - [+] announce. - [+] drop maxhp. - [+] adjust hp appropriately - [+] lose any flags where >fromlev is too high. - [+] handle monk f_hasattack specially. - [+] getmonkdr(level) - [+] getmonkattacks(level) - [+] keep track of what stats we gained and lose them again. - [+] TEST level drain with cursed xp pot - [+] TEST level drain with stats... - [+] prevent drinking when wearing full-face masks like gas mask/football helmet - [+] implement f_COVERSFACE. - [+] add it to objects. - [+] check it when doing caneat() candrink() - [+] up their AC bonus too - [+] large scorpion - [+] hellhound - [+] large primalities - [+] new vault flag: usehabitat:xxx - [+] means "set the habitat of all vault cells to xxx" - [+] real_getrandomob() should be given a CELL, not MAP. - [+] getrandomobofclass() should be given a CELL, not MAP. - [+] use CELL habitat to determine random obs - [+] apply to caves - [+] vault scatter: ignore locked cells (ie. reusable ones) new vaults - [+] dualroom - [+] sauna - vhot! - [+] pentagram and demons new pionic spells - [+] chi bolt - low dam ranged attack 1d4 - [+] chi strike (l4) - add 1d4 explosive damage to melee hits --- ai.c | 9 +- data.c | 241 +++++++++++++++++++++++--- data/hiscores.db | Bin 17408 -> 17408 bytes data/vaults/cave_bear.vlt | 1 + data/vaults/cave_troll.vlt | 1 + data/vaults/pentroom1.vlt | 26 +++ data/vaults/pentroom2.vlt | 27 +++ defs.h | 23 ++- doc/vaults.txt | 2 + flag.c | 1 + io.c | 51 ++++-- io.h | 3 +- lf.c | 340 +++++++++++++++++++++++++++---------- lf.h | 7 +- map.c | 18 +- nexus.c | 72 +++++--- nexus.h | 2 + objects.c | 63 +++---- objects.h | 6 +- spell.c | 46 ++++- text.c | 10 +- vault.c | 26 ++- 22 files changed, 783 insertions(+), 192 deletions(-) create mode 100644 data/vaults/pentroom1.vlt create mode 100644 data/vaults/pentroom2.vlt diff --git a/ai.c b/ai.c index 1631e63..1b6a6d6 100644 --- a/ai.c +++ b/ai.c @@ -2962,6 +2962,13 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG if ((ot->id == OT_S_BLINDNESS) && isblind(victim)) { specificcheckok = B_FALSE; } + if (ot->id == OT_S_BLINKASS) { + cell_t *targcell; + targcell = getcellindir(targcell, diropposite(victim->facing)); + if (!cellwalkable(lf, targcell, NULL)) { + specificcheckok = B_FALSE; + } + } if (ot->id == OT_S_BLOODBOIL) { if (lfhasflag(victim, F_BLOODBOIL)) { specificcheckok = B_FALSE; @@ -3615,7 +3622,7 @@ int useitemwithflag(lifeform_t *lf, enum FLAG whichflag) { if (hasflag(o->flags, whichflag)) { if (aiobok(lf, o, lf)) { if (o->type->obclass->id == OC_POTION) { - if (canquaff(lf, o)) { + if (candrink(lf, o)) { quaff(lf, o); return B_FALSE; } diff --git a/data.c b/data.c index fd0f014..a08f233 100644 --- a/data.c +++ b/data.c @@ -4448,6 +4448,7 @@ void initobjects(void) { addot(OT_S_DANCINGFLAME, "dancing flame", "Causes all fires in sight to 'dance' to adjacent creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 1, NA, NULL); @@ -4598,6 +4599,7 @@ void initobjects(void) { addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL); + addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 5, NA, NULL); addot(OT_S_WALLOFFIRE, "wall of fire", "Creates an roaring wall of flames.", MT_ICE, 0, OC_SPELL, SZ_TINY); @@ -5140,6 +5142,14 @@ void initobjects(void) { addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_ALLY, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); */ + addot(OT_S_CHIBOLT, "chi bolt", "Fires a small bolt of pure energy, dealing 1d4 explosive damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); + addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL); + addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addot(OT_S_STUN, "stun", "Stuns the target, preventing them from taking agressive action for a few seconds.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); @@ -5266,6 +5276,12 @@ void initobjects(void) { addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l4 + addot(OT_S_CHISTRIKE, "chi strike", "Adds 1d4 explosive damage to all melee attacks.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); + addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); + addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); + addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addot(OT_S_PACIFY, "pacify", "Induces calmness in another, preventing them from attacking.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability."); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); @@ -7572,7 +7588,7 @@ void initobjects(void) { addflag(lastot->flags, F_GENERATES, 50, 0, B_INADJCELL, "puff of smoke"); addflag(lastot->flags, F_GENERATES, 50, 0, B_INADJCELL, "puff of smoke"); addot(OT_FIRESMALL, "small fire", "A small blaze.", MT_FIRE, 0, OC_EFFECT, SZ_SMALL); - addflag(lastot->flags, F_GLYPH, C_RED, '}', NA, NULL); + addflag(lastot->flags, F_GLYPH, C_DARKRED, '}', NA, NULL); addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "goes out"); addflag(lastot->flags, F_TEMPMOD, 5, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); @@ -8208,14 +8224,15 @@ void initobjects(void) { addot(OT_GASMASK, "gas mask", "A full face and neck mask which protects the wearer from both head damage and toxic gasses.", MT_RUBBER, 3.5, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 4, NA, NA, NULL); addflag(lastot->flags, F_ACCURACYMOD, -10, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_POISONGAS, NA, NULL); - addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -2, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -4, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 65, NA, NA, NULL); addflag(lastot->flags, F_STARTSPLAIN, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_COVERSFACE, B_TRUE, NA, NA, NULL); addot(OT_HELM, "helmet", "A plain metal helmet.", MT_METAL, 2, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); @@ -8226,12 +8243,13 @@ void initobjects(void) { addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); addflag(lastot->flags, F_MULTISIZE, B_TRUE, NA, NA, NULL); - addflag(lastot->flags, F_ARMOURRATING, 3, NA, NA, NULL); + addflag(lastot->flags, F_ARMOURRATING, 4, NA, NA, NULL); addflag(lastot->flags, F_ACCURACYMOD, -10, NA, NA, NULL); addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL); - addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -1, NA, NULL); + addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -3, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addflag(lastot->flags, F_STARTSPLAIN, B_TRUE, NA, NA, NULL); + addflag(lastot->flags, F_COVERSFACE, B_TRUE, NA, NA, NULL); addot(OT_GOLDCROWN, "golden crown", "A heavy gold crown, encrusted with jewels.", MT_GOLD, 5, OC_ARMOUR, SZ_SMALL); addflag(lastot->flags, F_RARITY, H_ALL, 25, RR_RARE, NULL); addflag(lastot->flags, F_GOESON, BP_HEAD, NA, NA, NULL); @@ -11019,7 +11037,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOPRINTS, B_TRUE, 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_CANWILL, OT_S_BURNINGWAVE, NA, NA, "pw:10;"); + addflag(lastrace->flags, F_CANWILL, OT_S_BURNINGWAVE, NA, NA, "pw:10;range:3;"); addflag(lastrace->flags, F_CASTCHANCE, 100, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_TECH, NA, NULL); @@ -14074,7 +14092,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); - addrace(R_PRIMALFIREL, "lesser fire primality", 30, 'E', C_RED, MT_FIRE, RC_MAGIC, "A living mass of fire, animated by powerful magic."); + addrace(R_PRIMALFIREL, "lesser fire primality", 30, 'E', C_DARKRED, MT_FIRE, RC_MAGIC, "A living mass of fire, animated by powerful magic."); setbodytype(lastrace, BT_HUMANOID); addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); @@ -14106,7 +14124,68 @@ void initrace(void) { addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); - addrace(R_PRIMALSTONE, "stone primality", 200, 'E', C_GREY, MT_STONE, RC_MAGIC, "A living mass of stone, animated by powerful magic."); + addrace(R_PRIMALFIREG, "greater fire primality", 50, 'E', C_ORANGE, MT_FIRE, RC_MAGIC, "A living mass of fire, animated by powerful magic."); + setbodytype(lastrace, BT_HUMANOID); + addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, 72, RR_VERYRARE, NULL); + addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 9, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 10, NA, NA, NULL); + addflag(lastrace->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL); + addflag(lastrace->flags, F_DTVULN, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_DTVULN, DT_WATER, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "medium fire"); + addflag(lastrace->flags, F_FLAMESTRIKE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_TOUCHBURN, 8, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANCAST, OT_S_PYROMANIA, NA, NA, "pw:1;"); + addflag(lastrace->flags, F_CANCAST, OT_S_FLAMEBURST, NA, NA, "pw:10;"); + addflag(lastrace->flags, F_CANCAST, OT_S_DANCINGFLAME, NA, NA, "pw:1;"); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "burns brightly"); + addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "large fire"); + addflag(lastrace->flags, F_UNSUMMONOB, NA, NA, NA, "large fire"); + addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); + + addrace(R_PRIMALSTONEL, "lesser stone primality", 100, 'E', C_GREY, MT_STONE, RC_MAGIC, "A living mass of stone, animated by powerful magic."); + setbodytype(lastrace, BT_HUMANOID); + addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_EXHIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_EXHIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_CAVE, 72, RR_RARE, NULL); + addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 4, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); + addflag(lastrace->flags, F_ARMOURRATING, 12, NA, NA, NULL); + addflag(lastrace->flags, F_EVASION, -50, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); + addflag(lastrace->flags, F_ACTIONSPEED, SP_VERYSLOW, NA, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 8, NA, NULL); + addflag(lastrace->flags, F_HEAVYBLOW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "boulder"); + addflag(lastrace->flags, F_UNSUMMONOB, NA, NA, NA, "boulder"); + addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); + + addrace(R_PRIMALSTONEG, "greater stone primality", 200, 'E', C_GREY, MT_STONE, RC_MAGIC, "A living mass of stone, animated by powerful magic."); setbodytype(lastrace, BT_HUMANOID); addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_EXHIGH, NA, NULL); @@ -14133,7 +14212,7 @@ void initrace(void) { addflag(lastrace->flags, F_UNSUMMONOB, NA, NA, NA, "boulder"); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); - addrace(R_PRIMALSTONEL, "lesser stone primality", 120, 'E', C_GREY, MT_STONE, RC_MAGIC, "A living mass of stone, animated by powerful magic."); + addrace(R_PRIMALSTONE, "stone primality", 120, 'E', C_GREY, MT_STONE, RC_MAGIC, "A living mass of stone, animated by powerful magic."); setbodytype(lastrace, BT_HUMANOID); addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_EXHIGH, NA, NULL); @@ -14146,8 +14225,8 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_RARE, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL); - addflag(lastrace->flags, F_TR, 5, 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_ARMOURRATING, 12, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, -50, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); @@ -14160,7 +14239,7 @@ void initrace(void) { addflag(lastrace->flags, F_UNSUMMONOB, NA, NA, NA, "boulder"); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); - addrace(R_PRIMALSTORM, "storm primality", 50, 'E', C_LIGHTCYAN, MT_GAS, RC_MAGIC, "A living storm of seething winds and electricity, animated by powerful magic."); + addrace(R_PRIMALSTORMG, "greater storm primality", 50, 'E', C_LIGHTCYAN, MT_GAS, RC_MAGIC, "A living storm of seething winds and electricity, animated by powerful magic."); setbodytype(lastrace, BT_HUMANOID); addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); @@ -14198,7 +14277,7 @@ void initrace(void) { addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); - addrace(R_PRIMALSTORML, "lesser storm primality", 50, 'E', C_LIGHTCYAN, MT_GAS, RC_MAGIC, "A living storm of seething winds and electricity, animated by powerful magic."); + addrace(R_PRIMALSTORM, "storm primality", 50, 'E', C_CYAN, MT_GAS, RC_MAGIC, "A living storm of seething winds and electricity, animated by powerful magic."); setbodytype(lastrace, BT_HUMANOID); addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); @@ -14222,11 +14301,49 @@ void initrace(void) { addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_VERYFAST, NA, NA, NULL); addflag(lastrace->flags, F_SPELLSPEED, SP_NORMAL, NA, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_AIRFISTS, 3, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, 3, NA, NULL); + addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); + addflag(lastrace->flags, F_WINDSHIELD, 20, NA, NA, NULL); + addflag(lastrace->flags, F_CANCAST, OT_S_LIGHTNINGBOLT, NA, NA, "pw:2;"); + addflag(lastrace->flags, F_CANCAST, OT_S_SLEETSTORM, 15, 15, "pw:4;"); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "whirls violently"); + addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL); + addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, NULL); + addflag(lastrace->flags, F_UNSUMMONOB, NA, NA, NA, NULL); + addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); + + addrace(R_PRIMALSTORML, "lesser storm primality", 50, 'E', C_DARKCYAN, MT_GAS, RC_MAGIC, "A living storm of seething winds and electricity, animated by powerful magic."); + setbodytype(lastrace, BT_HUMANOID); + addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_EXHIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); + addflag(lastrace->flags, F_DTIMMUNE, DT_ELECTRIC, NA, NA, NULL); + addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_DTIMMUNE, DT_PROJECTILE, NA, NA, NULL); + addflag(lastrace->flags, F_DTIMMUNE, DT_WATER, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, NULL); + addflag(lastrace->flags, F_ACTIONSPEED, SP_FAST, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_AIRFISTS, 2, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_ZAPPER, 2, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_WINDSHIELD, 20, NA, NA, NULL); - addflag(lastrace->flags, F_CANCAST, OT_S_LIGHTNINGBOLT, NA, NA, "pw:2;"); + addflag(lastrace->flags, F_CANCAST, OT_S_LIGHTNINGBOLT, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANCAST, OT_S_SLEETSTORM, 15, 15, "pw:4;"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "whirls violently"); addflag(lastrace->flags, F_CASTWITHOUTIQ, B_TRUE, NA, NA, NULL); @@ -15811,7 +15928,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_FREQUENT, NULL); - addflag(lastrace->flags, F_NUMAPPEAR, 3, 4, NA, ""); + addflag(lastrace->flags, F_NUMAPPEAR, 1, 4, NA, ""); addflag(lastrace->flags, F_ARMOURRATING, 4, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -16083,8 +16200,8 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, 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_TEETH, 10, NA, NULL); - addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 10, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 6, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 6, NA, NULL); addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 5, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); @@ -16102,6 +16219,44 @@ 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); + + addrace(R_DOGFIRE, "hell hound", 40, 'd', C_RED, MT_FLESH, RC_DEMON, "Demonic canines who belch fire from between their slavering jaws."); + setbodytype(lastrace, BT_QUADRAPED); + addbodypart(lastrace, BP_TAIL, NULL); + addflag(lastrace->flags, F_EXTRACORPSE, 100, NA, NA, "medium fire"); + addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_VLOW, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); + addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, ""); + addflag(lastrace->flags, F_DAMAGEGROUNDOBS, 2, DT_FIRE, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, 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_TEETH, 8, NA, NULL); + addflag(lastrace->flags, F_ARMOURRATING, 5, NA, NA, NULL); + addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); + addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_ENHANCESMELL, 8, NA, NA, NULL); + addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining"); + addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "howls^a howl"); + addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling"); + addflag(lastrace->flags, F_CRITKNOCKDOWN, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_MORALE, 15, NA, NA, NULL); + addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "unleashes its fiery breath"); + addflag(lastrace->flags, F_CANCAST, OT_S_FIREBALL, NA, NA, "pw:3;"); + addflag(lastrace->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL); + addflag(lastrace->flags, F_DTVULN, DT_COLD, NA, NA, NULL); + addflag(lastrace->flags, F_DTVULN, DT_WATER, NA, NA, "2d6"); + addrace(R_DOGWAR, "war hound", 40, 'd', C_DARKYELLOW, MT_FLESH, RC_ANIMAL, "Canines bred for war."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); @@ -16709,7 +16864,7 @@ void initrace(void) { addrace(R_RATPLAGUE, "plague rat", 3, 'r', C_GREEN, MT_FLESH, RC_ANIMAL, "Plague rats are named both for their infectious bite as well as the great speed at which they run."); setbodytype(lastrace, BT_QUADRAPED); addbodypart(lastrace, BP_TAIL, NULL); - addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); @@ -16782,13 +16937,12 @@ void initrace(void) { addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACE, R_DWARF, NA, NA, NULL); - addrace(R_SCORPION, "giant scorpion", 25, 'x', C_LIGHTMAGENTA, MT_FLESH, RC_ANIMAL, "A large, venomous scorpion."); + addrace(R_SCORPION, "scorpion", 25, 'x', C_LIGHTMAGENTA, MT_FLESH, RC_ANIMAL, "A large, venomous scorpion."); setbodytype(lastrace, BT_QUADRAPED); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_UNCOMMON, NULL); - addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); @@ -16809,6 +16963,34 @@ void initrace(void) { addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling"); + addrace(R_SCORPIONL, "giant scorpion", 25, 'x', C_LIGHTMAGENTA, MT_FLESH, RC_ANIMAL, "A huge, dog-sized scorpion."); + setbodytype(lastrace, BT_QUADRAPED); + addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL); + addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_RARE, NULL); + addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); + addflag(lastrace->flags, F_STARTATT, A_CHA, AT_EXLOW, NA, NULL); + addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL); + addflag(lastrace->flags, F_TR, 5, NA, NA, NULL); + addflag(lastrace->flags, F_SIZE, SZ_SMALL, 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_NOSPELLS, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_STING, 5, NA, NULL); + addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 5, NA, NULL); + addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); + addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 150, "30-50"); + addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL); + addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); + addflag(lastrace->flags, F_NOISETEXT, N_WALK, SV_TALK, NA, "^scuttling"); + + addrace(R_SLUG, "acid slug", 150, 'P', C_GREY, MT_FLESH, RC_ANIMAL, "While acid slugs lack the protective shell of their snail cousings, their rubbery flesh is extremely resilient. Their acid-based attacks also make them much more dangerous."); addbodypart(lastrace, BP_BODY, NULL); addbodypart(lastrace, BP_HEAD, NULL); @@ -17129,7 +17311,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HITDICE, 4, NA, NA, NULL); @@ -17167,7 +17349,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); - addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SPIDERCLIMB, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL); @@ -17200,7 +17382,7 @@ void initrace(void) { addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_EXTRACORPSE, 90, NA, NA, "purple venom sac"); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); - addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); @@ -17274,7 +17456,7 @@ void initrace(void) { addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); - addflag(lastrace->flags, F_NOSMELL, B_TRUE, NA, NA, NULL); + addflag(lastrace->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL); @@ -19837,10 +20019,12 @@ void initrace(void) { addflag(r->flags, F_FILLPOT, OT_POT_AMBROSIA, NA, NA, NULL); addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); addflag(r->flags, F_GIFTTIMER, 0, 50, NA, NULL); + addflag(r->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL); } else if (r->raceclass->id == RC_MAGIC) { addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL); addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL); } else if (r->raceclass->id == RC_PLANT) { addflag(r->flags, F_NOKO, B_TRUE, NA, NA, NULL); addflag(r->flags, F_GETKILLEDVERB, NA, NA, NA, "destroy"); @@ -19856,12 +20040,14 @@ void initrace(void) { addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL); addflag(r->flags, F_DAYBOOST, 10, NA, NA, NULL); + addflag(r->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL); } else if (r->raceclass->id == RC_SLIME) { addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL); addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL); addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL); } else if (r->raceclass->id == RC_ROBOT) { addflag(r->flags, F_NOKO, B_TRUE, NA, NA, NULL); addflag(r->flags, F_GETKILLEDVERB, NA, NA, NA, "destroy"); @@ -19878,6 +20064,7 @@ void initrace(void) { addflag(r->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); addflag(r->flags, F_BLOODOB, NA, NA, NA, "puddle of oil"); addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NOSMELL, B_TRUE, NA, NA, NULL); if (!hasflagval(r->flags, F_NOISETEXT, N_WALK, NA, NA, NULL)) { addflag(r->flags, F_NOISETEXT, N_WALK, 2, NA, "^whirring"); @@ -19895,7 +20082,11 @@ void initrace(void) { addflag(r->flags, F_DTIMMUNE, DT_POISONGAS, NA, NA, NULL); addflag(r->flags, F_DTIMMUNE, DT_DECAY, NA, NA, NULL); addflag(r->flags, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL); - addflag(r->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NOTAKECRITS, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NOBREATH, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NORESTHEAL, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NOSTAM, B_TRUE, NA, NA, NULL); + addflag(r->flags, F_NONAUSEA, B_TRUE, NA, NA, NULL); // +/- 15 accuracy during day/night addflag(r->flags, F_NIGHTBOOST, 15, NA, NA, NULL); addflag(r->flags, F_DAYBOOST, -15, NA, NA, NULL); diff --git a/data/hiscores.db b/data/hiscores.db index 2eed152baec73d7eb97d8d501f47d5b787afddcc..e58d5e260f8f7ed35dd14edb91e3348b24ef766d 100644 GIT binary patch delta 100 zcmV-q0Gt1Shyj3z0gxL3F|i!z2Ln9<&yxoTc>)5@vw{ds0tEyE00BL-)Cw>S2m%92 z00XcCO0y9dJ_8?QJqG{*6ET4sSaNS-Om;CKL}hGtWpW@_VRCY5Z*r4vGB%T|HxaY2 G8&D`m9~@=? delta 61 zcmV-D0K)%(hyj3z0gxL3FtHry2Ln6;)RPAYc>)9Pvw{ds0tEsACj|qu)Cw>S1_1-G T00XeI5g0iGk$`Qpup3Y)9t#m! diff --git a/data/vaults/cave_bear.vlt b/data/vaults/cave_bear.vlt index e703787..37bfca8 100644 --- a/data/vaults/cave_bear.vlt +++ b/data/vaults/cave_bear.vlt @@ -23,6 +23,7 @@ scatter(3,1,-4,-2) mon:bear cub:1-3:50 goesin:dungeon goesin:cave goesin:forest +usehabitat:cave mayrotate rarity:uncommon maintainedge diff --git a/data/vaults/cave_troll.vlt b/data/vaults/cave_troll.vlt index 40cc1b4..6405a4c 100644 --- a/data/vaults/cave_troll.vlt +++ b/data/vaults/cave_troll.vlt @@ -23,6 +23,7 @@ scatter(3,1,-4,-2) mon:random troll:2-4:100 goesin:dungeon goesin:cave goesin:forest +usehabitat:cave mayrotate rarity:veryrare maintainedge diff --git a/data/vaults/pentroom1.vlt b/data/vaults/pentroom1.vlt new file mode 100644 index 0000000..2f09317 --- /dev/null +++ b/data/vaults/pentroom1.vlt @@ -0,0 +1,26 @@ +@id:pentagram_room +@map +rr###x###rr +rr#.....#rr +rr#.PPP.#rr +r#.PP.PP.#r +rx.P.d.P.xr +r#.PP.PP.#r +rr#.PPP.#rr +rr#.....#rr +rr###x###rr +@end + +@legend +#:cell:SOLID +P:ob:pentagram +d:mon:random demon +x:ob:locked iron door +@end + +@flags +mayrotate +goesin:dungeon +rarity:rare +@end + diff --git a/data/vaults/pentroom2.vlt b/data/vaults/pentroom2.vlt new file mode 100644 index 0000000..443ea7b --- /dev/null +++ b/data/vaults/pentroom2.vlt @@ -0,0 +1,27 @@ +@id:pentagram_room_2 +@map +rr###x###rr +rr#.....#rr +rr#.PPP.#rr +r#.PP.PP.#r +rx.P...P.xr +r#.PP..P.#r +rr#.PPP.#rr +rr#.....#rr +rr###x###rr +@end + +@legend +#:cell:SOLID +P:ob:pentagram +x:ob:locked iron door +@end + +@flags +mayrotate +goesin:dungeon +rarity:rare +scatter(1,1,-2,-2) mon:random demon:90% +scatter(1,1,-2,-2) mon:random demon:25% +@end + diff --git a/defs.h b/defs.h index d84d85d..072e23d 100644 --- a/defs.h +++ b/defs.h @@ -14,6 +14,10 @@ // #define PRACTICETIME 15 // #attempts it takes to learn new weapon skill + +// how much your str/agi/etc goes up every few levels +#define STATAMTPERLEVEL 5 + // Probabilities #define ONEIN_FOUNTAINDRYUP 3 #define PCTCH_PILLAR 5 @@ -1334,10 +1338,13 @@ enum RACE { R_POLTERGEIST, R_PRIMALFIRE, R_PRIMALFIREL, + R_PRIMALFIREG, R_PRIMALSTONE, R_PRIMALSTONEL, + R_PRIMALSTONEG, R_PRIMALSTORM, R_PRIMALSTORML, + R_PRIMALSTORMG, R_SANDMAN, R_SASQUATCH, R_SATYR, @@ -1408,6 +1415,7 @@ enum RACE { R_DOG, R_DOGBLINK, R_DOGDEATH, + R_DOGFIRE, R_DOGWAR, R_ELEPHANT, R_GOAT, @@ -1429,6 +1437,7 @@ enum RACE { R_RATPLAGUE, R_ROC, R_SCORPION, + R_SCORPIONL, R_SLUG, R_SNAIL, R_SNAKE, @@ -1999,6 +2008,8 @@ enum OBTYPE { OT_S_BAFFLE, OT_S_BOOSTCONFIDENCE, OT_S_CHARM, + OT_S_CHIBOLT, + OT_S_CHISTRIKE, OT_S_DISORIENT, OT_S_HUNGER, OT_S_LETHARGY, @@ -3317,6 +3328,8 @@ enum FLAG { // assign a random f_armoursize on creation. F_ARMOURSIZE, // v0 = sz_xxx, can be "medium", "human" or "large". F_ARMOURRATING, // val0 * 2 = pct of damage reduced + F_COVERSFACE, // this armour copmletely covers the body part it is + // equipped on. F_SHIELD, // this is a shield - use special bodyhitchance code // v0 = amount to add to shieldblock skillcheck when using // this. @@ -3455,6 +3468,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_NONAUSEA, // lf can't get nauseated but can still smell. F_NOSTAM, // this lf has infinite stamina F_NOTALK, // override ability to talk F_NOGIVECRITS, // monsters can't take critical hits @@ -3567,6 +3581,7 @@ enum FLAG { // can have multiple of these flags, if so then // randomly select one each time. F_RESTCOUNT, // val0 = how long you've been resting for + F_NORESTHEAL, // this lf never gains hp from resting. F_RESTHEALTIME, // val0 = how long to rest before healing hp F_RESTHEALAMT, // val0 = how many hp to gain after resting x turns F_RESTHEALMPAMT, // val0 = how many MP to gain after resting x turns @@ -4209,6 +4224,9 @@ enum FLAG { F_EVASION, // % chance of evading an attack // healing/resting/training + F_STATGAINED, // keeps track of what attrib we picked to increase + // on each levelup (used for subsequent level drains) + // v0 = level , v1 = stat selected F_HASNEWLEVEL, // we have a new xp lev, but haven't trained yet. F_STATGAINREADY, // ready to increase str/int etc. v2 is how many times // we can do it. @@ -4289,6 +4307,7 @@ enum FLAG { F_VAULTDLEVMIN, // v0 = mininum map depth/difficulty for this vault F_VAULTDLEVMAX, // v0 = maximum map depth/difficulty for this vault F_VAULTEXIT, // v0/1=x,y for exit. + F_VAULTHABITAT, // call cells in this vault have habitat=v0 F_VAULTGOESIN, // this vault randomly appears in habitat type v0. // can be repeated multiple times // if a vault doesnt have this flag, it can go anywhere @@ -4510,6 +4529,7 @@ enum ERROR { E_INJURED, E_STASIS, E_TOOCOLD, + E_FACECOVERED, }; @@ -5032,7 +5052,7 @@ typedef struct lifeform_s { int att[MAXATTS]; int baseatt[MAXATTS]; - int origatt[MAXATTS]; + int origatt[MAXATTS]; // used when polymorphed float forgettimer; @@ -5138,6 +5158,7 @@ typedef struct flag_s { long obfrom; // for conferred flags, link to object->id. -1 if not conferred. // for FROMGODGIFT or FROMGODPIETY, this is the race->id of // the god who gifted you this flag. + int fromlev; // we got this flag from achieveing job level xx. // int known; diff --git a/doc/vaults.txt b/doc/vaults.txt index 16eee9b..adf3b02 100644 --- a/doc/vaults.txt +++ b/doc/vaults.txt @@ -74,6 +74,8 @@ Flags can be: goesin:xxx // can only randomly appear in habitat xxx + usehabitat:xxx // cells in this vault have habitat=xxx + margin:x,y // must be x/y away from edges of map // MAY ONLY USE ONE OF THE FOLLOWING diff --git a/flag.c b/flag.c index c58ddfe..67670f6 100644 --- a/flag.c +++ b/flag.c @@ -255,6 +255,7 @@ flag_t *addflag_real(flagpile_t *fp, enum FLAG id, int val1, int val2, int val3, f->origlifetime = lifetime; f->known = known; f->obfrom = obfromid; + f->fromlev = NA; f->skillfrom = NULL; diff --git a/io.c b/io.c index 3bdb590..ce66148 100644 --- a/io.c +++ b/io.c @@ -3163,6 +3163,30 @@ void announcetime(int h, int m, int s, int showfull) { } } +void cantdrink(enum ERROR reason) { + object_t *oo; + char buf[BUFLEN]; + switch (reason) { + case E_INSUBSTANTIAL: + msg("You need a physical body to do that!"); + break; + case E_UNDEAD: + msg("You are undead and don't need to drink."); + break; + case E_FACECOVERED: + oo = facecovered(player); + assert(oo); + getobname(oo,buf, 1); + msg("You can't drink through your %s!", noprefix(buf)); + break; + default: + case E_WRONGOBTYPE: + msg("You can't drink that!"); + break; + } +} + + int confirm_badfeeling(object_t *o) { char ch; ch = askchar("You have a bad feeling about this. Continue?", "yn", "n", B_TRUE, B_FALSE); @@ -7920,7 +7944,9 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel } } break; + case F_NOTAKECRITS: if (lorelev >= PR_NOVICE) sprintf(buf, "Immune to critical hits."); break; case F_NOPRAY: if (lorelev >= PR_BEGINNER) sprintf(buf, "Cannot worship gods."); break; + case F_NORESTHEAL: if (lorelev >= PR_NOVICE) sprintf(buf, "Cannot restore gain HP by resting."); break; case F_NOSMELL: if ((lorelev >= PR_NOVICE) ) sprintf(buf, "No sense of smell."); break; case F_NOCTURNAL: if ((lorelev >= PR_BEGINNER) && !forplayersel) sprintf(buf, "Sleeps during the day."); break; case F_NOSPELLS: if (lorelev >= PR_NOVICE) sprintf(buf, "Cannot use magic."); break; @@ -8964,7 +8990,7 @@ void doquaff(obpile_t *op) { // quaffable objects here? (don't need to be able to pick them up) for (o = player->cell->obpile->first; o ; o = o->next) { - if (isdrinkable(o) && canquaff(player, o) ) { + if (isdrinkable(o) ) { char obname[BUFLEN]; char buf[BUFLEN]; char ch; @@ -8993,7 +9019,7 @@ void doquaff(obpile_t *op) { liquid = askobject(op, "Quaff what", "You have nothing drinkable.", NULL, 'q', &cs, B_FALSE); } if (liquid) { - if (canquaff(player, liquid)) { + if (candrink(player, liquid)) { if (isunknownbadobject(liquid) && skillcheck(player, A_WIS, 120, 0)) { if (!confirm_badfeeling(liquid)) { msg("Cancelled."); @@ -9003,16 +9029,11 @@ void doquaff(obpile_t *op) { quaff(player, liquid); } else { - switch (reason) { - case E_INSUBSTANTIAL: - msg("You need a physical body to do that!"); - break; - case E_WRONGOBTYPE: - default: - msg("You can't drink that!"); - break; - } + cantdrink(reason); + return; } + } else { + msg("Cancelled."); } } @@ -11679,7 +11700,7 @@ int screenglyphmatches(int x, int y, glyph_t *g) { } // prompts the player to learn a new spell from school 'ss' (ss_none means any) -void select_new_spell(enum SPELLSCHOOL ss) { +void select_new_spell(enum SPELLSCHOOL ss, int lev) { int done = B_FALSE; flag_t *f; char qbuf[BUFLEN]; @@ -11692,7 +11713,11 @@ void select_new_spell(enum SPELLSCHOOL ss) { ot = prompt.result; if (ot) { if (prompt.whichq == 0) { // learn the spell - addtempflag(player->flags, F_CANCAST, ot->id, NA, NA, NULL, FROMJOB); + flag_t *ff; + ff = addtempflag(player->flags, F_CANCAST, ot->id, NA, NA, NULL, FROMJOB); + if (lev >= 1) { + ff->fromlev = lev; + } done = B_TRUE; } else { describespell(ot); diff --git a/io.h b/io.h index f221e2a..f878039 100644 --- a/io.h +++ b/io.h @@ -19,6 +19,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f); int announceobflaggain(object_t *o, flag_t *f); void announceobflagloss(object_t *o, flag_t *f); void announcetime(int h, int m, int s, int showfull); +void cantdrink(enum ERROR reason); int confirm_badfeeling(object_t *o); int confirm_injury_action(enum BODYPART bp, enum DAMTYPE dt, char *actionname); lifeform_t *askgod(char *prompt, int onlyprayed, int forpray); @@ -137,7 +138,7 @@ void redrawpause(void); void redrawresume(void); void restoregamewindows(void); int screenglyphmatches(int x, int y, glyph_t *g); -void select_new_spell(enum SPELLSCHOOL ss); +void select_new_spell(enum SPELLSCHOOL ss, int lev); void setcol(WINDOW *win, enum COLOUR col); void unsetcol(WINDOW *win, enum COLOUR col); void setobcolour(WINDOW *win, object_t *o, int set); diff --git a/lf.c b/lf.c index c77157a..f2012a5 100644 --- a/lf.c +++ b/lf.c @@ -860,6 +860,14 @@ int candrink(lifeform_t *lf, object_t *o) { reason = E_WRONGOBTYPE; return B_FALSE; } + if (getlfmaterial(lf) == MT_GAS) { + reason = E_INSUBSTANTIAL; + return B_FALSE; + } + if (facecovered(lf)) { + reason = E_FACECOVERED; + return B_FALSE; + } reason = E_OK; return B_TRUE; } @@ -943,6 +951,11 @@ int caneat(lifeform_t *lf, object_t *o) { return B_FALSE; } } + + if (facecovered(lf)) { + reason = E_FACECOVERED; + return B_FALSE; + } return B_TRUE; } @@ -1223,21 +1236,6 @@ int canpush(lifeform_t *lf, object_t *o, int dir) { } -int canquaff(lifeform_t *lf, object_t *o) { - if (!isdrinkable(o)) { - reason = E_WRONGOBTYPE; - return B_FALSE; - } - - if (getlfmaterial(lf) == MT_GAS) { - reason = E_INSUBSTANTIAL; - return B_FALSE; - } - - return B_TRUE; -} - - // can lf reach victim to attack them? int canreach(lifeform_t *lf, lifeform_t *victim, int *reachpenalty) { int diff,lffootheight,victimfootheight; @@ -3926,15 +3924,16 @@ void die(lifeform_t *lf) { lifeform_t *l; int battledone = B_TRUE; for (l = lf->cell->map->lf ; l ; l = l->next) { - if (!isplayer(l) && areenemies(l, player) && haslof(l->cell, player->cell, LOF_WALLSTOP, NULL)) { - if (l != lf) { + if (!isplayer(l) && areenemies(l, player) && (l != lf)) { + if ((getcelldist(l->cell, player->cell) <= 3) || + haslof(l->cell, player->cell, LOF_WALLSTOP, NULL)) { battledone = B_FALSE; break; } } } if (battledone) { - pleasegodmaybe(R_GODBATTLE, 5); + pleasegodmaybe(R_GODBATTLE, 1); } } @@ -4776,6 +4775,7 @@ void dumplev(void) { int eat(lifeform_t *lf, object_t *o) { char lfname[BUFLEN]; char obname[BUFLEN]; + object_t *oo; char buf[BUFLEN]; flag_t *f; double nutrition; @@ -4806,15 +4806,7 @@ int eat(lifeform_t *lf, object_t *o) { if (drinking) { if (!candrink(lf, o)) { if (isplayer(lf)) { - switch (reason) { - case E_UNDEAD: - msg("You are undead and don't need to drink."); - break; - default: - case E_WRONGOBTYPE: - msg("You can't drink that!"); - break; - } + cantdrink(reason); } return B_TRUE; } @@ -4837,6 +4829,12 @@ int eat(lifeform_t *lf, object_t *o) { case E_PARTVEGETARIAN: msg("You aren't hungry enough to eat meat yet."); break; + case E_FACECOVERED: + oo = facecovered(lf); + assert(oo); + getobname(oo,buf, 1); + msg("You can't eat through your %s!", noprefix(buf)); + break; case E_WRONGOBTYPE: default: msg("You can't eat that!"); @@ -5556,7 +5554,8 @@ void enhanceskills(lifeform_t *lf) { } if (att != A_NONE) { - modattr(lf, att, 5); + addflag(lf->flags, F_STATGAINED, lf->level, att, NA, NULL); + modattr(lf, att, STATAMTPERLEVEL); } f->val[2]--; @@ -5731,6 +5730,7 @@ void enhanceskills(lifeform_t *lf) { } // end if isplayer if (gainedxplev) { + flag_t *ff; // give job-based level rewards f = levelabilityready(lf); while (f) { @@ -5749,17 +5749,20 @@ void enhanceskills(lifeform_t *lf) { } } // now add the new one - addtempflag(lf->flags, F_CANWILL, f->val[1], f->val[2], f->val[2], f->text, FROMJOB); - + ff = addtempflag(lf->flags, F_CANWILL, f->val[1], f->val[2], f->val[2], f->text, FROMJOB); + ff->fromlev = lf->level; } else if (f->id == F_LEVFLAG) { - addtempflag(lf->flags, f->val[1], f->val[2], NA, NA, f->text, FROMJOB); + ff = addtempflag(lf->flags, f->val[1], f->val[2], NA, NA, f->text, FROMJOB); + ff->fromlev = lf->level; } else if (f->id == F_LEVSKILL) { - giveskill(lf, f->val[1]); + ff = giveskill(lf, f->val[1]); + ff->fromlev = lf->level; } else if ((f->id == F_LEVSPELL) && !lfhasflag(lf, F_NOSPELLS)) { - addtempflag(lf->flags, F_CANCAST, f->val[1], NA, NA, NULL, FROMJOB); + ff = addtempflag(lf->flags, F_CANCAST, f->val[1], NA, NA, NULL, FROMJOB); + ff->fromlev = lf->level; } else if ((f->id == F_LEVSPELLSCHOOL) && !lfhasflag(lf, F_NOSPELLS)) { // select a spell from school if (isplayer(lf)) { - select_new_spell(f->val[1]); + select_new_spell(f->val[1], lf->level); } else { // monster gets random spell makespellchoicelist(&prompt, lf, "xx","xx:", f->val[1], B_TRUE, B_FALSE, B_FALSE, lf->maxmp); @@ -5768,7 +5771,8 @@ void enhanceskills(lifeform_t *lf) { // pick one randomly ot = (objecttype_t *)prompt.choice[rnd(0,prompt.nchoices-1)].data; if (ot) { - addtempflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL, FROMJOB); + ff = addtempflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL, FROMJOB); + ff->fromlev = lf->level; } } } @@ -5839,7 +5843,8 @@ void enhanceskills(lifeform_t *lf) { ot = prompt.result; if (ot) { if (prompt.whichq == 0) { // learn the spell - addtempflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL, FROMJOB); + ff = addtempflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL, FROMJOB); + ff->fromlev = lf->level; done = B_TRUE; } else { describespell(ot); @@ -5855,7 +5860,8 @@ void enhanceskills(lifeform_t *lf) { // pick randomly ot = (objecttype_t *)prompt.choice[rnd(0,prompt.nchoices-1)].data; if (ot) { - addtempflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL, FROMJOB); + ff = addtempflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL, FROMJOB); + ff->fromlev = lf->level; } } } @@ -5873,45 +5879,7 @@ void enhanceskills(lifeform_t *lf) { // special case level-based job effects if (hasjob(lf, J_MONK)) { // enhance fist strength and change type - //f = lfhasflagval(lf, F_HASATTACK, OT_FISTS, NA, NA, NULL); - f = lfhasflag(lf, F_HASATTACK); - if (f) { - int newdr; - newdr = lf->level+2; - limit(&newdr, NA, 12); - if (newdr <= f->val[1]) { - // do nothing - your unarmed attack was already stronger or - // equivilant. - } else if (newdr > f->val[1]) { - f->val[1] = newdr; - if (isplayer(lf)) msg("^gYour unarmed attack damage has increased!"); - } - } - // enhance # attacks - f = lfhasflag(lf, F_MAXATTACKS); - if (f) { - int min,max; - min = f->val[0]; - max = f->val[1]; - if ((lf->level >= 2) && (lf->level <= 3)) { - min = 1; max = 1; - } else if ((lf->level >= 4) && (lf->level <= 6)) { - min = 1; max = 2; - } else if ((lf->level >= 7) && (lf->level <= 9)) { - min = 2; max = 2; - } else if ((lf->level >= 10) && (lf->level <= 12)) { - min = 2; max = 3; - } else if ((lf->level >= 13) && (lf->level <= 16)) { - min = 3; max = 3; - } else if (lf->level >= 17) { - min = 3; max = 4; - } - if ((min > f->val[0]) || (max > f->val[1])) { - f->val[0] = min; - f->val[1] = max; - if (isplayer(lf)) msg("^gYour number of unarmed attacks has increased!"); - } - } + adjustmonk(lf, B_FALSE); } // allomancy sometimes lets you learn spells @@ -5929,7 +5897,8 @@ void enhanceskills(lifeform_t *lf) { ot = prompt.result; if (ot) { if (prompt.whichq == 0) { // learn the spell - addflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL); + ff = addflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL); + ff->fromlev = lf->level; } else { describespell(ot); } @@ -5963,7 +5932,8 @@ void enhanceskills(lifeform_t *lf) { ot = prompt.result; if (ot) { if (prompt.whichq == 0) { // learn the spell - addflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL); + ff = addflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL); + ff->fromlev = lf->level; } else { describespell(ot); } @@ -6077,6 +6047,15 @@ object_t *eyesshaded(lifeform_t *lf) { return NULL; } +object_t *facecovered(lifeform_t *lf) { + object_t *mask; + mask = getarmour(lf, BP_HEAD); + if (mask && hasflag(mask->flags, F_COVERSFACE)) { + return mask; + } + return NULL; +} + int fall(lifeform_t *lf, lifeform_t *fromlf, int announce) { char lfname[BUFLEN]; @@ -9044,6 +9023,37 @@ int getmiscastchance(lifeform_t *lf) { return chance; } +void getmonkattacks(int level, int *rmin, int *rmax) { + int min = 1,max = 1; + if ((level >= 2) && (level <= 3)) { + min = 1; max = 1; + } else if ((level >= 4) && (level <= 6)) { + min = 1; max = 2; + } else if ((level >= 7) && (level <= 9)) { + min = 2; max = 2; + } else if ((level >= 10) && (level <= 12)) { + min = 2; max = 3; + } else if ((level >= 13) && (level <= 16)) { + min = 3; max = 3; + } else if (level >= 17) { + min = 3; max = 4; + } + if (rmin) *rmin = min; + if (rmax) *rmax = max; +} + +int getmonkdr(int level) { + int dr = 5; + if (level <= 2) { + dr = 5; + } else { + dr = level + 2; + } + limit(&dr, NA, 12); + return dr; +} + + int getmorale(lifeform_t *lf) { flag_t *f; f = hasflag(lf->flags, F_MORALE); @@ -11988,7 +11998,7 @@ int giverandomobs(lifeform_t *lf, int amt) { } for (i = 0; i < amt; i++) { - if (getrandomob(lf->cell->map, buf)) { + if (getrandomob(lf->cell, buf)) { object_t *o; o = addob(lf->pack, buf); if (o) { @@ -12346,6 +12356,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { int db = B_FALSE; obpile_t *op; map_t *targmap; + cell_t *mapcell; enum LFSIZE maxobsize = SZ_MAX; int isshop = B_FALSE; int depthmod2 = 0; @@ -12358,9 +12369,11 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { maxobsize = getobsize(targob); if (hasflag(targob->flags, F_SHOP)) isshop = B_TRUE; depthmod2 += rnd(2,8); + mapcell = c; } else if (lf) { op = lf->pack; targmap = lf->cell->map; + mapcell = lf->cell; } else { assert("error - givestartobs() called without lf or targob" == 0); } @@ -12544,7 +12557,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { initcondv(&cs, CC_MAXSIZE, B_TRUE, maxobsize, CC_NONE); - if (real_getrandomob(targmap, buf, targmap->depth + depthmod, NA, RR_NONE, B_TRUE, &cs)) { + if (real_getrandomob(mapcell, buf, targmap->depth + depthmod, NA, RR_NONE, B_TRUE, &cs)) { if (isshop) apply_shopob_restrictions(buf); o = addob(op, buf); } @@ -12575,7 +12588,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { apply_wep_tr_limit(lf, &cs); } - if (real_getrandomob(targmap, buf, targmap->depth + depthmod, NA, RR_NONE, B_TRUE, &cs )) { + if (real_getrandomob(mapcell, buf, targmap->depth + depthmod, NA, RR_NONE, B_TRUE, &cs )) { if (db) snprintf(buf2, BUFLEN, "finished startobdt successfuly."); if (isshop) apply_shopob_restrictions(buf); o = addob(op, buf); @@ -12609,7 +12622,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { apply_wep_tr_limit(lf, &cs); } - if (real_getrandomob(targmap, buf, targmap->depth + depthmod, NA, getrarityval(text), B_TRUE, &cs)) { + if (real_getrandomob(mapcell, buf, targmap->depth + depthmod, NA, getrarityval(text), B_TRUE, &cs)) { char buf3[BUFLEN]; if (db) snprintf(buf2, BUFLEN, "finished startobwepsk successfuly."); sprintf(buf3, "%s%s%s",text,strlen(text) ? " " : "",buf); @@ -12648,7 +12661,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) { } //obdb = B_TRUE; - if (real_getrandomob(targmap, buf, getmapdifficulty(targmap) + depthmod, NA, RR_NONE, B_TRUE, &cs)) { + if (real_getrandomob(mapcell, buf, getmapdifficulty(targmap) + depthmod, NA, RR_NONE, B_TRUE, &cs)) { if (db) snprintf(buf2, BUFLEN, "finished startobclass, success."); if (isshop) apply_shopob_restrictions(buf); o = addob(op, buf); @@ -13491,6 +13504,44 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJUR return B_FALSE; } + +// return TRUE on failure +int leveldrain(lifeform_t *lf, int amt, int power, lifeform_t *fromlf) { + int resisted = B_FALSE; + if (isimmuneto(lf->flags, DT_NECROTIC, B_FALSE)) resisted = B_TRUE; + if (!resisted && isresistantto(lf->flags, DT_NECROTIC, B_FALSE) && onein(2)) resisted = B_TRUE; + + // fit check + if (!resisted && skillcheck(lf, SC_CON, 100+(power*6), 0 )) { + resisted = B_TRUE; + } + if (resisted) { + if (isplayer(lf)) { + msg("You struggle to retain your life force!"); + } + return B_TRUE; + } + + // announce + if (isplayer(lf)) { + msg("^%cYou feel your life force draining away!",getlfcol(lf, CC_VBAD)); + } + if (fromlf) { + char lfname[BUFLEN]; + setkillverb(lf, "Life-drained"); + real_getlfnamea(fromlf, lfname, NULL, B_TRUE, B_TRUE); + setlastdam(lf, lfname); + } else { + setkillverb(lf, "Killed"); + setlastdam(lf, "life force drain"); + } + if (fromlf) { + lf->lastdamlf = fromlf->id; + } + loselevel(lf, amt, fromlf); + return B_FALSE; +} + int lfcanbekod(lifeform_t *lf) { if (isundead(lf)) return B_FALSE; switch (getraceclass(lf)) { @@ -15308,6 +15359,46 @@ object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int dos return retob; } +// will never make stats worse unelss allowloss is true. +void adjustmonk(lifeform_t *lf, int allowloss) { + flag_t *f; + f = lfhasflagval(lf, F_HASATTACK, OT_FISTS, NA, NA, NULL); + //f = lfhasflag(lf, F_HASATTACK); + if (f) { + int newdr; + newdr = getmonkdr(lf->level); + if (newdr < f->val[1]) { + if (allowloss) { + f->val[1] = newdr; + if (isplayer(lf)) msg("^%cYour unarmed attack damage has decreased!", getlfcol(lf, CC_VBAD)); + } else { + // do nothing - your unarmed attack was already stronger or + // equivilant. + } + } else if (newdr > f->val[1]) { + f->val[1] = newdr; + if (isplayer(lf)) msg("^%cYour unarmed attack damage has increased!", getlfcol(lf, CC_GOOD)); + } + } + // enhance # attacks + f = lfhasflag(lf, F_MAXATTACKS); + if (f) { + int min,max; + getmonkattacks(lf->level, &min, &max); + if ((min < f->val[0]) || (max < f->val[1])) { + if (allowloss) { + f->val[0] = min; + f->val[1] = max; + if (isplayer(lf)) msg("^%cYour number of unarmed attacks has decreased!", getlfcol(lf, CC_VBAD)); + } + } else if ((min > f->val[0]) || (max > f->val[1])) { + f->val[0] = min; + f->val[1] = max; + if (isplayer(lf)) msg("^%cYour number of unarmed attacks has increased!", getlfcol(lf, CC_GOOD)); + } + } +} + void adjustspeedforwater(lifeform_t *lf, int *speed) { object_t *o; flag_t *f; @@ -17198,6 +17289,85 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr } // end if !isdead } +void loselevel(lifeform_t *lf, int amt, lifeform_t *fromlf) { + flag_t *f,*nextf; + float hpratio,mpratio; + int newlev; + int ndice,nsides,plus; + int nretflags,i; + flag_t *retflag[MAXCANDIDATES]; + if (isplayer(lf)) { + lf->level -= amt; + lf->newlevel = lf->level; + lf->xp = getxpforlev(lf->level); + } else { + f = lfhasflag(lf, F_TR); + if (f) { + f->val[0] -= amt; + } + } + newlev = gettr(lf); + + if (newlev <= 0) { + // dead. + lf->hp = 0; + lf->maxhp = 0; + return; + } + + + // adjust hp + hpratio = ((float)lf->hp / (float)lf->maxhp); + gethitdicestats(lf, &ndice,&nsides,&plus); + lf->maxhp -= ((ndice*nsides)+plus); + lf->hp = hpratio * (float)lf->maxhp; + + // adjust mp + mpratio = ((float)lf->mp / (float)getmaxmp(lf)); + getmpdicestats(lf, &ndice,&plus); + lf->maxmp -= ((ndice*4)+plus); + lf->mp = mpratio * (float)getmaxmp(lf); + + // lose stats (do this after hitdice in case we + // lower our fitness) + getflags(lf->flags, retflag, &nretflags, F_STATGAINED, F_NONE); + for (i = 0; i < nretflags; i++) { + f = retflag[i]; + if (f->val[0] > newlev) { + // reduce BASE attrib too. not using modattr because this + // is a permenant change. + modattr(lf, f->val[1], -STATAMTPERLEVEL); + lf->baseatt[f->val[1]] -= STATAMTPERLEVEL; + } + killflag(f); + } + + + // stop spells + interrupt(lf); + loseconcentration(lf); + + // handle monks + if (hasjob(lf, J_MONK)) { + adjustmonk(lf, B_TRUE); + } + + // lose flags. + for (f = lf->flags->first ; f; f = nextf) { + nextf = f->next; + if (f->fromlev > newlev) { + killflag(f); + } + } + + if (isplayer(lf)) { + statdirty = B_TRUE; + drawstatus(); + wrefresh(statwin); + msg("^%cWelcome back to level %d.",getlfcol(lf, CC_BAD), lf->level); + } +} + void losemp(lifeform_t *lf, int amt) { if (isplayer(lf)) { if (lf->bartimer == 2) { @@ -17409,7 +17579,7 @@ int makenauseated(lifeform_t *lf, int amt, int howlong, enum ERROR *why) { if (why) *why = E_NOEFFECT; return B_TRUE; // your own smell makes you used to it } - if (lfhasflag(lf, F_NOSMELL)) { + if (lfhasflag(lf, F_NOSMELL) || lfhasflag(lf, F_NONAUSEA)) { if (why) *why = E_NOEFFECT; return B_TRUE; // can't smell it. } @@ -25752,7 +25922,7 @@ int rest(lifeform_t *lf, int onpurpose) { if (!lfhasflag(lf, F_POISONED)) { // slowly heal hp/mp - if (!training) { + if (!training && !lfhasflag(lf, F_NORESTHEAL)) { ff = lfhasflag(lf, F_RESTHEALAMT); if (ff) { hpheal = ff->val[0]; diff --git a/lf.h b/lf.h index 7dd49b5..a9eae79 100644 --- a/lf.h +++ b/lf.h @@ -14,6 +14,7 @@ void addskilldesc(enum SKILL id, enum SKILLLEVEL lev, char *text, int wantmsg); //subjob_t *addsubjob(enum SUBJOB id, char *name, char *desc, char letter); object_t *addtrail(lifeform_t *lf, cell_t *where, int dir, int doprints, int doscents); void adjustdamlf(lifeform_t *lf, int *amt, enum DAMTYPE damtype); +void adjustmonk(lifeform_t *lf, int allowloss); void adjustspeedforwater(lifeform_t *lf, int *speed); void age(lifeform_t *lf, int pct); void adjustdamforblessings(lifeform_t *attacker, int *dam, lifeform_t *victim, int blessed); @@ -61,7 +62,6 @@ int canoperate(lifeform_t *lf, object_t *o, enum ERROR *why); int canpickup(lifeform_t *lf, object_t *o, int amt); int canpolymorphto(enum RACE rid); int canpush(lifeform_t *lf, object_t *o, int dir); -int canquaff(lifeform_t *lf, object_t *o); int canreach(lifeform_t *lf, lifeform_t *victim, int *reachpenalty); int canreachbp(lifeform_t *lf, lifeform_t *victim, enum BODYPART bp); int cansee(lifeform_t *viewer, lifeform_t *viewee); @@ -113,6 +113,7 @@ int enrage(lifeform_t *lf, int howlong); int exchangeweapon(lifeform_t *lf); void extinguishlf(lifeform_t *lf); object_t *eyesshaded(lifeform_t *lf); +object_t *facecovered(lifeform_t *lf); int fall(lifeform_t *lf, lifeform_t *fromlf, int announce); int fallasleep(lifeform_t *lf, enum SLEEPTYPE how, int howlong); int fall_from_air(lifeform_t *lf); @@ -216,6 +217,8 @@ 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); +void getmonkattacks(int level, int *rmin, int *rmax); +int getmonkdr(int level); int getmorale(lifeform_t *lf); int getnaturalflightheight(lifeform_t *lf); int getnextshortcut(lifeform_t *lf); @@ -333,6 +336,7 @@ flag_t *hasname(lifeform_t *lf); int hassoul(lifeform_t *lf); void inc_quad_range(enum QUADRANT *start, enum QUADRANT *end, int howmuch); int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJURY forcetype); +int leveldrain(lifeform_t *lf, int amt, int power, lifeform_t *fromlf); int lfcanbekod(lifeform_t *lf); int lfcanbestoned(lifeform_t *lf); flag_t *lfhasflag(lifeform_t *lf, enum FLAG fid); @@ -424,6 +428,7 @@ int losehp_bp(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *fromlf, char *damsrc, int reducedam, object_t *fromob, int retaliate, int *waskod, int doeffects, int bodypart); void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fromlf, object_t *fromob, int retaliate, int ko, int *waskod, int prelowhp, int bodypart); void losemp(lifeform_t *lf, int amt); +void loselevel(lifeform_t *lf, int amt, lifeform_t *fromlf); void loseskill(lifeform_t *lf, enum SKILL skid); void magicwoods_angry(lifeform_t *who); void magicwoods_warn(lifeform_t *who); diff --git a/map.c b/map.c index 351257c..7639ed6 100644 --- a/map.c +++ b/map.c @@ -610,7 +610,7 @@ object_t *addrandomob(cell_t *c) { initcond(&cs); - if (real_getrandomob(c->map, buf, NA, c->habitat->id, RR_NONE, B_FALSE, &cs)) { + if (real_getrandomob(c, buf, NA, c->habitat->id, RR_NONE, B_FALSE, &cs)) { if (db) dblog("adding rand obj %s to cell %d,%d",buf,c->x,c->y); o = addob(c->obpile, buf); } @@ -5764,6 +5764,21 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r dbtime("finished linkexits - vault %s", v->id); } + // set vault cell habitat if required. + f = hasflag(v->flags, F_VAULTHABITAT); + if (f) { + habitat_t *h; + h = findhabitat(f->val[0]); + assert(h); + for (y = miny; y <= maxy; y++) { + for (x = minx; x <= maxx; x++) { + cell_t *c; + c = getcellat(map, x, y); + c->habitat = h; + } + } + } + // lock cells if required dbtime("start locking cells - vault %s", v->id); if (hasflag(v->flags, F_MAINTAINEDGE)) { @@ -7680,6 +7695,7 @@ void finalisemonster(lifeform_t *lf, lifeform_t *leader, flagpile_t *wantflags, } */ autoskill(lf); + } celltype_t *findcelltype(enum CELLTYPE cid) { diff --git a/nexus.c b/nexus.c index d847dc9..4f5bf7e 100644 --- a/nexus.c +++ b/nexus.c @@ -514,6 +514,7 @@ int main(int argc, char **argv) { } } } + } @@ -1402,6 +1403,41 @@ warning_t *findwarning(char *text) { return NULL; } +void getmpdicestats(lifeform_t *lf, int *ndice,int *plus) { + flag_t *f; + if (ndice) *ndice = 0; + if (plus) *plus = 0; + f = hasflag(lf->flags, F_MPDICE); + if (f) { + if (ndice) *ndice = f->val[0]; + if (f->val[1] != NA) { + if (plus) *plus = f->val[1]; + } + } +} + +void gethitdicestats(lifeform_t *lf, int *ndice,int *nsides,int *plus) { + flag_t *f; + + if (ndice) *ndice = 0; + if (nsides) *nsides = HITDIESIDES; + if (plus) *plus = 0; + + f = hasflag(lf->flags, F_HITDICE); + if (f) { + if (ndice) *ndice = f->val[0]; + if (f->val[1] > 0) { + if (plus) *plus = f->val[1]; + } + if (f->val[2] > 0) { + if (nsides) *nsides = f->val[2]; + } + } else { + if (ndice) *ndice = 1; + if (plus) *plus = 0; + } +} + void gettrrange(int depth, int *min, int *max, int range, int oodok) { int mid; @@ -1903,8 +1939,8 @@ int rolldie(int ndice, int sides) { return res; } + int rollhitdice(lifeform_t *lf, int wantmax) { - flag_t *f; int ndice, nsides = HITDIESIDES, plus = 0; int myroll = 0; int maxroll; @@ -1912,20 +1948,7 @@ int rollhitdice(lifeform_t *lf, int wantmax) { int db = B_FALSE; int myfitness; - f = hasflag(lf->flags, F_HITDICE); - if (f) { - ndice = f->val[0]; - if (f->val[1] > 0) { - plus = f->val[1]; - } - if (f->val[2] > 0) { - nsides = f->val[2]; - } - } else { - ndice = 1; - plus = 0; - } - + gethitdicestats(lf, &ndice,&nsides,&plus); maxroll = (ndice * nsides) + plus; if (wantmax) { @@ -1951,32 +1974,27 @@ int rollhitdice(lifeform_t *lf, int wantmax) { } int rollmpdice(lifeform_t *lf, int wantmax) { - flag_t *f; int ndice, plus,roll,i; float mod; flag_t *retflag[MAXCANDIDATES]; int nretflags; + int max; if (lfhasflag(lf, F_NOSPELLS)) { return 0; } - f = hasflag(lf->flags, F_MPDICE); - if (f) { - ndice = f->val[0]; - if (f->val[1] == NA) plus = 0; - else plus = f->val[1]; - } else { - return 0; - } - - mod = 100 + getstatmod(lf, A_IQ); + getmpdicestats(lf, &ndice,&plus); + max = (ndice * 4) + plus; + if (max <= 0) return 0; if (wantmax) { - roll = (ndice * 4) + plus; + roll = max; } else { roll = rolldie(ndice, 4) + plus; } + + mod = 100 + getstatmod(lf, A_IQ); roll = pctof(mod, roll); // modify via racial flags diff --git a/nexus.h b/nexus.h index eb233fd..cae3f5b 100644 --- a/nexus.h +++ b/nexus.h @@ -15,6 +15,8 @@ void dobresnham(int d, int xinc1, int yinc1, int dinc1, int xinc2, int yinc2, in void donextturn(map_t *map); command_t *findcommand(enum COMMAND id); warning_t *findwarning(char *text); +void gethitdicestats(lifeform_t *lf, int *ndice,int *nsides,int *plus); +void getmpdicestats(lifeform_t *lf, int *ndice,int *plus); void gettrrange(int depth, int *min, int *max, int range, int oodok); int getoption(enum OPTION id); enum COLOUR getpctcol(float num, float max); diff --git a/objects.c b/objects.c index d16e124..a9c5c9b 100644 --- a/objects.c +++ b/objects.c @@ -1189,7 +1189,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum char buf[BUFLEN]; cell_t *cc; cc = getobpilelocation(where); - ot = getrandomobwithflag(cc->map, F_CONTAINER, buf); + ot = getrandomobwithflag(cc, F_CONTAINER, buf); if (ot) { found = B_TRUE; } @@ -1199,9 +1199,9 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum cell_t *cc; cc = getobpilelocation(where); // really want: impassable and not a dfeature - ot = getrandomobwithflag(cc->map, F_IMPASSABLE, buf); + ot = getrandomobwithflag(cc, F_IMPASSABLE, buf); while (ot->obclass->id == OC_DFEATURE) { - ot = getrandomobwithflag(cc->map, F_IMPASSABLE, buf); + ot = getrandomobwithflag(cc, F_IMPASSABLE, buf); } if (ot) { found = B_TRUE; @@ -6760,7 +6760,7 @@ objecttype_t *getoppositestairs(objecttype_t *ot) { // if no objectclass given then it will be picked randomly, or (if wepsk isn't sk_none) set to oc_weapon. //objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forcehabitat, enum LFSIZE maxsize, enum SKILL wepsk, enum RARITY forcerr, int forpickup, ... ) { -objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forcehabitat, enum RARITY forcerr, int forpickup, condset_t *cs) { +objecttype_t *real_getrandomob(cell_t *cell, char *buf, int forcedepth, int forcehabitat, enum RARITY forcerr, int forpickup, condset_t *cs) { objecttype_t *ot; objecttype_t *poss[MAXRANDOMOBCANDIDATES]; int nposs = 0; @@ -6790,8 +6790,8 @@ objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forceh if (forcehabitat != NA) { hab = findhabitat(forcehabitat); - } else if (map) { - hab = map->habitat; + } else if (cell) { + hab = cell->map->habitat; } else { hab = NULL; } @@ -6805,8 +6805,10 @@ objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forceh //if (forcedepth != NA) { if (forcedepth >= 0) { depth = forcedepth; + } else if (cell) { + depth = getmapdifficulty(cell->map); } else { - depth = getmapdifficulty(map); + depth = getmapdifficulty(NULL); } getrarityrange(depth, &raritymin, &raritymax, RARITYVARIANCEOB, B_TRUE); @@ -7067,7 +7069,7 @@ objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forceh } if (!om) { // in sewers, everythinng is shoddy - if ((map->habitat->id == H_SEWER) && hasflagval(ot->flags, F_CANHAVEOBMOD, OM_SHODDY, NA, NA, NULL)) { + if (hab && (hab->id == H_SEWER) && hasflagval(ot->flags, F_CANHAVEOBMOD, OM_SHODDY, NA, NA, NULL)) { om = findobmod(OM_SHODDY); } } @@ -7076,7 +7078,7 @@ objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forceh strcat(cursestr, " "); } - if ((map->habitat->id == H_SEWER) && (ot->obclass->id == OC_FOOD)) { + if (hab && (hab->id == H_SEWER) && (ot->obclass->id == OC_FOOD)) { strcat(cursestr, "tainted "); } @@ -7100,18 +7102,18 @@ objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forceh return ot; } -objecttype_t *getrandomob(map_t *map, char *buf) { +objecttype_t *getrandomob(cell_t *cell, char *buf) { condset_t cs; initcond(&cs); - return real_getrandomob(map, buf, NA, NA, RR_NONE, B_FALSE, &cs); + return real_getrandomob(cell, buf, NA, NA, RR_NONE, B_FALSE, &cs); } -objecttype_t *getrandomobwithflag(map_t *map, enum FLAG fid, char *buf) { +objecttype_t *getrandomobwithflag(cell_t *cell, enum FLAG fid, char *buf) { condset_t cs; initcondv(&cs, CC_HASFLAG, B_TRUE, fid, CC_NONE); - return real_getrandomob(map, buf, NA, NA, RR_NONE, B_FALSE, &cs); + return real_getrandomob(cell, buf, NA, NA, RR_NONE, B_FALSE, &cs); } enum OBCLASS getrandomobclass(enum HABITAT hab) { @@ -11072,7 +11074,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) { } } // learn any spell - select_new_spell(SS_NONE); + select_new_spell(SS_NONE, NA); break; case OT_GODSTONE_NATURE: // cure diseases @@ -12380,24 +12382,27 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE dospelleffects(lf, OT_S_PASSWALL, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL); break; case OT_POT_EXPERIENCE: - // gain xp! - if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 150, 0)) { - if (isplayer(lf)) { - msg("You feel momentarily more experienced."); - } - break; - } - if (isplayer(lf)) { - msg("You feel more experienced!"); - // purposely not using gainxp - lf->xp = getxpforlev(lf->level+1); + if (potblessed == B_CURSED) { + leveldrain(lf, 1, 99, NULL); } else { - if (cansee(player, lf)) { - msg("%s looks more experienced!", lfname); + // gain xp! + if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 150, 0)) { + if (isplayer(lf)) { + msg("You feel momentarily more experienced."); + } + break; } + if (isplayer(lf)) { + msg("You feel more experienced!"); + // purposely not using gainxp + lf->xp = getxpforlev(lf->level+1); + } else { + if (cansee(player, lf)) { + msg("%s looks more experienced!", lfname); + } + } + gainlevel(lf, B_TRUE); } - gainlevel(lf, B_TRUE); - break; case OT_POT_FISHLUNG: if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 150, 0)) { diff --git a/objects.h b/objects.h index 0e401c7..906ad25 100644 --- a/objects.h +++ b/objects.h @@ -152,9 +152,9 @@ float getobweight(object_t *o); float getobunitweight(object_t *o); objecttype_t *getoppositestairs(objecttype_t *ot); //objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forcehabitat, enum LFSIZE maxsize, enum SKILL wepsk, enum RARITY forcerr, int forpickup, ... ); -objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forcehabitat, enum RARITY forcerr, int forpickup, condset_t *cs); -objecttype_t *getrandomob(map_t *map, char *buf); -objecttype_t *getrandomobwithflag(map_t *map, enum FLAG fid, char *buf); +objecttype_t *real_getrandomob(cell_t *cell, char *buf, int forcedepth, int forcehabitat, enum RARITY forcerr, int forpickup, condset_t *cs); +objecttype_t *getrandomob(cell_t *cell, char *buf); +objecttype_t *getrandomobwithflag(cell_t *cell, enum FLAG fid, char *buf); enum OBCLASS getrandomobclass(enum HABITAT hab); int getobrarity(object_t *o, enum RARITY *rr); enum SPELLSCHOOL getschool(enum OBTYPE sid); diff --git a/spell.c b/spell.c index c556762..ea8420b 100644 --- a/spell.c +++ b/spell.c @@ -1932,6 +1932,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef addchoice(&prompt, o->letter, obname, NULL, o, NULL); } } + prompt.maycancel = B_TRUE; if (prompt.nchoices <= 1) { msg("You don't have anything which you are able to resize."); @@ -5580,6 +5581,47 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fightback(target, caster); } } + } else if (spellid == OT_S_CHIBOLT) { + char lfname[BUFLEN]; + char numbuf[BUFLEN]; + + numtotext(power, numbuf); + // animation + anim(caster->cell, targcell, '}', C_LIGHTGREEN); + if (isplayer(caster) || cansee(player, caster)) { + msg("%s fire%s a bolt of chi energy.",castername,isplayer(caster) ? "" : "s"); + if (seenbyplayer) *seenbyplayer = B_TRUE; + } + + target = haslf(targcell); + if (target) { + int dam; + char attackname[BUFLEN]; + getlfname(target, lfname); + dam = rnd(1,4); + sprintf(attackname, "a bolt of chi energy"); + // target takes magical damage + // always hit + if (check_for_block(caster, target, dam, DT_EXPLOSIVE, 999, attackname, B_RANGED)) { + } else { + if (cansee(player, target)) { + msg("^%cA bolt of chi energy hits %s.",getlfcol(target, CC_BAD), lfname); + } + losehp(target, dam, DT_MAGIC, caster, attackname); + } + } + } else if (spellid == OT_S_CHISTRIKE) { + flag_t *f; + if (isplayer(caster)) { + msg("An aura of chi energy forms around your %s!",getbodypartname(caster, BP_HANDS)); + if (seenbyplayer) *seenbyplayer = B_TRUE; + } else if (cansee(player, caster)) { + msg("An aura of chi energy forms around %s%s %s!",castername, getpossessive(castername), + getbodypartname(caster, BP_HANDS)); + if (seenbyplayer) *seenbyplayer = B_TRUE; + } + f = addtempflag(caster->flags, F_AWARENESS, DT_EXPLOSIVE, NA, NA, "1d4", FROMSPELL); + f->obfrom = spellid; } else if (spellid == OT_S_CHILL) { char lfname[BUFLEN]; int exposedlimbs,dam; @@ -8429,7 +8471,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } // target takes magical damage // always hit - if (check_for_block(caster, target, dam, DT_FIRE, 999, attackname, B_RANGED)) { + if (check_for_block(caster, target, dam, DT_MAGIC, 999, attackname, B_RANGED)) { } else { if (cansee(player, target)) { if (power == 1) { @@ -8438,7 +8480,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ msg("^%c%s spikes of mana hit %s.",getlfcol(target, CC_BAD), numbuf, lfname); } } - losehp(target, dam, DT_MAGIC, caster, "a mana spike"); + losehp(target, dam, DT_MAGIC, caster, attackname); } } } else if (spellid == OT_S_MAGSHIELD) { diff --git a/text.c b/text.c index db6a2e5..dac44a0 100644 --- a/text.c +++ b/text.c @@ -1257,13 +1257,19 @@ char *getflagsourcetext(flag_t *f, char *buf) { if (f->pile->owner && !isplayer(f->pile->owner)) return buf; switch (f->lifetime) { case FROMSKILL: - case FROMJOB: case FROMGODGIFT: case FROMGODPIETY: case FROMSPELL: case FROMABIL: case FROMINJURY: - sprintf(buf," (%s)",getsourcetext(f->lifetime)); + sprintf(buf," (%s",getsourcetext(f->lifetime)); + if (f->fromlev != NA) { + char xpbuf[BUFLEN]; + sprintf(xpbuf, ", XPLev %d",f->fromlev); + strcat(buf, xpbuf); + } else { + strcat(buf, ")"); + } break; case FROMOBEQUIP: case FROMOBHOLD: diff --git a/vault.c b/vault.c index dcf86f2..8289c34 100644 --- a/vault.c +++ b/vault.c @@ -310,7 +310,9 @@ void addvaultcontents(map_t *m, vault_t *v, int minx, int miny, int maxx, int ma if (c) { int valid = B_TRUE; totcells++; - if (f->val[0] == VT_LF) { + if (c->locked) { + valid = B_FALSE; + } else if (f->val[0] == VT_LF) { // make sure it's walkable if (!cellwalkable(NULL, c, NULL)) valid = B_FALSE; } else if (f->val[0] == VT_OB) { @@ -1531,6 +1533,28 @@ int handleline(vault_t *v, char *line) { p = line + 4; addflag(v->flags, F_VAULTTAG, B_TRUE, NA, NA, p); ok = B_TRUE; + } else if (strstarts(line, "usehabitat")) { + char *p; + p = line + strlen("usehabitat"); + if (*p == ':') { + habitat_t *h; + char buf[BUFLEN]; + p++; + p = readuntil(buf, p, ','); // really jsut want EOL + h = findhabitatbyname(buf); + if (h) { + if (hasflag(v->flags, F_VAULTHABITAT)) { + dblog("multiple usehabitat definitions found: '%s'", line); + } else { + addflag(v->flags, F_VAULTHABITAT, h->id, NA, NA, NULL); + ok = B_TRUE; + } + } else { + dblog("invalid usehabitat() definition: '%s' [BAD HABITAT]", line); + } + } else { + dblog("invalid usehabitat() definition: '%s'", line); + } } } }