diff --git a/attack.cpp b/attack.cpp index 404ab58e..edbbd088 100644 --- a/attack.cpp +++ b/attack.cpp @@ -104,7 +104,7 @@ EX bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags) if(m1 == moArrowTrap && arrow_stuns(m2)) return true; - if(m2 == moAnimatedDie && !(flags & (AF_MAGIC | AF_CRUSH))) return false; + if(among(m2, moAnimatedDie, moAngryDie) && !(flags & (AF_MAGIC | AF_CRUSH))) return false; if(among(m2, moAltDemon, moHexDemon, moPair, moCrusher, moNorthPole, moSouthPole, moMonk) && !(flags & (AF_EAT | AF_MAGIC | AF_BULL | AF_CRUSH))) return false; diff --git a/content.cpp b/content.cpp index 0f8a7eae..f6f3aafd 100644 --- a/content.cpp +++ b/content.cpp @@ -1715,6 +1715,10 @@ MONSTER('d', 0x603010, "Animated Die", moAnimatedDie, ZERO, RESERVED, moHexDemon "Other rolls and attacks are not allowed." ) +MONSTER('d', 0x901010, "Angry Die", moAngryDie, ZERO, RESERVED, moHexDemon, + "You have made a die unhappy, and it remembers that! This one won't forgive you, no matter what you do." + ) + //shmupspecials MONSTER( '@', 0xC0C0C0, "Rogue", moPlayer, CF_FACE_UP | CF_PLAYER, RESERVED, moNone, "In the Shoot'em Up mode, you are armed with thrown Knives.") MONSTER( '*', 0xC0C0C0, "Knife", moBullet, ZERO | CF_BULLET, RESERVED, moNone, "A simple, but effective, missile, used by rogues.") diff --git a/environment.cpp b/environment.cpp index 7a6ce518..8adc39f4 100644 --- a/environment.cpp +++ b/environment.cpp @@ -481,7 +481,7 @@ EX void bfs() { else if(isMagneticPole(c2->monst)) havewhat |= HF_MAGNET; else if(c2->monst == moAltDemon) havewhat |= HF_ALT; else if(c2->monst == moHexDemon) havewhat |= HF_HEXD; - else if(c2->monst == moAnimatedDie) havewhat |= HF_HEXD; + else if(among(c2->monst, moAnimatedDie, moAngryDie)) havewhat |= HF_HEXD; else if(c2->monst == moMonk) havewhat |= HF_MONK; else if(c2->monst == moShark || c2->monst == moCShark || among(c2->monst, moRusalka, moPike)) havewhat |= HF_SHARK; else if(c2->monst == moAirElemental) diff --git a/game.cpp b/game.cpp index a035ad41..6fbc57fc 100644 --- a/game.cpp +++ b/game.cpp @@ -394,6 +394,12 @@ EX void pushThumper(const movei& mi) { addMessage(XLAT("The die is now happy, but won't reward you outside of the Land of Dice!")); } } + if(w == waHappyDie && dice::data[cto].happy() <= 0) { + cto->monst = moAngryDie; + cto->wall = waNone; + cto->stuntime = 5; + addMessage(XLAT("You have made a Happy Die angry!")); + } } else cto->wall = w; diff --git a/graph.cpp b/graph.cpp index b5f2d044..5a81c0fc 100644 --- a/graph.cpp +++ b/graph.cpp @@ -2252,7 +2252,7 @@ EX bool drawMonsterType(eMonster m, cell *where, const shiftmatrix& V1, color_t return true; } - case moAnimatedDie: { + case moAnimatedDie: case moAngryDie: { if(where) dice::draw_die(where, V, 1, darkena(col, 0, 0xFF)); else @@ -2886,7 +2886,7 @@ EX bool drawMonster(const shiftmatrix& Vparam, int ct, cell *c, color_t col, col // golems, knights, and hyperbugs don't face the player (mondir-controlled) // also whatever in the lineview mode, and whatever in the quotient geometry - else if(c->monst == moAnimatedDie) { + else if(among(c->monst, moAnimatedDie, moAngryDie)) { transmatrix U = inverse_shift(Vparam, Vs); U = rgpushxto0(tC0(U)); die_target = Vparam; diff --git a/monstermove.cpp b/monstermove.cpp index 3ede8970..4a9a6f8a 100644 --- a/monstermove.cpp +++ b/monstermove.cpp @@ -103,7 +103,7 @@ EX void moveEffect(const movei& mi, eMonster m) { tortoise::move_baby(cf, ct); } - if(m == moAnimatedDie && mi.proper()) + if(among(m, moAnimatedDie, moAngryDie) && mi.proper()) dice::roll(mi); } @@ -1152,9 +1152,10 @@ EX void groupmove2(const movei& mi, eMonster movtype, flagtype mf) { } moveMonster(mi); + onpath(from, 0); - if(mi.t->monst == moAnimatedDie) { + if(among(mi.t->monst, moAnimatedDie, moAngryDie)) { /* other dice will not pathfind through the original cell */ /* this makes it easier for the player to roll dice correctly */ onpath(c, 0); diff --git a/orbs.cpp b/orbs.cpp index 19f8426f..2fbca22d 100644 --- a/orbs.cpp +++ b/orbs.cpp @@ -810,6 +810,8 @@ EX eMonster summonedAt(cell *dest) { return moBomberbird; if(dest->wall == waRichDie) return moAnimatedDie; + if(dest->wall == waHappyDie) + return moAngryDie; if(dest->wall == waTrapdoor) return dest->land == laPalace ? moFatGuard : moOrangeDog; if(dest->land == laFrog && dest->wall == waNone) { @@ -910,6 +912,8 @@ void summonAt(cell *dest) { dest->wall = waBoat, dest->item = itNone; if(dest->monst == moAnimatedDie) dest->wall = waNone; + if(dest->monst == moAngryDie) + dest->wall = waNone; if(dest->monst == moViking && dest->land == laKraken) dest->item = itOrbFish; if(dest->wall == waStrandedBoat) @@ -1113,6 +1117,12 @@ void blowoff(const movei& mi) { cf->item = itDice; items[itDice]--; } + if(ct->wall == waHappyDie && dice::data[ct].happy() <= 0) { + ct->monst = moAngryDie; + ct->wall = waNone; + ct->stuntime = 5; + addMessage(XLAT("You have made a Happy Die angry!")); + } items[itOrbAir]--; createNoise(2); bfs(); @@ -1147,7 +1157,8 @@ EX movei blowoff_destination(cell *c, int& di) { if(dtype) for(int e=d; etype; e++) { int di = e % c->type; cell *c2 = c->move(di); - if((c->monst == moAnimatedDie || c->wall == waHappyDie || c->wall == waRichDie) && ctof(c2)) continue; + if((c->monst == moAnimatedDie || c->monst == moAngryDie || c->wall == waHappyDie || c->wall == waRichDie) && ctof(c2)) + continue; if(c2 && c2->cpdist > c->cpdist && passable(c2, c, P_BLOW)) return movei(c, c2, di); } return movei(c, c, NO_SPACE); diff --git a/pcmove.cpp b/pcmove.cpp index 257d48e7..385cd4d0 100644 --- a/pcmove.cpp +++ b/pcmove.cpp @@ -759,6 +759,8 @@ void pcmove::tell_why_cannot_attack() { addMessage(XLAT("You cannot attack Jellies in their wall form!")); else if(c2->monst == moAnimatedDie) addMessage(XLAT("You can only push this die if the highest number would be on the top!")); + else if(c2->monst == moAngryDie) + addMessage(XLAT("This die is really angry at you!")); else addMessage(XLAT("For some reason... cannot attack!")); }