- [+] 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
This commit is contained in:
Rob Pearce 2012-12-03 05:12:29 +00:00
parent c839387b84
commit ae01d1bbfa
22 changed files with 783 additions and 192 deletions

9
ai.c
View File

@ -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;
}

241
data.c
View File

@ -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);

Binary file not shown.

View File

@ -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

View File

@ -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

26
data/vaults/pentroom1.vlt Normal file
View File

@ -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

27
data/vaults/pentroom2.vlt Normal file
View File

@ -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

23
defs.h
View File

@ -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;

View File

@ -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

1
flag.c
View File

@ -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;

51
io.c
View File

@ -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);

3
io.h
View File

@ -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);

340
lf.c
View File

@ -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];

7
lf.h
View File

@ -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);

18
map.c
View File

@ -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) {

72
nexus.c
View File

@ -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

View File

@ -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);

View File

@ -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,6 +12382,9 @@ 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:
if (potblessed == B_CURSED) {
leveldrain(lf, 1, 99, NULL);
} else {
// gain xp!
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 150, 0)) {
if (isplayer(lf)) {
@ -12397,7 +12402,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
}
}
gainlevel(lf, B_TRUE);
}
break;
case OT_POT_FISHLUNG:
if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 150, 0)) {

View File

@ -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);

46
spell.c
View File

@ -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) {

10
text.c
View File

@ -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:

26
vault.c
View File

@ -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);
}
}
}
}