- [+] populate ant nest with objects (set rarity)

- [+] when placing any vault with maintainedge, set "LOCKED" for all
      cells
- [+] change all mapmaking code to honour LOCKED(not just digdungeon)
    - [+] room placement code
    - [+] cave
    - [+] dungeon
    - [+] forest
    - [+] sewer
    - [+] swamp
- [+] fixed. BUG: TRAVEL to the swamp, walk up stairs...
    - [+] ERROR - stairs should link to existing map ('dungeon L7 (id
          #3)', depth 7), but
          it has no free stairs.--More--
    - [+] walking _down_ is okay.
    - [+] was only checking to link entryob when we were going DOWN
          stairs.
- [+] place fixed vaults _BEFORE_ creating habitats ???
    - [+] this will only work after all creation routines honour
          "->locked"
    - [+] set locked on all fixed vault cells after making them.
- [+] better code for removal of internal doors.
- [+] bug! fleeing monsters taking no time!
- [+] brainbat
- [+] consume corpses to regain life? make this a normal death spell.
    - [+] f_consumesouls
    - [+] anything that dies in sight nearby heals her.
    - [+] "%s consumes the soul of the dying %s ?"
    - [+] give this to baba yaga
- [+] loading bug with map flags:
    - [+] getting a flag with text = "flags"
    - [+] am i saving something else with a space in it ???
    - [+] %s in fscanf doesn't handle spaces!
        - [+] in save.c, when I'm liable to get spaces in a string,
              replace %s with:
            - [+]  sscanf("%[ a-xA-Z0-9+'*/-]")
- [+] earthwyrm
    - [+] divine into two monsters if slashed
    - [+] appear in ant nests
This commit is contained in:
Rob Pearce 2012-04-05 09:28:20 +00:00
parent 892440031d
commit 0f9db848d3
15 changed files with 546 additions and 182 deletions

1
ai.c
View File

@ -586,7 +586,6 @@ int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim
break; break;
} }
} }
// aim at an adjacent wall cell // aim at an adjacent wall cell
if (spellcell) *spellcell = poss[rnd(0,nposs-1)]; if (spellcell) *spellcell = poss[rnd(0,nposs-1)];
} else if (spelltype->id == OT_S_PLANTWALK) { } else if (spelltype->id == OT_S_PLANTWALK) {

View File

@ -1197,8 +1197,10 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
addflag(victim->flags, F_BEHEADED, B_TRUE, NA, NA, NULL); addflag(victim->flags, F_BEHEADED, B_TRUE, NA, NA, NULL);
addflag(victim->flags, F_MUTILATED, B_TRUE, NA, NA, NULL); addflag(victim->flags, F_MUTILATED, B_TRUE, NA, NA, NULL);
} else if (strstr(buf, "bisect")) { } else if (strstr(buf, "bisect")) {
if (victim->race->id != R_EARTHWYRM) {
addflag(victim->flags, F_MUTILATED, B_TRUE, NA, NA, NULL); addflag(victim->flags, F_MUTILATED, B_TRUE, NA, NA, NULL);
} }
}
if ((isplayer(lf) || cansee(player, victim)) && !hasflag(victim->flags, F_NODEATHANNOUNCE)) { if ((isplayer(lf) || cansee(player, victim)) && !hasflag(victim->flags, F_NODEATHANNOUNCE)) {
if (!hasflag(victim->flags, F_PHANTASM)) { if (!hasflag(victim->flags, F_PHANTASM)) {
// don't also say "the xx dies" // don't also say "the xx dies"

112
data.c
View File

@ -1390,9 +1390,11 @@ void initobjects(void) {
addocnoun(lastobjectclass, "furniture"); addocnoun(lastobjectclass, "furniture");
addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastobjectclass->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastobjectclass->flags, F_RARITY, H_CAVE, RR_RARE, NA, NULL); // override for habitat addflag(lastobjectclass->flags, F_RARITY, H_CAVE, RR_RARE, NA, NULL); // override for habitat
addflag(lastobjectclass->flags, F_RARITY, H_ANTNEST, RR_NEVER, NA, NULL); // override for habitat
addoc(OC_TERRAIN, "Terrain", "Water, etc.", '\\', C_GREY, RR_NEVER); addoc(OC_TERRAIN, "Terrain", "Water, etc.", '\\', C_GREY, RR_NEVER);
addoc(OC_TRAP, "Trap", "Fiendish traps.", '^', C_GREY, RR_RARE); addoc(OC_TRAP, "Trap", "Fiendish traps.", '^', C_GREY, RR_RARE);
addocnoun(lastobjectclass, "trap"); addocnoun(lastobjectclass, "trap");
addflag(lastobjectclass->flags, F_RARITY, H_ANTNEST, RR_NEVER, NA, NULL); // override for habitat
addoc(OC_MONEY, "Money", "The standard currency of Nexus.", '$', C_GREY, RR_UNCOMMON); addoc(OC_MONEY, "Money", "The standard currency of Nexus.", '$', C_GREY, RR_UNCOMMON);
addoc(OC_SCROLL, "Scrolls", "An arcane roll of parchment, inscribed with many magical glyphs.", '?', C_GREY, RR_COMMON); addoc(OC_SCROLL, "Scrolls", "An arcane roll of parchment, inscribed with many magical glyphs.", '?', C_GREY, RR_COMMON);
addocnoun(lastobjectclass, "scroll"); addocnoun(lastobjectclass, "scroll");
@ -2166,6 +2168,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, "");
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 250, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 250, NA, NA, NULL);
addot(OT_AMETHYST, "amethyst", "A purple gemstone.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_AMETHYST, "amethyst", "A purple gemstone.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
@ -2175,6 +2178,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 15, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 15, NA, NA, NULL);
addot(OT_DIAMOND, "diamond", "A sparkling diamond.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_DIAMOND, "diamond", "A sparkling diamond.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
@ -2184,6 +2188,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, "");
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_UNCOMMON, ""); addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_UNCOMMON, "");
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
addot(OT_EMERALD, "emerald", "A deep green gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_EMERALD, "emerald", "A deep green gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
@ -2193,6 +2198,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, "");
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_UNCOMMON, ""); addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_UNCOMMON, "");
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 650, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 650, NA, NA, NULL);
addot(OT_OPAL, "opal", "An amorphous form of silica related to quartz.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addot(OT_OPAL, "opal", "An amorphous form of silica related to quartz.", MT_STONE, 0.1, OC_ROCK, SZ_TINY);
@ -2202,6 +2208,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, "");
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 70, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 70, NA, NA, NULL);
addot(OT_PEARL, "pearl", "A small pinkish-white gem.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addot(OT_PEARL, "pearl", "A small pinkish-white gem.", MT_STONE, 0.1, OC_ROCK, SZ_TINY);
@ -2211,6 +2218,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 30, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 30, NA, NA, NULL);
addot(OT_RUBY, "ruby", "A large red gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_RUBY, "ruby", "A large red gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
@ -2220,6 +2228,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, "");
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 110, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 110, NA, NA, NULL);
addot(OT_SAPPHIRE, "sapphire", "A brilliant blue gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_SAPPHIRE, "sapphire", "A brilliant blue gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
@ -2229,6 +2238,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, "");
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_UNCOMMON, ""); addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_UNCOMMON, "");
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 850, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 850, NA, NA, NULL);
addot(OT_TOPAZ, "topaz stone", "A dull blue gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_TOPAZ, "topaz stone", "A dull blue gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
@ -2238,6 +2248,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, "");
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_STOMACH, 100, RR_COMMON, "");
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 60, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 60, NA, NA, NULL);
@ -2424,15 +2435,19 @@ void initobjects(void) {
addflag(lastot->flags, F_EDIBLE, B_TRUE, 40, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 40, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addot(OT_BANANA, "banana", "Ba-na-na-na-na-na na-na na-na-na.", MT_FOOD, 0.3, OC_FOOD, SZ_TINY); addot(OT_BANANA, "banana", "Ba-na-na-na-na-na na-na na-na-na.", MT_FOOD, 0.3, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_YELLOW, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_YELLOW, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 50, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addot(OT_BANANASKIN, "banana skin", "A slippery banana skin.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); addot(OT_BANANASKIN, "banana skin", "A slippery banana skin.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_YELLOW, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_YELLOW, '%', NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 70, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_SLIPPERY, 15, NA, NA, NULL); addflag(lastot->flags, F_SLIPPERY, 15, NA, NA, NULL);
addflag(lastot->flags, F_SLIPMOVE, 15, NA, NA, NULL); addflag(lastot->flags, F_SLIPMOVE, 15, NA, NA, NULL);
addot(OT_BERRY, "berry", "Juicy, brightly coloured berries.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); addot(OT_BERRY, "berry", "Juicy, brightly coloured berries.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY);
@ -2441,11 +2456,13 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, 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_ANTNEST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_NUMAPPEAR, 1, 15, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 15, NA, "");
addot(OT_BREADFRESH, "loaf of fresh bread", "A freshly-baked loaf of bread.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addot(OT_BREADFRESH, "loaf of fresh bread", "A freshly-baked loaf of bread.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 200, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 200, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some bread"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some bread");
addot(OT_BREADGARLIC, "loaf of garlic bread", "A pungent loaf of garlic bread. Nauseates those around you and restores some health.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addot(OT_BREADGARLIC, "loaf of garlic bread", "A pungent loaf of garlic bread. Nauseates those around you and restores some health.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL);
@ -2459,10 +2476,12 @@ void initobjects(void) {
addflag(lastot->flags, F_EDIBLE, B_TRUE, 60, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 60, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addot(OT_CHOCOLATE, "block of chocolate", "An entire block of chocolate.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addot(OT_CHOCOLATE, "block of chocolate", "An entire block of chocolate.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 250, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 250, NA, "");
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_ANTNEST, 100, RR_COMMON, NULL);
addot(OT_CLOVER, "four leafed clover", "A rare 4-leafed clover.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); addot(OT_CLOVER, "four leafed clover", "A rare 4-leafed clover.", MT_FOOD, 0.1, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_GREEN, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREEN, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, "");
@ -2481,6 +2500,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some bread"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some bread");
addot(OT_CACFRUIT, "cactus fruit", "The nutritous fruit from a cactus plant.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addot(OT_CACFRUIT, "cactus fruit", "The nutritous fruit from a cactus plant.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_RED, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_RED, '%', NA, NULL);
@ -2491,12 +2511,14 @@ void initobjects(void) {
addflag(lastot->flags, F_EDIBLE, B_TRUE, 85, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 85, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addot(OT_GARLIC, "clove of garlic", "A very pungent clove of raw garlic. ", MT_FOOD, 0.1, OC_FOOD, SZ_TINY); addot(OT_GARLIC, "clove of garlic", "A very pungent clove of raw garlic. ", MT_FOOD, 0.1, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 5, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, "");
addot(OT_HOTDOG, "hot dog", "A chunk of meat sandwiched between two pieces of bread. Temporarily increases strength, and provides some healing.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addot(OT_HOTDOG, "hot dog", "A chunk of meat sandwiched between two pieces of bread. Temporarily increases strength, and provides some healing.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_RED, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_RED, '%', NA, NULL);
@ -2512,6 +2534,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, NULL);
addflag(lastot->flags, F_RARITY, H_SWAMP, 100, RR_FREQUENT, NULL); addflag(lastot->flags, F_RARITY, H_SWAMP, 100, RR_FREQUENT, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, "");
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "mushroom"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "mushroom");
addot(OT_MUSHROOMTOAD, "toadstool", "A poisonous variety of mushroom.", MT_FOOD, 0.2, OC_FOOD, SZ_TINY); addot(OT_MUSHROOMTOAD, "toadstool", "A poisonous variety of mushroom.", MT_FOOD, 0.2, OC_FOOD, SZ_TINY);
@ -2521,6 +2544,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, NULL);
addflag(lastot->flags, F_RARITY, H_SWAMP, 100, RR_FREQUENT, NULL); addflag(lastot->flags, F_RARITY, H_SWAMP, 100, RR_FREQUENT, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_PURIFIESTO, OT_MUSHROOMSHI, NA, NA, NULL); addflag(lastot->flags, F_PURIFIESTO, OT_MUSHROOMSHI, NA, NA, NULL);
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, "");
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "mushroom"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "mushroom");
@ -2531,6 +2555,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EDIBLE, B_TRUE, 22, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 22, NA, "");
addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 90, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 90, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_NUMAPPEAR, 1, 12, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 12, NA, "");
addflag(lastot->flags, F_GROWSTO, OT_TREE, VT_OB, NA, NULL); addflag(lastot->flags, F_GROWSTO, OT_TREE, VT_OB, NA, NULL);
addot(OT_ONION, "onion", "An edible bulb, known for its irritant effects on the eyes.", MT_FOOD, 0.2, OC_FOOD, SZ_TINY); addot(OT_ONION, "onion", "An edible bulb, known for its irritant effects on the eyes.", MT_FOOD, 0.2, OC_FOOD, SZ_TINY);
@ -2538,11 +2563,13 @@ void initobjects(void) {
addflag(lastot->flags, F_EDIBLE, B_TRUE, 60, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 60, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addot(OT_PASSIONFRUIT, "passionfruit", "A succulent passionfruit.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addot(OT_PASSIONFRUIT, "passionfruit", "A succulent passionfruit.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_MAGENTA, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_MAGENTA, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addot(OT_POISONSAC, "venom sac", "A small sac of flesh, filled with potent venom.", MT_FLESH, 0.2, OC_FOOD, SZ_TINY); // weight normally comes from corpse type addot(OT_POISONSAC, "venom sac", "A small sac of flesh, filled with potent venom.", MT_FLESH, 0.2, OC_FOOD, SZ_TINY); // weight normally comes from corpse type
addflag(lastot->flags, F_GLYPH, C_BLUE, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, "");
@ -2551,6 +2578,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_MAGENTA, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_MAGENTA, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 250, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 250, NA, "");
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_RARE, NULL);
addot(OT_ROASTMEAT, "chunk of roast meat", "A chunk of flame-roasted flesh.", MT_FLESH, 1, OC_FOOD, SZ_TINY); // weight normally comes from corpse type addot(OT_ROASTMEAT, "chunk of roast meat", "A chunk of flame-roasted flesh.", MT_FLESH, 1, OC_FOOD, SZ_TINY); // weight normally comes from corpse type
addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 100, NA, "");
@ -2582,6 +2610,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EDIBLE, B_TRUE, 30, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 30, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, NA, NULL);
// corpses // corpses
addot(OT_CORPSE, "corpse", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_TINY); addot(OT_CORPSE, "corpse", "xxx", MT_FLESH, 1, OC_CORPSE, SZ_TINY);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); // will be overridden addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); // will be overridden
@ -2593,6 +2622,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '%', NA, NULL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 25, NA, NULL); addflag(lastot->flags, F_EDIBLE, B_TRUE, 25, NA, NULL);
addflag(lastot->flags, F_ISMEAT, B_TRUE, 80, NA, ""); addflag(lastot->flags, F_ISMEAT, B_TRUE, 80, NA, "");
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, NULL);
addot(OT_FINGER, "severed finger", "The severed finger from some kind of creature.", MT_FLESH, 0.02, OC_CORPSE, SZ_TINY); addot(OT_FINGER, "severed finger", "The severed finger from some kind of creature.", MT_FLESH, 0.02, OC_CORPSE, SZ_TINY);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL); addflag(lastot->flags, F_EDIBLE, B_TRUE, 1, NA, NULL);
addflag(lastot->flags, F_ISMEAT, B_TRUE, 80, NA, ""); addflag(lastot->flags, F_ISMEAT, B_TRUE, 80, NA, "");
@ -4043,6 +4073,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Creatures with higher intelligence will take more damage."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Creatures with higher intelligence will take more damage.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, 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);
@ -8334,7 +8365,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STAYINROOM, NA, B_TRUE, NA, NULL); // stay in our room, but we can chase targets out. addflag(lastrace->flags, F_STAYINROOM, NA, B_MAYCHASE, NA, NULL); // stay in our room, but we can chase targets out.
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "50-100 gold coins"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "50-100 gold coins");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "+2 halberd"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "+2 halberd");
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great armour"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "great armour");
@ -8392,7 +8423,10 @@ void initrace(void) {
addflag(lastrace->flags, F_CANCAST, OT_S_ENTANGLE, NA, NA, "pw:10;"); addflag(lastrace->flags, F_CANCAST, OT_S_ENTANGLE, NA, NA, "pw:10;");
addflag(lastrace->flags, F_CANCAST, OT_S_BLINK, NA, NA, "pw:6;"); addflag(lastrace->flags, F_CANCAST, OT_S_BLINK, NA, NA, "pw:6;");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "grins"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "grins");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "cackles");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "gestures");
addflag(lastrace->flags, F_CASTCHANCE, 50, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 50, NA, NA, NULL);
addflag(lastrace->flags, F_CONSUMESOULS, 50, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "cackles evilly^an evil cackling"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "cackles evilly^an evil cackling");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
@ -9805,7 +9839,8 @@ void initrace(void) {
addflag(lastrace->flags, F_CASTTYPE, OT_S_CHARM, CT_GAZE, NA, NULL); addflag(lastrace->flags, F_CASTTYPE, OT_S_CHARM, CT_GAZE, NA, NULL);
//addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, 10, 10, NULL); //addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, 10, 10, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_PLANTWALK, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_PLANTWALK, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_CHARM, NA, B_APPENDYOU, "smiles seductively and beckons"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_CHARM, NA, B_APPENDYOU, "smiles seductively");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_CHARM, NA, B_APPENDYOU, "blows a kiss");
addflag(lastrace->flags, F_WANTSOBFLAG, F_GEM, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_GEM, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_WANTS, OT_GOLD, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
@ -10351,7 +10386,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 87, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 87, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_CAVE, 100, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, 80, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 80, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_UNCOMMON, NULL); addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 4, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 4, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); addflag(lastrace->flags, F_TR, 4, NA, NA, NULL);
@ -10359,7 +10394,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, ""); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL);
addflag(lastrace->flags, F_NUMAPPEAR, 2, 4, NA, NULL); addflag(lastrace->flags, F_NUMAPPEAR, 1, 3, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
@ -10376,7 +10411,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CANCAST, OT_S_PASSWALL, NA, NA, "pw:5;"); addflag(lastrace->flags, F_CANCAST, OT_S_PASSWALL, NA, NA, "pw:5;");
addflag(lastrace->flags, F_CASTCHANCE, 50, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 50, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_PASSWALL, NA, NA, NULL); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_PASSWALL, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_DIG, NA, NA, "burrows down into the ground"); addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_DIG, NA, NA, "burrows into a wall");
addflag(lastrace->flags, F_STABILITY, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STABILITY, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "shouts^a shout");
addflag(lastrace->flags, F_DODGES, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DODGES, B_TRUE, NA, NA, NULL);
@ -12820,6 +12855,35 @@ void initrace(void) {
addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings");
addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_EATCONFER, F_MUTABLE, B_TRUE, NA, "100"); addflag(lastrace->flags, F_EATCONFER, F_MUTABLE, B_TRUE, NA, "100");
addrace(R_BATBRAIN, "brain bat", 6, 'B', C_RED, MT_FLESH, RC_ANIMAL, "Rare bats, said to exhibit strange psionic behaviour.");
setbodytype(lastrace, BT_BIRD);
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_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_VERYFAST, NA, NA, "");
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, 4, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 2, NA, NULL);
addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings");
addflag(lastrace->flags, F_CANCAST, OT_S_STUN, 3, 3, "pw:3;");
addflag(lastrace->flags, F_CANCAST, OT_S_DISORIENT, 3, 3, "pw:3;");
addflag(lastrace->flags, F_CANCAST, OT_S_PSIBLAST, 3, 3, "pw:1;");
addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL);
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL);
addrace(R_BATVAMPIRE, "vampire bat", 6, 'B', C_BLUE, MT_FLESH, RC_ANIMAL, "Bats which suck the blood of their victims."); 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); setbodytype(lastrace, BT_BIRD);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
@ -13169,7 +13233,7 @@ void initrace(void) {
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL);
addrace(R_ANTS, "giant soldier ant", 25, 'a', C_RED, MT_FLESH, RC_ANIMAL, "The fighter of the giant ant family. Giant soldier ants are equipped with a powerful acidic stinger."); addrace(R_ANTS, "giant soldier ant", 25, 'a', C_ORANGE, MT_FLESH, RC_ANIMAL, "The fighter of the giant ant family. Giant soldier ants are equipped with a powerful acidic stinger.");
setbodytype(lastrace, BT_QUADRAPED); setbodytype(lastrace, BT_QUADRAPED);
lastrace->baseid = R_ANT; lastrace->baseid = R_ANT;
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -14646,7 +14710,10 @@ void initrace(void) {
addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_WORMGLUT, "glutwyrm", 25, 'W', C_MAGENTA, MT_FLESH, RC_DRAGON, "Gigantic wyrms who have become so obese over the centuries that they have evolved to be wingless. They swallow their prey whole, slowly digesting their still living bodies."); // end animals
// dragons / wyrms
addrace(R_WORMGLUT, "glutwyrm", 2500, 'W', C_MAGENTA, MT_FLESH, RC_DRAGON, "Gigantic wyrms who have become so obese over the centuries that they have evolved to be wingless. They swallow their prey whole, slowly digesting their still living bodies.");
addbodypart(lastrace, BP_HEAD, NULL); addbodypart(lastrace, BP_HEAD, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -14674,9 +14741,32 @@ void initrace(void) {
addflag(lastrace->flags, F_FLEEONHPPCT, 20, NA, NA, ""); addflag(lastrace->flags, F_FLEEONHPPCT, 20, NA, NA, "");
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
// end animals
// dragons / wyrms addrace(R_EARTHWYRM, "earthwyrm", 25, 'w', C_BROWN, MT_FLESH, RC_DRAGON, "Giant scaled wormlike creatures. Their large mouths are ringed with hundreds of sharp teeth.");
addbodypart(lastrace, BP_HEAD, NULL);
addbodypart(lastrace, BP_TAIL, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
//addflag(lastrace->flags, F_HATESALL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, 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_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_NOTALK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 2, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 4, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 8, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_ANTNEST, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 6, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_WALK, SV_TALK, NA, "^slithering");
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_WYVERN, "wyvern", 150, 'w', C_MAGENTA, MT_FLESH, RC_DRAGON, "Wyverns are smaller, malformed wyrms which were born without their usual breath powers."); addrace(R_WYVERN, "wyvern", 150, 'w', C_MAGENTA, MT_FLESH, RC_DRAGON, "Wyverns are smaller, malformed wyrms which were born without their usual breath powers.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -17007,7 +17097,7 @@ void initskills(void) {
addskilldesc(sk->id, PR_BEGINNER, "^gYou gain the 'wild strike' ability.^n", B_FALSE); addskilldesc(sk->id, PR_BEGINNER, "^gYou gain the 'wild strike' ability.^n", B_FALSE);
addskilldesc(sk->id, PR_ADEPT, "^g+10% damage bonus.^n", B_FALSE); addskilldesc(sk->id, PR_ADEPT, "^g+10% damage bonus.^n", B_FALSE);
addskilldesc(sk->id, PR_ADEPT, "^g+2 accuracy.^n", B_FALSE); addskilldesc(sk->id, PR_ADEPT, "^g+2 accuracy.^n", B_FALSE);
addskilldesc(sk->id, PR_ADEPT, "^gYou can now alter your attack style to deal different damage types^n.", B_FALSE); addskilldesc(sk->id, PR_ADEPT, "^gYou can now alter your attacks' damage types^n.", B_FALSE);
addskilldesc(sk->id, PR_SKILLED, "^g+3 accuracy, +20% damage bonus.^n", B_FALSE); addskilldesc(sk->id, PR_SKILLED, "^g+3 accuracy, +20% damage bonus.^n", B_FALSE);
addskilldesc(sk->id, PR_SKILLED, "^gYou can now block certain attacks with this kind of weapon.^n", B_FALSE); addskilldesc(sk->id, PR_SKILLED, "^gYou can now block certain attacks with this kind of weapon.^n", B_FALSE);
addskilldesc(sk->id, PR_EXPERT, "^g+4 accuracy, +30% damage bonus.^n", B_FALSE); addskilldesc(sk->id, PR_EXPERT, "^g+4 accuracy, +30% damage bonus.^n", B_FALSE);

Binary file not shown.

7
defs.h
View File

@ -78,6 +78,7 @@
#define B_TRUE (-1) #define B_TRUE (-1)
#define B_MAYBE (-2) #define B_MAYBE (-2)
#define B_MAYCHASE (-1)
#define B_ONLYEXTERNAL (-1) #define B_ONLYEXTERNAL (-1)
#define B_FORCE (-2) #define B_FORCE (-2)
#define B_ONPURPOSE (-1) #define B_ONPURPOSE (-1)
@ -1122,6 +1123,7 @@ enum RACE {
R_ANTS, R_ANTS,
R_ANTLION, R_ANTLION,
R_BAT, R_BAT,
R_BATBRAIN,
R_BATMUTATED, R_BATMUTATED,
R_BATVAMPIRE, R_BATVAMPIRE,
R_BEAR, R_BEAR,
@ -1185,6 +1187,7 @@ enum RACE {
R_DRAGONWHITE, R_DRAGONWHITE,
R_DRAGONWHITEY, R_DRAGONWHITEY,
R_DRAGONWHITEA, R_DRAGONWHITEA,
R_EARTHWYRM,
R_WYVERN, R_WYVERN,
// insects // insects
R_BLASTBUG, R_BLASTBUG,
@ -2894,6 +2897,7 @@ enum FLAG {
// power. if not given, power comes from depth. // power. if not given, power comes from depth.
F_NOSMELL, // lf can't smell. not affected by stench, and F_NOSMELL, // lf can't smell. not affected by stench, and
// can't get enhancesmell. // can't get enhancesmell.
F_NOTALK, // override ability to talk
F_RESTINGINMOTEL, // sounds will not wake up this lf. monster won't F_RESTINGINMOTEL, // sounds will not wake up this lf. monster won't
// see them. // see them.
// v0 = max time allowed to rest before checkout // v0 = max time allowed to rest before checkout
@ -2929,6 +2933,8 @@ enum FLAG {
F_GAVEMONEY, // v0 tracks how much money we gave away this turn F_GAVEMONEY, // v0 tracks how much money we gave away this turn
// used for r_godgreed anger effects. // used for r_godgreed anger effects.
F_CLIMBING, // lf is currently climbing a wall F_CLIMBING, // lf is currently climbing a wall
F_CONSUMESOULS, // lf gains hp from those who die nearby.
// up to v0% of their maxhp.
F_COUNTER, // generic counter flag for race abilities. F_COUNTER, // generic counter flag for race abilities.
F_DEBUG, // debugging enabled F_DEBUG, // debugging enabled
F_ACCURACYMOD, // modify your accuracy by val0 F_ACCURACYMOD, // modify your accuracy by val0
@ -3025,6 +3031,7 @@ enum FLAG {
F_STARTHIDDENPCT, // val0 = pct chance auto-generated monster will F_STARTHIDDENPCT, // val0 = pct chance auto-generated monster will
// start off hidden // start off hidden
F_CORPSETYPE, // text field specifies what corpse obtype to leave F_CORPSETYPE, // text field specifies what corpse obtype to leave
// NULL no corpse.
F_CORPSEFLAG, // add flag v0 to our corpse. F_CORPSEFLAG, // add flag v0 to our corpse.
// v1->v0, v2->v1, text->text // v1->v0, v2->v1, text->text
F_EXTRACORPSE, // text field specifies what additional corpse F_EXTRACORPSE, // text field specifies what additional corpse

2
god.c
View File

@ -793,7 +793,7 @@ lifeform_t *godappears(enum RACE rid, cell_t *where) {
strcpy(killedname, ""); strcpy(killedname, "");
if (!where) { if (!where) {
// somewhere next to the player. // somewhere next to the player.
where = real_getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, player); where = real_getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, player);
if (!where) { if (!where) {
where = getrandomadjcell(player->cell, B_FALSE, B_NOEXPAND); where = getrandomadjcell(player->cell, B_FALSE, B_NOEXPAND);
} }

144
lf.c
View File

@ -1584,6 +1584,9 @@ int cantalk(lifeform_t *lf) {
if (lfhasflag(lf, F_PHANTASM)) { if (lfhasflag(lf, F_PHANTASM)) {
return B_FALSE; return B_FALSE;
} }
if (lfhasflag(lf, F_NOTALK)) {
return B_FALSE;
}
// if the lf can't explicitly talk, check its race // if the lf can't explicitly talk, check its race
if (!lfhasflag(lf, F_CANTALK)) { if (!lfhasflag(lf, F_CANTALK)) {
if (!racecantalk(lf->race->id)) { if (!racecantalk(lf->race->id)) {
@ -1834,10 +1837,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
getlfname(lf, lfname); getlfname(lf, lfname);
// special case // special case
f = lfhasflagval(lf, F_SPELLCASTTEXT, sid, NA, NA, NULL); // specific text for this spell f = getspellcasttextflag(lf, sid);
if (!f) {
f = lfhasflagval(lf, F_SPELLCASTTEXT, OT_NONE, NA, NA, NULL); // generic spellcast
}
if (f) { if (f) {
if (strlen(f->text)) { if (strlen(f->text)) {
snprintf(whattosay, BUFLEN, "%s %s", lfname, f->text); snprintf(whattosay, BUFLEN, "%s %s", lfname, f->text);
@ -2792,6 +2792,13 @@ void die(lifeform_t *lf) {
char reanimateas[BUFLEN]; char reanimateas[BUFLEN];
cell_t *where; cell_t *where;
int thisisplayer = B_FALSE; int thisisplayer = B_FALSE;
// for earthwyrms etc dividing
enum RACE dividerace = R_NONE;
cell_t *dividecell[2] = {NULL, NULL};
char dividename[BUFLEN];
int dividetr, dividehp;
int dividelos = B_FALSE;
strcpy(reanimateas, ""); strcpy(reanimateas, "");
@ -2913,6 +2920,37 @@ void die(lifeform_t *lf) {
} }
noise(exitcell, NULL, NC_OTHER, SV_TALK, "a loud 'click'.", NULL); noise(exitcell, NULL, NC_OTHER, SV_TALK, "a loud 'click'.", NULL);
} }
if (lf->race->id == R_EARTHWYRM) {
// remember stats
dividehp = lf->maxhp / 2;
dividetr = gettr(lf) / 2;
if ((dividehp >= 1) && (dividetr >= 1)) {
dividerace = lf->race->id;
getlfname(lf, dividename);
if (cansee(player, lf)) dividelos = B_TRUE;
// are there 2 random cells free?
dividecell[0] = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_NOEXPAND, LOF_WALLSTOP, NULL, NULL, NULL);
if (dividecell[0]) {
dividecell[1] = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_NOEXPAND, LOF_WALLSTOP, NULL, dividecell[0], NULL);
}
if (!dividecell[1]) {
dividecell[1] = lf->cell;
}
if (dividecell[0] && dividecell[1]) {
// don't leave a corpse
killflagsofid(lf->flags, F_CORPSETYPE);
killflagsofid(lf->flags, F_EXTRACORPSE);
killflagsofid(lf->flags, F_NOCORPSE);
addflag(lf->flags, F_CORPSETYPE, NA, NA, NA, NULL);
}
}
}
if ((lf->race->id == R_VAMPIRE) && !hasflag(lf->flags, F_ORIGRACE)) { if ((lf->race->id == R_VAMPIRE) && !hasflag(lf->flags, F_ORIGRACE)) {
// if are asleep or killed by running water/sunlight, we will die normally // if are asleep or killed by running water/sunlight, we will die normally
if (lfhasflag(lf, F_ASLEEP) || (lf->lastdamtype == DT_DIRECT)) { if (lfhasflag(lf, F_ASLEEP) || (lf->lastdamtype == DT_DIRECT)) {
@ -3153,6 +3191,8 @@ void die(lifeform_t *lf) {
dropobs = B_FALSE; dropobs = B_FALSE;
} }
// drop/kill all objects // drop/kill all objects
if (corpsecell && (willbecomeghost || !thisisplayer)) { if (corpsecell && (willbecomeghost || !thisisplayer)) {
while (lf->pack->first) { while (lf->pack->first) {
@ -3174,6 +3214,23 @@ void die(lifeform_t *lf) {
// drop corpse/splatter blood // drop corpse/splatter blood
if (corpsecell) { if (corpsecell) {
lifeform_t *souleater = NULL;
flag_t *soulflag = NULL;
// soul consumed?
if (corpsecell) {
lifeform_t *l;
for (l = lf->cell->map->lf ; l ; l = l->next) {
if (haslos(l, lf->cell)) {
soulflag = lfhasflag(l, F_CONSUMESOULS);
if (soulflag) {
souleater = l;
break;
}
}
}
}
if (vaporised) { if (vaporised) {
if (lf->material->id == MT_FLESH) { if (lf->material->id == MT_FLESH) {
switch (rnd(1,2)) { switch (rnd(1,2)) {
@ -3185,6 +3242,23 @@ void die(lifeform_t *lf) {
break; break;
} }
} }
} else if (souleater && soulflag) {
int amt;
if (isplayer(souleater)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%cYou consume %s%s soul!", getlfcol(souleater, CC_GOOD), lfname, getpossessive(lfname));
} else if (cansee(player, souleater)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
getlfname(souleater, buf);
msg("^%c%s consumes %s%s soul!", getlfcol(souleater, CC_GOOD), buf, lfname, getpossessive(lfname));
}
amt = pctof( rnd(1,soulflag->val[0]), lf->maxhp);
limit(&amt, 1, NA);
gainhp(souleater, amt);
// drop bones
addob(corpsecell->obpile, "pile of ash");
} else if ((lf->lastdamtype == DT_BASH) && lfhasflag(lf, F_FROZEN)) { } else if ((lf->lastdamtype == DT_BASH) && lfhasflag(lf, F_FROZEN)) {
// shattered // shattered
fragments(corpsecell, "chunk of ice", 2, UNLIMITED); fragments(corpsecell, "chunk of ice", 2, UNLIMITED);
@ -3389,6 +3463,7 @@ void die(lifeform_t *lf) {
} }
} }
if (willbecomeghost) { if (willbecomeghost) {
flag_t *f, *nextf; flag_t *f, *nextf;
// remove all job flags // remove all job flags
@ -3473,6 +3548,31 @@ void die(lifeform_t *lf) {
// IMPORTANT: DO NOT REFERENCE lf->xxxx AFTER THIS POINT // IMPORTANT: DO NOT REFERENCE lf->xxxx AFTER THIS POINT
// UNLESS WE ARE _SURE_ IT IS THE PLAYER (ie. thisisplayer = true) // UNLESS WE ARE _SURE_ IT IS THE PLAYER (ie. thisisplayer = true)
if (dividerace != R_NONE) {
if (dividelos) {
msg("^w%s divides!", dividename);
}
// add two new worms nearby, with less hp.
for (i = 0;i < 2; i++) {
lifeform_t *newlf;
newlf = addmonster(dividecell[i], dividerace, NULL, B_FALSE, 1, B_FALSE, NULL);
if (newlf) {
// half hp
f = hasflag(newlf->flags, F_HITDICE);
f->val[0] = 0;
f->val[1] = 1;
f->val[2] = dividehp;
newlf->maxhp = dividehp;
newlf->hp = dividehp;
// half TR
f = hasflag(newlf->flags, F_TR);
f->val[0] = dividetr;
// no xp for killing
killflagsofid(newlf->flags, F_XPVAL);
addflag(newlf->flags, F_XPVAL, 0, NA, NA, NULL);
}
}
}
// Note that if we reanimate, the new monster will appear in an // Note that if we reanimate, the new monster will appear in an
@ -5798,7 +5898,7 @@ int flee(lifeform_t *lf) {
if (db) dblog("%s - failed to flee via %s", lfname, stairs->type->name); if (db) dblog("%s - failed to flee via %s", lfname, stairs->type->name);
} }
// move away from them // move away from them
if (!moveawayfrom(lf, fleefrom->cell, DT_ORTH, B_FALSE, B_FALSE, B_NOTONPURPOSE)) { if (!moveawayfrom(lf, fleefrom->cell, DT_ORTH, B_FALSE, B_FALSE, isplayer(lf) ? B_NOTONPURPOSE : B_ONPURPOSE)) {
if (db) dblog("%s - fleeing by moving away", lfname); if (db) dblog("%s - fleeing by moving away", lfname);
return B_TRUE; return B_TRUE;
} }
@ -8082,6 +8182,28 @@ int getsmellrange(lifeform_t *lf) {
return range; return range;
} }
flag_t *getspellcasttextflag(lifeform_t *lf, enum OBTYPE sid) {
flag_t *f;
flag_t *retflag[MAXCANDIDATES],*genposs[MAXCANDIDATES],*specposs[MAXCANDIDATES];
int nretflags,i,ngenposs = 0,nspecposs = 0;
getflags(lf->flags, retflag, &nretflags, F_SPELLCASTTEXT, F_NONE);
for (i = 0; i < nretflags; i++) {
if (retflag[i]->val[0] == sid ) {
specposs[nspecposs++] = retflag[i];
} else if (retflag[i]->val[0] == OT_NONE) {
genposs[ngenposs++] = retflag[i];
}
}
if (nspecposs) {
f = specposs[rnd(0,nspecposs-1)];
} else if (ngenposs) {
f = genposs[rnd(0,ngenposs-1)];
} else {
f = NULL;
}
return f;
}
glyph_t *getlfglyph(lifeform_t *lf) { glyph_t *getlfglyph(lifeform_t *lf) {
flag_t *f; flag_t *f;
@ -8600,7 +8722,15 @@ char *real_getlfname(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall,
if (!lfrace) { if (!lfrace) {
if (lfhasflag(lf, F_LYCANTHROPE)) { if (lfhasflag(lf, F_LYCANTHROPE)) {
// lycanthropes appear as human unless you know better // lycanthropes appear as human unless you know better
if (getlorelevel(player, RC_HUMANOID) >= PR_ADEPT) { if ((getlorelevel(player, RC_HUMANOID) >= PR_ADEPT) ||
(getlorelevel(player, RC_MAGIC) >= PR_BEGINNER)) {
lfrace = lf->race;
} else {
lfrace = findrace(R_HUMAN);
}
} else if (lf->race->id == R_ANDROID) {
if ((getlorelevel(player, RC_HUMANOID) >= PR_BEGINNER) ||
(getlorelevel(player, RC_ROBOT) >= PR_BEGINNER)) {
lfrace = lf->race; lfrace = lf->race;
} else { } else {
lfrace = findrace(R_HUMAN); lfrace = findrace(R_HUMAN);
@ -21614,7 +21744,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
// straight back down! // straight back down!
if (hasflag(o->flags, F_PIT) && (dir == D_UP) && !isairborne(lf)) { if (hasflag(o->flags, F_PIT) && (dir == D_UP) && !isairborne(lf)) {
cell_t *noholecell; cell_t *noholecell;
noholecell = real_getrandomadjcell(newcell, WE_WALKABLE, B_ALLOWEXPAND, LOF_NEED, NULL, NULL); noholecell = real_getrandomadjcell(newcell, WE_WALKABLE, B_ALLOWEXPAND, LOF_NEED, NULL, NULL, NULL );
if (noholecell) { if (noholecell) {
// go here instead // go here instead
newcell = noholecell; newcell = noholecell;

1
lf.h
View File

@ -197,6 +197,7 @@ object_t *getouterequippedob(lifeform_t *lf, enum BODYPART bp);
enum LFCONDITION getseenlfconditioncutoff(lifeform_t *lf); enum LFCONDITION getseenlfconditioncutoff(lifeform_t *lf);
char *getseenlfconditionname(lifeform_t *lf, lifeform_t *viewer); char *getseenlfconditionname(lifeform_t *lf, lifeform_t *viewer);
int getsmellrange(lifeform_t *lf); int getsmellrange(lifeform_t *lf);
flag_t *getspellcasttextflag(lifeform_t *lf, enum OBTYPE sid);
glyph_t *getlfglyph(lifeform_t *lf); glyph_t *getlfglyph(lifeform_t *lf);
enum MATERIAL getlfmaterial(lifeform_t *lf); enum MATERIAL getlfmaterial(lifeform_t *lf);
enum SKILLLEVEL getlorelevel(lifeform_t *lf, enum RACECLASS rcid); enum SKILLLEVEL getlorelevel(lifeform_t *lf, enum RACECLASS rcid);

393
map.c
View File

@ -132,7 +132,7 @@ void addhomeobs(lifeform_t *lf, int dolevelobs) {
cell_t *c; cell_t *c;
o = addob(homeobloc->obpile, f->text); o = addob(homeobloc->obpile, f->text);
if (o && (homeobloc == lf->cell) && isimpassableob(o, lf, SZ_ANY)) { if (o && (homeobloc == lf->cell) && isimpassableob(o, lf, SZ_ANY)) {
c = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL); c = real_getrandomadjcell(lf->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, NULL);
if (c) { if (c) {
homeobloc = c; // future obs will go here too. homeobloc = c; // future obs will go here too.
moveob(o, homeobloc->obpile, o->amt); moveob(o, homeobloc->obpile, o->amt);
@ -455,7 +455,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
lifeform_t *newlf; lifeform_t *newlf;
// find an adjacent cell to one of the newly added monsters, // find an adjacent cell to one of the newly added monsters,
// starting with the first one // starting with the first one
adjcell = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL); adjcell = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, NULL);
// did we find one? // did we find one?
if (!adjcell) break; if (!adjcell) break;
@ -505,7 +505,7 @@ lifeform_t *addmonster(cell_t *c, enum RACE rid, char *racename, int randomjobok
enum RACE newrid; enum RACE newrid;
race_t *newr; race_t *newr;
adjcell = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL); adjcell = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, NULL);
if (!adjcell) break; if (!adjcell) break;
newrid = parserace(f->text, NULL, NULL, NULL, NULL); newrid = parserace(f->text, NULL, NULL, NULL, NULL);
@ -1330,8 +1330,10 @@ int cellokforreachability(cell_t *startcell, cell_t *c, int srcroomid, int dir,
return B_MAYBE; return B_MAYBE;
} }
// kill everything in the given cell (lifeforms && objects)
// but DONT remove the cell itself.
void clearcell(cell_t *c) { void clearcell(cell_t *c) {
// kill everything there - (lifeforms && objects)
if (c->lf && !isplayer(c->lf)) { if (c->lf && !isplayer(c->lf)) {
killlf(c->lf); killlf(c->lf);
} }
@ -2950,13 +2952,6 @@ void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *
int numpasses = 50; int numpasses = 50;
// fill entire maze with walls
for (y = 0; y < map->h; y++) {
for (x = 0; x < map->w; x++) {
addcell(map, x, y);
}
}
// is the map lit? // is the map lit?
/* /*
@ -2978,11 +2973,22 @@ void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *
emptycell = getmapempty(map); emptycell = getmapempty(map);
solidcell = getmapsolid(map); solidcell = getmapsolid(map);
// fill entire maze with walls
for (y = 0; y < map->h; y++) {
for (x = 0; x < map->w; x++) {
c = getcellat(map, x, y);
setcelltype(c, solidcell);
}
}
// pick initial random points // pick initial random points
for (i = 0; i < numstartpos; i++) { for (i = 0; i < numstartpos; i++) {
c = getrandomcell(map); c = getrandomcell(map);
if (!c->locked) {
setcelltype(c, emptycell); setcelltype(c, emptycell);
} }
}
expand_cave(map, numpasses); expand_cave(map, numpasses);
@ -3060,13 +3066,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
enum CELLTYPE emptycell,solidcell; enum CELLTYPE emptycell,solidcell;
char buf[BUFLEN]; char buf[BUFLEN];
// fill entire maze with walls
for (y = 0; y < map->h; y++) {
for (x = 0; x < map->w; x++) {
addcell(map, x, y);
}
}
// select dungeon shape. // select dungeon shape.
if (onein(3)) { if (onein(3)) {
shape = rnd(0,MAXMAPSHAPES-1); shape = rnd(0,MAXMAPSHAPES-1);
@ -3171,7 +3170,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
} }
} }
// is the map lit? // is the map lit?
/* /*
@ -3191,36 +3189,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
*/ */
map->illumination = IL_FULLLIT; map->illumination = IL_FULLLIT;
// random chance of different wall type
if (onein(6)) {
switch (rnd(1,3)) {
case 1:
addflag(map->flags, F_CELLTYPESOLID, CT_WALLBRICK, NA, NA, NULL);
break;
case 2:
addflag(map->flags, F_CELLTYPESOLID, CT_WALLMETAL, NA, NA, NULL);
break;
case 3:
addflag(map->flags, F_CELLTYPESOLID, CT_WALLWOOD, NA, NA, NULL);
break;
}
}
// random chance of different floor type
if (onein(6)) {
switch (rnd(1,3)) {
case 1:
addflag(map->flags, F_CELLTYPEEMPTY, CT_FLOORCARPET, NA, NA, NULL);
break;
case 2:
addflag(map->flags, F_CELLTYPEEMPTY, CT_FLOORTILE, NA, NA, NULL);
break;
case 3:
addflag(map->flags, F_CELLTYPEEMPTY, CT_FLOORWOOD, NA, NA, NULL);
break;
}
}
// what kind of cells will 'empty' ones be? // what kind of cells will 'empty' ones be?
emptycell = getmapempty(map); emptycell = getmapempty(map);
solidcell = getmapsolid(map); solidcell = getmapsolid(map);
@ -3229,9 +3197,11 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
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 = getcellat(map, x, y); c = getcellat(map, x, y);
if (!getcellvault(c) && c->type->solid) {
setcelltype(c, solidcell); setcelltype(c, solidcell);
} }
} }
}
// pick initial random spot // pick initial random spot
if (corridortype == CDT_NORMAL) { if (corridortype == CDT_NORMAL) {
@ -3554,7 +3524,7 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
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 = getcellat(map, x, y);
setcelltype(c, onein(4) ? CT_DIRT : emptycell ); setcelltype(c, onein(4) ? CT_DIRT : emptycell );
} }
} }
@ -3641,7 +3611,6 @@ void createforest(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) { void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
map->nrooms = 0; // reset room counts
switch (map->habitat->id) { switch (map->habitat->id) {
case H_DUNGEON: case H_DUNGEON:
createdungeon(map, depth, parentmap, exitdir, entryob); createdungeon(map, depth, parentmap, exitdir, entryob);
@ -3750,7 +3719,10 @@ void createheaven(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
sparseness = how many times to chop off dead ends sparseness = how many times to chop off dead ends
looppct = percentage change of turning dead-end into loop looppct = percentage change of turning dead-end into loop
maxrooms = max # of rooms maxrooms = max # of rooms
exitdir = direction you WENT to get to this map.
*/ */
void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int exitdir, object_t *entryob) { void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int exitdir, object_t *entryob) {
lifeform_t *lf; lifeform_t *lf;
map_t *m; map_t *m;
@ -3759,6 +3731,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
enum HABITAT habitat; enum HABITAT habitat;
regionthing_t *thing[MAXOUTLINETHINGS]; regionthing_t *thing[MAXOUTLINETHINGS];
int nthings = 0,failed,nstairslinked = 0; int nthings = 0,failed,nstairslinked = 0;
int nprevaults = 0;
int db = B_TRUE; int db = B_TRUE;
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
@ -3979,52 +3952,28 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
if (db) dblog(" %d things remembered for later.",nthings); if (db) dblog(" %d things remembered for later.",nthings);
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
failed = B_TRUE; failed = B_TRUE;
while (failed) { while (failed) {
failed = B_FALSE; failed = B_FALSE;
// build it...
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
if (db) dblog(" creating map habitat."); selectcelltypes(map);
createhabitat(map, depth, parentmap, exitdir, entryob);
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
// add home objects // create initial map cells (they will be solid)
if (db) dblog(" adding home objects."); for (y = 0; y < map->h; y++) {
for (lf = map->lf ; lf ; lf = lf->next) { for (x = 0; x < map->w; x++) {
addhomeobs(lf, B_TRUE); addcell(map, x, y);
} }
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging }
map->nrooms = 0; // reset room counts
// place forced vaults.
if (db) dblog(" adding forced vaults first...");
// add outline things
if (db) dblog(" adding remembered region outline things...");
for (i = 0; i < nthings ;i++) { for (i = 0; i < nthings ;i++) {
vault_t *v; vault_t *v = NULL;
cell_t *c; //cell_t *c;
// add this thing
switch (thing[i]->whatkind) { switch (thing[i]->whatkind) {
case RT_HABITAT: // already handled above
break;
case RT_OBJECT:
if (db) dblog(" adding forced regionthing object: %s", thing[i]->what);
c = getrandomroomcell(map, ANYROOM, WE_WALKABLE);
if (!c) c = getrandomcell(map);
c = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL);
addob(c->obpile, thing[i]->what);
break;
case RT_LF:
if (db) dblog(" adding forced regionthing lifeform: %s", thing[i]->what);
c = getrandomroomcell(map, ANYROOM, WE_WALKABLE);
if (!c) c = getrandomcell(map);
c = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL);
addmonster(c, R_SPECIFIED, thing[i]->what, B_FALSE, thing[i]->value, B_TRUE, NULL);
break;
case RT_REGIONLINK:
if (db) dblog(" adding regionlink");
createregionlink(map, NULL, NULL, thing[i]->what, thing[i]->value, map->region);
// ... don't need to do this since we know there won't be anywhere to link to.
//linkstairs(o);
break;
case RT_VAULT: case RT_VAULT:
if (db) dblog(" adding vault"); if (db) dblog(" adding vault");
v = findvault(thing[i]->what); v = findvault(thing[i]->what);
@ -4052,8 +4001,83 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
failed = B_TRUE; failed = B_TRUE;
} }
break; break;
default:
break;
}
if (failed) break;
// did we make a vault?
if (v) {
room_t *r;
int x,y;
// lock all vault's cells
r = &map->room[map->nrooms-1];
for (y = r->y1; y <= r->y2; y++) {
for (x = r->x1; x <= r->x2; x++) {
cell_t *c;
c = getcellat(map, x, y);
c->locked = B_TRUE;
}
}
}
} // for each remembered thing
if (failed) {
dblog("********* got errors during forced vault placement - restarting map creation. *********");
unmakemap(map);
continue;
}
if (db) dblog(" finished forced vault creation (%d placed).", nprevaults);
// build it...
if (db) dblog(" starting map build.");
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
if (db) dblog(" creating map habitat.");
createhabitat(map, depth, parentmap, exitdir, entryob);
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
// add home objects
if (db) dblog(" adding home objects.");
for (lf = map->lf ; lf ; lf = lf->next) {
addhomeobs(lf, B_TRUE);
}
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
// add outline things
if (db) dblog(" adding remembered region outline things...");
for (i = 0; i < nthings ;i++) {
//vault_t *v;
cell_t *c;
// add this thing
switch (thing[i]->whatkind) {
case RT_HABITAT: // already handled above
break;
case RT_OBJECT:
if (db) dblog(" adding forced regionthing object: %s", thing[i]->what);
c = getrandomroomcell(map, ANYROOM, WE_WALKABLE);
if (!c) c = getrandomcell(map);
c = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, NULL);
addob(c->obpile, thing[i]->what);
break;
case RT_LF:
if (db) dblog(" adding forced regionthing lifeform: %s", thing[i]->what);
c = getrandomroomcell(map, ANYROOM, WE_WALKABLE);
if (!c) c = getrandomcell(map);
c = real_getrandomadjcell(c, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, NULL);
addmonster(c, R_SPECIFIED, thing[i]->what, B_FALSE, thing[i]->value, B_TRUE, NULL);
break;
case RT_REGIONLINK:
if (db) dblog(" adding regionlink");
createregionlink(map, NULL, NULL, thing[i]->what, thing[i]->value, map->region);
// ... don't need to do this since we know there won't be anywhere to link to.
//linkstairs(o);
break;
case RT_NONE: case RT_NONE:
break; break;
default:
break;
} }
} }
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
@ -4067,24 +4091,13 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
if (failed) { if (failed) {
region_t *r,*nextr;
dblog("********* got errors - restarting map creation. *********"); dblog("********* got errors - restarting map creation. *********");
// remove map flags added during vault creation. unmakemap(map);
killflagsofid(map->flags, F_MAPSHAPE); continue;
killflagsofid(map->flags, F_ROOMEXIT);
// unlink stairs on adjacent maps
unlinkstairsto(map);
// remove regions created by regionlinks in this map.
for (r = firstregion ; r ; r = nextr ){
nextr = r->next;
if (r->createdbymapid == map->id) {
killregion(r);
} }
} } // end while failed)
}
}
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
//if (gamemode == GM_GAMESTARTED) checkallflags(player->cell->map); // debugging
if (map->habitat->id == H_CAVE) { if (map->habitat->id == H_CAVE) {
// expand the cave a little more now that we've fixed reachability. // expand the cave a little more now that we've fixed reachability.
@ -4093,7 +4106,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
} }
// add any required stairs // add any required stairs
finalisemap(map, entryob); finalisemap(map, entryob, exitdir);
// special cases // special cases
// village - add town walls and clear it out // village - add town walls and clear it out
@ -4389,7 +4402,8 @@ void createsewer(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
// fill entire maze with walls // fill entire maze with walls
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++) {
addcell(map, x, y); c = getcellat(map, x, y);
setcelltype(c, getcellempty(c));
} }
} }
roomon = malloc((roomcountx * roomcounty) * sizeof(int)); roomon = malloc((roomcountx * roomcounty) * sizeof(int));
@ -4760,6 +4774,17 @@ int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *r
linkexits(map, roomid); linkexits(map, roomid);
} }
// lock cells if required
if (hasflag(v->flags, F_MAINTAINEDGE)) {
for (y = miny; y <= maxy; y++) {
for (x = minx; x <= maxx; x++) {
cell_t *c;
c = getcellat(map, x, y);
c->locked = B_TRUE;
}
}
}
// remove bones vault files after creation. // remove bones vault files after creation.
if (hasflagval(v->flags, F_VAULTTAG, NA, NA, NA, "bones")) { if (hasflagval(v->flags, F_VAULTTAG, NA, NA, NA, "bones")) {
removevaultfile(v->filename); removevaultfile(v->filename);
@ -5723,12 +5748,12 @@ void expand_cave(map_t *map, int numpasses) {
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 = getcellat(map, x, y); c = getcellat(map, x, y);
if (!c->type->solid && !c->visited) { // cell is empty and not processed already? if (!c->type->solid && !c->visited && !c->locked) { // cell is empty and not processed already?
cell_t *c2; cell_t *c2;
// check for surrounding solid cells // check for surrounding solid cells
for (dir = DC_N; dir <= DC_NW; dir++) { for (dir = DC_N; dir <= DC_NW; dir++) {
c2 = getcellindir(c, dir); c2 = getcellindir(c, dir);
if (c2 && c2->type->solid && pctchance(chancetoclear)) { if (c2 && c2->type->solid && !c2->locked && pctchance(chancetoclear)) {
setcelltype(c2, getmapempty(map)); setcelltype(c2, getmapempty(map));
} }
} }
@ -5768,7 +5793,7 @@ void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *c
} }
} }
void finalisemap(map_t *map, object_t *entryob) { void finalisemap(map_t *map, object_t *entryob, int exitdir) {
enum OBTYPE upstairtype, downstairtype; enum OBTYPE upstairtype, downstairtype;
int i,d,x,y; int i,d,x,y;
int linkedentry = B_FALSE; int linkedentry = B_FALSE;
@ -5850,7 +5875,7 @@ void finalisemap(map_t *map, object_t *entryob) {
} }
o = addobfast(c->obpile, upstairtype); o = addobfast(c->obpile, upstairtype);
assert(o); assert(o);
if (entryob && !linkedentry) { if (entryob && (exitdir == D_DOWN) && !linkedentry) {
linkstairs(o, entryob); linkstairs(o, entryob);
linkedentry = B_TRUE; linkedentry = B_TRUE;
} else { } else {
@ -5864,24 +5889,6 @@ void finalisemap(map_t *map, object_t *entryob) {
} }
} }
// if our up stairs were created by a vault, then we now need to link them.
if (entryob && !linkedentry) {
for (y = 0; (y < map->h) && !linkedentry; y++) {
for (x = 0; (x < map->w) && !linkedentry; x++) {
c = getcellat(map, x, y);
o = hasob(c->obpile, upstairtype);
if (o && !hasflag(o->flags, F_MAPLINK)) {
linkstairs(o, entryob);
linkedentry = B_TRUE;
break;
}
}
}
if (!linkedentry) {
dblog("ERROR - couldn't link stairs back to map entry object.");
msg("ERROR - couldn't link stairs back to map entry object."); more();
}
}
// DOWN STAIRS // DOWN STAIRS
if ((downstairtype != OT_NONE) && (map->depth < map->region->rtype->maxdepth)) { if ((downstairtype != OT_NONE) && (map->depth < map->region->rtype->maxdepth)) {
@ -5897,21 +5904,52 @@ void finalisemap(map_t *map, object_t *entryob) {
} }
o = addobfast(c->obpile, downstairtype); o = addobfast(c->obpile, downstairtype);
assert(o); assert(o);
if (entryob && (exitdir == D_UP) && !linkedentry) {
linkstairs(o, entryob);
linkedentry = B_TRUE;
} else {
linkstairs(o, NULL); linkstairs(o, NULL);
} }
} }
}
// if our up/down stairs were created by a vault, then we now need to link them.
if (entryob && !linkedentry) {
enum OBTYPE wantoid;
if (exitdir == D_DOWN) {
wantoid = upstairtype;
} else {
wantoid = downstairtype;
}
for (y = 0; (y < map->h) && !linkedentry; y++) {
for (x = 0; (x < map->w) && !linkedentry; x++) {
c = getcellat(map, x, y);
o = hasob(c->obpile, wantoid);
if (o && !hasflag(o->flags, F_MAPLINK)) {
linkstairs(o, entryob);
linkedentry = B_TRUE;
break;
}
}
}
if (!linkedentry) {
dblog("ERROR - couldn't link stairs back to map entry object.");
msg("ERROR - couldn't link stairs back to map entry object."); more();
}
}
// other finalisation tasks...
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 = getcellat(map, x, y); c = getcellat(map, x, y);
for (o = c->obpile->first ; o ; o = nexto) { for (o = c->obpile->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
if (c->room && c->room->vault) { if (!getcellvault(c)) {
} else { // remove doors which go nowhere (internal to rooms)
// remove doors which go nowhere
if (isdoor(o, NULL)) { if (isdoor(o, NULL)) {
int dir, ok = B_FALSE; int dir, ok = B_FALSE;
cell_t *c2; /*
// check all directions for a cell which isn't // check all directions for a cell which isn't
// part of this room. // part of this room.
for (dir = DC_N; dir <= DC_NW; dir++) { for (dir = DC_N; dir <= DC_NW; dir++) {
@ -5921,6 +5959,18 @@ void finalisemap(map_t *map, object_t *entryob) {
break; break;
} }
} }
*/
// doors must be between two solid cells
for (dir = DC_N; dir <= DC_NW; dir++) {
cell_t *c1;
cell_t *c2;
c1 = getcellindir(c, dir);
c2 = getcellindir(c, diropposite(dir));
if (issolid(c1) && issolid(c2)) {
ok = B_TRUE;
break;
}
}
if (!ok) { if (!ok) {
killob(o); killob(o);
continue; continue;
@ -6618,10 +6668,10 @@ int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved) {
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand) { cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand) {
return real_getrandomadjcell(c, wantempty, allowexpand, LOF_NEED, NULL, NULL); return real_getrandomadjcell(c, wantempty, allowexpand, LOF_NEED, NULL, NULL, NULL);
} }
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob, lifeform_t *preferlos) { cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob, cell_t *dontwantcell, lifeform_t *preferlos) {
int radius = 1; int radius = 1;
int x,y; int x,y;
cell_t *poss[MAXCANDIDATES]; cell_t *poss[MAXCANDIDATES];
@ -6638,6 +6688,7 @@ cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LO
if (new && if (new &&
(new != c) && (new != c) &&
(getcelldist(c,new) == radius) && (getcelldist(c,new) == radius) &&
(new != dontwantcell) &&
haslof(c, new, needlof, NULL)) { haslof(c, new, needlof, NULL)) {
enum OBTYPE *badoid; enum OBTYPE *badoid;
int ok = B_FALSE; int ok = B_FALSE;
@ -7499,7 +7550,7 @@ int linkholes(map_t *map) {
// this will automatically avoid lifeforms since we're using // this will automatically avoid lifeforms since we're using
// we_walkable rather than we_notwall. this saves problems // we_walkable rather than we_notwall. this saves problems
// with someine coming up underneath you! // with someine coming up underneath you!
c2 = real_getrandomadjcell(c2, WE_NOLF, B_ALLOWEXPAND, LOF_DONTNEED, &ot->id, NULL); c2 = real_getrandomadjcell(c2, WE_NOLF, B_ALLOWEXPAND, LOF_DONTNEED, &ot->id, NULL, NULL);
} }
// clear out the cell if required // clear out the cell if required
if (c2->type->solid) { if (c2->type->solid) {
@ -8105,6 +8156,39 @@ int remove_deadends(map_t *m, int howmuch) {
return count; return count;
} }
void selectcelltypes(map_t *map) {
if (map->habitat->id == H_DUNGEON) {
// random chance of different wall type
if (onein(6)) {
switch (rnd(1,3)) {
case 1:
addflag(map->flags, F_CELLTYPESOLID, CT_WALLBRICK, NA, NA, NULL);
break;
case 2:
addflag(map->flags, F_CELLTYPESOLID, CT_WALLMETAL, NA, NA, NULL);
break;
case 3:
addflag(map->flags, F_CELLTYPESOLID, CT_WALLWOOD, NA, NA, NULL);
break;
}
}
// random chance of different floor type
if (onein(6)) {
switch (rnd(1,3)) {
case 1:
addflag(map->flags, F_CELLTYPEEMPTY, CT_FLOORCARPET, NA, NA, NULL);
break;
case 2:
addflag(map->flags, F_CELLTYPEEMPTY, CT_FLOORTILE, NA, NA, NULL);
break;
case 3:
addflag(map->flags, F_CELLTYPEEMPTY, CT_FLOORWOOD, NA, NA, NULL);
break;
}
}
}
}
void set_scanned_glyph(int targettype, void *what, char *descappend, char *desc, glyph_t *glyph) { void set_scanned_glyph(int targettype, void *what, char *descappend, char *desc, glyph_t *glyph) {
if (targettype == TT_MONSTER) { if (targettype == TT_MONSTER) {
if (desc) { if (desc) {
@ -8273,7 +8357,7 @@ int unlinkstairsto(map_t *unlinkmap) {
int db = B_TRUE; int db = B_TRUE;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
if (db) dblog("starting unlinkstairsto for unlikmap='%s'",unlinkmap->name); if (db) dblog(" starting unlinkstairsto for unlinkmap='%s'",unlinkmap->name);
// get a list of all stair object ids on this unlinkmap. // get a list of all stair object ids on this unlinkmap.
for (y = 0; y < unlinkmap->h; y++) { for (y = 0; y < unlinkmap->h; y++) {
for (x = 0; x < unlinkmap->w; x++) { for (x = 0; x < unlinkmap->w; x++) {
@ -8288,7 +8372,7 @@ int unlinkstairsto(map_t *unlinkmap) {
if (db) dblog(" found %d stairs on unlinkmap.",nbadids); if (db) dblog(" found %d stairs on unlinkmap.",nbadids);
// go through all maps and remove any stairs which link to unlinkmap // go through all maps and remove any stairs which link to unlinkmap
if (db) dblog(" searching other maps for stairs linking to unlinkmap."); if (db) dblog(" searching other maps for stairs linking TO unlinkmap.");
for (m = firstmap ; m ; m = m->next) { for (m = firstmap ; m ; m = m->next) {
for (y = 0; y < m->h; y++) { for (y = 0; y < m->h; y++) {
for (x = 0; x < m->w; x++) { for (x = 0; x < m->w; x++) {
@ -8320,7 +8404,7 @@ int unlinkstairsto(map_t *unlinkmap) {
} }
// now remove all links from stairs on unlinkmap // now remove all links from stairs on unlinkmap
if (db) dblog(" removing maplinks from stairs on unlinkmap."); if (db) dblog(" removing maplinks FROM stairs on unlinkmap.");
for (y = 0; y < unlinkmap->h; y++) { for (y = 0; y < unlinkmap->h; y++) {
for (x = 0; x < unlinkmap->w; x++) { for (x = 0; x < unlinkmap->w; x++) {
c = getcellat(unlinkmap, x,y); c = getcellat(unlinkmap, x,y);
@ -8329,10 +8413,43 @@ int unlinkstairsto(map_t *unlinkmap) {
} }
} }
} }
if (db) dblog("finished unlinkstairsto for unlikmap='%s'",unlinkmap->name); if (db) dblog(" finished unlinkstairsto for unlinkmap='%s'",unlinkmap->name);
return B_FALSE; return B_FALSE;
} }
void unmakemap(map_t *map) {
region_t *r,*nextr;
int i;
int db = B_TRUE;
int nlf = 0,nreg = 0;
if (db) dblog("unmaking map.");
// remove map lifeforms
while (map->lf) {
killlf(map->lf);
nlf++;
}
if (db) dblog(" %d lifeforms removed.", nlf);
// remove map flags added during vault creation.
killflagsofid(map->flags, F_MAPSHAPE);
killflagsofid(map->flags, F_ROOMEXIT);
// unlink stairs on adjacent maps
unlinkstairsto(map);
// remove regions created by regionlinks in this map.
for (r = firstregion ; r ; r = nextr ){
nextr = r->next;
if (r->createdbymapid == map->id) {
killregion(r);
nreg++;
}
}
if (db) dblog(" %d linked regions removed.", nreg);
// free cells on this map
for (i = 0; i < (map->w*map->h); i++){
killcell(map->cell[i]);
free(map->cell[i]);
map->cell[i] = NULL;
}
}
void updateknowncells(void) { void updateknowncells(void) {
//int x,y; //int x,y;

6
map.h
View File

@ -96,7 +96,7 @@ void dumpmap(map_t *map, int showrooms);
void expand_cave(map_t *map, int numpasses); void expand_cave(map_t *map, int numpasses);
void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *centre); void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *centre);
void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int dirtype, int wantannounce); void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int dirtype, int wantannounce);
void finalisemap(map_t *map, object_t *entryob); void finalisemap(map_t *map, object_t *entryob, int exitdir);
void finalisemonster(lifeform_t *lf, lifeform_t *leader, flagpile_t *wantflags, enum BEHAVIOUR wantbehaviour, int idx); void finalisemonster(lifeform_t *lf, lifeform_t *leader, flagpile_t *wantflags, enum BEHAVIOUR wantbehaviour, int idx);
celltype_t *findcelltype(enum CELLTYPE cid); celltype_t *findcelltype(enum CELLTYPE cid);
celltype_t *findcelltypebyname(char *name); celltype_t *findcelltypebyname(char *name);
@ -128,7 +128,7 @@ int getnewdigdir(cell_t *cell, int lastdir, int turnpct, int *moved);
int getobchance(int habitat); int getobchance(int habitat);
int getthingchance(int habitat); int getthingchance(int habitat);
cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand); cell_t *getrandomadjcell(cell_t *c, int wantempty, int allowexpand);
cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob, lifeform_t *preferlos); cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LOFTYPE needlof, enum OBTYPE *dontwantob, cell_t *dontwantcell, lifeform_t *preferlos);
cell_t *getrandomcell(map_t *map); cell_t *getrandomcell(map_t *map);
cell_t *getrandomcelloftype(map_t *map, enum CELLTYPE id); cell_t *getrandomcelloftype(map_t *map, enum CELLTYPE id);
int getrandomdir(int dirtype); int getrandomdir(int dirtype);
@ -180,12 +180,14 @@ void moveobtoclearcell(object_t *o);
int orthdir(int compassdir); int orthdir(int compassdir);
enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob, enum SUBJOB *wantsubjob, enum BEHAVIOUR *wantbehaviour); enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob, enum SUBJOB *wantsubjob, enum BEHAVIOUR *wantbehaviour);
int remove_deadends(map_t *m, int howmuch); int remove_deadends(map_t *m, int howmuch);
void selectcelltypes(map_t *map);
void set_scanned_glyph(int targettype, void *what, char *descappend, char *desc, glyph_t *glyph); void set_scanned_glyph(int targettype, void *what, char *descappend, char *desc, glyph_t *glyph);
void setcellknown(cell_t *cell, int forcelev); void setcellknown(cell_t *cell, int forcelev);
void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype); void setcellknownradius(cell_t *centre, int forcelev, int radius, int dirtype);
void setcelltype(cell_t *cell, enum CELLTYPE id); void setcelltype(cell_t *cell, enum CELLTYPE id);
int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring); int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring);
int unlinkstairsto(map_t *unlinkmap); int unlinkstairsto(map_t *unlinkmap);
void unmakemap(map_t *map);
void updateknowncells(void); void updateknowncells(void);
int validateregions(void); int validateregions(void);
int validateregionthing(regionthing_t *thing); int validateregionthing(regionthing_t *thing);

View File

@ -377,7 +377,7 @@ int main(int argc, char **argv) {
assert(r); assert(r);
// create pet, in view of player if possible. // create pet, in view of player if possible.
c = real_getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_NEED, &avoidob, player); c = real_getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_NEED, &avoidob, NULL, player);
assert(c); assert(c);
pet = addlf(c, r->id, 1); pet = addlf(c, r->id, 1);
// mark us as its master // mark us as its master

21
save.c
View File

@ -359,7 +359,11 @@ map_t *loadmap(FILE *f) {
// load room defs // load room defs
fscanf(f, "nrooms:%d\n",&m->nrooms); fscanf(f, "nrooms:%d\n",&m->nrooms);
for (i = 0; i < m->nrooms; i++) { for (i = 0; i < m->nrooms; i++) {
fscanf(f, "%d,%d,%d,%d,%d,%s\n",&m->room[i].id, char line[BUFLEN];
fgets(line, BUFLEN, f);
//if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0';
sscanf(line, "%d,%d,%d,%d,%d,%[ a-xA-Z_0-9+'*/-]\n",&m->room[i].id,
&m->room[i].x1, &m->room[i].y1, &m->room[i].x1, &m->room[i].y1,
&m->room[i].x2, &m->room[i].y2, buf); &m->room[i].x2, &m->room[i].y2, buf);
m->room[i].vault = findvault(buf); m->room[i].vault = findvault(buf);
@ -630,6 +634,7 @@ int loadregions(FILE *f) {
if (db) dblog("Found %d region outlines.\n",numoutlines); if (db) dblog("Found %d region outlines.\n",numoutlines);
for (n = 0; n < numoutlines; n++) { for (n = 0; n < numoutlines; n++) {
regionthing_t *thing; regionthing_t *thing;
if (db) dblog(" loading regionoutline #%d / %d",n+1, numoutlines);
fscanf(f, "startro\n"); fscanf(f, "startro\n");
fscanf(f, "rtypeid:%d\n",&rtid); // region type id fscanf(f, "rtypeid:%d\n",&rtid); // region type id
addregionoutline(rtid); addregionoutline(rtid);
@ -638,19 +643,25 @@ int loadregions(FILE *f) {
for (i = 0; i < nthings; i++) { for (i = 0; i < nthings; i++) {
int depth,x,y,val,id; int depth,x,y,val,id;
enum REGIONTHING whatkind; enum REGIONTHING whatkind;
char buf[BUFLEN],*p; char buf[BUFLEN];
fscanf(f, "startthing\n"); fscanf(f, "startthing\n");
fscanf(f, " thingid:%d\n",&id); fscanf(f, " thingid:%d\n",&id);
fscanf(f, " thingdepth:%d,%d,%d\n",&depth, &x, &y); fscanf(f, " thingdepth:%d,%d,%d\n",&depth, &x, &y);
fscanf(f, " thingkind:%d\n",(int *)&whatkind); fscanf(f, " thingkind:%d\n",(int *)&whatkind);
fscanf(f, " thingval:%d\n",&val); fscanf(f, " thingval:%d\n",&val);
fscanf(f, " thingwhat:%s\n",buf); fscanf(f, " thingwhat:%[ a-xA-Z_0-9+'*/-]\n",buf);
fscanf(f, "endthing\n"); fscanf(f, "endthing\n");
// replace ^ with ' ' in thingwhat // replace ^ with ' ' in thingwhat
/*
for (p = buf ; *p; p++) { for (p = buf ; *p; p++) {
if (*p == '^') *p = ' '; if (*p == '^') *p = ' ';
} }
*/
if (db) dblog(" got regionthing: [%s]", buf);
thing = addregionthing(lastregionoutline, depth, x, y, whatkind, val, streq(buf, "NULL") ? NULL : buf); thing = addregionthing(lastregionoutline, depth, x, y, whatkind, val, streq(buf, "NULL") ? NULL : buf);
thing->id = id; thing->id = id;
} }
@ -1216,11 +1227,13 @@ int saveregions(FILE *f) {
fprintf(f, " thingkind:%d\n",(int)ro->thing[i].whatkind); fprintf(f, " thingkind:%d\n",(int)ro->thing[i].whatkind);
fprintf(f, " thingval:%d\n",(int)ro->thing[i].value); fprintf(f, " thingval:%d\n",(int)ro->thing[i].value);
if (strlen(ro->thing[i].what)) { if (strlen(ro->thing[i].what)) {
char localwhat[BUFLEN],*p; char localwhat[BUFLEN];
strcpy(localwhat,ro->thing[i].what); strcpy(localwhat,ro->thing[i].what);
/*
for (p = localwhat ; *p; p++) { for (p = localwhat ; *p; p++) {
if (*p == ' ') *p = '^'; if (*p == ' ') *p = '^';
} }
*/
fprintf(f, " thingwhat:%s\n",localwhat); fprintf(f, " thingwhat:%s\n",localwhat);
} else { } else {
fprintf(f, " thingwhat:NULL\n"); fprintf(f, " thingwhat:NULL\n");

16
spell.c
View File

@ -6207,7 +6207,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
badoid[1] = OT_NONE; badoid[1] = OT_NONE;
for (i = 0; i < amt; i++) { for (i = 0; i < amt; i++) {
cell_t *c; cell_t *c;
c = real_getrandomadjcell(targcell, WE_NOTWALL, B_ALLOWEXPAND, LOF_WALLSTOP, badoid, NULL); c = real_getrandomadjcell(targcell, WE_NOTWALL, B_ALLOWEXPAND, LOF_WALLSTOP, badoid, NULL, NULL);
if (c) { if (c) {
object_t *water; object_t *water;
water = addob(c->obpile, "water"); water = addob(c->obpile, "water");
@ -7691,7 +7691,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
job_t *j; job_t *j;
object_t *o; object_t *o;
// create a mirror image // create a mirror image
targcell = real_getrandomadjcell(caster->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_NEED, NULL, caster); targcell = real_getrandomadjcell(caster->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_NEED, NULL, NULL, caster);
if (!targcell) break; if (!targcell) break;
lf = clonelf(caster, targcell); lf = clonelf(caster, targcell);
if (!lf) break; if (!lf) break;
@ -8193,7 +8193,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
if (dstcell && !cellwalkable(caster, dstcell, NULL)) { if (dstcell && !cellwalkable(caster, dstcell, NULL)) {
dstcell = real_getrandomadjcell(dstcell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL); dstcell = real_getrandomadjcell(dstcell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, NULL);
} }
if (dstcell) { if (dstcell) {
@ -8316,7 +8316,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
if (!cellwalkable(caster, targcell, NULL)) { if (!cellwalkable(caster, targcell, NULL)) {
targcell = real_getrandomadjcell(targcell, WE_WALKABLE, B_NOEXPAND, LOF_DONTNEED, NULL, NULL); targcell = real_getrandomadjcell(targcell, WE_WALKABLE, B_NOEXPAND, LOF_DONTNEED, NULL, NULL, NULL);
if (!targcell) { if (!targcell) {
fizzle(caster); fizzle(caster);
return B_FALSE; return B_FALSE;
@ -8713,7 +8713,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
object_t *srcportal,*dstportal; object_t *srcportal,*dstportal;
// find adjacent cell for portal // find adjacent cell for portal
srccell = real_getrandomadjcell(caster->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_NEED, NULL, caster); srccell = real_getrandomadjcell(caster->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_NEED, NULL, NULL, caster);
if (!srccell) { if (!srccell) {
fizzle(caster); fizzle(caster);
return B_TRUE; return B_TRUE;
@ -10684,7 +10684,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
badoid[0] = OT_MUDPOOL; badoid[0] = OT_MUDPOOL;
badoid[1] = OT_NONE; badoid[1] = OT_NONE;
for (i = 0; i < powerleft; i++) { for (i = 0; i < powerleft; i++) {
c = real_getrandomadjcell(targcell, WE_NOTWALL, B_ALLOWEXPAND, LOF_DONTNEED, badoid, NULL); c = real_getrandomadjcell(targcell, WE_NOTWALL, B_ALLOWEXPAND, LOF_DONTNEED, badoid, NULL, NULL);
if (c) { if (c) {
o = addob(c->obpile, "pool of mud"); o = addob(c->obpile, "pool of mud");
if (o) { if (o) {
@ -12494,7 +12494,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (hasflag(o->flags, F_IMPASSABLE)) { if (hasflag(o->flags, F_IMPASSABLE)) {
cell_t *newloc; cell_t *newloc;
// if so, don't put it where the player is! // if so, don't put it where the player is!
newloc = real_getrandomadjcell(target->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, target); newloc = real_getrandomadjcell(target->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, target);
o = relinkob(o, newloc->obpile); o = relinkob(o, newloc->obpile);
} }
if (o) { if (o) {
@ -13739,7 +13739,7 @@ int summonlfs(lifeform_t *caster, cell_t *where, enum RACE wantrace, enum RACECL
for (i = 0; i < howmany; i++) { for (i = 0; i < howmany; i++) {
// get random adjacent cell // get random adjacent cell
// (prefer cells in sight of caster) // (prefer cells in sight of caster)
c = real_getrandomadjcell(where, WE_EMPTY, B_ALLOWEXPAND, LOF_NEED, NULL, caster); c = real_getrandomadjcell(where, WE_EMPTY, B_ALLOWEXPAND, LOF_NEED, NULL, NULL, caster);
if (!c) { if (!c) {
return ncreated; return ncreated;
} }

5
text.c
View File

@ -1134,6 +1134,7 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
if (damtype == DT_SLASH) { if (damtype == DT_SLASH) {
skill_t *sk; skill_t *sk;
int canbehead = B_TRUE; int canbehead = B_TRUE;
if (wep) { if (wep) {
sk = getobskill(wep->flags); sk = getobskill(wep->flags);
if (sk && (sk->id != SK_LONGBLADES) && (sk->id != SK_EXOTICWEPS)) { if (sk && (sk->id != SK_LONGBLADES) && (sk->id != SK_EXOTICWEPS)) {
@ -1142,7 +1143,9 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
} }
} }
if (canbehead) { if (canbehead) {
if (!hasbp(victim, BP_HEAD)) { if (victim && (victim->race->id == R_EARTHWYRM)) {
return "bisect";
} else if (!hasbp(victim, BP_HEAD)) {
return "bisect"; return "bisect";
} else { } else {
if ((getlfsize(victim) >= SZ_MEDIUM) && onein(3)) { if ((getlfsize(victim) >= SZ_MEDIUM) && onein(3)) {

View File

@ -1346,7 +1346,7 @@ int handleline(vault_t *v, char *line) {
dblog("invalid goesin() definition: '%s'", line); dblog("invalid goesin() definition: '%s'", line);
} }
} else if (streq(line, "keepmonsinroom")) { } else if (streq(line, "keepmonsinroom")) {
addflag(v->flags, F_STAYINROOM, NA, B_TRUE, NA, NULL); addflag(v->flags, F_STAYINROOM, NA, B_MAYCHASE, NA, NULL);
ok = B_TRUE; ok = B_TRUE;
} else if (streq(line, "maintainedge")) { } else if (streq(line, "maintainedge")) {
addflag(v->flags, F_MAINTAINEDGE, B_TRUE, NA, NA, NULL); addflag(v->flags, F_MAINTAINEDGE, B_TRUE, NA, NA, NULL);