- [+] make ring of invisibility also drain your hp!
- [+] monster with tremorsense can 'hear' - [+] allow attacking of wall cells with normal melee attacks - [+] glass should shatter - [+] option: stop running on hearing a sound - [+] make describerace use downline(). - [+] make certain strengths and weaknesses not show up in player selection - [+] An uncursed manriki wraps around the hawk. The hawk falls to the ground. A black bear comes into view. You critically scratch #. The black bear roars. - [+] check construct_hit_string. - [+] i was hitting a hawk. - [+] still some entrances overlapping glyphs. - [+] genericise checking code in fix_Reachabilty - [+] Also: in fix_reachability, disallow linking to cells which: - [+] are adjacent to a door - [+] are part of a vault with maintain_edge, and are 't marked as exits. - [+] looking a bit better now... - [+] incorrect glyph colour for animated zombies - [+] grow/shrink potions? to change lf size to fit armour. - [+] resizelf() - [+] modification spell (l2) - [+] grow - [+] shrink - [+] potions - [+] cursed growth does shrink - [+] make rare monsters / objects only sometimes be known.
This commit is contained in:
parent
4cff04558c
commit
bbaca368e7
210
attack.c
210
attack.c
|
@ -157,6 +157,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
AT_NONE = 0,
|
||||
AT_LF = 1,
|
||||
AT_OB = 2,
|
||||
AT_WALL = 3,
|
||||
} attacktype = AT_NONE;
|
||||
void *attacktarget;
|
||||
int attacklfid = -1;
|
||||
|
@ -279,31 +280,16 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
attacktype = AT_OB;
|
||||
attacktarget = o;
|
||||
} else {
|
||||
// TODO: attack wall?
|
||||
if (!lfhasflag(lf, F_HURRICANESTRIKE)) {
|
||||
/*
|
||||
flag_t *sf;
|
||||
lifeform_t *stomachlf = NULL;
|
||||
sf = hasflag(lf->cell->map->flags, F_STOMACHOF);
|
||||
if (sf) {
|
||||
stomachlf = findlf(NULL, sf->val[0]);
|
||||
}
|
||||
// we ARE allowed to attack stomach walls.
|
||||
if (sf && stomachlf && (c->type->id == CT_WALLFLESH)) {
|
||||
attacktype = AT_LF;
|
||||
attacktarget = stomachlf;
|
||||
} else {
|
||||
// not allowed to attack normal walls
|
||||
if (c->type->solid) {
|
||||
attacktype = AT_WALL;
|
||||
attacktarget = c;
|
||||
} else {
|
||||
if (isplayer(lf)) {
|
||||
msg("There is nothing there to attack!");
|
||||
}
|
||||
return B_TRUE;
|
||||
}
|
||||
*/
|
||||
if (isplayer(lf)) {
|
||||
msg("There is nothing there to attack!");
|
||||
}
|
||||
return B_TRUE;
|
||||
} // end if !hurricanestrike
|
||||
}
|
||||
}
|
||||
|
@ -450,6 +436,12 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
|
|||
attacksdone = maxattacks;
|
||||
break;
|
||||
}
|
||||
} else if (attacktype == AT_WALL) {
|
||||
if (attackwall(lf, (cell_t *)attacktarget, wep[i], damflag[i])) {
|
||||
// failed
|
||||
attacksdone = maxattacks;
|
||||
break;
|
||||
}
|
||||
}
|
||||
attacksdone++;
|
||||
|
||||
|
@ -680,7 +672,9 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
object_t *armour;
|
||||
char noun[BUFLEN];
|
||||
critpos = getrandomcorebp(victim, lf);
|
||||
if (critpos != BP_NONE) {
|
||||
if (critpos == BP_NONE) {
|
||||
strcpy(victimbpname, victimname);
|
||||
} else {
|
||||
armour = getequippedob(victim->pack, critpos);
|
||||
if (armour) {
|
||||
char armname[BUFLEN];
|
||||
|
@ -711,7 +705,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
|
|||
getlfname(victim, victimname);
|
||||
}
|
||||
|
||||
|
||||
// weapon passing through ghosts etc?
|
||||
if (hit) {
|
||||
if (lfhasflag(victim, F_NONCORPOREAL) &&
|
||||
|
@ -1402,12 +1395,16 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
if (isplayer(lf) && hasflag(o->flags, F_LOCKED)) {
|
||||
angergodmaybe(R_GODTHIEVES, 25, GA_MONEY);
|
||||
}
|
||||
|
||||
if (isdeadob(o)) {
|
||||
break;
|
||||
}
|
||||
} // end foreach damtype
|
||||
|
||||
// special weapon effects, as long as you're not doing a heavy blow
|
||||
if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) {
|
||||
wepeffects(wep->flags, obloc, damflag, dam[0]);
|
||||
if (!isdeadob(o)) {
|
||||
// special weapon effects, as long as you're not doing a heavy blow
|
||||
if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) {
|
||||
wepeffects(wep->flags, obloc, damflag, dam[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isunarmed) {
|
||||
|
@ -1426,6 +1423,169 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
|
|||
return B_FALSE;
|
||||
}
|
||||
|
||||
int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag) {
|
||||
int dam[100];
|
||||
enum DAMTYPE damtype[100];
|
||||
int ndam = 0;
|
||||
char attackername[BUFLEN];
|
||||
char obname[BUFLEN];
|
||||
int isunarmed = B_FALSE;
|
||||
char buf[BUFLEN];
|
||||
int i;
|
||||
int maxhp;
|
||||
|
||||
moveeffects(lf);
|
||||
if (isdead(lf)) return B_TRUE;
|
||||
|
||||
maxhp = c->type->hp;
|
||||
|
||||
// get names
|
||||
getlfname(lf, attackername);
|
||||
|
||||
// don't need to figure out accuracy - we always hit.
|
||||
|
||||
// determine damage
|
||||
ndam = 0;
|
||||
//if (unarmedflag && (unarmedflag->val[0] != NA)) {
|
||||
dam[ndam] = getdamroll(wep, NULL, damflag);
|
||||
|
||||
// modify for strength
|
||||
if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
|
||||
dam[ndam] = (int)((float)dam[ndam] * getstrdammod(lf));
|
||||
}
|
||||
|
||||
// damtype?
|
||||
damtype[ndam] = getdamtype(wep);
|
||||
ndam++;
|
||||
|
||||
// don't need to check for blessed vs mosnters
|
||||
|
||||
// determine extra damage
|
||||
getextradamwep(wep, &dam[0], &damtype[0], &ndam);
|
||||
getextradamlf(lf, &dam[0], &damtype[0], &ndam);
|
||||
|
||||
|
||||
for (i = 0; i < ndam; i++) {
|
||||
// announce the hit
|
||||
construct_hit_string(lf, NULL, attackername, c->type->name, NULL, wep, damtype[i], dam[i], maxhp, i, B_FALSE, B_FALSE, B_FALSE, isunarmed, buf);
|
||||
|
||||
if (strlen(buf)) {
|
||||
msg("%s", buf);
|
||||
}
|
||||
if (!isplayer(lf) && !cansee(player, lf)) {
|
||||
char noisebuf[BUFLEN];
|
||||
int vol;
|
||||
switch (c->type->material->id) {
|
||||
case MT_METAL:
|
||||
strcpy(noisebuf, "a metallic clanging.");
|
||||
vol = 4;
|
||||
break;
|
||||
case MT_GLASS:
|
||||
strcpy(noisebuf, "cracking glass.");
|
||||
vol = 4;
|
||||
break;
|
||||
case MT_WOOD:
|
||||
case MT_DRAGONWOOD:
|
||||
strcpy(noisebuf, "splintering wood.");
|
||||
vol = 4;
|
||||
break;
|
||||
case MT_BONE:
|
||||
case MT_STONE:
|
||||
strcpy(noisebuf, "a dull thumping.");
|
||||
vol = 3;
|
||||
break;
|
||||
case MT_GOLD:
|
||||
case MT_SILVER:
|
||||
case MT_LEATHER:
|
||||
strcpy(noisebuf, "a dull thumping.");
|
||||
vol = 2;
|
||||
break;
|
||||
case MT_PAPER:
|
||||
case MT_WETPAPER:
|
||||
case MT_RUBBER:
|
||||
strcpy(noisebuf, "a dull thumping.");
|
||||
vol = 1;
|
||||
break;
|
||||
default:
|
||||
strcpy(noisebuf, "something being hit.");
|
||||
vol = 3;
|
||||
break;
|
||||
}
|
||||
noise(c, NULL, NC_OTHER, vol, noisebuf, NULL);
|
||||
}
|
||||
|
||||
if ((i == 0) && (wep->type->id == OT_FISTS) && hasflag(c->type->material->flags, F_HARDNESS)) {
|
||||
object_t *gloves;
|
||||
gloves = getequippedob(lf->pack, BP_HANDS);
|
||||
if (gloves && hasflag(gloves->flags, F_HARDNESS)) {
|
||||
// ok
|
||||
} else if ((c->type->material->id == MT_WOOD) && (getskill(lf, SK_UNARMED) >= PR_ADEPT)) {
|
||||
// ok
|
||||
} else {
|
||||
char buf[BUFLEN];
|
||||
snprintf(buf, BUFLEN, "punching %s", obname);
|
||||
if ( losehp(lf, 1, DT_BASH, lf, buf)) {
|
||||
if (isplayer(lf)) {
|
||||
msg("^bOw!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// smash wood bonus
|
||||
if ((wep->type->id == OT_FISTS) &&
|
||||
(c->type->material->id == MT_WOOD) &&
|
||||
(getskill(lf, SK_UNARMED) >= PR_ADEPT)) {
|
||||
dam[i] += rnd(1,6);
|
||||
}
|
||||
|
||||
// adjust dam
|
||||
adjustdammaterial(&dam[i], damtype[i], c->type->material->id);
|
||||
|
||||
if (dam[i] > 0) {
|
||||
// wall loses hp
|
||||
c->hp -= dam[i];
|
||||
if (c->hp <= 0) {
|
||||
char cellname[BUFLEN];
|
||||
int shattered = B_FALSE;
|
||||
enum MATERIAL cellmat;
|
||||
// remember cell properties
|
||||
sprintf(cellname, "%s %s", needan(c->type->name) ? "An" : "A", c->type->name);
|
||||
cellmat = c->type->material->id;
|
||||
// cell dies (have to do this before calling fragments())
|
||||
setcelltype(c, c->map->habitat->emptycelltype);
|
||||
// announce
|
||||
if (haslos(player, c)) {
|
||||
msg("%s %s!", cellname, shattered ? "shatters" : "is destroyed");
|
||||
}
|
||||
// shatter?
|
||||
if (willshatter(cellmat)) {
|
||||
char what[BUFLEN];
|
||||
shattered = B_TRUE;
|
||||
noise(c, NULL, NC_OTHER, SV_CAR, "something shattering.", NULL);
|
||||
if (getshardobname(cellmat, what)) {
|
||||
fragments(c, what, 0, 3); // TODO: use speed so shards will hit lfs
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // end foreach damtype
|
||||
|
||||
// no special weapon effects on cells.
|
||||
|
||||
// weapon gets damaged ?
|
||||
if (wep && (ndam > 0)) {
|
||||
if (wepdullable(wep)) {
|
||||
// weapon gets duller
|
||||
if (rnd(1,2)) makeduller(wep, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
enum DAMTYPE basedamagetype(enum DAMTYPE dt) {
|
||||
switch (dt) {
|
||||
case DT_HEAT:
|
||||
|
|
1
attack.h
1
attack.h
|
@ -5,6 +5,7 @@ void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int *
|
|||
int attackcell(lifeform_t *lf, cell_t *c, int force);
|
||||
int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag);
|
||||
int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag);
|
||||
int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag);
|
||||
enum DAMTYPE basedamagetype(enum DAMTYPE dt);
|
||||
int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE damtype, int difficulty, char *attackname);
|
||||
//void confereffects(flagpile_t *fp, lifeform_t *victim);
|
||||
|
|
26
data.c
26
data.c
|
@ -2189,6 +2189,9 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_VALUE, 10, NA, NA, NULL);
|
||||
addot(OT_POT_CANINETRACKING, "potion of canine tracking", "Mimics the effects of a 'canine tracking' spell.", MT_GLASS, 1, OC_POTION, SZ_TINY);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
|
||||
addot(OT_POT_GROWTH, "potion of growth", "A magical liquid which causes the imbiber's body to instantly undergo rapid growth.", MT_GLASS, 1, OC_POTION, SZ_TINY);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_VALUE, 50, NA, NA, NULL);
|
||||
|
||||
addot(OT_POT_HEALINGMIN, "potion of minor healing", "Restores 1-10 health to whoever drinks it.", MT_GLASS, 1, OC_POTION, SZ_TINY);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 100, NA, NULL);
|
||||
|
@ -2830,7 +2833,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
// l2
|
||||
addot(OT_S_BLADEBURN, "bladeburn", "Ignites the target's bladed weapon, causing it to temporarily deal fire damage. The spell's power determines how long it will last.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addot(OT_S_BLADEBURN, "bladeburn", "Ignites the caster's weapon, causing it to temporarily deal fire damage. The spell's power determines how long it will last.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines its duration.");
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
|
||||
|
@ -3467,6 +3470,14 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
|
||||
// l2
|
||||
addot(OT_S_SIZEUP, "unnatural growth", "Causes the caster's body to grow in size.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
addot(OT_S_SIZEDOWN, "unnatural shrinkage", "Causes the caster's body to shrink in size.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
|
||||
addot(OT_S_DARKNESS, "darkness", "Permenantly darkens the area around the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power III, you can control where the darkness appears.");
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power VIII, the darkness becomes permenant.");
|
||||
|
@ -3485,6 +3496,7 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
|
||||
|
||||
// l3
|
||||
addot(OT_S_INVISIBILITY, "invisibility", "Temporarily renders the target invisible.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
|
||||
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the invisibility will last.");
|
||||
|
@ -5290,7 +5302,6 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
|
||||
addflag(lastot->flags, F_GOESON, BP_BODY, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_ARMOURRATING, 5, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_ARMOURPENALTY, 10, 10, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_DTIMMUNE, DT_FIRE, NA, NULL);
|
||||
addflag(lastot->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL);
|
||||
|
@ -5781,9 +5792,10 @@ void initobjects(void) {
|
|||
addflag(lastot->flags, F_ENCHANTABLE, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_IDWHENUSED, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_VALUE, 350, NA, NA, NULL);
|
||||
addot(OT_RING_INVIS, "ring of invisibility", "Renders the wearer invisible.", MT_METAL, 0.1, OC_RING, SZ_MINI);
|
||||
addot(OT_RING_INVIS, "ring of invisibility", "Renders the wearer invisible - but drains the wearer's health at the same time.", MT_METAL, 0.1, OC_RING, SZ_MINI);
|
||||
addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_UNCOMMON, "");
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_INVISIBLE, NA, NA, NULL);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_HPDRAIN, 1, DT_DIRECT, "life force draining");
|
||||
addflag(lastot->flags, F_VALUE, 400, NA, NA, NULL);
|
||||
addot(OT_RING_INVULN, "ring of invulnerability", "Grants the caster complete immunity to physical harm.", MT_METAL, 0.1, OC_RING, SZ_MINI);
|
||||
addflag(lastot->flags, F_EQUIPCONFER, F_INVULNERABLE, NA, NA, NULL);
|
||||
|
@ -6984,6 +6996,7 @@ void initobjects(void) {
|
|||
|
||||
void initoptions(void) {
|
||||
addoption(OPT_ALWAYSSHOWTRAILS, "always show trail objects", B_FALSE);
|
||||
addoption(OPT_STOPRUNONNOISE, "stop running if sound heard", B_TRUE);
|
||||
}
|
||||
|
||||
void initrace(void) {
|
||||
|
@ -8871,7 +8884,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^slurping");
|
||||
addflag(lastrace->flags, F_DTIMMUNE, DT_ACID, B_TRUE, NA, NULL);
|
||||
addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "puddle of acid");
|
||||
addflag(lastrace->flags, F_DIESPLATTER, 3, NA, NA, "splash of acid");
|
||||
addflag(lastrace->flags, F_DIESPLATTER, 3, 0, NA, "splash of acid");
|
||||
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOFLEE, 5, NA, NA, NULL);
|
||||
|
@ -9008,6 +9021,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_BEGINNER, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLL, NULL);
|
||||
|
||||
addrace(R_XAT, "xat", 2, 'x', C_BROWN, MT_FLESH, RC_ANIMAL, "Xats are wild pigs with the claws of a dog.");
|
||||
setbodytype(lastrace, BT_QUADRAPED);
|
||||
|
@ -9875,7 +9889,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 1, NA, "^slurping");
|
||||
addflag(lastrace->flags, F_DTIMMUNE, DT_ACID, B_TRUE, NA, NULL);
|
||||
addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "puddle of acid");
|
||||
addflag(lastrace->flags, F_DIESPLATTER, 3, NA, NA, "splash of acid");
|
||||
addflag(lastrace->flags, F_DIESPLATTER, 3, 0, NA, "splash of acid");
|
||||
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
|
||||
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL);
|
||||
|
@ -9908,7 +9922,7 @@ void initrace(void) {
|
|||
addflag(lastrace->flags, F_BREATHWATER, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
|
||||
addflag(lastrace->flags, F_AUTOCREATEOB, 0, NA, NA, "puddle of slime");
|
||||
addflag(lastrace->flags, F_DIESPLATTER, 3, NA, NA, "puddle of slime");
|
||||
addflag(lastrace->flags, F_DIESPLATTER, 3, 0, NA, "puddle of slime");
|
||||
addrace(R_SNAKE, "brown snake", 3, 's', C_BROWN, MT_FLESH, RC_ANIMAL, "Common venomous snakes.");
|
||||
setbodytype(lastrace, BT_SNAKE);
|
||||
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
|
||||
|
|
BIN
data/hiscores.db
BIN
data/hiscores.db
Binary file not shown.
22
defs.h
22
defs.h
|
@ -65,6 +65,8 @@
|
|||
// Booleans
|
||||
#define B_FALSE (0)
|
||||
#define B_TRUE (-1)
|
||||
#define B_MAYBE (-2)
|
||||
|
||||
#define B_FORCE (-2)
|
||||
#define B_ONPURPOSE (-1)
|
||||
#define B_CHANGEDIR (-1)
|
||||
|
@ -1213,6 +1215,7 @@ enum OBTYPE {
|
|||
OT_POT_EXPERIENCE,
|
||||
OT_POT_FURY,
|
||||
OT_POT_GASEOUSFORM,
|
||||
OT_POT_GROWTH,
|
||||
OT_POT_HEALING,
|
||||
OT_POT_HEALINGMIN,
|
||||
OT_POT_HEALINGMAJ,
|
||||
|
@ -1394,6 +1397,8 @@ enum OBTYPE {
|
|||
OT_S_POLYMORPH,
|
||||
OT_S_POLYMORPHRND,
|
||||
OT_S_QUICKENSTONE,
|
||||
OT_S_SIZEUP,
|
||||
OT_S_SIZEDOWN,
|
||||
// nature / enviromancy
|
||||
OT_S_BARKSKIN,
|
||||
OT_S_CALLLIGHTNING,
|
||||
|
@ -2083,6 +2088,9 @@ enum FLAG {
|
|||
F_NOQUALITY, // can't be masterwork / shoddy
|
||||
F_CORPSEOF, // this is a corpse of montype val0.
|
||||
// text is how it died.
|
||||
F_REVIVETIMER, // v0 = cur, v1 = max. v0 incremenets each tick.
|
||||
// when v0 == v1, this object changes into lf of race
|
||||
// v2.
|
||||
F_DTCONVERT, // damtype val0 converts this to f->text
|
||||
F_DTCREATEOB, // damtype val0 creates object f->text here
|
||||
// v1 = radius to burst in
|
||||
|
@ -2392,8 +2400,12 @@ enum FLAG {
|
|||
// v0 is the order in which these are displayed (0-5)
|
||||
F_BONDESC, // text=extra description for playable races.
|
||||
// v0 is the display order.
|
||||
// v1=true means 'don't display this one during
|
||||
// player race selection)
|
||||
F_PENDESC, // text=extra description for playable races.
|
||||
// v0 is the display order.
|
||||
// v1=true means 'don't display this one during
|
||||
// player race selection)
|
||||
//F_SPELLLETTER, // text[0] = letter to cast this spell
|
||||
F_AICASTTOFLEE, // AI can cast this spell to help flee/heal
|
||||
// v0 is who to target
|
||||
|
@ -2435,6 +2447,9 @@ enum FLAG {
|
|||
// unconscious. announce it when you wake up.
|
||||
F_TURNED, // lf turned this turn.
|
||||
F_PRAYEDTO, // player has prayed to this god before.
|
||||
F_HPDRAIN, // lf loses v0 hit points eath turn.
|
||||
// v1 = damtype
|
||||
// text = killer damage string
|
||||
F_GAVEMONEY, // v0 tracks how much money we gave away this turn
|
||||
// used for r_godgreed anger effects.
|
||||
F_CLIMBING, // lf is currently climbing a wall
|
||||
|
@ -2600,6 +2615,8 @@ enum FLAG {
|
|||
// e = exits
|
||||
// s = shops
|
||||
// t = traps
|
||||
// o = rare Objects
|
||||
// m = rare Monsters
|
||||
// eg: text=="st" means they know of shops+traps
|
||||
F_NOJOBTEXT, // this lf's name is 'a xxx', not 'a xxx wizard' etc
|
||||
F_LASTDIR, // this is the last direction we moved.
|
||||
|
@ -2707,6 +2724,7 @@ enum FLAG {
|
|||
F_DIESPLATTER, // this lf will splatter objcets of type 'text'
|
||||
// when it dies.
|
||||
// v0 = max distance to splatter (or UNLIMITED)
|
||||
// v1 = how fast to shoot objects (0 = just place them)
|
||||
// text = type of object to splatter
|
||||
F_OBESE, // double base weight for race!
|
||||
F_ORIGRACE, // original player race (if you polymorphed)
|
||||
|
@ -2967,6 +2985,9 @@ enum FLAG {
|
|||
// v0 is pct chance of door (as opposed to empty
|
||||
// doorway with no door).
|
||||
F_AUTOPOPULATE, // fill this vault with obs/mons/pillars like normal rooms
|
||||
F_MAINTAINEDGE, // when calling fixreachability(), only allow
|
||||
// corridors to enter this vault through cells
|
||||
// marked as exits.
|
||||
F_NORANDOM, // this vault does not randomly appear
|
||||
// OR this spell doesn't apear in books
|
||||
F_VAULTATOB, // v0/1=x/y, v2=pctchance, text=obname
|
||||
|
@ -3262,6 +3283,7 @@ typedef struct warning_s {
|
|||
|
||||
enum OPTION {
|
||||
OPT_ALWAYSSHOWTRAILS,
|
||||
OPT_STOPRUNONNOISE,
|
||||
};
|
||||
|
||||
typedef struct option_s {
|
||||
|
|
6
flag.c
6
flag.c
|
@ -469,8 +469,10 @@ int fpisbad(flagpile_t *fp) {
|
|||
}
|
||||
|
||||
|
||||
void copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id) {
|
||||
// returns # of flags copied
|
||||
int copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id) {
|
||||
flag_t *f;
|
||||
int ndone = 0;
|
||||
for (f = src->first ; f ; f = f->next) {
|
||||
// gone past the requrested id's number - ie. it's not there.
|
||||
if (f->id > id) break;
|
||||
|
@ -487,8 +489,10 @@ void copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id) {
|
|||
f->altval->val[2],
|
||||
f->altval->text);
|
||||
}
|
||||
ndone++;
|
||||
}
|
||||
}
|
||||
return ndone;
|
||||
}
|
||||
|
||||
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime) {
|
||||
|
|
2
flag.h
2
flag.h
|
@ -14,7 +14,7 @@ void changeflagtext(flag_t *f, char *newtext);
|
|||
void checkmapflags(map_t *m);
|
||||
int fpisbad(flagpile_t *fp);
|
||||
void checkflagpile(flagpile_t *fp);
|
||||
void copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id);
|
||||
int copyflag(flagpile_t *dst, flagpile_t *src, enum FLAG id);
|
||||
void copyflags(flagpile_t *dst, flagpile_t *src, int lifetime);
|
||||
int countflags(flagpile_t *fp);
|
||||
int flagcausesloscalc(enum FLAG fid);
|
||||
|
|
140
io.c
140
io.c
|
@ -3472,6 +3472,7 @@ void describeob(object_t *o) {
|
|||
void describerace(enum RACE rid) {
|
||||
char buf[BUFLEN];
|
||||
char *buf2;
|
||||
char ch;
|
||||
int x,y;
|
||||
race_t *r;
|
||||
cls();
|
||||
|
@ -3487,16 +3488,18 @@ void describerace(enum RACE rid) {
|
|||
wmove(mainwin, 2, 0);
|
||||
|
||||
buf2 = malloc(HUGEBUFLEN * sizeof(char));
|
||||
makedesc_race(rid, buf2, B_TRUE);
|
||||
makedesc_race(rid, buf2, B_TRUE, B_FALSE);
|
||||
//textwithcol(mainwin, buf2);
|
||||
getyx(mainwin,y,x);
|
||||
wrapprint(mainwin, &y, &x, "%s", buf2);
|
||||
ch = wrapprint(mainwin, &y, &x, "%s", buf2);
|
||||
free(buf2);
|
||||
|
||||
wrefresh(mainwin);
|
||||
|
||||
// wait for key
|
||||
getch();
|
||||
// wait for key, unless we quit from the 'more' prompt
|
||||
if (ch != 27) {
|
||||
getch();
|
||||
}
|
||||
real_clearmsg(B_TRUE);
|
||||
restoregamewindows();
|
||||
}
|
||||
|
@ -4163,22 +4166,24 @@ void docomms_areainfo(char *who, flagpile_t *fp, lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
// veryrare objects
|
||||
ndone = 0;
|
||||
for (y = 0; y < player->cell->map->h ; y++) {
|
||||
for (x = 0; x < player->cell->map->w; x++) {
|
||||
c = getcellat(player->cell->map, x,y);
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (hasflag(o->flags, F_SHOP)) continue; // shops were already handled
|
||||
f = hasflag(o->type->flags, F_RARITY);
|
||||
if (f && (f->val[2] == RR_VERYRARE)) {
|
||||
msg("\"I hear there is a rare %s nearby...\"", o->type->name); more();
|
||||
setcellknown(c, PR_MASTER);
|
||||
ndone++;
|
||||
if (strchr(knowflag->text, 'o')) {
|
||||
ndone = 0;
|
||||
for (y = 0; y < player->cell->map->h ; y++) {
|
||||
for (x = 0; x < player->cell->map->w; x++) {
|
||||
c = getcellat(player->cell->map, x,y);
|
||||
for (o = c->obpile->first ; o ; o = o->next) {
|
||||
if (hasflag(o->flags, F_SHOP)) continue; // shops were already handled
|
||||
f = hasflag(o->type->flags, F_RARITY);
|
||||
if (f && (f->val[2] == RR_VERYRARE)) {
|
||||
msg("\"I hear there is a rare %s nearby...\"", o->type->name); more();
|
||||
setcellknown(c, PR_MASTER);
|
||||
ndone++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ndone) needredraw = B_TRUE;
|
||||
}
|
||||
if (ndone) needredraw = B_TRUE;
|
||||
// staircases
|
||||
if (strchr(knowflag->text, 'e')) {
|
||||
ndone = 0;
|
||||
|
@ -4252,37 +4257,39 @@ void docomms_areadangers(char *who, flagpile_t *fp, lifeform_t *lf) {
|
|||
totdone += ndone;
|
||||
}
|
||||
// veryrare monsters
|
||||
gethitdicerange(getmapdifficulty(player->cell->map), &min,&max, RARITYVARIANCELF, B_FALSE);
|
||||
if (strchr(knowflag->text, 'm')) {
|
||||
gethitdicerange(getmapdifficulty(player->cell->map), &min,&max, RARITYVARIANCELF, B_FALSE);
|
||||
|
||||
ndone = 0;
|
||||
for (y = 0; y < player->cell->map->h ; y++) {
|
||||
for (x = 0; x < player->cell->map->w; x++) {
|
||||
c = getcellat(player->cell->map, x,y);
|
||||
if (c->lf && !isplayer(c->lf) && (c->lf != lf) && areenemies(c->lf, player)) {
|
||||
int showit = B_FALSE;
|
||||
enum RARITY rr;
|
||||
getracerarity(NULL, c->lf->race->id, &rr);
|
||||
if (rr == RR_VERYRARE) {
|
||||
showit = B_TRUE;
|
||||
} else {
|
||||
// out of depth monsters?
|
||||
int hd;
|
||||
hd = gethitdicerace(c->lf->race);
|
||||
if (hd > max) {
|
||||
ndone = 0;
|
||||
for (y = 0; y < player->cell->map->h ; y++) {
|
||||
for (x = 0; x < player->cell->map->w; x++) {
|
||||
c = getcellat(player->cell->map, x,y);
|
||||
if (c->lf && !isplayer(c->lf) && (c->lf != lf) && areenemies(c->lf, player)) {
|
||||
int showit = B_FALSE;
|
||||
enum RARITY rr;
|
||||
getracerarity(NULL, c->lf->race->id, &rr);
|
||||
if (rr == RR_VERYRARE) {
|
||||
showit = B_TRUE;
|
||||
} else {
|
||||
// out of depth monsters?
|
||||
int hd;
|
||||
hd = gethitdicerace(c->lf->race);
|
||||
if (hd > max) {
|
||||
showit = B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (showit) {
|
||||
char lfname[BUFLEN];
|
||||
real_getlfnamea(c->lf, lfname, B_FALSE, B_TRUE);
|
||||
msg("\"There is %s living nearby...\"", lfname); more();
|
||||
ndone++;
|
||||
if (showit) {
|
||||
char lfname[BUFLEN];
|
||||
real_getlfnamea(c->lf, lfname, B_FALSE, B_TRUE);
|
||||
msg("\"There is %s living nearby...\"", lfname); more();
|
||||
ndone++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
totdone += ndone;
|
||||
}
|
||||
totdone += ndone;
|
||||
|
||||
|
||||
msg("\"I know of no %sdangers in this area.\"", (totdone) ? "other " : "");
|
||||
|
@ -6110,7 +6117,7 @@ char *makedesc_ob(object_t *o, char *retbuf) {
|
|||
return retbuf;
|
||||
}
|
||||
|
||||
char *makedesc_race(enum RACE rid, char *retbuf, int showextra) {
|
||||
char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel) {
|
||||
race_t *r;
|
||||
char buf[HUGEBUFLEN];
|
||||
flag_t *retflag[MAXCANDIDATES],*f;
|
||||
|
@ -6176,8 +6183,11 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra) {
|
|||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
if (f->val[0] == curidx) {
|
||||
snprintf(buf, HUGEBUFLEN, "@- %s\n", f->text);
|
||||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
if ((f->val[1] == B_TRUE) && forplayersel) {
|
||||
} else {
|
||||
snprintf(buf, HUGEBUFLEN, "@- %s\n", f->text);
|
||||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
curidx++;
|
||||
break;
|
||||
|
@ -6264,7 +6274,7 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra) {
|
|||
case F_ENHANCESMELL: sprintf(buf, "Enhanced sense of smell (range %d)", f->val[0]); break;
|
||||
case F_FLYING: sprintf(buf, "Can fly at will"); break;
|
||||
case F_HEAVYBLOW: sprintf(buf, "Attacks will knock enemies backwards"); break;
|
||||
case F_HUMANOID: sprintf(buf, "Can use weapons and armour."); break;
|
||||
case F_HUMANOID: if (!forplayersel) sprintf(buf, "Can use weapons and armour."); break;
|
||||
case F_LEVITATING: sprintf(buf, "Can levitate at will"); break;
|
||||
case F_MEDITATES: sprintf(buf, "Meditates to retain awareness while sleeping."); break;
|
||||
case F_MPMOD: if (f->val[0] > 0) sprintf(buf, "+%d Mana", f->val[0]); break;
|
||||
|
@ -6313,8 +6323,11 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra) {
|
|||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
if (f->val[0] == curidx) {
|
||||
snprintf(buf, HUGEBUFLEN, "@- %s\n", f->text);
|
||||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
if ((f->val[1] == B_TRUE) && forplayersel) {
|
||||
} else {
|
||||
snprintf(buf, HUGEBUFLEN, "@- %s\n", f->text);
|
||||
strncat(retbuf, buf, HUGEBUFLEN);
|
||||
}
|
||||
donesomething = B_TRUE;
|
||||
curidx++;
|
||||
break;
|
||||
|
@ -6330,7 +6343,7 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra) {
|
|||
switch (f->id) {
|
||||
case F_CARNIVORE: sprintf(buf, "Will only eat meat."); break;
|
||||
case F_DEAF: sprintf(buf, "Deaf"); break;
|
||||
case F_DIURNAL: sprintf(buf, "Sleeps at night."); break;
|
||||
case F_DIURNAL: if (!forplayersel) sprintf(buf, "Sleeps at night."); break;
|
||||
case F_DTVULN:
|
||||
if (!hasflag(doneflags, F_DTVULN)) {
|
||||
if (f->val[0] == DT_ALL) {
|
||||
|
@ -6362,7 +6375,7 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra) {
|
|||
break;
|
||||
case F_MPMOD: if (f->val[0] < 0) sprintf(buf, "%d Mana", f->val[0]); break;
|
||||
case F_NEEDSWATER: sprintf(buf, "Will suffocate without water"); break;
|
||||
case F_NOCTURNAL: sprintf(buf, "Sleeps during the day."); break;
|
||||
case F_NOCTURNAL: if (!forplayersel) sprintf(buf, "Sleeps during the day."); break;
|
||||
case F_NOPACK: sprintf(buf, "Cannot carry objects."); break;
|
||||
case F_SIZE:
|
||||
if (hasflag(r->flags, F_HUMANOID) && (f->val[0] != SZ_HUMAN)) {
|
||||
|
@ -6373,7 +6386,9 @@ char *makedesc_race(enum RACE rid, char *retbuf, int showextra) {
|
|||
sprintf(buf, "Will not leave its home territory."); break;
|
||||
break;
|
||||
case F_TAMABLE:
|
||||
sprintf(buf, "Susceptible to bribery."); break;
|
||||
if (!forplayersel) {
|
||||
sprintf(buf, "Susceptible to bribery.");
|
||||
}
|
||||
break;
|
||||
case F_VEGETARIAN: sprintf(buf, "Will not eat meat."); break;
|
||||
case F_VISRANGEMOD: if (f->val[0] < 0) sprintf(buf, "Reduced vision range (%d)", f->val[0]); break;
|
||||
|
@ -8331,7 +8346,9 @@ char getchoicestr(prompt_t *prompt, int useshortcuts, int showallatstart) {
|
|||
// only print if on the page
|
||||
if ((i >= first) && !atbottom) {
|
||||
// show heading first
|
||||
wattron(mainwin, A_REVERSE);
|
||||
mvwprintw(mainwin, y, 0, "%s", curheading);
|
||||
wattroff(mainwin, A_REVERSE);
|
||||
y++;
|
||||
}
|
||||
doneheading = B_TRUE;
|
||||
|
@ -12064,20 +12081,21 @@ int warnabout(char *what) {
|
|||
}
|
||||
|
||||
// @ = tab
|
||||
void wrapprint(WINDOW *win, int *y, int *x, char *format, ... ) {
|
||||
char wrapprint(WINDOW *win, int *y, int *x, char *format, ... ) {
|
||||
char word[HUGEBUFLEN],buf[HUGEBUFLEN];
|
||||
char *p;
|
||||
va_list args;
|
||||
int w,nspaces = 0;
|
||||
int w,nspaces = 0,h;
|
||||
int first = B_TRUE;
|
||||
|
||||
va_start(args, format);
|
||||
vsnprintf( buf, HUGEBUFLEN, format, args );
|
||||
va_end(args);
|
||||
|
||||
if (!strlen(buf)) return;
|
||||
if (!strlen(buf)) return '\0';
|
||||
|
||||
w = getmaxx(win);
|
||||
h = getmaxy(win);
|
||||
|
||||
// remember the amount of spaces at the end
|
||||
p = buf + strlen(buf) - 1;
|
||||
|
@ -12105,7 +12123,25 @@ void wrapprint(WINDOW *win, int *y, int *x, char *format, ... ) {
|
|||
*x = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (gamemode == GM_GAMESTARTED) {
|
||||
if (*y >= h-2) {
|
||||
char ch;
|
||||
centre(win,C_WHITE, h-1, "--More--");
|
||||
ch = getch();
|
||||
if (ch == 27) { // esc
|
||||
return ch;
|
||||
} else {
|
||||
// clear window
|
||||
wclear(win);
|
||||
*y = 0;
|
||||
*x = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wmove(win, *y, *x);
|
||||
|
||||
if (first) {
|
||||
first = B_FALSE;
|
||||
} else if (*x != 0) {
|
||||
|
@ -12137,6 +12173,8 @@ void wrapprint(WINDOW *win, int *y, int *x, char *format, ... ) {
|
|||
//wattroff(win, A_BOLD);
|
||||
setcol(win, C_GREY);
|
||||
getyx(win, *y, *x);
|
||||
|
||||
return '\0';
|
||||
}
|
||||
|
||||
|
||||
|
|
4
io.h
4
io.h
|
@ -106,7 +106,7 @@ int keycodetokey(int keycode, int escseqok);
|
|||
void listobs(WINDOW *win, object_t **mylist, int *sellist, int *selcount, int firstob, int *counter, int lastline, int *y, char *myletters, int forpickup, int showpoints);
|
||||
char *makedesc_god(lifeform_t *god, char *retbuf);
|
||||
char *makedesc_ob(object_t *o, char *retbuf);
|
||||
char *makedesc_race(enum RACE rid, char *retbuf, int showextra);
|
||||
char *makedesc_race(enum RACE rid, char *retbuf, int showextra, int forplayersel);
|
||||
char *makedesc_skill(enum SKILL skid, char *retbuf, enum SKILLLEVEL levhilite);
|
||||
char *makedesc_spell(objecttype_t *ot, char *retbuf);
|
||||
void makespellchoicelist(prompt_t *pr, lifeform_t *lf, char *ques, char *ques2, enum SPELLSCHOOL wantschool, int wantunknown, int wantlowmp, int wanttoohard,int mpcutoff);
|
||||
|
@ -136,4 +136,4 @@ void tombstone(lifeform_t *lf);
|
|||
void updatestatus(void);
|
||||
int updateviewfor(cell_t *cell);
|
||||
int warnabout(char *what);
|
||||
void wrapprint(WINDOW *win, int *y, int *x, char *format, ... );
|
||||
char wrapprint(WINDOW *win, int *y, int *x, char *format, ... );
|
||||
|
|
226
lf.c
226
lf.c
|
@ -1,6 +1,7 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -2546,10 +2547,10 @@ void die(lifeform_t *lf) {
|
|||
if (vaporised) {
|
||||
switch (rnd(1,2)) {
|
||||
case 1:
|
||||
fragments(corpsecell, "chunk of flesh", 2, UNLIMITED);
|
||||
fragments(corpsecell, "chunk of flesh", 0, UNLIMITED);
|
||||
break;
|
||||
case 2:
|
||||
fragments(corpsecell, "pool of blood", 2, UNLIMITED);
|
||||
fragments(corpsecell, "pool of blood", 0, UNLIMITED);
|
||||
break;
|
||||
}
|
||||
} else if ((lf->lastdamtype == DT_BASH) && lfhasflag(lf, F_FROZEN)) {
|
||||
|
@ -2620,6 +2621,11 @@ void die(lifeform_t *lf) {
|
|||
copyflag(corpse->flags, lf->flags, F_KNOWSABOUT);
|
||||
copyflag(corpse->flags, lf->flags, F_HOMEMAP);
|
||||
|
||||
// some corpses will regenerate...
|
||||
if (copyflag(corpse->flags, lf->flags, F_REVIVETIMER)) {
|
||||
killflagsofid(corpse->flags, F_OBHPDRAIN);
|
||||
}
|
||||
|
||||
// corpse of a player pet?
|
||||
if (ispetof(lf, player)) {
|
||||
addflag(corpse->flags, F_PETOF, player->id, NA, NA, NULL);
|
||||
|
@ -2634,6 +2640,14 @@ void die(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
|
||||
// inherit size from lf
|
||||
f = hasflag(corpse->flags, F_SIZE);
|
||||
if (f) {
|
||||
f->val[0] = getlfsize(lf);
|
||||
} else {
|
||||
addflag(corpse->flags, F_SIZE, getlfsize(lf), NA, NA, NULL);
|
||||
}
|
||||
|
||||
// remember what killed us.
|
||||
f = hasflag(corpse->flags, F_CORPSEOF);
|
||||
if (f) {
|
||||
|
@ -2659,7 +2673,7 @@ void die(lifeform_t *lf) {
|
|||
flag_t *f;
|
||||
f = lfhasflag(lf, F_DIESPLATTER);
|
||||
if (f) {
|
||||
fragments(corpsecell, f->text, 1, f->val[0]);
|
||||
fragments(corpsecell, f->text, f->val[1], f->val[0]);
|
||||
}
|
||||
}
|
||||
} // end if corpsecell
|
||||
|
@ -2754,6 +2768,13 @@ void genareaknowledge(flagpile_t *fp, int chancemod) {
|
|||
if (pctchance(75 + chancemod)) {
|
||||
strcat(knownstuff, "e");
|
||||
}
|
||||
// rare monsters/objects? (highish chance)
|
||||
if (pctchance(60 + chancemod)) {
|
||||
strcat(knownstuff, "o");
|
||||
}
|
||||
if (pctchance(60 + chancemod)) {
|
||||
strcat(knownstuff, "m");
|
||||
}
|
||||
// shops? (med chance)
|
||||
if (pctchance(50 + chancemod)) {
|
||||
strcat(knownstuff, "s");
|
||||
|
@ -4664,34 +4685,37 @@ void gainxp(lifeform_t *lf, long amt) {
|
|||
lf->xp += amt;
|
||||
if (isplayer(lf)) statdirty = B_TRUE;
|
||||
assert(lf->xp >= 0);
|
||||
}
|
||||
|
||||
// skill xp
|
||||
if (isplayer(lf)) {
|
||||
int amtneeded;
|
||||
// skill xp
|
||||
if (isplayer(lf)) {
|
||||
long amtneeded;
|
||||
|
||||
amtneeded = getspforpoint(lf);
|
||||
amtneeded = getspforpoint(lf);
|
||||
assert(amtneeded > 0);
|
||||
|
||||
lf->skillxp += amt;
|
||||
lf->skillxp += amt;
|
||||
|
||||
assert(lf->skillxp >= 0);
|
||||
while (lf->skillxp >= amtneeded) {
|
||||
newskillpoints++;
|
||||
lf->skillxp -= amtneeded;
|
||||
if (isplayer(lf)) statdirty = B_TRUE;
|
||||
assert(lf->skillxp >= 0);
|
||||
while (lf->skillxp >= amtneeded) {
|
||||
newskillpoints++;
|
||||
lf->skillxp -= amtneeded;
|
||||
if (isplayer(lf)) statdirty = B_TRUE;
|
||||
}
|
||||
// debug!
|
||||
if (newskillpoints >= 3) {
|
||||
raise(SIGINT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doxp) {
|
||||
// ready for next level? can only go up ONE level.
|
||||
if (lf->xp >= getxpforlev(lf->level + 1)) {
|
||||
gainlevel(lf, B_FALSE); // this will increment 'newlevel'
|
||||
}
|
||||
}
|
||||
if (newskillpoints) {
|
||||
lf->skillpoints += newskillpoints;
|
||||
msg("^GYou feel ready to learn a new skill!");
|
||||
lf->totskillpoints += newskillpoints;
|
||||
if (newskillpoints) {
|
||||
lf->skillpoints += newskillpoints;
|
||||
msg("^GYou feel ready to learn a new skill!");
|
||||
lf->totskillpoints += newskillpoints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6610,6 +6634,7 @@ glyph_t *getlfglyph(lifeform_t *lf) {
|
|||
tempglyph.colour = lf->race->glyph.colour;
|
||||
} else if ((f = lfhasflag(lf, F_GLYPH)) != NULL) {
|
||||
tempglyph.ch = f->val[1];
|
||||
tempglyph.colour = f->val[0];
|
||||
} else {
|
||||
tempglyph = lf->race->glyph;
|
||||
}
|
||||
|
@ -7030,6 +7055,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
|
|||
char lname[BUFLEN];
|
||||
job_t *j;
|
||||
flag_t *f;
|
||||
enum LFSIZE size,racesize;
|
||||
|
||||
|
||||
// 'the' or 'your' ?
|
||||
|
@ -7051,6 +7077,24 @@ char *real_getlfname(lifeform_t *lf, char *buf, int usevis, int showall) {
|
|||
|
||||
// construct description string
|
||||
strcpy(descstring, "");
|
||||
|
||||
// has their size changed?
|
||||
f = hasflag(lf->race->flags, F_SIZE);
|
||||
if (f) {
|
||||
racesize = f->val[0];
|
||||
} else {
|
||||
racesize = SZ_HUMAN; // default
|
||||
}
|
||||
size = getlfsize(lf);
|
||||
if (size != racesize) {
|
||||
if (size == SZ_HUMAN) {
|
||||
strcat(descstring, "human-sized ");
|
||||
} else {
|
||||
strcat(descstring, getsizetext(size));
|
||||
strcat(descstring, " ");
|
||||
}
|
||||
}
|
||||
|
||||
if (lfhasflag(lf, F_FROZEN)) {
|
||||
strcat(descstring, "frozen ");
|
||||
}
|
||||
|
@ -10557,6 +10601,8 @@ void killlf(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
int isdeaf(lifeform_t *lf) {
|
||||
if (lfhasflag(lf, F_TREMORSENSE)) return B_FALSE;
|
||||
|
||||
if (lfhasflag(lf, F_DEAF)) return B_TRUE;
|
||||
if (isresting(lf) && lfhasflag(lf, F_RESTINGINMOTEL)) return B_TRUE;
|
||||
if (lfhasflagval(lf, F_INJURY, IJ_EARSRINGING, NA, NA, NULL)) return B_TRUE;
|
||||
|
@ -13257,6 +13303,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
// you can see the cell which made the noise
|
||||
if (seetext) {
|
||||
msg("%s", seetext);
|
||||
rv = B_TRUE;
|
||||
}
|
||||
} else if (text && !isdeaf(l) && ((nclass != NC_MOVEMENT) || !lfhasflag(l, F_DONELISTEN))) {
|
||||
// this means you can only hear one 'walk' sound per turn
|
||||
|
@ -13328,7 +13375,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
rv = B_TRUE;
|
||||
}
|
||||
// can only hear one 'walk' sound per turn.
|
||||
if (isplayer(l) && (nclass == NC_MOVEMENT)) {
|
||||
if (nclass == NC_MOVEMENT) {
|
||||
addflag(l->flags, F_DONELISTEN, B_TRUE, NA, NA, NULL);
|
||||
practice(l, SK_LISTEN, 1);
|
||||
}
|
||||
|
@ -13415,6 +13462,12 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
|
|||
} else { // can't hear the sound.
|
||||
}
|
||||
} // end for each lf on map
|
||||
|
||||
if (rv == B_TRUE) {
|
||||
if (getoption(OPT_STOPRUNONNOISE)) {
|
||||
stoprunning(player);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -16009,7 +16062,6 @@ void startlfturn(lifeform_t *lf) {
|
|||
}
|
||||
|
||||
// sixth sense spell warnings
|
||||
|
||||
f = hasactivespell(lf, OT_S_SIXTHSENSE);
|
||||
if (f) {
|
||||
cell_t *retcell[MAXCANDIDATES];
|
||||
|
@ -16559,7 +16611,7 @@ void startlfturn(lifeform_t *lf) {
|
|||
|
||||
// effects for/on your own flags
|
||||
getflags(lf->flags, retflag, &nretflags, F_ATTACHEDTO, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FEIGNFOOLEDBY,F_FLEEFROM,
|
||||
F_GRABBEDBY, F_GRABBING, F_GUNTARGET, F_BOOSTSPELL, F_FEIGNINGDEATH, F_INJURY,
|
||||
F_GRABBEDBY, F_GRABBING, F_GUNTARGET, F_BOOSTSPELL, F_FEIGNINGDEATH, F_HPDRAIN, F_INJURY,
|
||||
F_NOFLEEFROM, F_PETOF, F_SPOTTED, F_STABBEDBY, F_TARGETCELL, F_TARGETLF, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
f = retflag[i];
|
||||
|
@ -16696,6 +16748,14 @@ void startlfturn(lifeform_t *lf) {
|
|||
}
|
||||
}
|
||||
} // end if f_target or f_targetcell
|
||||
|
||||
// hp drain
|
||||
if (f->id == F_HPDRAIN) {
|
||||
losehp(lf, f->val[0], DT_DIRECT, NULL, f->text);
|
||||
if (isdead(lf)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // end loop through lf flags
|
||||
}
|
||||
|
||||
|
@ -17004,7 +17064,6 @@ lifeform_t *summonmonster(lifeform_t *caster, cell_t *c, enum RACE rid, char *ra
|
|||
|
||||
|
||||
int takeoff(lifeform_t *lf, object_t *o) {
|
||||
flag_t *f;
|
||||
char obname[BUFLEN];
|
||||
char buf[BUFLEN];
|
||||
|
||||
|
@ -17066,19 +17125,7 @@ int takeoff(lifeform_t *lf, object_t *o) {
|
|||
|
||||
}
|
||||
|
||||
// lose flags
|
||||
loseobflags(lf, o, F_EQUIPCONFER);
|
||||
|
||||
f = hasflag(o->flags, F_CREATEDBYSPELL);
|
||||
if (f) stopspell(lf, f->val[0]);
|
||||
|
||||
if (obproduceslight(o)) {
|
||||
calclight((getoblocation(o))->map);
|
||||
setlosdirty(lf);
|
||||
//precalclos(lf);
|
||||
drawscreen();
|
||||
}
|
||||
|
||||
unequipeffects(lf, o);
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
@ -17432,6 +17479,29 @@ void turntoface(lifeform_t *lf, cell_t *dstcell) {
|
|||
setfacing(lf, getdirtowards(lf->cell, dstcell, NULL, B_FALSE, DT_ORTH) );
|
||||
}
|
||||
|
||||
void unequipeffects(lifeform_t *lf, object_t *o) {
|
||||
flag_t *f;
|
||||
// lose flags
|
||||
loseobflags(lf, o, F_EQUIPCONFER);
|
||||
|
||||
if (obproduceslight(o)) {
|
||||
calclight((getoblocation(o))->map);
|
||||
setlosdirty(lf);
|
||||
//precalclos(lf);
|
||||
drawscreen();
|
||||
}
|
||||
|
||||
if (o->type->id == OT_ENERGYBLADE) {
|
||||
stopspell(lf, OT_S_SUMMONWEAPON);
|
||||
// object might be dead now, so stop.
|
||||
return;
|
||||
}
|
||||
|
||||
f = hasflag(o->flags, F_CREATEDBYSPELL);
|
||||
if (f) {
|
||||
stopspell(lf, f->val[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void unsummon(lifeform_t *lf, int vanishobs) {
|
||||
lifeform_t *creator = NULL;
|
||||
|
@ -17530,19 +17600,7 @@ int unweild(lifeform_t *lf, object_t *o) {
|
|||
}
|
||||
}
|
||||
|
||||
// lose flags
|
||||
loseobflags(lf, o, F_EQUIPCONFER);
|
||||
|
||||
if (obproduceslight(o)) {
|
||||
calclight((getoblocation(o))->map);
|
||||
setlosdirty(lf);
|
||||
//precalclos(lf);
|
||||
drawscreen();
|
||||
}
|
||||
|
||||
if (o->type->id == OT_ENERGYBLADE) {
|
||||
stopspell(lf, OT_S_SUMMONWEAPON);
|
||||
}
|
||||
unequipeffects(lf, o);
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
@ -18109,6 +18167,72 @@ int validateraces(void) {
|
|||
return goterror;
|
||||
}
|
||||
|
||||
// returns TRUE on error
|
||||
int resizelf(lifeform_t *lf, enum LFSIZE newsize) {
|
||||
flag_t *f;
|
||||
enum LFSIZE origsize;
|
||||
int changedir;
|
||||
char lfname[BUFLEN];
|
||||
object_t *o,*nexto;
|
||||
getlfname(lf, lfname);
|
||||
f = hasflag(lf->flags, F_SIZE);
|
||||
if (f) {
|
||||
origsize = f->val[0];
|
||||
} else {
|
||||
origsize = SZ_HUMAN; // default
|
||||
}
|
||||
|
||||
if (origsize == newsize) {
|
||||
return B_TRUE;
|
||||
} else if (newsize > origsize) {
|
||||
changedir = 1;
|
||||
} else {
|
||||
changedir = -1;
|
||||
}
|
||||
|
||||
if (f) {
|
||||
f->val[0] = newsize;
|
||||
} else {
|
||||
addflag(lf->flags, F_SIZE, newsize, NA, NA, NULL);
|
||||
}
|
||||
|
||||
// announce
|
||||
if (isplayer(lf)) {
|
||||
msg("Your body %s unnaturally!", (changedir == 1) ? "grows" : "shrinks");
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s %s unnaturally!", lfname, (changedir == 1) ? "grows" : "shrinks");
|
||||
}
|
||||
|
||||
// effects on objects, armour etc
|
||||
for (o = lf->pack->first ; o ; o = nexto) {
|
||||
nexto = o->next;
|
||||
|
||||
// object is now the wrong size?
|
||||
if (isequipped(o) && isarmour(o)) {
|
||||
if (!armourfits(lf, o, NULL)) {
|
||||
char obname[BUFLEN];
|
||||
getobname(o, obname, o->amt);
|
||||
if (isplayer(lf)) {
|
||||
msg("Your %s no longer fits!", noprefix(obname));
|
||||
} else if (cansee(player, lf)) {
|
||||
msg("%s%s %s no longer fits!", lfname, getpossessive(lfname), noprefix(obname));
|
||||
}
|
||||
killflagsofid(o->flags, F_EQUIPPED);
|
||||
unequipeffects(lf, o);
|
||||
if (isplayer(lf)) statdirty = B_TRUE; // might have impacted AR
|
||||
}
|
||||
}
|
||||
|
||||
// object is now too big to hold?
|
||||
if (canpickup(lf, o, o->amt) == E_TOOBIG) {
|
||||
drop(o, o->amt);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
int rest(lifeform_t *lf, int onpurpose) {
|
||||
flag_t *f;
|
||||
flag_t *ff;
|
||||
|
|
2
lf.h
2
lf.h
|
@ -368,6 +368,7 @@ int readytotrain(lifeform_t *lf);
|
|||
int recruit(lifeform_t *lf);
|
||||
void refreshlevelabilities(lifeform_t *lf);
|
||||
void relinklf(lifeform_t *src, map_t *dst);
|
||||
int resizelf(lifeform_t *lf, enum LFSIZE newsize);
|
||||
int rest(lifeform_t *lf, int onpurpose);
|
||||
void setskillused(lifeform_t *lf, enum SKILL skid);
|
||||
int startclimbing(lifeform_t *lf);
|
||||
|
@ -416,6 +417,7 @@ void timeeffectslf(lifeform_t *lf);
|
|||
int tryclimb(lifeform_t *lf, cell_t *where, char *towhat);
|
||||
int touch(lifeform_t *lf, object_t *o);
|
||||
void turntoface(lifeform_t *lf, cell_t *dstcell);
|
||||
void unequipeffects(lifeform_t *lf, object_t *o);
|
||||
void unpoison(lifeform_t *lf);
|
||||
void unsummon(lifeform_t *lf, int vanishobs);
|
||||
int unweild(lifeform_t *lf, object_t *o);
|
||||
|
|
244
map.c
244
map.c
|
@ -805,6 +805,7 @@ void adjustcellglyphforlight(cell_t *c, glyph_t *g) {
|
|||
int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int doorpct, int dooropenchance) {
|
||||
int i,d;
|
||||
cell_t *poss[MAXCANDIDATES], *cell[MAXCANDIDATES]; // TODO: should this be maxroomw * maxroomh ?
|
||||
int possdir[MAXCANDIDATES];
|
||||
int ncells = 0, npossible = 0;
|
||||
int doorsadded = 0;
|
||||
int db = B_TRUE;
|
||||
|
@ -835,11 +836,13 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
|
|||
makedoor(cell[i], dooropenchance);
|
||||
} else {
|
||||
setcelltype(cell[i], cell[i]->habitat->emptycelltype);
|
||||
cell[i]->isroomwall = compassdir(d);
|
||||
addflag(map->flags, F_ROOMEXIT, roomid, cell[i]->x, cell[i]->y, "from autodoors, only way out");
|
||||
}
|
||||
} else {
|
||||
// otherwise mark this as a _potential_ door location.
|
||||
poss[npossible] = cell[i];
|
||||
possdir[npossible] = d;
|
||||
npossible++;
|
||||
}
|
||||
}
|
||||
|
@ -857,6 +860,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
|
|||
setcelltype(poss[sel], poss[sel]->habitat->emptycelltype);
|
||||
addflag(map->flags, F_ROOMEXIT, roomid, poss[sel]->x, poss[sel]->y, "from autodoors, potential location");
|
||||
}
|
||||
poss[sel]->isroomwall = compassdir(possdir[sel]);
|
||||
|
||||
doorsadded++;
|
||||
}
|
||||
|
@ -888,7 +892,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
|
|||
}
|
||||
sel = rnd(0,nposs-1);
|
||||
used[poss[sel]] = B_TRUE;
|
||||
dodoor[ndodoors++] = poss[sel];
|
||||
dodoor[ndodoors] = poss[sel];
|
||||
}
|
||||
|
||||
// actually make the doors
|
||||
|
@ -906,6 +910,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
|
|||
addflag(map->flags, F_ROOMEXIT, roomid, cell[sel]->x, cell[sel]->y, "from autodoors, forced at end");
|
||||
doorsadded++;
|
||||
}
|
||||
cell[sel]->isroomwall = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1041,6 +1046,63 @@ int cellhaslos(cell_t *c1, cell_t *dest) {
|
|||
return B_TRUE;
|
||||
}
|
||||
|
||||
// is the given cell a wall of a vault with maintain_edge, and not marked as an exit?
|
||||
int cellisfixedvaultwall(cell_t *c) {
|
||||
if ( getcellvault(c) &&
|
||||
c->type->solid &&
|
||||
hasflag(c->room->vault->flags, F_MAINTAINEDGE) &&
|
||||
!hasflagval(c->map->flags, F_ROOMEXIT, c->room->id, c->x, c->y, NULL) ) {
|
||||
return B_TRUE;
|
||||
}
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
// returns B_TRUE, B_FALSE or B_MAYBE
|
||||
int cellokforreachability(cell_t *startcell, cell_t *c, int srcroomid, int dir, int wantfilled, int *insameroom) {
|
||||
int db = B_TRUE;
|
||||
if ((srcroomid >= 0) && (getroomid(c) == srcroomid) && c->type->solid && startcell->type->solid) {
|
||||
// hits a wall of the same room,
|
||||
// and start cell NOT one inside the room.
|
||||
|
||||
// invalid
|
||||
if (insameroom) *insameroom = B_TRUE;
|
||||
if (db) dblog(" going %s hits wall of same room. invalid.", getdirname(dir));
|
||||
return B_FALSE;
|
||||
} else if (isroom(c) && (getroomid(c) != srcroomid) && (c->isroomwall != diropposite(dir))) {
|
||||
// cell is in a different room, but not the correct edge
|
||||
// invalid
|
||||
if (insameroom) *insameroom = B_FALSE;
|
||||
if (db) dblog(" going %s hits wrong wall of different room. invalid.", getdirname(dir));
|
||||
return B_FALSE;
|
||||
} else if (cellisfixedvaultwall(c)) {
|
||||
// cell is a wall of a maintain_edge vault, and not an exit cell
|
||||
// invalid
|
||||
if (insameroom) *insameroom = B_FALSE;
|
||||
if (db) dblog(" going %s hits non-exit wall maintain_edge vault. invalid.", getdirname(dir));
|
||||
return B_FALSE;
|
||||
} else if (isroom(c) && (getroomid(c) != srcroomid) && c->type->solid && countadjdoors(c) ) {
|
||||
// cell is the wall of a different room, and adjacent to a door.
|
||||
// invalid
|
||||
if (insameroom) *insameroom = B_FALSE;
|
||||
if (db) dblog(" going %s hits wall adjacent to door. invalid.", getdirname(dir));
|
||||
return B_FALSE;
|
||||
} else if (cellwalkable(NULL, c, NULL)) {
|
||||
if (getroomid(c) == srcroomid) {
|
||||
// invalid
|
||||
if (insameroom) *insameroom = B_TRUE;
|
||||
if (db) dblog(" going %s hits empty cell of same room. invalid.", getdirname(dir));
|
||||
return B_FALSE;
|
||||
} else {
|
||||
if (!wantfilled || c->filled) {
|
||||
// walkable and not in this vault. finished.
|
||||
// valid.
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return B_MAYBE;
|
||||
}
|
||||
|
||||
void clearcell(cell_t *c) {
|
||||
// kill everything there - (lifeforms && objects)
|
||||
if (c->lf && !isplayer(c->lf)) {
|
||||
|
@ -1820,6 +1882,20 @@ int countadjrooms(cell_t *cell) {
|
|||
return count;
|
||||
}
|
||||
|
||||
int countadjdoors(cell_t *cell) {
|
||||
int d;
|
||||
int doors = 0;
|
||||
|
||||
for (d = DC_N; d <= DC_NW; d++) {
|
||||
cell_t *newcell;
|
||||
newcell = getcellindir(cell, d);
|
||||
if (newcell || hasobwithflag(newcell->obpile, F_DOOR)) {
|
||||
doors++;
|
||||
}
|
||||
}
|
||||
return doors;
|
||||
}
|
||||
|
||||
int countadjwalls(cell_t *cell) {
|
||||
int d;
|
||||
int walls = 0;
|
||||
|
@ -3742,64 +3818,57 @@ void killmap(map_t *m) {
|
|||
// if 'wantfilled' is set, only link to "filled" cells.
|
||||
// return TRUE on failure.
|
||||
int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
||||
int db = B_FALSE;
|
||||
int d, roomid;
|
||||
int db = B_TRUE;
|
||||
int d, roomid,startd,endd;
|
||||
int poss2[MAXCANDIDATES],nposs2;
|
||||
int dist[MAXDIR_ORTH],hitsedge[MAXDIR_ORTH], sameroom[MAXDIR_ORTH];
|
||||
cell_t *directendcell[MAXDIR_ORTH];
|
||||
int mindist = 999,maxdist = -1;
|
||||
cell_t *c;
|
||||
int forcedir = D_NONE;
|
||||
|
||||
if (ncellsadded) *ncellsadded = 0;
|
||||
|
||||
if (db) dblog(" calling linkexit() for cell at %d,%d", startcell->x, startcell->y);
|
||||
|
||||
roomid = getroomid(startcell);
|
||||
if (db) dblog(" calling linkexit() for cell at %d,%d in roomid %d", startcell->x, startcell->y, roomid);
|
||||
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
hitsedge[d] = B_TRUE;
|
||||
directendcell[d] = NULL;
|
||||
}
|
||||
|
||||
// link it. starting from the door, count the number of cells in
|
||||
// link it.
|
||||
// if our cell is marked specifically as a room exit, our first direction MUST be out the
|
||||
// door.
|
||||
if (startcell->isroomwall != D_NONE) {
|
||||
forcedir = startcell->isroomwall;
|
||||
startd = forcedir;
|
||||
endd = forcedir;
|
||||
} else {
|
||||
startd = D_N; endd = D_W;
|
||||
}
|
||||
|
||||
// otherwise, starting from the door, count the number of cells in
|
||||
// each direction until we hit an empty (walkable) cell which isn't a room.
|
||||
|
||||
// if we hit a cell of this roomid, mark this dir as invalid.
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
for (d = startd; d <= endd; d++) {
|
||||
dist[d] = 0;
|
||||
hitsedge[d] = B_FALSE;
|
||||
sameroom[d] = B_FALSE;
|
||||
c = getcellindir(startcell, d);
|
||||
while (c) {
|
||||
int rv;
|
||||
dist[d]++;
|
||||
if ((roomid >= 0) && getroomid(c) == roomid) { // same room
|
||||
//if (wantfilled && c->type->solid) {
|
||||
if (c->type->solid) {
|
||||
// This is an exception:
|
||||
// if startcell is a cell _inside_ the room as opposed to
|
||||
// a cell inside the room's walls.
|
||||
// in this case, we ARE allowed to travel through the room's walls.
|
||||
} else {
|
||||
// mark dir as invalid
|
||||
dist[d] = 999;
|
||||
sameroom[d] = B_TRUE;
|
||||
if (db) dblog(" going %s hits same room. invalid.", getdirname(d));
|
||||
break;
|
||||
}
|
||||
} else if (isroom(c) && (getroomid(c) != roomid) && (c->isroomwall != diropposite(d))) {
|
||||
// cell is in a different room, but not the correct edge
|
||||
// mark dir as invalid
|
||||
|
||||
rv = cellokforreachability(startcell, c, roomid, d, wantfilled, &(sameroom[d]));
|
||||
if (rv == B_FALSE) {
|
||||
dist[d] = 999;
|
||||
sameroom[d] = B_FALSE;
|
||||
if (db) dblog(" going %s hits wrong wall of different room. invalid.", getdirname(d));
|
||||
break;
|
||||
} else if (cellwalkable(NULL, c, NULL)) {
|
||||
if (!wantfilled || c->filled) {
|
||||
// walkable and not in this vault. finished.
|
||||
directendcell[d] = c;
|
||||
if (db) dblog(" can make %s path (hits empty cell at dist %d)", getdirname(d), dist[d]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
} else if (rv == B_TRUE) {
|
||||
directendcell[d] = c;
|
||||
if (db) dblog(" can make %s path (hits empty cell at dist %d)", getdirname(d), dist[d]);
|
||||
} else { // ie. rv == B_MAYBE
|
||||
int perpdir[2],n;
|
||||
cell_t *pcell = NULL;
|
||||
perpdir[0] = d - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
|
||||
|
@ -3813,6 +3882,7 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
proomid = getroomid(pcell);
|
||||
if (((roomid == -1 ) || (proomid != roomid)) && cellwalkable(NULL, pcell, NULL)) {
|
||||
if ((proomid >= 0) && (pcell->isroomwall != diropposite(perpdir[n]))) {
|
||||
} else if (cellisfixedvaultwall(pcell)) {
|
||||
} else {
|
||||
if (!wantfilled || c->filled) {
|
||||
// finished.
|
||||
|
@ -3855,23 +3925,29 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
int nstartposs = 0;
|
||||
// no good directions.
|
||||
if (db) dblog(" No directions lead to valid cells. Trying turns.");
|
||||
// starting at the LONGEST distance, traverse up each dir,
|
||||
// branching off looking for rooms.
|
||||
|
||||
// find longest distance that doesn't go through same room
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (!sameroom[d] && (dist[d] > maxdist2)) {
|
||||
maxdist2 = dist[d];
|
||||
|
||||
if (forcedir != D_NONE) {
|
||||
startdir = forcedir;
|
||||
} else {
|
||||
// starting at the LONGEST distance, traverse up each dir,
|
||||
// branching off looking for rooms.
|
||||
|
||||
// find longest distance that doesn't go through same room
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (!sameroom[d] && (dist[d] > maxdist2)) {
|
||||
maxdist2 = dist[d];
|
||||
}
|
||||
}
|
||||
}
|
||||
// pick one randomly
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (dist[d] == maxdist2) {
|
||||
startposs[nstartposs++] = d;
|
||||
// pick one randomly
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (dist[d] == maxdist2) {
|
||||
startposs[nstartposs++] = d;
|
||||
}
|
||||
}
|
||||
if (nstartposs) {
|
||||
startdir = startposs[rnd(0,nstartposs-1)];
|
||||
}
|
||||
}
|
||||
if (nstartposs) {
|
||||
startdir = startposs[rnd(0,nstartposs-1)];
|
||||
}
|
||||
|
||||
if (wantfilled) {
|
||||
|
@ -3902,6 +3978,7 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
|
||||
while (c2) {
|
||||
int gotsolution = B_FALSE;
|
||||
int rv;
|
||||
turndist++;
|
||||
|
||||
perpcell[nperpcells] = c2; // this will be used if we need to make 2 turns
|
||||
|
@ -3909,25 +3986,12 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
perpturndir1[nperpcells] = perpdir[n];
|
||||
nperpcells++;
|
||||
|
||||
if ((roomid >= 0) && (getroomid(c2) == roomid)) {
|
||||
if (wantfilled && c2->type->solid) {
|
||||
// see EXCEPTION above.
|
||||
} else {
|
||||
// hits same room, not ok.
|
||||
break;
|
||||
}
|
||||
} else if (cellwalkable(NULL, c2, NULL)) {
|
||||
if (!wantfilled || c2->filled) {
|
||||
if (db) dblog(" Got to an empty cell here.");
|
||||
gotsolution = B_TRUE;
|
||||
}
|
||||
} else if (isroom(c2) && (c2->isroomwall != diropposite(perpdir[n]))) {
|
||||
// wrong wall of room
|
||||
// mark dir as invalid
|
||||
dist[d] = 999;
|
||||
sameroom[d] = B_FALSE;
|
||||
if (db) dblog(" going %s hits wrong wall of different room. invalid.", getdirname(d));
|
||||
rv = cellokforreachability(startcell, c2, roomid, perpdir[n], wantfilled, NULL);
|
||||
|
||||
if (rv == B_FALSE) {
|
||||
break;
|
||||
} else if (rv == B_TRUE) {
|
||||
gotsolution = B_TRUE;
|
||||
} else if (turndist > 1) {
|
||||
// check l/r too
|
||||
int perpdir2[2],nn;
|
||||
|
@ -3942,6 +4006,7 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
if ( ((roomid == -1) || (proomid != roomid)) &&
|
||||
cellwalkable(NULL, pcell, NULL)) {
|
||||
if ((proomid >= 0) && (pcell->isroomwall != diropposite(perpdir2[n]))) {
|
||||
} else if (cellisfixedvaultwall(pcell)) {
|
||||
} else {
|
||||
if (!wantfilled || pcell->filled) {
|
||||
// finished.
|
||||
|
@ -4013,27 +4078,16 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
c2 = getcellindir(perpcell[i], dir3[n]);
|
||||
while (c2) {
|
||||
int gotsolution = B_FALSE;
|
||||
int rv;
|
||||
turndist++;
|
||||
if (db) dblog_nocr("(%d,%d)",c2->x,c2->y);
|
||||
if ((roomid >= 0) && (getroomid(c2) == roomid)) {
|
||||
if (wantfilled && c2->type->solid) {
|
||||
// see EXCEPTION above.
|
||||
} else {
|
||||
// hits same room, not ok.
|
||||
break;
|
||||
}
|
||||
} else if (cellwalkable(NULL, c2, NULL)) {
|
||||
if (!wantfilled || c2->filled) {
|
||||
if (db) dblog(" Got to an empty cell here.");
|
||||
gotsolution = B_TRUE;
|
||||
}
|
||||
} else if (isroom(c2) && (c2->isroomwall != diropposite(dir3[n]))) {
|
||||
// wrong wall of room
|
||||
// mark dir as invalid
|
||||
dist[d] = 999;
|
||||
sameroom[d] = B_FALSE;
|
||||
if (db) dblog(" going %s hits wrong wall of different room. invalid.", getdirname(d));
|
||||
|
||||
rv = cellokforreachability(startcell, c2, roomid, perpdir[n], wantfilled, NULL);
|
||||
|
||||
if (rv == B_FALSE) {
|
||||
break;
|
||||
} else if (rv == B_TRUE) {
|
||||
gotsolution = B_TRUE;
|
||||
} else if (turndist > 1) {
|
||||
// check l/r too
|
||||
int perpdir2[2],nn;
|
||||
|
@ -4049,6 +4103,7 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
cellwalkable(NULL, pcell, NULL)) {
|
||||
if ((proomid >= 0) && (pcell->isroomwall != diropposite(perpdir2[nn]))) {
|
||||
// different room and hits wrong wall.
|
||||
} else if (cellisfixedvaultwall(pcell)) {
|
||||
} else {
|
||||
if (!wantfilled || pcell->filled) {
|
||||
// finished.
|
||||
|
@ -4167,7 +4222,7 @@ int linkexits(map_t *m, int roomid) {
|
|||
int x,y,i;
|
||||
cell_t *poss[MAXCANDIDATES],*c;
|
||||
int nposs = 0;
|
||||
int db = B_FALSE;
|
||||
int db = B_TRUE;
|
||||
int nadded = 0;
|
||||
int minx = -1, miny = -1, maxx = -1, maxy = -1;
|
||||
int roomidx = -1;
|
||||
|
@ -4225,15 +4280,14 @@ int linkexits(map_t *m, int roomid) {
|
|||
for (i = 0; i < nposs; i++) {
|
||||
int ncorridors = 0,d;
|
||||
|
||||
if (db) dblog("exit at %d,%d:",poss[i]->x, poss[i]->y);
|
||||
if (db) dblog("exit #%d at %d,%d: (%s)",i, poss[i]->x, poss[i]->y,
|
||||
(poss[i]->isroomwall != D_NONE) ? getdirname(poss[i]->isroomwall) : "nodir");
|
||||
// if exit is solid and COMPLETELY surrounded by solid, ignore it.
|
||||
if (poss[i]->type->solid && (countcellexits(poss[i], DT_ORTH) == 0)){
|
||||
if (db) dblog("cell is solid and surrounded by solids. ignoring.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (db) dblog("linking exit #%d",i);
|
||||
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
c = getcellindir(poss[i], d);
|
||||
if (c && cellwalkable(NULL, c, NULL) && (getroomid(c) != roomid)) {
|
||||
|
@ -5595,6 +5649,20 @@ cell_t *getrandomcelloftype(map_t *map, enum CELLTYPE id) {
|
|||
return cell;
|
||||
}
|
||||
|
||||
int compassdir(int orthdir) {
|
||||
switch (orthdir) {
|
||||
case D_N:
|
||||
return DC_N;
|
||||
case D_S:
|
||||
return DC_S;
|
||||
case D_E:
|
||||
return DC_E;
|
||||
case D_W:
|
||||
return DC_W;
|
||||
}
|
||||
return D_NONE;
|
||||
}
|
||||
|
||||
|
||||
int getrandomdir(int dirtype) {
|
||||
if (dirtype == DT_ORTH) {
|
||||
|
|
4
map.h
4
map.h
|
@ -14,6 +14,8 @@ regiontype_t *addregiontype(enum REGIONTYPE id, char *name, int pluralname, enum
|
|||
void adjustcellglyphforlight(cell_t *c, glyph_t *col);
|
||||
int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int doorpct, int dooropenchance);
|
||||
int cellhaslos(cell_t *c1, cell_t *dest);
|
||||
int cellisfixedvaultwall(cell_t *c);
|
||||
int cellokforreachability(cell_t *startcell, cell_t *c, int srcroomid, int dir, int wantfilled, int *insameroom);
|
||||
void clearcell(cell_t *c);
|
||||
void clearcell_exceptflags(cell_t *c, ...);
|
||||
int doelementspread(cell_t *c);
|
||||
|
@ -39,9 +41,11 @@ void getroomedge(map_t *m, int roomid, int minx, int miny, int maxx, int maxy, i
|
|||
object_t *gettopobject(cell_t *where, int forglyph);
|
||||
void calclight(map_t *map);
|
||||
int calcroompos(map_t *map, int w, int h, int xmargin, int ymargin, int *bx, int *by, int force);
|
||||
int compassdir(int orthdir);
|
||||
int countadjcellsoftype(cell_t *cell, int id);
|
||||
int countadjrooms(cell_t *cell);
|
||||
int countadjcellswithflag(cell_t *cell, enum FLAG fid, int dirtype);
|
||||
int countadjdoors(cell_t *cell);
|
||||
int countadjwalls(cell_t *cell);
|
||||
int countcellexits(cell_t *cell, int dirtype);
|
||||
int countcellexitsfor(lifeform_t *lf);
|
||||
|
|
4
nexus.c
4
nexus.c
|
@ -215,7 +215,7 @@ int main(int argc, char **argv) {
|
|||
if (hasflag(r->flags, F_PLAYABLE)) {
|
||||
char *longdesc;
|
||||
longdesc = malloc(HUGEBUFLEN * sizeof(char));
|
||||
makedesc_race(r->id, longdesc, B_TRUE );
|
||||
makedesc_race(r->id, longdesc, B_TRUE, B_TRUE );
|
||||
addchoice(&prompt, ch++, r->name, NULL, r, longdesc);
|
||||
free(longdesc);
|
||||
}
|
||||
|
@ -355,6 +355,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
if (sb1) {
|
||||
addflag(player->flags, F_CANCAST, sb1->contents->first->type->id, NA, NA, NULL);
|
||||
addflag(sb1->flags, F_NOPOINTS, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
|
||||
initprompt(&prompt, "Select your secondary spell school:");
|
||||
|
@ -388,6 +389,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
if (sb2) {
|
||||
addflag(player->flags, F_CANCAST, sb2->contents->first->type->id, NA, NA, NULL);
|
||||
addflag(sb2->flags, F_NOPOINTS, B_TRUE, NA, NA, NULL);
|
||||
}
|
||||
identify(sb1);
|
||||
identify(sb2);
|
||||
|
|
87
objects.c
87
objects.c
|
@ -3378,8 +3378,15 @@ void fragments(cell_t *centre, char *what, int speed, int howfar) {
|
|||
done = B_FALSE;
|
||||
while (!done) {
|
||||
c = getcellindir(c, dir);
|
||||
if (c && cellwalkable(NULL, c, NULL)) {
|
||||
maxdist++;
|
||||
if (c) {
|
||||
if (cellwalkable(NULL, c, NULL)) {
|
||||
maxdist++;
|
||||
} else {
|
||||
if (c->lf && !c->type->solid) {
|
||||
maxdist++;
|
||||
}
|
||||
done = B_TRUE;
|
||||
}
|
||||
} else {
|
||||
done = B_TRUE;
|
||||
}
|
||||
|
@ -3412,8 +3419,17 @@ void fragments(cell_t *centre, char *what, int speed, int howfar) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
// add object
|
||||
addob(dst->obpile, what);
|
||||
if (speed) {
|
||||
object_t *o;
|
||||
// add object then fire it
|
||||
o = addob(centre->obpile, what);
|
||||
if (o) {
|
||||
fireat(NULL, o, o->amt, dst, speed, NULL);
|
||||
}
|
||||
} else {
|
||||
// add object
|
||||
addob(dst->obpile, what);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4576,6 +4592,20 @@ cell_t *getobpilelocation(obpile_t *op) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// note: should have an entry here for everything which willshatter()
|
||||
char *getshardobname(enum MATERIAL mid, char *buf) {
|
||||
switch (mid) {
|
||||
case MT_GLASS:
|
||||
strcpy(buf, "piece of broken glass");
|
||||
break;
|
||||
case MT_ICE:
|
||||
strcpy(buf, "chunk of ice");
|
||||
break;
|
||||
default: return NULL;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *getshopobname(object_t *o, char *buf, int count) {
|
||||
if (gettechlevel(o->type->id) > getskill(player, SK_TECHUSAGE)) {
|
||||
// unidentified tech - hide the name
|
||||
|
@ -9765,6 +9795,13 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
|
|||
case OT_POT_GASEOUSFORM:
|
||||
dospelleffects(lf, OT_S_GASEOUSFORM, (potblessed) ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE);
|
||||
break;
|
||||
case OT_POT_GROWTH:
|
||||
if (iscursed(o)) {
|
||||
dospelleffects(lf, OT_S_SIZEDOWN, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE);
|
||||
} else {
|
||||
dospelleffects(lf, OT_S_SIZEUP, 1, lf, NULL, lf->cell, B_UNCURSED, seen, B_TRUE);
|
||||
}
|
||||
break;
|
||||
case OT_POT_HEALING:
|
||||
dospelleffects(lf, OT_S_HEALING,potblessed ? 5 : 1, lf, NULL, lf->cell, potblessed, seen, B_TRUE);
|
||||
break;
|
||||
|
@ -10933,6 +10970,7 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
|
|||
case OT_POT_ELEMENTIMMUNE:
|
||||
case OT_POT_ETHEREALNESS:
|
||||
case OT_POT_GASEOUSFORM:
|
||||
case OT_POT_GROWTH:
|
||||
case OT_POT_LEVITATION:
|
||||
case OT_POT_POISON:
|
||||
case OT_POT_POLYMORPH:
|
||||
|
@ -12390,7 +12428,8 @@ void timeeffectsob(object_t *o) {
|
|||
|
||||
|
||||
// check each flag for this object...
|
||||
getflags(o->flags, retflag, &nretflags, F_ACTIVATED, F_EDIBLE, F_MATCONVERT, F_OBHPDRAIN, F_ONFIRE, F_RECHARGE, F_WALKDAM, F_WET, F_NONE);
|
||||
getflags(o->flags, retflag, &nretflags, F_ACTIVATED, F_EDIBLE, F_MATCONVERT, F_OBHPDRAIN, F_ONFIRE,
|
||||
F_RECHARGE, F_REVIVETIMER, F_WALKDAM, F_WET, F_NONE);
|
||||
for (i = 0; i < nretflags; i++) {
|
||||
object_t *oo,*nextoo;
|
||||
f = retflag[i];
|
||||
|
@ -12531,6 +12570,44 @@ void timeeffectsob(object_t *o) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// regenerates into a lf?
|
||||
if (f->id == F_REVIVETIMER) {
|
||||
cell_t *obloc = NULL;
|
||||
obloc = getoblocation(o);
|
||||
f->val[0]++;
|
||||
limit(&f->val[0], 0, f->val[1]);
|
||||
if (f->val[0] >= f->val[1]) {
|
||||
lifeform_t *lf;
|
||||
cell_t *lfloc = NULL;
|
||||
if (obloc) {
|
||||
if (obloc->lf) {
|
||||
lfloc = getrandomadjcell(obloc, WE_WALKABLE, B_NOEXPAND);
|
||||
} else {
|
||||
lfloc = obloc;
|
||||
}
|
||||
}
|
||||
|
||||
if (lfloc) {
|
||||
// revive!
|
||||
lf = addmonster(lfloc, f->val[2], NULL, B_FALSE, 1, B_FALSE, NULL);
|
||||
// corpse vanishes
|
||||
removeob(o, o->amt);
|
||||
// announce
|
||||
if (haslos(player, lfloc) || haslos(player, obloc)) {
|
||||
msg("%s comes to life!", obname);
|
||||
interrupt(player);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if ((f->val[1] - f->val[0]) <= 10) {
|
||||
if (haslos(player, obloc)) {
|
||||
// pass a perception chekc to see it moving...
|
||||
if (skillcheck(player, SC_SEARCH, 20, 0)) {
|
||||
msg("%s twitches.", obname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// damaging objects here will damage other objects
|
||||
if (f->id == F_WALKDAM) {
|
||||
|
|
|
@ -122,6 +122,7 @@ char *getobextrainfo(object_t *o, char *buf);
|
|||
cell_t *getoblocation(object_t *o);
|
||||
cell_t *getobpilelocation(obpile_t *op);
|
||||
char *getobname(object_t *o, char *buf, int count);
|
||||
char *getshardobname(enum MATERIAL mid, char *buf);
|
||||
char *getshopobname(object_t *o, char *buf, int count);
|
||||
char *getobnametrue(object_t *o, char *buf, int count);
|
||||
char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wantcondition, int adjustforblind, int wantblesscurse, int showall);
|
||||
|
|
24
spell.c
24
spell.c
|
@ -8772,6 +8772,30 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
|
|||
if (isplayer(caster)) {
|
||||
msg("You will now be warned of creatures behind you.");
|
||||
}
|
||||
} else if ((spellid == OT_S_SIZEUP) || (spellid == OT_S_SIZEDOWN)) {
|
||||
enum LFSIZE origsize,newsize;
|
||||
origsize = getlfsize(caster);
|
||||
if (spellid == OT_S_SIZEUP) {
|
||||
if (origsize >= SZ_ENORMOUS) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
newsize = origsize + 1;
|
||||
} else { // ie. sizedown
|
||||
if (origsize <= SZ_MINI) {
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
newsize = origsize - 1;
|
||||
}
|
||||
if (resizelf(caster, newsize)) {
|
||||
// failed
|
||||
fizzle(caster);
|
||||
return B_TRUE;
|
||||
}
|
||||
if (isplayer(caster) || cansee(player, caster)) {
|
||||
if (seenbyplayer) *seenbyplayer = B_TRUE;
|
||||
}
|
||||
} else if (spellid == OT_S_SLEEP) {
|
||||
int howlong;
|
||||
target = targcell->lf;
|
||||
|
|
3
vault.c
3
vault.c
|
@ -1330,6 +1330,9 @@ int handleline(vault_t *v, char *line) {
|
|||
} else {
|
||||
dblog("invalid goesin() definition: '%s'", line);
|
||||
}
|
||||
} else if (streq(line, "maintainedge")) {
|
||||
addflag(v->flags, F_MAINTAINEDGE, B_TRUE, NA, NA, NULL);
|
||||
ok = B_TRUE;
|
||||
} else if (strstarts(line, "margin")) {
|
||||
char *p;
|
||||
p = line + 6;
|
||||
|
|
|
@ -21,5 +21,6 @@ X:exit
|
|||
goesin:dungeon
|
||||
mayrotate
|
||||
rarity:vrare
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
|
@ -22,5 +22,6 @@ scatter(3,1,-4,-2) mon:bear cub:1-3:50
|
|||
goesin:dungeon
|
||||
mayrotate
|
||||
rarity:uncommon
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
|
@ -35,5 +35,6 @@ scatter(1,1,-2,-2) ob:wooden footstool:0-3
|
|||
scatter(1,1,-2,-2) ob:random food:0-2
|
||||
mayflipx
|
||||
tag:caveboss
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
|
@ -16,5 +16,6 @@ m:mon:sleeping random
|
|||
goesin:dungeon
|
||||
mayrotate
|
||||
rarity:uncommon
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
@flags
|
||||
goesin:dungeon
|
||||
autodoors:50
|
||||
autopop
|
||||
rarity:frequent
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
|
@ -17,5 +17,6 @@ x:exit
|
|||
@flags
|
||||
goesin:dungeon
|
||||
rarity:frequent
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
|
@ -17,4 +17,5 @@ x:exit
|
|||
goesin:dungeon
|
||||
rarity:frequent
|
||||
mayrotate
|
||||
maintainedge
|
||||
@end
|
||||
|
|
|
@ -26,5 +26,6 @@ shrine
|
|||
norandom
|
||||
mayrotate
|
||||
goesin:dungeon
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
|
@ -33,5 +33,6 @@ atoneof(10,1)(10,3)(10,5) ob:portal to lv1
|
|||
scatter(1,1,-2,-2) ob:wooden footstool:0-3
|
||||
scatter(1,1,-2,-2) ob:random food:0-2
|
||||
mayrotate
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
|
@ -42,5 +42,6 @@ scatter(0,0,-1,-1) ob:common weapon:4-5
|
|||
mayrotate
|
||||
! mayscale
|
||||
rarity:rare
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
|
@ -15,5 +15,6 @@ o:ob:1-5 random tools
|
|||
@flags
|
||||
goesin:dungeon
|
||||
rarity:uncommon
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
|
@ -15,5 +15,6 @@ o:ob:1-5 random technology
|
|||
@flags
|
||||
goesin:dungeon
|
||||
rarity:uncommon
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
|
@ -20,5 +20,6 @@ mayrotate
|
|||
rarity:vrare
|
||||
! don't link to rest of map. ie this can be in the middle of nowhere.
|
||||
nolink
|
||||
maintainedge
|
||||
@end
|
||||
|
||||
|
|
Loading…
Reference in New Issue