From 343d0719b18a61e2bab1160a5152094940e245cb Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Wed, 11 Oct 2017 22:16:07 +0200 Subject: [PATCH] adapted most new lands for Shmup and some other modes --- bigstuff.cpp | 21 +++++++--- flags.cpp | 4 ++ game.cpp | 14 +++++-- graph.cpp | 4 +- help.cpp | 2 +- orbs.cpp | 11 +++++- shmup.cpp | 109 +++++++++++++++++++++++++++++++++------------------ 7 files changed, 113 insertions(+), 52 deletions(-) diff --git a/bigstuff.cpp b/bigstuff.cpp index e7473e0a..ca3b4cf7 100644 --- a/bigstuff.cpp +++ b/bigstuff.cpp @@ -1012,12 +1012,23 @@ void buildBigStuff(cell *c, cell *from) { } bool openplains(cell *c) { - celllister cl(c, purehepta ? 5 : 7, 1000000, NULL); - for(cell *c: cl.lst) { - while(c->mpdist > 8) setdist(c, c->mpdist-1, NULL); - if(c->land != laHunting) return false; + if(purehepta) { + celllister cl(c, 5, 1000000, NULL); + int bad = 0; + for(cell *c: cl.lst) { + while(c->mpdist > 8) setdist(c, c->mpdist-1, NULL); + if(c->land != laHunting) {bad++; if(bad>5) return false;} + } + return true; } - return true; + else { + celllister cl(c, purehepta ? 5 : 7, 1000000, NULL); + for(cell *c: cl.lst) { + while(c->mpdist > 8) setdist(c, c->mpdist-1, NULL); + if(c->land != laHunting) return false; + } + return true; + } } void doOvergenerate() { diff --git a/flags.cpp b/flags.cpp index d69fcbce..0fd311c8 100644 --- a/flags.cpp +++ b/flags.cpp @@ -49,6 +49,10 @@ bool isFire(cell *w) { return w->wall == waFire || w->wall == waPartialFire || w->wall == waEternalFire; } +bool isFireOrMagma(cell *w) { + return isFire(w) || w->wall == waMagma; + } + bool isThumper(eWall w) { return w == waThumperOff || w == waThumperOn; } diff --git a/game.cpp b/game.cpp index f15bdc69..5a0e473c 100644 --- a/game.cpp +++ b/game.cpp @@ -631,7 +631,7 @@ bool againstWind(cell *cto, cell *cfrom) { if(!cfrom || !cto) return false; int dcto = airdist(cto), dcfrom = airdist(cfrom); if(dcto < dcfrom) return true; - if(cfrom->land == laBlizzard && cto->land == laBlizzard && dcto == 3 && dcfrom == 3) { + if(cfrom->land == laBlizzard && !shmup::on && cto->land == laBlizzard && dcto == 3 && dcfrom == 3) { char vfrom = windmap::at(cfrom); char vto = windmap::at(cto); int z = (vfrom-vto) & 255; @@ -2428,8 +2428,9 @@ bool recalcTide; #define LANDDIST LHU.bytes[1] #define CHAOSPARAM LHU.bytes[2] -int alchemyval(cell *c, int t) { - return (windmap::at(c) + (turncount+t)*4) & 255; +int lavatide(cell *c, int t) { + int tc = (shmup::on ? shmup::curtime/400 : turncount); + return (windmap::at(c) + (tc+t)*4) & 255; } void checkTide(cell *c) { @@ -2464,7 +2465,7 @@ void checkTide(cell *c) { c->wall = waSea; } if(c->land == laVolcano) { - int id = alchemyval(c, 0); + int id = lavatide(c, 0); if(id < 96) { if(c->wall == waNone || isWateryOrBoat(c) || c->wall == waVinePlant) { if(isWateryOrBoat(c)) @@ -5534,6 +5535,11 @@ bool checkNeedMove(bool checkonly, bool attacking) { if(checkonly) return true; addMessage(XLAT("This spot will be burning soon! RUN!")); } + else if(cwt.c->wall == waMagma && !markOrb(itOrbWinter) && !markOrb2(itOrbShield)) { + if(markOrb2(itOrbAether)) return false; + if(checkonly) return true; + addMessage(XLAT("Run away from the magma!")); + } else if(cwt.c->wall == waChasm) { if(markOrb2(itOrbAether)) return false; if(checkonly) return true; diff --git a/graph.cpp b/graph.cpp index 605311fe..91b22782 100644 --- a/graph.cpp +++ b/graph.cpp @@ -2384,7 +2384,7 @@ void setcolors(cell *c, int& wcol, int &fcol) { case laLivefjord: fcol = 0x306030; break; case laVolcano: { - int id = alchemyval(c, -1)/4; + int id = lavatide(c, -1)/4; if(c->wall == waMagma) { if(id == 95/4-1) fcol = wcol = 0x200000; else if(id == 95/4) fcol = wcol = 0x100000; @@ -2666,7 +2666,7 @@ void setcolors(cell *c, int& wcol, int &fcol) { } /* if(false && isAlch2(c, true)) { - int id = alchemyval(c, -1); + int id = lavatide(c, -1); if(id < 96) wcol = gradient(0x800000, 0xFF0000, 0, id, 96); else diff --git a/help.cpp b/help.cpp index 1d211a4c..3cb60711 100644 --- a/help.cpp +++ b/help.cpp @@ -656,7 +656,7 @@ void describeMouseover() { } } else if(c->land == laVolcano) { - int id = alchemyval(c, -1)/4; + int id = lavatide(c, -1)/4; if(id < 96/4) out += " (" + turnstring(96/4-id) + XLAT(" to go cold") + ")"; else diff --git a/orbs.cpp b/orbs.cpp index 4c68b0ec..2a7db29f 100644 --- a/orbs.cpp +++ b/orbs.cpp @@ -138,6 +138,10 @@ void reduceOrbPowers() { reduceOrbPower(itOrbHorns, 77); reduceOrbPower(itOrbLava, 80); reduceOrbPower(itOrbMorph, 80); + + reduceOrbPower(itOrbSide1, 120); + reduceOrbPower(itOrbSide2, 120); + reduceOrbPower(itOrbSide3, 120); if(cwt.c->land != laWildWest) reduceOrbPower(itRevolver, 6); whirlwind::calcdirs(cwt.c); @@ -877,7 +881,7 @@ void poly_attack(cell *dest) { dest->monst = target; if(!dest->stuntime) dest->stuntime = 1; checkStunKill(dest); - useupOrb(itOrbMorph, 2); + useupOrb(itOrbMorph, 3); createNoise(3); bfs(); checkmoveO(); @@ -1299,6 +1303,11 @@ int orbcharges(eItem it) { case itOrbLava: return 50; + + case itOrbSide1: + case itOrbSide2: + case itOrbSide3: + return 50; default: return 0; diff --git a/shmup.cpp b/shmup.cpp index 96d0d6f4..104d7e06 100644 --- a/shmup.cpp +++ b/shmup.cpp @@ -1256,37 +1256,20 @@ void shootBullet(monster *m) { bullet->parenttype = m->type; additional.push_back(bullet); - if(markOrb(itOrbThorns)) { + eItem orbdir[8] = { + itNone, itOrbSide1, itOrbThorns, itOrbSide2, itOrbSide3, itOrbSide2, itOrbThorns, itOrbSide1 + }; + + for(int i=1; i<8; i++) if(markOrb(orbdir[i])) { monster* bullet = new monster; bullet->base = m->base; - bullet->at = m->at * spin(M_PI/2); + bullet->at = m->at * spin(M_PI/4*i); bullet->type = moBullet; bullet->parent = m; bullet->pid = m->pid; bullet->parenttype = m->type; additional.push_back(bullet); } - - if(markOrb(itOrbThorns)) { - monster* bullet = new monster; - bullet->base = m->base; - bullet->at = m->at * spin(-M_PI/2); - bullet->type = moBullet; - bullet->parent = m; - bullet->pid = m->pid; - bullet->parenttype = m->type; - additional.push_back(bullet); - } - - if(markOrb(itOrbDash)) { - monster* bullet = new monster; - bullet->base = m->base; - bullet->at = m->at * spin(M_PI); - bullet->type = moBullet; - bullet->parent = m; - bullet->parenttype = m->type; - additional.push_back(bullet); - } } void killThePlayer(eMonster m) { @@ -1331,7 +1314,8 @@ void oceanCurrents(transmatrix& nat, monster *m, int delta) { } } -void airCurrents(transmatrix& nat, monster *m, int delta) { +bool airCurrents(transmatrix& nat, monster *m, int delta) { + bool carried = false; cell *c = m->base; if(c->land == laWhirlwind) { whirlwind::calcdirs(c); @@ -1341,6 +1325,7 @@ void airCurrents(transmatrix& nat, monster *m, int delta) { double spd = SCALE * delta / 900.; + if(m->type == moVoidBeast) spd = -spd; if(spd) { transmatrix goal = gmatrix[c2]; @@ -1350,9 +1335,31 @@ void airCurrents(transmatrix& nat, monster *m, int delta) { nat = nat * rspintox(H); nat = nat * xpush(spd); nat = nat * spintox(H); + carried = true; } } } + if(c->land == laBlizzard) { + int wmc = windmap::at(c); + forCellEx(c2, c) { + if(!c2 || !gmatrix.count(c2)) continue; + int z = (windmap::at(c2) - wmc) & 255; + if(z >= 128) z -= 256; + if(m->type == moVoidBeast) z = -z; + if(z < windmap::NOWINDFROM && z > -windmap::NOWINDFROM) { + transmatrix goal = gmatrix[c2]; + + // transmatrix t = spintox(H) * xpush(delta/300.) * rspintox(H); + + hyperpoint H = inverse(m->pat) * goal * C0; + nat = nat * rspintox(H); + nat = nat * xpush(z * SCALE * delta / 50000.); + nat = nat * spintox(H); + carried = true; + } + } + } + return carried; } void roseCurrents(transmatrix& nat, monster *m, int delta) { @@ -1423,7 +1430,8 @@ bool swordKills(eMonster m) { return m != moHedge && m != moMetalBeast && m != moMetalBeast2 && m != moTortoise && m != moGreater && m != moRoseBeauty - && m != moReptile && !isBull(m) && m != moButterfly; + && m != moReptile && !isBull(m) && m != moButterfly && + m != moSalamander && m != moTerraWarrior; } bool hornKills(eMonster m) { @@ -1432,7 +1440,8 @@ bool hornKills(eMonster m) { && m != moTortoise && m != moGreater && m != moSkeleton && m != moDraugr && m != moRoseBeauty && m != moReptile && !isBull(m) && m != moButterfly && !isBulletType(m) - && m != moPalace && m != moFatGuard && m != moVizier; + && m != moPalace && m != moFatGuard && m != moVizier && + m != moSalamander && m != moTerraWarrior; } bool hornStuns(eMonster m) { @@ -1445,8 +1454,10 @@ bool noncrashable(monster *m, monster *by) { if(mt == moDraugr && by->type != moDraugr) return true; if(isBull(mt)) return true; if(mt == moReptile) return true; + if(mt == moSalamander) return true; if(mt == moRoseBeauty && by->type != moRoseLady) return true; if(mt == moTortoise) return true; + if(mt == moTerraWarrior) return true; if(mt == moSkeleton) return true; return false; } @@ -1570,8 +1581,7 @@ void movePlayer(monster *m, int delta) { if(m->base->land == laWhirlpool && !markOrb(itOrbWater)) oceanCurrents(nat, m, delta); - if(m->base->land == laWhirlwind) - airCurrents(nat, m, delta); + airCurrents(nat, m, delta); if(rosedist(m->base) == 1) roseCurrents(nat, m, delta); @@ -1582,6 +1592,8 @@ void movePlayer(monster *m, int delta) { playergo[cpid] = mgo * SCALE * delta / 600; + if(playergo[cpid] && markOrb(itOrbDash)) playergo[cpid] *= 1.5; + bool go = false; cell *c2 = m->base; @@ -1773,7 +1785,7 @@ void movePlayer(monster *m, int delta) { if(isWatery(m->base) && !m->inBoat && !markOrb(itOrbFish)) m->dead = true; - if(isFire(m->base) && !markOrb(itOrbWinter)) + if(isFireOrMagma(m->base) && !markOrb(itOrbWinter)) m->dead = true; } @@ -2102,6 +2114,9 @@ void moveBullet(monster *m, int delta) { nat = nat * xpush(delta * SCALE * m->vel / speedfactor()); cell *c2 = m->findbase(nat); + if(m->parent && isPlayer(m->parent) && markOrb(itOrbLava) && c2 != m->base && !isPlayerOn(m->base)) + makeflame(m->base, 5, false); + if(isActivable(c2)) activateActiv(c2, true); // knives break mirrors and clouds @@ -2183,14 +2198,16 @@ void moveBullet(monster *m, int delta) { // if((m2->type == moPalace || m2->type == moFatGuard || m2->type == moSkeleton || m2->type == moVizier || isMetalBeast(m2->type) || m2->type == moTortoise || - m2->type == moReptile) && m2->hitpoints > 1) { + m2->type == moReptile || m2->type == moSalamander || m2->type == moTerraWarrior) && m2->hitpoints > 1) { m2->rebasePat(m2->pat * rspintox(inverse(m2->pat) * nat0 * C0)); - if(m2->type != moSkeleton && !isMetalBeast(m2->type) && m2->type != moReptile) + if(m2->type != moSkeleton && !isMetalBeast(m2->type) && m2->type != moReptile && m2->type != moSalamander) m2->hitpoints--; m->dead = true; if(m2->type == moVizier) ; else if(m2->type == moFatGuard) m2->stunoff = curtime + 600; + else if(m2->type == moTerraWarrior) + m2->stunoff = curtime + 300 * (6 - m2->hitpoints); else if(m2->type == moMetalBeast || m2->type == moMetalBeast2) m2->stunoff = curtime + 3000; else if(m2->type == moReptile) @@ -2288,8 +2305,12 @@ void moveMonster(monster *m, int delta) { if(isWatery(m->base) && !survivesWater(m->type) && !m->inBoat && m->type != moReptile) killMonster(m, moNone); - if(isFire(m->base) && !survivesFire(m->type)) - killMonster(m, moNone); + if(isFireOrMagma(m->base)) { + if(m->type == moSalamander) + m->stunoff = max(ticks+500, m->stunoff); + else if(!survivesFire(m->type)) + killMonster(m, moNone); + } if(m->base->wall == waClosedGate && !survivesWall(m->type)) killMonster(m, moNone); @@ -2307,6 +2328,8 @@ void moveMonster(monster *m, int delta) { step *= 2; else if(m->type == moEagle) step *= 1.6; + else if(m->type == moHunterDog) + step *= 1.5; else if(m->type == moLancer) step *= 1.25; else if(isDemon(m->type)) { @@ -2339,10 +2362,15 @@ void moveMonster(monster *m, int delta) { if(m->blowoff > curtime) { step = SCALE * -delta / 1000.; } - else if(m->type == moFatGuard || m->type == moTortoise || m->type == moRagingBull) + else if(m->type == moFatGuard || m->type == moTortoise || m->type == moRagingBull || m->type == moTerraWarrior) step = 0; else if(m->type == moReptile) step = SCALE * -delta / 1000. * (m->stunoff - curtime) / 3000.; + else if(m->type == moSalamander) { + if(isFireOrMagma(m->base)) step = 0; + else + step = SCALE * -delta / 2000.; + } else step = SCALE * -delta/2000.; } @@ -2397,7 +2425,7 @@ void moveMonster(monster *m, int delta) { cell *cnext = c; for(int i=0; itype; i++) { cell *c2 = c->mov[i]; - if(c2 && gmatrix.count(c2) && HEAT(c2) > HEAT(c) && isIcyLand(c2) && passable(c2, c, 0)) + if(c2 && gmatrix.count(c2) && (c2->land == laVolcano || (isIcyLand(c2) && HEAT(c2) > HEAT(c))) && passable(c2, c, 0)) cnext = c2; } goal = gmatrix[cnext]; @@ -2482,8 +2510,8 @@ void moveMonster(monster *m, int delta) { if(c->land == laWhirlpool && (m->type == moShark || m->type == moCShark || m->type == moPirate)) oceanCurrents(nat, m, delta), carried = true; - if(m->base->land == laWhirlwind) - airCurrents(nat, m, delta), carried = true; + if(m->type != moGhost && m->type != moFriendlyGhost && m->type != moAirElemental) + carried |= airCurrents(nat, m, delta); if(rosedist(m->base) == 1) roseCurrents(nat, m, delta), carried = true; @@ -2570,7 +2598,7 @@ void moveMonster(monster *m, int delta) { if(isSlimeMover(m->type) || m->type == moWaterElemental) usetongue = true; if(isWatery(c2) && !survivesWater(m->type) && !m->inBoat) usetongue = true; if(c2->wall == waChasm && !survivesChasm(m->type)) usetongue = true; - if(isFire(c2) && !survivesFire(m->type) && !m->inBoat) usetongue = true; + if(isFireOrMagma(c2) && !survivesFire(m->type) && !m->inBoat) usetongue = true; if(isBird(m->type) && !passable_for(moEagle, c2, c, 0)) usetongue = true; if(usetongue) { if(curtime < m->nextshot) return; @@ -2601,6 +2629,9 @@ void moveMonster(monster *m, int delta) { if(c2 != m->base && cellUnstable(m->base) && !ignoresPlates(m->type)) doesFallSound(m->base); + if(m->type == moWolf && c2->land == laVolcano) m->type = moLavaWolf; + if(m->type == moLavaWolf && isIcyLand(c2)) m->type = moWolf; + if(c2 != m->base && m->type == moWitchFire) makeflame(m->base, 10, false); if(c2 != m->base && m->type == moFireElemental) makeflame(m->base, 20, false); if(c2 != m->base && m->type == moWaterElemental) placeWater(c2, m->base); @@ -2786,7 +2817,7 @@ void activateMonstersAt(cell *c) { } if(c->monst && isMimic(c->monst)) c->monst = moNone; // mimics are awakened by awakenMimics - if(c->monst && !isIvy(c) && !isWorm(c) && !isMutantIvy(c) && !isKraken(c->monst) && c->monst != moPrincess) { + if(c->monst && !isIvy(c) && !isWorm(c) && !isMutantIvy(c) && !isKraken(c->monst) && c->monst != moPrincess && c->monst != moHunterGuard) { // awaken as a monster monster *enemy = new monster; enemy->at = Id;