From 6317101d663ba33908b9080cf4f77ab2a307d0fe Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Wed, 26 Feb 2020 02:49:35 +0100 Subject: [PATCH] Orb of Plague --- attack.cpp | 4 ++-- content.cpp | 2 +- hyper.h | 1 + inventory.cpp | 2 +- orbgen.cpp | 2 +- orbs.cpp | 6 ++--- pcmove.cpp | 62 ++++++++++++++++++++++++++++++++++++--------------- system.cpp | 2 +- 8 files changed, 54 insertions(+), 27 deletions(-) diff --git a/attack.cpp b/attack.cpp index 7c82fde0..036f5d0b 100644 --- a/attack.cpp +++ b/attack.cpp @@ -138,10 +138,10 @@ EX bool canAttack(cell *c1, eMonster m1, cell *c2, eMonster m2, flagtype flags) if(m2 == moGreater || m2 == moGreaterM) if(!(flags & (AF_MAGIC | AF_SWORD_INTO | AF_HORNS | AF_CRUSH))) return false; - if(!(flags & (AF_GUN | AF_SWORD | AF_SWORD_INTO | AF_MAGIC))) + if(!(flags & (AF_GUN | AF_SWORD | AF_SWORD_INTO | AF_MAGIC | AF_PLAGUE))) if(c1 != c2 && !logical_adjacent(c1, m1, c2)) return false; - if(!(flags & (AF_LANCE | AF_STAB | AF_BACK | AF_APPROACH | AF_GUN | AF_MAGIC))) + if(!(flags & (AF_LANCE | AF_STAB | AF_BACK | AF_APPROACH | AF_GUN | AF_MAGIC | AF_PLAGUE | AF_SIDE))) if(c1 && c2 && againstRose(c1, c2) && !ignoresSmell(m1)) return false; diff --git a/content.cpp b/content.cpp index 5481f3ae..e27950a6 100644 --- a/content.cpp +++ b/content.cpp @@ -1562,7 +1562,7 @@ MONSTER( 'P', 0xC08080, "Pike", moPike, CF_FACE_SIDE | CF_SHARK, RESERVED, moSha MONSTER( 'S', 0xC0C080, "Yellow Skipper", moYellowSkipper, CF_FACE_SIDE | CF_SHARK, RESERVED, moShark, "Just a nasty shark.") /* unused */ MONSTER( 'R', 0x4040C0, "Rusałka", moRusalka, CF_FACE_SIDE | CF_SHARK, RESERVED, moShark, "A water spirit. When killed, she will try to drown you, by changing dry land to shallow water and shallow water to deep water.") -ITEM( 'o', 0x808080, "Orb of the Swamp", itOrbSwamp, IC_ORB, ZERO, RESERVED, osUtility, NODESCYET) +ITEM( 'o', 0x808080, "Orb of Plague", itOrbPlague, IC_ORB, ZERO, RESERVED, osOffensive, NODESCYET) NATIVE(among(m, moPike, moRusalka) ? 2 : 0) REQ( GOLD(R30) ) diff --git a/hyper.h b/hyper.h index 39a5137d..417064ec 100644 --- a/hyper.h +++ b/hyper.h @@ -483,6 +483,7 @@ typedef function cellfunction; #define AF_BULL Flag(29) // bull attack #define AF_SIDE Flag(30) // side attack #define AF_CRUSH Flag(31) // Crusher's delayed attack +#define AF_PLAGUE Flag(32) // Orb of Plague (do not check adjacency) #if CAP_SDL diff --git a/inventory.cpp b/inventory.cpp index 038bf648..bbdc3be0 100644 --- a/inventory.cpp +++ b/inventory.cpp @@ -353,7 +353,7 @@ EX namespace inv { gainOrbs(itBrownian, itOrbChoice); gainOrbs(itFrog, itOrbImpact); - gainOrbs(itWet, itOrbSwamp); + gainOrbs(itWet, itOrbPlague); gainOrbs(itEclectic, itOrbChaos); #if CAP_DAILY diff --git a/orbgen.cpp b/orbgen.cpp index f25c346d..5ffeabf8 100644 --- a/orbgen.cpp +++ b/orbgen.cpp @@ -161,7 +161,7 @@ EX vector orbinfos = { {orbgenflags::S_NATIVE, laEclectic, 1000, 1000, itOrbChaos}, {orbgenflags::S_GUEST, laEclectic, 4000, 0, itOrbWinter}, {orbgenflags::S_GUEST, laEclectic, 2000, 0, itOrbLightning}, - {orbgenflags::S_GUEST, laWet, 1000, 1000, itOrbSwamp}, + {orbgenflags::S_GUEST, laWet, 1000, 1000, itOrbPlague}, {orbgenflags::S_GUEST, laWet, 4000, 0, itOrbFish}, {orbgenflags::S_NATIVE, laWhirlpool, 0, 2000, itOrbWater}, // needs to be last }; diff --git a/orbs.cpp b/orbs.cpp index f669187b..54418dcd 100644 --- a/orbs.cpp +++ b/orbs.cpp @@ -158,7 +158,7 @@ EX void reduceOrbPowers() { reduceOrbPower(itOrbIntensity, 120); reduceOrbPower(itOrbImpact, 120); reduceOrbPower(itOrbChaos, 120); - reduceOrbPower(itOrbSwamp, 120); + reduceOrbPower(itOrbPlague, 120); reduceOrbPower(itOrbSide1, 120); reduceOrbPower(itOrbSide2, 120); @@ -1504,8 +1504,8 @@ EX int orbcharges(eItem it) { case itOrbChaos: return 60; - case itOrbSwamp: - return 60; + case itOrbPlague: + return 30; default: return 0; diff --git a/pcmove.cpp b/pcmove.cpp index eff2a1e0..c9cb143c 100644 --- a/pcmove.cpp +++ b/pcmove.cpp @@ -1245,28 +1245,51 @@ EX void swordAttackStatic() { swordAttackStatic(bb); } +EX void sideAttackAt(cell *mf, int dir, cell *mt, eMonster who, eItem orb) { + eMonster m = mt->monst; + flagtype f = AF_SIDE; + if(orb == itOrbPlague) f |= AF_PLAGUE; + if(items[itOrbSlaying]) f|= AF_CRUSH; + if(m) println(hlog, "canAttack ", dnameof(m), " at ", mt, ":", canAttack(mf, who, mt, m, f)); + if(canAttack(mf, who, mt, m, f)) { + if((f & AF_CRUSH) && !canAttack(mf, who, mt, m, AF_SIDE | AF_MUSTKILL)) + markOrb(itOrbSlaying); + markOrb(orb); + if(who != moPlayer) markOrb(itOrbEmpathy); + if(attackMonster(mt, AF_NORMAL | AF_SIDE | AF_MSG, who) || isAnyIvy(m)) { + println(hlog, "spread from ", mt); + forCellEx(mx, mt) if(celldistance(mx, mf) > celldistance(mx, mf->move(dir)) && celldistance(mx, mf) <= 4) + sideAttackAt(mf, dir, mx, who, orb); + produceGhost(mt, m, who); + } + } + else if(mt->wall == waSmallTree) { + mt->wall = waNone; + forCellEx(mx, mt) if(celldistance(mx, mf) > celldistance(mx, mf->move(dir)) && celldistance(mx, mf) <= 4) + sideAttackAt(mf, dir, mx, who, orb); + } + else if(mt->wall == waBigTree) + mt->wall = waSmallTree; + else if(mt->wall == waExplosiveBarrel && orb != itOrbPlague) + explodeBarrel(mt); + } + EX void sideAttack(cell *mf, int dir, eMonster who, int bonus, eItem orb) { if(!items[orb]) return; if(who != moPlayer && !items[itOrbEmpathy]) return; for(int k: {-1, 1}) { cell *mt = mf->modmove(dir + k*bonus); - eMonster m = mt->monst; - flagtype f = AF_SIDE; - if(items[itOrbSlaying]) f|= AF_CRUSH; - if(canAttack(mf, who, mt, m, f)) { - if((f & AF_CRUSH) && !canAttack(mf, who, mt, m, AF_SIDE | AF_MUSTKILL)) - markOrb(itOrbSlaying); - markOrb(orb); - if(who != moPlayer) markOrb(itOrbEmpathy); - if(attackMonster(mt, AF_NORMAL | AF_SIDE | AF_MSG, who)) - produceGhost(mt, m, who); - } - else if(mt->wall == waBigTree) - mt->wall = waSmallTree; - else if(mt->wall == waSmallTree) - mt->wall = waNone; - else if(mt->wall == waExplosiveBarrel) - explodeBarrel(mt); + sideAttackAt(mf, dir, mt, who, orb); + } + } + +EX void sideAttackPlague(cell *mf, int dir, eMonster who) { + if(!items[itOrbPlague]) return; + cellwalker cw(mf, dir); + cw += wstep; + for(int i=2; itype-1; i++) { + println(hlog, "sa = ", (cw+i).cpeek(), " mo = ", dnameof((cw+i).cpeek()->monst)); + sideAttackAt(mf, dir, (cw+i).cpeek(), who, itOrbPlague); } } @@ -1275,7 +1298,10 @@ EX void sideAttack(cell *mf, int dir, eMonster who, int bonuskill) { int k = tkills(); sideAttack(mf, dir, who, 1, itOrbSide1); sideAttack(mf, dir, who, 2, itOrbSide2); - sideAttack(mf, dir, who, 3, itOrbSide3); + sideAttack(mf, dir, who, 3, itOrbSide3); + k -= tkills(); + sideAttackPlague(mf, dir, who); + k += tkills(); if(who == moPlayer) { int kills = tkills() - k + bonuskill; diff --git a/system.cpp b/system.cpp index 4ef8896f..5d94e29a 100644 --- a/system.cpp +++ b/system.cpp @@ -835,7 +835,7 @@ EX void applyBoxes() { applyBoxOrb(itOrbImpact); applyBoxOrb(itOrbChaos); - applyBoxOrb(itOrbSwamp); + applyBoxOrb(itOrbPlague); applyBoxI(itEclectic); applyBoxI(itFrog); applyBoxI(itWet);