Skip to content

Instantly share code, notes, and snippets.

@bluebear94
Last active August 12, 2019 18:01
Show Gist options
  • Save bluebear94/0d8307c8c95b378180ced1f5899cb694 to your computer and use it in GitHub Desktop.
Save bluebear94/0d8307c8c95b378180ced1f5899cb694 to your computer and use it in GitHub Desktop.
void TDRTestStage0::startBoss() {
tdr::EnemyHandle boss =
g->getEnemyList().createBoss(tdr::PV(416 - 32, 150), 24, 64);
boss.setTexcoords(agl::UIRect16{0, 0, 128, 128});
tdr::BossScene& scene = g->registerBossScene(boss);
scene.setId(0);
scene.addBossAttack(
0,
{
/* .handler = */ [=, &scene]() {
std::cerr << "nonspell 1\n";
const tdr::BossAttack* at = scene.currentAttack();
kcr::Manager& man = getManager();
man.spawn([=, &scene]() {
tdr::BulletList& bl = g->getBulletList();
int counter = 0;
int nFrames = 0;
while (true) {
counter += 10;
while (counter >= 100) {
kfp::s16_16 x =
g->getRng().next<kfp::s16_16>(0, g->getDimensions().x);
kfp::frac32 a = g->getRng().next<kfp::frac32>(
"0.245"_frac32, "0.255"_frac32);
if (scene.currentAttack() != at) return;
bl.createLooseLaser(
tdr::PV(x, 0), 3, a, 100, 8, shot::greenBall, 0);
counter -= 100;
}
kcr::yield();
++nFrames;
}
});
man.spawn([=, &scene]() {
tdr::BulletList& bl = g->getBulletList();
while (true) {
if (scene.currentAttack() != at) return;
kfp::frac32 angle =
kfp::frac32::raw(g->getRng().getBits<uint32_t, 32>());
bl.createShotA1(
boss.getPosition(), 3, angle, shot::purpleBall, 0);
kcr::yield();
}
});
man.spawn(
[=, &scene](tdr::EnemyHandle boss) {
auto& rng = g->getRng();
while (true) {
tdr::cwait(90);
if (scene.currentAttack() != at) return;
tdr::PV destination = {
rng.next<kfp::s16_16>(50, g->getDimensions().x - 50),
rng.next<kfp::s16_16>(50, 350)};
tdr::moveTowardAtSpeed(boss, destination, 5, [=, &scene]() {
return scene.currentAttack() == at;
});
}
},
boss);
},
/* .score = */ 0, // nonspell
/* .startTime = */ 60 * 60,
/* .health = */ 5000,
/* .id = */ 0,
/* .isTimeout = */ false,
});
scene.addBossAttack(
0,
{
/* .handler = */ [=, &scene]() {
// Port of Vija's first spell in NTP
std::cerr << "spell 1\n";
const tdr::BossAttack* at = scene.currentAttack();
kcr::Manager& man = getManager();
tdr::PV centre = g->getPlayfield().getDimensions() / 2;
man.spawn(
[=, &scene](tdr::EnemyHandle boss) {
tdr::PV destination = centre;
tdr::moveTowardAtSpeed(boss, destination, 5, [=, &scene]() {
return scene.currentAttack() == at;
});
},
boss);
man.spawn([=, &scene]() {
using namespace kfp::literals;
int width = g->getPlayfield().getWidth();
int height = g->getPlayfield().getHeight();
tdr::BulletList& bl = g->getBulletList();
int d = 1;
int graphPeriod = 5 - d / 2;
// This is doubled from the original source code, because
// TDRTest runs at twice the resolution of NTP.
kfp::s16_16 graphInterval = 30 - "2.6"_s16_16 * d;
int ways = 8 + 2 * d;
kfp::frac32 phi;
/* local */ {
tdr::PV src = boss.getPosition(),
dest = g->getPlayer().getPosition();
tdr::PV d = dest - src;
kfp::s16_16 l;
kfp::rectp(d.x, d.y, l, phi);
}
kfp::frac32 theta = phi;
kfp::frac32 phase = 0;
tdr::BulletHandle orb =
bl.createShotA1(centre, 4, theta, shot::orangeBubble, 0);
orb.setSpellResistant(true);
orb.setDeleteWhenOutOfBounds(false);
int r = 200 + 40 * d;
kfp::frac32 av = kfp::frac32::raw(11930464 + 5965232 * d);
tdr::cwait(r / 4);
kfp::s16_16 x = 0;
kfp::frac32 ss = "0.25"_frac32;
kfp::s16_16 gs = "0.9"_s16_16 - "0.15"_s16_16 * d;
kfp::s16_16 gss = 2 + "0.2"_s16_16 * d;
for (size_t frame = 0; scene.currentAttack() == at; ++frame) {
theta += av;
phase += av * "3.1729"_u16_16;
kfp::s2_30 c, s;
kfp::sincos(phase, c, s);
kfp::s16_16 rp = (1 + "0.2"_s16_16 * s) * r;
kfp::sincos(theta, c, s);
orb.setPosition(boss.getPosition() + tdr::PV{rp * c, rp * s});
if (frame % 30 == 0) {
kfp::frac32 a = g->getRng().next<kfp::frac32>();
for (int i = 0; i < ways; ++i) {
bl.createShotA1(orb.getPosition(), 2, a, shot::redStar, 0);
a += kfp::frac32::raw((uint32_t)((1LL << 32) / ways));
}
}
if (frame % graphPeriod == 0) {
kfp::frac32 angleToPlayer;
/* local */ {
tdr::PV src = orb.getPosition(),
dest = g->getPlayer().getPosition();
tdr::PV d = dest - src;
kfp::s16_16 l;
kfp::rectp(d.x, d.y, l, angleToPlayer);
}
kfp::s16_16 y =
(kfp::s16_16)(kfp::u16_16(height) * angleToPlayer);
tdr::BulletHandle shot =
bl.createShotA1({x, y}, 0, ss, shot::orangeMissile, 30);
kcr::spawn(
[=,
graph = (s > 0) ? shot::redMissile : shot::blueMissile](
tdr::BulletHandle shot) {
tdr::cwait(90);
if (shot.isMarkedForDeletion()) return;
shot.setSpeed((1 + gs) * gss);
shot.setGraphic(graph);
},
shot);
ss = -ss;
x += graphInterval;
if (x > width) x -= width;
}
kcr::yield();
}
});
},
/* .score = */ 4'000'000,
/* .startTime = */ 60 * 60,
/* .health = */ 14000,
/* .id = */ 1,
/* .isTimeout = */ false,
});
scene.addBossAttack(
1,
{
/* .handler = */ [=, &scene]() {
std::cerr << "spell 2\n";
const tdr::BossAttack* at = scene.currentAttack();
kcr::Manager& man = getManager();
man.spawn(
[=, &scene](tdr::EnemyHandle boss) {
using namespace kfp::literals;
auto& rng = g->getRng();
tdr::BulletList& bl = g->getBulletList();
while (true) {
tdr::cwait(90);
if (scene.currentAttack() != at) return;
tdr::PV destination = {
rng.next<kfp::s16_16>(50, g->getDimensions().x - 50),
rng.next<kfp::s16_16>(50, 350)};
tdr::moveTowardAtSpeed(boss, destination, 7, [=, &scene]() {
return scene.currentAttack() == at;
});
if (scene.currentAttack() != at) return;
for (size_t i = 0; i < 15; ++i) {
kfp::s16_16 speed = rng.next("7.5"_s16_16, "11.5"_s16_16);
kfp::frac32 angle = rng.next<kfp::frac32>();
bl.createShotA1(
boss.getPosition(), speed, angle, shot::pulsatingOrb,
15);
}
for (size_t i = 0; i < 15; ++i) {
kfp::s16_16 speed = rng.next("2.5"_s16_16, "5.5"_s16_16);
kfp::frac32 angle = rng.next<kfp::frac32>();
bl.createShotA1(
boss.getPosition(), speed, angle, shot::pulsatingOrb,
15);
}
}
},
boss);
man.spawn([=, &scene]() {
using namespace kfp::literals;
tdr::BulletList& bl = g->getBulletList();
auto& rng = g->getRng();
tdr::cwait(120);
while (true) {
if (scene.currentAttack() != at) return;
kfp::frac32 angle = rng.next<kfp::frac32>();
bl.createLooseLaser(
boss.getPosition() + tdr::PV{-30, -10}, 6, angle, 150, 8,
shot::blueMissile, 0);
angle = rng.next<kfp::frac32>();
bl.createLooseLaser(
boss.getPosition() + tdr::PV{30, -10}, 6, angle, 150, 8,
shot::blueMissile, 0);
tdr::cwait(10);
}
});
},
/* .score = */ 4'500'000,
/* .startTime = */ 75 * 60,
/* .health = */ 9000,
/* .id = */ 2,
/* .isTimeout = */ false,
});
getManager().spawn([boss, g = this->g]() {
while (!boss.isMarkedForDeletion()) { kcr::yield(); }
tdr::cwait(240);
g->finishStage();
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment