More godstones:

- [+] amberon: rename to "Purity"
    - [+] make it cure deformities etc ?
    - [+] massive damage to undead ?
- [+] thieves: of vengeance
    - [+] makes all monsters attack themselves
    - [+] steals all weapons from monsters
- [+] mercy: of mercy..
    - [+] acts as ring of miracles (when charged)
- [+] make "mirror image" be a modification spell instead of
      mental ?
- [+] make resize spells target a lf, rather than the caster
- [+] l2 spell alchemy - convert metal object into power% its value in gold!
      (maxpower 5)
    - [+] need wantmaterial in doaskobject
- [+] move ring of miracles check out of losehp().
    - [+] instead, just use the die() one.
- [+] titans have more hit points than gods!!! fix this.
This commit is contained in:
Rob Pearce 2012-02-21 19:45:01 +00:00
parent 067cd92f37
commit 0f914d8819
11 changed files with 231 additions and 108 deletions

View File

@ -446,7 +446,9 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) {
// did we just attack someone by accident? // did we just attack someone by accident?
if (!isplayer(lf) && !areenemies(lf, victim) && (lf->race->raceclass->id == RC_HUMANOID) && if (!isplayer(lf) && !areenemies(lf, victim) && (lf->race->raceclass->id == RC_HUMANOID) &&
(getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) >= A_LOW) ) { (getattrbracket(getattr(lf, A_IQ), A_IQ, NULL) >= A_LOW) ) {
saysorry = B_TRUE; if (lf != victim) {
saysorry = B_TRUE;
}
} }
// announce attacks from behind which aren't backstabs. // announce attacks from behind which aren't backstabs.
@ -862,7 +864,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag)
applylfdammod(&dam[0], lf, wep); applylfdammod(&dam[0], lf, wep);
// modify for size // modify for size
modifyforsize(&dam[0], lf, victim, 5, M_PCT); modifyforsize(&dam[0], lf, victim, 10, M_PCT);
// backstab? // backstab?
if (willbackstab(lf, victim, wep)) { if (willbackstab(lf, victim, wep)) {

63
data.c
View File

@ -2051,7 +2051,31 @@ void initobjects(void) {
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, RR_VERYRARE, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, RR_VERYRARE, NULL);
// godstones // godstones
addot(OT_GODSTONEJ, "Godstone of Justice", "An ancient artifact representing the power of justice.", MT_STONE, 3, OC_GODSTONE, SZ_SMALL); addot(OT_GODSTONE_DESTRUCTION, "Godstone of Destruction", "An ancient artifact representing the power of anger.", MT_STONE, 3, OC_GODSTONE, SZ_SMALL);
addflag(lastot->flags, F_GLYPH, C_RED, '*', NA, NULL);
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
addflag(lastot->flags, F_CHARGES, 100, 100, NA, NULL);
addflag(lastot->flags, F_RECHARGE, 1, NA, NA, NULL);
addflag(lastot->flags, F_AIHEALITEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LINKGOD, R_GODFIRE, NA, NA, NULL);
addot(OT_GODSTONE_LIFE, "Godstone of Life", "An ancient artifact representing the power of Life and Healing.", MT_STONE, 3, OC_GODSTONE, SZ_SMALL);
addflag(lastot->flags, F_GLYPH, C_WHITE, '*', NA, NULL);
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
addflag(lastot->flags, F_CHARGES, 100, 100, NA, NULL);
addflag(lastot->flags, F_RECHARGE, 1, NA, NA, NULL);
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LINKGOD, R_GODLIFE, NA, NA, NULL);
addot(OT_GODSTONE_MERCY, "Godstone of Mercy", "An ancient artifact representing the power of Mercy and Forgiveness.", MT_STONE, 3, OC_GODSTONE, SZ_SMALL);
addflag(lastot->flags, F_GLYPH, C_GREEN, '*', NA, NULL);
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
addflag(lastot->flags, F_CHARGES, 100, 100, NA, NULL);
addflag(lastot->flags, F_RECHARGE, 1, NA, NA, NULL);
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LINKGOD, R_GODMERCY, NA, NA, NULL);
addot(OT_GODSTONE_PURITY, "Godstone of Purity", "An ancient artifact representing the power of Purity and Order.", MT_STONE, 3, OC_GODSTONE, SZ_SMALL);
addflag(lastot->flags, F_GLYPH, C_MAGENTA, '*', NA, NULL); addflag(lastot->flags, F_GLYPH, C_MAGENTA, '*', NA, NULL);
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
addflag(lastot->flags, F_CHARGES, 100, 100, NA, NULL); addflag(lastot->flags, F_CHARGES, 100, 100, NA, NULL);
@ -2060,23 +2084,16 @@ void initobjects(void) {
addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LINKGOD, R_GODPURITY, NA, NA, NULL); addflag(lastot->flags, F_LINKGOD, R_GODPURITY, NA, NA, NULL);
addot(OT_GODSTONER, "Godstone of Rage", "An ancient artifact representing the power of anger.", MT_STONE, 3, OC_GODSTONE, SZ_SMALL);
addflag(lastot->flags, F_GLYPH, C_RED, '*', NA, NULL);
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
addflag(lastot->flags, F_CHARGES, 100, 100, NA, NULL);
addflag(lastot->flags, F_RECHARGE, 1, NA, NA, NULL);
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LINKGOD, R_GODFIRE, NA, NA, NULL);
addot(OT_GODSTONEL, "Godstone of Life", "An ancient artifact representing the power of life.", MT_STONE, 3, OC_GODSTONE, SZ_SMALL);
addflag(lastot->flags, F_GLYPH, C_WHITE, '*', NA, NULL); addot(OT_GODSTONE_REVENGE, "Godstone of Revenge", "An ancient artifact representing the power of Revenge and Thievery.", MT_STONE, 3, OC_GODSTONE, SZ_SMALL);
addflag(lastot->flags, F_GLYPH, C_BLUE, '*', NA, NULL);
addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL);
addflag(lastot->flags, F_CHARGES, 100, 100, NA, NULL); addflag(lastot->flags, F_CHARGES, 100, 100, NA, NULL);
addflag(lastot->flags, F_RECHARGE, 1, NA, NA, NULL); addflag(lastot->flags, F_RECHARGE, 1, NA, NA, NULL);
addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_AIBOOSTITEM, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL); addflag(lastot->flags, F_REPLENISHABLE, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LINKGOD, R_GODLIFE, NA, NA, NULL); addflag(lastot->flags, F_LINKGOD, R_GODTHIEVES, NA, NA, NULL);
// flora // flora
addot(OT_FLOWER, "flower", "A colourful woodland flower.", MT_PLANT, 0.01, OC_FLORA, SZ_TINY); addot(OT_FLOWER, "flower", "A colourful woodland flower.", MT_PLANT, 0.01, OC_FLORA, SZ_TINY);
@ -2574,7 +2591,7 @@ void initobjects(void) {
addflag(lastot->flags, F_VALUE, 400, NA, NA, NULL); addflag(lastot->flags, F_VALUE, 400, NA, NA, NULL);
addflag(lastot->flags, F_RARITY, H_ALL, 50, RR_RARE, NULL); addflag(lastot->flags, F_RARITY, H_ALL, 50, RR_RARE, NULL);
addot(OT_SCR_REPLENISHMENT, "scroll of replenishment", "Restores a random amount of charges to a wand.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL); addot(OT_SCR_REPLENISHMENT, "scroll of replenishment", "Restores a random amount of charges to an object.", MT_PAPER, 0.5, OC_SCROLL, SZ_SMALL);
addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL); addflag(lastot->flags, F_RARITY, H_ALL, NA, RR_UNCOMMON, NULL);
addflag(lastot->flags, F_SCROLLNEEDSOB, B_ALWAYS, NA, NA, NULL); addflag(lastot->flags, F_SCROLLNEEDSOB, B_ALWAYS, NA, NA, NULL);
addflag(lastot->flags, F_LINKSPELL, OT_S_REPLENISH, NA, NA, NULL); addflag(lastot->flags, F_LINKSPELL, OT_S_REPLENISH, NA, NA, NULL);
@ -3613,12 +3630,6 @@ 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_MIRRORIMAGE, "mirror image", "Creates ^bpower^n illusionary clones of the caster to distract enemies. These clones cannot deal damage, and vanish when hit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many clones are created, and how many hits they can sustain.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
// l3 // l3
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.");
@ -3709,14 +3720,22 @@ void initobjects(void) {
addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, 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);
// l2 // l2
addot(OT_S_SIZEUP, "unnatural growth", "Causes the caster's body to grow in size.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SIZEUP, "unnatural growth", "Causes the target's body to grow in size. They will become easier to hit, but deal less damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, 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_MAXPOWER, 1, NA, NA, NULL);
addot(OT_S_SIZEDOWN, "unnatural shrinkage", "Causes the caster's body to shrink in size.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_SIZEDOWN, "unnatural shrinkage", "Causes the target's body to shrink in size. They will deal less damage, but become harder to hit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, 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_MAXPOWER, 1, NA, NA, NULL);
addot(OT_S_MIRRORIMAGE, "mirror image", "Creates ^bpower^n illusionary clones of the caster to distract enemies. These clones cannot deal damage, and vanish when hit.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how many clones are created, and how many hits they can sustain.");
addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL);
addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL);
addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL);
addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL);
addot(OT_S_DARKNESS, "darkness", "Permenantly darkens the area around the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addot(OT_S_DARKNESS, "darkness", "Permenantly darkens the area around the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY);
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power III, you can control where the darkness appears."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power III, you can control where the darkness appears.");
addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power VIII, the darkness becomes permenant."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power VIII, the darkness becomes permenant.");
@ -8579,7 +8598,7 @@ void initrace(void) {
addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL); addflag(lastrace->flags, F_RARITY, H_DUNGEON, NA, RR_VERYRARE, NULL);
addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL);
addflag(lastrace->flags, F_SIZE, SZ_ENORMOUS, NA, NA, NULL); addflag(lastrace->flags, F_SIZE, SZ_ENORMOUS, NA, NA, NULL);
addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "49d4"); addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "24d4");
addflag(lastrace->flags, F_ARMOURRATING, 20, NA, NA, NULL); addflag(lastrace->flags, F_ARMOURRATING, 20, NA, NA, NULL);
addflag(lastrace->flags, F_EVASION, -30, NA, NA, NULL); addflag(lastrace->flags, F_EVASION, -30, NA, NA, NULL);
addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL);

View File

@ -23,7 +23,7 @@ c:ob:lit candelabrum
A:ob:good armour A:ob:good armour
W:ob:good weapon W:ob:good weapon
_:ob:pentagram _:ob:pentagram
_:ob:Godstone of Rage _:ob:Godstone of Destruction
C:ob:chest C:ob:chest
@end @end

View File

@ -24,7 +24,7 @@ c:ob:lit candelabrum
A:ob:good armour A:ob:good armour
W:ob:good weapon W:ob:good weapon
_:ob:pentagram _:ob:pentagram
_:ob:Godstone of Rage _:ob:Godstone of Destruction
C:ob:chest C:ob:chest
@end @end

View File

@ -14,7 +14,7 @@
#:cell:metal wall #:cell:metal wall
+:ob:locked iron door +:ob:locked iron door
+:exit +:exit
g:ob:Godstone of Justice g:ob:Godstone of Purity
^:ob:gas trap ^:ob:gas trap
c:ob:candelabrum c:ob:candelabrum
m:ob:landmine trap m:ob:landmine trap

8
defs.h
View File

@ -1241,9 +1241,11 @@ enum OBTYPE {
// money // money
OT_GOLD, OT_GOLD,
// godstones // godstones
OT_GODSTONEJ, OT_GODSTONE_DESTRUCTION,
OT_GODSTONEL, OT_GODSTONE_LIFE,
OT_GODSTONER, OT_GODSTONE_MERCY,
OT_GODSTONE_PURITY,
OT_GODSTONE_REVENGE,
// flora // flora
OT_FLOWER, OT_FLOWER,
OT_LEAF, OT_LEAF,

38
god.c
View File

@ -1422,7 +1422,7 @@ void godstone_pickup_effects(lifeform_t *god, lifeform_t *opposegod, object_t *o
wprintw(mainwin, "my possession can we be sure of its safety.\n\n"); wprintw(mainwin, "my possession can we be sure of its safety.\n\n");
wprintw(mainwin, "Your first waypoint is the portal atop the dungeon. This will\n"); wprintw(mainwin, "Your first waypoint is the portal atop the dungeon. This will\n");
wprintw(mainwin, "to the Realm of Gods, where both of your objectives can be\n"); wprintw(mainwin, "to the Realm of Gods, where both of your objectives can be\n");
wprintw(mainwin, "achieved.\""); wprintw(mainwin, "achieved.\"\n");
break; break;
case R_GODDEATH: case R_GODDEATH:
wprintw(mainwin, "\"Heh, heh, heh.\n\n"); wprintw(mainwin, "\"Heh, heh, heh.\n\n");
@ -1463,7 +1463,7 @@ void godstone_pickup_effects(lifeform_t *god, lifeform_t *opposegod, object_t *o
wprintw(mainwin, "the stone should at least grant you a slim chance of survival.\n"); wprintw(mainwin, "the stone should at least grant you a slim chance of survival.\n");
wprintw(mainwin, "It might even be powerful enough for you to triumph...\n\n"); wprintw(mainwin, "It might even be powerful enough for you to triumph...\n\n");
wprintw(mainwin, "But let us not dwell on that. Find the portal to my realm on\n"); wprintw(mainwin, "But let us not dwell on that. Find the portal to my realm on\n");
wprintw(mainwin, "the surface, and take the first step towards eternal life!\""); wprintw(mainwin, "the surface, and take the first step towards eternal life!\"\n");
break; break;
case R_GODMAGIC: case R_GODMAGIC:
wprintw(mainwin, "\"One has made a monumental discovery!\n\n"); wprintw(mainwin, "\"One has made a monumental discovery!\n\n");
@ -1484,22 +1484,20 @@ void godstone_pickup_effects(lifeform_t *god, lifeform_t *opposegod, object_t *o
case R_GODMERCY: case R_GODMERCY:
wprintw(mainwin, "\"HALT! By touching the Godstone of Vengeance, you have commited a\n"); wprintw(mainwin, "\"HALT! By touching the Godstone of Vengeance, you have commited a\n");
wprintw(mainwin, "unspeakable sin! By rights your action should condemn you for\n"); wprintw(mainwin, "unspeakable sin! By rights your action should condemn you for\n");
wprintw(mainwin, "eternity. However...\"\n"); wprintw(mainwin, "eternity. However...\"\n\n");
wprintw(mainwin, "Yumi's grave expression softens.\n"); wprintw(mainwin, "Yumi's grave expression softens.\n\n");
wprintw(mainwin, "\"I embody mercy, and all sins can be forgiven. In this case, the\n"); wprintw(mainwin, "\"I embody mercy, and all sins can be forgiven. In this case, the road\n");
wprintw(mainwin, "road to your redemption is tied with the deed itself.\n\n"); wprintw(mainwin, "to your redemption is tied with the deed itself. Bring the stone to me.\n");
wprintw(mainwin, "Bring the stone to me. Perform this penance and not only will you\n"); wprintw(mainwin, "Perform this penance and not only will you be forgiven, but you will ensure\n");
wprintw(mainwin, "be forgiven, but you will ensure that your mistake is never again\n"); wprintw(mainwin, "that your mistake is never again repeated for all eternity. The God of\n");
wprintw(mainwin, "repeated for all eternity. The God of Revenge will be neutralised,"); wprintw(mainwin, "Revenge will be neutralised, his influence ended.\n\n");
wprintw(mainwin, "his influence ended.\n\n"); wprintw(mainwin, "Mercy however, extends even to the divine. I would not doom Felix to a\n");
wprintw(mainwin, "Mercy however, extends even to the divine. I would not doom Felix\n"); wprintw(mainwin, "life of misery, his very essence ripped away. Should you possess the\n");
wprintw(mainwin, "to a life of misery, his very essence ripped away. Should you\n"); wprintw(mainwin, "power, the Godstone could be used to grant Felix the peaceful sleep\n");
wprintw(mainwin, "possess the power, the Godstone would be used to grant Felix the\n"); wprintw(mainwin, "of death. For a tormented soul such as his, this would truly be a mercy.\n\n");
wprintw(mainwin, "peaceful sleep of death. For a tormented soul such as his, this\n"); wprintw(mainwin, "Either way, your atonement begins now. Travel up to the surface, and enter\n");
wprintw(mainwin, "would truly be a mercy.\n\n"); wprintw(mainwin, "the magic portal. Complete your task in the Realm of Gods and all will be\n");
wprintw(mainwin, "Either way, your atonement begins now. Travel up to the surface,\n"); wprintw(mainwin, "forgiven.\"\n");
wprintw(mainwin, "and enter the magic portal. Once you arrive in the Realm of Gods\n");
wprintw(mainwin, "and complete your task, all will be forgiven.\"");
break; break;
case R_GODNATURE: case R_GODNATURE:
wprintw(mainwin, "\"%s! You hold the Godstone of Rage!\n\n", toupper(player->race->name[0]), (player->race->name + 1)); wprintw(mainwin, "\"%s! You hold the Godstone of Rage!\n\n", toupper(player->race->name[0]), (player->race->name + 1));
@ -1525,7 +1523,7 @@ void godstone_pickup_effects(lifeform_t *god, lifeform_t *opposegod, object_t *o
wprintw(mainwin, "Of course you don't need to bother with all that. Just bring the stone\n"); wprintw(mainwin, "Of course you don't need to bother with all that. Just bring the stone\n");
wprintw(mainwin, "to me and I'll do the rest. There's a portal up on the surface, all\n"); wprintw(mainwin, "to me and I'll do the rest. There's a portal up on the surface, all\n");
wprintw(mainwin, "you need to do is step through, track me down, and hand over that little\n"); wprintw(mainwin, "you need to do is step through, track me down, and hand over that little\n");
wprintw(mainwin, "trinket. Piece of cake!\""); wprintw(mainwin, "trinket. Piece of cake!\"\n");
break; break;
case R_GODPURITY: case R_GODPURITY:
wprintw(mainwin, "\"Mortal! You hold an ancient artifact of immense power!\n"); wprintw(mainwin, "\"Mortal! You hold an ancient artifact of immense power!\n");
@ -1539,7 +1537,7 @@ void godstone_pickup_effects(lifeform_t *god, lifeform_t *opposegod, object_t *o
wprintw(mainwin, "for him to be confronted directly.\n\n"); wprintw(mainwin, "for him to be confronted directly.\n\n");
wprintw(mainwin, "Travel to the Realm of Gods mortal, and come to me with the\n"); wprintw(mainwin, "Travel to the Realm of Gods mortal, and come to me with the\n");
wprintw(mainwin, "stone. If you find and destroy the Chaos god on the way, all"); wprintw(mainwin, "stone. If you find and destroy the Chaos god on the way, all");
wprintw(mainwin, "the better. Chaos and impurity MUST be ended!\""); wprintw(mainwin, "the better. Chaos and impurity MUST be ended!\"\n");
break; break;
default: default:
break; break;

38
lf.c
View File

@ -13343,12 +13343,14 @@ int losehp_real(lifeform_t *lf, int amt, enum DAMTYPE damtype, lifeform_t *froml
} }
/*
// large damage will be stopped by a ring of miracles // large damage will be stopped by a ring of miracles
if ((amt >= (lf->maxhp / 2)) && (amt >= 20)) { if ((amt >= (lf->maxhp / 2)) && (amt >= 20)) {
if (useringofmiracles(lf, 1)) { if (useringofmiracles(lf, 1)) {
return 0; return 0;
} }
} }
*/
// occasionally drop blood // occasionally drop blood
if (damtypecausesbleed(damtype) && onein(3)) { if (damtypecausesbleed(damtype) && onein(3)) {
@ -19504,8 +19506,8 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) {
return B_FALSE; return B_FALSE;
} }
// use a ring of miracles if we have one, and drain 'charges' // use a ring of miracles (or godstone of mercy) if we have one, and drain 'charges'
// charges from it. if expired, it will vanish. // charges from it. if expired, ring of miracles will vanish.
// returns B_TRUE if we found one. // returns B_TRUE if we found one.
int useringofmiracles(lifeform_t *lf, int charges) { int useringofmiracles(lifeform_t *lf, int charges) {
object_t *o; object_t *o;
@ -19517,23 +19519,37 @@ int useringofmiracles(lifeform_t *lf, int charges) {
getlfname(lf, lfname); getlfname(lf, lfname);
for (o = lf->pack->first ; o ; o = o->next) { for (o = lf->pack->first ; o ; o = o->next) {
if ( (o->type->id == OT_RING_MIRACLES) && int doit = B_FALSE;
isequipped(o) && // use ring of miracles first
getcharges(o) ) { if ( (o->type->id == OT_RING_MIRACLES) && isequipped(o) && getcharges(o) ) {
doit = B_TRUE;
} else if ((o->type->id == OT_GODSTONE_MERCY) && isfullycharged(o)) {
doit = B_TRUE;
}
if (doit) {
char obname[BUFLEN]; char obname[BUFLEN];
getobname(o, obname, 1); getobname(o, obname, 1);
if (isplayer(lf) || cansee(player, lf)) { if (isplayer(lf) || cansee(player, lf)) {
msg("%s%s %s flashes!", lfname, getpossessive(lfname), noprefix(obname)); if (o->type->id == OT_RING_MIRACLES) {
msg("%s%s %s flashes!", lfname, getpossessive(lfname), noprefix(obname));
} else {
msg("%s flashes!", obname);
}
} }
// you know know the obejct
makeknown(o->type->id);
// use a charge // use a charge
if (usecharge(o) <= 0) { if (o->type->id == OT_RING_MIRACLES) {
if (isplayer(lf) || cansee(player, lf)) { if (usecharge(o) <= 0) {
msg("%s%s %s crumbles to dust.", lfname, getpossessive(lfname), noprefix(obname)); if (isplayer(lf) || cansee(player, lf)) {
msg("%s%s %s crumbles to dust.", lfname, getpossessive(lfname), noprefix(obname));
}
removeob(o, ALL);
} }
removeob(o, ALL); } else { // ie. godstone
usecharges(o, getcharges(o));
} }
makeknown(OT_RING_MIRACLES);
return B_TRUE; return B_TRUE;
} }
} }

166
objects.c
View File

@ -6847,6 +6847,15 @@ int isflammable(object_t *o) {
return B_FALSE; return B_FALSE;
} }
int isfullycharged(object_t *o) {
flag_t *f;
f = hasflag(o->flags, F_CHARGES);
if (f && (f->val[0] == f->val[1])) {
return B_TRUE;
}
return B_FALSE;
}
// returns amt of damage to do if touched while hot. // returns amt of damage to do if touched while hot.
int isheatable(object_t *o) { int isheatable(object_t *o) {
if (hasflag(o->flags, F_WET)) { if (hasflag(o->flags, F_WET)) {
@ -9069,9 +9078,8 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
noise(where, NULL, NC_OTHER, SV_WHISPER, "something burning.", NULL); noise(where, NULL, NC_OTHER, SV_WHISPER, "something burning.", NULL);
} }
} else if (o->type->obclass->id == OC_GODSTONE) { } else if (o->type->obclass->id == OC_GODSTONE) {
f = hasflag(o->flags, F_CHARGES); if (isfullycharged(o)) {
if (f && (f->val[0] == f->val[1])) { int i;
int x,y;
// announce // announce
if (isplayer(lf)){ if (isplayer(lf)){
msg("Your %s unleashes a blast of power!", noprefix(obname)); msg("Your %s unleashes a blast of power!", noprefix(obname));
@ -9082,8 +9090,9 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
} }
noise(lf->cell, NULL, NC_OTHER, 10, "an ear-splitting crack", NULL); noise(lf->cell, NULL, NC_OTHER, 10, "an ear-splitting crack", NULL);
switch (o->type->id) { switch (o->type->id) {
case OT_GODSTONEJ: // justice case OT_GODSTONE_PURITY:
// everyone in lof drops to same hp as user // everyone in lof drops to same hp as user
/*
for (y = 0; y < lf->cell->map->h; y++) { for (y = 0; y < lf->cell->map->h; y++) {
for (x = 0; x < lf->cell->map->w; x++) { for (x = 0; x < lf->cell->map->w; x++) {
cell_t *c; cell_t *c;
@ -9091,58 +9100,122 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
if (c && c->lf && (c->lf != lf) && haslof(lf->cell, c, LOF_NEED, NULL)) { if (c && c->lf && (c->lf != lf) && haslof(lf->cell, c, LOF_NEED, NULL)) {
c->lf->hp = lf->hp; c->lf->hp = lf->hp;
if (isplayer(c->lf)) { if (isplayer(c->lf)) {
msg("You are blasted with the power of justice!"); msg("You are blasted with the power of Purity!");
} else if (cansee(player, c->lf)) { } else if (cansee(player, c->lf)) {
char lfname[BUFLEN]; char lfname[BUFLEN];
getlfname(c->lf, lfname); getlfname(c->lf, lfname);
msg("%s is blasted with the power of justice!", lfname); msg("%s is blasted with the power of Purity!", lfname);
} }
} }
} }
} }
*/
for (i = 0; i < lf->cell->map->w * lf->cell->map->h; i++) {
cell_t *c;
c = lf->cell->map->cell[i];
if (c->lf && haslof(lf->cell, c, LOF_WALLSTOP, NULL)) {
// announce
if (isplayer(c->lf)) {
msg("You are blasted with the power of Purity!");
} else if (cansee(player, c->lf)) {
char lfname[BUFLEN];
getlfname(c->lf, lfname);
msg("%s is blasted with the power of Purity!", lfname);
}
// revert polymorphs
if (lfhasflag(c->lf, F_ORIGRACE)) {
dospelleffects(NULL, OT_A_POLYREVERT, 1,
c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE);
}
// fix injuries ("deformities")
killflagsofid(c->lf->flags, F_INJURY);
// destroy undead
if (isundead(c->lf)) {
losehp(c->lf, 50, DT_DIRECT, lf, "the Godstone of Purity");
}
}
}
break; break;
case OT_GODSTONER: // rage case OT_GODSTONE_DESTRUCTION: // rage
// everyone in lof gets f_rage, and hates everything // everyone in lof gets f_rage, and hates everything
for (y = 0; y < lf->cell->map->h; y++) { for (i = 0; i < lf->cell->map->w * lf->cell->map->h; i++) {
for (x = 0; x < lf->cell->map->w; x++) { cell_t *c;
cell_t *c; c = lf->cell->map->cell[i];
c = getcellat(lf->cell->map, x, y); if (c->lf && (c->lf != lf) && haslof(lf->cell, c, LOF_WALLSTOP, NULL)) {
if (c && c->lf && (c->lf != lf) && haslof(lf->cell, c, LOF_NEED, NULL)) { int howlong = 50;
int howlong = 50; // create fire
// create fire addobfast(c->obpile, OT_FIRELARGE);
addobfast(c->obpile, OT_FIRELARGE); // enrage
// enrage addtempflag(c->lf->flags, F_RAGE, B_TRUE, NA, NA, NULL, howlong);
addtempflag(c->lf->flags, F_RAGE, B_TRUE, NA, NA, NULL, howlong); if (!isplayer(c->lf)) {
if (!isplayer(c->lf)) { addtempflag(c->lf->flags, F_HATESALL, B_TRUE, NA, NA, NULL, howlong);
addtempflag(c->lf->flags, F_HATESALL, B_TRUE, NA, NA, NULL, howlong); loseaitargets(c->lf);
loseaitargets(c->lf);
}
} }
} }
} }
break; break;
case OT_GODSTONEL: // life case OT_GODSTONE_LIFE: // life
// everything in sight is restored // everything in sight is restored
// all corpses in sight are revived // all corpses in sight are revived
// everyone in lof gets f_rage, and hates everything // everyone in lof gets f_rage, and hates everything
for (y = 0; y < lf->cell->map->h; y++) { for (i = 0; i < lf->cell->map->w * lf->cell->map->h; i++) {
for (x = 0; x < lf->cell->map->w; x++) { cell_t *c;
cell_t *c; c = lf->cell->map->cell[i];
c = getcellat(lf->cell->map, x, y); if (haslof(lf->cell, c, LOF_WALLSTOP, NULL)) {
if (c && haslof(lf->cell, c, LOF_NEED, NULL)) { if (c->lf) {
if (c->lf) { // restore
// restore dospelleffects(NULL, OT_S_RESTORATION, 1,
dospelleffects(NULL, OT_S_RESTORATION, 1, c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE);
c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE); } else {
} else { object_t *oo, *nextoo;
object_t *oo, *nextoo; // revive corpses
// revive corpses for (oo = c->obpile->first ; oo ; oo = nextoo) {
for (oo = c->obpile->first ; oo ; oo = nextoo) { nextoo = oo->next;
nextoo = oo->next; if (oo->type->id == OT_CORPSE) {
if (oo->type->id == OT_CORPSE) { dospelleffects(NULL, OT_S_RESSURECTION, 1,
dospelleffects(NULL, OT_S_RESSURECTION, 1, NULL, oo, c, B_BLESSED, NULL, B_TRUE);
NULL, oo, c, B_BLESSED, NULL, B_TRUE); }
} }
}
}
}
break;
case OT_GODSTONE_REVENGE:
// everyone's objects appear underneath you
// everyone else attacks themself
for (i = 0; i < lf->cell->map->w * lf->cell->map->h; i++) {
cell_t *c;
char lfname[BUFLEN],othername[BUFLEN];
getlfname(lf, lfname);
c = lf->cell->map->cell[i];
if (c->lf && (c->lf != lf) && haslof(lf->cell, c, LOF_WALLSTOP, NULL)) {
object_t *oo, *nextoo;
// they get an injury
dospelleffects(NULL, OT_S_FLAYFLESH, 1, c->lf, NULL, c, B_BLESSED, NULL, B_TRUE);
// they attack themself.
attackcell(c->lf, c, B_TRUE);
// then all their objects appear under you
if (isplayer(c->lf)) {
msg("All your objects appear at %s%s feet!", lfname,
getpossessive(lfname));
} else if (cansee(player, c->lf)) {
getlfname(c->lf, othername);
msg("All %s%s objects appear at %s%s feet!", othername,
getpossessive(othername),
lfname, getpossessive(lfname));
}
for (oo = c->lf->pack->first ; oo ; oo = nextoo) {
cell_t *where;
nextoo = oo->next;
where = lf->cell;
if (!moveob(oo, where->obpile, ALL) ){
// try somewhere nearby
where = getrandomadjcell(where, WE_WALKABLE, B_NOEXPAND);
if (where) {
moveob(oo, where->obpile, ALL);
} }
} }
} }
@ -9152,7 +9225,8 @@ int operate(lifeform_t *lf, object_t *o, cell_t *where) {
default: default:
break; break;
} }
f->val[0] = 0; // use up all charges // use up all charges
usecharges(o, getcharges(o));
} else { } else {
if (isplayer(lf)) { if (isplayer(lf)) {
nothinghappens(); nothinghappens();
@ -13220,8 +13294,14 @@ void timeeffectsob(object_t *o) {
} else { } else {
// if it hasn't been extinguished, the object burns // if it hasn't been extinguished, the object burns
if (f->id == F_ONFIRE) { if (f->id == F_ONFIRE) {
takedamage(o, 2, DT_FIRE); // TODO: don't hardcode if (isweapon(o) && isequipped(o)) {
if (hasflag(o->flags, F_DEAD)) return; // don't deal damage for flaming equipped weapons. if we do,
// it will make them hot, and then they'll get dropped. the idea
// with weapons is that only the blade is on fire.
} else {
takedamage(o, 2, DT_FIRE); // TODO: don't hardcode
if (hasflag(o->flags, F_DEAD)) return;
}
} }
} }
} }

View File

@ -190,6 +190,7 @@ flag_t *isequipped(object_t *o);
int isequippedon(object_t *o, enum BODYPART bp); int isequippedon(object_t *o, enum BODYPART bp);
int isfirearm(object_t *o); int isfirearm(object_t *o);
int isflammable(object_t *o); int isflammable(object_t *o);
int isfullycharged(object_t *o);
int isheatable(object_t *o); int isheatable(object_t *o);
int isknown(object_t *o); int isknown(object_t *o);
int isknownot(objecttype_t *ot); int isknownot(objecttype_t *ot);

13
spell.c
View File

@ -5781,7 +5781,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
msg("Unseen forces rip into %s%s flesh!", targetname, getpossessive(targetname)); msg("Unseen forces rip into %s%s flesh!", targetname, getpossessive(targetname));
} }
criticalhit(caster, target, getrandomcorebp(target, NULL), rnd(1,6), DT_SLASH); criticalhit(caster, target, getrandomcorebp(target, NULL), rnd(1,6), DT_SLASH);
pleasegodmaybe(R_GODDEATH, 3); if (isplayer(caster)) pleasegodmaybe(R_GODDEATH, 3);
} else if (spellid == OT_S_GLYPHWARDING) { } else if (spellid == OT_S_GLYPHWARDING) {
char buf[BUFLEN]; char buf[BUFLEN];
sprintf(buf, "^g*WARD%d*^n", power/2); sprintf(buf, "^g*WARD%d*^n", power/2);
@ -9538,7 +9538,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
f->obfrom = spellid; f->obfrom = spellid;
} else if ((spellid == OT_S_SIZEUP) || (spellid == OT_S_SIZEDOWN)) { } else if ((spellid == OT_S_SIZEUP) || (spellid == OT_S_SIZEDOWN)) {
enum LFSIZE origsize,newsize; enum LFSIZE origsize,newsize;
origsize = getlfsize(caster); target = targcell->lf;
if (!target) {
fizzle(caster);
return B_TRUE;
}
origsize = getlfsize(target);
if (spellid == OT_S_SIZEUP) { if (spellid == OT_S_SIZEUP) {
if (origsize >= SZ_ENORMOUS) { if (origsize >= SZ_ENORMOUS) {
fizzle(caster); fizzle(caster);
@ -9552,12 +9557,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_
} }
newsize = origsize - 1; newsize = origsize - 1;
} }
if (resizelf(caster, newsize)) { if (resizelf(target, newsize)) {
// failed // failed
fizzle(caster); fizzle(caster);
return B_TRUE; return B_TRUE;
} }
if (isplayer(caster) || cansee(player, caster)) { if (isplayer(target) || cansee(player, target)) {
if (seenbyplayer) *seenbyplayer = B_TRUE; if (seenbyplayer) *seenbyplayer = B_TRUE;
} }
} else if (spellid == OT_S_SLEEP) { } else if (spellid == OT_S_SLEEP) {