mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-25 01:20:37 +00:00
Orb of Plague improved
This commit is contained in:
parent
ca60e463b3
commit
688fc50036
12
attack.cpp
12
attack.cpp
@ -1196,8 +1196,10 @@ EX void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill IS(0)) {
|
|||||||
}
|
}
|
||||||
eMonster m = c->monst;
|
eMonster m = c->monst;
|
||||||
int k = tkills();
|
int k = tkills();
|
||||||
if(attackMonster(c, AF_STAB | AF_MSG, who))
|
if(attackMonster(c, AF_STAB | AF_MSG, who)) {
|
||||||
|
spread_plague(mt, c, t, who);
|
||||||
produceGhost(c, m, who);
|
produceGhost(c, m, who);
|
||||||
|
}
|
||||||
if(tkills() > k) numsh++;
|
if(tkills() > k) numsh++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1223,8 +1225,11 @@ EX void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill IS(0)) {
|
|||||||
if(c->monst == moFlailer && isPrincess(who) && isUnarmed(who))
|
if(c->monst == moFlailer && isPrincess(who) && isUnarmed(who))
|
||||||
achievement_gain("PRINCESS_PACIFIST");
|
achievement_gain("PRINCESS_PACIFIST");
|
||||||
|
|
||||||
if(attackMonster(c, 0, who)) numflail++;
|
if(attackMonster(c, 0, who)) {
|
||||||
if(m == moVizier) produceGhost(c, m, who);
|
numflail++;
|
||||||
|
spread_plague(mf, c, t, who);
|
||||||
|
produceGhost(c, m, who);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1236,6 +1241,7 @@ EX void stabbingAttack(cell *mf, cell *mt, eMonster who, int bonuskill IS(0)) {
|
|||||||
if(anglestraight(mt, backdir, t)) flag |= AF_HORNS;
|
if(anglestraight(mt, backdir, t)) flag |= AF_HORNS;
|
||||||
if(canAttack(mt,who,c,c->monst, flag)) {
|
if(canAttack(mt,who,c,c->monst, flag)) {
|
||||||
if(attackMonster(c, flag | AF_MSG, who)) numlance++;
|
if(attackMonster(c, flag | AF_MSG, who)) numlance++;
|
||||||
|
spread_plague(mt, c, t, who);
|
||||||
produceGhost(c, mm, who);
|
produceGhost(c, mm, who);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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( '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,
|
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.")
|
"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 Plague", itOrbPlague, IC_ORB, ZERO, RESERVED, osOffensive, NODESCYET)
|
ITEM( 'o', 0x808080, "Orb of Plague", itOrbPlague, IC_EMPATHY, ZERO, RESERVED, osOffensive, NODESCYET)
|
||||||
NATIVE(among(m, moPike, moRusalka) ? 2 : 0)
|
NATIVE(among(m, moPike, moRusalka) ? 2 : 0)
|
||||||
REQ( GOLD(R30) )
|
REQ( GOLD(R30) )
|
||||||
|
|
||||||
|
13
graph.cpp
13
graph.cpp
@ -3897,6 +3897,19 @@ EX void drawParticleSpeed(cell *c, color_t col, int speed) {
|
|||||||
EX void drawParticle(cell *c, color_t col, int maxspeed IS(100)) {
|
EX void drawParticle(cell *c, color_t col, int maxspeed IS(100)) {
|
||||||
drawParticleSpeed(c, col, 1 + rand() % maxspeed);
|
drawParticleSpeed(c, col, 1 + rand() % maxspeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EX void drawDirectionalParticle(cell *c, int dir, color_t col, int maxspeed IS(100)) {
|
||||||
|
LATE( drawDirectionalParticle(c, dir, col, maxspeed); )
|
||||||
|
if(vid.particles && !confusingGeometry()) {
|
||||||
|
int speed = 1 + rand() % maxspeed;
|
||||||
|
auto fd = flashdata(ticks, rand() % 16, c, col, speed);
|
||||||
|
fd.angle = -atan2(tC0(currentmap->adj(c, dir)));
|
||||||
|
fd.angle += 2 * M_PI * (rand() % 100 - rand() % 100) / 100 / c->type;
|
||||||
|
flashes.push_back(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EX void drawParticles(cell *c, color_t col, int qty, int maxspeed IS(100)) {
|
EX void drawParticles(cell *c, color_t col, int qty, int maxspeed IS(100)) {
|
||||||
if(vid.particles)
|
if(vid.particles)
|
||||||
while(qty--) drawParticle(c,col, maxspeed);
|
while(qty--) drawParticle(c,col, maxspeed);
|
||||||
|
@ -1228,6 +1228,7 @@ EX void snakeAttack(cell *c, bool mounted) {
|
|||||||
mounted ? AF_ONLY_ENEMY : (AF_ONLY_FBUG | AF_GETPLAYER))) {
|
mounted ? AF_ONLY_ENEMY : (AF_ONLY_FBUG | AF_GETPLAYER))) {
|
||||||
eMonster m2 = c->move(j)->monst;
|
eMonster m2 = c->move(j)->monst;
|
||||||
attackMonster(c->move(j), AF_NORMAL | AF_GETPLAYER | AF_MSG, moHexSnake);
|
attackMonster(c->move(j), AF_NORMAL | AF_GETPLAYER | AF_MSG, moHexSnake);
|
||||||
|
spread_plague(c, c->move(j), j, moHexSnake);
|
||||||
produceGhost(c->move(j), moHexSnake, m2);
|
produceGhost(c->move(j), moHexSnake, m2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1659,6 +1660,7 @@ EX void movegolems(flagtype flags) {
|
|||||||
markOrb(itOrbEmpathy), markOrb(itOrbSlaying);
|
markOrb(itOrbEmpathy), markOrb(itOrbSlaying);
|
||||||
attackMonster(c2, flags | AF_MSG, m);
|
attackMonster(c2, flags | AF_MSG, m);
|
||||||
animateAttack(movei(c, dir), LAYER_SMALL);
|
animateAttack(movei(c, dir), LAYER_SMALL);
|
||||||
|
spread_plague(c, c2, dir, m);
|
||||||
produceGhost(c2, m2, m);
|
produceGhost(c2, m2, m);
|
||||||
sideAttack(c, dir, m, 0);
|
sideAttack(c, dir, m, 0);
|
||||||
if(revenge) c->monst = m = moPrincessArmed;
|
if(revenge) c->monst = m = moPrincessArmed;
|
||||||
|
59
pcmove.cpp
59
pcmove.cpp
@ -717,6 +717,7 @@ bool pcmove::after_escape() {
|
|||||||
playSound(c2, "hit-axe" + pick123());
|
playSound(c2, "hit-axe" + pick123());
|
||||||
changes.ccell(c2);
|
changes.ccell(c2);
|
||||||
c2->wall = waNone;
|
c2->wall = waNone;
|
||||||
|
spread_plague(cwt.at, c2, mi.d, moPlayer);
|
||||||
return swing();
|
return swing();
|
||||||
}
|
}
|
||||||
else if(c2->wall == waBigTree) {
|
else if(c2->wall == waBigTree) {
|
||||||
@ -887,7 +888,10 @@ bool pcmove::attack() {
|
|||||||
changes.ccell(c2);
|
changes.ccell(c2);
|
||||||
// salamanders are stunned for longer time when pushed into a wall
|
// salamanders are stunned for longer time when pushed into a wall
|
||||||
if(c2->monst == moSalamander && (mip.t == c2 || !mip.t)) c2->stuntime = 10;
|
if(c2->monst == moSalamander && (mip.t == c2 || !mip.t)) c2->stuntime = 10;
|
||||||
if(!c2->monst) produceGhost(c2, m, moPlayer);
|
if(!c2->monst) {
|
||||||
|
spread_plague(cwt.at, c2, mi.d, moPlayer);
|
||||||
|
produceGhost(c2, m, moPlayer);
|
||||||
|
}
|
||||||
if(mip.proper()) pushMonster(mip);
|
if(mip.proper()) pushMonster(mip);
|
||||||
animateAttack(mi, LAYER_SMALL);
|
animateAttack(mi, LAYER_SMALL);
|
||||||
}
|
}
|
||||||
@ -1264,31 +1268,51 @@ EX void swordAttackStatic() {
|
|||||||
swordAttackStatic(bb);
|
swordAttackStatic(bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void sideAttackAt(cell *mf, int dir, cell *mt, eMonster who, eItem orb) {
|
EX int plague_kills;
|
||||||
|
|
||||||
|
EX void spread_plague(cell *mf, cell *mt, int dir, eMonster who) {
|
||||||
|
if(!items[itOrbPlague]) return;
|
||||||
|
int kk = tkills();
|
||||||
|
forCellEx(mx, mt) if(celldistance(mx, mf) > celldistance(mx, mf->move(dir)) && celldistance(mx, mf) <= 4) {
|
||||||
|
sideAttackAt(mf, dir, mx, who, itOrbPlague, mt);
|
||||||
|
}
|
||||||
|
plague_kills += tkills() - kk;
|
||||||
|
}
|
||||||
|
|
||||||
|
EX void sideAttackAt(cell *mf, int dir, cell *mt, eMonster who, eItem orb, cell *pf) {
|
||||||
eMonster m = mt->monst;
|
eMonster m = mt->monst;
|
||||||
flagtype f = AF_SIDE;
|
flagtype f = AF_SIDE;
|
||||||
if(orb == itOrbPlague) f |= AF_PLAGUE;
|
if(orb == itOrbPlague) f |= AF_PLAGUE;
|
||||||
if(items[itOrbSlaying]) f|= AF_CRUSH;
|
if(items[itOrbSlaying]) f|= AF_CRUSH;
|
||||||
if(m) println(hlog, "canAttack ", dnameof(m), " at ", mt, ":", canAttack(mf, who, mt, m, f));
|
if(!items[orb]) return;
|
||||||
|
auto plague_particles = [&] {
|
||||||
|
if(orb == itOrbPlague) {
|
||||||
|
for(int i=0; i<16; i++)
|
||||||
|
drawDirectionalParticle(pf, neighborId(pf, mt), iinf[orb].color);
|
||||||
|
}
|
||||||
|
};
|
||||||
if(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))
|
if((f & AF_CRUSH) && !canAttack(mf, who, mt, m, AF_SIDE | AF_MUSTKILL))
|
||||||
markOrb(itOrbSlaying);
|
markOrb(itOrbSlaying);
|
||||||
markOrb(orb);
|
markOrb(orb);
|
||||||
|
plague_particles();
|
||||||
if(who != moPlayer) markOrb(itOrbEmpathy);
|
if(who != moPlayer) markOrb(itOrbEmpathy);
|
||||||
if(attackMonster(mt, AF_NORMAL | AF_SIDE | AF_MSG, who) || isAnyIvy(m)) {
|
if(attackMonster(mt, AF_NORMAL | AF_SIDE | AF_MSG, who) || isAnyIvy(m)) {
|
||||||
println(hlog, "spread from ", mt);
|
if(mt->monst != m) spread_plague(mf, mt, dir, who);
|
||||||
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);
|
produceGhost(mt, m, who);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(mt->wall == waSmallTree) {
|
else if(mt->wall == waSmallTree) {
|
||||||
|
plague_particles();
|
||||||
|
markOrb(orb);
|
||||||
mt->wall = waNone;
|
mt->wall = waNone;
|
||||||
forCellEx(mx, mt) if(celldistance(mx, mf) > celldistance(mx, mf->move(dir)) && celldistance(mx, mf) <= 4)
|
spread_plague(mf, mt, dir, who);
|
||||||
sideAttackAt(mf, dir, mx, who, orb);
|
|
||||||
}
|
}
|
||||||
else if(mt->wall == waBigTree)
|
else if(mt->wall == waBigTree) {
|
||||||
|
plague_particles();
|
||||||
|
markOrb(orb);
|
||||||
mt->wall = waSmallTree;
|
mt->wall = waSmallTree;
|
||||||
|
}
|
||||||
else if(mt->wall == waExplosiveBarrel && orb != itOrbPlague)
|
else if(mt->wall == waExplosiveBarrel && orb != itOrbPlague)
|
||||||
explodeBarrel(mt);
|
explodeBarrel(mt);
|
||||||
}
|
}
|
||||||
@ -1298,29 +1322,18 @@ EX void sideAttack(cell *mf, int dir, eMonster who, int bonus, eItem orb) {
|
|||||||
if(who != moPlayer && !items[itOrbEmpathy]) return;
|
if(who != moPlayer && !items[itOrbEmpathy]) return;
|
||||||
for(int k: {-1, 1}) {
|
for(int k: {-1, 1}) {
|
||||||
cell *mt = mf->modmove(dir + k*bonus);
|
cell *mt = mf->modmove(dir + k*bonus);
|
||||||
sideAttackAt(mf, dir, mt, who, orb);
|
sideAttackAt(mf, dir, mt, who, orb, mf);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EX void sideAttack(cell *mf, int dir, eMonster who, int bonuskill) {
|
EX void sideAttack(cell *mf, int dir, eMonster who, int bonuskill) {
|
||||||
|
|
||||||
int k = tkills();
|
int k = tkills();
|
||||||
|
plague_kills = 0;
|
||||||
sideAttack(mf, dir, who, 1, itOrbSide1);
|
sideAttack(mf, dir, who, 1, itOrbSide1);
|
||||||
sideAttack(mf, dir, who, 2, itOrbSide2);
|
sideAttack(mf, dir, who, 2, itOrbSide2);
|
||||||
sideAttack(mf, dir, who, 3, itOrbSide3);
|
sideAttack(mf, dir, who, 3, itOrbSide3);
|
||||||
k -= tkills();
|
k -= tkills() - plague_kills;
|
||||||
sideAttackPlague(mf, dir, who);
|
|
||||||
k += tkills();
|
|
||||||
|
|
||||||
if(who == moPlayer) {
|
if(who == moPlayer) {
|
||||||
int kills = tkills() - k + bonuskill;
|
int kills = tkills() - k + bonuskill;
|
||||||
|
Loading…
Reference in New Issue
Block a user