- [+] battlemage spellbook

- [+] make it grimoire.
    - [+] don't learn the first spell automatically
    - [+] only start with 3 spell schools, and they must be from:
- [+] wizards with no subjob:
    - [+] get a grimoire rather than a spellbook. but first spell is
          always mana spike?
- [+] need some frequent forest vaults
    - [+] tree passage:
    - [+] tree circle
- [+] more enlarge/shrink object effects
    - [+] wooden door = wood wall
    - [+] wooden barrel - wooden dor
- [+] i turned into a cloud of gas. why was i not flying?
    - [+] when you polymorph to creautre with natural flight, start
          flying right away
- [+] show %age chance when studying a scroll
- [+] redo skillcheck code so we can calculate % chance beforehand.
- [+] automatically unlock all doors in starting room
- [+] reduce accuracy for innate attakcs- at the moment they always hit!
    - [+] based on agility.
    - [+] test with monk......
- [+] You have the following spells active:
      3 damage reduction, vuln to fire
- [+] grimoire - why could druid see 'knock' ? think this is fixed now.
- [+] new killverbs:  "murdered" "slain"
- [+] superheat not working if you miss. fixed.
- [+] skillchecks for NC_SPELLEFFECT noises should always succeed.
- [+] modifydamage dealt now that monsters have more hp:
    - [+] initial wizard spells
        - [+] chill
        - [+] spark
        - [+] manaspike
    - [+] later wiz spells
    - [+] fire on ground
- [+] new type of spellbook:
    - [+] general - one spell from each school "spell tome" ? "xxx's
          grimoire"/
- [+] another flagpile corruption bug.
    - [+] asked a mammoan hunter to join me.
    - [+] Marcus shouts "Beware a mosquitoid!".  You hear heavy
          footsteps.
    - [+] Assertion failed: ("flagpile is corrupt!" == 0), function
          checkflagpile, file flag.c, line 456.
    - [+] (timeeffects on footprints)
- [-] when you "vomit then wake up", need to recalc los
    - [+] killflag() is meant to fix this!
    - [ ] why isnt it working?
- [+] bug: wasn't identify()ing starting weapons when you selected them.
- [+] allow temples to try to belss unknown objects.
- [+] allow describing obs from askobmulti()
- [+] warrior read a grimoire, why did it get identified? fixed.
- [+] reduce cost to repair stuff
- [+] dancing flame -l1: fires spread to adjacent lfs
- [+] cleansing fire = l2: use nearby fire to heal -heal (power*20)%
      from each one.
    - [+] maxpower 5
- [+] quicken fire - l4: make flame primarliry
- [+] magic barriers should vanish if you walk into your own one
    - [+] implement
- [+] fleeing from something with F_NOMOVE shouldn't be cowardice
- [+] fix crash in check_for_block()
- [+] new branch: sylvan forest
    - [+] entrance to this branch: hollow tree?
    * [+] add some forest vaults
    - [+] get rid of 'the sun is coming up" messages
    - [+] nature spells which work better outside need to change...
          make it 'when in sylvan woods' instead
- [+] need a spell to teleport to entrance of a branch!
    - [+] done. TRAVEL.
This commit is contained in:
Rob Pearce 2012-03-26 20:21:43 +00:00
parent cbbab346e2
commit d872098c48
15 changed files with 768 additions and 245 deletions

15
ai.c
View File

@ -2475,6 +2475,21 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG
if ((ot->id == OT_S_BLINDNESS) && isblind(victim)) { if ((ot->id == OT_S_BLINDNESS) && isblind(victim)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;
} }
if ((ot->id == OT_S_DANCINGFLAME) || (ot->id == OT_S_CLEANSINGFIRE)) {
int i;
int found = B_FALSE;
// any fire in sight?
for (i = 0; i < lf->nlos; i++) {
if (hasobofmaterial(lf->los[i]->obpile, MT_FIRE) ||
(hasobwithflag(lf->los[i]->obpile, F_ONFIRE))) {
found = B_TRUE;
break;
}
}
if (!found) {
specificcheckok = B_FALSE;
}
}
if (ot->id == OT_A_DISARM) { if (ot->id == OT_A_DISARM) {
if (!getweapon(victim)) { if (!getweapon(victim)) {
specificcheckok = B_FALSE; specificcheckok = B_FALSE;

View File

@ -1789,9 +1789,9 @@ int check_for_block(lifeform_t *lf, lifeform_t *victim, int dam, enum DAMTYPE da
getlfname(victim, victimname); getlfname(victim, victimname);
// announce // announce
real_getobname(shield[i], shname, 1, B_PREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_NOSHOWALL); real_getobname(shield[i], shname, 1, B_PREMODS, B_NOCONDITION, B_BLINDADJUST, B_NOBLESSINGS, B_NOUSED, B_NOSHOWALL);
if (isplayer(lf)) { // player is atatcking if (lf && isplayer(lf)) { // player is atatcking
msg("%s blocks %s with %s.", victimname, attackname, shname); msg("%s blocks %s with %s.", victimname, attackname, shname);
} else if (cansee(player, lf) || cansee(player, victim)) { // monster is attacking } else if ((lf && cansee(player, lf)) || cansee(player, victim)) { // monster is attacking
msg("%s block%s %s with %s.", victimname, isplayer(victim) ? "" : "s", msg("%s block%s %s with %s.", victimname, isplayer(victim) ? "" : "s",
attackname, shname); attackname, shname);
} }

113
data.c
View File

@ -196,7 +196,7 @@ void initjobs(void) {
addsubjob(SJ_PALADIN, "Paladin", "Paladins are holy warriors dedicated to the Goddess of Life. They gain powerful abilities and have access to healing magics, but these powers are dependant upon their goddess' approval. Paladins must take holy vows to only ever use battle equipiment which has first been blessed.", 'p'); addsubjob(SJ_PALADIN, "Paladin", "Paladins are holy warriors dedicated to the Goddess of Life. They gain powerful abilities and have access to healing magics, but these powers are dependant upon their goddess' approval. Paladins must take holy vows to only ever use battle equipiment which has first been blessed.", 'p');
addsubjob(SJ_SCOURGE, "Scourge", "Scourges have dedicated their life to ridding the world of magic. Strict training has granted them an innate immunity to magic, but this immunity also extends to beneficial effects.", 's'); addsubjob(SJ_SCOURGE, "Scourge", "Scourges have dedicated their life to ridding the world of magic. Strict training has granted them an innate immunity to magic, but this immunity also extends to beneficial effects.", 's');
addsubjob(SJ_AIRMAGE, "Skymage", "Initially the weakest of the mages, higher level Skymages become both extremely versatile and extremely power.", 's'); addsubjob(SJ_AIRMAGE, "Skymage", "Initially the weakest of the mages, higher level Skymages become both extremely versatile and extremely power.", 's');
addsubjob(SJ_WILDMAGE, "Wizard", "", 'w'); addsubjob(SJ_WILDMAGE, "Wild Mage", "Wild mages specialise in the random power of wild magic.", 'w');
// job definitions // job definitions
@ -904,7 +904,7 @@ void initjobs(void) {
addflag(lastjob->flags, F_CANLEARN, SK_LORE_UNDEAD, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LORE_UNDEAD, NA, NA, NULL);
// abilities // abilities
addflag(lastjob->flags, F_NEEDOBFORSPELLS, OT_WIZARDSTAFF, NA, NA, NULL); addflag(lastjob->flags, F_NEEDOBFORSPELLS, OT_WIZARDSTAFF, NA, NA, NULL);
addflag(lastjob->flags, F_MAXHPMOD, 50, NA, NA, NULL); // low hp addflag(lastjob->flags, F_MAXHPMOD, 80, NA, NA, NULL); // low hp
addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL); addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL);
addflag(lastjob->flags, F_RESTHEALTIME, 6, NA, NA, NULL); // wizard heals slowly, but regenerates mp addflag(lastjob->flags, F_RESTHEALTIME, 6, NA, NA, NULL); // wizard heals slowly, but regenerates mp
addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 3, F_DETECTMAGIC, B_TRUE, NULL);
@ -3238,18 +3238,13 @@ void initobjects(void) {
// elemental - fire magic // elemental - fire magic
/////////////////// ///////////////////
// 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); addot(OT_S_DANCINGFLAME, "dancing flame", "Causes all fires in sight to 'dance' to adjacent creatures.", 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_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_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 1, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 1, 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 2d3 fire damage to creatures and objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
@ -3264,14 +3259,21 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 1, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 1, NA, NULL);
// l2
addot(OT_S_BLADEBURN, "bladeburn", "Ignites the caster's weapon, causing it to temporarily deal fire damage. The spell's power determines how long it will last.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_BLADEBURN, "bladeburn", "Ignites the caster's weapon, causing it to temporarily deal fire damage. The spell's power determines how long it will last.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines its duration."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines its duration.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 2, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 2, NA, NULL);
// l2
addot(OT_S_CLEANSINGFIRE, "cleansing fire", "Draws power from nearby fires to heal the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell will affect up to ^bpower^n fires, healing 30% hit points from each.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOFLEE, ST_ANYWHERE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_FIREDART, "flame dart", "Fires a medium-sized dart of fire, dealing 1d6+^bpower^n fire damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_FIREDART, "flame dart", "Fires a medium-sized dart of fire, dealing 1d6+^bpower^n fire damage.", 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_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
@ -3280,6 +3282,17 @@ void initobjects(void) {
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);
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 2, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 2, NA, NULL);
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);
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 1, 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); 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_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
@ -3324,6 +3337,13 @@ 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_WALLSTOP, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 4, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODFIRE, 4, NA, NULL);
addot(OT_S_QUICKENFIRE, "quicken fire", "Forms nearby fire into powerful fire primalities.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many creatures will be created.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level VI, stronger creatures will be created.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 8, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL);
// l5 // l5
addot(OT_S_BURNINGWAVE, "burning wave", "Fire bursts from the ground in a line towards the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_BURNINGWAVE, "burning wave", "Fire bursts from the ground in a line towards the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's range is based on its power."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's range is based on its power.");
@ -3348,7 +3368,7 @@ void initobjects(void) {
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); 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, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_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);
@ -3357,7 +3377,7 @@ void initobjects(void) {
// elemental - cold // elemental - cold
/////////////////// ///////////////////
// l1 // l1
addot(OT_S_CHILL, "chill", "Deals minor (1d3) cold damage to a single target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_CHILL, "chill", "Deals 1 cold damage to the target per exposed body part.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
@ -3738,7 +3758,8 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_PLEASESGOD, R_GODLIFE, 1, NA, NULL); addflag(lastot->flags, F_PLEASESGOD, R_GODLIFE, 1, NA, NULL);
// l2 // l2
addot(OT_S_SPEAKDEAD, "speak with dead", "Temporarily allow a corpse to answer questions about its former life.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SPEAKDEAD, "speak with dead", "When one stands upon a corpse and casts this spell, the corpse will temporarily be able to answer questions about its former life.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell will only function correctly on races capable of speech.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
@ -4039,7 +4060,7 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addot(OT_S_QUICKENSTONE, "quicken stone", "Crafts nearby stone into powerful rock primalities.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_QUICKENSTONE, "quicken stone", "Crafts nearby stone into powerful stone primalities.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many creatures will be created."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many creatures will be created.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level VI, stronger creatures will be created."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level VI, stronger creatures will be created.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
@ -4217,7 +4238,7 @@ void initobjects(void) {
// wild // wild
/////////////////// ///////////////////
// l1 // l1
addot(OT_S_MANASPIKE, "mana spike", "Fires a small bolt of wild magic, dealing 1d2 magical damage per power level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_MANASPIKE, "mana spike", "Fires a small bolt of wild magic, dealing 1d4 magical damage per power level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
@ -4479,7 +4500,13 @@ void initobjects(void) {
addot(OT_MANUAL, "manual", "Teaches you one level of its subject matter.", MT_PAPER, 1.5, OC_BOOK, SZ_SMALL); addot(OT_MANUAL, "manual", "Teaches you one level of its subject matter.", MT_PAPER, 1.5, OC_BOOK, SZ_SMALL);
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_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL);
addot(OT_SPELLBOOK, "spellbook", "Teaches you the spells contained within.", MT_PAPER, 1.5, OC_BOOK, SZ_SMALL); addot(OT_SPELLBOOK, "spellbook", "Spellbooks contain a selection of spells from a single school.", MT_PAPER, 1.5, OC_BOOK, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 100, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL);
addot(OT_GRIMOIRE, "grimoire", "Grimoires contain spells from a variety of schools.", MT_PAPER, 2, OC_BOOK, SZ_SMALL);
addflag(lastot->flags, F_NO_A, B_TRUE, NA, 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_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_CAVE, 100, RR_VERYRARE, NULL);
@ -5634,7 +5661,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, "3d4"); addflag(lastot->flags, F_WALKDAM,DT_FIRE, NA, NA, "4d6");
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, "!");
@ -5646,7 +5673,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, "2d4"); addflag(lastot->flags, F_WALKDAM, DT_FIRE, NA, NA, "2d6");
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, 7, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 7, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
@ -5657,7 +5684,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, "1d4"); addflag(lastot->flags, F_WALKDAM, DT_FIRE, NA, NA, "1d6");
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, 5, NA, NA, NULL); addflag(lastot->flags, F_PRODUCESLIGHT, 5, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
@ -5672,7 +5699,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_BLOCKSVIEW, 3, NA, NA, NULL); addflag(lastot->flags, F_BLOCKSVIEW, 3, NA, NA, NULL);
addflag(lastot->flags, F_WALKDAM, DT_HEAT, NA, NA, "1d2"); addflag(lastot->flags, F_WALKDAM, DT_HEAT, NA, NA, "1d4");
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addot(OT_STEAMPUFF, "puff of steam", "A small puff of scalding steam.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM); addot(OT_STEAMPUFF, "puff of steam", "A small puff of scalding steam.", MT_GAS, 0, OC_EFFECT, SZ_MEDIUM);
@ -5683,7 +5710,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_BLOCKSVIEW, 1, NA, NA, NULL); addflag(lastot->flags, F_BLOCKSVIEW, 1, NA, NA, NULL);
addflag(lastot->flags, F_WALKDAM, DT_HEAT, NA, NA, "1d1+1"); addflag(lastot->flags, F_WALKDAM, DT_HEAT, NA, NA, "1d4");
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addot(OT_SLEETSTORM, "storm of sleet", "An intense storm of sleet. Hampers movement and deals minor cold damage.", MT_GAS, 0, OC_EFFECT, SZ_LARGE); addot(OT_SLEETSTORM, "storm of sleet", "An intense storm of sleet. Hampers movement and deals minor cold damage.", MT_GAS, 0, OC_EFFECT, SZ_LARGE);
@ -5781,8 +5808,8 @@ void initobjects(void) {
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
addflag(lastot->flags, F_WALKDAM, DT_COLD, NA, NA, "1d6"); addflag(lastot->flags, F_WALKDAM, DT_COLD, NA, NA, "2d3");
addflag(lastot->flags, F_WALKDAM, DT_PROJECTILE, NA, NA, "1d5"); addflag(lastot->flags, F_WALKDAM, DT_PROJECTILE, NA, NA, "2d3");
addflag(lastot->flags, F_WALKDAMBP, BP_HEAD, DT_WATER, NA, "1d2"); addflag(lastot->flags, F_WALKDAMBP, BP_HEAD, DT_WATER, NA, "1d2");
addflag(lastot->flags, F_WALKDAMBP, BP_SHOULDERS, DT_WATER, NA, "1d2"); addflag(lastot->flags, F_WALKDAMBP, BP_SHOULDERS, DT_WATER, NA, "1d2");
addflag(lastot->flags, F_WALKDAMBP, BP_BODY, DT_WATER, NA, "1d2"); addflag(lastot->flags, F_WALKDAMBP, BP_BODY, DT_WATER, NA, "1d2");
@ -5797,7 +5824,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_KNOCKAWAY, 4, 40, 12, "4d6"); addflag(lastot->flags, F_KNOCKAWAY, 4, 40, 12, "12d3");
addflag(lastot->flags, F_OBMOVESRANDOMLY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBMOVESRANDOMLY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
@ -5826,7 +5853,7 @@ void initobjects(void) {
addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDIETEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOOBDAMTEXT, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_KNOCKAWAY, 2, 35, 10, "3d6"); addflag(lastot->flags, F_KNOCKAWAY, 2, 35, 10, "8d3");
addflag(lastot->flags, F_OBMOVESRANDOMLY, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_OBMOVESRANDOMLY, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!"); addflag(lastot->flags, F_THEREISHERE, B_TRUE, NA, NA, "!");
@ -6567,7 +6594,6 @@ void initobjects(void) {
// DAMTYPE _cannot_ be overridden (yet)! // DAMTYPE _cannot_ be overridden (yet)!
addot(OT_FISTS, "fists", "human fists", MT_FLESH, 0, OC_WEAPON, SZ_TINY); addot(OT_FISTS, "fists", "human fists", MT_FLESH, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_BASH, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 2, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_UNARMED, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_UNARMED, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 1, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 1, NA, NA, NULL);
@ -6583,7 +6609,6 @@ void initobjects(void) {
// this one is for the pirate // this one is for the pirate
addot(OT_HOOKHAND, "hook", "hook", MT_METAL, 0, OC_WEAPON, SZ_TINY); addot(OT_HOOKHAND, "hook", "hook", MT_METAL, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_SLASH, 4, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 4, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_UNARMED, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_UNARMED, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, 2, NA, "scratch"); addflag(lastot->flags, F_ATTACKVERB, NA, 2, NA, "scratch");
@ -6593,7 +6618,6 @@ void initobjects(void) {
addot(OT_TEETH, "teeth", "teeth object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_TEETH, "teeth", "teeth object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_BITE, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_BITE, 2, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
@ -6602,7 +6626,6 @@ void initobjects(void) {
addot(OT_TRAMPLE, "trample", "trample object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_TRAMPLE, "trample", "trample object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_CRUSH, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_CRUSH, 2, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "trample"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "trample");
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
@ -6610,7 +6633,6 @@ void initobjects(void) {
addot(OT_BEAK, "beak", "beak object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_BEAK, "beak", "beak object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_BITE, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_BITE, 2, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
@ -6621,7 +6643,6 @@ void initobjects(void) {
addflag(lastot->flags, F_DAM, DT_SLASH, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_SLASH, 2, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "drill"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "drill");
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
@ -6635,7 +6656,6 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTACKVERB, 19, 24, NA, "gouge"); addflag(lastot->flags, F_ATTACKVERB, 19, 24, NA, "gouge");
addflag(lastot->flags, F_ATTACKVERB, 25, NA, NA, "shred"); addflag(lastot->flags, F_ATTACKVERB, 25, NA, NA, "shred");
addflag(lastot->flags, F_KILLVERB, 70, NA, NA, "disembowel"); addflag(lastot->flags, F_KILLVERB, 70, NA, NA, "disembowel");
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
@ -6650,7 +6670,6 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTACKVERB, 19, 24, NA, "gouge"); addflag(lastot->flags, F_ATTACKVERB, 19, 24, NA, "gouge");
addflag(lastot->flags, F_ATTACKVERB, 25, NA, NA, "shred"); addflag(lastot->flags, F_ATTACKVERB, 25, NA, NA, "shred");
addflag(lastot->flags, F_KILLVERB, 70, NA, NA, "disembowel"); addflag(lastot->flags, F_KILLVERB, 70, NA, NA, "disembowel");
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
@ -6660,7 +6679,6 @@ void initobjects(void) {
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, 11, NA, "kick"); addflag(lastot->flags, F_ATTACKVERB, NA, 11, NA, "kick");
addflag(lastot->flags, F_ATTACKVERB, 12, NA, NA, "trample"); addflag(lastot->flags, F_ATTACKVERB, 12, NA, NA, "trample");
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
@ -6669,7 +6687,6 @@ void initobjects(void) {
addflag(lastot->flags, F_DAM, DT_BASH, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 2, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "butt"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "butt");
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
@ -6678,7 +6695,6 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "sting"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "sting");
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_ACID, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_ACID, 2, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
@ -6687,7 +6703,6 @@ void initobjects(void) {
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "tailslap"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "tailslap");
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 4, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 80, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
@ -6696,7 +6711,6 @@ void initobjects(void) {
addflag(lastot->flags, F_DAM, DT_BASH, 10, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 10, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "slap"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "slap");
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL); addflag(lastot->flags, F_CRITCHANCE, 5, NA, NA, NULL);
@ -6704,13 +6718,11 @@ void initobjects(void) {
addot(OT_TONGUE, "tongue", "tongue object", MT_FLESH, 0, OC_WEAPON, SZ_TINY); addot(OT_TONGUE, "tongue", "tongue object", MT_FLESH, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_PIERCE, 10, NA, NULL); addflag(lastot->flags, F_DAM, DT_PIERCE, 10, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 110, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addot(OT_ZAPPER, "zapper", "zapper object", MT_NOTHING, 0, OC_WEAPON, SZ_TINY); addot(OT_ZAPPER, "zapper", "zapper object", MT_NOTHING, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_ELECTRIC, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_ELECTRIC, 2, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
@ -6718,7 +6730,6 @@ void initobjects(void) {
// monster weapons // monster weapons
addot(OT_ACIDATTACK, "acidattack", "acid attack object", MT_WATER, 0, OC_WEAPON, SZ_TINY); addot(OT_ACIDATTACK, "acidattack", "acid attack object", MT_WATER, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_ACID, 2, NA, NULL); addflag(lastot->flags, F_DAM, DT_ACID, 2, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 75, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "sting"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "sting");
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
@ -6726,20 +6737,17 @@ void initobjects(void) {
addot(OT_TOUCHBURN, "burning touch", "burning touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_TOUCHBURN, "burning touch", "burning touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_FIRE, 1, NA, NULL); addflag(lastot->flags, F_DAM, DT_FIRE, 1, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "burn"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "burn");
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addot(OT_TOUCHCHILL, "chilling touch", "chilling touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_TOUCHCHILL, "chilling touch", "chilling touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_COLD, 1, NA, NULL); addflag(lastot->flags, F_DAM, DT_COLD, 1, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "freeze"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "freeze");
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addot(OT_TOUCHCONFUSE, "confusing touch", "confusing touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_TOUCHCONFUSE, "confusing touch", "confusing touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_BASH, 1, NA, NULL); addflag(lastot->flags, F_DAM, DT_BASH, 1, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "touch"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "touch");
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
@ -6748,14 +6756,12 @@ void initobjects(void) {
addflag(lastot->flags, F_HITCONFERVALS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HITCONFERVALS, B_TRUE, NA, NA, NULL);
addot(OT_TOUCHHOLY, "holy touch", "holy touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_TOUCHHOLY, "holy touch", "holy touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_HOLY, 1, NA, NULL); addflag(lastot->flags, F_DAM, DT_HOLY, 1, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "smite"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "smite");
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_UNARMEDWEP, B_TRUE, NA, NA, NULL);
addot(OT_TOUCHNECROTIC, "necrotic touch", "generic undead touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY); addot(OT_TOUCHNECROTIC, "necrotic touch", "generic undead touch object", MT_BONE, 0, OC_WEAPON, SZ_TINY);
addflag(lastot->flags, F_DAM, DT_NECROTIC, 1, NA, NULL); addflag(lastot->flags, F_DAM, DT_NECROTIC, 1, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "drain"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "drain");
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL); addflag(lastot->flags, F_USESSKILL, SK_NONE, NA, NA, NULL);
@ -6764,7 +6770,6 @@ void initobjects(void) {
addflag(lastot->flags, F_ARMOURPIERCE, 90, NA, NA, ""); addflag(lastot->flags, F_ARMOURPIERCE, 90, NA, NA, "");
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "touch"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "touch");
addflag(lastot->flags, F_DAM, DT_TOUCH, 1, NA, NULL); addflag(lastot->flags, F_DAM, DT_TOUCH, 1, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_HITCONFER, F_PARALYZED, SC_CON, 22, "1-2"); addflag(lastot->flags, F_HITCONFER, F_PARALYZED, SC_CON, 22, "1-2");
addflag(lastot->flags, F_HITCONFERVALS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HITCONFERVALS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
@ -6774,7 +6779,6 @@ void initobjects(void) {
addflag(lastot->flags, F_ARMOURPIERCE, 90, NA, NA, ""); addflag(lastot->flags, F_ARMOURPIERCE, 90, NA, NA, "");
addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "touch"); addflag(lastot->flags, F_ATTACKVERB, NA, NA, NA, "touch");
addflag(lastot->flags, F_DAM, DT_TOUCH, 1, NA, NULL); addflag(lastot->flags, F_DAM, DT_TOUCH, 1, NA, NULL);
addflag(lastot->flags, F_ACCURACY, 100, NA, NA, NULL);
addflag(lastot->flags, F_HITCONFER, F_PARALYZED, SC_CON, 30, "3-5"); addflag(lastot->flags, F_HITCONFER, F_PARALYZED, SC_CON, 30, "3-5");
addflag(lastot->flags, F_HITCONFERVALS, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_HITCONFERVALS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_NOSTRDAMMOD, B_TRUE, NA, NA, NULL);
@ -8755,6 +8759,7 @@ void initrace(void) {
// sacrifices // sacrifices
addflag(lastrace->flags, F_SACRIFICEOBWITHFLAG, F_BATTLESPOILS, NA, 3, "OB explode#S into a shower of blood!"); addflag(lastrace->flags, F_SACRIFICEOBWITHFLAG, F_BATTLESPOILS, NA, 3, "OB explode#S into a shower of blood!");
addflag(lastrace->flags, F_SACRIFICEOB, OT_SPELLBOOK, NA, 10, "OB explode#S into a shower of blood!"); addflag(lastrace->flags, F_SACRIFICEOB, OT_SPELLBOOK, NA, 10, "OB explode#S into a shower of blood!");
addflag(lastrace->flags, F_SACRIFICEOB, OT_GRIMOIRE, NA, 10, "OB explode#S into a shower of blood!");
addrace(R_GODNATURE, "Ekrub", 200, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Ekrub is goddess of nature and creation. She appears as a female figure dressed in farming clothes. Ekrub has a burning hatred of all dragonkind, who she views as abhorrent due to their destructive nature."); addrace(R_GODNATURE, "Ekrub", 200, '@', C_BOLDMAGENTA, MT_FLESH, RC_GOD, "Ekrub is goddess of nature and creation. She appears as a female figure dressed in farming clothes. Ekrub has a burning hatred of all dragonkind, who she views as abhorrent due to their destructive nature.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
@ -11077,7 +11082,7 @@ void initrace(void) {
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL);
addrace(R_PRIMALSTONE, "rock primality", 200, 'E', C_GREY, MT_STONE, RC_MAGIC, "A living mass of stone, animated by powerful magic."); addrace(R_PRIMALSTONE, "stone primality", 200, 'E', C_GREY, MT_STONE, RC_MAGIC, "A living mass of stone, animated by powerful magic.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, 72, RR_RARE, NULL); addflag(lastrace->flags, F_RARITY, H_CAVE, 72, RR_RARE, NULL);
@ -11103,7 +11108,7 @@ void initrace(void) {
addflag(lastrace->flags, F_UNSUMMONOB, NA, NA, NA, "boulder"); addflag(lastrace->flags, F_UNSUMMONOB, NA, NA, NA, "boulder");
addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOSLEEP, B_TRUE, NA, NA, NULL);
addrace(R_PRIMALSTONEL, "lesser rock primality", 120, 'E', C_GREY, MT_STONE, RC_MAGIC, "A living mass of stone, animated by powerful magic."); addrace(R_PRIMALSTONEL, "lesser stone primality", 120, 'E', C_GREY, MT_STONE, RC_MAGIC, "A living mass of stone, animated by powerful magic.");
setbodytype(lastrace, BT_HUMANOID); setbodytype(lastrace, BT_HUMANOID);
addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL); addflag(lastrace->flags, F_ALIGNMENT, AL_NONE, NA, NA, NULL);
addflag(lastrace->flags, F_RARITY, H_CAVE, 72, RR_RARE, NULL); addflag(lastrace->flags, F_RARITY, H_CAVE, 72, RR_RARE, NULL);
@ -15001,8 +15006,8 @@ void initrace(void) {
addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, NULL); addflag(lastrace->flags, F_ACTIONSPEED, SP_SLOW, NA, NA, NULL);
addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 4, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, 3, NA, NULL);
addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 5, NA, NULL); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, 3, NA, NULL);
addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL); addflag(lastrace->flags, F_CANWILL, OT_A_GRAB, NA, NA, NULL);
addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_SILENTMOVE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_RANDOMTALKPCT, 20, NA, NA, NULL); addflag(lastrace->flags, F_RANDOMTALKPCT, 20, NA, NA, NULL);

Binary file not shown.

9
defs.h
View File

@ -517,7 +517,8 @@ enum NOISECLASS {
NC_MOVEMENT = 1, NC_MOVEMENT = 1,
NC_SPEECH = 2, NC_SPEECH = 2,
NC_FIGHTING = 3, NC_FIGHTING = 3,
NC_OTHER = 4, NC_SPELLEFFECT = 4,
NC_OTHER = 5,
}; };
enum QUADRANT { enum QUADRANT {
@ -1479,6 +1480,7 @@ enum OBTYPE {
OT_SCR_TURNUNDEAD, OT_SCR_TURNUNDEAD,
OT_SCR_WISH, OT_SCR_WISH,
// BOOKS // BOOKS
OT_GRIMOIRE,
OT_MANUAL, OT_MANUAL,
OT_SPELLBOOK, OT_SPELLBOOK,
// spells // spells
@ -1545,6 +1547,8 @@ enum OBTYPE {
OT_S_BLADEBURN, OT_S_BLADEBURN,
OT_S_BURNINGFEET, OT_S_BURNINGFEET,
OT_S_BURNINGWAVE, OT_S_BURNINGWAVE,
OT_S_CLEANSINGFIRE,
OT_S_DANCINGFLAME,
OT_S_FIREDART, OT_S_FIREDART,
OT_S_FIREBALL, OT_S_FIREBALL,
OT_S_FLAMEPILLAR, OT_S_FLAMEPILLAR,
@ -1552,6 +1556,7 @@ enum OBTYPE {
OT_S_IMMOLATE, OT_S_IMMOLATE,
OT_S_METEOR, OT_S_METEOR,
OT_S_PYROMANIA, OT_S_PYROMANIA,
OT_S_QUICKENFIRE,
OT_S_SPARK, OT_S_SPARK,
OT_S_SUPERHEAT, OT_S_SUPERHEAT,
OT_S_WALLOFFIRE, OT_S_WALLOFFIRE,
@ -2809,6 +2814,7 @@ enum FLAG {
// f_rndspellposs. // f_rndspellposs.
F_RNDSPELLSCHOOL, // monster's random spells can come from F_RNDSPELLSCHOOL, // monster's random spells can come from
// school v0, between level v1 and v2. // school v0, between level v1 and v2.
// if v0 is SS_NONE, pick a random school.
// (optional) text = "pw:xxx;" to show spell // (optional) text = "pw:xxx;" to show spell
// power. if not given, power comes from depth. // power. if not given, power comes from depth.
F_RNDSPELLPOSS, // monster's random spells can be spellid v0. F_RNDSPELLPOSS, // monster's random spells can be spellid v0.
@ -3166,6 +3172,7 @@ enum FLAG {
F_SACRIFICEOBBLESSED, // v0 = can sacrifice obs with ->blessed=v0 and blessknown! F_SACRIFICEOBBLESSED, // v0 = can sacrifice obs with ->blessed=v0 and blessknown!
F_NAME, // text = lf's name. ie. lfname = "Fred" F_NAME, // text = lf's name. ie. lfname = "Fred"
// also used for names of OT_GRIMOIRE objects
F_NAMED, // text = lf's name. ie. lfname = "xat named Fred" F_NAMED, // text = lf's name. ie. lfname = "xat named Fred"
F_XPMOD, // add/subtract this much from calculated xpval F_XPMOD, // add/subtract this much from calculated xpval
F_BLOODOB, // text = type of object to drop for blood F_BLOODOB, // text = type of object to drop for blood

67
io.c
View File

@ -2785,7 +2785,9 @@ lifeform_t *askgod(char *prompttext, int onlyprayed) {
while (!done) { while (!done) {
getchoice(&prompt); getchoice(&prompt);
lf = (lifeform_t *)prompt.result; lf = (lifeform_t *)prompt.result;
if (prompt.whichq == 0) { if (!lf) {
break;
} else if (prompt.whichq == 0) {
break; break;
} else { } else {
describegod(lf); describegod(lf);
@ -3255,6 +3257,7 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
char myletters[MAXPILEOBS+1]; char myletters[MAXPILEOBS+1];
char msghistbuf[BUFLEN],numstring[BUFLEN]; char msghistbuf[BUFLEN],numstring[BUFLEN];
char pbuf[BUFLEN]; char pbuf[BUFLEN];
char altprompt[BUFLEN];
int firstob = 0; int firstob = 0;
int nextpage = -1; int nextpage = -1;
int lastline = SCREENH-4; int lastline = SCREENH-4;
@ -3262,10 +3265,13 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
int count = ALL; int count = ALL;
char nextlet = 'a'; char nextlet = 'a';
int useobletters; int useobletters;
int descmode = B_FALSE;
objectclass_t *wantoc = NULL; objectclass_t *wantoc = NULL;
clearretobs(); clearretobs();
sprintf(altprompt, "Describe what");
if (countobs(op, B_FALSE) <= 0) { if (countobs(op, B_FALSE) <= 0) {
// no objects in pack // no objects in pack
cls(); cls();
@ -3357,8 +3363,10 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
if (nextpage != -1) { if (nextpage != -1) {
mvwprintw(mainwin, y, 0, MORESTRING); mvwprintw(mainwin, y, 0, MORESTRING);
} }
if (strlen(numstring) > 0) { if (descmode) {
snprintf(pbuf, BUFLEN,"%s (%s','=all, ESC to quit) [%s]: ",prompt, snprintf(pbuf, BUFLEN,"%s (ESC to quit): ", altprompt);
} else if (strlen(numstring) > 0) {
snprintf(pbuf, BUFLEN,"%s (%s','=all, ESC to quit) [%s]: ", prompt,
(opts & AO_INCLUDENOTHING) ? "- for nothing, " : "", (opts & AO_INCLUDENOTHING) ? "- for nothing, " : "",
numstring); numstring);
} else { } else {
@ -3418,20 +3426,24 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
} }
} }
if (which != -1) { if (which != -1) {
int val; if (descmode) {
if (selected[i]) val = B_FALSE; describeob(mylist[i]);
else val = B_TRUE;
selected[i] = val;
if (val == B_TRUE) {
selcount[i] = count;
if (selcount[i] > mylist[i]->amt) selcount[i] = mylist[i]->amt;
} else { } else {
selcount[i] = 0; int val;
if (selected[i]) val = B_FALSE;
else val = B_TRUE;
selected[i] = val;
if (val == B_TRUE) {
selcount[i] = count;
if (selcount[i] > mylist[i]->amt) selcount[i] = mylist[i]->amt;
} else {
selcount[i] = 0;
}
// reset count
strcpy(numstring, "");
count = ALL;
} }
// reset count
strcpy(numstring, "");
count = ALL;
} }
} else if ((ch == '-') && (opts & AO_INCLUDENOTHING)) { // select nothing } else if ((ch == '-') && (opts & AO_INCLUDENOTHING)) { // select nothing
reason = E_SELNOTHING; reason = E_SELNOTHING;
@ -3441,6 +3453,9 @@ int askobjectmulti(obpile_t *op, char *prompt, long opts) {
addmsghist(msghistbuf); addmsghist(msghistbuf);
restoregamewindows(); restoregamewindows();
return B_TRUE; return B_TRUE;
} else if (ch == '?') { // toggle select/describe
if (descmode) descmode = B_FALSE;
else descmode = B_TRUE;
} else if (ch == ',') { // toggle all/none } else if (ch == ',') { // toggle all/none
int val; int val;
if (selected[0]) { // deselect all if (selected[0]) { // deselect all
@ -4343,7 +4358,7 @@ void docomms(lifeform_t *lf) {
if (cantalk(lf)) { if (cantalk(lf)) {
char *p = NULL; char *p = NULL;
if (lf->race->raceclass->id == RC_HUMANOID) { if (lf->race->raceclass->id == RC_HUMANOID) {
p = assignnpcname(lf); p = assignnpcname(lf->flags);
} }
sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p); sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p);
} }
@ -6844,23 +6859,33 @@ char *makedesc_ob(object_t *o, char *retbuf) {
object_t *oo; object_t *oo;
int showcontents = B_TRUE; int showcontents = B_TRUE;
if ((o->type->id == OT_SPELLBOOK) && !isknown(o)) { if ((o->type->id == OT_SPELLBOOK) || (o->type->id == OT_GRIMOIRE)) {
showcontents = B_FALSE; if (!isknown(o)) {
showcontents = B_FALSE;
}
} }
if (showcontents) { if (showcontents) {
if (o->type->id == OT_SPELLBOOK) { if ((o->type->id == OT_SPELLBOOK) || (o->type->id == OT_GRIMOIRE)) {
sprintf(buf, "\n%s contain%s the following spells:\n", OB1(o,"It","They"), OBS1(o)); sprintf(buf, "\n%s contain%s the following spells:\n", OB1(o,"It","They"), OBS1(o));
} else { } else {
sprintf(buf, "\n%s currently contain%s:\n", OB1(o,"It","They"), OBS1(o)); sprintf(buf, "\n%s currently contain%s:\n", OB1(o,"It","They"), OBS1(o));
} }
strncat(retbuf, buf, HUGEBUFLEN); strncat(retbuf, buf, HUGEBUFLEN);
for (oo = o->contents->first ;oo ; oo = oo->next) { for (oo = o->contents->first ;oo ; oo = oo->next) {
char contentname[BUFLEN]; char contentname[BUFLEN];
// don't show spells from schools we don't know
if ((o->type->id == OT_SPELLBOOK) || (o->type->id == OT_GRIMOIRE)) {
if (getspellschoolknown(player, oo->type->id) == SS_NONE) {
continue;
}
}
getobname(oo, contentname, oo->amt); getobname(oo, contentname, oo->amt);
sprintf(buf, " - %s", contentname); sprintf(buf, " - %s", contentname);
if (o->type->id == OT_SPELLBOOK) { if ((o->type->id == OT_SPELLBOOK) || (o->type->id == OT_GRIMOIRE)) {
char lbuf[BUFLEN]; char lbuf[BUFLEN];
sprintf(lbuf, " (Lv %d)%s", getspelllevel(oo->type->id), sprintf(lbuf, " (Lv %d)%s", getspelllevel(oo->type->id),
lfhasflagval(player, F_CANCAST, oo->type->id, NA, NA, NULL) ? lfhasflagval(player, F_CANCAST, oo->type->id, NA, NA, NULL) ?
@ -12243,7 +12268,7 @@ void showlfstats(lifeform_t *lf, int showall) {
} }
strcat(thisline, ")"); strcat(thisline, ")");
mvwprintw(mainwin, y, 0, "%s", desc); mvwprintw(mainwin, y, 0, "%s", thisline);
y++; y++;
nfound++; nfound++;
} }

309
lf.c
View File

@ -910,6 +910,10 @@ int canhear(lifeform_t *lf, cell_t *dest, int volume) {
if (cell->type->solid) { if (cell->type->solid) {
sounddist--; sounddist--;
} }
// magic barriers stop all sound
if (hasob(cell->obpile, OT_MAGICBARRIER)) {
return B_FALSE;
}
// hearing range decreases by one // hearing range decreases by one
sounddist--; sounddist--;
@ -2121,7 +2125,7 @@ int charmedaction(lifeform_t *lf, flag_t *charmflag) {
getlfname(lf, lfname); getlfname(lf, lfname);
getobname(o, obname, o->amt); getobname(o, obname, o->amt);
msg("^w%s hands over %s to %s.", lfname, obname, msg("^w%s hands over %s to %s.", lfname, obname,
cansee(lf, charmer) ? charmername : "someone"); cansee(player, charmer) ? charmername : "someone");
} }
moveob(o, charmer->pack, o->amt); moveob(o, charmer->pack, o->amt);
} }
@ -3158,7 +3162,7 @@ void die(lifeform_t *lf) {
if (lf->race->id == R_BLASTBUG) { if (lf->race->id == R_BLASTBUG) {
flag_t *hpflag; flag_t *hpflag;
hpflag = hasflag(corpse->flags, F_OBHP); hpflag = hasflag(corpse->flags, F_OBHP);
if (hpflag) hpflag->val[0] = rnd(4,5); if (hpflag) hpflag->val[0] = rnd(5,6);
} }
// corpse of a player pet? // corpse of a player pet?
@ -7351,12 +7355,21 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) {
int acc = 0,i; int acc = 0,i;
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags; int nretflags;
int unarmed = B_FALSE;
// get weapon // get weapon
if (wep) { if (wep) {
acc = getobaccuracy(wep, lf, B_FALSE); acc = getobaccuracy(wep, lf, B_FALSE);
if (hasflag(wep->flags, F_UNARMEDWEP)) {
unarmed = B_TRUE;
} else {
unarmed = B_FALSE;
}
} else { } else {
acc = 100; // innate attack unarmed = B_TRUE;
// for unarmed attacks, accuracy is based on agility
acc = getattr(lf, A_AGI) + 20;
limit(&acc, 20, 100);
} }
// dual weilding? // dual weilding?
@ -7422,6 +7435,7 @@ int getlfaccuracy(lifeform_t *lf, object_t *wep) {
} }
*/ */
// modify for blindness // modify for blindness
if (isblind(lf)) { if (isblind(lf)) {
acc -= 50; acc -= 50;
@ -8938,7 +8952,7 @@ enum BODYPART getrandomcorebp(lifeform_t *lf, lifeform_t *attacker) {
race_t *getrandomcorpserace(cell_t *c) { race_t *getrandomcorpserace(cell_t *c) {
race_t *r = NULL; race_t *r = NULL;
while (!r || (hasflag(r->flags, F_NOCORPSE))) { while (!r || hasflag(r->flags, F_NOCORPSE) || hasflag(r->flags, F_CORPSETYPE) || hasflag(r->flags, F_EXTRACORPSE)) {
if (c) r = getrandomrace(c, NA); if (c) r = getrandomrace(c, NA);
else r = getreallyrandomrace(RC_ANY); else r = getreallyrandomrace(RC_ANY);
} }
@ -9898,42 +9912,60 @@ void givejob(lifeform_t *lf, enum JOB jobid) {
} }
givesubjob(lf, sj); givesubjob(lf, sj);
if (j->id == J_WIZARD) { if (j->id == J_WIZARD) {
object_t *sb2; object_t *sb2;
skill_t *sk; skill_t *sk;
// wizards now get a secondary school // wizards with no subjob:
initprompt(&prompt, "Select your secondary spell school:"); if (sj == SJ_NONE) {
addchoice(&prompt, 'd', getskillname(SK_SS_DIVINATION), NULL, findskill(SK_SS_DIVINATION), NULL); object_t *sb1;
addchoice(&prompt, 'm', getskillname(SK_SS_MODIFICATION), NULL, findskill(SK_SS_MODIFICATION), NULL); // start with a grimoire of spells
addchoice(&prompt, 's', getskillname(SK_SS_SUMMONING), NULL, findskill(SK_SS_SUMMONING), NULL); sb1 = addob(lf->pack, "grimoire");
addchoice(&prompt, 't', getskillname(SK_SS_TRANSLOCATION), NULL, findskill(SK_SS_TRANSLOCATION), NULL); identify(sb1);
getchoice(&prompt);
sk = (skill_t *) prompt.result; // monsters get spells from a random school
switch (sk->id) { addflag(lf->flags, F_RNDSPELLCOUNT, rnd(2,4), NA, NA, NULL);
case SK_SS_DIVINATION: addflag(lf->flags, F_RNDSPELLSCHOOL, SS_NONE, 1, lf->level, NULL);
sb2 = addob(lf->pack, "spellbook of divination magic");
break;
case SK_SS_MODIFICATION:
sb2 = addob(lf->pack, "spellbook of modification magic");
break;
case SK_SS_SUMMONING:
sb2 = addob(lf->pack, "spellbook of summoning magic");
break;
case SK_SS_TRANSLOCATION:
sb2 = addob(lf->pack, "spellbook of translocation magic");
break;
default:
sb2 = NULL;
break;
} }
if (sb2) {
addflag(lf->flags, F_CANCAST, sb2->contents->first->type->id, NA, NA, NULL); if (sj != SJ_NONE) {
if (isplayer(lf)) { // wizards with sub-jobs now get a secondary school
addflag(lf->flags, F_SHORTCUT, getnextshortcut(lf), NA, NA, sb2->contents->first->type->name); initprompt(&prompt, "Select your secondary spell school:");
addflag(sb2->flags, F_NOPOINTS, B_TRUE, NA, NA, NULL); addchoice(&prompt, 'd', getskillname(SK_SS_DIVINATION), NULL, findskill(SK_SS_DIVINATION), NULL);
addchoice(&prompt, 'm', getskillname(SK_SS_MODIFICATION), NULL, findskill(SK_SS_MODIFICATION), NULL);
addchoice(&prompt, 's', getskillname(SK_SS_SUMMONING), NULL, findskill(SK_SS_SUMMONING), NULL);
addchoice(&prompt, 't', getskillname(SK_SS_TRANSLOCATION), NULL, findskill(SK_SS_TRANSLOCATION), NULL);
getchoice(&prompt);
sk = (skill_t *) prompt.result;
switch (sk->id) {
case SK_SS_DIVINATION:
sb2 = addob(lf->pack, "spellbook of divination magic");
break;
case SK_SS_MODIFICATION:
sb2 = addob(lf->pack, "spellbook of modification magic");
break;
case SK_SS_SUMMONING:
sb2 = addob(lf->pack, "spellbook of summoning magic");
break;
case SK_SS_TRANSLOCATION:
sb2 = addob(lf->pack, "spellbook of translocation magic");
break;
default:
sb2 = NULL;
break;
} }
if (sb2) {
addflag(lf->flags, F_CANCAST, sb2->contents->first->type->id, NA, NA, NULL);
if (isplayer(lf)) {
addflag(lf->flags, F_SHORTCUT, getnextshortcut(lf), NA, NA, sb2->contents->first->type->name);
addflag(sb2->flags, F_NOPOINTS, B_TRUE, NA, NA, NULL);
}
}
identify(sb2);
} }
identify(sb2);
} }
} }
@ -9998,25 +10030,10 @@ void givesubjob(lifeform_t *lf, enum SUBJOB sj) {
break; break;
// warrior types // warrior types
case SJ_BATTLEMAGE: case SJ_BATTLEMAGE:
// starts off skilled in one school // starts off with a grimoire (special code in objects.c will restrict this
switch (rnd(1,2)) { // to only have 3 spells)
case 1: sb1 = addob(lf->pack, "grimoire");
giveskilllev(lf, SK_SS_FIRE, PR_NOVICE); identify(sb1);
sb1 = addob(lf->pack, "spellbook of fire magic");
if (!isplayer(lf)) {
addflag(lf->flags, F_RNDSPELLCOUNT, rnd(1,2), NA, NA, NULL);
addflag(lf->flags, F_RNDSPELLSCHOOL, SS_FIRE, 1, 3, NULL);
}
break;
case 2:
giveskilllev(lf, SK_SS_COLD, PR_NOVICE);
sb1 = addob(lf->pack, "spellbook of cold magic");
if (!isplayer(lf)) {
addflag(lf->flags, F_RNDSPELLCOUNT, rnd(1,2), NA, NA, NULL);
addflag(lf->flags, F_RNDSPELLSCHOOL, SS_COLD, 1, 3, NULL);
}
break;
}
// can learn some spell schools, but only up to adept level // can learn some spell schools, but only up to adept level
addtempflag(lf->flags, F_CANLEARN, SK_SS_FIRE, PR_ADEPT, NA, NULL, FROMJOB); addtempflag(lf->flags, F_CANLEARN, SK_SS_FIRE, PR_ADEPT, NA, NULL, FROMJOB);
addtempflag(lf->flags, F_CANLEARN, SK_SS_COLD, PR_ADEPT, NA, NULL, FROMJOB); addtempflag(lf->flags, F_CANLEARN, SK_SS_COLD, PR_ADEPT, NA, NULL, FROMJOB);
@ -10036,6 +10053,12 @@ void givesubjob(lifeform_t *lf, enum SUBJOB sj) {
killflagsofid(lf->flags, F_MAXHPMOD); killflagsofid(lf->flags, F_MAXHPMOD);
// remove warrior's level abilities // remove warrior's level abilities
killflagsofid(lf->flags, F_LEVABIL); killflagsofid(lf->flags, F_LEVABIL);
// make sure we have the right skills
for (o = sb1->contents->first ; o ; o = o->next) {
giveskill(lf, getschoolskill(getspellschool(o->type->id)));
}
// un-set sb1 so we don't automatically learn the first spell
sb1 = NULL;
break; break;
case SJ_PALADIN: case SJ_PALADIN:
// extra skills - healing magic & speech // extra skills - healing magic & speech
@ -10714,7 +10737,10 @@ void givestartobs(lifeform_t *lf, object_t *targob, flagpile_t *fp) {
object_t *o; object_t *o;
// give that weapon // give that weapon
o = addobfast(lf->pack, ot->id); o = addobfast(lf->pack, ot->id);
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);
identify(o);
}
// give one extra rank of skill in this weapon // give one extra rank of skill in this weapon
sk = getobskill(o->flags); sk = getobskill(o->flags);
@ -12376,7 +12402,9 @@ int isinbattle(lifeform_t *lf, int includedistant) {
lifeform_t *l; lifeform_t *l;
for (l = lf->cell->map->lf ; l ;l = l->next) { for (l = lf->cell->map->lf ; l ;l = l->next) {
if ((l != lf) && areenemies(l, lf) && cansee(lf, l)) { if ((l != lf) && areenemies(l, lf) && cansee(lf, l)) {
return B_TRUE; if (!lfhasflag(l, F_DOESNTMOVE)) {
return B_TRUE;
}
} }
} }
} else { } else {
@ -12385,7 +12413,9 @@ int isinbattle(lifeform_t *lf, int includedistant) {
cell_t *c; cell_t *c;
c = getcellindir(lf->cell, dir); c = getcellindir(lf->cell, dir);
if (c && c->lf && areenemies(lf, c->lf) && cansee(lf, c->lf)) { if (c && c->lf && areenemies(lf, c->lf) && cansee(lf, c->lf)) {
return B_TRUE; if (!lfhasflag(c->lf, F_DOESNTMOVE)) {
return B_TRUE;
}
} }
} }
} }
@ -13557,7 +13587,7 @@ int askforinfo(lifeform_t *lf, int diffmod) {
askingprice = 0; askingprice = 0;
// passed - free! // passed - free!
} else { } else {
if (!greedy && (difficulty - result >= 10)) { if (!greedy && (result <= 40)) {
// will not help! // will not help!
askingprice = -1; askingprice = -1;
} else { } else {
@ -13643,28 +13673,31 @@ int askforpayment(lifeform_t *shk, lifeform_t *lf) {
} }
*/ */
char *assignnpcname(lifeform_t *lf) { char *assignnpcname(flagpile_t *fp) {
npcname_t *poss,*sel; npcname_t *sel;
int *poss;
int nposs = 0,i; int nposs = 0,i;
poss = malloc(numnpcnames * sizeof(npcname_t *)); poss = malloc(numnpcnames * sizeof(int));
// already got one? // already got one?
if (lfhasflag(lf, F_NAME)) { if (hasflag(fp, F_NAME)) {
return NULL; return NULL;
} }
// count possibilities // count possibilities
for (i = 0;i < numnpcnames; i++) { for (i = 0;i < numnpcnames; i++) {
if (npcname[i].valid) { if (npcname[i].valid) {
poss[nposs++] = npcname[i]; poss[nposs++] = i;
} }
} }
// get random name // get random name
i = rnd(0,nposs); i = poss[rnd(0,nposs-1)];
sel = &npcname[i]; sel = &npcname[i];
// none else can use this name now // none else can use this name now
sel->valid = B_FALSE; sel->valid = B_FALSE;
addflag(lf->flags, F_NAME, NA, NA, NA, sel->name); addflag(fp, F_NAME, NA, NA, NA, sel->name);
free(poss);
return sel->name; return sel->name;
} }
@ -13786,6 +13819,9 @@ void autospells(lifeform_t *lf, int howmany) {
int thispower; int thispower;
objecttype_t *sp; objecttype_t *sp;
ss = retflag[i]->val[0]; ss = retflag[i]->val[0];
if (ss == SS_NONE) {
ss = getrandomspellschool(NULL, B_FALSE);
}
min = retflag[i]->val[1]; min = retflag[i]->val[1];
max = retflag[i]->val[2]; max = retflag[i]->val[2];
texttospellopts(retflag[i]->text, "pw:", &thispower, NULL); texttospellopts(retflag[i]->text, "pw:", &thispower, NULL);
@ -14291,6 +14327,7 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
char buf2[BUFLEN]; char buf2[BUFLEN];
char lfname[BUFLEN]; char lfname[BUFLEN];
int prelowhp = B_FALSE,ko = B_FALSE; int prelowhp = B_FALSE,ko = B_FALSE;
int murder = B_FALSE;
flag_t *f; flag_t *f;
if (gamemode < GM_GAMESTARTED) return 0; if (gamemode < GM_GAMESTARTED) return 0;
@ -14305,6 +14342,10 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
prelowhp = B_TRUE; prelowhp = B_TRUE;
} }
if (fromlf && areallies(lf, fromlf)) {
murder = B_TRUE;
}
// adjust for source object's material // adjust for source object's material
if (fromob) { if (fromob) {
@ -14528,7 +14569,19 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
case DT_MELT: setkillverb(lf, "Melted"); break; case DT_MELT: setkillverb(lf, "Melted"); break;
case DT_PIERCE: setkillverb(lf, "Impaled"); break; case DT_PIERCE: setkillverb(lf, "Impaled"); break;
case DT_EXPLOSIVE: setkillverb(lf, "Vaporised"); break; case DT_EXPLOSIVE: setkillverb(lf, "Vaporised"); break;
default: break; default:
if (fromlf) {
if (murder) {
setkillverb(lf, "Murdered");
} else if (amt >= lf->maxhp) {
setkillverb(lf, "Slaughtered");
} else {
setkillverb(lf, "Slain");
}
} else {
setkillverb(lf, "Killed");
}
break;
} }
} }
@ -15350,6 +15403,7 @@ void noarmouron(race_t *r, enum BODYPART bp) {
int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, char *text, char *seetext) { int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume, char *text, char *seetext) {
lifeform_t *l; lifeform_t *l;
int sounddist; int sounddist;
int alwayshear = B_FALSE;
int rv = B_FALSE; int rv = B_FALSE;
assert(text); assert(text);
@ -15358,6 +15412,10 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
return B_FALSE; return B_FALSE;
} }
if (nclass == NC_SPELLEFFECT) {
alwayshear = B_TRUE;
}
// sound will travel 3*volume cells // sound will travel 3*volume cells
sounddist = getsounddist(volume); sounddist = getsounddist(volume);
@ -15400,7 +15458,7 @@ int noise(cell_t *c, lifeform_t *noisemaker, enum NOISECLASS nclass, int volume,
// skillcheck to hear this // skillcheck to hear this
if ( (isplayer(l) && haslos(l, c)) || // only player can "hear by seeing" if ( (isplayer(l) && haslos(l, c)) || // only player can "hear by seeing"
(canhear(l, c, volume) && skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) { (canhear(l, c, volume) && (alwayshear || skillcheck(l, SC_LISTEN, difficulty, lbonus)) ) ) {
flag_t *f; flag_t *f;
// announce? // announce?
if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) { if (isplayer(l) && !lfhasflag(l, F_ASLEEP)) {
@ -15621,6 +15679,9 @@ enum NOISECLASS noisetypetoclass(enum NOISETYPE nt) {
case N_WALK: case N_WALK:
case N_FLY: case N_FLY:
return NC_MOVEMENT; return NC_MOVEMENT;
case N_SONICBOLT:
case N_WARCRY:
return NC_SPELLEFFECT;
default: default:
break; break;
} }
@ -16287,20 +16348,20 @@ int push(lifeform_t *lf, object_t *o, int dir) {
int racecantalk(enum RACE rid) { int racecantalk(enum RACE rid) {
race_t *r; race_t *r;
switch (rid) {
case RC_DEMON:
case RC_DRAGON:
case RC_GOD:
case RC_HUMANOID:
// these ones can talk
return B_TRUE;
break;
default:
break;
}
r = findrace(rid); r = findrace(rid);
if (r) { if (r) {
switch (r->raceclass->id) {
case RC_DEMON:
case RC_DRAGON:
case RC_GOD:
case RC_HUMANOID:
// these ones can talk
return B_TRUE;
break;
default:
break;
}
if (hasflag(r->flags, F_CANTALK)) return B_TRUE; if (hasflag(r->flags, F_CANTALK)) return B_TRUE;
} }
return B_FALSE; return B_FALSE;
@ -16353,7 +16414,7 @@ int recruit(lifeform_t *lf) {
maxmult = 20; maxmult = 20;
// passed // passed
} else { } else {
if (difficulty - result >= 10) { if (result <= 30) {
// very expensive // very expensive
minmult = 20; minmult = 20;
maxmult = 30; maxmult = 30;
@ -16403,7 +16464,7 @@ int recruit(lifeform_t *lf) {
// give them a name // give them a name
//if (getjob(lf)) { //if (getjob(lf)) {
if (lf->race->raceclass->id == RC_HUMANOID) { if (lf->race->raceclass->id == RC_HUMANOID) {
p = assignnpcname(lf); p = assignnpcname(lf->flags);
} }
sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p); sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p);
} else { } else {
@ -17764,6 +17825,14 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
if (lfhasflag(lf, F_NATURALFLIGHT) && !isairborne(lf)) {
if (cancast(lf, OT_S_FLIGHT, NULL)) {
notime = B_TRUE;
castspell(lf, OT_S_FLIGHT, lf, NULL, lf->cell, NULL, NULL);
notime = B_FALSE;
}
}
if (isplayer(lf)) { if (isplayer(lf)) {
needredraw = B_TRUE; needredraw = B_TRUE;
statdirty = B_TRUE; statdirty = B_TRUE;
@ -17771,6 +17840,7 @@ void setrace(lifeform_t *lf, enum RACE rid, int frompolymorph) {
needredraw = B_TRUE; needredraw = B_TRUE;
} }
//if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging //if (gamemode == GM_GAMESTARTED) checkmapflags(player->cell->map); // debugging
} // end if gamestarted } // end if gamestarted
if (reverting) { if (reverting) {
@ -17917,32 +17987,23 @@ int shoot(lifeform_t *lf) {
return B_FALSE; return B_FALSE;
} }
int getskillcheckchance(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod) {
int skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod) {
return real_skillcheck(lf, ct, diff, mod, NULL);
}
// positive mod makes it easier, negative makes it harder
int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *result) {
int attrib; int attrib;
int levmod; int levmod;
int othermod = 0; int othermod = 0;
int db = B_FALSE; int db = B_FALSE;
int roll;
int modroll;
int luckmod = 0; int luckmod = 0;
char mbuf[BUFLEN]; char mbuf[BUFLEN];
flag_t *retflag[MAXCANDIDATES]; flag_t *retflag[MAXCANDIDATES];
int nretflags,i; int nretflags,i;
flag_t *f; flag_t *f;
int pct;
/*
if (lfhasflag(lf, F_DEBUG)) { if (lfhasflag(lf, F_DEBUG)) {
//if (ct != SC_STEALTH) { // dont show debug info for stealth checks if (ct != SC_STEALTH) { // dont show debug info for stealth checks
db = B_TRUE; db = B_TRUE;
//} }
} }
*/
switch (ct) { switch (ct) {
case SC_STR: case SC_STR:
@ -18142,19 +18203,45 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
sumflags(lf->flags, F_EXTRALUCK, &luckmod, NULL, NULL); sumflags(lf->flags, F_EXTRALUCK, &luckmod, NULL, NULL);
othermod += luckmod; othermod += luckmod;
roll = rolldie(1, 20); pct = 100 - (diff*5); // ie. diff 20 = 100%, 10 = 50%
pct += (attrib*5);
pct += (mod*5);
pct += (levmod*5);
pct += (othermod*5);
if (db) { if (db) {
snprintf(mbuf, BUFLEN, "%s skillcheck (%d) - need %d, got %d(rll)+%d(attr)+%d(lvm)+%d(othmod)+%d(mod)=",lf->race->name, snprintf(mbuf, BUFLEN, "%s skcheck (%d): diff=%d, %d(attr)+%d(lvm)+%d(othmod)+%d(mod),pct=%d%%",
ct, diff, roll, attrib,levmod, othermod,mod); lf->race->name,
ct, diff, attrib,levmod, othermod,mod,pct);
msg(mbuf); more();
} }
modroll = roll; limit(&pct, 0, 100);
modroll += attrib; return pct;
modroll += mod; }
modroll += levmod;
modroll += othermod; int skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod) {
return real_skillcheck(lf, ct, diff, mod, NULL);
}
// positive mod makes it easier, negative makes it harder
// "result" will be filled with difference between our pct chance and what you rolled.
// positive "result" means you rolled higher than what you need.
// negative "result" means you rolled lower.
int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *result) {
int roll,db = B_FALSE, pct;
if (lfhasflag(lf, F_DEBUG)) {
if (ct != SC_STEALTH) { // dont show debug info for stealth checks
db = B_TRUE;
}
}
pct = getskillcheckchance(lf, ct, diff, mod);
roll = rnd(1,100);
if (db) { if (db) {
msg("%s%d.",mbuf,modroll); msg("rolled %d, need <= %d.",roll,pct);
} }
// auto-fail some things // auto-fail some things
@ -18163,31 +18250,29 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
case SC_CLIMB: case SC_CLIMB:
case SC_DODGE: case SC_DODGE:
case SC_SHIELDBLOCK: case SC_SHIELDBLOCK:
roll = 0; roll = 9999;
modroll = 0;
break; break;
default: break; default: break;
} }
} }
if (lfhasflag(lf, F_RAGE) && (ct == SC_STEALTH)) { if (lfhasflag(lf, F_RAGE) && (ct == SC_STEALTH)) {
roll = 0; roll = 9999;
modroll = 0;
} }
// auto pass some things // auto pass some things
if (lfhasflag(lf, F_RAGE) && (ct == SC_MORALE)) { if (lfhasflag(lf, F_RAGE) && (ct == SC_MORALE)) {
modroll = diff; roll = 0;
} }
// natural 20 will pass some checks // natural 20 will pass some checks
if (roll == 20) { if (roll <= 5) {
switch (ct) { switch (ct) {
case SC_DODGE: case SC_DODGE:
case SC_STEALTH: case SC_STEALTH:
if (db) { if (db) {
msg("%s skillcheck passed with natural 20.", lf->race->name); msg("%s skillcheck passed with natural 20.", lf->race->name);
} }
modroll = diff; roll = 0;
break; break;
default: default:
break; break;
@ -18195,10 +18280,10 @@ int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *r
} }
if (result) { if (result) {
*result = modroll; *result = roll - pct;
} }
if (modroll >= diff) { if (roll <= pct) {
// passed! // passed!
// some checks will train skills when passed. // some checks will train skills when passed.
switch (ct) { switch (ct) {
@ -22071,7 +22156,7 @@ int wear(lifeform_t *lf, object_t *o) {
} else if (penalty >= 10) { } else if (penalty >= 10) {
strcpy(howmuch, "quite"); strcpy(howmuch, "quite");
} else { } else {
strcpy(howmuch, "slightly "); strcpy(howmuch, "slightly");
} }
msg("^wYou find this shield %s cumbersome to use.", howmuch); msg("^wYou find this shield %s cumbersome to use.", howmuch);
} }

3
lf.h
View File

@ -22,7 +22,7 @@ int areenemies(lifeform_t *lf1, lifeform_t *lf2);
int armourfits(lifeform_t *lf, object_t *o, enum ERROR *reason); 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(flagpile_t *fp);
void autoshortcut(lifeform_t *lf, enum OBTYPE spellid); void autoshortcut(lifeform_t *lf, enum OBTYPE spellid);
void autoskill(lifeform_t *lf); void autoskill(lifeform_t *lf);
void autospells(lifeform_t *lf, int howmany); void autospells(lifeform_t *lf, int howmany);
@ -434,6 +434,7 @@ int setlfmaterial(lifeform_t *lf, enum MATERIAL id, int wantannounce);
void setlosdirty(lifeform_t *lf); void setlosdirty(lifeform_t *lf);
void setstamina(lifeform_t *lf, float howmuch); void setstamina(lifeform_t *lf, float howmuch);
int shoot(lifeform_t *lf); int shoot(lifeform_t *lf);
int getskillcheckchance(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod) ;
int skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod); int skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod);
int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *result); int real_skillcheck(lifeform_t *lf, enum CHECKTYPE ct, int diff, int mod, int *result);
int skillcheckvs(lifeform_t *lf1, enum CHECKTYPE ct1, int mod1, lifeform_t *lf2, enum CHECKTYPE ct2, int mod2); int skillcheckvs(lifeform_t *lf1, enum CHECKTYPE ct1, int mod1, lifeform_t *lf2, enum CHECKTYPE ct2, int mod2);

4
map.c
View File

@ -5243,7 +5243,7 @@ void explodesinglecell(cell_t *c, int dam, int killwalls, object_t *o, cell_t *c
if (c->lf) { if (c->lf) {
char buf[BUFLEN]; char buf[BUFLEN];
if (o) { if (o) {
getobname(o, obname, 1); getobnametrue(o, obname, 1);
snprintf(buf, BUFLEN, "an exploding %s",strchr(obname, ' ')+1); snprintf(buf, BUFLEN, "an exploding %s",strchr(obname, ' ')+1);
} else { } else {
snprintf(buf, BUFLEN, "an explosion"); snprintf(buf, BUFLEN, "an explosion");
@ -7625,7 +7625,7 @@ void setcellknown(cell_t *cell, int forcelev) {
if (hasflag(player->flags, F_PHOTOMEM)) { if (hasflag(player->flags, F_PHOTOMEM)) {
cell->knowntime = PERMENANT; cell->knowntime = PERMENANT;
} else if (slev == PR_INEPT) { } else if (slev == PR_INEPT) {
cell->knowntime = getattr(player, A_IQ); cell->knowntime = getattr(player, A_IQ)*2;
} else { } else {
cell->knowntime = PERMENANT; cell->knowntime = PERMENANT;
} }

50
move.c
View File

@ -1524,7 +1524,7 @@ int movelf(lifeform_t *lf, cell_t *newcell) {
if (!preseenbyplayer) { if (!preseenbyplayer) {
// TODO: also check for isresting(l), if we have allies standing watch // TODO: also check for isresting(l), if we have allies standing watch
getlfnamea(lf, lfname); getlfnamea(lf, lfname);
msg("%s comes into view.", lfname); msg("%s %ss into view.", lfname, getmoveverb(lf));
} }
dointerrupt = B_TRUE; dointerrupt = B_TRUE;
// mark the observed race as known. // mark the observed race as known.
@ -3156,14 +3156,50 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) {
} }
} }
} else { // somethign random is in the way } else { // somethign random is in the way
if (isplayer(lf) && inway) { if (inway) {
char obname[BUFLEN]; // walking into your own magic barrier?
if (haslos(lf, cell)) { if ((inway->type->id == OT_MAGICBARRIER) &&
getobname(inway, obname, 1); hasflagval(inway->flags, F_CREATEDBY, lf->id, NA, NA, NULL)) {
enum OBTYPE barriertype;
int x,y;
cell_t *cc;
barriertype = inway->type->id;
// vanish this and any other magical barriers we made.
for (y = 0; y < cell->map->h; y++) {
for (x = 0; x < cell->map->w; x++) {
cc = getcellat(cell->map, x,y);
if (cc) {
object_t *oo,*nextoo;
int ndone = 0;
for (oo = cc->obpile->first ; oo ; oo = nextoo) {
nextoo = oo->next;
if ((oo->type->id == barriertype) &&
hasflagval(oo->flags, F_CREATEDBY, lf->id, NA, NA, NULL)) {
takedamage(oo, 999, DT_DIRECT);
ndone++;
}
}
if (ndone) {
removedeadobs(cc->obpile);
}
}
}
}
// NOW is the move possible?
if (moveclear(lf, dir, &errcode)) {
moveto(lf, cell, B_TRUE, B_TRUE);
}
} else { } else {
strcpy(obname, "something"); if (isplayer(lf)) {
char obname[BUFLEN];
if (haslos(lf, cell)) {
getobname(inway, obname, 1);
} else {
strcpy(obname, "something");
}
msg("There is %s in your way.",obname);
}
} }
msg("There is %s in your way.",obname);
} }
} }
break; break;

View File

@ -411,15 +411,22 @@ int main(int argc, char **argv) {
player->facing = D_ALL; player->facing = D_ALL;
setlosdirty(player); setlosdirty(player);
// don't want any mosnters starting within los/lof of player // changes for anything within los/lof of player's starting pos:
// - don't want any mosnters starting here
// - don't want any locked doors
slev = getskill(player, SK_CARTOGRAPHY); slev = getskill(player, SK_CARTOGRAPHY);
for (y = 0; y < player->cell->map->h; y++) { for (y = 0; y < player->cell->map->h; y++) {
for (x = 0; x < player->cell->map->w; x++) { for (x = 0; x < player->cell->map->w; x++) {
c = getcellat(player->cell->map, x, y); c = getcellat(player->cell->map, x, y);
if (c && (haslos(player, c) || haslof(player->cell, c, LOF_WALLSTOP, NULL))) { if (c && (haslos(player, c) || haslof(player->cell, c, LOF_WALLSTOP, NULL))) {
object_t *o,*nexto;
if (c->lf && !isplayer(c->lf) && !ispetof(c->lf, player)) { if (c->lf && !isplayer(c->lf) && !ispetof(c->lf, player)) {
killlf(c->lf); killlf(c->lf);
} }
for (o = c->obpile->first ; o ; o = nexto) {
nexto = o->next;
killflagsofid(o->flags, F_LOCKED);
}
} }
} }
} }

241
objects.c
View File

@ -1549,15 +1549,20 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
// remember the book's school (used for description) // remember the book's school (used for description)
addflag(o->flags, F_LINKSCHOOL, bookcontents, NA, NA, NULL); addflag(o->flags, F_LINKSCHOOL, bookcontents, NA, NA, NULL);
// add contents to the book // add contents to the book
if (where->owner && isplayer(where->owner) && (gamemode == GM_CHARGEN)) { if (where->owner && isplayer(where->owner) && (gamemode == GM_CHARGEN)) {
enum OBTYPE firstspell;
// giving to player at start of game // giving to player at start of game
nspells = 5; if (hasjob(where->owner, J_WIZARD)) {
firstlev = 2; enum OBTYPE firstspell;
nspells = 5;
firstlev = 2;
// fixed first spell // fixed first spell
firstspell = getfirstwizspell(bookcontents); firstspell = getfirstwizspell(bookcontents);
assert(addobfast(o->contents, firstspell)); assert(addobfast(o->contents, firstspell));
} else {
nspells = 5;
firstlev = 1;
}
} else { } else {
nspells = rnd(2,5); nspells = rnd(2,5);
firstlev = rnd(1,4); firstlev = rnd(1,4);
@ -1572,7 +1577,100 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
assert(addobfast(o->contents, oid)); assert(addobfast(o->contents, oid));
} }
} }
} else { } else if (o->type->id == OT_GRIMOIRE) {
// 1 spell from each school
int i;
int nschools = -1;
enum SPELLSCHOOL school[MAXCANDIDATES];
if (where->owner && isplayer(where->owner) && (gamemode == GM_CHARGEN)) {
if (hassubjob(where->owner, SJ_BATTLEMAGE)) {
nschools = 3;
} else if (hasjob(where->owner, J_WIZARD)) {
nschools = 6;
}
}
if (nschools == -1) {
enum SPELLSCHOOL ss;
nschools = 0;
// one spell from each school
for (ss = SS_NONE; ss <= SS_LAST; ss++) {
if (schoolappearsinbooks(ss) && !streq(getschoolname(ss), "badschool")) {
school[nschools] = ss;
nschools++;
}
}
} else {
// select actual random schools to use.
for (i = 0; i < nschools; i++) {
if (where->owner && hassubjob(where->owner, SJ_BATTLEMAGE)) {
switch (rnd(1,6)) {
case 1: school[i] = SS_FIRE; break;
case 2: school[i] = SS_COLD; break;
case 3: school[i] = SS_AIR; break;
case 4: school[i] = SS_MODIFICATION; break;
case 5: school[i] = SS_TRANSLOCATION; break;
case 6: school[i] = SS_WILD; break;
}
} else if (where->owner && hasjob(where->owner, J_WIZARD)) {
school[i] = getrandomspellschool(where->owner, B_TRUE);
} else {
// should never happen?
school[i] = getrandomspellschool(NULL, B_FALSE);
}
}
}
// now select the actual spells to give.
for (i = 0; i < nschools; i++) {
enum SPELLSCHOOL ss;
enum OBTYPE oid;
int wantlev = 1;
ss = school[i];
// giving to player at start of game? limit levels to
// 1-3.
if (where->owner && isplayer(where->owner) && (gamemode == GM_CHARGEN)) {
if (hasjob(where->owner, J_WIZARD)) {
switch (rnd(1,10)) {
case 1: case 2: case 3:
case 4: case 5: case 6:
wantlev = 1;
break;
case 7: case 8: case 9:
wantlev = 2;
break;
case 10:
wantlev = 3;
break;
}
} else if (hassubjob(where->owner, SJ_BATTLEMAGE)) {
wantlev = 1;
} else {
wantlev = getrandomgrimoirelev();
}
} else { // not going to the player
wantlev = getrandomgrimoirelev();
}
// add a random spell from this school
oid = getrandomspellfromschool(ss,wantlev);
if (oid == OT_NONE) {
dblog("couldnt find grimoire contents for school=%s, lev=%d", getschoolname(ss), wantlev);
msg("couldnt find grimoire contents for school=%s, lev=%d", getschoolname(ss), wantlev);
} else if (!hasob(o->contents, oid)) {
assert(addobfast(o->contents, oid));
}
}
// now assign the grimoire a name
if (where->owner && isplayer(where->owner) && (gamemode == GM_CHARGEN)) {
char buf[BUFLEN];
getplayername(buf);
addflag(o->flags, F_NAME, NA, NA, NA, buf);
} else {
assignnpcname(o->flags);
}
} else { // ie. manual
assert(findskill(bookcontents)); assert(findskill(bookcontents));
addflag(o->flags, F_MANUALOF, bookcontents, NA, NA, NULL); addflag(o->flags, F_MANUALOF, bookcontents, NA, NA, NULL);
} }
@ -3850,11 +3948,9 @@ int getcharges(object_t *o) {
// return the base accuracy for the weapon 'wep', or for a throw/unarmed attack if wep is null. // return the base accuracy for the weapon 'wep', or for a throw/unarmed attack if wep is null.
// (ie. the accuracy for a range of 0). // (ie. the accuracy for a range of 0).
int getobaccuracy(object_t *wep, lifeform_t *weilder, int forthrow) { int getobaccuracy(object_t *wep, lifeform_t *weilder, int forthrow) {
int acc; int acc = -1;
flag_t *f; flag_t *f;
acc = 100; // default accuracy of 100%
if (wep) { if (wep) {
// override with weapon's (lack of) accuracy // override with weapon's (lack of) accuracy
f = hasflag(wep->flags, F_ACCURACY); f = hasflag(wep->flags, F_ACCURACY);
@ -3863,14 +3959,29 @@ int getobaccuracy(object_t *wep, lifeform_t *weilder, int forthrow) {
// ie. accuracy of 75% means 25% penalty // ie. accuracy of 75% means 25% penalty
// etc // etc
acc = f->val[0]; acc = f->val[0];
} else {
// if weapon doesn't have F_accuracy flag, use lifeform's agility.
acc = -1;
} }
}
if (acc == -1) {
if (weilder) {
// initial accuracy is based on your agility.
acc = getattr(weilder, A_AGI) + 20;
limit(&acc, 20, 100);
} else {
acc = 100;
}
}
if (wep) {
// blessed weapons have better base accuracy // blessed weapons have better base accuracy
if (wep->blessed == B_BLESSED) acc += 10; if (wep->blessed == B_BLESSED) acc += 10;
//bonusses? //bonusses?
acc += (getobbonus(wep, B_FALSE)*10); acc += (getobbonus(wep, B_FALSE)*10);
} }
if (weilder && !forthrow) { if (weilder && !forthrow) {
@ -4037,6 +4148,8 @@ int real_getobvalue(object_t *o, int amt) {
if (o->type->id == OT_SPELLBOOK) { if (o->type->id == OT_SPELLBOOK) {
price += (89*countobs(o->contents, B_FALSE)); price += (89*countobs(o->contents, B_FALSE));
} else if (o->type->id == OT_GRIMOIRE) {
price += (59*countobs(o->contents, B_FALSE));
} }
getflags(o->flags, retflag, &nretflags, F_ARMOURRATING, F_ARMOURSIZE, F_BONUS, F_DAM, F_EDIBLE, F_LINKSPELL, F_MANUALOF, F_NONE); getflags(o->flags, retflag, &nretflags, F_ARMOURRATING, F_ARMOURSIZE, F_BONUS, F_DAM, F_EDIBLE, F_LINKSPELL, F_MANUALOF, F_NONE);
@ -4267,6 +4380,29 @@ brand_t *getrandombrandfor(objecttype_t *ot) {
return result; return result;
} }
int getrandomgrimoirelev(void) {
int wantlev = 1;
switch (rnd(1,10)) {
case 1:
case 2:
case 3:
case 4:
case 5:
wantlev = rnd(1,2);
break;
case 6:
case 7:
case 8:
wantlev = rnd(3,4);
break;
case 9:
case 10:
wantlev = rnd(5,6);
break;
}
return wantlev;
}
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf) { objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf) {
objecttype_t *ot; objecttype_t *ot;
int count = 0,sel,n; int count = 0,sel,n;
@ -4397,7 +4533,7 @@ char *gethiddennameot(enum OBTYPE otid) {
ot = findot(otid); ot = findot(otid);
// otherwise special case for unidentified books... // otherwise special case for unidentified books...
if (ot->id == OT_SPELLBOOK) { if ((ot->id == OT_SPELLBOOK) || (ot->id == OT_GRIMOIRE)) {
flag_t *f; flag_t *f;
f = hasflag(ot->flags, F_HASHIDDENNAME); f = hasflag(ot->flags, F_HASHIDDENNAME);
if (f) { if (f) {
@ -5090,6 +5226,12 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
strcat(basename, " of "); strcat(basename, " of ");
strcat(basename, getschoolname(f->val[0])); strcat(basename, getschoolname(f->val[0]));
} }
} else if (o->type->id == OT_GRIMOIRE) {
// check F_NAME field
f = hasflag(o->flags, F_NAME);
if (f) {
sprintf(basename, "%s%s grimoire", f->text, getpossessive(f->text));
}
} else { } else {
f = hasflag(o->flags, F_MANUALOF); f = hasflag(o->flags, F_MANUALOF);
if (f) { if (f) {
@ -5602,7 +5744,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
// apply prefix now! // apply prefix now!
if (count == 1) { if (count == 1) {
if (hasflag(o->flags, F_NO_A)) { if (hasflag(o->flags, F_NO_A) && isknown(o)) {
no_a = B_TRUE; no_a = B_TRUE;
} }
@ -10561,9 +10703,10 @@ void potioneffects(lifeform_t *lf, enum OBTYPE oid, object_t *o, enum BLESSTYPE
} }
// it will disappear eventually // it will disappear eventually
addflag(newob->flags, F_OBHP, i, i, NA, NULL); //addflag(newob->flags, F_OBHP, i, i, NA, NULL);
addflag(newob->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); //addflag(newob->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(newob->flags, F_OBHPDRAIN, 1, NA, NA, NULL); //addflag(newob->flags, F_OBHPDRAIN, 1, NA, NA, NULL);
addflag(newob->flags, F_CREATEDBY, lf->id, NA, NA, NULL);
} }
} }
break; break;
@ -10783,7 +10926,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
if (playercansee) { if (playercansee) {
if (o->type->obclass->id == OC_BOOK) { if (o->type->obclass->id == OC_BOOK) {
// is this a spellbook? // is this a spellbook?
if (o->type->id == OT_SPELLBOOK) { if ((o->type->id == OT_SPELLBOOK) || (o->type->id == OT_GRIMOIRE)) {
// if so, only id it if we can understand it. // if so, only id it if we can understand it.
willid = B_FALSE; willid = B_FALSE;
} else { } else {
@ -11232,19 +11375,42 @@ int readsomething(lifeform_t *lf, object_t *o) {
} }
} else if (o->type->obclass->id == OC_BOOK) { } else if (o->type->obclass->id == OC_BOOK) {
// is this a spellbook? // is this a spellbook?
if (o->type->id == OT_SPELLBOOK) { if ((o->type->id == OT_SPELLBOOK) || (o->type->id == OT_GRIMOIRE)) {
object_t *oo; object_t *oo;
char ch = 'a'; char ch = 'a';
enum SPELLSCHOOL school; enum SPELLSCHOOL school;
enum SKILLLEVEL slev; enum SKILLLEVEL slev;
f = hasflag(o->flags, F_LINKSCHOOL); if (o->type->id == OT_SPELLBOOK) {
school = f->val[0]; f = hasflag(o->flags, F_LINKSCHOOL);
slev = getskill(lf, getschoolskill(school)); school = f->val[0];
slev = getskill(lf, getschoolskill(school));
if (!slev) { if (!slev) {
if (isplayer(lf)) msg("You cannot comprehend the contents of this book."); if (isplayer(lf)) {
maketried(o->type->id, NULL); msg("You cannot comprehend the contents of this book.");
return B_FALSE; maketried(o->type->id, NULL);
}
return B_FALSE;
}
} else { // ie. grimoire
object_t *oo;
enum SPELLSCHOOL ss;
int found = B_FALSE;
// grimoire - do you know ANY spell school?
for (oo = o->contents->first; oo ; oo = oo->next) {
ss = getspellschoolknown(lf, oo->type->id);
if ((ss != SS_NONE) && getskill(lf, getschoolskill(ss))) {
found = B_TRUE;
break;
}
}
if (!found) {
if (isplayer(lf)) {
msg("You cannot comprehend the contents of this book.");
maketried(o->type->id, NULL);
}
return B_FALSE;
}
} }
// player now knows what it is - id it! // player now knows what it is - id it!
@ -11261,7 +11427,10 @@ int readsomething(lifeform_t *lf, object_t *o) {
// we are skilled in the right school. now ask which spell to learn. // we are skilled in the right school. now ask which spell to learn.
initprompt(&prompt, "Which spell will you try to learn?"); initprompt(&prompt, "Which spell will you try to learn?");
for (oo = o->contents->first ;oo ; oo = oo->next) { for (oo = o->contents->first ;oo ; oo = oo->next) {
if (!hasflagval(lf->flags, F_CANCAST, oo->type->id, NA, NA, NULL)) { // do you know _this_ spell's school?
// is it one you can't already cast?
if ((getspellschoolknown(lf, oo->type->id) != SS_NONE) &&
!hasflagval(lf->flags, F_CANCAST, oo->type->id, NA, NA, NULL)) {
char *longdesc; char *longdesc;
char shortdesc[BUFLEN]; char shortdesc[BUFLEN];
longdesc = malloc(HUGEBUFLEN * sizeof(char)); longdesc = malloc(HUGEBUFLEN * sizeof(char));
@ -11284,7 +11453,7 @@ int readsomething(lifeform_t *lf, object_t *o) {
ch = getchoicestr(&prompt, B_FALSE, B_TRUE); ch = getchoicestr(&prompt, B_FALSE, B_TRUE);
if ((ch == '\0') || (ch == '-')) { if ((ch == '\0') || (ch == '-')) {
// not 'cancelled' because we still took time // not 'cancelled' because we still took time
msg("You close the spellbook without reading it."); msg("You close the %s without reading it.", o->type->name);
maketried(o->type->id, NULL); maketried(o->type->id, NULL);
return B_FALSE; return B_FALSE;
} }
@ -11617,11 +11786,19 @@ int shatter(object_t *o, int hitlf, char *damstring, lifeform_t *fromlf) {
char obname[BUFLEN]; char obname[BUFLEN];
char targetname[BUFLEN]; char targetname[BUFLEN];
int seen = B_FALSE; int seen = B_FALSE;
flag_t *f;
if (hasflag(o->flags, F_NOSHATTER)) { if (hasflag(o->flags, F_NOSHATTER)) {
return B_FALSE; return B_FALSE;
} }
f = hasflag(o->flags, F_EXPLODEONDEATH);
if (!f) f = hasflag(o->flags, F_EXPLODEONDAM);
if (f) {
explodeob(o, f, f->val[1]);
return B_FALSE;
}
getobname(o,obname,o->amt); getobname(o,obname,o->amt);
where = getoblocation(o); where = getoblocation(o);
@ -13008,8 +13185,9 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
} }
} }
if (thrower && hasactivespell(thrower, OT_S_WHATGOESUP)) {
if (newob && !isdeadob(newob)) { if (newob && !isdeadob(newob)) {
if (thrower && hasactivespell(thrower, OT_S_WHATGOESUP)) {
// on the ground? // on the ground?
if ((newob->pile->where == where) && haslof(newob->pile->where, thrower->cell, LOF_NEED, NULL)) { if ((newob->pile->where == where) && haslof(newob->pile->where, thrower->cell, LOF_NEED, NULL)) {
if (isplayer(thrower)) { if (isplayer(thrower)) {
@ -13021,10 +13199,9 @@ int real_fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int sp
} }
moveob(newob, thrower->pack, newob->amt); moveob(newob, thrower->pack, newob->amt);
} }
} }
} }
/* /*
if (firearm && outofammo && isplayer(thrower)) { if (firearm && outofammo && isplayer(thrower)) {
char buf[BUFLEN]; char buf[BUFLEN];

View File

@ -101,6 +101,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);
int getrandomgrimoirelev(void);
objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf); objecttype_t *getrandomobofclass(enum OBCLASS ocid, int minrarity, int maxrarity, lifeform_t *forlf);
enum OBTYPE getrandomtrapforob(void); enum OBTYPE getrandomtrapforob(void);
int getfirearmrange(object_t *o); int getfirearmrange(object_t *o);

25
shops.c
View File

@ -22,7 +22,7 @@
#define DEF_BLESSCOST 50 #define DEF_BLESSCOST 50
#define DEF_SURCHARGE 15 #define DEF_SURCHARGE 15
#define DEF_RESIZECOST 80 #define DEF_RESIZECOST 80
#define DEF_REPAIRCOSTPERHP 5 #define DEF_REPAIRCOSTPERHP 2
extern enum GAMEMODE gamemode; extern enum GAMEMODE gamemode;
extern prompt_t prompt; extern prompt_t prompt;
@ -579,7 +579,13 @@ enum SHOPRETURN shopbless(lifeform_t *lf, object_t *vm, int starty, char *toptex
sprintf(buf, "Bless which object (you have $%d)?", countmoney(lf->pack)); sprintf(buf, "Bless which object (you have $%d)?", countmoney(lf->pack));
initprompt(&prompt, buf); initprompt(&prompt, buf);
for (o = player->pack->first ; o ; o = o->next) { for (o = player->pack->first ; o ; o = o->next) {
int ok = B_FALSE;
if (o->blessknown && (o->blessed != B_BLESSED) && !hasflag(o->flags, F_NOBLESS)) { if (o->blessknown && (o->blessed != B_BLESSED) && !hasflag(o->flags, F_NOBLESS)) {
ok = B_TRUE;
} else if (!o->blessknown && !hasflag(o->flags, F_NOBLESS)) {
ok = B_TRUE;
}
if (ok) {
char costbuf[BUFLEN]; char costbuf[BUFLEN];
getobname(o, buf, o->amt); getobname(o, buf, o->amt);
sprintf(costbuf, "%-60s($%d)", buf, getshopblessprice(o, vm)); sprintf(costbuf, "%-60s($%d)", buf, getshopblessprice(o, vm));
@ -599,8 +605,23 @@ enum SHOPRETURN shopbless(lifeform_t *lf, object_t *vm, int starty, char *toptex
} else { } else {
msg("You hand over $%d to the priest.", cost); more(); msg("You hand over $%d to the priest.", cost); more();
givemoney(player, NULL, cost); givemoney(player, NULL, cost);
// already blessed?
msg("The priest raise his hands in supplication."); more(); msg("The priest raise his hands in supplication."); more();
blessob(o); if (isblessed(o)) {
msg("\"Hey, this item is already blessed!\""); more();
o->blessknown = B_TRUE;
// chance to get your money back.
if (skillcheck(player, SC_SPEECH, 20, 0)) {
char goldbuf[BUFLEN];
msg("\"...so I will return your payment.\""); more();
sprintf(goldbuf, "%d gold coins", cost);
addob(player->pack, goldbuf);
} else {
msg("\"Unfortunately, we do not offer refunds.\""); more();
}
} else {
blessob(o);
}
more(); more();
} }
} }

163
spell.c
View File

@ -1857,15 +1857,19 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// ask what to inspect // ask what to inspect
initprompt(&prompt, "Study which scroll?"); initprompt(&prompt, "Study which scroll?");
prompt.maycancel = B_TRUE;
for (o = user->pack->first ; o ; o = o->next) { for (o = user->pack->first ; o ; o = o->next) {
if ((o->type->obclass->id == OC_SCROLL) && isknown(o)) { if ((o->type->obclass->id == OC_SCROLL) && isknown(o)) {
f = hasflag(o->flags, F_LINKSPELL); f = hasflag(o->flags, F_LINKSPELL);
if (f && !cancast(user, f->val[0], NULL)) { if (f && !cancast(user, f->val[0], NULL)) {
char buf2[BUFLEN]; char buf2[BUFLEN];
int pct;
getobname(o, buf, o->amt); getobname(o, buf, o->amt);
difficulty = 20 + (getspelllevel(f->val[0])*3); difficulty = 20 + (getspelllevel(f->val[0])*3);
sprintf(buf2, "%s (%d%% success chance)", buf, difficulty); mod = getspellskill(user, f->val[0]) * 3;
addchoice(&prompt, o->letter, buf, NULL, f, NULL); pct = getskillcheckchance(user, SC_LEARNMAGIC, difficulty, mod);
sprintf(buf2, "%s (%d%% success chance)", buf, pct);
addchoice(&prompt, o->letter, buf2, NULL, f, NULL);
} }
} }
} }
@ -1884,8 +1888,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
// try to transcribe it... // try to transcribe it...
difficulty = 20 + (getspelllevel(f->val[0])*3); difficulty = 20 + (getspelllevel(f->val[0])*3);
mod = getspellskill(user, f->val[0]) * 3;
mod = getspellskill(user, f->val[0]) * 2;
if (skillcheck(user, SC_LEARNMAGIC, difficulty, mod)) { if (skillcheck(user, SC_LEARNMAGIC, difficulty, mod)) {
addflag(user->flags, F_CANCAST, f->val[0], NA, NA, NULL); addflag(user->flags, F_CANCAST, f->val[0], NA, NA, NULL);
@ -4550,6 +4553,52 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("The electricity arcs!"); msg("The electricity arcs!");
} }
} // end while narccells } // end while narccells
} else if (spellid == OT_S_CLEANSINGFIRE) {
int i;
int pct = 0;
int ndone = 0;
object_t *o,*nexto;
if (!target) target = caster;
// find all fires within los
for (i = 0; i < target->nlos; i++) {
for (o = target->los[i]->obpile->first ; o ; o = nexto) {
nexto = o->next;
if (ndone >= power) break;
if (o->material->id == MT_FIRE) {
char obname[BUFLEN];
int oamt;
getobname(o, obname, o->amt);
oamt = o->amt;
killob(o);
pct += 30;
if (haslos(player, target->los[i])) {
msg("%s %s out!", obname, (oamt == 1) ? "goes" : "go");
}
ndone++;
continue;
}
if (killflagsofid(o->flags, F_ONFIRE)) {
pct += 20;
ndone++;
continue;
}
}
}
limit(&pct, 0, 100);
if (pct) {
if (isplayer(target)) {
msg("Your wounds are healed!");
} else if (cansee(player, target)) {
char lfname[BUFLEN];
getlfname(target, lfname);
msg("%s%s wounds are healed!", lfname, getpossessive(lfname));
}
gainhp(target, pctof(pct, target->maxhp));
} else {
fizzle(caster);
return B_TRUE;
}
} else if (spellid == OT_S_CLONE) { } else if (spellid == OT_S_CLONE) {
// duplicate the caster // duplicate the caster
targcell = getrandomadjcell(caster->cell, WE_WALKABLE, B_NOEXPAND); targcell = getrandomadjcell(caster->cell, WE_WALKABLE, B_NOEXPAND);
@ -5200,6 +5249,49 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
fizzle(caster); fizzle(caster);
return B_TRUE; return B_TRUE;
} }
} else if (spellid == OT_S_DANCINGFLAME) {
int i;
int ndone = 0;
object_t *o;
if (!target) target = caster;
// find all fires within los
for (i = 0; i < target->nlos; i++) {
enum OBTYPE fireid = OT_NONE;
o = hasobofmaterial(target->los[i]->obpile, MT_FIRE);
if (o) {
fireid = o->type->id;
} else {
o = hasobwithflag(target->los[i]->obpile, F_ONFIRE);
if (o) {
fireid = OT_FIRESMALL;
}
}
if (fireid != OT_NONE) {
int dir;
cell_t *c;
// any nearby lfs?
for (dir = DC_N; dir <= DC_NW; dir++) {
c = getcellindir(target->los[i], dir);
if (c && c->lf) {
object_t *newob;
newob = addobfast(c->obpile, OT_FIRESMALL);
if (newob) {
ndone++;
if (haslos(player, c)) {
char obname[BUFLEN];
getobname(newob, obname, 1);
msg("%s spreads!", obname);
}
}
}
}
}
}
if (!ndone) {
fizzle(caster);
return B_TRUE;
}
} else if (spellid == OT_S_DARKNESS) { } else if (spellid == OT_S_DARKNESS) {
if (!targcell) targcell = caster->cell; if (!targcell) targcell = caster->cell;
// centre on the caster // centre on the caster
@ -7162,7 +7254,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("%s", buf); msg("%s", buf);
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
msg("%s is engulfed in roaring flames!", targname); msg("%s is engulfed in roaring flames!", targname);
addobfast(target->cell->obpile, OT_FIRESMALL); addobfast(target->cell->obpile, OT_FIREMED);
} }
} else { } else {
if (isplayer(caster)) { if (isplayer(caster)) {
@ -8446,12 +8538,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(target, lfname); getlfname(target, lfname);
getobname(o, obname, o->amt);
if (haslos(player, newcell)) { if (haslos(player, newcell)) {
msg("%s%s %s suddenly appears next to it!", lfname, getpossessive(lfname), msg("%s%s %s suddenly appears next to it!", lfname, getpossessive(lfname),
noprefix(buf)); noprefix(obname));
} else { } else {
msg("%s%s %s suddenly vanishes!", lfname, getpossessive(lfname), msg("%s%s %s suddenly vanishes!", lfname, getpossessive(lfname),
noprefix(buf)); noprefix(obname));
} }
} }
} else { } else {
@ -9530,6 +9623,54 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
fizzle(caster); fizzle(caster);
return B_TRUE; return B_TRUE;
} }
} else if (spellid == OT_S_QUICKENFIRE) {
int howmany,i,n,sel,nposs = 0,nseen = 0;
cell_t *c;
object_t *o,*poss[MAXCANDIDATES];
howmany = (power / 2) + 1;
// get a list of all fire cells near caster
for (i = DC_N; i <= DC_NW; i++) {
c = getcellindir(caster->cell, i);
if (c) {
o = hasobofmaterial(c->obpile, MT_FIRE);
if (o) {
poss[nposs++] = o;
}
}
}
limit(&howmany, NA, nposs);
if (!howmany) {
fizzle(caster);
return B_TRUE;
}
// now change them
for (i = 0; i < howmany; i++) {
lifeform_t *lf;
enum RACE rid;
// pick a random one
sel = rnd(0,nposs-1);
o = poss[sel];
// turn it into a golem
c = getoblocation(o);
killob(o);
if (power < 6) {
rid = R_PRIMALFIREL;
} else {
rid = R_PRIMALFIRE;
}
lf = summonmonster(caster, c, rid, NULL, 30, B_TRUE);
if (haslos(player, c)) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
nseen++;
}
// remove it from the list
for (n = sel ; n < (nposs-1); n++) {
poss[n] = poss[n+1];
}
nposs--;
}
// set dirty line of sight for caster, as walls have vanished
caster->losdirty = B_TRUE;
} else if (spellid == OT_S_QUICKENSTONE) { } else if (spellid == OT_S_QUICKENSTONE) {
int howmany,i,n,sel,nposs = 0,nseen = 0; int howmany,i,n,sel,nposs = 0,nseen = 0;
cell_t *c,*poss[MAXCANDIDATES]; cell_t *c,*poss[MAXCANDIDATES];
@ -9560,7 +9701,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else { } else {
rid = R_PRIMALSTONE; rid = R_PRIMALSTONE;
} }
lf = summonmonster(caster, c, R_PRIMALSTONE, NULL, 30, B_TRUE); lf = summonmonster(caster, c, rid, NULL, 30, B_TRUE);
if (haslos(player, c)) { if (haslos(player, c)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
nseen++; nseen++;
@ -10234,7 +10375,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
if (targcell->lf) { if (targcell->lf) {
losehp(targcell->lf, roll("2d2"), DT_FIRE, caster, "a burst of flame"); losehp(targcell->lf, roll("2d3"), DT_FIRE, caster, "a burst of flame");
} }
for (o = targcell->obpile->first ; o ; o = nexto) { for (o = targcell->obpile->first ; o ; o = nexto) {
nexto = o->next; nexto = o->next;
@ -10298,6 +10439,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else { } else {
strcpy(weapon, ""); strcpy(weapon, "");
} }
snprintf(buf, BUFLEN, "\"I was killed by %s", killer); snprintf(buf, BUFLEN, "\"I was killed by %s", killer);
if (strlen(weapon)) { if (strlen(weapon)) {
strcat(buf, ", "); strcat(buf, ", ");
@ -11821,7 +11963,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
petify(lf, target); petify(lf, target);
if (isplayer(target)) { if (isplayer(target)) {
p = assignnpcname(lf); p = assignnpcname(lf->flags);
sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p); sayphrase(lf, SP_RECRUIT_ACCEPT, SV_TALK, NA, p);
} }
@ -12962,6 +13104,7 @@ int schoolappearsinbooks(enum SPELLSCHOOL ss) {
case SS_ABILITY: case SS_ABILITY:
case SS_ALLOMANCY: case SS_ALLOMANCY:
case SS_MENTAL: case SS_MENTAL:
case SS_NATURE:
return B_FALSE; return B_FALSE;
default: default:
break; break;