mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-04-14 06:43:15 +00:00
Asteroids
This commit is contained in:
parent
4727e71590
commit
5356eba11c
@ -1257,6 +1257,10 @@ LAND( 0x30FF30, "Irradiated Field", laVariant, ZERO, itVarTreasure, RESERVED,
|
||||
|
||||
// add new content here
|
||||
|
||||
LAND( 0x202020, "Asteroids", laAsteroids, ZERO, itAsteroid, RESERVED, NODESCYET)
|
||||
ITEM( '*', 0xFFFFFF, "Ice Diamond", itAsteroid, IC_TREASURE, ZERO, RESERVED, osNone, NODESCYET)
|
||||
MONSTER('A', 0x606040, "Asteroid", moAsteroid, ZERO, RESERVED, moAsteroid, NODESCYET)
|
||||
|
||||
//shmupspecials
|
||||
MONSTER( '@', 0xC0C0C0, "Rogue", moPlayer, ZERO | CF_PLAYER, RESERVED, moNone, "In the Shoot'em Up mode, you are armed with thrown Knives.")
|
||||
MONSTER( '*', 0xC0C0C0, "Knife", moBullet, ZERO | CF_BULLET, RESERVED, moNone, "A simple, but effective, missile, used by rogues.")
|
||||
|
3
game.cpp
3
game.cpp
@ -888,7 +888,7 @@ bool passable_for(eMonster m, cell *w, cell *from, flagtype extra) {
|
||||
if(m == moPair)
|
||||
return !(w && from && againstPair(from, w, m)) && passable(w, from, extra);
|
||||
if(m == passive_switch) return false;
|
||||
if(minf[m].mgroup == moYeti || isBug(m) || isDemon(m) || m == moHerdBull || m == moMimic) {
|
||||
if(minf[m].mgroup == moYeti || isBug(m) || isDemon(m) || m == moHerdBull || m == moMimic || m == moAsteroid) {
|
||||
if((isWitch(m) || m == moEvilGolem) && w->land != laPower && w->land != laHalloween)
|
||||
return false;
|
||||
return passable(w, from, extra);
|
||||
@ -6958,6 +6958,7 @@ bool collectItem(cell *c2, bool telekinesis) {
|
||||
else playSound(c2, "pickup-orb");
|
||||
if(items[itOrbChoice]) items[itOrbChoice] = 0, had_choice = true;
|
||||
int oc = orbcharges(it);
|
||||
if(c2->land == laAsteroids) oc = 10;
|
||||
if(markOrb(itOrbIntensity)) oc = oc * 6 / 5;
|
||||
if(!items[it]) items[it]++;
|
||||
items[it] += oc;
|
||||
|
@ -27,6 +27,8 @@ ld hexshift;
|
||||
|
||||
ld sword_size = 0;
|
||||
|
||||
ld asteroid_size[8];
|
||||
|
||||
// the results are:
|
||||
// hexf = 0.378077 hcrossf = 0.620672 tessf = 1.090550
|
||||
// hexhexdist = 0.566256
|
||||
|
@ -1891,6 +1891,11 @@ bool drawMonsterType(eMonster m, cell *where, const transmatrix& V, color_t col,
|
||||
ShadowV(V, shTentHead, PPR::GIANTSHADOW);
|
||||
return false;
|
||||
}
|
||||
|
||||
case moAsteroid: {
|
||||
queuepoly(V, shAsteroid[1], darkena(col, 0, 0xFF));
|
||||
return false;
|
||||
}
|
||||
|
||||
default: ;
|
||||
}
|
||||
|
7
hyper.h
7
hyper.h
@ -233,6 +233,7 @@ constexpr transmatrix diag(ld a, ld b, ld c, ld d) {
|
||||
#endif
|
||||
}
|
||||
|
||||
const static hyperpoint Hypc = hyperpoint(0, 0, 0, 0);
|
||||
|
||||
// identity matrix
|
||||
const static transmatrix Id = diag(1,1,1,1);
|
||||
@ -898,18 +899,19 @@ namespace shmup {
|
||||
eMonster parenttype; // type of the parent
|
||||
int nextshot; // when will it be able to shot (players/flailers)
|
||||
int pid; // player ID
|
||||
char hitpoints;
|
||||
int hitpoints; // hitpoints; or time elapsed in Asteroids
|
||||
int stunoff;
|
||||
int blowoff;
|
||||
double swordangle; // sword angle wrt at
|
||||
double vel; // velocity, for flail balls
|
||||
double footphase;
|
||||
bool isVirtual; // off the screen: gmatrix is unknown, and pat equals at
|
||||
hyperpoint inertia;// for frictionless lands
|
||||
|
||||
monster() {
|
||||
dead = false; inBoat = false; parent = NULL; nextshot = 0;
|
||||
stunoff = 0; blowoff = 0; footphase = 0; no_targetting = false;
|
||||
swordangle = 0;
|
||||
swordangle = 0; inertia = Hypc;
|
||||
}
|
||||
|
||||
void store();
|
||||
@ -1641,6 +1643,7 @@ void destroyBoats(cell *c, cell *cf, bool strandedToo);
|
||||
extern bool showoff;
|
||||
extern int lastexplore;
|
||||
extern int truelotus;
|
||||
extern int asteroids_generated, asteroid_orbs_generated;
|
||||
extern eLand lastland;
|
||||
extern time_t timerstart;
|
||||
extern bool timerstopped;
|
||||
|
@ -136,9 +136,6 @@ hyperpoint hpxy3(ld x, ld y, ld z) {
|
||||
return hpxyz3(x,y,z, euclid ? 1 : sphere ? sqrt(1-x*x-y*y-z*z) : sqrt(1+x*x+y*y+z*z));
|
||||
}
|
||||
|
||||
// center of the pseudosphere
|
||||
const hyperpoint Hypc = hyperpoint(0,0,0,0);
|
||||
|
||||
// origin of the hyperbolic plane
|
||||
const hyperpoint C02 = hyperpoint(0,0,1,0);
|
||||
const hyperpoint C03 = hyperpoint(0,0,0,1);
|
||||
@ -241,6 +238,16 @@ transmatrix cspin(int a, int b, ld alpha) {
|
||||
|
||||
transmatrix spin(ld alpha) { return cspin(0, 1, alpha); }
|
||||
|
||||
transmatrix random_spin() {
|
||||
if(DIM == 2) return spin(randd() * 2 * M_PI);
|
||||
else {
|
||||
ld alpha2 = acos(randd() * 2 - 1);
|
||||
ld alpha = randd() * 2 * M_PI;
|
||||
ld alpha3 = randd() * 2 * M_PI;
|
||||
return cspin(0, 1, alpha) * cspin(0, 2, alpha2) * cspin(1, 2, alpha3);
|
||||
}
|
||||
}
|
||||
|
||||
transmatrix eupush(ld x, ld y) {
|
||||
transmatrix T = Id;
|
||||
T[0][DIM] = x;
|
||||
|
@ -2377,6 +2377,9 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
c->monst = moGhost;
|
||||
break;
|
||||
|
||||
case laAsteroids:
|
||||
break;
|
||||
|
||||
case landtypes: break;
|
||||
}
|
||||
}
|
||||
|
@ -237,6 +237,9 @@ int isNative(eLand l, eMonster m) {
|
||||
case laMagnetic:
|
||||
return isMagneticPole(m) ? 2 : 0;
|
||||
|
||||
case laAsteroids:
|
||||
return m == moAsteroid ? 2 : 0;
|
||||
|
||||
case landtypes: return 0;
|
||||
}
|
||||
return false;
|
||||
@ -316,7 +319,7 @@ bool landUnlocked(eLand l) {
|
||||
case laStorms: case laWhirlwind:
|
||||
return gold() >= R60;
|
||||
|
||||
case laWildWest: case laHalloween:
|
||||
case laWildWest: case laHalloween: case laAsteroids:
|
||||
return false;
|
||||
|
||||
case laIce: case laJungle: case laCaves: case laDesert:
|
||||
|
@ -291,6 +291,7 @@ eItem wanderingTreasure(cell *c) {
|
||||
if(l == laEAir) return itAirShard;
|
||||
if(l == laEEarth) return itEarthShard;
|
||||
if(l == laElementalWall) return itNone;
|
||||
if(l == laAsteroids) return itNone;
|
||||
if(l == laMirror && c->type != 6) return itNone;
|
||||
if(l == laMirrorOld && c->type != 6) return itNone;
|
||||
if(l == laEmerald) {
|
||||
@ -498,6 +499,26 @@ void wandering() {
|
||||
|
||||
else if(c->monst || c->pathdist == PINFD) break;
|
||||
|
||||
else if(c->land == laAsteroids) {
|
||||
int gen = 0;
|
||||
if(asteroids_generated * 12 <= items[itAsteroid]) gen = 2;
|
||||
if(gen == 0) {
|
||||
int qty = 0;
|
||||
for(cell *c: currentmap->allcells()) if(c->monst == moAsteroid) qty++;
|
||||
if(!qty) gen = 1;
|
||||
}
|
||||
if(gen) c->monst = moAsteroid, c->hitpoints = 4;
|
||||
if(gen == 2)
|
||||
asteroids_generated++;
|
||||
|
||||
if(items[itAsteroid] > (asteroid_orbs_generated+2) * (asteroid_orbs_generated+3) && !c->item) {
|
||||
c->item = pick(itOrbThorns, itOrbSide1, itOrbSide2, itOrbSide3, itOrbShield, itOrbLife);
|
||||
asteroid_orbs_generated++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
else if(c->land == laClearing && wchance(items[itMutant2], 150) && items[itMutant2] >= 15 && !c->monst && c->type == 7)
|
||||
c->monst = moRedFox;
|
||||
|
||||
|
13
polygons.cpp
13
polygons.cpp
@ -1677,7 +1677,7 @@ hpcshape
|
||||
shDragonWings,
|
||||
shSolidBranch, shWeakBranch, shBead0, shBead1,
|
||||
shBatWings, shBatBody, shBatMouth, shBatFang, shBatEye,
|
||||
shParticle[16],
|
||||
shParticle[16], shAsteroid[8],
|
||||
shReptile[5][4],
|
||||
shReptileBody, shReptileHead, shReptileFrontFoot, shReptileRearFoot,
|
||||
shReptileFrontLeg, shReptileRearLeg, shReptileTail, shReptileEye,
|
||||
@ -2311,7 +2311,16 @@ void procedural_shapes() {
|
||||
for(int i=0; i<16; i++) {
|
||||
bshape(shParticle[i], PPR::PARTICLE);
|
||||
for(int t=0; t<6; t++)
|
||||
hpcpush(xspinpush0(M_PI * t * 2 / 6 + M_PI * 2/6 * hrand(100) / 150., (0.03 + hrand(100) * 0.0003) * scalefactor));
|
||||
// hpcpush(xspinpush0(M_PI * t * 2 / 6 + M_PI * 2/6 * hrand(100) / 150., (0.03 + hrand(100) * 0.0003) * scalefactor));
|
||||
hpcpush(xspinpush0(M_PI * t * 2 / 6 + M_PI * 2/6 * randd() / 1.5, (0.03 + randd() * 0.03) * scalefactor));
|
||||
hpc.push_back(hpc[last->s]);
|
||||
}
|
||||
|
||||
for(int i=0; i<8; i++) {
|
||||
asteroid_size[i] = scalefactor * 0.1 * pow(2, (i-1) * 1. / DIM);
|
||||
bshape(shAsteroid[i], PPR::PARTICLE);
|
||||
for(int t=0; t<12; t++)
|
||||
hpcpush(xspinpush0(M_PI * t / 6, asteroid_size[i] * (1 - randd() * .2)));
|
||||
hpc.push_back(hpc[last->s]);
|
||||
}
|
||||
|
||||
|
170
shmup.cpp
170
shmup.cpp
@ -1283,6 +1283,27 @@ void visibleFor(int t) {
|
||||
visibleAt = max(visibleAt, curtime + t);
|
||||
}
|
||||
|
||||
ld bullet_velocity(eMonster t) {
|
||||
switch(t) {
|
||||
case moBullet:
|
||||
return 1/300.;
|
||||
case moFireball:
|
||||
return 1/500.;
|
||||
case moCrushball:
|
||||
return 1/1000.;
|
||||
case moAirball:
|
||||
return 1/200.;
|
||||
case moArrowTrap:
|
||||
return 1/200.;
|
||||
case moTongue:
|
||||
return 1/1500.;
|
||||
default:
|
||||
return 1/300.;
|
||||
}
|
||||
}
|
||||
|
||||
int frontdir() { return DIM == 2 ? 0 : 2; }
|
||||
|
||||
void shootBullet(monster *m) {
|
||||
monster* bullet = new monster;
|
||||
bullet->base = m->base;
|
||||
@ -1291,6 +1312,10 @@ void shootBullet(monster *m) {
|
||||
bullet->parent = m;
|
||||
bullet->pid = m->pid;
|
||||
bullet->parenttype = m->type;
|
||||
bullet->inertia = m->inertia;
|
||||
bullet->inertia[frontdir()] += bullet_velocity(m->type) * SCALE;
|
||||
bullet->hitpoints = 0;
|
||||
|
||||
additional.push_back(bullet);
|
||||
|
||||
eItem orbdir[8] = {
|
||||
@ -1305,6 +1330,10 @@ void shootBullet(monster *m) {
|
||||
bullet->parent = m;
|
||||
bullet->pid = m->pid;
|
||||
bullet->parenttype = m->type;
|
||||
bullet->hitpoints = 0;
|
||||
using namespace hyperpoint_vec;
|
||||
bullet->inertia = spin(-M_PI/4 * i) * m->inertia;
|
||||
bullet->inertia[frontdir()] += bullet_velocity(m->type) * SCALE;
|
||||
additional.push_back(bullet);
|
||||
}
|
||||
}
|
||||
@ -1592,6 +1621,8 @@ static const int reflectflag = P_MIRRORWALL;
|
||||
|
||||
void movePlayer(monster *m, int delta) {
|
||||
|
||||
bool inertia_based = m->base->land == laAsteroids;
|
||||
|
||||
cpid = m->pid;
|
||||
|
||||
#if CAP_RACING
|
||||
@ -1720,6 +1751,7 @@ void movePlayer(monster *m, int delta) {
|
||||
if(playerturn[cpid] && canmove && !blown && DIM == 2) {
|
||||
m->swordangle -= playerturn[cpid];
|
||||
nat = nat * spin(playerturn[cpid]);
|
||||
if(inertia_based) m->inertia = spin(-playerturn[cpid]) * m->inertia;
|
||||
}
|
||||
transmatrix nat0 = nat;
|
||||
|
||||
@ -1752,6 +1784,7 @@ void movePlayer(monster *m, int delta) {
|
||||
if(mdy > 1) mdy = 1;
|
||||
if(mdy < -1) mdy = -1;
|
||||
if(mdx > 1) mdx = 1;
|
||||
|
||||
if(mdx < -1) mdx = -1;
|
||||
if(racing::on) {
|
||||
if(m->vel * -mdy < 0) mdy *= 3;
|
||||
@ -1795,6 +1828,14 @@ void movePlayer(monster *m, int delta) {
|
||||
nextstep:
|
||||
|
||||
transmatrix nat1 = nat;
|
||||
|
||||
hyperpoint avg_inertia;
|
||||
|
||||
if(inertia_based) {
|
||||
avg_inertia = m->inertia;
|
||||
m->inertia[frontdir()] += playergo[cpid] / 1000;
|
||||
avg_inertia[frontdir()] += playergo[cpid] / 2000;
|
||||
}
|
||||
|
||||
for(int igo=0; igo<IGO && !go; igo++) {
|
||||
|
||||
@ -1802,10 +1843,21 @@ void movePlayer(monster *m, int delta) {
|
||||
|
||||
playergoturn[cpid] = igospan[go];
|
||||
|
||||
if(DIM == 3)
|
||||
if(inertia_based) {
|
||||
if(igo) { go = false; break; }
|
||||
ld r = hypot_d(DIM, avg_inertia);
|
||||
nat = nat * rspintox(avg_inertia) * xpush(r * delta) * spintox(avg_inertia);
|
||||
}
|
||||
else if(DIM == 3) {
|
||||
nat = nat1 * cpush(0, playerstrafe[cpid]) * cpush(2, playergo[cpid]) * cspin(0, 2, playerturn[cpid]) * cspin(1, 2, playerturny[cpid]);
|
||||
else if(playergo[cpid])
|
||||
m->inertia[0] = playerstrafe[cpid] / delta;
|
||||
m->inertia[1] = 0;
|
||||
m->inertia[2] = playergo[cpid] / delta;
|
||||
}
|
||||
else if(playergo[cpid]) {
|
||||
nat = nat1 * spin(igospan[igo]) * xpush(playergo[cpid]) * spin(-igospan[igo]);
|
||||
m->inertia = spin(igospan[igo]) * xpush0(playergo[cpid] / delta);
|
||||
}
|
||||
|
||||
// spin(span[igo]) * xpush(playergo[cpid]) * spin(-span[igo]);
|
||||
|
||||
@ -1898,13 +1950,16 @@ void movePlayer(monster *m, int delta) {
|
||||
if(!go) {
|
||||
playergo[cpid] = playergoturn[cpid] = playerstrafe[cpid] = 0;
|
||||
if(DIM == 3) playerturn[cpid] = playerturny[cpid] = 0;
|
||||
m->inertia = Hypc;
|
||||
}
|
||||
|
||||
if(go) {
|
||||
|
||||
if(DIM == 3)
|
||||
if(DIM == 3) {
|
||||
swordmatrix[cpid] =
|
||||
cspin(1, 2, -playerturny[cpid]) * cspin(0, 2, -playerturn[cpid]) * swordmatrix[cpid];
|
||||
m->inertia = cspin(1, 2, -playerturny[cpid]) * cspin(0, 2, -playerturn[cpid]) * m->inertia;
|
||||
}
|
||||
|
||||
if(c2 != m->base) {
|
||||
if(cellUnstable(m->base) && !markOrb(itOrbAether))
|
||||
@ -2320,7 +2375,37 @@ transmatrix frontpush(ld x) {
|
||||
if(DIM == 2) return xpush(x);
|
||||
else return cpush(2, x);
|
||||
}
|
||||
|
||||
ld collision_distance(monster *bullet, monster *target) {
|
||||
if(target->type == moAsteroid)
|
||||
return SCALE * 0.15 + asteroid_size[target->hitpoints & 7];
|
||||
return SCALE * 0.3;
|
||||
}
|
||||
|
||||
void spawn_asteroids(monster *bullet, monster *target) {
|
||||
if(target->hitpoints <= 1) return;
|
||||
hyperpoint rnd = random_spin() * point2(SCALE/3000., 0);
|
||||
|
||||
hyperpoint bullet_inertia = inverse(target->pat) * bullet->pat * bullet->inertia;
|
||||
|
||||
for(int i=0; i<2; i++) {
|
||||
using namespace hyperpoint_vec;
|
||||
monster* child = new monster;
|
||||
child->base = target->base;
|
||||
child->at = target->at;
|
||||
child->type = target->type;
|
||||
child->parent = NULL;
|
||||
child->pid = target->pid;
|
||||
child->parenttype = target->type;
|
||||
child->inertia = target->inertia;
|
||||
child->inertia += bullet_inertia / 5;
|
||||
child->hitpoints = target->hitpoints - 1;
|
||||
if(i == 0) child->inertia += rnd;
|
||||
if(i == 1) child->inertia -= rnd;
|
||||
additional.push_back(child);
|
||||
}
|
||||
}
|
||||
|
||||
void moveBullet(monster *m, int delta) {
|
||||
cpid = m->pid;
|
||||
m->findpat();
|
||||
@ -2329,6 +2414,12 @@ void moveBullet(monster *m, int delta) {
|
||||
transmatrix nat0 = m->pat;
|
||||
transmatrix nat = m->pat;
|
||||
|
||||
bool inertia_based = m->base->land == laAsteroids;
|
||||
|
||||
if(m->base->land == laAsteroids) {
|
||||
m->hitpoints += delta;
|
||||
if(m->hitpoints >= 500) m->dead = true;
|
||||
}
|
||||
|
||||
if(isReptile(m->base->wall)) m->base->wparam = reptilemax();
|
||||
|
||||
@ -2339,22 +2430,17 @@ void moveBullet(monster *m, int delta) {
|
||||
nat = nat * rspintox(inverse(m->pat) * m->parent->pat * C0) * spin(M_PI);
|
||||
}
|
||||
}
|
||||
else if(m->type == moBullet)
|
||||
m->vel = 1/300.;
|
||||
else if(m->type == moFireball)
|
||||
m->vel = 1/500.;
|
||||
else if(m->type == moCrushball)
|
||||
m->vel = 1/1000.;
|
||||
else if(m->type == moAirball)
|
||||
m->vel = 1/200.;
|
||||
else if(m->type == moArrowTrap)
|
||||
m->vel = 1/200.;
|
||||
else if(m->type == moTongue) {
|
||||
m->vel = 1/1500.;
|
||||
if(m->isVirtual || !m->parent || intval(nat*C0, m->parent->pat*C0) > SCALE2 * 0.4)
|
||||
m->dead = true;
|
||||
else m->vel = bullet_velocity(m->type);
|
||||
|
||||
if(m->type == moTongue && (m->isVirtual || !m->parent || intval(nat*C0, m->parent->pat*C0) > SCALE2 * 0.4))
|
||||
m->dead = true;
|
||||
|
||||
if(inertia_based) {
|
||||
ld r = hypot_d(DIM, m->inertia);
|
||||
nat = nat * rspintox(m->inertia) * xpush(r * delta) * spintox(m->inertia);
|
||||
}
|
||||
nat = nat * frontpush(delta * SCALE * m->vel / speedfactor());
|
||||
else
|
||||
nat = nat * frontpush(delta * SCALE * m->vel / speedfactor());
|
||||
cell *c2 = m->findbase(nat);
|
||||
|
||||
if(m->parent && isPlayer(m->parent) && markOrb(itOrbLava) && c2 != m->base && !isPlayerOn(m->base))
|
||||
@ -2410,6 +2496,8 @@ void moveBullet(monster *m, int delta) {
|
||||
if(!m->isVirtual) for(monster* m2: nonvirtual) {
|
||||
if(m2 == m || (m2 == m->parent && m->vel >= 0) || m2->parent == m->parent)
|
||||
continue;
|
||||
|
||||
if(m2->dead) continue;
|
||||
|
||||
eMonster ptype = parentOrSelf(m)->type;
|
||||
bool slayer = m->type == moCrushball ||
|
||||
@ -2424,9 +2512,9 @@ void moveBullet(monster *m, int delta) {
|
||||
// fireballs/airballs don't collide
|
||||
if(m->type == moFireball && m2->type == moFireball) continue;
|
||||
if(m->type == moAirball && m2->type == moAirball) continue;
|
||||
double d = intval(m2->pat*C0, m->pat*C0);
|
||||
double d = hdist(m2->pat*C0, m->pat*C0);
|
||||
|
||||
if(d < SCALE2 * 0.1) {
|
||||
if(d < collision_distance(m, m2)) {
|
||||
|
||||
if(m2->type == passive_switch) { m->dead = true; continue; }
|
||||
|
||||
@ -2526,6 +2614,10 @@ void moveBullet(monster *m, int delta) {
|
||||
multi::kills[cpid]--;
|
||||
mirrorspirits++;
|
||||
}
|
||||
if(m2->dead && m2->type == moAsteroid) {
|
||||
gainItem(itAsteroid);
|
||||
spawn_asteroids(m, m2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2553,6 +2645,8 @@ bool dragonbreath(cell *dragon) {
|
||||
|
||||
void moveMonster(monster *m, int delta) {
|
||||
|
||||
bool inertia_based = m->type == moAsteroid;
|
||||
|
||||
bool stunned = m->stunoff > curtime || m->blowoff > curtime;
|
||||
|
||||
if(stunned && cellUnstable(m->base))
|
||||
@ -2623,7 +2717,14 @@ void moveMonster(monster *m, int delta) {
|
||||
if(nearplayer) markOrb(itOrbBeauty), step /= 2;
|
||||
}
|
||||
|
||||
if(m->isVirtual) return;
|
||||
if(m->isVirtual) {
|
||||
if(m->type == moAsteroid) {
|
||||
ld r = hypot_d(DIM, m->inertia);
|
||||
transmatrix nat = m->pat * rspintox(m->inertia) * xpush(r * delta) * spintox(m->inertia);
|
||||
m->rebasePat(nat);
|
||||
}
|
||||
return;
|
||||
}
|
||||
transmatrix nat = m->pat;
|
||||
|
||||
if(stunned) {
|
||||
@ -2643,6 +2744,8 @@ void moveMonster(monster *m, int delta) {
|
||||
}
|
||||
|
||||
else if(m->type == moRagingBull && m->stunoff == CHARGING) ;
|
||||
|
||||
else if(m->type == moAsteroid) ;
|
||||
|
||||
else {
|
||||
|
||||
@ -2809,7 +2912,12 @@ void moveMonster(monster *m, int delta) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(DIM == 3 && igo) {
|
||||
if(inertia_based) {
|
||||
if(igo) return;
|
||||
ld r = hypot_d(DIM, m->inertia);
|
||||
nat = nat * rspintox(m->inertia) * xpush(r * delta) * spintox(m->inertia);
|
||||
}
|
||||
else if(DIM == 3 && igo) {
|
||||
ld fspin = rand() % 1000;
|
||||
nat = nat0 * cspin(1,2,fspin) * spin(igospan[igo]) * xpush(step) * spin(-igospan[igo]) * cspin(2,1,fspin);
|
||||
}
|
||||
@ -2818,7 +2926,7 @@ void moveMonster(monster *m, int delta) {
|
||||
}
|
||||
|
||||
if(m->type != moRagingBull && !peace::on)
|
||||
if(intval(nat*C0, goal*C0) >= intval(m->pat*C0, goal*C0) && !stunned && !carried) {
|
||||
if(intval(nat*C0, goal*C0) >= intval(m->pat*C0, goal*C0) && !stunned && !carried && !inertia_based) {
|
||||
igo++; goto igo_retry; }
|
||||
|
||||
for(int i=0; i<multi::players; i++) for(int b=0; b<2; b++) if(sword::orbcount(b)) {
|
||||
@ -2832,11 +2940,14 @@ void moveMonster(monster *m, int delta) {
|
||||
|
||||
monster* crashintomon = NULL;
|
||||
|
||||
if(!m->isVirtual) for(monster *m2: nonvirtual) if(m2!=m && m2->type != moBullet && m2->type != moArrowTrap) {
|
||||
if(!m->isVirtual && m->type != moAsteroid) for(monster *m2: nonvirtual) if(m2!=m && m2->type != moBullet && m2->type != moArrowTrap) {
|
||||
double d = intval(m2->pat*C0, nat*C0);
|
||||
if(d < SCALE2 * 0.1) crashintomon = m2;
|
||||
}
|
||||
|
||||
if(m->type == moAsteroid) for(int i=0; i<players; i++) if(pc[i] && hdist(tC0(pc[i]->pat), tC0(m->pat)) < collision_distance(pc[i], m))
|
||||
crashintomon = pc[i];
|
||||
|
||||
if(!peace::on)
|
||||
for(int i=0; i<players; i++)
|
||||
if(crashintomon == pc[i])
|
||||
@ -2862,7 +2973,7 @@ void moveMonster(monster *m, int delta) {
|
||||
}
|
||||
}
|
||||
|
||||
if(crashintomon) { igo++; goto igo_retry; }
|
||||
if(crashintomon && m->type != moAsteroid) { igo++; goto igo_retry; }
|
||||
|
||||
cell *c2 = m->findbase(nat);
|
||||
if(reflectflag & P_MIRRORWALL) reflect(c2, m->base, nat);
|
||||
@ -3129,6 +3240,9 @@ void activateMonstersAt(cell *c) {
|
||||
enemy->hitpoints = c->hitpoints;
|
||||
if(c->wall == waBoat && isLeader(c->monst))
|
||||
enemy->inBoat = true, c->wall = waSea;
|
||||
if(c->monst == moAsteroid) {
|
||||
enemy->inertia = random_spin() * point2(SCALE/3000., 0);
|
||||
}
|
||||
c->monst = moNone;
|
||||
active.push_back(enemy);
|
||||
}
|
||||
@ -3572,6 +3686,12 @@ bool drawMonster(const transmatrix& V, cell *c, const transmatrix*& Vboat, trans
|
||||
transmatrix t = view * spin(curtime / 50.0);
|
||||
queuepoly(mmscale(t, 1.15), shFlailMissile, (minf[m->type].color << 8) | 0xFF);
|
||||
ShadowV(view, shFlailMissile);
|
||||
break;
|
||||
}
|
||||
case moAsteroid: {
|
||||
transmatrix t = view * spin(curtime / 500.0);
|
||||
queuepoly(mmscale(t, 1.15), shAsteroid[m->hitpoints & 7], (minf[m->type].color << 8) | 0xFF);
|
||||
ShadowV(t, shAsteroid[m->hitpoints & 7]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@ bool canvas_invisible;
|
||||
int truelotus;
|
||||
int gamecount;
|
||||
|
||||
int asteroids_generated, asteroid_orbs_generated;
|
||||
|
||||
time_t timerstart, savetime;
|
||||
bool timerstopped;
|
||||
int savecount;
|
||||
@ -287,6 +289,8 @@ void initgame() {
|
||||
gen_wandering = true;
|
||||
}
|
||||
truelotus = 0;
|
||||
asteroids_generated = 0;
|
||||
asteroid_orbs_generated = 0;
|
||||
survivalist = true;
|
||||
#if CAP_CRYSTAL
|
||||
crystal::used_compass_inside = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user