- [+] object descriptions giving away obmods! fixed.

- [+] change lf summoning to better control hostility
- [+] gods should be able to see invisible
- [+] travel spell to quickly get around branches
- [+] treant / ent = green T
    - [+] old/normal/young
    - [+] older = slower
    - [+] elder can cast 'animate tree' ?
- [+] bug: when you offer a godstone to a god outside of realm of gods,
      they are saying "no" but still taking it.
- [+] gods should yell out a warning when you walk over a new godstone
    - [+] this lets the player know that picking it up will anger that
          god.
    - [+] then add f_donewarning to it.
This commit is contained in:
Rob Pearce 2012-03-22 23:17:28 +00:00
parent 653b5ac864
commit 672e26a81c
28 changed files with 552 additions and 103 deletions

49
ai.c
View File

@ -500,6 +500,33 @@ int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim
} }
if (spelllf) *spelllf = NULL; if (spelllf) *spelllf = NULL;
if (spellob) *spellob = NULL; if (spellob) *spellob = NULL;
} else if ((spelltype->id == OT_S_ANIMATESTATUE) || (spelltype->id == OT_S_ANIMATETREE)) {
cell_t *cell[MAXCANDIDATES],*poss[MAXCANDIDATES];
int ncells,i,nposs = 0;
enum OBTYPE oid;
if (spelltype->id == OT_S_ANIMATESTATUE) {
oid = OT_STATUE;
} else {
oid = OT_TREE;
}
if (spelllf) *spelllf = NULL;
if (spellob) *spellob = NULL;
// adjacent cell with a tree?
getradiuscells(lf->cell, 1, DT_COMPASS, B_TRUE, LOF_DONTNEED, B_FALSE, cell, &ncells, 0);
for (i = 0; i < ncells; i++) {
if (hasob(cell[i]->obpile, oid)) {
poss[nposs++] = cell[i];
}
}
if (!nposs) {
if (spellcell) spellcell = NULL;
return B_TRUE;
}
if (spellcell) {
*spellcell = poss[rnd(0,nposs-1)];
}
} else if (spelltype->id == OT_A_JUMP) { } else if (spelltype->id == OT_A_JUMP) {
cell_t *cell[MAXCANDIDATES],*c; cell_t *cell[MAXCANDIDATES],*c;
cell_t *poss[MAXCANDIDATES]; cell_t *poss[MAXCANDIDATES];
@ -2304,6 +2331,28 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
} }
} }
} }
} else if (ot->id == OT_S_ANIMATESTATUE) {
cell_t *cell[MAXCANDIDATES];
int ncells,i;
// adjacent cell with a tree?
getradiuscells(lf->cell, 1, DT_COMPASS, B_TRUE, LOF_DONTNEED, B_FALSE, cell, &ncells, 0);
for (i = 0; i < ncells; i++) {
if (hasob(cell[i]->obpile, OT_STATUE)) {
ok = B_TRUE;
break;
}
}
} else if (ot->id == OT_S_ANIMATETREE) {
cell_t *cell[MAXCANDIDATES];
int ncells,i;
// adjacent cell with a tree?
getradiuscells(lf->cell, 1, DT_COMPASS, B_TRUE, LOF_DONTNEED, B_FALSE, cell, &ncells, 0);
for (i = 0; i < ncells; i++) {
if (hasob(cell[i]->obpile, OT_TREE)) {
ok = B_TRUE;
break;
}
}
} else if (ot->id == OT_S_DIG) { } else if (ot->id == OT_S_DIG) {
cell_t *cell[MAXCANDIDATES]; cell_t *cell[MAXCANDIDATES];
int ncells,i; int ncells,i;

View File

@ -225,8 +225,8 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
real_warnabout(TEXT_WARN_NOXP_GOODVSPEACEFUL, PERMENANT, B_FALSE); real_warnabout(TEXT_WARN_NOXP_GOODVSPEACEFUL, PERMENANT, B_FALSE);
} }
} }
// above average wisdom will prvent you from annoying your god // average wisdom will prvent you from annoying your god
if (getattrbracket(getattr(lf, A_WIS), A_WIS, NULL) >= AT_GTAVERAGE) { if (getattrbracket(getattr(lf, A_WIS), A_WIS, NULL) >= AT_AVERAGE) {
enum HELPLESSTYPE how; enum HELPLESSTYPE how;
if (ishelplessvictim(c->lf, lf, &how)) { if (ishelplessvictim(c->lf, lf, &how)) {
int dowarning = B_FALSE; int dowarning = B_FALSE;
@ -255,8 +255,8 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
} }
} }
} }
// high wisdom will prevent you from starting fires // above average wisdom will prevent you from starting fires
if (getattrbracket(getattr(lf, A_WIS), A_WIS, NULL) >= AT_HIGH) { if (getattrbracket(getattr(lf, A_WIS), A_WIS, NULL) >= AT_GTAVERAGE) {
if (hasflag(c->type->material->flags, F_FLAMMABLE)) { if (hasflag(c->type->material->flags, F_FLAMMABLE)) {
if (getlorelevel(player, c->lf->race->raceclass->id) >= PR_BEGINNER) { if (getlorelevel(player, c->lf->race->raceclass->id) >= PR_BEGINNER) {
if (c->lf->race->id == R_FIREBUG) { if (c->lf->race->id == R_FIREBUG) {

171
data.c
View File

@ -1433,6 +1433,7 @@ void initobjects(void) {
addflag(lastobjectclass->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastobjectclass->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastobjectclass->flags, F_OPERWITHOUTID, B_TRUE, NA, NA, NULL); addflag(lastobjectclass->flags, F_OPERWITHOUTID, B_TRUE, NA, NA, NULL);
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastobjectclass->flags, F_GODSTONE, B_TRUE, NA, B_TRUE, NULL);
addoc(OC_CORPSE, "Corpses", "Dead flesh which was once living.", '%', C_GREY, RR_NEVER); addoc(OC_CORPSE, "Corpses", "Dead flesh which was once living.", '%', C_GREY, RR_NEVER);
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
@ -1581,6 +1582,7 @@ void initobjects(void) {
addot(OT_HOLEINGROUND, "hole in the ground", "A gaping hole in the ground.", MT_NOTHING, 0, OC_DFEATURE, SZ_LARGE); addot(OT_HOLEINGROUND, "hole in the ground", "A gaping hole in the ground.", MT_NOTHING, 0, OC_DFEATURE, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_BLUE, '^', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, '^', NA, NULL);
addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, "hole"); addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, "hole");
addflag(lastot->flags, F_DONTSHOWDEST, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DONTSHOWDEST, B_TRUE, NA, NA, NULL);
@ -1601,6 +1603,21 @@ void initobjects(void) {
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL);
addot(OT_TREEDOWN, "hollow tree leading down", "A huge hollow tree containing an ascending staircase.", MT_DRAGONWOOD, 3000, OC_DFEATURE, SZ_HUGE);
addflag(lastot->flags, F_GLYPH, C_BROWN, '>', NA, NULL);
addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, "hollow tree");
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_TREEUP, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MAKESNOISE, 33, 1, NA, "rustling leaves.");
addflag(lastot->flags, F_MAKESNOISE, 33, 1, NA, "birds chirping.");
addot(OT_TREEUP, "hollow tree leading up", "A huge hollow tree containing an ascending staircase.", MT_DRAGONWOOD, 3000, OC_DFEATURE, SZ_HUGE);
addflag(lastot->flags, F_GLYPH, C_BROWN, '<', NA, NULL);
addflag(lastot->flags, F_CLIMBABLE, D_UP, NA, NA, "hollow tree");
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_TREEDOWN, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addot(OT_TUNNELDOWN, "tunnel leading down", "A wide tunnel leading downwards.", MT_STONE, 3000, OC_DFEATURE, SZ_HUGE); addot(OT_TUNNELDOWN, "tunnel leading down", "A wide tunnel leading downwards.", MT_STONE, 3000, OC_DFEATURE, SZ_HUGE);
addflag(lastot->flags, F_GLYPH, C_BROWN, '>', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '>', NA, NULL);
addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, "tunnel"); addflag(lastot->flags, F_CLIMBABLE, D_DOWN, NA, NA, "tunnel");
@ -1982,6 +1999,7 @@ void initobjects(void) {
// rocks // rocks
addot(OT_BOULDER, "boulder", "A massive stone boulder.", MT_STONE, 80, OC_ROCK, SZ_HUGE); addot(OT_BOULDER, "boulder", "A massive stone boulder.", MT_STONE, 80, OC_ROCK, SZ_HUGE);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_GLYPH, NA, '\'', NA, NULL); addflag(lastot->flags, F_GLYPH, NA, '\'', NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
@ -2005,8 +2023,9 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL); addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL);
addot(OT_STATUE, "statue", "A stone statue of a monster.", MT_STONE, 80, OC_ROCK, SZ_HUMAN); addot(OT_STATUE, "statue", "A stone statue of a monster.", MT_STONE, 80, OC_ROCK, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 75, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, "");
addflag(lastot->flags, F_RARITY, H_VILLAGE, 80, NA, ""); addflag(lastot->flags, F_RARITY, H_VILLAGE, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_FOREST, NA, RR_RARE, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_GLYPH, NA, '\'', NA, NULL); addflag(lastot->flags, F_GLYPH, NA, '\'', NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL); // will be overridden addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL); // will be overridden
@ -2019,8 +2038,9 @@ void initobjects(void) {
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "a statue"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "a statue");
addot(OT_STONE, "stone", "A medium-sized roundish stone.", MT_STONE, 0.5, OC_ROCK, SZ_TINY); addot(OT_STONE, "stone", "A medium-sized roundish stone.", MT_STONE, 0.5, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, NA, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, NA, RR_COMMON, "");
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, 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_DAMAGABLE, B_TRUE, NA, NA, NULL);
@ -3689,6 +3709,17 @@ void initobjects(void) {
addflag(lastot->flags, F_CASTINGTIME, 2, NA, NA, NULL); addflag(lastot->flags, F_CASTINGTIME, 2, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODNATURE, 5, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODNATURE, 5, NA, NULL);
// l6
addot(OT_S_ANIMATETREE, "animate tree", "Imbues a nearby tree with the power of life, turning it into a powerful treant.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL);
addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_SPECIAL, NA, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODNATURE, 25, NA, NULL);
/////////////////// ///////////////////
// life spells / cleric spells // life spells / cleric spells
/////////////////// ///////////////////
@ -4165,10 +4196,15 @@ void initobjects(void) {
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l5
addot(OT_S_GATE, "gate", "Creates a portal to a different dungeon level (within ^bpower^n*2 levels).", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_GATE, "gate", "Creates a portal to a different dungeon level (within ^bpower^n*2 levels).", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
// l5
addot(OT_S_TRAVEL, "travel", "Instantly teleports the caster to the start of a given dungeon branch.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
// l6 // l6
addot(OT_S_PLANESHIFT, "planeshift", "Instantly transports the caster to a different plane of existence.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_PLANESHIFT, "planeshift", "Instantly transports the caster to a different plane of existence.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL);
@ -5429,7 +5465,7 @@ void initobjects(void) {
addflag(lastot->flags, F_HELPSREST, 15, 1, NA, NULL); addflag(lastot->flags, F_HELPSREST, 15, 1, NA, NULL);
addot(OT_BOOKSHELF, "bookshelf", "A set of wooden shelves, sized for book storage.", MT_WOOD, 150, OC_FURNITURE, SZ_HUMAN); addot(OT_BOOKSHELF, "bookshelf", "A set of wooden shelves, sized for book storage.", MT_WOOD, 150, OC_FURNITURE, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_GLYPH, C_BROWN, '\\', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '\\', NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
@ -5526,7 +5562,7 @@ void initobjects(void) {
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL); addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addot(OT_WOODENTABLE, "wooden table", "A waist-height wooden table.", MT_WOOD, 25, OC_FURNITURE, SZ_HUMAN); addot(OT_WOODENTABLE, "wooden table", "A waist-height wooden table.", MT_WOOD, 25, OC_FURNITURE, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_ALL, 70, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_GLYPH, C_BROWN, '\\', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '\\', NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_HUMAN, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_HUMAN, NA, NULL);
addflag(lastot->flags, F_CRUSHABLE, SZ_LARGE, NA, NA, NULL); addflag(lastot->flags, F_CRUSHABLE, SZ_LARGE, NA, NA, NULL);
@ -8394,7 +8430,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_VLOW, 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_STARTATT, A_CHA, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 0, 1, NA, NULL); addflag(lastrace->flags, F_HITDICE, 0, 1, NA, NULL);
addflag(lastrace->flags, F_TR, 2, NA, NA, NULL); addflag(lastrace->flags, F_TR, 4, NA, NA, NULL);
addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, B_TRUE, NULL); addflag(lastrace->flags, F_DOESNTMOVE, B_TRUE, NA, B_TRUE, NULL);
addflag(lastrace->flags, F_NOPRINTS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOPRINTS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
@ -9453,6 +9489,124 @@ void initrace(void) {
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_EATCONFER, F_VISRANGEMOD, 1, NA, "50"); addflag(lastrace->flags, F_EATCONFER, F_VISRANGEMOD, 1, NA, "50");
addrace(R_TREANTYOUNG, "treant youngling", 500, 'T', C_BROWN, MT_WOOD, RC_HUMANOID, "Treants are huge living trees, with humanoid facial features visible on their trunks.");
setbodytype(lastrace, BT_HUMANOID);
setbodypartname(lastrace, BP_HEAD, "face");
setbodypartname(lastrace, BP_BODY, "trunk");
setbodypartname(lastrace, BP_NECK, "trunk");
setbodypartname(lastrace, BP_SHOULDERS, "trunk");
setbodypartname(lastrace, BP_HANDS, "branches");
setbodypartname(lastrace, BP_RIGHTFINGER, "right branch");
setbodypartname(lastrace, BP_LEFTFINGER, "left branch");
setbodypartname(lastrace, BP_LEGS, "roots");
setbodypartname(lastrace, BP_FEET, "roots");
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "tree");
addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 7, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 7, NA, NA, NULL);
addflag(lastrace->flags, F_EVASION, -20, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 12, NA, NULL);
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_WATER, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_LIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_VHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "bellows^a bellow");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL);
addrace(R_TREANT, "treant", 700, 'T', C_GREEN, MT_WOOD, RC_HUMANOID, "Treants are huge living trees, with humanoid facial features visible on their trunks.");
setbodytype(lastrace, BT_HUMANOID);
setbodypartname(lastrace, BP_HEAD, "face");
setbodypartname(lastrace, BP_BODY, "trunk");
setbodypartname(lastrace, BP_NECK, "trunk");
setbodypartname(lastrace, BP_SHOULDERS, "trunk");
setbodypartname(lastrace, BP_HANDS, "branches");
setbodypartname(lastrace, BP_RIGHTFINGER, "right branch");
setbodypartname(lastrace, BP_LEFTFINGER, "left branch");
setbodypartname(lastrace, BP_LEGS, "roots");
setbodypartname(lastrace, BP_FEET, "roots");
addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 9, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 9, NA, NA, NULL);
addflag(lastrace->flags, F_EVASION, -20, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_VERYSLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_VERYSLOW, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 16, NA, NULL);
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_WATER, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_LIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_VHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "bellows^a bellow");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL);
addrace(R_TREANTOLD, "treant elder", 900, 'T', C_BOLDGREEN, MT_WOOD, RC_HUMANOID, "Treants are huge living trees, with humanoid facial features visible on their trunks.");
setbodytype(lastrace, BT_HUMANOID);
setbodypartname(lastrace, BP_HEAD, "face");
setbodypartname(lastrace, BP_BODY, "trunk");
setbodypartname(lastrace, BP_NECK, "trunk");
setbodypartname(lastrace, BP_SHOULDERS, "trunk");
setbodypartname(lastrace, BP_HANDS, "branches");
setbodypartname(lastrace, BP_RIGHTFINGER, "right branch");
setbodypartname(lastrace, BP_LEFTFINGER, "left branch");
setbodypartname(lastrace, BP_LEGS, "roots");
setbodypartname(lastrace, BP_FEET, "roots");
addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 9, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 11, NA, NA, NULL);
addflag(lastrace->flags, F_EVASION, -20, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_ULTRASLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_ULTRASLOW, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 20, NA, NULL);
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_WATER, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_LIGHT, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_VHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_ANIMATETREE, 25, 25, "pw:1;");
addflag(lastrace->flags, F_CASTCHANCE, 40, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_ANIMATETREE, NA, NA, "waves its branches");
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "bellows^a bellow");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 20, NA, NA, NULL);
addrace(R_GIANTHILL, "mountain giant", 160, 'H', C_GREY, MT_FLESH, RC_HUMANOID, "Enormous humanoids who dwell in the mountains, using their grat strength to leap between valleys and pelt their prey with enormous boulders."); addrace(R_GIANTHILL, "mountain giant", 160, 'H', C_GREY, MT_FLESH, RC_HUMANOID, "Enormous humanoids who dwell in the mountains, using their grat strength to leap between valleys and pelt their prey with enormous boulders.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
@ -11269,7 +11423,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CHA, 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_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_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_FREQUENT, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 2, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 2, NA, NA, NULL); addflag(lastrace->flags, F_TR, 2, NA, NA, NULL);
@ -15574,6 +15728,7 @@ void initrace(void) {
addflag(r->flags, F_RESISTMAG, 15, NA, NA, NULL); addflag(r->flags, F_RESISTMAG, 15, NA, NA, NULL);
addflag(r->flags, F_MEDITATES, B_TRUE, NA, NA, NULL); addflag(r->flags, F_MEDITATES, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_SEEINDARK, 10, NA, NA, NULL); addflag(r->flags, F_SEEINDARK, 10, NA, NA, NULL);
addflag(r->flags, F_SEEINVIS, B_TRUE, NA, NA, NULL);
addflag(r->flags, F_CANWILL, OT_S_PLANESHIFT, NA, NA, "pw:1;"); addflag(r->flags, F_CANWILL, OT_S_PLANESHIFT, NA, NA, "pw:1;");
} else if (r->raceclass->id == RC_MAGIC) { } else if (r->raceclass->id == RC_MAGIC) {
addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL); addflag(r->flags, F_DISEASEIMMUNE, B_TRUE, NA, NA, NULL);

Binary file not shown.

View File

@ -21,6 +21,7 @@ scatter(3,1,-4,-2) ob:random food:7-10
scatter(3,1,-4,-2) mon:queen ant:1:100 scatter(3,1,-4,-2) mon:queen ant:1:100
scatter(2,1,-2,-2) cell:dirt wall:5-6 scatter(2,1,-2,-2) cell:dirt wall:5-6
goesin:dungeon goesin:dungeon
goesin:forest
goesin:cave goesin:cave
mayrotate mayrotate
rarity:uncommon rarity:uncommon

View File

@ -19,6 +19,7 @@ X:exit
@flags @flags
goesin:dungeon goesin:dungeon
goesin:forest
mayrotate mayrotate
rarity:vrare rarity:vrare
maintainedge maintainedge

View File

@ -10,7 +10,7 @@
@end @end
@legend @legend
#:cell:SOLID #:cell:dirt wall
O:ob:boulder O:ob:boulder
O:exit O:exit
B:mon:grizzly bear B:mon:grizzly bear
@ -21,6 +21,7 @@ scatter(3,1,-4,-2) ob:random food:5-10
scatter(3,1,-4,-2) mon:bear cub:1-3:50 scatter(3,1,-4,-2) mon:bear cub:1-3:50
goesin:dungeon goesin:dungeon
goesin:cave goesin:cave
goesin:forest
mayrotate mayrotate
rarity:uncommon rarity:uncommon
maintainedge maintainedge

View File

@ -21,6 +21,7 @@ scatter(3,1,-4,-2) ob:bone:3-5
scatter(3,1,-4,-2) mon:random troll:2-4:100 scatter(3,1,-4,-2) mon:random troll:2-4:100
goesin:dungeon goesin:dungeon
goesin:cave goesin:cave
goesin:forest
mayrotate mayrotate
rarity:veryrare rarity:veryrare
maintainedge maintainedge

View File

@ -7,13 +7,14 @@
@end @end
@legend @legend
#:cell:SOLID #:cell:brick wall
m:mon:sleeping random m:mon:sleeping random
+:ob:locked iron gate +:ob:locked iron gate
@end @end
@flags @flags
goesin:dungeon goesin:dungeon
goesin:forest
mayrotate mayrotate
rarity:uncommon rarity:uncommon
maintainedge maintainedge

View File

@ -14,6 +14,7 @@
@flags @flags
goesin:dungeon goesin:dungeon
goesin:forest
mayrotate mayrotate
autopop autopop
rarity:uncommon rarity:uncommon

View File

@ -9,6 +9,7 @@ random(5,5)
@flags @flags
goesin:dungeon goesin:dungeon
goesin:forest
autodoors:25 autodoors:25
autopop autopop
entertext:You enter a small shrubbery. entertext:You enter a small shrubbery.

View File

@ -19,6 +19,7 @@ c:ob:chest
@flags @flags
goesin:dungeon goesin:dungeon
goesin:forest
autodoors:50 autodoors:50
autopop autopop
rarity:uncommon rarity:uncommon

View File

@ -13,6 +13,7 @@ w:ob:very deep water
@flags @flags
goesin:cave goesin:cave
goesin:forest
autopop autopop
rarity:common rarity:common
@end @end

View File

@ -20,5 +20,6 @@ o:ob:random tool:50
goesin:dungeon goesin:dungeon
rarity:uncommon rarity:uncommon
maintainedge maintainedge
mayrotate
@end @end

View File

@ -20,5 +20,6 @@ o:ob:random technology:50
goesin:dungeon goesin:dungeon
rarity:uncommon rarity:uncommon
maintainedge maintainedge
mayrotate
@end @end

View File

@ -21,6 +21,7 @@ scatter(2,1,-2,-2) mon:random:1
scatter(2,1,-2,-2) ob:furniture:1-2 scatter(2,1,-2,-2) ob:furniture:1-2
mayrotate mayrotate
goesin:cave goesin:cave
goesin:forest
rarity:common rarity:common
@end @end

24
defs.h
View File

@ -198,14 +198,18 @@
#define MAXVISLIMIT (MAXVISRANGE*20) #define MAXVISLIMIT (MAXVISRANGE*20)
#define MAX_EYEADJ 20 #define MAX_EYEADJ 20
#define MINCLEARINGRADIUS 2 #define MINCLEARINGRADIUS 4
#define MAXCLEARINGRADIUS 5 #define MAXCLEARINGRADIUS 7
#define MAX_ATTRIBVAL 100 #define MAX_ATTRIBVAL 100
#define MAXMAPROOMS 80 #define MAXMAPROOMS 80
// note: -1 is treated as zero
#define MINROOMS_WOODS -1
#define MAXROOMS_WOODS 3
#define MINROOMS 5 #define MINROOMS 5
#define MAXROOMS 10 #define MAXROOMS 10
#define MIN_ROOMH 4 #define MIN_ROOMH 4
@ -776,6 +780,7 @@ enum CELLTYPE {
CT_WALLFLESH, CT_WALLFLESH,
CT_WALLGLASS, CT_WALLGLASS,
CT_WALLMETAL, CT_WALLMETAL,
CT_WALLTREE,
CT_WALLWOOD, CT_WALLWOOD,
// empty // empty
CT_CORRIDOR, CT_CORRIDOR,
@ -1045,6 +1050,9 @@ enum RACE {
R_SPRITEFIRE, R_SPRITEFIRE,
R_SPRITEGRAVE, R_SPRITEGRAVE,
R_SPRITEICE, R_SPRITEICE,
R_TREANTYOUNG,
R_TREANT,
R_TREANTOLD,
R_TRICLOPS, R_TRICLOPS,
R_TROGLODYTE, R_TROGLODYTE,
R_TROLL, R_TROLL,
@ -1293,6 +1301,8 @@ enum OBTYPE {
OT_HOLEINROOF, OT_HOLEINROOF,
OT_STAIRSDOWN, OT_STAIRSDOWN,
OT_STAIRSUP, OT_STAIRSUP,
OT_TREEDOWN,
OT_TREEUP,
OT_TUNNELDOWN, OT_TUNNELDOWN,
OT_TUNNELUP, OT_TUNNELUP,
OT_PORTAL, OT_PORTAL,
@ -1621,6 +1631,7 @@ enum OBTYPE {
OT_S_SIZEUP, OT_S_SIZEUP,
OT_S_SIZEDOWN, OT_S_SIZEDOWN,
// nature / enviromancy // nature / enviromancy
OT_S_ANIMATETREE,
OT_S_BARKSKIN, OT_S_BARKSKIN,
OT_S_CALLLIGHTNING, OT_S_CALLLIGHTNING,
OT_S_CALLWIND, OT_S_CALLWIND,
@ -1675,6 +1686,7 @@ enum OBTYPE {
OT_S_PLANESHIFT, OT_S_PLANESHIFT,
OT_S_SUCK, OT_S_SUCK,
OT_S_TELEPORT, OT_S_TELEPORT,
OT_S_TRAVEL,
OT_S_TWIDDLE, OT_S_TWIDDLE,
// -- wild // -- wild
OT_S_ALARM, OT_S_ALARM,
@ -2276,6 +2288,7 @@ enum ANIMALTYPE {
enum FLAG { enum FLAG {
F_NONE = 0, // dummy flag F_NONE = 0, // dummy flag
// map flags // map flags
F_FIRSTINBRANCH, // this map is the first level in its branch
F_MAPCOORDS, // v0+v1 are x/y coords for this map area F_MAPCOORDS, // v0+v1 are x/y coords for this map area
F_MAPSHAPE, // v0 = enum MAPSHAPE F_MAPSHAPE, // v0 = enum MAPSHAPE
F_ROOMEXIT, // there is an exit from room v0 at x=v1,y=v2 F_ROOMEXIT, // there is an exit from room v0 at x=v1,y=v2
@ -2285,6 +2298,8 @@ enum FLAG {
F_CELLTYPESOLID, // use celltype v0 for solid cells (walls) F_CELLTYPESOLID, // use celltype v0 for solid cells (walls)
F_CELLTYPEEMPTY, // use celltype v0 for empty cells (corridors/rooms) F_CELLTYPEEMPTY, // use celltype v0 for empty cells (corridors/rooms)
// object flags // object flags
F_GODSTONE, // this is a godstone.
// if v2 = TRUE, means we need to warn when we walk onto it.
F_BADOBJECT, // this object is dangerous. ie. potion of poison, F_BADOBJECT, // this object is dangerous. ie. potion of poison,
// potion of sleep, etc. // potion of sleep, etc.
F_BATTLESPOILS, // this obejct was dropped by a monster which the F_BATTLESPOILS, // this obejct was dropped by a monster which the
@ -2562,7 +2577,7 @@ enum FLAG {
// stairs / teleporters / portals // stairs / teleporters / portals
F_CLIMBABLE, // this is a stiarcase, v0 = up/down/in F_CLIMBABLE, // this is a stiarcase, v0 = up/down/in
// also use this for portals // also use this for portals
// text = you climb down XXXX // text = you climb down a/an XXXX
// OPTIONAL v1 = id of region to link to. // OPTIONAL v1 = id of region to link to.
F_PIT, // this is a pit which we can fall down. F_PIT, // this is a pit which we can fall down.
// v0 = up/down // v0 = up/down
@ -3818,6 +3833,7 @@ enum REGIONTYPE {
RG_PIT, RG_PIT,
RG_SEWER, RG_SEWER,
RG_STOMACH, RG_STOMACH,
RG_WOODS,
}; };
enum HABITAT { enum HABITAT {

View File

@ -7,4 +7,5 @@ map.c:
create new habitats if required. create new habitats if required.
text.c:
update getregionname() update getregionname()

2
god.c
View File

@ -468,7 +468,7 @@ void angergod(enum RACE rid, int amt, enum GODANGERREASON why) {
// damage it // damage it
getobname(o, obname, o->amt); getobname(o, obname, o->amt);
msg("Your %s %s struck by divine force!", OB1(o, "is", "are"), noprefix(obname)); msg("Your %s %s struck by divine force!", OB1(o, "is", "are"), noprefix(obname));
takedamage(o, roll("2d4"), DT_DIRECT); takedamage(o, rnd(10,40), DT_DIRECT);
} }
break; break;
case 2: case 2:

6
io.c
View File

@ -4234,6 +4234,10 @@ void docomms(lifeform_t *lf) {
getobname(o, buf, count); getobname(o, buf, count);
givemoney(player, lf, count); givemoney(player, lf, count);
msg("You give %s to %s.", buf, lfname); msg("You give %s to %s.", buf, lfname);
} else if (isgod(lf) && (o->type->obclass->id == OC_GODSTONE)) {
getobname(o, buf, o->amt);
msg("You offer %s to %s.", buf, lfname);
givenob = o;
} else { } else {
givenob = moveob(o, lf->pack, count); givenob = moveob(o, lf->pack, count);
if (givenob) { if (givenob) {
@ -6365,7 +6369,7 @@ char *makedesc_ob(object_t *o, char *retbuf) {
// if known, show what it confers // if known, show what it confers
for (f = o->flags->first ; f ; f = f->next) { for (f = o->flags->first ; f ; f = f->next) {
if ((f->id == F_HOLDCONFER) || (f->id == F_EQUIPCONFER) || (f->id == F_ACTIVATECONFER)) { if ((f->id == F_HOLDCONFER) || (f->id == F_EQUIPCONFER) || (f->id == F_ACTIVATECONFER)) {
if (obknown) { if (obknown && f->known) {
objecttype_t *ot; objecttype_t *ot;
if (f->id == F_HOLDCONFER) strcpy(buf, "When held, it"); if (f->id == F_HOLDCONFER) strcpy(buf, "When held, it");
else if (f->id == F_ACTIVATECONFER) strcpy(buf, "When activated, it"); else if (f->id == F_ACTIVATECONFER) strcpy(buf, "When activated, it");

24
lf.c
View File

@ -18644,13 +18644,18 @@ void startlfturn(lifeform_t *lf) {
int dir,chance; int dir,chance;
if (piety < 100) { if (piety < 100) {
dir = 1; dir = 1;
chance = piety;
limit(&chance, 10, 100);
} else { } else {
dir = -1; dir = -1;
chance = 100 - (piety-200); // ie. 100 max
limit(&chance, 10, 50);
} }
chance = abs(piety) / 100; // the further away from neutral you are, the less chance
if (onein(chance)) { // piety/anger has of 'expiring'
// slowly move towards zero if (pctchance(chance)) {
modpiety(godlf[i]->race->id, (piety < 0) ? 1 : -1); // slowly move towards normal
modpiety(godlf[i]->race->id, dir);
} }
} }
} }
@ -19344,6 +19349,17 @@ void startlfturn(lifeform_t *lf) {
continue; continue;
} }
f = hasflag(o->flags, F_GODSTONE);
if (f && (f->val[2] == B_TRUE)) {
flag_t *f2;
lifeform_t *god;
// warn!
f2 = hasflag(o->flags, F_LINKGOD);
god = findgod(f2->val[0]);
godsay(god->id, B_TRUE, "Mortal! Do not touch that!"); more();
f->val[2] = B_FALSE;
}
f = hasflag(o->flags, F_WALKDAM); f = hasflag(o->flags, F_WALKDAM);
if (f) { if (f) {
applywalkdam(lf, roll(f->text), f->val[0], o); applywalkdam(lf, roll(f->text), f->val[0], o);

169
map.c
View File

@ -666,6 +666,7 @@ int getmapmaxvisrange(map_t *m) {
} else if (m->habitat->id == H_DUNGEON) { } else if (m->habitat->id == H_DUNGEON) {
// in dungeon, reduce distance based on depth (ie. ambient light) // in dungeon, reduce distance based on depth (ie. ambient light)
maxrange -= m->depth; maxrange -= m->depth;
limit(&maxrange, 1, NA);
} }
limit(&maxrange, 0, MAXVISRANGE); limit(&maxrange, 0, MAXVISRANGE);
@ -1667,6 +1668,34 @@ void floodfill(cell_t *startcell) {
} }
} }
// populates thing & nthings with all "regionthings" with
// whatkind == RT_REGIONLINK.
// ie. links to all the map branches.
// returns # found
int getbranchlinks(regionthing_t **thing, int *nthings) {
int i;
region_t *r;
regionthing_t *temp;
*nthings = 0;
for (r = firstregion ; r ; r = r->next) {
if (!r->outline) continue;
for (i = 0; i < r->outline->nthings; i++ ){
// pick a random regionlink thing.
temp = &r->outline->thing[i];
if (temp->whatkind == RT_REGIONLINK) {
regiontype_t *rtype;
rtype = findregiontype(temp->value);
if ( (rtype->id != RG_MAINDUNGEON) &&
(rtype->id != RG_WORLDMAP)) {
thing[(*nthings)++] = temp;
}
}
}
}
return *nthings;
}
cell_t *getcellat(map_t *map, int x, int y) { cell_t *getcellat(map_t *map, int x, int y) {
if (!isonmap(map, x, y)) return NULL; if (!isonmap(map, x, y)) return NULL;
return map->cell[y*map->w + x]; return map->cell[y*map->w + x];
@ -1987,6 +2016,7 @@ void calclight(map_t *map) {
int radius; int radius;
object_t *o; object_t *o;
/*
// lit based on depth // lit based on depth
if (isoutdoors(map)) { if (isoutdoors(map)) {
int hours,mins,secs; int hours,mins,secs;
@ -1997,11 +2027,11 @@ void calclight(map_t *map) {
// ie. daytime // ie. daytime
makelit(c, L_PERMLIGHT, -1); makelit(c, L_PERMLIGHT, -1);
} }
} else { }
*/
//if ((map->depth <= 5) && (c->lit != L_PERMDARK)) { //if ((map->depth <= 5) && (c->lit != L_PERMDARK)) {
if ((map->illumination == IL_FULLLIT) && (c->lit != L_PERMDARK)) { if ((map->illumination == IL_FULLLIT) && (c->lit != L_PERMDARK)) {
makelit(c, L_PERMLIGHT, -1); makelit(c, L_PERMLIGHT, -1);
}
} }
// TODO: has dark producing lf? // TODO: has dark producing lf?
@ -2369,6 +2399,37 @@ int countstairs(map_t *m, int dir) {
return count; return count;
} }
void createborder(map_t *map, enum CELLTYPE solidtype) {
int x,y;
cell_t *c;
// now do a border
y = 0;
for (x = 0; x < map->w; x++) {
// n
c = getcellat(map, x, 0);
clearcell(c);
setcelltype(c,solidtype);
c->locked = B_TRUE;
// s
c = getcellat(map, x, map->h-1);
clearcell(c);
setcelltype(c,solidtype);
c->locked = B_TRUE;
}
for (y = 1; y < map->h-1; y++) {
// w
c = getcellat(map, 0, y);
clearcell(c);
setcelltype(c,solidtype);
c->locked = B_TRUE;
// e
c = getcellat(map, map->w-1, y);
clearcell(c);
setcelltype(c,solidtype);
c->locked = B_TRUE;
}
}
void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) { void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
int wantrooms = B_TRUE; int wantrooms = B_TRUE;
int x,y,i; int x,y,i;
@ -2462,31 +2523,7 @@ void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *
*/ */
// now do a border // now do a border
y = 0; createborder(map, solidcell);
for (x = 0; x < map->w; x++) {
// n
c = getcellat(map, x, 0);
clearcell(c);
setcelltype(c,solidcell);
c->locked = B_TRUE;
// s
c = getcellat(map, x, map->h-1);
clearcell(c);
setcelltype(c,solidcell);
c->locked = B_TRUE;
}
for (y = 1; y < map->h-1; y++) {
// w
c = getcellat(map, 0, y);
clearcell(c);
setcelltype(c,solidcell);
c->locked = B_TRUE;
// e
c = getcellat(map, map->w-1, y);
clearcell(c);
setcelltype(c,solidcell);
c->locked = B_TRUE;
}
} }
// //
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) { void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
@ -3019,6 +3056,7 @@ void createfakes(map_t *map, cell_t *cell) {
void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings) { void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob, int nclearings) {
int x,y; int x,y;
enum CELLTYPE emptycell; enum CELLTYPE emptycell;
enum CELLTYPE solidcell;
int i; int i;
int ntrees; int ntrees;
int density; int density;
@ -3026,14 +3064,17 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
char buf[BUFLEN]; char buf[BUFLEN];
cell_t *retcell[MAXCANDIDATES]; cell_t *retcell[MAXCANDIDATES];
int nretcells; int nretcells;
int numrooms = 0;
//object_t *o; //object_t *o;
// fill entire maze with emptiness // fill entire maze with emptiness
emptycell = getmapempty(map); emptycell = getmapempty(map);
solidcell = getmapsolid(map);
for (y = 0; y < map->h; y++) { for (y = 0; y < map->h; y++) {
for (x = 0; x < map->w; x++) { for (x = 0; x < map->w; x++) {
c = addcell(map, x, y); c = addcell(map, x, y);
setcelltype(c, emptycell); setcelltype(c, onein(4) ? CT_DIRT : emptycell );
} }
} }
@ -3047,11 +3088,17 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
for (i = 0; i < ntrees; i++) { for (i = 0; i < ntrees; i++) {
c = getrandomcell(map); c = getrandomcell(map);
while (c->lf) c = getrandomcell(map); while (c->lf) c = getrandomcell(map);
switch (rnd(0,1)) { if (onein(2)) {
default: case 0: strcpy(buf, "tree"); break; killallobs(c->obpile);
case 1: strcpy(buf, "shrub"); break; setcelltype(c, solidcell);
} else {
setcelltype(c, onein(2) ? emptycell : CT_DIRT);
switch (rnd(0,1)) {
default: case 0: strcpy(buf, "tree"); break;
case 1: strcpy(buf, "shrub"); break;
}
addob(c->obpile, buf);
} }
addob(c->obpile, buf);
} }
// clearings // clearings
for (i = 0; i < nclearings; i++) { for (i = 0; i < nclearings; i++) {
@ -3061,6 +3108,7 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
// clear obs in all clearing cells // clear obs in all clearing cells
getradiuscells(c, w, DT_ORTH, B_FALSE, LOF_DONTNEED, B_TRUE, retcell, &nretcells, B_FALSE); getradiuscells(c, w, DT_ORTH, B_FALSE, LOF_DONTNEED, B_TRUE, retcell, &nretcells, B_FALSE);
for (n = 0; n < nretcells; n++) { for (n = 0; n < nretcells; n++) {
setcelltype(c, emptycell);
// kill all obs here // kill all obs here
while (retcell[n]->obpile->first) killob(retcell[n]->obpile->first); while (retcell[n]->obpile->first) killob(retcell[n]->obpile->first);
} }
@ -3073,7 +3121,7 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
} }
break; break;
case 2: // add clusters of trees case 2: // add clusters of trees
nclearings = rnd(5,10); nclearings = rnd(10,15);
for (i = 0; i < nclearings; i++) { for (i = 0; i < nclearings; i++) {
int w,n; int w,n;
c = getrandomcell(map); c = getrandomcell(map);
@ -3083,15 +3131,31 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
getradiuscells(c, w, DT_ORTH, B_FALSE, LOF_DONTNEED, B_TRUE, retcell, &nretcells, 80); getradiuscells(c, w, DT_ORTH, B_FALSE, LOF_DONTNEED, B_TRUE, retcell, &nretcells, 80);
for (n = 0; n < nretcells; n++) { for (n = 0; n < nretcells; n++) {
switch (rnd(0,1)) { if (onein(2)) {
default: case 0: strcpy(buf, "tree"); break; killallobs(retcell[n]->obpile);
case 1: strcpy(buf, "shrub"); break; setcelltype(retcell[n], solidcell);
} else {
setcelltype(retcell[n], onein(2) ? emptycell : CT_DIRT);
switch (rnd(0,1)) {
default: case 0: strcpy(buf, "tree"); break;
case 1: strcpy(buf, "shrub"); break;
}
addob(retcell[n]->obpile, buf);
} }
addob(retcell[n]->obpile, buf);
} }
} }
break; break;
} }
// random vaults
numrooms = rnd(MINROOMS_WOODS, MAXROOMS_WOODS);
for (i = 0; i < numrooms; i++) {
vault_t *v;
v = getvaulttype(map);
createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL);
}
createborder(map, CT_WALLTREE);
} }
@ -5220,6 +5284,12 @@ void finalisemap(map_t *map, object_t *entryob) {
nupstairsneeded = map->region->rtype->stairsperlev - countmapobs(map, upstairtype); nupstairsneeded = map->region->rtype->stairsperlev - countmapobs(map, upstairtype);
ndownstairsneeded = map->region->rtype->stairsperlev - countmapobs(map, downstairtype); ndownstairsneeded = map->region->rtype->stairsperlev - countmapobs(map, downstairtype);
// override # up stairs for first level of a branch.
if (hasflag(map->flags, F_FIRSTINBRANCH)) {
nupstairsneeded = 1;
}
if ( (nupstairsneeded && (upstairtype == OT_NONE)) || if ( (nupstairsneeded && (upstairtype == OT_NONE)) ||
(ndownstairsneeded && (downstairtype == OT_NONE)) ) { (ndownstairsneeded && (downstairtype == OT_NONE)) ) {
dblog("ERROR - need up/down stairs, but no stairtype defined for habitat %s!", map->habitat->name); dblog("ERROR - need up/down stairs, but no stairtype defined for habitat %s!", map->habitat->name);
@ -5266,6 +5336,7 @@ void finalisemap(map_t *map, object_t *entryob) {
if (!c) { if (!c) {
// ANY cell at all, doesn't have to be a room. // ANY cell at all, doesn't have to be a room.
c = getrandomcell(map); c = getrandomcell(map);
c = getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND);
} }
} }
o = addobfast(c->obpile, upstairtype); o = addobfast(c->obpile, upstairtype);
@ -5279,7 +5350,9 @@ void finalisemap(map_t *map, object_t *entryob) {
} }
} }
// make sure we have at least one up stairs // make sure we have at least one up stairs
assert(findobinmap(map, upstairtype)); if (map->region->rtype->id != RG_WORLDMAP) {
assert(findobinmap(map, upstairtype));
}
} }
// DOWN STAIRS // DOWN STAIRS
@ -5291,6 +5364,7 @@ void finalisemap(map_t *map, object_t *entryob) {
if (!c) { if (!c) {
// ANY cell at all, doesn't have to be a room. // ANY cell at all, doesn't have to be a room.
c = getrandomcell(map); c = getrandomcell(map);
c = getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND);
} }
} }
o = addobfast(c->obpile, downstairtype); o = addobfast(c->obpile, downstairtype);
@ -6337,6 +6411,7 @@ cell_t *getstairdestination(object_t *o, int *madenewmap) {
// first map of a newly created region? // first map of a newly created region?
if (newregion->id != curmap->region->id) { if (newregion->id != curmap->region->id) {
newdepth = 1; newdepth = 1;
addflag(newmap->flags, F_FIRSTINBRANCH, B_TRUE, NA, NA, NULL);
} }
createmap(newmap, newdepth, newregion, curmap, dir, o); createmap(newmap, newdepth, newregion, curmap, dir, o);
// at this point, stairs should have a destination (map creation will // at this point, stairs should have a destination (map creation will
@ -6430,7 +6505,7 @@ void initmap(void) {
// thingchance, obchance, vaultchance, maxvisrange, upstiartype, downstairtype // thingchance, obchance, vaultchance, maxvisrange, upstiartype, downstairtype
addhabitat(H_DUNGEON, "dungeon", CT_CORRIDOR, CT_WALL, 3, 50, 30, 6, OT_STAIRSUP, OT_STAIRSDOWN); addhabitat(H_DUNGEON, "dungeon", CT_CORRIDOR, CT_WALL, 3, 50, 30, 6, OT_STAIRSUP, OT_STAIRSDOWN);
addhabitat(H_CAVE, "cave", CT_DIRT, CT_WALLDIRT, 5, 65, 10, 6, OT_TUNNELUP, OT_TUNNELDOWN); addhabitat(H_CAVE, "cave", CT_DIRT, CT_WALLDIRT, 5, 65, 10, 6, OT_TUNNELUP, OT_TUNNELDOWN);
addhabitat(H_FOREST, "forest", CT_GRASS, CT_WALL, 3, 75, 0, MAXVISRANGE, OT_NONE, OT_NONE); addhabitat(H_FOREST, "forest", CT_GRASS, CT_WALLTREE, 3, 75, 0, MAXVISRANGE, OT_TREEUP, OT_TREEDOWN);
addhabitat(H_HEAVEN, "heaven", CT_CORRIDOR, CT_WALLGLASS, 5, 0, 0, MAXVISRANGE, OT_NONE, OT_NONE); addhabitat(H_HEAVEN, "heaven", CT_CORRIDOR, CT_WALLGLASS, 5, 0, 0, MAXVISRANGE, OT_NONE, OT_NONE);
addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5, OT_NONE, OT_NONE); addhabitat(H_PIT, "pit", CT_CORRIDOR, CT_WALL, 0, 0, 0, 5, OT_NONE, OT_NONE);
addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 3, 70, 0, MAXVISRANGE, OT_NONE, OT_NONE); addhabitat(H_VILLAGE, "village", CT_GRASS, CT_WALL, 3, 70, 0, MAXVISRANGE, OT_NONE, OT_NONE);
@ -6446,6 +6521,7 @@ void initmap(void) {
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30); addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30);
addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, B_SOLID, B_OPAQUE, MT_FLESH, 0, 25); addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, B_SOLID, B_OPAQUE, MT_FLESH, 0, 25);
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0, 20); addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0, 20);
addcelltype(CT_WALLTREE, "dense bushland", UNI_SHADEDARK, C_GREEN, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100);
addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, B_SOLID, B_OPAQUE, MT_METAL, 0, 75); addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, B_SOLID, B_OPAQUE, MT_METAL, 0, 75);
// cell types - non-solid // cell types - non-solid
addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, B_EMPTY, B_TRANS, MT_STONE, 0, -1); addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
@ -6462,12 +6538,15 @@ void initmap(void) {
addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -2, -1); addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -2, -1);
// region types // region types
// maxdepth stairs stair major? depthmod // name, pluralname?, defaulthab, maxdepth stairs stair major? depthmod
// perlev dir // perlev dir
addregiontype(RG_WORLDMAP, "The Surface", B_FALSE, H_FOREST, 10, 0, D_NONE, B_TRUE, 0); addregiontype(RG_WORLDMAP, "The Surface", B_FALSE, H_FOREST, 10, 0, D_NONE, B_TRUE, 0);
addregiontype(RG_HEAVEN, "The Realm of Gods", B_FALSE, H_HEAVEN, 1, 0, D_NONE, B_FALSE, 0);
// main branches
addregiontype(RG_MAINDUNGEON, "The Main Dungeon", B_FALSE, H_DUNGEON, 25, 3, D_DOWN, B_TRUE, 0); addregiontype(RG_MAINDUNGEON, "The Main Dungeon", B_FALSE, H_DUNGEON, 25, 3, D_DOWN, B_TRUE, 0);
addregiontype(RG_CAVE, "The Goblin Caves", B_TRUE, H_CAVE, 5, 1, D_DOWN, B_TRUE, 2); addregiontype(RG_CAVE, "The Goblin Caves", B_TRUE, H_CAVE, 5, 1, D_DOWN, B_TRUE, 2);
addregiontype(RG_HEAVEN, "The Realm of Gods", B_FALSE, H_HEAVEN, 1, 0, D_NONE, B_FALSE, 0); addregiontype(RG_WOODS, "The Sylvan Woods", B_TRUE, H_FOREST, 5, 3, D_DOWN, B_TRUE, 1);
// minor branches
addregiontype(RG_PIT, "A Pit", B_FALSE, H_PIT, 1, 1, D_DOWN, B_FALSE, 0); addregiontype(RG_PIT, "A Pit", B_FALSE, H_PIT, 1, 1, D_DOWN, B_FALSE, 0);
addregiontype(RG_SEWER, "A Sewer", B_FALSE, H_SEWER, 1, 0, D_NONE, B_FALSE, 2); addregiontype(RG_SEWER, "A Sewer", B_FALSE, H_SEWER, 1, 0, D_NONE, B_FALSE, 2);
addregiontype(RG_STOMACH, "A Stomach", B_FALSE, H_STOMACH, 1, 0, D_NONE, B_FALSE, 0); addregiontype(RG_STOMACH, "A Stomach", B_FALSE, H_STOMACH, 1, 0, D_NONE, B_FALSE, 0);
@ -6512,7 +6591,9 @@ void initmaplayout(void) {
addregionoutline(RG_MAINDUNGEON); addregionoutline(RG_MAINDUNGEON);
addregionthing(lastregionoutline, 1, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISPLAYERSTART, NULL); addregionthing(lastregionoutline, 1, NA, NA, RT_RNDVAULTWITHFLAG, F_VAULTISPLAYERSTART, NULL);
// l2-4: goblin caves // l2-4: sylvan woods
addregionthing(lastregionoutline, rnd(2,4), NA, NA, RT_REGIONLINK, RG_WOODS, "hollow tree leading down");
// l2-5: goblin caves
addregionthing(lastregionoutline, rnd(2,4), NA, NA, RT_REGIONLINK, RG_CAVE, "tunnel leading down"); addregionthing(lastregionoutline, rnd(2,4), NA, NA, RT_REGIONLINK, RG_CAVE, "tunnel leading down");
// l6: jimbo's lair // l6: jimbo's lair
addregionthing(lastregionoutline, 6, NA, NA, RT_VAULT, NA, "jimbos_lair"); addregionthing(lastregionoutline, 6, NA, NA, RT_VAULT, NA, "jimbos_lair");

2
map.h
View File

@ -25,6 +25,7 @@ int doelementspread(cell_t *c);
int fix_reachability(map_t *m); int fix_reachability(map_t *m);
int fix_unreachable_cell(cell_t *badcell); int fix_unreachable_cell(cell_t *badcell);
void floodfill(cell_t *startcell); void floodfill(cell_t *startcell);
int getbranchlinks(regionthing_t **thing, int *nthings);
cell_t *getcellat(map_t *map, int x, int y); cell_t *getcellat(map_t *map, int x, int y);
int getcellclimbdifficulty(cell_t *c); int getcellclimbdifficulty(cell_t *c);
int getcellclimbdifficultyavg(cell_t *c); int getcellclimbdifficultyavg(cell_t *c);
@ -61,6 +62,7 @@ int countmapobs(map_t *m, enum OBTYPE oid);
int countmapobswithflag(map_t *m, enum FLAG flagid); int countmapobswithflag(map_t *m, enum FLAG flagid);
int countmapobswithflagval(map_t *m, enum FLAG flagid, int val0, int val1, int val2, char *text); int countmapobswithflagval(map_t *m, enum FLAG flagid, int val0, int val1, int val2, char *text);
int countstairs(map_t *m, int dir); int countstairs(map_t *m, int dir);
void createborder(map_t *map, enum CELLTYPE solidtype);
void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob); void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob); void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
void createfakes(map_t *map, cell_t *cell); void createfakes(map_t *map, cell_t *cell);

View File

@ -1813,6 +1813,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
} }
} }
/*
// if it's the player's turn, announce sun set/rise // if it's the player's turn, announce sun set/rise
if (isplayer(map->lf) && isoutdoors(map)) { if (isplayer(map->lf) && isoutdoors(map)) {
int h,m,s; int h,m,s;
@ -1823,6 +1824,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
msg("The sun is setting."); msg("The sun is setting.");
} }
} }
*/
if (db) dblog("cur time is %ld\n",curtime); if (db) dblog("cur time is %ld\n",curtime);
} }

View File

@ -1647,25 +1647,11 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
char buf[BUFLEN]; char buf[BUFLEN];
// fill in map destination. // fill in map destination.
if (!wantregionthing) { if (!wantregionthing) {
region_t *r; regionthing_t *poss[MAXCANDIDATES];
regionthing_t *rthing,*poss[MAXCANDIDATES]; int nposs = 0;
int nposs = 0,i;
getbranchlinks(poss, &nposs);
for (r = firstregion ; r ; r = r->next) {
if (!r->outline) continue;
for (i = 0; i < r->outline->nthings; i++ ){
// pick a random regionlink thing.
rthing = &r->outline->thing[i];
if (rthing->whatkind == RT_REGIONLINK) {
regiontype_t *rtype;
rtype = findregiontype(rthing->value);
if ( (rtype->id != RG_MAINDUNGEON) &&
(rtype->id != RG_WORLDMAP)) {
poss[nposs++] = rthing;
}
}
}
}
if (nposs) { if (nposs) {
wantregionthing = poss[rnd(0,nposs-1)]; wantregionthing = poss[rnd(0,nposs-1)];
} }
@ -6975,7 +6961,6 @@ int isknown(object_t *o) {
return B_FALSE; return B_FALSE;
} }
return isknownot(o->type); return isknownot(o->type);
} }

135
spell.c
View File

@ -3534,7 +3534,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (haslos(player, caster->cell)) { if (haslos(player, caster->cell)) {
msg("The pentagram pulses red."); msg("The pentagram pulses red.");
} }
if (summonlfs(caster, caster->cell, R_NONE, RC_DEMON, SZ_ANY, AL_NONE, 1, PERMENANT, B_FALSE)) { if (summonlfs(caster, caster->cell, R_NONE, RC_DEMON, SZ_ANY, AL_NONE, 1, PERMENANT, B_MAYBE)) {
if (isplayer(caster) || cansee(player, caster)) { if (isplayer(caster) || cansee(player, caster)) {
msg("An other-worldly demon appears!"); msg("An other-worldly demon appears!");
} }
@ -3873,8 +3873,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("%s comes to life!",obname); msg("%s comes to life!",obname);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
addflag(lf->flags, F_XPVAL, 0, NA, NA, NULL);
if (caster) { if (caster) {
petify(lf, caster); petify(lf, caster);
addflag(lf->flags, F_SUMMONEDBY, caster->id, rnd(50,100), NA, NULL);
} }
// no corpse after death (so you can't keep reanimating it) // no corpse after death (so you can't keep reanimating it)
addflag(lf->flags, F_NOCORPSE, NA, NA, NA, NULL); addflag(lf->flags, F_NOCORPSE, NA, NA, NA, NULL);
@ -3886,6 +3888,48 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
fizzle(caster); fizzle(caster);
return B_TRUE; return B_TRUE;
} }
} else if (spellid == OT_S_ANIMATETREE) {
object_t *o;
o = hasob(targcell->obpile, OT_TREE);
if (o) {
lifeform_t *lf = NULL;
char obname[BUFLEN];
enum RACE rid;
// determine new race
switch (rnd(1,6)) {
case 1:
case 2:
case 3:
rid = R_TREANTYOUNG;
break;
case 4:
case 5:
rid = R_TREANT;
break;
case 6:
rid = R_TREANTOLD;
break;
}
getobname(o, obname, 1);
removeob(o, ALL);
lf = addmonster(targcell, rid, NULL, B_FALSE, 1, B_FALSE, NULL);
if (cansee(player, lf)) {
msg("%s comes to life!",obname);
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
addflag(lf->flags, F_XPVAL, 0, NA, NA, NULL);
if (caster) {
petify(lf, caster);
addflag(lf->flags, F_SUMMONEDBY, caster->id, rnd(50,100), NA, NULL);
}
if (isplayer(caster)) {
angergodmaybe(R_GODFIRE, 50, GA_HERESY);
}
} else {
fizzle(caster);
return B_TRUE;
}
} else if (spellid == OT_S_ANTICIPATE) { } else if (spellid == OT_S_ANTICIPATE) {
if (!target) target = targcell->lf; if (!target) target = targcell->lf;
if (!target) { if (!target) {
@ -4285,7 +4329,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// outdoors? // outdoors?
if (caster && (getraceclass(caster) == RC_GOD)) { if (caster && (getraceclass(caster) == RC_GOD)) {
losehp(target, rolldie(5,6), DT_ELECTRIC, caster, "a heavenly bolt of lightning"); losehp(target, rolldie(5,6), DT_ELECTRIC, caster, "a heavenly bolt of lightning");
} else if (isoutdoors(target->cell->map)) { } else if (target->cell->map->habitat->id == H_FOREST) {
losehp(target, rolldie(4,6), DT_ELECTRIC, caster, "a bolt of lightning"); losehp(target, rolldie(4,6), DT_ELECTRIC, caster, "a bolt of lightning");
} else { } else {
losehp(target, rolldie(3,6), DT_ELECTRIC, caster, "a bolt of lightning"); losehp(target, rolldie(3,6), DT_ELECTRIC, caster, "a bolt of lightning");
@ -6596,7 +6640,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} else if (spellid == OT_S_HAILSTORM) { } else if (spellid == OT_S_HAILSTORM) {
int failed = B_FALSE; int failed = B_FALSE;
if (caster && isoutdoors(caster->cell->map)) { if (caster && (caster->cell->map->habitat->id == H_FOREST)) {
power += 3; power += 3;
limit(&power, NA, 10); limit(&power, NA, 10);
} }
@ -7702,6 +7746,70 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// 5 is the same as AT_VHIGH strength // 5 is the same as AT_VHIGH strength
real_fireat(caster, targob, 1, targcell, 5, NULL, B_TRUE, spellid); real_fireat(caster, targob, 1, targcell, 5, NULL, B_TRUE, spellid);
} else if (spellid == OT_S_TRAVEL) {
regionthing_t *poss[MAXCANDIDATES],*rt;
region_t *srcregion = NULL;
int nposs,i,depth;
char ch = 'a';
cell_t *dstcell = NULL;
if (!isplayer(caster)) return B_TRUE;
// ask which region to go to
getbranchlinks(poss, &nposs);
if (!nposs) {
fizzle(caster);
return B_TRUE;
}
initprompt(&prompt, "Where do you wish to travel?");
prompt.maycancel = B_TRUE;
for (i = 0; i < nposs; i++) {
regiontype_t *destregiontype;
destregiontype = findregiontype(poss[i]->value);
addchoice(&prompt, ch++, destregiontype->name, NULL, poss[i], NULL);
}
ch = getchoice(&prompt);
rt = (regionthing_t *)prompt.result;
depth = rt->depth;
// find region containing this link.
findregionthing(rt->id, &srcregion);
if (srcregion) {
object_t *dstob = NULL;
region_t *destregion = NULL;
map_t *srcmap;
if (isplayer(caster)) {
msg("There is a blinding flash of light...");
wrefresh(msgwin);
}
// does the map contining the link exist?
srcmap = findregionmap(srcregion->id, depth);
if (!srcmap) {
// we'll need to create the map.
srcmap = addmap();
createmap(srcmap, depth, srcregion, NULL, D_NONE, NULL);
}
// find the regionlink object. ie. the stairs/portal which goes to
// the given region.
destregion = findregionbytype(rt->value);
dstob = findmapobwithflagval(srcmap, F_CLIMBABLE, NA, destregion->id, NA, NULL);
assert(dstob);
dstcell = getoblocation(dstob);
} else {
msg("srcregion doesnt exist!");
}
if (dstcell) {
teleportto(caster, dstcell, B_FALSE);
} else {
fizzle(caster);
return B_TRUE;
}
} else if (spellid == OT_S_PLANESHIFT) { } else if (spellid == OT_S_PLANESHIFT) {
map_t *m; map_t *m;
target = caster; target = caster;
@ -8596,7 +8704,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
getlfname(targ[i],targname); getlfname(targ[i],targname);
msg("%s %s struck by a bolt of lightning!",targname, is(targ[i])); msg("%s %s struck by a bolt of lightning!",targname, is(targ[i]));
} }
if (isoutdoors(targ[i]->cell->map)) { if (caster && (targ[i]->cell->map->habitat->id == H_FOREST)) {
losehp(targ[i], rolldie(4,6), DT_ELECTRIC, caster, "a bolt of lightning"); losehp(targ[i], rolldie(4,6), DT_ELECTRIC, caster, "a bolt of lightning");
} else { } else {
losehp(targ[i], rolldie(3,6), DT_ELECTRIC, caster, "a bolt of lightning"); losehp(targ[i], rolldie(3,6), DT_ELECTRIC, caster, "a bolt of lightning");
@ -8807,7 +8915,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
target = targcell->lf; target = targcell->lf;
if (isoutdoors(targcell->map)) { if (targcell->map->habitat->id == H_FOREST) {
power += 5; power += 5;
limit(&power, NA, 10); limit(&power, NA, 10);
} }
@ -9878,7 +9986,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} else if (spellid == OT_S_SLEETSTORM) { } else if (spellid == OT_S_SLEETSTORM) {
int failed = B_FALSE; int failed = B_FALSE;
if (isoutdoors(caster->cell->map)) { if (caster && caster->cell->map->habitat->id == H_FOREST) {
power += 3; power += 3;
limit(&power, NA, 10); limit(&power, NA, 10);
} }
@ -10874,7 +10982,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
enum LFSIZE wantsize; enum LFSIZE wantsize;
enum RACECLASS wantrc; enum RACECLASS wantrc;
enum RACE wantrace = R_NONE; enum RACE wantrace = R_NONE;
int friendly; int friendly = B_MAYBE;
char racename[BUFLEN]; char racename[BUFLEN];
lifeform_t *summoner = NULL; lifeform_t *summoner = NULL;
@ -10894,7 +11002,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
wantsize = SZ_ANY; wantsize = SZ_ANY;
nwant = 8; nwant = 8;
successrate = 100; successrate = 100;
friendly = B_FALSE; friendly = B_MAYBE;
break; break;
case OT_S_HECTASSERVANT: case OT_S_HECTASSERVANT:
wantrace = R_HECTASSERVANT; wantrace = R_HECTASSERVANT;
@ -12999,6 +13107,11 @@ int stopspell(lifeform_t *caster, enum OBTYPE spellid) {
// returns # created // returns # created
// pass EITHER wantrace OR wantrc + wantsize + wantalign // pass EITHER wantrace OR wantrc + wantsize + wantalign
//
// friendly can be:
// b_true - force summoned lfs to be peaceful
// b_maybe - leave hostility as set by race
// b_false - force summoned lfs to be hostile
int summonlfs(lifeform_t *caster, cell_t *where, enum RACE wantrace, enum RACECLASS wantrc, enum LFSIZE wantsize, enum ALIGNMENT wantalign, int howmany, int lifetime, int friendly) { int summonlfs(lifeform_t *caster, cell_t *where, enum RACE wantrace, enum RACECLASS wantrc, enum LFSIZE wantsize, enum ALIGNMENT wantalign, int howmany, int lifetime, int friendly) {
lifeform_t *newlf; lifeform_t *newlf;
race_t *r = NULL; race_t *r = NULL;
@ -13065,11 +13178,15 @@ int summonlfs(lifeform_t *caster, cell_t *where, enum RACE wantrace, enum RACECL
addflag(newlf->flags, F_XPVAL, 0, NA, NA, NULL); addflag(newlf->flags, F_XPVAL, 0, NA, NA, NULL);
// summoned // summoned
addflag(newlf->flags, F_SUMMONEDBY, caster->id, lifetime, NA, NULL); addflag(newlf->flags, F_SUMMONEDBY, caster->id, lifetime, NA, NULL);
if (friendly) { if (friendly == B_TRUE) {
addflag(newlf->flags, F_PETOF, caster->id, NA, NA, NULL); addflag(newlf->flags, F_PETOF, caster->id, NA, NA, NULL);
if (areallies(player, caster)) { if (areallies(player, caster)) {
makefriendly(newlf, PERMENANT); makefriendly(newlf, PERMENANT);
} }
} else if (friendly == B_FALSE) {
if (!lfhasflag(newlf, F_HOSTILE)) {
addflag(newlf->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
}
} }
ncreated++; ncreated++;
} }

21
text.c
View File

@ -466,13 +466,13 @@ char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam
return "bash"; return "bash";
} }
} else if (dam <= 12) { } else if (dam <= 12) {
return "pound";
} else if (dam <= 16) {
return "slam";
} else if (dam <= 20) {
return "pummel"; return "pummel";
} else if (dam <= 18) { } else {
if (onein(2)) { return "clobber";
return "slam";
} else {
return "clobber";
}
} }
} else if (damtype == DT_BITE) { } else if (damtype == DT_BITE) {
if (lf && (ownersize <= SZ_SMALL)) { if (lf && (ownersize <= SZ_SMALL)) {
@ -1373,6 +1373,9 @@ char *getregionname(char *buf, map_t *m, region_t *r, enum REGIONNAMEFORMAT how)
case RG_CAVE: case RG_CAVE:
snprintf(buf, BUFLEN, "goblin caves L%d", m->depth); snprintf(buf, BUFLEN, "goblin caves L%d", m->depth);
break; break;
case RG_WOODS:
snprintf(buf, BUFLEN, "syvan woods L%d", m->depth);
break;
case RG_WORLDMAP: case RG_WORLDMAP:
snprintf(buf, BUFLEN, "the surface(%d,%d)",x,y); snprintf(buf, BUFLEN, "the surface(%d,%d)",x,y);
break; break;
@ -1397,6 +1400,9 @@ char *getregionname(char *buf, map_t *m, region_t *r, enum REGIONNAMEFORMAT how)
case RG_CAVE: case RG_CAVE:
snprintf(buf, BUFLEN, "on level %d of the goblin caves", m->depth); snprintf(buf, BUFLEN, "on level %d of the goblin caves", m->depth);
break; break;
case RG_WOODS:
snprintf(buf, BUFLEN, "on level %d of the sylvan woods", m->depth);
break;
case RG_WORLDMAP: case RG_WORLDMAP:
snprintf(buf, BUFLEN, "on the surface(%d,%d)",x,y); snprintf(buf, BUFLEN, "on the surface(%d,%d)",x,y);
break; break;
@ -1421,6 +1427,9 @@ char *getregionname(char *buf, map_t *m, region_t *r, enum REGIONNAMEFORMAT how)
case RG_CAVE: case RG_CAVE:
strcpy(buf, "the goblin caves"); strcpy(buf, "the goblin caves");
break; break;
case RG_WOODS:
strcpy(buf, "the sylvan woods");
break;
case RG_WORLDMAP: case RG_WORLDMAP:
strcpy(buf, "the surface"); strcpy(buf, "the surface");
break; break;

View File

@ -781,7 +781,7 @@ vault_t *getvaulttype(map_t *m) {
return poss[rnd(0,nposs-1)]; return poss[rnd(0,nposs-1)];
} }
// if we have no possibilities, lower rarity and try again // if we have no possibilities, lower rarity and try again
if (rr == RR_COMMON) { if (rr == RR_FREQUENT) {
// give up. // give up.
break; break;
} else { } else {