- [+] when seeing footprints, give size. ("you see small footprints")

- [+] barrels sometimes have things other than food/potions
    - [+] when you generate a container objects, lookup its contents
          class and add F_STARTOB flags before calling givestartobs
    - [+] examples:
        - [+] a single dead corpse.
        - [+] food & drink
        - [+] lots of one particular dry things (salt, sugar)
        - [+] water
        - [+] gunpowder
        - [+] ammo
- [+] engineering mods
    - [+] adept: dismantle doors
    - [+] adept: dismantle WALLS- ie. do dig without using a tool.
        - [+] only some walls.  ones which have been constructed.
            - [+] ie. brick.  wood.
            - [+] NOT stone or metal.
    - [+] skilled: double wall dam
New psionic spells:
- [+] precognition (l2, +5 ev)
- [+] psionic blast (stun all around)
- [+] know weakness
- [+] mental feedback (deal damage based on iq, replaces previous
      'psionic blast')
- [+] mindwhip
- [+] awareness
- [+] replace mass stun with mass sleep.
- [+] statis - startlfturn stuff doesn't happen (l4)
- [+] Clank should now actually appear.
This commit is contained in:
Rob Pearce 2012-11-23 04:54:27 +00:00
parent e30d5f334f
commit 5b28b3571e
10 changed files with 753 additions and 445 deletions

111
data.c
View File

@ -540,21 +540,20 @@ void initjobs(void) {
addflag(lastjob->flags, F_CANWILL, OT_A_FEIGNDEATH, NA, NA, NULL); addflag(lastjob->flags, F_CANWILL, OT_A_FEIGNDEATH, NA, NA, NULL);
addflag(lastjob->flags, F_MAXATTACKS, 1, 1, NA, NULL); // this will go up later addflag(lastjob->flags, F_MAXATTACKS, 1, 1, NA, NULL); // this will go up later
// gained abilities // gained abilities
// somewhere: slow falling when next to walls
// somehwere: alertness when sleeping
addflag(lastjob->flags, F_LEVSKILL, 2, SK_SS_MENTAL, NA, NULL); addflag(lastjob->flags, F_LEVSKILL, 2, SK_SS_MENTAL, NA, NULL);
addflag(lastjob->flags, F_LEVFLAG, 2, F_MPDICE, 1, NULL); addflag(lastjob->flags, F_LEVFLAG, 2, F_MPDICE, 1, NULL);
// 2: body control - low metabolism addflag(lastjob->flags, F_LEVFLAG, 3, F_DTIMMUNE, DT_FALL, NULL);
addflag(lastjob->flags, F_LEVSPELL, 3, OT_S_LOWERMETAB, NA, NULL); addflag(lastjob->flags, F_LEVSPELL, 3, OT_S_LOWERMETAB, NA, NULL);
// 4: self-healing (mp), immune to haste/slow (innate) // 4: self-healing (mp), immune to haste/slow (innate)
addflag(lastjob->flags, F_LEVABIL, 4, OT_A_FLURRY, NA, "pw:1;"); addflag(lastjob->flags, F_LEVABIL, 4, OT_A_FLURRY, NA, "pw:1;");
addflag(lastjob->flags, F_LEVFLAG, 4, F_MEDITATES, B_TRUE, NULL);
addflag(lastjob->flags, F_LEVFLAG, 5, F_DISEASEIMMUNE, B_TRUE, NULL); addflag(lastjob->flags, F_LEVFLAG, 5, F_DISEASEIMMUNE, B_TRUE, NULL);
// 6: waterawlk via 'body equilibrium' (innate) // 6: waterawlk via 'body equilibrium' (innate)
addflag(lastjob->flags, F_LEVABIL, 6, OT_A_AIMEDSTRIKE, NA, NULL); addflag(lastjob->flags, F_LEVABIL, 6, OT_A_AIMEDSTRIKE, NA, NULL);
addflag(lastjob->flags, F_LEVABIL, 7, OT_A_IRONFIST, NA, NULL); addflag(lastjob->flags, F_LEVABIL, 7, OT_A_IRONFIST, NA, NULL);
// 8: molecular manipulation (ie. lower hardness of physical obs by level-7, not lfs) (innate) // 8: molecular manipulation (ie. lower hardness of physical obs by level-7, not lfs) (innate)
addflag(lastjob->flags, F_LEVFLAG, 8, F_TREMORSENSE, NA, NULL); addflag(lastjob->flags, F_LEVFLAG, 8, F_TREMORSENSE, NA, NULL);
// 9: resistance to charm, hypnosis, sleep (innate) addflag(lastjob->flags, F_LEVFLAG, 9, F_NOCHARM, B_TRUE, NULL);
addflag(lastjob->flags, F_LEVFLAG, 10, F_DTIMMUNE, DT_POISON, NULL); addflag(lastjob->flags, F_LEVFLAG, 10, F_DTIMMUNE, DT_POISON, NULL);
addflag(lastjob->flags, F_LEVSPELL, 11, OT_S_PSYARMOUR, NA, NULL); addflag(lastjob->flags, F_LEVSPELL, 11, OT_S_PSYARMOUR, NA, NULL);
// 12: quivering palm (v.high mp cost OR once every 200 turns or so) // 12: quivering palm (v.high mp cost OR once every 200 turns or so)
@ -2033,6 +2032,11 @@ void initobjects(void) {
addflag(lastmaterial->flags, F_HARDNESS, 2, NA, NA, NULL); addflag(lastmaterial->flags, F_HARDNESS, 2, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTVULN, DT_BASH, NA, NA, NULL); addflag(lastmaterial->flags, F_DTVULN, DT_BASH, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTVULN, DT_COLD, NA, NA, NULL); addflag(lastmaterial->flags, F_DTVULN, DT_COLD, NA, NA, NULL);
addmaterial(MT_BRICK, "brick", 14);
addflag(lastmaterial->flags, F_HARDNESS, 4, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_BASH, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_FIRE, NA, NA, NULL);
addflag(lastmaterial->flags, F_DTIMMUNE, DT_COLD, NA, NA, NULL);
addmaterial(MT_GOLD, "gold", 16); addmaterial(MT_GOLD, "gold", 16);
addflag(lastmaterial->flags, F_HARDNESS, 3, NA, NA, NULL); addflag(lastmaterial->flags, F_HARDNESS, 3, NA, NA, NULL);
addmaterial(MT_DURANITE, "duranite", 20); addmaterial(MT_DURANITE, "duranite", 20);
@ -2971,6 +2975,16 @@ void initobjects(void) {
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "1"); addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "1");
addot(OT_BRICK, "brick", "A heavy brick.", MT_STONE, 3, OC_ROCK, SZ_TINY);
addflag(lastot->flags, F_STACKABLE, B_TRUE, NA, NA, "");
addflag(lastot->flags, F_RARITY, H_DUNGEON, NA, RR_RARE, "");
addflag(lastot->flags, F_RARITY, H_CAVE, NA, RR_RARE, NULL);
addflag(lastot->flags, F_RARITY, H_FOREST, NA, RR_RARE, "");
addflag(lastot->flags, F_NUMAPPEAR, 1, 5, NA, "");
addflag(lastot->flags, F_NOBLESS, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_DAMAGABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_THROWMISSILE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_MISSILEDAM, NA, NA, NA, "3");
// gems // gems
addot(OT_AQUAMARINE, "aquamarine stone", "An aqua-coloured gemstone.", MT_STONE, 0.2, OC_ROCK, SZ_TINY); addot(OT_AQUAMARINE, "aquamarine stone", "An aqua-coloured gemstone.", MT_STONE, 0.2, OC_ROCK, SZ_TINY);
@ -4106,10 +4120,10 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
// l3 // l3
addot(OT_S_AWARENESS, "heightened awareness", "This spell effectively gives the caster \"eyes in the back of their head\", expending their field of vision to a full 360 degrees.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_DETECTAURA, "detect aura", "Senses holiness or evil near the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addot(OT_S_DETECTOBS, "detect objects", "Senses objects near the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_DETECTOBS, "detect objects", "Senses objects near the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the detection range and spell duration."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the detection range and spell duration.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
@ -4121,10 +4135,11 @@ void initobjects(void) {
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
// l4 // l4
addot(OT_S_DETECTAURA, "detect aura", "Senses holiness or evil near the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_AWARENESS, "heightened awareness", "This spell effectively gives the caster \"eyes in the back of their head\", expending their field of vision to a full 360 degrees.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addot(OT_S_LORE, "lore", "Obtain knowledge about any one species.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_LORE, "lore", "Obtain knowledge about any one species.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, 1, NA, NA, "At power I, you gain Novice level knowledge."); addflag(lastot->flags, F_EXTRADESC, 1, NA, NA, "At power I, you gain Novice level knowledge.");
addflag(lastot->flags, F_EXTRADESC, 2, NA, NA, "At power II, you gain Beginner level knowledge."); addflag(lastot->flags, F_EXTRADESC, 2, NA, NA, "At power II, you gain Beginner level knowledge.");
@ -5032,15 +5047,28 @@ 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_TARGETTEDSPELL, TT_NONE, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_NONE, 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);
// l2 addot(OT_S_LETHARGY, "lethargy", "Reduces the target's stamina by ^bpower^n*2.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addot(OT_S_ANTICIPATE, "anticipate action", "Allows the caster to automatically dodge the target's attacks.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power detemines the number of attacks dodged.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, 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);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_LOWERMETAB, "lower metabolism", "Slow your body's functions, decreasing your rate of hunger but also your movement speed.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level III: your speed penalty is reduced.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level V: you no longer suffer a speed penalty.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l2
addot(OT_S_PRECOGNITION, "precognition", "Grants the caster the ability to see a very small distance into the future, aiding evasion.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Caster gains +5 EV.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addot(OT_S_DISORIENT, "disorient", "Spins the target around to face away from the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_DISORIENT, "disorient", "Spins the target around to face away from the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
@ -5048,12 +5076,20 @@ void initobjects(void) {
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_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);
addot(OT_S_LOWERMETAB, "lower metabolism", "Slow your body's functions, decreasing your rate of hunger but also your movement speed.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_KNOWWEAKNESS, "know weakness", "Attunes the caster's mind to other peoples' weaknesses, granting a +2 damage bonus.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level III: your speed penalty is reduced.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level V: you no longer suffer a speed penalty.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addot(OT_S_MINDWHIP, "mind whip", "Directly assault a nearby target's brain, dealing 2-6 damage to intelligent creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "This spell only functions on creatures of 'Low' or higher intelligence.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_TELEKINESIS, "telekinesis", "Mentally move or manipulate nearby objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_TELEKINESIS, "telekinesis", "Mentally move or manipulate nearby objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "This spell can lift up to 10kg per power level."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "This spell can lift up to 10kg per power level.");
@ -5061,13 +5097,6 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL);
addot(OT_S_LETHARGY, "lethargy", "Reduces the target's stamina by ^bpower^n*2.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_PSYSHOVE, "psychic shove", "Telekinetically pushes against the target. Depending on relative weight, either the target or the caster will fly away.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_PSYSHOVE, "psychic shove", "Telekinetically pushes against the target. Depending on relative weight, either the target or the caster will fly away.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Note: the push is not powerful enough to cause direct damage."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Note: the push is not powerful enough to cause direct damage.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
@ -5079,7 +5108,15 @@ void initobjects(void) {
addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l3 // l3
addot(OT_S_PSIBLAST, "psionic blast", "Assaults the target's brain with a mental feedback loop, dealing damage based on their intelligence.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_ANTICIPATE, "anticipate action", "Allows the caster to automatically dodge the target's attacks.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power detemines the number of attacks dodged.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, 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_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addot(OT_S_MFEEDBACK, "mental feedback", "Assaults the target's brain with a mental feedback loop, dealing damage based on their intelligence.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Creatures with higher intelligence will take more damage."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Creatures with higher intelligence will take more damage.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
@ -5087,6 +5124,12 @@ 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_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_PSIBLAST, "psionic blast", "Stuns all nearby living creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Creatures are stunned for ^bpower^n+4 turns.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJSELF, NA, NA, NULL);
addot(OT_S_PSYARMOUR, "psychic armour", "Mentally block incoming attacks.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_PSYARMOUR, "psychic armour", "Mentally block incoming attacks.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The psychic armour's Armour Rating is ^bpower*4^n."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The psychic armour's Armour Rating is ^bpower*4^n.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
@ -5124,11 +5167,18 @@ void initobjects(void) {
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
addot(OT_S_STUNMASS, "mass stun", "Stuns all creatures within sight.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SLEEPMASS, "mass sleep", "Stuns all creatures within sight.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL);
addot(OT_S_STASIS, "stasis", "Freezes time inside your body, preventing many effects such as poison, hunger, and even breathing.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Note that health regeneration is also prevented while in stasis.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL);
addflag(lastot->flags, F_ONGOING, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL);
// l5 // l5
addot(OT_S_CHARM, "charm", "Causes another lifeform to temporary become friendly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_CHARM, "charm", "Causes another lifeform to temporary become friendly.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability and duration."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability and duration.");
@ -9927,7 +9977,7 @@ void initrace(void) {
setbodypartname(lastrace, BP_RIGHTFINGER, "right sensor"); setbodypartname(lastrace, BP_RIGHTFINGER, "right sensor");
setbodypartname(lastrace, BP_LEFTFINGER, "left sensor"); setbodypartname(lastrace, BP_LEFTFINGER, "left sensor");
addflag(lastrace->flags, F_NAME, NA, NA, NA, "Clank"); addflag(lastrace->flags, F_NAME, NA, NA, NA, "Clank");
addflag(lastrace->flags, F_UNIQUE, NA, NA, NA, NULL); addflag(lastrace->flags, F_UNIQUE, 33, BH_MAINDUNGEON, 1, "4-8");
addflag(lastrace->flags, F_HOSTILE, NA, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, NA, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_HUMAN, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL); addflag(lastrace->flags, F_HITDICE, 6, NA, NA, NULL);
@ -15143,7 +15193,7 @@ void initrace(void) {
addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL); addflag(lastrace->flags, F_STARTSKILL, SK_FLIGHT, PR_ADEPT, NA, NULL);
addflag(lastrace->flags, F_CANCAST, OT_S_STUN, 3, 3, "pw:3;"); addflag(lastrace->flags, F_CANCAST, OT_S_STUN, 3, 3, "pw:3;");
addflag(lastrace->flags, F_CANCAST, OT_S_DISORIENT, 3, 3, "pw:3;"); addflag(lastrace->flags, F_CANCAST, OT_S_DISORIENT, 3, 3, "pw:3;");
addflag(lastrace->flags, F_CANCAST, OT_S_PSIBLAST, 3, 3, "pw:1;"); addflag(lastrace->flags, F_CANCAST, OT_S_MFEEDBACK, 3, 3, "pw:1;");
addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL); addflag(lastrace->flags, F_ENHANCESMELL, 4, NA, NA, NULL);
addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_NOCTURNAL, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL); addflag(lastrace->flags, F_MORALE, 6, NA, NA, NULL);
@ -19515,8 +19565,9 @@ void initskills(void) {
addskilldesc(SK_ENGINEERING, PR_BEGINNER, "You can now detect hollow spaces.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_BEGINNER, "You can now detect hollow spaces.", B_TRUE);
addskilldesc(SK_ENGINEERING, PR_BEGINNER, "You can now identify trap types.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_BEGINNER, "You can now identify trap types.", B_TRUE);
addskilldesc(SK_ENGINEERING, PR_ADEPT, "You can now create barricades and basic traps.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_ADEPT, "You can now create barricades and basic traps.", B_TRUE);
addskilldesc(SK_ENGINEERING, PR_ADEPT, "You can now dismantle doors as well as obstacles.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_ADEPT, "You can now dismantle doors and made-made walls.", B_TRUE);
addskilldesc(SK_ENGINEERING, PR_SKILLED, "You now automatically detect traps.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_SKILLED, "You now automatically detect traps.", B_TRUE);
addskilldesc(SK_ENGINEERING, PR_SKILLED, "Your speed at dismantling walls is doubled.", B_TRUE);
addskilldesc(SK_ENGINEERING, PR_EXPERT, "You can now create advanced traps.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_EXPERT, "You can now create advanced traps.", B_TRUE);
addskilldesc(SK_ENGINEERING, PR_MASTER, "You are now immune to most trap effects.", B_TRUE); addskilldesc(SK_ENGINEERING, PR_MASTER, "You are now immune to most trap effects.", B_TRUE);
addskill(SK_THROWING, "Throwing", "Your accuracy when throwing objects at things.", 50); addskill(SK_THROWING, "Throwing", "Your accuracy when throwing objects at things.", 50);

32
defs.h
View File

@ -393,6 +393,17 @@
#define MAXDIR_MAP 15 #define MAXDIR_MAP 15
enum CONTAINERCONTENTS {
CC_AMMO,
CC_FOOD,
CC_FOODDRINK,
CC_GUNPOWDER,
CC_CONDIMENTS,
CC_CORPSE,
CC_WATER,
};
enum CELLCONDITION { enum CELLCONDITION {
CC_NONE, // CC_NONE, //
@ -1507,6 +1518,7 @@ enum MATERIAL {
MT_DIRT = 30, MT_DIRT = 30,
MT_CRYSTAL = 31, MT_CRYSTAL = 31,
MT_DURANITE = 32, MT_DURANITE = 32,
MT_BRICK = 33,
}; };
// Object Types // Object Types
@ -1582,13 +1594,14 @@ enum OBTYPE {
OT_TRAPTRIP, OT_TRAPTRIP,
OT_TRAPWIND, OT_TRAPWIND,
// rocks // rocks
OT_STONE,
OT_ASH, OT_ASH,
OT_ASHEXPLODE, OT_ASHEXPLODE,
OT_ASHCONCEAL, OT_ASHCONCEAL,
OT_ASHINVIS, OT_ASHINVIS,
OT_ASHSLEEP, OT_ASHSLEEP,
OT_BRICK,
OT_GEMOFSEEING, OT_GEMOFSEEING,
OT_STONE,
// gems // gems
OT_AQUAMARINE, OT_AQUAMARINE,
OT_AMETHYST, OT_AMETHYST,
@ -1870,15 +1883,20 @@ enum OBTYPE {
OT_S_HUNGER, OT_S_HUNGER,
OT_S_LETHARGY, OT_S_LETHARGY,
OT_S_LOWERMETAB, OT_S_LOWERMETAB,
OT_S_KNOWWEAKNESS,
OT_S_MFEEDBACK,
OT_S_MINDSCAN, OT_S_MINDSCAN,
OT_S_MINDWHIP,
OT_S_MIRRORIMAGE, OT_S_MIRRORIMAGE,
OT_S_PACIFY, OT_S_PACIFY,
OT_S_PRECOGNITION,
OT_S_PSIBLAST, OT_S_PSIBLAST,
OT_S_PSYARMOUR, OT_S_PSYARMOUR,
OT_S_PSYSHOVE, OT_S_PSYSHOVE,
OT_S_SLEEP, OT_S_SLEEP,
OT_S_SLEEPMASS,
OT_S_STASIS,
OT_S_STUN, OT_S_STUN,
OT_S_STUNMASS,
OT_S_TELEKINESIS, OT_S_TELEKINESIS,
OT_S_VENTRILOQUISM, OT_S_VENTRILOQUISM,
// nature / enviromancy // nature / enviromancy
@ -2893,6 +2911,8 @@ enum FLAG {
F_HELPSCLIMB, // object gives v0 bonus to sc_climb checks. F_HELPSCLIMB, // object gives v0 bonus to sc_climb checks.
F_HELPSDIG, // object can dig. does v0 dam to cells. F_HELPSDIG, // object can dig. does v0 dam to cells.
// also makes noise 'text' at volume v1 // also makes noise 'text' at volume v1
F_DIGCELLTYPE, // object can dig through this celltype
F_DIGCELLMAT, // object can dig through cells of this material
F_HELPSDISARM, // object gives v0 bonus to disarm trap checks. F_HELPSDISARM, // object gives v0 bonus to disarm trap checks.
F_HELPSREPAIR, // object gives v1 bonus to repairing obejcts F_HELPSREPAIR, // object gives v1 bonus to repairing obejcts
// made of material v0. Also decreases the // made of material v0. Also decreases the
@ -3437,6 +3457,9 @@ enum FLAG {
// it will be specially handled. // it will be specially handled.
F_CONTAINER, // this object is a container - you can use 'o' F_CONTAINER, // this object is a container - you can use 'o'
// to take stuff out or put it in. // to take stuff out or put it in.
F_CONTENTS, // v0 = enum CONTAINERCONTENTS for this container
// when object is generated, a random F_CONTENTS
// flag will be chosen.
F_HOLDING, // this container is a xxx of holding and makes objects F_HOLDING, // this container is a xxx of holding and makes objects
// inside become weightless // inside become weightless
F_STARTJOB, // val0 = %chance of starting with it, v1 = jobid F_STARTJOB, // val0 = %chance of starting with it, v1 = jobid
@ -3887,6 +3910,9 @@ enum FLAG {
// this lf does 'text' extra damage of damtype v0 // this lf does 'text' extra damage of damtype v0
// if v1 is TRUE, also deal extra damage based on // if v1 is TRUE, also deal extra damage based on
// the flagpile's F_BONUS flag. // the flagpile's F_BONUS flag.
//
// if v0 is NA, damage is added to initial damage
// roll.
F_EXTRADAMWITHCHARGES, // if this objects has charges remaining, F_EXTRADAMWITHCHARGES, // if this objects has charges remaining,
// deal an extra "text" damage of type v0. // deal an extra "text" damage of type v0.
F_EXTRAINFO, // knows extra info F_EXTRAINFO, // knows extra info
@ -3996,6 +4022,7 @@ enum FLAG {
// (but not for obs in pack) // (but not for obs in pack)
// if val2 is true, will only make light if ob // if val2 is true, will only make light if ob
// is activated! // is activated!
F_STASIS, // many startlfturn effects don't happen.
F_SLOWACT, // modifier for action speed F_SLOWACT, // modifier for action speed
F_SLOWMETAB, // hunger counter increases slower, poison cures slower. F_SLOWMETAB, // hunger counter increases slower, poison cures slower.
// v0 is multiplier // v0 is multiplier
@ -4326,6 +4353,7 @@ enum ERROR {
E_CLIMBING, E_CLIMBING,
E_DANGEROUS, E_DANGEROUS,
E_INJURED, E_INJURED,
E_STASIS,
}; };

19
io.c
View File

@ -1201,6 +1201,7 @@ cell_t *real_askcoords(char *prompt, char *subprompt, int targettype, lifeform_t
return NULL; return NULL;
} }
// returns a direction
char askdir(char *prompt, int maycancel, int usedrunk) { char askdir(char *prompt, int maycancel, int usedrunk) {
int dirch,dir = D_NONE; int dirch,dir = D_NONE;
dirch = askchar(prompt, "yuhjklbn.-","-", B_FALSE, maycancel); dirch = askchar(prompt, "yuhjklbn.-","-", B_FALSE, maycancel);
@ -2100,6 +2101,12 @@ int announceflaggain(lifeform_t *lf, flag_t *f) {
msg("%s %s sprinting!",lfname, isplayer(lf) ? "start" : "starts"); msg("%s %s sprinting!",lfname, isplayer(lf) ? "start" : "starts");
donesomething = B_TRUE; donesomething = B_TRUE;
break; break;
case F_STASIS:
if (isplayer(lf)) { // don't know if monsters get it
msg("Time within you warps and slows down!");
donesomething = B_TRUE;
}
break;
case F_STAMBOOST: case F_STAMBOOST:
if (isplayer(lf)) { if (isplayer(lf)) {
msg("^gYour stamina feels boosted!"); msg("^gYour stamina feels boosted!");
@ -2874,6 +2881,12 @@ int announceflagloss(lifeform_t *lf, flag_t *f) {
donesomething = B_TRUE; donesomething = B_TRUE;
} }
break; break;
case F_STASIS:
if (isplayer(lf)) {
msg("Time within you returns to normal.");
donesomething = B_TRUE;
}
break;
case F_STAMBOOST: case F_STAMBOOST:
if (isplayer(lf)) { if (isplayer(lf)) {
msg("Your stamina no longer feels boosted."); msg("Your stamina no longer feels boosted.");
@ -14050,6 +14063,12 @@ void showlfstats(lifeform_t *lf, int showall) {
y++; y++;
} }
f = hasflag_real(lf->flags, F_STASIS, B_TRUE, NULL, FROMRACE);
if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "Time within your body has been frozen.", you(lf));
y++;
}
f = hasflag_real(lf->flags, F_STAMBOOST, B_TRUE, NULL, FROMRACE); f = hasflag_real(lf->flags, F_STAMBOOST, B_TRUE, NULL, FROMRACE);
if (f && (f->known)) { if (f && (f->known)) {
mvwprintw(mainwin, y, 0, "%s stamina is currently being boosted.", your(lf)); mvwprintw(mainwin, y, 0, "%s stamina is currently being boosted.", your(lf));

759
lf.c
View File

@ -2642,6 +2642,9 @@ int check_rest_ok(lifeform_t *lf) {
case E_MONSTERNEARBY: case E_MONSTERNEARBY:
msg("You cannot rest - there are monsters in view!"); msg("You cannot rest - there are monsters in view!");
break; break;
case E_STASIS:
msg("You cannot rest while your body is in stasis.");
break;
default: default:
msg("You cannot rest for some reason."); msg("You cannot rest for some reason.");
break; break;
@ -2766,28 +2769,41 @@ int continuedigging(lifeform_t *lf) {
if (digob) makeopersound(lf->cell,digob); if (digob) makeopersound(lf->cell,digob);
digpower = f->val[2]; digpower = f->val[2];
if (getskill(lf, SK_ENGINEERING) >= PR_SKILLED) {
digpower *= 2;
}
c->hp -= digpower; c->hp -= digpower;
if (c->hp <= 0) { if (c->hp <= 0) {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You finish digging through %s %s.",needan(c->type->name) ? "an" : "a", c->type->name); msg("You finish %s %s %s.",digob ? "digging through" : "dismantling",
needan(c->type->name) ? "an" : "a", c->type->name);
needredraw = B_TRUE; needredraw = B_TRUE;
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("%s finishes digging through %s %s.",lfname,needan(c->type->name) ? "an" : "a", c->type->name); msg("%s finishes %s %s %s.",lfname,
digob ? "digging through" : "dismantling",
needan(c->type->name) ? "an" : "a", c->type->name);
needredraw = B_TRUE; needredraw = B_TRUE;
} }
// replace wall // replace wall
setcelltype(c, c->map->habitat->emptycelltype); //setcelltype(c, c->map->habitat->emptycelltype);
breakwall(c, NULL);
// stop digging // stop digging
killflag(f); killflag(f);
} else { } else {
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You dig into %s %s.",needan(c->type->name) ? "an" : "a", c->type->name); msg("You %s into %s %s.",
digob ? "dig into" : "continue dismantling",
needan(c->type->name) ? "an" : "a", c->type->name);
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("%s digs into %s %s.",lfname,needan(c->type->name) ? "an" : "a", c->type->name); msg("%s %s %s %s.",lfname,
digob ? "digs into" : "continues dismantling",
needan(c->type->name) ? "an" : "a", c->type->name);
} }
} }
return B_FALSE; return B_FALSE;
@ -4356,25 +4372,29 @@ void dumpxp(void) {
} }
} }
int digcell(lifeform_t *lf, cell_t *c, object_t *o) { // pass o OR ot, not both.
int digcell(lifeform_t *lf, cell_t *c, object_t *o, int dismantle) {
char obname[BUFLEN]; char obname[BUFLEN];
flag_t *f; flag_t *f;
int digpower = 1; int digpower = 1;
getobname(o, obname, 1);
f = hasflag(o->flags, F_HELPSDIG);
if (f) {
digpower = f->val[0];
}
if (!c) { if (!c) {
return B_TRUE; return B_TRUE;
} }
if (o) {
f = hasflag(o->flags, F_HELPSDIG);
if (f) {
digpower = f->val[0];
}
getobname(o, obname, 1);
}
if (c->type->solid) { if (c->type->solid) {
turntoface(lf, c); turntoface(lf, c);
if (isdiggable(c)) { if (isdiggable(c, dismantle ? OT_A_DISMANTLE : o->type->id)) {
char digoid[BUFLEN]; char digoid[BUFLEN];
// start digging! // start digging!
if (o) { if (o && !dismantle) {
sprintf(digoid, "%ld",o->id); sprintf(digoid, "%ld",o->id);
} else { } else {
strcpy(digoid,""); strcpy(digoid,"");
@ -4383,20 +4403,31 @@ int digcell(lifeform_t *lf, cell_t *c, object_t *o) {
addflag(lf->flags, F_DIGGING, c->x, c->y, digpower, digoid); addflag(lf->flags, F_DIGGING, c->x, c->y, digpower, digoid);
if (isplayer(lf)) { if (isplayer(lf)) {
msg("You start digging into %s %s.", needan(c->type->name) ? "an" : "a", c->type->name); if (dismantle) {
msg("You start dismantling %s %s.", needan(c->type->name) ? "an" : "a", c->type->name);
} else {
msg("You start digging into %s %s.", needan(c->type->name) ? "an" : "a", c->type->name);
}
needredraw = B_TRUE; needredraw = B_TRUE;
} else if (cansee(player, lf)) { } else if (cansee(player, lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("%s starts digging into %s %s.", lfname, needan(c->type->name) ? "an" : "a", c->type->name); msg("%s starts %s %s %s.", lfname,
dismantle ? "dismantling" : "digging into",
needan(c->type->name) ? "an" : "a", c->type->name);
needredraw = B_TRUE; needredraw = B_TRUE;
} }
taketime(lf, getactspeed(lf)); taketime(lf, getactspeed(lf));
} else { } else {
// fail // fail
if (isplayer(lf)) { if (isplayer(lf)) {
msg("This wall is too hard to dig."); if (dismantle) {
msg("You can only dismantle man-made walls.");
} else {
msg("This wall is too hard to dig.");
}
} }
return B_TRUE;
} }
} else { // not solid } else { // not solid
int failed = B_FALSE; int failed = B_FALSE;
@ -19402,6 +19433,11 @@ int safetorest(lifeform_t *lf) {
lifeform_t *l; lifeform_t *l;
reason = E_OK; reason = E_OK;
if (lfhasflag(lf, F_STASIS)) {
reason = E_STASIS;
return B_FALSE;
}
for (l = lf->cell->map->lf ; l ; l = l->next) { for (l = lf->cell->map->lf ; l ; l = l->next) {
if ((l != lf) && (areenemies(lf, l) || !isknownpeaceful(l) ) && if ((l != lf) && (areenemies(lf, l) || !isknownpeaceful(l) ) &&
!lfhasflag(l, F_HARMLESS) && !lfhasflag(l, F_FEIGNINGDEATH)) { !lfhasflag(l, F_HARMLESS) && !lfhasflag(l, F_FEIGNINGDEATH)) {
@ -21604,7 +21640,7 @@ void startlfturn(lifeform_t *lf) {
enum ERROR error; enum ERROR error;
object_t *o,*nexto; object_t *o,*nexto;
flag_t *f; flag_t *f;
flag_t *asp, *sf; flag_t *asp, *sf,*stasis = NULL;
char buf[BUFLEN]; char buf[BUFLEN];
lifeform_t *l; lifeform_t *l;
int i; int i;
@ -21625,6 +21661,8 @@ void startlfturn(lifeform_t *lf) {
// debugging // debugging
lf->redraws = 0; lf->redraws = 0;
stasis = lfhasflag(lf, F_STASIS);
// more debug // more debug
if (isplayer(lf)) { if (isplayer(lf)) {
if ((gamemode == GM_GAMESTARTED) && (getalignment(lf) != playerorigalignment)) { if ((gamemode == GM_GAMESTARTED) && (getalignment(lf) != playerorigalignment)) {
@ -21765,39 +21803,42 @@ void startlfturn(lifeform_t *lf) {
} }
// drown? if (!stasis) {
o = hasobwithflag(lf->cell->obpile, F_DEEPWATER); // drown?
if (o) { o = hasobwithflag(lf->cell->obpile, F_DEEPWATER);
if (checkfordrowning(lf, o)) { if (o) {
if (isdead(lf)) return; if (checkfordrowning(lf, o)) {
if (isdead(lf)) return;
}
// fixes stench
killtransitoryflags(lf->flags, F_STENCH);
} else {
// amulet of swimming?
if (hasequippedobid(lf->pack, OT_AMU_SWIMMING) && (lf->race->id == R_SWAN) && ispolymorphed(lf)) {
// revert to normal form
abilityeffects(lf, OT_A_POLYREVERT, lf->cell, lf, NULL);
}
} }
// fixes stench
killtransitoryflags(lf->flags, F_STENCH); // suffocate?
} else { if (needstobreath(lf)) {
// amulet of swimming? if (lfhasflag(lf, F_NEEDSWATER) && !hasobwithflag(lf->cell->obpile, F_DEEPWATER)) {
if (hasequippedobid(lf->pack, OT_AMU_SWIMMING) && (lf->race->id == R_SWAN) && ispolymorphed(lf)) { int dam;
// revert to normal form if (isplayer(lf)) {
abilityeffects(lf, OT_A_POLYREVERT, lf->cell, lf, NULL); msg("^BYou are suffocating without water to breath!");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%c%s is suffocating!", getlfcol(lf, CC_VBAD), lfname);
}
dam = lf->maxhp / 3;
limit(&dam, 1, NA);
losehp(lf, dam, DT_DIRECT, NULL, "suffocation");
if (isdead(lf)) return;
}
} }
} }
// suffocate?
if (needstobreath(lf)) {
if (lfhasflag(lf, F_NEEDSWATER) && !hasobwithflag(lf->cell->obpile, F_DEEPWATER)) {
int dam;
if (isplayer(lf)) {
msg("^BYou are suffocating without water to breath!");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%c%s is suffocating!", getlfcol(lf, CC_VBAD), lfname);
}
dam = lf->maxhp / 3;
limit(&dam, 1, NA);
losehp(lf, dam, DT_DIRECT, NULL, "suffocation");
if (isdead(lf)) return;
}
}
// vampire in sunlight? // vampire in sunlight?
if ((lf->race->id == R_VAMPIRE) && isoutdoors(lf->cell->map) && !isnighttime()) { if ((lf->race->id == R_VAMPIRE) && isoutdoors(lf->cell->map) && !isnighttime()) {
if (isplayer(lf)) { if (isplayer(lf)) {
@ -21846,7 +21887,7 @@ void startlfturn(lifeform_t *lf) {
} }
// oooooo replace with f_bleeding ? // oooooo replace with f_bleeding ?
if (lfhasflagval(lf, F_INJURY, IJ_ARTERYPIERCE, NA, NA, NULL)) { if (!stasis && lfhasflagval(lf, F_INJURY, IJ_ARTERYPIERCE, NA, NA, NULL)) {
if (!bleedfrom(lf, BP_HANDS, B_SPLATTER)) { if (!bleedfrom(lf, BP_HANDS, B_SPLATTER)) {
if (isplayer(lf)) msg("^BYou bleed!"); if (isplayer(lf)) msg("^BYou bleed!");
losehp(lf, rnd(2,8), DT_DIRECT, NULL, "blood loss"); losehp(lf, rnd(2,8), DT_DIRECT, NULL, "blood loss");
@ -21854,37 +21895,38 @@ void startlfturn(lifeform_t *lf) {
} }
// get more hungry // get more hungry
modhunger(lf, 1); if (!stasis) {
modhunger(lf, 1);
// regeneration // regeneration
sumflags(lf->flags, F_REGENERATES, &i, NULL, NULL); sumflags(lf->flags, F_REGENERATES, &i, NULL, NULL);
if ((tp == TP_TWILIGHTMORN) || (tp == TP_SUNRISE)) { if ((tp == TP_TWILIGHTMORN) || (tp == TP_SUNRISE)) {
if (isplayer(lf) && godprayedto(R_GODLIFE)) { if (isplayer(lf) && godprayedto(R_GODLIFE)) {
i += 1; i += 1;
}
} }
} if (i > 0) {
if (i > 0) { // heal hp
// heal hp gainhp(lf, i);
gainhp(lf, i);
}
// MP regeneration
getflags(lf->flags, retflag, &nretflags, F_MPREGEN, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (f->id == F_MPREGEN) {
gainmp(lf, f->val[0]);
} }
}
// MP regeneration
getflags(lf->flags, retflag, &nretflags, F_MPREGEN, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if (f->id == F_MPREGEN) {
gainmp(lf, f->val[0]);
}
}
// druid gains mp from plants // druid gains mp from plants
if (hasjob(lf, J_DRUID)) { if (hasjob(lf, J_DRUID)) {
int chance = 0; int chance = 0;
// 5% per plant in sight of gaining mp // 5% per plant in sight of gaining mp
chance = countplantsinsight(lf) * 5; chance = countplantsinsight(lf) * 5;
if (pctchance(chance)) { if (pctchance(chance)) {
gainmp(lf, 1); gainmp(lf, 1);
}
} }
} }
@ -21920,10 +21962,12 @@ void startlfturn(lifeform_t *lf) {
} }
if (lossamt) modstamina(lf, -lossamt); if (lossamt) modstamina(lf, -lossamt);
} else { } else {
// if we didn't take action last turn, regenerate stamina. if (!stasis) {
if (!killflagsofid(lf->flags, F_TOOKACTION) && !lfhasflag(lf, F_TRAINING)) { // if we didn't take action last turn, regenerate stamina.
if (getstamina(lf) < getmaxstamina(lf)) { if (!killflagsofid(lf->flags, F_TOOKACTION) && !lfhasflag(lf, F_TRAINING)) {
modstamina(lf, getstamregen(lf)); if (getstamina(lf) < getmaxstamina(lf)) {
modstamina(lf, getstamregen(lf));
}
} }
} }
} }
@ -22245,51 +22289,53 @@ void startlfturn(lifeform_t *lf) {
} }
} }
// handle life objects if (!stasis) {
f = lfhasflag(lf, F_LIFEOB); // handle life objects
if (f) { f = lfhasflag(lf, F_LIFEOB);
cell_t *corpseloc = NULL; if (f) {
object_t *corpse; cell_t *corpseloc = NULL;
char corpsename[BUFLEN]; object_t *corpse;
char corpsename[BUFLEN];
corpseloc = findnearbylifeob(lf->cell, NA, f, &corpse); corpseloc = findnearbylifeob(lf->cell, NA, f, &corpse);
if (corpse) { if (corpse) {
// did we find a corpse in range ? // did we find a corpse in range ?
if (corpse->type->id == OT_CORPSE) { if (corpse->type->id == OT_CORPSE) {
strcpy(corpsename, "corpse"); strcpy(corpsename, "corpse");
} else { } else {
strcpy(corpsename, corpse->type->name); strcpy(corpsename, corpse->type->name);
}
if (lf->race->id == R_GHOST) {
// give possession ability
if (isplayer(lf) && !lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL)) {
flag_t *f2;
char pwbuf[BUFLEN];
int power;
power = lf->level / 3;
if (power < 1) power = 1;
if (power > 10) power = 10;
snprintf(pwbuf, BUFLEN, "pw:%d;",power);
f2 = addflag(lf->flags, F_CANWILL, OT_S_POSSESSION, NA, NA, pwbuf);
f2->lifetime = FROMRACE;
} }
if (lf->race->id == R_GHOST) {
// give possession ability
if (isplayer(lf) && !lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL)) {
flag_t *f2;
char pwbuf[BUFLEN];
int power;
power = lf->level / 3;
if (power < 1) power = 1;
if (power > 10) power = 10;
snprintf(pwbuf, BUFLEN, "pw:%d;",power);
f2 = addflag(lf->flags, F_CANWILL, OT_S_POSSESSION, NA, NA, pwbuf);
f2->lifetime = FROMRACE;
}
}
} else {
// can't see corpse
if (lf->race->id == R_GHOST) {
flag_t *f2;
f2 = lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL);
if (f2) killflag(f2);
}
// drain life
if (isplayer(lf)) {
msg("^BWithout your %s, you feel yourself fading into nothingness.", corpsename);
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s seems to be fading from view!", lfname);
}
losehp(lf, f->val[2], DT_DIRECT, NULL, "fading into nothingness");
} }
} else {
// can't see corpse
if (lf->race->id == R_GHOST) {
flag_t *f2;
f2 = lfhasflagval(lf, F_CANWILL, OT_S_POSSESSION, NA, NA, NULL);
if (f2) killflag(f2);
}
// drain life
if (isplayer(lf)) {
msg("^BWithout your %s, you feel yourself fading into nothingness.", corpsename);
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("%s seems to be fading from view!", lfname);
}
losehp(lf, f->val[2], DT_DIRECT, NULL, "fading into nothingness");
} }
} }
@ -22549,206 +22595,207 @@ void startlfturn(lifeform_t *lf) {
} }
} }
getflags(lf->flags, retflag, &nretflags, F_POISONED, F_NONE); if (!stasis) {
for (i = 0; i < nretflags; i++) { getflags(lf->flags, retflag, &nretflags, F_POISONED, F_NONE);
poisontype_t *pt; for (i = 0; i < nretflags; i++) {
f = retflag[i]; poisontype_t *pt;
pt = findpoisontype(f->val[0]); f = retflag[i];
// chance of fighting it off - gets easier over time. pt = findpoisontype(f->val[0]);
// // chance of fighting it off - gets easier over time.
if ((f->lifetime > 0) && skillcheck(lf, SC_POISON, (f->lifetime * 20), -(f->val[1]*10) )) { //
killflag(f); if ((f->lifetime > 0) && skillcheck(lf, SC_POISON, (f->lifetime * 20), -(f->val[1]*10) )) {
} else { killflag(f);
flag_t *asleep; } else {
int chance; flag_t *asleep;
int ko; int chance;
// being asleep helps. int ko;
asleep = hasflag(lf->flags, F_ASLEEP); // being asleep helps.
ko = isunconscious(lf); asleep = hasflag(lf->flags, F_ASLEEP);
// chance of losing hp ko = isunconscious(lf);
chance = pt->dampct; // chance of losing hp
if (f->val[1] > 1) { chance = pt->dampct;
//+10% chance per power > 1 if (f->val[1] > 1) {
chance = pctof(100 + ((f->val[1] - 1)*10), chance); //+10% chance per power > 1
} chance = pctof(100 + ((f->val[1] - 1)*10), chance);
if (!ko && pctchance(chance)) {
char buf[BUFLEN];
if (isplayer(lf) || cansee(player, lf)) {
char *p;
char lfname[BUFLEN],lfnameposs[BUFLEN];
getlfname(lf, lfname);
sprintf(lfnameposs, "%s%s",lfname, getpossessive(lfname));
p = strdup(pt->damverb);
if (isplayer(lf)) {
strrep(&p, "YOUR", "Your", NULL);
if (asleep) {
strrep(&p, "YOU", "You wake up and", NULL);
} else {
strrep(&p, "YOU", "You", NULL);
}
strrep(&p, "#S", "", NULL);
} else {
strrep(&p, "YOUR", lfnameposs, NULL);
if (asleep) {
char replacetext[BUFLEN];
sprintf(replacetext, "%s wakes and", lfname);
strrep(&p, "YOU", replacetext, NULL);
} else {
strrep(&p, "YOU", lfname, NULL);
}
strrep(&p, "#S", "s", NULL);
}
msg("%s", p);
free(p);
if (asleep) {
int origborn;
origborn = lf->born;
lf->born = B_FALSE; // supress a second announcement of waking up
killflagsofid(lf->flags, F_ASLEEP);
lf->born = origborn;
} else {
taketime(lf, getactspeed(lf));
}
} }
// special case if (!ko && pctchance(chance)) {
if (pt->id == P_TETANUS) { char buf[BUFLEN];
enum BODYPART bp,poss[MAXBODYPARTS]; if (isplayer(lf) || cansee(player, lf)) {
int nposs = 0; char *p;
for (bp = 0; bp < MAXBODYPARTS; bp++) { char lfname[BUFLEN],lfnameposs[BUFLEN];
int ok;
switch (bp) {
case BP_LEGS:
case BP_HEAD:
case BP_HANDS:
case BP_BODY:
case BP_TAIL:
case BP_WINGS:
ok = B_TRUE;
break;
default:
ok = B_FALSE;
break;
}
if (ok && hasbp(lf, bp)) {
poss[nposs++] = bp;
}
}
if (nposs) {
object_t *oo;
bp = poss[rnd(0,nposs-1)];
switch (bp) {
case BP_LEGS:
injure(lf, bp, DT_BASH, IJ_LEGBROKEN);
break;
case BP_HEAD: break; // no bad effects
case BP_HANDS: // drop your weapon
oo = getequippedob(lf->pack, bp);
if (oo) drop(oo, oo->amt);
break;
case BP_BODY:
if (onein(2)) {
injure(lf, bp, DT_BASH, IJ_RIBCRACKED);
} else {
if (isplayer(lf)) {
msg("^BYour spine snaps!");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%c%s%s spine snaps!", getlfcol(lf, CC_VBAD),
lfname, getpossessive(lfname));
}
losehp_real(lf, lf->maxhp, DT_DIRECT, NULL, "tetanus", B_FALSE, NULL, B_FALSE, NULL, B_FALSE, BP_NONE);
}
break;
case BP_TAIL:
injure(lf, bp, DT_BASH, IJ_TAILBROKEN);
break;
case BP_WINGS:
injure(lf, bp, DT_SLASH, IJ_WINGTORN);
break;
default: break;
}
}
} else {
snprintf(buf, BUFLEN, "%s^from %s",pt->name, f->text);
losehp(lf, pt->dam * f->val[1], DT_DIRECT, NULL, buf);
}
if (pt->vomitob != OT_NONE) {
addobfast(lf->cell->obpile, pt->vomitob);
}
loseconcentration(lf);
}
// extra effects
if (!ko && (f->val[0] == P_COLD)) {
if (rnd(1,100) <= 10) {
object_t *wep;
if (isplayer(lf)) {
msg("^bYou shiver uncontrollably.");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname); getlfname(lf, lfname);
msg("^%c%s shivers.", getlfcol(lf, CC_BAD), lfname); sprintf(lfnameposs, "%s%s",lfname, getpossessive(lfname));
p = strdup(pt->damverb);
if (isplayer(lf)) {
strrep(&p, "YOUR", "Your", NULL);
if (asleep) {
strrep(&p, "YOU", "You wake up and", NULL);
} else {
strrep(&p, "YOU", "You", NULL);
}
strrep(&p, "#S", "", NULL);
} else {
strrep(&p, "YOUR", lfnameposs, NULL);
if (asleep) {
char replacetext[BUFLEN];
sprintf(replacetext, "%s wakes and", lfname);
strrep(&p, "YOU", replacetext, NULL);
} else {
strrep(&p, "YOU", lfname, NULL);
}
strrep(&p, "#S", "s", NULL);
}
msg("%s", p);
free(p);
if (asleep) {
int origborn;
origborn = lf->born;
lf->born = B_FALSE; // supress a second announcement of waking up
killflagsofid(lf->flags, F_ASLEEP);
lf->born = origborn;
} else {
taketime(lf, getactspeed(lf));
}
} }
wep = getweapon(lf);
if (wep) { // special case
char wname[BUFLEN]; if (pt->id == P_TETANUS) {
getobname(wep, wname, 1); enum BODYPART bp,poss[MAXBODYPARTS];
drop(wep, wep->amt); int nposs = 0;
for (bp = 0; bp < MAXBODYPARTS; bp++) {
int ok;
switch (bp) {
case BP_LEGS:
case BP_HEAD:
case BP_HANDS:
case BP_BODY:
case BP_TAIL:
case BP_WINGS:
ok = B_TRUE;
break;
default:
ok = B_FALSE;
break;
}
if (ok && hasbp(lf, bp)) {
poss[nposs++] = bp;
}
}
if (nposs) {
object_t *oo;
bp = poss[rnd(0,nposs-1)];
switch (bp) {
case BP_LEGS:
injure(lf, bp, DT_BASH, IJ_LEGBROKEN);
break;
case BP_HEAD: break; // no bad effects
case BP_HANDS: // drop your weapon
oo = getequippedob(lf->pack, bp);
if (oo) drop(oo, oo->amt);
break;
case BP_BODY:
if (onein(2)) {
injure(lf, bp, DT_BASH, IJ_RIBCRACKED);
} else {
if (isplayer(lf)) {
msg("^BYour spine snaps!");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%c%s%s spine snaps!", getlfcol(lf, CC_VBAD),
lfname, getpossessive(lfname));
}
losehp_real(lf, lf->maxhp, DT_DIRECT, NULL, "tetanus", B_FALSE, NULL, B_FALSE, NULL, B_FALSE, BP_NONE);
}
break;
case BP_TAIL:
injure(lf, bp, DT_BASH, IJ_TAILBROKEN);
break;
case BP_WINGS:
injure(lf, bp, DT_SLASH, IJ_WINGTORN);
break;
default: break;
}
}
} else {
snprintf(buf, BUFLEN, "%s^from %s",pt->name, f->text);
losehp(lf, pt->dam * f->val[1], DT_DIRECT, NULL, buf);
}
if (pt->vomitob != OT_NONE) {
addobfast(lf->cell->obpile, pt->vomitob);
} }
loseconcentration(lf); loseconcentration(lf);
} }
} else if (f->val[0] == P_MIGRAINE) {
// sleeping will avoid all migraine effects // extra effects
if (!asleep && !ko) { if (!ko && (f->val[0] == P_COLD)) {
object_t *lamp = NULL; if (rnd(1,100) <= 10) {
int amt; object_t *wep;
amt = lfproduceslight(lf, &lamp);
if (amt) {
int dam;
// note: amt will be doubled due to light vulnerability,
// so half it here.
dam = amt/2;
limit(&dam, 1, NA);
losehp(lf, dam, DT_LIGHT, NULL, "a migraine");
if (isplayer(lf)) { if (isplayer(lf)) {
char obname[BUFLEN]; msg("^bYou shiver uncontrollably.");
if (lamp) { } else if (cansee(player, lf)) {
getobname(lamp, obname, lamp->amt); char lfname[BUFLEN];
} else { getlfname(lf, lfname);
strcpy(obname, "a body"); // noprefix will strip the 'a ' msg("^%c%s shivers.", getlfcol(lf, CC_BAD), lfname);
}
wep = getweapon(lf);
if (wep) {
char wname[BUFLEN];
getobname(wep, wname, 1);
drop(wep, wep->amt);
}
loseconcentration(lf);
}
} else if (f->val[0] == P_MIGRAINE) {
// sleeping will avoid all migraine effects
if (!asleep && !ko) {
object_t *lamp = NULL;
int amt;
amt = lfproduceslight(lf, &lamp);
if (amt) {
int dam;
// note: amt will be doubled due to light vulnerability,
// so half it here.
dam = amt/2;
limit(&dam, 1, NA);
losehp(lf, dam, DT_LIGHT, NULL, "a migraine");
if (isplayer(lf)) {
char obname[BUFLEN];
if (lamp) {
getobname(lamp, obname, lamp->amt);
} else {
strcpy(obname, "a body"); // noprefix will strip the 'a '
}
msg("Your head explodes in pain at the light from your %s!", noprefix(obname));
} }
msg("Your head explodes in pain at the light from your %s!", noprefix(obname));
} }
} }
} }
} }
} }
}
f = hasflag(lf->flags, F_NAUSEATED);
if (f) {
// chance of being delayed
if (onein(4)) {
if (isplayer(lf)) {
msg("^bYou %s!", rnd(0,1) ? "retch" : "gag");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%c%s %s.", getlfcol(lf, CC_BAD), lfname, rnd(0,1) ? "retches" : "gags");
}
taketime(lf,getactspeed(lf));
f = hasflag(lf->flags, F_NAUSEATED); loseconcentration(lf);
if (f) {
// chance of being delayed
if (onein(4)) {
if (isplayer(lf)) {
msg("^bYou %s!", rnd(0,1) ? "retch" : "gag");
} else if (cansee(player, lf)) {
char lfname[BUFLEN];
getlfname(lf, lfname);
msg("^%c%s %s.", getlfcol(lf, CC_BAD), lfname, rnd(0,1) ? "retches" : "gags");
} }
taketime(lf,getactspeed(lf));
loseconcentration(lf);
} }
} } // end if !statis
if (lfhasflag(lf, F_FROZEN)) { if (lfhasflag(lf, F_FROZEN)) {
int willmelt = B_FALSE; int willmelt = B_FALSE;
@ -22898,27 +22945,29 @@ void startlfturn(lifeform_t *lf) {
} }
} }
f = hasflag(o->flags, F_CAUSESCOUGH); if (!stasis) {
if (f && !isimmuneto(lf->flags, DT_POISONGAS, B_FALSE)) { f = hasflag(o->flags, F_CAUSESCOUGH);
char obname[BUFLEN]; if (f && !isimmuneto(lf->flags, DT_POISONGAS, B_FALSE)) {
getobname(o, obname, o->amt); char obname[BUFLEN];
if (!skillcheck(lf, SC_CON, f->val[0] * o->amt, 0)) { getobname(o, obname, o->amt);
if (isplayer(lf)) { if (!skillcheck(lf, SC_CON, f->val[0] * o->amt, 0)) {
msg("^wYou cough on %s.", obname); if (isplayer(lf)) {
} else if (cansee(player, lf)) { msg("^wYou cough on %s.", obname);
char lfname[BUFLEN]; } else if (cansee(player, lf)) {
getlfname(lf, lfname); char lfname[BUFLEN];
msg("%s coughs on %s.",lfname, obname); getlfname(lf, lfname);
msg("%s coughs on %s.",lfname, obname);
}
taketime(lf, 5);
loseconcentration(lf);
} }
taketime(lf, 5);
loseconcentration(lf);
} }
} f = hasflag(o->flags, F_STENCH);
if (f) {
f = hasflag(o->flags, F_STENCH); makenauseated(lf, f->val[1], 2, NULL);
if (f) { }
makenauseated(lf, f->val[1], 2, NULL);
} }
// for flags which can occur multiple times // for flags which can occur multiple times
@ -23058,31 +23107,33 @@ void startlfturn(lifeform_t *lf) {
} }
} }
if ((f->id == F_INCUBATING) && (f->val[1] > 0)) { if (!stasis) {
f->val[1]--; if ((f->id == F_INCUBATING) && (f->val[1] > 0)) {
if (f->val[1] <= 0) { f->val[1]--;
// note: this functino will kill f if (f->val[1] <= 0) {
completeincubation(lf, f); // note: this functino will kill f
continue; completeincubation(lf, f);
continue;
}
} }
}
// bleeding injuries can stain armour. also mark injuries as no longer new. // bleeding injuries can stain armour. also mark injuries as no longer new.
if ((f->id == F_INJURY) && (f->val[2] == DT_SLASH)) { if ((f->id == F_INJURY) && (f->val[2] == DT_SLASH)) {
object_t *arm; object_t *arm;
if (f->obfrom == B_NEWINJURY) f->obfrom = B_FALSE; if (f->obfrom == B_NEWINJURY) f->obfrom = B_FALSE;
arm = getequippedob(lf->pack, f->val[1]); arm = getequippedob(lf->pack, f->val[1]);
if (arm && !hasobmod(arm, findobmod(OM_BLOODSTAINED)) && pctchance(5)) applyobmod(arm, findobmod(OM_BLOODSTAINED)); if (arm && !hasobmod(arm, findobmod(OM_BLOODSTAINED)) && pctchance(5)) applyobmod(arm, findobmod(OM_BLOODSTAINED));
} }
if (f->id == F_SIZETIMER) { if (f->id == F_SIZETIMER) {
f->val[1]--; f->val[1]--;
if (f->val[1] <= 0) { if (f->val[1] <= 0) {
resizelf(lf, f->val[0], f->val[2]); resizelf(lf, f->val[0], f->val[2]);
// resizelf will have now killed 'f'. // resizelf will have now killed 'f'.
continue; continue;
}
} }
} }
@ -23147,10 +23198,12 @@ void startlfturn(lifeform_t *lf) {
} }
// recharge abilities // recharge abilities
if ((f->id == F_CANWILL) || (f->id == F_CANCAST)) { if (!stasis) {
if (f->val[2] != NA) { if ((f->id == F_CANWILL) || (f->id == F_CANCAST)) {
if (f->val[1] < f->val[2]) { if (f->val[2] != NA) {
f->val[1]++; if (f->val[1] < f->val[2]) {
f->val[1]++;
}
} }
} }
} }
@ -23183,12 +23236,14 @@ void startlfturn(lifeform_t *lf) {
} // end if f_target or f_targetcell } // end if f_target or f_targetcell
// hp drain // hp drain
if (f->id == F_HPDRAIN) { if (!stasis) {
losehp(lf, f->val[0], f->val[1], NULL, f->text); if (f->id == F_HPDRAIN) {
if (isdead(lf)) { losehp(lf, f->val[0], f->val[1], NULL, f->text);
break; if (isdead(lf)) {
} break;
} }
}
}
} // end loop through lf flags } // end loop through lf flags
// picked up your first godstone ? // picked up your first godstone ?

2
lf.h
View File

@ -96,7 +96,7 @@ int countplantsinsight(lifeform_t *lf);
void debug(lifeform_t *lf); void debug(lifeform_t *lf);
int demandbribe(lifeform_t *lf); int demandbribe(lifeform_t *lf);
void die(lifeform_t *lf); void die(lifeform_t *lf);
int digcell(lifeform_t *lf, cell_t *c, object_t *o); int digcell(lifeform_t *lf, cell_t *c, object_t *o, int dismantle);
int digdown(lifeform_t *lf, object_t *o); int digdown(lifeform_t *lf, object_t *o);
int digup(lifeform_t *lf, object_t *o); int digup(lifeform_t *lf, object_t *o);
//void do_eyesight_adjust(lifeform_t *lf); //void do_eyesight_adjust(lifeform_t *lf);

61
map.c
View File

@ -1126,7 +1126,9 @@ void breakwall(cell_t *c, char *why, ...) {
if (origtype->solid && roomwall && onein(2)) { if (origtype->solid && roomwall && onein(2)) {
switch (origtype->material->id) { switch (origtype->material->id) {
case MT_STONE: addob(c->obpile, "1-30 stones"); break; case MT_STONE: addob(c->obpile, "1-30 stones"); break;
case MT_BRICK: addob(c->obpile, "1-30 bricks"); break;
case MT_GLASS: addob(c->obpile, "1-30 pieces of broken glass"); break; case MT_GLASS: addob(c->obpile, "1-30 pieces of broken glass"); break;
case MT_WOOD: addob(c->obpile, "1-30 shards of wood"); break;
default: break; default: break;
} }
} }
@ -3642,14 +3644,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
shape = MS_NORMAL; shape = MS_NORMAL;
} }
// xxxxxxxxxxxxxxxxx
shape = MS_NORMAL;
switch (shape) { switch (shape) {
case MS_NORMAL:// normal case MS_NORMAL:// normal
break; break;
@ -3806,9 +3800,6 @@ void createdungeon(map_t *map, int depth, map_t *parentmap, int exitdir, object_
} }
} }
// xxxxxxxxxxxxxxxxx
shape = CDT_SIMPLE;
// is the map lit? // is the map lit?
if (depth < 5) { if (depth < 5) {
map->illumination = IL_FULLLIT; map->illumination = IL_FULLLIT;
@ -8472,7 +8463,7 @@ void initmap(void) {
// cell types - solid // cell types - solid
// floorheight, hp, volmod, absorbant // floorheight, hp, volmod, absorbant
addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 50, 0, B_NOABSORB); addcelltype(CT_WALL, "rock wall", UNI_SHADEDARK, C_GREY, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 50, 0, B_NOABSORB);
addcelltype(CT_WALLBRICK, "brick wall", UNI_SHADEDARK, C_ORANGE, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 40, 0, B_NOABSORB); addcelltype(CT_WALLBRICK, "brick wall", UNI_SHADEDARK, C_ORANGE, NA, B_SOLID, B_OPAQUE, MT_BRICK, 0, 40, 0, B_NOABSORB);
addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEMED, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 20, 0, B_NOABSORB); addcelltype(CT_WALLDIRT, "dirt wall", UNI_SHADEMED, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_STONE, 0, 20, 0, B_NOABSORB);
addcelltype(CT_WALLDURANITE, "duranite wall", UNI_SHADEDARK, C_MAGENTA, NA, B_SOLID, B_OPAQUE, MT_DURANITE, 0, 20000, 0, B_NOABSORB); addcelltype(CT_WALLDURANITE, "duranite wall", UNI_SHADEDARK, C_MAGENTA, NA, B_SOLID, B_OPAQUE, MT_DURANITE, 0, 20000, 0, B_NOABSORB);
addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30, 0, B_NOABSORB); addcelltype(CT_WALLWOOD, "wooden wall", UNI_SOLID, C_BROWN, NA, B_SOLID, B_OPAQUE, MT_WOOD, 0, 30, 0, B_NOABSORB);
@ -8669,16 +8660,42 @@ int isdark(cell_t *c) {
return B_FALSE; return B_FALSE;
} }
int isdiggable(cell_t *c) { int isdiggable(cell_t *c, enum OBTYPE withwhat) {
switch (c->type->id) { objecttype_t *ot;
case CT_WALLFLESH: ot = findot(withwhat);
case CT_WALLDIRT: if (!ot) {
case CT_WALL: // just check whether the cell material
case CT_WALLWOOD: // is EVER diggable.
case CT_WALLGLASS: switch (c->type->id) {
return B_TRUE; case CT_WALLFLESH:
default: case CT_WALLDIRT:
break; case CT_WALL:
case CT_WALLWOOD:
case CT_WALLGLASS:
return B_TRUE;
default:
break;
}
} else if (ot->id == OT_A_DISMANTLE) {
// using dismantle ability - only mad-made materials.
switch (c->type->material->id) {
case MT_BRICK:
case MT_WOOD:
return B_TRUE;
default: break;
}
} else {
flag_t *retflag[MAXCANDIDATES],*f;
int nretflags,i;
getflags(ot->flags, retflag, &nretflags, F_DIGCELLTYPE, F_DIGCELLMAT, F_NONE);
for (i = 0; i < nretflags; i++) {
f = retflag[i];
if ((f->id == F_DIGCELLTYPE) && (c->type->id == f->val[0])) {
return B_TRUE;
} else if ((f->id == F_DIGCELLMAT) && (c->type->material->id == f->val[0])) {
return B_TRUE;
}
}
} }
return B_FALSE; return B_FALSE;
} }

2
map.h
View File

@ -163,7 +163,7 @@ void initmap(void);
void initmaplayout(void); void initmaplayout(void);
int isadjacent(cell_t *src, cell_t *dst); int isadjacent(cell_t *src, cell_t *dst);
int isdark(cell_t *c); int isdark(cell_t *c);
int isdiggable(cell_t *c); int isdiggable(cell_t *c, enum OBTYPE withwhat);
int isdoor(object_t *o, int *isopen); int isdoor(object_t *o, int *isopen);
int isempty(cell_t *c); int isempty(cell_t *c);
int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph); int isinscanrange(cell_t *c, void **thing, char *desc, glyph_t *glyph);

View File

@ -2220,10 +2220,12 @@ object_t *addobject(obpile_t *where, char *name, int canstack, int dolinks, enum
// for validation purposes // for validation purposes
if (obloc) { if (obloc) {
// containers // containers
if (hasflag(o->flags, F_CONTAINER)) { f = hasflag(o->flags, F_CONTAINER);
if (getoblocation(o)) { if (f && getoblocation(o)) {
givestartobs(NULL, o, o->flags); // randomly generate container contents if required.
} gencontainercontents(o);
givestartobs(NULL, o, o->flags);
} }
// locked? // locked?
@ -4054,6 +4056,66 @@ int gethardness(enum MATERIAL matid) {
return 0; return 0;
} }
void gencontainercontents(object_t *o) {
flag_t *retflag[MAXCANDIDATES],*f;
int nretflags = 0;
race_t *r;
char buf[BUFLEN];
getflags(o->flags, retflag, &nretflags, F_CONTENTS, F_NONE);
if (!nretflags) return;
f = retflag[rnd(0,nretflags-1)];
switch (f->val[0]) {
case CC_AMMO:
addflag(o->flags, F_STARTOB, 50, NA, NA, "1-10 arrows");
addflag(o->flags, F_STARTOB, 50, NA, NA, "1-10 arrows");
addflag(o->flags, F_STARTOB, 50, NA, NA, "1-10 arrows");
addflag(o->flags, F_STARTOB, 50, NA, NA, "1-10 bolts");
addflag(o->flags, F_STARTOB, 50, NA, NA, "1-10 bolts");
addflag(o->flags, F_STARTOB, 50, NA, NA, "1-10 bullets");
addflag(o->flags, F_STARTOB, 50, NA, NA, "1-10 bullets");
break;
case CC_CORPSE:
r = getrandomraceofsize(getobsize(o));
if (r) {
sprintf(buf, "%s corpse", r->name);
addflag(o->flags, F_STARTOB, 100, NA, NA, buf);
}
break;
case CC_CONDIMENTS:
switch (rnd(1,2)) {
default: case 1: sprintf(buf, "pinch of salt"); break;
case 2: sprintf(buf, "lump of sugar"); break;
}
addflag(o->flags, F_STARTOB, 100, 10, 20, buf);
break;
case CC_FOOD:
addflag(o->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(o->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(o->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(o->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(o->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(o->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
break;
case CC_FOODDRINK:
addflag(o->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL);
addflag(o->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL);
addflag(o->flags, F_STARTOBCLASS, 50, OC_POTION, NA, NULL);
addflag(o->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(o->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
addflag(o->flags, F_STARTOBCLASS, 50, OC_FOOD, NA, NULL);
break;
case CC_GUNPOWDER:
addflag(o->flags, F_STARTOB, 100, 5, 20, "pile of gunpowder");
break;
case CC_WATER:
addflag(o->flags, F_STARTOB, 100, NA, NA, "very deep water");
break;
default: break;
}
}
void genhiddennames(void) { void genhiddennames(void) {
objecttype_t *ot; objecttype_t *ot;
flag_t *f; flag_t *f;
@ -4183,7 +4245,6 @@ int getbreakob(object_t *o, char *bigobname, char *smallobname) {
strcpy(bigobname, ""); strcpy(bigobname, "");
strcpy(smallobname, ""); strcpy(smallobname, "");
// flag overrides code below // flag overrides code below
found = 0; found = 0;
getflags(o->flags, retflag, &nretflags, F_BREAKOB, F_NONE); getflags(o->flags, retflag, &nretflags, F_BREAKOB, F_NONE);
@ -5090,6 +5151,7 @@ int getmaterialvalue(enum MATERIAL mat) {
case MT_PLANT: case MT_PLANT:
case MT_ICE: case MT_ICE:
case MT_STONE: case MT_STONE:
case MT_BRICK:
return 1; return 1;
case MT_WATER: case MT_WATER:
return 1; return 1;
@ -5621,7 +5683,7 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
snprintf(dname, BUFLEN, "%s", getdirname(f->val[1])); snprintf(dname, BUFLEN, "%s", getdirname(f->val[1]));
dname[0] = tolower(dname[0]); dname[0] = tolower(dname[0]);
strcat(basename, dname); strcat(basename, dname);
} else { } else { // ie. footprints
char buf[BUFLEN]; char buf[BUFLEN];
enum SKILLLEVEL lorelev; enum SKILLLEVEL lorelev;
// beginner perception and upwards gets depth // beginner perception and upwards gets depth
@ -5646,8 +5708,13 @@ char *real_getobname(object_t *o, char *buf, int count, int wantpremods, int wan
snprintf(buf, BUFLEN, "%s %s",r->name, o->type->name); snprintf(buf, BUFLEN, "%s %s",r->name, o->type->name);
strcat(basename, buf); strcat(basename, buf);
} else if (lorelev >= PR_NOVICE) { } else if (lorelev >= PR_NOVICE) {
// novice - you just get 'animal footprints' etc flag_t *sf;
snprintf(buf, BUFLEN, "%s %s",r->raceclass->name, o->type->name); enum LFSIZE sz = SZ_HUMAN;
// novice - you just get 'small animal footprints' etc
sf = hasflag(r->flags, F_SIZE);
if (sf) sz = sf->val[0];
snprintf(buf, BUFLEN, "%s %s %s",getsizetext(sz),
r->raceclass->name, o->type->name);
strcat(basename, buf); strcat(basename, buf);
} else { } else {
strcat(basename, o->type->name); strcat(basename, o->type->name);
@ -11026,7 +11093,7 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
dir = chartodir(ch); dir = chartodir(ch);
c = getcellindir(lf->cell, dir); c = getcellindir(lf->cell, dir);
if (digcell(lf, c, o)) { if (digcell(lf, c, o, B_FALSE)) {
// failed // failed
return B_TRUE; return B_TRUE;
} }

View File

@ -68,6 +68,7 @@ objecttype_t *findotn(char *name); // find objecttype by name
recipe_t *findrecipefor(enum OBTYPE result); recipe_t *findrecipefor(enum OBTYPE result);
int fountain_will_dryup(object_t *o); int fountain_will_dryup(object_t *o);
void fragments(cell_t *centre, char *what, int speed, int howfar); void fragments(cell_t *centre, char *what, int speed, int howfar);
void gencontainercontents(object_t *o);
void genhiddennames(void); void genhiddennames(void);
enum LFSIZE getarmoursize(object_t *o); enum LFSIZE getarmoursize(object_t *o);
enum RARITY getavgrarity(flagpile_t *fp); enum RARITY getavgrarity(flagpile_t *fp);

126
spell.c
View File

@ -1176,7 +1176,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
objecttype_t *newot = NULL; objecttype_t *newot = NULL;
int numnew = 0; int numnew = 0;
int dir; int dir;
char dirch;
cell_t *c; cell_t *c;
object_t *o; object_t *o;
char obname[BUFLEN]; char obname[BUFLEN];
@ -1197,32 +1196,40 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef
slev = getskill(user, SK_ENGINEERING); slev = getskill(user, SK_ENGINEERING);
dirch = askdir("Dismantle obstacle in which direction (- to cancel)", B_TRUE, B_FALSE); dir = askdir("Dismantle obstacle in which direction (- to cancel)", B_TRUE, B_FALSE);
if (dirch == D_NONE) { if (dir == D_NONE) {
msg("Cancelled."); msg("Cancelled.");
return B_TRUE; return B_TRUE;
} else if (dirch == D_MYSELF) { } else if (dir == D_MYSELF) {
c = user->cell; c = user->cell;
} else {
dir = chartodir(dirch);
} }
c = getcellindir(user->cell, dir); c = getcellindir(user->cell, dir);
// antything there? // antything there?
o = hasobwithflag(c->obpile, F_CLIMBOBSTACLE); o = hasobwithflag(c->obpile, F_CLIMBOBSTACLE);
if (c->type->solid) { if (c->type->solid) {
msg("There is nothing to dismantle there."); if (slev >= PR_ADEPT) {
return B_TRUE; // you can try to dismantle walls. digcell() will
// check whether it is actually diggable.
} else {
msg("There is nothing you can dismantle there.");
return B_TRUE;
}
} else if (!o) { } else if (!o) {
if (slev >= PR_ADEPT) { if (slev >= PR_ADEPT) {
// you can dismantle doors too... // you can dismantle doors too...
o = hasdoor(c); o = hasdoor(c);
} }
if (!o) { if (!o) {
msg("There is nothing to dismantle there."); msg("There is nothing you can dismantle there.");
return B_TRUE; return B_TRUE;
} }
} }
if (!o) {
// ie trying to dismantle a wall
return digcell(user, c, NULL, B_TRUE);
}
// figrue out what to replace it with // figrue out what to replace it with
switch (o->material->id) { switch (o->material->id) {
@ -8501,6 +8508,29 @@ 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_MINDWHIP) {
target = targcell->lf;
if (!target) {
fizzle(caster);
return B_TRUE;
}
if (isplayer(target)) {
msg("^%cA lash of psychic power assaults your mind!",getlfcol(target, CC_BAD));
} else if (isplayer(caster)) {
char lfname[BUFLEN];
getlfname(target, lfname);
msg("^%cYou psycically lash %s%s mind!", getlfcol(target, CC_BAD),
lfname, getpossessive(lfname));
}
if (getattrbracket(getattr(target, A_IQ), A_IQ, NULL) <= AT_VLOW) {
if (isplayer(caster)) {
char tname[BUFLEN];
getlfname(target, tname);
msg("%s is unaffected.", tname);
}
return B_TRUE;
}
losehp(target, rnd(2,6), DT_DIRECT, caster, "a psychic lash");
} else if (spellid == OT_S_MIRRORIMAGE) { } else if (spellid == OT_S_MIRRORIMAGE) {
int i,ndone = 0; int i,ndone = 0;
int seen = B_FALSE; int seen = B_FALSE;
@ -9428,7 +9458,15 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
// now kill the caster! // now kill the caster!
die(caster); die(caster);
} }
} else if (spellid == OT_S_PSIBLAST) { } else if (spellid == OT_S_PRECOGNITION) {
flag_t *f;
// always targetted at caster
targcell = caster->cell;
target = caster;
f = addtempflag(caster->flags, F_EVASION, 5, NA, NA, "precognition", FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_MFEEDBACK) {
int dam,iq; int dam,iq;
enum ATTRBRACKET iqb; enum ATTRBRACKET iqb;
char targetname[BUFLEN]; char targetname[BUFLEN];
@ -9446,7 +9484,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
fizzle(caster); fizzle(caster);
return B_TRUE; return B_TRUE;
} }
dam = rnd(1,(iq/5)); dam = rnd((iq/10),(iq/5));
losehp(target, dam, DT_DIRECT, caster, "a psionic blast"); losehp(target, dam, DT_DIRECT, caster, "a psionic blast");
getlfname(target, targetname); getlfname(target, targetname);
if (isplayer(target)) { if (isplayer(target)) {
@ -9454,6 +9492,31 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} else if (cansee(player, target)) { } else if (cansee(player, target)) {
msg("^%c%s%s brain is blasted!",getlfcol(target, CC_BAD), targetname, getpossessive(targetname)); msg("^%c%s%s brain is blasted!",getlfcol(target, CC_BAD), targetname, getpossessive(targetname));
} }
} else if (spellid == OT_S_PSIBLAST) {
int range;
int x,y;
char buf[BUFLEN];
if (caster && !targcell) targcell = caster->cell;
range = 3;
sprintf(buf, "%s emit%s a blast of psionic power!",castername,isplayer(caster) ? "" : "s");
animradial(targcell, range, '}', C_CYAN, DT_COMPASS, buf, "Something emits a radial blast of psionic power!");
if (isplayer(caster) || haslos(player, targcell)) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
for (y = targcell->y - range ; y <= targcell->y + range; y++) {
for (x = targcell->x - range ; x <= targcell->x + range; x++) {
cell_t *c;
c = getcellat(targcell->map, x,y);
if (c && (getcelldist(targcell, c) <= range)) {
if (c->lf && (c->lf != caster) && haslof(targcell, c, B_FALSE, NULL)) {
stun(c->lf, 4+power);
}
}
}
}
} else if (spellid == OT_S_PSYARMOUR) { } else if (spellid == OT_S_PSYARMOUR) {
flag_t *f; flag_t *f;
// always targetted at caster // always targetted at caster
@ -9848,9 +9911,18 @@ 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_KNOWWEAKNESS) {
flag_t *f;
// always targetted at caster
targcell = caster->cell;
target = caster;
if (isplayer(caster)) {
msg("^gYour mind becomes attuned to your foes' weaknesses!");
}
f = addtempflag(caster->flags, F_EXTRADAM, NA, NA, 2, NULL, FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_LEVITATION) { } else if (spellid == OT_S_LEVITATION) {
flag_t *f; flag_t *f;
// always targetted at caster // always targetted at caster
@ -11469,14 +11541,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
} else if (spellid == OT_S_SLEEP) { } else if (spellid == OT_S_SLEEP) {
int howlong; int howlong;
target = targcell->lf; if (!target) target = targcell->lf;
if (lfhasflag(target, F_ASLEEP) || !cansleep(target)) { if (lfhasflag(target, F_ASLEEP) || !cansleep(target)) {
fizzle(caster); if (!frompot) fizzle(caster);
return B_TRUE; return B_TRUE;
} }
if (isplayer(target)) { if (isplayer(target)) {
msg("A sudden feeling of drowsiness washes over you!"); msg("A sudden feeling of drowsiness washes over you!");
} }
@ -11904,6 +11975,10 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f->text = strdup(dambuf); f->text = strdup(dambuf);
} }
real_fireat(caster, o, 1, targcell, 6, NULL, B_FALSE, OT_S_SPIKEVOLLEY, NULL); real_fireat(caster, o, 1, targcell, 6, NULL, B_FALSE, OT_S_SPIKEVOLLEY, NULL);
} else if (spellid == OT_S_STASIS) {
flag_t *f;
f = addtempflag(caster->flags, F_STASIS, B_TRUE, NA, NA, NULL, FROMSPELL);
f->obfrom = spellid;
} else if (spellid == OT_S_STENCH) { } else if (spellid == OT_S_STENCH) {
int howlong; int howlong;
enum ERROR why; enum ERROR why;
@ -12082,11 +12157,11 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
} }
} else if (spellid == OT_S_STUNMASS) { } else if (spellid == OT_S_SLEEPMASS) {
int i; int i;
int donesomething = B_FALSE; int donesomething = B_FALSE;
target = caster; target = caster;
// stun everyone within los of caster // sleep everyone within los of caster
for (i = 0; i < target->nlos; i++) { for (i = 0; i < target->nlos; i++) {
lifeform_t *thistarg; lifeform_t *thistarg;
@ -12094,17 +12169,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
thistarg = targcell->lf; thistarg = targcell->lf;
if (thistarg && (thistarg != caster)) { if (thistarg && (thistarg != caster)) {
if (lfhasflag(thistarg, F_ASLEEP) || !ischarmable(thistarg)) { if (lfhasflag(thistarg, F_ASLEEP) || !ischarmable(thistarg)) {
fizzle(caster); continue;
return B_TRUE;
}
if (spellresisted(thistarg, caster, spellid, power, seenbyplayer, B_TRUE)) {
} else {
donesomething = B_TRUE;
stun(thistarg, (power/5)+2);
if (isplayer(thistarg) || cansee(player, thistarg)) {
if (seenbyplayer) *seenbyplayer = B_TRUE;
}
} }
// we set frompot to B_TRUE to avoid 'fizzled' messages if there is someone
// unaffected in range.
dospelleffects(caster, OT_S_SLEEP, power+1, thistarg,NULL,NULL,blessed,
seenbyplayer, B_TRUE, NULL);
} }
} }