ref: 26bcbdbef7fdfbe83d9d63f6daff81a44a588ad6
parent: 88947cd016699382cd99d7cbf306e18cb6a5fb50
author: Clownacy <[email protected]>
date: Fri Feb 8 16:30:08 EST 2019
Added more NPCs Now with Muscle Doctor
--- a/src/NpcAct.h
+++ b/src/NpcAct.h
@@ -258,11 +258,21 @@
void ActNpc253(NPCHAR *npc);
void ActNpc254(NPCHAR *npc);
void ActNpc255(NPCHAR *npc);
-
+void ActNpc256(NPCHAR *npc);
+void ActNpc257(NPCHAR *npc);
+void ActNpc258(NPCHAR *npc);
void ActNpc259(NPCHAR *npc);
-
+void ActNpc260(NPCHAR *npc);
+void ActNpc261(NPCHAR *npc);
+void ActNpc262(NPCHAR *npc);
+void ActNpc263(NPCHAR *npc);
+void ActNpc264(NPCHAR *npc);
+void ActNpc265(NPCHAR *npc);
+void ActNpc266(NPCHAR *npc);
+void ActNpc267(NPCHAR *npc);
void ActNpc268(NPCHAR *npc);
-
+void ActNpc269(NPCHAR *npc);
+void ActNpc270(NPCHAR *npc);
void ActNpc271(NPCHAR *npc);
void ActNpc272(NPCHAR *npc);
void ActNpc273(NPCHAR *npc);
--- a/src/NpcAct240.cpp
+++ b/src/NpcAct240.cpp
@@ -1193,6 +1193,167 @@
npc->rect = rcRight[npc->ani_no];
}
+//Doctor (facing away)
+void ActNpc256(NPCHAR *npc)
+{
+ RECT rcLeft[6];
+
+ rcLeft[0] = {48, 160, 72, 192};
+ rcLeft[1] = {72, 160, 96, 192};
+ rcLeft[2] = {0, 128, 24, 160};
+ rcLeft[3] = {24, 128, 48, 160};
+ rcLeft[4] = {0, 160, 24, 192};
+ rcLeft[5] = {24, 160, 48, 192};
+
+ switch ( npc->act_no )
+ {
+ case 0:
+ gSuperXpos = 0;
+ npc->act_no = 1;
+ npc->y -= 0x1000;
+ // Fallthrough
+ case 1:
+ npc->ani_no = 0;
+ break;
+
+ case 10:
+ npc->act_no = 11;
+ npc->ani_wait = 0;
+ npc->ani_no = 0;
+ npc->count1 = 0;
+ // Fallthrough
+ case 11:
+ if (++npc->ani_wait > 5)
+ {
+ npc->ani_wait = 0;
+ ++npc->ani_no;
+ }
+
+ if (npc->ani_no > 1)
+ {
+ npc->ani_no = 0;
+ ++npc->count1;
+ }
+
+ if (npc->count1 > 5)
+ npc->act_no = 1;
+
+ break;
+
+ case 20:
+ npc->act_no = 21;
+ // Fallthrough
+ case 21:
+ npc->ani_no = 2;
+ break;
+
+ case 40:
+ npc->act_no = 41;
+ SetNpChar(257, npc->x - 0x1C00, npc->y - 0x2000, 0, 0, 0, 0, 0x100);
+ SetNpChar(257, npc->x - 0x1C00, npc->y - 0x2000, 0, 0, 2, 0, 0xAA);
+ // Fallthrough
+ case 41:
+ npc->ani_no = 4;
+ break;
+
+ case 50:
+ npc->act_no = 51;
+ npc->ani_wait = 0;
+ npc->ani_no = 4;
+ npc->count1 = 0;
+ // Fallthrough
+ case 51:
+ if (++npc->ani_wait > 5)
+ {
+ npc->ani_wait = 0;
+ ++npc->ani_no;
+ }
+
+ if (npc->ani_no > 5)
+ {
+ npc->ani_no = 4;
+ ++npc->count1;
+ }
+
+ if (npc->count1 > 5)
+ npc->act_no = 41;
+
+ break;
+ }
+
+ npc->rect = rcLeft[npc->ani_no];
+}
+
+//Red crystal
+void ActNpc257(NPCHAR *npc)
+{
+ RECT rc[3];
+
+ rc[0] = {176, 32, 184, 48};
+ rc[1] = {184, 32, 192, 48};
+ rc[2] = {0, 0, 0, 0};
+
+ switch (npc->act_no)
+ {
+ case 0:
+ npc->act_no = 1;
+ // Fallthrough
+ case 1:
+ if (gSuperXpos)
+ npc->act_no = 10;
+
+ break;
+
+ case 10:
+ if (npc->x < gSuperXpos)
+ npc->xm += 0x55;
+ if (npc->x > gSuperXpos)
+ npc->xm -= 0x55;
+
+ if (npc->y < gSuperYpos)
+ npc->ym += 0x55;
+ if (npc->y > gSuperYpos)
+ npc->ym -= 0x55;
+
+ if (npc->xm > 0x400)
+ npc->xm = 0x400;
+ if (npc->xm < -0x400)
+ npc->xm = -0x400;
+
+ if (npc->ym > 0x400)
+ npc->ym = 0x400;
+ if (npc->ym < -0x400)
+ npc->ym = -0x400;
+
+ npc->x += npc->xm;
+ npc->y += npc->ym;
+ break;
+ }
+
+ if (++npc->ani_wait > 3)
+ {
+ npc->ani_wait = 0;
+ ++npc->ani_no;
+ }
+
+ if (npc->ani_no > 1)
+ npc->ani_no = 0;
+
+ if (npc->direct == 0 && npc->xm > 0)
+ npc->ani_no = 2;
+ if (npc->direct == 2 && npc->xm < 0)
+ npc->ani_no = 2;
+
+ npc->rect = rc[npc->ani_no];
+}
+
+//Mimiga (sleeping)
+void ActNpc258(NPCHAR *npc)
+{
+ RECT rc = {48, 32, 64, 48};
+ npc->rect = rc;
+}
+
//Curly (carried and unconcious)
void ActNpc259(NPCHAR *npc)
{
--- a/src/NpcAct260.cpp
+++ b/src/NpcAct260.cpp
@@ -11,7 +11,1099 @@
#include "Caret.h"
#include "Map.h"
#include "Frame.h"
+#include "MycParam.h"
+//Shovel Brigade (caged)
+void ActNpc260(NPCHAR *npc)
+{
+ RECT rcLeft[3];
+ RECT rcRight[3];
+
+ rcLeft[0] = {128, 64, 144, 80};
+ rcLeft[1] = {144, 64, 160, 80};
+ rcLeft[2] = {224, 64, 240, 80};
+
+ rcRight[0] = {128, 80, 144, 96};
+ rcRight[1] = {144, 80, 160, 96};
+ rcRight[2] = {224, 80, 240, 96};
+
+ switch (npc->act_no)
+ {
+ case 0:
+ npc->x += 0x200;
+ npc->y -= 0x400;
+ npc->act_no = 1;
+ npc->ani_no = 0;
+ npc->ani_wait = 0;
+ // Fallthrough
+ case 1:
+ if (Random(0, 160) == 1)
+ {
+ npc->act_no = 2;
+ npc->act_wait = 0;
+ npc->ani_no = 1;
+ }
+
+ break;
+
+ case 2:
+ if (++npc->act_wait > 12)
+ {
+ npc->act_no = 1;
+ npc->ani_no = 0;
+ }
+
+ break;
+
+ case 10:
+ npc->act_no = 11;
+ npc->ani_no = 2;
+ SetNpChar(87, npc->x, npc->y - 0x2000, 0, 0, 0, 0, 0x100);
+
+ break;
+ }
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+
+ if (npc->direct == 0)
+ npc->rect = rcLeft[npc->ani_no];
+ else
+ npc->rect = rcRight[npc->ani_no];
+}
+
+//Chie (caged)
+void ActNpc261(NPCHAR *npc)
+{
+ RECT rcLeft[2];
+ RECT rcRight[2];
+
+ rcLeft[0] = {112, 32, 128, 48};
+ rcLeft[1] = {128, 32, 144, 48};
+
+ rcRight[0] = {112, 48, 128, 64};
+ rcRight[1] = {128, 48, 144, 64};
+
+ switch (npc->act_no)
+ {
+ case 0:
+ npc->x -= 0x200;
+ npc->y -= 0x400;
+ npc->act_no = 1;
+ npc->ani_no = 0;
+ npc->ani_wait = 0;
+ // Fallthrough
+ case 1:
+ if (Random(0, 160) == 1)
+ {
+ npc->act_no = 2;
+ npc->act_wait = 0;
+ npc->ani_no = 1;
+ }
+
+ break;
+
+ case 2:
+ if (++npc->act_wait > 12 )
+ {
+ npc->act_no = 1;
+ npc->ani_no = 0;
+ }
+
+ break;
+ }
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+
+ if (npc->direct == 0)
+ npc->rect = rcLeft[npc->ani_no];
+ else
+ npc->rect = rcRight[npc->ani_no];
+}
+
+//Chaco (caged)
+void ActNpc262(NPCHAR *npc)
+{
+ RECT rcLeft[2];
+ RECT rcRight[2];
+
+ rcLeft[0] = {128, 0, 144, 16};
+ rcLeft[1] = {144, 0, 160, 16};
+
+ rcRight[0] = {128, 16, 144, 32};
+ rcRight[1] = {144, 16, 160, 32};
+
+ switch (npc->act_no)
+ {
+ case 0:
+ npc->x -= 0x200;
+ npc->y -= 0x400;
+ npc->act_no = 1;
+ npc->ani_no = 0;
+ npc->ani_wait = 0;
+ // Fallthrough
+ case 1:
+ if (Random(0, 160) == 1)
+ {
+ npc->act_no = 2;
+ npc->act_wait = 0;
+ npc->ani_no = 1;
+ }
+
+ break;
+
+ case 2:
+ if (++npc->act_wait > 12)
+ {
+ npc->act_no = 1;
+ npc->ani_no = 0;
+ }
+
+ break;
+ }
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+
+ if (npc->direct == 0)
+ npc->rect = rcLeft[npc->ani_no];
+ else
+ npc->rect = rcRight[npc->ani_no];
+}
+
+//Doctor (boss)
+void ActNpc263(NPCHAR *npc)
+{
+ RECT rcLeft[9];
+ RECT rcRight[9];
+
+ rcLeft[0] = {0, 0, 24, 32};
+ rcLeft[1] = {24, 0, 48, 32};
+ rcLeft[2] = {48, 0, 72, 32};
+ rcLeft[3] = {0, 0, 0, 0};
+ rcLeft[4] = {72, 0, 96, 32};
+ rcLeft[5] = {96, 0, 120, 32};
+ rcLeft[6] = {120, 0, 144, 32};
+ rcLeft[7] = {144, 0, 168, 32};
+ rcLeft[8] = {264, 0, 288, 32};
+
+ rcRight[0] = {0, 32, 24, 64};
+ rcRight[1] = {24, 32, 48, 64};
+ rcRight[2] = {48, 32, 72, 64};
+ rcRight[3] = {0, 0, 0, 0};
+ rcRight[4] = {72, 32, 96, 64};
+ rcRight[5] = {96, 32, 120, 64};
+ rcRight[6] = {120, 32, 144, 64};
+ rcRight[7] = {144, 32, 168, 64};
+ rcRight[8] = {264, 32, 288, 64};
+
+ switch (npc->act_no)
+ {
+ case 0:
+ npc->act_no = 1;
+ npc->y += 0x1000;
+ npc->ani_no = 3;
+ break;
+
+ case 2:
+ if (++npc->act_wait / 2 & 1)
+ npc->ani_no = 0;
+ else
+ npc->ani_no = 3;
+
+ if (npc->act_wait > 50)
+ npc->act_no = 10;
+
+ break;
+
+ case 10:
+ npc->ym += 0x80;
+ npc->bits |= 0x20;
+ npc->damage = 3;
+
+ if (npc->flag & 8)
+ {
+ npc->act_no = 20;
+ npc->act_wait = 0;
+ npc->ani_no = 0;
+ npc->count2 = npc->life;
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+ }
+
+ break;
+
+ case 20:
+ if (++npc->act_wait < 50 && npc->life < npc->count2 - 20)
+ npc->act_wait = 50;
+
+ if (npc->act_wait == 50)
+ {
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+
+ npc->ani_no = 4;
+ }
+
+ if (npc->act_wait == 80)
+ {
+ npc->ani_no = 5;
+ PlaySoundObject(25, 1);
+
+ if (npc->direct == 0)
+ {
+ SetNpChar(264, npc->x - 0x2000, npc->y, 0, 0, 0, 0, 0x100);
+ SetNpChar(264, npc->x - 0x2000, npc->y, 0, 0, 0x400, 0, 0x100);
+ }
+ else
+ {
+ SetNpChar(264, npc->x + 0x2000, npc->y, 0, 0, 2, 0, 0x100);
+ SetNpChar(264, npc->x + 0x2000, npc->y, 0, 0, 2 + 0x400, 0, 0x100);
+ }
+ }
+
+ if (npc->act_wait == 120)
+ npc->ani_no = 0;
+
+ if (npc->act_wait > 130 && npc->life < npc->count2 - 50)
+ npc->act_wait = 161;
+
+ if (npc->act_wait > 160)
+ {
+ npc->act_no = 100;
+ npc->ani_no = 0;
+ }
+
+ break;
+
+ case 30:
+ npc->act_no = 31;
+ npc->act_wait = 0;
+ npc->ani_no = 6;
+ npc->tgt_x = npc->x;
+ npc->bits |= 0x20;
+ // Fallthrough
+ case 31:
+ if (++npc->act_wait / 2 & 1)
+ npc->x = npc->tgt_x;
+ else
+ npc->x = npc->tgt_x + 0x200;
+
+ if (npc->act_wait > 50)
+ {
+ npc->act_no = 32;
+ npc->act_wait = 0;
+ npc->ani_no = 7;
+ PlaySoundObject(101, 1);
+
+ for (int deg = 8; deg < 0x100; deg += 0x10)
+ {
+ const int xm = 2 * GetCos(deg);
+ const int ym = 2 * GetSin(deg);
+ SetNpChar(266, npc->x, npc->y, xm, ym, 0, 0, 0x100);
+ }
+ }
+
+ break;
+
+ case 32:
+ if (++npc->act_wait > 50)
+ npc->act_no = 100;
+
+ break;
+
+ case 100:
+ npc->act_no = 101;
+ npc->bits &= ~0x20;
+ npc->damage = 0;
+ npc->act_wait = 0;
+ PlaySoundObject(29, 1);
+ // Fallthrough
+ case 101:
+ npc->act_wait += 2;
+
+ if (npc->act_wait > 16)
+ {
+ npc->act_no = 102;
+ npc->act_wait = 0;
+ npc->ani_no = 3;
+ npc->tgt_x = Random(5, 35) * 0x2000;
+ npc->tgt_y = Random(5, 7) * 0x2000;
+ }
+
+ break;
+
+ case 102:
+ if (++npc->act_wait > 40 )
+ {
+ npc->act_no = 103;
+ npc->act_wait = 16;
+ npc->ani_no = 2;
+ npc->ym = 0;
+ npc->x = npc->tgt_x;
+ npc->y = npc->tgt_y;
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+ }
+
+ break;
+
+ case 103:
+ npc->act_wait -= 2;
+
+ if ( npc->act_wait <= 0 )
+ {
+ npc->bits |= 0x20;
+ npc->damage = 3;
+
+ if (npc->count1 < 3)
+ {
+ ++npc->count1;
+ npc->act_no = 10;
+ }
+ else
+ {
+ npc->count1 = 0;
+ npc->act_no = 30;
+ }
+ }
+
+ break;
+
+ case 500:
+ npc->bits &= ~0x20;
+ npc->ani_no = 6;
+ npc->ym += 0x10;
+
+ if (npc->flag & 8)
+ {
+ npc->act_no = 501;
+ npc->act_wait = 0;
+ npc->tgt_x = npc->x;
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+ }
+
+ break;
+
+ case 501:
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+
+ npc->ani_no = 8;
+
+ if (++npc->act_wait / 2 & 1)
+ npc->x = npc->tgt_x;
+ else
+ npc->x = npc->tgt_x + 0x200;
+
+ break;
+ }
+
+ if (npc->act_no >= 10)
+ {
+ if (npc->act_no == 102)
+ {
+ gSuperXpos = npc->tgt_x;
+ gSuperYpos = npc->tgt_y;
+ }
+ else
+ {
+ gSuperXpos = npc->x;
+ gSuperYpos = npc->y;
+ }
+ }
+
+ if (npc->ym > 0x5FF)
+ npc->ym = 0x5FF;
+
+ npc->x += npc->xm;
+ npc->y += npc->ym;
+
+ if (npc->direct == 0)
+ npc->rect = rcLeft[npc->ani_no];
+ else
+ npc->rect = rcRight[npc->ani_no];
+
+ if (npc->act_no == 101 || npc->act_no == 103)
+ {
+ npc->rect.top += npc->act_wait;
+ npc->rect.bottom -= npc->act_wait;
+ npc->view.top = (16 - npc->act_wait) << 9;
+ }
+ else
+ {
+ npc->view.top = 0x2000;
+ }
+}
+
+//Doctor red wave (projectile)
+void ActNpc264(NPCHAR *npc)
+{
+ RECT rc = {288, 0, 304, 16};
+
+ if (npc->x < 0 || npc->x > gMap.width * 0x2000)
+ {
+ VanishNpChar(npc);
+ return;
+ }
+
+ switch (npc->act_no)
+ {
+ case 0:
+ npc->act_no = 1;
+ npc->tgt_x = npc->x;
+ npc->tgt_y = npc->y;
+ npc->count1 = npc->direct / 8;
+ npc->direct &= 7;
+ // Fallthrough
+ case 1:
+ npc->count1 += 6;
+ npc->count1 &= 0xFF;
+ const unsigned char deg = npc->count1;
+
+ if (npc->act_wait < 128)
+ ++npc->act_wait;
+
+ if (npc->direct == 0)
+ npc->xm -= 21;
+ else
+ npc->xm += 21;
+
+ npc->tgt_x += npc->xm;
+
+ npc->x = npc->tgt_x + npc->act_wait * GetCos(deg) / 8;
+ npc->y = npc->tgt_y + npc->act_wait * GetSin(deg) / 2;
+
+ SetNpChar(265, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+
+ break;
+ }
+
+ npc->rect = rc;
+}
+
+//Doctor red ball projectile
+void ActNpc265(NPCHAR *npc)
+{
+ RECT rc[3];
+
+ rc[0] = {288, 16, 304, 32};
+ rc[1] = {288, 32, 304, 48};
+ rc[2] = {288, 48, 304, 64};
+
+ if (++npc->ani_wait > 3)
+ {
+ npc->ani_wait = 0;
+ ++npc->ani_no;
+ }
+
+ if (npc->ani_no > 2)
+ npc->cond = 0;
+ else
+ npc->rect = rc[npc->ani_no];
+}
+
+//Doctor red ball projectile (bouncing)
+void ActNpc266(NPCHAR *npc)
+{
+ RECT rc[2];
+
+ rc[0] = {304, 16, 320, 32};
+ rc[1] = {304, 32, 320, 48};
+
+ if (npc->flag & 1)
+ npc->xm = -npc->xm;
+ if (npc->flag & 4)
+ npc->xm = -npc->xm;
+
+ if (npc->flag & 2)
+ npc->ym = 0x200;
+ if (npc->flag & 8)
+ npc->ym = -0x200;
+
+ npc->x += npc->xm;
+ npc->y += npc->ym;
+
+ if (++npc->ani_no > 1)
+ npc->ani_no = 0;
+
+ npc->rect = rc[npc->ani_no];
+
+ if (++npc->act_wait % 4 == 1)
+ SetNpChar(265, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+
+ if (npc->act_wait > 250)
+ VanishNpChar(npc);
+}
+
+//Muscle Doctor
+void ActNpc267(NPCHAR *npc)
+{
+ RECT rcLeft[10];
+ RECT rcRight[10];
+
+ rcLeft[0] = {0, 0, 0, 0};
+ rcLeft[1] = {0, 64, 40, 112};
+ rcLeft[2] = {40, 64, 80, 112};
+ rcLeft[3] = {80, 64, 120, 112};
+ rcLeft[4] = {120, 64, 160, 112};
+ rcLeft[5] = {160, 64, 200, 112};
+ rcLeft[6] = {200, 64, 240, 112};
+ rcLeft[7] = {240, 64, 280, 112};
+ rcLeft[8] = {280, 64, 320, 112};
+ rcLeft[9] = {0, 160, 40, 208};
+
+ rcRight[0] = {0, 0, 0, 0};
+ rcRight[1] = {0, 112, 40, 160};
+ rcRight[2] = {40, 112, 80, 160};
+ rcRight[3] = {80, 112, 120, 160};
+ rcRight[4] = {120, 112, 160, 160};
+ rcRight[5] = {160, 112, 200, 160};
+ rcRight[6] = {200, 112, 240, 160};
+ rcRight[7] = {240, 112, 280, 160};
+ rcRight[8] = {280, 112, 320, 160};
+ rcRight[9] = {40, 160, 80, 208};
+
+ switch (npc->act_no)
+ {
+ case 0:
+ if (gMC.x < gSuperXpos)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+
+ if (npc->direct == 0)
+ npc->x = gSuperXpos - 0xC00;
+ else
+ npc->x = gSuperXpos + 0xC00;
+
+ npc->y = gSuperYpos;
+ // Fallthrough
+ case 1:
+ npc->act_no = 2;
+ // Fallthrough
+ case 2:
+ npc->ym += 0x80;
+
+ if (++npc->act_wait / 2 % 2)
+ npc->ani_no = 0;
+ else
+ npc->ani_no = 3;
+
+ break;
+
+ case 5:
+ npc->act_no = 6;
+ npc->ani_no = 1;
+ npc->ani_wait = 0;
+ // Fallthrough
+ case 6:
+ npc->ym += 0x80;
+
+ if (++npc->ani_wait > 40)
+ {
+ npc->ani_wait = 0;
+ ++npc->ani_no;
+ }
+
+ if (npc->ani_no > 2)
+ npc->ani_no = 1;
+
+ break;
+
+ case 7:
+ npc->act_no = 8;
+ npc->act_wait = 0;
+ npc->ani_no = 3;
+ // Fallthrough
+ case 8:
+ npc->ym += 0x40;
+
+ if (++npc->act_wait > 40)
+ npc->act_no = 10;
+
+ break;
+
+ case 10:
+ npc->bits |= 4;
+ npc->xm = 0;
+ npc->act_no = 11;
+ npc->act_wait = 0;
+ npc->ani_no = 1;
+ npc->ani_wait = 0;
+ npc->count2 = npc->life;
+ // Fallthrough
+ case 11:
+ npc->ym += 0x80;
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+
+ if (npc->flag & 8)
+ {
+ if (npc->life >= npc->count2 - 20)
+ {
+ if (++npc->ani_wait > 10)
+ {
+ npc->ani_wait = 0;
+
+ if (++npc->ani_no > 2)
+ npc->ani_no = 1;
+ }
+ }
+ else if (gMC.flag & 8 && gMC.x > npc->x - 0x6000 && gMC.x < npc->x + 0x6000 && npc->ani_no != 6)
+ {
+ npc->ani_no = 6;
+ DamageMyChar(5);
+ SetQuake(10);
+ PlaySoundObject(26, 1);
+ gMC.ym = -0x400;
+
+ if (gMC.x < npc->x)
+ gMC.xm = -0x5FF;
+ else
+ gMC.xm = 0x5FF;
+
+ for (int i = 0; i < 100; ++i)
+ SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y + (Random(-0x10, 0x10) * 0x200), 3 * Random(-0x200, 0x200), 3 * Random(-0x200, 0x200), 3, 0, 0xAA);
+ }
+ }
+ else
+ {
+ npc->ani_no = 4;
+ }
+
+ if (++npc->act_wait > 30 || npc->life < npc->count2 - 20)
+ {
+ if (++npc->count1 > 10)
+ npc->count1 = 0;
+
+ switch (npc->count1)
+ {
+ case 8:
+ npc->act_no = 20;
+ break;
+ case 2:
+ case 7:
+ npc->act_no = 100;
+ break;
+ case 3:
+ case 6:
+ npc->act_no = 30;
+ break;
+ case 1:
+ case 9:
+ npc->act_no = 40;
+ break;
+ default:
+ npc->act_no = 15;
+ npc->act_wait = 0;
+ break;
+ }
+ }
+
+ break;
+
+ case 15:
+ npc->ani_no = 3;
+ ++npc->act_wait;
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+
+ if (npc->act_wait > 20)
+ {
+ npc->act_no = 16;
+ npc->ani_no = 4;
+ npc->ani_wait = 0;
+ npc->ym = -0x600;
+
+ if (npc->direct == 0)
+ npc->xm = -0x400;
+ else
+ npc->xm = 0x400;
+ }
+
+ break;
+
+ case 16:
+ npc->ym += 0x40;
+
+ if (++npc->ani_wait > 1)
+ {
+ npc->ani_wait = 0;
+ ++npc->ani_no;
+ }
+
+ if (npc->ani_no > 5)
+ npc->ani_no = 4;
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+
+ if (npc->ym > 0 && npc->flag & 8)
+ npc->act_no = 17;
+
+ break;
+
+ case 17:
+ npc->act_no = 18;
+ npc->act_wait = 0;
+ SetQuake(10);
+ PlaySoundObject(26, 1);
+ // Fallthrough
+ case 18:
+ npc->ani_no = 3;
+ ++npc->act_wait;
+
+ npc->xm = 7 * npc->xm / 8;
+ npc->ym += 0x80;
+
+ if (npc->act_wait > 10)
+ npc->act_no = 10;
+
+ break;
+
+ case 20:
+ npc->act_no = 21;
+ npc->act_wait = 0;
+ // Fallthrough
+ case 21:
+ ++npc->act_wait;
+ npc->ani_no = 6;
+
+ if (npc->act_wait > 20 && npc->act_wait % 3 == 1)
+ {
+ const int ym = Random(-0x200u, 0x200);
+ const int xm = 4 * Random(0x100, 0x200);
+
+ if (npc->direct == 0)
+ SetNpChar(269, npc->x - 0x1000, npc->y - 0x800, -xm, ym, 0, 0, 0x100);
+ else
+ SetNpChar(269, npc->x + 0x1000, npc->y - 0x800, xm, ym, 2, 0, 0x100);
+
+ PlaySoundObject(39, 1);
+ }
+
+ if ( npc->act_wait > 90 )
+ npc->act_no = 10;
+
+ break;
+
+ case 30:
+ npc->act_no = 31;
+ npc->act_wait = 0;
+ npc->bits |= 1;
+ npc->bits &= ~0x20;
+ // Fallthrough
+ case 31:
+ npc->ani_no = 3;
+
+ if (++npc->act_wait > 20)
+ {
+ npc->act_no = 32;
+ npc->act_wait = 0;
+ npc->ani_no = 7;
+ npc->bits |= 0x80;
+ npc->damage = 10;
+ PlaySoundObject(25, 1);
+
+ if (npc->direct == 0)
+ npc->xm = -0x5FF;
+ else
+ npc->xm = 0x5FF;
+ }
+
+ break;
+
+ case 32:
+ ++npc->act_wait;
+ npc->ym = 0;
+
+ if (npc->act_wait / 2 % 2)
+ npc->ani_no = 7;
+ else
+ npc->ani_no = 8;
+
+ if (npc->act_wait > 30)
+ {
+ npc->act_wait = 0;
+ npc->act_no = 18;
+ npc->damage = 5;
+ npc->bits &= ~0x81;
+ npc->bits |= 0x20;
+ }
+
+ if (npc->flag & 1 || npc->flag & 4)
+ {
+ npc->act_no = 15;
+ npc->act_wait = 0;
+ npc->damage = 5;
+ npc->bits &= ~0x81;
+ npc->bits |= 0x20;
+ }
+
+ break;
+
+ case 40:
+ npc->ani_no = 3;
+ ++npc->act_wait;
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+
+ if (npc->act_wait > 20)
+ {
+ npc->act_no = 41;
+ npc->ani_no = 4;
+ npc->ani_wait = 0;
+ npc->ym = -0x800;
+
+ if (npc->direct == 0)
+ npc->xm = -0x400;
+ else
+ npc->xm = 0x400;
+ }
+
+ break;
+
+ case 41:
+ npc->ym += 0x40;
+
+ if (++npc->ani_wait > 1)
+ {
+ npc->ani_wait = 0;
+ ++npc->ani_no;
+ }
+
+ if (npc->ani_no > 5)
+ npc->ani_no = 4;
+
+ if (gMC.y > npc->y && gMC.x > npc->x - 0x1000 && gMC.x < npc->x + 0x1000)
+ {
+ npc->act_no = 16;
+ npc->ym = 0x5FF;
+ npc->xm = 0;
+ }
+
+ if (npc->ym > 0 && npc->flag & 8)
+ npc->act_no = 17;
+
+ break;
+
+ case 100:
+ npc->act_no = 101;
+ npc->act_wait = 0;
+ npc->bits &= ~0x24;
+ npc->damage = 0;
+ PlaySoundObject(29, 1);
+ // Fallthrough
+ case 101:
+ npc->act_wait += 2;
+
+ if (npc->act_wait > 28)
+ {
+ npc->act_no = 102;
+ npc->act_wait = 0;
+ npc->ani_no = 0;
+
+ npc->tgt_x = gMC.x;
+ npc->tgt_y = gMC.y - 0x4000;
+
+ if ( npc->tgt_y < 0x8000 )
+ npc->tgt_y = 0x8000;
+
+ if ( npc->tgt_x < 0x8000 )
+ npc->tgt_x = 0x8000;
+ if ( npc->tgt_x > 0x48000 )
+ npc->tgt_x = 0x48000;
+ }
+
+ break;
+
+ case 102:
+ if (++npc->act_wait > 40)
+ {
+ npc->act_no = 103;
+ npc->act_wait = 28;
+ npc->ani_no = 4;
+ npc->ym = 0;
+ npc->x = npc->tgt_x;
+ npc->y = npc->tgt_y;
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+ }
+
+ break;
+
+ case 103:
+ npc->act_wait -= 2;
+
+ if (npc->act_wait <= 0)
+ {
+ npc->bits |= 0x24;
+ npc->damage = 5;
+ npc->act_no = 16;
+ npc->ym = -0x200;
+ npc->xm = 0;
+ }
+
+ break;
+
+ case 500:
+ DeleteNpCharCode(269, 1);
+ npc->bits &= ~0x20;
+ npc->ani_no = 4;
+ npc->ym += 0x20;
+ npc->xm = 0;
+
+ if (npc->flag & 8)
+ {
+ npc->act_no = 501;
+ npc->act_wait = 0;
+ npc->tgt_x = npc->x;
+
+ if (gMC.x < npc->x)
+ npc->direct = 0;
+ else
+ npc->direct = 2;
+ }
+
+ break;
+
+ case 501:
+ npc->ani_no = 9;
+
+ if (++npc->act_wait / 2 % 2)
+ npc->x = npc->tgt_x;
+ else
+ npc->x = npc->tgt_x + 0x200;
+
+ break;
+
+ case 510:
+ npc->act_no = 511;
+ npc->act_wait = 0;
+ npc->ani_no = 9;
+ npc->tgt_x = npc->x;
+ npc->y += 0x2000;
+ npc->bits |= 8;
+ // Fallthrough
+ case 511:
+ SetQuake(2);
+
+ if (++npc->act_wait % 6 == 3)
+ PlaySoundObject(25, 1);
+
+ if (npc->act_wait / 2 % 2)
+ npc->x = npc->tgt_x;
+ else
+ npc->x = npc->tgt_x + 0x200;
+
+ if (npc->act_wait > 352)
+ {
+ npc->ani_no = 0;
+ npc->act_no = 0x200;
+ }
+
+ break;
+
+ case 520:
+ npc->damage = 0;
+ gSuperYpos = -0x4000;
+ break;
+ }
+
+ if (npc->act_no >= 11 && npc->act_no < 501)
+ {
+ if (npc->act_no == 102)
+ {
+ gSuperXpos = npc->tgt_x;
+ gSuperYpos = npc->tgt_y;
+ }
+ else
+ {
+ gSuperXpos = npc->x;
+ gSuperYpos = npc->y;
+ }
+ }
+
+ if (npc->ym > 0x5FF)
+ npc->ym = 0x5FF;
+
+ npc->x += npc->xm;
+ npc->y += npc->ym;
+
+ if (npc->act_no < 512)
+ {
+ if (npc->act_no >= 510)
+ {
+ SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - (((336 - npc->act_wait) / 8) * 0x200), Random(-0x200, 0x200), 2 * Random(-0x200, 0), 3, 0, 0xAA);
+ SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), Random(-0x200, 0x200), 2 * Random(-0x200, 0), 3, 0, 0xAA);
+ SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), 0, 2 * Random(-0x200, 0), 3, 0, 0xAA);
+ SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), 0, 2 * Random(-0x200, 0), 3, 0, 0xAA);
+ }
+ else if (npc->act_no != 102 && npc->act_no != 103 && Random(0, 3) == 2)
+ {
+ SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y + (Random(-8, 4) * 0x200), npc->xm, 0, 3, 0, 0x100);
+ }
+ }
+
+ if (npc->direct == 0)
+ npc->rect = rcLeft[npc->ani_no];
+ else
+ npc->rect = rcRight[npc->ani_no];
+
+ if (npc->act_no == 511)
+ {
+ npc->rect.top += npc->act_wait / 8;
+ npc->view.top = (44 - npc->act_wait / 8) * 0x200;
+ npc->view.bottom = 0x800;
+ }
+ else if (npc->act_no == 101 || npc->act_no == 103)
+ {
+ npc->rect.top += npc->act_wait;
+ npc->rect.bottom -= npc->act_wait;
+ npc->view.top = (28 - npc->act_wait) * 0x200;
+ }
+ else
+ {
+ npc->view.top = 0x3800;
+ }
+}
+
//Igor (enemy)
void ActNpc268(NPCHAR *npc)
{
@@ -209,6 +1301,138 @@
npc->rect = rcLeft[npc->ani_no];
else
npc->rect = rcRight[npc->ani_no];
+}
+
+//Red Bat (bouncing)
+void ActNpc269(NPCHAR *npc)
+{
+ RECT rcLeft[3];
+ RECT rcRight[3];
+
+ rcLeft[0] = {232, 0, 248, 16};
+ rcLeft[1] = {248, 0, 264, 16};
+ rcLeft[2] = {248, 16, 264, 32};
+
+ rcRight[0] = {232, 32, 248, 48};
+ rcRight[1] = {248, 32, 264, 48};
+ rcRight[2] = {248, 48, 264, 64};
+
+ switch (npc->act_no)
+ {
+ case 0:
+ npc->act_no = 1;
+ npc->xm2 = npc->xm;
+ npc->ym2 = npc->ym;
+ // Fallthrough
+ case 1:
+ if (npc->xm2 < 0 && npc->flag & 1)
+ {
+ npc->direct = 2;
+ npc->xm2 = -npc->xm2;
+ }
+ else if (npc->xm2 > 0 && npc->flag & 4)
+ {
+ npc->direct = 0;
+ npc->xm2 = -npc->xm2;
+ }
+ else if (npc->ym2 < 0 && npc->flag & 2)
+ {
+ npc->ym2 = -npc->ym2;
+ }
+ else if (npc->ym2 > 0 && npc->flag & 8)
+ {
+ npc->ym2 = -npc->ym2;
+ }
+
+ npc->x += npc->xm2;
+ npc->y += npc->ym2;
+
+ if (++npc->ani_wait > 2)
+ {
+ npc->ani_wait = 0;
+ ++npc->ani_no;
+ }
+
+ if (npc->ani_no > 2)
+ npc->ani_no = 0;
+
+ break;
+ }
+
+ if (npc->direct == 0)
+ npc->rect = rcLeft[npc->ani_no];
+ else
+ npc->rect = rcRight[npc->ani_no];
+}
+
+//Doctor's blood (or """"red energy"""")
+void ActNpc270(NPCHAR *npc)
+{
+ RECT rc[2];
+
+ rc[0] = {170, 34, 174, 38};
+ rc[1] = {170, 42, 174, 46};
+
+ if (npc->direct == 3 || npc->direct == 1)
+ {
+ if (npc->direct == 3)
+ npc->ym += 0x40;
+ if (npc->direct == 1)
+ npc->ym -= 0x40;
+
+ ++npc->act_wait;
+
+ if (npc->ym > 0x5FF)
+ npc->ym = 0x5FF;
+
+ npc->x += npc->xm;
+ npc->y += npc->ym;
+
+ if (npc->act_wait > 50)
+ npc->cond = 0;
+
+ if (npc->flag & 0xFF)
+ npc->cond = 0;
+ }
+ else if ( npc->direct == 2 )
+ {
+ if (npc->act_no == 0)
+ {
+ npc->act_no = 1;
+ npc->bits |= 8;
+
+ npc->xm = 3 * Random(-0x200, 0x200);
+ npc->ym = 3 * Random(-0x200, 0x200);
+
+ npc->count1 = Random(0x10, 0x33);
+ npc->count2 = Random(0x80, 0x100);
+ }
+
+ if (npc->x < npc->pNpc->x)
+ npc->xm += 0x200 / npc->count1;
+ if (npc->x > npc->pNpc->x)
+ npc->xm -= 0x200 / npc->count1;
+
+ if (npc->y < npc->pNpc->y)
+ npc->ym += 0x200 / npc->count1;
+ if (npc->y > npc->pNpc->y)
+ npc->ym -= 0x200 / npc->count1;
+
+ if (npc->xm > 2 * npc->count2)
+ npc->xm = 2 * npc->count2;
+ if (npc->xm < -2 * npc->count2)
+ npc->xm = -2 * npc->count2;
+
+ if (npc->ym > 3 * npc->count2)
+ npc->ym = 3 * npc->count2;
+ if (npc->ym < -3 * npc->count2)
+ npc->ym = -3 * npc->count2;
+
+ npc->x += npc->xm;
+ npc->y += npc->ym;
+ }
+
+ npc->rect = rc[Random(0, 1)];
}
// Ironhead block
--- a/src/NpcTbl.cpp
+++ b/src/NpcTbl.cpp
@@ -312,21 +312,21 @@
ActNpc253,
ActNpc254,
ActNpc255,
- nullptr,
- nullptr,
- nullptr,
+ ActNpc256,
+ ActNpc257,
+ ActNpc258,
ActNpc259,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
+ ActNpc260,
+ ActNpc261,
+ ActNpc262,
+ ActNpc263,
+ ActNpc264,
+ ActNpc265,
+ ActNpc266,
+ ActNpc267,
ActNpc268,
- nullptr,
- nullptr,
+ ActNpc269,
+ ActNpc270,
ActNpc271,
ActNpc272,
ActNpc273,