Orb of Plague

This commit is contained in:
Zeno Rogue 2020-02-26 02:49:35 +01:00
parent e13a604418
commit 6317101d66
8 changed files with 54 additions and 27 deletions

View File

@ -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;

View File

@ -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) )

View File

@ -483,6 +483,7 @@ typedef function<int(struct cell*)> 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

View File

@ -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

View File

@ -161,7 +161,7 @@ EX vector<orbinfo> 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
};

View File

@ -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;

View File

@ -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; i<cw.at->type-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;

View File

@ -835,7 +835,7 @@ EX void applyBoxes() {
applyBoxOrb(itOrbImpact);
applyBoxOrb(itOrbChaos);
applyBoxOrb(itOrbSwamp);
applyBoxOrb(itOrbPlague);
applyBoxI(itEclectic);
applyBoxI(itFrog);
applyBoxI(itWet);