From 0f914d881912d3684b73170eaa311a3d822e4760 Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Tue, 21 Feb 2012 19:45:01 +0000 Subject: [PATCH] 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. --- attack.c | 6 +- data.c | 63 +++++++++----- data/vaults/caveboss1.vlt | 2 +- data/vaults/caveboss2.vlt | 2 +- data/vaults/godshrine1.vlt | 2 +- defs.h | 8 +- god.c | 38 ++++----- lf.c | 38 ++++++--- objects.c | 166 +++++++++++++++++++++++++++---------- objects.h | 1 + spell.c | 13 ++- 11 files changed, 231 insertions(+), 108 deletions(-) diff --git a/attack.c b/attack.c index 42e5592..b1d7f4d 100644 --- a/attack.c +++ b/attack.c @@ -446,7 +446,9 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { // did we just attack someone by accident? if (!isplayer(lf) && !areenemies(lf, victim) && (lf->race->raceclass->id == RC_HUMANOID) && (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. @@ -862,7 +864,7 @@ int attacklf(lifeform_t *lf, lifeform_t *victim, object_t *wep, flag_t *damflag) applylfdammod(&dam[0], lf, wep); // modify for size - modifyforsize(&dam[0], lf, victim, 5, M_PCT); + modifyforsize(&dam[0], lf, victim, 10, M_PCT); // backstab? if (willbackstab(lf, victim, wep)) { diff --git a/data.c b/data.c index 59d2322..b57bfb3 100644 --- a/data.c +++ b/data.c @@ -2051,7 +2051,31 @@ void initobjects(void) { addflag(lastot->flags, F_VALUE, 1000, NA, NA, NULL); addflag(lastot->flags, F_RARITY, H_DUNGEON, 50, RR_VERYRARE, NULL); // 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_VALUE, 1000, NA, 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_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_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); + addflag(lastot->flags, F_LINKGOD, R_GODTHIEVES, NA, NA, NULL); // flora 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_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_SCROLLNEEDSOB, B_ALWAYS, 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_AICASTTOATTACK, ST_VICTIM, NA, 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 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."); @@ -3709,14 +3720,22 @@ void initobjects(void) { addflag(lastot->flags, F_AICASTTOATTACK, ST_ANYWHERE, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); // 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_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, 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_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, 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); 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."); @@ -8579,7 +8598,7 @@ void initrace(void) { 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_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_EVASION, -30, NA, NA, NULL); addflag(lastrace->flags, F_MOVESPEED, SP_NORMAL, NA, NA, NULL); diff --git a/data/vaults/caveboss1.vlt b/data/vaults/caveboss1.vlt index 78d4ce2..6796dd1 100644 --- a/data/vaults/caveboss1.vlt +++ b/data/vaults/caveboss1.vlt @@ -23,7 +23,7 @@ c:ob:lit candelabrum A:ob:good armour W:ob:good weapon _:ob:pentagram -_:ob:Godstone of Rage +_:ob:Godstone of Destruction C:ob:chest @end diff --git a/data/vaults/caveboss2.vlt b/data/vaults/caveboss2.vlt index 8c7ab20..257d293 100644 --- a/data/vaults/caveboss2.vlt +++ b/data/vaults/caveboss2.vlt @@ -24,7 +24,7 @@ c:ob:lit candelabrum A:ob:good armour W:ob:good weapon _:ob:pentagram -_:ob:Godstone of Rage +_:ob:Godstone of Destruction C:ob:chest @end diff --git a/data/vaults/godshrine1.vlt b/data/vaults/godshrine1.vlt index d077213..2e50a79 100644 --- a/data/vaults/godshrine1.vlt +++ b/data/vaults/godshrine1.vlt @@ -14,7 +14,7 @@ #:cell:metal wall +:ob:locked iron door +:exit -g:ob:Godstone of Justice +g:ob:Godstone of Purity ^:ob:gas trap c:ob:candelabrum m:ob:landmine trap diff --git a/defs.h b/defs.h index 59c954e..ac8a4df 100644 --- a/defs.h +++ b/defs.h @@ -1241,9 +1241,11 @@ enum OBTYPE { // money OT_GOLD, // godstones - OT_GODSTONEJ, - OT_GODSTONEL, - OT_GODSTONER, + OT_GODSTONE_DESTRUCTION, + OT_GODSTONE_LIFE, + OT_GODSTONE_MERCY, + OT_GODSTONE_PURITY, + OT_GODSTONE_REVENGE, // flora OT_FLOWER, OT_LEAF, diff --git a/god.c b/god.c index 2273124..604fa17 100644 --- a/god.c +++ b/god.c @@ -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, "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, "achieved.\""); + wprintw(mainwin, "achieved.\"\n"); break; case R_GODDEATH: 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, "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, "the surface, and take the first step towards eternal life!\""); + wprintw(mainwin, "the surface, and take the first step towards eternal life!\"\n"); break; case R_GODMAGIC: 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: 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, "eternity. However...\"\n"); - wprintw(mainwin, "Yumi's grave expression softens.\n"); - wprintw(mainwin, "\"I embody mercy, and all sins can be forgiven. In this case, the\n"); - wprintw(mainwin, "road to your redemption is tied with the deed itself.\n\n"); - wprintw(mainwin, "Bring the stone to me. Perform this penance and not only will you\n"); - wprintw(mainwin, "be forgiven, but you will ensure that your mistake is never again\n"); - wprintw(mainwin, "repeated for all eternity. The God of Revenge will be neutralised,"); - wprintw(mainwin, "his influence ended.\n\n"); - wprintw(mainwin, "Mercy however, extends even to the divine. I would not doom Felix\n"); - wprintw(mainwin, "to a life of misery, his very essence ripped away. Should you\n"); - wprintw(mainwin, "possess the power, the Godstone would be used to grant Felix the\n"); - wprintw(mainwin, "peaceful sleep of death. For a tormented soul such as his, this\n"); - wprintw(mainwin, "would truly be a mercy.\n\n"); - wprintw(mainwin, "Either way, your atonement begins now. Travel up to the surface,\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.\""); + wprintw(mainwin, "eternity. However...\"\n\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 road\n"); + wprintw(mainwin, "to your redemption is tied with the deed itself. Bring the stone to me.\n"); + wprintw(mainwin, "Perform this penance and not only will you be forgiven, but you will ensure\n"); + wprintw(mainwin, "that your mistake is never again repeated for all eternity. The God of\n"); + wprintw(mainwin, "Revenge will be neutralised, his influence ended.\n\n"); + wprintw(mainwin, "Mercy however, extends even to the divine. I would not doom Felix to a\n"); + wprintw(mainwin, "life of misery, his very essence ripped away. Should you possess the\n"); + wprintw(mainwin, "power, the Godstone could be used to grant Felix the peaceful sleep\n"); + wprintw(mainwin, "of death. For a tormented soul such as his, this would truly be a mercy.\n\n"); + wprintw(mainwin, "Either way, your atonement begins now. Travel up to the surface, and enter\n"); + wprintw(mainwin, "the magic portal. Complete your task in the Realm of Gods and all will be\n"); + wprintw(mainwin, "forgiven.\"\n"); break; case R_GODNATURE: 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, "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, "trinket. Piece of cake!\""); + wprintw(mainwin, "trinket. Piece of cake!\"\n"); break; case R_GODPURITY: 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, "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, "the better. Chaos and impurity MUST be ended!\""); + wprintw(mainwin, "the better. Chaos and impurity MUST be ended!\"\n"); break; default: break; diff --git a/lf.c b/lf.c index 32d6859..fabc0ff 100644 --- a/lf.c +++ b/lf.c @@ -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 if ((amt >= (lf->maxhp / 2)) && (amt >= 20)) { if (useringofmiracles(lf, 1)) { return 0; } } + */ // occasionally drop blood if (damtypecausesbleed(damtype) && onein(3)) { @@ -19504,8 +19506,8 @@ int usestairs(lifeform_t *lf, object_t *o, int onpurpose, int climb) { return B_FALSE; } -// use a ring of miracles if we have one, and drain 'charges' -// charges from it. if expired, it will vanish. +// use a ring of miracles (or godstone of mercy) if we have one, and drain 'charges' +// charges from it. if expired, ring of miracles will vanish. // returns B_TRUE if we found one. int useringofmiracles(lifeform_t *lf, int charges) { object_t *o; @@ -19517,23 +19519,37 @@ int useringofmiracles(lifeform_t *lf, int charges) { getlfname(lf, lfname); for (o = lf->pack->first ; o ; o = o->next) { - if ( (o->type->id == OT_RING_MIRACLES) && - isequipped(o) && - getcharges(o) ) { + int doit = B_FALSE; + // use ring of miracles first + 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]; getobname(o, obname, 1); 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 - if (usecharge(o) <= 0) { - if (isplayer(lf) || cansee(player, lf)) { - msg("%s%s %s crumbles to dust.", lfname, getpossessive(lfname), noprefix(obname)); + if (o->type->id == OT_RING_MIRACLES) { + if (usecharge(o) <= 0) { + 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; } } diff --git a/objects.c b/objects.c index 45053fb..8714181 100644 --- a/objects.c +++ b/objects.c @@ -6847,6 +6847,15 @@ int isflammable(object_t *o) { 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. int isheatable(object_t *o) { 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); } } else if (o->type->obclass->id == OC_GODSTONE) { - f = hasflag(o->flags, F_CHARGES); - if (f && (f->val[0] == f->val[1])) { - int x,y; + if (isfullycharged(o)) { + int i; // announce if (isplayer(lf)){ 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); switch (o->type->id) { - case OT_GODSTONEJ: // justice + case OT_GODSTONE_PURITY: // everyone in lof drops to same hp as user + /* for (y = 0; y < lf->cell->map->h; y++) { for (x = 0; x < lf->cell->map->w; x++) { 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)) { c->lf->hp = lf->hp; 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)) { char lfname[BUFLEN]; 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; - case OT_GODSTONER: // rage + case OT_GODSTONE_DESTRUCTION: // rage // everyone in lof gets f_rage, and hates everything - for (y = 0; y < lf->cell->map->h; y++) { - for (x = 0; x < lf->cell->map->w; x++) { - cell_t *c; - c = getcellat(lf->cell->map, x, y); - if (c && c->lf && (c->lf != lf) && haslof(lf->cell, c, LOF_NEED, NULL)) { - int howlong = 50; - // create fire - addobfast(c->obpile, OT_FIRELARGE); - // enrage - addtempflag(c->lf->flags, F_RAGE, B_TRUE, NA, NA, NULL, howlong); - if (!isplayer(c->lf)) { - addtempflag(c->lf->flags, F_HATESALL, B_TRUE, NA, NA, NULL, howlong); - loseaitargets(c->lf); - } + 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 && (c->lf != lf) && haslof(lf->cell, c, LOF_WALLSTOP, NULL)) { + int howlong = 50; + // create fire + addobfast(c->obpile, OT_FIRELARGE); + // enrage + addtempflag(c->lf->flags, F_RAGE, B_TRUE, NA, NA, NULL, howlong); + if (!isplayer(c->lf)) { + addtempflag(c->lf->flags, F_HATESALL, B_TRUE, NA, NA, NULL, howlong); + loseaitargets(c->lf); } } } break; - case OT_GODSTONEL: // life + case OT_GODSTONE_LIFE: // life // everything in sight is restored // all corpses in sight are revived // everyone in lof gets f_rage, and hates everything - for (y = 0; y < lf->cell->map->h; y++) { - for (x = 0; x < lf->cell->map->w; x++) { - cell_t *c; - c = getcellat(lf->cell->map, x, y); - if (c && haslof(lf->cell, c, LOF_NEED, NULL)) { - if (c->lf) { - // restore - dospelleffects(NULL, OT_S_RESTORATION, 1, - c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE); - } else { - object_t *oo, *nextoo; - // revive corpses - for (oo = c->obpile->first ; oo ; oo = nextoo) { - nextoo = oo->next; - if (oo->type->id == OT_CORPSE) { - dospelleffects(NULL, OT_S_RESSURECTION, 1, - NULL, oo, c, B_BLESSED, NULL, B_TRUE); - } + for (i = 0; i < lf->cell->map->w * lf->cell->map->h; i++) { + cell_t *c; + c = lf->cell->map->cell[i]; + if (haslof(lf->cell, c, LOF_WALLSTOP, NULL)) { + if (c->lf) { + // restore + dospelleffects(NULL, OT_S_RESTORATION, 1, + c->lf, NULL, c->lf->cell, B_BLESSED, NULL, B_TRUE); + } else { + object_t *oo, *nextoo; + // revive corpses + for (oo = c->obpile->first ; oo ; oo = nextoo) { + nextoo = oo->next; + if (oo->type->id == OT_CORPSE) { + dospelleffects(NULL, OT_S_RESSURECTION, 1, + 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: break; } - f->val[0] = 0; // use up all charges + // use up all charges + usecharges(o, getcharges(o)); } else { if (isplayer(lf)) { nothinghappens(); @@ -13220,8 +13294,14 @@ void timeeffectsob(object_t *o) { } else { // if it hasn't been extinguished, the object burns if (f->id == F_ONFIRE) { - takedamage(o, 2, DT_FIRE); // TODO: don't hardcode - if (hasflag(o->flags, F_DEAD)) return; + if (isweapon(o) && isequipped(o)) { + // 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; + } } } } diff --git a/objects.h b/objects.h index efa4f48..1803537 100644 --- a/objects.h +++ b/objects.h @@ -190,6 +190,7 @@ flag_t *isequipped(object_t *o); int isequippedon(object_t *o, enum BODYPART bp); int isfirearm(object_t *o); int isflammable(object_t *o); +int isfullycharged(object_t *o); int isheatable(object_t *o); int isknown(object_t *o); int isknownot(objecttype_t *ot); diff --git a/spell.c b/spell.c index afc7011..f62e640 100644 --- a/spell.c +++ b/spell.c @@ -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)); } 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) { char buf[BUFLEN]; 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; } else if ((spellid == OT_S_SIZEUP) || (spellid == OT_S_SIZEDOWN)) { 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 (origsize >= SZ_ENORMOUS) { fizzle(caster); @@ -9552,12 +9557,12 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } newsize = origsize - 1; } - if (resizelf(caster, newsize)) { + if (resizelf(target, newsize)) { // failed fizzle(caster); return B_TRUE; } - if (isplayer(caster) || cansee(player, caster)) { + if (isplayer(target) || cansee(player, target)) { if (seenbyplayer) *seenbyplayer = B_TRUE; } } else if (spellid == OT_S_SLEEP) {