- [+] fix carpetted floor colour

- [+] bug: giant ant zombie not attacking giant ant
- [+] change table symol to PI
- [+] replace footstool with chair
- [+] allow reusable cells in vaults
- [+] slippery floors should make pushing easier
- [+] when checking stairs i found "Pete footprints"
- [+] new monsters:
    - [+] polar bear
    - [+] owlbear
- [+] bug: sleeping monsters never waking up.
- [+] "random good weapon" wish broken. fixed now.
- [+] cope with med/small/large dancing weapons
    - [+] generice code to check baseid instead of raceid
    - [+] handle automatic generation - need to populate:
        - [+] select an appropriate object (rarity freq / common, 
              uncommon,  rare)
        - [+] copy from obejct to lf:
            - [+] OBHP
            - [+] SIZE
            - [+] OBATTACKDELAY
    - [+] bug: always getting 'twisted branch' for small dancing weapon
    - [+] bug: crash in attackcell. nweps = 0
- [+] replace thin walls with unicode symbols
    - [+] glass
    - [+] wood
    - [+] metal
    - [+] getcellglyph() looks at surrounding cells if required
        - [+] too slow?
- [+] attacking helpless undead shouldn't count
- [+] differentiate EXTRADAM from WOUNDING.
    - [+] wounding = add damage to ALL attacks
    - [+] EXTRADAM = add DIFFERENT type of damage
- [+] psionics on levelup
    - [+] make this a "select from iq/10", not a select from any
- [+] if poison needle trap misses, place it on the ground.
- [+] no nauseated effects while asleep.
- [+] if something runs out of view adjacent to you, say "xxx moves
      behind you"
- [+] ashkari bug:
    - [+] when getting enraged by the sight of something, f_rage runs
          out a few turns before f_aicontrolled. should be the same!!!
This commit is contained in:
Rob Pearce 2012-11-29 20:18:21 +00:00
parent e8cc823d72
commit c6fed68ba2
37 changed files with 853 additions and 349 deletions

9
ai.c
View File

@ -1195,6 +1195,7 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
// look for any hated lfs or enemies
newtarget = NULL;
lf->loslock = B_TRUE;
for (n = 0; n < lf->nlos; n++) {
lifeform_t *who;
if (lf->los[n] != lf->cell) { // not ourself
@ -1287,6 +1288,7 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
}
}
}
lf->loslock = B_FALSE;
if (nhateposs) {
newtarget = hateposs[rnd(0,nhateposs-1)];
} else if (nposs) {
@ -1835,6 +1837,7 @@ int ai_premovement(lifeform_t *lf) {
}
}
// ally needs ammo?
lf->loslock = B_TRUE;
for (i = 0; i < lf->nlos; i++) {
cell_t *c;
c = lf->los[i];
@ -1857,6 +1860,7 @@ int ai_premovement(lifeform_t *lf) {
}
}
}
lf->loslock = B_FALSE;
return B_FALSE;
}
@ -3375,6 +3379,7 @@ int lookforobs(lifeform_t *lf) {
// look around for objects which we want, if we don't already have a targetcell.
if (!hasflag(lf->flags, F_TARGETCELL)) {
if (db) dblog(".oO { no targetcell, so looking for remote objects }");
lf->loslock = B_TRUE;
for (i = 0 ; i < lf->nlos; i++) {
int gothere = B_FALSE;
int celldist;
@ -3386,7 +3391,6 @@ int lookforobs(lifeform_t *lf) {
for (o = c->obpile->first ; o ; o = nexto) {
nexto = o->next;
if (aiwants_real(lf, o, &covets, &noids, oid, oidcovet, &nwantflags, wantflag, wantflagcovet) &&
//canpickup(lf, o, 1)) {
aipickupok(lf, o)) {
gothere = B_TRUE;
@ -3415,7 +3419,6 @@ int lookforobs(lifeform_t *lf) {
((f->val[1] != B_COVETS) && (celldist <= targdist)) ) {
o = hasbetterweapon(lf, c->obpile);
if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o)) {
//&& canpickup(lf, o, 1)) {
if (db) dblog(".oO { remote cell has better weapon (%s). setting f_targetcell }",o->type->name);
gothere = B_TRUE;
}
@ -3433,7 +3436,6 @@ int lookforobs(lifeform_t *lf) {
o = hasbetterarmour(lf, c->obpile);
if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o)) {
//canpickup(lf, o, 1)) {
if (db) dblog(".oO { remote cell has better armour (%s). setting f_targetcell }",o->type->name);
gothere = B_TRUE;
}
@ -3544,6 +3546,7 @@ int lookforobs(lifeform_t *lf) {
}
}
lf->loslock = B_FALSE;
}
if (db) dblog(".oO { didn't find any obs i want }");
return B_FALSE;

View File

@ -554,6 +554,10 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
//maxattacks = nweps; // ie. all
maxattacks = getattacks(lf, NULL, NULL);
// cope with special monsters with NO innate attacks, but
// which still use weapons (eg. dancing weapon).
limit(&maxattacks, 1, NA);
/*
// if we have a weapon, this takes the place of one of our
@ -1177,7 +1181,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
// blessed vs undead
adjustdamforblessings(lf, &(dam[0]), victim, wep->blessed);
// modify for weapon skill, strength etc
// modify for weapon skill, strength, rings of wounding etc
applylfdammod(&dam[0], lf, wep);
// modify for size
@ -2648,7 +2652,7 @@ int getextradamlf(lifeform_t *lf, int *dam, enum DAMTYPE *damtype, int *ndam, in
return *dam;
}
// special case - EXTRADAM goes onto INITIAL dam[] if the same type, rather than
// special case - EXTRADAM of same damtype goes onto INITIAL dam[], rather than
// adding a new one.
getflags(lf->flags, retflag, &nretflags, F_EXTRADAM, F_NONE);
for (i = 0; i < nretflags; i++) {

318
data.c
View File

@ -2050,7 +2050,7 @@ void initobjects(void) {
addflag(lastmaterial->flags, F_HARDNESS, 20, NA, NA, NULL);
// object classes
addoc(OC_BUILDING, "Buildings", "Shops, etc.", '_', C_GREY, RR_RARE);
addoc(OC_BUILDING, "Buildings", "Shops, etc.", UNI_HOUSE, C_GREY, RR_RARE);
addocnoun(lastobjectclass, "building");
addocnoun(lastobjectclass, "shop");
addocnoun(lastobjectclass, "store");
@ -2754,8 +2754,8 @@ void initobjects(void) {
// traps - cell only
addot(OT_TRAPARROW, "arrow trap", "A pressure plate which causes arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
addflag(lastot->flags, F_TRAP, 80, B_TRUE, NA, "ground");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 76, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 76, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 76, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 76, RR_COMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_BROWN, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
@ -2765,8 +2765,8 @@ void initobjects(void) {
addot(OT_TRAPARROWP, "poison arrow trap", "A pressure plate which causes poisoned arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
addflag(lastot->flags, F_TRAP, 85, B_TRUE, NA, "ground");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 69, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 69, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_BROWN, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
@ -2776,8 +2776,8 @@ void initobjects(void) {
addot(OT_TRAPPIT, "pit trap", "A pressure plate which causes the floor to drop away.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
addflag(lastot->flags, F_TRAP, 85, B_TRUE, 22, "ground");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 85, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 85, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 85, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_GREY, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SECRET, 60, NA, NA, NULL);
@ -2796,8 +2796,8 @@ void initobjects(void) {
addot(OT_TRAPSUMMON, "summoning trap", "A magical trap which causes a monster to appear.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
addflag(lastot->flags, F_TRAP, 90, B_TRUE, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 60, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 60, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 60, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_ICECAVE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_GREEN, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
@ -2808,8 +2808,8 @@ void initobjects(void) {
addot(OT_TRAPTRIP, "tripwire", "A thin wire at ankle height.", MT_WIRE, 0.1, OC_TRAP, SZ_SMALL);
addflag(lastot->flags, F_TRAP, 50, B_FALSE, 20, "ground");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 90, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, RR_FREQUENT, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 90, RR_FREQUENT, NULL);
addflag(lastot->flags, F_GLYPH, C_GREY, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
@ -2845,8 +2845,8 @@ void initobjects(void) {
// traps - either cell on object
addot(OT_TRAPALARM, "alarm trap", "A pressure-triggered trap which sounds a loud siren.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
addflag(lastot->flags, F_TRAP, 65, B_TRUE, NA, "ground");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_FREQUENT, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_FREQUENT, NULL);
addflag(lastot->flags, F_OBJECTTRAP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_YELLOW, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
@ -2857,9 +2857,9 @@ void initobjects(void) {
addot(OT_TRAPEBLAST, "energy blast trap", "A magical trap which blasts its victim with energy.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
addflag(lastot->flags, F_TRAP, 70, B_TRUE, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 75, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ICECAVE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 75, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_ICECAVE, NA, RR_RARE, NULL);
addflag(lastot->flags, F_OBJECTTRAP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_MAGENTA, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
@ -2870,8 +2870,8 @@ void initobjects(void) {
addot(OT_TRAPFIRE, "fire trap", "A trap which fires a pillar of flame.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
addflag(lastot->flags, F_TRAP, 70, B_TRUE, 30, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 59, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 59, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 59, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 59, RR_RARE, NULL);
addflag(lastot->flags, F_OBJECTTRAP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_RED, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
@ -2882,7 +2882,7 @@ void initobjects(void) {
addot(OT_TRAPLIGHTNING, "electrical trap", "A metal pressure plate which triggers a bolt of arcing electricity.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
addflag(lastot->flags, F_TRAP, 65, B_TRUE, NA, "ground");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 59, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 59, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_OBJECTTRAP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_CYAN, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
@ -2893,8 +2893,8 @@ void initobjects(void) {
addot(OT_TRAPGAS, "gas trap", "A trap which releases poisonous gas.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
addflag(lastot->flags, F_TRAP, 70, B_TRUE, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 69, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 69, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 69, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_LIGHTGREEN, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
@ -2905,9 +2905,9 @@ void initobjects(void) {
addot(OT_TRAPMINE, "landmine trap", "A buried, pressure-sensitive explosive device.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
addflag(lastot->flags, F_TRAP, 100, B_TRUE, NA, "ground");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 50, NA, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 20, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, RR_VERYRARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 50, RR_VERYRARE, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 20, RR_VERYRARE, NULL);
addflag(lastot->flags, F_OBJECTTRAP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_GREY, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
@ -2918,9 +2918,9 @@ void initobjects(void) {
addot(OT_TRAPTELEPORT, "teleportation trap", "A magical dispersal field.", MT_NOTHING, 0, OC_TRAP, SZ_LARGE);
addflag(lastot->flags, F_TRAP, NA, B_TRUE, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, NA, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 80, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ICECAVE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 80, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ICECAVE, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_MAGENTA, '^', NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
@ -5260,7 +5260,7 @@ void initobjects(void) {
addflag(lastot->flags, F_MAXPOWER, 10, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_FLOATINGDISC, "floating disc", "Creates a disc of energy to carry your equipment.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power level determines how much wight the disc can carry.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power level determines how much weight the disc can carry.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL);
@ -7329,7 +7329,7 @@ void initobjects(void) {
addot(OT_WOODENTABLE, "wooden table", "A waist-height wooden table.", MT_WOOD, 25, OC_FURNITURE, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_WOOD, '\\', NA, NULL);
addflag(lastot->flags, F_GLYPH, C_WOOD, UNI_PI, NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_HUMAN, NA, NULL);
addflag(lastot->flags, F_CLIMBOBSTACLE, 25, NA, NA, NULL);
addflag(lastot->flags, F_CRUSHABLE, SZ_LARGE, NA, NA, NULL);
@ -7341,11 +7341,14 @@ void initobjects(void) {
addflag(lastot->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_DOORWOOD, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_WOODENSTOOL, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_WOODENCHAIR, VT_OB, NA, NULL);
addot(OT_WOODENSTOOL, "wooden footstool", "A small, wooden footstool.", MT_WOOD, 20, OC_FURNITURE, SZ_MEDIUM);
addot(OT_WOODENCHAIR, "wooden chair", "A small wooden chair.", MT_WOOD, 20, OC_FURNITURE, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_ALL, 83, RR_COMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_WOOD, '\\', NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MEDIUM, NA, NULL);
addflag(lastot->flags, F_CRUSHABLE, SZ_LARGE, NA, NA, NULL);
addflag(lastot->flags, F_PUSHABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_WOOD, UNI_CHAIR, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL);
@ -7406,7 +7409,7 @@ void initobjects(void) {
addflag(lastot->flags, F_INVISOB, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOGLYPH, NA, NA, NA, NULL);
addflag(lastot->flags, F_NOFEEL, NA, NA, NA, NULL);
//addflag(lastot->flags, F_TEMPMOD, -15, NA, NA, NULL); // this flag added by spell
addflag(lastot->flags, F_TEMPMOD, -20, NA, NA, NULL); // this flag replaced by spell
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); // overridden by spell
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
@ -7490,7 +7493,7 @@ void initobjects(void) {
addflag(lastot->flags, F_INVISOB, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOGLYPH, NA, NA, NA, NULL);
addflag(lastot->flags, F_NOFEEL, NA, NA, NA, NULL);
//addflag(lastot->flags, F_TEMPMOD, -15, NA, NA, NULL); // this flag added by spell
addflag(lastot->flags, F_TEMPMOD, 20, NA, NA, NULL); // this flag replaced by spell
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); // overridden by spell
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
@ -8452,7 +8455,7 @@ void initobjects(void) {
addflag(lastot->flags, F_VALUE, 300, NA, NA, NULL);
addot(OT_RING_WOUNDING, "ring of wounding", "Increases the damage output of the wearer.", MT_METAL, 0.1, OC_RING, SZ_MINI);
addflag(lastot->flags, F_RARITY, H_ALL, 73, RR_UNCOMMON, "");
addflag(lastot->flags, F_EQUIPCONFER, F_EXTRADAM, NA, NA, "0d0+4");
addflag(lastot->flags, F_EQUIPCONFER, F_WOUNDING, 4, NA, NULL);
addflag(lastot->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 350, NA, NA, NULL);
@ -8495,6 +8498,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EQUIPCONFER, F_HPDRAIN, 1, DT_DIRECT, "life force draining");
addflag(lastot->flags, F_VALUE, 400, NA, NA, NULL);
addot(OT_RING_CONTROL, "ring of control", "Allows the wearer control over teleportation and polymorphic effects.", MT_METAL, 0.1, OC_RING, SZ_MINI);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "This ring also prevents innate rage when seeing certain races.");
addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_RARE, "");
addflag(lastot->flags, F_EQUIPCONFER, F_CONTROL, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 350, NA, NA, NULL);
@ -10890,9 +10894,8 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_VLOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_HITDICE, 1, NA, 4, NULL);
addflag(lastrace->flags, F_TR, 4, NA, NA, NULL);
@ -10975,8 +10978,8 @@ void initrace(void) {
addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_NOSTAIRS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 0, 1, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
@ -11316,8 +11319,7 @@ void initrace(void) {
addflag(lastrace->flags, F_GODBONUS, PL_PLEASED, GB_FLAG, F_FEARLESS, "-1,NA,NA");
addflag(lastrace->flags, F_GODBONUS, PL_PLEASED, GB_FLAG, F_STAMBOOST, "5,NA,NA");
addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_ACCURACYMOD, "15,NA,NA");
sprintf(buf, "%d,%d,3", DT_DIRECT, B_FALSE);
addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_EXTRADAM, buf);
addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_WOUNDING, "3,NA,NA");
addflag(lastrace->flags, F_GODBONUS, PL_ECSTATIC, GB_FLAG, F_MINCRITCHANCE, "25,0,0");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "restoring stamina");
@ -12116,7 +12118,7 @@ void initrace(void) {
addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, RR_VERYRARE, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
@ -12904,7 +12906,7 @@ void initrace(void) {
setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
@ -13812,7 +13814,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ICECAVE, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
@ -13930,7 +13932,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 75, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 75, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
@ -13964,7 +13966,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 72, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 72, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL);
@ -13996,7 +13998,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_EXLOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 72, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 72, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
@ -14155,8 +14157,8 @@ void initrace(void) {
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "small dust cloud");
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "large dust cloud");
addflag(lastrace->flags, F_EXTRACORPSE, 50, NA, NA, "pile of sleeping powder");
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_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL);
@ -14259,8 +14261,8 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ICECAVE, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_ICECAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 2, NA, NA, NULL);
@ -14589,9 +14591,9 @@ void initrace(void) {
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_MASTERVAULTS, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL);
@ -15033,16 +15035,16 @@ void initrace(void) {
addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 1, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_BASH, NA, NA, NULL);
addrace(R_FUNGUSPETRIFY, "petrifungus", 0.5, 'F', C_BLUE, MT_PLANT, RC_PLANT, "This ominous blue fungus has evolved a particularly dangerous protective mechanism, releasing spores which instantly transform living flesh to stone.");
//has statues and stones nearby
addbodypart(lastrace, BP_BODY, 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_FOREST, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_HARMLESS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL);
@ -15060,7 +15062,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 4, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_BASH, NA, NA, NULL);
addrace(R_FUNGUSRAGE, "ragefungus", 0.5, 'F', C_RED, MT_PLANT, RC_PLANT, "This deep red fungus protects itself by explelling rage-inducing pheremones, causing predators to attack each other instead of it.");
addbodypart(lastrace, BP_BODY, NULL);
@ -15085,7 +15087,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 1, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_BASH, NA, NA, NULL);
addflag(lastrace->flags, F_FILLPOT, OT_POT_FURY, BLOODFORPOT, NA, NULL);
addrace(R_GLUON, "gluon", 1, 'F', C_YELLOW, MT_PLANT, RC_PLANT, "A walking plant-based monster whose body is covered with a thick glue-like secretion.");
@ -15137,7 +15139,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_BASH, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_S_CLONE, 0, 100, "pw:1;");
addflag(lastrace->flags, F_CANWILL, OT_S_ENTANGLE, 50, 50, "pw:2; range:1;");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_CLONE, NA, NA, "expands");
@ -15221,7 +15223,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HITDICE, 1, NA, 4, NULL);
addflag(lastrace->flags, F_TR, 2, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_BASH, NA, NA, NULL);
// end plants
// animals
@ -15255,11 +15257,11 @@ void initrace(void) {
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addrace(R_BATMUTATED, "mutated bat", 3, 'B', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Bats exposed to toxic radiation become mutated, and their sonic navigation skills turn deadly.");
setbodytype(lastrace, BT_BIRD);
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_FOREST, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
@ -15318,7 +15320,7 @@ void initrace(void) {
addflag(lastrace->flags, F_FILLPOT, OT_POT_MAGIC, BLOODFORPOT, NA, NULL);
addrace(R_BATVAMPIRE, "vampire bat", 6, 'B', C_BLUE, MT_FLESH, RC_ANIMAL, "Bats which suck the blood of their victims.");
setbodytype(lastrace, BT_BIRD);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -15355,7 +15357,7 @@ void initrace(void) {
addflag(lastrace->flags, F_TERRITORIAL, 2, NA , NA, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_FREQUENT, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL);
@ -15559,7 +15561,6 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ICECAVE, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_STARTASLEEPPCT, 80, NA, NA, NULL); // hibernating
addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL);
@ -15570,7 +15571,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 6, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 3, 3, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LTAVERAGE, NA, NULL);
@ -15596,7 +15597,6 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ICECAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTASLEEPPCT, 80, NA, NA, NULL); // hibernating
addflag(lastrace->flags, F_HITDICE, 7, NA, NA, NULL);
@ -15607,7 +15607,7 @@ void initrace(void) {
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_TEETH, 8, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 3, 3, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LTAVERAGE, NA, NULL);
@ -15625,6 +15625,69 @@ void initrace(void) {
addflag(lastrace->flags, F_MINIONS, 25, 1, 2, "bear cub");
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_BEAROWL, "owlbear", 750, 'Q', C_DARKYELLOW, MT_FLESH, RC_ANIMAL, "A crazed hybrid between an owl's head and a bear's body, madness shiens in this beast's eyes.");
setbodytype(lastrace, BT_QUADRAPED);
lastrace->baseid = R_BEAR;
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 7, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 8, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 8, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 8, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_BEAK, 6, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_HATESALL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roar");
addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_LISTEN, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_RAGE, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL);
addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_BEARPOLAR, "polar bear", 250, 'Q', C_WHITE, MT_FLESH, RC_ANIMAL, "A very large white bear.");
setbodytype(lastrace, BT_QUADRAPED);
lastrace->baseid = R_BEAR;
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_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_ICECAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 8, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 8, 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_ENHANCESMELL, 5, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 8, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 8, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 10, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roar");
addflag(lastrace->flags, F_STARTSKILL, SK_SWIMMING, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_CRUSH, NA, NA, "dam:2d6;");
addflag(lastrace->flags, F_CRITKNOCKDOWN, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 15, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_BEARCUB, "bear cub", 60, 'q', C_BROWN, MT_FLESH, RC_ANIMAL, "Cute little baby bears. Still dangerous though.");
setbodytype(lastrace, BT_QUADRAPED);
lastrace->baseid = R_BEAR;
@ -15894,7 +15957,8 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, 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_ENHANCESMELL, 6, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 3, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 4, NA, NA, NULL);
@ -15928,7 +15992,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, "");
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 10, NA, NULL);
@ -15986,8 +16050,8 @@ void initrace(void) {
setbodytype(lastrace, BT_QUADRAPED);
addbodypart(lastrace, BP_TAIL, NULL);
addflag(lastrace->flags, F_ALIGNMENT, AL_NEUTRAL, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, "");
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL);
@ -16156,7 +16220,7 @@ void initrace(void) {
addrace(R_HAWKBLOOD, "trained hawk", 1, 'A', C_LIGHTRED, MT_FLESH, RC_ANIMAL, "Once ordinary hawk, these creatures have been battle-hardened through regular combat."); // 'A' for Avian
setbodytype(lastrace, BT_BIRD);
lastrace->baseid = R_HAWK;
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_TERRITORIAL, 5, NA , NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
@ -17997,13 +18061,13 @@ void initrace(void) {
addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_CANWILL, OT_A_FLY, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_A_FLY, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 1, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 5, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 1, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 3, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 2, NA, "buzzes angrily^an angry buzzing");
addflag(lastrace->flags, F_NOISETEXT, N_FLY, SV_TALK, NA, "^buzzing wings");
@ -18107,8 +18171,8 @@ void initrace(void) {
addflag(lastrace->flags, F_EXTRACORPSE, NA, NA, NA, "small fire");
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 2, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
@ -18345,7 +18409,7 @@ void initrace(void) {
addbodypart(lastrace, BP_TAIL, NULL);
addbodypart(lastrace, BP_WINGS, NULL);
addflag(lastrace->flags, F_RARITY, H_HEAVEN, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_RARE, 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_SIZE, SZ_SMALL, NA, NA, NULL);
@ -18595,7 +18659,8 @@ void initrace(void) {
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSTAIRS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 1, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
@ -18690,8 +18755,8 @@ void initrace(void) {
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL);
@ -18975,7 +19040,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 8, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 9, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 10, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "pw:8;");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "cursed robe");
@ -19137,7 +19202,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
@ -19276,9 +19341,13 @@ void initrace(void) {
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_XPVAL, 0, NA, NA, NULL);
addrace(R_DANCINGWEAPON, "dancing weapon", 0, ')', C_GREY, MT_METAL, RC_OTHER, "A magically animated weapon.");
addrace(R_DANCINGWEAPONS, "small dancing weapon", 0, ')', C_GREY, MT_METAL, RC_OTHER, "A magically animated weapon.");
lastrace->baseid = R_DANCINGWEAPON;
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOKO, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_GETKILLEDVERB, NA, NA, NA, "destroy");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "average weapon");
addflag(lastrace->flags, F_GETKILLEDVERB, NA, NA, NA, "defeat");
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
@ -19290,6 +19359,69 @@ void initrace(void) {
addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 3, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL);
addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SILENTMOVE, 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_NOSLEEP, B_TRUE, NA, NA, NULL);
addrace(R_DANCINGWEAPON, "dancing weapon", 0, ')', C_GREY, MT_METAL, RC_OTHER, "A magically animated weapon.");
lastrace->baseid = R_DANCINGWEAPON;
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOKO, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_GETKILLEDVERB, NA, NA, NA, "defeat");
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "good weapon");
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 5, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL);
addflag(lastrace->flags, F_NOCORPSE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_SILENTMOVE, 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_NOSLEEP, B_TRUE, NA, NA, NULL);
addrace(R_DANCINGWEAPONL, "large dancing weapon", 0, ')', C_GREY, MT_METAL, RC_OTHER, "A magically animated weapon.");
lastrace->baseid = R_DANCINGWEAPON;
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOKO, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_GETKILLEDVERB, NA, NA, NA, "defeat");
addflag(lastrace->flags, F_RARITY, H_ALL, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great weapon");
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_NATURALFLIGHT, B_TRUE, NA, NA, "");
addflag(lastrace->flags, F_CANWILL, OT_S_FLIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_FLIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 8, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL);

Binary file not shown.

View File

@ -1,12 +1,12 @@
@id:antnest
@map
##ddddddd##
R#ddddddd#R
#dd.....dd#
dd.......dd
O.........d
dd.......dd
#dd.....dd#
##ddddddd##
R#ddddddd#R
@end
@legend
@ -14,6 +14,7 @@ dd.......dd
d:cell:dirt wall
.:cell:dirt
O:exit
R:reusable
@end
@flags

View File

@ -2,17 +2,17 @@
@id:babayagahut_2
@map
###################
######CcssscC######
###ccccccccccccc###
rrrrr#########rrrrr
rr####CcssscC####rr
r##ccccccccccccc##r
##cccccc...ccccc|##
#cccccc.ScS.cccc|.#
#Xccccc.cFc.cccc|.#
#cccccc.ScS.cccc|.#
##cccccc...ccccc|##
###ccccccccccccc###
######cccccBg######
###################
r##ccccccccccccc##r
rr####cccccBg####rr
rrrrr#########rrrrr
@end
@legend
@ -27,6 +27,7 @@ C:ob:ornate chest
|:ob:iron cage
X:ob:hut's doorway
w:ob:great random weapon
r:reusable
@end
@flags

View File

@ -1,12 +1,12 @@
@id:bear_cave
@map
###########
####....###
rrr######rr
rr##....##r
###......##
.O......B.#
###......##
####....###
###########
rr##....##r
rrr######rr
@end
@legend
@ -14,6 +14,7 @@
O:ob:boulder
O:exit
B:mon:grizzly bear
r:reusable
@end
@flags

View File

@ -1,18 +1,19 @@
@id:troll_cave
@map
###########
####....###
rrr######rr
rr##....##r
###......##
.O........#
###......##
####....###
###########
rr##....##r
rrr######rr
@end
@legend
#:cell:SOLID
O:ob:boulder
O:exit
r:reusable
@end
@flags

View File

@ -2,18 +2,18 @@
@id:caveboss_1
@map
##################
#################r
#c......a.c.+AA###
#.w#.#.#.#..#AA+C#
+..........f####_#
#.w#.#.#.#.W#//+C#
#c......a.c.+//###
##################
#################r
@end
@legend
#:cell:metal wall
f:ob:wooden footstool
f:ob:wooden chair
f:mon:goblin king
W:mon:red wyrmling
a:mon:goblin archer
@ -26,12 +26,13 @@ A:ob:great armour
_:ob:pentagram
_:ob:ancient stone key
C:ob:ornate chest
r:reusable
@end
@flags
goesin:cave
norandom
scatter(1,1,-2,-2) ob:wooden footstool:0-3
scatter(1,1,-2,-2) ob:wooden chair:0-3
scatter(1,1,-2,-2) ob:random food:0-2
mayflipx
tag:caveboss

View File

@ -2,20 +2,20 @@
@id:caveboss_2
@map
##################
###.........######
##############rrrr
###.........####rr
#.......w.c.+AA###
#.w.........#AA+C#
+..........W####_#
#.w........f#pp+C#
#.......w.c.+pp###
###.........######
##################
###.........####rr
##############rrrr
@end
@legend
#:cell:metal wall
W:ob:wooden footstool
W:ob:wooden chair
W:mon:red wyrmling
f:mon:goblin king
w:ob:goblin corpse
@ -28,12 +28,13 @@ _:ob:pentagram
_:ob:cursed excellent weapon
_:ob:ancient stone key
C:ob:ornate chest
r:reusable
@end
@flags
goesin:cave
norandom
scatter(1,1,-2,-2) ob:wooden footstool:0-3
scatter(1,1,-2,-2) ob:wooden chair:0-3
scatter(1,1,-2,-2) ob:random food:0-2
mayflipx
tag:caveboss

View File

@ -1,20 +1,21 @@
@id:circular_room
@map
#####+#####
###.....###
rr###+###rr
r##.....##r
##.......##
#.........#
+.........+
#.........#
##.......##
###.....###
#####+#####
r##.....##r
rr###+###rr
@end
@legend
#:cell:SOLID
+:ob:wooden door
+:exit
r:reusable
@end
@flags

View File

@ -1,19 +1,21 @@
@id:diagonal_cross
@map
#X.#####.X#
#X.##r##.X#
##..###..##
###..#..###
####...####
####...####
####.#.####
###.###.###
r##..#..##r
rr##...##rr
rrr#.O.#rrr
rr##...##rr
r##..#..##r
##..###..##
#X.#####.X#
#X.##r##.X#
@end
@legend
#:cell:SOLID
O:ob:large fire:50
X:exit
r:reusable
@end
@flags

View File

@ -15,7 +15,7 @@ autopop
! tables & chairs
fill(1,1,-2,-2) cell:tiled floor
scatter(1,1,-2,-2) ob:wooden table:20%
scatter(1,1,-2,-2) ob:wooden footstool:20%
scatter(1,1,-2,-2) ob:wooden chair:20%
scatter(1,1,-2,-2) ob:random food:1-2
scatter(1,1,-2,-2) ob:refrigerator:1
scatter(1,1,-2,-2) ob:steak knife:1-5

View File

@ -1,12 +1,12 @@
@id:firepit
@map
####+####
####.####
##ff_ff##
##ff_ff##
##ff.ff##
##ffcff##
####d####
rr##+##rr
r###.###r
r#ff_ff#r
r#ff_ff#r
r#ff.ff#r
r#ffcff#r
r###d###r
@end
@legend
@ -18,6 +18,7 @@ _:ob:barricade:30
f:ob:immutable large fire
c:ob:untrapped ornate chest
d:ob:secret door:15:cell:SOLID
r:reusable
@end
@flags

View File

@ -1,19 +1,20 @@
! a circular room filled with water
@id:fishbowl
@map
##ggggg##
r#ggggg#r
gggwwwggg
gwwwwwwwg
gwwwwwwwg
gwwwwwwwg
gggwwwggg
##ggggg##
r#ggggg#r
@end
@legend
#:cell:SOLID
g:cell:glass wall
w:ob:very deep water:100
r:reusable
@end
@flags

View File

@ -21,7 +21,7 @@ X:exit
>:ob:staircase going down
+:ob:wooden door
/:ob:wooden table
-:ob:wooden footstool
-:ob:wooden chair
c:ob:lit candelabrum
@:mon:jailer
@end
@ -30,7 +30,7 @@ c:ob:lit candelabrum
goesin:dungeon
norandom
atoneof(10,1)(10,3)(10,5) ob:portal to lv1
scatter(1,1,-2,-2) ob:wooden footstool:0-3
scatter(1,1,-2,-2) ob:wooden chair:0-3
scatter(1,1,-2,-2) ob:random food:0-2
mayrotate
maintainedge

View File

@ -1,18 +1,19 @@
@id:oval_room
@map
####+####
rr##+##rr
###...###
#.......#
#.......#
#.......#
###...###
####+####
rr##+##rr
@end
@legend
#:cell:SOLID
+:ob:wooden door
+:exit
r:reusable
@end
@flags

View File

@ -1,10 +1,10 @@
@id:guarded_pitbridge
@map
##X###
##X##r
#^_^##
#^_^m#
#^_^##
##X###
##X##r
@end
@legend
@ -13,6 +13,7 @@ _:ob:barricade
^:ob:hole in the ground
m:mon:humanoid with firearm
X:exit
r:reusable
@end
@flags

View File

@ -1,17 +1,18 @@
@id:playerstart_5
@map
#######
r#####r
##...##
#.....#
#..p..x
#.....#
##...##
#######
r#####r
@end
@legend
#:cell:SOLID
p:ob:playerstart
x:exit
r:reusable
@end
@flags
goesin:dungeon

View File

@ -1,19 +1,20 @@
@id:playerstart_6
@map
######
####.#
###..x
rrr###
rr##.#
r##..x
##...#
#..p.#
##...#
###..x
####.#
######
r##..x
rr##.#
rrr###
@end
@legend
#:cell:SOLID
p:ob:playerstart
x:exit
r:reusable
@end
@flags
goesin:dungeon

View File

@ -1,17 +1,18 @@
@id:roundabout
@map
###x###
r##x##r
##...##
#..#..#
x.###.x
#..#..#
##...##
###x###
r##x##r
@end
@legend
#:cell:SOLID
x:exit
r:reusable
@end
@flags

View File

@ -1,6 +1,6 @@
@id:uturn
@map
###########
r#########r
###.....###
##..###..##
#X.#####.X#
@ -9,6 +9,7 @@
@legend
#:cell:SOLID
X:exit
r:reusable
@end
@flags

View File

@ -2,15 +2,15 @@
@id:woodsboss_1
@map
..fffffff..
.ff.....ff.
rrfffffffrr
rff.....ffr
ff..,,,,.ff
f..,,,,,,.f
+,,,,,,,_.f
f..,,,,,,.f
ff..,,,,.ff
.ff.....ff.
..fffffff..
rff.....ffr
rrfffffffrr
@end
@legend
@ -20,6 +20,7 @@ f:ob:bone fence
,:cell:dirt
_:mon:walking hut
_:cell:dirt
r:reusable
@end
@flags

23
defs.h
View File

@ -68,14 +68,18 @@
#define DEF_HITDICE "1d4"
// unicode chars
#define UNI_DYNAMIC 0x2500 // use surrounding cells and box chars
#define UNI_SOLID 0x2588
#define UNI_SHADELIGHT 0x2591
#define UNI_SHADEMED 0x2592
#define UNI_SHADEDARK 0x2593
#define UNI_SPIRAL 0x2202
#define UNI_SUN 0x203B
#define UNI_CHAIR 0x2441
#define UNI_CLOUD 0x203B
//#define UNI_SOLID '#'
#define UNI_HOUSE 0x2302
#define UNI_PI 0x03C0
#define UNI_TUNNEL 0x2126
#define UNI_TREELOTS 0x2051
#define UNI_TREE 0x2042
@ -399,6 +403,13 @@
#define MAXDIR_MAP 15
enum CELLADJUSTTYPE {
CA_NONE = 0,
CA_CH,
CA_COL,
CA_BOTH,
};
enum TEMPERATURE {
T_VCOLD = -3,
T_COLD = -2,
@ -1349,6 +1360,8 @@ enum RACE {
R_BEAR,
R_BEARCUB,
R_BEARGRIZZLY,
R_BEAROWL,
R_BEARPOLAR,
R_BILCO,
R_CATCHEETAH,
R_CATLION,
@ -1453,7 +1466,9 @@ enum RACE {
R_WRAITHICE,
R_ZOMBIE,
// special
R_DANCINGWEAPONS,
R_DANCINGWEAPON,
R_DANCINGWEAPONL,
R_FLOATINGDISC,
R_GASCLOUD,
R_HECTASSERVANT,
@ -2232,7 +2247,7 @@ enum OBTYPE {
OT_WEAPONRACK,
OT_WOODENTABLE,
OT_WOODENBARREL,
OT_WOODENSTOOL,
OT_WOODENCHAIR,
// misc objects
OT_BONE,
OT_CHEST,
@ -3331,6 +3346,8 @@ enum FLAG {
// f_mutable.
// player only flags
F_AICONTROLLED, // player will be controlled by the computer
// if v2 = F_RAGE, then this is because we are
// enraged.
F_DONEBURNMSG, // tells the game not to say 'the {celltype} burns!'
F_DONEDARKMSG, // tells the game not to say 'it is very dark here'
F_DONELISTEN, // supress further 'you hear xx' messages this turn.
@ -4108,6 +4125,7 @@ enum FLAG {
F_PATHFINDING, // you are following a path via 'G'
// to coords v0,v1 on mapid v2
F_SPRINTING, // you are sprinting.
F_WOUNDING, // increase all damage done by this lf by v0
F_WINDSHIELD,// has a windshield protecting against missiles of speed
// v0 or lower.
F_DODGES, // you dodge missed attacks
@ -4775,6 +4793,7 @@ enum VAULTTHING {
VT_OB,
VT_LF,
VT_CELL,
VT_REUSABLE,
};
typedef struct vlegend_s {
@ -4876,7 +4895,7 @@ typedef struct cell_s {
} cell_t;
typedef struct celltype_s {
int id; // eg. dungeonfloor, wall, door
enum CELLTYPE id; // eg. dungeonfloor, wall, door
struct glyph_s glyph;
/*
char glyph; // how to display it

1
flag.c
View File

@ -1016,7 +1016,6 @@ flag_t *incflag(flagpile_t *fp, enum FLAG fid, int val1, int val2, int val3) {
return f;
}
int istransitoryflag(flag_t *f) {
if ((f->lifetime >= FROMEXTERNAL_LOW) && (f->lifetime <= FROMEXTERNAL_HIGH)) {
return B_FALSE;

103
io.c
View File

@ -118,6 +118,32 @@ choice_t *addchoice(prompt_t *p, char ch, char *text, char *desc, void *data, ch
return &(p->choice[p->nchoices - 1]);
}
void killchoice(prompt_t *p, int idx) {
int n;
for (n = idx; n < p->nchoices-1; n++) {
if (p->choice[n].text) free(p->choice[n].text);
if (p->choice[n].desc) free(p->choice[n].desc);
if (p->choice[n].longdesc) free(p->choice[n].longdesc);
// shuffle other choices down
p->choice[n].ch = p->choice[n+1].ch;
if (p->choice[n+1].text) p->choice[n].text = strdup(p->choice[n+1].text);
else p->choice[n].text = strdup("");
if (p->choice[n+1].desc) p->choice[n].desc = strdup(p->choice[n+1].desc);
else p->choice[n].desc = strdup("");
if (p->choice[n+1].longdesc) p->choice[n].longdesc = strdup(p->choice[n+1].longdesc);
else p->choice[n].longdesc = strdup("");
p->choice[n].data = p->choice[n+1].data;
p->choice[n].heading = p->choice[n+1].heading;
p->choice[n].hilite = p->choice[n+1].hilite;
p->choice[n].valid = p->choice[n+1].valid;
p->choice[n].shortcutslot = p->choice[n+1].shortcutslot;
}
p->nchoices--;
}
void addheading(prompt_t *p, char *text) {
p->choice[p->nchoices].ch = '\0';
p->choice[p->nchoices].text = strdup(text);
@ -939,7 +965,7 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
}
wep = getweapon(c->lf);
if (wep && (c->lf->race->id != R_DANCINGWEAPON)) {
if (wep && (c->lf->race->baseid != R_DANCINGWEAPON)) {
object_t *secwep;
char obname[BUFLEN];
char obname2[BUFLEN];
@ -1357,7 +1383,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
return B_FALSE;
}
if (lf->race->id == R_DANCINGWEAPON) {
if (lf->race->baseid == R_DANCINGWEAPON) {
return B_FALSE;
}
@ -1842,6 +1868,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE;
break;
case F_EXTRADAM:
case F_WOUNDING:
if (isplayer(lf)) { // don't know if monsters get it
msg("You feel more dangerous!");
donesomething = B_TRUE;
@ -2236,7 +2263,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
if (!lf->born) {
return B_FALSE;
}
if (lf->race->id == R_DANCINGWEAPON) {
if (lf->race->baseid == R_DANCINGWEAPON) {
return B_FALSE;
}
@ -2510,6 +2537,7 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE;
break;
case F_EXTRADAM:
case F_WOUNDING:
if (isplayer(lf)) { // don't know if monsters lose it
msg("You no longer feel more dangerous.");
donesomething = B_TRUE;
@ -5214,7 +5242,7 @@ void docomms_areadangers(char *who, flagpile_t *fp, lifeform_t *lf) {
if (c->lf && !isplayer(c->lf) && (c->lf != lf) && areenemies(c->lf, player)) {
int showit = B_FALSE;
enum RARITY rr;
getracerarity(NULL, c->lf->race->id, &rr);
getracerarity(H_ALL, c->lf->race->id, &rr);
if (rr == RR_VERYRARE) {
showit = B_TRUE;
} else {
@ -7070,7 +7098,12 @@ char *makedesc_ob(object_t *o, char *retbuf) {
strncat(retbuf, buf2, HUGEBUFLEN);
break;
case F_EXTRADAM:
sprintf(buf2, "%s will cause you to deal more damage.\n", buf);
sprintf(buf2, "%s will cause you to deal additional %s damage on each attack.\n", buf,
getdamname(f->val[0]));
strncat(retbuf, buf2, HUGEBUFLEN);
break;
case F_WOUNDING:
sprintf(buf2, "%s will grant +%d extra damage on all attacks.\n", buf, f->val[0]);
strncat(retbuf, buf2, HUGEBUFLEN);
break;
case F_EXTRALUCK:
@ -9622,7 +9655,7 @@ void initgfx(void) {
initcol(C_BLUE, 0, 0, 1000);
initcol(C_INDIGO, 300, 0, 520);
initcol(C_MAGENTA, 1000, 0, 1000);
initcol(C_PINK, 820, 368, 368);
initcol(C_PINK, 820, 384, 576);
initcol(C_CYAN, 0, 1000, 1000);
initcol(C_GREY, 800, 800, 800);
initcol(C_YELLOW, 1000, 1000, 0);
@ -9632,11 +9665,11 @@ void initgfx(void) {
initcol(C_BONE, 556, 548, 448);
initcol(C_BRICK, 568, 140, 140);
initcol(C_METAL, 500, 500, 500);
initcol(C_FLESH, 952, 612, 408);
initcol(C_FLESH, 952, 812, 608);
initcol(C_FOG, 812, 808, 728);
initcol(C_MOSS, 0, 748, 428);
initcol(C_CARPET1, 560, 480, 336);
initcol(C_CARPET2, 0, 556, 468);
initcol(C_CARPET1, 360, 280, 136);
initcol(C_CARPET2, 160, 80, 36);
initcol(C_SMOKE, 250, 250, 300);
initcol(C_WOOD, 384, 244, 64);
// dark cols
@ -13246,7 +13279,7 @@ void showlfstats(lifeform_t *lf, int showall) {
}
}
}
if (nfound) y++;
//if (nfound) y++;
// obvious physical effects first.
f = lfhasknownflag(lf, F_BEINGSTONED);
@ -13898,7 +13931,7 @@ void showlfstats(lifeform_t *lf, int showall) {
y++;
}
getflags(lf->flags, retflag, &nretflags, F_EXTRADAM, F_NONE);
getflags(lf->flags, retflag, &nretflags, F_EXTRADAM, F_WOUNDING,F_NONE);
for (i = 0; i < nretflags; i++) {
if (showall || f->known) {
int ndice,nsides,bonus;
@ -13907,32 +13940,38 @@ void showlfstats(lifeform_t *lf, int showall) {
char damtypebuf[BUFLEN];
int min = 0,max = 0;
f = retflag[i];
if (f->val[2] == NA) {
texttodice(f->text, &ndice,&nsides,&bonus);
} else {
if (f->id == F_EXTRADAM) {
if (f->val[2] == NA) {
texttodice(f->text, &ndice,&nsides,&bonus);
} else {
ndice = 0;
nsides = 1;
bonus = f->val[2];
}
if ((f->lifetime == FROMOBEQUIP) ||
(f->lifetime == FROMOBHOLD) ||
(f->lifetime == FROMOBACTIVATE) ) {
object_t *obfrom;
obfrom = findobbyid(lf->pack, f->obfrom);
if (obfrom) {
int bonusdam;
sumflags(obfrom->flags, F_BONUS, &bonusdam, NULL, NULL);
bonus += bonusdam;
}
}
if (f->val[0] == NA) {
strcpy(damtypebuf, "damage");
} else {
snprintf(damtypebuf, BUFLEN, "%s damage", getdamname(f->val[0]));
}
} else { // ie. f_wounding
ndice = 0;
nsides = 1;
bonus = f->val[2];
}
if ((f->lifetime == FROMOBEQUIP) ||
(f->lifetime == FROMOBHOLD) ||
(f->lifetime == FROMOBACTIVATE) ) {
object_t *obfrom;
obfrom = findobbyid(lf->pack, f->obfrom);
if (obfrom) {
int bonusdam;
sumflags(obfrom->flags, F_BONUS, &bonusdam, NULL, NULL);
bonus += bonusdam;
}
}
if (f->val[0] == NA) {
bonus = f->val[0];
strcpy(damtypebuf, "damage");
} else {
snprintf(damtypebuf, BUFLEN, "%s damage", getdamname(f->val[0]));
}
dicetotext(ndice, nsides, bonus, &min, &max, dicebuf, mmbuf);
if (strcmp(dicebuf, mmbuf)) {
mvwprintw(mainwin, y, 0, "%s deal%s %s (%s) extra %s each hit.", you(lf),

1
io.h
View File

@ -1,6 +1,7 @@
#include <ncurses.h>
#include "defs.h"
choice_t *addchoice(prompt_t *p, char ch, char *text, char *desc, void *data, char *longdesc);
void killchoice(prompt_t *p, int idx);
void addheading(prompt_t *p, char *text);
void addmsghist(char *text);
void addpromptq(prompt_t *p, char *q);

258
lf.c
View File

@ -1184,6 +1184,7 @@ int canpolymorphto(enum RACE rid) {
int canpush(lifeform_t *lf, object_t *o, int dir) {
cell_t *obcell, *dstcell;
float adjweight;
reason = E_OK;
if ((getlfmaterial(lf) == MT_GAS) || lfhasflag(lf, F_NONCORPOREAL)) {
@ -1191,8 +1192,14 @@ int canpush(lifeform_t *lf, object_t *o, int dir) {
return B_FALSE;
}
// check lf weight
if (getobweight(o) > getmaxpushweight(lf)) {
// check object weight vs. lf weight
// adjust object weight for cell sliperriness.
adjweight = getobweight(o);
if (o->pile->where) {
adjweight -= getslipperyness(o->pile->where, NULL);
limitf(&adjweight, 0, NA);
}
if (adjweight > getmaxpushweight(lf)) {
reason = E_TOOHEAVY;
return B_FALSE;
}
@ -1670,7 +1677,7 @@ int canweild(lifeform_t *lf, object_t *o) {
}
// special case...
if (lf->race->id == R_DANCINGWEAPON) {
if (lf->race->baseid == R_DANCINGWEAPON) {
return B_TRUE;
}
@ -3490,7 +3497,7 @@ void die(lifeform_t *lf) {
}
}
if (lf->race->id == R_DANCINGWEAPON) {
if (lf->race->baseid == R_DANCINGWEAPON) {
if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s drops to the ground.", buf);
@ -4128,11 +4135,30 @@ void dumplf(void) {
dblog("END LIFEFORM DUMP (%d found)",count);
}
void dumpmonsters(void) {
void dumpmonsters(enum HABITAT hab) {
race_t *r;
flag_t *f;
int wanthd;
habitat_t *h;
int wanthd,i;
int totcount = 0;
FILE *out;
//f = hasflagval(r->flags, F_RARITY, map->habitat->id, NA, NA, NULL);
out = fopen("monsters.html", "wt");
assert(out);
h = findhabitat(hab);
fprintf(out, "<html>\n");
fprintf(out, "<body>\n");
fprintf(out, "<h1>Monsters for habitat '%s'</h1>\n",h ? h->name : "<any>");
fprintf(out, "<table border=1>\n");
fprintf(out, "<tr><th>&nbsp;</th>");
for (i = RR_FREQUENT; i <= RR_UNIQUE; i++) {
fprintf(out, "<th>%s</th>",getrarityname(i));
}
fprintf(out, "</tr>\n");
dblog("START MONSTER DUMP:");
for (wanthd = 0; wanthd <= maxmonhitdice ; wanthd++) {
@ -4145,18 +4171,38 @@ void dumpmonsters(void) {
}
}
dblog("MONSTERS WITH THREAT RATING %d (%d found):",wanthd, count);
for (r = firstrace ; r ; r = r->next) {
int thishd;
thishd = gettrrace(r);
if (thishd == wanthd) {
int max;
f = hasflag(r->flags, F_HITDICE);
max = flagtomaxhp(f);
dblog("\t%s (%d hp)",r->name, max);
fprintf(out, "<tr>\n");
fprintf(out, "\t<th>Threat Rating %d</th>\n", wanthd);
for (i = RR_FREQUENT; i <= RR_UNIQUE; i++) {
int thiscount = 0;
fprintf(out, "\t<td>\n");
for (r = firstrace ; r ; r = r->next) {
int thishd;
enum RARITY rr;
thishd = gettrrace(r);
getracerarity(hab, r->id, &rr);
if ((thishd == wanthd) && (rr == i)) {
int max;
f = hasflag(r->flags, F_HITDICE);
max = flagtomaxhp(f);
dblog("\t%s (%d hp)",r->name, max);
fprintf(out, "\t\t%s (%d hp)<br>\n",r->name, max);
thiscount++;
}
}
if (!thiscount) {
fprintf(out, "&nbsp;\n");
}
fprintf(out, "\t</td>\n");
}
fprintf(out, "</tr>\n");
}
dblog("END MONSTER DUMP (%d found)",totcount);
fprintf(out, "</table>\n");
fprintf(out, "</body>\n");
fprintf(out, "</html>\n");
fclose(out);
}
void genareaknowledge(flagpile_t *fp, int chancemod) {
@ -4357,7 +4403,7 @@ void dumpxp(void) {
// dump
dblog("%-10s%-30s%s","XP", "Race", "Rarity");
for (i = 0; i < xplistlen; i++) {
dblog("%-10d%-30s%d",xpposs[i], raceposs[i]->name,getracerarity(NULL, raceposs[i]->id, NULL));
dblog("%-10d%-30s%d",xpposs[i], raceposs[i]->name,getracerarity(H_ALL, raceposs[i]->id, NULL));
}
// free mem
@ -5703,6 +5749,11 @@ void enhanceskills(lifeform_t *lf) {
wantschool = f->val[1];
nleft = f->val[2];
// adjust by intelligence
nleft += getextraspellchoices(lf);
limit(&nleft, 1, NA);
// get all possible spells to learn, from the given school
sprintf(qbuf, "Learn which new spell (maxmp=%d):", getmaxmp(player));
makespellchoicelist(&prompt, player, qbuf, "Describe which spell:", f->val[1], B_TRUE, B_FALSE, B_FALSE, player->maxmp);
@ -5858,19 +5909,32 @@ void enhanceskills(lifeform_t *lf) {
slev = getskill(lf, SK_SS_MENTAL);
if (pctchance(slev*20)) {
char qbuf[BUFLEN];
int pickfrom;
sprintf(qbuf, "Learn which psionic power (maxmp=%d):", getmaxmp(player));
// construct list of castable mental spells
makespellchoicelist(&prompt, lf, qbuf, "Describe which psionic power:", SS_MENTAL, B_TRUE, B_FALSE, B_FALSE, player->maxmp);
if (prompt.nchoices > 0) {
objecttype_t *ot;
msg("Your brain has unlocked a new psionic power!"); more();
getchoicestr(&prompt, B_TRUE, B_TRUE);
ot = prompt.result;
if (ot) {
if (prompt.whichq == 0) { // learn the spell
addflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL);
} else {
describespell(ot);
// randomly remove choices down to (IQ/10)
pickfrom = getattr(lf, A_IQ)/10;
if (pickfrom > 0) {
while (prompt.nchoices > pickfrom) {
int sel;
sel = rnd(0,prompt.nchoices-1);
killchoice(&prompt, sel);
}
if (prompt.nchoices > 0) {
objecttype_t *ot;
msg("Your brain has unlocked a new psionic power!"); more();
getchoicestr(&prompt, B_TRUE, B_TRUE);
ot = prompt.result;
if (ot) {
if (prompt.whichq == 0) { // learn the spell
addflag(lf->flags, F_CANCAST, ot->id, NA, NA, NULL);
} else {
describespell(ot);
}
}
}
}
@ -5888,13 +5952,35 @@ void enhanceskills(lifeform_t *lf) {
} // end if gainedxplev
}
// returns B_TRUE if we were already enraged.
int enrage(lifeform_t *lf, int howlong) {
if (lfhasflag(lf, F_RAGE)) return B_TRUE;
flag_t *retflag[MAXCANDIDATES],*f;
int nretflags = 0,i;
int alreadyraging = B_FALSE;
// already enraged?
getflags(lf->flags, retflag, &nretflags, F_RAGE, F_AICONTROLLED, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (f->lifetime > 0) {
if (f->id == F_RAGE) {
f->lifetime = howlong;
alreadyraging = B_TRUE;
} else if ((f->id == F_AICONTROLLED) && (f->val[2] == F_RAGE)) {
if (isplayer(lf)) {
f->lifetime = howlong;
alreadyraging = B_TRUE;
}
}
}
}
if (alreadyraging) return B_TRUE;
addtempflag(lf->flags, F_RAGE, NA, NA, NA, NULL, howlong);
if (isplayer(lf)) {
addtempflag(lf->flags, F_AICONTROLLED, B_TRUE, NA, NA, NULL, howlong);
addtempflag(lf->flags, F_AICONTROLLED, B_TRUE, NA, F_RAGE, NULL, howlong);
} else {
loseaitargets(lf);
}
@ -8197,6 +8283,26 @@ int getexposedlimbs(lifeform_t *lf) {
return exposedlimbs;
}
// how many extra spells does this lf get to choose from?
// based on iq.
int getextraspellchoices(lifeform_t *lf) {
int mod = 0;
enum ATTRBRACKET iqb;
iqb = getattrbracket(getattr(lf, A_IQ), A_IQ, NULL);
switch (iqb) {
case AT_EXLOW: mod -= 3; break;
case AT_VLOW: mod -= 2; break;
case AT_LOW: mod -= 1; break;
case AT_LTAVERAGE: mod -= 1; break;
case AT_GTAVERAGE: mod += 1; break;
case AT_HIGH: mod += 1; break;
case AT_VHIGH: mod += 2; break;
case AT_EXHIGH: mod += 3; break;
default: break;
}
return mod;
}
object_t *getfirearm(lifeform_t *lf) {
object_t *o;
o = getequippedob(lf->pack, BP_SECWEAPON);
@ -9346,7 +9452,7 @@ glyph_t *getlfglyph(lifeform_t *lf) {
}
enum MATERIAL getlfmaterial(lifeform_t *lf) {
if (lf->race->id == R_DANCINGWEAPON) {
if (lf->race->baseid == R_DANCINGWEAPON) {
object_t *wep;
wep = getweapon(lf);
if (wep) {
@ -9953,7 +10059,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall,
if (usevis && !cansee(usevis, lf) && !showall) {
snprintf(buf, BUFLEN, "something");
} else {
if (lf->race->id == R_DANCINGWEAPON) {
if (lf->race->baseid == R_DANCINGWEAPON) {
object_t *wep;
wep = getweapon(lf);
if (wep) {
@ -10289,18 +10395,23 @@ enum RACECLASS getraceclass(lifeform_t *lf) {
}
// returns rarity number. if optional rr is passed, this is will be returned too.
int getracerarity(map_t *map, enum RACE rid, enum RARITY *rr) {
// if 'hab' isn't H_ALL, get rarity for this habitat.
int getracerarity(enum HABITAT hab, enum RACE rid, enum RARITY *rr) {
race_t *r;
int rarity = -1;
if (rr) *rr = RR_NONE;
// default
if (rr) *rr = RR_NEVER;
r = findrace(rid);
if (r) {
flag_t *f = NULL;
if (map) {
f = hasflagval(r->flags, F_RARITY, map->habitat->id, NA, NA, NULL);
if (hasflag(r->flags, F_UNIQUE)) {
if (rr) *rr = RR_UNIQUE;
}
if (hab != H_ALL) {
f = hasflagval(r->flags, F_RARITY, hab, NA, NA, NULL);
if (!f) {
f = hasflagval(r->flags, F_RARITY, H_ALL, NA, NA, NULL);
}
@ -12544,6 +12655,15 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
o = addob(lf->pack, "map to the goblin caves");
assert(o);
}
// special case!
if (lf->race->baseid == R_DANCINGWEAPON) {
// link up the weapon object
o = hasobofclass(lf->pack, OC_WEAPON);
assert(o);
obtodancing(lf, o);
}
// make sure lf doesn't start off burdened!
while (isburdened(lf)) {
@ -14335,13 +14455,16 @@ int isgod(lifeform_t *lf) {
}
int ishelplessvictim(lifeform_t *victim, lifeform_t *attacker, enum HELPLESSTYPE *how) {
if (isundead(victim)) return B_FALSE;
if (!cansee(attacker, victim)) return B_FALSE;
if (isfleeing(victim)) {
if (how) *how = HL_FLEEING;
return B_TRUE;
} else if (!cansee(victim, attacker) && (getraceclass(victim) != RC_PLANT)) {
if (how) *how = HL_CANTSEE;
return B_TRUE;
if (gettargetlf(victim) != attacker) {
if (how) *how = HL_CANTSEE;
return B_TRUE;
}
}
if (how) *how = HL_NONE;
return B_FALSE;
@ -15434,6 +15557,12 @@ void applylfdammod(int *dam, lifeform_t *lf, object_t *wep) {
*dam = *dam + getstrdammod(lf);
}
// modify for generic f_extradam
getflags(lf->flags, retflag, &nretflags, F_WOUNDING, F_NONE);
for (i = 0; i < nretflags; i++) {
*dam += retflag[i]->val[0];
}
// strength scaling on weapon
getflags(wep->flags, retflag, &nretflags, F_ATTREQ, F_NONE);
for (i = 0; i < nretflags; i++) {
@ -15520,10 +15649,10 @@ int areallies(lifeform_t *lf1, lifeform_t *lf2) {
}
}
} else {
if (lf1->race->baseid == lf2->race->baseid) {
if (!isplayer(lf1) && !isplayer(lf2)) {
return B_TRUE;
}
if ((lf1->race->baseid == lf2->race->baseid) && // same base race
!isplayer(lf1) && !isplayer(lf2) && // not the player
(master1 == -1) && (master2 == -1)) { // not charmed/zombies/etc
return B_TRUE;
}
}
return B_FALSE;
@ -17841,17 +17970,20 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
difficulty = (int) ( ((float) dist / ((float)gethearingrange(l) + volume)) * 75);
}
/*
if (sleepflag) {
myvol = volume - 1;
} else {
myvol = volume;
}
limit(&myvol, 0, NA);
*/
myvol = volume;
// listen bonus is based on sound volume
lbonus = myvol;
lbonus = (myvol*5);
if (sleepflag) {
lbonus -= 5;
lbonus -= 25;
limit(&lbonus, 0, NA);
}
@ -22211,7 +22343,7 @@ void startlfturn(lifeform_t *lf) {
cell_t *c;
c = getcellindir(lf->cell, diropposite(lf->facing));
if (c && c->lf) {
if (isplayer(lf)) {
if (isplayer(lf) && !lfhasflag(lf, F_RAGE)) {
warn("^WYour tail brushes up against something behind you!");
} else {
turntoface(lf, c);
@ -22296,16 +22428,18 @@ void startlfturn(lifeform_t *lf) {
// special effects
if (lf->race->id == R_ASHKARI) {
if ((lf->race->id == R_ASHKARI) && !lfhasflag(lf, F_CONTROL)) {
lifeform_t *otherlf;
for (i = 1; i < lf->nlos; i++) {
otherlf = lf->los[i]->lf;
if (otherlf) {
if (lfhasflag(otherlf, F_CANINE) || lfhasflag(otherlf, F_AVIAN)) {
f = lfhasflag(lf, F_RAGE);
if (f && f->lifetime > 0) {
f->lifetime = DEF_RAGETIME/2;
if (f && (f->lifetime > 0)) {
// already enraged? just extend time.
enrage(lf, DEF_RAGETIME/2);
} else {
// announce, them make enraged.
if (isplayer(lf)) {
char lfname[BUFLEN];
getlfname(otherlf, lfname);
@ -22872,20 +23006,22 @@ void startlfturn(lifeform_t *lf) {
}
}
f = hasflag(lf->flags, F_NAUSEATED);
if (f) {
// chance of being delayed
if (onein(4)) {
if (isplayer(lf)) {
msg("^bYou %s!", rnd(0,1) ? "retch" : "gag");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%c%s %s.", getlfcol(lf, CC_BAD), lfname, rnd(0,1) ? "retches" : "gags");
}
taketime(lf,getactspeed(lf));
if (!isunconscious(lf) && !isasleep(lf)) {
f = hasflag(lf->flags, F_NAUSEATED);
if (f) {
// chance of being delayed
if (onein(4)) {
if (isplayer(lf)) {
msg("^bYou %s!", rnd(0,1) ? "retch" : "gag");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%c%s %s.", getlfcol(lf, CC_BAD), lfname, rnd(0,1) ? "retches" : "gags");
}
taketime(lf,getactspeed(lf));
loseconcentration(lf);
loseconcentration(lf);
}
}
}
} // end if !statis
@ -26380,7 +26516,7 @@ int weild(lifeform_t *lf, object_t *o) {
// if we asked to just unweild our weapon, exit now
// with no error.
if (!o) {
if ((gamemode == GM_GAMESTARTED) && lf->created && (lf->race->id != R_DANCINGWEAPON)) {
if ((gamemode == GM_GAMESTARTED) && lf->created && (lf->race->baseid != R_DANCINGWEAPON)) {
if (isplayer(lf)) {
msg("You are now fighting unarmed.");
} else if (cansee(player, lf)) {
@ -26406,7 +26542,7 @@ int weild(lifeform_t *lf, object_t *o) {
if (isplayer(lf) && isweapon(o)) maketried(o->type->id, NULL);
if ((gamemode == GM_GAMESTARTED) && lf->created && (lf->race->id != R_DANCINGWEAPON)) {
if ((gamemode == GM_GAMESTARTED) && lf->created && (lf->race->baseid != R_DANCINGWEAPON)) {
if (isplayer(lf)) {
char buf2[BUFLEN];
@ -26446,7 +26582,7 @@ int weild(lifeform_t *lf, object_t *o) {
}
}
} else if (cansee(player, lf)) {
if (lf->race->id != R_DANCINGWEAPON) {
if (lf->race->baseid != R_DANCINGWEAPON) {
char buf2[BUFLEN];
getlfname(lf, buf2);
msg("%s weilds %s.", buf2, buf);

5
lf.h
View File

@ -102,7 +102,7 @@ int digup(lifeform_t *lf, object_t *o);
//void do_eyesight_adjust(lifeform_t *lf);
void dumplev(void);
void dumplf(void);
void dumpmonsters(void);
void dumpmonsters(enum HABITAT hab);
void dumpxp(void);
int eat(lifeform_t *lf, object_t *o);
void endlfturn(lifeform_t *lf);
@ -183,6 +183,7 @@ char *getbodypartname(lifeform_t *lf, enum BODYPART bp);
char *getbodypartequipname(enum BODYPART bp);
object_t *getequippedob(obpile_t *op, enum BODYPART bp);
int getexposedlimbs(lifeform_t *lf);
int getextraspellchoices(lifeform_t *lf);
object_t *getfirearm(lifeform_t *lf);
enum LOFTYPE getfirearmloftype(lifeform_t *lf);
int getfootprinttime(lifeform_t *lf);
@ -272,7 +273,7 @@ char *getpoisonname(enum POISONTYPE ptype);
enum POISONSEVERITY getpoisonseverity(enum POISONTYPE ptype);
*/
enum RACECLASS getraceclass(lifeform_t *lf);
int getracerarity(map_t *map, enum RACE rid, enum RARITY *rr);
int getracerarity(enum HABITAT hab, enum RACE rid, enum RARITY *rr);
object_t *getrandomarmour(lifeform_t *lf, lifeform_t *attacker);
enum BEHAVIOUR getrandombehaviour(void);
enum BODYPART getrandomcorebp(lifeform_t *lf, lifeform_t *attacker);

123
map.c
View File

@ -961,11 +961,74 @@ branch_t *addbranch(enum BRANCH id, char *name, int pluralname, enum HABITAT def
return a;
}
void adjustcellglyph(cell_t *c, glyph_t *g) {
void adjustcellglyph(cell_t *c, glyph_t *g, enum CELLADJUSTTYPE how) {
if (how == CA_NONE) return;
if (g->ch == ' ') return;
if (c->type->altcol != C_NONE) {
if ((c->x + c->y) % 2) g->colour = c->type->altcol;
if ((how == CA_COL) || (how == CA_BOTH)) {
if (c->type->altcol != C_NONE) {
if ((c->x + c->y) % 2) g->colour = c->type->altcol;
}
}
if ((how == CA_CH) || (how == CA_BOTH)) {
// for certain cell types, select glyph based on surrounding cells of same type
if (g->ch == UNI_DYNAMIC) {
int adj = 0,i;
cell_t *c2;
for (i = D_N; i <= D_W; i++) {
int this;
c2 = getcellindir(c,i);
//if (c2 && c2->known && ((c2->type->id == c->type->id) || hasdoor(c2)) ) {
if (c2 && c2->known && (issolid(c2) || hasdoor(c2)) ) {
this = 1;
// we want:
// N E S W
// 8 4 2 1
if (i == D_N) this <<= 3;
else if (i == D_E) this <<= 2;
else if (i == D_S) this <<= 1;
} else {
this = 0;
}
adj |= this;
}
switch (adj) {
case 1: // left
case 4: // right
case 5: // horz
g->ch = 0x2500; break;
case 2: // down
case 10: // vert
case 8: // up
g->ch = 0x2502; break;
case 3: // down left
g->ch = 0x2510; break;
case 6: // down right
g->ch = 0x250c; break;
case 7: // T down
g->ch = 0x252c; break;
case 9: // up left
g->ch = 0x2518; break;
case 11: // T left
g->ch = 0x2524; break;
case 12: // up right
g->ch = 0x2514; break;
case 13: // T up
g->ch = 0x2534; break;
case 14: // T right
g->ch = 0x251c; break;
case 15: // cross
g->ch = 0x253c; break;
default:
if (c->known) {
g->ch = c->knownglyph.ch;
} else {
g->ch = 0x2500;
}
break;
}
}
}
/*
@ -1125,12 +1188,12 @@ void breakwall(cell_t *c, char *why, ...) {
if (why) {
setcellreason(c, "%s", buf);
}
if (origtype->solid && roomwall && onein(2)) {
if (origtype->solid && roomwall && onein(10)) {
switch (origtype->material->id) {
case MT_STONE: addob(c->obpile, "1-30 stones"); break;
case MT_BRICK: addob(c->obpile, "1-30 bricks"); break;
case MT_GLASS: addob(c->obpile, "1-30 pieces of broken glass"); break;
case MT_WOOD: addob(c->obpile, "1-30 shards of wood"); break;
case MT_STONE: addob(c->obpile, "1-10 stones"); break;
case MT_BRICK: addob(c->obpile, "1-5 bricks"); break;
case MT_GLASS: addob(c->obpile, "1-10 pieces of broken glass"); break;
case MT_WOOD: addob(c->obpile, "1-10 shards of wood"); break;
default: break;
}
}
@ -2316,9 +2379,9 @@ void doorfill_r(cell_t *startcell, cell_t *c, int *nfilled) {
int fix_reachability(map_t *m) {
int i,nfixed = 0;
int db = B_TRUE;
int donesomething;
cell_t *unreachcell[MAX_MAPW*MAX_MAPH];
cell_t *reachcell[MAX_MAPW*MAX_MAPH];
int nunreach = 0,nreach = 0;
cell_t *c = NULL;
if (db) dblog("fix_reachability starting.");
@ -2342,8 +2405,11 @@ int fix_reachability(map_t *m) {
}
// no empty cells in map?
if (!c) return B_FALSE;
nunreach = 1;
while (nunreach) {
donesomething = B_TRUE;
while (donesomething) {
int nunreach = 0,nreach = 0;
donesomething = B_FALSE;
// mark all cells as non-filled
for (i = 0; i < m->w * m->h; i++) {
m->cell[i]->filled = FALSE;
@ -2384,6 +2450,7 @@ int fix_reachability(map_t *m) {
if (db) dblog(" attempting to fix unreachable area at %d,%d.",
ucell->x, ucell->y);
donesomething = B_TRUE;
// first: try to link up the two areas.
ndoors = fix_unreach_via_doors(m);
@ -2392,7 +2459,6 @@ int fix_reachability(map_t *m) {
//,maxtries = 5;
// pick one of the unreachable cells
idx = rnd(0,nunreach-1);
//while (ntries < maxtries) {
while (idx != firstidx) {
if (firstidx == -1) firstidx = idx;
ucell = unreachcell[idx];
@ -2445,7 +2511,7 @@ int fix_reachability(map_t *m) {
c = ucell;
nfixed++;
}
}
} // end while donesomething
if (nfixed) {
if (db) dblog(" fix_reachability complete. found and fixed %d unreachable areas.", nfixed);
} else {
@ -2689,7 +2755,7 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
// scanned lf here?
if (isinscanrange(c, &thing, NULL, &tempgl) == TT_MONSTER) {
*g = tempgl;
adjustcellglyph(c, g);
//adjustcellglyph(c, g); - this is only for when we can see cell floor.
//mvwprintw(gamewin, y-viewy, x-viewx, "%c", glyph);
//drawglyph(&glyph, x, y);
return;
@ -2709,13 +2775,13 @@ void getcellglyph(glyph_t *g, cell_t *c, lifeform_t *viewer) {
} else {
// objects here, but we can't see them. draw the cell.
*g = c->type->glyph;
adjustcellglyph(c, g);
adjustcellglyph(c, g, CA_BOTH);
}
} else {
// draw cell normally
//drawcell(cell, x, y);
*g = c->type->glyph;
adjustcellglyph(c, g);
adjustcellglyph(c, g, CA_BOTH);
}
} else { // can't see the cell
void *thing;
@ -5591,7 +5657,8 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
setcelltype(cell, ct ? ct->id : getcellempty(cell));
// set roomid
cell->room = thisroom;
// add objects
// add objects. NOTE: this might _unset_ cell->room
// if 'reusable' is listed.
addvaultcellcontents(cell, v, x-minx,y-miny, rotation);
}
}
@ -5636,7 +5703,10 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
for (x = minx; x <= maxx; x++) {
cell_t *c;
c = getcellat(map, x, y);
setcelllocked(c, "maintainedge vaultcell");
if (getroomid(c) == roomid) {
// ie. not marked as reusable
setcelllocked(c, "maintainedge vaultcell");
}
}
}
}
@ -8561,14 +8631,14 @@ void initmap(void) {
addcelltype(CT_WALLBRICK, "brick wall", UNI_SHADEDARK, C_BRICK, NA, B_SOLID, B_OPAQUE, MT_BRICK, 0, 40, 0, B_NOABSORB);
addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEMED, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 20, 0, B_NOABSORB);
addcelltype(CT_WALLDURANITE, "duranite wall", UNI_SHADEDARK, C_MAGENTA, NA, B_SOLID, B_OPAQUE, MT_DURANITE, 0, 20000, 0, B_NOABSORB);
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_DARKBROWN, NA, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30, 0, B_NOABSORB);
addcelltype(CT_WALLDWOOD, "wyrmwood wall", UNI_SOLID, C_DARKBROWN, NA, B_SOLID, B_OPAQUE, MT_DRAGONWOOD, 0, 100, 0, B_NOABSORB);
addcelltype(CT_WALLWOOD, "wooden wall", UNI_DYNAMIC, C_DARKBROWN, NA, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30, 0, B_NOABSORB);
addcelltype(CT_WALLDWOOD, "wyrmwood wall", UNI_DYNAMIC, C_DARKBROWN, NA, B_SOLID, B_OPAQUE, MT_DRAGONWOOD, 0, 100, 0, B_NOABSORB);
addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_FLESH, NA, B_SOLID, B_OPAQUE, MT_FLESH, 0, 25, 0, B_NOABSORB);
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, NA, B_SOLID, B_TRANS, MT_GLASS, 0, 20, 0, B_NOABSORB);
addcelltype(CT_WALLGLASS, "glass wall", UNI_DYNAMIC, C_CYAN, NA, B_SOLID, B_TRANS, MT_GLASS, 0, 20, 0, B_NOABSORB);
addcelltype(CT_WALLICE, "ice wall", UNI_SHADEDARK, C_LIGHTCYAN, NA, B_SOLID, B_TRANS, MT_ICE, 0, 30, 0, B_NOABSORB);
//addcelltype(CT_WALLTREE, "dense bushland", UNI_SHADEDARK, C_GREEN, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100);
addcelltype(CT_WALLTREE, "dense bushland", UNI_TREELOTS, C_LIGHTGREEN, NA, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100, 0, B_NOABSORB);
addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_METAL, NA, B_SOLID, B_OPAQUE, MT_METAL, 0, 75, 0, B_NOABSORB);
addcelltype(CT_WALLMETAL, "metal wall", UNI_DYNAMIC, C_METAL, NA, B_SOLID, B_OPAQUE, MT_METAL, 0, 75, 0, B_NOABSORB);
// cell types - non-solid
addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0, B_NOABSORB);
addcelltype(CT_MOSSROCK, "mossy rock floor", '.', C_MOSS, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0, B_NOABSORB);
@ -9582,7 +9652,7 @@ void markroomwalls(map_t *m, room_t *r) {
for (x = r->x1+1; x <= r->x2-1; x++) {
for (y = r->y1; y <= r->y2; y++) {
c = getcellat(m, x, y);
if (c->type->solid) {
if (c->type->solid && (getroomid(c) == r->id)) {
c2 = getcellindir(c, DC_S);
if (c2 && !c2->type->solid) {
c->isroomwall = D_N;
@ -9594,7 +9664,7 @@ void markroomwalls(map_t *m, room_t *r) {
for (y = r->y1+1; y <= r->y2-1; y++) {
for (x = r->x2; x >= r->x1; x--) {
c = getcellat(m, x, y);
if (c->type->solid) {
if (c->type->solid && (getroomid(c) == r->id)) {
c2 = getcellindir(c, DC_W);
if (c2 && !c2->type->solid) {
c->isroomwall = D_E;
@ -9606,7 +9676,7 @@ void markroomwalls(map_t *m, room_t *r) {
for (x = r->x1+1; x <= r->x2-1; x++) {
for (y = r->y2; y >= r->y1; y--) {
c = getcellat(m, x, y);
if (c->type->solid) {
if (c->type->solid && (getroomid(c) == r->id)) {
c2 = getcellindir(c, DC_N);
if (c2 && !c2->type->solid) {
c->isroomwall = D_S;
@ -9618,7 +9688,7 @@ void markroomwalls(map_t *m, room_t *r) {
for (y = r->y1+1; y <= r->y2-1; y++) {
for (x = r->x1; x <= r->x2; x++) {
c = getcellat(m, x, y);
if (c->type->solid) {
if (c->type->solid && (getroomid(c) == r->id)) {
c2 = getcellindir(c, DC_E);
if (c2 && !c2->type->solid) {
c->isroomwall = D_W;
@ -10133,6 +10203,7 @@ void setcellknown(cell_t *cell, int forcelev) {
} else {
cell->knownglyph = cell->type->glyph;
}
adjustcellglyph(cell, &(cell->knownglyph), CA_CH);
// high cartography skill lets us remember certain objects...
if (slev >= PR_EXPERT) {

2
map.h
View File

@ -11,7 +11,7 @@ region_t *addregion(enum BRANCH rtype, region_t *parent, int outlineid, int dept
regionoutline_t *addregionoutline(enum BRANCH rtype);
regionthing_t *addregionthing(regionoutline_t *ro, int depth, int x, int y, enum REGIONTHING whatkind, int value, char *what);
branch_t *addbranch(enum BRANCH id, char *name, int pluralname, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major, int depthmod, int addparentdepth);
void adjustcellglyph(cell_t *c, glyph_t *col);
void adjustcellglyph(cell_t *c, glyph_t *g, enum CELLADJUSTTYPE how);
int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int doorpct, int dooropenchance);
void breakwall(cell_t *c, char *why, ...);
int cellhaslos(cell_t *c1, cell_t *dest);

6
move.c
View File

@ -1720,9 +1720,13 @@ int movelf(lifeform_t *lf, cell_t *newcell, int onpurpose) {
if (isadjacent(lf->cell, precell)) { // ie don't say this if we teleported/jumped
if (areenemies(player, lf)) {
char buf[BUFLEN];
int behind = B_FALSE;
getmoveverbother(lf, buf);
real_getlfnamea(lf, lfname, NULL, B_NOSHOWALL, B_CURRACE);
msg("%s %s out of view.", lfname, buf);
if (isbehind(lf, player) && isadjacent(lf->cell, player->cell)) {
behind = B_TRUE;
}
msg("%s %s %s.", lfname, buf, behind ? "behind you" : "out of view");
}
}
}

139
objects.c
View File

@ -412,7 +412,7 @@ material_t *addmaterial(enum MATERIAL id, char *name, float weightrating) {
return a;
}
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph, int glyphcolour, enum RARITY rarity) {
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, int glyph, int glyphcolour, enum RARITY rarity) {
objectclass_t *a;
// add to the end of the list
@ -505,6 +505,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
enum LFSIZE wantarmsize = SZ_ANY;
enum MATERIAL wantdiffmat = MT_NOTHING;
int minar = 0; // minimum AR for armour
int mindr = NA,maxdr = NA; // minimum DR for weapons
map_t *targetmap = NULL; // for portals
cell_t *targetcell = NULL; // for portals
int donesomething;
@ -525,10 +526,6 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
nadded = 0;
nretobs = 0;
if ((gamemode == GM_GAMESTARTED) && where->where) {
assert(!where->where->type->solid);
}
if (where->owner && hasflag(where->owner->flags, F_NOPACK)) {
if (db) dblog("error giving ob '%s' - owner isn't allowed to carry objects!", name);
nretobs = 0;
@ -895,12 +892,14 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
wantgoodness = G_AVERAGE;
p += strlen("average ");
donesomething = B_TRUE;
mindr = 3; maxdr = 5;
} else if (strstarts(p, "good ")) {
wantgoodness = G_GOOD;
if (onein(4)) wantblessed = B_BLESSED;
p += strlen("good ");
donesomething = B_TRUE;
limit(&minar, 1, NA);
mindr = 6; maxdr = 8;
} else if (strstarts(p, "great ")) {
wantgoodness = G_GREAT;
if (onein(3)) wantblessed = B_BLESSED;
@ -908,6 +907,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
p += strlen("great ");
limit(&minar, 2, NA);
donesomething = B_TRUE;
mindr = 9; maxdr = 11;
} else if (strstarts(p, "excellent ")) {
wantgoodness = G_EXCELLENT;
if (onein(2)) wantblessed = B_BLESSED;
@ -915,6 +915,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
p += strlen("excellent ");
limit(&minar, 3, NA);
donesomething = B_TRUE;
mindr = 12; maxdr = NA;
// object names
// brands
} else if (strstarts(p, "branded ")) {
@ -1123,7 +1124,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
limit(&minar, 1, NA);
}
ot = getrandomobofclass(oc->id, minrarity, maxrarity, matchlfskills, minar, musthaveflag);
ot = getrandomobofclass(oc->id, minrarity, maxrarity, matchlfskills, minar, mindr, maxdr, musthaveflag);
if (ot) {
found = B_TRUE;
break;
@ -1139,7 +1140,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
// want a specific rarity?
rrtorarity(wantrarity, &minrarity, &maxrarity);
ot = getrandomobofclass(OC_ROCK, minrarity, maxrarity, NULL, B_FALSE, F_GEM);
ot = getrandomobofclass(OC_ROCK, minrarity, maxrarity, NULL, B_FALSE, NA, NA, F_GEM);
if (ot) {
found = B_TRUE;
}
@ -1153,6 +1154,19 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
found = B_TRUE;
}
}
if (strstarts(p, "random impassable")) {
char buf[BUFLEN];
cell_t *cc;
cc = getobpilelocation(where);
// really want: impassable and not a dfeature
ot = getrandomobwithflag(cc->map, F_IMPASSABLE, buf);
while (ot->obclass->id == OC_DFEATURE) {
ot = getrandomobwithflag(cc->map, F_IMPASSABLE, buf);
}
if (ot) {
found = B_TRUE;
}
}
}
if (!found) {
@ -1170,6 +1184,18 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
}
if (db) dblog("DB: FOUND: ot->name = '%s'", ot->name );
// trying to place object on a solid cell?
if ((gamemode == GM_GAMESTARTED) && where->where) {
if (where->where->type->solid) {
// doors are okay - clear the solid cell first.
if (hasflag(ot->flags, F_DOOR)) {
setcelltype(where->where, getcellempty(where->where));
} else {
assert("BUG: trying to put object on solid cell." == 0);
}
}
}
// check for specific brands. eg. "xxx of pyromania"
// NOTE: this will override any random brands from "branded"
for (br = firstbrand ; br ; br = br->next) {
@ -1616,7 +1642,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
getrarityrange(where->where->map->depth, &min, &max, RARITYVARIANCEOB, B_FALSE);
// random potion type
ot = getrandomobofclass(OC_POTION, min, max, NULL, B_FALSE, F_NONE);
ot = getrandomobofclass(OC_POTION, min, max, NULL, B_FALSE, NA, NA, F_NONE);
if (ot) {
f->val[0] = ot->id;
}
@ -4913,7 +4939,7 @@ int getrandomgrimoirelev(void) {
return wantlev;
}
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf, int minar, enum FLAG musthaveflag) {
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf, int minar, int mindr, int maxdr, enum FLAG musthaveflag) {
objecttype_t *ot;
int totcount = 0, count = 0;
flag_t *f;
@ -4932,6 +4958,7 @@ objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity
int rarityok = B_FALSE;
int skillok = B_FALSE;
int armourok = B_FALSE;
int wepok = B_FALSE;
int flagok = B_FALSE;
// does rarity match?
f = hasflag(ot->flags, F_RARITY);
@ -4957,18 +4984,37 @@ objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity
if (minar && (ocid == OC_ARMOUR)) {
flag_t *f;
f = hasflag(ot->flags, F_ARMOURRATING);
if (f && (f->val[0] > 0)) {
if (f && (f->val[0] >= minar )) {
armourok = B_TRUE;
}
} else armourok = B_TRUE;
// min/max dr only applies if we're asking for weapons
if (((mindr != NA) || (maxdr != NA)) && (ocid == OC_WEAPON)) {
flag_t *f;
f = hasflag(ot->flags, F_DAM);
if (f) {
int minok = B_FALSE,maxok = B_FALSE;
if ((mindr == NA) || (f->val[1] >= mindr)) {
minok = B_TRUE;
}
if ((maxdr == NA) || (f->val[1] <= maxdr)) {
maxok = B_TRUE;
}
if (minok && maxok) {
wepok = B_TRUE;
}
}
} else wepok = B_TRUE;
if (musthaveflag != F_NONE) {
if (hasflag(ot->flags, musthaveflag)) {
flagok = B_TRUE;
}
} else flagok = B_TRUE;
if (skillok && rarityok && armourok && flagok) {
if (skillok && rarityok && armourok && wepok && flagok) {
poss[nposs++] = ot;
count++;
}
@ -5748,7 +5794,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
// monster lorelevel of beginner or higher - you get "newt footprints"
lorelev = getlorelevel(player, r->raceclass->id);
if ( lorelev >= PR_BEGINNER) {
if (( lorelev >= PR_BEGINNER) && !hasflag(r->flags, F_NAME)) {
snprintf(buf, BUFLEN, "%s %s",r->name, o->type->name);
strcat(basename, buf);
} else if (lorelev >= PR_NOVICE) {
@ -8594,10 +8640,41 @@ int knockbackob(object_t *o, int dir, int howfar, int power, lifeform_t *pusher)
return B_FALSE;
}
void obtodancing(lifeform_t *newlf, object_t *o) {
flag_t *f;
if (o->pile != newlf->pack) {
o = relinkob(o, newlf->pack);
}
if (!isequipped(o)) {
weild(newlf, o);
}
f = hasflag(o->flags, F_OBHP);
if (f) {
newlf->maxhp = f->val[1];
newlf->hp = newlf->maxhp;
}
f = hasflag(o->flags, F_SIZE);
if (f) {
flag_t *f2;
f2 = lfhasflag(newlf, F_SIZE);
if (f2) f2->val[0] = f->val[0];
else addflag(newlf->flags, F_SIZE, f->val[0], NA, NA, NULL);
}
f = hasflag(o->flags, F_OBATTACKDELAY);
if (f) {
int origspeed;
int newspeed;
origspeed = getmovespeed(newlf);
killflagsofid(newlf->flags, F_MOVESPEED);
newspeed = (int)((float)origspeed * ((float)f->val[0] / 100.0));
addflag(newlf->flags, F_MOVESPEED, newspeed, NA, NA, NULL);
}
}
// animate a weapon
lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level) {
cell_t *where;
flag_t *f;
lifeform_t *newlf;
where = getrandomadjcell(lf->cell, &ccwalkable, B_NOEXPAND);
@ -8605,38 +8682,16 @@ lifeform_t *makeanimated(lifeform_t *lf, object_t *o, int level) {
newlf = addlf(where, R_DANCINGWEAPON, level);
if (newlf) {
// remove existing weapon.
killallobs(newlf->pack);
if (isplayer(lf)) {
addflag(newlf->flags, F_FRIENDLY, B_TRUE, NA, NA, NULL);
} else if (hasflag(lf->flags, F_HOSTILE)) {
addflag(newlf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
}
addflag(lf->flags, F_NODEATHANNOUNCE, B_TRUE, NA, NA, NULL);
o = relinkob(o, newlf->pack);
weild(newlf, o);
f = hasflag(o->flags, F_OBHP);
if (f) {
newlf->maxhp = f->val[1];
newlf->hp = newlf->maxhp;
}
f = hasflag(o->flags, F_SIZE);
if (f) {
flag_t *f2;
f2 = lfhasflag(newlf, F_SIZE);
if (f2) f2->val[0] = f->val[0];
else addflag(lf->flags, F_SIZE, f->val[0], NA, NA, NULL);
}
f = hasflag(o->flags, F_OBATTACKDELAY);
if (f) {
int origspeed;
int newspeed;
origspeed = getmovespeed(newlf);
killflagsofid(newlf->flags, F_MOVESPEED);
newspeed = (int)((float)origspeed * ((float)f->val[0] / 100.0));
addflag(newlf->flags, F_MOVESPEED, newspeed, NA, NA, NULL);
}
obtodancing(newlf, o);
}
if (newlf) {
petify(newlf, lf);
@ -11917,7 +11972,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
addtempflag(lf->flags, F_BLIND, B_TRUE, NA, NA, NULL, i);
break;
case OT_POT_CANINETRACKING:
dospelleffects(lf, OT_S_CANINETRACKING, 5, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL);
dospelleffects(lf, OT_S_CANINETRACKING, 8, lf, NULL, lf->cell, potblessed, seen, B_TRUE, NULL);
break;
case OT_POT_COFFEE:
if (isplayer(lf)) {
@ -15976,7 +16031,9 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c, object_t *trapped
msg("A needle shoots out and hits %s!",lfname);
}
}
if (!avoided) {
if (avoided) {
addob(c->obpile, "poisoned needle");
} else {
poison(lf, rnd(10,20), P_VENOM, 1, "a needle trap", R_NONE, B_TRUE);
}
} else {

View File

@ -7,7 +7,7 @@ object_t *addemptyob(obpile_t *where, object_t *o);
hiddenname_t *addhiddenname(enum OBCLASS obclass, char *text);
knowledge_t *addknowledge(enum OBCLASS id, char *hiddenname, int known);
material_t *addmaterial(enum MATERIAL id, char *name, float weightrating);
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, char glyph, int glyphcolour, enum RARITY rarity);
objectclass_t *addoc(enum OBCLASS id, char *name, char *desc, int glyph, int glyphcolour, enum RARITY rarity);
void addocnoun(objectclass_t *oc, char *text);
object_t *addob(obpile_t *where, char *name);
object_t *addobfast(obpile_t *where, enum OBTYPE oid);
@ -110,7 +110,7 @@ object_t *getrandomammo(lifeform_t *lf);
objecttype_t *getrandomammofor(object_t *o, int usebasic);
brand_t *getrandombrandfor(objecttype_t *ot);
int getrandomgrimoirelev(void);
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf, int minar, enum FLAG musthaveflag);
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf, int minar, int mindr, int maxdr, enum FLAG musthaveflag);
enum OBTYPE getrandomtrapforob(object_t *o);
int getrustdampct(object_t *o);
int getfirearmrange(object_t *o);
@ -272,6 +272,7 @@ int obpropsmatch(object_t *a, object_t *b);
int obotpropsmatch(object_t *a, objecttype_t *b);
flag_t *obrestrictsmovement(object_t *o, lifeform_t *lf);
int obsfallthrough(cell_t *c, object_t *pit);
void obtodancing(lifeform_t *newlf, object_t *o);
int operate(lifeform_t *lf, object_t *o, cell_t *where);
enum RARITY pickrr(int whatfor);
int pilehasletter(obpile_t *op, char let);

26
spell.c
View File

@ -2367,10 +2367,10 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
switch (user->race->id) {
default:
case R_STIRGE:
satedat = 8;
satedat = 6;
break;
case R_LEECH:
satedat = 12;
satedat = 8;
break;
}
@ -4999,13 +4999,20 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
donemsg = B_TRUE;
}
o = retob[i];
// undo temperature effects from adding the ob
affect_temperature(o, B_REMOVE);
// replace the TEMPMOD flag.
killflagsofid(o->flags, F_TEMPMOD);
addflag(o->flags, F_TEMPMOD, tempmod, NA, NA, NULL);
// now re-apply temperature effects
affect_temperature(o, B_ADD);
f = hasflag(o->flags, F_OBHP);
if (f) {
f->val[1] = 40;
f->val[0] = f->val[1];
}
affect_temperature(o, B_ADD);
}
} else {
fizzle(caster);
@ -5736,7 +5743,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE;
}
for (i = 0; i < power; i++) {
ot = getrandomobofclass(OC_FOOD, NA, NA, NULL, B_FALSE, F_NONE);
ot = getrandomobofclass(OC_FOOD, NA, NA, NULL, B_FALSE, NA, NA, F_NONE);
o = addobfast(targcell->obpile, ot->id);
if (i == 0) {
getobname(o, obname, o->amt);
@ -5817,6 +5824,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else {
clearcell(c);
setcelltype(c, c->map->habitat->solidcelltype);
c->locked = B_FALSE;
}
}
}
@ -5826,18 +5834,20 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
vault_t *v;
int vx,vy;
int vw,vh;
int newroomid;
// ask for a vaulttype
v = askvault("Create which vault?");
if (createvault(caster->cell->map, caster->cell->map->nrooms, v, &vw, &vh, &vx, &vy)) {
newroomid = caster->cell->map->nrooms;
if (createvault(caster->cell->map, newroomid, v, &vw, &vh, &vx, &vy)) {
msg("Couldn't create a vault.");
} else {
char ch;
cell_t *c;
// link the new vault to the rest of the map
c = getcellat(caster->cell->map, vx, vy);
linkexits(caster->cell->map, getroomid(c));
//c = getcellat(caster->cell->map, vx, vy);
linkexits(caster->cell->map, newroomid);
msg("BAM! A vault has appeared nearby."); more();
needredraw = B_TRUE;
@ -11126,7 +11136,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (cansee(player, target)) {
char targname[BUFLEN];
getlfname(target, targname);
msg("%s looks very lethargic!", getlfcol(target, CC_BAD), targname);
msg("^%c%s looks very lethargic!", getlfcol(target, CC_BAD), targname);
}
modstamina(target, -amttolose);
} else if (spellid == OT_S_REFRACTION) {

2
text.c
View File

@ -316,7 +316,7 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
strcpy(buf, attackername);
capitalise(buf);
if (wep && !isunarmed && (lf->race->id != R_DANCINGWEAPON) && cansee(player, lf)) {
if (wep && !isunarmed && (lf->race->baseid != R_DANCINGWEAPON) && cansee(player, lf)) {
snprintf(withwep, BUFLEN, " with %s", wepname);
} else {
strcpy(withwep, "");

17
vault.c
View File

@ -360,11 +360,12 @@ void addvaultcontents(map_t *m, vault_t *v, int minx, int miny, int maxx, int ma
}
}
// set vault id for each cell
// set vault id for each cell (except for ones which were
// previously marked as reusable via RT_REUSABLE)
for (y = miny; y <= maxy; y++) {
for (x = minx; x <= maxx; x++) {
c = getcellat(m, x, y);
if (c) {
if (c && c->room) {
c->room->vault = v;
}
}
@ -381,6 +382,11 @@ int addvaultthing(cell_t *c, vault_t *v, enum VAULTTHING vt, char *what) {
// mark this position as a room exit
addflag(c->map->flags, F_ROOMEXIT, getroomid(c), c->x, c->y, "from addvaultthing");
break;
case VT_REUSABLE:
// this cell doesn't count as part of the room/vault
c->room = NULL;
c->locked = B_FALSE;
break;
case VT_OB:
if (streq(what, "random")) {
o = addrandomob(c);
@ -972,10 +978,13 @@ int handleline(vault_t *v, char *line) {
ok = B_TRUE;
}
}
} else { // special legend...
} else { // special legend types...
if (streq(arg[0], "exit")) {
addlegend(v, command[0], VT_EXIT, 100, "", VT_NONE, NULL);
ok = B_TRUE;
} else if (streq(arg[0], "reusable")) {
addlegend(v, command[0], VT_REUSABLE, 100, "", VT_NONE, NULL);
ok = B_TRUE;
} else {
dblog("invalid syntax for legend value");
}
@ -1810,7 +1819,7 @@ int real_vaultthingok(enum VAULTTHING vt, char *what, int *hasfire) {
ct = findcelltypebyname(what);
if (ct) return B_TRUE;
break;
default:
default: // ie. exit, reusable
return B_TRUE;
break;
}