- [+] disrupt undead

- [+] gust of wind has higher chance of knocking down small creatures
- [+] check: ensure vault names have no ' 's
- [+] loading bug: celltype id 0 doesn't exist.
- [+] loading bug: adding minotair - don't call sethomeroom()
- [+] fixed - bones bug: "2 loaves of stale bread"
- [+] crash when object thrown away by holy circle dies.
- [+] armour with "permenance" cast shouldn't be able to be healed
      either!
    - [+] use immutable instead of invulnerable
- [+] if you weild your spare weapon (and dont have a spare), remove
      'spareweapon' flag!
- [+] skoob should be made out of "water", not "ice" (don't want it to
      have hardness)
    - [+] change its material
    - [+] hitting water-based lfs should rust weapon!
- [+] rusted weapons should have 10-30% chance of giving tetanus.
    - [+] low chance of spasm each turn (5%)
    - [+] "your [xx] spasms/contorts violently!"
    - [+] hand = drop weapon
    - [+] leg = fall over
    - [+] jaw = nothing
    - [+] back = spine broken, you die
    - [+] tail = tail broken
    - [+] chest = rib broken
    - [+] wings = stop flying
- [+] electricity damage confuses robots
- [+] poison's power increase chance of its effects happening
    - [+] whenver tetanus effect fires, increase power.
- [+] electric damage spreads through water
- [+] create water spell (like grease, but just makes water)
- [+] objectgrowth spell shoudl use f_growsto instead of hardcoding
    - [+] v0 = obid or celltypeid
    - [+] vt = determines VT_ob or vt_cell
- [+] then add shrink spell which uses f_shrinksto
    - [+] deinfe it
    - [+] add effects
    - [+] specail case - brazer -> helmet should be red hot
- [+] hecta should mind attacking evil peaceful creatures
- [+] ai should still flee with bleeding legs
- [+] bandit had 90hp - problem with varlevel!! have changed
      calculation.
    - [+] monsters now just get 1 extra hit die per level after the
          first.
- [+] only some branches should use region->depthmod. others only use
      regiontype->depthmod.
- [+] spell: disrupt undead -
- [+] announce 'shatter' spell:  you hear an ultra=high pitched
      whining/ringing.
- [+] announce'sleep' spell: suddenly, you feel very drowsy.
- [+] inducefear: too powerful. tweak skillcheck values.
Initial work on baba yaga (sylvan forest boss)
This commit is contained in:
Rob Pearce 2012-04-01 19:48:13 +00:00
parent 61a5540866
commit 252a4024a7
16 changed files with 1214 additions and 482 deletions

124
attack.c
View File

@ -317,15 +317,17 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
if (!force && isplayer(lf) && wepdullable(priwep) if (!force && isplayer(lf) && wepdullable(priwep)
&& (getattrbracket(getattr(player, A_IQ), A_IQ, NULL) >= AT_GTAVERAGE) && && (getattrbracket(getattr(player, A_IQ), A_IQ, NULL) >= AT_GTAVERAGE) &&
!lfhasflag(lf, F_RAGE)) { !lfhasflag(lf, F_RAGE)) {
char obname[BUFLEN],wepname[BUFLEN],buf[BUFLEN]; if (!hasflagknown(priwep->flags, F_IMMUTABLE)) {
char ch; char obname[BUFLEN],wepname[BUFLEN],buf[BUFLEN];
real_getobname(o, obname, o->amt, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_NOSHOWALL); char ch;
getobname(priwep, wepname, priwep->amt); real_getobname(o, obname, o->amt, B_NOPREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_NOSHOWALL);
snprintf(buf, BUFLEN, "Attacking %s might damage your %s. Proceed?", obname, noprefix(wepname)); getobname(priwep, wepname, priwep->amt);
ch = askchar(buf, "yn","n", B_TRUE, B_FALSE); snprintf(buf, BUFLEN, "Attacking %s might damage your %s. Proceed?", obname, noprefix(wepname));
if (ch == 'n') { ch = askchar(buf, "yn","n", B_TRUE, B_FALSE);
// cancel. if (ch == 'n') {
return B_TRUE; // cancel.
return B_TRUE;
}
} }
}; };
} else { } else {
@ -580,7 +582,7 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
angergodmaybe(R_GODPURITY, 50, GA_ASSAULT); angergodmaybe(R_GODPURITY, 50, GA_ASSAULT);
switch (getalignment(attacktarget)) { switch (getalignment(attacktarget)) {
case AL_EVIL: case AL_EVIL:
angergodmaybe(R_GODDEATH, 20, GA_ASSAULT); // even more //angergodmaybe(R_GODDEATH, 20, GA_ASSAULT); // even more
break; break;
case AL_GOOD: case AL_GOOD:
angergodmaybe(R_GODPURITY, 20, GA_ASSAULT); // even more angergodmaybe(R_GODPURITY, 20, GA_ASSAULT); // even more
@ -956,7 +958,6 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
int damreducedbyarmour = 0; int damreducedbyarmour = 0;
int backstab = B_FALSE; int backstab = B_FALSE;
int prebleed = B_FALSE; int prebleed = B_FALSE;
flag_t *rust;
if (firstisbackstab && (i == 0)) backstab = B_TRUE; if (firstisbackstab && (i == 0)) backstab = B_TRUE;
@ -966,22 +967,14 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
// modify for rusted weapon. // modify for rusted weapon.
rust = hasflag(wep->flags, F_RUSTED); switch (damtype[i]) {
if (rust) { case DT_PIERCE:
switch (damtype[i]) { case DT_SLASH:
case DT_PIERCE: case DT_CHOP:
case DT_SLASH: dam[i] = pctof(getrustdampct(wep), dam[i]);
if (rust->val[0] >= R_TRUSTY) { break;
dam[i] -= (pctof(50, dam[i])); default:
} else if (rust->val[0] >= R_VRUSTY) { break;
dam[i] -= (pctof(25, dam[i]));
} else {
dam[i] -= (pctof(10, dam[i]));
}
break;
default:
break;
}
} }
// blocked by defender's shield? // blocked by defender's shield?
@ -1267,6 +1260,11 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
// other effects // other effects
if ((victim->material->id == MT_WATER) && wep && !isunarmed) {
makewet(wep, 1);
}
if (!isdead(victim) && !blocked && !dodged) { if (!isdead(victim) && !blocked && !dodged) {
// special weapon effects, as long as you're not doing a heavy blow // special weapon effects, as long as you're not doing a heavy blow
if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) { if (!lfhasflag(lf, F_HEAVYBLOW) && dam[0]) {
@ -1850,7 +1848,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d
protected = checkcritprotection(victim,armour); protected = checkcritprotection(victim,armour);
takedamage(armour, dam, damtype); takedamage(armour, dam, damtype);
} }
if (!protected) injure(victim, BP_BODY, damtype); if (!protected) injure(victim, BP_BODY, damtype, IJ_NONE);
break; break;
case BP_HEAD: case BP_HEAD:
if (pctchance(80)) fall(victim, lf, B_TRUE); if (pctchance(80)) fall(victim, lf, B_TRUE);
@ -1883,7 +1881,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d
takedamage(o, dam, damtype); takedamage(o, dam, damtype);
} }
} else { } else {
injure(victim, BP_HEAD, damtype); injure(victim, BP_HEAD, damtype, IJ_NONE);
} }
break; break;
case BP_HANDS: case BP_HANDS:
@ -1891,7 +1889,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d
protected = checkcritprotection(victim,armour); protected = checkcritprotection(victim,armour);
takedamage(armour, dam, damtype); takedamage(armour, dam, damtype);
} }
if (!protected) injure(victim, BP_HANDS, damtype); if (!protected) injure(victim, BP_HANDS, damtype, IJ_NONE);
if (onein(2)) { if (onein(2)) {
// drop your weapon! // drop your weapon!
@ -1915,7 +1913,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d
*/ */
takedamage(armour, dam, damtype); takedamage(armour, dam, damtype);
} else { } else {
injure(victim, BP_LEGS, damtype); injure(victim, BP_LEGS, damtype, IJ_NONE);
} }
break; break;
} }
@ -1924,7 +1922,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d
protected = checkcritprotection(victim,armour); protected = checkcritprotection(victim,armour);
takedamage(armour, dam, damtype); takedamage(armour, dam, damtype);
} }
if (!protected) injure(victim, hitpos, damtype); if (!protected) injure(victim, hitpos, damtype, IJ_NONE);
} else if (damtype == DT_EXPLOSIVE) { } else if (damtype == DT_EXPLOSIVE) {
if ((armour = getarmour(victim, hitpos)) != NULL) { if ((armour = getarmour(victim, hitpos)) != NULL) {
int min,max; int min,max;
@ -1934,7 +1932,7 @@ void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, int d
limit(&min, 1, NA); limit(&min, 1, NA);
takedamage(armour, rnd(min,max), DT_EXPLOSIVE); takedamage(armour, rnd(min,max), DT_EXPLOSIVE);
} }
if (!protected) injure(victim, hitpos, damtype); if (!protected) injure(victim, hitpos, damtype, IJ_NONE);
} }
if (lf) { if (lf) {
@ -2300,7 +2298,7 @@ int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag) {
int pct; int pct;
sumflags(o->pile->owner->flags, F_MELEEDAMPCT, &pct, NULL, NULL); sumflags(o->pile->owner->flags, F_MELEEDAMPCT, &pct, NULL, NULL);
if (pct != 0) { if (pct != 0) {
dam = pctof(f->val[0], dam); dam = pctof(pct, dam);
} }
} }
return dam; return dam;
@ -2529,6 +2527,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
int i; int i;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags = 0; int nretflags = 0;
char frombuf[BUFLEN];
if (!where) return; if (!where) return;
@ -2544,7 +2543,27 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
} }
victim = where->lf; victim = where->lf;
getflags(fp, retflag, &nretflags, F_FLAMESTRIKE, F_HEAVYBLOW, F_HITCONFER, F_RACESLAY, F_REVENGE, F_NONE); // calculate 'frombuf' string
strcpy(frombuf, "something unknown");
if (wep) {
if (owner) {
char lfname[BUFLEN];
char wepname[BUFLEN];
getlfnamea(owner, lfname);
getobname(wep, wepname, 1);
// ie. "a goblin's poisoned short sword"
snprintf(frombuf, BUFLEN, "%s%s %s",lfname,getpossessive(lfname), wepname);
} else {
char wepname[BUFLEN];
getobname(wep, wepname, 1);
// ie "a poisoned short sword"
snprintf(frombuf, BUFLEN, "%s", wepname);
}
}
getflags(fp, retflag, &nretflags, F_FLAMESTRIKE, F_HEAVYBLOW, F_HITCONFER, F_RACESLAY, F_REVENGE, F_RUSTED, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
if (f->id == F_FLAMESTRIKE) { if (f->id == F_FLAMESTRIKE) {
@ -2660,31 +2679,8 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
if (fid == F_POISONED) { if (fid == F_POISONED) {
// need to fill in the name of what poisoned us // need to fill in the name of what poisoned us
char frombuf[BUFLEN];
enum POISONTYPE ptype; enum POISONTYPE ptype;
int ppower; int ppower;
if (wep) {
if (owner) {
char lfname[BUFLEN];
char wepname[BUFLEN];
getlfnamea(owner, lfname);
getobname(wep, wepname, 1);
// ie. "a goblin's poisoned short sword"
snprintf(frombuf, BUFLEN, "%s%s %s",lfname,getpossessive(lfname), wepname);
} else {
char wepname[BUFLEN];
getobname(wep, wepname, 1);
// ie "a poisoned short sword"
snprintf(frombuf, BUFLEN, "%s", wepname);
}
} else {
if (strlen(ftext)) {
strcpy(frombuf, ftext);
} else {
strcpy(frombuf, "something unknown");
}
}
if (valflag) { if (valflag) {
ptype = valflag->val[0]; ptype = valflag->val[0];
@ -2699,6 +2695,9 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
ppower = 1; ppower = 1;
} }
if (!wep && strlen(ftext)) {
strcpy(frombuf, ftext);
}
poison(victim, howlong, ptype, ppower, frombuf, owner ? owner->race->id : R_NONE); poison(victim, howlong, ptype, ppower, frombuf, owner ? owner->race->id : R_NONE);
} else { } else {
// flag values // flag values
@ -2718,7 +2717,14 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) {
addflag(owner->flags, F_USEDPOISON, B_TRUE, NA, NA, NULL); addflag(owner->flags, F_USEDPOISON, B_TRUE, NA, NA, NULL);
} }
} }
} // end if (fid == hitconfer) } else if ((f->id == F_RUSTED) && victim ) {
int pct;
pct = f->val[0] * 10;
if (pctchance(pct)) {
poison(victim, PERMENANT, P_TETANUS, 1, frombuf, owner ? owner->race->id : R_NONE);
}
} // end if (fid == xxx)
} }
if (wep && owner && victim) { if (wep && owner && victim) {

216
data.c
View File

@ -1024,6 +1024,7 @@ void initobjects(void) {
addpoisontype(P_FOODBAD, "salmonella poisoning", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 2, 33, PS_POISON, 30); addpoisontype(P_FOODBAD, "salmonella poisoning", "Poisoned", "^bYOU vomit#S violently.", OT_VOMITPOOL, 2, 33, PS_POISON, 30);
addpoisontype(P_GAS, "gas inhalation", "Poisoned", "^bYOU cough#S.", OT_NONE, 1, 25, PS_POISON,0); addpoisontype(P_GAS, "gas inhalation", "Poisoned", "^bYOU cough#S.", OT_NONE, 1, 25, PS_POISON,0);
addpoisontype(P_ROT, "the mummy's curse", "Cursed", "", OT_NONE, 0, 0, PS_CURSE, 0); addpoisontype(P_ROT, "the mummy's curse", "Cursed", "", OT_NONE, 0, 0, PS_CURSE, 0);
addpoisontype(P_TETANUS, "tetanus", "Sick", "^bYOUR muscles spasm violently!", OT_NONE, 0, 3, PS_DISEASE, 15);
addpoisontype(P_VENOM, "venom poisoning", "Poisoned", "^bYOU cough#S up blood.", OT_BLOODSPLASH, 1, 25, PS_POISON, 0); addpoisontype(P_VENOM, "venom poisoning", "Poisoned", "^bYOU cough#S up blood.", OT_BLOODSPLASH, 1, 25, PS_POISON, 0);
addpoisontype(P_WEAKNESS, "weakening poison", "Poisoned", "cough", B_FALSE, 0, 0, PS_POISON, 0); addpoisontype(P_WEAKNESS, "weakening poison", "Poisoned", "cough", B_FALSE, 0, 0, PS_POISON, 0);
@ -1528,6 +1529,8 @@ void initobjects(void) {
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
addflag(lastot->flags, F_CANHAVEOBMOD, OM_MASTERWORK, 25, NA, NULL); addflag(lastot->flags, F_CANHAVEOBMOD, OM_MASTERWORK, 25, NA, NULL);
addflag(lastot->flags, F_CANHAVEOBMOD, OM_SHODDY, 25, NA, NULL); addflag(lastot->flags, F_CANHAVEOBMOD, OM_SHODDY, 25, NA, NULL);
addflag(lastot->flags, F_GROWSTO, CT_WALLWOOD, VT_CELL, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_BED, VT_OB, NA, NULL);
addot(OT_DOORIRON, "iron door", "A strong iron door.", MT_METAL, 300, OC_DFEATURE, SZ_LARGE); addot(OT_DOORIRON, "iron door", "A strong iron door.", MT_METAL, 300, OC_DFEATURE, SZ_LARGE);
// GLYPH here is a special case in getglyph // GLYPH here is a special case in getglyph
@ -1543,7 +1546,8 @@ void initobjects(void) {
addflag(lastot->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL); addflag(lastot->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL);
addflag(lastot->flags, F_DTIMMUNE, DT_SLASH, NA, NA, NULL); addflag(lastot->flags, F_DTIMMUNE, DT_SLASH, NA, NA, NULL);
addflag(lastot->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, CT_WALLMETAL, VT_CELL, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_SHIELD, VT_OB, NA, NULL);
addot(OT_FOUNTAIN, "fountain", "A running fountain of some kind of liquid.", MT_WATER, 20, OC_MISC, SZ_MEDIUM); addot(OT_FOUNTAIN, "fountain", "A running fountain of some kind of liquid.", MT_WATER, 20, OC_MISC, SZ_MEDIUM);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
@ -1559,6 +1563,7 @@ void initobjects(void) {
addflag(lastot->flags, F_DTCREATEOB, DT_FIRE, 0, DT_COMPASS, "cloud of steam"); addflag(lastot->flags, F_DTCREATEOB, DT_FIRE, 0, DT_COMPASS, "cloud of steam");
addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, B_DONTKILL, NULL); addflag(lastot->flags, F_DRINKABLE, B_TRUE, NA, B_DONTKILL, NULL);
addflag(lastot->flags, F_LINKOB, OT_POT_WATER, NA, NA, NULL); addflag(lastot->flags, F_LINKOB, OT_POT_WATER, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_WATERDEEP, VT_OB, NA, NULL);
// blocks movement, but you can see and fire through them. // blocks movement, but you can see and fire through them.
addot(OT_GATEIRON, "iron gate", "A gate comprised of a series of vertical iron bars, raised slightly above the floor.", MT_METAL, 500, OC_DFEATURE, SZ_LARGE); addot(OT_GATEIRON, "iron gate", "A gate comprised of a series of vertical iron bars, raised slightly above the floor.", MT_METAL, 500, OC_DFEATURE, SZ_LARGE);
@ -1573,8 +1578,22 @@ void initobjects(void) {
addflag(lastot->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL); addflag(lastot->flags, F_DTIMMUNE, DT_PIERCE, NA, NA, NULL);
addflag(lastot->flags, F_DTIMMUNE, DT_SLASH, NA, NA, NULL); addflag(lastot->flags, F_DTIMMUNE, DT_SLASH, NA, NA, NULL);
addflag(lastot->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_DTRESIST, DT_CHOP, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, CT_WALLMETAL, VT_CELL, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_IRONSTAFF, VT_OB, NA, NULL);
addot(OT_GATEBONE, "bone gate", "A grisly gate created from human bones.", MT_BONE, 60, OC_DFEATURE, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_GREY, '+', NA, NULL);
addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_BONE, VT_OB, NA, NULL);
addot(OT_GATEWOOD, "wooden gate", "A gate comprised of a series of wooden slats.", MT_WOOD, 200, OC_DFEATURE, SZ_LARGE); addot(OT_GATEWOOD, "wooden gate", "A gate comprised of a series of wooden slats.", MT_WOOD, 200, OC_DFEATURE, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_BROWN, '+', NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, '+', NA, NULL);
addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_DOOR, SZ_MIN, SZ_MAX, NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL);
@ -1583,6 +1602,18 @@ void initobjects(void) {
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, CT_WALLWOOD, VT_CELL, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_BED, VT_OB, NA, NULL);
addot(OT_FENCEBONE, "bone fence", "A tell fence created from what appear to be human bones.", MT_BONE, 150, OC_DFEATURE, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_GREY, '/', NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
addflag(lastot->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_BONE, VT_OB, NA, NULL);
addot(OT_FENCEWOOD, "wooden fence", "A tell fence created from a series of upright logs of wood.", MT_WOOD, 200, OC_DFEATURE, SZ_LARGE); addot(OT_FENCEWOOD, "wooden fence", "A tell fence created from a series of upright logs of wood.", MT_WOOD, 200, OC_DFEATURE, SZ_LARGE);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
@ -1590,9 +1621,10 @@ void initobjects(void) {
addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_BLOCKSLOF, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, CT_WALLWOOD, VT_CELL, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_BED, VT_OB, NA, NULL);
addot(OT_GRATINGFLOOR, "drainage grate", "A hatchway in the ground made of strong iron mesh.", MT_METAL, 40, OC_DFEATURE, SZ_MEDIUM); addot(OT_GRATINGFLOOR, "drainage grate", "A hatchway in the ground made of strong iron mesh.", MT_METAL, 40, OC_DFEATURE, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
@ -1687,6 +1719,27 @@ void initobjects(void) {
// buildings // buildings
// baba yaga's hut
addot(OT_BABAYAGAHUT, "wooden hut", "A small wooden cabin on the ground, two chicken's legs folded underneath it.", MT_DRAGONWOOD, 1000, OC_BUILDING, SZ_LARGE);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_BROWN, '_', NA, NULL);
addflag(lastot->flags, F_CLIMBABLE, D_IN, NA, NA, "hut's door");
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_BYHUTDOOR, NA, NA, NULL);
killflagsofid(lastot->flags, F_SHOP);
// the exit to baba yaga's hut
addot(OT_BYHUTDOOR, "doorway", "The front door of Baba Yaga's hut.", MT_STONE, 3000, OC_DFEATURE, SZ_HUGE);
addflag(lastot->flags, F_GLYPH, C_BROWN, '>', NA, NULL);
addflag(lastot->flags, F_CLIMBABLE, D_IN, NA, NA, "doorway");
addflag(lastot->flags, F_OPPOSITESTAIRS, OT_BABAYAGAHUT, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LOCKED, B_TRUE, 40, NA, NULL);
addflag(lastot->flags, F_LOCKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addot(OT_MOTEL, "motel", "A small structure providing cheap overnight rooms for rent", MT_METAL, 500, OC_BUILDING, SZ_LARGE); addot(OT_MOTEL, "motel", "A small structure providing cheap overnight rooms for rent", MT_METAL, 500, OC_BUILDING, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_RARE, NULL);
@ -1857,6 +1910,7 @@ void initobjects(void) {
addflag(lastot->flags, F_LINKOB, OT_POT_WATER, NA, NA, NULL); addflag(lastot->flags, F_LINKOB, OT_POT_WATER, NA, NA, NULL);
addflag(lastot->flags, F_DEEPWATER, DP_MAX, NA, NA, NULL); addflag(lastot->flags, F_DEEPWATER, DP_MAX, NA, NA, NULL);
addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONEPERCELL, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, NA, VT_OB, NA, "water fountain");
// traps - cell only // traps - cell only
addot(OT_TRAPARROW, "arrow trap", "A pressure plate which causes arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL); addot(OT_TRAPARROW, "arrow trap", "A pressure plate which causes arrows to shoot at you.", MT_NOTHING, 0, OC_TRAP, SZ_SMALL);
@ -2050,6 +2104,8 @@ void initobjects(void) {
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL); addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL);
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "50-100 stones"); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "50-100 stones");
addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_STONE, VT_OB, NA, NULL);
addot(OT_ICICLE, "huge icicle", "A massive ice stalacmite.", MT_ICE, 200, OC_ROCK, SZ_LARGE); addot(OT_ICICLE, "huge icicle", "A massive ice stalacmite.", MT_ICE, 200, OC_ROCK, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_CYAN, '\'', NA, NULL); addflag(lastot->flags, F_GLYPH, C_CYAN, '\'', NA, NULL);
@ -2059,6 +2115,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL); addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_ICESHEET, VT_OB, NA, NULL);
addot(OT_STATUE, "statue", "A stone statue of a monster.", MT_STONE, 80, OC_ROCK, SZ_HUMAN); addot(OT_STATUE, "statue", "A stone statue of a monster.", MT_STONE, 80, OC_ROCK, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, ""); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, "");
@ -2176,6 +2233,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_POWDER, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash");
addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL);
addot(OT_ASHCONCEAL, "pile of concealing powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addot(OT_ASHCONCEAL, "pile of concealing powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL); addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
@ -2187,6 +2245,7 @@ void initobjects(void) {
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash");
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 80, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 80, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL);
addot(OT_ASHEXPLODE, "pile of exploding powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addot(OT_ASHEXPLODE, "pile of exploding powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL); addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
@ -2198,6 +2257,7 @@ void initobjects(void) {
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash");
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash");
addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL);
addot(OT_ASHINVIS, "pile of prankster's dust", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addot(OT_ASHINVIS, "pile of prankster's dust", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL); addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
@ -2209,6 +2269,7 @@ void initobjects(void) {
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash");
addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AIFLEEITEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 100, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL);
addot(OT_ASHSLEEP, "pile of sleeping powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addot(OT_ASHSLEEP, "pile of sleeping powder", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL); addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
@ -2219,6 +2280,7 @@ void initobjects(void) {
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "pile of ash");
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some ash");
addflag(lastot->flags, F_VALUE, 80, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 80, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_DUSTCLOUD, VT_OB, NA, NULL);
addot(OT_GEMOFSEEING, "gem of seeing", "Magically enhances your eyesight.", MT_STONE, 1, OC_ROCK, SZ_TINY); addot(OT_GEMOFSEEING, "gem of seeing", "Magically enhances your eyesight.", MT_STONE, 1, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_HOLDCONFER, F_XRAYVIS, 1, NA, NULL); addflag(lastot->flags, F_HOLDCONFER, F_XRAYVIS, 1, NA, NULL);
addflag(lastot->flags, F_HOLDCONFER, F_SEEINVIS, B_TRUE, NA, NULL); addflag(lastot->flags, F_HOLDCONFER, F_SEEINVIS, B_TRUE, NA, NULL);
@ -2280,6 +2342,8 @@ void initobjects(void) {
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6"); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6");
addflag(lastot->flags, F_GROWSTO, OT_SHRUB, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_LEAF, VT_OB, NA, NULL);
addot(OT_LEAF, "leaf", "A fallen leaf from a tree.", MT_PLANT, 0.01, OC_FLORA, SZ_TINY); addot(OT_LEAF, "leaf", "A fallen leaf from a tree.", MT_PLANT, 0.01, OC_FLORA, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, ""); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, "");
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, ""); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
@ -2287,6 +2351,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 10, NA, NULL);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6"); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6");
addflag(lastot->flags, F_GROWSTO, OT_SHRUB, VT_OB, NA, NULL);
addot(OT_MISTLETOE, "sprig of mistletoe", "A small cutting of mistletoe. Druids can sacrifice these cuttings to increase their magical reserves.", MT_PLANT, 0.01, OC_FLORA, SZ_TINY); addot(OT_MISTLETOE, "sprig of mistletoe", "A small cutting of mistletoe. Druids can sacrifice these cuttings to increase their magical reserves.", MT_PLANT, 0.01, OC_FLORA, SZ_TINY);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "leaf"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "leaf");
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, "");
@ -2295,6 +2360,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, NULL); addflag(lastot->flags, F_NUMAPPEAR, 1, 3, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6"); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "3d6");
addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OPERABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_SHRUB, VT_OB, NA, NULL);
addot(OT_SHRUB, "shrub", "A small but dense shrub.", MT_PLANT, 50, OC_FLORA, SZ_MEDIUM); addot(OT_SHRUB, "shrub", "A small but dense shrub.", MT_PLANT, 50, OC_FLORA, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, ""); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, "");
addflag(lastot->flags, F_GLYPH, C_GREEN, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREEN, '%', NA, NULL);
@ -2305,6 +2371,7 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6"); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6");
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_TREE, VT_OB, NA, NULL);
addot(OT_STUMP, "tree stump", "A large tree stump.", MT_WOOD, 150, OC_FLORA, SZ_LARGE); addot(OT_STUMP, "tree stump", "A large tree stump.", MT_WOOD, 150, OC_FLORA, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, ""); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_FREQUENT, "");
addflag(lastot->flags, F_GLYPH, C_BROWN, '\'', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, '\'', NA, NULL);
@ -2315,6 +2382,8 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6"); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6");
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_TREE, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_STICK, VT_OB, NA, NULL);
addot(OT_TREE, "tree", "A tree.", MT_WOOD, 200, OC_FLORA, SZ_LARGE); addot(OT_TREE, "tree", "A tree.", MT_WOOD, 200, OC_FLORA, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, ""); addflag(lastot->flags, F_RARITY, H_FOREST, 100, NA, "");
//addflag(lastot->flags, F_GLYPH, C_GREEN, '#', NA, NULL); //addflag(lastot->flags, F_GLYPH, C_GREEN, '#', NA, NULL);
@ -2329,6 +2398,8 @@ void initobjects(void) {
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6"); addflag(lastot->flags, F_DTVULN, DT_FIRE, NA, NA, "2d6");
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, CT_WALLTREE, VT_CELL, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_STUMP, VT_OB, NA, NULL);
// food // food
addot(OT_APPLE, "apple", "A crunchy apple.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addot(OT_APPLE, "apple", "A crunchy apple.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
@ -2382,6 +2453,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_HOLDCONFER, F_EXTRALUCK, 1, NA, NULL); addflag(lastot->flags, F_HOLDCONFER, F_EXTRALUCK, 1, NA, NULL);
addflag(lastot->flags, F_VALUE, 300, NA, NA, ""); addflag(lastot->flags, F_VALUE, 300, NA, NA, "");
addflag(lastot->flags, F_GROWSTO, OT_SHRUB, VT_OB, NA, NULL);
killflagsofid(lastot->flags, F_STACKABLE); killflagsofid(lastot->flags, F_STACKABLE);
addot(OT_CURADOUGH, "loaf of curadough", "This very rare form of bread can magically heal whoever eats it, as well as lowering their metabolism for a short period afterwards.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY); addot(OT_CURADOUGH, "loaf of curadough", "This very rare form of bread can magically heal whoever eats it, as well as lowering their metabolism for a short period afterwards.", MT_FOOD, 0.5, OC_FOOD, SZ_TINY);
addflag(lastot->flags, F_GLYPH, C_YELLOW, '%', NA, NULL); addflag(lastot->flags, F_GLYPH, C_YELLOW, '%', NA, NULL);
@ -2443,6 +2515,7 @@ void initobjects(void) {
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_NUMAPPEAR, 1, 12, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 12, NA, "");
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);
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, 60, NA, ""); addflag(lastot->flags, F_EDIBLE, B_TRUE, 60, NA, "");
@ -3829,6 +3902,10 @@ void initobjects(void) {
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODLIFE, 2, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODLIFE, 2, NA, NULL);
// l3 // l3
addot(OT_S_DISRUPTUNDEAD, "disrupt undead", "Disrupts the very essence of undead creatures, dealing 2-6 damage per spell power.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODLIFE, 1, NA, NULL);
addot(OT_S_HEALING, "healing", "Restores 10-20 health to the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_HEALING, "healing", "Restores 10-20 health to the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "This spell heals an extra 2 damage per power level."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "This spell heals an extra 2 damage per power level.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
@ -3838,7 +3915,7 @@ void initobjects(void) {
addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, 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);
addflag(lastot->flags, F_PLEASESGOD, R_GODLIFE, 3, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODLIFE, 3, NA, NULL);
addot(OT_S_HOLYAURA, "holy aura", "Surrounds the target with a holy aura, causing their weapon to deal holy damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_HOLYAURA, "holy aura", "Surrounds the target with a holy aura, causing their weapon to deal holy damage against vulnerable creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
@ -4037,7 +4114,20 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addot(OT_S_CREATEWATER, "create water", "Creates a large pool of shallow water.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the size of the pool.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, 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_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
// l2 // l2
addot(OT_S_OBJECTSHRINK, "shrink object", "Causes the target object to shrink to a tiny size.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_SIZEUP, "unnatural growth", "Causes the target's body to grow in size. They will become easier to hit, but deal more damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SIZEUP, "unnatural growth", "Causes the target's body to grow in size. They will become easier to hit, but deal more damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how long the effect will last."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how long the effect will last.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level V, self-targetted spells will also resize your armour."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level V, self-targetted spells will also resize your armour.");
@ -4816,6 +4906,7 @@ void initobjects(void) {
addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL);
addflag(lastot->flags, F_STARTOBRND, 30, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 30, NA, NA, NULL);
addflag(lastot->flags, F_STARTOBRND, 10, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 10, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_SACKLARGE, VT_OB, NA, NULL);
addot(OT_SACKLARGE, "large sack", "A large cloth sack.", MT_CLOTH, 1, OC_TOOLS, SZ_MEDIUM); addot(OT_SACKLARGE, "large sack", "A large cloth sack.", MT_CLOTH, 1, OC_TOOLS, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
@ -4830,6 +4921,8 @@ void initobjects(void) {
addflag(lastot->flags, F_STARTOBRND, 100, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 100, NA, NA, NULL);
addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL);
addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_SACKHUGE, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_SACK, VT_OB, NA, NULL);
addot(OT_SACKHUGE, "huge sack", "An enormous cloth sack.", MT_CLOTH, 1, OC_TOOLS, SZ_LARGE); addot(OT_SACKHUGE, "huge sack", "An enormous cloth sack.", MT_CLOTH, 1, OC_TOOLS, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL);
@ -4848,6 +4941,7 @@ void initobjects(void) {
addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL);
addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL);
addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_SACKLARGE, VT_OB, NA, NULL);
addot(OT_BAGOFHOLDING, "bag of holding", "A magical sack which causes items placed inside it to become weightless.", MT_CLOTH, 0.5, OC_TOOLS, SZ_SMALL); addot(OT_BAGOFHOLDING, "bag of holding", "A magical sack which causes items placed inside it to become weightless.", MT_CLOTH, 0.5, OC_TOOLS, SZ_SMALL);
@ -4864,6 +4958,7 @@ void initobjects(void) {
addflag(lastot->flags, F_STARTOBRND, 30, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 30, NA, NA, NULL);
addflag(lastot->flags, F_STARTOBRND, 10, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 10, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "sack"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "sack");
addflag(lastot->flags, F_GROWSTO, OT_BAGOFHOLDINGLARGE, VT_OB, NA, NULL);
addot(OT_BAGOFHOLDINGLARGE, "large bag of holding", "A large magical sack which causes items placed inside it to become weightless.", MT_CLOTH, 0.5, OC_TOOLS, SZ_MEDIUM); addot(OT_BAGOFHOLDINGLARGE, "large bag of holding", "A large magical sack which causes items placed inside it to become weightless.", MT_CLOTH, 0.5, OC_TOOLS, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_RARE, NULL);
@ -4880,6 +4975,8 @@ void initobjects(void) {
addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL);
addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "large sack"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "large sack");
addflag(lastot->flags, F_GROWSTO, OT_BAGOFHOLDINGHUGE, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_BAGOFHOLDING, VT_OB, NA, NULL);
addot(OT_BAGOFHOLDINGHUGE, "huge bag of holding", "An enormous magical sack which causes items placed inside it to become weightless.", MT_CLOTH, 0.5, OC_TOOLS, SZ_LARGE); addot(OT_BAGOFHOLDINGHUGE, "huge bag of holding", "An enormous magical sack which causes items placed inside it to become weightless.", MT_CLOTH, 0.5, OC_TOOLS, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_VERYRARE, NULL);
@ -4900,6 +4997,7 @@ void initobjects(void) {
addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL);
addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL); addflag(lastot->flags, F_STARTOBRND, 50, NA, NA, NULL);
addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "huge sack"); addflag(lastot->flags, F_HASHIDDENNAME, B_TRUE, NA, NA, "huge sack");
addflag(lastot->flags, F_SHRINKSTO, OT_BAGOFHOLDINGLARGE, VT_OB, NA, NULL);
addot(OT_SAFEBOX, "safebox", "A small metal container for safely storing valuables.", MT_METAL, 2, OC_TOOLS, SZ_SMALL); addot(OT_SAFEBOX, "safebox", "A small metal container for safely storing valuables.", MT_METAL, 2, OC_TOOLS, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 77, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 77, RR_UNCOMMON, NULL);
@ -5262,6 +5360,8 @@ void initobjects(void) {
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SLIPPERY, 14, NA, NA, NULL); addflag(lastot->flags, F_SLIPPERY, 14, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_ICICLE, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_ICECHUNK, VT_OB, NA, NULL);
addot(OT_ICECHUNK, "chunk of ice", "A chunk of ice.", MT_ICE, 0.5, OC_MISC, SZ_SMALL); addot(OT_ICECHUNK, "chunk of ice", "A chunk of ice.", MT_ICE, 0.5, OC_MISC, SZ_SMALL);
addflag(lastot->flags, F_EDIBLE, B_TRUE, 3, NA, NULL); addflag(lastot->flags, F_EDIBLE, B_TRUE, 3, NA, NULL);
addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL);
@ -5275,6 +5375,8 @@ void initobjects(void) {
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOSHATTER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSHATTER, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_ICICLE, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_PUDDLEWATER, VT_OB, NA, NULL);
addot(OT_MELTEDWAX, "lump of melted wax", "A useless lump of melted wax.", MT_WAX, 0.1, OC_MISC, SZ_TINY); addot(OT_MELTEDWAX, "lump of melted wax", "A useless lump of melted wax.", MT_WAX, 0.1, OC_MISC, SZ_TINY);
addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, NA, NA, NA, NULL);
@ -5563,6 +5665,8 @@ void initobjects(void) {
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOPICKUP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_HELPSREST, 15, 1, NA, NULL); addflag(lastot->flags, F_HELPSREST, 15, 1, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_DOORWOOD, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_WOODENTABLE, VT_OB, NA, NULL);
addot(OT_BOOKSHELF, "bookshelf", "A set of wooden shelves, sized for book storage.", MT_WOOD, 150, OC_FURNITURE, SZ_HUMAN); addot(OT_BOOKSHELF, "bookshelf", "A set of wooden shelves, sized for book storage.", MT_WOOD, 150, OC_FURNITURE, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
@ -5627,6 +5731,8 @@ void initobjects(void) {
addflag(lastot->flags, F_ONLYINROOM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONLYINROOM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_MAX, NA, NULL);
addflag(lastot->flags, F_MAKESNOISE, 33, 1, NA, "crackling flames."); addflag(lastot->flags, F_MAKESNOISE, 33, 1, NA, "crackling flames.");
addflag(lastot->flags, F_GROWSTO, OT_FIRELARGE, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, NA, VT_OB, NA, "red-hot helmet");
addot(OT_WEAPONRACK, "weapon rack", "A large matel frame, made to store weapons.", MT_METAL, 150, OC_FURNITURE, SZ_HUMAN); addot(OT_WEAPONRACK, "weapon rack", "A large matel frame, made to store weapons.", MT_METAL, 150, OC_FURNITURE, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 80, RR_UNCOMMON, NULL);
@ -5660,6 +5766,8 @@ void initobjects(void) {
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL); addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL); addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL); addflag(lastot->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_DOORWOOD, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_STICK, VT_OB, NA, NULL);
addot(OT_WOODENTABLE, "wooden table", "A waist-height wooden table.", MT_WOOD, 25, OC_FURNITURE, SZ_HUMAN); addot(OT_WOODENTABLE, "wooden table", "A waist-height wooden table.", MT_WOOD, 25, OC_FURNITURE, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
@ -5673,6 +5781,8 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL); addflag(lastot->flags, F_OBHP, 10, 10, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_BASH, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_DOORWOOD, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_WOODENSTOOL, VT_OB, NA, NULL);
addot(OT_WOODENSTOOL, "wooden footstool", "A small, wooden footstool.", MT_WOOD, 5, OC_FURNITURE, SZ_MEDIUM); addot(OT_WOODENSTOOL, "wooden footstool", "A small, wooden footstool.", MT_WOOD, 5, OC_FURNITURE, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_ALL, 83, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 83, RR_COMMON, NULL);
@ -5681,6 +5791,8 @@ void initobjects(void) {
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL); addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL);
addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL); addflag(lastot->flags, F_DTVULN, DT_CHOP, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_WOODENTABLE, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_STICK, VT_OB, NA, NULL);
// trail objects // trail objects
addot(OT_FOOTPRINT, "footprints", "Footprints which show the passage of some kind of creature.", MT_NOTHING, 0, OC_MISC, SZ_MINI); addot(OT_FOOTPRINT, "footprints", "Footprints which show the passage of some kind of creature.", MT_NOTHING, 0, OC_MISC, SZ_MINI);
@ -5715,6 +5827,7 @@ void initobjects(void) {
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addflag(lastot->flags, F_CAUSESCOUGH, 18, NA, NA, NULL); addflag(lastot->flags, F_CAUSESCOUGH, 18, NA, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_STONE, VT_OB, NA, NULL);
addot(OT_DUSTPUFF, "small dust cloud", "A small cloud of dust particles.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM); addot(OT_DUSTPUFF, "small dust cloud", "A small cloud of dust particles.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM);
addflag(lastot->flags, F_GLYPH, C_BROWN, UNI_SHADELIGHT, NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, UNI_SHADELIGHT, NA, NULL);
@ -5739,6 +5852,7 @@ void initobjects(void) {
addflag(lastot->flags, F_PRODUCESLIGHT, 10, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 10, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "roaring flames."); addflag(lastot->flags, F_MAKESNOISE, 33, 3, NA, "roaring flames.");
addflag(lastot->flags, F_SHRINKSTO, OT_FIREMED, VT_OB, NA, NULL);
addot(OT_FIREMED, "medium fire", "A medium-sized roaring fire.", MT_FIRE, 0, OC_EFFECT, SZ_MEDIUM); addot(OT_FIREMED, "medium fire", "A medium-sized roaring fire.", MT_FIRE, 0, OC_EFFECT, SZ_MEDIUM);
addflag(lastot->flags, F_GLYPH, C_RED, '}', NA, NULL); addflag(lastot->flags, F_GLYPH, C_RED, '}', NA, NULL);
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "small fire"); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "small fire");
@ -5751,6 +5865,8 @@ void initobjects(void) {
addflag(lastot->flags, F_PRODUCESLIGHT, 7, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 7, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addflag(lastot->flags, F_MAKESNOISE, 33, 2, NA, "roaring flames."); addflag(lastot->flags, F_MAKESNOISE, 33, 2, NA, "roaring flames.");
addflag(lastot->flags, F_GROWSTO, OT_FIRELARGE, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_FIRESMALL, VT_OB, NA, NULL);
addot(OT_FIRESMALL, "small fire", "A small blaze.", MT_FIRE, 0, OC_EFFECT, SZ_SMALL); addot(OT_FIRESMALL, "small fire", "A small blaze.", MT_FIRE, 0, OC_EFFECT, SZ_SMALL);
addflag(lastot->flags, F_GLYPH, C_RED, '}', NA, NULL); addflag(lastot->flags, F_GLYPH, C_RED, '}', NA, NULL);
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "goes out"); addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "goes out");
@ -5762,6 +5878,7 @@ void initobjects(void) {
addflag(lastot->flags, F_PRODUCESLIGHT, 5, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 5, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addflag(lastot->flags, F_MAKESNOISE, 33, 1, NA, "crackling flames."); addflag(lastot->flags, F_MAKESNOISE, 33, 1, NA, "crackling flames.");
addflag(lastot->flags, F_GROWSTO, OT_FIREMED, VT_OB, NA, NULL);
addot(OT_STEAMCLOUD, "cloud of steam", "A thick cloud of scalding steam.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN); addot(OT_STEAMCLOUD, "cloud of steam", "A thick cloud of scalding steam.", MT_GAS, 0, OC_EFFECT, SZ_HUMAN);
addflag(lastot->flags, F_GLYPH, C_WHITE, UNI_SHADEMED, NA, NULL); addflag(lastot->flags, F_GLYPH, C_WHITE, UNI_SHADEMED, NA, NULL);
@ -6428,6 +6545,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 5, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 5, NA, NULL);
addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL); addflag(lastot->flags, F_OBHP, 20, 20, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_WOODENTABLE, VT_OB, NA, NULL);
// similar to a buckler, but repairable, lighter, and less durable // similar to a buckler, but repairable, lighter, and less durable
addot(OT_SHIELDHIDE, "hide shield", "A small shield constructed out of animal skin.", MT_LEATHER, 2.00, OC_ARMOUR, SZ_SMALL); addot(OT_SHIELDHIDE, "hide shield", "A small shield constructed out of animal skin.", MT_LEATHER, 2.00, OC_ARMOUR, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
@ -6437,6 +6555,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 5, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 5, NA, NULL);
addflag(lastot->flags, F_OBHP, 18, 18, NA, NULL); addflag(lastot->flags, F_OBHP, 18, 18, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_CORPSE, VT_OB, NA, NULL);
addot(OT_SHIELD, "shield", "A medium-sized metal shield.", MT_METAL, 4.00, OC_ARMOUR, SZ_MEDIUM); addot(OT_SHIELD, "shield", "A medium-sized metal shield.", MT_METAL, 4.00, OC_ARMOUR, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
@ -6445,6 +6564,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 15, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 15, NA, NULL);
addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL); addflag(lastot->flags, F_OBHP, 30, 30, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_SHIELDLARGE, VT_OB, NA, NULL);
addot(OT_SHIELDLARGE, "large shield", "A large (if somewhat cumbersome) shield.", MT_METAL, 6.00, OC_ARMOUR, SZ_MEDIUM); addot(OT_SHIELDLARGE, "large shield", "A large (if somewhat cumbersome) shield.", MT_METAL, 6.00, OC_ARMOUR, SZ_MEDIUM);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
@ -6452,6 +6572,8 @@ void initobjects(void) {
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 20, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 20, NA, NULL);
addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL); addflag(lastot->flags, F_OBHP, 40, 40, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL);
addflag(lastot->flags, F_GROWSTO, OT_SHIELDTOWER, VT_OB, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_SHIELD, VT_OB, NA, NULL);
addot(OT_SHIELDTOWER, "tower shield", "An enormous but very cumbersome shield.", MT_METAL, 11.00, OC_ARMOUR, SZ_HUMAN); addot(OT_SHIELDTOWER, "tower shield", "An enormous but very cumbersome shield.", MT_METAL, 11.00, OC_ARMOUR, SZ_HUMAN);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL);
addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_SHIELD, B_TRUE, NA, NA, NULL);
@ -6460,6 +6582,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 30, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_SHIELDPENALTY, 30, NA, NULL);
addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL); addflag(lastot->flags, F_OBHP, 50, 50, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_SHIELDLARGE, VT_OB, NA, NULL);
// amulets // amulets
addot(OT_AMU_ANGER, "amulet of anger", "Allows its wearer to enter a state of bezerk rage at will.", MT_METAL, 0.3, OC_AMULET, SZ_TINY); addot(OT_AMU_ANGER, "amulet of anger", "Allows its wearer to enter a state of bezerk rage at will.", MT_METAL, 0.3, OC_AMULET, SZ_TINY);
@ -8142,7 +8265,7 @@ void initrace(void) {
addbehaviour(BH_SCRAWNY, "scrawny"); addbehaviour(BH_SCRAWNY, "scrawny");
// givebehaviour() will modify maxhp // givebehaviour() will modify maxhp
// unique monsters // unique monsters / bosses
addrace(R_JAILER, "jailer", 110, '@', C_MAGENTA, MT_FLESH, RC_HUMANOID, "Jailers are generally known for their surplus of brawn and utter lack of brains. This one is no different."); addrace(R_JAILER, "jailer", 110, '@', C_MAGENTA, MT_FLESH, RC_HUMANOID, "Jailers are generally known for their surplus of brawn and utter lack of brains. This one is no different.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_NAME, NA, NA, NA, "Jimbo"); addflag(lastrace->flags, F_NAME, NA, NA, NA, "Jimbo");
@ -8179,6 +8302,78 @@ void initrace(void) {
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_HUMANOID, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addrace(R_BABAYAGA, "Baba Yaga", 50, '@', C_MAGENTA, MT_FLESH, RC_HUMANOID, "A hideous old hag with long, thin grey hair. Her face is covered with warts, and her few remaining teeth are filed to sharp points.");
setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_NAME, NA, NA, NA, "Baba Yaga");
addflag(lastrace->flags, F_UNIQUE, NA, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, NA, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 20, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 20, NA, NA, NULL);
//addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
//addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 2, 2, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 6, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 6, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_EXHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_EXHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_EXLOW, NA, NULL);
addflag(lastrace->flags, F_RESISTMAG, 75, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_FIRE, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_COLD, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_MAGIC, NA, NA, NULL);
addflag(lastrace->flags, F_DTRESIST, DT_POISON, NA, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINVIS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_FEAR, NA, NA, "pw:3;");
addflag(lastrace->flags, F_CANCAST, OT_S_WEAKEN, NA, NA, "pw:5;");
addflag(lastrace->flags, F_CANCAST, OT_S_SUMMONANIMALSSM, 10, 10, "pw:5;count:5;");
addflag(lastrace->flags, F_CANCAST, OT_S_SUMMONANIMALSMD, 10, 10, "pw:5;count:4;");
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_SPELLCASTTEXT, OT_NONE, NA, B_APPENDYOU, "grins");
addflag(lastrace->flags, F_CASTCHANCE, 50, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "cackles evilly^an evil cackling");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addrace(R_BABAYAGAHUT, "walking hut", 1000, '_', C_BROWN, MT_DRAGONWOOD, RC_MAGIC, "A small wooden cabin which walks around upon enormous chicken legs. It has a single doorway, lined with razor-sharp teeth.");
addbodypart(lastrace, BP_BODY, "walls");
addbodypart(lastrace, BP_LEGS, "legs");
addbodypart(lastrace, BP_FEET, "feet");
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "wooden hut");
addflag(lastrace->flags, F_HOSTILE, NA, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUGE, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 5, NA, NA, NULL);
addflag(lastrace->flags, F_TR, 10, NA, NA, NULL);
//addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
//addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 9, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 12, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_EXLOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STAYINROOM, NA, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_JUMP, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_WALK, 2, NA, "^clucking");
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TIMID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
// races / monsters // races / monsters
// playable races // playable races
addrace(R_HUMAN, "human", 75, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Your average example of the Homo Sapiens species."); addrace(R_HUMAN, "human", 75, '@', C_BROWN, MT_FLESH, RC_HUMANOID, "Your average example of the Homo Sapiens species.");
@ -8261,7 +8456,7 @@ void initrace(void) {
// stats // stats
addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_PLAYABLE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CON, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_LOW, NA, NULL);
@ -11582,7 +11777,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 8, NA, NA, NULL);
addrace(R_SKOOB, "skoob", 40, 'g', C_WHITE, MT_ICE, RC_MAGIC, "Your typical snowman right down to the carrot nose, with just a two key differences: it is alive, and it is homocidal."); addrace(R_SKOOB, "skoob", 40, 'g', C_WHITE, MT_WATER, RC_MAGIC, "Your typical snowman right down to the carrot nose, with just a two key differences: it is alive, and it is homocidal.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "carrot"); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "carrot");
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "puddle of water"); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "puddle of water");
@ -13595,6 +13790,7 @@ void initrace(void) {
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "scuttle");
addrace(R_RATDIRE, "dire rat", 3, 'r', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Dire rats are massive rats, larger than most dogs. Unlike dogs, dire rats are equipped with razor sharp shark-like teeth and their bite is very much worse than their bark."); addrace(R_RATDIRE, "dire rat", 3, 'r', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Dire rats are massive rats, larger than most dogs. Unlike dogs, dire rats are equipped with razor sharp shark-like teeth and their bite is very much worse than their bark.");
setbodytype(lastrace, BT_QUADRAPED); setbodytype(lastrace, BT_QUADRAPED);
@ -13624,6 +13820,7 @@ void initrace(void) {
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 4, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 4, NA, NA, NULL);
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "scuttle");
addrace(R_RATPLAGUE, "plague rat", 3, 'r', C_GREEN, MT_FLESH, RC_ANIMAL, "Plague rats are named both for their infectious bite as well as the great speed at which they run."); addrace(R_RATPLAGUE, "plague rat", 3, 'r', C_GREEN, MT_FLESH, RC_ANIMAL, "Plague rats are named both for their infectious bite as well as the great speed at which they run.");
setbodytype(lastrace, BT_QUADRAPED); setbodytype(lastrace, BT_QUADRAPED);
@ -13655,6 +13852,7 @@ void initrace(void) {
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "scuttle");
addrace(R_ROC, "roc", 1, 'A', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Rocs are unbelievably gargantuan birds or prey, large enough to carry a fully-grown elephant. They are generally peaceful, but deadly once provoked."); // 'A' for Avian addrace(R_ROC, "roc", 1, 'A', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Rocs are unbelievably gargantuan birds or prey, large enough to carry a fully-grown elephant. They are generally peaceful, but deadly once provoked."); // 'A' for Avian
setbodytype(lastrace, BT_BIRD); setbodytype(lastrace, BT_BIRD);
@ -14014,6 +14212,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "1-10 webs"); addflag(lastrace->flags, F_HOMELEVOB, NA, NA, NA, "1-10 webs");
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, ""); addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "creep");
addrace(R_SPIDERFUNNELWEB, "giant funnelweb", 5, 'S', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Like a giant spider... but extremely venomous."); addrace(R_SPIDERFUNNELWEB, "giant funnelweb", 5, 'S', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Like a giant spider... but extremely venomous.");
setbodytype(lastrace, BT_SPIDER); setbodytype(lastrace, BT_SPIDER);
lastrace->baseid = R_SPIDER; lastrace->baseid = R_SPIDER;
@ -14050,6 +14249,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, ""); addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_POISON, NA, "15"); addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_POISON, NA, "15");
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "creep");
addrace(R_SPIDERREDBACK, "giant redback", 5, 'S', C_RED, MT_FLESH, RC_ANIMAL, "A version of a giant spider with a highly painful bite."); addrace(R_SPIDERREDBACK, "giant redback", 5, 'S', C_RED, MT_FLESH, RC_ANIMAL, "A version of a giant spider with a highly painful bite.");
setbodytype(lastrace, BT_SPIDER); setbodytype(lastrace, BT_SPIDER);
lastrace->baseid = R_SPIDER; lastrace->baseid = R_SPIDER;
@ -14086,6 +14286,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, ""); addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_POISON, NA, "10"); addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_POISON, NA, "10");
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "creep");
addrace(R_SPIDERTOMB, "tomb spider", 5, 'S', C_BLUE, MT_FLESH, RC_ANIMAL, "Tomb spiders are truly nightmarish beings. Their skin can absorb light itself, and they can boost their own life force by consuming the flesh of their victims."); addrace(R_SPIDERTOMB, "tomb spider", 5, 'S', C_BLUE, MT_FLESH, RC_ANIMAL, "Tomb spiders are truly nightmarish beings. Their skin can absorb light itself, and they can boost their own life force by consuming the flesh of their victims.");
setbodytype(lastrace, BT_SPIDER); setbodytype(lastrace, BT_SPIDER);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
@ -14121,6 +14322,7 @@ void initrace(void) {
addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, ""); addflag(lastrace->flags, F_FLEEONHPPCT, 25, NA, NA, "");
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "creep");
addrace(R_SWAN, "swan", 1, 'c', C_WHITE, MT_FLESH, RC_ANIMAL, "A graceful waterbird."); addrace(R_SWAN, "swan", 1, 'c', C_WHITE, MT_FLESH, RC_ANIMAL, "A graceful waterbird.");
setbodytype(lastrace, BT_BIRD); setbodytype(lastrace, BT_BIRD);

Binary file not shown.

19
defs.h
View File

@ -805,6 +805,7 @@ enum CELLTYPE {
CT_WALLMETAL, CT_WALLMETAL,
CT_WALLTREE, CT_WALLTREE,
CT_WALLWOOD, CT_WALLWOOD,
CT_WALLDWOOD,
// empty // empty
CT_CORRIDOR, CT_CORRIDOR,
CT_DIRT, CT_DIRT,
@ -978,6 +979,8 @@ enum RACE {
R_RANDOM, R_SPECIFIED, R_RANDOM, R_SPECIFIED,
// unique monstesr // unique monstesr
R_JAILER, R_JAILER,
R_BABAYAGAHUT,
R_BABAYAGA,
// playable races // playable races
R_ASHKARI, R_ASHKARI,
R_AVIAD, R_AVIAD,
@ -1325,8 +1328,10 @@ enum OBTYPE {
OT_STATUE, OT_STATUE,
OT_DOORWOOD, OT_DOORWOOD,
OT_DOORIRON, OT_DOORIRON,
OT_FENCEBONE,
OT_FENCEWOOD, OT_FENCEWOOD,
OT_FOUNTAIN, OT_FOUNTAIN,
OT_GATEBONE,
OT_GATEIRON, OT_GATEIRON,
OT_GATEWOOD, OT_GATEWOOD,
OT_SIGN, OT_SIGN,
@ -1343,6 +1348,8 @@ enum OBTYPE {
OT_PORTAL, OT_PORTAL,
OT_STOMACHEXIT, OT_STOMACHEXIT,
// buildings - rememebr to update MAXBUILDINGTYPES! // buildings - rememebr to update MAXBUILDINGTYPES!
OT_BABAYAGAHUT,
OT_BYHUTDOOR,
OT_MOTEL, OT_MOTEL,
OT_SHOPARMOUR, OT_SHOPARMOUR,
OT_SHOPBOOK, OT_SHOPBOOK,
@ -1622,6 +1629,7 @@ enum OBTYPE {
OT_S_TRUESTRIKE, OT_S_TRUESTRIKE,
OT_S_WHATGOESUP, OT_S_WHATGOESUP,
// -- life magic / cleric // -- life magic / cleric
OT_S_DISRUPTUNDEAD,
OT_S_HEALING, OT_S_HEALING,
OT_S_HEALINGMIN, OT_S_HEALINGMIN,
OT_S_HEALINGMAJ, OT_S_HEALINGMAJ,
@ -1652,6 +1660,7 @@ enum OBTYPE {
OT_S_TELEKINESIS, OT_S_TELEKINESIS,
// -- modification // -- modification
OT_S_ANIMATESTATUE, OT_S_ANIMATESTATUE,
OT_S_CREATEWATER, // also nature
OT_S_DARKNESS, OT_S_DARKNESS,
OT_S_ENCHANT, OT_S_ENCHANT,
OT_S_GASEOUSFORM, OT_S_GASEOUSFORM,
@ -1663,6 +1672,7 @@ enum OBTYPE {
OT_S_LIGHT, OT_S_LIGHT,
OT_S_MENDING, OT_S_MENDING,
OT_S_OBJECTGROWTH, OT_S_OBJECTGROWTH,
OT_S_OBJECTSHRINK,
OT_S_PASSWALL, OT_S_PASSWALL,
OT_S_PETRIFY, OT_S_PETRIFY,
OT_S_POLYMORPH, OT_S_POLYMORPH,
@ -2312,6 +2322,7 @@ enum POISONTYPE {
P_GAS, P_GAS,
P_MIGRAINE, P_MIGRAINE,
P_ROT, P_ROT,
P_TETANUS,
P_VENOM, P_VENOM,
P_WEAKNESS, P_WEAKNESS,
}; };
@ -2367,6 +2378,10 @@ enum FLAG {
F_ENCHANTABLE, // object can get +1/-1 ect F_ENCHANTABLE, // object can get +1/-1 ect
F_GEM, // this object is a gem. F_GEM, // this object is a gem.
F_GODGIFT, // this was a gift form god with race v0. F_GODGIFT, // this was a gift form god with race v0.
F_GROWSTO, // used for spells. v0=new oid or celltype.
// v1 = VT_OB or VT_CELL
F_SHRINKSTO, // used for spells. v0=new oid or celltype.
// v1 = VT_OB or VT_CELL
F_NOSHATTER, // object will not shatter, even if it's material should. F_NOSHATTER, // object will not shatter, even if it's material should.
F_STACKABLE, // can stack multiple objects togethr F_STACKABLE, // can stack multiple objects togethr
F_NO_PLURAL, // this obname doesn't need an 's' for plurals (eg. gold, money) F_NO_PLURAL, // this obname doesn't need an 's' for plurals (eg. gold, money)
@ -2379,6 +2394,7 @@ enum FLAG {
// v2=regionthing ID of RT_REGIONLINK thing // v2=regionthing ID of RT_REGIONLINK thing
// text = what this is a map to ie. "the goblin caves" // text = what this is a map to ie. "the goblin caves"
F_SIGNTEXT, // for 'sign' objects. f->text is what is says. F_SIGNTEXT, // for 'sign' objects. f->text is what is says.
F_IMMUTABLE, // this object cannot be damaged OR repaired.
F_IDWHENUSED, // fully identify an object when worn/weilded/operated/etc F_IDWHENUSED, // fully identify an object when worn/weilded/operated/etc
F_STARTBLESSED, // v0 = b_blessed or b_cursed F_STARTBLESSED, // v0 = b_blessed or b_cursed
F_REPELBLESSED, // v0 = b_blessed or b_cursed. repels other obejcts F_REPELBLESSED, // v0 = b_blessed or b_cursed. repels other obejcts
@ -3910,6 +3926,7 @@ enum REGIONTYPE {
RG_SEWER, RG_SEWER,
RG_STOMACH, RG_STOMACH,
RG_WOODS, RG_WOODS,
RG_BABAYAGAHUT,
}; };
enum HABITAT { enum HABITAT {
@ -3922,6 +3939,7 @@ enum HABITAT {
H_SEWER = 7, H_SEWER = 7,
H_STOMACH = 8, H_STOMACH = 8,
H_SWAMP = 9, H_SWAMP = 9,
H_BYHUT = 10,
H_ALL = 999 H_ALL = 999
}; };
@ -3935,6 +3953,7 @@ typedef struct regiontype_s {
int deeperdir; int deeperdir;
int majorbranch; int majorbranch;
int depthmod; int depthmod;
int addparentdepth;
struct regiontype_s *next, *prev; struct regiontype_s *next, *prev;
} regiontype_t; } regiontype_t;

57
io.c
View File

@ -313,6 +313,46 @@ void animcells(cell_t *src, cell_t **dst, int ndst, int gradual, char ch, char c
needredraw = B_TRUE; needredraw = B_TRUE;
} }
// make all the passed cells 'flash'
void animflashcells(cell_t **cell, int ncells, int ch,int colour, char *seetext) {
glyph_t gl;
int i;
int nseen = 0;
gl.ch = ch;
gl.colour = colour;
if (ncells == 0) return;
// update screen
updateviewfor(cell[0]);
drawlevelfor(player);
// hide cursor
curs_set(0);
for (i = 0; i <= ncells; i++) {
if (haslos(player, cell[i])) {
if (colour == C_RANDOM) gl.colour = rnd(C_FIRST, C_LAST);
drawglyph(&gl, cell[i]->x - viewx, cell[i]->y - viewy);
nseen++;
}
}
if (nseen) {
wrefresh(gamewin);
usleep(DEF_ANIMDELAY);
if (seetext) {
msg(seetext);
more();
}
}
// show cursor
curs_set(1);
needredraw = B_TRUE;
drawscreen();
}
void animline(cell_t *src, cell_t *dst, int gradual, char ch, char ch2, int colour) { void animline(cell_t *src, cell_t *dst, int gradual, char ch, char ch2, int colour) {
glyph_t gl; glyph_t gl;
int i; int i;
@ -1567,6 +1607,7 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
p = readuntil(buf, f->text, '^'); p = readuntil(buf, f->text, '^');
msg("^%c%s%s %s!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname), buf); msg("^%c%s%s %s!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname), buf);
donesomething = B_TRUE; donesomething = B_TRUE;
if (isplayer(lf)) more();
} }
break; break;
case F_INVISIBLE: case F_INVISIBLE:
@ -6141,8 +6182,10 @@ char *makedesc_ob(object_t *o, char *retbuf) {
strncat(retbuf, "\n", HUGEBUFLEN); strncat(retbuf, "\n", HUGEBUFLEN);
// been made invulnerable ? // been made invulnerable ?
if (hasflagknown(o->type->flags, F_INVULNERABLE) && !hasflag(o->flags, F_DAMAGABLE)) { if (hasflagknown(o->flags, F_INVULNERABLE) && !hasflag(o->flags, F_DAMAGABLE)) {
strncat(retbuf, "It is invulnerable to most damage.\n", HUGEBUFLEN); strncat(retbuf, "It is invulnerable to most damage.\n", HUGEBUFLEN);
} else if (hasflag(o->flags, F_IMMUTABLE)) {
strncat(retbuf, "Powerful magic has made its current condition permenant.\n", HUGEBUFLEN);
} else { } else {
// immunities // immunities
strcpy(buf, ""); strcpy(buf, "");
@ -6293,7 +6336,17 @@ char *makedesc_ob(object_t *o, char *retbuf) {
} }
f = hasflag(o->flags, F_RUSTED); f = hasflag(o->flags, F_RUSTED);
if (f) { if (f) {
sprintf(buf, "It is rusty.\n"); char rustbuf[BUFLEN];
switch (f->val[0]) {
case R_TRUSTY:
strcpy(rustbuf, "thouroughly rusty"); break;
case R_VRUSTY:
strcpy(rustbuf, "very rusty"); break;
case R_RUSTY:
default:
strcpy(rustbuf, "rusty"); break;
}
sprintf(buf, "It is %s (-%d%% damage).\n", rustbuf, 100 - getrustdampct(o));
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
} }
f = hasflag(o->flags, F_WATERPROOF); f = hasflag(o->flags, F_WATERPROOF);

1
io.h
View File

@ -5,6 +5,7 @@ void addheading(prompt_t *p, char *text);
void addmsghist(char *text); void addmsghist(char *text);
void addpromptq(prompt_t *p, char *q); void addpromptq(prompt_t *p, char *q);
void anim(cell_t *src, cell_t *dst, char ch, int colour); void anim(cell_t *src, cell_t *dst, char ch, int colour);
void animflashcells(cell_t **cell, int ncells, int ch,int colour, char *seetext);
void animline(cell_t *src, cell_t *dst, int gradual, char ch, char ch2, int colour); void animline(cell_t *src, cell_t *dst, int gradual, char ch, char ch2, int colour);
void animcells(cell_t *src, cell_t **dst, int ndst, int gradual, char ch, char ch2, int colour); void animcells(cell_t *src, cell_t **dst, int ndst, int gradual, char ch, char ch2, int colour);
//void animradial(cell_t *src, int radius, int ch, int colour); //void animradial(cell_t *src, int radius, int ch, int colour);

705
lf.c
View File

@ -1353,8 +1353,10 @@ int canwear(lifeform_t *lf, object_t *o, enum BODYPART where) {
// paladin? // paladin?
if (getsubjob(lf) == SJ_PALADIN) { if (getsubjob(lf) == SJ_PALADIN) {
if (!isblessed(o) || !o->blessknown) { if (!isblessed(o) || !o->blessknown) {
reason = E_PALADIN; if (isarmour(o)) {
return B_FALSE; reason = E_PALADIN;
return B_FALSE;
}
} }
} }
// injuries? // injuries?
@ -2529,6 +2531,18 @@ int continuerepairing(lifeform_t *lf, flag_t *repairflag) {
return B_FALSE; return B_FALSE;
} }
f = hasflag(o->flags, F_IMMUTABLE);
if (f) {
if (isplayer(lf)) {
char obname[BUFLEN];
real_getobname(o, obname, o->amt, B_PREMODS, B_NOCONDITION, B_BLINDADJUST, B_BLESSINGS, B_NOUSED, B_NOSHOWALL);
msg("Your %s somehow resists your attempts to repair it!", noprefix(obname));
}
killflag(repairflag);
f->known = B_TRUE;
return B_TRUE;
}
// get helper ob // get helper ob
helpob = getworkhelpob(lf->pack, o->material->id); helpob = getworkhelpob(lf->pack, o->material->id);
if (helpob) { if (helpob) {
@ -3282,6 +3296,11 @@ void die(lifeform_t *lf) {
headob = addob(corpsecell->obpile, headname); headob = addob(corpsecell->obpile, headname);
colourmatchob(headob, lf); colourmatchob(headob, lf);
} }
if (corpse->type->id == OT_BABAYAGAHUT) {
// link the hut to the new region.
createregionlink(corpsecell->map, corpsecell, corpse, NULL, RG_BABAYAGAHUT, corpsecell->map->region);
}
} }
// For bones files: // For bones files:
@ -5145,7 +5164,6 @@ int exchangeweapon(lifeform_t *lf) {
object_t *wep,*sec = NULL,*newsec = NULL; object_t *wep,*sec = NULL,*newsec = NULL;
// get secondary (if available) // get secondary (if available)
sec = hasobwithflag(lf->pack, F_SECONDARY); sec = hasobwithflag(lf->pack, F_SECONDARY);
// get current weapon // get current weapon
wep = getweapon(lf); wep = getweapon(lf);
@ -5163,7 +5181,6 @@ int exchangeweapon(lifeform_t *lf) {
if (sec) { if (sec) {
killflagsofid(sec->flags, F_SECONDARY);
// try to weild secondary // try to weild secondary
if (weild(lf, sec)) { if (weild(lf, sec)) {
// error // error
@ -5289,7 +5306,7 @@ int fall_from_air(lifeform_t *lf) {
} }
} }
if (willfall) fall(lf, NULL, B_TRUE); if (willfall) fall(lf, NULL, B_TRUE);
if (willinjure) injure(lf, getrandomcorebp(lf, NULL), DT_BASH); if (willinjure) injure(lf, getrandomcorebp(lf, NULL), DT_BASH, IJ_NONE);
if (willfall || willinjure) { if (willfall || willinjure) {
return B_TRUE; return B_TRUE;
} }
@ -10297,6 +10314,7 @@ void givesubjob(lifeform_t *lf, enum SUBJOB sj) {
} }
// can permenantly turn undead for 0 power. // can permenantly turn undead for 0 power.
addtempflag(lf->flags, F_CANWILL, OT_S_TURNUNDEAD, NA, NA, NULL, FROMJOB); addtempflag(lf->flags, F_CANWILL, OT_S_TURNUNDEAD, NA, NA, NULL, FROMJOB);
addtempflag(lf->flags, F_LEVABIL, 5, OT_S_DISRUPTUNDEAD, NA, NULL, FROMJOB);
if (isplayer(lf)) { if (isplayer(lf)) {
addflag(lf->flags, F_SHORTCUT, getnextshortcut(lf), NA, NA, "turn undead"); addflag(lf->flags, F_SHORTCUT, getnextshortcut(lf), NA, NA, "turn undead");
} }
@ -11325,11 +11343,13 @@ void inc_quad_range(enum QUADRANT *start, enum QUADRANT *end, int howmuch) {
// where shoudl always be body, hands, legs or head // where shoudl always be body, hands, legs or head
// damtype should be bash or slash // damtype should be bash or slash
int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) { //
char lfname[BUFLEN]; // if forcetype is not supplied, injury type will be selected randomly.
int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJURY forcetype) {
char lfname[BUFLEN],buf[BUFLEN];
char *desc = NULL; char *desc = NULL;
enum INJURY inj = IJ_NONE; enum INJURY inj = IJ_NONE;
enum BODYPART bp2; enum BODYPART bp2 = BP_NONE;
object_t *wep = NULL,*o; object_t *wep = NULL,*o;
int howlong; int howlong;
@ -11375,266 +11395,300 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
howlong = rnd(30,80); // might be overridden depending on injury howlong = rnd(30,80); // might be overridden depending on injury
if (damtype == DT_BASH) { if (forcetype) {
switch (where) { inj = forcetype;
case BP_BODY: } else {
switch (rnd(1,5)) { if (damtype == DT_BASH) {
case 1: switch (where) {
inj = IJ_RIBCRACKED; desc = strdup("ribs are cracked^carrying capacity halved"); break; case BP_BODY:
case 2: switch (rnd(1,5)) {
inj = IJ_RIBBROKEN; desc = strdup("ribs are broken^carrying capacity halved, -6 accuracy"); break; case 1:
case 3: inj = IJ_RIBCRACKED; break;
inj = IJ_TORSOBRUISED; desc = strdup("torso is bruised^-2 accuracy"); break; case 2:
case 4: inj = IJ_RIBBROKEN; break;
inj = IJ_TORSOBRUISEDBAD; desc = strdup("torso is badly bruised^-4 accuracy, -10% dam"); break; case 3:
case 5: inj = IJ_TORSOBRUISED; break;
inj = IJ_WINDED; desc = strdup("stomach is winded^-1 Fitness"); howlong = rnd(3,5); break; case 4:
} inj = IJ_TORSOBRUISEDBAD; break;
break; case 5:
case BP_HANDS: inj = IJ_WINDED; howlong = rnd(3,5); break;
switch (rnd(1,3)) { }
case 1: break;
inj = IJ_FINGERBROKEN; desc = strdup("finger is broken^-2 accuracy"); break; case BP_HANDS:
case 2: switch (rnd(1,3)) {
inj = IJ_SHOULDERDISLOCATED; desc = strdup("shoulder is dislocated^-4 accuracy, cannot weild heavy weapons"); break; case 1:
case 3: inj = IJ_FINGERBROKEN; break;
inj = IJ_HANDSWOLLEN; desc = strdup("hand is swollen^cannot wear/remove gloves"); break; case 2:
} inj = IJ_SHOULDERDISLOCATED; break;
break; case 3:
case BP_HEAD: inj = IJ_HANDSWOLLEN; break;
switch (rnd(1,4)) { }
case 1: break;
if (!eyesshaded(lf)) { case BP_HEAD:
inj = IJ_BLACKEYE; switch (rnd(1,4)) {
desc = strdup("eye is bruised^vision range halved"); case 1:
if (!eyesshaded(lf)) {
inj = IJ_BLACKEYE;
}
break;
case 2:
inj = IJ_CONCUSSION;
break;
case 3:
inj = IJ_WINDPIPECRUSHED;
break;
case 4:
inj = IJ_NOSEBROKEN;
break;
}
break;
case BP_LEGS:
if (onein(3)) {
inj = IJ_LEGBROKEN;
break;
} else {
switch (rnd(1,2)) {
case 1:
inj = IJ_LEGBRUISE;
break;
case 2:
inj = IJ_ANKLESWOLLEN;
break;
} }
break; }
case 2: break;
inj = IJ_CONCUSSION; case BP_TAIL:
desc = strdup("brain is concussed^random movement");
break;
case 3:
inj = IJ_WINDPIPECRUSHED;
desc = strdup("windpipe is crushed^fitness penalty");
break;
case 4:
inj = IJ_NOSEBROKEN;
desc = strdup("nose is broken^charisma penalty,reduced smell sense");
break;
}
break;
case BP_LEGS:
if (onein(3)) {
inj = IJ_LEGBROKEN;
desc = strdup("leg is broken^movement speed greatly lowered"); break;
} else {
switch (rnd(1,2)) { switch (rnd(1,2)) {
case 1: case 1:
inj = IJ_LEGBRUISE; inj = IJ_TAILBRUISED;
desc = strdup("leg is bruised^movement speed lowered"); break; break;
case 2: case 2:
inj = IJ_ANKLESWOLLEN; inj = IJ_TAILBROKEN;
desc = strdup("ankle is swollen^cannot wear/remove boots"); break; break;
} }
} break;
break; case BP_WINGS:
case BP_TAIL: inj = IJ_WINGBRUISED;
switch (rnd(1,2)) { break;
case 1: default: break;
inj = IJ_TAILBRUISED; }
desc = strdup("tail is bruised^accuracy penalty"); break; } else if (damtype == DT_SLASH) {
case 2: switch (where) {
inj = IJ_TAILBROKEN; case BP_BODY:
desc = strdup("tail is fractured^occasional random movement"); break; if (pctchance(10)) {
} if (isplayer(lf)) {
break; msg("^BYour heart is pierced!");
case BP_WINGS: } else if (cansee(player, lf)) {
inj = IJ_WINGBRUISED; msg("^%c%s%s heart is pierced!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname));
desc = strdup("wings are bruised^flight speed lowered"); break; }
break; if (lf->hp > 0) {
default: break; lf->hp = 0;
} }
} else if (damtype == DT_SLASH) { } else {
switch (where) { inj = IJ_CHESTBLEED; break;
case BP_BODY:
if (pctchance(10)) {
if (isplayer(lf)) {
msg("^BYour heart is pierced!");
} else if (cansee(player, lf)) {
msg("^%c%s%s heart is pierced!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname));
} }
if (lf->hp > 0) { break;
lf->hp = 0; case BP_HANDS:
switch (rnd(1,4)) {
case 1:
inj = IJ_HANDBLEED; break;
case 2:
inj = IJ_TENDONCUT; break;
case 3:
inj = IJ_ARTERYPIERCE; break;
case 4: // severed finger
if (onein(2)) bp2 = BP_RIGHTFINGER;
else bp2 = BP_LEFTFINGER;
if (hasbp(lf, bp2)) {
object_t *o;
addob(lf->cell->obpile, "severed finger");
o = getequippedob(lf->pack, bp2);
addflag(lf->flags, F_NOBODYPART, bp2, B_FROMINJURY, NA, NULL);
inj = IJ_FINGERMISSING;
howlong = PERMENANT;
if (o) {
char obname[BUFLEN];
if (isplayer(lf)) {
getobname(o,obname,o->amt);
msg("Your %s drops to the ground.",noprefix(obname));
} else if (cansee(player, lf)) {
getobname(o,obname,o->amt);
msg("%s%s %s drops to the ground.",lfname,getpossessive(lfname),noprefix(obname));
}
moveob(o, lf->cell->obpile, o->amt);
}
break;
}
break;
} }
} else { break;
inj = IJ_CHESTBLEED; desc = strdup("chest is bleeding^damage from enemies is increased"); break; case BP_HEAD:
} if (pctchance(10)) {
break; if (isplayer(lf)) {
case BP_HANDS: msg("^BYour brain is ruptured!");
switch (rnd(1,4)) { } else if (cansee(player, lf)) {
case 1: msg("^%c%s%s brain ruptures!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname));
inj = IJ_HANDBLEED; desc = strdup("hand is bleeding^attacking will cause damage"); break; }
case 2: if (lf->hp > 0) lf->hp = 0;
inj = IJ_TENDONCUT; desc = strdup("right flexor tendon is cut^cannot weild weapons"); break; } else {
case 3: switch (rnd(1,2)) {
inj = IJ_ARTERYPIERCE; desc = strdup("radial artery is pierced^1d8 damage per turn"); break; case 1:
case 4: // severed finger inj = IJ_EYELIDSCRAPED;
if (onein(2)) bp2 = BP_RIGHTFINGER; break;
else bp2 = BP_LEFTFINGER; case 2:
if (hasbp(lf, bp2)) { inj = IJ_EYEDESTROYED;
object_t *o; howlong = PERMENANT;
char buf[BUFLEN]; break;
addob(lf->cell->obpile, "severed finger");
o = getequippedob(lf->pack, bp2); }
addflag(lf->flags, F_NOBODYPART, bp2, B_FROMINJURY, NA, NULL); }
inj = IJ_FINGERMISSING; break;
sprintf(buf, "%s is severed^cannot wear rings on this hand", getbodypartname(lf, bp2)); case BP_LEGS:
desc = strdup(buf); switch (rnd(1,2)) {
howlong = PERMENANT; case 1:
if (o) { inj = IJ_LEGBLEED;
break;
case 2:
inj = IJ_HAMSTRUNG;
break;
}
break;
case BP_TAIL:
inj = IJ_TAILBLEED;
break;
case BP_WINGS:
switch (rnd(1,2)) {
case 1:
inj = IJ_WINGTORN;
break;
case 2:
inj = IJ_WINGBLEED;
break;
}
default: break;
}
} else if (damtype == DT_EXPLOSIVE) {
switch (where) {
case BP_BODY:
switch (rnd(1,3)) {
case 1: // collapsed lung
inj = IJ_LUNGCOLLAPSED;
break;
case 2:
inj = IJ_RIBCRACKED; break;
case 3:
inj = IJ_RIBBROKEN; break;
}
break;
case BP_HANDS:
// lose limb
if (onein(2)) bp2 = BP_WEAPON;
else bp2 = BP_SECWEAPON;
if (hasbp(lf, bp2)) {
object_t *o[2];
enum BODYPART fingerbp;
int i;
// drop anyting in that hand
o[0] = getequippedob(lf->pack, bp2);
if (bp2 == BP_WEAPON) {
o[1] = getequippedob(lf->pack, BP_RIGHTFINGER);
fingerbp = BP_RIGHTFINGER;
} else {
o[1] = getequippedob(lf->pack, BP_LEFTFINGER);
fingerbp = BP_LEFTFINGER;
}
addflag(lf->flags, F_NOBODYPART, bp2, B_FROMINJURY, NA, NULL);
addflag(lf->flags, F_NOBODYPART, fingerbp, B_FROMINJURY, NA, NULL);
inj = IJ_HANDMISSING;
howlong = PERMENANT;
for (i = 0; i < 2; i++) {
if (o[i]) {
char obname[BUFLEN]; char obname[BUFLEN];
if (isplayer(lf)) { if (isplayer(lf)) {
getobname(o,obname,o->amt); getobname(o[i],obname,o[i]->amt);
msg("Your %s drops to the ground.",noprefix(obname)); msg("Your %s drops to the ground.",noprefix(obname));
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
getobname(o,obname,o->amt); char lfname[BUFLEN];
getobname(o[i],obname,o[i]->amt);
msg("%s%s %s drops to the ground.",lfname,getpossessive(lfname),noprefix(obname)); msg("%s%s %s drops to the ground.",lfname,getpossessive(lfname),noprefix(obname));
} }
moveob(o, lf->cell->obpile, o->amt); moveob(o[i], lf->cell->obpile, o[i]->amt);
} }
break;
} }
break;
}
break;
case BP_HEAD:
if (pctchance(10)) {
if (isplayer(lf)) {
msg("^BYour brain is ruptured!");
} else if (cansee(player, lf)) {
msg("^%c%s%s brain ruptures!", getlfcol(lf, CC_VBAD), lfname, getpossessive(lfname));
} }
if (lf->hp > 0) lf->hp = 0; break;
} else { case BP_HEAD:
// burnt eyes
switch (rnd(1,2)) { switch (rnd(1,2)) {
case 1: case 1: // ringing ears
inj = IJ_EYELIDSCRAPED; desc = strdup("eyelid is scraped^accuracy penalty"); break; inj = IJ_EARSRINGING;
case 2: case 2: // blinded
inj = IJ_EYEDESTROYED; desc = strdup("right eye is destroyed^field of view halved"); addtempflag(lf->flags, F_BLIND, B_TRUE, NA, NA, NULL, rnd(50,100));
howlong = PERMENANT;
break; break;
} }
} break;
break; case BP_LEGS:
case BP_LEGS: // lose limb
switch (rnd(1,2)) { break;
case 1: case BP_TAIL:
inj = IJ_LEGBLEED; desc = strdup("leg is bleeding^movement will cause damage"); break; inj = IJ_TAILLACERATED;
case 2:
inj = IJ_HAMSTRUNG; desc = strdup("left hamstring is torn^lower move speed, chance of falling");
break;
}
break;
case BP_TAIL:
inj = IJ_TAILBLEED;
desc = strdup("tail is bleeding^no additional effects");
break;
case BP_WINGS:
switch (rnd(1,2)) {
case 1:
inj = IJ_WINGTORN;
desc = strdup("wings are torn^cannot fly");
break;
case 2:
inj = IJ_WINGBLEED;
desc = strdup("wings are bleeding^flying causes damage");
break;
}
default: break;
}
} else if (damtype == DT_EXPLOSIVE) {
switch (where) {
case BP_BODY:
switch (rnd(1,3)) {
case 1: // collapsed lung
inj = IJ_LUNGCOLLAPSED;
desc = strdup("lungs have collapsed^lose all stamina points");
case 2:
inj = IJ_RIBCRACKED; desc = strdup("ribs are cracked^carrying capacity halved"); break;
break;
case 3:
inj = IJ_RIBBROKEN; desc = strdup("ribs are broken^carrying capacity halved, -6 accuracy"); break;
}
break;
case BP_HANDS:
// lose limb
if (onein(2)) bp2 = BP_WEAPON;
else bp2 = BP_SECWEAPON;
if (hasbp(lf, bp2)) {
object_t *o[2];
char buf[BUFLEN];
enum BODYPART fingerbp;
int i;
// drop anyting in that hand
o[0] = getequippedob(lf->pack, bp2);
if (bp2 == BP_WEAPON) {
o[1] = getequippedob(lf->pack, BP_RIGHTFINGER);
fingerbp = BP_RIGHTFINGER;
} else {
o[1] = getequippedob(lf->pack, BP_LEFTFINGER);
fingerbp = BP_LEFTFINGER;
}
addflag(lf->flags, F_NOBODYPART, bp2, B_FROMINJURY, NA, NULL);
addflag(lf->flags, F_NOBODYPART, fingerbp, B_FROMINJURY, NA, NULL);
inj = IJ_HANDMISSING;
sprintf(buf, "%s is destroyed^cannot use this hand", getbodypartname(lf, bp2));
desc = strdup(buf);
howlong = PERMENANT; howlong = PERMENANT;
for (i = 0; i < 2; i++) { break;
if (o[i]) { case BP_WINGS:
char obname[BUFLEN]; inj = IJ_WINGDESTROYED;
if (isplayer(lf)) { howlong = PERMENANT;
getobname(o[i],obname,o[i]->amt); break;
msg("Your %s drops to the ground.",noprefix(obname)); default:
} else if (cansee(player, lf)) { break;
char lfname[BUFLEN]; }
getobname(o[i],obname,o[i]->amt);
msg("%s%s %s drops to the ground.",lfname,getpossessive(lfname),noprefix(obname));
}
moveob(o[i], lf->cell->obpile, o[i]->amt);
}
}
}
break;
case BP_HEAD:
// burnt eyes
switch (rnd(1,2)) {
case 1: // ringing ears
inj = IJ_EARSRINGING;
desc = strdup("ears are ringing^cannot hear sounds");
case 2: // blinded
addtempflag(lf->flags, F_BLIND, B_TRUE, NA, NA, NULL, rnd(50,100));
break;
}
break;
case BP_LEGS:
// lose limb
break;
case BP_TAIL:
inj = IJ_TAILLACERATED;
desc = strdup("tail is lacerated^chance of falling during movement");
howlong = PERMENANT;
break;
case BP_WINGS:
inj = IJ_WINGDESTROYED;
desc = strdup("wings are destroyed^cannot fly");
howlong = PERMENANT;
break;
default:
break;
} }
} }
// set description based on injury
switch (inj) {
case IJ_RIBCRACKED: desc = strdup("ribs are cracked^carrying capacity halved"); break;
case IJ_RIBBROKEN: desc = strdup("ribs are broken^carrying capacity halved, -6 accuracy"); break;
case IJ_TORSOBRUISED: desc = strdup("torso is bruised^-2 accuracy"); break;
case IJ_TORSOBRUISEDBAD: desc = strdup("torso is badly bruised^-4 accuracy, -10% dam"); break;
case IJ_WINDED: desc = strdup("stomach is winded^-1 Fitness"); break;
case IJ_BLACKEYE: desc = strdup("eye is bruised^vision range halved"); break;
case IJ_CONCUSSION: desc = strdup("brain is concussed^random movement"); break;
case IJ_WINDPIPECRUSHED: desc = strdup("windpipe is crushed^fitness penalty"); break;
case IJ_NOSEBROKEN: desc = strdup("nose is broken^charisma penalty,reduced smell sense");
case IJ_LEGBROKEN: desc = strdup("leg is broken^movement speed greatly lowered"); break;
case IJ_LEGBRUISE: desc = strdup("leg is bruised^movement speed lowered"); break;
case IJ_ANKLESWOLLEN: desc = strdup("ankle is swollen^cannot wear/remove boots"); break;
case IJ_TAILBRUISED: desc = strdup("tail is bruised^accuracy penalty"); break;
case IJ_TAILBROKEN: desc = strdup("tail is fractured^occasional random movement"); break;
case IJ_WINGBRUISED: desc = strdup("wings are bruised^flight speed lowered"); break;
case IJ_CHESTBLEED: desc = strdup("chest is bleeding^damage from enemies is increased"); break;
case IJ_HANDBLEED: desc = strdup("hand is bleeding^attacking will cause damage"); break;
case IJ_TENDONCUT: desc = strdup("right flexor tendon is cut^cannot weild weapons"); break;
case IJ_FINGERMISSING:
sprintf(buf, "%s is severed^cannot wear rings on this hand", getbodypartname(lf, bp2));
desc = strdup(buf);
break;
case IJ_EYELIDSCRAPED: desc = strdup("eyelid is scraped^accuracy penalty"); break;
case IJ_EYEDESTROYED: desc = strdup("right eye is destroyed^field of view halved"); break;
case IJ_LEGBLEED: desc = strdup("leg is bleeding^movement will cause damage"); break;
case IJ_HAMSTRUNG: desc = strdup("left hamstring is torn^lower move speed, chance of falling"); break;
case IJ_TAILBLEED: desc = strdup("tail is bleeding^no additional effects"); break;
case IJ_WINGTORN: desc = strdup("wings are torn^cannot fly"); break;
case IJ_WINGBLEED: desc = strdup("wings are bleeding^flying causes damage"); break;
case IJ_LUNGCOLLAPSED: desc = strdup("lungs have collapsed^lose all stamina points"); break;
case IJ_HANDMISSING:
sprintf(buf, "%s is destroyed^cannot use this hand", getbodypartname(lf, bp2));
desc = strdup(buf);
break;
case IJ_EARSRINGING: desc = strdup("ears are ringing^cannot hear sounds"); break;
case IJ_TAILLACERATED: desc = strdup("tail is lacerated^chance of falling during movement"); break;
case IJ_WINGDESTROYED: desc = strdup("wings are destroyed^cannot fly"); break;
case IJ_HANDSWOLLEN: desc = strdup("hand is swolled^rings cannot be put on/removed"); break;
case IJ_FINGERBROKEN: desc = strdup("finger is broken^acc penalty"); break;
case IJ_SHOULDERDISLOCATED: desc = strdup("shoulder is dislocated^acc penalty, cannot use heavy weapons"); break;
case IJ_ARTERYPIERCE: break; // fatal - no description
case IJ_NONE: break;
}
if (inj == IJ_NONE) { if (inj == IJ_NONE) {
if (desc) free(desc); if (desc) free(desc);
@ -14840,7 +14894,7 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
char buf[BUFLEN],lfname[BUFLEN]; char buf[BUFLEN],lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
if (lf->hp > 0) { if (lf->hp > 0) {
// effects based on damage type // effects based on damage type, if lf is still alive
if (damtype == DT_COLD) { if (damtype == DT_COLD) {
int i; int i;
if (lfhasflag(lf, F_COLDBLOOD)) { if (lfhasflag(lf, F_COLDBLOOD)) {
@ -14885,6 +14939,15 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
} }
} }
} }
} else if (damtype == DT_ELECTRIC) {
if (getraceclass(lf) == RC_ROBOT) {
f = hasflag(lf->flags, F_CONFUSED);
if (f) {
if (f->lifetime > 0) f->lifetime += rnd(dam, dam*2);
} else {
addtempflag(lf->flags, F_CONFUSED, B_TRUE, NA, NA, NULL, rnd(dam,dam*2));
}
}
} else if (damtype == DT_POISONGAS) { } else if (damtype == DT_POISONGAS) {
if (dam > 0) { if (dam > 0) {
if (!skillcheck(lf, SC_POISON, 35, 0)) { // HARD. if (!skillcheck(lf, SC_POISON, 35, 0)) { // HARD.
@ -14894,6 +14957,27 @@ void losehpeffects(lifeform_t *lf, int dam, enum DAMTYPE damtype, lifeform_t *fr
} }
} // end if hp > 0 } // end if hp > 0
// effects based on damage type, even if lf is dead
if (damtype == DT_ELECTRIC) {
if (hasobofmaterial(lf->cell->obpile, MT_WATER)) {
cell_t *retcell[MAX_MAPW*MAX_MAPH];
int nretcells = 0;
// anyone else in the water takes damage too
if (getconnectedwatercells(lf->cell, retcell, &nretcells)) {
int i;
animflashcells(retcell, nretcells, '/', C_WHITE, "Electricity arcs through the water!");
noise(lf->cell, NULL, NC_OTHER, SV_CAR, "arcing electricity", NULL);
for (i = 0 ; i < nretcells; i++) {
if (retcell[i]->lf && (retcell[i]->lf != lf)) {
if (!isairborne(retcell[i]->lf)) {
losehp_real(retcell[i]->lf, dam, DT_ELECTRIC, fromlf, "an electric shock", B_TRUE, NULL, B_FALSE, NULL, B_FALSE);
}
}
}
}
}
}
// special cases // special cases
if (lf->race->id == R_FUNGUSDREAM) { if (lf->race->id == R_FUNGUSDREAM) {
char buf2[BUFLEN]; char buf2[BUFLEN];
@ -16141,7 +16225,7 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
} }
if (psev != PS_CURSE) { if ((psev != PS_CURSE) && (howlong != PERMENANT)) {
// adjust time based on first aid skill // adjust time based on first aid skill
howlong -= getskill(lf, SK_FIRSTAID); howlong -= getskill(lf, SK_FIRSTAID);
if (howlong <= 0) { if (howlong <= 0) {
@ -16200,7 +16284,7 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
if (ii->val[2] < 1) ii->val[2] = 1; if (ii->val[2] < 1) ii->val[2] = 1;
if (getskill(lf, SK_FIRSTAID) >= PR_BEGINNER) { if (getskill(lf, SK_FIRSTAID) >= PR_BEGINNER) {
ii->known = B_TRUE; ii->known = B_TRUE;
msg("^BYou feel %s coming on more quickly.", pt->name); msg("^BYou recognise the increased onset of %s.", pt->name);
} }
} else { } else {
char ftext[BUFLEN]; char ftext[BUFLEN];
@ -16209,7 +16293,7 @@ void poison(lifeform_t *lf, int howlong, enum POISONTYPE ptype, int power, char
ii->obfrom = srcrace ? srcrace->id : NA; ii->obfrom = srcrace ? srcrace->id : NA;
if (getskill(lf, SK_FIRSTAID) >= PR_BEGINNER) { if (getskill(lf, SK_FIRSTAID) >= PR_BEGINNER) {
ii->known = B_TRUE; ii->known = B_TRUE;
msg("^BYou feel %s coming on.", pt->name); msg("^BYou recognise the onset of %s.", pt->name);
} else { } else {
ii->known = B_FALSE; ii->known = B_FALSE;
} }
@ -17534,7 +17618,7 @@ int sayphrase(lifeform_t *lf, enum SAYPHRASE what, int volume, int val0, char *t
// returns TRUE if something happened // returns TRUE if something happened
int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus) { int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus) {
int nfailures = 0,nsuccesses = 0,penalty = 0,i; int nfailures = 0,nsuccesses = 0,scareebonus = 0,i;
int nchecks; int nchecks;
if (!scarer) return B_FALSE; if (!scarer) return B_FALSE;
@ -17555,7 +17639,7 @@ int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus) {
// determine morale check penalty // determine morale check penalty
if (isbleeding(lf) || islowhp(lf)) { if (isbleeding(lf) || islowhp(lf)) {
penalty += 5; scareebonus -= 5;
} }
if (lfhasflag(lf, F_HUMANOID)) { if (lfhasflag(lf, F_HUMANOID)) {
object_t *o; object_t *o;
@ -17575,13 +17659,10 @@ int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus) {
} }
} }
} }
// modify by charisma: -3 to 3
scarerbonus += (getstatmod(lf, A_CHA) / 15);
// if you have morale left, you make 3 checks. chance of not fleeing at all. // if you have morale left, you make 3 checks. chance of not fleeing at all.
// if you DONT have morale left, the first check always fails. // if you DONT have morale left, the first check always fails.
if (getmorale(lf)) { if (isplayer(lf) || lfhasflag(lf, F_MORALE)) {
nfailures = 0; nfailures = 0;
nchecks = 3; nchecks = 3;
} else { } else {
@ -17589,8 +17670,12 @@ int scare(lifeform_t *lf, lifeform_t *scarer, int howlong, int scarerbonus) {
nchecks = 2; nchecks = 2;
// two checks - first one always fails. // two checks - first one always fails.
} }
// the person being scared gets a wisdom bonus
scareebonus += (getattr(lf, A_WIS)/20);
for (i = 0; i < nchecks; i++) { for (i = 0; i < nchecks; i++) {
if (!skillcheckvs(lf, SC_MORALE, -penalty, scarer, SC_MORALE, scarerbonus)) { if (!skillcheckvs(lf, SC_MORALE, scareebonus, scarer, SC_MORALE, scarerbonus)) {
nfailures++; nfailures++;
} }
} }
@ -17761,6 +17846,9 @@ void setguntarget(lifeform_t *lf, lifeform_t *targ) {
void sethomeroom(lifeform_t *lf) { void sethomeroom(lifeform_t *lf) {
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags = 0,i; int nretflags = 0,i;
if (gamemode == GM_LOADING) return;
getflags(lf->flags, retflag, &nretflags, F_STAYINROOM, F_NONE); getflags(lf->flags, retflag, &nretflags, F_STAYINROOM, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
if (retflag[i]->val[1] == NA) { if (retflag[i]->val[1] == NA) {
@ -17950,13 +18038,21 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
if (!retainhp) { if (!retainhp) {
// generate hp/maxhp from hit dice // generate hp/maxhp from hit dice
lf->maxhp = 0; lf->maxhp = 0;
for (i = 0; i < lf->level; i++) { if (isplayer(lf)) {
int wantmax = B_FALSE; for (i = 0; i < lf->level; i++) {
if ((i == 0) || !isplayer(lf)){ int wantmax = B_FALSE;
wantmax = B_TRUE; if (i == 0) {
wantmax = B_TRUE;
}
lf->maxhp += rollhitdice(lf, wantmax);
assert(lf->maxhp > 0);
}
} else {
lf->maxhp += rollhitdice(lf, B_TRUE);
// one more hitdie for every level after the first
for (i = 1; i < lf->level; i++) {
lf->maxhp += rolldie(1, HITDIESIDES);
} }
lf->maxhp += rollhitdice(lf, wantmax);
assert(lf->maxhp > 0);
} }
lf->hp = lf->maxhp; lf->hp = lf->maxhp;
@ -18432,7 +18528,9 @@ int getskillcheckchance(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod) {
othermod -= 10; othermod -= 10;
} }
} else if (ct == SC_MORALE) { } else if (ct == SC_MORALE) {
othermod += (getstatmod(lf, A_WIS) / 30); // ie. -1 to 1 if (isbleeding(lf) || islowhp(lf)) {
othermod -= 5;
}
} else if (ct == SC_OPENLOCKS) { } else if (ct == SC_OPENLOCKS) {
enum SKILLLEVEL slev; enum SKILLLEVEL slev;
slev = getskill(lf, SK_LOCKPICKING); slev = getskill(lf, SK_LOCKPICKING);
@ -19543,16 +19641,23 @@ void startlfturn(lifeform_t *lf) {
pt = findpoisontype(f->val[0]); pt = findpoisontype(f->val[0]);
// chance of fighting it off - gets easier over time. // chance of fighting it off - gets easier over time.
// //
if ((f->lifetime > 0) && skillcheck(lf, SC_POISON, (f->lifetime * 9), 0 )) { if ((f->lifetime > 0) && skillcheck(lf, SC_POISON, (f->lifetime * 9), -(f->val[1]) )) {
killflag(f); killflag(f);
} else { } else {
flag_t *asleep; flag_t *asleep;
int chance;
int ko; int ko;
// being asleep helps. // being asleep helps.
asleep = hasflag(lf->flags, F_ASLEEP); asleep = hasflag(lf->flags, F_ASLEEP);
ko = isunconscious(lf); ko = isunconscious(lf);
// chance of losing hp // chance of losing hp
if (!ko && pctchance(pt->dampct)) { chance = pt->dampct;
if (f->val[1] > 1) {
//+10% chance per power > 1
chance = pctof(100 + ((f->val[1] - 1)*10), chance);
}
if (!ko && pctchance(chance)) {
char buf[BUFLEN]; char buf[BUFLEN];
if (isplayer(lf) || cansee(player, lf)) { if (isplayer(lf) || cansee(player, lf)) {
char *p; char *p;
@ -19595,8 +19700,69 @@ void startlfturn(lifeform_t *lf) {
} }
} }
snprintf(buf, BUFLEN, "%s^from %s",pt->name, f->text); // special case
losehp(lf, pt->dam * f->val[1], DT_DIRECT, NULL, buf); if (pt->id == P_TETANUS) {
enum BODYPART bp,poss[MAXBODYPARTS];
int nposs = 0;
for (bp = 0; bp < MAXBODYPARTS; bp++) {
int ok;
switch (bp) {
case BP_LEGS:
case BP_HEAD:
case BP_HANDS:
case BP_BODY:
case BP_TAIL:
case BP_WINGS:
ok = B_TRUE;
break;
default:
ok = B_FALSE;
break;
}
if (ok && hasbp(lf, bp)) {
poss[nposs++] = bp;
}
}
if (nposs) {
object_t *oo;
bp = poss[rnd(0,nposs-1)];
switch (bp) {
case BP_LEGS:
injure(lf, bp, DT_BASH, IJ_LEGBROKEN);
break;
case BP_HEAD: break; // no bad effects
case BP_HANDS: // drop your weapon
oo = getequippedob(lf->pack, bp);
if (oo) drop(oo, oo->amt);
break;
case BP_BODY:
if (onein(2)) {
injure(lf, bp, DT_BASH, IJ_RIBCRACKED);
} else {
if (isplayer(lf)) {
msg("^BYour spine snaps!");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%c%s%s spine snaps!", getlfcol(lf, CC_VBAD),
lfname, getpossessive(lfname));
}
losehp_real(lf, lf->maxhp, DT_DIRECT, NULL, "tetanus", B_FALSE, NULL, B_FALSE, NULL, B_FALSE);
}
break;
case BP_TAIL:
injure(lf, bp, DT_BASH, IJ_TAILBROKEN);
break;
case BP_WINGS:
injure(lf, bp, DT_SLASH, IJ_WINGTORN);
break;
default: break;
}
}
} else {
snprintf(buf, BUFLEN, "%s^from %s",pt->name, f->text);
losehp(lf, pt->dam * f->val[1], DT_DIRECT, NULL, buf);
}
if (pt->vomitob != OT_NONE) { if (pt->vomitob != OT_NONE) {
addobfast(lf->cell->obpile, pt->vomitob); addobfast(lf->cell->obpile, pt->vomitob);
@ -21446,7 +21612,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
killflagsofid(lf->flags, F_FALLDISTANCE); killflagsofid(lf->flags, F_FALLDISTANCE);
if (!isimmuneto(lf->flags, DT_FALL, B_FALSE)) { if (!isimmuneto(lf->flags, DT_FALL, B_FALSE)) {
// injure legs // injure legs
injure(lf, BP_LEGS, DT_BASH); injure(lf, BP_LEGS, DT_BASH, IJ_NONE);
// fall over // fall over
fall(lf, NULL, B_FALSE); fall(lf, NULL, B_FALSE);
} }
@ -22558,6 +22724,7 @@ int weild(lifeform_t *lf, object_t *o) {
if (o) { if (o) {
getobname(o, buf, o->amt); getobname(o, buf, o->amt);
killflagsofid(o->flags, F_SECONDARY);
} else { } else {
snprintf(buf, BUFLEN, "nothing"); snprintf(buf, BUFLEN, "nothing");
} }

2
lf.h
View File

@ -291,7 +291,7 @@ int hashealableinjuries(lifeform_t *lf);
job_t *hasjob(lifeform_t *lf, enum JOB job); job_t *hasjob(lifeform_t *lf, enum JOB job);
int hassubjob(lifeform_t *lf, enum SUBJOB id); int hassubjob(lifeform_t *lf, enum SUBJOB id);
void inc_quad_range(enum QUADRANT *start, enum QUADRANT *end, int howmuch); void inc_quad_range(enum QUADRANT *start, enum QUADRANT *end, int howmuch);
int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype); int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype, enum INJURY forcetype);
int lfcanbestoned(lifeform_t *lf); int lfcanbestoned(lifeform_t *lf);
flag_t *lfhasflag(lifeform_t *lf, enum FLAG fid); flag_t *lfhasflag(lifeform_t *lf, enum FLAG fid);
flag_t *lfhasflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text); flag_t *lfhasflagval(lifeform_t *lf, enum FLAG fid, int val0, int val1, int val2, char *text);

97
map.c
View File

@ -903,7 +903,7 @@ regionthing_t *addregionthing(regionoutline_t *ro, int depth, int x, int y, enum
return rt; return rt;
} }
regiontype_t *addregiontype(enum REGIONTYPE id, char *name, int pluralname, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major, int depthmod) { regiontype_t *addregiontype(enum REGIONTYPE id, char *name, int pluralname, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major, int depthmod, int addparentdepth) {
regiontype_t *a; regiontype_t *a;
// add to the end of the list // add to the end of the list
@ -931,10 +931,10 @@ regiontype_t *addregiontype(enum REGIONTYPE id, char *name, int pluralname, enum
a->deeperdir = deeperdir; a->deeperdir = deeperdir;
a->majorbranch = major; a->majorbranch = major;
a->depthmod = depthmod; a->depthmod = depthmod;
a->addparentdepth = addparentdepth;
return a; return a;
} }
void adjustcellglyphforlight(cell_t *c, glyph_t *g) { void adjustcellglyphforlight(cell_t *c, glyph_t *g) {
if (g->ch == ' ') return; if (g->ch == ' ') return;
switch (c->lit) { switch (c->lit) {
@ -1880,6 +1880,33 @@ enum DEPTH getcellwaterdepth(cell_t *c, lifeform_t *lf) {
} }
// note that *ncells should be set to 0 before this function is called
int getconnectedwatercells(cell_t *c, cell_t **retcell, int *ncells) {
int d;
int i,found = B_FALSE;
for (i = 0; i < *ncells; i++) {
if (retcell[i] == c) {
found = B_TRUE;
break;
}
}
if (c && // not off the map
!found && // not already processed
!c->type->solid && // empty cell
hasobofmaterial(c->obpile, MT_WATER)) { // has water
retcell[*ncells] = c;
(*ncells)++;
} else {
return 0;
}
for (d = DC_N; d <= DC_NW; d++) {
getconnectedwatercells(getcellindir(c, d), retcell, ncells); // recursive call
}
return *ncells;
}
// returns the closest cell next to 'dst', when coming from 'src' // returns the closest cell next to 'dst', when coming from 'src'
// ie. if you start walking from src to dst, where will you end up? // ie. if you start walking from src to dst, where will you end up?
cell_t *get_closest_adjcell(cell_t *src, cell_t *dst) { cell_t *get_closest_adjcell(cell_t *src, cell_t *dst) {
@ -2433,6 +2460,33 @@ void createborder(map_t *map, enum CELLTYPE solidtype) {
} }
} }
void createbyhut(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
int x,y;
enum CELLTYPE emptycell,solidcell;
cell_t *c;
vault_t *v;
//object_t *o;
// what kind of cells will 'empty' ones be?
emptycell = getmapempty(map);
solidcell = getmapsolid(map);
// fill entire maze with walls
for (y = 0; y < map->h; y++) {
for (x = 0; x < map->w; x++) {
c = addcell(map, x, y);
setcelltype(c, solidcell);
}
}
// add a random babayaga's hut vault
v = findvaultwithtag("byhut");
assert(v);
if (createvault(map, map->nrooms, v, NULL, NULL, NULL, NULL)) {
dblog("ERROR - couldn't create byhut vault '%s' on map %s", v->id, map->name);
msg("ERROR - couldn't create byhut vault '%s' on map %s", v->id, map->name);
assert("failed to create babayaga's hut" == 0);
}
}
void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) { void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob) {
int wantrooms = B_TRUE; int wantrooms = B_TRUE;
int x,y,i; int x,y,i;
@ -3192,6 +3246,9 @@ void createhabitat(map_t *map, int depth, map_t *parentmap, int exitdir, object_
case H_SWAMP: case H_SWAMP:
createswamp(map, depth, parentmap, exitdir, entryob); createswamp(map, depth, parentmap, exitdir, entryob);
break; break;
case H_BYHUT:
createbyhut(map, depth, parentmap, exitdir, entryob);
break;
case H_ALL: case H_ALL:
dblog("ERROR - createhabitat with invalid habitat!"); dblog("ERROR - createhabitat with invalid habitat!");
msg("ERROR - createhabitat with invalid habitat!"); msg("ERROR - createhabitat with invalid habitat!");
@ -4860,7 +4917,9 @@ void createregionlink(map_t *m, cell_t *c, object_t *o, char *obname, enum REGIO
flag_t *f; flag_t *f;
region_t *r; region_t *r;
int basedepth = 0; int basedepth = 0;
if (newregiontype != RG_MAINDUNGEON) { regiontype_t *nrt;
nrt = findregiontype(newregiontype);
if (nrt->addparentdepth) {
basedepth = getmapdifficulty(m); basedepth = getmapdifficulty(m);
} }
// create a new region. // create a new region.
@ -6342,17 +6401,19 @@ cell_t *getstairdestination(object_t *o, int *madenewmap) {
if (!f) return NULL; if (!f) return NULL;
dir = getstairdirection(o); dir = getstairdirection(o);
if ((dir != D_UP) && (dir != D_DOWN)) { //if ((dir != D_UP) && (dir != D_DOWN)) {
if (o->type->id == OT_PORTAL) {
// ie this is a portal // ie this is a portal
return NULL; return NULL;
} else { } else {
if (dir == D_UP) newdepth = curmap->depth - 1;
else newdepth = curmap->depth + 1;
if (f->val[1] == NA) { if (f->val[1] == NA) {
// use same region // use same region
newregion = obcell->map->region; newregion = obcell->map->region;
if (dir == D_UP) newdepth = curmap->depth - 1;
else newdepth = curmap->depth + 1;
} else { } else {
newregion = findregion(f->val[1]); newregion = findregion(f->val[1]);
newdepth = 1;
} }
} }
@ -6469,6 +6530,7 @@ void initmap(void) {
addhabitat(H_SEWER, "sewer", CT_CORRIDOR, CT_WALL, 5, 50, 0, MAXVISRANGE, OT_NONE, OT_NONE); addhabitat(H_SEWER, "sewer", CT_CORRIDOR, CT_WALL, 5, 50, 0, MAXVISRANGE, OT_NONE, OT_NONE);
addhabitat(H_STOMACH, "stomach", CT_FLOORFLESH, CT_WALLFLESH, 5, 80, 0, MAXVISRANGE, OT_NONE, OT_NONE); addhabitat(H_STOMACH, "stomach", CT_FLOORFLESH, CT_WALLFLESH, 5, 80, 0, MAXVISRANGE, OT_NONE, OT_NONE);
addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 3, 50, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN); addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 3, 50, 0, MAXVISRANGE, OT_STAIRSUP, OT_STAIRSDOWN);
addhabitat(H_BYHUT, "babayaga's hut", CT_CORRIDOR, CT_WALLDWOOD, 0, 0, 0, MAXVISRANGE, OT_BYHUTDOOR, OT_NONE);
// cell types - solid // cell types - solid
// floorheight, hp // floorheight, hp
@ -6476,6 +6538,7 @@ void initmap(void) {
addcelltype(CT_WALLBRICK, "brick wall", UNI_SHADEDARK, C_ORANGE, B_SOLID, B_OPAQUE, MT_STONE, 0, 40); addcelltype(CT_WALLBRICK, "brick wall", UNI_SHADEDARK, C_ORANGE, B_SOLID, B_OPAQUE, MT_STONE, 0, 40);
addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEDARK, C_BROWN, B_SOLID, B_OPAQUE, MT_STONE, 0, 20); addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEDARK, C_BROWN, B_SOLID, B_OPAQUE, MT_STONE, 0, 20);
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30); addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30);
addcelltype(CT_WALLDWOOD, "wyrmwood wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_DRAGONWOOD, 0, 100);
addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, B_SOLID, B_OPAQUE, MT_FLESH, 0, 25); addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, B_SOLID, B_OPAQUE, MT_FLESH, 0, 25);
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0, 20); addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0, 20);
//addcelltype(CT_WALLTREE, "dense bushland", UNI_SHADEDARK, C_GREEN, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100); //addcelltype(CT_WALLTREE, "dense bushland", UNI_SHADEDARK, C_GREEN, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100);
@ -6496,18 +6559,22 @@ void initmap(void) {
addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -2, -1); addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -2, -1);
// region types // region types
// name, pluralname?, defaulthab, maxdepth stairs stair major? depthmod // name, pluralname?, defaulthab, maxdepth stairs stair major? depthmod inherit_parent_depth?
// perlev dir // perlev dir
addregiontype(RG_WORLDMAP, "The Surface", B_FALSE, H_FOREST, 10, 0, D_NONE, B_TRUE, 0);
addregiontype(RG_HEAVEN, "The Realm of Gods", B_FALSE, H_HEAVEN, 1, 0, D_NONE, B_FALSE, 0); addregiontype(RG_BABAYAGAHUT, "Baba Yaga's Hut", B_FALSE, H_BYHUT, 0, 0, D_NONE, B_FALSE, 0, B_FALSE);
addregiontype(RG_WORLDMAP, "The Surface", B_FALSE, H_FOREST, 10, 0, D_NONE, B_TRUE, 0, B_FALSE);
addregiontype(RG_HEAVEN, "The Realm of Gods", B_FALSE, H_HEAVEN, 1, 0, D_NONE, B_FALSE, 0, B_FALSE);
// main branches // main branches
addregiontype(RG_MAINDUNGEON, "The Main Dungeon", B_FALSE, H_DUNGEON, 25, 3, D_DOWN, B_TRUE, 0); addregiontype(RG_MAINDUNGEON, "The Main Dungeon", B_FALSE, H_DUNGEON, 25, 3, D_DOWN, B_TRUE, 0, B_FALSE);
addregiontype(RG_CAVE, "The Goblin Caves", B_TRUE, H_CAVE, 5, 1, D_DOWN, B_TRUE, 2); addregiontype(RG_CAVE, "The Goblin Caves", B_TRUE, H_CAVE, 5, 1, D_DOWN, B_TRUE, 2, B_FALSE);
addregiontype(RG_WOODS, "The Sylvan Woods", B_TRUE, H_FOREST, 5, 3, D_DOWN, B_TRUE, 1); addregiontype(RG_WOODS, "The Sylvan Woods", B_TRUE, H_FOREST, 5, 3, D_DOWN, B_TRUE, 1, B_FALSE);
// minor branches // minor branches
addregiontype(RG_PIT, "A Pit", B_FALSE, H_PIT, 1, 1, D_DOWN, B_FALSE, 0); addregiontype(RG_PIT, "A Pit", B_FALSE, H_PIT, 1, 1, D_DOWN, B_FALSE, 0, B_TRUE);
addregiontype(RG_SEWER, "A Sewer", B_FALSE, H_SEWER, 1, 0, D_NONE, B_FALSE, 2); addregiontype(RG_SEWER, "A Sewer", B_FALSE, H_SEWER, 1, 0, D_NONE, B_FALSE, 2, B_TRUE);
addregiontype(RG_STOMACH, "A Stomach", B_FALSE, H_STOMACH, 1, 0, D_NONE, B_FALSE, 0); addregiontype(RG_STOMACH, "A Stomach", B_FALSE, H_STOMACH, 1, 0, D_NONE, B_FALSE, 0, B_FALSE);
// special
} }

4
map.h
View File

@ -10,7 +10,7 @@ int addrandomthing(cell_t *c, int obchance, int *nadded);
region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid, int depthmod, int createdby); region_t *addregion(enum REGIONTYPE rtype, region_t *parent, int outlineid, int depthmod, int createdby);
regionoutline_t *addregionoutline(enum REGIONTYPE rtype); regionoutline_t *addregionoutline(enum REGIONTYPE rtype);
regionthing_t *addregionthing(regionoutline_t *ro, int depth, int x, int y, enum REGIONTHING whatkind, int value, char *what); regionthing_t *addregionthing(regionoutline_t *ro, int depth, int x, int y, enum REGIONTHING whatkind, int value, char *what);
regiontype_t *addregiontype(enum REGIONTYPE id, char *name, int pluralname, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major, int depthmod); regiontype_t *addregiontype(enum REGIONTYPE id, char *name, int pluralname, enum HABITAT defaulthabitat, int maxdepth, int stairsperlev, int deeperdir, int major, int depthmod, int addparentdepth);
void adjustcellglyphforlight(cell_t *c, glyph_t *col); 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 autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, int doorpct, int dooropenchance);
void breakwall(cell_t *c); void breakwall(cell_t *c);
@ -37,6 +37,7 @@ enum CELLTYPE getcellsolid(cell_t *c);
enum CELLTYPE getmapempty(map_t *m); enum CELLTYPE getmapempty(map_t *m);
enum CELLTYPE getmapsolid(map_t *m); enum CELLTYPE getmapsolid(map_t *m);
enum DEPTH getcellwaterdepth(cell_t *c, lifeform_t *lf); enum DEPTH getcellwaterdepth(cell_t *c, lifeform_t *lf);
int getconnectedwatercells(cell_t *c, cell_t **retcell, int *ncells);
cell_t *get_closest_adjcell(cell_t *src, cell_t *dst); cell_t *get_closest_adjcell(cell_t *src, cell_t *dst);
int getdoorlockdiff(int depth); int getdoorlockdiff(int depth);
int getdoorsecretdiff(int depth); int getdoorsecretdiff(int depth);
@ -63,6 +64,7 @@ int countmapobswithflag(map_t *m, enum FLAG flagid);
int countmapobswithflagval(map_t *m, enum FLAG flagid, int val0, int val1, int val2, char *text); int countmapobswithflagval(map_t *m, enum FLAG flagid, int val0, int val1, int val2, char *text);
int countstairs(map_t *m, int dir); int countstairs(map_t *m, int dir);
void createborder(map_t *map, enum CELLTYPE solidtype); void createborder(map_t *map, enum CELLTYPE solidtype);
void createbyhut(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob); void createcave(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob); void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
void createfakes(map_t *map, cell_t *cell); void createfakes(map_t *map, cell_t *cell);

2
move.c
View File

@ -3550,7 +3550,7 @@ int willmove(lifeform_t *lf, int dir, enum ERROR *error) {
// for at least average iq things... // for at least average iq things...
if (iq >= AT_AVERAGE) { if (iq >= AT_AVERAGE) {
// don't move if in pain // don't move if in pain
if (move_will_hurt(lf)) { if (move_will_hurt(lf) && !isfleeing(lf)) {
if (error) *error = E_WONT; if (error) *error = E_WONT;
return B_FALSE; return B_FALSE;
} }

229
objects.c
View File

@ -1573,6 +1573,13 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
lev = firstlev + i; lev = firstlev + i;
if (lev > MAXSPELLLEV) break; if (lev > MAXSPELLLEV) break;
oid = getrandomspellfromschool(bookcontents,lev); oid = getrandomspellfromschool(bookcontents,lev);
// special case - paladin's always have this spell
if ((lev == 3) && (where->owner) && hassubjob(where->owner, SJ_PALADIN) &&
(bookcontents == SS_LIFE)) {
while (oid == OT_S_DISRUPTUNDEAD) {
oid = getrandomspellfromschool(bookcontents,lev);
}
}
if (oid != OT_NONE) { if (oid != OT_NONE) {
assert(addobfast(o->contents, oid)); assert(addobfast(o->contents, oid));
} }
@ -2497,6 +2504,10 @@ void adjustdamob(object_t *o, int *dam, enum DAMTYPE damtype) {
*dam = 0; *dam = 0;
return; return;
} }
if (hasflag(o->flags, F_IMMUTABLE)) {
*dam = 0;
return;
}
// immune? // immune?
if (isimmuneto(o->flags, damtype, B_FALSE)) { if (isimmuneto(o->flags, damtype, B_FALSE)) {
@ -3556,7 +3567,7 @@ objecttype_t *findotn(char *name) {
modname = strrep(modname, "gems ", "gem ", NULL); modname = strrep(modname, "gems ", "gem ", NULL);
modname = strrep(modname, "knives", "knife", NULL); modname = strrep(modname, "knives", "knife", NULL);
modname = strrep(modname, "leaves", "leaf", NULL); modname = strrep(modname, "leaves", "leaf", NULL);
modname = strrep(modname, "loaves ", "load ", NULL); modname = strrep(modname, "loaves ", "loaf ", NULL);
modname = strrep(modname, "lumps ", "lump ", NULL); modname = strrep(modname, "lumps ", "lump ", NULL);
modname = strrep(modname, "pieces ", "piece ", NULL); modname = strrep(modname, "pieces ", "piece ", NULL);
modname = strrep(modname, "piles ", "pile ", NULL); modname = strrep(modname, "piles ", "pile ", NULL);
@ -3650,6 +3661,21 @@ objecttype_t *findotn(char *name) {
return NULL; return NULL;
} }
int getrustdampct(object_t *o) {
int pct = 100;
flag_t *rust;
rust = hasflag(o->flags, F_RUSTED);
if (rust) {
if (rust->val[0] >= R_TRUSTY) {
pct = 50;
} else if (rust->val[0] >= R_VRUSTY) {
pct = 75;
} else {
pct = 90;
}
}
return pct;
}
int getfirearmrange(object_t *o) { int getfirearmrange(object_t *o) {
flag_t *f; flag_t *f;
@ -3819,7 +3845,7 @@ void fragments(cell_t *centre, char *what, int speed, int howfar) {
// add object then fire it // add object then fire it
o = addob(centre->obpile, what); o = addob(centre->obpile, what);
if (o) { if (o) {
real_fireat(NULL, o, o->amt, dst, speed, NULL, B_FALSE, OT_NONE); real_fireat(NULL, o, o->amt, dst, speed, NULL, B_FALSE, OT_NONE, NULL);
} }
} else { } else {
// add object // add object
@ -5815,9 +5841,17 @@ char *getobconditionname(object_t *o, char *buf) {
iqb = AT_AVERAGE; // this should be sufficient to show everything iqb = AT_AVERAGE; // this should be sufficient to show everything
} }
if (iscorpse(o)) {
// only show 'immutable' if this is abnormal.
if (hasflagknown(o->flags, F_IMMUTABLE) && !hasflag(o->type->flags, F_IMMUTABLE)) {
strcpy(buf, "immutable");
} else {
strcpy(buf, ""); strcpy(buf, "");
}
if (iscorpse(o)) {
if (hasflag(o->flags, F_PREPARED)) { if (hasflag(o->flags, F_PREPARED)) {
if (strlen(buf)) strcat(buf, " ");
strcat(buf, "cooked"); strcat(buf, "cooked");
} }
if (hasflag(o->flags, F_SALTED)) { if (hasflag(o->flags, F_SALTED)) {
@ -5837,22 +5871,26 @@ char *getobconditionname(object_t *o, char *buf) {
} }
} else { } else {
char condbuf[BUFLEN];
if (iqb >= AT_LOW) { if (iqb >= AT_LOW) {
pct = getobhppct(o); pct = getobhppct(o);
if (pct >= 85) { if (pct >= 85) {
strcpy(buf, ""); strcpy(condbuf, "");
} else if (pct >= 75) { } else if (pct >= 75) {
snprintf(buf, BUFLEN, "battered"); snprintf(condbuf, BUFLEN, "battered");
} else if (pct >= 50) { } else if (pct >= 50) {
snprintf(buf, BUFLEN, "damaged"); snprintf(condbuf, BUFLEN, "damaged");
} else if (pct >= 25) { } else if (pct >= 25) {
snprintf(buf, BUFLEN, "very damaged"); snprintf(condbuf, BUFLEN, "very damaged");
} else { } else {
snprintf(buf, BUFLEN, "critically damaged"); snprintf(condbuf, BUFLEN, "critically damaged");
} }
} else { } else {
strcpy(buf, ""); strcpy(condbuf, "");
}
if (strlen(condbuf)) {
if (strlen(buf)) strcat(buf, " ");
strcat(buf, condbuf);
} }
} }
return buf; return buf;
@ -6557,10 +6595,10 @@ int getthrowdam(object_t *o) {
// non-missile objects do 25% less damage // non-missile objects do 25% less damage
if (!hasflag(o->flags, F_THROWMISSILE)) { if (!hasflag(o->flags, F_THROWMISSILE)) {
dam = pctof(75, dam); dam = pctof(75, dam);
} // soft materials do less damage
// soft materials do less damage if (gethardness(o->material->id) < 2) {
if (gethardness(o->material->id) < 2) { dam /= 2;
dam /= 2; }
} }
} }
@ -6573,7 +6611,7 @@ int getthrowdam(object_t *o) {
} }
// note: damage will also be modified based on speed in fireat() // note: damage will also be modified based on speed in fireat()
if (dam < 0) dam = 0;
return (int)ceil(dam); return (int)ceil(dam);
} }
@ -7905,6 +7943,10 @@ int makeduller(object_t *o, int howmuch) {
int oldbonus,newbonus; int oldbonus,newbonus;
int rv = B_FALSE; int rv = B_FALSE;
if (hasflag(o->flags, F_IMMUTABLE)) {
return B_FALSE;
}
// get object name before changing the bonus // get object name before changing the bonus
getobname(o,obname, 1); getobname(o,obname, 1);
@ -8061,20 +8103,27 @@ void makewet(object_t *o, int amt) {
killflagsofid(o->flags, F_HOT); killflagsofid(o->flags, F_HOT);
if (o->material->id == MT_METAL) { if (o->material->id == MT_METAL) {
if (amt < R_RUSTY) amt = R_RUSTY; int rustchance = 25;
if (amt > R_TRUSTY) amt = R_TRUSTY;
f = hasflag(o->flags, F_RUSTED); f = hasflag(o->flags, F_RUSTED);
if (f) { if (f) rustchance += 25;
if (f->val[0] < R_TRUSTY) {
// make more rusty if (pctchance(rustchance)) {
f->val[0] += amt; if (amt < R_RUSTY) amt = R_RUSTY;
if (amt > R_TRUSTY) amt = R_TRUSTY;
if (f) {
if (f->val[0] < R_TRUSTY) {
// make more rusty
f->val[0] += amt;
}
} else {
// rust
if (haslos(player, loc) && !isdead(player)) {
msg("^%c%s rust%s.",
(o->pile->owner && isplayer(o->pile->owner)) ? 'b' : 'n',
obnamefull,OBS1(o));
}
f = addflag(o->flags, F_RUSTED, amt, NA, NA, NULL);
} }
} else {
// rust
if (haslos(player, loc) && !isdead(player)) {
msg("%s rust%s.",obnamefull,OBS1(o));
}
f = addflag(o->flags, F_RUSTED, amt, NA, NA, NULL);
} }
} else { } else {
if (hasflag(o->flags, F_CANGETWET)) { if (hasflag(o->flags, F_CANGETWET)) {
@ -8096,7 +8145,6 @@ void makewet(object_t *o, int amt) {
f->val[1] = TM_WETTIME; f->val[1] = TM_WETTIME;
} }
} else { } else {
// get wet // get wet
if (!isdead(player)) { if (!isdead(player)) {
int doannounce = B_FALSE; int doannounce = B_FALSE;
@ -10129,36 +10177,42 @@ int pour(lifeform_t *lf, object_t *o) {
} }
} else if (o->type->id == OT_POT_RESTORATION) { } else if (o->type->id == OT_POT_RESTORATION) {
flag_t *f, *nextf; flag_t *f, *nextf;
if (isplayer(lf)) {
msg("Your %s looks as good as new!",noprefix(dstname));
}
// restore orig material
if (dst->material != dst->type->material) {
changemat(dst, dst->type->material->id);
}
// remove blessings/curses
setblessed(dst, B_UNCURSED);
dst->blessknown = B_TRUE;
// remove bonuses
killflagsofid(dst->flags, F_BONUS);
// remove temporary flags, obmod flags and modify some others
for (f = dst->flags->first ; f ; f = nextf) {
nextf = f->next;
if (f->lifetime > 0) {
killflag(f);
} else if (f->lifetime == FROMOBMOD) {
killflag(f);
} else if (f->id == F_FROZEN) {
killflag(f);
} else if (f->id == F_ONFIRE) {
killflag(f);
} else if (f->id == F_POISONED) {
killflag(f);
} else if (f->id == F_OBHP) {
f->val[0] = f->val[1];
}
} if (hasflag(dst->flags, F_IMMUTABLE)) {
if (isplayer(lf)) {
msg("For a moment, your %s looks as good as new.",noprefix(dstname));
}
} else {
if (isplayer(lf)) {
msg("Your %s looks as good as new!",noprefix(dstname));
}
// restore orig material
if (dst->material != dst->type->material) {
changemat(dst, dst->type->material->id);
}
// remove blessings/curses
setblessed(dst, B_UNCURSED);
dst->blessknown = B_TRUE;
// remove bonuses
killflagsofid(dst->flags, F_BONUS);
// remove temporary flags, obmod flags and modify some others
for (f = dst->flags->first ; f ; f = nextf) {
nextf = f->next;
if (f->lifetime > 0) {
killflag(f);
} else if (f->lifetime == FROMOBMOD) {
killflag(f);
} else if (f->id == F_FROZEN) {
killflag(f);
} else if (f->id == F_ONFIRE) {
killflag(f);
} else if (f->id == F_POISONED) {
killflag(f);
} else if (f->id == F_OBHP) {
f->val[0] = f->val[1];
}
}
}
// we now know what the potion was // we now know what the potion was
if (!isknown(o)) makeknown(o->type->id); if (!isknown(o)) makeknown(o->type->id);
@ -11302,29 +11356,31 @@ int readsomething(lifeform_t *lf, object_t *o) {
object_t *oo,*poss[MAXPILEOBS]; object_t *oo,*poss[MAXPILEOBS];
int nposs = 0; int nposs = 0;
// make a piece of armour invulnerable // make a weapon or piece of armour invulnerable
for (oo = lf->pack->first ; oo ; oo = oo->next) { for (oo = lf->pack->first ; oo ; oo = oo->next) {
if (isequipped(oo) && !hasflag(oo->flags, F_INVULNERABLE)) { if (isweapon(oo) || isarmour(oo)) {
poss[nposs++] = oo; if (isequipped(oo) && !hasflag(oo->flags, F_INVULNERABLE)) {
poss[nposs++] = oo;
}
} }
} }
if (nposs) { if (nposs) {
oo = poss[rnd(0,nposs-1)]; oo = poss[rnd(0,nposs-1)];
addflag(oo->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
killflagsofid(oo->flags, F_DAMAGABLE);
if (isplayer(lf)) { if (isplayer(lf)) {
char ooname[BUFLEN]; char ooname[BUFLEN];
getobname(oo, ooname, oo->amt); getobname(oo, ooname, oo->amt);
msg("Your %s become%s ultra-dense!", ooname, (oo->amt == 1) ? "s" : ""); msg("Your %s become%s ultra-dense!", noprefix(ooname), (oo->amt == 1) ? "s" : "");
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
char ooname[BUFLEN]; char ooname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
getobname(oo, ooname, oo->amt); getobname(oo, ooname, oo->amt);
msg("%s%s %s become%s ultra-dense!", lfname, getpossessive(lfname), msg("%s%s %s become%s ultra-dense!", lfname, getpossessive(lfname),
ooname, (oo->amt == 1) ? "s" : ""); noprefix(ooname), (oo->amt == 1) ? "s" : "");
} }
addflag(oo->flags, F_IMMUTABLE, B_TRUE, NA, NA, NULL);
killflagsofid(oo->flags, F_DAMAGABLE);
ndone++; ndone++;
} }
// still nothing done? // still nothing done?
@ -11495,7 +11551,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
} else { } else {
if (!giveskill(lf, f->val[0])) { if (!giveskill(lf, f->val[0])) {
// can't learn this skill. maybe you have f_noskill? // can't learn this skill. maybe you have f_noskill?
if (isplayer(lf)) msg("You are incapable of using this skill."); if (isplayer(lf)) msg("You are incapable of learning this skill.");
} }
} }
} }
@ -12435,11 +12491,11 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
} }
int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm) { int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm) {
return real_fireat(thrower, o, amt, where, speed, firearm, B_TRUE, OT_NONE); return real_fireat(thrower, o, amt, where, speed, firearm, B_TRUE, OT_NONE, NULL);
} }
// throw speed/2 is the damage multiplier // throw speed/2 is the damage multiplier
int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm, int announcethrow, enum OBTYPE fromspell) { int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm, int announcethrow, enum OBTYPE fromspell, object_t **newobptr) {
char throwername[BUFLEN]; char throwername[BUFLEN];
char throwernamea[BUFLEN]; char throwernamea[BUFLEN];
char realthrowername[BUFLEN]; char realthrowername[BUFLEN];
@ -12556,6 +12612,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
//taketime(thrower, SPEED_THROW); //taketime(thrower, SPEED_THROW);
// fail. // fail.
reason = E_CURSED; reason = E_CURSED;
if (newobptr) *newobptr = o;
return B_TRUE; return B_TRUE;
} }
} }
@ -12591,11 +12648,15 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
if (thrower) { if (thrower) {
if (firearm) { if (firearm) {
if (touch(thrower, firearm)) { if (touch(thrower, firearm)) {
if (newobptr) *newobptr = o;
return B_TRUE; return B_TRUE;
} }
} else { } else {
if (o->pile == thrower->pack) { if (o->pile == thrower->pack) {
if (touch(thrower, o)) { if (touch(thrower, o)) {
if (newobptr) {
if (!isdeadob(o)) *newobptr = o;
}
return B_TRUE; return B_TRUE;
} }
} }
@ -12772,6 +12833,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
} }
} }
removeob(o, amt); removeob(o, amt);
if (newobptr) *newobptr = NULL;
return B_FALSE; return B_FALSE;
} }
@ -12783,6 +12845,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
} }
moveob(o, thrower->cell->obpile, amt); moveob(o, thrower->cell->obpile, amt);
if (newobptr) *newobptr = o;
return B_FALSE; return B_FALSE;
} }
} }
@ -13015,6 +13078,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
targetname, isplayer(target) ? "" : "es", obname); targetname, isplayer(target) ? "" : "es", obname);
} }
moveob(o, target->pack, amt); moveob(o, target->pack, amt);
if (newobptr) *newobptr = o;
return B_FALSE; return B_FALSE;
} else { } else {
int dam = 0; int dam = 0;
@ -13224,6 +13288,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
angergodmaybe(R_GODMAGIC, 10, GA_HERESY); angergodmaybe(R_GODMAGIC, 10, GA_HERESY);
} }
if (newobptr) *newobptr = newob;
return B_FALSE; return B_FALSE;
} }
@ -13345,20 +13410,20 @@ void timeeffectsob(object_t *o) {
newc = getrandomadjcell(location, WE_NOTWALL, B_ALLOWEXPAND); newc = getrandomadjcell(location, WE_NOTWALL, B_ALLOWEXPAND);
if (newc) { if (newc) {
//flag_t *inv; //flag_t *inv;
object_t *newob = NULL;
// make sure the object doesn't take damage // make sure the object doesn't take damage
//inv = addflag(o->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL); //inv = addflag(o->flags, F_INVULNERABLE, B_TRUE, NA, NA, NULL);
fireat(NULL, o, o->amt, newc, 1, NULL); real_fireat(NULL, o, o->amt, newc, 1, NULL, B_TRUE, OT_NONE, &newob);
if (canseeloc) { if (newob && canseeloc) {
// player now knows that this is blessed // player now knows that this is blessed
o->blessknown = B_TRUE; newob->blessknown = B_TRUE;
} }
// update location
//if (inv) killflag(inv); // no other effects for the object this turn.
// further effects on this object will come from its new location // (in case it died when thrown away)
location = newc; return;
} else { } else {
// object can't go anywhere - it disintegrates. // object can't go anywhere - it disintegrates.
if (owner && cansee(player, owner)) { if (owner && cansee(player, owner)) {
@ -13576,11 +13641,13 @@ void timeeffectsob(object_t *o) {
} }
} }
if (f->id == F_EXPLODEONDEATH) { if (f->id == F_EXPLODEONDEATH) {
if (o->pile->where && haslos(player, o->pile->where)) { if (hasflag(o->flags, F_OBHPDRAIN)) {
// pass a perception check to see it sparking... if (o->pile->where && haslos(player, o->pile->where)) {
if (skillcheck(player, SC_SEARCH, 15, 0)) { // pass a perception check to see it sparking...
msg("^w%s sparks.^n", obname); if (skillcheck(player, SC_SEARCH, 15, 0)) {
msg("^w%s sparks.^n", obname);
}
} }
} }
} }
@ -14571,6 +14638,10 @@ int validateobs(void) {
return goterror; return goterror;
} }
// note: we don't check for F_IMMUTABLE here because we don't
// want to (for example) give away the flag on a weapon if the
// player attacks a door/wall with it, and doesn't know that
// it's immutable yet.
int wepdullable(object_t *o) { int wepdullable(object_t *o) {
enum DAMTYPE dt; enum DAMTYPE dt;

View File

@ -104,6 +104,7 @@ brand_t *getrandombrandfor(objecttype_t *ot);
int getrandomgrimoirelev(void); int getrandomgrimoirelev(void);
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf); objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf);
enum OBTYPE getrandomtrapforob(void); enum OBTYPE getrandomtrapforob(void);
int getrustdampct(object_t *o);
int getfirearmrange(object_t *o); int getfirearmrange(object_t *o);
int getfirearmspeed(object_t *o); int getfirearmspeed(object_t *o);
glyph_t *getglyph(object_t *o); glyph_t *getglyph(object_t *o);
@ -280,7 +281,7 @@ object_t *splitob(object_t *o);
int takedamage(object_t *o, int howmuch, int damtype); int takedamage(object_t *o, int howmuch, int damtype);
int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce); int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce);
int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm); int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm);
int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm, int announcethrow, enum OBTYPE fromspell); int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, object_t *firearm, int announcethrow, enum OBTYPE fromspell, object_t **newobptr);
void timeeffectsob(object_t *o); void timeeffectsob(object_t *o);
int touch_battle_spoils(object_t *o); int touch_battle_spoils(object_t *o);
void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c); void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c);

221
spell.c
View File

@ -5618,6 +5618,22 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (ndigs == 0) { if (ndigs == 0) {
if (isplayer(caster)) nothinghappens(); if (isplayer(caster)) nothinghappens();
} }
} else if (spellid == OT_S_DISRUPTUNDEAD) {
target = targcell->lf;
if (!target || !isundead(target)) {
fizzle(caster);
return B_TRUE;
}
if (isplayer(target)) {
msg("You feel your body's essence unraveling!");
} else if (cansee(player, target)) {
char lfname[BUFLEN];
getlfname(target, lfname);
msg("%s convulses.", lfname);
}
// use direct damage rather than holy, because otherwise it might be increased
// due to vulnerabilities
losehp(target, roll("2d3"), DT_DIRECT, caster, "disruption");
} else if (spellid == OT_S_DISORIENT) { } else if (spellid == OT_S_DISORIENT) {
target = targcell->lf; target = targcell->lf;
@ -6856,8 +6872,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
takedamage(o, 1, DT_COLD); takedamage(o, 1, DT_COLD);
donesomething = B_TRUE; donesomething = B_TRUE;
} }
} else if (spellid == OT_S_GREASE) { } else if ((spellid == OT_S_GREASE) || (spellid == OT_S_CREATEWATER)) {
int radius; int radius;
char createname[BUFLEN];
if (targcell->type->solid) { if (targcell->type->solid) {
fizzle(caster); fizzle(caster);
return B_TRUE; return B_TRUE;
@ -6865,7 +6882,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
radius = power/2; radius = power/2;
if (radius < 1) radius = 1; if (radius < 1) radius = 1;
addobburst(targcell, radius, DT_ORTH, "puddle of oil", caster, LOF_WALLSTOP); switch (spellid) {
case OT_S_CREATEWATER:
strcpy(createname, "large puddle of water");
break;
case OT_S_GREASE:
strcpy(createname, "puddle of oil");
break;
default:
fizzle(caster);
return B_TRUE;
}
addobburst(targcell, radius, DT_ORTH, createname, caster, LOF_WALLSTOP);
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
char underbuf[BUFLEN]; char underbuf[BUFLEN];
@ -6876,7 +6905,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else { } else {
strcpy(underbuf, ""); strcpy(underbuf, "");
} }
msg("A %spool of oil appears%s!", (radius == 1) ? "" : "huge ", underbuf); msg("A %s%s appears%s!", (radius == 1) ? "" : "huge ", createname, underbuf);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
} else if (spellid == OT_S_HAILSTORM) { } else if (spellid == OT_S_HAILSTORM) {
@ -7890,42 +7919,14 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (targob->type->obclass->id == OC_POTION) { } else if (targob->type->obclass->id == OC_POTION) {
newcelltype = CT_WALLGLASS; newcelltype = CT_WALLGLASS;
} else { } else {
switch (targob->type->id) { flag_t *f;
case OT_ASH: newoid = OT_DUSTCLOUD; break; f = hasflag(targob->flags, F_GROWSTO);
case OT_ASHCONCEAL: newoid = OT_DUSTCLOUD; break; if (f) {
case OT_ASHEXPLODE: newoid = OT_DUSTCLOUD; break; if (f->val[1] == VT_OB) {
case OT_ASHSLEEP: newoid = OT_DUSTCLOUD; break; newoid = f->val[0];
case OT_BAGOFHOLDING: newoid = OT_BAGOFHOLDINGLARGE; break; } else { // ie. cell
case OT_BAGOFHOLDINGLARGE: newoid = OT_BAGOFHOLDINGHUGE; break; newcelltype = f->val[0];
case OT_BED: newoid = OT_DOORWOOD; break; }
case OT_BUCKLER: newoid = OT_SHIELD; break;
case OT_CLOVER: newoid = OT_SHRUB; break;
case OT_DOORIRON: newcelltype = CT_WALLMETAL; break;
case OT_DOORWOOD: newcelltype = CT_WALLWOOD; break;
case OT_FENCEWOOD: newcelltype = CT_WALLWOOD; break;
case OT_FIRESMALL: newoid = OT_FIREMED; break;
case OT_FIREMED: newoid = OT_FIRELARGE; break;
case OT_FIREPLACE: newoid = OT_FIRELARGE; break;
case OT_FLOWER: newoid = OT_SHRUB; break;
case OT_FOUNTAIN: newoid = OT_WATERDEEP; break;
case OT_GATEIRON: newcelltype = CT_WALLMETAL; break;
case OT_GATEWOOD: newcelltype = CT_WALLWOOD; break;
case OT_ICESHEET: newoid = OT_ICICLE; break;
case OT_LEAF: newoid = OT_SHRUB; break;
case OT_MISTLETOE: newoid = OT_SHRUB; break;
case OT_NUT: newoid = OT_TREE; break;
case OT_SACK: newoid = OT_SACKLARGE; break;
case OT_SACKLARGE: newoid = OT_SACKHUGE; break;
case OT_SHIELDHIDE: newoid = OT_SHIELD; break;
case OT_SHIELD: newoid = OT_SHIELDLARGE; break;
case OT_SHIELDLARGE: newoid = OT_SHIELDTOWER; break;
case OT_SHRUB: newoid = OT_TREE; break;
case OT_STUMP: newoid = OT_TREE; break;
case OT_TREE: newcelltype = CT_WALLTREE; break;
case OT_WOODENBARREL: newoid = OT_DOORWOOD; break;
case OT_WOODENSTOOL: newoid = OT_WOODENTABLE; break;
case OT_WOODENTABLE: newoid = OT_DOORWOOD; break;
default: break;
} }
} }
@ -7965,6 +7966,102 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else { } else {
if (seen) msg("%s shudders for a moment.", obname); if (seen) msg("%s shudders for a moment.", obname);
} }
} else if (spellid == OT_S_OBJECTSHRINK) {
enum OBTYPE newoid = OT_NONE;
char obtocreate[BUFLEN];
enum LFSIZE newsize = SZ_ANY;
enum CELLTYPE newcelltype = CT_NONE;
skill_t *obsk = SK_NONE;
char obname[BUFLEN],newobname[BUFLEN];
int seen;
if (targcell->obpile->first) {
targob = doaskobject(targcell->obpile, "Target which object", NULL, NULL, B_TRUE, B_FALSE, B_FALSE, '\0', NULL, MT_NOTHING, AO_NONE, F_NONE);
}
strcpy(obtocreate, "");
if (!targob) {
fizzle(caster);
return B_TRUE;
}
targcell = getoblocation(targob);
if (haslos(player, targcell)) {
seen = B_TRUE;
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
getobname(targob, obname, 1);
obsk = getobskill(targob->flags);
if (isweapon(targob) && (obsk->id == SK_LONGBLADES)) {
newoid = OT_DAGGER;
} else if (isweapon(targob) && (obsk->id == SK_SHORTBLADES)) {
newoid = OT_KNIFE;
} else if (isweapon(targob) && (obsk->id == SK_CLUBS)) {
newoid = OT_STICK;
} else if (isweapon(targob) && (obsk->id == SK_AXES)) {
newoid = OT_KNIFE;
} else if ((targob->type->obclass->id == OC_ARMOUR) &&
hasflag(targob->flags, F_MULTISIZE) &&
(getarmoursize(targob) > SZ_TINY)) {
newsize = getarmoursize(targob) - 1;
} else if (targob->type->obclass->id == OC_POTION) {
newoid = OT_BROKENGLASS;
} else {
flag_t *f;
f = hasflag(targob->flags, F_SHRINKSTO);
if (f) {
if (f->val[1] == VT_OB) {
if (strlen(f->text)) {
strcpy(obtocreate, f->text);
} else {
newoid = f->val[0];
}
} else { // ie. cell
newcelltype = f->val[0];
}
}
}
if (newsize != SZ_ANY) {
resizeobject(targob, newsize);
getobname(targob, newobname, 1);
getobname(targob, newobname, 1);
if (seen) msg("%s shrinks into %s!", obname, newobname);
} else if (newcelltype != CT_NONE) {
cell_t *where;
if (seen) {
celltype_t *ct;
ct = findcelltype(newcelltype);
msg("%s shrinks into %s %s!", obname, needan(ct->name) ? "an" : "a", ct->name);
}
where = getoblocation(targob);
killob(targob);
setcelltype(where, newcelltype);
} else if (newoid == targob->id) {
if (seen) msg("%s shudders for a moment.", obname);
} else if (strlen(obtocreate) || (newoid != OT_NONE)) {
obpile_t *op;
op = targob->pile;
killob(targob);
if (strlen(obtocreate)) {
targob = addob(op, obtocreate);
} else {
targob = addobfast(op, newoid);
}
if (targob) {
getobname(targob, newobname, 1);
if (seen) msg("%s shrinks into %s!", obname, newobname);
if (targob->type->id == OT_WATERDEEP) {
cell_t *where;
where = getoblocation(targob);
setcelltype(where, CT_LOWFLOOR); // lower floor so water doesn't spread
}
} else {
if (seen) msg("%s shudders then implodes!", obname);
}
} else {
if (seen) msg("%s shudders for a moment.", obname);
}
} else if ((spellid == OT_S_ACCELMETAL) || (spellid == OT_S_PROPELMISSILE)) { } else if ((spellid == OT_S_ACCELMETAL) || (spellid == OT_S_PROPELMISSILE)) {
char oidbuf[BUFLEN]; char oidbuf[BUFLEN];
char obname[BUFLEN]; char obname[BUFLEN];
@ -8016,7 +8113,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
killflagsofid(caster->flags, F_THROWING); killflagsofid(caster->flags, F_THROWING);
// 5 is the same as AT_VHIGH strength // 5 is the same as AT_VHIGH strength
real_fireat(caster, targob, 1, targcell, 5, NULL, B_TRUE, spellid); real_fireat(caster, targob, 1, targcell, 5, NULL, B_TRUE, spellid, NULL);
} else if (spellid == OT_S_TRAVEL) { } else if (spellid == OT_S_TRAVEL) {
regionthing_t *poss[MAXCANDIDATES],*rt; regionthing_t *poss[MAXCANDIDATES],*rt;
region_t *srcregion = NULL; region_t *srcregion = NULL;
@ -9178,6 +9275,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f = addtempflag(caster->flags, F_GRAVLESSENED, power, NA, NA, NULL, FROMSPELL); f = addtempflag(caster->flags, F_GRAVLESSENED, power, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid; f->obfrom = spellid;
} else if (spellid == OT_S_GUSTOFWIND) { } else if (spellid == OT_S_GUSTOFWIND) {
int pen = 0;
obpile_t *op; obpile_t *op;
object_t *o, *nexto; object_t *o, *nexto;
object_t *poss[MAXPILEOBS],*blowob[MAXPILEOBS]; object_t *poss[MAXPILEOBS],*blowob[MAXPILEOBS];
@ -9241,9 +9339,20 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} }
// easyish save to avoid falling // easyish save to avoid falling
if (target && !skillcheck(target, SC_FALL, 12 + (power*2), 0)) { switch (getlfsize(target)) {
case SZ_MEDIUM:
pen = -3; break;
case SZ_SMALL:
pen = -5; break;
case SZ_TINY:
pen = -7; break;
case SZ_MINI:
pen = -9; break;
break;
default: pen = 0; break;
}
if (target && !skillcheck(target, SC_FALL, 12 + (power*2), pen)) {
fall(target, NULL, B_TRUE); fall(target, NULL, B_TRUE);
} }
needredraw = B_TRUE; needredraw = B_TRUE;
@ -9305,6 +9414,18 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
strcpy(fullobname, ""); strcpy(fullobname, "");
} }
f = hasflag(o->flags, F_IMMUTABLE);
if (f) {
if (isplayer(caster)) {
char obname[BUFLEN];
real_getobname(o, obname, o->amt, B_PREMODS, B_NOCONDITION, B_BLINDADJUST, B_BLESSINGS, B_NOUSED, B_NOSHOWALL);
msg("For some reason, %s is unaffected!", fullobname);
}
f->known = B_TRUE;
return B_FALSE;
}
f = hasflag(o->flags, F_OBHP); f = hasflag(o->flags, F_OBHP);
if (f) { if (f) {
if (blessed == B_CURSED) { if (blessed == B_CURSED) {
@ -10238,6 +10359,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} else if (spellid == OT_S_SHATTER) { } else if (spellid == OT_S_SHATTER) {
char buf[BUFLEN]; char buf[BUFLEN];
if (targcell->lf && isplayer(targcell->lf)) {
msg("Ultra-sonic vibrations ring through your body!");
}
snprintf(buf, BUFLEN, "%s%s shatter spell", castername, getpossessive(castername)); snprintf(buf, BUFLEN, "%s%s shatter spell", castername, getpossessive(castername));
if (!shattercell(targcell, caster, buf)) { if (!shattercell(targcell, caster, buf)) {
fizzle(caster); fizzle(caster);
@ -10318,6 +10442,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE; return B_TRUE;
} }
if (isplayer(target)) {
msg("A sudden feeling of drowsiness washes over you!");
}
if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) { if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) {
// 1st skill check passed. make another one. // 1st skill check passed. make another one.
if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) { if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) {
@ -10691,7 +10820,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
sprintf(dambuf, "%dd3", power); sprintf(dambuf, "%dd3", power);
f->text = strdup(dambuf); f->text = strdup(dambuf);
} }
real_fireat(caster, o, 1, targcell, 6, NULL, B_FALSE, OT_S_SPIKEVOLLEY); real_fireat(caster, o, 1, targcell, 6, NULL, B_FALSE, OT_S_SPIKEVOLLEY, NULL);
} else if (spellid == OT_S_STENCH) { } else if (spellid == OT_S_STENCH) {
int howlong; int howlong;
@ -11302,7 +11431,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// otherwise throw it there - but speed is based on // otherwise throw it there - but speed is based on
// caster's INTELLIGENCE, not strength like normal. // caster's INTELLIGENCE, not strength like normal.
addflag(caster->flags, F_TKTHROW, A_IQ, SK_SS_MENTAL, NA, NULL); addflag(caster->flags, F_TKTHROW, A_IQ, SK_SS_MENTAL, NA, NULL);
real_fireat(caster, targob, targob->amt, targcell, power, NULL, B_TRUE, spellid); real_fireat(caster, targob, targob->amt, targcell, power, NULL, B_TRUE, spellid, NULL);
killflagsofid(caster->flags, F_TKTHROW); killflagsofid(caster->flags, F_TKTHROW);
// note that we use fireat() rather than throwat() to avoid // note that we use fireat() rather than throwat() to avoid
// calling taketime() twice. // calling taketime() twice.
@ -11857,7 +11986,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// weilded weapons/armour // weilded weapons/armour
for (o = targcell->lf->pack->first ; o ; o = nexto) { for (o = targcell->lf->pack->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
if (o->type->material->id == MT_WOOD) { if ((o->type->material->id == MT_WOOD) || (o->type->material->id == MT_DRAGONWOOD)) {
if (isequipped(o)) { if (isequipped(o)) {
int dam; int dam;
f = hasflag(o->flags, F_OBHP); f = hasflag(o->flags, F_OBHP);
@ -11879,7 +12008,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
for (o = targcell->obpile->first ; o ; o = nexto) { for (o = targcell->obpile->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
if (o->type->material->id == MT_WOOD) { if ((o->type->material->id == MT_WOOD) || (o->type->material->id == MT_DRAGONWOOD)) {
int dam; int dam;
f = hasflag(o->flags, F_OBHP); f = hasflag(o->flags, F_OBHP);
if (f) { if (f) {

11
text.c
View File

@ -914,6 +914,8 @@ char *getdirname(int dir) {
return "West"; return "West";
case DC_NW: case DC_NW:
return "Northwest"; return "Northwest";
case D_IN:
return "into";
} }
return "?errordir?"; return "?errordir?";
} }
@ -1407,6 +1409,9 @@ char *getregionname(char *buf, map_t *m, region_t *r, enum REGIONNAMEFORMAT how)
case RG_STOMACH: case RG_STOMACH:
snprintf(buf, BUFLEN, "a stomach"); snprintf(buf, BUFLEN, "a stomach");
break; break;
case RG_BABAYAGAHUT:
snprintf(buf, BUFLEN, "baba yaga's hut");
break;
} }
} else if ((how == RF_LONG) && m) { } else if ((how == RF_LONG) && m) {
switch (r->rtype->id) { switch (r->rtype->id) {
@ -1434,6 +1439,9 @@ char *getregionname(char *buf, map_t *m, region_t *r, enum REGIONNAMEFORMAT how)
case RG_STOMACH: case RG_STOMACH:
snprintf(buf, BUFLEN, "inside a worm's stomach"); // TODO: " in a stomach of of xxx" snprintf(buf, BUFLEN, "inside a worm's stomach"); // TODO: " in a stomach of of xxx"
break; break;
case RG_BABAYAGAHUT:
snprintf(buf, BUFLEN, "in baba yaga's hut");
break;
} }
} else { // ie. RF_SHORT } else { // ie. RF_SHORT
switch (r->rtype->id) { switch (r->rtype->id) {
@ -1461,6 +1469,9 @@ char *getregionname(char *buf, map_t *m, region_t *r, enum REGIONNAMEFORMAT how)
case RG_STOMACH: case RG_STOMACH:
snprintf(buf, BUFLEN, "a stomach"); snprintf(buf, BUFLEN, "a stomach");
break; break;
case RG_BABAYAGAHUT:
snprintf(buf, BUFLEN, "baba yaga's hut");
break;
} }
} }
return buf; return buf;

View File

@ -878,7 +878,10 @@ int handleline(vault_t *v, char *line) {
if (streq(command, "@id")) { if (streq(command, "@id")) {
if (!v->id) { if (!v->id) {
if (nargs == 1) { if (nargs == 1) {
if (findvault(arg[0])) { if (strchr(arg[0], ' ')) {
dblog("Vault names may not contain spaces: '%s'.", arg[0]);
return B_TRUE;
} else if (findvault(arg[0])) {
dblog("Duplicate vault id %s", arg[0]); dblog("Duplicate vault id %s", arg[0]);
return B_TRUE; return B_TRUE;
} }