- [+] ai shuldn't want its home/life objects.

- [+] lich
    - [+] lifeob = ornate glass jar
    - [+] can walk up to 12 away
    - [+] chilling touch
    - [+] mindshield
    - [+] teleport back to jar on death
- [+] monster ghosts have lifeob = corpse, which we generate.
    - [+] but DONT let them possess the player ?  or dont let them
          possess anyhting ?
- [+] mosnters should say noooo! if their lifeob is destroyed
    - [+] lifeobs need a link back to owner f_lifeobfor xxx
- [+] lifeob check wasn't including the lf's cell itself.
- [+] spellcasttext for dryad - "Charm" = beckons
- [+] poltergeist should be invisible
- [+] troll should covet food
- [+] avian - birds should be friendly
- [+] scroll of permenance should make armour invulnerable
- [+] amulet of mind sheild - immune to psionics 
- [+] parserace() shouhld handle "random _baseid_" ie. random ant,
      random troll etc
- [+] vault: troll cave (very rare)
    - [+] trolls
    - [+] bones
    - [+] cooked corpses
- [+] bug: minions not being created in vaults.
- [+] vault: ant nest
    - [+] queen ant
    - [+] dirt floor
    - [+] lots of ants
    - [+] LOTS of food.
- [+] reduce flame volume
- [+] vault maintainedge not working.  slightly fixed now?
- [+] vampires are turning into gas clouds but then trying to attack.
- [+] new amulets
    - [+] Of evolution (turn into a merman in deep water, aviad instead
          of falling, (fireres humanoid) in fire, (coldred human) in
          cold)
        - [+] in deep water and can't swim? turn into merman
        - [+] about to fall through a hole? turn into a flying aviad
        - [+] in fire and not resistant? turn into a Lavax
        - [+] in cold and not resistant? turn into sasquatch
        - [+] all polymorphs are TEMPORARY (5 turns or so).
        - [+] no autoid
    - [+] of bloodthirst - walking over blood heals you!
        - [+] no autoid
    - [+] Of graceful swimming (auto turn into a swan when you enter
          water)
        - [+] no autoid
    - [+] paranoia (5% chance per turn to create monsters out of sight,
          but in lof)
        - [+] they will make a "walk" noise right away
        - [+] or something just "you hear xxx right behind you!"
This commit is contained in:
Rob Pearce 2012-03-08 19:42:25 +00:00
parent ea5d012876
commit a6aab1afe1
16 changed files with 879 additions and 247 deletions

50
ai.c
View File

@ -38,7 +38,7 @@ int aiattack(lifeform_t *lf, lifeform_t *victim, int timelimit) {
} }
if (!canattack(lf)) { if (!canattack(lf)) {
dblog(".oO { canattack() is false }"); if (db) dblog(".oO { canattack() is false }");
return B_TRUE; return B_TRUE;
} }
@ -646,6 +646,25 @@ int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim
return B_FALSE; return B_FALSE;
} }
cell_t *aigettargetcell(lifeform_t *lf, flag_t **targflag) {
flag_t *f;
if (targflag) {
*targflag = NULL;
}
f = hasflag(lf->flags, F_TARGETCELL);
if (!f) return NULL;
if (targflag) {
// set this even if the actual cell is invalid.
*targflag = f;
}
return getcellat(lf->cell->map, f->val[0], f->val[1]);
}
object_t *aigetwand(lifeform_t *lf, enum FLAG purpose) { object_t *aigetwand(lifeform_t *lf, enum FLAG purpose) {
object_t *o; object_t *o;
object_t *poss[MAXPILEOBS]; object_t *poss[MAXPILEOBS];
@ -796,6 +815,7 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
} }
} }
if (!lfhasflag(lf, F_STUNNED)) { if (!lfhasflag(lf, F_STUNNED)) {
lifeform_t *hateposs[MAXCANDIDATES],*poss[MAXCANDIDATES]; lifeform_t *hateposs[MAXCANDIDATES],*poss[MAXCANDIDATES];
int nposs = 0, nhateposs = 0; int nposs = 0, nhateposs = 0;
@ -990,24 +1010,31 @@ int ai_handle_emergencies(lifeform_t *lf, enum ATTRBRACKET iqb) {
if (lfhasflag(lf, F_RAGE)) return B_FALSE; if (lfhasflag(lf, F_RAGE)) return B_FALSE;
// if we are not near our life ob, move towards it! // if we are not near our life ob, and not moving towards it, do so!
f = lfhasflag(lf, F_LIFEOB); f = lfhasflag(lf, F_LIFEOB);
if (f) { if (f) {
if (!findnearbylifeob(lf->cell, f, NULL)) { if (!findnearbylifeob(lf->cell, NA, f, NULL)) {
cell_t *poss[8]; cell_t *poss[8];
int nposs = 0; int nposs = 0;
int dir; int dir;
cell_t *targcell;
// target cell near our life ob? if so, we're okay.
targcell = aigettargetcell(lf, NULL);
if (targcell && findnearbylifeob(targcell, NA, f, NULL)) {
} else {
if (db) dblog(".oO { not near my lifeob! }"); if (db) dblog(".oO { not near my lifeob! }");
for (dir = DC_N; dir <= DC_NW; dir++) { for (dir = DC_N; dir <= DC_NW; dir++) {
cell_t *c; cell_t *c;
c = getcellindir(lf->cell, dir); c = getcellindir(lf->cell, dir);
if (c && findnearbylifeob(c, f, NULL)) { if (c && findnearbylifeob(c, NA, f, NULL)) {
poss[nposs++] = c; poss[nposs++] = c;
} }
} }
if (nposs) { if (nposs) {
if (aigoto(lf, poss[rnd(0,nposs-1)], MR_OTHER, NULL, PERMENANT)) { cell_t *c;
if (db) dblog(".oO { moving close to lifeob }"); c = poss[rnd(0,nposs-1)];
if (aigoto(lf, c, MR_OTHER, NULL, PERMENANT)) {
if (db) dblog(".oO { moving closer to lifeob }");
// success // success
return B_TRUE; return B_TRUE;
} else { } else {
@ -1017,6 +1044,7 @@ int ai_handle_emergencies(lifeform_t *lf, enum ATTRBRACKET iqb) {
} }
} }
} }
}
// if our cell is dangerous, move away! // if our cell is dangerous, move away!
if (iqb >= AT_AVERAGE) { if (iqb >= AT_AVERAGE) {
@ -1341,17 +1369,16 @@ int ai_movement(lifeform_t *lf) {
int valid = B_TRUE; int valid = B_TRUE;
cell_t *c; cell_t *c;
int db = B_FALSE; int db = B_FALSE;
flag_t *f; flag_t *f = NULL;
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE; if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
if (lfhasflagval(lf, F_DOESNTMOVE, NA, NA, B_TRUE, NULL)) return B_FALSE; if (lfhasflagval(lf, F_DOESNTMOVE, NA, NA, B_TRUE, NULL)) return B_FALSE;
// do we have a target cell? // do we have a target cell?
f = hasflag(lf->flags, F_TARGETCELL); c = aigettargetcell(lf, &f);
if (!f) return B_FALSE; if (!f) return B_FALSE;
// is it still valid? // is it still valid?
c = getcellat(lf->cell->map, f->val[0], f->val[1]);
if (!c) { if (!c) {
valid = B_FALSE; valid = B_FALSE;
} else if (f->val[2] == MR_LF) { } else if (f->val[2] == MR_LF) {
@ -2567,6 +2594,11 @@ int aiwants(lifeform_t *lf, object_t *o, int *covets) {
int aiwants_real(lifeform_t *lf, object_t *o, int *covets, int *noids, enum OBTYPE *oid, int *oidcovet,int *nwantflags, enum FLAG *wantflag, int *wantflagcovet) { int aiwants_real(lifeform_t *lf, object_t *o, int *covets, int *noids, enum OBTYPE *oid, int *oidcovet,int *nwantflags, enum FLAG *wantflag, int *wantflagcovet) {
int i; int i;
if (hasflagval(o->flags, F_HOMEOBFOR, lf->id, NA, NA, NULL)) {
return B_FALSE;
}
for (i = 0; i < *noids; i++) { for (i = 0; i < *noids; i++) {
if (oid[i] == o->type->id) { if (oid[i] == o->type->id) {
if (covets) { if (covets) {

1
ai.h
View File

@ -8,6 +8,7 @@ int aigetchasetime(lifeform_t *lf);
cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *lasty, int *lastdir); cell_t *aigetlastknownpos(lifeform_t *lf, lifeform_t *target, int *lastx, int *lasty, int *lastdir);
object_t *aigetrangedattack(lifeform_t *lf, lifeform_t *target, enum RANGEATTACK *ra, int *range); object_t *aigetrangedattack(lifeform_t *lf, lifeform_t *target, enum RANGEATTACK *ra, int *range);
int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose); int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose);
cell_t *aigettargetcell(lifeform_t *lf, flag_t **targflag);
object_t *aigetwand(lifeform_t *lf, enum FLAG purpose); object_t *aigetwand(lifeform_t *lf, enum FLAG purpose);
flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit); flag_t *aigoto(lifeform_t *lf, cell_t *c, enum MOVEREASON why, void *data, int timelimit);
int ai_attack_existing_target(lifeform_t *lf); int ai_attack_existing_target(lifeform_t *lf);

View File

@ -344,6 +344,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
switch (reason) { switch (reason) {
case E_NOSTAM: msg("You are too tired to fight at the moment."); break; case E_NOSTAM: msg("You are too tired to fight at the moment."); break;
case E_STUNNED: msg("You are too stunned to fight at the moment."); break; case E_STUNNED: msg("You are too stunned to fight at the moment."); break;
case E_IMPOSSIBLE: msg("You have no way of attacking!"); break;
default: msg("For some reason, you cannot attack."); break; default: msg("For some reason, you cannot attack."); break;
} }
} }

257
data.c
View File

@ -5068,6 +5068,10 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, NA, '!', NA, NULL); addflag(lastot->flags, F_GLYPH, NA, '!', NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 82, NA, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 82, NA, NULL);
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addot(OT_GLASSJAR, "ornate glass jar", "A richly-painted glass jar, inlaid with valuable gemstones.", MT_GLASS, 0.2, OC_MISC, SZ_TINY);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_MAGENTA, '!', NA, NULL);
addflag(lastot->flags, F_VALUE, 800, NA, NA, NULL);
addot(OT_BROKENGLASS, "piece of broken glass", "Sharp shards of broken glass.", MT_GLASS, 0.1, OC_MISC, SZ_MINI); addot(OT_BROKENGLASS, "piece of broken glass", "Sharp shards of broken glass.", MT_GLASS, 0.1, OC_MISC, SZ_MINI);
addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL);
addflag(lastot->flags, F_NUMAPPEAR, 1, 8, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 8, NA, NULL);
@ -5338,7 +5342,7 @@ void initobjects(void) {
//addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "dries up"); //addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "dries up");
//addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "dry up"); //addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "dry up");
addflag(lastot->flags, F_NODIECONVERTTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NODIECONVERTTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_OBHP, 15, 15, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LINKOB, OT_POT_BLOOD, NA, NA, NULL); addflag(lastot->flags, F_LINKOB, OT_POT_BLOOD, NA, NA, NULL);
@ -5357,7 +5361,7 @@ void initobjects(void) {
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "blood stain"); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "blood stain");
addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "dries up"); addflag(lastot->flags, F_DIECONVERTTEXT, NA, NA, NA, "dries up");
addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "dry up"); addflag(lastot->flags, F_DIECONVERTTEXTPL, NA, NA, NA, "dry up");
addflag(lastot->flags, F_OBHP, 45, 45, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DRINKABLE, B_TRUE, 0, NA, NULL); addflag(lastot->flags, F_DRINKABLE, B_TRUE, 0, NA, NULL);
@ -5455,7 +5459,7 @@ void initobjects(void) {
addflag(lastot->flags, F_ONFIRE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONFIRE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ONLYINROOM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONLYINROOM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "crackling flames."); addflag(lastot->flags, F_MAKESNOISE, 33, 1, NA, "crackling flames.");
addot(OT_WEAPONRACK, "weapon rack", "A large matel frame, made to store weapons.", MT_METAL, 150, OC_FURNITURE, SZ_HUMAN); addot(OT_WEAPONRACK, "weapon rack", "A large matel frame, made to store weapons.", MT_METAL, 150, OC_FURNITURE, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_UNCOMMON, NULL);
@ -5579,7 +5583,7 @@ void initobjects(void) {
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 7, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 7, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "crackling flames."); addflag(lastot->flags, F_MAKESNOISE, 33, 2, NA, "roaring flames.");
addot(OT_FIRESMALL, "small fire", "A small blaze.", MT_FIRE, 0, OC_EFFECT, SZ_SMALL); 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_RED, '}', NA, NULL);
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "goes out"); addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "goes out");
@ -5590,7 +5594,7 @@ void initobjects(void) {
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 5, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 5, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "crackling flames."); addflag(lastot->flags, F_MAKESNOISE, 33, 1, NA, "crackling flames.");
addot(OT_STEAMCLOUD, "cloud of steam", "A thick cloud of scalding steam.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN); addot(OT_STEAMCLOUD, "cloud of steam", "A thick cloud of scalding steam.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN);
addflag(lastot->flags, F_GLYPH, C_WHITE, UNI_SHADEMED, NA, NULL); addflag(lastot->flags, F_GLYPH, C_WHITE, UNI_SHADEMED, NA, NULL);
@ -6293,6 +6297,9 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_RAGE, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_RAGE, NA, NULL);
addflag(lastot->flags, F_VALUE, 600, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 600, NA, NA, NULL);
addot(OT_AMU_BLOOD, "amulet of bloodthirst", "Causes its wearer's body to heal itself by absorbing nearby blood. As a result, the wearer will also never bleed.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_VERYRARE, NULL);
addflag(lastot->flags, F_VALUE, 1400, NA, NA, NULL);
addot(OT_AMU_CHEF, "chef's amulet", "Greatly lowers its wearers' metabolism.", MT_METAL, 0.3, OC_AMULET, SZ_TINY); addot(OT_AMU_CHEF, "chef's amulet", "Greatly lowers its wearers' metabolism.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_SLOWMETAB, 3, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SLOWMETAB, 3, NA, NULL);
@ -6301,6 +6308,10 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_S_BLINK, NA, "pw:6;"); addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_S_BLINK, NA, "pw:6;");
addflag(lastot->flags, F_VALUE, 600, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 600, NA, NA, NULL);
addot(OT_AMU_EVOLUTION, "amulet of evolution", "These rare amulets grant the wearer the ability to almost instantly evolve their body shape in response to danger.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
// no autoid
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_VERYRARE, NULL);
addflag(lastot->flags, F_VALUE, 1400, NA, NA, NULL);
addot(OT_AMU_FALLING, "amulet of feather fall", "Limits the effects of gravity on its wearer, rendering them immune to fall damage.", MT_METAL, 0.3, OC_AMULET, SZ_TINY); addot(OT_AMU_FALLING, "amulet of feather fall", "Limits the effects of gravity on its wearer, rendering them immune to fall damage.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_FALL, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_FALL, NA, NULL);
@ -6313,21 +6324,35 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_DTVULN, DT_SONIC, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_DTVULN, DT_SONIC, NA, NULL);
addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL);
addot(OT_AMU_PARANOIA, "amulet of paranoia", "Makes the caster periodically hear fake noises nearby. Or are they real....?", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
// no autoid!
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_PARANOIA, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 900, NA, NA, NULL);
addot(OT_AMU_SLEEP, "amulet of peaceful slumber", "Blocks out all sound while the wearer sleeps.", MT_METAL, 0.3, OC_AMULET, SZ_TINY); addot(OT_AMU_SLEEP, "amulet of peaceful slumber", "Blocks out all sound while the wearer sleeps.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
// no autoid!
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_STARTBLESSED, B_CURSED, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL);
addot(OT_AMU_SPELLBOOST, "archmage's amulet", "Greatly increases the power of the wearer's spells.", MT_METAL, 0.3, OC_AMULET, SZ_TINY); addot(OT_AMU_SPELLBOOST, "archmage's amulet", "Greatly increases the power of the wearer's spells.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, ""); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, "");
addflag(lastot->flags, F_VALUE, 900, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 900, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_MAGICBOOST, 5, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_MAGICBOOST, 5, NA, NULL);
addot(OT_AMU_SWIMMING, "amulet of graceful swimming", "These amulets were created by the naiads, in an attempt to prolong the life of their thralls. Upon contact with deep water, its wearer will instantly transform into a white swan.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastot->flags, F_VALUE, 900, NA, NA, NULL);
addot(OT_AMU_THIEF, "thief's amulet", "Crafted by a master thief, it allows its wearer the uncanny ability to pick almost any lock.", MT_METAL, 0.3, OC_AMULET, SZ_TINY); addot(OT_AMU_THIEF, "thief's amulet", "Crafted by a master thief, it allows its wearer the uncanny ability to pick almost any lock.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_PICKLOCK, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_CANWILL, OT_A_PICKLOCK, NA, NULL);
addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL);
addot(OT_AMU_VICTIM, "amulet of victimisation", "Causes all creatures who view the wearer to become hostile and agressive.", MT_METAL, 0.3, OC_AMULET, SZ_TINY); addot(OT_AMU_VICTIM, "amulet of victimisation", "Causes all creatures who view the wearer to become hostile and agressive.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
// no autoid!
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastot->flags, F_VALUE, 900, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 900, NA, NA, NULL);
addot(OT_AMU_VSESP, "amulet versus esp", "Protects its wearer from all psionic attacks.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_MINDSHIELD, B_TRUE, NA, NULL);
addflag(lastot->flags, F_VALUE, 600, NA, NA, NULL);
addot(OT_AMU_VSMAGIC, "amulet versus magic", "Confers a moderate level of magic resistance upon its wearer.", MT_METAL, 0.3, OC_AMULET, SZ_TINY); addot(OT_AMU_VSMAGIC, "amulet versus magic", "Confers a moderate level of magic resistance upon its wearer.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_RESISTMAG, 66, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_RESISTMAG, 66, NA, NULL);
@ -8107,6 +8132,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CASTCHANCE, 100, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 100, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, NULL);
addflag(lastrace->flags, F_AUTOROTATE, 1, NA, NA, NULL); addflag(lastrace->flags, F_AUTOROTATE, 1, NA, NA, NULL);
addflag(lastrace->flags, F_FOLLOWTIME, 3, NA, NA, NULL);
// human monsters... // human monsters...
@ -8857,7 +8883,8 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, 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_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_LIFEOB, OT_TREE, 2, 3, NULL); addflag(lastrace->flags, F_LIFEOB, OT_TREE, 2, 3, NULL);
addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "tree"); addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "tree");
addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "random gem"); addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "random gem");
@ -8872,6 +8899,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CANCAST, OT_S_CHARM, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANCAST, OT_S_CHARM, NA, NA, "pw:1;");
//addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, 10, 10, NULL); //addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, 10, 10, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_PLANTWALK, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_PLANTWALK, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_CHARM, NA, B_APPENDYOU, "beckons");
addflag(lastrace->flags, F_WANTSOBFLAG, F_GEM, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_GEM, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_WANTS, OT_GOLD, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
@ -9188,7 +9216,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 10, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 7, NA, NULL);
addflag(lastrace->flags, F_STARTOBWEPSK, 50, SK_POLEARMS, NA, NULL); addflag(lastrace->flags, F_STARTOBWEPSK, 50, SK_POLEARMS, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "shield"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "shield");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "leather armour");
@ -9698,7 +9726,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTJOB, 15, J_WARRIOR, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 15, J_WARRIOR, NA, NULL);
addflag(lastrace->flags, F_STARTJOB, 15, J_DRUID, NA, NULL); addflag(lastrace->flags, F_STARTJOB, 15, J_DRUID, NA, NULL);
addrace(R_MALIK, "malik", 5, 'n', C_BLUE, MT_FLESH, RC_MAGIC, "An evil fairy who thrives on murder. They delight in teleporting behind their victims for a quick backstab."); addrace(R_MALIK, "malik", 5, 'n', C_YELLOW, MT_FLESH, RC_MAGIC, "An evil fairy who thrives on murder. They delight in teleporting behind their victims for a quick backstab.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_NOCORPSE, NA, NA, NA, NULL); addflag(lastrace->flags, F_NOCORPSE, NA, NA, NA, NULL);
@ -9740,7 +9768,7 @@ void initrace(void) {
addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL);
addflag(lastrace->flags, F_HATESRACE, R_GNOLL, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACE, R_GNOLL, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "6d4+6"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "6d4+6");
addflag(lastrace->flags, F_TR, 6, NA, NA, NULL); addflag(lastrace->flags, F_TR, 7, NA, NA, NULL);
addflag(lastrace->flags, F_ARMOURRATING, 12, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 12, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_STAYINROOM, NA, NA, NA, NULL); // stay in our maze addflag(lastrace->flags, F_STAYINROOM, NA, NA, NA, NULL); // stay in our maze
@ -9774,7 +9802,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_FOREST, 66, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 66, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, 66, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, 66, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+0"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+0");
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); addflag(lastrace->flags, F_TR, 4, NA, NA, NULL);
addflag(lastrace->flags, F_EVASION, -5, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, -5, NA, NA, NULL);
addflag(lastrace->flags, F_ARMOURRATING, 11, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 11, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
@ -9809,7 +9837,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_FOREST, 66, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 66, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, 66, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, 66, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+0"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4+0");
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL); addflag(lastrace->flags, F_TR, 4, NA, NA, NULL);
addflag(lastrace->flags, F_ARMOURRATING, 8, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 8, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, 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_ACTIONSPEED, SP_NORMAL, NA, NA, "");
@ -10113,7 +10141,7 @@ void initrace(void) {
addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 3, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_SKILLED, NA, NULL);
addrace(R_POLTERGEIST, "poltergeist", 50, 'P', C_GREEN, MT_FLESH, RC_UNDEAD, "An evil ghostly spirit who telekinetically throws objects at its enemies."); // sPirit addrace(R_POLTERGEIST, "poltergeist", 50, 'p', C_GREEN, MT_FLESH, RC_UNDEAD, "An evil ghostly spirit who telekinetically throws objects at its enemies."); // sPirit
addbodypart(lastrace, BP_BODY, NULL); addbodypart(lastrace, BP_BODY, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
@ -10140,6 +10168,8 @@ void initrace(void) {
addflag(lastrace->flags, F_XPMULTIPLY, 2, NA, NA, NULL); addflag(lastrace->flags, F_XPMULTIPLY, 2, NA, NA, NULL);
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_INVISIBLE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STAYINROOM, NA, NA, NA, NULL);
addrace(R_PRIMALFIRE, "fire primality", 50, 'E', C_RED, MT_FIRE, RC_HUMANOID, "A living mass of fire, animated by powerful magic."); addrace(R_PRIMALFIRE, "fire primality", 50, 'E', C_RED, MT_FIRE, RC_HUMANOID, "A living mass of fire, animated by powerful magic.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -10276,6 +10306,50 @@ void initrace(void) {
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addrace(R_LAVAX, "lavax", 90, 'h', C_RED, MT_FLESH, RC_HUMANOID, "The Lavax are a race of humanoid creatures who dwell in volcanic regions. Their skin has hardened into a clay-like substance, and is completely immune to the effects of heat or fire.");
setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, "gne");
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4");
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL);
addflag(lastrace->flags, F_ARMOURRATING, 6, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 9, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_WEAPON, RANDOM, NULL);
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSBETTERARM, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
addrace(R_SASQUATCH, "sasquatch", 90, 'h', C_CYAN, MT_FLESH, RC_HUMANOID, "Over the years, humans dwelling in cold climates have evolved into sasquatches, their skin now covered with fur to protect against the elements.");
setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, "gne");
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "6d4");
addflag(lastrace->flags, F_TR, 6, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 50, OC_WEAPON, RANDOM, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 9, NA, NULL);
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSBETTERARM, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addrace(R_SATYR, "satyr", 80, 'h', C_GREEN, MT_FLESH, RC_HUMANOID, "A goat-like humanoid equipped with a set of magical panpipes."); addrace(R_SATYR, "satyr", 80, 'h', C_GREEN, MT_FLESH, RC_HUMANOID, "A goat-like humanoid equipped with a set of magical panpipes.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -10514,19 +10588,20 @@ void initrace(void) {
setbodypartname(lastrace, BP_HANDS, "claws"); setbodypartname(lastrace, BP_HANDS, "claws");
setbodypartname(lastrace, BP_RIGHTFINGER, "right foreclaw"); setbodypartname(lastrace, BP_RIGHTFINGER, "right foreclaw");
setbodypartname(lastrace, BP_LEFTFINGER, "left foreclaw"); setbodypartname(lastrace, BP_LEFTFINGER, "left foreclaw");
lastrace->baseid = R_TROLL;
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+0"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4");
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL); addflag(lastrace->flags, F_TR, 5, NA, NA, NULL);
addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 12, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 8, NA, NULL);
addflag(lastrace->flags, F_REGENERATES, 2, NA, NA, NULL); addflag(lastrace->flags, F_REGENERATES, 2, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL);
@ -10535,6 +10610,8 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL);
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLL, NULL); addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLL, NULL);
addrace(R_TROLLKIN, "trollkin", 100, 't', C_GREY, MT_FLESH, RC_HUMANOID, "Trollkins are the horrific offspring of a troll and a human. While they lack the regenerative abilities of a standard troll, their human genes grant them a greater level of intelligence."); addrace(R_TROLLKIN, "trollkin", 100, 't', C_GREY, MT_FLESH, RC_HUMANOID, "Trollkins are the horrific offspring of a troll and a human. While they lack the regenerative abilities of a standard troll, their human genes grant them a greater level of intelligence.");
@ -10554,7 +10631,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 8, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 7, NA, NULL);
addflag(lastrace->flags, F_REGENERATES, 1, NA, NA, NULL); addflag(lastrace->flags, F_REGENERATES, 1, NA, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 90, OC_WEAPON, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 90, OC_WEAPON, NA, NULL);
addflag(lastrace->flags, F_STARTOBCLASS, 70, OC_ARMOUR, NA, NULL); addflag(lastrace->flags, F_STARTOBCLASS, 70, OC_ARMOUR, NA, NULL);
@ -10573,6 +10650,7 @@ void initrace(void) {
setbodypartname(lastrace, BP_HANDS, "claws"); setbodypartname(lastrace, BP_HANDS, "claws");
setbodypartname(lastrace, BP_RIGHTFINGER, "right foreclaw"); setbodypartname(lastrace, BP_RIGHTFINGER, "right foreclaw");
setbodypartname(lastrace, BP_LEFTFINGER, "left foreclaw"); setbodypartname(lastrace, BP_LEFTFINGER, "left foreclaw");
lastrace->baseid = R_TROLL;
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
@ -10598,14 +10676,17 @@ void initrace(void) {
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FROSTBITE, NA, NA, "exhales a freezing wind"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FROSTBITE, NA, NA, "exhales a freezing wind");
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLL, NULL); addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLLSNOW, NULL);
addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "50"); addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "50");
addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addrace(R_TROLLSWAMP, "swamp troll", 100, 't', C_BOLDGREEN, MT_FLESH, RC_HUMANOID, "Twisted trolls who roam the swamplands, their claws infected with a lethal poison."); addrace(R_TROLLSWAMP, "swamp troll", 100, 't', C_BOLDGREEN, MT_FLESH, RC_HUMANOID, "Twisted trolls who roam the swamplands, their claws infected with a lethal poison.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
setbodypartname(lastrace, BP_HANDS, "claws"); setbodypartname(lastrace, BP_HANDS, "claws");
setbodypartname(lastrace, BP_RIGHTFINGER, "right foreclaw"); setbodypartname(lastrace, BP_RIGHTFINGER, "right foreclaw");
setbodypartname(lastrace, BP_LEFTFINGER, "left foreclaw"); setbodypartname(lastrace, BP_LEFTFINGER, "left foreclaw");
lastrace->baseid = R_TROLL;
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
@ -10617,7 +10698,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 12, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 8, NA, NULL);
addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 32, "5-10"); addflag(lastrace->flags, F_HITCONFER, F_POISONED, SC_POISON, 32, "5-10");
addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 3, NA, NULL); addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 3, NA, NULL);
addflag(lastrace->flags, F_REGENERATES, 2, NA, NA, NULL); addflag(lastrace->flags, F_REGENERATES, 2, NA, NA, NULL);
@ -10629,7 +10710,9 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL);
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLL, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLLSWAMP, NULL);
addrace(R_XAT, "xat", 2, 'x', C_BROWN, MT_FLESH, RC_ANIMAL, "Xats are wild pigs with the claws of a dog."); addrace(R_XAT, "xat", 2, 'x', C_BROWN, MT_FLESH, RC_ANIMAL, "Xats are wild pigs with the claws of a dog.");
setbodytype(lastrace, BT_QUADRAPED); setbodytype(lastrace, BT_QUADRAPED);
@ -10669,6 +10752,29 @@ void initrace(void) {
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
addrace(R_FISHFOLK, "fishfolk", 75, 'h', C_BOLDBLUE, MT_FLESH, RC_HUMANOID, "Water-dwelling humanoids capable of breathing normally in both water and air.");
setbodytype(lastrace, BT_HUMANOID);
addbodypart(lastrace, BP_TAIL, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, 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, NA, NA, NA, "2d3+4");
addflag(lastrace->flags, F_TR, 3, 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_HASATTACK, OT_FISTS, 2, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "trident");
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "spear");
addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSBETTERWEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSBETTERARM, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, "gne");
addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_BREATHWATER, B_TRUE, NA, NA, "");
addrace(R_MERLOCH, "merloch", 250, 'm', C_ORANGE, MT_FLESH, RC_AQUATIC, "Merlochs are bipedal, fishlike beings. Equally at home in the water or on land, they use their sonic scream to disable foes."); addrace(R_MERLOCH, "merloch", 250, 'm', C_ORANGE, MT_FLESH, RC_AQUATIC, "Merlochs are bipedal, fishlike beings. Equally at home in the water or on land, they use their sonic scream to disable foes.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
noarmouron(lastrace, BP_RIGHTFINGER); noarmouron(lastrace, BP_RIGHTFINGER);
@ -10687,6 +10793,8 @@ void initrace(void) {
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL); addflag(lastrace->flags, F_TR, 5, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, "");
addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_BREATHWATER, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL);
@ -11091,8 +11199,8 @@ void initrace(void) {
addflag(lastrace->flags, F_NUMAPPEAR, 3, 4, NA, ""); addflag(lastrace->flags, F_NUMAPPEAR, 3, 4, NA, "");
addflag(lastrace->flags, F_ARMOURRATING, 4, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 4, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+3"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+3");
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL); addflag(lastrace->flags, F_TR, 2, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, 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_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
@ -11105,7 +11213,7 @@ void initrace(void) {
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
addrace(R_ANTS, "giant soldier ant", 25, 'a', C_BROWN, MT_FLESH, RC_ANIMAL, "The fighter of the giant ant family. Giant soldier ants are equipped with a powerful acidic stinger."); addrace(R_ANTS, "giant soldier ant", 25, 'a', C_RED, MT_FLESH, RC_ANIMAL, "The fighter of the giant ant family. Giant soldier ants are equipped with a powerful acidic stinger.");
setbodytype(lastrace, BT_QUADRAPED); setbodytype(lastrace, BT_QUADRAPED);
lastrace->baseid = R_ANT; lastrace->baseid = R_ANT;
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -11115,15 +11223,17 @@ void initrace(void) {
addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+4"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+4");
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL); addflag(lastrace->flags, F_TR, 4, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, 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_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, ""); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, "");
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 4, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 4, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, "dam:1d8+3;"); addflag(lastrace->flags, F_HASATTACK, OT_STING, 6, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_STINGACID, NA, NA, "dam:1d6+3;needgrab:1;"); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, "dam:1d6;");
addflag(lastrace->flags, F_CANWILL, OT_A_STINGACID, NA, NA, "dam:3d3;needgrab:1;");
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling"); addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling");
@ -11141,13 +11251,13 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "6d4+6"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "6d4+6");
addflag(lastrace->flags, F_TR, 6, NA, NA, NULL); addflag(lastrace->flags, F_TR, 7, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, 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_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, ""); addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, "");
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 15, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 8, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, "dam:2d4;"); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, "dam:2d4;");
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
@ -11157,6 +11267,33 @@ void initrace(void) {
addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
// note: queen and does NOT have baseid ant. this is so that ant nests will only
// have one queen.
addrace(R_ANTQUEEN, "queen ant", 50, 'a', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Like their regular-sized counterparts, giant queen ants prefer to rely largely on their workers and soldiers for protection. If required however, they are quite capable of protecting themselves.");
setbodytype(lastrace, BT_QUADRAPED);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_MINIONS, 100, 5, 8, "random ant");
addflag(lastrace->flags, F_ARMOURRATING, 6, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "10d4");
addflag(lastrace->flags, F_TR, 10, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, 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_FLEEONHPPCT, 50, NA, NA, "");
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_STING, 12, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^scuttling");
addflag(lastrace->flags, F_ENHANCESMELL, 6, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_BILCO, "bilco", 25, ';', C_BOLDCYAN, MT_FLESH, RC_ANIMAL, "Bilcos appear to be abnormally large frogs with a strange blue tinge. Seasoned travellers know to beware the bilco's gurgle, which portends them belching out a massive torrent of water."); addrace(R_BILCO, "bilco", 25, ';', C_BOLDCYAN, MT_FLESH, RC_ANIMAL, "Bilcos appear to be abnormally large frogs with a strange blue tinge. Seasoned travellers know to beware the bilco's gurgle, which portends them belching out a massive torrent of water.");
setbodytype(lastrace, BT_QUADRAPED); setbodytype(lastrace, BT_QUADRAPED);
@ -11201,6 +11338,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "0d4+1"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "0d4+1");
addflag(lastrace->flags, F_TR, 0, NA, NA, NULL); addflag(lastrace->flags, F_TR, 0, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_BEAK, 2, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_BEAK, 2, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL);
addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL);
@ -11598,7 +11736,7 @@ void initrace(void) {
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
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."); 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_BODY, NULL);
addbodypart(lastrace, BP_HEAD, NULL); addbodypart(lastrace, BP_HEAD, NULL);
addbodypart(lastrace, BP_EYES, NULL); addbodypart(lastrace, BP_EYES, NULL);
@ -11628,7 +11766,7 @@ void initrace(void) {
addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_SNAIL, "mottled snail", 150, 'p', C_BROWN, MT_FLESH, RC_ANIMAL, "An enormous snail, protected by a hard, scaled shell and gifted with long, sharp fangs."); addrace(R_SNAIL, "mottled snail", 150, 'P', C_BROWN, MT_FLESH, RC_ANIMAL, "An enormous snail, protected by a hard, scaled shell and gifted with long, sharp fangs.");
addbodypart(lastrace, BP_BODY, NULL); addbodypart(lastrace, BP_BODY, NULL);
addbodypart(lastrace, BP_HEAD, NULL); addbodypart(lastrace, BP_HEAD, NULL);
addbodypart(lastrace, BP_EYES, NULL); addbodypart(lastrace, BP_EYES, NULL);
@ -11960,6 +12098,29 @@ void initrace(void) {
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, ""); addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addrace(R_SWAN, "swan", 1, 'c', C_WHITE, MT_FLESH, RC_ANIMAL, "A graceful waterbird.");
setbodytype(lastrace, BT_BIRD);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+2");
addflag(lastrace->flags, F_TR, 0, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_BEAK, 1, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_BEAK, 1, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_SWIMMING, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "squarks^squarking");
addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL);
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TIMID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_AVIAN, B_TRUE, NA, NA, NULL);
addrace(R_WOLFYOUNG, "young wolf", 10, 'd', C_GREY, MT_FLESH, RC_ANIMAL, "Immature wolves."); addrace(R_WOLFYOUNG, "young wolf", 10, 'd', C_GREY, MT_FLESH, RC_ANIMAL, "Immature wolves.");
setbodytype(lastrace, BT_QUADRAPED); setbodytype(lastrace, BT_QUADRAPED);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -13155,7 +13316,7 @@ void initrace(void) {
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addrace(R_GHOST, "ghost", 50, 'P', C_BLUE, MT_MAGIC, RC_UNDEAD, "Wispy spirits formed when a soul refuses to depart the earthly realm after death, ghosts exist part way between dimensions. The sight of a ghost can cause fear in all who behold it, and their ethereal nature makes them immune to most attacks."); // p for sPirit addrace(R_GHOST, "ghost", 50, 'p', C_BLUE, MT_MAGIC, RC_UNDEAD, "Wispy spirits formed when a soul refuses to depart the earthly realm after death, ghosts exist part way between dimensions. The sight of a ghost can cause fear in all who behold it, and their ethereal nature makes them immune to most attacks."); // p for sPirit
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL);
@ -13183,8 +13344,11 @@ void initrace(void) {
addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_INDUCEFEAR, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_INDUCEFEAR, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_INVISIBILITY, 40, 40, "pw:1;"); addflag(lastrace->flags, F_CANCAST, OT_S_INVISIBILITY, 40, 40, "pw:1;");
addflag(lastrace->flags, F_LIFEOB, OT_CORPSE, 5, 4, NULL);
addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "humanoid corpse");
// special: ghosts gain canwill->possession if they are near // special: ghosts gain canwill->possession if they are near
// their previous corpse. use f_mycorpse->oid for this. // their previous corpse. use f_lifeob with text=oid for this.
addrace(R_GHOUL, "ghoul", 50, 'Z', C_GREEN, MT_FLESH, RC_UNDEAD, "Ghouls are monstrous, undead humanoids who feed on flesh and reek of carrion. Their bodies are grey and hairless, their teeth fanged, and their nails sharped into deadly claws."); addrace(R_GHOUL, "ghoul", 50, 'Z', C_GREEN, MT_FLESH, RC_UNDEAD, "Ghouls are monstrous, undead humanoids who feed on flesh and reek of carrion. Their bodies are grey and hairless, their teeth fanged, and their nails sharped into deadly claws.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -13214,6 +13378,36 @@ void initrace(void) {
addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addrace(R_LICH, "lich", 50, 'L', C_MAGENTA, MT_FLESH, RC_UNDEAD, "Immensely powerful wizards can on rare occasions extend their own lives by becoming undead lichs. While their physical body continues to slowly decay, they remain all of their intellect and power.");
setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_EXHIGH, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_INDUCEFEAR, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "11d4");
addflag(lastrace->flags, F_TR, 11, 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_HASATTACK, OT_TOUCHCHILL, 10, NA, NULL);
addflag(lastrace->flags, F_HITCONFER, F_PARALYZED, SC_CON, 30, "1-2");
addflag(lastrace->flags, F_HITCONFERVALS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_ELECTRIC, NA, NA, NULL);
addflag(lastrace->flags, F_MINDSHIELD, 6, NA, NA, NULL);
addflag(lastrace->flags, F_RNDSPELLCOUNT, 6, NA, NA, NULL);
addflag(lastrace->flags, F_RNDSPELLSCHOOL, SS_DEATH, 1, 5, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_LORE_ARCANA, PR_EXPERT, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_SS_DEATH, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_LIFEOB, OT_GLASSJAR, 12, 20, NULL);
addflag(lastrace->flags, F_HOMEOB, 100, NA, NA, "ornate glass jar");
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "shouts^a shout");
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addrace(R_MUMMY, "mummy", 54, 'M', C_GREY, MT_FLESH, RC_UNDEAD, "A rotting humanoid figure clad in bandages."); addrace(R_MUMMY, "mummy", 54, 'M', C_GREY, MT_FLESH, RC_UNDEAD, "A rotting humanoid figure clad in bandages.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -13364,6 +13558,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+1"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "1d4+1");
addflag(lastrace->flags, F_TR, 1, NA, NA, NULL); addflag(lastrace->flags, F_TR, 1, NA, NA, NULL);
addflag(lastrace->flags, F_EVASION, 300, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 300, NA, NA, NULL);
addflag(lastrace->flags, F_NOATTACK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);

Binary file not shown.

View File

@ -1,12 +1,12 @@
@id:bear_cave @id:bear_cave
@map @map
########## ###########
###....### ####....###
##......## ###......##
O......B.# .O......B.#
##......## ###......##
###....### ####....###
########## ###########
@end @end
@legend @legend

23
defs.h
View File

@ -530,6 +530,7 @@ enum SAYPHRASE {
SP_BEGTHANKS, SP_BEGTHANKS,
SP_DIE, SP_DIE,
SP_DRUNK, SP_DRUNK,
SP_LIFEOB_DESTROYED,
SP_MERCYACCEPT, SP_MERCYACCEPT,
SP_INFO_ACCEPT, SP_INFO_ACCEPT,
SP_INFO_ASKPRICE, SP_INFO_ASKPRICE,
@ -1002,6 +1003,7 @@ enum RACE {
R_HOBGOBLINWAR, R_HOBGOBLINWAR,
R_KOBOLD, R_KOBOLD,
R_LEPRECHAUN, R_LEPRECHAUN,
R_LAVAX,
R_LIZARDMAN, R_LIZARDMAN,
R_MALIK, R_MALIK,
R_MINOTAUR, R_MINOTAUR,
@ -1022,6 +1024,7 @@ enum RACE {
R_PRIMALSTONE, R_PRIMALSTONE,
R_PRIMALSTONEL, R_PRIMALSTONEL,
R_SANDMAN, R_SANDMAN,
R_SASQUATCH,
R_SATYR, R_SATYR,
R_SHADOWCAT, R_SHADOWCAT,
R_SINKMITE, R_SINKMITE,
@ -1039,7 +1042,9 @@ enum RACE {
R_XAT, R_XAT,
// fish // fish
R_CRAB, R_CRAB,
R_FISHFOLK,
R_MERLOCH, R_MERLOCH,
R_MERMAN,
R_PIRANHA, R_PIRANHA,
R_PIRANHAKING, R_PIRANHAKING,
R_EELELEC, R_EELELEC,
@ -1054,6 +1059,7 @@ enum RACE {
R_UNYON, R_UNYON,
// animals // animals
R_ANT, R_ANT,
R_ANTQUEEN,
R_ANTS, R_ANTS,
R_ANTLION, R_ANTLION,
R_BAT, R_BAT,
@ -1091,6 +1097,7 @@ enum RACE {
R_SPIDERFUNNELWEB, R_SPIDERFUNNELWEB,
R_SPIDERREDBACK, R_SPIDERREDBACK,
R_SPIDERTOMB, R_SPIDERTOMB,
R_SWAN,
R_WOLFYOUNG, R_WOLFYOUNG,
R_WOLF, R_WOLF,
R_WOLFWINTER, R_WOLFWINTER,
@ -1131,6 +1138,7 @@ enum RACE {
R_GHAST, R_GHAST,
R_GHOST, R_GHOST,
R_GHOUL, R_GHOUL,
R_LICH,
R_MUMMY, R_MUMMY,
R_MUMMYG, R_MUMMYG,
R_REVENANT, R_REVENANT,
@ -1796,6 +1804,7 @@ enum OBTYPE {
OT_CHEST, OT_CHEST,
OT_EMPTYFLASK, OT_EMPTYFLASK,
OT_EMPTYVIAL, OT_EMPTYVIAL,
OT_GLASSJAR,
OT_CALTROP, OT_CALTROP,
OT_BROKENGLASS, OT_BROKENGLASS,
OT_ICECHUNK, OT_ICECHUNK,
@ -1911,15 +1920,20 @@ enum OBTYPE {
OT_SHIELDTOWER, OT_SHIELDTOWER,
// amulets // amulets
OT_AMU_ANGER, OT_AMU_ANGER,
OT_AMU_BLOOD,
OT_AMU_CHEF, OT_AMU_CHEF,
OT_AMU_ESCAPE, OT_AMU_ESCAPE,
OT_AMU_EVOLUTION,
OT_AMU_FALLING, OT_AMU_FALLING,
OT_AMU_FLIGHT, OT_AMU_FLIGHT,
OT_AMU_LISTEN, OT_AMU_LISTEN,
OT_AMU_PARANOIA,
OT_AMU_SLEEP, OT_AMU_SLEEP,
OT_AMU_SPELLBOOST, OT_AMU_SPELLBOOST,
OT_AMU_SWIMMING,
OT_AMU_THIEF, OT_AMU_THIEF,
OT_AMU_VICTIM, OT_AMU_VICTIM,
OT_AMU_VSESP,
OT_AMU_VSMAGIC, OT_AMU_VSMAGIC,
OT_AMU_VSPOISON, OT_AMU_VSPOISON,
// rings // rings
@ -2324,6 +2338,8 @@ enum FLAG {
F_REVIVETIMER, // v0 = cur, v1 = max. v0 incremenets each tick. F_REVIVETIMER, // v0 = cur, v1 = max. v0 incremenets each tick.
// when v0 == v1, this object changes into lf of race // when v0 == v1, this object changes into lf of race
// v2. // v2.
F_LIFEOBFOR, // this ob is the lifeobject for lf id v0.
F_HOMEOBFOR, // this ob is a homeobject for lf id v0.
F_DTCONVERT, // damtype val0 converts this to f->text F_DTCONVERT, // damtype val0 converts this to f->text
F_DTCREATEOB, // damtype val0 creates object f->text here F_DTCREATEOB, // damtype val0 creates object f->text here
// v1 = radius to burst in // v1 = radius to burst in
@ -2771,6 +2787,7 @@ enum FLAG {
F_ARMOURPENALTY, // lower your acc/ev by val0 due to cumbersome F_ARMOURPENALTY, // lower your acc/ev by val0 due to cumbersome
// armour. lowered by sk_armour skill. // armour. lowered by sk_armour skill.
// v0 is accuracy penalty, v1 is evasion penalty. // v0 is accuracy penalty, v1 is evasion penalty.
F_MINDSHIELD, // lf is immune to psionic attacks
F_MISCASTCHANCE, // lf has +v0% chance of spell failure F_MISCASTCHANCE, // lf has +v0% chance of spell failure
F_LEVRACE, // at level v0, this race is promoted to race v1 F_LEVRACE, // at level v0, this race is promoted to race v1
// must apply this to the BASE race. // must apply this to the BASE race.
@ -3083,7 +3100,8 @@ enum FLAG {
F_CANTALK, // this lf can talk, even if its raceclass normally F_CANTALK, // this lf can talk, even if its raceclass normally
// wouldn't be able to. // wouldn't be able to.
F_AQUATIC, // this race can attack normally in water and suffers no F_AQUATIC, // this race can attack normally in water and suffers no
// movement penalties // movement penalties. they can also swim at master
// level.
F_AVIAN, // this race is an avian F_AVIAN, // this race is an avian
F_CANINE, // this race is a canine F_CANINE, // this race is a canine
F_HUMANOID, // this race is a humanoid F_HUMANOID, // this race is a humanoid
@ -3095,6 +3113,7 @@ enum FLAG {
// if v0 is true or b_frominjury, you can regrow it // if v0 is true or b_frominjury, you can regrow it
// via a healing potion. // via a healing potion.
F_NOINJURIES, // this race cannot sustain injuries. F_NOINJURIES, // this race cannot sustain injuries.
F_NOATTACK, // this lf can't attack
F_NOPACK, // this race cannot hold objects F_NOPACK, // this race cannot hold objects
F_NOSPELLS, // this race cannot cast spells F_NOSPELLS, // this race cannot cast spells
F_NOPRINTS, // this race doesn't leave footprints F_NOPRINTS, // this race doesn't leave footprints
@ -3216,6 +3235,8 @@ enum FLAG {
F_PAIN, // take damage if you walk. v0=damtype,text is damage (xdy+z). F_PAIN, // take damage if you walk. v0=damtype,text is damage (xdy+z).
// if text not set, default dam is 1d2 // if text not set, default dam is 1d2
F_PARALYZED,// cannot do anything F_PARALYZED,// cannot do anything
F_PARANOIA, // mosnters randomly appear out of sight, or random
// noises happen from behind you.
F_PRONE, // lying on the ground F_PRONE, // lying on the ground
F_FROZEN, // made of ice F_FROZEN, // made of ice
F_HEAVENARM, // prevent the next v0 damage received. F_HEAVENARM, // prevent the next v0 damage received.

View File

@ -9,7 +9,7 @@ UNI_SOLID = deep water
A = avian / bird A = avian / bird
a = ant a = ant
B = bat B = bat
c = cockatrice / chicken c = cockatrice / chicken / small bird
C = celestial / divine ? C = celestial / divine ?
d = canine/dog d = canine/dog
D = ? D = ?
@ -25,14 +25,15 @@ i = insect
I = large insect I = large insect
j = jelly/ooze/leech j = jelly/ooze/leech
k = kobold k = kobold
L = lich, or other powerful undead ?
m = mutant / magic creature m = mutant / magic creature
M = mummy M = mummy
n = small humanoid / nymph / sprite n = small humanoid / nymph / sprite
N = necron N = necron
o = orc o = orc
O = monstrous humanoid (ie. ogre) O = monstrous humanoid (ie. ogre)
p = gastropod P = gastropod
P = sPirit p = sPirit
q = quadraped q = quadraped
Q = large quadraped Q = large quadraped
r = rodent r = rodent

21
io.c
View File

@ -1321,6 +1321,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
case F_MINDSHIELD:
if (isplayer(lf)) {
msg("^gYour mind feels insulated.^n");
donesomething = B_TRUE;
}
break;
case F_MISCASTCHANCE: case F_MISCASTCHANCE:
if (isplayer(lf)) { if (isplayer(lf)) {
msg("Your magical ability feels unreliable..."); msg("Your magical ability feels unreliable...");
@ -2048,6 +2054,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
case F_MINDSHIELD:
if (isplayer(lf)) {
msg("Your mind no longer feels insulated.");
donesomething = B_TRUE;
}
break;
case F_MISCASTCHANCE: case F_MISCASTCHANCE:
if (isplayer(lf)) { if (isplayer(lf)) {
msg("Your magical ability no longer feels unreliable."); msg("Your magical ability no longer feels unreliable.");
@ -6509,6 +6521,10 @@ char *makedesc_ob(object_t *o, char *retbuf) {
sprintf(buf2, "%s boosts the power of your spells by %d.\n", buf, f->val[1]); sprintf(buf2, "%s boosts the power of your spells by %d.\n", buf, f->val[1]);
strncat(retbuf, buf2, HUGEBUFLEN); strncat(retbuf, buf2, HUGEBUFLEN);
break; break;
case F_MINDSHIELD:
sprintf(buf2, "%s protects you from psionic attacks.\n", buf);
strncat(retbuf, buf2, HUGEBUFLEN);
break;
case F_MISCASTCHANCE: case F_MISCASTCHANCE:
sprintf(buf2, "%s causes your spells to become unreliable.\n", buf); sprintf(buf2, "%s causes your spells to become unreliable.\n", buf);
strncat(retbuf, buf2, HUGEBUFLEN); strncat(retbuf, buf2, HUGEBUFLEN);
@ -12624,6 +12640,11 @@ void showlfstats(lifeform_t *lf, int showall) {
isplayer(lf) ? "your" : "its", boost); isplayer(lf) ? "your" : "its", boost);
y++; y++;
} }
f = lfhasknownflag(lf, F_MINDSHIELD);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s are protected from psionic attacks.", you(lf));
y++;
}
f = lfhasknownflag(lf, F_MISCASTCHANCE); f = lfhasknownflag(lf, F_MISCASTCHANCE);
if (f && (f->known)) { if (f && (f->known)) {
int chance; int chance;

460
lf.c
View File

@ -200,6 +200,8 @@ void bleed(lifeform_t *lf, int splatter) {
if (lf->cell->type->solid) return; if (lf->cell->type->solid) return;
if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) return; if (hasobwithflag(lf->cell->obpile, F_DEEPWATER)) return;
if (hasequippedobid(lf->pack, OT_AMU_BLOOD)) return;
f = lfhasflag(lf, F_BLOODOB); f = lfhasflag(lf, F_BLOODOB);
if (f) { if (f) {
if (f->text) { if (f->text) {
@ -540,7 +542,12 @@ int canattack(lifeform_t *lf) {
} else if (lfhasflag(lf, F_STUNNED)) { } else if (lfhasflag(lf, F_STUNNED)) {
reason = E_STUNNED; reason = E_STUNNED;
return B_FALSE; return B_FALSE;
} else if (lfhasflag(lf, F_NOATTACK)) {
reason = E_IMPOSSIBLE;
return B_FALSE;
} }
return B_TRUE; return B_TRUE;
} }
@ -2089,7 +2096,7 @@ int charmedaction(lifeform_t *lf, flag_t *charmflag) {
} else { } else {
char obname[BUFLEN]; char obname[BUFLEN];
getobname(o, obname, o->amt); getobname(o, obname, o->amt);
msg("You hand over your %s to %s.", obname, msg("^wYou hand over your %s to %s.", obname,
cansee(lf, charmer) ? charmername : "your new master"); cansee(lf, charmer) ? charmername : "your new master");
moveob(o, charmer->pack, o->amt); moveob(o, charmer->pack, o->amt);
} }
@ -2108,7 +2115,7 @@ int charmedaction(lifeform_t *lf, flag_t *charmflag) {
} }
} }
if (!ndone) { if (!ndone) {
msg("You bask in the glory of %s!", cansee(lf, charmer) ? charmername : "your new master"); msg("^wYou bask in the glory of %s!", cansee(lf, charmer) ? charmername : "your new master");
taketime(lf, getactspeed(lf)); taketime(lf, getactspeed(lf));
} }
} else { } else {
@ -2117,10 +2124,10 @@ int charmedaction(lifeform_t *lf, flag_t *charmflag) {
turntoface(lf, charmer->cell); turntoface(lf, charmer->cell);
dir = getdirtowards(lf->cell, charmer->cell, lf, B_FALSE, DT_ORTH); dir = getdirtowards(lf->cell, charmer->cell, lf, B_FALSE, DT_ORTH);
if (dir == D_NONE) { if (dir == D_NONE) {
msg("You try to %s towards %s, but fail.", getmoveverb(lf), msg("^wYou try to %s towards %s, but fail.", getmoveverb(lf),
cansee(lf, charmer) ? charmername : "your new master"); cansee(lf, charmer) ? charmername : "your new master");
} else { } else {
msg("You mindlessly %s towards %s.", getmoveverb(lf), msg("^wYou mindlessly %s towards %s.", getmoveverb(lf),
cansee(lf, charmer) ? charmername : "your new master"); cansee(lf, charmer) ? charmername : "your new master");
trymove(lf, dir, B_FALSE, B_TRUE); trymove(lf, dir, B_FALSE, B_TRUE);
} }
@ -2163,11 +2170,34 @@ int checkfordrowning(lifeform_t *lf, object_t *o) {
return B_FALSE; return B_FALSE;
} }
depth = getobdepth(o, lf);
// activate amulet of swimming
if (depth >= DP_HEAD) {
object_t *o;
o = hasequippedobid(lf->pack, OT_AMU_SWIMMING);
if (o && !ispolymorphed(lf)) {
// transform into a swan!
if (!polymorphto(lf, R_SWAN, PERMENANT)) makeknown(o->type->id);
}
o = hasequippedobid(lf->pack, OT_AMU_EVOLUTION);
if (o) {
if (!polymorphto(lf, R_FISHFOLK, 5)) makeknown(o->type->id);
}
}
// recalculate depth now
depth = getobdepth(o, lf);
if (lfhasflag(lf, F_AQUATIC)) {
slev = PR_MASTER;
} else {
i = getskill(lf, SK_SWIMMING) - isburdened(lf); i = getskill(lf, SK_SWIMMING) - isburdened(lf);
limit(&i, 0, NA); limit(&i, 0, NA);
slev = i; slev = i;
}
depth = getobdepth(o, lf);
// apply water damage (ie rust etc) to armour. // apply water damage (ie rust etc) to armour.
for (i = 0; i <= depth; i++) { for (i = 0; i <= depth; i++) {
@ -2740,12 +2770,35 @@ void die(lifeform_t *lf) {
msg("^GYou feel the presence of a nearby coffin..."); msg("^GYou feel the presence of a nearby coffin...");
} else { } else {
addflag(lf->flags, F_WANTS, OT_COFFIN, B_COVETS, NA, NULL); addflag(lf->flags, F_WANTS, OT_COFFIN, B_COVETS, NA, NULL);
//killflagsofid(lf->flags, F_HOSTILE);
addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
} }
return; return;
} }
} }
if (lf->race->id == R_LICH) {
f = lfhasflag(lf, F_LIFEOB);
if (f) {
cell_t *loc;
loc = findnearbylifeob(lf->cell, UNLIMITED, f, NULL);
if (loc) {
// announce
if (thisisplayer) {
msg("^GYou feel your soul being pulled to safety!^n");
}
// teleport back to life ob, and revive.
teleportto(lf, loc, B_FALSE);
// restore all hp
lf->hp = lf->maxhp;
killflagsofid(lf->flags, F_DEAD);
return;
}
} else {
noise(lf->cell, lf, NC_OTHER, SV_CAR, "a horrified scream!", "screams in horror!");
}
}
if (lf->race->id == R_GLOWBUG) { if (lf->race->id == R_GLOWBUG) {
// final spell... // final spell...
castspell(lf, OT_S_FLASH, NULL, NULL, lf->cell, NULL, NULL); castspell(lf, OT_S_FLASH, NULL, NULL, lf->cell, NULL, NULL);
@ -5237,10 +5290,16 @@ lifeform_t *findlfunique(enum RACE rid) {
return NULL; return NULL;
} }
cell_t *findnearbylifeob(cell_t *src, flag_t *lifeobflag, object_t **retlifeob) { // if maxdist is NA, use the distance from the flag
// if maxdist is UNLIMITED, search the entire map
cell_t *findnearbylifeob(cell_t *src, int maxdist, flag_t *lifeobflag, object_t **retlifeob) {
object_t *corpse = NULL; object_t *corpse = NULL;
int maxdist;
if (maxdist == NA) {
maxdist = lifeobflag->val[1]; maxdist = lifeobflag->val[1];
} else if (maxdist == UNLIMITED) {
maxdist = MAXOF(src->map->w, src->map->h);
}
if (retlifeob) { if (retlifeob) {
*retlifeob = NULL; *retlifeob = NULL;
@ -5256,13 +5315,13 @@ cell_t *findnearbylifeob(cell_t *src, flag_t *lifeobflag, object_t **retlifeob)
} }
} else { } else {
// find closest location with corpse... // find closest location with corpse...
cell_t *retcell[MAXCANDIDATES]; cell_t *retcell[MAX_MAPW*MAX_MAPH];
int nretcells,i; int nretcells,i;
enum OBTYPE oid; enum OBTYPE oid;
int mindist = 9999; int mindist = 9999;
oid = lifeobflag->val[0]; oid = lifeobflag->val[0];
getradiuscells(src, maxdist, DT_COMPASS, B_FALSE, LOF_DONTNEED, B_FALSE, retcell, &nretcells, 0); getradiuscells(src, maxdist, DT_COMPASS, B_FALSE, LOF_DONTNEED, B_TRUE, retcell, &nretcells, 0);
for (i = 0; i < nretcells; i++) { for (i = 0; i < nretcells; i++) {
object_t *o; object_t *o;
cell_t *c; cell_t *c;
@ -5313,6 +5372,7 @@ race_t *findrace(enum RACE id) {
race_t *findracebyname(char *name) { race_t *findracebyname(char *name) {
race_t *r; race_t *r;
raceclass_t *rc; raceclass_t *rc;
char searchfor[BUFLEN];
// first check for exact matches // first check for exact matches
for (r = firstrace; r ; r = r->next) { for (r = firstrace; r ; r = r->next) {
if (!strcmp(r->name, name)) { if (!strcmp(r->name, name)) {
@ -5329,6 +5389,15 @@ race_t *findracebyname(char *name) {
} }
} }
// ...then partial matches start of words in name
// ie. "ant" should match "soldier ant" before matching "giant"
sprintf(searchfor, " %s",name);
for (r = firstrace; r ; r = r->next) {
if (strstr(r->name, searchfor)) {
return r;
}
}
// ...then partial matches in names // ...then partial matches in names
for (r = firstrace; r ; r = r->next) { for (r = firstrace; r ; r = r->next) {
if (strstr(r->name, name)) { if (strstr(r->name, name)) {
@ -7543,7 +7612,9 @@ int getnightvisrange(lifeform_t *lf) {
} }
// populates heartext, seetext and volume // populates heartext, seetext and volume
int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, char *heartext,char *seetext, int *volume) { // "lf" is optional. if not given, "noiseflag" should be provided.
// returns
int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, flag_t *noiseflag, char *heartext,char *seetext, int *volume) {
flag_t *retflag[MAXCANDIDATES],*nflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES],*nflag[MAXCANDIDATES];
int nretflags, i,nnflags = 0; int nretflags, i,nnflags = 0;
@ -7552,6 +7623,7 @@ int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, char *heartext,
if (heartext) strcpy(heartext, ""); if (heartext) strcpy(heartext, "");
if (seetext) strcpy(seetext, ""); if (seetext) strcpy(seetext, "");
if (lf) {
if (lfhasflag(lf, F_FROZEN)) { if (lfhasflag(lf, F_FROZEN)) {
// can't make noise if frozen! // can't make noise if frozen!
return B_TRUE; return B_TRUE;
@ -7571,21 +7643,23 @@ int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, char *heartext,
} }
if (nnflags) { if (nnflags) {
flag_t *f; noiseflag = nflag[rnd(0,nnflags-1)];
}
}
if (noiseflag) {
char verb[BUFLEN], noun[BUFLEN]; char verb[BUFLEN], noun[BUFLEN];
f = nflag[rnd(0,nnflags-1)]; if (volume) *volume = noiseflag->val[1];
if (volume) *volume = f->val[1]; if (noiseflag->text[0] == '^') {
if (f->text[0] == '^') {
strcpy(verb, ""); strcpy(verb, "");
//noun = strtok_r(f->text, "^", &dummy); //noun = strtok_r(noiseflag->text, "^", &dummy);
strcpy(noun, f->text + 1); strcpy(noun, noiseflag->text + 1);
} else { } else {
char *p; char *p;
p = readuntil(verb, f->text, '^'); p = readuntil(verb, noiseflag->text, '^');
readuntil(noun, p, '^'); // ie eol readuntil(noun, p, '^'); // ie eol
//verb = strtok_r(f->text, "^", &dummy); //verb = strtok_r(noiseflag->text, "^", &dummy);
//noun = strtok_r(NULL, "^", &dummy); //noun = strtok_r(NULL, "^", &dummy);
} }
@ -7600,10 +7674,10 @@ int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, char *heartext,
} }
} }
if (nid == N_WALK) { if (nid == N_WALK) {
*volume += getarmournoise(lf); if (lf) *volume += getarmournoise(lf);
} }
return B_FALSE; return B_FALSE;
} else { } else if (lf) {
// some defaults // some defaults
if (nid == N_WALK) { if (nid == N_WALK) {
enum LFSIZE sz; enum LFSIZE sz;
@ -7664,6 +7738,7 @@ int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, char *heartext,
if (seetext) strcpy(seetext, "shouts a blood-curdling war-cry!"); if (seetext) strcpy(seetext, "shouts a blood-curdling war-cry!");
return B_FALSE; return B_FALSE;
} }
// failed!
return B_TRUE; return B_TRUE;
} }
return B_FALSE; return B_FALSE;
@ -14397,6 +14472,8 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
// further effects if not dead... // further effects if not dead...
if (!isdead(lf)) { if (!isdead(lf)) {
object_t *o;
// fight back if required // fight back if required
if (fromlf && retaliate && !ko) { if (fromlf && retaliate && !ko) {
fightback(lf, fromlf); fightback(lf, fromlf);
@ -14480,6 +14557,19 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
more(); more();
} }
} }
o = hasequippedobid(lf->pack, OT_AMU_EVOLUTION);
if (o) {
enum DAMTYPE basedt;
basedt = basedamagetype(damtype);
if (basedt == DT_FIRE) {
if (!polymorphto(lf, R_LAVAX, 5)) makeknown(o->type->id);
} else if (basedt == DT_COLD) {
if (!polymorphto(lf, R_SASQUATCH, 5)) makeknown(o->type->id);
}
}
} // end if !isdead } // end if !isdead
} }
@ -14596,7 +14686,7 @@ void makenoise(lifeform_t *lf, enum NOISETYPE nid) {
int volume = 1; int volume = 1;
char hear[BUFLEN], see[BUFLEN]; char hear[BUFLEN], see[BUFLEN];
if (!getnoisedetails(lf, nid, hear, see, &volume)) { if (!getnoisedetails(lf, nid, NULL, hear, see, &volume)) {
// success // success
noise(lf->cell, lf, noisetypetoclass(nid), volume, strlen(hear) ? hear : NULL, strlen(see) ? see : NULL); noise(lf->cell, lf, noisetypetoclass(nid), volume, strlen(hear) ? hear : NULL, strlen(see) ? see : NULL);
} }
@ -15684,6 +15774,27 @@ int poisonthreatenslife(lifeform_t *lf, flag_t *f) {
return B_FALSE; return B_FALSE;
} }
int polymorphto(lifeform_t *lf, enum RACE rid, int howlong) {
// alreay that race? just update polymorph timer.
if (lf->race->id == rid) {
flag_t *f;
f = hasflag(lf->flags, F_POLYMORPHED);
if (f) {
f->lifetime = howlong;
}
return B_TRUE;
}
if (!hasflag(lf->flags, F_ORIGRACE)) {
// remember the original race
addflag(lf->flags, F_ORIGRACE, lf->race->id, NA, NA, NULL);
}
killflagsofid(lf->flags, F_POLYMORPHED);
addtempflag(lf->flags, F_POLYMORPHED, B_TRUE, NA, NA, NULL, howlong);
setrace(lf, rid, B_TRUE);
return B_FALSE;
}
// maybe practice a skill // maybe practice a skill
void practice(lifeform_t *lf, enum SKILL skid, int amt) { void practice(lifeform_t *lf, enum SKILL skid, int amt) {
flag_t *f; flag_t *f;
@ -16671,6 +16782,14 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
} }
say(lf, buf, volume); say(lf, buf, volume);
break; break;
case SP_LIFEOB_DESTROYED:
switch (rnd(1,3)) {
case 1: snprintf(buf, BUFLEN, "NOOOOOOOOO!"); break;
case 2: snprintf(buf, BUFLEN, "NO! What have you done!?"); break;
case 3: snprintf(buf, BUFLEN, "It cannot be!"); break;
}
rv = say(lf, buf, volume);
break;
case SP_MERCYACCEPT: case SP_MERCYACCEPT:
switch (rnd(1,2)) { switch (rnd(1,2)) {
case 1: case 1:
@ -17154,6 +17273,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
} }
loseconcentration(lf); loseconcentration(lf);
loseaitargets(lf);
// were we already polymorphed? // were we already polymorphed?
f = lfhasflag(lf, F_ORIGRACE); f = lfhasflag(lf, F_ORIGRACE);
@ -17332,15 +17452,99 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
// TODO: new race can use magic (F_NOSPELLS) // TODO: new race can use magic (F_NOSPELLS)
// new race can still hold all the items which you have // new race can still hold all the items which you have
if ((gamemode == GM_GAMESTARTED)) { if ((gamemode == GM_GAMESTARTED)) {
enum BODYPART bp;
object_t *o,*nexto; object_t *o,*nexto;
int donemeldmsg = B_FALSE;
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
// no pack? // no pack?
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next;
f = isequipped(o);
if (f) {
int stillok = B_TRUE;
if (!hasbp(lf, f->val[0])) {
stillok = B_FALSE;
} else if (isarmour(o) && !armourfits(lf, o, NULL)) {
stillok = B_FALSE;
}
if (!stillok) {
if (reverting) {
char obname[BUFLEN];
getobname(o, obname, o->amt);
// drop it!
if (isplayer(lf)) {
msg("Your %s drops to the ground!",noprefix(obname));
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s %s drop to the ground!",buf, getpossessive(buf),
noprefix(obname));
}
moveob(o, lf->cell->obpile, o->amt);
} else {
char obname[BUFLEN];
getobname(o, obname, o->amt);
if (!donemeldmsg) {
if (isplayer(lf)) {
msg("Your equipment melds into your new form!");
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s equipment melds into its new form!",buf, getpossessive(buf));
}
donemeldmsg = B_TRUE;
}
// drop it!
moveob(o, lf->polypack, o->amt);
}
}
}
}
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next;
if (!canpickup(lf, o, o->amt) && !isequipped(o)) {
if (reverting) {
char obname[BUFLEN];
getobname(o, obname, o->amt);
// drop it!
if (isplayer(lf)) {
msg("Your %s drops to the ground!",noprefix(obname));
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s %s drop to the ground!",buf, getpossessive(buf),
noprefix(obname));
}
moveob(o, lf->cell->obpile, o->amt);
} else {
char obname[BUFLEN];
getobname(o, obname, o->amt);
if (!donemeldmsg) {
if (isplayer(lf)) {
msg("Your equipment melds into your new form!");
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s equipment melds into its new form!",buf, getpossessive(buf));
}
donemeldmsg = B_TRUE;
}
moveob(o, lf->polypack, o->amt);
}
}
}
// drop/meld everything which isn't equipped.
// equipped objects are okay because if our new form lacked the required
// body part, they would have already been melded above.
if (lfhasflag(lf, F_NOPACK)) { if (lfhasflag(lf, F_NOPACK)) {
if (reverting) { if (reverting) {
// drop everything // drop everything which isn't equipped
if (countobs(lf->pack, B_FALSE)) { if (countobs(lf->pack, B_FALSE) - countobswithflag(lf->pack, F_EQUIPPED)) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("Your possessions drop to the ground!"); msg("Your possessions drop to the ground!");
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
@ -17350,89 +17554,22 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
} }
for (o = lf->pack->first ; o ; o = nexto) { for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
if (!isequipped(o)) moveob(o, lf->cell->obpile, o->amt);
moveob(o, lf->cell->obpile, o->amt);
} }
} else { } else {
// meld // meld
if (countobs(lf->pack, B_FALSE)) { if (countobs(lf->pack, B_FALSE) - countobswithflag(lf->pack, F_EQUIPPED)) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("Your possessions meld into your new form!"); msg("Your possessions meld into your new form!");
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
getlfname(lf, buf); getlfname(lf, buf);
msg("%s%s possessions meld into its new form!",buf, getpossessive(buf)); msg("%s%s possessions meld into its new form!",buf, getpossessive(buf));
} }
donemeldmsg = B_TRUE;
} }
for (o = lf->pack->first ; o ; o = nexto) { for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
if (!isequipped(o)) moveob(o, lf->polypack, o->amt);
moveob(o, lf->polypack, o->amt);
}
}
}
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
for (bp = BP_WEAPON; bp < MAXBODYPARTS; bp++) {
if (!hasbp(lf, bp)) {
o = getequippedob(lf->pack, bp);
if (o) {
if (reverting) {
char obname[BUFLEN];
getobname(o, obname, o->amt);
// drop it!
if (isplayer(lf)) {
msg("Your %s drops to the ground!",noprefix(obname));
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s %s drop to the ground!",buf, getpossessive(buf),
noprefix(obname));
}
moveob(o, lf->cell->obpile, o->amt);
} else {
char obname[BUFLEN];
getobname(o, obname, o->amt);
// drop it!
if (isplayer(lf)) {
msg("Your %s melds into your new form!",noprefix(obname));
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s %s melds into its new form!",buf, getpossessive(buf),
noprefix(obname));
}
moveob(o, lf->polypack, o->amt);
}
}
}
}
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next;
if (!canpickup(lf, o, o->amt)) {
if (reverting) {
char obname[BUFLEN];
getobname(o, obname, o->amt);
// drop it!
if (isplayer(lf)) {
msg("Your %s drops to the ground!",noprefix(obname));
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s %s drop to the ground!",buf, getpossessive(buf),
noprefix(obname));
}
moveob(o, lf->cell->obpile, o->amt);
} else {
char obname[BUFLEN];
getobname(o, obname, o->amt);
if (isplayer(lf)) {
msg("Your %s melds into your new form!",noprefix(obname));
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s %s melds into its new form!",buf, getpossessive(buf),
noprefix(obname));
}
moveob(o, lf->polypack, o->amt);
} }
} }
} }
@ -18042,7 +18179,7 @@ void startlfturn(lifeform_t *lf) {
int db = B_FALSE; int db = B_FALSE;
map_t *map; map_t *map;
enum ERROR error; enum ERROR error;
object_t *o; object_t *o,*nexto;
flag_t *f; flag_t *f;
flag_t *asp, *sf; flag_t *asp, *sf;
char buf[BUFLEN]; char buf[BUFLEN];
@ -18052,6 +18189,7 @@ void startlfturn(lifeform_t *lf) {
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags; int nretflags;
int movedlastturn = B_FALSE; int movedlastturn = B_FALSE;
object_t *bloodamu = NULL;
map = lf->cell->map; map = lf->cell->map;
@ -18157,7 +18295,14 @@ void startlfturn(lifeform_t *lf) {
if (checkfordrowning(lf, o)) { if (checkfordrowning(lf, o)) {
if (isdead(lf)) return; if (isdead(lf)) return;
} }
} else {
// amulet of swimming?
if (hasequippedobid(lf->pack, OT_AMU_SWIMMING) && (lf->race->id == R_SWAN) && ispolymorphed(lf)) {
// revert to normal form
abilityeffects(lf, OT_A_POLYREVERT, lf->cell, lf, NULL);
} }
}
// suffocate? // suffocate?
if (lfhasflag(lf, F_NEEDSWATER) && !hasobwithflag(lf->cell->obpile, F_DEEPWATER)) { if (lfhasflag(lf, F_NEEDSWATER) && !hasobwithflag(lf->cell->obpile, F_DEEPWATER)) {
int dam; int dam;
@ -18220,6 +18365,7 @@ void startlfturn(lifeform_t *lf) {
} }
} }
// oooooo replace with f_bleeding ? // oooooo replace with f_bleeding ?
if (lfhasflagval(lf, F_INJURY, IJ_ARTERYPIERCE, NA, NA, NULL)) { if (lfhasflagval(lf, F_INJURY, IJ_ARTERYPIERCE, NA, NA, NULL)) {
if (!bleedfrom(lf, BP_HANDS, B_SPLATTER)) { if (!bleedfrom(lf, BP_HANDS, B_SPLATTER)) {
@ -18321,6 +18467,58 @@ void startlfturn(lifeform_t *lf) {
} }
} }
if (pctchance(25) && lfhasflag(lf, F_PARANOIA) && !lfhasflag(lf, F_AWARENESS)) {
if (isplayer(lf)) {
cell_t *c;
c = getcellindir(lf->cell, diropposite(lf->facing));
if (c && cellwalkable(NULL, c, NULL)) {
int monisreal = B_FALSE;
race_t *r;
lifeform_t *mon;
if (pctchance(15)) monisreal = B_TRUE;
// either make a random noise from right behind the player,
// or ACTUALL create a monster behind them!
// get random mosnter who makes walk noise
f = NULL;
while (!f) {
r = getreallyrandomrace(RC_ANY);
f = hasflagval(r->flags, F_NOISETEXT, N_WALK, NA, NA, NULL);
// don't want mosnters which will create objects, since we are going
// to palce a temporary one!
if (hasflag(r->flags, F_AUTOCREATEOB)) f = NULL;
}
// create the monster directly behind you
if (monisreal) {
// set autogen to false, we don't want minions appearing too.
mon = addmonster(c, r->id, NULL, B_FALSE, 1, B_FALSE, NULL);
} else {
mon = addlf(c, r->id, 1);
}
if (mon) {
if (monisreal) {
killflagsofid(mon->flags, F_XPVAL);
addflag(mon->flags, F_XPVAL, 0, NA, NA, NULL);
turntoface(mon, lf->cell);
}
// it makes noise
makenoise(mon, N_WALK);
if (!monisreal) {
// now kill the monster
killlf(mon);
}
}
}
} else {
// monster just turns around to look behind.
loseaitargets(lf);
setfacing(lf, diropposite(lf->facing));
}
}
// sixth sense spell warnings // sixth sense spell warnings
f = lfhasflag(lf, F_SIXTHSENSE); f = lfhasflag(lf, F_SIXTHSENSE);
if (f) { if (f) {
@ -18521,7 +18719,7 @@ void startlfturn(lifeform_t *lf) {
object_t *corpse; object_t *corpse;
char corpsename[BUFLEN]; char corpsename[BUFLEN];
corpseloc = findnearbylifeob(lf->cell, f, &corpse); corpseloc = findnearbylifeob(lf->cell, NA, f, &corpse);
if (corpse) { if (corpse) {
// did we find a corpse in range ? // did we find a corpse in range ?
if (corpse->type->id == OT_CORPSE) { if (corpse->type->id == OT_CORPSE) {
@ -18531,22 +18729,24 @@ void startlfturn(lifeform_t *lf) {
} }
if (lf->race->id == R_GHOST) { if (lf->race->id == R_GHOST) {
// give possession ability // give possession ability
if (!lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL)) { if (isplayer(lf) && !lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL)) {
flag_t *f2;
char pwbuf[BUFLEN]; char pwbuf[BUFLEN];
int power; int power;
power = lf->level / 3; power = lf->level / 3;
if (power < 1) power = 1; if (power < 1) power = 1;
if (power > 10) power = 10; if (power > 10) power = 10;
snprintf(pwbuf, BUFLEN, "pw:%d;",power); snprintf(pwbuf, BUFLEN, "pw:%d;",power);
f = addflag(lf->flags, F_CANWILL, OT_S_POSSESSION, NA, NA, pwbuf); f2 = addflag(lf->flags, F_CANWILL, OT_S_POSSESSION, NA, NA, pwbuf);
f->lifetime = FROMRACE; f2->lifetime = FROMRACE;
} }
} }
} else { } else {
// can't see corpse // can't see corpse
if (lf->race->id == R_GHOST) { if (lf->race->id == R_GHOST) {
f = lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL); flag_t *f2;
if (f) killflag(f); f2 = lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL);
if (f2) killflag(f2);
} }
// drain life // drain life
if (isplayer(lf)) { if (isplayer(lf)) {
@ -18901,8 +19101,31 @@ void startlfturn(lifeform_t *lf) {
} }
if (isdead(lf)) return; if (isdead(lf)) return;
bloodamu = hasequippedobid(lf->pack, OT_AMU_BLOOD);
// effects from cell objects? // effects from cell objects?
for (o = lf->cell->obpile->first ; o ; o = o->next) { for (o = lf->cell->obpile->first ; o ; o = nexto) {
nexto = o->next;
if (bloodamu && (o->material->id == MT_BLOOD)) {
int amt;
amt = getobhp(o, NULL) * o->amt;
limit(&amt, 1, 10);
if (!isknown(bloodamu)) {
if (isplayer(lf) || cansee(player, lf)) {
char obname[BUFLEN],bname[BUFLEN];
char lfname[BUFLEN];
getlfname(lf, lfname);
getobname(bloodamu, obname, 1);
getobname(o, bname, 1);
msg("^%c%s%s %s sucks up %s!", getlfcol(lf, CC_GOOD), lfname, getpossessive(lfname), noprefix(obname), bname);
makeknown(bloodamu->type->id);
}
}
gainhp(lf, amt);
killob(o);
continue;
}
f = hasflag(o->flags, F_WALKDAM); f = hasflag(o->flags, F_WALKDAM);
if (f) { if (f) {
applywalkdam(lf, roll(f->text), f->val[0], o); applywalkdam(lf, roll(f->text), f->val[0], o);
@ -19570,6 +19793,11 @@ int takeoff(lifeform_t *lf, object_t *o) {
unequipeffects(lf, o); unequipeffects(lf, o);
// if you don't have a pack, it goes to the ground.
if (lfhasflag(lf, F_NOPACK)) {
moveob(o, lf->cell->obpile, o->amt);
}
return B_FALSE; return B_FALSE;
} }
@ -19737,7 +19965,18 @@ void timeeffectslf(lifeform_t *lf) {
int willfall = B_FALSE; int willfall = B_FALSE;
donesomething = B_FALSE; donesomething = B_FALSE;
if ((dir == D_DOWN) && !isairborne(lf)) { if ((dir == D_DOWN) && !isairborne(lf)) {
object_t *amu;
willfall = B_TRUE; willfall = B_TRUE;
amu = hasequippedobid(lf->pack, OT_AMU_EVOLUTION);
if (amu) {
if (!polymorphto(lf, R_AVIAD, 5)) {
makeknown(amu->type->id);
dospelleffects(lf, OT_S_FLIGHT, 1, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
willfall = B_FALSE;
}
}
} else if ((dir == D_UP) && lfhasflag(lf, F_LEVITATING)) { } else if ((dir == D_UP) && lfhasflag(lf, F_LEVITATING)) {
willfall = B_TRUE; willfall = B_TRUE;
} }
@ -20117,6 +20356,11 @@ void unequipeffects(lifeform_t *lf, object_t *o) {
if (f) { if (f) {
stopspell(lf, f->val[0]); stopspell(lf, f->val[0]);
} }
if ((o->type->id == OT_AMU_SWIMMING) && (lf->race->id == R_SWAN) && ispolymorphed(lf)) {
// revert to normal form
abilityeffects(lf, OT_A_POLYREVERT, lf->cell, lf, NULL);
}
} }
void unsummon(lifeform_t *lf, int vanishobs) { void unsummon(lifeform_t *lf, int vanishobs) {
@ -20218,6 +20462,11 @@ int unweild(lifeform_t *lf, object_t *o) {
unequipeffects(lf, o); unequipeffects(lf, o);
// if you don't have a pack, it goes to the ground.
if (lfhasflag(lf, F_NOPACK)) {
moveob(o, lf->cell->obpile, o->amt);
}
return B_FALSE; return B_FALSE;
} }
@ -21901,6 +22150,9 @@ int willbleedfrom(lifeform_t *lf, enum BODYPART bp) {
// don't bleed. // don't bleed.
return B_FALSE; return B_FALSE;
} }
if (hasequippedobid(lf->pack, OT_AMU_BLOOD)) return B_FALSE;
return B_TRUE; return B_TRUE;
} }

5
lf.h
View File

@ -108,7 +108,7 @@ job_t *findjob(enum JOB jobid);
job_t *findjobbyname(char *name); job_t *findjobbyname(char *name);
lifeform_t *findlf(map_t *m, int lfid); lifeform_t *findlf(map_t *m, int lfid);
lifeform_t *findlfunique(enum RACE rid); lifeform_t *findlfunique(enum RACE rid);
cell_t *findnearbylifeob(cell_t *src, flag_t *lifeobflag, object_t **retlifeob); cell_t *findnearbylifeob(cell_t *src, int maxdist, flag_t *lifeobflag, object_t **retlifeob);
poisontype_t *findpoisontype(enum POISONTYPE id); poisontype_t *findpoisontype(enum POISONTYPE id);
race_t *findrace(enum RACE id); race_t *findrace(enum RACE id);
race_t *findracebyname(char *name); race_t *findracebyname(char *name);
@ -188,7 +188,7 @@ int getmiscastchance(lifeform_t *lf);
int getmorale(lifeform_t *lf); int getmorale(lifeform_t *lf);
int getnextshortcut(lifeform_t *lf); int getnextshortcut(lifeform_t *lf);
int getnightvisrange(lifeform_t *lf); int getnightvisrange(lifeform_t *lf);
int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, char *heartext,char *seetext, int *volume); int getnoisedetails(lifeform_t *lf, enum NOISETYPE nid, flag_t *noiseflag, char *heartext,char *seetext, int *volume);
char *getlfconditionname(enum LFCONDITION cond); char *getlfconditionname(enum LFCONDITION cond);
object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp); object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp);
//int getowing(lifeform_t *buyer, int shopid, int *retnitems); //int getowing(lifeform_t *buyer, int shopid, int *retnitems);
@ -392,6 +392,7 @@ int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground, int anta
void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat, enum RACE srcraceid); void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char *fromwhat, enum RACE srcraceid);
int poisoncausesvomit(enum POISONTYPE ptype); int poisoncausesvomit(enum POISONTYPE ptype);
int poisonthreatenslife(lifeform_t *lf, flag_t *f); int poisonthreatenslife(lifeform_t *lf, flag_t *f);
int polymorphto(lifeform_t *lf, enum RACE rid, int howlong);
void practice(lifeform_t *lf, enum SKILL skid, int amt); void practice(lifeform_t *lf, enum SKILL skid, int amt);
//void precalclos_old(lifeform_t *lf); //void precalclos_old(lifeform_t *lf);
void precalclos(lifeform_t *lf); void precalclos(lifeform_t *lf);

46
map.c
View File

@ -124,9 +124,9 @@ void addhomeobs(lifeform_t *lf, int dolevelobs) {
cell_t *homeobloc; cell_t *homeobloc;
homeobloc = lf->cell; homeobloc = lf->cell;
for (f = lf->flags->first ; f ; f = f->next) { for (f = lf->flags->first ; f ; f = f->next) {
object_t *o = NULL;
if ((f->id == F_HOMEOB) && pctchance(f->val[0])) { if ((f->id == F_HOMEOB) && pctchance(f->val[0])) {
cell_t *c; cell_t *c;
object_t *o;
o = addob(homeobloc->obpile, f->text); o = addob(homeobloc->obpile, f->text);
if (o && (homeobloc == lf->cell) && isimpassableob(o, lf, SZ_ANY)) { if (o && (homeobloc == lf->cell) && isimpassableob(o, lf, SZ_ANY)) {
c = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL); c = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL);
@ -145,9 +145,17 @@ void addhomeobs(lifeform_t *lf, int dolevelobs) {
while (!cellwalkable(NULL, c, NULL)) { while (!cellwalkable(NULL, c, NULL)) {
c = getrandomcell(lf->cell->map); c = getrandomcell(lf->cell->map);
} }
addob(c->obpile, f->text); o = addob(c->obpile, f->text);
} }
} }
if (o) {
if (lfhasflagval(lf, F_LIFEOB, o->type->id, NA, NA, NULL)) {
addflag(o->flags, F_LIFEOBFOR, lf->id, NA, NA, NULL);
killflagsofid(o->flags, F_OBHPDRAIN);
}
addflag(o->flags, F_HOMEOBFOR, lf->id, NA, NA, NULL);
}
} }
} }
@ -197,7 +205,8 @@ map_t *addmap(void) {
// when monsters are made during level generation, autogen will be true. otherwise false; // when monsters are made during level generation, autogen will be true. otherwise false;
// if "rid" RR_SPECIFIED, parse racename to get the race. // if "rid" R_SPECIFIED, parse racename to get the race.
// rid can also be R_RANDOM.
// otherwise just use the given race. // otherwise just use the given race.
lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok, int amt, int autogen, int *nadded) { lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok, int amt, int autogen, int *nadded) {
lifeform_t *lf = NULL; lifeform_t *lf = NULL;
@ -385,6 +394,10 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
if (hasequippedobid(player->pack, OT_AMU_VICTIM)) { if (hasequippedobid(player->pack, OT_AMU_VICTIM)) {
// everything is hostile. // everything is hostile.
if (!lfhasflag(lf, F_HOSTILE)) addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); if (!lfhasflag(lf, F_HOSTILE)) addflag(lf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
} else {
// adjust hostility based on player's race
if ((player->race->id == R_AVIAD) && hasflag(lf->flags, F_AVIAN)) {
killflagsofid(lf->flags, F_HOSTILE);
} else { } else {
// adjust hostility based on player's alignment // adjust hostility based on player's alignment
switch (getalignment(player)) { switch (getalignment(player)) {
@ -406,6 +419,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
break; break;
} }
} }
} // end if hasequipped amu_victimisation
} }
lf->born = B_TRUE; lf->born = B_TRUE;
@ -476,12 +490,14 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
for (n = 0; n < nminions; n++) { for (n = 0; n < nminions; n++) {
lifeform_t *newlf; lifeform_t *newlf;
enum RACE newrid;
race_t *newr; race_t *newr;
adjcell = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL); adjcell = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL);
if (!adjcell) break; if (!adjcell) break;
newr = findracebyname(f->text); newrid = parserace(f->text, NULL, NULL, NULL);
newr = findrace(newrid);
if (!newr) break; if (!newr) break;
newlf = addlf(adjcell, newr->id, getrandommonlevel(newr, adjcell->map)); newlf = addlf(adjcell, newr->id, getrandommonlevel(newr, adjcell->map));
@ -942,6 +958,9 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
getroomedge(map, roomid, minx, miny, maxx, maxy, d, cell, &ncells, B_TRUE); getroomedge(map, roomid, minx, miny, maxx, maxy, d, cell, &ncells, B_TRUE);
for (i = 0; i < ncells; i++) { for (i = 0; i < ncells; i++) {
cell_t *newcell; cell_t *newcell;
if (cellisfixedvaultwall(cell[i])) continue;
// is there empty space on the other side of this wall segment? // is there empty space on the other side of this wall segment?
newcell = getcellindir(cell[i], d); newcell = getcellindir(cell[i], d);
if (newcell && !newcell->type->solid) { if (newcell && !newcell->type->solid) {
@ -7394,6 +7413,25 @@ enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob, enum S
// now get raceid // now get raceid
if (streq(p, "random")) { if (streq(p, "random")) {
return R_RANDOM; return R_RANDOM;
} else if (strstarts(p, "random ")) {
race_t *baser,*r;
// ie. "random xxx_baseraceid_xxx"
p += strlen("random ");
baser = findracebyname(p);
if (baser) {
enum RACE poss[MAXCANDIDATES];
int nposs = 0;
// find all races with this baseid
for (r = firstrace ; r ; r = r->next) {
if (r->baseid == baser->id) {
poss[nposs++] = r->id;
if (nposs == MAXCANDIDATES) break;
}
}
if (nposs) {
return poss[rnd(0,nposs-1)];
}
}
} else { } else {
race_t *r; race_t *r;
r = findracebyname(p); r = findracebyname(p);

4
move.c
View File

@ -225,7 +225,7 @@ int celldangerous(lifeform_t *lf, cell_t *cell, int onlyifknown, enum ERROR *err
f = hasflag(o->flags, F_DEEPWATER); f = hasflag(o->flags, F_DEEPWATER);
if (f) { if (f) {
// non swimming creature in water? // non swimming creature in water?
if (!isairborne(lf)) { if (!isairborne(lf) && !lfhasflag(lf, F_AQUATIC)) {
if ((getobdepth(o, lf) >= DP_HEAD)) { if ((getobdepth(o, lf) >= DP_HEAD)) {
if (getskill(lf, SK_SWIMMING) - isburdened(lf) <= 0) { if (getskill(lf, SK_SWIMMING) - isburdened(lf) <= 0) {
if (error) { if (error) {
@ -3396,7 +3396,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
if (!cell->lf) { if (!cell->lf) {
f = lfhasflag(lf, F_LIFEOB); f = lfhasflag(lf, F_LIFEOB);
if (f) { if (f) {
if (!findnearbylifeob(cell, f, NULL)) { if (!findnearbylifeob(cell, NA, f, NULL)) {
if (error) *error = E_WONT; if (error) *error = E_WONT;
return B_FALSE; return B_FALSE;
} }

129
objects.c
View File

@ -479,12 +479,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
int wantblessed = B_UNCURSED; int wantblessed = B_UNCURSED;
race_t *corpserace = NULL; race_t *corpserace = NULL;
int dorandombrand = B_FALSE; int dorandombrand = B_FALSE;
char wantnamed[BUFLEN];
brand_t *wantbrand = NULL; brand_t *wantbrand = NULL;
brand_t *br; brand_t *br;
obmod_t *om; obmod_t *om;
obmod_t *wantom[MAXOBMODS]; obmod_t *wantom[MAXOBMODS];
int wanthot = B_FALSE;
int wanthppct = 100; int wanthppct = 100;
regionthing_t *wantregionthing = NULL; regionthing_t *wantregionthing = NULL;
int bonus = 0; int bonus = 0;
@ -505,10 +503,10 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
int donesomething; int donesomething;
object_t *addedob[MAXPILEOBS]; object_t *addedob[MAXPILEOBS];
int nadded = 0; int nadded = 0;
flagpile_t *wantflags;
// for doors // for doors
enum FLAG doorflag[5]; enum FLAG doorflag[5];
int ndoorflags = 0; int ndoorflags = 0;
char *signtext = NULL;
int trapchance = 0; int trapchance = 0;
int lockchance = 0; int lockchance = 0;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
@ -519,8 +517,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
nadded = 0; nadded = 0;
nretobs = 0; nretobs = 0;
strcpy(wantnamed, "");
if ((gamemode == GM_GAMESTARTED) && where->where) { if ((gamemode == GM_GAMESTARTED) && where->where) {
assert(!where->where->type->solid); assert(!where->where->type->solid);
} }
@ -531,6 +527,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
return NULL; return NULL;
} }
wantflags = addflagpile(NULL, NULL);
if (forceoid != OT_NONE) { if (forceoid != OT_NONE) {
ot = findot(forceoid); ot = findot(forceoid);
howmany = 1; howmany = 1;
@ -561,6 +559,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
// check if we want a name. if so, remember it and strip off the suffix. // check if we want a name. if so, remember it and strip off the suffix.
p2 = strstr(localname, " named "); p2 = strstr(localname, " named ");
if (p2) { if (p2) {
char wantnamed[BUFLEN];
char *wantp; char *wantp;
char *copyfrom; char *copyfrom;
copyfrom = p2 + strlen(" named "); copyfrom = p2 + strlen(" named ");
@ -573,6 +572,8 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
*wantp = '\0'; *wantp = '\0';
// now strip the suffix // now strip the suffix
*p2 = '\0'; *p2 = '\0';
addflag(wantflags, F_NAMED, NA, NA, NA, wantnamed);
} }
// check for premods. eg. "flaming xxx" "frozen xxx" etc // check for premods. eg. "flaming xxx" "frozen xxx" etc
@ -707,9 +708,14 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
wantblessed = B_CURSED; wantblessed = B_CURSED;
p += strlen("cursed "); p += strlen("cursed ");
donesomething = B_TRUE; donesomething = B_TRUE;
// food flags
} else if (strstarts(p, "cooked ")) {
addflag(wantflags, F_PREPARED, B_TRUE, NA, NA, NULL);
p += strlen("cooked ");
donesomething = B_TRUE;
// flags // flags
} else if (strstarts(p, "red-hot ")) { } else if (strstarts(p, "red-hot ")) {
wanthot = B_TRUE; addflag(wantflags, F_HOT, 3, NA, NA, "1d4");
p += strlen("red-hot "); p += strlen("red-hot ");
donesomething = B_TRUE; donesomething = B_TRUE;
// condition flags // condition flags
@ -947,6 +953,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
targetcell = NULL; targetcell = NULL;
} }
} else { } else {
killflagpile(wantflags);
return NULL; return NULL;
} }
@ -966,7 +973,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
pp++; pp++;
} }
*sbp = '\0'; *sbp = '\0';
signtext = strdup(sbuf); addflag(wantflags, F_SIGNTEXT, NA, NA, NA, sbuf);
} }
ot = findot(OT_SIGN); ot = findot(OT_SIGN);
} else if (strstr(p, "spellbook of ")) { } else if (strstr(p, "spellbook of ")) {
@ -1052,6 +1059,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
//if (gamestarted) msg("DB: No match for object name '%s'", p ); //if (gamestarted) msg("DB: No match for object name '%s'", p );
if (db) dblog("DB: No match for object name '%s'", p ); if (db) dblog("DB: No match for object name '%s'", p );
nretobs = 0; nretobs = 0;
killflagpile(wantflags);
return NULL; return NULL;
} }
} }
@ -1095,6 +1103,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
if (hasob(where, ot->id)) { if (hasob(where, ot->id)) {
if (db) dblog("DB: trying to add >1 ONEPERCELL object to a cell. (%s) bailing out.", ot->name); if (db) dblog("DB: trying to add >1 ONEPERCELL object to a cell. (%s) bailing out.", ot->name);
nretobs = 0; nretobs = 0;
killflagpile(wantflags);
return NULL; return NULL;
} }
} }
@ -1113,6 +1122,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
if (where->owner || where->where) { if (where->owner || where->where) {
if (db) dblog("DB: Cannot give a spell object to a player, or a cell! object name '%s'", ot->name ); if (db) dblog("DB: Cannot give a spell object to a player, or a cell! object name '%s'", ot->name );
nretobs = 0; nretobs = 0;
killflagpile(wantflags);
return NULL; return NULL;
} }
} }
@ -1128,6 +1138,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
if (hasflag(ot->flags, F_NOPICKUP) && where->owner) { if (hasflag(ot->flags, F_NOPICKUP) && where->owner) {
if (db) dblog("DB: trying to give NOPICKUP object '%s' to a lifeform ('%s').", ot->name, where->owner->race->name ); if (db) dblog("DB: trying to give NOPICKUP object '%s' to a lifeform ('%s').", ot->name, where->owner->race->name );
nretobs = 0; nretobs = 0;
killflagpile(wantflags);
return NULL; return NULL;
} }
@ -1152,6 +1163,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
if (obexists(ot->id)) { if (obexists(ot->id)) {
if (db) dblog("DB: Unique ob %s already exists!", p ); if (db) dblog("DB: Unique ob %s already exists!", p );
nretobs = 0; nretobs = 0;
killflagpile(wantflags);
return NULL; return NULL;
} }
@ -1310,7 +1322,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
} }
/* /*
need to do the below for _all_ objects added (searchfor"each object added")! need to do the below for _all_ objects added (search "foreach object added")!
*/ */
for (i = 0; i < nadded; i++) { for (i = 0; i < nadded; i++) {
cell_t *obloc; cell_t *obloc;
@ -1342,10 +1354,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
changemat(o, wantdiffmat); changemat(o, wantdiffmat);
} }
if (strlen(wantnamed)) {
addflag(o->flags, F_NAMED, NA, NA, NA, wantnamed);
}
if (wanthppct != 100) { if (wanthppct != 100) {
f = hasflag(o->flags, F_OBHP); f = hasflag(o->flags, F_OBHP);
if (f) { if (f) {
@ -1361,11 +1369,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
} }
} }
// fill in sign text
if (signtext) {
addflag(o->flags, F_SIGNTEXT, NA, NA, NA, signtext);
}
// fill in portal destinations // fill in portal destinations
if (targetmap) { if (targetmap) {
int tx = NA,ty = NA; int tx = NA,ty = NA;
@ -1455,7 +1458,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
} }
} }
// food flags // food flags
if ((ot->obclass->id == OC_FOOD) && wantfoodtaint) { if ((ot->obclass->id == OC_FOOD) && wantfoodtaint) {
addflag(o->flags, F_TAINTED, B_TRUE, NA, NA, NULL); addflag(o->flags, F_TAINTED, B_TRUE, NA, NA, NULL);
@ -1464,10 +1466,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
if (o && hasflag(o->flags, F_LIGHTSOURCE) && wantlit) { if (o && hasflag(o->flags, F_LIGHTSOURCE) && wantlit) {
turnon(NULL, o); turnon(NULL, o);
} }
// hot?
if (o && wanthot) {
addflag(o->flags, F_HOT, 3, NA, NA, "1d4");
}
// firearms usually come loaded // firearms usually come loaded
if (o && isfirearm(o)) { if (o && isfirearm(o)) {
@ -2009,6 +2007,11 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
} }
} }
} }
// wantflags
if (o) {
copyflags(o->flags, wantflags, NA);
}
} // end if !loading } // end if !loading
if ((gamemode == GM_GAMESTARTED) && !inaskcoords) { if ((gamemode == GM_GAMESTARTED) && !inaskcoords) {
@ -2031,6 +2034,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
nretobs = nadded; nretobs = nadded;
// return the first object given // return the first object given
killflagpile(wantflags);
return addedob[0]; return addedob[0];
} }
@ -8255,6 +8259,9 @@ object_t *obexists(enum OBTYPE obid) {
void obdie(object_t *o) { void obdie(object_t *o) {
char obname[BUFLEN]; char obname[BUFLEN];
flag_t *f; flag_t *f;
cell_t *loc;
loc = getoblocation(o);
o->dying = B_TRUE; o->dying = B_TRUE;
@ -8319,10 +8326,10 @@ void obdie(object_t *o) {
if (f) { if (f) {
if (f->val[2] == B_IFACTIVATED) { if (f->val[2] == B_IFACTIVATED) {
if (isactivated(o)) { if (isactivated(o)) {
brightflash(getoblocation(o),f->val[0], NULL); brightflash(loc,f->val[0], NULL);
} }
} else { } else {
brightflash(getoblocation(o),f->val[0], NULL); brightflash(loc,f->val[0], NULL);
} }
} }
@ -8341,6 +8348,20 @@ void obdie(object_t *o) {
} }
} }
if (loc) {
flag_t *retflag[MAXCANDIDATES];
int nretflags = 0,i;
getflags(o->flags, retflag, &nretflags, F_LIFEOBFOR, F_NONE);
for (i = 0; i < nretflags; i++) {
lifeform_t *l;
l = findlf(loc->map, retflag[i]->val[0]);
if (l) {
sayphrase(l, SP_LIFEOB_DESTROYED, SV_CAR, NA, NULL);
}
}
}
killob(o); killob(o);
} }
@ -10152,6 +10173,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
int amt; int amt;
int failed; int failed;
int seenbyplayer; int seenbyplayer;
object_t *o2;
flag_t *f; flag_t *f;
if (isplayer(lf)) { if (isplayer(lf)) {
@ -10168,6 +10190,13 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
getlfname(lf, lfname); getlfname(lf, lfname);
// override?
if ((oid == OT_POT_BLOODC) && !lfhasflag(lf, F_BEINGSTONED)) {
if ((lf->race->id == R_VAMPIRE) || hasequippedobid(lf->pack, OT_AMU_BLOOD)) {
oid = OT_POT_BLOOD;
}
}
switch (oid) { switch (oid) {
case OT_POT_ACID: case OT_POT_ACID:
if (isplayer(lf)) { if (isplayer(lf)) {
@ -10511,9 +10540,18 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
} }
break; break;
case OT_POT_BLOOD: case OT_POT_BLOOD:
if (lf->race->id == R_VAMPIRE) { o2 = hasequippedobid(lf->pack, OT_AMU_BLOOD);
if ((lf->race->id == R_VAMPIRE) || o2) {
int b = B_UNCURSED; int b = B_UNCURSED;
if (isplayer(lf)) msg("This blood is delicious!"); if (isplayer(lf)) {
if (o2 && !isknown(o2)) {
char o2name[BUFLEN];
getobname(o2, o2name, o2->amt);
msg("^gYour %s pulses as your drink!^n", noprefix(o2name));
makeknown(o2->type->id);
}
msg("This blood is delicious!");
}
if (potblessed == B_BLESSED) { if (potblessed == B_BLESSED) {
b = B_CURSED; b = B_CURSED;
} else if (potblessed == B_CURSED) { } else if (potblessed == B_CURSED) {
@ -11029,10 +11067,39 @@ int readsomething(lifeform_t *lf, object_t *o) {
} }
if (isplayer(lf)) { if (isplayer(lf)) {
if (ndone) {
msg("You are surrounded by a stabilising aura."); msg("You are surrounded by a stabilising aura.");
} else { }
nothinghappens(); if (!ndone) {
object_t *oo,*poss[MAXPILEOBS];
int nposs = 0;
// make a piece of armour invulnerable
for (oo = lf->pack->first ; oo ; oo = oo->next) {
if (isequipped(oo) && !hasflag(o->flags, F_INVULNERABLE)) {
poss[nposs++] = oo;
}
}
if (nposs) {
oo = poss[rnd(0,nposs-1)];
addflag(oo->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
if (isplayer(lf)) {
char ooname[BUFLEN];
getobname(oo, ooname, oo->amt);
msg("Your %s become%s ultra-dense!", obname, (oo->amt == 1) ? "s" : "");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
char ooname[BUFLEN];
getlfname(lf, lfname);
getobname(oo, ooname, oo->amt);
msg("%s%s %s become%s ultra-dense!", lfname, getpossessive(lfname),
obname, (oo->amt == 1) ? "s" : "");
}
ndone++;
}
// still nothing done?
if (!ndone) {
if (isplayer(lf)) msg("Unfortunately, it doesn't seem to affect you.");
} }
} }
@ -11204,6 +11271,10 @@ object_t *relinkob(object_t *src, obpile_t *dst) {
// unweild // unweild
killflagsofid(src->flags, F_EQUIPPED); killflagsofid(src->flags, F_EQUIPPED);
if (src->pile->owner) {
unequipeffects(src->pile->owner, src);
}
// adjust letter... // adjust letter...
// gold should always have letter '$' // gold should always have letter '$'
if (src->type->obclass->id == OC_MONEY) { if (src->type->obclass->id == OC_MONEY) {

50
spell.c
View File

@ -310,7 +310,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (inway) { if (inway) {
// just get the lf in the way // just get the lf in the way
if (getnoisedetails(inway, N_WALK, thismovetext, NULL, &vol)) { if (getnoisedetails(inway, N_WALK, NULL, thismovetext, NULL, &vol)) {
// doesn't make noise // doesn't make noise
nposs = 0; nposs = 0;
} else { } else {
@ -327,7 +327,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
for (lf = c->map->lf ; lf ; lf = lf->next) { for (lf = c->map->lf ; lf ; lf = lf->next) {
if (lf == user) continue; if (lf == user) continue;
// get movement text // get movement text
if (getnoisedetails(lf, N_WALK, thismovetext, NULL, &vol)) continue; if (getnoisedetails(lf, N_WALK, NULL, thismovetext, NULL, &vol)) continue;
if (slev >= PR_EXPERT) { if (slev >= PR_EXPERT) {
// overwrite name // overwrite name
real_getlfnamea(lf, thismovetext, B_FALSE, B_FALSE); real_getlfnamea(lf, thismovetext, B_FALSE, B_FALSE);
@ -4593,7 +4593,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
if (isplayer(target)) {
howlong = 2+(power/5); // ie. 2-4
} else {
howlong = getspellduration(2,5,blessed) + power; howlong = getspellduration(2,5,blessed) + power;
}
if (isplayer(target)) { if (isplayer(target)) {
addtempflag(target->flags, F_CHARMEDBY, caster->id, NA, NA, NULL, howlong); addtempflag(target->flags, F_CHARMEDBY, caster->id, NA, NA, NULL, howlong);
@ -6516,16 +6520,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
} else { } else {
int howlong;
if (isplayer(caster) || haslos(player, target->cell)) { if (isplayer(caster) || haslos(player, target->cell)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
// remember the original race if (target->race->id == R_VAMPIRE) {
addflag(target->flags, F_ORIGRACE, target->race->id, NA, NA, NULL); howlong = PERMENANT;
if (target->race->id != R_VAMPIRE) { } else {
// polymorph is temporary howlong = 10;
addtempflag(target->flags, F_POLYMORPHED, B_TRUE, NA, NA, NULL, 10);
} }
setrace(target, R_GASCLOUD, B_TRUE); polymorphto(target, R_GASCLOUD, howlong);
} }
} else if (spellid == OT_S_GLACIATE) { } else if (spellid == OT_S_GLACIATE) {
object_t *o,*nexto; object_t *o,*nexto;
@ -7768,9 +7772,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
// teleport to destination. // teleport to destination.
msg("orig cell: %d,%d.", caster->cell->x, caster->cell->y);
teleportto(caster, targcell, B_FALSE); teleportto(caster, targcell, B_FALSE);
msg("new cell: %d,%d.", caster->cell->x, caster->cell->y);
} else if (spellid == OT_S_PARALYZE) { } else if (spellid == OT_S_PARALYZE) {
int howlong; int howlong;
int saved = B_FALSE; int saved = B_FALSE;
@ -9095,28 +9097,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
if (r) { if (r) {
int howlong;
//int rememberorig = B_FALSE; //int rememberorig = B_FALSE;
getlfname(target, buf);
// if this is the player, remember the original race and job...
if (!hasflag(target->flags, F_ORIGRACE)) {
// remember the original race
addflag(target->flags, F_ORIGRACE, target->race->id, NA, NA, NULL);
}
if (isplayer(target)) { if (isplayer(target)) {
int howlong;
// polymorph will be temporary... // polymorph will be temporary...
howlong = rnd(20,50); howlong = rnd(20,50);
addtempflag(target->flags, F_POLYMORPHED, B_TRUE, NA, NA, NULL, howlong);
} else { } else {
// permenant howlong = PERMENANT;
addflag(target->flags, F_POLYMORPHED, B_TRUE, NA, NA, NULL);
} }
polymorphto(target, r->id, howlong);
// become the new race!
setrace(target, r->id, B_TRUE);
// if someone cast the spell at themself and it's controlled, they can change back at will. // if someone cast the spell at themself and it's controlled, they can change back at will.
if (target == caster) { if (target == caster) {
@ -12793,6 +12783,7 @@ int spellokformonsters(int spellid) {
int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce) { int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power, int *seenbyplayer, int announce) {
char text[BUFLEN],buf[BUFLEN]; char text[BUFLEN],buf[BUFLEN];
int bonus = 0; int bonus = 0;
int resisted = B_FALSE;
// cannot resist spells from gods when they are on their home plane // cannot resist spells from gods when they are on their home plane
if (caster && (caster->race->raceclass->id == RC_GOD)) { if (caster && (caster->race->raceclass->id == RC_GOD)) {
@ -12825,7 +12816,14 @@ int spellresisted(lifeform_t *target, lifeform_t *caster, int spellid, int power
// cancel out the difficulty from NULLIFY being a level 4 spell // cancel out the difficulty from NULLIFY being a level 4 spell
bonus += 8; bonus += 8;
} }
if (skillcheck(target, SC_RESISTMAG, getmrdiff(spellid,power), bonus)) {
if (spellisfromschool(spellid, SS_MENTAL) && lfhasflag(target, F_MINDSHIELD)) {
resisted = B_TRUE;
} else {
resisted = skillcheck(target, SC_RESISTMAG, getmrdiff(spellid,power), bonus);
}
if (resisted) {
if (isplayer(target) || haslos(player, target->cell)) { if (isplayer(target) || haslos(player, target->cell)) {
if (announce) { if (announce) {
msg("%s",text); msg("%s",text);

View File

@ -395,7 +395,7 @@ int addvaultthing(cell_t *c, vault_t *v, enum VAULTTHING vt, char *what) {
break; break;
case VT_LF: case VT_LF:
lf = addmonster(c, R_SPECIFIED, what, B_TRUE, 1, B_FALSE, NULL); lf = addmonster(c, R_SPECIFIED, what, B_TRUE, 1, B_TRUE, NULL);
if (!lf) { if (!lf) {
dblog("invalid racename '%s' in vault", what); dblog("invalid racename '%s' in vault", what);
rv = B_TRUE; rv = B_TRUE;