- [+] increase damage for missiles

- [+] retain items on polymorph if new race has f_nopack or nobodypart
      for equipped stuff
    - [+] move obs to lf->polypack
    - [+] save this!
- [+] fix bugs with remembering/restoring stats on polyrevert.
- [+] scroll of permenance should make conferred attribute changes
      permenant
- [+] change strength damage mod to be range -2 to 2 (instead of a
      percentage)
- [+] corrected poison/methane gas difference.
- [+] hecta gift: necromancy books
- [+] damagecell()
    - [+] make rock walls turn to rubble ("50-100 stones")
- [+] change to lore skill: incrase damage by a fixed amount, not a
      percentage.
- [+] felix effect: evaulation (identify obs)
- [+] god piety should never change once thy are ignoring you.
- [+] shields should protect against crit hits
- [+] hecta no longer gives unholy water? 
- [+] I'm able to use OT_A_SHIELDBASH with 0 stamina.
- [+] CRASH during loading
    - [+] fixed
    - [+] ...but check for more....
- [+] quaff potion of fury - "you're too tired to do that right now"
- [+] player was being prompted for locaiton when monster tried to wear
      a bandage.
- [+] closing iron gates is making them opaque.
    - [+] only add blocksview if the objectTYPE has it.
- [+] fountains of experience not drying up.
- [+] looking for tracks on stairs.  never finding any!!
- [+] shop descriptions not working anymore.
- [+] left hand got destroyed by explosion.
    - [+] i then wore a ring... and it went on "left finger"!
- [+] all spell effects should cease just before death.
- [+] crystal shield/armour shouldn't call wear() but rather just set
      f_equipped directly.
- [+] bedrooms/kitchens should have tiled or carpet floors?
    - [+] tiled = less stability (especially with water!!)
    - [+] carpet = more stability
- [+] fire skeleton
- [+] firebug
- [+] ice wraith
- [+] winter wolf
- [+] skoob (snowman)
- [+] crymidia can cast crystal spells
- [+] blastbug
- [+] bilco - casts flood at itself.
- [+] rubber-like things
    - [+] slug
    - [+] snail
This commit is contained in:
Rob Pearce 2012-01-24 20:38:59 +00:00
parent 4a32308310
commit 5f4454d56a
20 changed files with 951 additions and 397 deletions

350
ai.c
View File

@ -394,178 +394,188 @@ object_t *aigetrangedattack(lifeform_t *lf, lifeform_t *target, enum RANGEATTACK
int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose) { int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim, lifeform_t **spelllf, cell_t **spellcell, object_t **spellob, enum FLAG purpose) {
int specialcase = B_FALSE; int specialcase = B_FALSE;
flag_t *f; flag_t *f;
enum SPELLTARGET spelltarg = ST_NONE;
// default - at victim. // default - at victim.
if (spelllf) *spelllf = victim; if (spelllf) *spelllf = victim;
if (spellcell) *spellcell = victim->cell; if (spellcell) *spellcell = victim->cell;
if (spellob) *spellob = NULL; if (spellob) *spellob = NULL;
f = hasflag(spelltype->flags, purpose); f = lfhasflagval(lf, F_AISPELLTARGETOVERRIDE, spelltype->id, NA, NA, NULL);
if (f) { if (f) {
switch (f->val[0]) { spelltarg = f->val[1];
case ST_VICTIM: } else {
// at victim. f = hasflag(spelltype->flags, purpose);
if (spelllf) *spelllf = victim; if (f) {
if (spellcell) *spellcell = victim->cell; spelltarg = f->val[0];
if (spellob) *spellob = NULL; }
break; }
case ST_ADJSELF: // cast at myself when next to victim
if (getcelldist(lf->cell, victim->cell) <= 1) { switch (spelltarg) {
if (spelllf) *spelllf = lf; case ST_VICTIM:
if (spellcell) *spellcell = lf->cell; // at victim.
if (spellob) *spellob = NULL; if (spelllf) *spelllf = victim;
} if (spellcell) *spellcell = victim->cell;
break; if (spellob) *spellob = NULL;
case ST_ADJVICTIM: // cast at victim when next to victim break;
if (getcelldist(lf->cell, victim->cell) <= 1) { case ST_ADJSELF: // cast at myself when next to victim
if (spelllf) *spelllf = victim; if (getcelldist(lf->cell, victim->cell) <= 1) {
if (spellcell) *spellcell = victim->cell;
if (spellob) *spellob = NULL;
}
break;
case ST_SELF:
if (spelllf) *spelllf = lf; if (spelllf) *spelllf = lf;
if (spellcell) *spellcell = lf->cell; if (spellcell) *spellcell = lf->cell;
if (spellob) *spellob = NULL; if (spellob) *spellob = NULL;
break; }
case ST_ANYWHERE: break;
if (spelllf) *spelllf = NULL; case ST_ADJVICTIM: // cast at victim when next to victim
if (spellcell) *spellcell = NULL; if (getcelldist(lf->cell, victim->cell) <= 1) {
if (spellob) *spellob = NULL;
break;
case ST_SPECIAL:
specialcase = B_TRUE;
break;
}
if (specialcase) {
if (spelltype->id == OT_A_CLIMB) {
int i,nposs = 0;
cell_t *poss[MAXCANDIDATES];
// cell in sight and adjacent? aispellok() should have already confirmed
// that there will be at least one of these.
for (i = 1; i < lf->nlos; i++) {
if (!lf->los[i]->lf && lf->los[i]->type->solid && (getcelldist(lf->cell, lf->los[i]) == 1)) {
poss[nposs++] = lf->los[i];
}
}
if (!nposs) {
if (spellcell) spellcell = NULL;
if (spelllf) *spelllf = NULL;
if (spellob) *spellob = NULL;
return B_TRUE;
}
if (spellcell) {
*spellcell = poss[rnd(0,nposs-1)];
}
if (spelllf) *spelllf = NULL;
if (spellob) *spellob = NULL;
} else if (spelltype->id == OT_A_JUMP) {
cell_t *cell[MAXCANDIDATES],*c;
cell_t *poss[MAXCANDIDATES];
int ncells,i,bestdist,nposs;
if (purpose == F_AICASTTOATTACK) {
bestdist = 99;
} else {
bestdist = -99;
}
getradiuscells(lf->cell, 2, DT_COMPASS, B_TRUE, LOF_WALLSTOP, B_FALSE, cell, &ncells, 0);
for (i = 0; i < ncells; i++) {
int disttovictim;
c = cell[i];
if (!cellwalkable(lf, c, NULL) || celldangerous(lf, c, B_TRUE, NULL)) {
continue;
}
disttovictim = getcelldist(victim->cell, c);
if (purpose == F_AICASTTOATTACK) {
// get closest cell to victim
if (disttovictim < bestdist) {
bestdist = disttovictim;
}
} else {
// get furthest cell from victim
if (disttovictim > bestdist) {
bestdist = disttovictim;
}
}
}
// now get all possible cells...
nposs = 0;
for (i = 0; i < ncells; i++) {
int disttovictim;
c = cell[i];
if (!cellwalkable(lf, c, NULL) || celldangerous(lf, c, B_TRUE, NULL)) {
continue;
}
disttovictim = getcelldist(victim->cell, c);
if (disttovictim == bestdist) {
poss[nposs++] = c;
}
}
// cast spell at one of the cells we found.
// we should ALWAYS have at least one cell, because aispellok()
// will check this.
if (spellcell) *spellcell = poss[rnd(0,nposs-1)];
} else if (spelltype->id == OT_S_DIG) {
cell_t *cell[MAXCANDIDATES],*poss[MAXCANDIDATES];
int ncells,i,nposs = 0;
getradiuscells(lf->cell, 1, DT_COMPASS, B_TRUE, LOF_DONTNEED, B_FALSE, cell, &ncells, 0);
for (i = 0; i < ncells; i++) {
if (cell[i]->type->solid &&
(cell[i]->type->material->id == MT_STONE) &&
getcelldist(cell[i], victim->cell) == 1) {
poss[nposs++] = cell[i];
break;
}
}
// aim at an adjacent wall cell
if (spellcell) *spellcell = poss[rnd(0,nposs-1)];
} else if (spelltype->id == OT_S_TELEKINESIS) {
float maxweight;
object_t *poss[MAXPILEOBS];
int nposs;
int i;
// find nearest object which can be picked up
// this is copied out of the telekenesis spell code!
maxweight = getlfweight(lf, B_NOOBS) +
(getlfweight(lf, B_NOOBS) * (getstatmod(lf, A_IQ) / 100));
nposs = 0;
for (i = 0; i < lf->nlos; i++) {
if (lf->los[i] != lf->cell) {
object_t *o;
for (o = lf->los[i]->obpile->first ; o ; o = o->next) {
if (!hasflag(o->flags, F_NOPICKUP) &&
getobweight(o) <= maxweight) {
poss[nposs] = o;
nposs++;
if (nposs >= MAXPILEOBS) break;
}
}
if (nposs >= MAXPILEOBS) break;
}
}
// should always be true since we check this in aispellok
if (nposs > 0) {
if (spellob) *spellob = poss[rnd(0,nposs-1)];
}
// cast spell at the victim
if (spelllf) *spelllf = victim; if (spelllf) *spelllf = victim;
if (spellcell) *spellcell = victim->cell; if (spellcell) *spellcell = victim->cell;
} else if (spelltype->id == OT_S_CHARM) { if (spellob) *spellob = NULL;
lifeform_t *l; }
l = getnearbypeaceful(lf); break;
if (l) { case ST_SELF:
if (spelllf) *spelllf = l; if (spelllf) *spelllf = lf;
if (spellcell) *spellcell = l->cell; if (spellcell) *spellcell = lf->cell;
if (spellob) *spellob = NULL; if (spellob) *spellob = NULL;
break;
case ST_ANYWHERE:
if (spelllf) *spelllf = NULL;
if (spellcell) *spellcell = NULL;
if (spellob) *spellob = NULL;
break;
case ST_SPECIAL:
specialcase = B_TRUE;
break;
case ST_NONE:
break;
}
if (specialcase) {
if (spelltype->id == OT_A_CLIMB) {
int i,nposs = 0;
cell_t *poss[MAXCANDIDATES];
// cell in sight and adjacent? aispellok() should have already confirmed
// that there will be at least one of these.
for (i = 1; i < lf->nlos; i++) {
if (!lf->los[i]->lf && lf->los[i]->type->solid && (getcelldist(lf->cell, lf->los[i]) == 1)) {
poss[nposs++] = lf->los[i];
} }
} }
if (!nposs) {
if (spellcell) spellcell = NULL;
if (spelllf) *spelllf = NULL;
if (spellob) *spellob = NULL;
return B_TRUE;
}
if (spellcell) {
*spellcell = poss[rnd(0,nposs-1)];
}
if (spelllf) *spelllf = NULL;
if (spellob) *spellob = NULL;
} else if (spelltype->id == OT_A_JUMP) {
cell_t *cell[MAXCANDIDATES],*c;
cell_t *poss[MAXCANDIDATES];
int ncells,i,bestdist,nposs;
if (purpose == F_AICASTTOATTACK) {
bestdist = 99;
} else {
bestdist = -99;
}
getradiuscells(lf->cell, 2, DT_COMPASS, B_TRUE, LOF_WALLSTOP, B_FALSE, cell, &ncells, 0);
for (i = 0; i < ncells; i++) {
int disttovictim;
c = cell[i];
if (!cellwalkable(lf, c, NULL) || celldangerous(lf, c, B_TRUE, NULL)) {
continue;
}
disttovictim = getcelldist(victim->cell, c);
if (purpose == F_AICASTTOATTACK) {
// get closest cell to victim
if (disttovictim < bestdist) {
bestdist = disttovictim;
}
} else {
// get furthest cell from victim
if (disttovictim > bestdist) {
bestdist = disttovictim;
}
}
}
// now get all possible cells...
nposs = 0;
for (i = 0; i < ncells; i++) {
int disttovictim;
c = cell[i];
if (!cellwalkable(lf, c, NULL) || celldangerous(lf, c, B_TRUE, NULL)) {
continue;
}
disttovictim = getcelldist(victim->cell, c);
if (disttovictim == bestdist) {
poss[nposs++] = c;
}
}
// cast spell at one of the cells we found.
// we should ALWAYS have at least one cell, because aispellok()
// will check this.
if (spellcell) *spellcell = poss[rnd(0,nposs-1)];
} else if (spelltype->id == OT_S_DIG) {
cell_t *cell[MAXCANDIDATES],*poss[MAXCANDIDATES];
int ncells,i,nposs = 0;
getradiuscells(lf->cell, 1, DT_COMPASS, B_TRUE, LOF_DONTNEED, B_FALSE, cell, &ncells, 0);
for (i = 0; i < ncells; i++) {
if (cell[i]->type->solid &&
(cell[i]->type->material->id == MT_STONE) &&
getcelldist(cell[i], victim->cell) == 1) {
poss[nposs++] = cell[i];
break;
}
}
// aim at an adjacent wall cell
if (spellcell) *spellcell = poss[rnd(0,nposs-1)];
} else if (spelltype->id == OT_S_TELEKINESIS) {
float maxweight;
object_t *poss[MAXPILEOBS];
int nposs;
int i;
// find nearest object which can be picked up
// this is copied out of the telekenesis spell code!
maxweight = getlfweight(lf, B_NOOBS) +
(getlfweight(lf, B_NOOBS) * (getstatmod(lf, A_IQ) / 100));
nposs = 0;
for (i = 0; i < lf->nlos; i++) {
if (lf->los[i] != lf->cell) {
object_t *o;
for (o = lf->los[i]->obpile->first ; o ; o = o->next) {
if (!hasflag(o->flags, F_NOPICKUP) &&
getobweight(o) <= maxweight) {
poss[nposs] = o;
nposs++;
if (nposs >= MAXPILEOBS) break;
}
}
if (nposs >= MAXPILEOBS) break;
}
}
// should always be true since we check this in aispellok
if (nposs > 0) {
if (spellob) *spellob = poss[rnd(0,nposs-1)];
}
// cast spell at the victim
if (spelllf) *spelllf = victim;
if (spellcell) *spellcell = victim->cell;
} else if (spelltype->id == OT_S_CHARM) {
lifeform_t *l;
l = getnearbypeaceful(lf);
if (l) {
if (spelllf) *spelllf = l;
if (spellcell) *spellcell = l->cell;
if (spellob) *spellob = NULL;
}
} }
} }
return B_FALSE; return B_FALSE;
@ -1962,14 +1972,24 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
char why[BUFLEN]; char why[BUFLEN];
if (reason == E_NOMP) { if (reason == E_NOMP) {
strcpy(why, "not enough mp"); strcpy(why, "not enough mp");
} else if (reason == E_CLIMBING) {
strcpy(why, "climbing");
} else if (reason == E_NOSTAM) { } else if (reason == E_NOSTAM) {
strcpy(why, "not enough stamina"); strcpy(why, "not enough stamina");
} else if (reason == E_LOWIQ) {
strcpy(why, "lowiq");
} else if (reason == E_PRONE) {
strcpy(why, "prone");
} else if (reason == E_SWIMMING) {
strcpy(why, "swimming");
} else if (reason == E_TOOPOWERFUL) { } else if (reason == E_TOOPOWERFUL) {
strcpy(why, "spell too powerful"); strcpy(why, "spell too powerful");
} else if (reason == E_NOTREADY) { } else if (reason == E_NOTREADY) {
strcpy(why, "abil not ready"); strcpy(why, "abil not ready");
} else if (reason == E_NEEDGRAB) { } else if (reason == E_NEEDGRAB) {
strcpy(why, "needs grab"); strcpy(why, "needs grab");
} else if (reason == E_INJURED) {
strcpy(why, "injured");
} else { } else {
strcpy(why, "unknown reason"); strcpy(why, "unknown reason");
} }
@ -2252,6 +2272,15 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
} }
if (ot->id == OT_S_ICECRUST) {
object_t *wep;
wep = getweapon(lf);
if (!wep) {
specificcheckok = B_FALSE;
} else if (hasflag(wep->flags, F_FROZEN)) {
specificcheckok = B_FALSE;
}
}
if ((ot->id == OT_S_INVISIBILITY) && lfhasflag(victim, F_INVISIBLE)) { if ((ot->id == OT_S_INVISIBILITY) && lfhasflag(victim, F_INVISIBLE)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
@ -2297,6 +2326,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
} }
if (ot->id == OT_S_SUMMONWEAPON) {
if (getweapon(lf)) {
specificcheckok = B_FALSE;
}
}
if ((ot->id == OT_A_SWOOP) || (ot->id == OT_A_CHARGE)) { if ((ot->id == OT_A_SWOOP) || (ot->id == OT_A_CHARGE)) {
cell_t *adjcell; cell_t *adjcell;
flag_t *willflag, *srflag; flag_t *willflag, *srflag;

View File

@ -781,7 +781,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (!willheal) { if (!willheal) {
enum SKILLLEVEL slev; enum SKILLLEVEL slev;
float loremult; float loreadd = 0;
// blessed vs undead // blessed vs undead
adjustdamforblessings(&(dam[0]), victim, wep->blessed); adjustdamforblessings(&(dam[0]), victim, wep->blessed);
@ -806,11 +806,11 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
// bonus for knowledge about the other lf's race? applied LAST. // bonus for knowledge about the other lf's race? applied LAST.
slev = getlorelevel(lf, victim->race->raceclass->id); slev = getlorelevel(lf, victim->race->raceclass->id);
if (slev == PR_INEPT) { if (slev == PR_INEPT) {
loremult = 1; loreadd = 0;
} else { } else {
loremult = 1 + (slev * 0.1); loreadd = slev;
} }
dam[0] = (int) ( (float)dam[0] * loremult ); dam[0] = (int) ( (float)dam[0] + loreadd );
} }
if (aidb) dblog(".oO { dealing %d %s damage }", dam[0], getdamname(damtype[0])); if (aidb) dblog(".oO { dealing %d %s damage }", dam[0], getdamname(damtype[0]));
@ -1293,7 +1293,7 @@ int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag) {
// modify for strength // modify for strength
if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) { if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
dam[ndam] = (int)((float)dam[ndam] * getstrdammod(lf)); dam[ndam] += getstrdammod(lf);
} }
// damtype? // damtype?
@ -1443,7 +1443,7 @@ int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag) {
// modify for strength // modify for strength
if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) { if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
dam[ndam] = (int)((float)dam[ndam] * getstrdammod(lf)); dam[ndam] += getstrdammod(lf);
} }
// damtype? // damtype?
@ -2044,35 +2044,21 @@ int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag) {
return dam; return dam;
} }
// returns a multiplier // returns amt of hp to modify damage by. (in range -3 to 3)
float getstrdammod(lifeform_t *lf) { int getstrdammod(lifeform_t *lf) {
float mod = 0; int mod = 0;
float base; int base;
// <9 = penalty
// 9,10,11,12 = average
// >12 = bonus
base = getattr(lf, A_STR); base = getattr(lf, A_STR);
if ((base >= 45) && (base <= 60)) { if ((base >= 45) && (base <= 60)) {
mod = 1; mod = 0;
} else if (base > 60) { } else if (base > 60) {
base -= 60; // ie. 0 - 40 base -= 60; // ie. 0 - 40
mod = 1 + (base / 12.0); // ie. up to 1.3 / +30% mod = base / 13;
} else { // ie. 0 through 44 } else { // ie. 0 through 44
// 0 = 0.1 base = 45 - base;
// 5 = 0.2 mod = base / 13;
// 10 = 0.3
// 15 = 0.4
// 20 = 0.5
// 25 = 0.6
// 30 = 0.7
// 35 = 0.8
// 40 = 0.9
mod = ((base/5) * 0.1); // ie. 10 -> 0.2 or 15 -> 0.3
mod += 0.1; // ie. 10 -> 0.3 or 15 -> 0.4
} }
return mod; return mod;
} }

View File

@ -24,7 +24,7 @@ void getdamrange(object_t *o, flag_t *f, int *min, int *max);
//float getdamreducepct(float armourrating); //float getdamreducepct(float armourrating);
int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag); int getdamroll(object_t *o, lifeform_t *victim, flag_t *damflag);
//int getunarmeddamroll(flag_t *f); //int getunarmeddamroll(flag_t *f);
float getstrdammod(lifeform_t *lf); int getstrdammod(lifeform_t *lf);
//obpile_t *getunarmedweapon(lifeform_t *lf, flag_t **uflag); //obpile_t *getunarmedweapon(lifeform_t *lf, flag_t **uflag);
int ismeleedam(enum DAMTYPE damtype); int ismeleedam(enum DAMTYPE damtype);
int isphysicaldam(enum DAMTYPE damtype); int isphysicaldam(enum DAMTYPE damtype);

300
data.c
View File

@ -686,15 +686,17 @@ void initjobs(void) {
addjob(J_ROGUE, "Rogue", "Rogues (sometimes known as \"thieves\") are criminals who are skilled in the appropriation of valuable goods. They can hide in the shadows, stab unsuspecting victims in the back and foil the most cunning traps."); addjob(J_ROGUE, "Rogue", "Rogues (sometimes known as \"thieves\") are criminals who are skilled in the appropriation of valuable goods. They can hide in the shadows, stab unsuspecting victims in the back and foil the most cunning traps.");
// stats // stats
addflag(lastjob->flags, F_JOBATTRMOD, A_STR, -15, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_STR, -10, NA, NULL);
addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 20, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 15, NA, NULL);
addflag(lastjob->flags, F_JOBATTRMOD, A_CON, -10, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_CON, -10, NA, NULL);
// initial objects // initial objects
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "dagger"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "dagger");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather cloak");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather armour");
addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5 lockpicks"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "5 lockpicks");
// initial skills // initial skills
addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_ATHLETICS, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_CLIMBING, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_CLIMBING, PR_BEGINNER, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_BEGINNER, NA, NULL);
@ -708,6 +710,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_STARTSKILL, SK_THROWING, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_THROWING, PR_NOVICE, NA, NULL);
addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_BEGINNER, NA, NULL);
// learnable skills // learnable skills
addflag(lastjob->flags, F_CANLEARN, SK_ARMOUR, PR_NOVICE, NA, NULL); // limit
addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, PR_SKILLED, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_CHANNELING, PR_SKILLED, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_COOKING, NA, NA, NULL);
addflag(lastjob->flags, F_CANLEARN, SK_PERCEPTION, PR_SKILLED, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_PERCEPTION, PR_SKILLED, NA, NULL);
@ -965,7 +968,7 @@ void initobjects(void) {
addobmod(OM_SHODDY,"shoddy"); addobmod(OM_SHODDY,"shoddy");
addflag_real(lastobmod->flags, F_SHODDY, B_TRUE, NA, NA, NULL, PERMENANT, B_KNOWN, -1); addflag_real(lastobmod->flags, F_SHODDY, B_TRUE, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
addobmod(OM_POISONED,"poisoned"); addobmod(OM_POISONED,"poisoned");
addflag_real(lastobmod->flags, F_HITCONFER, F_POISONED, SC_POISON, 30, "15-30", PERMENANT, B_KNOWN, -1); addflag_real(lastobmod->flags, F_HITCONFER, F_POISONED, SC_POISON, 40, "15-30", PERMENANT, B_KNOWN, -1);
addflag_real(lastobmod->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL, PERMENANT, B_KNOWN, -1); addflag_real(lastobmod->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL, PERMENANT, B_KNOWN, -1);
addobmod(OM_WET1,"damp"); addobmod(OM_WET1,"damp");
addflag_real(lastobmod->flags, F_WET, W_DAMP, NA, NA, NULL, PERMENANT, B_KNOWN, -1); addflag_real(lastobmod->flags, F_WET, W_DAMP, NA, NA, NULL, PERMENANT, B_KNOWN, -1);
@ -2851,7 +2854,7 @@ void initobjects(void) {
// elemental - fire // elemental - fire
/////////////////// ///////////////////
// l1 // l1
addot(OT_S_SPARK, "flambe", "Creates very hot but short lived burst of flame around the target, dealing 1-6 fire damage to creatures and objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SPARK, "flambe", "Creates very hot but short lived burst of flame around the target, dealing 2d2 fire damage to creatures and objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
@ -2960,6 +2963,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, 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_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
// l3 // l3
addot(OT_S_CRYSTALSHIELD, "crystalline shield", "Summons a shield of ice crystals to protect you from missiles.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_CRYSTALSHIELD, "crystalline shield", "Summons a shield of ice crystals to protect you from missiles.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how effective the shield is."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how effective the shield is.");
@ -2968,6 +2972,7 @@ void initobjects(void) {
addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 6, 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_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addot(OT_S_COLDRAY, "cold ray", "Shoots a blast of ice cold air, dealing 3d6 cold damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_COLDRAY, "cold ray", "Shoots a blast of ice cold air, dealing 3d6 cold damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how difficult the ray is to dodge."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how difficult the ray is to dodge.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
@ -3243,6 +3248,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_CASTINGTIME, 2, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
/////////////////// ///////////////////
// gravity // gravity
@ -3604,13 +3610,15 @@ void initobjects(void) {
addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 6, 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_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addot(OT_S_SUMMONWEAPON, "summon weapon", "Summons a blade of pure magic into your hands. Deals 1-^bpower^n damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SUMMONWEAPON, "summon weapon", "Summons a blade of pure magic into your hands.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines its Damage Rating.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_SUMMONING, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL);
addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_VARPOWER, B_TRUE, 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_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
// l2 // l2
addot(OT_S_CREATEFOOD, "sultan's feast", "Creates a meal in the target location.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_CREATEFOOD, "sultan's feast", "Creates a meal in the target location.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how much food is created."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how much food is created.");
@ -3764,6 +3772,14 @@ void initobjects(void) {
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the amount of charges restored."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the amount of charges restored.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
// l5
addot(OT_S_DETONATEDELAY, "delayed detonation", "Causes a given area to explode after a short delay.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l6 // l6
addot(OT_S_DETONATE, "detonate", "Causes a given area to explode with massive force.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_DETONATE, "detonate", "Causes a given area to explode with massive force.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the size of the explosion."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the size of the explosion.");
@ -3771,7 +3787,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_DOOR, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_DOOR, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// divine powers (spells/abilities) // divine powers (spells/abilities)
addot(OT_A_BLINDALL, "nosight", "Make everyone on the level blind.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addot(OT_A_BLINDALL, "nosight", "Make everyone on the level blind.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
@ -4810,6 +4826,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_WALKDAM, DT_WATER, NA, NA, "0d1+1"); //addflag(lastot->flags, F_WALKDAM, DT_WATER, NA, NA, "0d1+1");
addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, FALLTHRU, "0d1+1"); addflag(lastot->flags, F_WALKDAMBP, BP_FEET, DT_WATER, FALLTHRU, "0d1+1");
addflag(lastot->flags, F_SLIPPERY, 1, NA, NA, NULL);
addot(OT_PUDDLEWATERL, "large puddle of water", "A large pool of water.", MT_WATER, 20, OC_MISC, SZ_MEDIUM); addot(OT_PUDDLEWATERL, "large puddle of water", "A large pool of water.", 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);
@ -5143,7 +5160,6 @@ void initobjects(void) {
addflag(lastot->flags, F_WALKDAM, DT_HEAT, NA, NA, "1d1+1"); addflag(lastot->flags, F_WALKDAM, DT_HEAT, NA, NA, "1d1+1");
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addot(OT_SLEETSTORM, "storm of sleet", "An intense storm of sleet. Hampers movement", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addot(OT_SLEETSTORM, "storm of sleet", "An intense storm of sleet. Hampers movement", MT_GAS, 0, OC_EFFECT, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_CYAN, UNI_SHADEMED, NA, NULL); addflag(lastot->flags, F_GLYPH, C_CYAN, UNI_SHADEMED, NA, NULL);
addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL); addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL);
@ -5215,7 +5231,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
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_STENCH, B_TRUE, 1, NA, NULL); addflag(lastot->flags, F_WALKDAM, DT_POISONGAS, NA, NA, "1d2");
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addot(OT_METHANEPUFF, "puff of methane gas", "A small puff of foul-smelling gas.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM); addot(OT_METHANEPUFF, "puff of methane gas", "A small puff of foul-smelling gas.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM);
@ -5225,7 +5241,7 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
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_WALKDAM, DT_POISONGAS, NA, NA, "1d2"); addflag(lastot->flags, F_STENCH, B_TRUE, 1, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addot(OT_HAILSTORM, "hail storm", "An intense storm of damaging hail.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addot(OT_HAILSTORM, "hail storm", "An intense storm of damaging hail.", MT_GAS, 0, OC_EFFECT, SZ_LARGE);
@ -5264,6 +5280,17 @@ void initobjects(void) {
addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "vanishes"); addflag(lastot->flags, F_OBDIETEXT, B_TRUE, NA, NA, "vanishes");
addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 2, NA, NA, NULL);
addot(OT_VIBCLOUD, "vibrating cloud", "A cloud of unstable molecules.", MT_GAS, 0, OC_EFFECT, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_ORANGE, UNI_SHADEMED, NA, NULL);
addflag(lastot->flags, F_NODIECONVERTTEXT, NA, NA, NA, NULL);
addflag(lastot->flags, F_OBHP, 4, 4, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_EXPLODEONDEATH, NA, 2, NA, "8d2");
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addot(OT_VINE, "entangling vine", "A living vine which grasps nearby creature", MT_SILK, 0.1, OC_EFFECT, SZ_HUMAN); addot(OT_VINE, "entangling vine", "A living vine which grasps nearby creature", MT_SILK, 0.1, OC_EFFECT, SZ_HUMAN);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 82, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 82, RR_UNCOMMON, NULL);
@ -5693,6 +5720,7 @@ 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_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL);
killflagsofid(lastot->flags, F_ENCHANTABLE);
addot(OT_SPECTACLES, "pair of spectacles", "Eyewear with special lenses to enhance your vision.", MT_GLASS, 0.01, OC_ARMOUR, SZ_TINY); addot(OT_SPECTACLES, "pair of spectacles", "Eyewear with special lenses to enhance your vision.", MT_GLASS, 0.01, OC_ARMOUR, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL);
@ -5702,6 +5730,7 @@ void initobjects(void) {
addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, 1, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, 1, NA, NULL);
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL);
killflagsofid(lastot->flags, F_ENCHANTABLE);
addot(OT_SUNGLASSES, "pair of sunglasses", "Tinted eyewear to protect against sunlight.", MT_GLASS, 0.01, OC_ARMOUR, SZ_TINY); addot(OT_SUNGLASSES, "pair of sunglasses", "Tinted eyewear to protect against sunlight.", MT_GLASS, 0.01, OC_ARMOUR, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_COMMON, NULL);
@ -5713,6 +5742,7 @@ void initobjects(void) {
addflag(lastot->flags, F_TINTED, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_TINTED, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOQUALITY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 100, NA, NA, NULL);
killflagsofid(lastot->flags, F_ENCHANTABLE);
addot(OT_EYEPATCH, "eyepatch", "A small patch of black material which covers one eye. Scary looking.", MT_CLOTH, 0.01, OC_ARMOUR, SZ_TINY); addot(OT_EYEPATCH, "eyepatch", "A small patch of black material which covers one eye. Scary looking.", MT_CLOTH, 0.01, OC_ARMOUR, SZ_TINY);
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_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_FOREST, 100, RR_UNCOMMON, NULL);
@ -5721,6 +5751,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL); addflag(lastot->flags, F_SCARY, 2, NA, NA, NULL);
addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -2, NA, NULL); addflag(lastot->flags, F_EQUIPCONFER, F_VISRANGEMOD, -2, NA, NULL);
addflag(lastot->flags, F_CRITPROTECTION, 50, NA, NA, NULL); addflag(lastot->flags, F_CRITPROTECTION, 50, NA, NA, NULL);
killflagsofid(lastot->flags, F_ENCHANTABLE);
// armour - shields // armour - shields
addot(OT_BUCKLER, "buckler", "A small, unobtrusive wooden shield.", MT_WOOD, 3.00, OC_ARMOUR, SZ_SMALL); addot(OT_BUCKLER, "buckler", "A small, unobtrusive wooden shield.", MT_WOOD, 3.00, OC_ARMOUR, SZ_SMALL);
@ -5730,6 +5761,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
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);
// 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);
@ -5738,6 +5770,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
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);
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);
@ -5745,12 +5778,14 @@ void initobjects(void) {
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
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);
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);
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
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);
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);
@ -5758,6 +5793,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL); addflag(lastot->flags, F_GOESON, BP_SECWEAPON, NA, NA, NULL);
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);
// rings // rings
addot(OT_RING_EDUCATION, "ring of education", "Boosts earned XP and Skill points.", MT_METAL, 0.1, OC_RING, SZ_MINI); addot(OT_RING_EDUCATION, "ring of education", "Boosts earned XP and Skill points.", MT_METAL, 0.1, OC_RING, SZ_MINI);
@ -5990,6 +6026,7 @@ void initobjects(void) {
addot(OT_TENTACLE, "tentacle", "tentacle object", MT_FLESH, 0, OC_WEAPON, SZ_TINY); addot(OT_TENTACLE, "tentacle", "tentacle object", MT_FLESH, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_BASH, 10, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 10, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "slap");
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
@ -7285,6 +7322,9 @@ void initrace(void) {
addflag(lastrace->flags, F_MPMOD, -3, NA, NA, NULL); addflag(lastrace->flags, F_MPMOD, -3, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, "1d6"); addflag(lastrace->flags, F_DTVULN, DT_LIGHT, NA, NA, "1d6");
addflag(lastrace->flags, F_TAMABLE, 35, NA, NA, NULL); addflag(lastrace->flags, F_TAMABLE, 35, NA, NA, NULL);
// for ai:
addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_GEM, NA, NA, NULL);
addrace(R_ELF, "elf", 60, '@', C_GREEN, MT_FLESH, RC_HUMANOID, "Elves are slender, graceful beings around human-sized but far nimbler. They have high intelligence and magical affinity, but a lack of physical strength. Elves meditate instead of sleeping, thus maintaining basic awareness."); addrace(R_ELF, "elf", 60, '@', C_GREEN, MT_FLESH, RC_HUMANOID, "Elves are slender, graceful beings around human-sized but far nimbler. They have high intelligence and magical affinity, but a lack of physical strength. Elves meditate instead of sleeping, thus maintaining basic awareness.");
@ -8056,7 +8096,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "8d4"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4");
addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 9, NA, NA, NULL);
addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
@ -8554,11 +8594,11 @@ void initrace(void) {
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_LARGE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, NA, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, 60, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, 60, NA, NULL); addflag(lastrace->flags, F_RARITY, H_CAVE, 60, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, 66, NA, NULL); addflag(lastrace->flags, F_RARITY, H_FOREST, 66, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, 66, NA, NULL); addflag(lastrace->flags, F_RARITY, H_SWAMP, 66, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "7d4+0"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4+0");
addflag(lastrace->flags, F_EVASION, -5, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, -5, NA, NA, NULL);
addflag(lastrace->flags, F_ARMOURRATING, 11, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 11, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
@ -8686,6 +8726,37 @@ void initrace(void) {
addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DIURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
addrace(R_CRYMIDIA, "crymidia", 10, 'e', C_WHITE, MT_ICE, RC_MAGIC, "A floating crystalline form, a crymidia is formed when a mass of crystal becomes sentient.");
setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "10-20 chunks of ice");
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "chunk of ice");
addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_GTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4");
addflag(lastrace->flags, F_LEVITATING, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_S_LEVITATION, NA, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_S_LEVITATION, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_CANWILL, OT_S_SUMMONWEAPON, NA, NA, "pw:4;");
addflag(lastrace->flags, F_CANWILL, OT_S_ICECRUST, NA, NA, "pw:10;");
addflag(lastrace->flags, F_CANWILL, OT_S_CRYSTALARM, NA, NA, "pw:4;");
addflag(lastrace->flags, F_CANWILL, OT_S_CRYSTALSHIELD, NA, NA, "pw:4;");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "shimmers");
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_SS_COLD, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_SHIELDS, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
addflag(lastrace->flags, F_CASTCHANCE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addrace(R_PEGASUS, "pegasus", 130, 'Q', C_GREY, MT_FLESH, RC_MAGIC, "A legendary white, winged horse."); addrace(R_PEGASUS, "pegasus", 130, 'Q', C_GREY, MT_FLESH, RC_MAGIC, "A legendary white, winged horse.");
setbodytype(lastrace, BT_QUADRAPED); setbodytype(lastrace, BT_QUADRAPED);
addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_GOOD, NA, NA, NULL);
@ -8906,6 +8977,31 @@ void initrace(void) {
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_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL); addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL);
addrace(R_SKOOB, "skoob", 40, 'n', 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.");
setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "carrot");
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "puddle of water");
addflag(lastrace->flags, F_STARTATT, A_STR, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4");
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_CANWILL, OT_S_SNOWBALL, NA, NA, "pw:1;");
addflag(lastrace->flags, F_CANWILL, OT_S_SLIDE, NA, NA, "pw:10;");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "rubs its hands together");
addflag(lastrace->flags, F_HASATTACK, OT_TOUCHCHILL, 3, NA, NULL);
addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_SS_COLD, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
addflag(lastrace->flags, F_CASTCHANCE, 60, NA, NA, NULL);
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addrace(R_OOZEGREY, "sizzling slime", 10, 'j', C_GREEN, MT_SLIME, RC_SLIME, "Exactly what it sounds like - a small lump of green ooze. Green, acidic ooze."); addrace(R_OOZEGREY, "sizzling slime", 10, 'j', C_GREEN, MT_SLIME, RC_SLIME, "Exactly what it sounds like - a small lump of green ooze. Green, acidic ooze.");
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "puddle of slime"); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "puddle of slime");
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
@ -9007,7 +9103,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, UNLIMITED, NA, NA, NULL);
addrace(R_SPRITEICE, "ice sprite", 5, 'n', C_WHITE, MT_ICE, RC_MAGIC, "A small magical creature made from freezing ice."); addrace(R_SPRITEICE, "ice sprite", 5, 'n', C_CYAN, MT_ICE, RC_MAGIC, "A small magical creature made from freezing ice.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "sheet of ice"); addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "sheet of ice");
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "small puddle of water"); addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, "small puddle of water");
@ -9544,6 +9640,38 @@ void initrace(void) {
addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 14, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_BILCO, "bilco", 25, ';', C_BOLDCYAN, MT_FLESH, RC_ANIMAL, "Bilcos appear to be abnormally large frogs with a strange blue tinge. Seasoned travellers know to beware the bilco's gurgle, which portends them belching out a massive torrent of water.");
setbodytype(lastrace, BT_QUADRAPED);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_VULNTOSALT, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_AQUATIC, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SEWER, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4");
addflag(lastrace->flags, F_HASATTACK, OT_TONGUE, 3, NA, NULL);
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, SV_SHOUT, NA, "croaks^croaking");
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, SV_SHOUT, NA, "croaking^croaking");
addflag(lastrace->flags, F_NOISETEXT, N_SPELLCAST, SV_SHOUT, NA, "gurgles loudly^a loud gurgling");
addflag(lastrace->flags, F_CANWILL, OT_A_JUMP, NA, NA, "stamcost:0;");
addflag(lastrace->flags, F_CANWILL, OT_S_FLOOD, 20, 20, "pw:6;");
addflag(lastrace->flags, F_CANWILL, OT_S_WATERJET, NA, NA, "pw:4;");
addflag(lastrace->flags, F_STARTSKILL, SK_SWIMMING, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, NULL);
addflag(lastrace->flags, F_AISPELLTARGETOVERRIDE, OT_S_FLOOD, ST_SELF, NA, NULL);
addflag(lastrace->flags, F_WALKVERB, NA, NA, NA, "hop");
addrace(R_CHICKEN, "chicken", 0.5, 'c', C_BROWN, MT_FLESH, RC_ANIMAL, "A common farm-yard chicken."); addrace(R_CHICKEN, "chicken", 0.5, 'c', C_BROWN, MT_FLESH, RC_ANIMAL, "A common farm-yard chicken.");
setbodytype(lastrace, BT_BIRD); setbodytype(lastrace, BT_BIRD);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
@ -9694,10 +9822,11 @@ void initrace(void) {
addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOPACK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, 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_SEEINDARK, 3, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 6, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_TREMORSENSE, 10, NA, NA, NULL); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "croaks^croaking");
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "croaking^croaking");
addflag(lastrace->flags, F_CANWILL, OT_A_THRUST, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_THRUST, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_JUMP, NA, NA, "stamcost:0;"); addflag(lastrace->flags, F_CANWILL, OT_A_JUMP, NA, NA, "stamcost:0;");
addflag(lastrace->flags, F_CASTCHANCE, 100, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 100, NA, NA, NULL);
@ -10275,6 +10404,38 @@ void initrace(void) {
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL); addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL);
addrace(R_WOLFWINTER, "winter wolf", 25, 'd', C_CYAN, MT_FLESH, RC_ANIMAL, "Wolves which have lived in close proximity to the undead sometimes mutate into these frosty beasts. While their claws have become less sharp, they instead deal unnatural cold damage.");
setbodytype(lastrace, BT_QUADRAPED);
addbodypart(lastrace, BP_TAIL, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_VHIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_FAST, NA, NA, "");
addflag(lastrace->flags, F_ENHANCESMELL, 6, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "5d4+2");
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL);
addflag(lastrace->flags, F_EXTRADAM, DT_COLD, NA, NA, "1d6");
addflag(lastrace->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL);
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, 5, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SPRINT, NA, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_LOWHP, 2, NA, "whines in pain^whining");
addflag(lastrace->flags, F_NOISETEXT, N_FRUSTRATED, 3, NA, "growls^growling");
addflag(lastrace->flags, F_FLEEONHPPCT, 50, NA, NA, "");
addflag(lastrace->flags, F_HASSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL);
addflag(lastrace->flags, F_MORALE, 11, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_S_COLDRAY, 10, 10, "pw:2;");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "unleashes its icy breath");
addflag(lastrace->flags, F_CANINE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL);
addrace(R_WORMGLUT, "glutworm", 25, 'W', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Gigantic worms who swallow their prey whole, slowly digesting their still living bodies."); addrace(R_WORMGLUT, "glutworm", 25, 'W', C_MAGENTA, MT_FLESH, RC_ANIMAL, "Gigantic worms who swallow their prey whole, slowly digesting their still living bodies.");
addbodypart(lastrace, BP_HEAD, NULL); addbodypart(lastrace, BP_HEAD, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -10738,6 +10899,26 @@ void initrace(void) {
// end dragons // end dragons
// insects // insects
addrace(R_BLASTBUG, "blastbug", 2, 'x', C_ORANGE, MT_STONE, RC_INSECT, "Blastbugs have somehow evolved the ability to de-stabalise nearby oxygen molecules, resulting in devestation explosions.");
setbodytype(lastrace, BT_QUADRAPED);
addbodypart(lastrace, BP_TAIL, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_MEDIUM, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+0");
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, NA, NA, "100"); // massively strong to hold stones
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "snorts^a snort");
addflag(lastrace->flags, F_DTIMMUNE, DT_EXPLOSIVE, NA, NA, NULL);
addflag(lastrace->flags, F_CORPSEFLAG, F_EXPLODEONDEATH, NA, 2, "32d2");
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
addflag(lastrace->flags, F_WANTS, OT_STONE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_S_DETONATEDELAY, 20, 20, "pw:1;range:3;");
addflag(lastrace->flags, F_SPELLCASTTEXT, OT_NONE, NA, NA, "vibrates");
addrace(R_BUTTERFLY, "butterfly", 0.01, 'i', C_YELLOW, MT_FLESH, RC_ANIMAL, "A harmless, colourful butterfly."); addrace(R_BUTTERFLY, "butterfly", 0.01, 'i', C_YELLOW, MT_FLESH, RC_ANIMAL, "A harmless, colourful butterfly.");
setbodytype(lastrace, BT_BIRD); setbodytype(lastrace, BT_BIRD);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
@ -10870,6 +11051,21 @@ void initrace(void) {
addflag(lastrace->flags, F_TREMORSENSE, 3, NA, NA, NULL); addflag(lastrace->flags, F_TREMORSENSE, 3, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOFLEE, B_TRUE, NA, NA, NULL);
addrace(R_FIREBUG, "firebug", 2, 'x', C_RED, MT_FLESH, RC_INSECT, "Constantly burning insects which attack their victims with fire.");
setbodytype(lastrace, BT_QUADRAPED);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_SMALL, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4");
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_STARTATT, A_IQ, AT_LOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_LTAVERAGE, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TOUCHBURN, 3, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "flares its flames^crackling flames");
addflag(lastrace->flags, F_MORALE, 5, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
addrace(R_GLOWBUG, "glowbug", 1, 'i', C_WHITE, MT_FLESH, RC_INSECT, "Glowbugs are tiny flying creatures, magically producing light from their bodies."); addrace(R_GLOWBUG, "glowbug", 1, 'i', C_WHITE, MT_FLESH, RC_INSECT, "Glowbugs are tiny flying creatures, magically producing light from their bodies.");
setbodytype(lastrace, BT_BIRD); setbodytype(lastrace, BT_BIRD);
addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL);
@ -10984,6 +11180,7 @@ void initrace(void) {
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_HURRICANESTRIKE, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_HURRICANESTRIKE, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_S_BLINKASS, 3, 3, "pw:1;");
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 2, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 2, NA, NULL);
addflag(lastrace->flags, F_VAMPIRIC, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_VAMPIRIC, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, 10, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 10, NA, NA, NULL);
@ -11117,6 +11314,61 @@ void initrace(void) {
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addrace(R_SKELETONFIRE, "fire skeleton", 20, 'Z', C_RED, MT_BONE, RC_UNDEAD, "A walking set of flaming bones, imbued with the power of fire. They have all the advantages of normal skeletons but tend to burn victims with their flame rather than use weapons.");
setbodytype(lastrace, BT_HUMANOID);
setbodypartname(lastrace, BP_WEAPON, "right metacarpals");
setbodypartname(lastrace, BP_SECWEAPON, "left metacarpals");
setbodypartname(lastrace, BP_BODY, "ribs");
setbodypartname(lastrace, BP_HEAD, "skull");
setbodypartname(lastrace, BP_SHOULDERS, "scapulas");
setbodypartname(lastrace, BP_HANDS, "carpals");
setbodypartname(lastrace, BP_WAIST, "coccyx");
setbodypartname(lastrace, BP_LEGS, "fibulas");
setbodypartname(lastrace, BP_FEET, "tarsals");
setbodypartname(lastrace, BP_RIGHTFINGER, "right phalange");
setbodypartname(lastrace, BP_LEFTFINGER, "left phalange");
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL);
addflag(lastrace->flags, F_CORPSETYPE, NA, NA, NA, "5-20 flaming bones");
addflag(lastrace->flags, F_BLOODOB, NA, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "3d4");
addflag(lastrace->flags, F_EVASION, -10, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HASATTACK, OT_TOUCHBURN, 7, NA, NULL);
addflag(lastrace->flags, F_NOINJURIES, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_FALL, NA, NA, "1d3+3");
addflag(lastrace->flags, F_DTRESIST, DT_PIERCE, NA, NA, NULL);
addflag(lastrace->flags, F_HUMANOID, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addrace(R_WRAITHICE, "ice wraith", 20, 'Z', C_CYAN, MT_ICE, RC_UNDEAD, "Ice wraiths look like frozen humanoid forms, often garbed in threadbare clothing.");
setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_EVIL, NA, NA, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, NA, RR_COMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_FOREST, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_RARITY, H_SWAMP, NA, RR_UNCOMMON, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "4d4");
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_NORMAL, NA, NA, "");
addflag(lastrace->flags, F_HASATTACK, OT_TOUCHCHILL, 7, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "shoddy cloak");
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "scheeches^a screech");
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SPRINT, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addrace(R_GHAST, "ghast", 50, 'Z', C_MAGENTA, MT_FLESH, RC_UNDEAD, "A more slender and ghost-like form of ghoul. Ghasts are cunning and deadly, and possess a paralyzing touch."); addrace(R_GHAST, "ghast", 50, 'Z', C_MAGENTA, MT_FLESH, RC_UNDEAD, "A more slender and ghost-like form of ghoul. Ghasts are cunning and deadly, and possess a paralyzing touch.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
setbodypartname(lastrace, BP_HANDS, "claws"); setbodypartname(lastrace, BP_HANDS, "claws");
@ -11752,17 +12004,17 @@ void initskills(void) {
char buf[BUFLEN]; char buf[BUFLEN];
addskilldesc(sk->id, PR_INEPT, "At each skill level, more information about related creatures will be shown.", B_FALSE); addskilldesc(sk->id, PR_INEPT, "At each skill level, more information about related creatures will be shown.", B_FALSE);
addskilldesc(sk->id, PR_INEPT, "Each level also gives +10% damage and accuracy against related creatures.", B_FALSE); addskilldesc(sk->id, PR_INEPT, "Each level also gives +1 damage and +2 accuracy against related creatures.", B_FALSE);
snprintf(buf, BUFLEN, "^gYou now know basic information about %s.", rc->pluralname); snprintf(buf, BUFLEN, "^gYou now know basic information about %s.^n", rc->pluralname);
addskilldesc(sk->id, PR_NOVICE, buf, B_TRUE); addskilldesc(sk->id, PR_NOVICE, buf, B_TRUE);
snprintf(buf, BUFLEN, "^gYou can now determine how much damage %s will deal.", rc->pluralname); snprintf(buf, BUFLEN, "^gYou can now determine how much damage %s will deal.^n", rc->pluralname);
addskilldesc(sk->id, PR_BEGINNER, buf, B_TRUE); addskilldesc(sk->id, PR_BEGINNER, buf, B_TRUE);
snprintf(buf, BUFLEN, "^gYou can now determine how dangerous %s are.", rc->pluralname); snprintf(buf, BUFLEN, "^gYou can now determine how dangerous %s are.^n", rc->pluralname);
addskilldesc(sk->id, PR_ADEPT, buf, B_TRUE); addskilldesc(sk->id, PR_ADEPT, buf, B_TRUE);
snprintf(buf, BUFLEN, "^gYou can now anticipate how %s will react.", rc->pluralname); snprintf(buf, BUFLEN, "^gYou can now anticipate how %s will react.^n", rc->pluralname);
addskilldesc(sk->id, PR_SKILLED, buf, B_TRUE); addskilldesc(sk->id, PR_SKILLED, buf, B_TRUE);
snprintf(buf, BUFLEN, "^gYou now know everything there is to know about %s.", rc->pluralname); snprintf(buf, BUFLEN, "^gYou now know everything there is to know about %s.^n", rc->pluralname);
addskilldesc(sk->id, PR_MASTER, buf, B_TRUE); addskilldesc(sk->id, PR_MASTER, buf, B_TRUE);
} }
} }

Binary file not shown.

26
defs.h
View File

@ -708,8 +708,10 @@ enum CELLTYPE {
CT_VILLAGEGROUND, CT_VILLAGEGROUND,
CT_FAKE, CT_FAKE,
CT_FLOORFLESH, CT_FLOORFLESH,
CT_FLOORSHOP, CT_FLOORCARPET,
CT_FLOORWOOD, CT_FLOORSHOP,
CT_FLOORTILE,
CT_FLOORWOOD,
CT_GRASS, CT_GRASS,
CT_LOOPCORRIDOR, CT_LOOPCORRIDOR,
CT_LOWFLOOR, CT_LOWFLOOR,
@ -900,6 +902,7 @@ enum RACE {
R_BUGBEAR, R_BUGBEAR,
R_COCKATRICE, R_COCKATRICE,
R_CREEPINGCLAW, R_CREEPINGCLAW,
R_CRYMIDIA,
R_DARKMANTLE, R_DARKMANTLE,
R_EYEBAT, R_EYEBAT,
R_GIANTHILL, R_GIANTHILL,
@ -935,6 +938,7 @@ enum RACE {
R_SATYR, R_SATYR,
R_SHADOWCAT, R_SHADOWCAT,
R_SINKMITE, R_SINKMITE,
R_SKOOB,
R_SPRITEFIRE, R_SPRITEFIRE,
R_SPRITEGRAVE, R_SPRITEGRAVE,
R_SPRITEICE, R_SPRITEICE,
@ -967,6 +971,7 @@ enum RACE {
R_BEAR, R_BEAR,
R_BEARCUB, R_BEARCUB,
R_BEARGRIZZLY, R_BEARGRIZZLY,
R_BILCO,
R_CHICKEN, R_CHICKEN,
R_DOG, R_DOG,
R_DOGBLINK, R_DOGBLINK,
@ -993,8 +998,9 @@ enum RACE {
R_SPIDER, R_SPIDER,
R_SPIDERFUNNELWEB, R_SPIDERFUNNELWEB,
R_SPIDERREDBACK, R_SPIDERREDBACK,
R_WOLF,
R_WOLFYOUNG, R_WOLFYOUNG,
R_WOLF,
R_WOLFWINTER,
R_WORMGLUT, R_WORMGLUT,
// dragons // dragons
R_DRAGONBLUE, R_DRAGONBLUE,
@ -1007,8 +1013,10 @@ enum RACE {
R_DRAGONWHITEY, R_DRAGONWHITEY,
R_DRAGONWHITEA, R_DRAGONWHITEA,
// insects // insects
R_BLASTBUG,
R_BUTTERFLY, R_BUTTERFLY,
R_CENTIPEDE, R_CENTIPEDE,
R_FIREBUG,
R_GLOWBUG, R_GLOWBUG,
R_GIANTFLY, R_GIANTFLY,
R_GIANTBLOWFLY, R_GIANTBLOWFLY,
@ -1028,6 +1036,8 @@ enum RACE {
R_GHOST, R_GHOST,
R_GHOUL, R_GHOUL,
R_SKELETON, R_SKELETON,
R_SKELETONFIRE,
R_WRAITHICE,
R_ZOMBIE, R_ZOMBIE,
// special // special
R_DANCINGWEAPON, R_DANCINGWEAPON,
@ -1477,6 +1487,7 @@ enum OBTYPE {
OT_S_ALARM, OT_S_ALARM,
OT_S_MANASPIKE, OT_S_MANASPIKE,
OT_S_DETONATE, OT_S_DETONATE,
OT_S_DETONATEDELAY,
OT_S_ENERGYBOLT, OT_S_ENERGYBOLT,
OT_S_ENERGYBLAST, OT_S_ENERGYBLAST,
OT_S_FLASH, OT_S_FLASH,
@ -1677,6 +1688,7 @@ enum OBTYPE {
OT_METHANEPUFF, OT_METHANEPUFF,
OT_POISONCLOUD, OT_POISONCLOUD,
OT_POISONPUFF, OT_POISONPUFF,
OT_VIBCLOUD,
OT_VINE, OT_VINE,
OT_WEB, OT_WEB,
// armour - multipart // armour - multipart
@ -1956,6 +1968,7 @@ enum NOISETYPE {
N_FRUSTRATED, N_FRUSTRATED,
N_SONICBOLT, N_SONICBOLT,
N_WARCRY, N_WARCRY,
N_SPELLCAST,
}; };
enum LFSIZE { enum LFSIZE {
@ -2729,6 +2742,9 @@ enum FLAG {
// if v0 != OT_NONE, only use text for spellid v0 // if v0 != OT_NONE, only use text for spellid v0
// if v2 is 'appendyou' " at xxx" will // if v2 is 'appendyou' " at xxx" will
// be appended. // be appended.
F_AISPELLTARGETOVERRIDE, // when casting spellid v0, this lf will
// use v1 (ST_xxx) instead of what the AICASTTOxxx
// flag specifies.
F_NODEATHANNOUNCE, // don't say 'the xx dies' if this lf dies F_NODEATHANNOUNCE, // don't say 'the xx dies' if this lf dies
F_NODEATHSPEECH, // lf doesn't talk when dying F_NODEATHSPEECH, // lf doesn't talk when dying
F_BEHEADED, // use special corpse drop code F_BEHEADED, // use special corpse drop code
@ -3071,6 +3087,8 @@ enum FLAG {
// rest of the map. // rest of the map.
F_VAULTRANDOMMAP, // v0=minwidth, v1=minheight. this vault's map is F_VAULTRANDOMMAP, // v0=minwidth, v1=minheight. this vault's map is
// v0/1 can be NA. // v0/1 can be NA.
// OPTIONAL: v2 = floor cell type id
// OPTIONAL: text = wall cell type id (int)
// just a normal random room // just a normal random room
F_KEEPMARGIN, // this vault must be at least v0 from e/w of map F_KEEPMARGIN, // this vault must be at least v0 from e/w of map
// and at least v1 from n/s of map // and at least v1 from n/s of map
@ -3166,6 +3184,7 @@ enum LIGHTLEV {
// spell targets // spell targets
enum SPELLTARGET { enum SPELLTARGET {
ST_NONE = 0, // dont cast at all. for debugging.
ST_VICTIM, // cast at victim ST_VICTIM, // cast at victim
ST_ADJVICTIM, // cast at victim who is next to us ST_ADJVICTIM, // cast at victim who is next to us
ST_SELF, // cast at myself ST_SELF, // cast at myself
@ -3656,6 +3675,7 @@ typedef struct lifeform_s {
float forgettimer; float forgettimer;
struct obpile_s *pack; struct obpile_s *pack;
struct obpile_s *polypack; // for melded objects when polymorphed
struct flagpile_s *flags; struct flagpile_s *flags;

View File

@ -12,7 +12,7 @@ B = bat
c = cockatricoe c = cockatricoe
C = celestial / divine ? C = celestial / divine ?
d = canine/dog d = canine/dog
e = eye e = eye or floating thing
E = elemental ? E = elemental ?
f = feline/cat f = feline/cat
F = flora (flowers, plants, etc) F = flora (flowers, plants, etc)
@ -21,7 +21,6 @@ G = large goblin
h = humanoid h = humanoid
H = large humanoid H = large humanoid
i = insect i = insect
P = gastroPod
j = jelly/ooze/leech j = jelly/ooze/leech
k = kobold k = kobold
m = mutant m = mutant
@ -30,6 +29,7 @@ N = necron
o = orc o = orc
O = ogre O = ogre
p = sPirit p = sPirit
P = gastroPod
q = quadraped q = quadraped
Q = large quadraped Q = large quadraped
r = rodent r = rodent

94
god.c
View File

@ -616,12 +616,9 @@ int godgiftmaybe(enum RACE rid, int fromtemple) {
} }
break; break;
case 2: case 2:
snprintf(obtogive, BUFLEN, "3-5 cursed potions of water");
break;
case 3:
snprintf(obtogive, BUFLEN, "cursed branded weapon"); snprintf(obtogive, BUFLEN, "cursed branded weapon");
break; break;
case 4: // poison your weapon case 3: // poison your weapon
wep = getweapon(player); wep = getweapon(player);
if (wep && canbepoisoned(wep->type->id)) { if (wep && canbepoisoned(wep->type->id)) {
applyobmod(wep, findobmod(OM_POISONED)); applyobmod(wep, findobmod(OM_POISONED));
@ -630,7 +627,7 @@ int godgiftmaybe(enum RACE rid, int fromtemple) {
rollagain = B_TRUE; rollagain = B_TRUE;
} }
break; break;
case 5: // resistant/immune to necrotic case 4: // resistant/immune to necrotic
if (lfhasflagval(player, F_DTRESIST, DT_NECROTIC, NA, NA, NULL)) { if (lfhasflagval(player, F_DTRESIST, DT_NECROTIC, NA, NA, NULL)) {
if (lfhasflagval(player, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL)) { if (lfhasflagval(player, F_DTIMMUNE, DT_NECROTIC, NA, NA, NULL)) {
rollagain = B_TRUE; rollagain = B_TRUE;
@ -643,7 +640,7 @@ int godgiftmaybe(enum RACE rid, int fromtemple) {
f->obfrom = god->race->id; f->obfrom = god->race->id;
} }
break; break;
case 6: case 5: // become a vampire
if (player->race->id == R_VAMPIRE) { if (player->race->id == R_VAMPIRE) {
rollagain = B_TRUE; rollagain = B_TRUE;
} else { } else {
@ -651,6 +648,13 @@ int godgiftmaybe(enum RACE rid, int fromtemple) {
setrace(player, R_VAMPIRE, B_TRUE); // ie. don't set origrace! setrace(player, R_VAMPIRE, B_TRUE); // ie. don't set origrace!
} }
break; break;
case 6: // necromancy spells
if (!getskill(lf, SK_SS_DEATH)) {
giveskill(lf, SK_SS_DEATH);
} else {
snprintf(obtogive, BUFLEN, "spellbook of necromancy");
}
break;
} }
} }
break; break;
@ -793,7 +797,11 @@ void godsay(enum RACE rid, int says, char *format, ...) {
void modpiety(enum RACE rid, int amt) { void modpiety(enum RACE rid, int amt) {
lifeform_t *god; lifeform_t *god;
flag_t *f; flag_t *f;
god = findgod(rid); god = findgod(rid);
if (godblocked(god->race->id)) return;
f = lfhasflag(god, F_PIETY); f = lfhasflag(god, F_PIETY);
if (!f) return; if (!f) return;
f->val[0] += amt; f->val[0] += amt;
@ -1013,27 +1021,61 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE); dospelleffects(NULL, OT_S_DISPERSAL, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_FALSE);
} }
} else { } else {
int i,first = B_TRUE; int redo = B_TRUE;
msg("\"Allow me to reveal your surroundings...\""); object_t *possob[MAXPILEOBS];
dospelleffects(god, OT_S_MAPPING, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); int npossob,i,first;
dospelleffects(god, OT_S_REVEALHIDDEN, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE); while (redo) {
// unlock doors
for (i = 0; i < player->nlos; i++) { redo = B_FALSE;
cell_t *c;
object_t *o; switch (rnd(1,2)) {
c = player->los[i]; case 1:
if (c != player->cell) { msg("\"Allow me to reveal your surroundings...\"");
o = hascloseddoor(c); dospelleffects(god, OT_S_MAPPING, 5, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
if (o && hasflag(o->flags, F_LOCKED)) { dospelleffects(god, OT_S_REVEALHIDDEN, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
if (first) { // unlock doors
msg("\"Access granted!\""); first = B_TRUE;
first = B_FALSE; for (i = 0; i < player->nlos; i++) {
cell_t *c;
object_t *o;
c = player->los[i];
if (c != player->cell) {
o = hascloseddoor(c);
if (o && hasflag(o->flags, F_LOCKED)) {
if (first) {
msg("\"Access granted!\"");
first = B_FALSE;
}
killflagsofid(o->flags, F_LOCKED);
noise(c, NULL, NC_OTHER, SV_TALK, "the click of a lock.", NULL);
}
}
} }
killflagsofid(o->flags, F_LOCKED); break;
noise(c, NULL, NC_OTHER, SV_TALK, "the click of a lock.", NULL); case 2: // identify objects
} npossob = 0;
} for (o = lf->pack->first ; o ; o = o->next) {
} if (!isknown(o)) {
possob[npossob++] = o;
}
}
if (npossob) {
char oldname[BUFLEN],newname[BUFLEN];
o = possob[rnd(0,npossob-1)];
getobname(o,oldname,o->amt);
identify(o);
getobname(o,newname,o->amt);
msg("\"%s %s you are carrying %s %s!\"",
(o->amt == 1) ? "That" : "Those",
noprefix(oldname),
(o->amt == 1) ? "is" : "are",
newname);
} else {
redo = B_TRUE;
}
break;
} // end switch
}// end while redo
} }
break; break;
case R_GODMERCY: case R_GODMERCY:

32
io.c
View File

@ -6079,19 +6079,14 @@ char *makedesc_ob(object_t *o, char *retbuf) {
col = C_GREY; col = C_GREY;
} }
if (f->val[1] != NA) { if (f->val[1] != NA) {
sprintf(buf, "^%dIt requires at least %d %s to use%s.", col, f->val[1], getattrname(f->val[0]), sprintf(buf, "^%dIt requires at least %d %s to use%s.^n\n", col, f->val[1], getattrname(f->val[0]),
strlen(f->text) ? " effectively" : ""); strlen(f->text) ? " effectively" : "");
if (f->val[2] != NA) { strncat(retbuf, buf, HUGEBUFLEN);
char bbuf[BUFLEN];
sprintf(bbuf, " (bonus at %d)", f->val[2]);
strcat(buf, bbuf);
}
} }
if (f->val[2] != NA) { if (f->val[2] != NA) {
sprintf(buf, "^nIt can be used more effectively with at least %d %s.\n", f->val[2], getattrname(f->val[0])); sprintf(buf, "^nIt can be used more effectively with at least %d %s^n.\n", f->val[2], getattrname(f->val[0]));
strncat(retbuf, buf, HUGEBUFLEN);
} }
strcat(buf, "^n\n");
strncat(retbuf, buf, HUGEBUFLEN);
if (usable && isweapon(o)) { if (usable && isweapon(o)) {
if (pctmod > 0) { if (pctmod > 0) {
@ -7675,6 +7670,11 @@ int dothrow(obpile_t *op, object_t *o) {
// calculate throw range // calculate throw range
maxdist = getmaxthrowrange(player, o); maxdist = getmaxthrowrange(player, o);
if (maxdist < 1) {
msg("You are not strong enough to throw that.");
return B_TRUE;
}
// ask where to throw it // ask where to throw it
snprintf(buf2, BUFLEN, "Throw %s where?",buf); snprintf(buf2, BUFLEN, "Throw %s where?",buf);
snprintf(subprompt, BUFLEN, "%s->Throw->",buf); snprintf(subprompt, BUFLEN, "%s->Throw->",buf);
@ -10174,8 +10174,8 @@ void showlfstats(lifeform_t *lf, int showall) {
objecttype_t *ot; objecttype_t *ot;
int first; int first;
int i; int i;
float dammod; int dammod;
int accmod; //int accmod;
enum BODYPART bp; enum BODYPART bp;
enum BODYPART missingbp[MAXBODYPARTS]; enum BODYPART missingbp[MAXBODYPARTS];
int nmissingbp; int nmissingbp;
@ -10250,7 +10250,7 @@ void showlfstats(lifeform_t *lf, int showall) {
y2 = 2; y2 = 2;
dammod = getstrdammod(lf); dammod = getstrdammod(lf);
accmod = getstatmod(lf, A_AGI); //accmod = getstatmod(lf, A_AGI);
if (isplayer(lf)) { if (isplayer(lf)) {
getplayername(buf); getplayername(buf);
@ -10391,11 +10391,11 @@ void showlfstats(lifeform_t *lf, int showall) {
char buf2[BUFLEN]; char buf2[BUFLEN];
switch (i) { switch (i) {
case A_STR: case A_STR:
if (dammod > 1) { if (dammod >= 1) {
snprintf(buf2, BUFLEN, ", +%d%% dmg", (int)((dammod * 100) - 100) ); snprintf(buf2, BUFLEN, ", +%d dmg", dammod);
strcat(buf, buf2); strcat(buf, buf2);
} else if (dammod < 1) { } else if (dammod <= -1) {
snprintf(buf2, BUFLEN, ", -%d%% dmg", (int)(100 - (dammod * 100)) ); snprintf(buf2, BUFLEN, ", -%d dmg", abs(dammod));
strcat(buf, buf2); strcat(buf, buf2);
} }
break; break;

238
lf.c
View File

@ -544,8 +544,10 @@ int cancast(lifeform_t *lf, enum OBTYPE oid, int *mpcost) {
return B_FALSE; return B_FALSE;
} }
if (isswimming(lf) && (getskill(lf, SK_SWIMMING) < PR_EXPERT)) { if (isswimming(lf) && (getskill(lf, SK_SWIMMING) < PR_EXPERT)) {
reason = E_SWIMMING; if (!isaquatic(lf)) {
return B_FALSE; reason = E_SWIMMING;
return B_FALSE;
}
} }
if (isclimbing(lf)) { if (isclimbing(lf)) {
reason = E_CLIMBING; reason = E_CLIMBING;
@ -1678,6 +1680,8 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
} }
} }
// noise....
makenoise(lf, N_SPELLCAST);
// announce // announce
if (!isplayer(lf) && !fromob) { if (!isplayer(lf) && !fromob) {
@ -2387,6 +2391,8 @@ void die(lifeform_t *lf) {
castspell(lf, OT_S_FLASH, NULL, NULL, lf->cell, NULL, NULL); castspell(lf, OT_S_FLASH, NULL, NULL, lf->cell, NULL, NULL);
} }
loseconcentration(lf);
// revert to your original form first. // revert to your original form first.
if (lfhasflag(lf, F_POLYMORPHED)) { if (lfhasflag(lf, F_POLYMORPHED)) {
if (lfhasflag(lf, F_ORIGRACE)) { if (lfhasflag(lf, F_ORIGRACE)) {
@ -2644,6 +2650,12 @@ void die(lifeform_t *lf) {
if (copyflag(corpse->flags, lf->flags, F_REVIVETIMER)) { if (copyflag(corpse->flags, lf->flags, F_REVIVETIMER)) {
killflagsofid(corpse->flags, F_OBHPDRAIN); killflagsofid(corpse->flags, F_OBHPDRAIN);
} }
// special case
if (lf->race->id == R_BLASTBUG) {
flag_t *hpflag;
hpflag = hasflag(corpse->flags, F_OBHP);
if (hpflag) hpflag->val[0] = rnd(4,5);
}
// corpse of a player pet? // corpse of a player pet?
if (ispetof(lf, player)) { if (ispetof(lf, player)) {
@ -3474,10 +3486,14 @@ int eat(lifeform_t *lf, object_t *o) {
// blink! // blink!
dospelleffects(lf, OT_S_BLINK, 1, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE); dospelleffects(lf, OT_S_BLINK, 1, lf, NULL, NULL, B_UNCURSED, NULL, B_TRUE);
stopeating = B_TRUE;
} else if (hasflagval(o->flags, F_CORPSEOF, R_BLASTBUG, NA, NA, NULL)) {
dospelleffects(lf, OT_S_DETONATE, 10, lf, NULL, lf->cell, B_UNCURSED, NULL, B_TRUE);
stopeating = B_TRUE; stopeating = B_TRUE;
} }
// eating your pet is very bad! // eating your pet is very bad!
if (isplayer(lf) && hasflagval(o->flags, F_PETOF, player->id, NA, NA, NULL)) { if (isplayer(lf) && hasflagval(o->flags, F_PETOF, player->id, NA, NA, NULL)) {
angergodmaybe(R_GODPURITY, 150, GA_EAT); angergodmaybe(R_GODPURITY, 150, GA_EAT);
@ -4365,10 +4381,13 @@ int flee(lifeform_t *lf) {
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags; int nretflags;
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE; if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
real_getlfname(lf, lfname, B_FALSE, B_FALSE); real_getlfname(lf, lfname, B_FALSE, B_FALSE);
if (isdead(lf)) return B_FALSE;
// are we fleeing? // are we fleeing?
getflags(lf->flags, retflag, &nretflags, F_FLEEFROM, F_NONE); getflags(lf->flags, retflag, &nretflags, F_FLEEFROM, F_NONE);
@ -4397,7 +4416,7 @@ int flee(lifeform_t *lf) {
// player let something flee? // player let something flee?
if (isplayer(thisone)) { if (isplayer(thisone)) {
pleasegodmaybe(R_GODMERCY, 5); pleasegodmaybe(R_GODMERCY, 5);
angergodmaybe(R_GODDEATH, 25, GA_MERCY); angergodmaybe(R_GODDEATH, 15, GA_MERCY);
} }
killflag(f); killflag(f);
} else { } else {
@ -5513,8 +5532,8 @@ int getavgdam(lifeform_t *lf, int forxp) {
dammod = getstrdammod(lf); dammod = getstrdammod(lf);
// apply damage mod for strength // apply damage mod for strength
if (!hasflag(w->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) { if (!hasflag(w->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
mindam = (int)((float)mindam * dammod); mindam += dammod;
maxdam = (int)((float)maxdam * dammod); maxdam += dammod;
} }
if (mindam < 0) mindam = 0; if (mindam < 0) mindam = 0;
@ -9841,12 +9860,19 @@ int injure(lifeform_t *lf, enum BODYPART where, enum DAMTYPE damtype) {
if (hasbp(lf, bp2)) { if (hasbp(lf, bp2)) {
object_t *o[2]; object_t *o[2];
char buf[BUFLEN]; char buf[BUFLEN];
enum BODYPART fingerbp;
int i; int i;
// drop anyting in that hand // drop anyting in that hand
o[0] = getequippedob(lf->pack, bp2); o[0] = getequippedob(lf->pack, bp2);
if (bp2 == BP_WEAPON) o[1] = getequippedob(lf->pack, BP_RIGHTFINGER); if (bp2 == BP_WEAPON) {
else o[1] = getequippedob(lf->pack, BP_LEFTFINGER); 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, bp2, B_FROMINJURY, NA, NULL);
addflag(lf->flags, F_NOBODYPART, fingerbp, B_FROMINJURY, NA, NULL);
inj = IJ_HANDMISSING; inj = IJ_HANDMISSING;
sprintf(buf, "%s is destroyed^cannot use this hand", getbodypartname(lf, bp2)); sprintf(buf, "%s is destroyed^cannot use this hand", getbodypartname(lf, bp2));
desc = strdup(buf); desc = strdup(buf);
@ -10720,9 +10746,14 @@ void killlf(lifeform_t *lf) {
while (lf->pack->first) { while (lf->pack->first) {
killob(lf->pack->first); killob(lf->pack->first);
} }
// kill object pile
free(lf->pack); free(lf->pack);
lf->pack = NULL; lf->pack = NULL;
// kill any remaining obs
while (lf->polypack->first) {
killob(lf->polypack->first);
}
free(lf->polypack);
lf->polypack = NULL;
// kill flags // kill flags
killflagpile(lf->flags); killflagpile(lf->flags);
@ -11269,6 +11300,7 @@ lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller) {
a->created = B_FALSE; a->created = B_FALSE;
a->pack = addobpile(a, NOLOC, NOOB); a->pack = addobpile(a, NOLOC, NOOB);
a->polypack = addobpile(a, NOLOC, NOOB);
a->turnsskipped = 0; a->turnsskipped = 0;
@ -11786,7 +11818,7 @@ void applylfdammod(int *dam, lifeform_t *lf, object_t *wep) {
enum SKILLLEVEL slev; enum SKILLLEVEL slev;
// modify for strength // modify for strength
if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) { if (!hasflag(wep->flags, F_NOSTRDAMMOD) && !lfhasflag(lf, F_NOSTRDAMMOD)) {
*dam = (int)((float)*dam * getstrdammod(lf)); *dam = *dam + getstrdammod(lf);
} }
// strength scaling on weapon // strength scaling on weapon
@ -12862,8 +12894,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
// cold: dam*10 chance of shattering potions, or damaging other things. // cold: dam*10 chance of shattering potions, or damaging other things.
for (o = lf->pack->first ; o ; o = nexto) { for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
//if (isvulnto(o->flags, DT_COLD) && pctchance(amt*10)) { if (isvulnto(o->flags, DT_COLD, B_FALSE) && pctchance(amt*10)) {
if (isvulnto(o->flags, DT_COLD, B_FALSE)) {
int newdam; int newdam;
// object takes 1/4 of damage // object takes 1/4 of damage
newdam = pctof(25, amt); newdam = pctof(25, amt);
@ -15317,7 +15348,9 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
race_t *newrace; race_t *newrace;
char buf[BUFLEN]; char buf[BUFLEN];
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
race_t *origrace = NULL;
int nretflags; int nretflags;
int reverting = B_FALSE;
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
newrace = findrace(rid); newrace = findrace(rid);
@ -15332,20 +15365,23 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
loseconcentration(lf); loseconcentration(lf);
// were we already polymorphed?
f = lfhasflag(lf, F_ORIGRACE);
if (f) {
origrace = findrace(f->val[0]);
}
if (origrace && (newrace == origrace)) {
reverting = B_TRUE;
}
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
if (frompolymorph && (gamemode == GM_GAMESTARTED) && lf->race) { if (frompolymorph && (gamemode == GM_GAMESTARTED) && lf->race) {
race_t *origrace = NULL;
// remove 'become a ghost' flag // remove 'become a ghost' flag
killflagsofid(lf->flags, F_RISEASGHOST); killflagsofid(lf->flags, F_RISEASGHOST);
// were we already polymorphed?
f = lfhasflag(lf, F_ORIGRACE);
if (f) {
origrace = findrace(f->val[0]);
}
// announce // announce
if (origrace && (newrace == origrace)) { if (reverting) {
// reverting to original form.... // reverting to original form....
if (!isdead(lf)) { if (!isdead(lf)) {
if (isplayer(lf)) { if (isplayer(lf)) {
@ -15370,12 +15406,6 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
killflagsofid(lf->flags, F_ORIGRACE); killflagsofid(lf->flags, F_ORIGRACE);
killflagsofid(lf->flags, F_POLYMORPHED); killflagsofid(lf->flags, F_POLYMORPHED);
// restore stats
for (i = 0; i < MAXATTS; i++) {
lf->att[i] = lf->origatt[i];
lf->baseatt[i] = lf->origatt[i];
if (isplayer(lf)) statdirty = B_TRUE;
}
} else { } else {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^wYou transform into %s %s!", isvowel(newrace->name[0]) ? "an" : "a", newrace->name); msg("^wYou transform into %s %s!", isvowel(newrace->name[0]) ? "an" : "a", newrace->name);
@ -15450,12 +15480,28 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
} }
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
// generate stats if (reverting) {
for (i = 0; i < MAXATTS; i++) { // restore stats - note that your "base" attrib score
rollstat(lf, i); // is set to your original one here.
lf->baseatt[i] = lf->att[i]; for (i = 0; i < MAXATTS; i++) {
lf->att[i] = lf->origatt[i];
lf->baseatt[i] = lf->origatt[i];
}
if (isplayer(lf)) statdirty = B_TRUE;
} else {
// remember original atts
for (i = 0; i < MAXATTS; i++) {
lf->origatt[i] = lf->att[i];
}
// generate new stats
for (i = 0; i < MAXATTS; i++) {
rollstat(lf, i);
lf->baseatt[i] = lf->att[i];
}
} }
if (!retainhp) { if (!retainhp) {
// generate hp/maxhp from hit dice // generate hp/maxhp from hit dice
lf->maxhp = 0; lf->maxhp = 0;
@ -15488,6 +15534,8 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
lf->born = B_TRUE; lf->born = B_TRUE;
setlosdirty(lf);
// check whether: // check whether:
// new race can equip things (F_NOBODYPART xx) // new race can equip things (F_NOBODYPART xx)
// new race can hold objects (F_NOPACK xx) // new race can hold objects (F_NOPACK xx)
@ -15500,19 +15548,36 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
// no pack? // no pack?
if (lfhasflag(lf, F_NOPACK)) { if (lfhasflag(lf, F_NOPACK)) {
// drop everything if (reverting) {
if (countobs(lf->pack, B_FALSE)) { // drop everything
if (isplayer(lf)) { if (countobs(lf->pack, B_FALSE)) {
msg("Your possessions drop to the ground!"); if (isplayer(lf)) {
} else if (cansee(player, lf)) { msg("Your possessions drop to the ground!");
getlfname(lf, buf); } else if (cansee(player, lf)) {
msg("%s%s possessions drop to the ground!",buf, getpossessive(buf)); getlfname(lf, buf);
msg("%s%s possessions drop to the ground!",buf, getpossessive(buf));
}
}
for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next;
moveob(o, lf->cell->obpile, o->amt);
}
} else {
// meld
if (countobs(lf->pack, B_FALSE)) {
if (isplayer(lf)) {
msg("Your possessions meld into your new form!");
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s possessions meld into its new form!",buf, getpossessive(buf));
}
}
for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next;
moveob(o, lf->polypack, o->amt);
} }
}
for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next;
moveob(o, lf->cell->obpile, o->amt);
} }
} }
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
@ -15521,6 +15586,41 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
if (!hasbp(lf, bp)) { if (!hasbp(lf, bp)) {
o = getequippedob(lf->pack, bp); o = getequippedob(lf->pack, bp);
if (o) { if (o) {
if (reverting) {
char obname[BUFLEN];
getobname(o, obname, o->amt);
// drop it!
if (isplayer(lf)) {
msg("Your %s drops to the ground!",noprefix(obname));
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s %s drop to the ground!",buf, getpossessive(buf),
noprefix(obname));
}
moveob(o, lf->cell->obpile, o->amt);
} else {
char obname[BUFLEN];
getobname(o, obname, o->amt);
// drop it!
if (isplayer(lf)) {
msg("Your %s melds into your new form!",noprefix(obname));
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s %s melds into its new form!",buf, getpossessive(buf),
noprefix(obname));
}
moveob(o, lf->polypack, o->amt);
}
}
}
}
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next;
if (!canpickup(lf, o, o->amt)) {
if (reverting) {
char obname[BUFLEN]; char obname[BUFLEN];
getobname(o, obname, o->amt); getobname(o, obname, o->amt);
// drop it! // drop it!
@ -15532,28 +15632,20 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
noprefix(obname)); noprefix(obname));
} }
moveob(o, lf->cell->obpile, o->amt); moveob(o, lf->cell->obpile, o->amt);
} else {
char obname[BUFLEN];
getobname(o, obname, o->amt);
if (isplayer(lf)) {
msg("Your %s melds into your new form!",noprefix(obname));
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s %s melds into its new form!",buf, getpossessive(buf),
noprefix(obname));
}
moveob(o, lf->polypack, o->amt);
} }
} }
} }
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
for (o = lf->pack->first ; o ; o = nexto) {
nexto = o->next;
if (!canpickup(lf, o, o->amt)) {
char obname[BUFLEN];
getobname(o, obname, o->amt);
// drop it!
if (isplayer(lf)) {
msg("Your %s drops to the ground!",noprefix(obname));
} else if (cansee(player, lf)) {
getlfname(lf, buf);
msg("%s%s %s drop to the ground!",buf, getpossessive(buf),
noprefix(obname));
}
moveob(o, lf->cell->obpile, o->amt);
}
}
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
@ -15566,6 +15658,16 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
} // end if gamestarted } // end if gamestarted
if (reverting) {
// restore objects
while (lf->polypack->first) {
moveob(lf->polypack->first, lf->pack, lf->polypack->first->amt);
}
// in case something which affects our vision came out of ->polypack
setlosdirty(lf);
}
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
} }
@ -19013,13 +19115,17 @@ int wear(lifeform_t *lf, object_t *o) {
if (isplayer(lf)) msg("You have nowhere to wear that!"); if (isplayer(lf)) msg("You have nowhere to wear that!");
return B_TRUE; return B_TRUE;
} }
ch = getchoice(&prompt); if (isplayer(lf)) {
ch = getchoice(&prompt);
if (ch == '-') { if (ch == '-') {
bp = BP_NONE; bp = BP_NONE;
if (isplayer(lf)) msg("Cancelled."); if (isplayer(lf)) msg("Cancelled.");
return B_TRUE; return B_TRUE;
} else bp = *((enum BODYPART *)prompt.result); } else bp = *((enum BODYPART *)prompt.result);
} else {
bp = *((enum BODYPART *)prompt.choice[rnd(0,prompt.nchoices - 1)].data);
}
possbp[0] = bp; possbp[0] = bp;
nparts = 1; nparts = 1;

42
map.c
View File

@ -1212,6 +1212,14 @@ int damagecell(cell_t *c, int amt, enum DAMTYPE damtype) {
if (getshardobname(cellmat, what)) { if (getshardobname(cellmat, what)) {
fragments(c, what, 3, 3); fragments(c, what, 3, 3);
} }
} else {
switch (cellmat) {
case MT_STONE:
addob(c->obpile, "50-100 stones");
break;
default:
break;
}
} }
} }
return B_FALSE; return B_FALSE;
@ -5822,18 +5830,28 @@ int getslipperyness(cell_t *c, object_t **slipob) {
object_t *o,*bestob = NULL; object_t *o,*bestob = NULL;
int bestslip = 0; int bestslip = 0;
int totalslip = 0; int totalslip = 0;
int addition = 0;
if (slipob) *slipob = NULL; if (slipob) *slipob = NULL;
switch (c->type->id) {
case CT_FLOORTILE: addition = 2; break;
case CT_FLOORCARPET: addition = -2; break;
default: addition = 0; break;
}
for (o = c->obpile->first ; o ; o = o->next) { for (o = c->obpile->first ; o ; o = o->next) {
int thisslip; int thisslip;
sumflags(o->flags, F_SLIPPERY, &thisslip, NULL, NULL); sumflags(o->flags, F_SLIPPERY, &thisslip, NULL, NULL);
thisslip += addition;
limit(&thisslip, 0, NA);
if (thisslip > 0) { if (thisslip > 0) {
if (thisslip > bestslip) { if (thisslip > bestslip) {
bestob = o; bestob = o;
bestslip = thisslip; bestslip = thisslip;
} }
thisslip *= o->amt;
totalslip += thisslip;
} }
thisslip *= o->amt;
totalslip += thisslip;
} }
totalslip *= 2; totalslip *= 2;
@ -6009,28 +6027,32 @@ void initmap(void) {
addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 3, 50, 0, MAXVISRANGE); addhabitat(H_SWAMP, "swamp", CT_CORRIDOR, CT_WALL, 3, 50, 0, MAXVISRANGE);
// cell types - solid // cell types - solid
addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, B_SOLID, B_OPAQUE, MT_STONE, 0, 100); addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, B_SOLID, B_OPAQUE, MT_STONE, 0, 50);
addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEDARK, C_BROWN, B_SOLID, B_OPAQUE, MT_STONE, 0, 50); addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEDARK, C_BROWN, B_SOLID, B_OPAQUE, MT_STONE, 0, 25);
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 0, 50); addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, B_SOLID, B_OPAQUE, MT_WOOD, 0, 40);
addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, B_SOLID, B_OPAQUE, MT_FLESH, 0, 50); addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, B_SOLID, B_OPAQUE, MT_FLESH, 0, 30);
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0, 25); addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, B_SOLID, B_TRANS, MT_GLASS, 0, 20);
addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, B_SOLID, B_OPAQUE, MT_METAL, 0, 200); addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, B_SOLID, B_OPAQUE, MT_METAL, 0, 75);
// cell types - non-solid // cell types - non-solid
addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, B_EMPTY, B_TRANS, MT_STONE, 0, -1); addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
addcelltype(CT_CORRIDOR, "rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, 0, -1); addcelltype(CT_CORRIDOR, "rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
addcelltype(CT_LOOPCORRIDOR, "rock floor", 'L', C_GREY, B_EMPTY, B_TRANS, MT_STONE, 0, -1); addcelltype(CT_LOOPCORRIDOR, "rock floor", 'L', C_GREY, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
addcelltype(CT_FLOORCARPET, "carpetted floor", '.', C_YELLOW, B_EMPTY, B_TRANS, MT_CLOTH, 0, -1);
addcelltype(CT_FLOORWOOD, "wood floor", '.', C_BROWN, B_EMPTY, B_TRANS, MT_WOOD, 0, -1); addcelltype(CT_FLOORWOOD, "wood floor", '.', C_BROWN, B_EMPTY, B_TRANS, MT_WOOD, 0, -1);
addcelltype(CT_FLOORFLESH, "flesh floor", '.', C_RED, B_EMPTY, B_TRANS, MT_FLESH, 0, -1); addcelltype(CT_FLOORFLESH, "flesh floor", '.', C_RED, B_EMPTY, B_TRANS, MT_FLESH, 0, -1);
addcelltype(CT_FLOORSHOP, "shop floor", '.', C_BROWN, B_EMPTY, B_TRANS, MT_WOOD, 0, -1); addcelltype(CT_FLOORSHOP, "shop floor", '.', C_BROWN, B_EMPTY, B_TRANS, MT_WOOD, 0, -1);
addcelltype(CT_FLOORTILE, "tiled floor", '.', C_WHITE, B_EMPTY, B_TRANS, MT_METAL, 0, -1);
addcelltype(CT_GRASS, "grass", '.', C_GREEN, B_EMPTY, B_TRANS, MT_PLANT, 0, -1); addcelltype(CT_GRASS, "grass", '.', C_GREEN, B_EMPTY, B_TRANS, MT_PLANT, 0, -1);
addcelltype(CT_DIRT, "dirt", '.', C_BROWN, B_EMPTY, B_TRANS, MT_STONE, 0, -1); addcelltype(CT_DIRT, "dirt", '.', C_BROWN, B_EMPTY, B_TRANS, MT_STONE, 0, -1);
addcelltype(CT_LOWFLOOR, "low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -1, -1); addcelltype(CT_LOWFLOOR, "low rock floor", '.', C_GREY, B_EMPTY, B_TRANS, MT_STONE, -1, -1);
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
addregiontype(RG_WORLDMAP, "The Surface", B_FALSE, H_FOREST, 10, 0, D_NONE, B_TRUE, 0); // maxdepth stairs stair major? depthmod
// perlev dir
addregiontype(RG_WORLDMAP, "The Surface", B_FALSE, H_FOREST, 10, 0, D_NONE, B_TRUE, 0);
addregiontype(RG_MAINDUNGEON, "The Main Dungeon", B_FALSE, H_DUNGEON, 25, 3, D_DOWN, B_TRUE, 0); addregiontype(RG_MAINDUNGEON, "The Main Dungeon", B_FALSE, H_DUNGEON, 25, 3, D_DOWN, B_TRUE, 0);
addregiontype(RG_CAVE, "The Goblin Caves", B_TRUE, H_CAVE, 5, 1, D_DOWN, B_TRUE, 5); addregiontype(RG_CAVE, "The Goblin Caves", B_TRUE, H_CAVE, 5, 1, D_DOWN, B_TRUE, 2);
addregiontype(RG_HEAVEN, "The Realm of Gods", B_FALSE, H_HEAVEN, 1, 0, D_NONE, B_FALSE, 0); addregiontype(RG_HEAVEN, "The Realm of Gods", B_FALSE, H_HEAVEN, 1, 0, D_NONE, B_FALSE, 0);
addregiontype(RG_PIT, "A Pit", B_FALSE, H_PIT, 1, 1, D_DOWN, B_FALSE, 0); addregiontype(RG_PIT, "A Pit", B_FALSE, H_PIT, 1, 1, D_DOWN, B_FALSE, 0);
addregiontype(RG_SEWER, "A Sewer", B_FALSE, H_SEWER, 1, 0, D_NONE, B_FALSE, 2); addregiontype(RG_SEWER, "A Sewer", B_FALSE, H_SEWER, 1, 0, D_NONE, B_FALSE, 2);

4
move.c
View File

@ -2076,7 +2076,9 @@ int closedoor(lifeform_t *lf, object_t *o) {
f = hasflag(o->flags, F_DOOR); f = hasflag(o->flags, F_DOOR);
addflag(o->flags, F_IMPASSABLE, f->val[0], f->val[1], f->val[2], f->text); addflag(o->flags, F_IMPASSABLE, f->val[0], f->val[1], f->val[2], f->text);
addflag(o->flags, F_BLOCKSVIEW, B_TRUE, NA, NA, NULL); if (hasflag(o->type->flags, F_BLOCKSVIEW)) {
copyflag(o->flags, o->type->flags, F_BLOCKSVIEW);
}
if (lf) { if (lf) {
// stop sprinting // stop sprinting

View File

@ -2516,13 +2516,6 @@ int canseeob(lifeform_t *lf, object_t *o) {
return B_FALSE; return B_FALSE;
} }
} }
if (isblind(player) || (o->pile->where && !haslos(player, o->pile->where)) ) {
if (hasflag(o->flags, F_NOFEEL)) {
return B_FALSE;
}
}
f = hasflag(o->flags, F_TRAIL); f = hasflag(o->flags, F_TRAIL);
if (f) { if (f) {
if (f->val[2] == S_SIGHT) { if (f->val[2] == S_SIGHT) {
@ -2572,6 +2565,15 @@ int canseeob(lifeform_t *lf, object_t *o) {
} }
} }
if (o->pile->where && (o->pile->where->map == lf->cell->map)) {
if (isblind(lf) || (!haslos(lf, o->pile->where)) ) {
if (hasflag(o->flags, F_NOFEEL)) {
return B_FALSE;
}
}
}
return B_TRUE; return B_TRUE;
} }
@ -3403,6 +3405,21 @@ recipe_t *findrecipefor(enum OBTYPE result) {
return NULL; return NULL;
} }
int fountain_will_dryup(object_t *o) {
if (hasflagval(o->flags, F_LINKOB, OT_POT_EXPERIENCE, NA, NA, NULL) ||
onein(ONEIN_FOUNTAINDRYUP)) {
cell_t *loc;
loc = getoblocation(o);
if (haslos(player, loc)) {
char fname[BUFLEN];
getobname(o, fname, o->amt);
msg("%s dries up.", fname);
}
return B_TRUE;
}
return B_FALSE;
}
void fragments(cell_t *centre, char *what, int speed, int howfar) { void fragments(cell_t *centre, char *what, int speed, int howfar) {
cell_t *c,*dst; cell_t *c,*dst;
int n,dir; int n,dir;
@ -4384,7 +4401,9 @@ enum DEPTH getobdepth(object_t *o, lifeform_t *lf) {
char *getobdesc(object_t *o, char *buf) { char *getobdesc(object_t *o, char *buf) {
int blind = B_FALSE; int blind = B_FALSE;
int known = B_FALSE;
if (gamemode == GM_GAMESTARTED) { if (gamemode == GM_GAMESTARTED) {
// can't see the object ?
if (o->pile->owner == player) { if (o->pile->owner == player) {
if (!haslos(player, player->cell) || isblind(player)) { if (!haslos(player, player->cell) || isblind(player)) {
if (!hasflag(o->flags, F_FEELTEXT)) { if (!hasflag(o->flags, F_FEELTEXT)) {
@ -4393,7 +4412,15 @@ char *getobdesc(object_t *o, char *buf) {
} }
} }
} }
if (isknown(o) && !blind) {
if (isknown(o)) {
known = B_TRUE;
} else {
if (o->pile->parentob && hasflag(o->pile->parentob->flags, F_SHOP)) {
known = B_TRUE;
}
}
if (known && !blind) {
if (o->type->id == OT_CORPSE) { if (o->type->id == OT_CORPSE) {
flag_t *f; flag_t *f;
f = hasflag(o->flags, F_CORPSEOF); f = hasflag(o->flags, F_CORPSEOF);
@ -7958,11 +7985,12 @@ void obdie(object_t *o) {
if (f->val[2] == B_IFACTIVATED) { if (f->val[2] == B_IFACTIVATED) {
if (isactivated(o)) { if (isactivated(o)) {
explodeob(o, f, f->val[1]); explodeob(o, f, f->val[1]);
return;
} }
} else { } else {
explodeob(o, f, f->val[1]); explodeob(o, f, f->val[1]);
return;
} }
return;
} }
@ -8920,7 +8948,6 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
getobname(newob, newobname, newob->amt); getobname(newob, newobname, newob->amt);
msgnocap("%c - %s.",newob->letter, newobname); msgnocap("%c - %s.",newob->letter, newobname);
} }
// kill the ground object?
switch (oo->type->id) { switch (oo->type->id) {
case OT_SPLASHWATER: case OT_SPLASHWATER:
case OT_BLOODSPLASH: case OT_BLOODSPLASH:
@ -8930,20 +8957,13 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
removeob(oo, 1); removeob(oo, 1);
break; break;
case OT_FOUNTAIN: case OT_FOUNTAIN:
if (hasflagval(oo->flags, F_LINKOB, OT_POT_EXPERIENCE, NA, NA, NULL) || if (fountain_will_dryup(oo)) {
onein(ONEIN_FOUNTAINDRYUP)) {
cell_t *loc;
loc = getoblocation(oo);
if (haslos(player, loc)) {
char fname[BUFLEN];
getobname(oo, fname, oo->amt);
msg("%s dries up.", obname);
}
removeob(oo, oo->amt); removeob(oo, oo->amt);
} }
break; break;
default: default:
break; break;
} }
} else { } else {
msg("That doesn't seem like a very good idea."); msg("That doesn't seem like a very good idea.");
@ -9403,7 +9423,6 @@ int pour(lifeform_t *lf, object_t *o) {
// god effects // god effects
if (isplayer(lf)) { if (isplayer(lf)) {
pleasegodmaybe(R_GODPURITY, 3); pleasegodmaybe(R_GODPURITY, 3);
angergodmaybe(R_GODDEATH, 15, GA_HERESY);
} }
} else if ((o->type->id == OT_POT_WATER) && (o->blessed == B_CURSED)) { // unholy water } else if ((o->type->id == OT_POT_WATER) && (o->blessed == B_CURSED)) { // unholy water
if (isplayer(lf)) { if (isplayer(lf)) {
@ -9416,7 +9435,6 @@ int pour(lifeform_t *lf, object_t *o) {
if (!isknown(o)) makeknown(o->type->id); if (!isknown(o)) makeknown(o->type->id);
// god effects // god effects
if (isplayer(lf)) { if (isplayer(lf)) {
pleasegodmaybe(R_GODDEATH, 3);
angergodmaybe(R_GODPURITY, 25, GA_HERESY); angergodmaybe(R_GODPURITY, 25, GA_HERESY);
} }
} else if (o->type->id == OT_POT_INVULN) { } else if (o->type->id == OT_POT_INVULN) {
@ -9648,13 +9666,10 @@ void quaff(lifeform_t *lf, object_t *o) {
} }
// fountains sometimes dry up // fountains sometimes dry up
if ((o->type->id == OT_FOUNTAIN) && onein(ONEIN_FOUNTAINDRYUP)) { if (o->type->id == OT_FOUNTAIN) {
cell_t *loc; if (fountain_will_dryup(o)) {
// dry up (ie. remove DONTKILL property) // dry up (ie. remove DONTKILL property)
drinkflag->val[2] = NA; drinkflag->val[2] = NA;
loc = getoblocation(o);
if (haslos(player, loc)) {
msg("%s dries up.", obname);
} }
} }
@ -9877,6 +9892,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
break; break;
case OT_POT_FURY: case OT_POT_FURY:
lf->stamina = getmaxstamina(lf);
abilityeffects(lf, OT_A_RAGE, lf->cell, lf, NULL); abilityeffects(lf, OT_A_RAGE, lf->cell, lf, NULL);
break; break;
case OT_POT_GASEOUSFORM: case OT_POT_GASEOUSFORM:
@ -10547,6 +10563,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
removeob(o, 1); removeob(o, 1);
} else if (o->type->id == OT_SCR_PERMENANCE) { } else if (o->type->id == OT_SCR_PERMENANCE) {
int ndone = 0; int ndone = 0;
enum ATTRIB a;
flag_t *f; flag_t *f;
// makes certain flags permenant // makes certain flags permenant
for (f = lf->flags->first ; f ; f = f->next) { for (f = lf->flags->first ; f ; f = f->next) {
@ -10555,6 +10572,17 @@ int readsomething(lifeform_t *lf, object_t *o) {
ndone++; ndone++;
} }
} }
// make enhanced/reduced attributes permenant
for (a = 0; a < MAXATTS; a++) {
int innate,actual;
innate = lf->att[a];
actual = getattr(lf, a);
if (actual != innate) {
lf->att[a] = actual;
ndone++;
if (isplayer(lf)) statdirty = B_TRUE;
}
}
if (isplayer(lf)) { if (isplayer(lf)) {
if (ndone) { if (ndone) {
@ -11929,7 +11957,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
glyph_t *gl; glyph_t *gl;
gl = getglyph(o); gl = getglyph(o);
anim(where, srcloc, gl->ch, gl->colour); anim(where, srcloc, gl->ch, gl->colour);
msg("%s is reflected away from %s!", obname, targetname); msg("%s %s reflected away from %s!", obname, (o->amt == 1) ? "is" : "are", targetname);
} }
// adjust target // adjust target
where = srcloc; where = srcloc;
@ -12031,7 +12059,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
if (check_for_block(thrower, target, getthrowdam(o) + speed, DT_PROJECTILE, difficulty, attackname)) { if (check_for_block(thrower, target, getthrowdam(o) + speed, DT_PROJECTILE, difficulty, attackname)) {
announcedmiss = B_TRUE; announcedmiss = B_TRUE;
youhit = B_FALSE; youhit = B_FALSE;
missiledam += ((speed*2)+1); missiledam += ((speed*2)+rnd(1,4));
} }
} }
@ -12218,7 +12246,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
wepeffects(o->flags, target->cell, hasflag(o->flags, F_DAM), dam); wepeffects(o->flags, target->cell, hasflag(o->flags, F_DAM), dam);
missiledam += ((speed*2)+1); missiledam += ((speed*2)+rnd(1,4));
if (willtangle) { if (willtangle) {
missiledam = 0; // don't damage the misisle missiledam = 0; // don't damage the misisle

View File

@ -63,6 +63,7 @@ obmod_t *findobmod(enum OBMOD id);
objecttype_t *findot(enum OBTYPE id); objecttype_t *findot(enum OBTYPE id);
objecttype_t *findotn(char *name); // find objecttype by name objecttype_t *findotn(char *name); // find objecttype by name
recipe_t *findrecipefor(enum OBTYPE result); recipe_t *findrecipefor(enum OBTYPE result);
int fountain_will_dryup(object_t *o);
void fragments(cell_t *centre, char *what, int speed, int howfar); void fragments(cell_t *centre, char *what, int speed, int howfar);
void genhiddennames(void); void genhiddennames(void);
enum LFSIZE getarmoursize(object_t *o); enum LFSIZE getarmoursize(object_t *o);

41
save.c
View File

@ -276,6 +276,34 @@ lifeform_t *loadlf(FILE *f, cell_t *where) {
} }
if (db) dblog("----> done (id=%ld)",thisid); if (db) dblog("----> done (id=%ld)",thisid);
} }
// now repeat the above for polypack...
obcount = 0;
obid = 9998; // for testing
rv = fscanf(f, "polyob:%ld\n",&obid);
while (obid != -1) {
if (db) dblog("--> Load ob id %d into polypack list...",obid);
l->polypack->oblist[obcount] = obid;
obcount++;
fscanf(f, "polyob:%ld\n",&obid);
}
// terminate with -1s!
for (i = obcount ; i < MAXPILEOBS; i++) {
l->polypack->oblist[i] = -1;
}
if (db) dblog("--> Finished polypack oblist. Found %d objects.",obcount);
// now load object defs for this lf's pack!
fscanf(f, "polyobdefs\n");
for (i = 0; i < obcount; i++) {
long thisid;
if (db) dblog("--> Creating polypack ob #%d for lf.",i);
//if (db) dblog("-----> ob %d/%d...\n",i+1,obcount);
if (loadob(f, l->polypack, &thisid)) {
dblog("Error - can't create object %d/%d!\n",i+1,obcount);
exit(1);
}
if (db) dblog("----> done (id=%ld)",thisid);
}
// is this the player? // is this the player?
if (l->controller == C_PLAYER) { if (l->controller == C_PLAYER) {
@ -857,6 +885,19 @@ int savelf(FILE *f, lifeform_t *l) {
saveob(f, o); saveob(f, o);
} }
// lifeform polypack objects
obcount = 0;
for (o = l->polypack->first ; o ; o = o->next) {
fprintf(f, "polyob:%ld\n",o->id);
obcount++;
}
fprintf(f, "polyob:-1\n");
fprintf(f, "polyobdefs\n");
// now save our polypack object definitions
for (o = l->polypack->first ; o ; o = o->next) {
saveob(f, o);
}
return B_FALSE; return B_FALSE;
} }

70
spell.c
View File

@ -2317,7 +2317,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (isplayer(user)) { if (isplayer(user)) {
msg("You try to trip %s, but fail.",targetname); msg("You try to trip %s, but fail.",targetname);
} else if (cansee(player, user)) { } else if (cansee(player, user)) {
msg("%s tries to trip %s, but fail.",username, targetname); msg("%s tries to trip %s, but fails.",username, targetname);
} }
} }
} else if (abilid == OT_A_TUMBLE) { } else if (abilid == OT_A_TUMBLE) {
@ -4828,7 +4828,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("%s forms %s %s%s %s!", obname, getbodypartequipname(bp[i]), msg("%s forms %s %s%s %s!", obname, getbodypartequipname(bp[i]),
castername, getpossessive(castername), getbodypartname(target, bp[i])); castername, getpossessive(castername), getbodypartname(target, bp[i]));
} }
wear(target, o); // don't use "wear" because we don't want it being announced.
addflag(o->flags, F_EQUIPPED, bp[i], -1, -1, NULL);
// set its values // set its values
f = hasflag(o->flags, F_OBHP); f = hasflag(o->flags, F_OBHP);
if (f) { if (f) {
@ -4861,7 +4862,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
o = addob(target->pack, "ice crystal shield"); o = addob(target->pack, "ice crystal shield");
if (o) { if (o) {
if (canwear(target, o, BP_NONE)) { if (canwear(target, o, BP_SECWEAPON)) {
flag_t *f; flag_t *f;
enum LFSIZE sz; enum LFSIZE sz;
if (power <= 2) { if (power <= 2) {
@ -4878,7 +4879,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("A %s shield of shimmering ice forms in %s%s hand!", getsizetext(sz), castername, msg("A %s shield of shimmering ice forms in %s%s hand!", getsizetext(sz), castername,
getpossessive(castername)); getpossessive(castername));
} }
wear(target, o); // don't use "wear" because we don't want it being announced.
addflag(o->flags, F_EQUIPPED, BP_SECWEAPON, -1, -1, NULL);
// set its values // set its values
f = hasflag(o->flags, F_OBHP); f = hasflag(o->flags, F_OBHP);
if (f) { if (f) {
@ -5244,11 +5246,17 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} // end if isplayer } // end if isplayer
} else if (spellid == OT_S_DETONATE) { } else if (spellid == OT_S_DETONATE) {
// don't need line of fire! // don't need line of fire!
explodecells(targcell, 20, B_TRUE, NULL, power / 4, DT_ORTH, B_TRUE); explodecells(targcell, 20+(power*2), B_TRUE, NULL, power / 4, DT_ORTH, B_TRUE);
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
} else if (spellid == OT_S_DETONATEDELAY) {
addobfast(targcell->obpile, OT_VIBCLOUD);
if (haslos(player, targcell)) {
msg("The air nearby begins to vibrate violently..."); more();
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
} else if (spellid == OT_S_EQANDOP) { } else if (spellid == OT_S_EQANDOP) {
flag_t *f; flag_t *f;
f = addtempflag(caster->flags, F_REFLECTION, B_TRUE, NA, NA, NULL, FROMSPELL); f = addtempflag(caster->flags, F_REFLECTION, B_TRUE, NA, NA, NULL, FROMSPELL);
@ -6468,7 +6476,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// affect equipped objects // affect equipped objects
for (o = target->pack->first ; o ; o = nexto) { for (o = target->pack->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
// destroy metal items on the ground
if (ismetal(o->material->id)) { if (ismetal(o->material->id)) {
int dodam = B_FALSE; int dodam = B_FALSE;
if (isequippedon(o, BP_WEAPON) || isequippedon(o, BP_SECWEAPON)) { if (isequippedon(o, BP_WEAPON) || isequippedon(o, BP_SECWEAPON)) {
@ -6491,7 +6498,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
noprefix(obname), OBS1(o)); noprefix(obname), OBS1(o));
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
takedamage(o, rnd(1,4), DT_HEAT); takedamage(o, rnd(6,12), DT_HEAT);
} }
} }
} }
@ -6515,7 +6522,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// affect objects on ground // affect objects on ground
for (o = targcell->obpile->first ; o ; o = nexto) { for (o = targcell->obpile->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
// destroy metal items on the ground // damage metal items on the ground
if (ismetal(o->material->id)) { if (ismetal(o->material->id)) {
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
char obname[BUFLEN]; char obname[BUFLEN];
@ -6524,7 +6531,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
donesomething = B_FALSE; donesomething = B_FALSE;
} }
takedamage(o, rnd(1,4), DT_HEAT); takedamage(o, rnd(6,12), DT_HEAT);
} }
} }
} }
@ -8592,17 +8599,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_FALSE; return B_FALSE;
} }
amttolose = power*2; amttolose = power*2;
// only announce if the target will have some stamina left. if (isplayer(target)) {
// if they drop to 0, modstamina will handle the announce. msg("You suddenly feel very lethargic!");
if (getstamina(target) >= amttolose) { } else if (cansee(player, target)) {
if (isplayer(target)) { char targname[BUFLEN];
msg("You suddenly feel very lethargic!"); getlfname(target, targname);
} else if (cansee(player, target)) { msg("%s looks very lethargic!", targname);
char targname[BUFLEN]; }
getlfname(target, targname);
msg("%s looks very lethargic!", targname);
}
}
modstamina(target, -amttolose); modstamina(target, -amttolose);
} else if (spellid == OT_S_REPELINSECTS) { } else if (spellid == OT_S_REPELINSECTS) {
// just announce // just announce
@ -9080,7 +9083,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
if (targcell->lf) { if (targcell->lf) {
losehp(targcell->lf, rnd(1,6), DT_FIRE, caster, "a spark"); losehp(targcell->lf, rnd(2,2), DT_FIRE, caster, "a spark");
} else { } else {
for (o = targcell->obpile->first ; o ; o = nexto) { for (o = targcell->obpile->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
@ -9923,7 +9926,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// set its damage value // set its damage value
f = hasflag(o->flags, F_DAM); f = hasflag(o->flags, F_DAM);
if (f) { if (f) {
f->val[1] = 2+(power*2); f->val[1] = 2+power;
} }
addflag(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL); addflag(o->flags, F_CREATEDBYSPELL, spellid, NA, NA, NULL);
} else { } else {
@ -10054,6 +10057,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
char lfname[BUFLEN]; char lfname[BUFLEN];
cell_t *retcell[MAXRETCELLS]; cell_t *retcell[MAXRETCELLS];
int nretcell,i; int nretcell,i;
int dam;
// animation // animation
//anim(caster->cell, targcell, '}', C_BLUE); //anim(caster->cell, targcell, '}', C_BLUE);
if (isplayer(caster) || cansee(player, caster)) { if (isplayer(caster) || cansee(player, caster)) {
@ -10062,30 +10066,37 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
dam = roll("2d6");
calcbresnham(caster->cell->map, caster->cell->x, caster->cell->y, targcell->x, targcell->y, retcell, &nretcell); calcbresnham(caster->cell->map, caster->cell->x, caster->cell->y, targcell->x, targcell->y, retcell, &nretcell);
for (i = 1; i < nretcell; i++) { for (i = 1; i < nretcell; i++) {
target = haslf(retcell[i]); target = haslf(retcell[i]);
if (target) { if (target) {
int dir,amt, i; int dir,amt, n;
object_t *arm[MAXBODYPARTS]; object_t *arm[MAXBODYPARTS];
int narm = 0; int narm = 0;
int dam;
getlfname(target, lfname); getlfname(target, lfname);
// hit // hit
if (cansee(player, target)) { if (cansee(player, target)) {
msg("%s %s hit by a jet of water!",lfname, is(target)); msg("%s %s hit by a jet of water!",lfname, is(target));
} }
// does less damage the further you are away.
if (dam > 0) dam--;
// water damage will generally be turn to zero unless people are specifically // water damage will generally be turn to zero unless people are specifically
// vulnerable to water, so do bashing damage too. // vulnerable to water, so do bashing damage too.
losehp(target, roll("3d4"), DT_WATER, caster, "a high-pressure jet of water"); losehp(target, dam, DT_WATER, caster, "a high-pressure jet of water");
losehp(target, roll("3d4"), DT_BASH, caster, "a high-pressure jet of water"); losehp(target, dam, DT_BASH, caster, "a high-pressure jet of water");
// knock backwards // knock backwards
dir = getdirtowards(caster->cell, target->cell, target, B_FALSE, DT_COMPASS); dir = getdirtowards(caster->cell, target->cell, target, B_FALSE, DT_COMPASS);
amt = (power/3); if (amt < 2) amt = 2; amt = (power/3); if (amt < 2) amt = 2;
knockback(target, dir, amt, caster, 0, B_TRUE); knockback(target, dir, amt, caster, 0, B_TRUE);
// rust // rust
getallouterarmour(target, arm, &narm); getallouterarmour(target, arm, &narm);
for (i = 0; i < narm; i++) { for (n = 0; n < narm; n++) {
takedamage(arm[i], R_TRUSTY, DT_WATER); takedamage(arm[n], R_TRUSTY, DT_WATER);
} }
// add water object // add water object
addob(retcell[i]->obpile, "large puddle of water"); addob(retcell[i]->obpile, "large puddle of water");
@ -11160,8 +11171,11 @@ int getstamcost(lifeform_t *lf, enum OBTYPE oid) {
flag_t *f; flag_t *f;
f = lfhasflagval(lf, F_CANWILL, oid, NA, NA, NULL); f = lfhasflagval(lf, F_CANWILL, oid, NA, NA, NULL);
if (f) { if (f) {
int newcost;
// override stamina cost? // override stamina cost?
texttospellopts(f->text, "stamcost:", &stamcost, NULL); if (texttospellopts(f->text, "stamcost:", &newcost, NULL)) {
stamcost = newcost;
}
} }
if (stamcost == -1) { if (stamcost == -1) {
objecttype_t *ot; objecttype_t *ot;

8
text.c
View File

@ -99,7 +99,7 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
// modify victimname if required // modify victimname if required
//if (helpless && !isbehind(lf, victim)) { //if (helpless && !isbehind(lf, victim)) {
if (!isplayer(victim) && ishelplessvictim(victim, lf, &helpless)) { if (victim && !isplayer(victim) && ishelplessvictim(victim, lf, &helpless)) {
char *vn; char *vn;
// strip "the" from "the xxx" // strip "the" from "the xxx"
vn = strdup(victimname); vn = strdup(victimname);
@ -1914,9 +1914,11 @@ void texttospellopts(char *text, int *power, char *damstr, int *needgrab, int *r
} }
*/ */
void texttospellopts(char *text, ... ) { // returns # opts filled in
int texttospellopts(char *text, ... ) {
char *p; char *p;
va_list args; va_list args;
int nfilled = 0;
char *validname[] = { char *validname[] = {
"pw:", "pw:",
"dam:", "dam:",
@ -1990,6 +1992,7 @@ void texttospellopts(char *text, ... ) {
} else if (argtype[foundidx] == 's') { } else if (argtype[foundidx] == 's') {
strcpy((char *)writeto, valfull); strcpy((char *)writeto, valfull);
} }
nfilled++;
} }
} }
} }
@ -1999,6 +2002,7 @@ void texttospellopts(char *text, ... ) {
if (wantname) writeto = va_arg(args, void *); if (wantname) writeto = va_arg(args, void *);
} }
va_end(args); va_end(args);
return nfilled;
} }
char *you(lifeform_t *lf) { char *you(lifeform_t *lf) {

2
text.h
View File

@ -60,7 +60,7 @@ char *strends(char *a, char *suffix);
char *strstarts(char *a, char *prefix); char *strstarts(char *a, char *prefix);
int strpixmatch(char *haystack, char *needle); int strpixmatch(char *haystack, char *needle);
int texttodice(char *text, int *ndice, int *nsides, int *bonus); int texttodice(char *text, int *ndice, int *nsides, int *bonus);
void texttospellopts(char *text, ... ); int texttospellopts(char *text, ... );
//void texttospellopts(char *text, int *power, char *damstr, int *needgrab, int *range, char *racestr); //void texttospellopts(char *text, int *power, char *damstr, int *needgrab, int *range, char *racestr);
char *you(lifeform_t *lf); char *you(lifeform_t *lf);
char *you_l(lifeform_t *lf); char *you_l(lifeform_t *lf);

View File

@ -9,6 +9,7 @@
@end @end
@legend @legend
.:cell:carpetted floor
#:cell:rock wall #:cell:rock wall
b:ob:wooden bed b:ob:wooden bed
t:ob:wooden table t:ob:wooden table

View File

@ -13,6 +13,7 @@ entertext:You enter a dining room.
autodoors:75 autodoors:75
autopop autopop
! tables & chairs ! tables & chairs
fill(1,1,-2,-2) cell:tiled floor
scatter(1,1,-2,-2) ob:wooden table:20% scatter(1,1,-2,-2) ob:wooden table:20%
scatter(1,1,-2,-2) ob:wooden footstool:20% scatter(1,1,-2,-2) ob:wooden footstool:20%
scatter(1,1,-2,-2) ob:random food:1-2 scatter(1,1,-2,-2) ob:random food:1-2