adapted most new lands for Shmup and some other modes

This commit is contained in:
Zeno Rogue 2017-10-11 22:16:07 +02:00
parent 2fd8f6b339
commit 343d0719b1
7 changed files with 113 additions and 52 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

109
shmup.cpp
View File

@ -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; i<c->type; 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;