- [+] most monsters which covet food should have snatch - so that you

can just drop food for them.
- [+] when looking for remote obs, DO include adjacent cells with lfs,
      if we have the snatch ability.
- [+] some long thin levels (80 x 12 ?)
- [+] fix code to remove useless doors.
    - [+] 0 pairs of dirs with empty cells = change door to wall
    - [+] pick an adjacent empty cell
    - [+] floodfill the 8 cells around the door.
        - [+] start with adj cell
        - [+] can't go more than 1 cell away from door
        - [+] solid cells or doors will stop movement
    - [+] if no unfilled cells around the door, bad.
- [+] new way of fixing unconnected levels - portal!
    - [+] pick one spot in each section then place a portal there.
- [+] dying should cure poison
- [+] tweaks to attack text
- [+] floor tile effecst
    - [+] absorbancy - ie. carpet should absorb water.
    - [+] converyors
    - [+] only walkable sometime (crushers?)
- [+] in tombstone, show "eaten by Rattus", not "eaten by a rattus"
- [+] god of nature should like eating animals all the time, not just
      when hungry (makes piety gain easier)
- [+] announce when eyes are protected from a spellcloud
- [+] klikirak should like setting off fire traps.
- [+] floodfill() should follow portals to the same level.
- [+] show >1 skillpoints in green on status bar
- [+] bug: gods are apeparing behind you.
    - [+] bug in getrandomadjcell
- [+] gods' planeshift spells failing? might be fixed now. using
      getrandomroomcell instead of getrandomcell.
- [+] increaes damage dealt by smite evil/good
- [+] lightning javelins shouldn't be stackable
- [+] monsters not firing ranged weapons!
    - [+] they just walk back and forth
    - [+] bug with how i was calling haslof() for cells other than
          where the mosnter was (in getdiraway())
- [+] turn undead should only work if caster level*2 is >= monster level
fullblock basics:
- [+] penalties
    - [+] lowers visrange to 1
    - [+] huge attack penalties
    - [+] huge evasion penalties
- [+] vhigh chance of all ranged damage going to shield instead.
    - [+] buckler = 75 (small)
    - [+] shield = 80
    - [+] large shield = 85
    - [+] tower = 90
    - [+] plus shield skill*2
- [+] use check_shield_block in all spell effects
    - [+] this checks whether player is shieldblocoking (or evades??)
    - [+] then applies damage appropriatly.
- [+] new ability;
- [+] stopped by:
    - [+] losing or unequipping the shield
    - [+] being interrupted
    - [+] casting a spell or using an ability
- [+] exotic weapons should cost more.
- [+] maybe prevent prayer until gods have been pleased enough ?
    - [+] while you're not worshipping anyone, piety gain is x4.
    - [+] once first one hits 'pleased', they will appear and offer you
          a place
    - [+] advantge to this is that you get a gift
    - [+] picking up new gold should please felix......
    - [+] you shoudl only be able to sacrifice untouched gold. this
          pleases felix double as much as grabbing it.
    - [+] gods sohuld appear "in a cloud of ..."
        - [+] bjorn - blood
        - [+] klik - fire
        - [+] lumara - bright light
This commit is contained in:
Rob Pearce 2012-11-09 11:50:52 +00:00
parent 3bb1edae8b
commit db635b50db
22 changed files with 1180 additions and 390 deletions

45
ai.c
View File

@ -2432,10 +2432,9 @@ int aipickupok(lifeform_t *lf, object_t *o) {
} }
*/ */
if (isedible(o)) { //if (isedible(o) && caneat(lf, o) && !isinbattle(lf, B_NODISTANT, B_FALSE)) {
if (caneat(lf, o) && !isinbattle(lf, B_NODISTANT, B_FALSE)) { if (isedible(o) && caneat(lf, o)) {
ok = B_TRUE; ok = B_TRUE;
}
} else if (canpickup(lf, o, 1)) { } else if (canpickup(lf, o, 1)) {
ok = B_TRUE; ok = B_TRUE;
} }
@ -3366,15 +3365,17 @@ int lookforobs(lifeform_t *lf) {
c = lf->los[i]; c = lf->los[i];
celldist = getcelldist(lf->cell, c); celldist = getcelldist(lf->cell, c);
if ((c != lf->cell) && !c->lf && !lfhasflagval(lf, F_IGNORECELL, c->x, c->y, NA, NULL)) { if ((c != lf->cell) && (!c->lf || cancast(lf, OT_A_SNATCH, NULL)) &&
!lfhasflagval(lf, F_IGNORECELL, c->x, c->y, NA, NULL)) {
for (o = c->obpile->first ; o ; o = nexto) { for (o = c->obpile->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
if (aiwants_real(lf, o, &covets, &noids, oid, oidcovet, &nwantflags, wantflag, wantflagcovet) && if (aiwants_real(lf, o, &covets, &noids, oid, oidcovet, &nwantflags, wantflag, wantflagcovet) &&
canpickup(lf, o, 1)) { //canpickup(lf, o, 1)) {
aipickupok(lf, o)) {
gothere = B_TRUE; gothere = B_TRUE;
// if we are in battle only go for it if we covet it and // if we are in battle only go for it if we covet it and
// it's closer than our target // it's similar distance to our target
if (target) { if (target) {
if (!covets || (celldist > targdist)) { if (!covets || (celldist > targdist)) {
gothere = B_FALSE; gothere = B_FALSE;
@ -3397,8 +3398,8 @@ int lookforobs(lifeform_t *lf) {
if (!target || if (!target ||
((f->val[1] != B_COVETS) && (celldist <= targdist)) ) { ((f->val[1] != B_COVETS) && (celldist <= targdist)) ) {
o = hasbetterweapon(lf, c->obpile); o = hasbetterweapon(lf, c->obpile);
if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o) && if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o)) {
canpickup(lf, o, 1)) { //&& canpickup(lf, o, 1)) {
if (db) dblog(".oO { remote cell has better weapon (%s). setting f_targetcell }",o->type->name); if (db) dblog(".oO { remote cell has better weapon (%s). setting f_targetcell }",o->type->name);
gothere = B_TRUE; gothere = B_TRUE;
} }
@ -3415,8 +3416,8 @@ int lookforobs(lifeform_t *lf) {
((f->val[1] != B_COVETS) && (celldist <= targdist)) ) { ((f->val[1] != B_COVETS) && (celldist <= targdist)) ) {
o = hasbetterarmour(lf, c->obpile); o = hasbetterarmour(lf, c->obpile);
if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o) && if (o && !isdangerousob(o, lf, B_TRUE) && aipickupok(lf, o)) {
canpickup(lf, o, 1)) { //canpickup(lf, o, 1)) {
if (db) dblog(".oO { remote cell has better armour (%s). setting f_targetcell }",o->type->name); if (db) dblog(".oO { remote cell has better armour (%s). setting f_targetcell }",o->type->name);
gothere = B_TRUE; gothere = B_TRUE;
} }
@ -3426,19 +3427,31 @@ int lookforobs(lifeform_t *lf) {
} }
if (gothere) { if (gothere) {
// cast a spell? long obid;
int success = B_FALSE;
// remember object id.
obid = o->id;
// cast a spell to get it?
if (cancast(lf, OT_S_CALLWIND, NULL) && haslofknown(lf->cell, c, LOF_NEED, NULL)) { if (cancast(lf, OT_S_CALLWIND, NULL) && haslofknown(lf->cell, c, LOF_NEED, NULL)) {
if (!castspell(lf, OT_S_CALLWIND, NULL, o, c, NULL, NULL)) { if (!castspell(lf, OT_S_CALLWIND, NULL, o, c, NULL, NULL)) {
// successful success = B_TRUE;
return B_TRUE;
} }
} }
if (cancast(lf, OT_A_SNATCH, NULL) && haslofknown(lf->cell, c, LOF_NEED, NULL)) { if (cancast(lf, OT_A_SNATCH, NULL) && haslofknown(lf->cell, c, LOF_NEED, NULL) &&
(getcelldist(lf->cell, c) == 1)) {
if (!useability(lf, OT_A_SNATCH, NULL, c)) { if (!useability(lf, OT_A_SNATCH, NULL, c)) {
// successful success = B_TRUE;
return B_TRUE;
} }
} }
if (success) {
// got the object. now try to eat it if possible.
object_t *oo;
oo = hasobid(lf->pack, obid);
if (oo && isedible(oo) && caneat(lf, oo)) {
eat(lf, o);
}
return B_TRUE;
}
// start walking towards target cell // start walking towards target cell
if (aigoto(lf, c, MR_OB, o, aigetchasetime(lf))) { if (aigoto(lf, c, MR_OB, o, aigetchasetime(lf))) {
return B_FALSE; return B_FALSE;

View File

@ -1244,7 +1244,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
} }
sprintf(attackname, "%s%s attack", attackername, getpossessive(attackername)); sprintf(attackname, "%s%s attack", attackername, getpossessive(attackername));
difficulty = 100 + (gettr(victim)*5) - (gettr(lf)*5); difficulty = 100 + (gettr(victim)*5) - (gettr(lf)*5);
if (check_for_block(lf, victim, dam[i], damtype[i], difficulty, attackname)) { if (check_for_block(lf, victim, dam[i], damtype[i], difficulty, attackname, isadjacent(lf->cell,victim->cell))) {
blocked = B_TRUE; blocked = B_TRUE;
break; // stop processing damage now. break; // stop processing damage now.
} }
@ -1456,7 +1456,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
if (damtypecausesbleed(damtype[i], wep)) { if (damtypecausesbleed(damtype[i], wep)) {
bleed(victim, B_SPLATTER); bleed(victim, B_SPLATTER);
} }
} else if (strstr(buf, "bisect")) { } else if (strstr(buf, "bisect") || strstr(buf, "dismember")) {
if (victim->race->id != R_EARTHWYRM) { if (victim->race->id != R_EARTHWYRM) {
addflag(victim->flags, F_MUTILATED, B_TRUE, NA, NA, NULL); addflag(victim->flags, F_MUTILATED, B_TRUE, NA, NA, NULL);
} }
@ -2165,12 +2165,31 @@ enum DAMTYPE basedamagetype(enum DAMTYPE dt) {
} }
// returns B_TRUE if victim blocked lf's attack // returns B_TRUE if victim blocked lf's attack
int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE damtype, int difficulty, char *attackname) { //
// Note: sometimes we'll call this function with a check difficulty of IMPOSSIBLE.
// This means that it'sonly possible to block the attack if you are in
// 'fullshield' mode.
int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE damtype, int difficulty, char *attackname, int ranged) {
object_t *shield[MAXPILEOBS]; object_t *shield[MAXPILEOBS];
int checkmod[MAXPILEOBS]; int checkmod[MAXPILEOBS];
int nshields,i; int nshields,i;
flag_t *fflag;
long shid;
if (lf && !cansee(victim, lf)) return B_FALSE; fflag = lfhasflag(victim, F_FULLSHIELD);
if (fflag) {
shid = atol(fflag->text);
} else {
shid = -1;
}
if (lf && !cansee(victim, lf)) {
// in fullblock mode, you can block even if you can't see
// your attacker.
if (!fflag) {
return B_FALSE;
}
}
if (lfhasflag(victim, F_STUNNED) || !hasfreeaction(victim)) { if (lfhasflag(victim, F_STUNNED) || !hasfreeaction(victim)) {
return B_FALSE; return B_FALSE;
} }
@ -2181,8 +2200,16 @@ int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE da
// get all usable shields for this damtype // get all usable shields for this damtype
getallshields(victim, damtype, shield, checkmod, &nshields); getallshields(victim, damtype, shield, checkmod, &nshields);
for (i = 0; i < nshields; i++) { for (i = 0; i < nshields; i++) {
int blocked = B_FALSE;
int fullbonus = 0;
if (fflag && ranged && (shield[i]->id == shid)) {
fullbonus = 40 + (getobsize(shield[i])*5);
}
// did we block with this object? // did we block with this object?
if (skillcheck(victim, SC_SHIELDBLOCK, difficulty, checkmod[i])) { if (skillcheck(victim, SC_SHIELDBLOCK, difficulty, checkmod[i] + fullbonus)) {
blocked = B_TRUE;
}
if (blocked) {
char shname[BUFLEN]; char shname[BUFLEN];
char victimname[BUFLEN]; char victimname[BUFLEN];
getlfname(victim, victimname); getlfname(victim, victimname);

View File

@ -7,7 +7,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag); int attackob(lifeform_t *lf, object_t *o, object_t *wep, flag_t *damflag);
int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag); int attackwall(lifeform_t *lf, cell_t *c, object_t *wep, flag_t *damflag);
enum DAMTYPE basedamagetype(enum DAMTYPE dt); enum DAMTYPE basedamagetype(enum DAMTYPE dt);
int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE damtype, int difficulty, char *attackname); int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE damtype, int difficulty, char *attackname, int ranged);
//void confereffects(flagpile_t *fp, lifeform_t *victim); //void confereffects(flagpile_t *fp, lifeform_t *victim);
void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, object_t *wep, int dam, enum DAMTYPE damtype); void criticalhit(lifeform_t *lf, lifeform_t *victim, enum BODYPART hitpos, object_t *wep, int dam, enum DAMTYPE damtype);
int damtypecausesbleed(enum DAMTYPE dt, object_t *fromob); int damtypecausesbleed(enum DAMTYPE dt, object_t *fromob);

118
data.c
View File

@ -2172,7 +2172,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GROWSTO, CT_WALLMETAL, VT_CELL, NA, NULL); addflag(lastot->flags, F_GROWSTO, CT_WALLMETAL, VT_CELL, NA, NULL);
addflag(lastot->flags, F_SHRINKSTO, OT_SHIELD, VT_OB, NA, NULL); addflag(lastot->flags, F_SHRINKSTO, OT_SHIELD, VT_OB, NA, NULL);
addot(OT_FOUNTAIN, "fountain", "A running fountain of some kind of liquid.", MT_WATER, 20, OC_MISC, SZ_MEDIUM); addot(OT_FOUNTAIN, "fountain", "A running fountain of some kind of liquid.", MT_NOTHING, 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);
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, 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);
@ -2855,6 +2855,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NUMAPPEAR, 1, 100, NA, ""); addflag(lastot->flags, F_NUMAPPEAR, 1, 100, NA, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some gold"); addflag(lastot->flags, F_FEELTEXT, NA, NA, NA, "some gold");
addflag(lastot->flags, F_UNTOUCHED, B_TRUE, NA, NA, NULL); // for god of thieves
// rocks // rocks
addot(OT_BOULDER, "boulder", "A massive stone boulder.", MT_STONE, 80, OC_ROCK, SZ_HUGE); addot(OT_BOULDER, "boulder", "A massive stone boulder.", MT_STONE, 80, OC_ROCK, SZ_HUGE);
@ -2934,6 +2935,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 250, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 250, NA, NA, NULL);
addflag(lastot->flags, F_UNTOUCHED, B_TRUE, NA, NA, NULL); // for god of thieves
addot(OT_AMETHYST, "amethyst", "A purple gemstone.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_AMETHYST, "amethyst", "A purple gemstone.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_MAGENTA, '*', NA, NULL); addflag(lastot->flags, F_GLYPH, C_MAGENTA, '*', NA, NULL);
@ -2944,6 +2946,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 15, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 15, NA, NA, NULL);
addflag(lastot->flags, F_UNTOUCHED, B_TRUE, NA, NA, NULL); // for god of thieves
addot(OT_DIAMOND, "diamond", "A sparkling diamond.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_DIAMOND, "diamond", "A sparkling diamond.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_WHITE, '*', NA, NULL); addflag(lastot->flags, F_GLYPH, C_WHITE, '*', NA, NULL);
@ -2954,6 +2957,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
addflag(lastot->flags, F_UNTOUCHED, B_TRUE, NA, NA, NULL); // for god of thieves
addot(OT_EMERALD, "emerald", "A deep green gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_EMERALD, "emerald", "A deep green gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_GREEN, '*', NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREEN, '*', NA, NULL);
@ -2964,6 +2968,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 650, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 650, NA, NA, NULL);
addflag(lastot->flags, F_UNTOUCHED, B_TRUE, NA, NA, NULL); // for god of thieves
addot(OT_OPAL, "opal", "An amorphous form of silica related to quartz.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addot(OT_OPAL, "opal", "An amorphous form of silica related to quartz.", MT_STONE, 0.1, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_GREY, '*', NA, NULL); addflag(lastot->flags, F_GLYPH, C_GREY, '*', NA, NULL);
@ -2974,6 +2979,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 70, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 70, NA, NA, NULL);
addflag(lastot->flags, F_UNTOUCHED, B_TRUE, NA, NA, NULL); // for god of thieves
addot(OT_PEARL, "pearl", "A small pinkish-white gem.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addot(OT_PEARL, "pearl", "A small pinkish-white gem.", MT_STONE, 0.1, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_WHITE, '*', NA, NULL); addflag(lastot->flags, F_GLYPH, C_WHITE, '*', NA, NULL);
@ -2984,6 +2990,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 30, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 30, NA, NA, NULL);
addflag(lastot->flags, F_UNTOUCHED, B_TRUE, NA, NA, NULL); // for god of thieves
addot(OT_RUBY, "ruby", "A large red gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_RUBY, "ruby", "A large red gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_RED, '*', NA, NULL); addflag(lastot->flags, F_GLYPH, C_RED, '*', NA, NULL);
@ -2994,6 +3001,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 110, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 110, NA, NA, NULL);
addflag(lastot->flags, F_UNTOUCHED, B_TRUE, NA, NA, NULL); // for god of thieves
addot(OT_SAPPHIRE, "sapphire", "A brilliant blue gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_SAPPHIRE, "sapphire", "A brilliant blue gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_CYAN, '*', NA, NULL); addflag(lastot->flags, F_GLYPH, C_CYAN, '*', NA, NULL);
@ -3004,6 +3012,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 850, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 850, NA, NA, NULL);
addflag(lastot->flags, F_UNTOUCHED, B_TRUE, NA, NA, NULL); // for god of thieves
addot(OT_TOPAZ, "topaz stone", "A dull blue gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_TOPAZ, "topaz stone", "A dull blue gem.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_GEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_GLYPH, C_BLUE, '*', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BLUE, '*', NA, NULL);
@ -3014,7 +3023,7 @@ void initobjects(void) {
addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, ""); addflag(lastot->flags, F_RARITY, H_ANTNEST, 100, RR_COMMON, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_VALUE, 60, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 60, NA, NA, NULL);
addflag(lastot->flags, F_UNTOUCHED, B_TRUE, NA, NA, NULL); // for god of thieves
addot(OT_ASH, "pile of ash", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY); addot(OT_ASH, "pile of ash", "A pile of ash.", MT_STONE, 0.1, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL); addflag(lastot->flags, F_GLYPH, NA, ',', NA, NULL);
@ -3882,7 +3891,7 @@ void initobjects(void) {
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODDEATH, 2, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODDEATH, 2, NA, NULL);
addot(OT_S_SMITEGOOD, "smite good", "Instantly deals 1-^bpower*2^n damage to good creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SMITEGOOD, "smite good", "Instantly deals 1d4 + ^bpower^nd4 damage to good creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, 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_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
@ -4849,7 +4858,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addot(OT_S_SMITEEVIL, "smite evil", "Instantly deals 1-^bpower*2^n damage to evil creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SMITEEVIL, "smite evil", "Instantly deals 1d4 _ ^bpower^nd4 damage to evil creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 10, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 10, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
@ -5541,6 +5550,10 @@ void initobjects(void) {
addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL); addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
addot(OT_A_FULLSHIELD, "fullshield", "Raise your shield to (almost) completely cover your body.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "While in fullshield mode your vision, evasion and accuracy are greatly lowered.");
addflag(lastot->flags, F_STAMCOST, 1, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addot(OT_A_GRAB, "grab", "You can grab hold of nearby enemies to prevent their escape.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addot(OT_A_GRAB, "grab", "You can grab hold of nearby enemies to prevent their escape.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
@ -8485,7 +8498,6 @@ void initobjects(void) {
addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL); addflag(lastot->flags, F_CANHAVEOBMOD, OM_POISONED, 17, NA, NULL);
addot(OT_JAVELINLT, "lightning javelin", "A long, sharp missile weapon which transforms into a bolt of lightning when thrown.", MT_METAL, 4, OC_MISSILE, SZ_MEDIUM); addot(OT_JAVELINLT, "lightning javelin", "A long, sharp missile weapon which transforms into a bolt of lightning when thrown.", MT_METAL, 4, OC_MISSILE, SZ_MEDIUM);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "3"); addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "3");
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_RARE, NULL);
@ -10877,7 +10889,13 @@ void initrace(void) {
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "removing polymorphs"); addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "removing polymorphs");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "purifying food"); addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "purifying food");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "blessing your items"); addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "blessing your items");
// text
addflag(lastrace->flags, F_GODBONUSTEXT, NA, NA, NA, "You have impressed me, mortal!");
addflag(lastrace->flags, F_GODNOBONUSTEXT, NA, NA, NA, "Your service is lacking, mortal.");
addflag(lastrace->flags, F_GODGIFTTEXT, NA, NA, NA, "I bestow a gift upon you, mortal!");
addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "Mortal! Your actions have impressed me.");
addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "I offer you a place in my service.");
addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "appears in a flash of power!");
addrace(R_GODBATTLE, "Bjorn", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Bjorn the Battlelord is the god of honourable combat. He appears as a heavily built, bearded warrior clad in well-used armour."); addrace(R_GODBATTLE, "Bjorn", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Bjorn the Battlelord is the god of honourable combat. He appears as a heavily built, bearded warrior clad in well-used armour.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -10952,7 +10970,13 @@ void initrace(void) {
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "repairing items"); addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "repairing items");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "detecting enemies"); addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "detecting enemies");
addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "blessing your weapon"); addflag(lastrace->flags, F_GODNOBATTLE, NA, NA, NA, "blessing your weapon");
// text
addflag(lastrace->flags, F_GODBONUSTEXT, NA, NA, NA, "Onwards to victory!");
addflag(lastrace->flags, F_GODNOBONUSTEXT, NA, NA, NA, "Your slothfulness has earned you a demotion, soldier.");
addflag(lastrace->flags, F_GODGIFTTEXT, NA, NA, NA, "Gather up the spoils of battle!");
addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "Your actions have proved worthy of notice.");
addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "Join me in my eternal battle!");
addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "appears in a shower of blood!");
addrace(R_GODNATURE, "Ekrub", 200, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Ekrub is goddess of nature and creation. She appears as a female figure dressed in farming clothes. Ekrub has a burning hatred of all dragonkind, who she views as abhorrent due to their destructive nature."); addrace(R_GODNATURE, "Ekrub", 200, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Ekrub is goddess of nature and creation. She appears as a female figure dressed in farming clothes. Ekrub has a burning hatred of all dragonkind, who she views as abhorrent due to their destructive nature.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -10997,7 +11021,7 @@ void initrace(void) {
} }
} }
addflag(lastrace->flags, F_GODPOISON, B_FALSE, 25, NA, NULL); addflag(lastrace->flags, F_GODPOISON, B_FALSE, 25, NA, NULL);
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "eating animals when hungry"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "eating animals");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "killing dragons"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "killing dragons");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "cooking"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "cooking");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "creating objects"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "creating objects");
@ -11026,8 +11050,13 @@ void initrace(void) {
addflag(lastrace->flags, F_GODBONUS, PL_PLEASED, GB_FLAG, F_PLANTFRIEND, "-1,NA,NA"); addflag(lastrace->flags, F_GODBONUS, PL_PLEASED, GB_FLAG, F_PLANTFRIEND, "-1,NA,NA");
addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_DISEASEIMMUNE, "1,NA,NA"); addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_DISEASEIMMUNE, "1,NA,NA");
addflag(lastrace->flags, F_GODBONUS, PL_ECSTATIC, GB_FLAG, F_AUTOTANGLE, "20,5,NA"); addflag(lastrace->flags, F_GODBONUS, PL_ECSTATIC, GB_FLAG, F_AUTOTANGLE, "20,5,NA");
// text
addflag(lastrace->flags, F_GODBONUSTEXT, NA, NA, NA, "You are progressing in nature's path...");
addflag(lastrace->flags, F_GODNOBONUSTEXT, NA, NA, NA, "Nature will not tolerate the lazy.");
addflag(lastrace->flags, F_GODGIFTTEXT, NA, NA, NA, "Harvest nature's bounty!");
addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "You have demonstrated an affinity for creation.");
addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "Nature would welcome your continued worship.");
addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "coalesces out of twisting air currents!");
addrace(R_GODTHIEVES, "Felix", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Felix is the god of Thieves, Revenge and Greed. He generally appears as an overweight glutton carrying his contraband loot around in huge sacks. Despite this, he is amazingly agile and is said to be able to steal one's soul right out of their body."); addrace(R_GODTHIEVES, "Felix", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Felix is the god of Thieves, Revenge and Greed. He generally appears as an overweight glutton carrying his contraband loot around in huge sacks. Despite this, he is amazingly agile and is said to be able to steal one's soul right out of their body.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -11073,6 +11102,7 @@ void initrace(void) {
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "stealing items"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "stealing items");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "lockpicking"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "lockpicking");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "bribery"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "bribery");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "gaining wealth");
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "purchasing items"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "purchasing items");
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "giving away or discarding money"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "giving away or discarding money");
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "opening locked objects through force"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "opening locked objects through force");
@ -11093,6 +11123,13 @@ void initrace(void) {
addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_SKILLCHECKMOD, buf); addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_SKILLCHECKMOD, buf);
sprintf(buf, "%d,40,NA", SC_SEARCH); sprintf(buf, "%d,40,NA", SC_SEARCH);
addflag(lastrace->flags, F_GODBONUS, PL_ECSTATIC, GB_FLAG, F_SKILLCHECKMOD, buf); addflag(lastrace->flags, F_GODBONUS, PL_ECSTATIC, GB_FLAG, F_SKILLCHECKMOD, buf);
// text
addflag(lastrace->flags, F_GODBONUSTEXT, NA, NA, NA, "Very impressive...");
addflag(lastrace->flags, F_GODNOBONUSTEXT, NA, NA, NA, "I expect more results, mortal.");
addflag(lastrace->flags, F_GODGIFTTEXT, NA, NA, NA, "Loyalty has its rewards...");
addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "Some would denounce your greed... but others would welcome it.");
addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "We could work together, you and I. What say you?");
addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "steps out of the shadows.");
addrace(R_GODLIFE, "Glorana", 2, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Glorana is the goddess of life. She appears as a pulsating orb of holy energy."); addrace(R_GODLIFE, "Glorana", 2, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Glorana is the goddess of life. She appears as a pulsating orb of holy energy.");
addbodypart(lastrace, BP_BODY, "life energy"); addbodypart(lastrace, BP_BODY, "life energy");
@ -11152,6 +11189,13 @@ void initrace(void) {
addflag(lastrace->flags, F_GODBONUS, PL_PLEASED, GB_FLAG, F_STAMBOOST, "3"); addflag(lastrace->flags, F_GODBONUS, PL_PLEASED, GB_FLAG, F_STAMBOOST, "3");
addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_HOLYTOUCH, "1"); addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_HOLYTOUCH, "1");
addflag(lastrace->flags, F_GODBONUS, PL_ECSTATIC, GB_FLAG, F_REGENERATES, "1,NA,NA"); addflag(lastrace->flags, F_GODBONUS, PL_ECSTATIC, GB_FLAG, F_REGENERATES, "1,NA,NA");
// text
addflag(lastrace->flags, F_GODBONUSTEXT, NA, NA, NA, "A good life has its rewards!");
addflag(lastrace->flags, F_GODNOBONUSTEXT, NA, NA, NA, "You must be more proactive, my child.");
addflag(lastrace->flags, F_GODGIFTTEXT, NA, NA, NA, "Use this gift to spread the joy of life!");
addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "Well met, my child! I am Glorana, protector of all that is living.");
addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "I would gladly welcome you to into my service, should you accept.");
addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "appears in a shaft of holy light.");
addrace(R_GODDEATH, "Hecta", 100, '@', C_BOLDMAGENTA, MT_BONE, RC_GOD, "The skeletal god of Death is garbed in a cloak made of pure shadow. and weilds an enormous scythe."); addrace(R_GODDEATH, "Hecta", 100, '@', C_BOLDMAGENTA, MT_BONE, RC_GOD, "The skeletal god of Death is garbed in a cloak made of pure shadow. and weilds an enormous scythe.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -11211,6 +11255,13 @@ void initrace(void) {
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "sending servants to aid you"); addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "sending servants to aid you");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "slaying a nearby enemy"); addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "slaying a nearby enemy");
addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "animating the dead"); addflag(lastrace->flags, F_GODBATTLE, NA, NA, NA, "animating the dead");
// text
addflag(lastrace->flags, F_GODBONUSTEXT, NA, NA, NA, "Your kills are impressive...");
addflag(lastrace->flags, F_GODNOBONUSTEXT, NA, NA, NA, "Lazy servants can easily be removed...");
addflag(lastrace->flags, F_GODGIFTTEXT, NA, NA, NA, "Your service has impressed me...");
addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "I bring you an offer, murderous fleshling.");
addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "Great power in life, in return for eternal service in death.");
addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "rises up from the underworld!");
addrace(R_GODFIRE, "Klikirak", 2, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Klikirak is the burning god of Fire and Destruction. He is visible only as a raging inferno of fire, destroying anything in his path."); addrace(R_GODFIRE, "Klikirak", 2, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Klikirak is the burning god of Fire and Destruction. He is visible only as a raging inferno of fire, destroying anything in his path.");
addbodypart(lastrace, BP_BODY, "flames"); addbodypart(lastrace, BP_BODY, "flames");
@ -11257,7 +11308,14 @@ void initrace(void) {
// granted bonuses // granted bonuses
addflag(lastrace->flags, F_GODBONUS, PL_PLEASED, GB_DTRESIST, DT_FIRE, NULL); addflag(lastrace->flags, F_GODBONUS, PL_PLEASED, GB_DTRESIST, DT_FIRE, NULL);
addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_DTIMMUNE, DT_FIRE, NULL); addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_DTIMMUNE, DT_FIRE, NULL);
// TODO: e = burning body // e = burning body. hardcoded.
// text
addflag(lastrace->flags, F_GODBONUSTEXT, NA, NA, NA, "DESTROY IN MY NAME!");
addflag(lastrace->flags, F_GODNOBONUSTEXT, NA, NA, NA, "PAY ATTENTION!");
addflag(lastrace->flags, F_GODGIFTTEXT, NA, NA, NA, "TAKE AND DESTROY!");
addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "YOU BURN/DESTROY... I BURN/DESTROY...");
addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "WE BURN/DESTROY TOGETHER! YES?");
addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "appears in a burst of white-hot fire!");
addrace(R_GODMAGIC, "Lumara", 55, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Lumara is the goddess of magic. She appears as a slender elderly woman, her expression wise with age."); addrace(R_GODMAGIC, "Lumara", 55, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Lumara is the goddess of magic. She appears as a slender elderly woman, her expression wise with age.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -11317,6 +11375,13 @@ void initrace(void) {
addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_MAGICBOOST, 1, NULL); addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_MAGICBOOST, 1, NULL);
addflag(lastrace->flags, F_GODBONUS, PL_ECSTATIC, GB_MAGICBOOST, 1, NULL); addflag(lastrace->flags, F_GODBONUS, PL_ECSTATIC, GB_MAGICBOOST, 1, NULL);
addflag(lastrace->flags, F_GODBONUS, PL_ECSTATIC, GB_FLAG, F_MPREGEN, "1,0,0"); addflag(lastrace->flags, F_GODBONUS, PL_ECSTATIC, GB_FLAG, F_MPREGEN, "1,0,0");
// text
addflag(lastrace->flags, F_GODBONUSTEXT, NA, NA, NA, "One is on the right path!");
addflag(lastrace->flags, F_GODNOBONUSTEXT, NA, NA, NA, "One must always strive towards the path!");
addflag(lastrace->flags, F_GODGIFTTEXT, NA, NA, NA, "One has earned a reward!");
addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "One walks the path of magic... but One has far to go.");
addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "Become my student, and experience the full spectrum of arcane knowledge.");
addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "appears in a swirl of multicoloured lights!");
addrace(R_GODMERCY, "Yumi", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Yumi is the goddess of Mercy and Forgiveness. She has a calm, serene face and wears simple clothing."); addrace(R_GODMERCY, "Yumi", 300, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Yumi is the goddess of Mercy and Forgiveness. She has a calm, serene face and wears simple clothing.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -11373,8 +11438,14 @@ void initrace(void) {
addflag(lastrace->flags, F_GODBONUS, PL_PLEASED, GB_FLAG, F_ENHANCESEARCH, "10,NA,NA"); addflag(lastrace->flags, F_GODBONUS, PL_PLEASED, GB_FLAG, F_ENHANCESEARCH, "10,NA,NA");
addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_DETECTAURAS, "1,NA,NA"); addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_DETECTAURAS, "1,NA,NA");
addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_DETECTLIFE, "5,0,NA"); addflag(lastrace->flags, F_GODBONUS, PL_DELIGHTED, GB_FLAG, F_DETECTLIFE, "5,0,NA");
// TODO: e = save life ??? // e = save life. hardcoded.
// text
addflag(lastrace->flags, F_GODBONUSTEXT, NA, NA, NA, "Your devoutness is impressive.");
addflag(lastrace->flags, F_GODNOBONUSTEXT, NA, NA, NA, "Your lack of proactiveness is disappointing...");
addflag(lastrace->flags, F_GODGIFTTEXT, NA, NA, NA, "As you have shown mercy, so shall you receive it!");
addflag(lastrace->flags, F_GODASK1, NA, NA, NA, "Such mercy as you have shown is rarely seen in your kind.");
addflag(lastrace->flags, F_GODASK2, NA, NA, NA, "Would you consider a position as my disciple?");
addflag(lastrace->flags, F_GODTEXTAPPEAR, NA, NA, NA, "fades slowly into view.");
// monsters // monsters
addrace(R_BEHOLDER, "beholder", 5, 'e', C_MAGENTA, MT_FLESH, RC_MAGIC, "A floating orb of flesh with a large mouth, single central eye, and numerous smaller eyestalks."); addrace(R_BEHOLDER, "beholder", 5, 'e', C_MAGENTA, MT_FLESH, RC_MAGIC, "A floating orb of flesh with a large mouth, single central eye, and numerous smaller eyestalks.");
@ -11697,7 +11768,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 4, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_FISTS, 4, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "knife"); addflag(lastrace->flags, F_STARTOB, 100, NA, NA, "knife");
addflag(lastrace->flags, F_CANCAST, OT_S_PLANTWALK, NA, NA, NULL); addflag(lastrace->flags, F_CANCAST, OT_S_PLANTWALK, NA, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_CHARM, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANCAST, OT_S_CHARM, NA, NA, "pw:1;range:4;");
addflag(lastrace->flags, F_CASTCHANCE, 70, NA, NA, NULL); addflag(lastrace->flags, F_CASTCHANCE, 70, NA, NA, NULL);
addflag(lastrace->flags, F_CASTTYPE, OT_S_CHARM, CT_GAZE, NA, NULL); addflag(lastrace->flags, F_CASTTYPE, OT_S_CHARM, CT_GAZE, NA, NULL);
//addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, 10, 10, NULL); //addflag(lastrace->flags, F_CANCAST, OT_S_SLEEP, 10, 10, NULL);
@ -14117,6 +14188,7 @@ 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_CARNIVORE, 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_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLL, "comes to life!"); addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLL, "comes to life!");
addrace(R_TROLLKIN, "trollkin", 100, 't', C_GREY, MT_FLESH, RC_HUMANOID, "Trollkins are the horrific offspring of a troll and a human. While they lack the regenerative abilities of a standard troll, their human genes grant them a greater level of intelligence."); addrace(R_TROLLKIN, "trollkin", 100, 't', C_GREY, MT_FLESH, RC_HUMANOID, "Trollkins are the horrific offspring of a troll and a human. While they lack the regenerative abilities of a standard troll, their human genes grant them a greater level of intelligence.");
@ -14198,6 +14270,7 @@ void initrace(void) {
addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "50"); addflag(lastrace->flags, F_EATCONFER, F_DTRESIST, DT_COLD, NA, "50");
addflag(lastrace->flags, F_CARNIVORE, 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_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addrace(R_TROLLSWAMP, "swamp troll", 100, 't', C_BOLDGREEN, MT_FLESH, RC_HUMANOID, "Twisted trolls who roam the swamplands, their claws infected with a lethal poison."); addrace(R_TROLLSWAMP, "swamp troll", 100, 't', C_BOLDGREEN, MT_FLESH, RC_HUMANOID, "Twisted trolls who roam the swamplands, their claws infected with a lethal poison.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -14238,6 +14311,7 @@ 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_CARNIVORE, 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_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLLSWAMP, "comes to life!"); addflag(lastrace->flags, F_REVIVETIMER, 0, 25, R_TROLLSWAMP, "comes to life!");
addrace(R_UNICORN, "unicorn", 500, 'u', C_WHITE, MT_FLESH, RC_ANIMAL, "Powerful steeds with gleaming coats of pure white, and a single ivory horn protruding from their forehead."); addrace(R_UNICORN, "unicorn", 500, 'u', C_WHITE, MT_FLESH, RC_ANIMAL, "Powerful steeds with gleaming coats of pure white, and a single ivory horn protruding from their forehead.");
@ -14492,6 +14566,7 @@ void initrace(void) {
addflag(lastrace->flags, F_TR, 4, NA, NA, NULL); addflag(lastrace->flags, F_TR, 4, NA, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_WHIPATTACK, 6, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_WHIPATTACK, 6, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "pw:1;");
addflag(lastrace->flags, F_CANWILL, OT_S_SUCK, NA, NA, "pw:1;range:2;"); addflag(lastrace->flags, F_CANWILL, OT_S_SUCK, NA, NA, "pw:1;range:2;");
@ -14693,7 +14768,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_STR, AT_HIGH, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_MINDLESS, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_AGI, AT_EXLOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_AGI, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CON, AT_RANDOM, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_WIS, AT_EXLOW, NA, NULL);
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
@ -14921,6 +14996,7 @@ 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_CARNIVORE, 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_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL); addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL);
addflag(lastrace->flags, F_SKILLCHECKMOD, SC_SLIP, -15, NA, NULL); // paws can't grip addflag(lastrace->flags, F_SKILLCHECKMOD, SC_SLIP, -15, NA, NULL); // paws can't grip
@ -14961,6 +15037,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STABILITY, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STABILITY, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL); addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL);
addflag(lastrace->flags, F_FELINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FELINE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HATESRACEWITHFLAG, F_CANINE, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACEWITHFLAG, F_CANINE, NA, NA, NULL);
@ -15004,6 +15081,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_SWIMMING, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_SWIMMING, PR_SKILLED, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_CLIMBING, PR_SKILLED, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_CLIMBING, PR_SKILLED, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL); addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL);
addflag(lastrace->flags, F_FELINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FELINE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HATESRACEWITHFLAG, F_CANINE, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACEWITHFLAG, F_CANINE, NA, NA, NULL);
@ -15044,6 +15122,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STABILITY, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STABILITY, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_MASTER, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL); addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL);
addflag(lastrace->flags, F_FELINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FELINE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_HATESRACEWITHFLAG, F_CANINE, NA, NA, NULL); addflag(lastrace->flags, F_HATESRACEWITHFLAG, F_CANINE, NA, NA, NULL);
@ -15076,6 +15155,7 @@ 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_CARNIVORE, 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_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL); addflag(lastrace->flags, F_FATALFOOD, OT_CHOCOLATE, NA, NA, NULL);
addflag(lastrace->flags, F_EATCONFER, F_CANSEETHROUGHMAT, MT_GAS, NA, "80"); addflag(lastrace->flags, F_EATCONFER, F_CANSEETHROUGHMAT, MT_GAS, NA, "80");
addflag(lastrace->flags, F_FELINE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_FELINE, B_TRUE, NA, NA, NULL);
@ -15106,6 +15186,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_CHA, AT_AVERAGE, NA, NULL);
addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_VEGETARIAN, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roar"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 4, NA, "roars^a roar");
addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 3, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
@ -15978,6 +16059,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, 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_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
@ -16011,6 +16093,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
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_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 4, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 4, NA, NA, NULL);
@ -16045,6 +16128,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, NA, NULL); addflag(lastrace->flags, F_HITCONFERVALS, P_VENOM, 1, 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_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_POISONGAS, NA, NA, NULL);
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
@ -16590,6 +16674,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, 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_CARNIVORE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, 4, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SPRINT, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SPRINT, NA, NA, NULL);
addflag(lastrace->flags, F_LEVRACE, 5, R_WOLF, NA, NULL); addflag(lastrace->flags, F_LEVRACE, 5, R_WOLF, NA, NULL);
@ -16625,6 +16710,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, 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_CARNIVORE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_SEEINDARK, 5, NA, 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_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_LOWHP, 2, NA, "whines in pain^whining");
@ -16694,6 +16780,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOSPELLS, B_TRUE, 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_CARNIVORE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SNATCH, NA, NA, "range:1;");
addflag(lastrace->flags, F_SEEINDARK, 5, NA, 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_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_LOWHP, 2, NA, "whines in pain^whining");
@ -16734,7 +16821,6 @@ void initrace(void) {
addflag(lastrace->flags, F_EVASION, 10, NA, 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_NOSPELLS, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_CARNIVORE, 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_SEEINDARK, 5, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SPRINT, 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_LOWHP, 2, NA, "whines in pain^whining");

Binary file not shown.

24
defs.h
View File

@ -86,6 +86,12 @@
#define B_TRUE (-1) #define B_TRUE (-1)
#define B_MAYBE (-2) #define B_MAYBE (-2)
#define B_NORANGED (0)
#define B_RANGED (-1)
#define B_NOABSORB (0)
#define B_ABSORB (-1)
#define B_ALLOWID (-1) #define B_ALLOWID (-1)
#define B_NOID (0) #define B_NOID (0)
@ -513,6 +519,8 @@ enum SHOPACTION {
#define FROMLYCANTHROPY (-9861) #define FROMLYCANTHROPY (-9861)
#define FROMGAMESTART (-9860) #define FROMGAMESTART (-9860)
#define IMPOSSIBLE (9999)
// flag lifetimes - external sources (ie. don't kill them) // flag lifetimes - external sources (ie. don't kill them)
#define FROMEXTERNAL_HIGH (-7000) #define FROMEXTERNAL_HIGH (-7000)
#define FROMRACE (-7872) #define FROMRACE (-7872)
@ -1939,6 +1947,7 @@ enum OBTYPE {
OT_A_FEIGNDEATH, OT_A_FEIGNDEATH,
OT_A_FLIP, OT_A_FLIP,
OT_A_FLURRY, OT_A_FLURRY,
OT_A_FULLSHIELD,
OT_A_GRAB, OT_A_GRAB,
OT_A_CHARGE, OT_A_CHARGE,
OT_A_COMBOSTRIKE, OT_A_COMBOSTRIKE,
@ -2582,6 +2591,7 @@ enum FLAG {
// potion of sleep, etc. // potion of sleep, etc.
F_BATTLESPOILS, // this obejct was dropped by a monster which the F_BATTLESPOILS, // this obejct was dropped by a monster which the
// player killed, and has not yet been touched. // player killed, and has not yet been touched.
F_UNTOUCHED, // this obejct has not yet been picked up by anyone
F_BEINGUSED, // this object is currently being used F_BEINGUSED, // this object is currently being used
F_BRANDCHANCE, // this object has v0% extra chance of being branded F_BRANDCHANCE, // this object has v0% extra chance of being branded
F_DEAD, // object will be removed. v0 = lfid who killed it F_DEAD, // object will be removed. v0 = lfid who killed it
@ -3230,6 +3240,7 @@ enum FLAG {
// if text is set, and it was the player waking up, // if text is set, and it was the player waking up,
// then print this text. // then print this text.
F_TURNED, // lf turned this turn. F_TURNED, // lf turned this turn.
F_GODOFFERDONE, // player has been offered a position with a god
F_PRAYEDTO, // player has prayed to this god before. F_PRAYEDTO, // player has prayed to this god before.
F_GODBLOCKED, // player may NOT pray to this god F_GODBLOCKED, // player may NOT pray to this god
F_GIFTTIMER, // v0 = ticks down to zero whenever you please this F_GIFTTIMER, // v0 = ticks down to zero whenever you please this
@ -3572,6 +3583,12 @@ enum FLAG {
F_GODBONUS, // this god gives enum GODBONUS v1 at pietylev v0 F_GODBONUS, // this god gives enum GODBONUS v1 at pietylev v0
// v2 = arg to GB.. // v2 = arg to GB..
// text = arg2 // text = arg2
F_GODBONUSTEXT, // text = what the god says when you get a bonus
F_GODNOBONUSTEXT, // text = what the god says when you lose a bonus
F_GODGIFTTEXT, // text = what the god says when you get a gift
F_GODASK1, // text = how the god asks you to join them
F_GODASK2, // text = how the god asks you to join them (2nd line)
F_GODTEXTAPPEAR, // text = godname ->xxxxx<- (when they teleport in)
F_GODOF, // text = what this lf is the god of. use capitals. F_GODOF, // text = what this lf is the god of. use capitals.
F_GODLIKES, // text = something this god likes (ie. incs piety) F_GODLIKES, // text = something this god likes (ie. incs piety)
F_GODDISLIKES, // text = something this god likes (ie. decs piety) F_GODDISLIKES, // text = something this god likes (ie. decs piety)
@ -3792,6 +3809,8 @@ enum FLAG {
F_FREEZINGTOUCH,// next thing touched turns to ice! F_FREEZINGTOUCH,// next thing touched turns to ice!
// v1 = power // v1 = power
// v2 is save difficulty // v2 is save difficulty
F_FULLSHIELD, // lf is fully hiding behind a shield (obid v0).
// text = obid of shield being used.
F_GRABBEDBY,// you've been grabbed by lf id v0 F_GRABBEDBY,// you've been grabbed by lf id v0
F_GRABBING, // you are grabbing lf id v0 F_GRABBING, // you are grabbing lf id v0
F_HIDING, // lifeform is hiding. v0 is modifier to stealth checks. F_HIDING, // lifeform is hiding. v0 is modifier to stealth checks.
@ -4581,8 +4600,10 @@ enum MAPSHAPE {
MS_CROSS, MS_CROSS,
MS_CIRCLE, MS_CIRCLE,
MS_TURRET, MS_TURRET,
MS_HORZ,
MS_VERT,
}; };
#define MAXMAPSHAPES (4) #define MAXMAPSHAPES (6)
enum CORRIDORTYPE { enum CORRIDORTYPE {
CDT_NORMAL, // make corridors, remove deadends, add rooms, autolink CDT_NORMAL, // make corridors, remove deadends, add rooms, autolink
@ -4637,6 +4658,7 @@ typedef struct celltype_s {
int floorheight; // 0 is default. <0 is low. int floorheight; // 0 is default. <0 is low.
int hp; // hit points left. <0 = invulnerable int hp; // hit points left. <0 = invulnerable
int volumemod; // modifer to footstep volume int volumemod; // modifer to footstep volume
int absorbent; // will this cell absorb liquids?
struct material_s *material; struct material_s *material;
struct flagpile_s *flags; struct flagpile_s *flags;

12
flag.c
View File

@ -620,6 +620,7 @@ int flagcausesloscalc(enum FLAG fid) {
case F_ASLEEP: case F_ASLEEP:
case F_BLIND: case F_BLIND:
case F_BLOCKSVIEW: case F_BLOCKSVIEW:
case F_FULLSHIELD:
case F_NIGHTVISRANGEMOD: case F_NIGHTVISRANGEMOD:
case F_PRONE: case F_PRONE:
case F_PRODUCESLIGHT: case F_PRODUCESLIGHT:
@ -700,6 +701,7 @@ int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid) {
case F_EATING: case F_EATING:
case F_FASTMOVE: case F_FASTMOVE:
case F_FLYING: case F_FLYING:
case F_FULLSHIELD:
case F_GRAVBOOSTED: case F_GRAVBOOSTED:
case F_GUNTARGET: case F_GUNTARGET:
case F_HASNEWLEVEL: case F_HASNEWLEVEL:
@ -1468,6 +1470,7 @@ int flagretainedduringpoly(enum FLAG fid) {
case F_HOSTILE: case F_HOSTILE:
case F_LYCANTHROPE: case F_LYCANTHROPE:
case F_ALIGNMENT: case F_ALIGNMENT:
case F_GENDER:
return B_TRUE; return B_TRUE;
default: break; default: break;
} }
@ -1529,6 +1532,15 @@ int getflags(flagpile_t *fp, flag_t **retflag, int *nretflags, ... ) {
return *nretflags; return *nretflags;
} }
char *getflagtext(flagpile_t *fp, enum FLAG fid) {
flag_t *f;
f = hasflag(fp, fid);
if (f) {
return f->text;
}
return "?unknownflagtext?";
}
void getmaxflags(flagpile_t *fp, int id, int *max0, int *max1, int *max2) { void getmaxflags(flagpile_t *fp, int id, int *max0, int *max1, int *max2) {
flag_t *f; flag_t *f;
if (max0) *max0 = 0; if (max0) *max0 = 0;

1
flag.h
View File

@ -28,6 +28,7 @@ int flagstacks(enum FLAG fid);
int flagtomaxhp(flag_t *f); int flagtomaxhp(flag_t *f);
cell_t *getflagpilelocation(flagpile_t *fp); cell_t *getflagpilelocation(flagpile_t *fp);
int getflags(flagpile_t *fp, flag_t **retflag, int *nretflags, ... ); int getflags(flagpile_t *fp, flag_t **retflag, int *nretflags, ... );
char *getflagtext(flagpile_t *fp, enum FLAG fid);
void getmaxflags(flagpile_t *fp, int id, int *max0, int *max1, int *max2); void getmaxflags(flagpile_t *fp, int id, int *max0, int *max1, int *max2);
flag_t *getrandomflag(flagpile_t *fp, enum FLAG fid); flag_t *getrandomflag(flagpile_t *fp, enum FLAG fid);
flag_t *hasflag(flagpile_t *fp, int id); flag_t *hasflag(flagpile_t *fp, int id);

224
god.c
View File

@ -516,6 +516,37 @@ int angergodmaybe(enum RACE rid, int amt, enum GODANGERREASON why) {
return B_FALSE; return B_FALSE;
} }
void askforworship(enum RACE rid) {
lifeform_t *god;
char yn;
// make sure the player knows about it!
killtransitoryflags(player->flags, F_BLIND);
killtransitoryflags(player->flags, F_DEAF);
god = godappears(rid, NULL);
if (!god) return;
addflag(player->flags, F_GODOFFERDONE, B_TRUE, NA, NA, NULL);
say(god, getflagtext(god->flags, F_GODASK1), SV_TALK); more();
msg("\"%s\"", getflagtext(god->flags, F_GODASK2)); more();
yn = askchar("Will you accept", "yn", "n", B_TRUE, B_FALSE);
if (yn == 'y') {
// should never be true, but check just in case...
if (!godprayedto(rid)) {
addflag(god->flags, F_PRAYEDTO, B_TRUE, NA, NA, NULL);
}
// always get a gift, but announce it first.
say(god, getflagtext(god->flags, F_GODGIFTTEXT), SV_TALK); more();
godgiftmaybe(rid, B_TRUE, B_FALSE);
// increment piety so that it doesn't remain around the border.
modpiety(rid, PIETYPRAYLOSS);
}
}
void checkgodbonus(enum RACE rid, enum PIETYLEV newlev, enum PIETYLEV oldlev) { void checkgodbonus(enum RACE rid, enum PIETYLEV newlev, enum PIETYLEV oldlev) {
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags,i; int nretflags,i;
@ -616,7 +647,7 @@ void dooffer(void) {
} else if ((f->id == F_SACRIFICEOBCLASS) && (f->val[0] == o->type->obclass->id)) { } else if ((f->id == F_SACRIFICEOBCLASS) && (f->val[0] == o->type->obclass->id)) {
ok = B_TRUE; ok = B_TRUE;
thispiety = f->val[2]; thispiety = f->val[2];
// will be override late though, if val[0] is OC_MONEY // will be overridden late though, if val[0] is OC_MONEY
} else if ((f->id == F_SACRIFICEOBWITHFLAG) && hasflag(o->flags, f->val[0])) { } else if ((f->id == F_SACRIFICEOBWITHFLAG) && hasflag(o->flags, f->val[0])) {
ok = B_TRUE; ok = B_TRUE;
thispiety = f->val[2]; thispiety = f->val[2];
@ -627,20 +658,29 @@ void dooffer(void) {
ok = B_TRUE; ok = B_TRUE;
thispiety = f->val[2]; thispiety = f->val[2];
} }
// god of thieves only accepts untouched stuff
if (ok && (god->race->id == R_GODTHIEVES)) {
if (!hasflag(o->flags, F_UNTOUCHED)) {
ok = B_FALSE;
thispiety = 0;
}
}
if (ok) { if (ok) {
char *p; char *p;
char obname[BUFLEN]; char obname[BUFLEN];
cell_t *newcell = NULL; cell_t *newcell = NULL;
// gold/gems are treated differently // gold/gems are treated differently
// if you don't donate at least 100gold worth, you if (o->type->id == OT_GOLD) {
// might not get any piety. thispiety = (getobvalue(o) / 2);
if ((o->type->id == OT_GOLD) || hasflag(o->flags, F_GEM)) { } else if (hasflag(o->flags, F_GEM)) {
if (pctchance(getobvalue(o))) { thispiety = (getobvalue(o) / 50);
thispiety = (getobvalue(o) / 100); //if (pctchance(getobvalue(o))) {
} else { //} else {
thispiety = 0; // thispiety = 0;
} // }
} }
// special effect sacrificing flora to ekrub makes it turn into a // special effect sacrificing flora to ekrub makes it turn into a
@ -873,42 +913,16 @@ enum OBTYPE getrelatedgodstone(enum RACE rid) {
void givegodbonus(enum RACE rid, flag_t *bf) { void givegodbonus(enum RACE rid, flag_t *bf) {
flag_t *f; flag_t *f;
lifeform_t *god;
int targ[3], arg = NA; int targ[3], arg = NA;
enum PIETYLEV bonuslev; enum PIETYLEV bonuslev;
enum GODBONUS bonusid; enum GODBONUS bonusid;
god = findgod(rid);
if (!god) return;
// god announcement. // god announcement.
switch (rid) { godsay(rid, B_TRUE, getflagtext(god->flags, F_GODBONUSTEXT));
case R_GODPURITY:
godsay(rid, B_TRUE, "You have impressed me, mortal!");
break;
case R_GODTHIEVES:
godsay(rid, B_TRUE, "Very impressive...");
break;
case R_GODDEATH:
godsay(rid, B_TRUE, "Your kills are impressive...");
break;
case R_GODFIRE:
godsay(rid, B_TRUE, "DESTROY!");
break;
case R_GODLIFE:
godsay(rid, B_TRUE, "A good life has its rewards!");
break;
case R_GODMERCY:
godsay(rid, B_TRUE, "Your devoutness is impressive.");
break;
case R_GODNATURE:
godsay(rid, B_TRUE, "You are progressing in nature's path...");
break;
case R_GODBATTLE:
godsay(rid, B_TRUE, "Onwards to victory!");
break;
case R_GODMAGIC:
godsay(rid, B_TRUE, "One is on the right path!");
break;
default:
break;
}
more(); more();
// increment piety so that it doesn't keep bouncing around the border. // increment piety so that it doesn't keep bouncing around the border.
@ -964,43 +978,29 @@ void givegodbonus(enum RACE rid, flag_t *bf) {
break; break;
} }
} }
int prayedtoany(void) {
int i;
for (i = 0; i < ngodlfs; i++) {
if (godlf[i] && godprayedto(godlf[i]->race->id)) {
return B_TRUE;
}
}
return B_FALSE;
}
void removegodbonus(enum RACE rid, flag_t *bf) { void removegodbonus(enum RACE rid, flag_t *bf) {
int targ[3], arg = NA; int targ[3], arg = NA;
enum PIETYLEV bonuslev; enum PIETYLEV bonuslev;
enum GODBONUS bonusid; enum GODBONUS bonusid;
lifeform_t *god;
god = findgod(rid);
if (!god) return;
// god announcement. // god announcement.
switch (rid) { godsay(rid, B_TRUE, getflagtext(god->flags, F_GODNOBONUSTEXT));
case R_GODPURITY:
godsay(rid, B_TRUE, "Your service is lacking, mortal.");
break;
case R_GODTHIEVES:
godsay(rid, B_TRUE, "I expect more results, mortal.");
break;
case R_GODDEATH:
godsay(rid, B_TRUE, "Lazy servants can easily be removed...");
break;
case R_GODFIRE:
godsay(rid, B_TRUE, "PAY ATTENTION!");
break;
case R_GODLIFE:
godsay(rid, B_TRUE, "You must be more proactive, my child.");
break;
case R_GODMERCY:
godsay(rid, B_TRUE, "You lack of proactiveness is disappointing...");
break;
case R_GODNATURE:
godsay(rid, B_TRUE, "Nature will not tolerate the lazy.");
break;
case R_GODBATTLE:
godsay(rid, B_TRUE, "Your slothfulness has earned you a demotion, soldier.");
break;
case R_GODMAGIC:
godsay(rid, B_TRUE, "One must always strive towards the path!");
break;
default:
break;
}
more(); more();
// parse regular rags // parse regular rags
@ -1044,7 +1044,10 @@ lifeform_t *godappears(enum RACE rid, cell_t *where) {
// somewhere next to the player. // somewhere next to the player.
where = real_getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, player, MT_NOTHING); where = real_getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, player, MT_NOTHING);
if (!where) { if (!where) {
where = getrandomadjcell(player->cell, B_FALSE, B_NOEXPAND); where = real_getrandomadjcell(player->cell, WE_NOTWALL, B_ALLOWEXPAND, LOF_WALLSTOP, NULL, NULL, player, MT_NOTHING);
}
if (!where) {
where = real_getrandomadjcell(player->cell, WE_NOTWALL, B_ALLOWEXPAND, LOF_DONTNEED, NULL, NULL, player, MT_NOTHING);
} }
} }
@ -1063,6 +1066,21 @@ lifeform_t *godappears(enum RACE rid, cell_t *where) {
} else { } else {
teleportto(god, where, B_TRUE); teleportto(god, where, B_TRUE);
// visual effect for some gods
switch (god->race->id) {
case R_GODBATTLE: // bloodsplatter
addob(god->cell->obpile, "splash of blood");
addobsinradius(god->cell, 2, DT_COMPASS, "splash of blood", B_TRUE, NULL);
break;
case R_GODLIFE: //light
addob(god->cell->obpile, "bright light");
addobsinradius(god->cell, 2, DT_COMPASS, "bright light", B_TRUE, NULL);
break;
case R_GODFIRE: // fire
addob(god->cell->obpile, "large fire");
break;
default: break;
}
} }
return god; return god;
@ -1103,7 +1121,7 @@ int godblocked(enum RACE rid) {
} }
// maybe get a gift // maybe get a gift
int godgiftmaybe(enum RACE rid, int fromtemple) { int godgiftmaybe(enum RACE rid, int fromtemple, int announce) {
lifeform_t *god; lifeform_t *god;
int piety,gotgift = B_FALSE; int piety,gotgift = B_FALSE;
enum PIETYLEV plev; enum PIETYLEV plev;
@ -1140,38 +1158,11 @@ int godgiftmaybe(enum RACE rid, int fromtemple) {
killflagsofid(player->flags, F_ASLEEP); killflagsofid(player->flags, F_ASLEEP);
switch (god->race->id) { if (announce) {
case R_GODPURITY: // god announcement.
godsay(god->race->id, B_TRUE, "I bestow a gift upon you, mortal!"); godsay(rid, B_TRUE, getflagtext(god->flags, F_GODGIFTTEXT));
break;
case R_GODTHIEVES:
godsay(god->race->id, B_TRUE, "Loyalty has its rewards...");
break;
case R_GODDEATH:
godsay(god->race->id, B_TRUE, "Your service has impressed me...");
break;
case R_GODFIRE:
godsay(god->race->id, B_TRUE, "DESTROY IN MY NAME!");
break;
case R_GODLIFE:
godsay(god->race->id, B_TRUE, "Use this gift to spread the joy of life!");
break;
case R_GODMERCY:
godsay(god->race->id, B_TRUE, "As you have shown mercy, so shall you receive it!");
break;
case R_GODNATURE:
godsay(god->race->id, B_TRUE, "Harvest nature's bounty!");
break;
case R_GODBATTLE:
godsay(god->race->id, B_TRUE, "Gather up the spoils of battle!");
break;
case R_GODMAGIC:
godsay(god->race->id, B_TRUE, "One has earned a reward!");
break;
default:
break;
}
more(); more();
}
strcpy(obtogive, ""); strcpy(obtogive, "");
switch (god->race->id) { switch (god->race->id) {
case R_GODBATTLE: case R_GODBATTLE:
@ -1910,6 +1901,17 @@ void pleasegod(enum RACE rid, int amt) {
// don't please/anger gods while enraged. // don't please/anger gods while enraged.
if (lfhasflag(player, F_RAGE)) return; if (lfhasflag(player, F_RAGE)) return;
// if you haven't praeyd to anyone yet, piety
// gain is boosted heaps.
/*
if (!prayedtoany()) {
switch (rid) {
case R_GODTHIEVES: amt *= 4; break;
default: break;
}
}
*/
lf = findgod(rid); lf = findgod(rid);
real_getlfname(lf, lfname, NULL, B_NOSHOWALL, B_REALRACE); real_getlfname(lf, lfname, NULL, B_NOSHOWALL, B_REALRACE);
@ -1959,10 +1961,16 @@ void pleasegod(enum RACE rid, int amt) {
break; break;
} }
} }
godgiftmaybe(rid, B_FALSE); godgiftmaybe(rid, B_FALSE, B_TRUE);
}
// //
checkgodbonus(rid,newplev, oldplev); checkgodbonus(rid,newplev, oldplev);
}
if (!prayedtoany() && !lfhasflag(player, F_GODOFFERDONE)) {
if ((newplev > oldplev) && (newplev >= PL_PLEASED)) {
askforworship(rid);
}
}
} }
void pleasegodmaybe(enum RACE rid, int amt) { void pleasegodmaybe(enum RACE rid, int amt) {
@ -1973,6 +1981,9 @@ void pleasegodmaybe(enum RACE rid, int amt) {
modplev = abs(getpietylev(rid, NULL, NULL)); modplev = abs(getpietylev(rid, NULL, NULL));
if (!prayedtoany()) {
chance = 1;
} else {
// the angrier or more happy the god gets, the harder it // the angrier or more happy the god gets, the harder it
// is to please them. // is to please them.
// ie. INDIFFERENT = 1 in 1 (always) // ie. INDIFFERENT = 1 in 1 (always)
@ -1985,6 +1996,7 @@ void pleasegodmaybe(enum RACE rid, int amt) {
chance--; chance--;
limit(&chance, 1, NA); limit(&chance, 1, NA);
} }
}
if (onein(chance)) { if (onein(chance)) {
pleasegod(rid, amt); pleasegod(rid, amt);

4
god.h
View File

@ -2,6 +2,7 @@
void angergod(enum RACE rid, int amt, enum GODANGERREASON why); void angergod(enum RACE rid, int amt, enum GODANGERREASON why);
int angergodmaybe(enum RACE rid, int amt, enum GODANGERREASON why); int angergodmaybe(enum RACE rid, int amt, enum GODANGERREASON why);
void askforworship(enum RACE rid);
void checkgodbonus(enum RACE rid, enum PIETYLEV newlev, enum PIETYLEV oldlev); void checkgodbonus(enum RACE rid, enum PIETYLEV newlev, enum PIETYLEV oldlev);
void dooffer(void); void dooffer(void);
lifeform_t *findgod(enum RACE rid); lifeform_t *findgod(enum RACE rid);
@ -18,7 +19,7 @@ void givegodbonus(enum RACE rid, flag_t *bf);
lifeform_t *godappears(enum RACE rid, cell_t *where); lifeform_t *godappears(enum RACE rid, cell_t *where);
void god_usepoison_response(void); void god_usepoison_response(void);
int godblocked(enum RACE rid); int godblocked(enum RACE rid);
int godgiftmaybe(enum RACE rid, int fromtemple); int godgiftmaybe(enum RACE rid, int fromtemple, int announce);
int godisangry(enum RACE rid); int godisangry(enum RACE rid);
int godprayedto(enum RACE rid); int godprayedto(enum RACE rid);
void godsay(enum RACE rid, int says, char *format, ...); void godsay(enum RACE rid, int says, char *format, ...);
@ -28,6 +29,7 @@ void parsegodbonusargs(flag_t *bf, enum PIETYLEV *bonuslev, enum GODBONUS *bonus
void pleasegod(enum RACE rid, int amt); void pleasegod(enum RACE rid, int amt);
void pleasegodmaybe(enum RACE rid, int amt); void pleasegodmaybe(enum RACE rid, int amt);
int prayto(lifeform_t *lf, lifeform_t *god); int prayto(lifeform_t *lf, lifeform_t *god);
int prayedtoany(void);
void removegodbonus(enum RACE rid, flag_t *bf); void removegodbonus(enum RACE rid, flag_t *bf);
void setpiety(enum RACE rid, int amt); void setpiety(enum RACE rid, int amt);
int uncurse_one_equipped(lifeform_t *lf, char *text); int uncurse_one_equipped(lifeform_t *lf, char *text);

39
io.c
View File

@ -1311,6 +1311,7 @@ void announcearrival(lifeform_t *lf, map_t *newmap) {
} }
int announceflaggain(lifeform_t *lf, flag_t *f) { int announceflaggain(lifeform_t *lf, flag_t *f) {
object_t *o;
int donesomething = B_FALSE; int donesomething = B_FALSE;
lifeform_t *lf2; lifeform_t *lf2;
char lfname[BUFLEN]; char lfname[BUFLEN];
@ -1672,6 +1673,18 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
case F_FULLSHIELD:
o = hasobid(lf->pack, atol(f->text));
assert(o);
getobname(o,obname,1);
if (isplayer(lf)) {
msg("You are now cowering behind your %s.", noprefix(obname));
donesomething = B_TRUE;
} else {
msg("%s is now cowering behind %s.", lfname, obname);
donesomething = B_TRUE;
}
break;
case F_HEAVENARM: case F_HEAVENARM:
if (isplayer(lf)) { // don't know if monsters get it if (isplayer(lf)) { // don't know if monsters get it
msg("^%cYou are surrounded by a %s!", getlfcol(lf, CC_GOOD), f->text); msg("^%cYou are surrounded by a %s!", getlfcol(lf, CC_GOOD), f->text);
@ -2506,6 +2519,10 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
msg("^%c%s %s less sick now.^n", getlfcol(lf, CC_VGOOD), lfname, isplayer(lf) ? "feel" : "looks"); msg("^%c%s %s less sick now.^n", getlfcol(lf, CC_VGOOD), lfname, isplayer(lf) ? "feel" : "looks");
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_FULLSHIELD:
msg("%s %s no longer fully shielded.", lfname, isplayer(lf) ? "are" : "is");
donesomething = B_TRUE;
break;
case F_HEAVENARM: case F_HEAVENARM:
if (isplayer(lf)) { // don't know if monsters get it if (isplayer(lf)) { // don't know if monsters get it
msg("^%cYour %s vanishes!", getlfcol(lf, CC_BAD), f->text); msg("^%cYour %s vanishes!", getlfcol(lf, CC_BAD), f->text);
@ -11118,8 +11135,10 @@ void drawstatus(void) {
} }
wattron(statwin, A_BOLD); wprintw(statwin, " Trn:"); wattroff(statwin, A_BOLD); wattron(statwin, A_BOLD); wprintw(statwin, " Trn:"); wattroff(statwin, A_BOLD);
wprintw(statwin, "%d/%d%% ", player->skillpoints, if (player->skillpoints > 0) setcol(statwin, C_BOLDGREEN);
(int) ((float)player->skillxp / (float)getspforpoint(player) * 100.0) ); wprintw(statwin, "%d", player->skillpoints);
if (player->skillpoints > 0) unsetcol(statwin, C_BOLDGREEN);
wprintw(statwin, "/%d%% ", (int) ((float)player->skillxp / (float)getspforpoint(player) * 100.0) );
// blinded? // blinded?
@ -11364,6 +11383,13 @@ void drawstatus(void) {
unsetcol(statwin, C_MAGENTA); unsetcol(statwin, C_MAGENTA);
} }
f = lfhasflag(player, F_FULLSHIELD);
if (f) {
setcol(statwin, C_MAGENTA);
wprintw(statwin, " FullShld");
unsetcol(statwin, C_MAGENTA);
}
// construct waiting string // construct waiting string
strcpy(waitbuf, ""); strcpy(waitbuf, "");
/* /*
@ -13876,6 +13902,15 @@ void showlfstats(lifeform_t *lf, int showall) {
mvwprintw(mainwin, y, 0, "Gravity is lessened around %s, preventing fall damage, increasing flight speed and reducing load.", you_l(lf)); mvwprintw(mainwin, y, 0, "Gravity is lessened around %s, preventing fall damage, increasing flight speed and reducing load.", you_l(lf));
y++; y++;
} }
f = lfhasknownflag(lf, F_FULLSHIELD);
if (f && (f->known)) {
object_t *sh;
char obname[BUFLEN];
sh = hasobid(lf->pack, atol(f->text));
getobname(sh, obname, 1);
mvwprintw(mainwin, y, 0, "%s %s fully shielded by %s %s.", you(lf), is(lf), your(lf), obname);
y++;
}
f = lfhasknownflag(lf, F_HEAVENARM); f = lfhasknownflag(lf, F_HEAVENARM);
if (f && (f->known)) { if (f && (f->known)) {
char hpbuf[BUFLEN]; char hpbuf[BUFLEN];

85
lf.c
View File

@ -1937,6 +1937,8 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar
// take time // take time
taketime(lf, getspellspeed(lf)); taketime(lf, getspellspeed(lf));
killflagsofid(lf->flags, F_FULLSHIELD);
if (!fromob) { if (!fromob) {
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags,tempboost = 0,i; int nretflags,tempboost = 0,i;
@ -3075,6 +3077,10 @@ void die(lifeform_t *lf) {
willbecomeghost = B_TRUE; willbecomeghost = B_TRUE;
} }
// remove poison when you die
killflagsofid(lf->flags, F_INCUBATING);
killflagsofid(lf->flags, F_POISONED);
// died after entering a new level without a chance to move? // died after entering a new level without a chance to move?
// note that this won't save you frmo bring killed by a monster which // note that this won't save you frmo bring killed by a monster which
// chases you up/down the stairs. // chases you up/down the stairs.
@ -5056,10 +5062,10 @@ int eat(lifeform_t *lf, object_t *o) {
} }
// eating animals pleases ekrub // eating animals pleases ekrub
if (corpserace && (corpserace->raceclass->id == RC_ANIMAL)) { if (corpserace && (corpserace->raceclass->id == RC_ANIMAL)) {
if (gethungerlevel(gethungerval(lf)) > H_NONE) { //if (gethungerlevel(gethungerval(lf)) > H_NONE) {
pleasegodmaybe(R_GODNATURE, 5); pleasegodmaybe(R_GODNATURE, 5);
addflag(o->flags, F_NOSACRIFICE, B_TRUE, NA, NA, NULL); addflag(o->flags, F_NOSACRIFICE, B_TRUE, NA, NA, NULL);
} //}
} }
} }
@ -5835,6 +5841,7 @@ int fall(lifeform_t *lf, lifeform_t *fromlf, int announce) {
addflag(lf->flags, F_PRONE, B_TRUE, NA, NA, NULL); addflag(lf->flags, F_PRONE, B_TRUE, NA, NA, NULL);
loseconcentration(lf); loseconcentration(lf);
interrupt(lf);
breakgrabs(lf, B_TRUE, B_TRUE); breakgrabs(lf, B_TRUE, B_TRUE);
if (isvulnto(lf->flags, DT_FALL, B_FALSE)) { if (isvulnto(lf->flags, DT_FALL, B_FALSE)) {
// 0 will be repplaced with the dtvuln flag // 0 will be repplaced with the dtvuln flag
@ -7677,6 +7684,10 @@ int getevasion(lifeform_t *lf) {
} }
} }
if (lfhasflag(lf, F_FULLSHIELD)) {
ev -= 50;
}
// modify for stickiness // modify for stickiness
if (hasobwithflag(lf->cell->obpile, F_RESTRICTMOVEMENT)) { if (hasobwithflag(lf->cell->obpile, F_RESTRICTMOVEMENT)) {
ev -= 50; ev -= 50;
@ -8320,6 +8331,10 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) {
// modify for weilder's level // modify for weilder's level
acc += (lf->level * 2); acc += (lf->level * 2);
if (lfhasflag(lf, F_FULLSHIELD)) {
acc -= 50;
}
if (lfhasflag(lf, F_RAGE)) { if (lfhasflag(lf, F_RAGE)) {
// huge bonus // huge bonus
acc += 50; acc += 50;
@ -9278,6 +9293,10 @@ int getvisrange(lifeform_t *lf, int useambient) {
// can't see as far if you're on the ground // can't see as far if you're on the ground
range /= 2; range /= 2;
} }
if (lfhasflag(lf, F_FULLSHIELD)) {
if (range > 1) range = 1;
}
limit(&range, 0, MAXVISRANGE); limit(&range, 0, MAXVISRANGE);
return range; return range;
} }
@ -9525,6 +9544,11 @@ char *real_getlfname(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall,
lorelev = PR_MASTER; lorelev = PR_MASTER;
} }
f = hasname(lf);
if (f) {
strcpy(the, "");
strcpy(lname, f->text);
} else {
// 'the' or 'your' ? // 'the' or 'your' ?
f = lfhasflag(lf, F_NAME); f = lfhasflag(lf, F_NAME);
if (f) { if (f) {
@ -9548,6 +9572,7 @@ char *real_getlfname(lifeform_t *lf, char *buf, lifeform_t *usevis, int showall,
strcpy(lname, lfrace->name); strcpy(lname, lfrace->name);
} }
} }
}
// construct description string // construct description string
strcpy(descstring, ""); strcpy(descstring, "");
@ -9702,7 +9727,7 @@ char *real_getlfnamea(lifeform_t *lf, char *buf, lifeform_t * usevis, int showal
real_getlfname(lf, buf2, usevis, showall, useorigrace); real_getlfname(lf, buf2, usevis, showall, useorigrace);
if (lfhasflag(lf, F_NAME) || lfhasflag(lf, F_UNIQUE)) { if (hasname(lf) || lfhasflag(lf, F_UNIQUE)) {
strcpy(the, ""); strcpy(the, "");
} else { } else {
if (ispetof(lf, player)) { if (ispetof(lf, player)) {
@ -12315,6 +12340,23 @@ int hastempinjuries(lifeform_t *lf) {
return count; return count;
} }
flag_t *hasname(lifeform_t *lf) {
flag_t *nameflag = NULL,*f;
// check for polymorphed named creatures
f = lfhasflag(lf, F_ORIGRACE);
if (f) {
race_t *origrace;
origrace = findrace(f->val[0]);
if (origrace) {
nameflag = hasflag(origrace->flags, F_NAME);
}
}
if (!nameflag) {
nameflag = lfhasflag(lf, F_NAME);
}
return nameflag;
}
/* /*
int hassubjob(lifeform_t *lf, enum SUBJOB id) { int hassubjob(lifeform_t *lf, enum SUBJOB id) {
flag_t *f; flag_t *f;
@ -13143,7 +13185,7 @@ int haslofknown(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdes
} }
// got line of fire to dest? if lof is blocked, return last cell in 'newdest' // got line of fire to dest? if lof is blocked, return last cell in 'newdest'
// if 'srclf' is set, we are checking whether 'srclf' THINKS they have line of fire. ie invisible/unseed // if 'srclf' is set, we are checking whether 'srclf' THINKS they have line of fire. ie invisible/unseed
// lifeforms don't block lof. // lifeforms don't block lof. also srclf won't be able to block its own lof.
// //
// if 'walllfsok' is set, then we ARE allowed to have lineoffire to walls (ie. solid cells) if there is a lifeform // if 'walllfsok' is set, then we ARE allowed to have lineoffire to walls (ie. solid cells) if there is a lifeform
// there. // there.
@ -13238,7 +13280,7 @@ int haslof_real(cell_t *src, cell_t *dest, enum LOFTYPE loftype, cell_t **newdes
// lifeforms block lof unless: // lifeforms block lof unless:
// - they're in the first cell (ie the one doing the throwing/firing/shooting/etc) // - they're in the first cell (ie the one doing the throwing/firing/shooting/etc)
// - they're in our destination // - they're in our destination
if (cell->lf && (!isprone(cell->lf)) && (loftype & LOF_LFSSTOP)) { if (cell->lf && (!isprone(cell->lf)) && (loftype & LOF_LFSSTOP) && (cell->lf != srclf)) {
int lfcanblocklof = B_TRUE; int lfcanblocklof = B_TRUE;
if (srclf && !cansee(srclf, cell->lf)) { if (srclf && !cansee(srclf, cell->lf)) {
@ -15839,6 +15881,8 @@ int loadfirearmfast(lifeform_t *lf, int onpurpose) {
} }
void loseconcentration(lifeform_t *lf) { void loseconcentration(lifeform_t *lf) {
killflagsofid(lf->flags, F_FULLSHIELD);
// stop sprinting // stop sprinting
stopsprinting(lf); stopsprinting(lf);
@ -17449,11 +17493,13 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
} else if (noisemaker && !isplayer(noisemaker) && (nclass == NC_MOVEMENT)) { } else if (noisemaker && !isplayer(noisemaker) && (nclass == NC_MOVEMENT)) {
// monsters won't turn to face other monsters' footsteps // monsters won't turn to face other monsters' footsteps
} else if (tf) { } else if (tf) {
lifeform_t *targlf = NULL;
if (tf->id == F_TARGETLF) { if (tf->id == F_TARGETLF) {
lifeform_t *targlf;
// will probably ignore the sound unless // will probably ignore the sound unless
// it is closer. // it is closer.
targlf = gettargetlf(l); targlf = findlf(l->cell->map, tf->val[0]);
}
if (targlf) {
if (getcelldist(l->cell, c) < getcelldist(l->cell, targlf->cell)) { if (getcelldist(l->cell, c) < getcelldist(l->cell, targlf->cell)) {
if ((volume >= 4) && onein(2)) { if ((volume >= 4) && onein(2)) {
willrespond = B_TRUE; willrespond = B_TRUE;
@ -19592,8 +19638,13 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
msg("^wYou revert to your original form!"); msg("^wYou revert to your original form!");
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
getlfname(lf, buf); getlfname(lf, buf);
if (hasname(lf)) {
msg("^w%s transforms back to %s original form!", newrace->name,
(getgender(lf) == G_FEMALE) ? "her" : "his");
} else {
msg("^wThe %s transforms back to its original form!", newrace->name); msg("^wThe %s transforms back to its original form!", newrace->name);
} }
}
//} //}
// reverting from initial lycanthrope change? // reverting from initial lycanthrope change?
@ -19706,7 +19757,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
// set material // set material
lf->material = lf->race->material; lf->material = lf->race->material;
// inherit most flags from race // inherit most flags from new race
for (f = lf->race->flags->first ; f ; f = f->next) { for (f = lf->race->flags->first ; f ; f = f->next) {
int ignorethis = B_FALSE; int ignorethis = B_FALSE;
switch (f->id) { switch (f->id) {
@ -22248,7 +22299,7 @@ void startlfturn(lifeform_t *lf) {
// effects for/on your own flags // effects for/on your own flags
getflags(lf->flags, retflag, &nretflags, F_ANTICIPATE, F_ATTACHEDTO, F_CANCAST, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FEIGNFOOLEDBY,F_FLEEFROM, getflags(lf->flags, retflag, &nretflags, F_ANTICIPATE, F_ATTACHEDTO, F_CANCAST, F_CANWILL, F_CHARMEDBY, F_CLIMBING, F_FEIGNFOOLEDBY,F_FLEEFROM,
F_GRABBEDBY, F_GRABBING, F_HIDING, F_BOOSTSPELL, F_FEIGNINGDEATH, F_HPDRAIN, F_INCUBATING, F_INJURY, F_GRABBEDBY, F_GRABBING, F_HIDING, F_BOOSTSPELL, F_FEIGNINGDEATH, F_FULLSHIELD,F_HPDRAIN, F_INCUBATING, F_INJURY,
F_NOFLEEFROM, F_PETOF, F_SIZETIMER, F_SPOTTED, F_STRIKETOKO, F_TARGETCELL, F_TARGETLF, F_NONE); F_NOFLEEFROM, F_PETOF, F_SIZETIMER, F_SPOTTED, F_STRIKETOKO, F_TARGETCELL, F_TARGETLF, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
@ -22294,6 +22345,15 @@ void startlfturn(lifeform_t *lf) {
} }
} }
if (f->id == F_FULLSHIELD) {
object_t *sh;
sh = hasobid(lf->pack, atol(f->text));
if (!sh || !isequipped(sh)) {
killflag(f);
continue;
}
}
if (f->id == F_GRABBEDBY) { if (f->id == F_GRABBEDBY) {
lifeform_t *lf2; lifeform_t *lf2;
lf2 = findlf(NULL, f->val[0]); lf2 = findlf(NULL, f->val[0]);
@ -23626,6 +23686,9 @@ int useability(lifeform_t *lf, enum OBTYPE aid, lifeform_t *who, cell_t *where)
} }
} }
if (aid != OT_A_FULLSHIELD) {
killflagsofid(lf->flags, F_FULLSHIELD);
}
// taketime() will happen during abiltiyeffects() // taketime() will happen during abiltiyeffects()
// use the ability // use the ability
@ -23711,7 +23774,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
object_t *dstportal; object_t *dstportal;
wantdepth = rnd(1,lf->cell->map->region->rtype->maxdepth); wantdepth = rnd(1,lf->cell->map->region->rtype->maxdepth);
// generate random destination portal // generate random destination portal
dstportal = linkportal(o, wantdepth); dstportal = linkportaltodepth(o, wantdepth);
if (dstportal) { if (dstportal) {
flag_t *newf; flag_t *newf;
// if source portal is temporary, make the // if source portal is temporary, make the
@ -23871,7 +23934,7 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
if (curmap->depth < MAXDEPTH) { if (curmap->depth < MAXDEPTH) {
newdepth = rnd(curmap->depth, curmap->depth + 5); newdepth = rnd(curmap->depth, curmap->depth + 5);
limit(&newdepth, curmap->depth, MAXDEPTH); limit(&newdepth, curmap->depth, MAXDEPTH);
linkportal(o, newdepth); linkportaltodepth(o, newdepth);
newcell = getstairdestination(o, &madenewmap); newcell = getstairdestination(o, &madenewmap);
} }
if (!newcell) { if (!newcell) {

1
lf.h
View File

@ -313,6 +313,7 @@ int real_hasfreeaction(lifeform_t *lf, enum FLAG exception);
int hashealableinjuries(lifeform_t *lf); int hashealableinjuries(lifeform_t *lf);
job_t *hasjob(lifeform_t *lf, enum JOB job); job_t *hasjob(lifeform_t *lf, enum JOB job);
int hasjobcat(lifeform_t *lf, enum JOBCATEGORY jcid); int hasjobcat(lifeform_t *lf, enum JOBCATEGORY jcid);
flag_t *hasname(lifeform_t *lf);
//int hassubjob(lifeform_t *lf, enum SUBJOB id); //int hassubjob(lifeform_t *lf, enum SUBJOB id);
int hassoul(lifeform_t *lf); int hassoul(lifeform_t *lf);
void inc_quad_range(enum QUADRANT *start, enum QUADRANT *end, int howmuch); void inc_quad_range(enum QUADRANT *start, enum QUADRANT *end, int howmuch);

470
map.c
View File

@ -980,7 +980,7 @@ int autodoors(map_t *map, int roomid, int minx, int miny, int maxx, int maxy, in
int possdir[MAXCANDIDATES]; int possdir[MAXCANDIDATES];
int ncells = 0, npossible = 0; int ncells = 0, npossible = 0;
int doorsadded = 0; int doorsadded = 0;
int db = B_TRUE; int db = B_FALSE;
if (db) dblog("autodoors starting"); if (db) dblog("autodoors starting");
@ -2018,9 +2018,101 @@ int doelementspread(cell_t *c) {
return B_FALSE; return B_FALSE;
} }
// returns # cells filled in
int dodoorfill(cell_t *c) {
int dir,nfilled = 0,db = B_FALSE;
cell_t *firstadj = NULL;
int firstdir = D_NONE;
// fill in the door cell itself
c->filled = B_TRUE;
// empty all surrounding cells
for (dir = DC_N; dir <= DC_NW; dir++) {
cell_t *c2;
c2 = getcellindir(c, dir);
if (c2) {
c2->filled = B_FALSE;
if (!firstadj && !issolid(c2)) {
firstadj = c2;
firstdir = dir;
}
}
}
if (db) dblog("first dir was %s\n",getdirname(firstdir));
if (!firstadj) return 0;
// floodfill from an adacent cell
doorfill_r(c, firstadj, &nfilled);
// debug...
if (db) {
int order[9] = {
DC_NW, DC_N, DC_NE,
DC_W, D_NONE, DC_E,
DC_SW, DC_S, DC_SE
};
int i;
char buf[BUFLEN];
cell_t *c2;
strcpy(buf, "");
for (i = 0; i < 9; i++) {
dir = order[i];
if (dir == D_NONE) {
strcat(buf, "+");
} else {
c2 = getcellindir(c, dir);
if (c2) {
if (c2->filled) {
strcat(buf, "F");
} else {
if (issolid(c2)) {
strcat(buf, "#");
} else {
strcat(buf, ".");
}
}
} else {
strcat(buf, "x");
}
}
switch (dir) {
case DC_NE:
case DC_E:
case DC_SE:
dblog("%s", buf);
strcpy(buf, "");
break;
}
}
}
return nfilled;
}
void doorfill_r(cell_t *startcell, cell_t *c, int *nfilled) {
int d;
if (c && // not off the map
!c->type->solid && // empty cell
!c->filled && // not already filled
!hasdoor(c) && // not a door
(getcelldist(startcell,c) == 1) // adjacent to first cell
) {
if (nfilled) (*nfilled)++;
c->filled = B_TRUE;
} else {
return;
}
for (d = DC_N; d <= DC_NW; d++) {
doorfill_r(startcell, getcellindir(c, d), nfilled); // recursive call
}
}
int fix_reachability(map_t *m) { int fix_reachability(map_t *m) {
int i,keepgoing = B_TRUE, nfixed = 0; int i,nfixed = 0;
int db = B_TRUE; int db = B_TRUE;
cell_t *unreachcell[MAX_MAPW*MAX_MAPH];
cell_t *reachcell[MAX_MAPW*MAX_MAPH];
int nunreach = 0,nreach = 0;
cell_t *c = NULL; cell_t *c = NULL;
if (db) dblog("fix_reachability starting."); if (db) dblog("fix_reachability starting.");
@ -2044,15 +2136,18 @@ int fix_reachability(map_t *m) {
} }
// no empty cells in map? // no empty cells in map?
if (!c) return B_FALSE; if (!c) return B_FALSE;
while (keepgoing) { nunreach = 1;
keepgoing = B_FALSE; while (nunreach) {
// mark all cells as non-filled // mark all cells as non-filled
for (i = 0; i < m->w * m->h; i++) { for (i = 0; i < m->w * m->h; i++) {
m->cell[i]->filled = FALSE; m->cell[i]->filled = FALSE;
} }
// floodfill // floodfill
floodfill(c); floodfill(c);
// any remaining non-filled empty cells? // any remaining non-filled empty cells?
nunreach = 0;
nreach = 0;
for (i = 0; i < m->w * m->h; i++) { for (i = 0; i < m->w * m->h; i++) {
if (!m->cell[i]->type->solid && !m->cell[i]->filled && if (!m->cell[i]->type->solid && !m->cell[i]->filled &&
((m->cell[i]->room && m->cell[i]->room->prevault) || !m->cell[i]->locked ) ) { ((m->cell[i]->room && m->cell[i]->room->prevault) || !m->cell[i]->locked ) ) {
@ -2061,19 +2156,57 @@ int fix_reachability(map_t *m) {
if (v && hasflag(v->flags, F_VAULTNOLINK)) { if (v && hasflag(v->flags, F_VAULTNOLINK)) {
// don't need to link it. // don't need to link it.
} else { } else {
int nadded = 0; unreachcell[nunreach++] = m->cell[i];
// found an unreachable cell! link it back to a filled cell. }
if (db) dblog(" found unreachable area at %d,%d. will fix it.", } else {
m->cell[i]->x, m->cell[i]->y); if (!m->cell[i]->type->solid) {
// reachable.
reachcell[nreach++] = m->cell[i];
}
}
}
// try to fix unreachable areas.
if (nunreach) {
int nadded = 0,nportals = 0;
int idx,ntries = 0,maxtries = 5;
cell_t *ucell;
// pick one of the unreachable cells
while (ntries < maxtries) {
idx = rnd(0,nunreach-1);
ucell = unreachcell[idx];
// try to link it back to a filled cell.
if (db) dblog(" attempting to fix unreachable area at %d,%d.",
ucell->x, ucell->y);
if (linkexit(m->cell[i], B_TRUE, &nadded)) { if (!linkexit(ucell, B_TRUE, &nadded)) {
// failed! // fixed.
if (db) dblog(" fix_reachability failed - couldn't fix an unreachable area."); if (db) dblog(" successfully fixed by digging tunnels.");
return B_TRUE; break;
} else {
if (db) dblog("failed, trying new cell.");
ntries++;
}
}
if (ntries >= maxtries) {
cell_t *rcell;
int ptries = 0;
// failed! try to link via portals.
if (db) dblog(" couldn't link via tunnels. trying to link via portals.");
// select random REACHABLE cell
while (ptries < maxtries) {
rcell = reachcell[rnd(0,nreach-1)];
if (!createportallink(ucell,rcell, OT_PORTAL)) {
if (db) dblog(" successfully fixed by adding portals.");
nportals++;
break;
} else {
ptries++;
}
}
} }
if (nadded) { if (nadded || nportals) {
if (db) dblog(" fixed unreachable area by adding %d cells.", nadded); if (db) dblog(" fixed unreachable area by adding %d cells and %d portals.", nadded,nportals);
} else { } else {
// didn't add anything - fail! // didn't add anything - fail!
if (db) dblog(" fix_reachability failed."); if (db) dblog(" fix_reachability failed.");
@ -2082,12 +2215,8 @@ int fix_reachability(map_t *m) {
// now run the test again. // now run the test again.
// 'c' will be where the next flood will will happen. // 'c' will be where the next flood will will happen.
keepgoing = B_TRUE; c = ucell;
c = m->cell[i];
nfixed++; nfixed++;
break;
}
}
} }
} }
if (db) dblog(" fix_reachability complete. fixed %d unreachable areas.", nfixed); if (db) dblog(" fix_reachability complete. fixed %d unreachable areas.", nfixed);
@ -2097,6 +2226,7 @@ int fix_reachability(map_t *m) {
void floodfill(cell_t *startcell) { void floodfill(cell_t *startcell) {
int d; int d;
object_t *o;
if (startcell && // not off the map if (startcell && // not off the map
!startcell->type->solid && // empty cell !startcell->type->solid && // empty cell
!startcell->filled) { // not already filled !startcell->filled) { // not already filled
@ -2107,6 +2237,23 @@ void floodfill(cell_t *startcell) {
for (d = DC_N; d <= DC_NW; d++) { for (d = DC_N; d <= DC_NW; d++) {
floodfill(getcellindir(startcell, d)); // recursive call floodfill(getcellindir(startcell, d)); // recursive call
} }
// follow portals
o = hasob(startcell->obpile, OT_PORTAL);
if (o) {
flag_t *f;
// not using getstairdest cause we don't want to generate
// new levels due to unlinked portals.
f = hasflag(o->flags, F_MAPLINK);
if (f && (f->val[0] == startcell->map->id) &&
(f->val[1] != NA) && (f->val[2] != NA)) {
cell_t *c;
c = getcellat(startcell->map, f->val[1], f->val[2]);
if (c) {
floodfill(c); // recursive call
dblog("FLOODFILL THROUGH PORTAL");
}
}
}
} }
// populates thing & nthings with all "regionthings" with: // populates thing & nthings with all "regionthings" with:
@ -3197,7 +3344,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
int moved = 0; int moved = 0;
enum CELLTYPE emptycell,solidcell; enum CELLTYPE emptycell,solidcell;
char buf[BUFLEN]; //char buf[BUFLEN];
// select dungeon shape. // select dungeon shape.
if (onein(3)) { if (onein(3)) {
@ -3208,6 +3355,40 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
switch (shape) { switch (shape) {
case MS_NORMAL:// normal case MS_NORMAL:// normal
break; break;
case MS_HORZ: // horizontal bar
// ######
// ######
//
// ######
// ######
for (y = 0; y < map->h/4; y++) {
for (x = 0; x < map->w; x++) {
c = getcellat(map, x, y); c->locked = B_TRUE;
}
}
for (y = (map->h/4)*3; y < map->h; y++) {
for (x = 0; x < map->w; x++) {
c = getcellat(map, x, y); c->locked = B_TRUE;
}
}
break;
case MS_VERT: // vertical bar
// ## ##
// ## ##
// ## ##
// ## ##
// ## ##
for (x = 0; x < map->w/4; x++) {
for (y = 0; y < map->h; y++) {
c = getcellat(map, x, y); c->locked = B_TRUE;
}
}
for (x = (map->w/4)*3; x < map->w; x++) {
for (y = 0; y < map->h; y++) {
c = getcellat(map, x, y); c->locked = B_TRUE;
}
}
break;
case MS_CROSS: // cross case MS_CROSS: // cross
// ## ## // ## ##
// ## ## // ## ##
@ -3276,6 +3457,17 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
} }
addflag(map->flags, F_MAPSHAPE, shape, NA, NA, NULL); addflag(map->flags, F_MAPSHAPE, shape, NA, NA, NULL);
for (y = 0; y < map->h; y++) {
for (x = 0; x < map->w; x++) {
c = getcellat(map, x, y);
if (c->locked) {
c->visited = B_TRUE;
}
}
}
/*
for (y = 0; y < map->h; y++) { for (y = 0; y < map->h; y++) {
strcpy(buf, ""); strcpy(buf, "");
for (x = 0; x < map->w; x++) { for (x = 0; x < map->w; x++) {
@ -3291,6 +3483,7 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
} }
dblog("%s",buf); dblog("%s",buf);
} }
*/
// randomise dungeon parameters // randomise dungeon parameters
turnpct += (rnd(0,40)-20); // (-20 to +20)% turnpct += (rnd(0,40)-20); // (-20 to +20)%
@ -4233,6 +4426,9 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
} }
} }
if (!failed) {
remove_baddoors(map);
}
// ensure there are no unreachable areas // ensure there are no unreachable areas
if (!failed) { if (!failed) {
if (fix_reachability(map)) { if (fix_reachability(map)) {
@ -4256,7 +4452,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
expand_cave(map, 2); expand_cave(map, 2);
} }
// add any required stairs // add any required stairs, fix doors, etc.
finalisemap(map, entryob, exitdir); finalisemap(map, entryob, exitdir);
// special cases // special cases
@ -5442,7 +5638,7 @@ int linkexits(map_t *m, int roomid) {
int x,y,i; int x,y,i;
cell_t *poss[MAXCANDIDATES],*c; cell_t *poss[MAXCANDIDATES],*c;
int nposs = 0; int nposs = 0;
int db = B_TRUE; int db = B_FALSE;
int nadded = 0; int nadded = 0;
int minx = -1, miny = -1, maxx = -1, maxy = -1; int minx = -1, miny = -1, maxx = -1, maxy = -1;
int roomidx = -1; int roomidx = -1;
@ -5666,6 +5862,52 @@ void createbranchlink(map_t *m, cell_t *c, object_t *o, char *obname, enum BRANC
f->val[1] = r->id; f->val[1] = r->id;
} }
// return true on error
int createportallink(cell_t *src, cell_t *dst, enum OBTYPE portalid) {
object_t *dstportal = NULL,*srcportal = NULL;
// make sure cells exist
if (!src || !dst) {
dblog(" createportals(): src or dst cell doesn't exist");
return B_TRUE;
}
// make sure cells are empty
if (issolid(src) || issolid(dst)) {
dblog(" createportals(): src or dst cell is solid");
return B_TRUE;
}
// make sure neither cell has a portal already
if (hasob(src->obpile, portalid) || hasob(dst->obpile, portalid)) {
dblog(" createportals(): src or dst cell already has a portal");
return B_TRUE;
}
// add the portals
srcportal = addobfast(src->obpile, portalid);
if (!srcportal) {
dblog(" createportals(): couldn't create source portal.");
return B_TRUE;
}
dstportal = addobfast(dst->obpile, portalid);
if (!dstportal) {
dblog(" createportals(): couldn't create destination portal.");
killob(srcportal);
return B_TRUE;
}
linkportals(srcportal,dstportal);
return B_FALSE;
}
int linkportals(object_t *srcportal, object_t *dstportal) {
cell_t *src,*dst;
src = getoblocation(srcportal);
dst = getoblocation(dstportal);
if (!src || !dst) return B_TRUE;
// link them
addflag_real(srcportal->flags, F_MAPLINK, dst->map->id, dst->x, dst->y, NULL, PERMENANT, B_FALSE, -1);
addflag_real(dstportal->flags, F_MAPLINK, src->map->id, src->x, src->y, NULL, PERMENANT, B_FALSE, -1);
return B_FALSE;
}
void createriver(map_t *m) { void createriver(map_t *m) {
int dir,width,startcentre,endcentre; int dir,width,startcentre,endcentre;
cell_t *retcell[MAX_MAPW*MAX_MAPH]; cell_t *retcell[MAX_MAPW*MAX_MAPH];
@ -5884,6 +6126,36 @@ int dirtoy(int dt, int dir) {
return 0; return 0;
} }
int doorisvalid(object_t *o) {
int dir,nfilled = 0;
cell_t *c;
c = getoblocation(o);
/*
// doors must be between two solid cells
for (dir = DC_N; dir <= DC_SE; dir++) {
cell_t *c1;
cell_t *c2;
c1 = getcellindir(c, dir);
c2 = getcellindir(c, diropposite(dir));
if (!issolid(c1) && !issolid(c2)) {
return B_TRUE;
}
}
*/
if (!dodoorfill(c)) {
// door is surrounded by walls
return B_FALSE;
}
// if there are any empty unfilled cells around the door, it's ok.
nfilled = 0;
for (dir = DC_N; dir <= DC_NW; dir++) {
cell_t *c2;
c2 = getcellindir(c, dir);
if (c2 && !issolid(c2) && !c2->filled) return B_TRUE;
}
return B_FALSE;
}
void dumpmap(map_t *map, int showrooms) { void dumpmap(map_t *map, int showrooms) {
int x,y; int x,y;
@ -6205,45 +6477,12 @@ void finalisemap(map_t *map, object_t *entryob, int exitdir) {
} }
} }
// other finalisation tasks... // other finalisation tasks...
for (y = 0; y < map->h; y++) { for (y = 0; y < map->h; y++) {
for (x = 0; x < map->w; x++) { for (x = 0; x < map->w; x++) {
c = getcellat(map, x, y); c = getcellat(map, x, y);
for (o = c->obpile->first ; o ; o = nexto) { for (o = c->obpile->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
if (!getcellvault(c)) {
// remove doors which go nowhere (internal to rooms)
if (isdoor(o, NULL)) {
int dir, ok = B_FALSE;
/*
// check all directions for a cell which isn't
// part of this room.
for (dir = DC_N; dir <= DC_NW; dir++) {
c2 = getcellindir(c, dir);
if (c2 && cellwalkable(NULL, c2, NULL) && getroomid(c2) != getroomid(c)) {
ok = B_TRUE;
break;
}
}
*/
// doors must be between two solid cells
for (dir = DC_N; dir <= DC_NW; dir++) {
cell_t *c1;
cell_t *c2;
c1 = getcellindir(c, dir);
c2 = getcellindir(c, diropposite(dir));
if (issolid(c1) && issolid(c2)) {
ok = B_TRUE;
break;
}
}
if (!ok) {
killob(o);
continue;
}
}
}
// unlinked stairs? ie ones added from vaults. if so, link them. // unlinked stairs? ie ones added from vaults. if so, link them.
if (hasflag(o->flags, F_CLIMBABLE) && !hasflag(o->flags, F_MAPLINK)) { if (hasflag(o->flags, F_CLIMBABLE) && !hasflag(o->flags, F_MAPLINK)) {
if (!hasflag(o->flags, F_PORTAL)) { if (!hasflag(o->flags, F_PORTAL)) {
@ -6998,12 +7237,16 @@ cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LO
int numwithlof = 0; int numwithlof = 0;
for (y = c->y - radius ; y <= c->y + radius ; y++) { for (y = c->y - radius ; y <= c->y + radius ; y++) {
for (x = c->x - radius ; x <= c->x + radius ; x++) { for (x = c->x - radius ; x <= c->x + radius ; x++) {
int gotlof = B_FALSE;
new = getcellat(c->map, x, y); new = getcellat(c->map, x, y);
if (new && haslof(c, new, needlof, NULL)) {
gotlof = B_TRUE;
numwithlof++;
}
if (new && if (new &&
(new != c) && (new != c) &&
(getcelldist(c,new) == radius) && (getcelldist(c,new) == radius) &&
(new != dontwantcell) && (new != dontwantcell) && gotlof) {
haslof(c, new, needlof, NULL)) {
enum OBTYPE *badoid; enum OBTYPE *badoid;
int ok = B_FALSE; int ok = B_FALSE;
numwithlof++; numwithlof++;
@ -7036,7 +7279,9 @@ cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LO
} }
// found any possibilities ? // found any possibilities ?
if (nposs) { if (preferlos && nlosposs) {
done = B_TRUE;
} else if (!preferlos && nposs) {
done = B_TRUE; done = B_TRUE;
} else { } else {
if (allowexpand) { if (allowexpand) {
@ -7044,12 +7289,24 @@ cell_t *real_getrandomadjcell(cell_t *c, int wantempty, int allowexpand, enum LO
// increment radius // increment radius
radius++; radius++;
} else { } else {
return NULL; if (preferlos) {
} // start again without preferlos
radius = 1;
preferlos = NULL;
} else { } else {
return NULL; return NULL;
} }
} }
} else {
if (preferlos) {
// start again without preferlos
radius = 1;
preferlos = NULL;
} else {
return NULL;
}
}
}
} }
// select a random cell // select a random cell
@ -7431,33 +7688,33 @@ void initmap(void) {
addhabitat(H_MASTERVAULTS, "master vaults", CT_FLOORDURANITE, CT_WALLDURANITE, 5, 0, 0, MAXVISRANGE, OT_VSTAIRSUP, OT_VSTAIRSDOWN); addhabitat(H_MASTERVAULTS, "master vaults", CT_FLOORDURANITE, CT_WALLDURANITE, 5, 0, 0, MAXVISRANGE, OT_VSTAIRSUP, OT_VSTAIRSDOWN);
// cell types - solid // cell types - solid
// floorheight, hp, volmod // floorheight, hp, volmod, absorbant
addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 50, 0); addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 50, 0, B_NOABSORB);
addcelltype(CT_WALLBRICK, "brick wall", UNI_SHADEDARK, C_ORANGE, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 40, 0); addcelltype(CT_WALLBRICK, "brick wall", UNI_SHADEDARK, C_ORANGE, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 40, 0, B_NOABSORB);
addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEMED, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 20, 0); addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEMED, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 20, 0, B_NOABSORB);
addcelltype(CT_WALLDURANITE, "duranite wall", UNI_SHADEDARK, C_MAGENTA, NA, B_SOLID, B_OPAQUE, MT_DURANITE, 0, 20000, 0); addcelltype(CT_WALLDURANITE, "duranite wall", UNI_SHADEDARK, C_MAGENTA, NA, B_SOLID, B_OPAQUE, MT_DURANITE, 0, 20000, 0, B_NOABSORB);
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30, 0); addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30, 0, B_NOABSORB);
addcelltype(CT_WALLDWOOD, "wyrmwood wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_DRAGONWOOD, 0, 100, 0); addcelltype(CT_WALLDWOOD, "wyrmwood wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_DRAGONWOOD, 0, 100, 0, B_NOABSORB);
addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, NA, B_SOLID, B_OPAQUE, MT_FLESH, 0, 25, 0); addcelltype(CT_WALLFLESH, "flesh wall", UNI_SOLID, C_RED, NA, B_SOLID, B_OPAQUE, MT_FLESH, 0, 25, 0, B_NOABSORB);
addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, NA, B_SOLID, B_TRANS, MT_GLASS, 0, 20, 0); addcelltype(CT_WALLGLASS, "glass wall", UNI_SOLID, C_CYAN, NA, B_SOLID, B_TRANS, MT_GLASS, 0, 20, 0, B_NOABSORB);
//addcelltype(CT_WALLTREE, "dense bushland", UNI_SHADEDARK, C_GREEN, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100); //addcelltype(CT_WALLTREE, "dense bushland", UNI_SHADEDARK, C_GREEN, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100);
addcelltype(CT_WALLTREE, "dense bushland", UNI_TREELOTS, C_GREEN, NA, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100, 0); addcelltype(CT_WALLTREE, "dense bushland", UNI_TREELOTS, C_GREEN, NA, B_SOLID, B_OPAQUE, MT_PLANT, 0, 100, 0, B_NOABSORB);
addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, NA, B_SOLID, B_OPAQUE, MT_METAL, 0, 75, 0); addcelltype(CT_WALLMETAL, "metal wall", UNI_SOLID, C_WHITE, NA, B_SOLID, B_OPAQUE, MT_METAL, 0, 75, 0, B_NOABSORB);
// cell types - non-solid // cell types - non-solid
addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0); addcelltype(CT_FAKE, "fake cell", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0, B_NOABSORB);
addcelltype(CT_MOSSROCK, "mossy rock floor", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0); addcelltype(CT_MOSSROCK, "mossy rock floor", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0, B_NOABSORB);
addcelltype(CT_CORRIDOR, "rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0); addcelltype(CT_CORRIDOR, "rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0, B_NOABSORB);
addcelltype(CT_LOOPCORRIDOR, "rock floor", 'L', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0); addcelltype(CT_LOOPCORRIDOR, "rock floor", 'L', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, 0, -1, 0, B_NOABSORB);
addcelltype(CT_FLOORCARPET, "carpetted floor", '.', C_RED, C_ORANGE, B_EMPTY, B_TRANS, MT_CLOTH, 0, -1, -1); addcelltype(CT_FLOORCARPET, "carpetted floor", '.', C_RED, C_ORANGE, B_EMPTY, B_TRANS, MT_CLOTH, 0, -1, -1, B_ABSORB);
addcelltype(CT_FLOORDURANITE, "duranite floor", '.', C_MAGENTA, NA, B_EMPTY, B_TRANS, MT_DURANITE, 0, -1, 1); addcelltype(CT_FLOORDURANITE, "duranite floor", '.', C_MAGENTA, NA, B_EMPTY, B_TRANS, MT_DURANITE, 0, -1, 1, B_NOABSORB);
addcelltype(CT_FLOORWOOD, "wood floor", '.', C_BROWN, NA, B_EMPTY, B_TRANS, MT_WOOD, 0, -1, 1); addcelltype(CT_FLOORWOOD, "wood floor", '.', C_BROWN, NA, B_EMPTY, B_TRANS, MT_WOOD, 0, -1, 1, B_NOABSORB);
addcelltype(CT_FLOORFLESH, "flesh floor", '.', C_RED, NA, B_EMPTY, B_TRANS, MT_FLESH, 0, -1, -2); addcelltype(CT_FLOORFLESH, "flesh floor", '.', C_RED, NA, B_EMPTY, B_TRANS, MT_FLESH, 0, -1, -2, B_NOABSORB);
addcelltype(CT_FLOORSHOP, "shop floor", '.', C_BROWN, NA, B_EMPTY, B_TRANS, MT_WOOD, 0, -1, 0); addcelltype(CT_FLOORSHOP, "shop floor", '.', C_BROWN, NA, B_EMPTY, B_TRANS, MT_WOOD, 0, -1, 0, B_NOABSORB);
addcelltype(CT_FLOORTILE, "tiled floor", '.', C_CYAN, C_WHITE, B_EMPTY, B_TRANS, MT_METAL, 0, -1, 2); addcelltype(CT_FLOORTILE, "tiled floor", '.', C_CYAN, C_WHITE, B_EMPTY, B_TRANS, MT_METAL, 0, -1, 2, B_NOABSORB);
addcelltype(CT_GRASS, "grass", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_PLANT, 0, -1, -1); addcelltype(CT_GRASS, "grass", '.', C_GREEN, NA, B_EMPTY, B_TRANS, MT_PLANT, 0, -1, -1, B_ABSORB);
addcelltype(CT_DIRT, "dirt", '.', C_BROWN, C_YELLOW, B_EMPTY, B_TRANS, MT_STONE, 0, -1, -1); addcelltype(CT_DIRT, "dirt", '.', C_BROWN, C_YELLOW, B_EMPTY, B_TRANS, MT_STONE, 0, -1, -1, B_NOABSORB /* mud instead */);
addcelltype(CT_LOWFLOOR, "low rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, -1, -1, 0); addcelltype(CT_LOWFLOOR, "low rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, -1, -1, 0, B_NOABSORB);
addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, -2, -1, 0); addcelltype(CT_VLOWFLOOR, "very low rock floor", '.', C_GREY, NA, B_EMPTY, B_TRANS, MT_STONE, -2, -1, 0, B_NOABSORB);
// region types // region types
// name, pluralname?, defaulthab, maxdepth stairs stair major? depthmod inherit_parent_depth? // name, pluralname?, defaulthab, maxdepth stairs stair major? depthmod inherit_parent_depth?
@ -8079,7 +8336,7 @@ int linkholes(map_t *map) {
return nlinked; return nlinked;
} }
object_t *linkportal(object_t *srcportal, int wantdepth) { object_t *linkportaltodepth(object_t *srcportal, int wantdepth) {
cell_t *srcloc,*newcell; cell_t *srcloc,*newcell;
map_t *newmap = NULL; map_t *newmap = NULL;
object_t *dstportal = NULL; object_t *dstportal = NULL;
@ -8097,15 +8354,12 @@ object_t *linkportal(object_t *srcportal, int wantdepth) {
while (!cellwalkable(NULL, newcell, NULL) || hasenterableobject(newcell) || getcellwaterdepth(newcell, NULL)) { while (!cellwalkable(NULL, newcell, NULL) || hasenterableobject(newcell) || getcellwaterdepth(newcell, NULL)) {
newcell = getrandomcell(newmap); newcell = getrandomcell(newmap);
} }
// add the dst portal // add the dst portal
dstportal = addobfast(newcell->obpile, srcportal->type->id); dstportal = addobfast(newcell->obpile, srcportal->type->id);
assert(dstportal); assert(dstportal);
// link the dst portal linkportals(srcportal,dstportal);
addflag_real(dstportal->flags, F_MAPLINK, srcloc->map->id, srcloc->x, srcloc->y, NULL, PERMENANT, B_FALSE, -1);
// link the source portal
addflag_real(srcportal->flags, F_MAPLINK, newmap->id, newcell->x, newcell->y, NULL, PERMENANT, B_FALSE, -1);
return dstportal; return dstportal;
} }
@ -8211,6 +8465,7 @@ int linkstairs(object_t *o, object_t *o2) {
return B_FALSE; return B_FALSE;
} }
void makedoor(cell_t *cell, int openchance) { void makedoor(cell_t *cell, int openchance) {
object_t *o; object_t *o;
map_t *m; map_t *m;
@ -8729,6 +8984,39 @@ int remove_deadends(map_t *m, int howmuch) {
return count; return count;
} }
// returns # doors removed
int remove_baddoors(map_t *m) {
int x,y,num=0;
object_t *o,*nexto;
cell_t *c;
// remove useless doors.
for (y = 0; y < m->h; y++) {
for (x = 0; x < m->w; x++) {
c = getcellat(m, x, y);
for (o = c->obpile->first ; o ; o = nexto) {
nexto = o->next;
//if (!getcellvault(c)) {
if (!cellisfixedvaultwall(c)) {
// remove doors which go nowhere (internal to rooms)
if (isdoor(o, NULL)) {
if (!doorisvalid(o)) {
num++;
dblog("removed useless door at %d,%d", c->x, c->y);
killob(o);
// no other obs here?
if (!countobs(c->obpile, B_FALSE)) {
setcelltype(c, getcellsolid(c));
}
continue;
}
}
}
}
}
}
return num;
}
void selectcelltypes(map_t *map) { void selectcelltypes(map_t *map) {
if (map->habitat->id == H_DUNGEON) { if (map->habitat->id == H_DUNGEON) {
// random chance of different wall type // random chance of different wall type

8
map.h
View File

@ -30,6 +30,8 @@ cell_t *delve_rndpull(cellstore_t *cs, cell_t **c);
void delve_storecell(cellstore_t *cs, cell_t *c); void delve_storecell(cellstore_t *cs, cell_t *c);
int damagecell(cell_t *c, int amt, enum DAMTYPE damtype, lifeform_t *fromlf); int damagecell(cell_t *c, int amt, enum DAMTYPE damtype, lifeform_t *fromlf);
int doelementspread(cell_t *c); int doelementspread(cell_t *c);
int dodoorfill(cell_t *c);
void doorfill_r(cell_t *startcell, cell_t *c, int *nfilled);
int fix_reachability(map_t *m); int fix_reachability(map_t *m);
int fix_unreachable_cell(cell_t *badcell); int fix_unreachable_cell(cell_t *badcell);
void floodfill(cell_t *startcell); void floodfill(cell_t *startcell);
@ -84,6 +86,7 @@ void createheaven(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int exitdir, object_t *entryob); void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int exitdir, object_t *entryob);
void createmastervaults(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob); void createmastervaults(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
void createpit(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob); void createpit(map_t *map, int depth, map_t *parentmap, int exitdir, object_t *entryob);
int createportallink(cell_t *c1, cell_t *c2, enum OBTYPE portalid);
void createbranchlink(map_t *m, cell_t *c, object_t *o, char *obname, enum BRANCH newbranch, region_t *parent); void createbranchlink(map_t *m, cell_t *c, object_t *o, char *obname, enum BRANCH newbranch, region_t *parent);
void createregionthing(map_t *map, regionthing_t *rt); void createregionthing(map_t *map, regionthing_t *rt);
void createriver(map_t *m); void createriver(map_t *m);
@ -95,6 +98,7 @@ void createswamp(map_t *map, int depth, map_t *parentmap, int exitdir, object_t
int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety); int createvault(map_t *map, int roomid, vault_t *v, int *retw, int *reth, int *retx, int *rety);
int dirtox(int dt, int dir); int dirtox(int dt, int dir);
int dirtoy(int dt, int dir); int dirtoy(int dt, int dir);
int doorisvalid(object_t *o);
void dumpmap(map_t *map, int showrooms); void dumpmap(map_t *map, int showrooms);
void expand_cave(map_t *map, int numpasses); void expand_cave(map_t *map, int numpasses);
void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *centre, lifeform_t *fromwho); void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *centre, lifeform_t *fromwho);
@ -176,7 +180,8 @@ void killregion(region_t *r);
int linkexit(cell_t *c, int wantfilled, int *ncellsadded); int linkexit(cell_t *c, int wantfilled, int *ncellsadded);
int linkexits(map_t *m, int roomid); int linkexits(map_t *m, int roomid);
int linkholes(map_t *map); int linkholes(map_t *map);
object_t *linkportal(object_t *srcportal, int wantdepth); object_t *linkportaltodepth(object_t *srcportal, int wantdepth);
int linkportals(object_t *srcportal, object_t *dstportal);
int linkstairs(object_t *o, object_t *o2); int linkstairs(object_t *o, object_t *o2);
void makedoor(cell_t *cell, int openchance); void makedoor(cell_t *cell, int openchance);
void makelit(cell_t *c, enum OBTYPE how, int howlong, int power); void makelit(cell_t *c, enum OBTYPE how, int howlong, int power);
@ -188,6 +193,7 @@ void moveobtoclearcell(object_t *o);
int orthdir(int compassdir); int orthdir(int compassdir);
enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob, enum BEHAVIOUR *wantbehaviour); enum RACE parserace(char *name, flagpile_t *wantflags, enum JOB *wantjob, enum BEHAVIOUR *wantbehaviour);
int remove_deadends(map_t *m, int howmuch); int remove_deadends(map_t *m, int howmuch);
int remove_baddoors(map_t *m);
void selectcelltypes(map_t *map); void selectcelltypes(map_t *map);
void set_scanned_glyph(int targettype, void *what, char *descappend, char *desc, glyph_t *glyph); void set_scanned_glyph(int targettype, void *what, char *descappend, char *desc, glyph_t *glyph);
void setcellknown(cell_t *cell, int forcelev); void setcellknown(cell_t *cell, int forcelev);

6
move.c
View File

@ -680,7 +680,7 @@ int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int d
} }
if (keepinlof) { if (keepinlof) {
if (!haslof(c, dst, LOF_NEED, NULL)) { if (!haslof_real(c, dst, LOF_NEED, NULL, srclf, B_TRUE)) {
ok = B_FALSE; ok = B_FALSE;
} }
} }
@ -2824,8 +2824,12 @@ int teleportto(lifeform_t *lf, cell_t *c, int wantsmoke) {
msg("Suddenly, your surroundings appear different!"); msg("Suddenly, your surroundings appear different!");
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
getlfname(lf, buf); getlfname(lf, buf);
if (getraceclass(lf) == RC_GOD) {
msg("%s %s!", buf, getflagtext(lf->flags, F_GODTEXTAPPEAR));
} else {
msg("%s appears!", buf); msg("%s appears!", buf);
} }
}
// show any objects here, just like if we moved. // show any objects here, just like if we moved.
// BUT don't let dolook() clear the msg bar if there are // BUT don't let dolook() clear the msg bar if there are
// no objects here. // no objects here.

View File

@ -696,7 +696,7 @@ int main(int argc, char **argv) {
return B_FALSE; return B_FALSE;
} }
celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp, int volumemod) { celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp, int volumemod, int absorbent) {
celltype_t *a; celltype_t *a;
// add to the end of the list // add to the end of the list
@ -730,6 +730,7 @@ celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, i
a->floorheight = floorheight; a->floorheight = floorheight;
a->hp = hp; a->hp = hp;
a->volumemod = volumemod; a->volumemod = volumemod;
a->absorbent = absorbent;
a->flags = addflagpile(NULL, NULL); a->flags = addflagpile(NULL, NULL);
@ -2070,7 +2071,7 @@ void timeeffectsworld(map_t *map, int updategametime) {
splittime(&th, &tm, &ts); splittime(&th, &tm, &ts);
timeleft -= TICK_INTERVAL; timeleft -= TICK_INTERVAL;
dblog("------ tick (time=%ld %d:%d:%d) ----", curtime,th,tm,ts); dblog("------ tick (time=%ld %02d:%02d:%02d) ----", curtime,th,tm,ts);
// global time-based effects on map or map objects // global time-based effects on map or map objects
for (y = 0; y < map->h; y++) { for (y = 0; y < map->h; y++) {

View File

@ -1,6 +1,6 @@
#include "defs.h" #include "defs.h"
celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp, int volumemod); celltype_t *addcelltype(int id, char *name, int glyph, int colour, int altcol, int solid, int transparent, enum MATERIAL mat, int floorheight, int hp, int volumemod, int absobent);
warning_t *addwarning(char *text, int lifetime); warning_t *addwarning(char *text, int lifetime);
void checkdeath(void); void checkdeath(void);
void checkendgame(void); void checkendgame(void);

View File

@ -1452,6 +1452,9 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
o->blessed = B_CURSED; o->blessed = B_CURSED;
} }
} }
if (where->owner && isplayer(where->owner)) {
killflagsofid(o->flags, F_UNTOUCHED);
}
// fill in portal destinations // fill in portal destinations
@ -4307,7 +4310,6 @@ int real_getobvalue(object_t *o, int amt) {
} else if (o->type->id == OT_GRIMOIRE) { } else if (o->type->id == OT_GRIMOIRE) {
price += (59*countobs(o->contents, B_FALSE)); price += (59*countobs(o->contents, B_FALSE));
} }
getflags(o->flags, retflag, &nretflags, F_ARMOURRATING, F_ARMOURSIZE, F_BONUS, F_DAM, F_EDIBLE, F_LINKSPELL, F_MANUALOF, F_NONE); getflags(o->flags, retflag, &nretflags, F_ARMOURRATING, F_ARMOURSIZE, F_BONUS, F_DAM, F_EDIBLE, F_LINKSPELL, F_MANUALOF, F_NONE);
for (i = 0; i < nretflags; i++) { for (i = 0; i < nretflags; i++) {
f = retflag[i]; f = retflag[i];
@ -4315,7 +4317,7 @@ int real_getobvalue(object_t *o, int amt) {
if (f->id == F_DAM) { if (f->id == F_DAM) {
int min,max; int min,max;
getdamrange(o, f, &min, &max); getdamrange(o, f, &min, &max);
price += (max*5); price += (max*7);
} }
// armour rating // armour rating
if (f->id == F_ARMOURRATING) { if (f->id == F_ARMOURRATING) {
@ -4351,6 +4353,11 @@ int real_getobvalue(object_t *o, int amt) {
} }
} }
if (hasflagval(o->flags, F_USESSKILL, SK_EXOTICWEPS, NA, NA, NULL)) {
price *= 2;
}
// TODO: rings? // TODO: rings?
if (hasflag(o->flags, F_HASBRAND)) { if (hasflag(o->flags, F_HASBRAND)) {
@ -6381,8 +6388,8 @@ objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forceh
} }
while (!done) { while (!done) {
if (db || partdb) dblog("adding random object with rarity value between %d - %d and rr <= %d, for habitat %s", if (db || partdb) dblog("adding random object with rarity value between %d - %d and rr <= %d(%s), for habitat %s",
raritymin,raritymax,wantrr, habname); raritymin,raritymax,wantrr, getrarityname(wantrr), habname);
if (db || partdb) { if (db || partdb) {
char dbuf[BUFLEN]; char dbuf[BUFLEN];
if (wantsk) { if (wantsk) {
@ -6452,8 +6459,8 @@ objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forceh
if (thisrr == wantrr) { if (thisrr == wantrr) {
rarok = B_TRUE; rarok = B_TRUE;
} else { } else {
if (db) dblog(" %s rarity(%d) doesn't match wantrr(%d)", ot->name, if (db) dblog(" %s rarity(%d) doesn't match wantrr(%d,%s)", ot->name,
rarflag->val[2], wantrr); rarflag->val[2], wantrr, getrarityname(wantrr));
} }
} else { } else {
if (db) dblog(" rarity of %s out of range (%d)", ot->name, rarflag->val[1]); if (db) dblog(" rarity of %s out of range (%d)", ot->name, rarflag->val[1]);
@ -6540,18 +6547,18 @@ objecttype_t *real_getrandomob(map_t *map, char *buf, int forcedepth, int forceh
if (rrmoddir == -1) { if (rrmoddir == -1) {
if (wantrr > RR_FREQUENT) { if (wantrr > RR_FREQUENT) {
wantrr--; wantrr--;
if (db || partdb) dblog("rarity at min/max and no obs. lowering wantrr to %d.",wantrr); if (db || partdb) dblog("rarity at min/max and no obs. lowering wantrr to %d (%s).",wantrr,getrarityname(wantrr));
} else { } else {
// wantrr is already at rr_frequent // wantrr is already at rr_frequent
// start increasing it now. // start increasing it now.
wantrr = origwantrr + 1; wantrr = origwantrr + 1;
rrmoddir = 1; rrmoddir = 1;
if (db || partdb) dblog("rarity got below frequent. raising to original rr + 1 (%d)",wantrr); if (db || partdb) dblog("rarity got below frequent. raising to original rr + 1 (%d, %s)",wantrr,getrarityname(wantrr));
} }
} else { } else {
if (wantrr < RR_VERYRARE) { if (wantrr < RR_VERYRARE) {
wantrr++; wantrr++;
if (db || partdb) dblog("rarity at min/max and no obs. raising wantrr to %d.",wantrr); if (db || partdb) dblog("rarity at min/max and no obs. raising wantrr to %d(s).",wantrr,getrarityname(wantrr));
} else { } else {
// give up // give up
strcpy(buf, ""); strcpy(buf, "");
@ -8563,6 +8570,7 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
int i,preburdened = B_FALSE; int i,preburdened = B_FALSE;
int db = B_FALSE; int db = B_FALSE;
int redrawaftermove = B_FALSE; int redrawaftermove = B_FALSE;
int pleasethiefgod = 0;
lifeform_t *robbedlf = NULL; lifeform_t *robbedlf = NULL;
flag_t *f; flag_t *f;
@ -8573,6 +8581,16 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
return NULL; return NULL;
} }
if (dst->owner && isplayer(dst->owner) && hasflag(src->flags, F_UNTOUCHED)) {
// values here should be half as much as if you
// were to sacrifice it.
if (src->type->id == OT_GOLD) {
pleasethiefgod = (getobvalue(src) / 4);
} else if (hasflag(src->flags, F_GEM)) {
pleasethiefgod = (getobvalue(src) / 100);
}
}
touch_battle_spoils(src); touch_battle_spoils(src);
// object being taken from an unconscious lf? // object being taken from an unconscious lf?
@ -8786,6 +8804,10 @@ object_t *real_moveob(object_t *src, obpile_t *dst, int howmany, int stackok) {
} }
} }
if (pleasethiefgod) {
pleasegodmaybe(R_GODTHIEVES, pleasethiefgod);
}
// in case you picked up money, something which changes your AR, etc // in case you picked up money, something which changes your AR, etc
if (isplayer(dst->owner)) { if (isplayer(dst->owner)) {
statdirty = B_TRUE; statdirty = B_TRUE;
@ -12204,14 +12226,14 @@ int readsomething(lifeform_t *lf, object_t *o) {
if (isplayer(lf)) { if (isplayer(lf)) {
char ooname[BUFLEN]; char ooname[BUFLEN];
getobname(oo, ooname, oo->amt); getobname(oo, ooname, oo->amt);
msg("Your %s become%s ultra-dense!", noprefix(ooname), (oo->amt == 1) ? "s" : ""); msg("Your %s become%s ultra-dense!", noprefix(ooname), OBS1(oo));
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
char ooname[BUFLEN]; char ooname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
getobname(oo, ooname, oo->amt); getobname(oo, ooname, oo->amt);
msg("%s%s %s become%s ultra-dense!", lfname, getpossessive(lfname), msg("%s%s %s become%s ultra-dense!", lfname, getpossessive(lfname),
noprefix(ooname), (oo->amt == 1) ? "s" : ""); noprefix(ooname), OBS1(oo));
} }
addflag(oo->flags, F_IMMUTABLE, B_TRUE, NA, NA, NULL); addflag(oo->flags, F_IMMUTABLE, B_TRUE, NA, NA, NULL);
killflagsofid(oo->flags, F_DAMAGABLE); killflagsofid(oo->flags, F_DAMAGABLE);
@ -12407,6 +12429,12 @@ object_t *relinkob(object_t *src, obpile_t *dst) {
// previous owner loses all flags conferred by this object // previous owner loses all flags conferred by this object
loseobflags(src->pile->owner, src, ALLCONFERRED); loseobflags(src->pile->owner, src, ALLCONFERRED);
} }
if (dst->owner) {
if (isplayer(dst->owner)) {
// can't now sacrifice this money!
killflagsofid(src->flags, F_UNTOUCHED);
}
}
// unweild // unweild
killflagsofid(src->flags, F_EQUIPPED); killflagsofid(src->flags, F_EQUIPPED);
@ -13973,7 +14001,7 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
// an actual physical shield? // an actual physical shield?
sprintf(attackname, "%s", obname); sprintf(attackname, "%s", obname);
difficulty = 60 + (speed*10); difficulty = 60 + (speed*10);
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, B_RANGED)) {
announcedmiss = B_TRUE; announcedmiss = B_TRUE;
youhit = B_FALSE; youhit = B_FALSE;
missiledam += ((speed*2)+rnd(1,4)); missiledam += ((speed*2)+rnd(1,4));
@ -14650,6 +14678,21 @@ void timeeffectsob(object_t *o) {
} }
} }
if (location && onground) {
if ((o->type->material->id == MT_WATER) || (o->type->id == OT_SPLASHWATER)) {
if (location->type->absorbent) {
if (haslos(player, location)) {
msg("%s %s absorbed into the %s.", obname,
OB1(o,"is","are"), location->type->name);
}
removeob(o, ALL);
return;
}
}
}
// check each flag for this object... // check each flag for this object...
getflags(o->flags, retflag, &nretflags, F_ACTIVATED, F_EDIBLE, F_EXPLODEONDEATH, F_MATCONVERT, F_HOT, F_KNOCKAWAY, F_OBHPDRAIN, F_ONFIRE, getflags(o->flags, retflag, &nretflags, F_ACTIVATED, F_EDIBLE, F_EXPLODEONDEATH, F_MATCONVERT, F_HOT, F_KNOCKAWAY, F_OBHPDRAIN, F_ONFIRE,
F_RECHARGE, F_REVIVETIMER, F_WALKDAM, F_WET, F_NONE); F_RECHARGE, F_REVIVETIMER, F_WALKDAM, F_WET, F_NONE);
@ -15370,6 +15413,9 @@ void trapeffects(object_t *trapob, enum OBTYPE oid, cell_t *c, object_t *trapped
movelf(lf, escapeto, B_TRUE); movelf(lf, escapeto, B_TRUE);
} }
} }
if (lf && isplayer(lf)) {
pleasegodmaybe(R_GODFIRE, 10);
}
if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards if (trapob) removeob(trapob, trapob->amt); // trap dies afterwards
} else if (oid == OT_TRAPLIGHTNING) { } else if (oid == OT_TRAPLIGHTNING) {
// can't be dodged // can't be dodged
@ -15861,6 +15907,8 @@ int wepdullable(object_t *o) {
if (!o) return B_FALSE; if (!o) return B_FALSE;
if (o->blessed) return B_FALSE;
// exceptions // exceptions
switch (o->type->id) { switch (o->type->id) {
case OT_NANOBLADE: case OT_NANOBLADE:

View File

@ -820,7 +820,7 @@ enum SHOPRETURN shopmiracle(lifeform_t *lf, object_t *vm, int starty, char *topt
givemoney(lf, NULL, cost); givemoney(lf, NULL, cost);
godgiftmaybe(god->race->id, B_TRUE); godgiftmaybe(god->race->id, B_TRUE, B_TRUE);
more(); more();
return SR_BACK; return SR_BACK;

232
spell.c
View File

@ -850,6 +850,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} }
practice(user, SK_COOKING, 1); practice(user, SK_COOKING, 1);
ncooked++; ncooked++;
if (isplayer(user)) pleasegodmaybe(R_GODNATURE, 1);
} }
// set donesomething even if the actual cooking failed. // set donesomething even if the actual cooking failed.
donesomething = B_TRUE; donesomething = B_TRUE;
@ -1325,7 +1326,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
taketime(user, getactspeed(user)); taketime(user, getactspeed(user));
if (lfhasflag(target, F_NONCORPOREAL)) { if (lfhasflag(target, F_NONCORPOREAL)) {
if (isplayer(user)) { if (isplayer(user)) {
msg("You grab at %s%s insubstantial body.", targetname, getpossessive(targetname)); msg("You grab at %s%s insubstantial body.", targetname, getpossessive(targetname));
@ -1423,6 +1423,45 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// now attack them // now attack them
attackcell(user, target->cell, B_TRUE); attackcell(user, target->cell, B_TRUE);
} else if (abilid == OT_A_FULLSHIELD) {
object_t *shield[MAXPILEOBS],*selshield = NULL;
int checkmod[MAXPILEOBS];
int nshields,i;
char shtext[BUFLEN];
if (isimmobile(user)) {
if (isplayer(user)) msg("You can't do that while stuck!");
return B_TRUE;
}
if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) {
if (isplayer(user)) msg("You can't do that while swimming!");
return B_TRUE;
} else if (isstuck(user)) {
if (isplayer(user)) msg("You can't do that while stuck!");
return B_TRUE;
}
// stop fullshielding.
if (lfhasflag(user, F_FULLSHIELD)) {
killflagsofid(user->flags, F_FULLSHIELD);
taketime(user, getactspeed(user));
return B_FALSE;
}
getallshields(user, DT_BASH, shield, checkmod, &nshields);
for (i = 0; i < nshields; i++) {
if (isshield(shield[i])) {
selshield = shield[i];
break;
}
}
if (!selshield) {
if (isplayer(user)) msg("You need to equip a shield first!");
return B_TRUE;
}
sprintf(shtext, "%ld", selshield->id);
addflag(user->flags, F_FULLSHIELD, NA, NA, NA, shtext);
taketime(user, getactspeed(user));
} else if (abilid == OT_A_GRAB) { } else if (abilid == OT_A_GRAB) {
flag_t *f; flag_t *f;
@ -2012,6 +2051,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
} else if (abilid == OT_A_SNATCH) { } else if (abilid == OT_A_SNATCH) {
object_t *o = NULL; object_t *o = NULL;
flag_t *f; flag_t *f;
char obname[BUFLEN];
if (!targcell) { if (!targcell) {
int dir; int dir;
@ -2046,12 +2086,11 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
if (isplayer(user)) msg("Cancelled."); if (isplayer(user)) msg("Cancelled.");
return B_TRUE; return B_TRUE;
} }
getobname(o, obname, 1);
// spell doesn't take any time, using an object does. // spell doesn't take any time, using an object does.
if (fromob) { if (fromob) {
if (cansee(player, user)) { if (cansee(player, user)) {
char obname[BUFLEN];
getobname(o, obname, 1);
msg("%s%s %s wraps around %s.", username, getpossessive(username), msg("%s%s %s wraps around %s.", username, getpossessive(username),
noprefix(fromobname), obname); noprefix(fromobname), obname);
} }
@ -2059,7 +2098,14 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// setting v0 to spellid just in case pickup() changes flags // setting v0 to spellid just in case pickup() changes flags
addflag(user->flags, F_NOTIME, OT_A_SNATCH, NA, NA, NULL); addflag(user->flags, F_NOTIME, OT_A_SNATCH, NA, NA, NULL);
} }
pickup(user, o, 1, B_TRUE, B_TRUE);
if (!pickup(user, o, 1, B_TRUE, B_FALSE)) {
if (isplayer(user)) {
msg("You snatch %s from the ground!",obname);
} else if (cansee(player, user)) {
msg("%s snatches %s from the ground!",username, obname);
}
}
f = lfhasflagval(user, F_NOTIME, OT_A_SNATCH, NA, NA, NULL); f = lfhasflagval(user, F_NOTIME, OT_A_SNATCH, NA, NA, NULL);
if (f) killflag(f); if (f) killflag(f);
} else if (abilid == OT_A_SONICBOLT) { } else if (abilid == OT_A_SONICBOLT) {
@ -5430,6 +5476,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// target takes magical damage // target takes magical damage
// always hit // always hit
if (!isimmuneto(target->flags, DT_COLD, B_FALSE)) { if (!isimmuneto(target->flags, DT_COLD, B_FALSE)) {
// partially avoidable
if (check_for_block(caster, target, dam, DT_COLD, 999, "the icy air", B_RANGED)) {
dam /= 2;
}
losehp(target, dam, DT_COLD, caster, "a chill spell"); losehp(target, dam, DT_COLD, caster, "a chill spell");
} }
} else if (spellid == OT_S_COLDBURST) { } else if (spellid == OT_S_COLDBURST) {
@ -5455,13 +5505,20 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (targcell->lf) { if (targcell->lf) {
if (targcell->lf != caster) { if (targcell->lf != caster) {
char lfname[BUFLEN]; char lfname[BUFLEN];
int dam;
// automatic hit // automatic hit
getlfname(targcell->lf, lfname); getlfname(targcell->lf, lfname);
dam = rolldie(1,8)+3;
// partially avoidable
if (check_for_block(caster, target, dam, DT_COLD, 999, "a burst of coldness", B_RANGED)) {
dam /= 2;
} else {
if (haslos(player, targcell)) { if (haslos(player, targcell)) {
msg("^%c%s %s chilled!",getlfcol(targcell->lf, CC_BAD), msg("^%c%s %s chilled!",getlfcol(targcell->lf, CC_BAD),
lfname,is(targcell->lf)); lfname,is(targcell->lf));
} }
losehp(targcell->lf, rolldie(1,8)+3, DT_COLD, caster, "a burst of coldness"); }
losehp(targcell->lf, dam, DT_COLD, caster, "a burst of coldness");
} }
} else { } else {
// noone there, hit objects. // noone there, hit objects.
@ -5497,14 +5554,18 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else { } else {
int dam; int dam;
// hit // hit
if (cansee(player, target)) {
msg("^%cA blast of icy air assails %s.",getlfcol(target, CC_BAD), lfname);
}
dam = roll("3d6"); dam = roll("3d6");
if (power > 1) { // overcast for dragons if (power > 1) { // overcast for dragons
dam += (power-1); dam += (power-1);
} }
losehp(target, roll("3d6"), DT_COLD, caster, "a blast of ice-cold air"); if (check_for_block(caster, target, dam, DT_COLD, 999, "a blast of icy air", B_RANGED)) {
dam /= 2;
} else {
if (cansee(player, target)) {
msg("^%cA blast of icy air assails %s.",getlfcol(target, CC_BAD), lfname);
}
}
losehp(target, dam, DT_COLD, caster, "a blast of ice-cold air");
// ray stops here. // ray stops here.
break; break;
} }
@ -6052,12 +6113,17 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
c2 = getcellindir(c, d2); c2 = getcellindir(c, d2);
if (c2 && !c2->type->solid && c2->lf) { if (c2 && !c2->type->solid && c2->lf) {
if (!isimmuneto(c2->lf->flags, DT_PROJECTILE, B_FALSE)) { if (!isimmuneto(c2->lf->flags, DT_PROJECTILE, B_FALSE)) {
int dam;
dam = roll("2d6");
if (check_for_block(caster, c2->lf, dam, DT_PROJECTILE, 999, "flying debris", B_RANGED)) {
} else {
if (cansee(player, c2->lf)) { if (cansee(player, c2->lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(c2->lf, lfname); getlfname(c2->lf, lfname);
msg("%s %s showered with debris!", lfname, isplayer(c2->lf) ? "are" : "is"); msg("%s %s showered with debris!", lfname, isplayer(c2->lf) ? "are" : "is");
} }
losehp(c2->lf, rnd(2,6), DT_PROJECTILE, NULL, "flying debris"); losehp(c2->lf, dam, DT_PROJECTILE, NULL, "flying debris");
}
} }
} }
} }
@ -6607,7 +6673,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
c = getcellat(targcell->map, x,y); c = getcellat(targcell->map, x,y);
if (c && (getcelldist(targcell, c) <= range)) { if (c && (getcelldist(targcell, c) <= range)) {
if (c->lf && (c->lf != caster) && haslof(targcell, c, B_FALSE, NULL)) { if (c->lf && (c->lf != caster) && haslof(targcell, c, B_FALSE, NULL)) {
int dam;
dam = roll("2d6");
// automatic hit // automatic hit
if (check_for_block(caster, c->lf, dam, DT_MAGIC, 999, "an energy blast", B_RANGED)) {
} else {
if (isplayer(c->lf)) { if (isplayer(c->lf)) {
msg("^%cA blast of energy hits you!", getlfcol(c->lf, CC_BAD)); msg("^%cA blast of energy hits you!", getlfcol(c->lf, CC_BAD));
} else if (cansee(player, c->lf)) { } else if (cansee(player, c->lf)) {
@ -6615,7 +6685,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
getlfname(c->lf, lfname); getlfname(c->lf, lfname);
msg("^%cA blast of energy hits %s.", getlfcol(c->lf, CC_BAD), lfname); msg("^%cA blast of energy hits %s.", getlfcol(c->lf, CC_BAD), lfname);
} }
losehp(c->lf, roll("2d6"), DT_MAGIC, caster, "an energy blast"); losehp(c->lf, dam, DT_MAGIC, caster, "an energy blast");
}
} }
} }
} }
@ -6868,9 +6939,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
target = haslf(targcell); target = haslf(targcell);
if (target) { if (target) {
int dam;
getlfname(target, lfname); getlfname(target, lfname);
// target takes magical damage // target takes magical damage
// ALWAYS hits. // ALWAYS hits.
dam = rolldie(power*2,4);
if (check_for_block(caster, target, dam, DT_MAGIC, 999, "an energy bolt", B_RANGED)) {
} else {
if (cansee(player, target)) { if (cansee(player, target)) {
if (power == 1) { if (power == 1) {
msg("^%cA bolt of energy hits %s.",getlfcol(target, CC_BAD), lfname); msg("^%cA bolt of energy hits %s.",getlfcol(target, CC_BAD), lfname);
@ -6878,7 +6953,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("^%c%s bolts of energy hit %s.",getlfcol(target, CC_BAD), numbuf, lfname); msg("^%c%s bolts of energy hit %s.",getlfcol(target, CC_BAD), numbuf, lfname);
} }
} }
losehp(target, rolldie(power*2,4), DT_MAGIC, caster, "an energy bolt"); }
losehp(target, dam, DT_MAGIC, caster, "an energy bolt");
} }
} else if ((spellid == OT_S_FIREBALL) || (spellid == OT_S_METEOR)) { } else if ((spellid == OT_S_FIREBALL) || (spellid == OT_S_METEOR)) {
int failed = B_FALSE; int failed = B_FALSE;
@ -6932,11 +7008,21 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
setobcreatedby(o, caster); setobcreatedby(o, caster);
} }
if (c->lf) { if (c->lf) {
int dam;
char attackname[BUFLEN];
if (spellid == OT_S_FIREBALL) { if (spellid == OT_S_FIREBALL) {
losehp(c->lf, rolldie(power,3), DT_FIRE, caster, "a fireball"); dam = rolldie(power,3);
strcpy(attackname, "a fireball");
} else { } else {
losehp(c->lf, 30+rolldie(power,6), DT_FIRE, caster, "a meterorite"); dam = 30+rolldie(power,6);
strcpy(attackname, "a meteorite");
} }
if (check_for_block(caster, c->lf, dam, DT_FIRE, 999, attackname, B_RANGED)) {
// partial damage
dam /= 2;
}
losehp(c->lf, dam, DT_FIRE, caster, attackname);
} }
} }
} }
@ -7023,11 +7109,16 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("A dart of flame misses %s.",lfname); msg("A dart of flame misses %s.",lfname);
} }
} else { } else {
int dam;
// hit // hit
dam = rnd(1,6) + power;
if (check_for_block(caster, target, dam, DT_FIRE, 999, "a dart of flame", B_RANGED)) {
} else {
if (isplayer(target) || cansee(player, target)) { if (isplayer(target) || cansee(player, target)) {
msg("^%cA dart of flame hits %s.",getlfcol(target, CC_BAD), lfname); msg("^%cA dart of flame hits %s.",getlfcol(target, CC_BAD), lfname);
} }
losehp(target, rnd(1,6) + power, DT_FIRE, caster, "a dart of flame"); losehp(target, dam, DT_FIRE, caster, "a dart of flame");
}
} }
} else { } else {
damageallobs(NULL, targcell->obpile, 0, DT_FIRE, caster); damageallobs(NULL, targcell->obpile, 0, DT_FIRE, caster);
@ -7056,13 +7147,18 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (targcell && (getcelldistorth(caster->cell, targcell) <= range)) { if (targcell && (getcelldistorth(caster->cell, targcell) <= range)) {
if (targcell->lf && (targcell->lf != caster) && haslof(caster->cell, targcell, B_FALSE, NULL)) { if (targcell->lf && (targcell->lf != caster) && haslof(caster->cell, targcell, B_FALSE, NULL)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
int dam;
dam = rolldie(2,6);
// automatic hit // automatic hit
getlfname(targcell->lf, lfname); getlfname(targcell->lf, lfname);
if (check_for_block(caster, targcell->lf, dam, DT_FIRE, 999, "a burst of fire", B_RANGED)) {
} else {
if (haslos(caster, targcell)) { if (haslos(caster, targcell)) {
msg("^%c%s burn%s!",getlfcol(targcell->lf, CC_BAD), msg("^%c%s burn%s!",getlfcol(targcell->lf, CC_BAD),
lfname,isplayer(targcell->lf) ? "" : "s"); lfname,isplayer(targcell->lf) ? "" : "s");
} }
losehp(targcell->lf, rolldie(2,6), DT_FIRE, caster, "a burst of fire"); losehp(targcell->lf, dam, DT_FIRE, caster, "a burst of fire");
}
} }
damageallobs(NULL, targcell->obpile, rolldie(2,6), DT_FIRE, caster); damageallobs(NULL, targcell->obpile, rolldie(2,6), DT_FIRE, caster);
} }
@ -8234,9 +8330,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
target = haslf(targcell); target = haslf(targcell);
if (target) { if (target) {
int dam;
char attackname[BUFLEN];
getlfname(target, lfname); getlfname(target, lfname);
dam = rolldie(power, 4);
if (power == 1) {
sprintf(attackname, "a spike of mana");
} else {
sprintf(attackname, "%s spikes of mana", numbuf);
}
// target takes magical damage // target takes magical damage
// always hit // always hit
if (check_for_block(caster, target, dam, DT_FIRE, 999, attackname, B_RANGED)) {
} else {
if (cansee(player, target)) { if (cansee(player, target)) {
if (power == 1) { if (power == 1) {
msg("^%cA spike of mana hits %s.",getlfcol(target, CC_BAD), lfname); msg("^%cA spike of mana hits %s.",getlfcol(target, CC_BAD), lfname);
@ -8244,7 +8350,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("^%c%s spikes of mana hit %s.",getlfcol(target, CC_BAD), numbuf, lfname); msg("^%c%s spikes of mana hit %s.",getlfcol(target, CC_BAD), numbuf, lfname);
} }
} }
losehp(target, rolldie(power,4), DT_MAGIC, caster, "a mana spike"); losehp(target, dam, DT_MAGIC, caster, "a mana spike");
}
} }
} else if (spellid == OT_S_MAGSHIELD) { } else if (spellid == OT_S_MAGSHIELD) {
object_t *o,*nexto; object_t *o,*nexto;
@ -9006,9 +9113,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (m) { if (m) {
int ntries = 0; int ntries = 0;
// find random free cell in map // find random free cell in map
targcell = getrandomcell(m); //targcell = getrandomcell(m);
targcell = getrandomroomcell(m, ANYROOM, WE_WALKABLE);
while (!cellwalkable(target, targcell, NULL) || celldangerous(target, targcell, B_FALSE, NULL)) { while (!cellwalkable(target, targcell, NULL) || celldangerous(target, targcell, B_FALSE, NULL)) {
targcell = getrandomcell(m); //targcell = getrandomcell(m);
targcell = getrandomroomcell(m, ANYROOM, WE_WALKABLE);
ntries++; ntries++;
if (ntries >= 5) { if (ntries >= 5) {
fizzle(caster); fizzle(caster);
@ -9505,7 +9614,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
dstportal = linkportal(srcportal, newdepth); dstportal = linkportaltodepth(srcportal, newdepth);
setobcreatedby(dstportal, caster); setobcreatedby(dstportal, caster);
@ -9791,9 +9900,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (power > 1) { if (power > 1) {
dam += power; // maxpower is 1, but blue dragons can exceed this dam += power; // maxpower is 1, but blue dragons can exceed this
} }
if (check_for_block(caster, c->lf, dam, DT_ELECTRIC, 999, "a lightning bolt", B_RANGED)) {
} else {
losehp(c->lf, dam, DT_ELECTRIC, caster, "a lightning bolt"); losehp(c->lf, dam, DT_ELECTRIC, caster, "a lightning bolt");
nhits--;
}
if (haslos(player, c)) { if (haslos(player, c)) {
if (fromob) { if (fromob) {
char lfname[BUFLEN]; char lfname[BUFLEN];
@ -9804,6 +9913,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
} }
nhits--;
}
}
} else if (spellid == OT_S_LIGHTNINGSTORM) { } else if (spellid == OT_S_LIGHTNINGSTORM) {
char targname[BUFLEN]; char targname[BUFLEN];
lifeform_t *poss[MAXCANDIDATES], *targ[MAXCANDIDATES]; lifeform_t *poss[MAXCANDIDATES], *targ[MAXCANDIDATES];
@ -9848,15 +9960,21 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
for (i = 0; i < ntarg; i++) { for (i = 0; i < ntarg; i++) {
int dam;
if (cansee(player, targ[i])) { if (cansee(player, targ[i])) {
getlfname(targ[i],targname); getlfname(targ[i],targname);
msg("^%c%s %s struck by a bolt of lightning!",getlfcol(targ[i], CC_BAD), msg("^%c%s %s struck by a bolt of lightning!",getlfcol(targ[i], CC_BAD),
targname, is(targ[i])); targname, is(targ[i]));
} }
if (caster && (targ[i]->cell->map->habitat->id == H_FOREST)) { if (caster && (targ[i]->cell->map->habitat->id == H_FOREST)) {
losehp(targ[i], rolldie(4,6), DT_ELECTRIC, caster, "a bolt of lightning"); dam = rolldie(4,6);
} else { } else {
losehp(targ[i], rolldie(3,6), DT_ELECTRIC, caster, "a bolt of lightning"); dam = rolldie(3,6);
}
if (check_for_block(caster, targ[i], dam, DT_ELECTRIC, 999, "a bolt of lightning", B_RANGED)) {
} else {
losehp(targ[i], dam, DT_ELECTRIC, caster, "a bolt of lightning");
} }
} }
@ -11208,8 +11326,18 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
cell_t *c; cell_t *c;
c = retcell[i]; c = retcell[i];
if (c->lf) { if (c->lf) {
int dam;
dam = rolldie(nhits, 6);
// hit with ice // hit with ice
losehp(c->lf, rolldie(nhits, 6), DT_COLD, caster, "a burst of ice shards"); if (check_for_block(caster, c->lf, dam, DT_COLD, 999, "a burst of ice shards", B_RANGED)) {
} else {
if (isplayer(c->lf) || cansee(player, c->lf)) {
char lfname[BUFLEN];
getlfname(c->lf, lfname);
msg("^%cA burst of ice shards hits %s.",getlfcol(target, CC_BAD), lfname);
}
losehp(c->lf, dam, DT_COLD, caster, "a burst of ice shards");
}
nhits--; nhits--;
} }
if (haslos(player, c)) { if (haslos(player, c)) {
@ -11424,7 +11552,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
// use direct damage rather than holy, because otherwise it might be increased // use direct damage rather than holy, because otherwise it might be increased
// due to vulnerabilities // due to vulnerabilities
losehp(target, rnd(1,power*2), DT_DIRECT, caster, "a smiting"); losehp(target, rolldie(1+power,4), DT_DIRECT, caster, "a smiting");
} else if (spellid == OT_S_SNAPFREEZE) { } else if (spellid == OT_S_SNAPFREEZE) {
target = haslf(targcell); target = haslf(targcell);
if (target) { if (target) {
@ -11469,7 +11597,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// *** // ***
// * // *
if (targcell->lf) { if (targcell->lf) {
if (check_for_block(caster, targcell->lf, 1, DT_COLD, 999, "a snowball", B_RANGED)) {
} else {
losehp(targcell->lf, 1, DT_COLD, caster, "a snowball"); losehp(targcell->lf, 1, DT_COLD, caster, "a snowball");
}
} else { } else {
addob(targcell->obpile, "small puddle of water"); addob(targcell->obpile, "small puddle of water");
} }
@ -11477,7 +11608,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
c = getcellindir(targcell, dir); c = getcellindir(targcell, dir);
if (c && !c->type->solid ) { if (c && !c->type->solid ) {
if (c->lf) { if (c->lf) {
losehp(c->lf, 1, DT_COLD, caster, "a snowball"); if (check_for_block(caster, c->lf, 1, DT_COLD, 999, "a burst of snow", B_RANGED)) {
} else {
losehp(c->lf, 1, DT_COLD, caster, "a burst of snow");
}
} else { } else {
addob(c->obpile, "small puddle of water"); addob(c->obpile, "small puddle of water");
} }
@ -12372,6 +12506,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (spellid == OT_S_TURNUNDEAD) { } else if (spellid == OT_S_TURNUNDEAD) {
int i,ndone = 0; int i,ndone = 0;
lifeform_t *lf; lifeform_t *lf;
if (caster && !isplayer(caster) && cansee(player, caster)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s glows brightly with the essense of life!", lfname);
}
if (!target) { if (!target) {
target = caster; target = caster;
} }
@ -12381,15 +12520,31 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
lf = targcell->lf; lf = targcell->lf;
if (lf && (lf != caster) && isundead(lf)) { if (lf && (lf != caster) && isundead(lf)) {
int howlong = 10; int howlong = 10;
int worked = B_TRUE; int worked = B_FALSE;
// TODO: does it work? depends on caster level & intelligence & power if ((gettr(caster)+power)*2 > gettr(lf)) {
worked = B_TRUE; worked = B_TRUE;
// TODO: how long for? depends on caster level & intelligence & power } else {
int diff;
diff = gettr(lf) - ((gettr(caster)+power)*2);
// if monster level is too high, the chance of working
// is 50%, -10% for every level too high.
if (pctchance(50-diff)) {
worked = B_TRUE;
}
}
howlong = rnd(10,20)+(power*2); howlong = rnd(10,20)+(power*2);
if (worked) { if (worked) {
// don't use scare() since it will fail due to them being undead. // don't use scare() since it will fail due to them being undead.
addtempflag(lf->flags, F_FLEEFROM, target->id, NA, NA, NULL,howlong); addtempflag(lf->flags, F_FLEEFROM, target->id, NA, NA, NULL,howlong);
ndone++; ndone++;
} else {
if (isplayer(lf)) {
msg("You resist the urge to flee from the lifeforce aura.");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s flinches.", lfname);
}
} }
} }
} }
@ -14476,6 +14631,10 @@ int stopallspells(lifeform_t *lf) {
if (!stopspell(lf, f->val[0])) nstopped++; if (!stopspell(lf, f->val[0])) nstopped++;
} }
} }
// also stop spelllike abilities
nstopped += killflagsofid(lf->flags, F_FULLSHIELD);
return nstopped; return nstopped;
} }
@ -14582,7 +14741,20 @@ void spellcloud(cell_t *srcloc, int radius, int dirtype, int ch, enum COLOUR col
safe = B_TRUE; safe = B_TRUE;
} }
if (aimedateyes && (!hasbp(c->lf, BP_EYES) || getarmour(c->lf, BP_EYES))) { if (aimedateyes && (!hasbp(c->lf, BP_EYES) || getarmour(c->lf, BP_EYES))) {
object_t *arm;
safe = B_TRUE; safe = B_TRUE;
arm = getarmour(c->lf, BP_EYES);
if (arm) {
char armname[BUFLEN];
getobname(arm, armname, 1);
if (isplayer(c->lf)) {
msg("Your %s protects your eyes.", noprefix(armname));
} else if (cansee(player, c->lf)) {
char lfname[BUFLEN];
getlfname(c->lf, lfname);
msg("%s%s %s protects its eyes.", lfname, getpossessive(lfname), noprefix(armname));
}
}
} }
if (!safe) { if (!safe) {
if (distfunc(srcloc, c) <= radius) { if (distfunc(srcloc, c) <= radius) {

17
text.c
View File

@ -610,9 +610,9 @@ char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam
} else if (dam <= 16) { } else if (dam <= 16) {
return "slam"; return "slam";
} else if (dam <= 20) { } else if (dam <= 20) {
return "pummel"; return "smash";
} else { } else {
return "clobber"; return "pulverise";
} }
} }
} else if (damtype == DT_BITE) { } else if (damtype == DT_BITE) {
@ -708,7 +708,7 @@ char *getattackverb(lifeform_t *lf, object_t *wep, enum DAMTYPE damtype, int dam
if (dam <= 2) { if (dam <= 2) {
return "scratch"; return "scratch";
} else if (dam <= 6) { } else if (dam <= 6) {
return "hit"; return "cut";
} else if (dam <= 12) { } else if (dam <= 12) {
return "slash"; return "slash";
} else { } else {
@ -1324,14 +1324,11 @@ char *getkillverb(lifeform_t *victim, object_t *wep, enum DAMTYPE damtype, int d
if (canbehead) { if (canbehead) {
if (victim && (victim->race->id == R_EARTHWYRM)) { if (victim && (victim->race->id == R_EARTHWYRM)) {
return "bisect"; return "bisect";
} else if (!hasbp(victim, BP_HEAD)) { } else if (hasbp(victim, BP_HEAD) && (getlfsize(victim) >= SZ_MEDIUM) && onein(3)) {
return "bisect";
} else {
if ((getlfsize(victim) >= SZ_MEDIUM) && onein(3)) {
return "behead"; return "behead";
} else { } else {
return "bisect"; if (onein(2) && (getraceclass(victim) == RC_HUMANOID)) return "dismember";
} else return "bisect";
} }
} }
} }
@ -2122,7 +2119,7 @@ char *makekillertext(char *retbuf, char *killverb, char *lastdam, map_t *where,
p = strtok_r(lastdam,"^", &dummy); p = strtok_r(lastdam,"^", &dummy);
if (p) { if (p) {
if (!strcmp(p, "you")) { if (streq(p, "you")) {
strcpy(retbuf, "Committed suicide"); strcpy(retbuf, "Committed suicide");
} else { } else {
snprintf(retbuf, BUFLEN, "%s %s %s",killverb, snprintf(retbuf, BUFLEN, "%s %s %s",killverb,