- [+] rename dragon to wyrm

- [+] cooked food shouldn't "completely rot away"
- [+] fire l6: meteor - large version of fireball
- [+] burning feet
- [+] evaporate should be a fire spell too.
- [+] more gods should remove curse for you.
- [+] eyebats shouldn't sleep
- [+] make hecta's prayers even more powerful.
- [+] fix bug in bjorn's truestrike effect
- [+] bjorn should un-dull weapons
- [+] fix buggy supply closet definitions - was getting 1-5 of same
      object rather than 1-5 different ones
- [+] restrict potion of growth to lower levels.
- [+] change method of determining how much you can carry.
- [+] change initial modification spell to 'enlarge object'
- [+] enlarge object
    - [+] door -> seals with surroundings
    - [+] rock -> boulder
    - [+] sword -> greatsword
    - [+] buckler -> next size shield
    - [+] bag -> next size bag
    - [+] or should this be a different spell?
- [+] immolate
    - [+] if a successful unarmed attack, lf catches on fire.
- [+] wizard isn't weilding staff. are fists better?
- [+] freezing touch shouldn't work on dragonwood
- [+] fix bug preventing vision when meditating
- [+] auto shortcuts
    - [+] wizards: pri/sec spells are 1/2
    - [+] cook:  lowest shortcut left.
- [+] statbar not being updated when i drink potion of magic.
- [+] warn that flying will stop mapping.
- [+] bjorn gifts should only be ones which you are skilled in!
    - [+] add 'appropriate'
    - [+] then apply to god.c
- [+] warn if you pick up poison stuff and you god doesn't like it
    - [+] "I hope you're not planning on using that/those...."
- [+] superheat - throw potion like a grenade
This commit is contained in:
Rob Pearce 2012-01-29 22:47:43 +00:00
parent a4ac951f15
commit ee42bdc73f
22 changed files with 877 additions and 265 deletions

46
ai.c
View File

@ -1,3 +1,4 @@
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -576,6 +577,21 @@ int aigetspelltarget(lifeform_t *lf, objecttype_t *spelltype, lifeform_t *victim
if (spellcell) *spellcell = l->cell; if (spellcell) *spellcell = l->cell;
if (spellob) *spellob = NULL; if (spellob) *spellob = NULL;
} }
} else if (spelltype->id == OT_S_SUPERHEAT) {
// get all potions
object_t *poss[MAXPILEOBS],*o;
int nposs = 0;
for (o = lf->pack->first ; o ; o = o->next) {
if (hasflag(o->flags, F_DRINKABLE)) {
poss[nposs++] = o;
}
}
assert(nposs); // aispellok should have checked.
if (spelllf) *spelllf = NULL;
if (spellcell) *spellcell = victim->cell;
if (spellob) *spellob = poss[rnd(0,nposs-1)];
} }
} }
return B_FALSE; return B_FALSE;
@ -907,19 +923,32 @@ int ai_bored(lifeform_t *lf, lifeform_t *master, int icanattack) {
// returns true if we did somethign // returns true if we did somethign
int ai_handle_emergencies(lifeform_t *lf, enum ATTRBRACKET iqb) { int ai_handle_emergencies(lifeform_t *lf, enum ATTRBRACKET iqb) {
int db = B_FALSE; int db = B_FALSE;
int moveawayfromcell = B_FALSE;
if (lfhasflag(lf, F_DEBUG)) db = B_TRUE; if (lfhasflag(lf, F_DEBUG)) db = B_TRUE;
if (lfhasflag(lf, F_RAGE)) return B_FALSE; if (lfhasflag(lf, F_RAGE)) return B_FALSE;
if (iqb >= AT_AVERAGE) { if (iqb >= AT_AVERAGE) {
if (celldangerous(lf, lf->cell, B_TRUE, NULL)) { if (celldangerous(lf, lf->cell, B_TRUE, NULL)) {
if (db) dblog("%s o O { there is something dangerous here, moving away } ", lf->race->name);
// if our cell is dangerous, move away! // if our cell is dangerous, move away!
if (!dorandommove(lf, B_NOBADMOVES, B_FALSE)) { moveawayfromcell = B_TRUE;
return B_TRUE;
}
} }
} }
// hot feet? move somewhere.
if (!moveawayfromcell && lfhasflag(lf, F_HOTFEET) && !isimmuneto(lf->flags, DT_FIRE, B_FALSE)) {
if (db) dblog("%s o O { i have f_hotfeet, moving away } ", lf->race->name);
moveawayfromcell = B_TRUE;
}
if (moveawayfromcell) {
if (!dorandommove(lf, B_NOBADMOVES, B_FALSE, B_TRUE)) {
return B_TRUE;
}
}
// flying monsters not flying? // flying monsters not flying?
if (!isprone(lf)) { if (!isprone(lf)) {
if (hasflag(lf->race->flags, F_FLYING) && !lfhasflag(lf, F_FLYING)) { if (hasflag(lf->race->flags, F_FLYING) && !lfhasflag(lf, F_FLYING)) {
@ -1347,7 +1376,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
} else if (isadjacent(lf->cell, target->cell)) { } else if (isadjacent(lf->cell, target->cell)) {
if (db) dblog(".oO { i can see my master adjacent - moving randomly }"); if (db) dblog(".oO { i can see my master adjacent - moving randomly }");
// move randomly. TODO: just return ?? // move randomly. TODO: just return ??
dorandommove(lf, B_NOBADMOVES, B_TRUE); dorandommove(lf, B_NOBADMOVES, B_TRUE, B_FALSE);
return B_FALSE; return B_FALSE;
} }
// otherwise fall through to below movement code. // otherwise fall through to below movement code.
@ -1645,7 +1674,7 @@ int aimovetolf(lifeform_t *lf, lifeform_t *target, int wantattack) {
if (onein(2)) { if (onein(2)) {
rest(lf, B_TRUE); rest(lf, B_TRUE);
} else { } else {
if (dorandommove(lf, B_NOBADMOVES, B_FALSE)) { if (dorandommove(lf, B_NOBADMOVES, B_FALSE, B_FALSE)) {
rest(lf, B_TRUE); rest(lf, B_TRUE);
} }
} }
@ -1915,7 +1944,7 @@ void aiturn(lifeform_t *lf) {
// DEFAULT - try to move in a random direction // DEFAULT - try to move in a random direction
if (db) dblog(".oO { default - moving randomly }"); if (db) dblog(".oO { default - moving randomly }");
dorandommove(lf, B_NOBADMOVES, B_TRUE); // this function will call rest() if we cant move dorandommove(lf, B_NOBADMOVES, B_TRUE, B_FALSE); // this function will call rest() if we cant move
// somehow still here? // somehow still here?
if (!lf->timespent) { if (!lf->timespent) {
@ -2182,6 +2211,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
if (getnearbypeaceful(lf)) { if (getnearbypeaceful(lf)) {
ok = B_TRUE; ok = B_TRUE;
} }
} else if (ot->id == OT_S_SUPERHEAT) {
// got a potion?
if (victim && hasobwithflag(lf->pack, F_DRINKABLE) && haslof(lf->cell, victim->cell, LOF_NEED, NULL)) {
ok = B_TRUE;
}
} else { } else {
if (db) dblog(".oO { cant cast %s - specialcase conditions not yet coded }", ot ? ot->name : "?unkownspell?"); if (db) dblog(".oO { cant cast %s - specialcase conditions not yet coded }", ot ? ot->name : "?unkownspell?");
return B_FALSE; return B_FALSE;

View File

@ -18,6 +18,9 @@
extern lifeform_t *player; extern lifeform_t *player;
extern lifeform_t *godlf[];
extern int ngodlfs;
extern enum ERROR reason; extern enum ERROR reason;
int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype, lifeform_t *attacker) { int applyarmourdamage(lifeform_t *lf, object_t *wep, int dam, enum DAMTYPE damtype, lifeform_t *attacker) {
@ -512,11 +515,21 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
} }
} }
if (lfhasflag(lf, F_USEDPOISON)) { if (lfhasflag(lf, F_USEDPOISON)) {
int i;
flag_t *f;
killflagsofid(lf->flags, F_USEDPOISON); killflagsofid(lf->flags, F_USEDPOISON);
angergodmaybe(R_GODPURITY, 100, GA_POISON); for (i = 0; i < ngodlfs; i++) {
angergodmaybe(R_GODMERCY, 25, GA_POISON); if (godlf[i]) {
angergodmaybe(R_GODBATTLE, 25, GA_POISON); f = lfhasflag(godlf[i], F_GODPOISON);
pleasegodmaybe(R_GODDEATH, 3); if (f) {
if (f->val[0]) {
pleasegodmaybe(godlf[i]->race->id, f->val[1]);
} else {
angergodmaybe(godlf[i]->race->id, f->val[1], GA_POISON);
}
}
}
}
} }
} }
} }
@ -561,7 +574,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
enum BODYPART critpos = BP_NONE; enum BODYPART critpos = BP_NONE;
if (wep) { if (wep) {
wepsk = getobskill(wep); wepsk = getobskill(wep->flags);
} }
if (lfhasflag(lf, F_DEBUG)) { if (lfhasflag(lf, F_DEBUG)) {

120
data.c
View File

@ -1039,6 +1039,8 @@ void initobjects(void) {
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_SLOWMOVE, 5, NA, NULL, PERMENANT, B_UNKNOWN, -1); addflag_real(lastbrand->flags, F_EQUIPCONFER, F_SLOWMOVE, 5, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addbrand(BR_STEALTH, "of stealth", BP_FEET, B_UNCURSED, 0); addbrand(BR_STEALTH, "of stealth", BP_FEET, B_UNCURSED, 0);
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_SILENTMOVE, B_TRUE, NA, NULL, PERMENANT, B_UNKNOWN, -1); addflag_real(lastbrand->flags, F_EQUIPCONFER, F_SILENTMOVE, B_TRUE, NA, NULL, PERMENANT, B_UNKNOWN, -1);
addbrand(BR_PUNISHMENT, "of punishment", BP_FEET, B_CURSED, 80);
addflag_real(lastbrand->flags, F_EQUIPCONFER, F_HOTFEET, 1, DT_FIRE, "red-hot footwear", PERMENANT, B_UNKNOWN, -1);
// hands // hands
addbrand(BR_POWER, "of power", BP_HANDS, B_UNCURSED, 0); addbrand(BR_POWER, "of power", BP_HANDS, B_UNCURSED, 0);
@ -1132,10 +1134,11 @@ void initobjects(void) {
addflag(lastmaterial->flags, F_MATCONVERT, MT_FIRE, NA, NA, "lump of melted wax"); addflag(lastmaterial->flags, F_MATCONVERT, MT_FIRE, NA, NA, "lump of melted wax");
addflag(lastmaterial->flags, F_MATCONVERTTEXT, MT_FIRE, NA, NA, "melts"); addflag(lastmaterial->flags, F_MATCONVERTTEXT, MT_FIRE, NA, NA, "melts");
addflag(lastmaterial->flags, F_MATCONVERTTEXTPL, MT_FIRE, NA, NA, "melt"); addflag(lastmaterial->flags, F_MATCONVERTTEXTPL, MT_FIRE, NA, NA, "melt");
addmaterial(MT_DRAGONWOOD, "dragonwood", 3); addmaterial(MT_DRAGONWOOD, "wyrmwood", 3);
addflag(lastmaterial->flags, F_HARDNESS, 5, NA, NA, NULL); addflag(lastmaterial->flags, F_HARDNESS, 5, NA, NA, NULL);
addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL); addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL); addflag(lastmaterial->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addmaterial(MT_RUBBER, "rubber", 4); addmaterial(MT_RUBBER, "rubber", 4);
addmaterial(MT_LEATHER, "leather", 4); addmaterial(MT_LEATHER, "leather", 4);
addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL); addflag(lastmaterial->flags, F_CANGETWET, B_TRUE, NA, NA, NULL);
@ -1593,7 +1596,6 @@ void initobjects(void) {
addflag(lastot->flags, F_REPELBLESSED, B_BLESSED, B_CURSED, NA, NULL); addflag(lastot->flags, F_REPELBLESSED, B_BLESSED, B_CURSED, NA, NULL);
addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOFEEL, B_TRUE, NA, NA, NULL);
addot(OT_PORTAL, "magic portal", "A magical portal to a different place...", MT_MAGIC, 0, OC_DFEATURE, SZ_LARGE); addot(OT_PORTAL, "magic portal", "A magical portal to a different place...", MT_MAGIC, 0, OC_DFEATURE, SZ_LARGE);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 80, RR_VERYRARE, NULL);
addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, '^', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BOLDGREEN, '^', NA, NULL);
@ -1815,7 +1817,6 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL); addflag(lastot->flags, F_OBHP, 80, 80, NA, NULL);
addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "50-100 stones"); addflag(lastot->flags, F_DIECONVERT, NA, NA, NA, "50-100 stones");
addot(OT_ICICLE, "huge icicle", "A massive ice stalacmite.", MT_ICE, 200, OC_ROCK, SZ_LARGE); addot(OT_ICICLE, "huge icicle", "A massive ice stalacmite.", MT_ICE, 200, OC_ROCK, SZ_LARGE);
addflag(lastot->flags, F_GLYPH, C_CYAN, '\'', NA, NULL); addflag(lastot->flags, F_GLYPH, C_CYAN, '\'', NA, NULL);
addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL); addflag(lastot->flags, F_IMPASSABLE, SZ_MIN, SZ_LARGE, NA, NULL);
@ -2224,7 +2225,7 @@ void initobjects(void) {
addot(OT_POT_CANINETRACKING, "potion of canine tracking", "Mimics the effects of a 'canine tracking' spell.", MT_GLASS, 1, OC_POTION, SZ_TINY); addot(OT_POT_CANINETRACKING, "potion of canine tracking", "Mimics the effects of a 'canine tracking' spell.", MT_GLASS, 1, OC_POTION, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_COMMON, NULL);
addot(OT_POT_GROWTH, "potion of growth", "A magical liquid which causes the imbiber's body to instantly undergo rapid growth.", MT_GLASS, 1, OC_POTION, SZ_TINY); addot(OT_POT_GROWTH, "potion of growth", "A magical liquid which causes the imbiber's body to instantly undergo rapid growth.", MT_GLASS, 1, OC_POTION, SZ_TINY);
addflag(lastot->flags, F_RARITY, H_ALL, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 75, RR_RARE, NULL);
addflag(lastot->flags, F_VALUE, 50, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 50, NA, NA, NULL);
addot(OT_POT_HEALINGMIN, "potion of minor healing", "Restores 1-10 health to whoever drinks it.", MT_GLASS, 1, OC_POTION, SZ_TINY); addot(OT_POT_HEALINGMIN, "potion of minor healing", "Restores 1-10 health to whoever drinks it.", MT_GLASS, 1, OC_POTION, SZ_TINY);
@ -2856,6 +2857,16 @@ void initobjects(void) {
// elemental - fire // elemental - fire
/////////////////// ///////////////////
// l1 // l1
addot(OT_S_BURNINGFEET, "hotfoot", "Heats the soles of the target's feet to an uncomfortable level, dealing 1 fire damage each turn they remain still.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "If the target is wearing metal footwear, damage is inceased to 2 per turn.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines its duration (maximum 6 turns).");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 3, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_SPARK, "flambe", "Creates very hot but short lived burst of flame around the target, dealing 2d2 fire damage to creatures and objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SPARK, "flambe", "Creates very hot but short lived burst of flame around the target, dealing 2d2 fire damage to creatures and objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
@ -2884,15 +2895,37 @@ 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_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
addot(OT_S_IMMOLATE, "immolate", "If the caster can successfully touch the target, they are instantly engulfed in flames.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
addot(OT_S_SUPERHEAT, "superheat", "Excites the liquid molecules in a single potion, causing its contents to explode upon impact (8d2 damage).", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL);
// l3 // l3
addot(OT_S_FLAMEBURST, "flame burst", "Creates a radial blast of fire out from the caster, inflicting 2d6 fire damage to all within.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_FLAMEBURST, "flame burst", "Creates a radial blast of fire out from the caster, inflicting 2d6 fire damage to all within.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The size of the radial blast is based on the spell's power."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The size of the radial blast is based on the spell's power.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
addot(OT_S_FIREBALL, "fireball", "Creates a huge ball of fire, dealing up to ^bpower^nd3 damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The damage is lower for enemies further away from the ball's centre.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_RANGE, 6, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // TODO: should be "near victim"
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
// l4 // l4
addot(OT_S_FLAMEPILLAR, "flame pillar", "Creates a tall pillar of flame.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_FLAMEPILLAR, "flame pillar", "Creates a tall pillar of flame.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the size and duration of the fire."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the spell's range, and the fire's size.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
@ -2910,10 +2943,11 @@ 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_RANGE, 3, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL);
addot(OT_S_FIREBALL, "fireball", "Creates a huge ball of fire, dealing up to ^bpower^nd3 damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); // l6
addot(OT_S_METEOR, "meteor", "Launches a white-hot meteorite towards the target location, dealing up to ^bpower^nd6+30 damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The damage is lower for enemies further away from the ball's centre."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The damage is lower for enemies further away from the ball's centre.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // TODO: should be "near victim" addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // TODO: should be "near victim"
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL);
@ -3114,6 +3148,14 @@ 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);
// l3 // l3
addot(OT_S_EVAPORATE, "evaporate", "Instantly converts all water in the given area into scalding steam (including potions).", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the amount of water affected.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_OBJECT, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_CALLLIGHTNING, "call lightning", "Blasts a single enemy with a bolt of lightning from the sky, dealing 3d6 damage (4d6 if outdoors).", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_CALLLIGHTNING, "call lightning", "Blasts a single enemy with a bolt of lightning from the sky, dealing 3d6 damage (4d6 if outdoors).", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL);
@ -3145,12 +3187,6 @@ void initobjects(void) {
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, 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);
addot(OT_S_EVAPORATE, "evaporate", "Instantly converts all water in the given area into steam.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the amount of water affected.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_SLEETSTORM, "sleet storm", "Creates an cloud of sleet, hampering vision and movement.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SLEETSTORM, "sleet storm", "Creates an cloud of sleet, hampering vision and movement.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the size of the storm."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the size of the storm.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "This spell's power is boosted when cast outside."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "This spell's power is boosted when cast outside.");
@ -3484,6 +3520,11 @@ void initobjects(void) {
// modification // modification
/////////////////// ///////////////////
// l1 // l1
addot(OT_S_OBJECTGROWTH, "enlarge object", "Causes the target object to grow to an enormous size.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_HOLDPORTAL, "seal entrance", "Magically closes and jams a door, preventing it from opening.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_HOLDPORTAL, "seal entrance", "Magically closes and jams a door, preventing it from opening.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL);
@ -5114,7 +5155,7 @@ void initobjects(void) {
addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL); addflag(lastot->flags, F_OBHP, 3, 3, NA, NULL);
addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL); addflag(lastot->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_WALKDAM,DT_FIRE, NA, NA, "8d4"); addflag(lastot->flags, F_WALKDAM,DT_FIRE, NA, NA, "6d4");
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_PRODUCESLIGHT, 10, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 10, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
@ -6644,7 +6685,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 3, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL);
@ -6657,7 +6698,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 3, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL);
@ -6671,7 +6712,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_RARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 3, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL);
@ -6684,7 +6725,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 3, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL);
@ -6698,7 +6739,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 3, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL);
@ -6712,7 +6753,7 @@ void initobjects(void) {
addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL); addflag(lastot->flags, F_GLYPH, C_BROWN, ')', NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 3, NA, NULL);
addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL); addflag(lastot->flags, F_OBATTACKDELAY, 100, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL); addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_LORE_ARCANA, NA, NA, NULL);
@ -7590,6 +7631,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CANWILL, OT_S_WISHLIMITED, NA, NA, "pw:10;"); addflag(lastrace->flags, F_CANWILL, OT_S_WISHLIMITED, NA, NA, "pw:10;");
addflag(lastrace->flags, F_CANWILL, OT_S_PLANESHIFT, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANWILL, OT_S_PLANESHIFT, NA, NA, "pw:1;");
// likes/dislikes // likes/dislikes
addflag(lastrace->flags, F_GODPOISON, B_FALSE, 100, NA, NULL);
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "destroying the undead"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "destroying the undead");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "killing evil creatures"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "killing evil creatures");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "blessing objects"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "blessing objects");
@ -7644,6 +7686,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CANWILL, OT_A_HURRICANESTRIKE, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_HURRICANESTRIKE, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_FLURRY, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_FLURRY, NA, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_SHIELDBASH, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_SHIELDBASH, NA, NA, NULL);
addflag(lastrace->flags, F_GODPOISON, B_FALSE, 25, NA, NULL);
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "victory in battle"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "victory in battle");
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "prolonged peace"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "prolonged peace");
addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "the use of poison"); addflag(lastrace->flags, F_GODDISLIKES, NA, NA, NA, "the use of poison");
@ -7742,6 +7785,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CANWILL, OT_S_WISHLIMITED, NA, NA, "pw:10;"); addflag(lastrace->flags, F_CANWILL, OT_S_WISHLIMITED, NA, NA, "pw:10;");
addflag(lastrace->flags, F_CANWILL, OT_S_PLANESHIFT, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANWILL, OT_S_PLANESHIFT, NA, NA, "pw:1;");
// likes // likes
addflag(lastrace->flags, F_GODPOISON, B_TRUE, 3, NA, NULL);
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "killing (especially the good-aligned)"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "killing (especially the good-aligned)");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "attacking the helpless"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "attacking the helpless");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "casting necromancy spells"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "casting necromancy spells");
@ -7834,6 +7878,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CANWILL, OT_S_DISPERSAL, NA, NA, "pw:10;"); addflag(lastrace->flags, F_CANWILL, OT_S_DISPERSAL, NA, NA, "pw:10;");
addflag(lastrace->flags, F_CANWILL, OT_S_SLEEP, NA, NA, "pw:10;"); addflag(lastrace->flags, F_CANWILL, OT_S_SLEEP, NA, NA, "pw:10;");
addflag(lastrace->flags, F_CANWILL, OT_S_PLANESHIFT, NA, NA, "pw:1;"); addflag(lastrace->flags, F_CANWILL, OT_S_PLANESHIFT, NA, NA, "pw:1;");
addflag(lastrace->flags, F_GODPOISON, B_FALSE, 25, NA, NULL);
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "the successful casting of healing spells"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "the successful casting of healing spells");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "allowing fleeing creatures to escape"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "allowing fleeing creatures to escape");
addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "acts of charity"); addflag(lastrace->flags, F_GODLIKES, NA, NA, NA, "acts of charity");
@ -7910,7 +7955,7 @@ void initrace(void) {
addflag(lastrace->flags, F_MINIONS, 20, 1, 3, "goblin warrior"); addflag(lastrace->flags, F_MINIONS, 20, 1, 3, "goblin warrior");
addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 10, NA, NA, NULL);
addrace(R_COCKATRICE, "cockatrice", 5, 'c', C_YELLOW, MT_FLESH, RC_MAGIC, "A small two-legged dragon with a rooster's head. Its touch is said to petrify the flesh of living creatures."); addrace(R_COCKATRICE, "cockatrice", 5, 'c', C_YELLOW, MT_FLESH, RC_DRAGON, "A small two-legged wyrm with a rooster's head. Its touch is said to petrify the flesh of living creatures.");
setbodytype(lastrace, BT_QUADRAPED); setbodytype(lastrace, BT_QUADRAPED);
addbodypart(lastrace, BP_WINGS, NULL); addbodypart(lastrace, BP_WINGS, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -8016,6 +8061,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_PERCEPTION, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings"); addflag(lastrace->flags, F_NOISETEXT, N_FLY, 1, NA, "^flapping wings");
addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 30, NA, NA, NULL);
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addrace(R_TRICLOPS, "triclops", 160, 'H', C_BROWN, MT_FLESH, RC_HUMANOID, "The three-eyes triclops race are blessed with extraordiny perceptive and are nearly impossible to surprise. They commonly use their third eye to stun enemies, then finish them off with their huge weapons."); addrace(R_TRICLOPS, "triclops", 160, 'H', C_BROWN, MT_FLESH, RC_HUMANOID, "The three-eyes triclops race are blessed with extraordiny perceptive and are nearly impossible to surprise. They commonly use their third eye to stun enemies, then finish them off with their huge weapons.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -10567,8 +10613,8 @@ void initrace(void) {
addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CANEATRAW, B_TRUE, NA, NA, NULL);
// end animals // end animals
// dragons // dragons / wyrms
addrace(R_DRAGONBLUE, "blue dragon", 400, 'D', C_BLUE, MT_FLESH, RC_DRAGON, "Blue dragons are massive reptilian creatures who can (and will) consume almost any living creature."); addrace(R_DRAGONBLUE, "blue wyrm", 400, 'D', C_BLUE, MT_FLESH, RC_DRAGON, "Blue wyrms are massive reptilian creatures who can (and will) consume almost any living creature.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addbodypart(lastrace, BP_WINGS, NULL); addbodypart(lastrace, BP_WINGS, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -10616,7 +10662,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);
addrace(R_DRAGONBLUEY, "young blue dragon", 150, 'D', C_BLUE, MT_FLESH, RC_DRAGON, "Blue dragons are massive reptilian creatures who can (and will) consume almost any living creature."); addrace(R_DRAGONBLUEY, "young blue wyrms", 150, 'D', C_BLUE, MT_FLESH, RC_DRAGON, "Blue wyrms are massive reptilian creatures who can (and will) consume almost any living creature.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addbodypart(lastrace, BP_WINGS, NULL); addbodypart(lastrace, BP_WINGS, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -10664,7 +10710,7 @@ void initrace(void) {
addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, 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_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addrace(R_DRAGONBLUEA, "ancient blue dragon", 600, 'D', C_BLUE, MT_FLESH, RC_DRAGON, "Blue dragons are massive reptilian creatures who can (and will) consume almost any living creature."); addrace(R_DRAGONBLUEA, "ancient blue wyrms", 600, 'D', C_BLUE, MT_FLESH, RC_DRAGON, "Blue wyrms are massive reptilian creatures who can (and will) consume almost any living creature.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addbodypart(lastrace, BP_WINGS, NULL); addbodypart(lastrace, BP_WINGS, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -10720,7 +10766,7 @@ void initrace(void) {
addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addrace(R_DRAGONRED, "red dragon", 400, 'D', C_RED, MT_FLESH, RC_DRAGON, "Red dragons are massive evil reptilians who thrive on destruction, especially by means of fire."); addrace(R_DRAGONRED, "red wyrms", 400, 'D', C_RED, MT_FLESH, RC_DRAGON, "Red wyrms are massive evil reptilians who thrive on destruction, especially by means of fire.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addbodypart(lastrace, BP_WINGS, NULL); addbodypart(lastrace, BP_WINGS, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -10768,7 +10814,7 @@ void initrace(void) {
addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, 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_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addrace(R_DRAGONREDY, "young red dragon", 150, 'D', C_RED, MT_FLESH, RC_DRAGON, "Red dragons are massive evil reptilians who thrive on destruction, especially by means of fire."); addrace(R_DRAGONREDY, "young red wyrms", 150, 'D', C_RED, MT_FLESH, RC_DRAGON, "Red wyrms are massive evil reptilians who thrive on destruction, especially by means of fire.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addbodypart(lastrace, BP_WINGS, NULL); addbodypart(lastrace, BP_WINGS, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -10812,7 +10858,7 @@ void initrace(void) {
addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, 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_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addrace(R_DRAGONREDA, "ancient red dragon", 600, 'D', C_RED, MT_FLESH, RC_DRAGON, "Red dragons are massive evil reptilians who thrive on destruction, especially by means of fire."); addrace(R_DRAGONREDA, "ancient red wyrms", 600, 'D', C_RED, MT_FLESH, RC_DRAGON, "Red wyrms are massive evil reptilians who thrive on destruction, especially by means of fire.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addbodypart(lastrace, BP_WINGS, NULL); addbodypart(lastrace, BP_WINGS, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -10863,7 +10909,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);
addrace(R_DRAGONWHITE, "white dragon", 400, 'D', C_WHITE, MT_FLESH, RC_DRAGON, "Although white dragons are smaller than other varieties, their icy breath still makes them a formidable threat."); addrace(R_DRAGONWHITE, "white wyrms", 400, 'D', C_WHITE, MT_FLESH, RC_DRAGON, "Although white wyrms are smaller than other varieties, their icy breath still makes them a formidable threat.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addbodypart(lastrace, BP_WINGS, NULL); addbodypart(lastrace, BP_WINGS, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -10910,7 +10956,7 @@ void initrace(void) {
addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, 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_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addrace(R_DRAGONWHITEY, "young white dragon", 150, 'D', C_WHITE, MT_FLESH, RC_DRAGON, "Although white dragons are smaller than other varieties, their icy breath still makes them a formidable threat."); addrace(R_DRAGONWHITEY, "young white wyrms", 150, 'D', C_WHITE, MT_FLESH, RC_DRAGON, "Although white wyrms are smaller than other varieties, their icy breath still makes them a formidable threat.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addbodypart(lastrace, BP_WINGS, NULL); addbodypart(lastrace, BP_WINGS, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -10952,7 +10998,7 @@ void initrace(void) {
addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, 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_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
addrace(R_DRAGONWHITEA, "ancient white dragon", 600, 'D', C_WHITE, MT_FLESH, RC_DRAGON, "Although white dragons are smaller than other varieties, their icy breath still makes them a formidable threat."); addrace(R_DRAGONWHITEA, "ancient white wyrms", 600, 'D', C_WHITE, MT_FLESH, RC_DRAGON, "Although white wyrms are smaller than other varieties, their icy breath still makes them a formidable threat.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addbodypart(lastrace, BP_WINGS, NULL); addbodypart(lastrace, BP_WINGS, NULL);
addbodypart(lastrace, BP_TAIL, NULL); addbodypart(lastrace, BP_TAIL, NULL);
@ -11002,7 +11048,7 @@ void initrace(void) {
addflag(lastrace->flags, F_WANTS, OT_GOLD, NA, NA, NULL); addflag(lastrace->flags, F_WANTS, OT_GOLD, 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_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL);
// end dragons // end dragons / wyrms
// insects // insects
addrace(R_BLASTBUG, "blastbug", 2, 'x', C_ORANGE, MT_STONE, RC_INSECT, "Blastbugs have somehow evolved the ability to de-stabalise nearby oxygen molecules, resulting in devestation explosions."); addrace(R_BLASTBUG, "blastbug", 2, 'x', C_ORANGE, MT_STONE, RC_INSECT, "Blastbugs have somehow evolved the ability to de-stabalise nearby oxygen molecules, resulting in devestation explosions.");
@ -11468,7 +11514,7 @@ void initrace(void) {
addflag(lastrace->flags, F_HASATTACK, OT_TOUCHCHILL, 7, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TOUCHCHILL, 7, NA, NULL);
addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL); addflag(lastrace->flags, F_DTVULN, DT_FIRE, NA, NA, NULL);
addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "shoddy cloak"); addflag(lastrace->flags, F_STARTOB, 50, NA, NA, "shoddy cloak");
addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "scheeches^a screech"); addflag(lastrace->flags, F_NOISETEXT, N_GETANGRY, 3, NA, "screeches^a screech");
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_DEAF, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SEEINDARK, B_TRUE, NA, NA, NULL);
@ -11779,7 +11825,7 @@ void initraceclasses(void) {
addraceclass(RC_ANIMAL, "animal", "animals and insects", SK_LORE_NATURE); addraceclass(RC_ANIMAL, "animal", "animals and insects", SK_LORE_NATURE);
addraceclass(RC_AQUATIC, "aquatic creature", "aquatic creatures", SK_LORE_NATURE); addraceclass(RC_AQUATIC, "aquatic creature", "aquatic creatures", SK_LORE_NATURE);
addraceclass(RC_DEMON, "demon", "demons", SK_LORE_DEMONS); addraceclass(RC_DEMON, "demon", "demons", SK_LORE_DEMONS);
addraceclass(RC_DRAGON, "dragon", "dragons", SK_LORE_DRAGONS); addraceclass(RC_DRAGON, "wyrm", "wyrms", SK_LORE_DRAGONS);
addraceclass(RC_GOD, "god", "dieties", SK_NONE); addraceclass(RC_GOD, "god", "dieties", SK_NONE);
addraceclass(RC_HUMANOID, "humanoid", "humanoid creatures", SK_LORE_HUMANOID); addraceclass(RC_HUMANOID, "humanoid", "humanoid creatures", SK_LORE_HUMANOID);
addraceclass(RC_INSECT, "insect", "insects and animals", SK_LORE_NATURE); addraceclass(RC_INSECT, "insect", "insects and animals", SK_LORE_NATURE);
@ -11965,17 +12011,15 @@ void initskills(void) {
addskilldesc(SK_TWOWEAPON, PR_EXPERT, "^gYou gain the 'flurry attack' ability.^n", B_FALSE); addskilldesc(SK_TWOWEAPON, PR_EXPERT, "^gYou gain the 'flurry attack' ability.^n", B_FALSE);
addskilldesc(SK_TWOWEAPON, PR_MASTER, "^gYou can now deflect attacks with your second weapon.^n", B_TRUE); addskilldesc(SK_TWOWEAPON, PR_MASTER, "^gYou can now deflect attacks with your second weapon.^n", B_TRUE);
// knowledge // knowledge
// descriptions for all of these will be added later.
addskill(SK_LORE_ARCANA, "Lore:Arcana", "Allows you a chance of recognising magical objects and creatures.", 5); addskill(SK_LORE_ARCANA, "Lore:Arcana", "Allows you a chance of recognising magical objects and creatures.", 5);
addskilldesc(SK_LORE_ARCANA, PR_NOVICE, "^gYou can attempt to identify objects with the 'inspect' ability.^n", B_FALSE); addskilldesc(SK_LORE_ARCANA, PR_NOVICE, "^gYou can attempt to identify objects with the 'inspect' ability.^n", B_FALSE);
addskilldesc(SK_LORE_ARCANA, PR_ADEPT, "^gYou gain the 'study scrolls' ability.", B_FALSE); addskilldesc(SK_LORE_ARCANA, PR_ADEPT, "^gYou gain the 'study scrolls' ability.", B_FALSE);
// descriptions will be added later.
addskill(SK_LORE_DEMONS, "Lore:Demonology", "Determines your knowledge about demons.", 5); addskill(SK_LORE_DEMONS, "Lore:Demonology", "Determines your knowledge about demons.", 5);
// descriptions will be added later.
addskill(SK_LORE_DRAGONS, "Lore:Dragons", "Determines your knowledge about dragons.", 5);
// descriptions will be added later.
addskill(SK_LORE_HUMANOID, "Lore:Humanoid", "Determines your knowledge about humanoid (bipedal) creatures.", 5); addskill(SK_LORE_HUMANOID, "Lore:Humanoid", "Determines your knowledge about humanoid (bipedal) creatures.", 5);
addskill(SK_LORE_NATURE, "Lore:Nature", "Determines your knowledge of plants, animals and insects.", 5); addskill(SK_LORE_NATURE, "Lore:Nature", "Determines your knowledge of plants, animals and insects.", 5);
addskill(SK_LORE_UNDEAD, "Lore:Undead", "Determines your knowledge of the undead.", 5); addskill(SK_LORE_UNDEAD, "Lore:Undead", "Determines your knowledge of the undead.", 5);
addskill(SK_LORE_DRAGONS, "Lore:Wyrms", "Determines your knowledge about wryms.", 5);
// weaponry // weaponry
addskill(SK_AXES, "Axes", "Helps you use chopping weapons like axes.", 50); addskill(SK_AXES, "Axes", "Helps you use chopping weapons like axes.", 50);

Binary file not shown.

13
defs.h
View File

@ -19,6 +19,7 @@
// Text // Text
#define TEXT_WARN_ATTACK_NOXP "You will not gain experience until you train. Really attack?" #define TEXT_WARN_ATTACK_NOXP "You will not gain experience until you train. Really attack?"
#define TEXT_WARN_CLIMB "Really attempt to climb without Climbing skill?" #define TEXT_WARN_CLIMB "Really attempt to climb without Climbing skill?"
#define TEXT_WARN_FLY "Warning: while airborne you will not map your surroundings."
// Defaults // Defaults
#define DEF_AIFOLLOWTIME (50) // if target lf is out of view #define DEF_AIFOLLOWTIME (50) // if target lf is out of view
@ -1360,13 +1361,17 @@ enum OBTYPE {
OT_S_WINDSHIELD, OT_S_WINDSHIELD,
// -- elemental - fire // -- elemental - fire
OT_S_BLADEBURN, OT_S_BLADEBURN,
OT_S_BURNINGFEET,
OT_S_BURNINGWAVE, OT_S_BURNINGWAVE,
OT_S_FIREDART, OT_S_FIREDART,
OT_S_FIREBALL, OT_S_FIREBALL,
OT_S_FLAMEPILLAR, OT_S_FLAMEPILLAR,
OT_S_FLAMEBURST, OT_S_FLAMEBURST,
OT_S_IMMOLATE,
OT_S_METEOR,
OT_S_PYROMANIA, OT_S_PYROMANIA,
OT_S_SPARK, OT_S_SPARK,
OT_S_SUPERHEAT,
// -- elemental - ice // -- elemental - ice
OT_S_ABSOLUTEZERO, OT_S_ABSOLUTEZERO,
OT_S_CHILL, OT_S_CHILL,
@ -1429,6 +1434,7 @@ enum OBTYPE {
OT_S_KNOCK, OT_S_KNOCK,
OT_S_LIGHT, OT_S_LIGHT,
OT_S_MENDING, OT_S_MENDING,
OT_S_OBJECTGROWTH,
OT_S_PASSWALL, OT_S_PASSWALL,
OT_S_PETRIFY, OT_S_PETRIFY,
OT_S_POLYMORPH, OT_S_POLYMORPH,
@ -2100,7 +2106,7 @@ enum FLAG {
F_GOESON, // val0 = where it can be equipped. F_GOESON, // val0 = where it can be equipped.
F_GOESONMULTI, // ob is equipped on _ALL_ F_GOESON flags, rather than F_GOESONMULTI, // ob is equipped on _ALL_ F_GOESON flags, rather than
// equipped on _ONE OF_ the. // equipped on _ONE OF_ the.
F_BONUS, // val0=bonus/penalty to damage/armour. ie. +1 sword F_BONUS, // val0=bonus/penalty to damage+accuracy/armour. ie. +1 sword
F_THROWMISSILE, // weapon would make a good thrown missle - used by AI F_THROWMISSILE, // weapon would make a good thrown missle - used by AI
F_UNIQUE, // only one may appear F_UNIQUE, // only one may appear
F_GLYPH, // override the glyph with the first char of text. F_GLYPH, // override the glyph with the first char of text.
@ -2508,6 +2514,8 @@ enum FLAG {
F_TOOKACTION, // lf purposely took action in their last turn. F_TOOKACTION, // lf purposely took action in their last turn.
F_MOVED, // lf purposely walked/flew/swum/moved in prev turn F_MOVED, // lf purposely walked/flew/swum/moved in prev turn
F_HASBEENMOVED, // an object moved this lf since their last turn. F_HASBEENMOVED, // an object moved this lf since their last turn.
F_HOTFEET, // target takes v0 damage of type v1 unless they move.
// text = killed by xxx
F_WASROBBED, // your stuff was stolen while you were F_WASROBBED, // your stuff was stolen while you were
// unconscious. announce it when you wake up. // unconscious. announce it when you wake up.
F_TURNED, // lf turned this turn. F_TURNED, // lf turned this turn.
@ -2776,6 +2784,8 @@ enum FLAG {
// if v0 is b_true, means this is a goddess // if v0 is b_true, means this is a goddess
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)
F_GODPOISON, // v0=TRUE: god likes using poison. gain v1 piety
// v0=FALSE: god hates using poison. lose v1 piety
// for all sacrifice flags: // for all sacrifice flags:
// v2: amt of piety for each sacrifice // v2: amt of piety for each sacrifice
// text: "the xxx disappears in yyyy" // text: "the xxx disappears in yyyy"
@ -3932,6 +3942,7 @@ enum BRAND {
BR_ANTIMAG, BR_ANTIMAG,
BR_CONCEALMENT, BR_CONCEALMENT,
BR_SHARPNESS, BR_SHARPNESS,
BR_PUNISHMENT,
BR_PYROMANIA, BR_PYROMANIA,
BR_REVENGE, BR_REVENGE,
BR_REFLECTION, BR_REFLECTION,

235
god.c
View File

@ -570,6 +570,18 @@ enum PIETYLEV getpietylev(enum RACE rid, enum COLOUR *col, char *happiness) {
return PL_INDIFFERENT; return PL_INDIFFERENT;
} }
int getprayedgods(lifeform_t **retgod, int *nretgods) {
int i;
*nretgods = 0;
for (i = 0; i < ngodlfs; i++) {
if (lfhasflag(godlf[i], F_PRAYEDTO)) {
retgod[*nretgods] = godlf[i];
(*nretgods)++;
}
}
return *nretgods;
}
lifeform_t *getrandomgod(void) { lifeform_t *getrandomgod(void) {
if (ngodlfs == 0) { if (ngodlfs == 0) {
return NULL; return NULL;
@ -673,10 +685,10 @@ int godgiftmaybe(enum RACE rid, int fromtemple) {
rollagain = B_FALSE; rollagain = B_FALSE;
switch (rnd(1,2)) { switch (rnd(1,2)) {
case 1: case 1:
snprintf(obtogive, BUFLEN, "excellent branded weapon"); snprintf(obtogive, BUFLEN, "excellent appropriate branded weapon");
break; break;
case 2: case 2:
snprintf(obtogive, BUFLEN, "excellent branded armour"); snprintf(obtogive, BUFLEN, "excellent appropriate branded armour");
break; break;
} }
} }
@ -1005,7 +1017,7 @@ void pleasegod(enum RACE rid, int amt) {
msg("You feel Lumara's presense nearby."); msg("You feel Lumara's presense nearby.");
break; break;
case R_GODMERCY: case R_GODMERCY:
msg("You feel a sense of peace."); msg("You feel a sense of serenity.");
break; break;
case R_GODPURITY: case R_GODPURITY:
msg("You hear a distant choir singing."); msg("You hear a distant choir singing.");
@ -1042,6 +1054,7 @@ void pleasegodmaybe(enum RACE rid, int amt) {
int prayto(lifeform_t *lf, lifeform_t *god) { int prayto(lifeform_t *lf, lifeform_t *god) {
int piety,i; int piety,i;
char assisttext[BUFLEN];
taketime(lf, getactspeed(lf)); taketime(lf, getactspeed(lf));
@ -1076,14 +1089,35 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
// if we get here, piety is >= 100. // if we get here, piety is >= 100.
// you get some help... // you get some help...
godsay(god->race->id, B_TRUE, "You appear in need of assistance, mortal!");
switch (god->race->id) {
case R_GODBATTLE:
strcpy(assisttext, "Message received, soldier!");
break;
case R_GODTHIEVES:
strcpy(assisttext, "What mischief have you gotten yourself into, then?");
break;
case R_GODDEATH:
strcpy(assisttext, "You desire a favour, fleshling?");
break;
case R_GODMERCY:
strcpy(assisttext, "I hear your prayer, child.");
break;
case R_GODMAGIC:
strcpy(assisttext, "One calls upon the eldritch powers...");
break;
case R_GODPURITY:
default:
strcpy(assisttext, "You appear in need of assistance, mortal!");
break;
}
godsay(god->race->id, B_TRUE, assisttext);
switch (god->race->id) { switch (god->race->id) {
lifeform_t *l; lifeform_t *l;
int donesomething = B_FALSE; int donesomething = B_FALSE,n;
cell_t *c; cell_t *c;
object_t *o; object_t *o;
object_t *oposs[MAXPILEOBS];
int noposs = 0, n;
case R_GODBATTLE: case R_GODBATTLE:
if (isinbattle(player, B_TRUE)) { if (isinbattle(player, B_TRUE)) {
int redo = B_TRUE; int redo = B_TRUE;
@ -1121,40 +1155,51 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
}// end while redo }// end while redo
} else { } else {
// not in battle... // not in battle...
int redo = B_TRUE,i; int done = B_FALSE;
object_t *o; object_t *o,*wep;
while (redo) { wep = getweapon(player);
redo = B_FALSE;
switch (rnd(1,3)) { if (uncurse_one_equipped(lf, "\"Be free of your curse!\"")){
case 1: // detect life done = B_TRUE;
msg("\"Seek out battle in my name!\""); }
dospelleffects(god, OT_S_DETECTLIFE, 10, lf, NULL, lf->cell, B_BLESSED, NULL, B_TRUE);
break; if (!done) {
case 2: // bless weapon // try to repair armour or undull weapons
msg("\"Fight in my name!\""); i = 0;
o = getweapon(player); for (o = lf->pack->first ; o ; o = o->next) {
if (o && !isblessed(o)) { if (isequipped(o)) {
blessob(o); if (isdamaged(o) || (getobbonus(o, B_FALSE) < 0)) {
} else { dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE);
redo = B_TRUE; i++;
} }
break; }
case 3: // repair armour }
i = 0; if (i) {
for (o = lf->pack->first ; o ; o = o->next) { msg("\"Keep fighting, warrior!\"");
if (isdamaged(o)) { done = B_TRUE;
dospelleffects(lf, OT_S_MENDING, 10, NULL, o, NULL, B_BLESSED, NULL, B_FALSE); }
i++; }
if (!done) {
int redo = B_TRUE;
while (redo) {
redo = B_FALSE;
switch (rnd(1,2)) {
case 1: // detect life
msg("\"Seek out battle in my name!\"");
dospelleffects(god, OT_S_DETECTLIFE, 10, lf, NULL, lf->cell, B_BLESSED, NULL, B_TRUE);
break;
case 2: // bless weapon
msg("\"Fight in my name!\"");
o = getweapon(player);
if (o && !isblessed(o)) {
blessob(o);
} else {
redo = B_TRUE;
} }
} break;
if (i) { } // end switch
msg("\"Keep fighting, warrior!\""); }// end while redo
} else { }
redo = B_TRUE;
}
break;
} // end switch
}// end while redo
} }
break; break;
case R_GODPURITY: case R_GODPURITY:
@ -1163,17 +1208,12 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
if (c) { if (c) {
dospelleffects(god, OT_S_LIGHT, 10, NULL, NULL, c, B_BLESSED, NULL, B_TRUE); dospelleffects(god, OT_S_LIGHT, 10, NULL, NULL, c, B_BLESSED, NULL, B_TRUE);
} }
// get list of cursed obs // uncurse ALL equipped obs
noposs = 0;
for (o = lf->pack->first ; o ; o = o->next) { for (o = lf->pack->first ; o ; o = o->next) {
if (iscursed(o)) { if (iscursed(o) && isequipped(o)) {
oposs[noposs++] = o; blessob(o);
} }
} }
if (noposs) {
o = oposs[rnd(0,noposs-1)];
blessob(o);
}
// smite evil // smite evil
for (l = lf->cell->map->lf ; l ; l = l->next) { for (l = lf->cell->map->lf ; l ; l = l->next) {
if (getalignment(l) == AL_EVIL) { if (getalignment(l) == AL_EVIL) {
@ -1191,12 +1231,11 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
msg("\"Behold, the power of death!\""); msg("\"Behold, the power of death!\"");
c = NULL; c = NULL;
n = OT_NONE; n = OT_NONE;
switch (rnd(0,4)) { switch (rnd(0,3)) {
case 0: n = OT_S_PAIN; break; case 0: n = OT_S_PAIN; break;
case 1: n = OT_S_DRAINLIFE; break; case 1: n = OT_S_DRAINLIFE; break;
case 2: n = OT_S_BLINDNESS; break; case 2: n = OT_S_FLAYFLESH; break;
case 3: n = OT_S_FLAYFLESH; break; case 3: n = OT_S_HECTASSERVANT;
case 4: n = OT_S_HECTASSERVANT;
c = getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND); c = getrandomadjcell(player->cell, WE_WALKABLE, B_ALLOWEXPAND);
break; break;
} }
@ -1210,14 +1249,21 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
} }
if (n != OT_NONE) { if (n != OT_NONE) {
// kill first lifeform in sight.
for (i = 1; i < lf->nlos; i++) { for (i = 1; i < lf->nlos; i++) {
lifeform_t *who; lifeform_t *who;
who = lf->los[i]->lf; who = lf->los[i]->lf;
if (who && !areallies(lf, who)) { if (who && !areallies(lf, who)) {
if (isundead(who)) { if (isundead(who)) {
makepeaceful(who, god); makepeaceful(who, god);
} else if (gethitdice(who) <= 4) {
// instakill
who->lastdamtype = DT_NECROTIC;
setlastdam(who, "Hecta's finger of death.");
who->hp = 0;
} else { } else {
castspell(god, n, who, NULL, who->cell, NULL, NULL); castspell(god, n, who, NULL, who->cell, NULL, NULL);
dospelleffects(god, n, 20, who, NULL, who->cell, B_UNCURSED, NULL, B_FALSE);
break; break;
} }
} }
@ -1277,6 +1323,13 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
int redo = B_TRUE; int redo = B_TRUE;
object_t *possob[MAXPILEOBS]; object_t *possob[MAXPILEOBS];
int npossob,i,first; int npossob,i,first;
object_t *o;
// uncurse one equipped ob
if (uncurse_one_equipped(lf, "\"Curses, schmurses!\"")){
redo = B_FALSE;
}
while (redo) { while (redo) {
redo = B_FALSE; redo = B_FALSE;
switch (rnd(1,2)) { switch (rnd(1,2)) {
@ -1332,34 +1385,43 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
case R_GODMAGIC: case R_GODMAGIC:
if (player->mp <= (getmaxmp(player)/2)) { if (player->mp <= (getmaxmp(player)/2)) {
gainmp(lf, getmaxmp(lf)); gainmp(lf, getmaxmp(lf));
msg("\"I have replenished your magical reserves!\""); msg("\"One's magical reserves have been filled!\"");
} else { } else {
object_t *toid[MAXPILEOBS],*touncurse[MAXPILEOBS]; object_t *toid[MAXPILEOBS],*touncurse[MAXPILEOBS];
int idnum = 0, uncursenum = 0; int idnum = 0, uncursenum = 0;
// any unid'd scrolls/books? int done = B_FALSE;
for (o = player->pack->first ; o ; o = o->next) {
if ((o->type->obclass->id == OC_SCROLL) || (o->type->obclass->id == OC_BOOK)) { // uncurse one equipped ob
if (!isknown(o)) { if (uncurse_one_equipped(lf, "\"One's curse is lifted.\"")){
toid[idnum++] = o; done = B_TRUE;
}
if (isequipped(o) && iscursed(o)) {
touncurse[uncursenum++] = o;
}
}
} }
if (idnum) { if (!done) {
msg("\"I grant you the favour of knowledge!\""); // any unid'd scrolls/books?
o = toid[rnd(0,idnum-1)]; for (o = player->pack->first ; o ; o = o->next) {
dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE); if ((o->type->obclass->id == OC_SCROLL) || (o->type->obclass->id == OC_BOOK)) {
} else if (uncursenum) { if (!isknown(o)) {
msg("\"I grant you the favour of redemption!\""); toid[idnum++] = o;
o = touncurse[rnd(0,uncursenum-1)]; }
uncurseob(o, NULL); if (isequipped(o) && iscursed(o)) {
} else { touncurse[uncursenum++] = o;
// just regain mana. }
gainmp(lf, getmaxmp(lf)); }
msg("\"I have replenished your magical reserves!\""); }
if (idnum) {
msg("\"One is granted the favour of knowledge!\"");
o = toid[rnd(0,idnum-1)];
dospelleffects(god, OT_S_IDENTIFY, 10, NULL, o, NULL, B_UNCURSED, NULL, B_FALSE);
} else if (uncursenum) {
msg("\"One is granted the favour of redemption!\"");
o = touncurse[rnd(0,uncursenum-1)];
uncurseob(o, NULL);
} else {
// just regain mana.
gainmp(lf, getmaxmp(lf));
msg("\"One's magical reserves have been filled!\"");
}
} }
} }
break; break;
@ -1379,6 +1441,9 @@ int prayto(lifeform_t *lf, lifeform_t *god) {
castspell(god, OT_S_HEALINGMAJ, player, NULL, player->cell, NULL, NULL); castspell(god, OT_S_HEALINGMAJ, player, NULL, player->cell, NULL, NULL);
donesomething = B_TRUE; donesomething = B_TRUE;
} }
// uncurse one equipped ob
uncurse_one_equipped(lf, "\"Let thy curse be ended!\"");
break; break;
default: default:
break; break;
@ -1410,3 +1475,25 @@ void setpiety(enum RACE rid, int amt) {
f->val[0] = amt; f->val[0] = amt;
limit(&f->val[0], PIETY_MIN, PIETY_MAX); limit(&f->val[0], PIETY_MIN, PIETY_MAX);
} }
// uncurse one equipped ob
// returns true if we do somethign
int uncurse_one_equipped(lifeform_t *lf, char *text) {
object_t *possob[MAXPILEOBS],*o;
int npossob;
npossob = 0;
for (o = lf->pack->first ; o ; o = o->next) {
if (iscursed(o) && isequipped(o)) {
possob[npossob++] = o;
}
}
if (npossob) {
o = possob[rnd(0,npossob-1)];
if (text) {
msg(text);
}
blessob(o);
return B_TRUE;
}
return B_FALSE;
}

2
god.h
View File

@ -7,6 +7,7 @@ lifeform_t *findgod(enum RACE rid);
enum RACE getopposinggod(enum RACE rid); enum RACE getopposinggod(enum RACE rid);
int getpiety(enum RACE rid); int getpiety(enum RACE rid);
enum PIETYLEV getpietylev(enum RACE rid, enum COLOUR *col, char *happiness); enum PIETYLEV getpietylev(enum RACE rid, enum COLOUR *col, char *happiness);
int getprayedgods(lifeform_t **retgod, int *nretgods);
lifeform_t *getrandomgod(void); lifeform_t *getrandomgod(void);
lifeform_t *getrandomprayedgod(void); lifeform_t *getrandomprayedgod(void);
lifeform_t *godappears(enum RACE rid, cell_t *where); lifeform_t *godappears(enum RACE rid, cell_t *where);
@ -19,3 +20,4 @@ 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);
void setpiety(enum RACE rid, int amt); void setpiety(enum RACE rid, int amt);
int uncurse_one_equipped(lifeform_t *lf, char *text);

61
io.c
View File

@ -1468,8 +1468,17 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
case F_HOTFEET:
if (isplayer(lf)) {
msg("Your %s feel like they are on fire!", getbodypartname(lf, BP_FEET));
donesomething = B_TRUE;
} else {
msg("%s%s %s are on fire!", lfname, getpossessive(lfname), getbodypartname(lf, BP_FEET));
donesomething = B_TRUE;
}
break;
case F_ICESLIDE: case F_ICESLIDE:
msg("Sheets of ice start forming under %s%s feet!",lfname, getpossessive(lfname)); msg("Sheets of ice start forming under %s%s %s!",lfname, getpossessive(lfname), getbodypartname(lf, BP_FEET));
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_INJURY: case F_INJURY:
@ -1593,6 +1602,9 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
case F_FLYING: case F_FLYING:
msg("%s begin%s to fly!",lfname, isplayer(lf) ? "" : "s"); msg("%s begin%s to fly!",lfname, isplayer(lf) ? "" : "s");
donesomething = B_TRUE; donesomething = B_TRUE;
if (isplayer(lf)) {
real_warnabout(TEXT_WARN_FLY, PERMENANT, B_FALSE);
}
break; break;
case F_FROZEN: case F_FROZEN:
// strip "frozen" out... // strip "frozen" out...
@ -1633,6 +1645,9 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
break; break;
case F_LEVITATING: case F_LEVITATING:
msg("%s begin%s to levitate in the air!",lfname, isplayer(lf) ? "" : "s"); msg("%s begin%s to levitate in the air!",lfname, isplayer(lf) ? "" : "s");
if (isplayer(lf)) {
real_warnabout(TEXT_WARN_FLY, PERMENANT, B_FALSE);
}
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_MAGSHIELD: case F_MAGSHIELD:
@ -2140,6 +2155,15 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
case F_HOTFEET:
if (isplayer(lf)) {
msg("Your %s feel cooler now.", getbodypartname(lf, BP_FEET));
donesomething = B_TRUE;
} else {
msg("%s%s %s look cooler now", lfname, getpossessive(lfname), getbodypartname(lf, BP_FEET));
donesomething = B_TRUE;
}
break;
case F_ICESLIDE: case F_ICESLIDE:
msg("%s%s feet are longer generating ice.",lfname, getpossessive(lfname)); msg("%s%s feet are longer generating ice.",lfname, getpossessive(lfname));
donesomething = B_TRUE; donesomething = B_TRUE;
@ -5892,6 +5916,10 @@ char *makedesc_ob(object_t *o, char *retbuf) {
sprintf(buf2, "%s decreases gravity around you.\n", buf); sprintf(buf2, "%s decreases gravity around you.\n", buf);
strncat(retbuf, buf2, HUGEBUFLEN); strncat(retbuf, buf2, HUGEBUFLEN);
break; break;
case F_HOTFEET:
sprintf(buf2, "%s causes your feet to constantly burn.\n", buf);
strncat(retbuf, buf2, HUGEBUFLEN);
break;
case F_DODGES: case F_DODGES:
sprintf(buf2, "%s allows you to dodge attacks.\n", buf); sprintf(buf2, "%s allows you to dodge attacks.\n", buf);
strncat(retbuf, buf2, HUGEBUFLEN); strncat(retbuf, buf2, HUGEBUFLEN);
@ -9155,13 +9183,7 @@ void handleinput(void) {
break; break;
case 'm': // 'm'agic/abilities (magic) case 'm': // 'm'agic/abilities (magic)
addflag(player->flags, F_LASTCMD, NA, NA, NA, temp); addflag(player->flags, F_LASTCMD, NA, NA, NA, temp);
if (wantrepeat) { domagic(OT_NONE, NA, NA);
//domagic(repeatflag.val[2], repeatflag.val[0], repeatflag.val[1]);
// don't repeat the target cell!
domagic(repeatflag.val[2], NA, NA);
} else {
domagic(OT_NONE, NA, NA);
}
break; break;
case 'M': // 'M'emorise magic/ability shortcut case 'M': // 'M'emorise magic/ability shortcut
domemmagic(); domemmagic();
@ -11903,9 +11925,13 @@ void showlfstats(lifeform_t *lf, int showall) {
mvwprintw(mainwin, y, 0, "%s %s surrounded by a holy aura.", you(lf), is(lf)); mvwprintw(mainwin, y, 0, "%s %s surrounded by a holy aura.", you(lf), is(lf));
y++; y++;
} }
f = lfhasknownflag(lf, F_HOTFEET);
if (f) {
msg("%s feet are on fire (%s %s damage per turn stationary)",your(lf), f->val[0], getdamnamenoun(f->val[1]));
}
f = lfhasknownflag(lf, F_ICESLIDE); f = lfhasknownflag(lf, F_ICESLIDE);
if (f) { if (f) {
msg("%s%s feet automatically generating sheets of ice.",your(lf)); msg("%s feet automatically generating sheets of ice.",your(lf));
} }
f = lfhasknownflag(lf, F_FREEZINGTOUCH); f = lfhasknownflag(lf, F_FREEZINGTOUCH);
@ -12333,9 +12359,15 @@ void tombstone(lifeform_t *lf) {
endwin(); endwin();
} }
int warnabout(char *what) {
return real_warnabout(what, DEF_WARNINGTIME, B_TRUE);
}
// //
// returns TRUE if you answered 'Yes' or you'd already accepted this warning // returns TRUE if you answered 'Yes' or you'd already accepted this warning
int warnabout(char *what) { //
int real_warnabout(char *what, int lifetime, int doquestion) {
char ch = 'n'; char ch = 'n';
warning_t *w; warning_t *w;
// have we already warned about this? // have we already warned about this?
@ -12343,13 +12375,18 @@ int warnabout(char *what) {
if (w) { if (w) {
w->lifetime = DEF_WARNINGTIME; w->lifetime = DEF_WARNINGTIME;
ch = 'y'; ch = 'y';
} else { } else if (doquestion) {
char ques[BUFLEN]; char ques[BUFLEN];
sprintf(ques, "%s", what); sprintf(ques, "%s", what);
ch = askchar(what, "yn", "n", B_TRUE, B_FALSE); ch = askchar(what, "yn", "n", B_TRUE, B_FALSE);
} else {
more();
msg("%s", what);
more();
ch = 'y';
} }
if (ch == 'y') { if (ch == 'y') {
addwarning(what); addwarning(what, lifetime);
return B_TRUE; return B_TRUE;
} }
return B_FALSE; return B_FALSE;

1
io.h
View File

@ -136,4 +136,5 @@ void tombstone(lifeform_t *lf);
void updatestatus(void); void updatestatus(void);
int updateviewfor(cell_t *cell); int updateviewfor(cell_t *cell);
int warnabout(char *what); int warnabout(char *what);
int real_warnabout(char *what, int lifetime, int doquestion);
char wrapprint(WINDOW *win, int *y, int *x, char *format, ... ); char wrapprint(WINDOW *win, int *y, int *x, char *format, ... );

130
lf.c
View File

@ -1157,10 +1157,13 @@ int cansee_real(lifeform_t *viewer, lifeform_t *viewee, int uselos) {
} }
// viewer asleep? // viewer asleep?
if (lfhasflag(viewer, F_ASLEEP)) { f = lfhasflag(viewer, F_ASLEEP);
// can only 'see' yourself if (f) {
if (viewee != viewer) { if (f->val[1] != ST_MEDITATING) {
return B_FALSE; // can only 'see' yourself
if (viewee != viewer) {
return B_FALSE;
}
} }
} }
@ -2427,7 +2430,7 @@ void die(lifeform_t *lf) {
if (god && !godisangry(god->race->id)) { if (god && !godisangry(god->race->id)) {
switch (god->race->id) { switch (god->race->id) {
case R_GODBATTLE: case R_GODBATTLE:
godsay(god->race->id, B_TRUE, "Rest in peace, brave warrior!"); more(); godsay(god->race->id, B_TRUE, "Rest in peace, brave warrior."); more();
break; break;
case R_GODDEATH: case R_GODDEATH:
godsay(god->race->id, B_TRUE, "Come to me, my servant..."); more(); godsay(god->race->id, B_TRUE, "Come to me, my servant..."); more();
@ -6826,9 +6829,8 @@ int getattacks(lifeform_t *lf, int *min, int *max) {
float getmaxcarryweight(lifeform_t *lf) { float getmaxcarryweight(lifeform_t *lf) {
float max; float max;
float mod;
enum ATTRBRACKET sbrack;
/*
sbrack = getattrbracket(getattr(lf, A_STR), A_STR, NULL); sbrack = getattrbracket(getattr(lf, A_STR), A_STR, NULL);
switch (sbrack) { switch (sbrack) {
case AT_EXLOW: case AT_EXLOW:
@ -6854,6 +6856,10 @@ float getmaxcarryweight(lifeform_t *lf) {
} }
max = getlfweight(lf, B_NOOBS) * mod; max = getlfweight(lf, B_NOOBS) * mod;
*/
// half your weight + your strength
max = (getlfweight(lf, B_NOOBS)/2) + getattr(lf, A_STR);
if (lfhasflagval(lf, F_INJURY, IJ_RIBBROKEN, NA, NA, NULL)) { if (lfhasflagval(lf, F_INJURY, IJ_RIBBROKEN, NA, NA, NULL)) {
max /= 2; max /= 2;
@ -8531,7 +8537,7 @@ enum SKILLLEVEL getweaponskill(lifeform_t *lf, object_t *o) {
if (!o) { if (!o) {
return getskill(lf, SK_UNARMED); return getskill(lf, SK_UNARMED);
} }
sk = getobskill(o); sk = getobskill(o->flags);
if (sk) { if (sk) {
enum SKILLLEVEL weplev; enum SKILLLEVEL weplev;
weplev = getskill(lf, sk->id); weplev = getskill(lf, sk->id);
@ -9290,7 +9296,7 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
if (isplayer(lf)) addflag(o->flags, F_NOPOINTS, B_TRUE, NA, NA, NULL); if (isplayer(lf)) addflag(o->flags, F_NOPOINTS, B_TRUE, NA, NA, NULL);
// give one extra rank of skill in this weapon // give one extra rank of skill in this weapon
sk = getobskill(o); sk = getobskill(o->flags);
giveskill(lf, sk->id); giveskill(lf, sk->id);
} }
} }
@ -12104,6 +12110,37 @@ char *assignnpcname(lifeform_t *lf) {
return sel->name; return sel->name;
} }
void autoshortcut(lifeform_t *lf, enum OBTYPE spellid) {
flag_t *retflag[MAXCANDIDATES],*f;
int nretflags,i,found = B_FALSE;
int min = 1;
objecttype_t *ot = NULL;
getflags(lf->flags, retflag, &nretflags, F_CANCAST, F_CANWILL, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (f->val[0] == spellid) {
found = B_TRUE;
}
}
if (!found) {
return;
}
ot = findot(spellid);
if (ot) {
// set to lowest possible shortcut
getflags(lf->flags, retflag, &nretflags, F_CANCAST, F_CANWILL, F_NONE);
for (i = 0; i < nretflags; i++) {
if (retflag[i]->val[0] > min) {
min = retflag[i]->val[0];
}
}
if (min < 10) {
addflag(lf->flags, F_SHORTCUT, min, NA, NA, ot->name);
}
}
}
// make sure player has at least novice skill in all their start weapons/armour // make sure player has at least novice skill in all their start weapons/armour
void autoskill(lifeform_t *lf) { void autoskill(lifeform_t *lf) {
skill_t *sk; skill_t *sk;
@ -12129,7 +12166,7 @@ void autoskill(lifeform_t *lf) {
for (o = lf->pack->first ; o ; o = o->next) { for (o = lf->pack->first ; o ; o = o->next) {
//if (isweapon(o) && canweild(lf, o)) { //if (isweapon(o) && canweild(lf, o)) {
if (isweapon(o)) { if (isweapon(o)) {
sk = getobskill(o); sk = getobskill(o->flags);
if (sk && !getskill(lf, sk->id)) { if (sk && !getskill(lf, sk->id)) {
giveskilllev(lf, sk->id, slev); giveskilllev(lf, sk->id, slev);
} }
@ -13964,6 +14001,25 @@ int pickup(lifeform_t *lf, object_t *what, int howmany, int fromground, int want
return B_TRUE; return B_TRUE;
} }
// picked up something our god doesn't like?
if (isplayer(lf)) {
if ( hasflagknown(o->flags, F_POISONED) ||
hasflagvalknown(o->flags, F_HITCONFER, F_POISONED, NA, NA, NULL)) {
int i,nretgods;
lifeform_t *retgod[MAXGODS];
getprayedgods(retgod, &nretgods);
for (i = 0 ; i < nretgods; i++) {
if (lfhasflagval(retgod[i], F_GODPOISON, B_FALSE, NA, NA, NULL)) {
// warn...
godsay(retgod[i]->race->id, B_TRUE, "I hope you're not planning on using that...");
break;
}
}
}
}
return B_FALSE; return B_FALSE;
} }
@ -16318,6 +16374,7 @@ void startlfturn(lifeform_t *lf) {
int donefeetwet = B_FALSE; int donefeetwet = B_FALSE;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags; int nretflags;
int movedlastturn = B_FALSE;
map = lf->cell->map; map = lf->cell->map;
@ -16372,8 +16429,9 @@ void startlfturn(lifeform_t *lf) {
// clear one-turn-only flags // clear one-turn-only flags
killflagsofid(lf->flags, F_DONELISTEN); killflagsofid(lf->flags, F_DONELISTEN);
killflagsofid(lf->flags, F_NOSWAP); killflagsofid(lf->flags, F_NOSWAP);
killflagsofid(lf->flags, F_HASBEENMOVED); movedlastturn = 0;
killflagsofid(lf->flags, F_MOVED); movedlastturn += killflagsofid(lf->flags, F_HASBEENMOVED);
movedlastturn += killflagsofid(lf->flags, F_MOVED);
// if we didn't turn lsat move, kill our turncounter // if we didn't turn lsat move, kill our turncounter
if (!killflagsofid(lf->flags, F_TURNED)) { if (!killflagsofid(lf->flags, F_TURNED)) {
@ -16677,6 +16735,8 @@ void startlfturn(lifeform_t *lf) {
getlfname(lf, lfname); getlfname(lf, lfname);
msg("%s is repelled away from %s!",buf, lfname); msg("%s is repelled away from %s!",buf, lfname);
} }
} else if (o->material->id == MT_WATER) {
killtransitoryflags(lf->flags, F_HOTFEET);
} }
} }
} }
@ -17015,6 +17075,34 @@ void startlfturn(lifeform_t *lf) {
} }
if (isdead(lf)) return; if (isdead(lf)) return;
if (!movedlastturn) {
getflags(lf->flags, retflag, &nretflags, F_HOTFEET, F_NONE);
if (nretflags && !hasobofmaterial(lf->cell->obpile, MT_WATER)) {
for (i = 0; i < nretflags; i++) {
int dam;
enum DAMTYPE dt;
f = retflag[i];
dam = f->val[0];
dt = f->val[1];
o = getarmour(lf, BP_FEET);
if (o && ismetal(o->material->id)) {
dam *= 2;
}
if (losehp(lf, dam, dt, NULL, f->text)) {
if (isplayer(lf)) {
msg("^bYour %s burn!^n", getbodypartname(lf, BP_FEET));
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^b%s%s %s burn!^n", lfname, getpossessive(lfname), getbodypartname(lf, BP_FEET));
}
}
}
}
}
if (isdead(lf)) return;
// effects from cell objects? // effects from cell objects?
for (o = lf->cell->obpile->first ; o ; o = o->next) { for (o = lf->cell->obpile->first ; o ; o = o->next) {
f = hasflag(o->flags, F_WALKDAM); f = hasflag(o->flags, F_WALKDAM);
@ -17206,11 +17294,15 @@ void startlfturn(lifeform_t *lf) {
} }
if (f->id == F_STRIKETOKO) { if (f->id == F_STRIKETOKO) {
skill_t *sk; object_t *weapon;
sk = getobskill(getweapon(lf)); weapon = getweapon(lf);
if (!sk || (sk->id != SK_CLUBS)) { if (weapon) { // (unarmed is ok)
killflag(f); skill_t *sk;
continue; sk = getobskill(weapon->flags);
if (!sk || (sk->id != SK_CLUBS)) {
killflag(f);
continue;
}
} }
} }
@ -17252,7 +17344,7 @@ void startlfturn(lifeform_t *lf) {
// hp drain // hp drain
if (f->id == F_HPDRAIN) { if (f->id == F_HPDRAIN) {
losehp(lf, f->val[0], DT_DIRECT, NULL, f->text); losehp(lf, f->val[0], f->val[1], NULL, f->text);
if (isdead(lf)) { if (isdead(lf)) {
break; break;
} }
@ -19672,7 +19764,7 @@ int weild(lifeform_t *lf, object_t *o) {
} else { } else {
// warn if unskilled in this weapon // warn if unskilled in this weapon
skill_t *sk; skill_t *sk;
sk = getobskill(o); sk = getobskill(o->flags);
if (sk && !getskill(lf, sk->id)) { if (sk && !getskill(lf, sk->id)) {
msg("^wYou feel rather inept with this weapon."); msg("^wYou feel rather inept with this weapon.");
} else { } else {

1
lf.h
View File

@ -21,6 +21,7 @@ int armourfits(lifeform_t *lf, object_t *o, enum ERROR *reason);
int askforinfo(lifeform_t *lf, int diffmod); int askforinfo(lifeform_t *lf, int diffmod);
int askforpayment(lifeform_t *shk, lifeform_t *lf); int askforpayment(lifeform_t *shk, lifeform_t *lf);
char *assignnpcname(lifeform_t *lf); char *assignnpcname(lifeform_t *lf);
void autoshortcut(lifeform_t *lf, enum OBTYPE spellid);
void autoskill(lifeform_t *lf); void autoskill(lifeform_t *lf);
void autotarget(lifeform_t *lf); void autotarget(lifeform_t *lf);
void autoweild(lifeform_t *lf); void autoweild(lifeform_t *lf);

44
map.c
View File

@ -4785,6 +4785,8 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int
void expand_cave(map_t *map, int numpasses) { void expand_cave(map_t *map, int numpasses) {
int n,x,y,dir; int n,x,y,dir;
cell_t *c; cell_t *c;
int chancetoclear;
chancetoclear = rnd(15,25);
for (n = 0; n < numpasses; n++) { for (n = 0; n < numpasses; n++) {
// for each dug map cell, 25% chance of clearing each adjacent cell // for each dug map cell, 25% chance of clearing each adjacent cell
for (y = 0; y < map->h; y++) { for (y = 0; y < map->h; y++) {
@ -4795,7 +4797,7 @@ void expand_cave(map_t *map, int numpasses) {
// check for surrounding solid cells // check for surrounding solid cells
for (dir = DC_N; dir <= DC_NW; dir++) { for (dir = DC_N; dir <= DC_NW; dir++) {
c2 = getcellindir(c, dir); c2 = getcellindir(c, dir);
if (c2 && c2->type->solid && pctchance(25)) { if (c2 && c2->type->solid && pctchance(chancetoclear)) {
setcelltype(c2, map->habitat->emptycelltype); setcelltype(c2, map->habitat->emptycelltype);
} }
} }
@ -7046,9 +7048,8 @@ void setcelltype(cell_t *cell, enum CELLTYPE id) {
// returns true if something happened // returns true if something happened
int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring) { int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring) {
lifeform_t *target; lifeform_t *target;
char targetname[BUFLEN], buf[BUFLEN]; char targetname[BUFLEN];
object_t *o, *nexto; object_t *o, *nexto;
int seen = B_FALSE;
int rv = B_FALSE; int rv = B_FALSE;
target = c->lf; target = c->lf;
@ -7057,42 +7058,7 @@ int shattercell(cell_t *c, lifeform_t *fromlf, char *damstring) {
} }
// shatter solid glass cells // shatter solid glass cells
if (c->type->solid && willshatter(c->type->material->id)) { if (c->type->solid && willshatter(c->type->material->id)) {
enum MATERIAL origmat; damagecell(c, 9999, DT_DIRECT);
rv = B_TRUE;
// announce
if (haslos(player, c)) {
msg("%s %s shatters!",needan(c->type->name) ? "An" : "A", c->type->name);
seen = B_TRUE;
} else {
// very loud
noise(c, NULL, NC_OTHER, SV_CAR, "shattering glass.", NULL);
}
if (target) {
if (seen) {
msg("%s %s showered in %s shards!", targetname, is(target), c->type->material->name);
}
losehp(target, rnd(1,100), DT_SLASH, fromlf, damstring); // BIG damage
}
// remember original material
origmat = c->type->material->id;
// change cell type
setcelltype(c, c->habitat->emptycelltype);
// place shards
if (origmat == MT_GLASS) {
int numshards;
numshards = rnd(50,100);
snprintf(buf, BUFLEN, "%d pieces of broken glass",numshards);
addob(c->obpile, buf);
} else if (origmat == MT_ICE) {
int numshards;
numshards = rnd(50,100);
snprintf(buf, BUFLEN, "%d chunks of ice",numshards);
addob(c->obpile, buf);
}
} }
// shatter lifeform-owned objects // shatter lifeform-owned objects

8
move.c
View File

@ -513,7 +513,7 @@ int diropposite(int dir) {
// restonfail means "if we can't find any valid moves, just rest" // restonfail means "if we can't find any valid moves, just rest"
// returns true on error // returns true on error
int dorandommove(lifeform_t *lf, int badmovesok, int restonfail) { int dorandommove(lifeform_t *lf, int badmovesok, int restonfail, int strafe) {
int origtimespent; int origtimespent;
int dir; int dir;
int tries = 0; int tries = 0;
@ -561,7 +561,7 @@ int dorandommove(lifeform_t *lf, int badmovesok, int restonfail) {
} }
origtimespent = lf->timespent; origtimespent = lf->timespent;
rv = trymove(lf, dir, B_TRUE, B_FALSE); rv = trymove(lf, dir, B_TRUE, strafe);
if (restonfail && (rv || (lf->timespent == origtimespent))) { if (restonfail && (rv || (lf->timespent == origtimespent))) {
// ie move failed // ie move failed
rest(lf, B_TRUE); rest(lf, B_TRUE);
@ -942,7 +942,7 @@ int moveawayfrom(lifeform_t *lf, cell_t *dst, int dirtype, int keepinlof, int st
int rv = B_TRUE; int rv = B_TRUE;
if (isblind(lf)) { if (isblind(lf)) {
dorandommove(lf, B_TRUE, B_TRUE); dorandommove(lf, B_TRUE, B_TRUE, B_FALSE);
return B_FALSE; return B_FALSE;
} }
@ -1701,7 +1701,7 @@ int movetowards(lifeform_t *lf, cell_t *dst, int dirtype, int strafe) {
if (isblind(lf)) { if (isblind(lf)) {
if (db) dblog(".oO { i am blind - movetorwards calling dorandommove. }"); if (db) dblog(".oO { i am blind - movetorwards calling dorandommove. }");
dorandommove(lf, B_TRUE, B_TRUE); dorandommove(lf, B_TRUE, B_TRUE, B_FALSE);
return B_FALSE; return B_FALSE;
} }

2
move.h
View File

@ -8,7 +8,7 @@ int closedoorat(lifeform_t *lf, cell_t *c);
int closedoor(lifeform_t *lf, object_t *o); int closedoor(lifeform_t *lf, object_t *o);
enum RELATIVEDIR getrelativedir(lifeform_t *lf, int dir); enum RELATIVEDIR getrelativedir(lifeform_t *lf, int dir);
int diropposite(int dir); int diropposite(int dir);
int dorandommove(lifeform_t *lf, int badmovesok, int restonfail); int dorandommove(lifeform_t *lf, int badmovesok, int restonfail, int strafe);
int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype, int keepinlof); int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype, int keepinlof);
int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype); int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype);
int getwalkoffdir(lifeform_t *lf, int dir); int getwalkoffdir(lifeform_t *lf, int dir);

17
nexus.c
View File

@ -297,7 +297,6 @@ int main(int argc, char **argv) {
/*o = hasob(where->obpile, OT_PLAYERSTART); /*o = hasob(where->obpile, OT_PLAYERSTART);
killob(o);*/ killob(o);*/
// place the portal to realm of gods // place the portal to realm of gods
c = getrandomcell(surfmap); c = getrandomcell(surfmap);
while (!cellwalkable(NULL, c, NULL)) { while (!cellwalkable(NULL, c, NULL)) {
@ -375,6 +374,7 @@ int main(int argc, char **argv) {
} }
if (sb1) { if (sb1) {
addflag(player->flags, F_CANCAST, sb1->contents->first->type->id, NA, NA, NULL); addflag(player->flags, F_CANCAST, sb1->contents->first->type->id, NA, NA, NULL);
addflag(player->flags, F_SHORTCUT, 1, NA, NA, sb1->contents->first->type->name);
addflag(sb1->flags, F_NOPOINTS, B_TRUE, NA, NA, NULL); addflag(sb1->flags, F_NOPOINTS, B_TRUE, NA, NA, NULL);
} }
@ -409,6 +409,7 @@ int main(int argc, char **argv) {
} }
if (sb2) { if (sb2) {
addflag(player->flags, F_CANCAST, sb2->contents->first->type->id, NA, NA, NULL); addflag(player->flags, F_CANCAST, sb2->contents->first->type->id, NA, NA, NULL);
addflag(player->flags, F_SHORTCUT, 2, NA, NA, sb2->contents->first->type->name);
addflag(sb2->flags, F_NOPOINTS, B_TRUE, NA, NA, NULL); addflag(sb2->flags, F_NOPOINTS, B_TRUE, NA, NA, NULL);
} }
identify(sb1); identify(sb1);
@ -455,6 +456,10 @@ int main(int argc, char **argv) {
petify(pet, player); petify(pet, player);
} }
// more automated shortcuts
autoshortcut(player, OT_A_COOK);
getplayernamefull(pname); getplayernamefull(pname);
snprintf(welcomemsg, BUFLEN, "Greetings %s, welcome to nexus!", pname); snprintf(welcomemsg, BUFLEN, "Greetings %s, welcome to nexus!", pname);
// 00:00 - 23:59 // 00:00 - 23:59
@ -612,7 +617,7 @@ celltype_t *addcelltype(int id, char *name, int glyph, int colour, int solid, in
return a; return a;
} }
warning_t *addwarning(char *text) { warning_t *addwarning(char *text, int lifetime) {
warning_t *a; warning_t *a;
// add to the end of the list // add to the end of the list
@ -632,7 +637,7 @@ warning_t *addwarning(char *text) {
// set props // set props
a->text = strdup(text); a->text = strdup(text);
a->lifetime = DEF_WARNINGTIME; a->lifetime = lifetime;
return a; return a;
} }
@ -1798,8 +1803,10 @@ void timeeffectsworld(map_t *map, int updategametime) {
// time out warnings // time out warnings
for (w = firstwarning ;w ; w = nextw) { for (w = firstwarning ;w ; w = nextw) {
nextw = w->next; nextw = w->next;
w->lifetime--; if (w->lifetime > 0) {
if (w->lifetime <= 0) killwarning(w); w->lifetime--;
if (w->lifetime <= 0) killwarning(w);
}
} }
//dblog("AFTER SORT AND ADJUST....."); //dblog("AFTER SORT AND ADJUST.....");

View File

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

101
objects.c
View File

@ -462,6 +462,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
int nom = 0; int nom = 0;
int n; int n;
int bookcontents = -1;// a skill for manuals, or a spellschool id for spellbooks int bookcontents = -1;// a skill for manuals, or a spellschool id for spellbooks
lifeform_t *matchlfskills = NULL;
int wantblessknown = B_FALSE; int wantblessknown = B_FALSE;
enum DEPTH wantdepth = DP_MAX; enum DEPTH wantdepth = DP_MAX;
int wantlit = B_FALSE; int wantlit = B_FALSE;
@ -708,6 +709,15 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
wantrarity = RR_VERYRARE; wantrarity = RR_VERYRARE;
p += strlen("very rare "); p += strlen("very rare ");
donesomething = B_TRUE; donesomething = B_TRUE;
// force weapon/armour to be ones the holder is skilled in?
} else if (strstarts(p, "appropriate ")) {
if (where->owner) {
matchlfskills = where->owner;
} else {
matchlfskills = player;
}
p += strlen("appropriate ");
donesomething = B_TRUE;
// weapon "goodness" // weapon "goodness"
} else if (strstarts(p, "average ")) { } else if (strstarts(p, "average ")) {
wantgoodness = G_AVERAGE; wantgoodness = G_AVERAGE;
@ -891,6 +901,9 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
int found = B_FALSE; int found = B_FALSE;
// check for things like "weapon" or "random ring" // check for things like "weapon" or "random ring"
// for weapons and armour, "matchlfskills" being set
// means that we should only select weapons/armour which
// matchlfskills is skilled in.
for (oc = objectclass; oc ; oc = oc->next) { for (oc = objectclass; oc ; oc = oc->next) {
int i; int i;
int matched = B_FALSE; int matched = B_FALSE;
@ -905,7 +918,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
// want a specific rarity? // want a specific rarity?
rrtorarity(wantrarity, &minrarity, &maxrarity); rrtorarity(wantrarity, &minrarity, &maxrarity);
ot = getrandomobofclass(oc->id, minrarity, maxrarity); ot = getrandomobofclass(oc->id, minrarity, maxrarity, matchlfskills);
if (ot) { if (ot) {
found = B_TRUE; found = B_TRUE;
break; break;
@ -1291,7 +1304,7 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int wantlinkholes
getrarityrange(where->where->map->depth, &min, &max, RARITYVARIANCEOB, B_FALSE); getrarityrange(where->where->map->depth, &min, &max, RARITYVARIANCEOB, B_FALSE);
// random potion type // random potion type
ot = getrandomobofclass(OC_POTION, min, max); ot = getrandomobofclass(OC_POTION, min, max, NULL);
if (ot) { if (ot) {
f->val[0] = ot->id; f->val[0] = ot->id;
} }
@ -2227,6 +2240,17 @@ void adjustdamob(object_t *o, int *dam, enum DAMTYPE damtype) {
} }
} }
// cooked food won't decay to nothing
if ((damtype == DT_DECAY) && hasflag(o->flags, F_PREPARED)) {
int hpcur;
hpcur = getobhp(o, NULL);
if (hpcur <= *dam) {
// go to 1 hp
*dam = hpcur - 1;
return;
}
}
// adjust damage // adjust damage
if (o->blessed == B_BLESSED) { if (o->blessed == B_BLESSED) {
// high chance of no hp loss // high chance of no hp loss
@ -3665,9 +3689,10 @@ int getobpoints(object_t *o) {
} }
// returns the skill associated with this object // returns the skill associated with this object
skill_t *getobskill(object_t *o) { // (via its flagpile)
skill_t *getobskill(flagpile_t *fp) {
flag_t *f; flag_t *f;
f = hasflag(o->flags, F_USESSKILL); f = hasflag(fp, F_USESSKILL);
if (f) { if (f) {
return findskill(f->val[0]); return findskill(f->val[0]);
} }
@ -3974,26 +3999,36 @@ brand_t *getrandombrandfor(objecttype_t *ot) {
return result; return result;
} }
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity) { objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf) {
objecttype_t *ot; objecttype_t *ot;
int count = 0,sel,n; int count = 0,sel,n;
flag_t *f; flag_t *f;
for (ot = objecttype ; ot ; ot = ot->next) { for (ot = objecttype ; ot ; ot = ot->next) {
if ((ot->obclass->id == ocid) && !hasflag(ot->flags, F_UNIQUE)) { if ((ot->obclass->id == ocid) && !hasflag(ot->flags, F_UNIQUE)) {
int rarityok = B_FALSE;
int skillok = B_FALSE;
// does rarity match?
f = hasflag(ot->flags, F_RARITY); f = hasflag(ot->flags, F_RARITY);
if (f) { if (f) {
int ok = B_FALSE;
if (f->val[1] == NA) { if (f->val[1] == NA) {
ok = B_TRUE; rarityok = B_TRUE;
} else if ( ((minrarity == NA) || (f->val[1] >= minrarity)) && } else if ( ((minrarity == NA) || (f->val[1] >= minrarity)) &&
((maxrarity == NA) || (f->val[1] <= maxrarity)) ) { ((maxrarity == NA) || (f->val[1] <= maxrarity)) ) {
ok = B_TRUE; rarityok = B_TRUE;
} }
if (ok) { }
count++; // if we're randomly selecting an objcet for a lf, make sure it matches their
// skillset
if (forlf) {
skill_t *sk;
sk = getobskill(ot->flags);
if (!sk || getskill(forlf, sk->id)) {
skillok = B_TRUE;
} }
} else skillok = B_TRUE;
if (skillok && rarityok) {
count++;
} }
} }
} }
@ -4006,15 +4041,28 @@ objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity
if ((ot->obclass->id == ocid) && !hasflag(ot->flags, F_UNIQUE)) { if ((ot->obclass->id == ocid) && !hasflag(ot->flags, F_UNIQUE)) {
f = hasflag(ot->flags, F_RARITY); f = hasflag(ot->flags, F_RARITY);
if (f) { if (f) {
int ok = B_FALSE; int rarityok = B_FALSE;
int skillok = B_FALSE;
if (f->val[1] == NA) { // does rarity match?
ok = B_TRUE; f = hasflag(ot->flags, F_RARITY);
} else if ( ((minrarity == NA) || (f->val[1] >= minrarity)) && if (f) {
((maxrarity == NA) || (f->val[1] <= maxrarity)) ) { if (f->val[1] == NA) {
ok = B_TRUE; rarityok = B_TRUE;
} else if ( ((minrarity == NA) || (f->val[1] >= minrarity)) &&
((maxrarity == NA) || (f->val[1] <= maxrarity)) ) {
rarityok = B_TRUE;
}
} }
if (ok) { // if we're randomly selecting an objcet for a lf, make sure it matches their
// skillset
if (forlf) {
skill_t *sk;
sk = getobskill(ot->flags);
if (!sk || getskill(forlf, sk->id)) {
skillok = B_TRUE;
}
} else skillok = B_TRUE;
if (skillok && rarityok) {
n++; n++;
if (n == sel) { if (n == sel) {
return ot; return ot;
@ -4187,6 +4235,17 @@ int getobattackdelay(object_t *o) {
return delay; return delay;
} }
int getobhp(object_t *o, int *max) {
flag_t *f;
f = hasflag(o->flags, F_OBHP);
if (f) {
if (max) *max = f->val[1];
return f->val[0];
}
// default
if (max) *max = 1;
return 1;
}
float getobhppct(object_t *o) { float getobhppct(object_t *o) {
float pct; float pct;
@ -9960,7 +10019,7 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
if (getmaxmp(lf) > 0) { if (getmaxmp(lf) > 0) {
msg("Your magical energy is restored."); msg("Your magical energy is restored.");
lf->mp = getmaxmp(lf); gainmp(lf, getmaxmp(lf));
} else { } else {
nothinghappens(); nothinghappens();
if (seen) *seen = B_FALSE; if (seen) *seen = B_FALSE;
@ -11357,7 +11416,7 @@ int real_takedamage(object_t *o, int howmuch, int damtype, int wantannounce) {
makewet(o, howmuch); makewet(o, howmuch);
} }
// catches on fire? // initial effects based on damage type
if (damtype == DT_FIRE) { if (damtype == DT_FIRE) {
if ( ((o->type->id == OT_CANDLE) || (o->type->id == OT_TORCH) || (o->type->id == OT_CANDELABRUM)) && if ( ((o->type->id == OT_CANDLE) || (o->type->id == OT_TORCH) || (o->type->id == OT_CANDELABRUM)) &&
!isactivated(o)) { !isactivated(o)) {

View File

@ -83,7 +83,7 @@ int getmissileaccuracy(lifeform_t *thrower, cell_t *where, object_t *missile, ob
int getobaccuracy(object_t *wep, lifeform_t *weilder); int getobaccuracy(object_t *wep, lifeform_t *weilder);
int getobbonus(object_t *o, int onlyknown); int getobbonus(object_t *o, int onlyknown);
int getobpoints(object_t *o); int getobpoints(object_t *o);
skill_t *getobskill(object_t *o); skill_t *getobskill(flagpile_t *fp);
enum LFSIZE getobsize(object_t *o); enum LFSIZE getobsize(object_t *o);
int getobspellpower(object_t *o, lifeform_t *lf); int getobspellpower(object_t *o, lifeform_t *lf);
int getobvalue(object_t *o); int getobvalue(object_t *o);
@ -96,7 +96,7 @@ objecttype_t *getbasicweaponforskill(enum SKILL skid);
object_t *getrandomammo(lifeform_t *lf); object_t *getrandomammo(lifeform_t *lf);
objecttype_t *getrandomammofor(object_t *o); objecttype_t *getrandomammofor(object_t *o);
brand_t *getrandombrandfor(objecttype_t *ot); brand_t *getrandombrandfor(objecttype_t *ot);
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity); objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf);
enum OBTYPE getrandomtrapforob(void); enum OBTYPE getrandomtrapforob(void);
char *getdamname(enum DAMTYPE damtype); char *getdamname(enum DAMTYPE damtype);
char *getdamnamenoun(enum DAMTYPE damtype); char *getdamnamenoun(enum DAMTYPE damtype);
@ -108,6 +108,7 @@ int gethardness(enum MATERIAL matid);
char *genhiddenname(enum OBCLASS id); char *genhiddenname(enum OBCLASS id);
char *gethiddenname(object_t *o); char *gethiddenname(object_t *o);
int getobattackdelay(object_t *o); int getobattackdelay(object_t *o);
int getobhp(object_t *o, int *max);
float getobhppct(object_t *o); float getobhppct(object_t *o);
int getobmaxhp(object_t *o); int getobmaxhp(object_t *o);
int getletindex(char let); int getletindex(char let);

309
spell.c
View File

@ -1882,11 +1882,15 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
msg("The scroll crumbles to dust."); msg("The scroll crumbles to dust.");
removeob(o, 1); removeob(o, 1);
} else if (abilid == OT_A_STRIKETOKO) { } else if (abilid == OT_A_STRIKETOKO) {
skill_t *sk; object_t *wep;
sk = getobskill(getweapon(user)); wep = getweapon(user);
if (!sk || (sk->id != SK_CLUBS)) { if (wep) {
if (isplayer(user)) msg("You can only use bashing weapons to fight mercifully."); skill_t *sk;
return B_TRUE; sk = getobskill(wep->flags);
if (!sk || (sk->id != SK_CLUBS)) {
if (isplayer(user)) msg("You can only use bashing weapons to fight mercifully.");
return B_TRUE;
}
} }
if (lfhasflag(user, F_STRIKETOKO)) { if (lfhasflag(user, F_STRIKETOKO)) {
@ -2709,7 +2713,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
wep = getweapon(user); wep = getweapon(user);
if (wep) { if (wep) {
wepsk = getobskill(wep); wepsk = getobskill(wep->flags);
} else { } else {
wepsk = findskill(SK_UNARMED); wepsk = findskill(SK_UNARMED);
} }
@ -4006,6 +4010,25 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f = addtempflag(caster->flags, F_SLOWMOVE, 5, NA, NA, NULL, FROMSPELL); f = addtempflag(caster->flags, F_SLOWMOVE, 5, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid; f->obfrom = spellid;
} }
} else if (spellid == OT_S_BURNINGFEET) {
char killertext[BUFLEN];
if (!target) {
target = targcell->lf;
}
if (!target) {
fizzle(caster);
return B_TRUE;
}
if (!hasbp(target, BP_FEET)) {
fizzle(caster);
return B_TRUE;
}
sprintf(killertext, "%s%s hotfoot spell", castername, getpossessive(castername));
addflag(target->flags, F_HOTFEET, 1, DT_FIRE, NA, killertext);
if (isplayer(target) || cansee(player, target)) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
} else if (spellid == OT_S_BURNINGWAVE) { } else if (spellid == OT_S_BURNINGWAVE) {
cell_t *retcell[MAXRETCELLS]; cell_t *retcell[MAXRETCELLS];
int nretcell; int nretcell;
@ -4681,7 +4704,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
return B_TRUE; return B_TRUE;
} }
for (i = 0; i < power; i++) { for (i = 0; i < power; i++) {
ot = getrandomobofclass(OC_FOOD, NA, NA); ot = getrandomobofclass(OC_FOOD, NA, NA, NULL);
o = addobfast(targcell->obpile, ot->id); o = addobfast(targcell->obpile, ot->id);
if (i == 0) { if (i == 0) {
getobname(o, obname, o->amt); getobname(o, obname, o->amt);
@ -5282,31 +5305,58 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// don't need line of fire! // don't need line of fire!
getradiuscells(targcell, power, DT_ORTH, B_FALSE, LOF_NEED, B_TRUE, cell, &ncells, B_FALSE); getradiuscells(targcell, power, DT_ORTH, B_FALSE, LOF_NEED, B_TRUE, cell, &ncells, B_FALSE);
for (i = 0; i < ncells; i++) { for (i = 0; i < ncells; i++) {
int cellseen = B_FALSE;
object_t *o,*nexto; object_t *o,*nexto;
if (haslos(player, cell[i])) {
cellseen = B_TRUE;
}
for (o = cell[i]->obpile->first ; o ; o = nexto) { for (o = cell[i]->obpile->first ; o ; o = nexto) {
int dosteam = B_FALSE;
nexto = o->next; nexto = o->next;
if (getmaterialstate(o->material->id) == MS_LIQUID) { if (getmaterialstate(o->material->id) == MS_LIQUID) {
int cellseen = B_FALSE;
if (haslos(player, cell[i])) {
cellseen = B_TRUE;
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
// if 20kilos or more, make steam // if 20kilos or more, make steam
if (getobweight(o) >= 25) { if (getobweight(o) >= 25) {
addob(cell[i]->obpile, "cloud of steam"); dosteam = B_TRUE;
if (cellseen) nsteamseen++; if (cellseen) nsteamseen++;
} }
nseen++; nseen++;
removeob(o, ALL); removeob(o, ALL);
} else if (o->material->id == MT_ICE) { } else if ((o->material->id == MT_ICE) || (o->type->obclass->id == OC_POTION)) {
takedamage(o, roll("2d6"), DT_FIRE); char obname[BUFLEN];
dosteam = B_TRUE;
if (cellseen) nsteamseen++;
nseen++;
getobname(o, obname, o->amt);
msg("%s boil%s and explode%s!", obname, OBS1(o), OBS1(o));
removeob(o, ALL);
}
if (dosteam) {
addob(cell[i]->obpile, "cloud of steam");
}
}
if (cell[i]->lf) {
for (o = cell[i]->lf->pack->first ; o ; o = nexto) {
nexto = o->next;
if ((o->material->id == MT_ICE) || (o->type->obclass->id == OC_POTION)) {
char obname[BUFLEN];
if (cellseen) nsteamseen++;
nseen++;
getobname(o, obname, o->amt);
msg("%s boil%s and explode%s!", obname, OBS1(o), OBS1(o));
removeob(o, ALL);
addob(cell[i]->obpile, "cloud of steam");
}
} }
} }
} }
if (nsteamseen) { if (nsteamseen) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
msg("A huge cloud of steam appears!"); msg("A huge cloud of steam appears!");
} else if (nseen) { } else if (nseen) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
msg("Some nearby liquid evaporates!"); msg("Some nearby liquid evaporates!");
} else { } else {
fizzle(caster); fizzle(caster);
@ -5713,22 +5763,36 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
losehp(target, rolldie(power,4), DT_MAGIC, caster, "an energy bolt"); losehp(target, rolldie(power,4), DT_MAGIC, caster, "an energy bolt");
} }
} else if (spellid == OT_S_FIREBALL) { } else if ((spellid == OT_S_FIREBALL) || (spellid == OT_S_METEOR)) {
int failed = B_FALSE; int failed = B_FALSE;
char fbname[BUFLEN];
enum OBTYPE fire1, fire2,fire3;
if (spellid == OT_S_FIREBALL) {
strcpy(fbname, "a huge ball of fire");
fire1 = OT_FIREMED;
fire2 = OT_FIREMED;
fire3 = OT_FIRESMALL;
} else {
strcpy(fbname, "a flaming meteorite");
fire1 = OT_FIRELARGE;
fire2 = OT_FIRELARGE;
fire3 = OT_FIREMED;
}
if (targcell) { if (targcell) {
if (!targcell->type->solid || hasflag(targcell->type->material->flags, F_FLAMMABLE)) { if (!targcell->type->solid || hasflag(targcell->type->material->flags, F_FLAMMABLE)) {
int dir; int dir;
cell_t *c; cell_t *c;
object_t *o; object_t *o;
// centre fireball here... // centre fireball here...
if (isplayer(caster)) { if (isplayer(caster)) {
msg("You launch an enormous ball of fire!"); msg("You launch %s!", fbname);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (cansee(player, caster)) { } else if (cansee(player, caster)) {
msg("%s launches an enormous ball of fire!",castername); msg("%s launches %s!",castername, fbname);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} else if (haslos(player, targcell)) { } else if (haslos(player, targcell)) {
msg("An enormous ball of fire explodes!"); msg("%s explodes!", fbname);
} }
anim(caster->cell, targcell, '^', C_RED); anim(caster->cell, targcell, '^', C_RED);
@ -5742,16 +5806,20 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// 232 // 232
// 1 // 1
// add large fires to surrounding cells // add large fires to surrounding cells
addob(targcell->obpile, "medium fire"); addobfast(targcell->obpile, fire1);
for (dir = D_N; dir <= D_W; dir++) { for (dir = D_N; dir <= D_W; dir++) {
c = getcellindir(targcell, dir); c = getcellindir(targcell, dir);
if (c && (!c->type->solid || hasflag(c->type->material->flags, F_FLAMMABLE)) ) { if (c && (!c->type->solid || hasflag(c->type->material->flags, F_FLAMMABLE)) ) {
o = addob(c->obpile, "medium fire"); o = addobfast(c->obpile, fire1);
if (o) { if (o) {
setobcreatedby(o, caster); setobcreatedby(o, caster);
} }
if (c->lf) { if (c->lf) {
losehp(c->lf, rolldie(power,3), DT_FIRE, caster, "a fireball"); if (spellid == OT_S_FIREBALL) {
losehp(c->lf, rolldie(power,3), DT_FIRE, caster, "a fireball");
} else {
losehp(c->lf, 30+rolldie(power,6), DT_FIRE, caster, "a meterorite");
}
} }
} }
} }
@ -5759,14 +5827,20 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
cell_t *c; cell_t *c;
c = getcellindir(targcell, dir); c = getcellindir(targcell, dir);
if (c && (!c->type->solid || hasflag(c->type->material->flags, F_FLAMMABLE)) ) { if (c && (!c->type->solid || hasflag(c->type->material->flags, F_FLAMMABLE)) ) {
o = addob(c->obpile, "medium fire"); o = addobfast(c->obpile, fire2);
if (o) { if (o) {
setobcreatedby(o, caster); setobcreatedby(o, caster);
} }
if (c->lf) { if (c->lf) {
int ndice; int ndice;
ndice = power / 2; if (ndice < 1) ndice = 1; ndice = power / 2; if (ndice < 1) ndice = 1;
losehp(c->lf, rolldie(ndice,3), DT_FIRE, caster, "a fireball");
if (spellid == OT_S_FIREBALL) {
losehp(c->lf, rolldie(ndice,3), DT_FIRE, caster, "a fireball");
} else {
losehp(c->lf, 15+rolldie(ndice,5), DT_FIRE, caster, "a meteorite");
}
} }
} }
} }
@ -5776,14 +5850,19 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (c) { if (c) {
c = getcellindir(c, dir); c = getcellindir(c, dir);
if (c && (!c->type->solid || hasflag(c->type->material->flags, F_FLAMMABLE)) ) { if (c && (!c->type->solid || hasflag(c->type->material->flags, F_FLAMMABLE)) ) {
o = addob(c->obpile, "small fire"); o = addobfast(c->obpile, fire3);
if (o) { if (o) {
setobcreatedby(o, caster); setobcreatedby(o, caster);
} }
if (c->lf) { if (c->lf) {
int ndice; int ndice;
ndice = power / 2; if (ndice < 1) ndice = 1; ndice = power / 2; if (ndice < 1) ndice = 1;
losehp(c->lf, rolldie(ndice,2), DT_FIRE, caster, "a fireball"); if (spellid == OT_S_FIREBALL) {
losehp(c->lf, rolldie(ndice,2), DT_FIRE, caster, "a fireball");
} else {
losehp(c->lf, 7+rolldie(ndice,4), DT_FIRE, caster, "a meteorite");
}
} }
} }
} }
@ -6134,7 +6213,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else { } else {
int rv; int rv;
getobname(o, buf, o->amt); getobname(o, buf, o->amt);
rv = changemat(o, MT_ICE); if (isimmuneto(o->flags, DT_COLD, B_FALSE)) {
rv = E_NOEFFECT;
} else {
rv = changemat(o, MT_ICE);
}
if (rv) { if (rv) {
if (rv == E_NOEFFECT) { if (rv == E_NOEFFECT) {
if (o->pile->owner) { if (o->pile->owner) {
@ -6453,7 +6536,8 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (!frompot) { if (!frompot) {
pleasegodmaybe(R_GODMERCY, 3); pleasegodmaybe(R_GODMERCY, 3);
} }
angergodmaybe(R_GODDEATH, 20, GA_HERESY); // god of death REALLY doesn't like healing.
angergodmaybe(R_GODDEATH, 40, GA_HERESY);
} }
// hostile monsters might calm down // hostile monsters might calm down
if (!frompot && donesomething && isplayer(caster) && !isplayer(target) && (getallegiance(target) == AL_HOSTILE)) { if (!frompot && donesomething && isplayer(caster) && !isplayer(target) && (getallegiance(target) == AL_HOSTILE)) {
@ -6730,6 +6814,32 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else { } else {
// monsters can't id things! // monsters can't id things!
} }
} else if (spellid == OT_S_IMMOLATE) {
char targname[BUFLEN],buf[BUFLEN];
if (!target) {
target = targcell->lf;
}
if (!target) {
fizzle(caster);
return B_TRUE;
}
getlfname(target, targname);
if (rolltohit(caster, target, NULL, NULL)) {
if (isplayer(caster) || cansee(player, caster)) {
construct_hit_string(caster, target, castername, targname, targname, NULL, DT_TOUCH, 0, target->maxhp,
0, B_FALSE, B_FALSE, B_FALSE, B_TRUE, buf);
msg("%s", buf);
if (seenbyplayer) *seenbyplayer = B_TRUE;
msg("%s is engulfed in roaring flames!", targname);
addobfast(target->cell->obpile, OT_FIRESMALL);
}
} else {
if (isplayer(caster)) {
msg("You try to touch %s, but fail.", targname);
} else if (cansee(player, caster)) {
msg("%s tries to touch %s, but fails.", castername, targname);
}
}
} else if (spellid == OT_S_INFINITEDEATH) { } else if (spellid == OT_S_INFINITEDEATH) {
lifeform_t *l; lifeform_t *l;
if (isplayer(caster)) { if (isplayer(caster)) {
@ -7045,12 +7155,98 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("%s is unaffected.", lfname); msg("%s is unaffected.", lfname);
} }
} }
} else if (spellid == OT_S_OBJECTGROWTH) {
enum OBTYPE newoid = OT_NONE;
enum LFSIZE newsize = SZ_ANY;
skill_t *obsk = SK_NONE;
char obname[BUFLEN],newobname[BUFLEN];
int seen;
if (targcell->obpile->first) {
targob = doaskobject(targcell->obpile, "Target which object", NULL, B_TRUE, B_FALSE, B_FALSE, '\0', AO_NONE, F_NONE);
}
if (!targob) {
fizzle(caster);
return B_TRUE;
}
targcell = getoblocation(targob);
if (haslos(player, targcell)) {
seen = B_TRUE;
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
getobname(targob, obname, 1);
obsk = getobskill(targob->flags);
if (isweapon(targob) && (obsk->id == SK_LONGBLADES)) {
newoid = OT_GREATSWORD;
} else if (isweapon(targob) && (obsk->id == SK_SHORTBLADES)) {
newoid = OT_GREATSWORD;
} else if (isweapon(targob) && (obsk->id == SK_CLUBS)) {
newoid = OT_GREATCLUB;
} else if (isweapon(targob) && (obsk->id == SK_AXES)) {
newoid = OT_GREATAXE;
} else if (targob->type->obclass->id == OC_ROCK) {
newoid = OT_BOULDER;
} else if ((targob->type->obclass->id == OC_ARMOUR) &&
hasflag(targob->flags, F_MULTISIZE) &&
(getarmoursize(targob) < SZ_LARGE)) {
newsize = getarmoursize(targob) + 1;
} else {
switch (targob->type->id) {
case OT_ASH: newoid = OT_STONE; break;
case OT_ASHCONCEAL: newoid = OT_STONE; break;
case OT_ASHEXPLODE: newoid = OT_STONE; break;
case OT_ASHSLEEP: newoid = OT_STONE; break;
case OT_BAGOFHOLDING: newoid = OT_BAGOFHOLDINGLARGE; break;
case OT_BAGOFHOLDINGLARGE: newoid = OT_BAGOFHOLDINGHUGE; break;
case OT_BUCKLER: newoid = OT_SHIELD; break;
case OT_DOORWOOD: newoid = OT_DOORIRON; break;
case OT_FIRESMALL: newoid = OT_FIREMED; break;
case OT_FIREMED: newoid = OT_FIRELARGE; break;
case OT_FLOWER: newoid = OT_SHRUB; break;
case OT_FOUNTAIN: newoid = OT_WATERDEEP; break;
case OT_WOODENSTOOL: newoid = OT_WOODENTABLE; break;
case OT_ICESHEET: newoid = OT_ICICLE; break;
case OT_LEAF: newoid = OT_SHRUB; break;
case OT_MISTLETOE: newoid = OT_SHRUB; break;
case OT_SACK: newoid = OT_SACKLARGE; break;
case OT_SACKLARGE: newoid = OT_SACKHUGE; break;
case OT_SHIELDHIDE: newoid = OT_SHIELD; break;
case OT_SHIELD: newoid = OT_SHIELDLARGE; break;
case OT_SHIELDLARGE: newoid = OT_SHIELDTOWER; break;
case OT_SHRUB: newoid = OT_TREE; break;
case OT_STUMP: newoid = OT_TREE; break;
default: break;
}
}
if (newsize != SZ_ANY) {
resizeobject(targob, newsize);
getobname(targob, obname, 1);
if (seen) msg("%s grows into %s!", obname, newobname);
} else if (newoid == targob->id) {
if (seen) msg("%s shudders for a moment.", obname);
} else if (newoid != OT_NONE) {
obpile_t *op;
op = targob->pile;
killob(targob);
targob = addobfast(op, newoid);
if (targob) {
getobname(targob, newobname, 1);
if (seen) msg("%s grows into %s!", obname, newobname);
} else {
if (seen) msg("%s shudders then explodes!", obname);
}
} else {
if (seen) msg("%s shudders for a moment.", obname);
}
} else if (spellid == OT_S_ACCELMETAL) { } else if (spellid == OT_S_ACCELMETAL) {
char oidbuf[BUFLEN]; char oidbuf[BUFLEN];
flag_t *f; flag_t *f;
if (!targob) { if (!targob) {
// ask for an object // ask for an object
targob = askobject(caster->pack, "Fire which object", NULL, 't', AO_NONE); targob = askobject(caster->pack, "Accelerate which object", NULL, 't', AO_NONE);
} }
if (!targob || !ismetal(targob->material->id) ) { if (!targob || !ismetal(targob->material->id) ) {
fizzle(caster); fizzle(caster);
@ -9405,6 +9601,51 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else { } else {
fizzle(caster); fizzle(caster);
} }
} else if (spellid == OT_S_SUPERHEAT) {
char obname[BUFLEN];
// needs:
// object = which potion to throw
// cell = where to throw the potion
if (!targob && isplayer(caster)) {
targob = askobjectwithflag(caster->pack, "Superheat which potion", NULL, 'q', AO_NONE, F_DRINKABLE);
}
if (!targob) {
fizzle(caster);
return B_TRUE;
}
targob = splitob(targob);
if (!targob) {
if (isplayer(caster)) {
msg("Your pack is too full for this spell to work!");
}
fizzle(caster);
return B_TRUE;
}
getobname(targob, obname, 1);
if (isplayer(caster)) {
msg("Your %s begins to bubble violently!", noprefix(obname)); more();
} else if (cansee(player, caster)) {
msg("%s%s %s begins to bubble violently!", castername, getpossessive(castername), noprefix(obname));
}
// potion will explode next turn if you don't throw it.
addflag(targob->flags, F_EXPLODEONDEATH, NA, 1, NA, "6d2"); //ie . 6-12 damage
addflag(targob->flags, F_EXPLODEONDAM, NA, 1, NA, "6d2"); //ie . 6-12 damage
addflag(targob->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
if (isplayer(caster) && !targcell) {
char buf[BUFLEN],buf2[BUFLEN];
sprintf(buf, "Throw %s where?", obname);
sprintf(buf2, "Superheat->%s->", obname);
targcell = askcoords(buf, buf2,TT_MONSTER, caster, getmaxthrowrange(caster, targob), LOF_NEED, B_TRUE);
}
if (!targcell) {
fizzle(caster);
return B_TRUE;
}
fireat(caster, targob, 1, targcell, getthrowspeed(caster), NULL);
} else if (spellid == OT_S_TAILWIND) { } else if (spellid == OT_S_TAILWIND) {
if (!target) target = caster; if (!target) target = caster;
if (isplayer(target)) { if (isplayer(target)) {
@ -9742,9 +9983,9 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
fizzle(caster); fizzle(caster);
return B_FALSE; return B_FALSE;
} }
f = addtempflag(caster->flags, F_TRUESTRIKE, power, NA, NA, NULL, FROMSPELL); f = addtempflag(target->flags, F_TRUESTRIKE, power, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid; f->obfrom = spellid;
f = addtempflag(caster->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL, FROMSPELL); f = addtempflag(target->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid; f->obfrom = spellid;
} else if (spellid == OT_S_TURNUNDEAD) { } else if (spellid == OT_S_TURNUNDEAD) {
int i; int i;
@ -10582,7 +10823,8 @@ enum OBTYPE getfirstwizspell(enum SPELLSCHOOL school) {
case SS_DEATH: firstspell = OT_S_STENCH; break; case SS_DEATH: firstspell = OT_S_STENCH; break;
case SS_DIVINATION: firstspell = OT_S_SIXTHSENSE; break; case SS_DIVINATION: firstspell = OT_S_SIXTHSENSE; break;
case SS_GRAVITY: firstspell = OT_S_TRUESTRIKE; break; case SS_GRAVITY: firstspell = OT_S_TRUESTRIKE; break;
case SS_MODIFICATION: firstspell = OT_S_HOLDPORTAL; break; //case SS_MODIFICATION: firstspell = OT_S_HOLDPORTAL; break;
case SS_MODIFICATION: firstspell = OT_S_OBJECTGROWTH; break;
case SS_TRANSLOCATION: firstspell = OT_S_APPORTATION; break; case SS_TRANSLOCATION: firstspell = OT_S_APPORTATION; break;
case SS_SUMMONING: firstspell = OT_S_GLYPHWARDING; break; case SS_SUMMONING: firstspell = OT_S_GLYPHWARDING; break;
default: default:
@ -11177,6 +11419,9 @@ int getspellrange(lifeform_t *lf, enum OBTYPE spellid, int power) {
case OT_S_DIG: case OT_S_DIG:
range = power; range = power;
break; break;
case OT_S_FLAMEPILLAR:
range = power;
break;
case OT_S_LIGHTNINGBOLT: case OT_S_LIGHTNINGBOLT:
range = (power*3); range = (power*3);
break; break;

10
text.c
View File

@ -95,7 +95,11 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
// default // default
strcpy(retbuf, ""); strcpy(retbuf, "");
getobname(wep, wepname, 1); if (wep) {
getobname(wep, wepname, 1);
} else {
strcpy(wepname, "?noweapon?"); // should never be displayed
}
// modify victimname if required // modify victimname if required
//if (helpless && !isbehind(lf, victim)) { //if (helpless && !isbehind(lf, victim)) {
@ -139,7 +143,7 @@ char *construct_hit_string(lifeform_t *lf, lifeform_t *victim, char *attackernam
} }
strcpy(extradambuf, ""); strcpy(extradambuf, "");
if (dam == 0) { if ((dam == 0) && (damtype != DT_TOUCH)) {
if (!victim || getlorelevel(lf, victim->race->raceclass->id)) { if (!victim || getlorelevel(lf, victim->race->raceclass->id)) {
//strcpy(extradambuf, " but do no damage"); //strcpy(extradambuf, " but do no damage");
strcpy(extradambuf, " ineffectually"); strcpy(extradambuf, " ineffectually");
@ -986,7 +990,7 @@ char *getobmodprefix(object_t *o, obmod_t *om) {
} else if (isweapon(o)) { } else if (isweapon(o)) {
flag_t *f = NULL; flag_t *f = NULL;
skill_t *sk; skill_t *sk;
sk = getobskill(o); sk = getobskill(o->flags);
if (sk) { if (sk) {
if (om->id == OM_MASTERWORK) { if (om->id == OM_MASTERWORK) {
switch (sk->id) { switch (sk->id) {

View File

@ -9,7 +9,11 @@
#:cell:rock wall #:cell:rock wall
+:ob:wooden door +:ob:wooden door
+:exit +:exit
o:ob:1-5 random tools o:ob:random tool
o:ob:random tool:50
o:ob:random tool:50
o:ob:random tool:50
o:ob:random tool:50
@end @end
@flags @flags

View File

@ -9,7 +9,11 @@
#:cell:rock wall #:cell:rock wall
+:ob:wooden door +:ob:wooden door
+:exit +:exit
o:ob:1-5 random technology o:ob:random technology
o:ob:random technology:50
o:ob:random technology:50
o:ob:random technology:50
o:ob:random technology:50
@end @end
@flags @flags