shithub: cstory

Download patch

ref: 6347cb406df36dbc6065fa3d89fc0919e9104f12
parent: 9e62a6d8146e1d0c5a06482a757ca950cf578102
parent: 33063161624f0b989f02680a6e4f71e5f4a983da
author: Cucky <44537737+cuckydev@users.noreply.github.com>
date: Thu Feb 7 10:47:58 EST 2019

Merge pull request #43 from Clownacy/master

Everything up to Plantation (and even some of that) done

--- a/Makefile
+++ b/Makefile
@@ -41,9 +41,12 @@
 	ArmsItem \
 	Back \
 	Boss \
+	BossAlmo1 \
 	BossFrog \
+	BossIronH \
 	BossLife \
 	BossOhm \
+	BossTwinD \
 	BossX \
 	BulHit \
 	Bullet \
@@ -80,6 +83,8 @@
 	NpcAct160 \
 	NpcAct180 \
 	NpcAct200 \
+	NpcAct220 \
+	NpcAct240 \
 	NpcAct260 \
 	NpcAct280 \
 	NpcAct300 \
--- a/src/Boss.cpp
+++ b/src/Boss.cpp
@@ -4,8 +4,11 @@
 #include "WindowsWrapper.h"
 
 #include "Boss.h"
+#include "BossAlmo1.h"
 #include "BossFrog.h"
+#include "BossIronH.h"
 #include "BossOhm.h"
+#include "BossTwinD.h"
 #include "BossX.h"
 #include "NpChar.h"
 #include "MyChar.h"
@@ -190,9 +193,9 @@
 	ActBossChar_Omega,
 	ActBossChar_Frog,
 	ActBossChar_MonstX,
-	nullptr, //ActBossChar_Core,
-	nullptr, //ActBossChar_Ironhead,
-	nullptr, //ActBossChar_Twin,
+	ActBossChar_Core,
+	ActBossChar_Ironhead,
+	ActBossChar_Twin,
 	nullptr, //ActBossChar_Undead,
 	nullptr, //ActBossChar_Press,
 	nullptr, //ActBossChar_Ballos
--- /dev/null
+++ b/src/BossAlmo1.cpp
@@ -1,0 +1,596 @@
+#include "BossAlmo1.h"
+
+#include "Boss.h"
+#include "Frame.h"
+#include "Game.h"
+#include "Map.h"
+#include "MyChar.h"
+#include "NpChar.h"
+#include "Sound.h"
+#include "Triangle.h"
+
+static void ActBossChar_Core_Face(NPCHAR *npc)
+{
+	RECT rect[4];
+
+	rect[0] = {0, 0, 72, 112};
+	rect[1] = {0, 112, 72, 224};
+	rect[2] = {160, 0, 232, 112};
+	rect[3] = {0, 0, 0, 0};
+
+	switch (npc->act_no)
+	{
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 2;
+			npc->bits = 8;
+			npc->view.front = 0x4800;
+			npc->view.top = 0x7000;
+			// Fallthrough
+		case 11:
+			npc->x = gBoss[0].x - 0x4800;
+			npc->y = gBoss[0].y;
+			break;
+
+		case 50:
+			npc->act_no = 51;
+			npc->act_wait = 112;
+			// Fallthrough
+		case 51:
+			if (--npc->act_wait == 0)
+			{
+				npc->act_no = 100;
+				npc->ani_no = 3;
+			}
+
+			npc->x = gBoss[0].x - 0x4800;
+			npc->y = gBoss[0].y;
+			break;
+
+		case 100:
+			npc->ani_no = 3;
+			break;
+	}
+
+	npc->rect = rect[npc->ani_no];
+
+	if (npc->act_no == 51)
+		npc->rect.bottom = npc->act_wait + npc->rect.top;
+}
+
+static void ActBossChar_Core_Tail(NPCHAR *npc)
+{
+	RECT rect[3];
+
+	rect[0] = {72, 0, 160, 112};
+	rect[1] = {72, 112, 160, 224};
+	rect[2] = {0, 0, 0, 0};
+
+	switch (npc->act_no)
+	{
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 0;
+			npc->bits = 8;
+			npc->view.front = 0x5800;
+			npc->view.top = 0x7000;
+			// Fallthrough
+		case 11:
+			npc->x = gBoss[0].x + 0x5800;
+			npc->y = gBoss[0].y;
+			break;
+
+		case 50:
+			npc->act_no = 51;
+			npc->act_wait = 112;
+			// Fallthrough
+		case 51:
+			if (--npc->act_wait == 0)
+			{
+				npc->act_no = 100;
+				npc->ani_no = 2;
+			}
+
+			npc->x = gBoss[0].x + 0x5800;
+			npc->y = gBoss[0].y;
+			break;
+
+		case 100:
+			npc->ani_no = 2;
+			break;
+	}
+
+	npc->rect = rect[npc->ani_no];
+
+	if (npc->act_no == 51)
+		npc->rect.bottom = npc->act_wait + npc->rect.top;
+}
+
+static void ActBossChar_Core_Mini(NPCHAR *npc)
+{
+	RECT rect[3];
+
+	rect[0] = {256, 0, 320, 40};
+	rect[1] = {256, 40, 320, 80};
+	rect[2] = {256, 80, 320, 120};
+
+	npc->life = 1000;
+
+	switch (npc->act_no)
+	{
+		case 10:
+			npc->ani_no = 2;
+			npc->bits &= ~0x20;
+			break;
+
+		case 100:
+			npc->act_no = 101;
+			npc->ani_no = 2;
+			npc->act_wait = 0;
+			npc->tgt_x = gBoss[0].x + (Random(-0x80, 0x20) * 0x200);
+			npc->tgt_y = gBoss[0].y + (Random(-0x40, 0x40) * 0x200);
+			npc->bits |= 0x20;
+			// Fallthrough
+		case 101:
+			npc->x += (npc->tgt_x - npc->x) / 16;
+			npc->y += (npc->tgt_y - npc->y) / 16;
+
+			if (++npc->act_wait > 50)
+				npc->ani_no = 0;
+
+			break;
+
+		case 120:
+			npc->act_no = 121;
+			npc->act_wait = 0;
+			// Fallthrough
+		case 121:
+			if (++npc->act_wait / 2 % 2)
+				npc->ani_no = 0;
+			else
+				npc->ani_no = 1;
+
+			if (npc->act_wait > 20)
+				npc->act_no = 130;
+
+			break;
+
+		case 130:
+			npc->act_no = 131;
+			npc->ani_no = 2;
+			npc->act_wait = 0;
+			npc->tgt_x = npc->x + (Random(0x18, 0x30) * 0x200);
+			npc->tgt_y = npc->y + (Random(-4, 4) * 0x200);
+			// Fallthrough
+		case 131:
+			npc->x += (npc->tgt_x - npc->x) / 16;
+			npc->y += (npc->tgt_y - npc->y) / 16;
+
+			if (++npc->act_wait > 50)
+			{
+				npc->act_no = 140;
+				npc->ani_no = 0;
+			}
+
+			if (npc->act_wait == 1 || npc->act_wait == 3)
+			{
+				const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y) + Random(-2, 2);
+				const int ym = 2 * GetSin(deg);
+				const int xm = 2 * GetCos(deg);
+				SetNpChar(178, npc->x, npc->y, xm, ym, 0, 0, 0x100);
+				PlaySoundObject(39, 1);
+			}
+
+			break;
+
+		case 140:
+			npc->x += (npc->tgt_x - npc->x) / 16;
+			npc->y += (npc->tgt_y - npc->y) / 16;
+			break;
+
+		case 200:
+			npc->act_no = 201;
+			npc->ani_no = 2;
+			npc->xm = 0;
+			npc->ym = 0;
+			// Fallthrough
+		case 201:
+			npc->xm += 0x20;
+			npc->x += npc->xm;
+
+			if (npc->x > (gMap.width * 0x2000) + 0x4000)
+				npc->cond = 0;
+
+			break;
+	}
+
+	if (npc->shock)
+		npc->tgt_x += 0x400;
+
+	npc->rect = rect[npc->ani_no];
+}
+
+static void ActBossChar_Core_Hit(NPCHAR *npc)
+{
+	switch (npc->count1)
+	{
+		case 0:
+			npc->x = gBoss[0].x;
+			npc->y = gBoss[0].y - 0x4000;
+			break;
+		case 1:
+			npc->x = gBoss[0].x + 0x3800;
+			npc->y = gBoss[0].y;
+			break;
+		case 2:
+			npc->x = gBoss[0].x + 0x800;
+			npc->y = gBoss[0].y + 0x4000;
+			break;
+		case 3:
+			npc->x = gBoss[0].x - 0x3800;
+			npc->y = gBoss[0].y + 0x800;
+			break;
+	}
+}
+
+void ActBossChar_Core(void)
+{
+	static unsigned char flash;
+
+	bool bShock = false;
+
+	switch (gBoss[0].act_no)
+	{
+		case 0:
+			gBoss[0].act_no = 10;
+			gBoss[0].exp = 1;
+			gBoss[0].cond = 0x80;
+			gBoss[0].bits = 0x800C;
+			gBoss[0].life = 650;
+			gBoss[0].hit_voice = 114;
+			gBoss[0].x = 0x9A000;
+			gBoss[0].y = 0x1C000;
+			gBoss[0].xm = 0;
+			gBoss[0].ym = 0;
+			gBoss[0].code_event = 1000;
+			gBoss[0].bits |= 0x200;
+
+			gBoss[4].cond = 0x80;
+			gBoss[4].act_no = 10;
+
+			gBoss[5].cond = 0x80;
+			gBoss[5].act_no = 10;
+
+			gBoss[8].cond = 0x80;
+			gBoss[8].bits = 12;
+			gBoss[8].view.front = 0;
+			gBoss[8].view.top = 0;
+			gBoss[8].hit.back = 0x5000;
+			gBoss[8].hit.top = 0x2000;
+			gBoss[8].hit.bottom = 0x2000;
+			gBoss[8].count1 = 0;
+
+			gBoss[9] = gBoss[8];
+			gBoss[9].hit.back = 0x4800;
+			gBoss[9].hit.top = 0x3000;
+			gBoss[9].hit.bottom = 0x3000;
+			gBoss[9].count1 = 1;
+
+			gBoss[10] = gBoss[8];
+			gBoss[10].hit.back = 0x5800;
+			gBoss[10].hit.top = 0x1000;
+			gBoss[10].hit.bottom = 0x1000;
+			gBoss[10].count1 = 2;
+
+			gBoss[11] = gBoss[8];
+			gBoss[11].cond |= 0x10;
+			gBoss[11].hit.back = 0x2800;
+			gBoss[11].hit.top = 0x2800;
+			gBoss[11].hit.bottom = 0x2800;
+			gBoss[11].count1 = 3;
+
+			gBoss[1].cond = 0x80;
+			gBoss[1].act_no = 10;
+			gBoss[1].bits = 44;
+			gBoss[1].life = 1000;
+			gBoss[1].hit_voice = 54;
+			gBoss[1].hit.back = 0x3000;
+			gBoss[1].hit.top = 0x2000;
+			gBoss[1].hit.bottom = 0x2000;
+			gBoss[1].view.front = 0x4000;
+			gBoss[1].view.top = 0x2800;
+			gBoss[1].x = gBoss[0].x - 0x1000;
+			gBoss[1].y = gBoss[0].y - 0x8000;
+
+			gBoss[2] = gBoss[1];
+			gBoss[2].x = gBoss[0].x + 0x2000;
+			gBoss[2].y = gBoss[0].y;
+
+			gBoss[3] = gBoss[1];
+			gBoss[3].x = gBoss[0].x - 0x1000;
+			gBoss[3].y = gBoss[0].y + 0x8000;
+
+			gBoss[6] = gBoss[1];
+			gBoss[6].x = gBoss[0].x - 0x6000;
+			gBoss[6].y = gBoss[0].y - 0x4000;
+
+			gBoss[7] = gBoss[1];
+			gBoss[7].x = gBoss[0].x - 0x6000;
+			gBoss[7].y = gBoss[0].y + 0x4000;
+			break;
+
+		case 200:
+			gBoss[0].act_no = 201;
+			gBoss[0].act_wait = 0;
+			gBoss[11].bits &= ~0x20;
+			gSuperYpos = 0;
+			CutNoise();
+			// Fallthrough
+		case 201:
+			gBoss[0].tgt_x = gMC.x;
+			gBoss[0].tgt_y = gMC.y;
+
+			if (++gBoss[0].act_wait > 400)
+			{
+				++gBoss[0].count1;
+				PlaySoundObject(115, 1);
+
+				if (gBoss[0].count1 > 3)
+				{
+					gBoss[0].count1 = 0;
+					gBoss[0].act_no = 220;
+					gBoss[4].ani_no = 0;
+					gBoss[5].ani_no = 0;
+					bShock = true;
+				}
+				else
+				{
+					gBoss[0].act_no = 210;
+					gBoss[4].ani_no = 0;
+					gBoss[5].ani_no = 0;
+					bShock = true;
+				}
+			}
+
+			break;
+
+		case 210:
+			gBoss[0].act_no = 211;
+			gBoss[0].act_wait = 0;
+			gBoss[0].count2 = gBoss[0].life;
+			gBoss[11].bits |= 0x20;
+			// Fallthrough
+		case 211:
+			gBoss[0].tgt_x = gMC.x;
+			gBoss[0].tgt_y = gMC.y;
+
+			if (gBoss[0].shock)
+			{
+				if ((++flash >> 1) % 2)
+				{
+					gBoss[4].ani_no = 0;
+					gBoss[5].ani_no = 0;
+				}
+				else
+				{
+					gBoss[4].ani_no = 1;
+					gBoss[5].ani_no = 1;
+				}
+			}
+			else
+			{
+				gBoss[4].ani_no = 0;
+				gBoss[5].ani_no = 0;
+			}
+
+			if (++gBoss[0].act_wait % 100 == 1)
+			{
+				gCurlyShoot_wait = Random(80, 100);
+				gCurlyShoot_x = gBoss[11].x;
+				gCurlyShoot_y = gBoss[11].y;
+			}
+
+			if (gBoss[0].act_wait < 200 && gBoss[0].act_wait % 20 == 1)
+				SetNpChar(179, gBoss[0].x + (Random(-0x30, -0x10) * 0x200), gBoss[0].y + (Random(-0x40, 0x40) * 0x200), 0, 0, 0, 0, 0x100);
+
+			if (gBoss[0].act_wait > 400 || gBoss[0].life < gBoss[0].count2 - 200)
+			{
+				gBoss[0].act_no = 200;
+				gBoss[4].ani_no = 2;
+				gBoss[5].ani_no = 0;
+				bShock = true;
+			}
+
+			break;
+
+		case 220:
+			gBoss[0].act_no = 221;
+			gBoss[0].act_wait = 0;
+			gSuperYpos = 1;
+			gBoss[11].bits |= 0x20u;
+			SetQuake(100);
+			SetNoise(1, 1000);
+			// Fallthrough
+		case 221:
+			++gBoss[0].act_wait;
+			SetNpChar(199, gMC.x + (Random(-50, 150) * 0x400), gMC.y + (Random(-0xA0, 0xA0) * 0x200), 0, 0, 0, 0, 0x100);
+			gMC.xm -= 0x20;
+			gMC.cond |= 0x20;
+
+			if (gBoss[0].shock)
+			{
+				if ((++flash >> 1) % 2)
+				{
+					gBoss[4].ani_no = 0;
+					gBoss[5].ani_no = 0;
+				}
+				else
+				{
+					gBoss[4].ani_no = 1;
+					gBoss[5].ani_no = 1;
+				}
+			}
+			else
+			{
+				gBoss[4].ani_no = 0;
+				gBoss[5].ani_no = 0;
+			}
+
+			if (gBoss[0].act_wait == 300 || gBoss[0].act_wait == 350 || gBoss[0].act_wait == 400)
+			{
+				const unsigned char deg = GetArktan(gBoss[0].x - gMC.x, gBoss[0].y - gMC.y);
+				const int ym = 3 * GetSin(deg);
+				const int xm = 3 * GetCos(deg);
+				SetNpChar(218, gBoss[0].x - 0x5000, gBoss[0].y, xm, ym, 0, 0, 0x100);
+				PlaySoundObject(101, 1);
+			}
+
+			if ( gBoss[0].act_wait > 400 )
+			{
+				gBoss[0].act_no = 200;
+				gBoss[4].ani_no = 2;
+				gBoss[5].ani_no = 0;
+				bShock = true;
+			}
+
+			break;
+
+		case 500:
+			CutNoise();
+
+			gBoss[0].act_no = 501;
+			gBoss[0].act_wait = 0;
+			gBoss[0].xm = 0;
+			gBoss[0].ym = 0;
+			gBoss[4].ani_no = 2;
+			gBoss[5].ani_no = 0;
+			gBoss[1].act_no = 200;
+			gBoss[2].act_no = 200;
+			gBoss[3].act_no = 200;
+			gBoss[6].act_no = 200;
+			gBoss[7].act_no = 200;
+
+			SetQuake(20);
+
+			for (int i = 0; i < 0x20; ++i)
+				SetNpChar(4, gBoss[0].x + (Random(-0x80, 0x80) * 0x200), gBoss[0].y + (Random(-0x40, 0x40) * 0x200), Random(-0x80, 0x80) * 0x200, Random(-0x80, 0x80) * 0x200, 0, 0, 0x100);
+
+			for (int i = 0; i < 12; ++i)
+				gBoss[i].bits &= ~0x24;
+
+			// Fallthrough
+		case 501:
+			if (++gBoss[0].act_wait % 16)
+				SetNpChar(4, gBoss[0].x + (Random(-0x40, 0x40) * 0x200), gBoss[0].y + (Random(-0x20, 0x20) * 0x200), Random(-0x80, 0x80) * 0x200, Random(-0x80, 0x80) * 0x200, 0, 0, 0x100);
+
+			if (gBoss[0].act_wait / 2 % 2)
+				gBoss[0].x -= 0x200;
+			else
+				gBoss[0].x += 0x200;
+
+			if (gBoss[0].x < 0x7E000)
+				gBoss[0].x += 0x80;
+			else
+				gBoss[0].x -= 0x80;
+
+			if (gBoss[0].y < 0x16000)
+				gBoss[0].y += 0x80;
+			else
+				gBoss[0].y -= 0x80;
+
+			break;
+
+		case 600:
+			gBoss[0].act_no = 601;
+			gBoss[4].act_no = 50;
+			gBoss[5].act_no = 50;
+			gBoss[8].bits &= ~4;
+			gBoss[9].bits &= ~4;
+			gBoss[10].bits &= ~4;
+			gBoss[11].bits &= ~4;
+			// Fallthrough
+		case 601:
+			if (++gBoss[0].act_wait / 2 % 2)
+				gBoss[0].x -= 0x800;
+			else
+				gBoss[0].x += 0x800;
+
+			break;
+	}
+
+	if (bShock)
+	{
+		SetQuake(20);
+
+		gBoss[1].act_no = 100;
+		gBoss[2].act_no = 100;
+		gBoss[3].act_no = 100;
+		gBoss[6].act_no = 100;
+		gBoss[7].act_no = 100;
+
+		PlaySoundObject(26, 1);
+
+		for (int i = 0; i < 8; ++i)
+			SetNpChar(4, gBoss[4].x + (Random(-0x20, 0x10) * 0x200), gBoss[4].y, Random(-0x200, 0x200), Random(-0x100, 0x100), 0, 0, 0x100);
+	}
+
+	if (gBoss[0].act_no >= 200 && gBoss[0].act_no < 300)
+	{
+		switch (gBoss[0].act_wait)
+		{
+			case 80:
+				gBoss[1].act_no = 120;
+				break;
+			case 110:
+				gBoss[2].act_no = 120;
+				break;
+			case 140:
+				gBoss[3].act_no = 120;
+				break;
+			case 170:
+				gBoss[6].act_no = 120;
+				break;
+			case 200:
+				gBoss[7].act_no = 120;
+				break;
+		}
+
+		if (gBoss[0].x < gBoss[0].tgt_x + 0x14000)
+			gBoss[0].xm += 4;
+		if (gBoss[0].x > gBoss[0].tgt_x + 0x14000)
+			gBoss[0].xm -= 4;
+
+		if (gBoss[0].y < gBoss[0].tgt_y)
+			gBoss[0].ym += 4;
+		if (gBoss[0].y > gBoss[0].tgt_y)
+			gBoss[0].ym -= 4;
+	}
+
+	if (gBoss[0].xm > 0x80)
+		gBoss[0].xm = 0x80;
+	if (gBoss[0].xm < -0x80)
+		gBoss[0].xm = -0x80;
+
+	if (gBoss[0].ym > 0x80)
+		gBoss[0].ym = 0x80;
+	if (gBoss[0].ym < -0x80)
+		gBoss[0].ym = -0x80;
+
+	gBoss[0].x += gBoss[0].xm;
+	gBoss[0].y += gBoss[0].ym;
+
+	ActBossChar_Core_Face(&gBoss[4]);
+
+	ActBossChar_Core_Tail(&gBoss[5]);
+
+	ActBossChar_Core_Mini(&gBoss[1]);
+	ActBossChar_Core_Mini(&gBoss[2]);
+	ActBossChar_Core_Mini(&gBoss[3]);
+	ActBossChar_Core_Mini(&gBoss[6]);
+	ActBossChar_Core_Mini(&gBoss[7]);
+
+	ActBossChar_Core_Hit(&gBoss[8]);
+	ActBossChar_Core_Hit(&gBoss[9]);
+	ActBossChar_Core_Hit(&gBoss[10]);
+	ActBossChar_Core_Hit(&gBoss[11]);
+}
--- /dev/null
+++ b/src/BossAlmo1.h
@@ -1,0 +1,3 @@
+#pragma once
+
+void ActBossChar_Core(void);
--- /dev/null
+++ b/src/BossIronH.cpp
@@ -1,0 +1,207 @@
+#include "BossIronH.h"
+
+#include "Boss.h"
+#include "Frame.h"
+#include "Game.h"
+#include "MyChar.h"
+#include "Sound.h"
+#include "WindowsWrapper.h"
+
+void ActBossChar_Ironhead(void)
+{
+	switch (gBoss[0].act_no)
+	{
+		case 0:
+			gBoss[0].cond = 0x80;
+			gBoss[0].exp = 1;
+			gBoss[0].direct = 2;
+			gBoss[0].act_no = 100;
+			gBoss[0].x = 0x14000;
+			gBoss[0].y = 0x10000;
+			gBoss[0].view.front = 0x5000;
+			gBoss[0].view.top = 0x1800;
+			gBoss[0].view.back = 0x3000;
+			gBoss[0].view.bottom = 0x1800;
+			gBoss[0].hit_voice = 54;
+			gBoss[0].hit.front = 0x2000;
+			gBoss[0].hit.top = 0x1400;
+			gBoss[0].hit.back = 0x2000;
+			gBoss[0].hit.bottom = 0x1400;
+			gBoss[0].bits = 0x8228;
+			gBoss[0].size = 3;
+			gBoss[0].damage = 10;
+			gBoss[0].code_event = 1000;
+			gBoss[0].life = 400;
+			break;
+
+		case 100:
+			gBoss[0].act_no = 101;
+			gBoss[0].bits &= ~0x20;
+			gBoss[0].act_wait = 0;
+			// Fallthrough
+		case 101:
+			if (++gBoss[0].act_wait > 50)
+			{
+				gBoss[0].act_no = 250;
+				gBoss[0].act_wait = 0;
+			}
+
+			if (gBoss[0].act_wait % 4 == 0)
+				SetNpChar(197, Random(15, 18) * 0x2000, Random(2, 13) * 0x2000, 0, 0, 0, 0, 0x100);
+
+			break;
+
+		case 250:
+			gBoss[0].act_no = 251;
+
+			if (gBoss[0].direct == 2)
+			{
+				gBoss[0].x = 0x1E000;
+				gBoss[0].y = gMC.y;
+			}
+			else
+			{
+				gBoss[0].x = 0x5A000;
+				gBoss[0].y = Random(2, 13) * 0x2000;
+			}
+
+			gBoss[0].tgt_x = gBoss[0].x;
+			gBoss[0].tgt_y = gBoss[0].y;
+
+			gBoss[0].ym = Random(-0x200, 0x200);
+			gBoss[0].xm = Random(-0x200, 0x200);
+
+			gBoss[0].bits |= 0x20;
+			// Fallthrough
+		case 251:
+			if (gBoss[0].direct == 2)
+			{
+				gBoss[0].tgt_x += 0x400;
+			}
+			else
+			{
+				gBoss[0].tgt_x -= 0x200;
+
+				if (gMC.y > gBoss[0].tgt_y)
+					gBoss[0].tgt_y += 0x200;
+				else
+					gBoss[0].tgt_y -= 0x200;
+			}
+
+			if (gBoss[0].tgt_x > gBoss[0].x)
+				gBoss[0].xm += 8;
+			else
+				gBoss[0].xm -= 8;
+
+			if (gBoss[0].tgt_y > gBoss[0].y)
+				gBoss[0].ym += 8;
+			else
+				gBoss[0].ym -= 8;
+
+			if (gBoss[0].ym > 0x200)
+				gBoss[0].ym = 0x200;
+			if (gBoss[0].ym < -0x200)
+				gBoss[0].ym = -0x200;
+
+			gBoss[0].x += gBoss[0].xm;
+			gBoss[0].y += gBoss[0].ym;
+
+			if (gBoss[0].direct == 2)
+			{
+				if (gBoss[0].x > 0x5A000)
+				{
+					gBoss[0].direct = 0;
+					gBoss[0].act_no = 100;
+				}
+			}
+			else
+			{
+				if (gBoss[0].x < 0x22000)
+				{
+					gBoss[0].direct = 2;
+					gBoss[0].act_no = 100;
+				}
+			}
+
+			if (gBoss[0].direct == 0 && (++gBoss[0].act_wait == 300 || gBoss[0].act_wait == 310 || gBoss[0].act_wait == 320))
+			{
+				PlaySoundObject(39, 1);
+				SetNpChar(198, gBoss[0].x + 0x1400, gBoss[0].y + 0x200, Random(-3, 0) * 0x200, Random(-3, 3) * 0x200, 2, 0, 0x100);
+			}
+
+			if (++gBoss[0].ani_wait > 2)
+			{
+				gBoss[0].ani_wait = 0;
+				++gBoss[0].ani_no;
+			}
+
+			if (gBoss[0].ani_no > 7)
+				gBoss[0].ani_no = 0;
+
+			break;
+
+		case 1000:
+			gBoss[0].bits &= ~0x20;
+			gBoss[0].ani_no = 8;
+			gBoss[0].damage = 0;
+			gBoss[0].act_no = 1001;
+			gBoss[0].tgt_x = gBoss[0].x;
+			gBoss[0].tgt_y = gBoss[0].y;
+			SetQuake(20);
+
+			for (int i = 0; i < 0x20; ++i)
+				SetNpChar(4, gBoss[0].x + (Random(-0x80, 0x80) * 0x200), gBoss[0].y + (Random(-0x40, 0x40) * 0x200), Random(-0x80, 0x80) * 0x200, Random(-0x80, 0x80) * 0x200, 0, 0, 0x100);
+
+			DeleteNpCharCode(197, 1);
+			DeleteNpCharCode(271, 1);
+			DeleteNpCharCode(272, 1);
+			// Fallthrough
+		case 1001:
+			gBoss[0].tgt_x -= 0x200;
+
+			gBoss[0].x = gBoss[0].tgt_x + (Random(-1, 1) * 0x200);
+			gBoss[0].y = gBoss[0].tgt_y + (Random(-1, 1) * 0x200);
+
+			if (++gBoss[0].act_wait % 4 == 0)
+				SetNpChar(4, gBoss[0].x + (Random(-0x80u, 0x80) * 0x200), gBoss[0].y + (Random(-0x40u, 0x40) * 0x200), Random(-0x80, 0x80) * 0x200, Random(-0x80, 0x80) * 0x200, 0, 0, 0x100);
+
+			break;
+	}
+
+	RECT rc[9];
+	RECT rcDamage[9];
+
+	rc[0] = {0, 0, 64, 24};
+	rc[1] = {64, 0, 128, 24};
+	rc[2] = {128, 0, 192, 24};
+	rc[3] = {64, 0, 128, 24};
+	rc[4] = {0, 0, 64, 24};
+	rc[5] = {192, 0, 256, 24};
+	rc[6] = {256, 0, 320, 24};
+	rc[7] = {192, 0, 256, 24};
+	rc[8] = {256, 48, 320, 72};
+
+	rcDamage[0] = {0, 24, 64, 48};
+	rcDamage[1] = {64, 24, 128, 48};
+	rcDamage[2] = {128, 24, 192, 48};
+	rcDamage[3] = {64, 24, 128, 48};
+	rcDamage[4] = {0, 24, 64, 48};
+	rcDamage[5] = {192, 24, 256, 48};
+	rcDamage[6] = {256, 24, 320, 48};
+	rcDamage[7] = {192, 24, 256, 48};
+	rcDamage[8] = {256, 48, 320, 72};
+
+	if (gBoss[0].shock)
+	{
+		static unsigned char flash;
+
+		if ((++flash >> 1) % 2)
+			gBoss[0].rect = rc[gBoss[0].ani_no];
+		else
+			gBoss[0].rect = rcDamage[gBoss[0].ani_no];
+	}
+	else
+	{
+		gBoss[0].rect = rc[gBoss[0].ani_no];
+	}
+}
\ No newline at end of file
--- /dev/null
+++ b/src/BossIronH.h
@@ -1,0 +1,3 @@
+#pragma once
+
+void ActBossChar_Ironhead(void);
--- /dev/null
+++ b/src/BossTwinD.cpp
@@ -1,0 +1,551 @@
+#include "BossTwinD.h"
+
+#include "Boss.h"
+#include "Flash.h"
+#include "Game.h"
+#include "MyChar.h"
+#include "NpChar.h"
+#include "Sound.h"
+#include "Triangle.h"
+#include "WindowsWrapper.h"
+
+static void ActBossCharT_DragonBody(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {0, 0, 40, 40};
+	rcLeft[1] = {40, 0, 80, 40};
+	rcLeft[2] = {80, 0, 120, 40};
+
+	rcRight[0] = {0, 40, 40, 80};
+	rcRight[1] = {40, 40, 80, 80};
+	rcRight[2] = {80, 40, 120, 80};
+
+	unsigned char deg;
+	switch (npc->act_no)
+	{
+		case 0:
+			deg = npc->count1 + (npc->pNpc->count1 / 4);
+			npc->act_no = 10;
+			npc->x += npc->pNpc->x + npc->pNpc->tgt_x * GetCos(deg);
+			npc->y += npc->pNpc->y + npc->pNpc->tgt_y * GetSin(deg);
+			// Fallthrough
+		case 10:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			break;
+
+		case 100:
+			deg = npc->count1 + (npc->pNpc->count1 / 4);
+			npc->tgt_x = npc->pNpc->x + npc->pNpc->tgt_x * GetCos(deg);
+			npc->tgt_y = npc->pNpc->y + npc->pNpc->tgt_y * GetSin(deg);
+			npc->x += (npc->tgt_x - npc->x) / 8;
+			npc->y += (npc->tgt_y - npc->y) / 8;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			break;
+
+		case 1000:
+			npc->act_no = 1001;
+			npc->bits &= ~0x20;
+			// Fallthrough
+		case 1001:
+			deg = npc->count1 + (npc->pNpc->count1 / 4);
+			npc->tgt_x = npc->pNpc->x + npc->pNpc->tgt_x * GetCos(deg);
+			npc->tgt_y = npc->pNpc->y + npc->pNpc->tgt_y * GetSin(deg);
+			npc->x += (npc->tgt_x - npc->x) / 8;
+			npc->y += (npc->tgt_y - npc->y) / 8;
+
+			if (npc->pNpc->x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			break;
+	}
+
+	if (++npc->ani_wait > 2)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+static void ActBossCharT_DragonHead(NPCHAR *npc)
+{
+	RECT rcLeft[4];
+	RECT rcRight[4];
+
+	rcLeft[0] = {0, 80, 40, 112};
+	rcLeft[1] = {40, 80, 80, 112};
+	rcLeft[2] = {80, 80, 120, 112};
+	rcLeft[3] = {120, 80, 160, 112};
+
+	rcRight[0] = {0, 112, 40, 144};
+	rcRight[1] = {40, 112, 80, 144};
+	rcRight[2] = {80, 112, 120, 144};
+	rcRight[3] = {120, 112, 160, 144};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			break;
+
+		case 100:
+			npc->act_no = 200;
+			// Fallthrough
+		case 200:
+			npc->bits &= ~0x20;
+			npc->ani_no = 0;
+			npc->hit.front = 0x2000;
+			npc->act_no = 201;
+			npc->count1 = Random(100, 200);
+			// Fallthrough
+		case 201:
+			if (npc->count1)
+			{
+				--npc->count1;
+			}
+			else
+			{
+				npc->act_no = 210;
+				npc->act_wait = 0;
+				npc->count2 = 0;
+			}
+
+			break;
+
+		case 210:
+			if (++npc->act_wait == 3)
+				npc->ani_no = 1;
+
+			if (npc->act_wait == 6)
+			{
+				npc->ani_no = 2;
+				npc->hit.front = 0x1000;
+				npc->bits |= 0x20;
+				npc->count2 = 0;
+			}
+
+			if (npc->act_wait > 150)
+			{
+				npc->act_no = 220;
+				npc->act_wait = 0;
+			}
+
+			if (npc->shock)
+				++npc->count2;
+
+			if (npc->count2 > 10)
+			{
+				PlaySoundObject(51, 1);
+				SetDestroyNpChar(npc->x, npc->y, npc->view.back, 4);
+				npc->act_no = 300;
+				npc->act_wait = 0;
+				npc->ani_no = 3;
+				npc->hit.front = 0x2000;
+			}
+
+			break;
+
+		case 220:
+			if (++npc->act_wait % 8 == 1)
+			{
+				const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y) + Random(-6, 6);
+				const int ym = GetSin(deg);
+				const int xm = GetCos(deg);
+
+				if (npc->direct == 0)
+					SetNpChar(202, npc->x - 0x1000, npc->y, xm, ym, 0, 0, 0x100);
+				else
+					SetNpChar(202, npc->x + 0x1000, npc->y, xm, ym, 0, 0, 0x100);
+
+				PlaySoundObject(33, 1);
+			}
+
+			if (npc->act_wait > 50)
+				npc->act_no = 200;
+
+			break;
+
+		case 300:
+			if (++npc->act_wait > 100)
+				npc->act_no = 200;
+
+			break;
+
+		case 400:
+			npc->act_no = 401;
+			npc->act_wait = 0;
+			npc->ani_no = 0;
+			npc->hit.front = 0x2000;
+			npc->bits &= ~0x20;
+			// Fallthrough
+		case 401:
+			if (++npc->act_wait == 3)
+				npc->ani_no = 1;
+
+			if (npc->act_wait == 6)
+			{
+				npc->ani_no = 2;
+				npc->hit.front = 0x1000;
+				npc->bits |= 0x20;
+				npc->count2 = 0;
+			}
+
+			if (npc->act_wait > 20 && npc->act_wait % 32 == 1)
+			{
+				const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y) + Random(-6, 6);
+				const int ym = GetSin(deg);
+				const int xm = GetCos(deg);
+
+				if (npc->direct == 0)
+					SetNpChar(202, npc->x - 0x1000, npc->y, xm, ym, 0, 0, 0x100);
+				else
+					SetNpChar(202, npc->x + 0x1000, npc->y, xm, ym, 0, 0, 0x100);
+
+				PlaySoundObject(33, 1);
+			}
+
+			break;
+
+		case 1000:
+			npc->bits &= ~0x20;
+			npc->ani_no = 3;
+			break;
+	}
+
+	npc->direct = npc->pNpc->direct;
+
+	if (npc->direct == 0)
+		npc->x = npc->pNpc->x - 0x800;
+	else
+		npc->x = npc->pNpc->x + 0x800;
+
+	npc->y = npc->pNpc->y - 0x1000;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+void ActBossChar_Twin(void)
+{
+	switch (gBoss[0].act_no)
+	{
+		case 0:
+			gBoss[0].cond = 0x80;
+			gBoss[0].direct = 0;
+			gBoss[0].act_no = 10;
+			gBoss[0].exp = 0;
+			gBoss[0].x = 0x14000;
+			gBoss[0].y = 0x10000;
+			gBoss[0].view.front = 0x1000;
+			gBoss[0].view.top = 0x1000;
+			gBoss[0].view.back = 0x10000;
+			gBoss[0].view.bottom = 0x1000;
+			gBoss[0].hit_voice = 54;
+			gBoss[0].hit.front = 0x1000;
+			gBoss[0].hit.top = 0x1000;
+			gBoss[0].hit.back = 0x1000;
+			gBoss[0].hit.bottom = 0x1000;
+			gBoss[0].bits = 8;
+			gBoss[0].bits |= 0x200;
+			gBoss[0].size = 3;
+			gBoss[0].damage = 0;
+			gBoss[0].code_event = 1000;
+			gBoss[0].life = 500;
+			gBoss[0].count2 = Random(700, 1200);
+			gBoss[0].tgt_x = 180;
+			gBoss[0].tgt_y = 61;
+
+			gBoss[2].view.back = 0x2800;
+			gBoss[2].view.front = 0x2800;
+			gBoss[2].view.top = 0x2000;
+			gBoss[2].view.bottom = 0x2000;
+			gBoss[2].hit.back = 0x1800;
+			gBoss[2].hit.front = 0x1800;
+			gBoss[2].hit.top = 0x1400;
+			gBoss[2].hit.bottom = 0x1400;
+			gBoss[2].bits = 12;
+			gBoss[2].pNpc = &gBoss[3];
+			gBoss[2].cond = 0x90;
+			gBoss[2].damage = 10;
+
+			gBoss[3].cond = 0x80;
+			gBoss[3].view.back = 0x2800;
+			gBoss[3].view.front = 0x2800;
+			gBoss[3].view.top = 0x2800;
+			gBoss[3].view.bottom = 0x2800;
+			gBoss[3].hit.back = 0x1800;
+			gBoss[3].hit.front = 0x1800;
+			gBoss[3].hit.top = 0x400;
+			gBoss[3].hit.bottom = 0x2000;
+			gBoss[3].bits = 8;
+			gBoss[3].pNpc = gBoss;
+			gBoss[3].damage = 10;
+
+			gBoss[4] = gBoss[2];
+			gBoss[4].pNpc = &gBoss[5];
+
+			gBoss[5] = gBoss[3];
+			gBoss[5].count1 = 128;
+			break;
+
+		case 20:
+			if (--gBoss[0].tgt_x <= 112)
+			{
+				gBoss[0].act_no = 100;
+				gBoss[0].act_wait = 0;
+				gBoss[2].act_no = 100;
+				gBoss[4].act_no = 100;
+				gBoss[3].act_no = 100;
+				gBoss[5].act_no = 100;
+			}
+
+			break;
+
+		case 100:
+			if (++gBoss[0].act_wait < 100)
+			{
+				++gBoss[0].count1;
+			}
+			else
+			{
+				if (gBoss[0].act_wait < 120)
+				{
+					gBoss[0].count1 += 2;
+				}
+				else
+				{
+					if (gBoss[0].act_wait < gBoss[0].count2)
+					{
+						gBoss[0].count1 += 4;
+					}
+					else
+					{
+						if (gBoss[0].act_wait < gBoss[0].count2 + 40)
+						{
+							gBoss[0].count1 += 2;
+						}
+						else
+						{
+							if (gBoss[0].act_wait < gBoss[0].count2 + 60)
+							{
+								++gBoss[0].count1;
+							}
+							else
+							{
+								gBoss[0].act_wait = 0;
+								gBoss[0].act_no = 110;
+								gBoss[0].count2 = Random(400, 700);
+								break;
+							}
+						}
+					}
+				}
+			}
+
+			if (gBoss[0].count1 > 0x3FF)
+				gBoss[0].count1 -= 0x400;
+
+			break;
+
+		case 110:
+			if (++gBoss[0].act_wait < 20)
+			{
+				--gBoss[0].count1;
+			}
+			else
+			{
+				if (gBoss[0].act_wait < 60)
+				{
+					gBoss[0].count1 -= 2;
+				}
+				else
+				{
+					if (gBoss[0].act_wait < gBoss[0].count2)
+					{
+						gBoss[0].count1 -= 4;
+					}
+					else
+					{
+						if (gBoss[0].act_wait < gBoss[0].count2 + 40)
+						{
+							gBoss[0].count1 -= 2;
+						}
+						else
+						{
+							if (gBoss[0].act_wait < gBoss[0].count2 + 60)
+							{
+								--gBoss[0].count1;
+							}
+							else
+							{
+								if (gBoss[0].life < 300)
+								{
+									gBoss[0].act_wait = 0;
+									gBoss[0].act_no = 400;
+									gBoss[2].act_no = 400;
+									gBoss[4].act_no = 400;
+								}
+								else
+								{
+									gBoss[0].act_wait = 0;
+									gBoss[0].act_no = 100;
+									gBoss[0].count2 = Random(400, 700);
+								}
+
+								break;
+							}
+						}
+					}
+				}
+			}
+
+			if (gBoss[0].count1 <= 0)
+				gBoss[0].count1 += 0x400;
+
+			break;
+
+		case 400:
+			if (++gBoss[0].act_wait > 100)
+			{
+				gBoss[0].act_wait = 0;
+				gBoss[0].act_no = 401;
+			}
+
+			break;
+
+		case 401:
+			if (++gBoss[0].act_wait < 100)
+			{
+				++gBoss[0].count1;
+			}
+			else
+			{
+				if (gBoss[0].act_wait < 120)
+				{
+					gBoss[0].count1 += 2;
+				}
+				else
+				{
+					if (gBoss[0].act_wait < 500)
+					{
+						gBoss[0].count1 += 4;
+					}
+					else
+					{
+						if (gBoss[0].act_wait < 540)
+						{
+							gBoss[0].count1 += 2;
+						}
+						else
+						{
+							if (gBoss[0].act_wait < 560)
+							{
+								++gBoss[0].count1;
+							}
+							else
+							{
+								gBoss[0].act_no = 100;
+								gBoss[0].act_wait = 0;
+								gBoss[2].act_no = 100;
+								gBoss[4].act_no = 100;
+								break;
+							}
+						}
+					}
+				}
+			}
+
+			if ( gBoss[0].count1 > 0x3FF )
+				gBoss[0].count1 -= 0x400;
+
+			break;
+
+		case 1000:
+			gBoss[0].act_no = 1001;
+			gBoss[0].act_wait = 0;
+			gBoss[2].act_no = 1000;
+			gBoss[3].act_no = 1000;
+			gBoss[4].act_no = 1000;
+			gBoss[5].act_no = 1000;
+			SetDestroyNpChar(gBoss[0].x, gBoss[0].y, gBoss[0].view.back, 40);
+			break;
+
+		case 1001:
+			if (++gBoss[0].act_wait > 100)
+				gBoss[0].act_no = 1010;
+
+			SetNpChar(4, gBoss[0].x + (Random(-0x80, 0x80) * 0x200), gBoss[0].y + (Random(-70, 70) * 0x200), 0, 0, 0, 0, 0x100);
+			break;
+
+		case 1010:
+			gBoss[0].count1 += 4;
+
+			if (gBoss[0].count1 > 0x3FF)
+				gBoss[0].count1 -= 0x400;
+
+			if (gBoss[0].tgt_x > 8)
+				--gBoss[0].tgt_x;
+			if (gBoss[0].tgt_y > 0)
+				--gBoss[0].tgt_y;
+
+			if (gBoss[0].tgt_x < -8)
+				++gBoss[0].tgt_x;
+			if (gBoss[0].tgt_y < 0)
+				++gBoss[0].tgt_y;
+
+			if (gBoss[0].tgt_y == 0)
+			{
+				gBoss[0].act_no = 1020;
+				gBoss[0].act_wait = 0;
+				SetFlash(gBoss[0].x, gBoss[0].y, 1);
+				PlaySoundObject(35, 1);
+			}
+
+			break;
+
+		case 1020:
+			if (++gBoss[0].act_wait > 50)
+			{
+				DeleteNpCharCode(211, 1);
+				gBoss[0].cond = 0;
+				gBoss[1].cond = 0;
+				gBoss[2].cond = 0;
+				gBoss[3].cond = 0;
+				gBoss[4].cond = 0;
+				gBoss[5].cond = 0;
+				gBoss[0].act_no = 0;
+			}
+
+			break;
+	}
+
+	ActBossCharT_DragonHead(&gBoss[2]);
+	ActBossCharT_DragonBody(&gBoss[3]);
+	ActBossCharT_DragonHead(&gBoss[4]);
+	ActBossCharT_DragonBody(&gBoss[5]);
+
+	RECT rc = {0, 0, 0, 0};
+	gBoss[0].rect = rc;
+}
\ No newline at end of file
--- /dev/null
+++ b/src/BossTwinD.h
@@ -1,0 +1,3 @@
+#pragma once
+
+void ActBossChar_Twin(void);
--- a/src/MyChar.cpp
+++ b/src/MyChar.cpp
@@ -639,6 +639,131 @@
 	}
 }
 
+void ActMyChar_Stream(bool bKey)
+{
+	gMC.up = false;
+	gMC.down = false;
+
+	if (bKey)
+	{
+		if (gKey & (gKeyRight | gKeyLeft))
+		{
+			if (gKey & gKeyLeft)
+				gMC.xm -= 0x100;
+
+			if (gKey & gKeyRight)
+				gMC.xm += 0x100;
+		}
+		else if (gMC.xm > 0x7F || gMC.xm < -0x7F)
+		{
+			if (gMC.xm > 0)
+				gMC.xm -= 0x80;
+			else if (gMC.xm < 0)
+				gMC.xm += 0x80;
+		}
+		else
+		{
+			gMC.xm = 0;
+		}
+
+		if (gKey & (gKeyDown | gKeyUp))
+		{
+			if (gKey & gKeyUp)
+				gMC.ym -= 0x100;
+
+			if (gKey & gKeyDown)
+				gMC.ym += 0x100;
+		}
+		else if (gMC.ym > 0x7F || gMC.ym < -0x7F)
+		{
+			if (gMC.ym > 0)
+				gMC.ym -= 0x80;
+			else if (gMC.ym < 0)
+				gMC.ym += 0x80;
+		}
+		else
+		{
+			gMC.ym = 0;
+		}
+	}
+	else
+	{
+		if (gMC.xm > 0x7F || gMC.xm < -0x3F)
+		{
+			if (gMC.xm > 0)
+				gMC.xm -= 0x80;
+			else if (gMC.xm < 0)
+				gMC.xm += 0x80;
+		}
+		else
+		{
+			gMC.xm = 0;
+		}
+
+		if (gMC.ym > 0x7F || gMC.ym < -0x3F)
+		{
+			if (gMC.ym > 0)
+				gMC.ym -= 0x80;
+			else if (gMC.ym < 0)
+				gMC.ym += 0x80;
+		}
+		else
+		{
+			gMC.ym = 0;
+		}
+	}
+
+	if (gMC.ym < -0x200 && gMC.flag & 2)
+		SetCaret(gMC.x, gMC.y - gMC.hit.top, 13, 5);
+	if (gMC.ym > 0x200 && gMC.flag & 8)
+		SetCaret(gMC.x, gMC.hit.bottom + gMC.y, 13, 5);
+
+	if (gMC.xm > 0x400)
+		gMC.xm = 0x400;
+	if (gMC.xm < -0x400)
+		gMC.xm = -0x400;
+
+	if (gMC.ym > 0x400)
+		gMC.ym = 0x400;
+	if (gMC.ym < -0x400)
+		gMC.ym = -0x400;
+
+	if ((gKey & (gKeyUp | gKeyLeft)) == (gKeyLeft | gKeyUp))
+	{
+		if (gMC.xm < -780)
+			gMC.xm = -780;
+		if (gMC.ym < -780)
+			gMC.ym = -780;
+	}
+
+	if ((gKey & (gKeyUp | gKeyRight)) == (gKeyRight | gKeyUp))
+	{
+		if (gMC.xm > 780)
+			gMC.xm = 780;
+		if (gMC.ym < -780)
+			gMC.ym = -780;
+	}
+
+	if ((gKey & (gKeyDown | gKeyLeft)) == (gKeyLeft | gKeyDown))
+	{
+		if (gMC.xm < -780)
+			gMC.xm = -780;
+		if (gMC.ym > 780)
+			gMC.ym = 780;
+	}
+
+	if ((gKey & (gKeyDown | gKeyRight)) == (gKeyRight | gKeyDown))
+	{
+		if (gMC.xm > 780)
+			gMC.xm = 780;
+		if (gMC.ym > 780)
+			gMC.ym = 780;
+	}
+
+	gMC.x += gMC.xm;
+	gMC.y += gMC.ym;
+}
+
 void AirProcess()
 {
 	if (gMC.equip & 0x10)
@@ -713,7 +838,7 @@
 				break;
 			
 			case 1:
-				//ActMyChar_Stream(bKey);
+				ActMyChar_Stream(bKey);
 				break;
 			
 			default:
--- a/src/NpcAct.h
+++ b/src/NpcAct.h
@@ -180,7 +180,8 @@
 void ActNpc175(NPCHAR *npc);
 void ActNpc176(NPCHAR *npc);
 void ActNpc177(NPCHAR *npc);
-
+void ActNpc178(NPCHAR *npc);
+void ActNpc179(NPCHAR *npc);
 void ActNpc180(NPCHAR *npc);
 void ActNpc181(NPCHAR *npc);
 void ActNpc182(NPCHAR *npc);
@@ -190,7 +191,7 @@
 void ActNpc186(NPCHAR *npc);
 void ActNpc187(NPCHAR *npc);
 void ActNpc188(NPCHAR *npc);
-
+void ActNpc189(NPCHAR *npc);
 void ActNpc190(NPCHAR *npc);
 void ActNpc191(NPCHAR *npc);
 void ActNpc192(NPCHAR *npc);
@@ -197,13 +198,45 @@
 void ActNpc193(NPCHAR *npc);
 void ActNpc194(NPCHAR *npc);
 void ActNpc195(NPCHAR *npc);
-
+void ActNpc196(NPCHAR *npc);
+void ActNpc197(NPCHAR *npc);
+void ActNpc198(NPCHAR *npc);
 void ActNpc199(NPCHAR *npc);
-
+void ActNpc200(NPCHAR *npc);
+void ActNpc201(NPCHAR *npc);
+void ActNpc202(NPCHAR *npc);
+void ActNpc203(NPCHAR *npc);
+void ActNpc204(NPCHAR *npc);
+void ActNpc205(NPCHAR *npc);
+void ActNpc206(NPCHAR *npc);
+void ActNpc207(NPCHAR *npc);
+void ActNpc208(NPCHAR *npc);
+void ActNpc209(NPCHAR *npc);
+void ActNpc210(NPCHAR *npc);
 void ActNpc211(NPCHAR *npc);
-
+void ActNpc212(NPCHAR *npc);
+void ActNpc213(NPCHAR *npc);
+void ActNpc214(NPCHAR *npc);
+void ActNpc215(NPCHAR *npc);
+void ActNpc216(NPCHAR *npc);
+void ActNpc217(NPCHAR *npc);
+void ActNpc218(NPCHAR *npc);
 void ActNpc219(NPCHAR *npc);
+void ActNpc220(NPCHAR *npc);
+void ActNpc221(NPCHAR *npc);
+void ActNpc222(NPCHAR *npc);
+void ActNpc223(NPCHAR *npc);
+void ActNpc224(NPCHAR *npc);
+void ActNpc225(NPCHAR *npc);
+void ActNpc226(NPCHAR *npc);
+void ActNpc227(NPCHAR *npc);
+void ActNpc228(NPCHAR *npc);
 
+void ActNpc259(NPCHAR *npc);
+
+void ActNpc271(NPCHAR *npc);
+void ActNpc272(NPCHAR *npc);
+
 void ActNpc278(NPCHAR *npc);
 
 void ActNpc292(NPCHAR *npc);
@@ -215,6 +248,12 @@
 void ActNpc302(NPCHAR *npc);
 
 void ActNpc334(NPCHAR *npc);
+void ActNpc335(NPCHAR *npc);
+void ActNpc336(NPCHAR *npc);
+
+void ActNpc347(NPCHAR *npc);
+
+void ActNpc349(NPCHAR *npc);
 
 void ActNpc355(NPCHAR *npc);
 
--- a/src/NpcAct160.cpp
+++ b/src/NpcAct160.cpp
@@ -1517,3 +1517,89 @@
 
 	npc->rect = rc[npc->ani_no];
 }
+
+//Core blade projectile
+void ActNpc178(NPCHAR *npc)
+{
+	if (npc->flag & 0xFF)
+	{
+		SetCaret(npc->x, npc->y, 2, 0);
+		npc->cond = 0;
+	}
+
+	if (npc->flag & 0x100)
+	{
+		npc->y += npc->ym / 2;
+		npc->x += npc->xm / 2;
+	}
+	else
+	{
+		npc->y += npc->ym;
+		npc->x += npc->xm;
+	}
+
+	RECT rect_left[3];
+
+	rect_left[0] = {0, 224, 16, 240};
+	rect_left[1] = {16, 224, 32, 240};
+	rect_left[2] = {32, 224, 48, 240};
+
+	if (++npc->ani_wait > 1)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	npc->rect = rect_left[npc->ani_no];
+
+	if (++npc->count1 > 150)
+	{
+		VanishNpChar(npc);
+		SetCaret(npc->x, npc->y, 2, 0);
+	}
+}
+
+//Core wisp projectile
+void ActNpc179(NPCHAR *npc)
+{
+	if (npc->flag & 0xFF)
+	{
+		npc->cond = 0;
+		SetCaret(npc->x, npc->y, 2, 0);
+	}
+
+	npc->xm -= 0x20;
+	npc->ym = 0;
+
+	if (npc->xm < -0x400)
+		npc->xm = -0x400;
+
+	npc->y += npc->ym;
+	npc->x += npc->xm;
+
+	RECT rect_left[3];
+
+	rect_left[0] = {48, 224, 72, 240};
+	rect_left[1] = {72, 224, 96, 240};
+	rect_left[2] = {96, 224, 120, 240};
+
+	if (++npc->ani_wait > 1)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	npc->rect = rect_left[npc->ani_no];
+
+	if (++npc->count1 > 300)
+	{
+		VanishNpChar(npc);
+		SetCaret(npc->x, npc->y, 2, 0);
+	}
+}
--- a/src/NpcAct180.cpp
+++ b/src/NpcAct180.cpp
@@ -12,6 +12,7 @@
 #include "Frame.h"
 #include "Bullet.h"
 #include "Flags.h"
+#include "NpcHit.h"
 
 //Curly AI
 void ActNpc180(NPCHAR *npc)
@@ -858,6 +859,72 @@
 		npc->rect = rect_right[npc->ani_no];
 }
 
+//Unused homing flame object (possibly related to the Core?)
+void ActNpc189(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->xm = -0x40;
+			// Fallthrough
+		case 1:
+			npc->y += npc->ym;
+
+			if (++npc->act_wait > 0x100)
+				npc->act_no = 10;
+
+			break;
+
+		case 10:
+			if (gMC.x < npc->x)
+				npc->xm -= 8;
+			else
+				npc->xm += 8;
+
+			if (gMC.y < npc->y)
+				npc->ym -= 8;
+			else
+				npc->ym += 8;
+
+			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 (gMC.x < npc->x)
+		npc->direct = 0;
+	else
+		npc->direct = 2;
+
+	if (++npc->ani_wait > 2)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	RECT rect[3];
+
+	rect[0] = {224, 184, 232, 200};
+	rect[1] = {232, 184, 240, 200};
+	rect[2] = {240, 184, 248, 200};
+
+	npc->rect = rect[npc->ani_no];
+}
+
 //Broken robot
 void ActNpc190(NPCHAR *npc)
 {
@@ -1107,7 +1174,143 @@
 //Grate
 void ActNpc195(NPCHAR *npc)
 {
-	npc->rect = {112, 64, 128, 80};
+	RECT rc = {112, 64, 128, 80};
+	npc->rect = rc;
+}
+
+//Ironhead motion wall
+void ActNpc196(NPCHAR *npc)
+{
+	RECT rcLeft = {112, 64, 144, 80};
+	RECT rcRight = {112, 80, 144, 96};
+
+	npc->x -= 0xC00;
+
+	if (npc->x <= 0x26000)
+		npc->x += 0x2C000;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft;
+	else
+		npc->rect = rcRight;
+}
+
+//Porcupine Fish
+void ActNpc197(NPCHAR *npc)
+{
+	RECT rc[4];
+
+	rc[0] = {0, 0, 16, 16};
+	rc[1] = {16, 0, 32, 16};
+	rc[2] = {32, 0, 48, 16};
+	rc[3] = {48, 0, 64, 16};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 10;
+			npc->ani_wait = 0;
+			npc->ym = Random(-0x200, 0x200);
+			npc->xm = 0x800;
+			// Fallthrough
+		case 10:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (npc->xm < 0)
+			{
+				npc->damage = 3;
+				npc->act_no = 20;
+			}
+
+			break;
+
+		case 20:
+			npc->damage = 3;
+
+			if (++npc->ani_wait > 0)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 3)
+				npc->ani_no = 2;
+
+			if (npc->x < 0x6000)
+			{
+				npc->destroy_voice = 0;
+				LoseNpChar(npc, 1);
+			}
+
+			break;
+	}
+
+	if (npc->flag & 2)
+		npc->ym = 0x200;
+	if (npc->flag & 8)
+		npc->ym = -0x200;
+
+	npc->xm -= 12;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Ironhead projectile
+void ActNpc198(NPCHAR *npc)
+{
+	RECT rcRight[3];
+
+	rcRight[0] = {208, 48, 224, 72};
+	rcRight[1] = {224, 48, 240, 72};
+	rcRight[2] = {240, 48, 256, 72};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			if (++npc->act_wait > 20)
+			{
+				npc->act_no = 1;
+				npc->xm = 0;
+				npc->ym = 0;
+				npc->count1 = 0;
+			}
+
+			break;
+
+		case 1:
+			npc->xm += 0x20;
+			break;
+	}
+
+	if (++npc->ani_wait > 0)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	npc->rect = rcRight[npc->ani_no];
+
+	if (++npc->count1 > 100)
+		npc->cond = 0;
+
+	if (npc->count1 % 4 == 1)
+		PlaySoundObject(46, 1);
 }
 
 //Water/wind particles
--- a/src/NpcAct200.cpp
+++ b/src/NpcAct200.cpp
@@ -8,7 +8,856 @@
 #include "Sound.h"
 #include "Back.h"
 #include "Triangle.h"
+#include "Bullet.h"
+#include "Caret.h"
+#include "Frame.h"
 
+//Dragon Zombie
+void ActNpc200(NPCHAR *npc)
+{
+	RECT rcLeft[6];
+	RECT rcRight[6];
+
+	rcLeft[0] = {0, 0, 40, 40};
+	rcLeft[1] = {40, 0, 80, 40};
+	rcLeft[2] = {80, 0, 120, 40};
+	rcLeft[3] = {120, 0, 160, 40};
+	rcLeft[4] = {160, 0, 200, 40};
+	rcLeft[5] = {200, 0, 240, 40};
+
+	rcRight[0] = {0, 40, 40, 80};
+	rcRight[1] = {40, 40, 80, 80};
+	rcRight[2] = {80, 40, 120, 80};
+	rcRight[3] = {120, 40, 160, 80};
+	rcRight[4] = {160, 40, 200, 80};
+	rcRight[5] = {200, 40, 240, 80};
+
+	if (npc->act_no < 100 && npc->life < 950)
+	{
+		PlaySoundObject(72, 1);
+		SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8);
+		SetExpObjects(npc->x, npc->y, npc->exp);
+		npc->act_no = 100;
+		npc->bits &= ~0x20;
+		npc->damage = 0;
+	}
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 10;
+			npc->count1 = 0;
+			// Fallthrough
+		case 10:
+			if (++npc->ani_wait > 30)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (npc->count1)
+				--npc->count1;
+
+			if (npc->count1 == 0 && gMC.x > npc->x - 0xE000 && gMC.x < npc->x + 0xE000)
+				npc->act_no = 20;
+
+			break;
+
+		case 20:
+			npc->act_no = 21;
+			npc->act_wait = 0;
+			// Fallthrough
+		case 21:
+			if (++npc->act_wait / 2 % 2)
+				npc->ani_no = 2;
+			else
+				npc->ani_no = 3;
+
+			if (npc->act_wait > 30)
+				npc->act_no = 30;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			break;
+
+		case 30:
+			npc->act_no = 31;
+			npc->act_wait = 0;
+			npc->ani_no = 4;
+			npc->tgt_x = gMC.x;
+			npc->tgt_y = gMC.y;
+			// Fallthrough
+		case 31:
+			if (++npc->act_wait < 40 && npc->act_wait % 8 == 1)
+			{
+				const unsigned char deg = npc->direct ? GetArktan(npc->x + 0x1C00 - npc->tgt_x, npc->y - npc->tgt_y) : GetArktan( npc->x - 0x1C00 - npc->tgt_x, npc->y - npc->tgt_y) + Random(-6, 6);
+				const int ym = 3 * GetSin(deg);
+				const int xm = 3 * GetCos(deg);
+
+				if (npc->direct == 0)
+					SetNpChar(202, npc->x - 0x1C00, npc->y, xm, ym, 0, 0, 0x100);
+				else
+					SetNpChar(202, npc->x + 0x1C00, npc->y, xm, ym, 0, 0, 0x100);
+
+				if ((gMC.cond & 2) == 0)
+					PlaySoundObject(33, 1);
+			}
+
+			if (npc->act_wait > 60)
+			{
+				npc->act_no = 10;
+				npc->count1 = Random(100, 200);
+				npc->ani_wait = 0;
+			}
+
+			break;
+
+		case 100:
+			npc->ani_no = 5;
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Dragon Zombie (dead)
+void ActNpc201(NPCHAR *npc)
+{
+	RECT rcLeft[1];
+	RECT rcRight[1];
+
+	rcLeft[0] = {200, 0, 240, 40};
+	rcRight[0] = {200, 40, 240, 80};
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Dragon Zombie projectile
+void ActNpc202(NPCHAR *npc)
+{
+	RECT rect_left[3];
+
+	if (npc->flag & 0xFF)
+	{
+		npc->cond = 0;
+		SetCaret(npc->x, npc->y, 2, 0);
+	}
+
+	npc->y += npc->ym;
+	npc->x += npc->xm;
+
+	rect_left[0] = {184, 216, 200, 240};
+	rect_left[1] = {200, 216, 216, 240};
+	rect_left[2] = {216, 216, 232, 240};
+
+	if (++npc->ani_wait > 1)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if ( npc->ani_no > 2 )
+		npc->ani_no = 0;
+
+	npc->rect = rect_left[npc->ani_no];
+
+	if (++npc->count1 > 300)
+	{
+		npc->cond = 0;
+		SetCaret(npc->x, npc->y, 2, 0);
+	}
+}
+
+//Critter (destroyed Egg Corridor)
+void ActNpc203(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {0, 80, 16, 96};
+	rcLeft[1] = {16, 80, 32, 96};
+	rcLeft[2] = {32, 80, 48, 96};
+
+	rcRight[0] = {0, 96, 16, 112};
+	rcRight[1] = {16, 96, 32, 112};
+	rcRight[2] = {32, 96, 48, 112};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->y += 0x600;
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (npc->act_wait >= 8 && gMC.x > npc->x - 0xE000 && gMC.x < npc->x + 0xE000 && gMC.y > npc->y - 0xA000 && gMC.y < npc->y + 0xA000)
+			{
+				npc->ani_no = 1;
+			}
+			else
+			{
+				if ( npc->act_wait < 8 )
+					++npc->act_wait;
+				npc->ani_no = 0;
+			}
+
+			if (npc->shock)
+			{
+				npc->act_no = 2;
+				npc->ani_no = 0;
+				npc->act_wait = 0;
+			}
+
+			if (npc->act_wait >= 8 && gMC.x > npc->x - 0x6000 && gMC.x < npc->x + 0x6000 && gMC.y > npc->y - 0xA000 && gMC.y < npc->y + 0x6000)
+			{
+				npc->act_no = 2;
+				npc->ani_no = 0;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 3;
+				npc->ani_no = 2;
+				npc->ym = -0x5FF;
+
+				if ((gMC.cond & 2) == 0)
+					PlaySoundObject(30, 1);
+
+				if (npc->direct == 0)
+					npc->xm = -0x100;
+				else
+					npc->xm = 0x100;
+			}
+
+			break;
+
+		case 3:
+			if (npc->flag & 8)
+			{
+				npc->xm = 0;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+				npc->act_no = 1;
+
+				if ((gMC.cond & 2) == 0)
+					PlaySoundObject(23, 1);
+			}
+
+			break;
+	}
+
+	npc->ym += 0x40;
+	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];
+}
+
+//Falling spike (small)
+void ActNpc204(NPCHAR *npc)
+{
+	RECT rc[2]; // [sp+4h] [bp-20h]@1
+
+	rc[0] = {240, 80, 256, 96};
+	rc[1] = {240, 144, 256, 160};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->tgt_x = npc->x;
+			// Fallthrough
+		case 1:
+			if (gMC.x > npc->x - 0x1800 && gMC.x < npc->x + 0x1800 && gMC.y > npc->y)
+				npc->act_no = 2;
+			break;
+
+		case 2:
+			if (++npc->act_wait / 6 % 2)
+				npc->x = npc->tgt_x - 0x200;
+			else
+				npc->x = npc->tgt_x;
+
+			if (npc->act_wait > 30)
+			{
+				npc->act_no = 3;
+				npc->ani_no = 1;
+			}
+			break;
+
+		case 3:
+			npc->ym += 0x20;
+
+			if (npc->flag & 0xFF)
+			{
+				if ((gMC.cond & 2) == 0)
+					PlaySoundObject(12, 1);
+
+				SetDestroyNpChar(npc->x, npc->y, npc->view.back, 4);
+				npc->cond = 0;
+				return;
+			}
+
+			break;
+	}
+
+	if (npc->ym > 0xC00)
+		npc->ym = 0xC00;
+
+	npc->y += npc->ym;
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Falling spike (large)
+void ActNpc205(NPCHAR *npc)
+{
+	RECT rc[2];
+
+	rc[0] = {112, 80, 128, 112};
+	rc[1] = {128, 80, 144, 112};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->tgt_x = npc->x;
+			npc->y += 0x800;
+			// Fallthrough
+		case 1:
+			if (gMC.x > npc->x - 0x1800 && gMC.x < npc->x + 0x1800 && gMC.y > npc->y)
+				npc->act_no = 2;
+
+			break;
+
+		case 2:
+			if (++npc->act_wait / 6 % 2)
+				npc->x = npc->tgt_x - 0x200;
+			else
+				npc->x = npc->tgt_x;
+
+			if (npc->act_wait > 30)
+			{
+				npc->act_no = 3;
+				npc->ani_no = 1;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 3:
+			npc->ym += 0x20;
+
+			if (gMC.y > npc->y)
+			{
+				npc->bits &= ~0x40;
+				npc->damage = 0x7F;
+			}
+			else
+			{
+				npc->bits |= 0x40;
+				npc->damage = 0;
+			}
+
+			if (++npc->act_wait > 8 && npc->flag & 0xFF)
+			{
+				npc->bits |= 0x40;
+				npc->act_no = 4;
+				npc->act_wait = 0;
+				npc->ym = 0;
+				npc->damage = 0;
+				PlaySoundObject(12, 1);
+				SetDestroyNpChar(npc->x, npc->y, npc->view.back, 4);
+				SetBullet(24, npc->x, npc->y, 0);
+				return;
+			}
+
+			break;
+
+		case 4:
+			if (++npc->act_wait > 4)
+			{
+				npc->act_no = 5;
+				npc->bits |= 0x20;
+			}
+
+			break;
+	}
+
+	if (npc->ym > 0xC00)
+		npc->ym = 0xC00;
+
+	npc->y += npc->ym;
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Counter Bomb
+void ActNpc206(NPCHAR *npc)
+{
+	RECT rect_left[3];
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->tgt_x = npc->x;
+			npc->tgt_y = npc->y;
+			npc->count1 = 120;
+			npc->act_wait = Random(0, 50);
+			// Fallthrough
+		case 1:
+			if (++npc->act_wait >= 50)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 2;
+				npc->ym = 0x300;
+			}
+
+			break;
+
+		case 2:
+			if (gMC.x > npc->x - 0xA000 && gMC.x < npc->x + 0xA000)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 3;
+			}
+
+			if (npc->shock)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 3;
+			}
+
+			break;
+
+		case 3:
+			switch (npc->act_wait)
+			{
+				case 60 * 0:
+					SetNpChar(207, npc->x + 0x2000, npc->y + 0x800, 0, 0, 0, 0, 0x100);
+					break;
+
+				case 60 * 1:
+					SetNpChar(207, npc->x + 0x2000, npc->y + 0x800, 0, 0, 1, 0, 0x100);
+					break;
+
+				case 60 * 2:
+					SetNpChar(207, npc->x + 0x2000, npc->y + 0x800, 0, 0, 2, 0, 0x100);
+					break;
+
+				case 60 * 3:
+					SetNpChar(207, npc->x + 0x2000, npc->y + 0x800, 0, 0, 3, 0, 0x100);
+					break;
+
+				case 60 * 4:
+					SetNpChar(207, npc->x + 0x2000, npc->y + 0x800, 0, 0, 4, 0, 0x100);
+					break;
+
+				case 60 * 5:
+					npc->hit.back = 0x10000;
+					npc->hit.front = 0x10000;
+					npc->hit.top = 0xC800;
+					npc->hit.bottom = 0xC800;
+					npc->damage = 30;
+					PlaySoundObject(35, 1);
+					SetDestroyNpChar(npc->x, npc->y, 0x10000, 100);
+					SetQuake(20);
+					npc->cond |= 8;
+					break;
+			}
+
+			++npc->act_wait;
+			break;
+	}
+
+	if (npc->act_no > 1)
+	{
+		if (npc->tgt_y < npc->y)
+			npc->ym -= 0x10;
+		if (npc->tgt_y > npc->y)
+			npc->ym += 0x10;
+
+		if (npc->ym > 0x100)
+			npc->ym = 0x100;
+		if (npc->ym < -0x100)
+			npc->ym = -0x100;
+	}
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	rect_left[0] = {80, 80, 120, 120};
+	rect_left[1] = {120, 80, 160, 120};
+	rect_left[2] = {160, 80, 200, 120};
+
+	if (++npc->ani_wait > 4)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	npc->rect = rect_left[npc->ani_no];
+}
+
+//Counter Bomb's countdown
+void ActNpc207(NPCHAR *npc)
+{
+	RECT rc[5];
+
+	rc[0] = {0, 144, 16, 160};
+	rc[1] = {16, 144, 32, 160};
+	rc[2] = {32, 144, 48, 160};
+	rc[3] = {48, 144, 64, 160};
+	rc[4] = {64, 144, 80, 160};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = npc->direct;
+			PlaySoundObject(43, 1);
+			// Fallthrough
+		case 1:
+			npc->x += 0x200;
+
+			if (++npc->act_wait > 8)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 2;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 30)
+			{
+				npc->cond = 0;
+				return;
+			}
+
+			break;
+	}
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Basu (destroyed Egg Corridor)
+void ActNpc208(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {248, 80, 272, 104};
+	rcLeft[1] = {272, 80, 296, 104};
+	rcLeft[2] = {296, 80, 320, 104};
+
+	rcRight[0] = {248, 104, 272, 128};
+	rcRight[1] = {272, 104, 296, 128};
+	rcRight[2] = {296, 104, 320, 128};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			if (gMC.x < npc->x + 0x2000 && gMC.x > npc->x - 0x2000)
+			{
+				npc->bits |= 0x20;
+				npc->ym = -0x200;
+				npc->tgt_x = npc->x;
+				npc->tgt_y = npc->y;
+				npc->act_no = 1;
+				npc->act_wait = 0;
+				npc->count1 = npc->direct;
+				npc->count2 = 0;
+				npc->damage = 6;
+
+				if (npc->direct == 0)
+				{
+					npc->x = gMC.x + 0x20000;
+					npc->xm = -0x2FF;
+				}
+				else
+				{
+					npc->x = gMC.x - 0x20000;
+					npc->xm = 0x2FF;
+				}
+			}
+			else
+			{
+				npc->rect.right = 0;
+				npc->damage = 0;
+				npc->xm = 0;
+				npc->ym = 0;
+				npc->bits &= ~0x20;
+			}
+
+			return;
+
+		case 1:
+			if (gMC.x < npc->x)
+			{
+				npc->direct = 0;
+				npc->xm -= 0x10;
+			}
+			else
+			{
+				npc->direct = 2;
+				npc->xm += 0x10;
+			}
+
+			if (npc->flag & 1)
+				npc->xm = 0x200;
+			if (npc->flag & 4)
+				npc->xm = -0x200;
+
+			if (npc->tgt_y > npc->y)
+				npc->ym += 8;
+			else
+				npc->ym -= 8;
+
+			if (npc->xm > 0x2FF)
+				npc->xm = 0x2FF;
+			if (npc->xm < -0x2FF)
+				npc->xm = -0x2FF;
+
+			if (npc->ym > 0x200)
+				npc->ym = 0x200;
+			if (npc->ym < -0x200)
+				npc->ym = -0x200;
+
+			if (npc->shock)
+			{
+				npc->x += npc->xm / 2;
+				npc->y += npc->ym / 2;
+			}
+			else
+			{
+				npc->x += npc->xm;
+				npc->y += npc->ym;
+			}
+
+			if (gMC.x > npc->x + 0x32000 || gMC.x < npc->x - 0x32000)
+			{
+				npc->act_no = 0;
+				npc->xm = 0;
+				npc->direct = npc->count1;
+				npc->x = npc->tgt_x;
+				npc->rect.right = 0;
+				npc->damage = 0;
+				return;
+			}
+
+			break;
+	}
+
+	if (npc->act_no)
+	{
+		if (npc->act_wait < 150)
+			++npc->act_wait;
+
+		if (npc->act_wait == 150)
+		{
+			if (++npc->count2 % 8 == 0 && npc->x < gMC.x + 0x14000 && npc->x > gMC.x - 0x14000)
+			{
+				const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y) + Random(-6, 6);
+				const int ym = 3 * GetSin(deg);
+				const int xm = 3 * GetCos(deg);
+				SetNpChar(209, npc->x, npc->y, xm, ym, 0, 0, 0x100);
+				PlaySoundObject(39, 1);
+			}
+
+			if (npc->count2 > 16)
+			{
+				npc->act_wait = 0;
+				npc->count2 = 0;
+			}
+		}
+	}
+
+	if (++npc->ani_wait > 1)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 1)
+		npc->ani_no = 0;
+
+	if (npc->act_wait > 120 && npc->act_wait / 2 % 2 == 1 && npc->ani_no == 1)
+		npc->ani_no = 2;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Basu projectile (destroyed Egg Corridor)
+void ActNpc209(NPCHAR *npc)
+{
+	if (npc->flag & 0xFF)
+	{
+		npc->cond = 0;
+		SetCaret(npc->x, npc->y, 2, 0);
+	}
+
+	npc->y += npc->ym;
+	npc->x += npc->xm;
+
+	RECT rect_left[4];
+
+	rect_left[0] = {232, 96, 248, 112};
+	rect_left[1] = {200, 112, 216, 128};
+	rect_left[2] = {216, 112, 232, 128};
+	rect_left[3] = {232, 112, 248, 128};
+
+	if (++npc->ani_wait > 2)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 3)
+		npc->ani_no = 0;
+
+	npc->rect = rect_left[npc->ani_no];
+
+	if (++npc->count1 > 300)
+	{
+		npc->cond = 0;
+		SetCaret(npc->x, npc->y, 2, 0);
+	}
+}
+
+//Beetle (destroyed Egg Corridor)
+void ActNpc210(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {0, 112, 16, 128};
+	rcLeft[1] = {16, 112, 32, 128};
+
+	rcRight[0] = {32, 112, 48, 128};
+	rcRight[1] = {48, 112, 64, 128};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			if (gMC.x >= npc->x + 0x2000 || gMC.x <= npc->x - 0x2000)
+			{
+				npc->bits &= ~0x20;
+				npc->rect.right = 0;
+				npc->damage = 0;
+				npc->xm = 0;
+				npc->ym = 0;
+				return;
+			}
+
+			npc->bits |= 0x20;
+			npc->ym = -0x200;
+			npc->tgt_y = npc->y;
+			npc->act_no = 1;
+			npc->damage = 2;
+
+			if (npc->direct == 0)
+			{
+				npc->x = gMC.x + 0x20000;
+				npc->xm = -0x2FF;
+			}
+			else
+			{
+				npc->x = gMC.x - 0x20000;
+				npc->xm = 0x2FF;
+			}
+
+			break;
+
+		case 1:
+			if (gMC.x < npc->x)
+			{
+				npc->direct = 0;
+				npc->xm -= 0x10;
+			}
+			else
+			{
+				npc->direct = 2;
+				npc->xm += 0x10;
+			}
+
+			if (npc->xm > 0x2FF)
+				npc->xm = 0x2FF;
+			if (npc->xm < -0x2FF)
+				npc->xm = -0x2FF;
+
+			if (npc->tgt_y > npc->y)
+				npc->ym += 8;
+			else
+				npc->ym -= 8;
+
+			if (npc->ym > 0x200)
+				npc->ym = 0x200;
+			if (npc->ym < -0x200)
+				npc->ym = -0x200;
+
+			if (npc->shock)
+			{
+				npc->x += npc->xm / 2;
+				npc->y += npc->ym / 2;
+			}
+			else
+			{
+				npc->x += npc->xm;
+				npc->y += npc->ym;
+			}
+
+			break;
+	}
+
+	if (++npc->ani_wait > 1)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 1)
+		npc->ani_no = 0;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
 //Spikes (small)
 void ActNpc211(NPCHAR *npc)
 {
@@ -20,6 +869,594 @@
 	rects[3] = {304, 200, 320, 216};
 
 	npc->rect = rects[npc->code_event];
+}
+
+//Sky Dragon
+void ActNpc212(NPCHAR *npc)
+{
+	RECT rcRight[4];
+
+	rcRight[0] = {160, 152, 200, 192};
+	rcRight[1] = {200, 152, 240, 192};
+	rcRight[2] = {240, 112, 280, 152};
+	rcRight[3] = {280, 112, 320, 152};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->y -= 0x800;
+			// Fallthrough
+		case 1:
+			if (++npc->ani_wait > 30)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+			npc->tgt_y = npc->y - 0x2000;
+			npc->tgt_x = npc->x - 0xC00;
+			npc->ym = 0;
+			npc->bits |= 8;
+			// Fallthrough
+		case 11:
+			if (npc->tgt_x > npc->x)
+				npc->xm += 8;
+			else
+				npc->xm -= 8;
+
+			if (npc->tgt_y > npc->y)
+				npc->ym += 8;
+			else
+				npc->ym -= 8;
+
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+
+			if (++npc->ani_wait > 5)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 3)
+				npc->ani_no = 2;
+
+			break;
+
+		case 20:
+			npc->act_no = 21;
+			npc->bits |= 8u;
+			// Fallthrough
+		case 21:
+			if (npc->tgt_y > npc->y)
+				npc->ym += 0x10;
+			else
+				npc->ym -= 0x10;
+
+			npc->xm += 0x20;
+
+			if (npc->xm > 0x600)
+				npc->xm = 0x600;
+			if (npc->xm < -0x600)
+				npc->xm = -0x600;
+
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 3)
+				npc->ani_no = 2;
+
+			break;
+
+		case 30:
+			npc->act_no = 31;
+			SetNpChar(297, 0, 0, 0, 0, 0, npc, 0x100);
+			break;
+	}
+
+	npc->rect = rcRight[npc->ani_no];
+
+	if (gMC.equip & 0x40)
+	{
+		if (npc->ani_no > 1)
+		{
+			npc->rect.top += 40;
+			npc->rect.bottom += 40;
+		}
+	}
+}
+
+//Night Spirit
+void ActNpc213(NPCHAR *npc)
+{
+	RECT rect[10];
+
+	rect[0] = {0, 0, 0, 0};
+	rect[1] = {0, 0, 48, 48};
+	rect[2] = {48, 0, 96, 48};
+	rect[3] = {96, 0, 144, 48};
+	rect[4] = {144, 0, 192, 48};
+	rect[5] = {192, 0, 240, 48};
+	rect[6] = {240, 0, 288, 48};
+	rect[7] = {0, 48, 48, 96};
+	rect[8] = {48, 48, 96, 96};
+	rect[9] = {96, 48, 144, 96};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->ani_no = 0;
+			npc->tgt_x = npc->x;
+			npc->tgt_y = npc->y;
+			// Fallthrough
+		case 1:
+			if (gMC.y > npc->y - 0x1000 && gMC.y < npc->y + 0x1000)
+			{
+				if (npc->direct == 0)
+					npc->y -= 0x1E000;
+				else
+					npc->y += 0x1E000;
+
+				npc->act_no = 10;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+				npc->ym = 0;
+				npc->bits |= 0x20;
+			}
+
+			break;
+
+		case 10:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 3)
+				npc->ani_no = 1;
+
+			if (++npc->act_wait > 200)
+			{
+				npc->act_no = 20;
+				npc->act_wait = 0;
+				npc->ani_no = 4;
+			}
+
+			break;
+
+		case 20:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 6)
+				npc->ani_no = 4;
+
+			if (++npc->act_wait > 50)
+			{
+				npc->act_no = 30;
+				npc->act_wait = 0;
+				npc->ani_no = 7;
+			}
+
+			break;
+
+		case 30:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 9)
+				npc->ani_no = 7;
+
+			if (++npc->act_wait % 5 == 1)
+			{
+				SetNpChar(214, npc->x, npc->y, (Random(2, 12) * 0x200) / 4, Random(-0x200, 0x200), 0, 0, 0x100);
+				PlaySoundObject(21, 1);
+			}
+
+			if (npc->act_wait > 50)
+			{
+				npc->act_no = 10;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 40:
+			if (npc->tgt_y > npc->y)
+				npc->ym += 0x40;
+			else
+				npc->ym -= 0x40;
+
+			if (npc->ym < -0x400)
+				npc->ym = -0x400;
+			if (npc->ym > 0x400)
+				npc->ym = 0x400;
+
+			if (npc->shock)
+				npc->y += npc->ym / 2;
+			else
+				npc->y += npc->ym;
+
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 6)
+				npc->ani_no = 4;
+
+			if (gMC.y < npc->tgt_y + 0x1E000 && gMC.y > npc->tgt_y - 0x1E000)
+			{
+				npc->act_no = 20;
+				npc->act_wait = 0;
+				npc->ani_no = 4;
+			}
+			break;
+	}
+
+	if (npc->act_no >= 10 && npc->act_no <= 30)
+	{
+		if (gMC.y > npc->y)
+			npc->ym += 25;
+		else
+			npc->ym -= 25;
+
+		if (npc->ym < -0x400)
+			npc->ym = -0x400;
+		if (npc->ym > 0x400)
+			npc->ym = 0x400;
+
+		if (npc->flag & 2)
+			npc->ym = 0x200;
+		if (npc->flag & 8)
+			npc->ym = -0x200;
+
+		if (npc->shock)
+			npc->y += npc->ym / 2;
+		else
+			npc->y += npc->ym;
+
+		if ( gMC.y > npc->tgt_y + 0x1E000 || gMC.y < npc->tgt_y - 0x1E000 )
+			npc->act_no = 40;
+	}
+
+	npc->rect = rect[npc->ani_no];
+}
+
+//Night Spirit projectile
+void ActNpc214(NPCHAR *npc)
+{
+	RECT rect[3];
+
+	rect[0] = {144, 48, 176, 64};
+	rect[1] = {176, 48, 208, 64};
+	rect[2] = {208, 48, 240, 64};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->bits |= 8;
+			// Fallthrough
+		case 1:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 2)
+				npc->ani_no = 0;
+
+			npc->xm -= 25;
+
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+
+			if (npc->xm < 0)
+				npc->bits &= ~8;
+
+			if (npc->flag & 0xFF)
+			{
+				SetDestroyNpChar(npc->x, npc->y, npc->view.back, 4);
+				PlaySoundObject(28, 1);
+				npc->cond = 0;
+			}
+
+			break;
+	}
+
+	npc->rect = rect[npc->ani_no];
+}
+
+//Sandcroc (Outer Wall)
+void ActNpc215(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->ani_no = 0;
+			npc->act_no = 1;
+			npc->act_wait = 0;
+			npc->tgt_y = npc->y;
+			npc->bits &= ~0x20;
+			npc->bits &= ~4;
+			npc->bits &= ~1;
+			npc->bits &= ~8;
+			// Fallthrough
+		case 1:
+			if (gMC.x > npc->x - 0x1800 && gMC.x < npc->x + 0x1800 && gMC.y > npc->y && gMC.y < npc->y + 0x1000)
+			{
+				npc->act_no = 15;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 15:
+			if (++npc->act_wait > 10)
+			{
+				PlaySoundObject(102, 1);
+				npc->act_no = 20;
+			}
+
+			break;
+
+		case 20:
+			if (++npc->ani_wait > 3)
+			{
+				++npc->ani_no;
+				npc->ani_wait = 0;
+			}
+
+			if (npc->ani_no == 3)
+				npc->damage = 15;
+
+			if (npc->ani_no == 4)
+			{
+				npc->bits |= 0x20;
+				npc->act_no = 30;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 30:
+			npc->bits |= 1;
+			npc->damage = 0;
+			++npc->act_wait;
+
+			if (npc->shock)
+			{
+				npc->act_no = 40;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 40:
+			npc->bits |= 8;
+			npc->y += 0x200;
+
+			if (++npc->act_wait == 32)
+			{
+				npc->bits &= ~1;
+				npc->bits &= ~0x20;
+				npc->act_no = 50;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 50:
+			if (npc->act_wait < 100)
+			{
+				++npc->act_wait;
+			}
+			else
+			{
+				npc->y = npc->tgt_y;
+				npc->ani_no = 0;
+				npc->act_no = 0;
+			}
+
+			break;
+	}
+
+	RECT rect[5];
+
+	rect[0] = {0, 0, 0, 0};
+	rect[1] = {0, 96, 48, 128};
+	rect[2] = {48, 96, 96, 128};
+	rect[3] = {96, 96, 144, 128};
+	rect[4] = {144, 96, 192, 128};
+
+	npc->rect = rect[npc->ani_no];
+}
+
+//Debug Cat
+void ActNpc216(NPCHAR *npc)
+{
+	RECT rect = {256, 192, 272, 216};
+
+	npc->rect = rect;
+}
+
+//Itoh
+void ActNpc217(NPCHAR *npc)
+{
+	RECT rect[8];
+
+	rect[0] = {144, 64, 160, 80};
+	rect[1] = {160, 64, 176, 80};
+	rect[2] = {176, 64, 192, 80};
+	rect[3] = {192, 64, 208, 80};
+	rect[4] = {144, 80, 160, 96};
+	rect[5] = {160, 80, 176, 96};
+	rect[6] = {144, 80, 160, 96};
+	rect[7] = {176, 80, 192, 96};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			npc->xm = 0;
+			// Fallthrough
+		case 1:
+			if (Random(0, 120) == 10)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->ani_no = 2;
+			npc->xm = 0;
+			break;
+
+		case 20:
+			npc->act_no = 21;
+			npc->ani_no = 2;
+			npc->xm += 0x200;
+			npc->ym -= 0x400;
+			break;
+
+		case 21:
+			if (npc->flag & 8)
+			{
+				npc->ani_no = 3;
+				npc->act_no = 30;
+				npc->act_wait = 0;
+				npc->xm = 0;
+				npc->tgt_x = npc->x;
+			}
+
+			break;
+
+		case 30:
+			npc->ani_no = 3;
+
+			if (++npc->act_wait / 2 % 2)
+				npc->x = npc->tgt_x + 0x200;
+			else
+				npc->x = npc->tgt_x;
+
+			break;
+
+		case 40:
+			npc->act_no = 41;
+			npc->ym = -0x200;
+			npc->ani_no = 2;
+			// Fallthrough
+		case 41:
+			if (npc->flag & 8)
+			{
+				npc->act_no = 42;
+				npc->ani_no = 4;
+			}
+
+			break;
+
+		case 42:
+			npc->xm = 0;
+			npc->ani_no = 4;
+			break;
+
+		case 50:
+			npc->act_no = 51;
+			npc->act_wait = 0;
+			// Fallthrough
+		case 51:
+			if (++npc->act_wait > 32)
+				npc->act_no = 42;
+
+			npc->xm = 0x200;
+
+			if (++npc->ani_wait > 3)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 7)
+				npc->ani_no = 4;
+
+			break;
+	}
+
+	npc->ym += 0x40;
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	npc->rect = rect[npc->ani_no];
+}
+
+// Core giant energy ball projectile
+void ActNpc218(NPCHAR *npc)
+{
+	RECT rc[2];
+
+	rc[0] = {256, 120, 288, 152};
+	rc[1] = {288, 120, 320, 152};
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	if (++npc->act_wait > 200)
+		npc->cond = 0;
+
+	if (++npc->ani_wait > 2)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 1)
+		npc->ani_no = 0;
+
+	npc->rect = rc[npc->ani_no];
 }
 
 //Smoke generator
--- /dev/null
+++ b/src/NpcAct220.cpp
@@ -1,0 +1,512 @@
+#include "WindowsWrapper.h"
+
+#include "NpcAct.h"
+
+#include "MyChar.h"
+#include "NpChar.h"
+#include "Game.h"
+#include "Sound.h"
+#include "Back.h"
+#include "Triangle.h"
+#include "Bullet.h"
+#include "Caret.h"
+#include "Frame.h"
+
+//Shovel Brigade
+void ActNpc220(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {0, 64, 16, 80};
+	rcLeft[1] = {16, 64, 32, 80};
+
+	rcRight[0] = {0, 80, 16, 96};
+	rcRight[1] = {16, 80, 32, 96};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 1:
+			if (Random(0, 120) == 10)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Shovel Brigade (walking)
+void ActNpc221(NPCHAR *npc)
+{
+	RECT rcLeft[6];
+	RECT rcRight[6];
+
+	rcLeft[0] = {0, 64, 16, 80};
+	rcLeft[1] = {16, 64, 32, 80};
+	rcLeft[2] = {32, 64, 48, 80};
+	rcLeft[3] = {0, 64, 16, 80};
+	rcLeft[4] = {48, 64, 64, 80};
+	rcLeft[5] = {0, 64, 16, 80};
+
+	rcRight[0] = {0, 80, 16, 96};
+	rcRight[1] = {16, 80, 32, 96};
+	rcRight[2] = {32, 80, 48, 96};
+	rcRight[3] = {0, 80, 16, 96};
+	rcRight[4] = {48, 80, 64, 96};
+	rcRight[5] = {0, 80, 16, 96};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			npc->xm = 0;
+			// Fallthrough
+		case 1:
+			if (Random(0, 60) == 1)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			if (Random(0, 60) == 1)
+			{
+				npc->act_no = 10;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->act_wait = Random(0, 16);
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+
+			if (Random(0, 9) % 2)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+			// Fallthrough
+		case 11:
+			if (npc->direct == 0 && npc->flag & 1)
+				npc->direct = 2;
+			else if ( npc->direct == 2 && npc->flag & 4 )
+				npc->direct = 0;
+
+			if (npc->direct == 0)
+				npc->xm = -0x200;
+			else
+				npc->xm = 0x200;
+
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 2;
+
+			if (++npc->act_wait > 32)
+				npc->act_no = 0;
+
+			break;
+	}
+
+	npc->ym += 0x20;
+	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];
+}
+
+//Prison bars
+void ActNpc222(NPCHAR *npc)
+{
+	RECT rc = {96, 168, 112, 200};
+
+	if (npc->act_no == 0)
+	{
+		++npc->act_no;
+		npc->y -= 0x1000;
+	}
+
+	npc->rect = rc;
+}
+
+//Momorin
+void ActNpc223(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {80, 192, 96, 216};
+	rcLeft[1] = {96, 192, 112, 216};
+	rcLeft[2] = {112, 192, 128, 216};
+
+	rcRight[0] = {80, 216, 96, 240};
+	rcRight[1] = {96, 216, 112, 240};
+	rcRight[2] = {112, 216, 128, 240};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			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 3:
+			npc->ani_no = 2;
+			break;
+	}
+
+	if (npc->act_no < 2 && gMC.y < npc->y + 0x2000 && gMC.y > npc->y - 0x2000)
+	{
+		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
+void ActNpc224(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->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 (npc->act_no < 2 && gMC.y < npc->y + 0x2000 && gMC.y > npc->y - 0x2000)
+	{
+		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];
+}
+
+//Megane
+void ActNpc225(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {64, 64, 80, 80};
+	rcLeft[1] = {80, 64, 96, 80};
+
+	rcRight[0] = {64, 80, 80, 96};
+	rcRight[1] = {80, 80, 96, 96};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			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 (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Kanpachi
+void ActNpc226(NPCHAR *npc)
+{
+	RECT rcRight[7];
+
+	rcRight[0] = {256, 56, 272, 80};
+	rcRight[1] = {272, 56, 288, 80};
+	rcRight[2] = {288, 56, 304, 80};
+	rcRight[3] = {256, 56, 272, 80};
+	rcRight[4] = {304, 56, 320, 80};
+	rcRight[5] = {256, 56, 272, 80};
+	rcRight[6] = {240, 56, 256, 80};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			npc->xm = 0;
+			// Fallthrough
+		case 1:
+			if (Random(0, 60) == 1)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 11:
+			npc->xm = 0x200;
+
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 2;
+
+			++npc->act_wait;
+			break;
+
+		case 20:
+			npc->xm = 0;
+			npc->ani_no = 6;
+			break;
+	}
+
+	npc->ym += 0x20;
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	npc->rect = rcRight[npc->ani_no];
+}
+
+//Bucket
+void ActNpc227(NPCHAR *npc)
+{
+	RECT rc = {208, 32, 224, 48};
+	npc->rect = rc;
+}
+
+//Droll (guard)
+void ActNpc228(NPCHAR *npc)
+{
+	RECT rcLeft[4];
+	RECT rcRight[4];
+
+	rcLeft[0] = {0, 0, 32, 40};
+	rcLeft[1] = {32, 0, 64, 40};
+	rcLeft[2] = {64, 0, 96, 40};
+	rcLeft[3] = {96, 0, 128, 40};
+
+	rcRight[0] = {0, 40, 32, 80};
+	rcRight[1] = {32, 40, 64, 80};
+	rcRight[2] = {64, 40, 96, 80};
+	rcRight[3] = {96, 40, 128, 80};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->y -= 0x1000;
+			// Fallthrough
+		case 1:
+			npc->xm = 0;
+			npc->act_no = 2;
+			npc->ani_no = 0;
+			// Fallthrough
+		case 2:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (++npc->ani_wait > 50)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 2;
+			npc->act_wait = 0;
+			// Fallthrough
+		case 11:
+			if (++npc->act_wait > 10)
+			{
+				npc->act_no = 12;
+				npc->ani_no = 3;
+				npc->ym = -0x600;
+
+				if (npc->direct == 0)
+					npc->xm = -0x200;
+				else
+					npc->xm = 0x200;
+			}
+
+			break;
+
+		case 12:
+			if (npc->flag & 8)
+			{
+				npc->ani_no = 2;
+				npc->act_no = 13;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 13:
+			npc->xm /= 2;
+
+			if (++npc->act_wait > 10)
+				npc->act_no = 1;
+
+			break;
+	}
+
+	npc->ym += 0x40;
+	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];
+}
--- /dev/null
+++ b/src/NpcAct240.cpp
@@ -1,0 +1,69 @@
+#include "WindowsWrapper.h"
+
+#include "NpcAct.h"
+
+#include "MyChar.h"
+#include "NpChar.h"
+#include "Game.h"
+#include "Sound.h"
+#include "Back.h"
+#include "Triangle.h"
+
+//Curly (carried and unconcious)
+void ActNpc259(NPCHAR *npc)
+{
+	RECT rcLeft = {224, 96, 240, 112};
+	RECT rcRight = {224, 112, 240, 128};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->bits &= ~0x2000;
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			if (gMC.direct == 0)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			npc->y = gMC.y - 0x800;
+
+			if (npc->direct == 0)
+			{
+				npc->x = gMC.x + 0x600;
+				npc->rect = rcLeft;
+			}
+			else
+			{
+				npc->x = gMC.x - 0x600;
+				npc->rect = rcRight;
+			}
+
+			if (gMC.ani_no % 2)
+				++npc->rect.top;
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->xm = 0x40;
+			npc->ym = -0x20;
+
+			npc->rect = rcLeft;
+			break;
+
+		case 11:
+			if (npc->y < 0x8000)
+				npc->ym = 0x20;
+
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+			break;
+
+		case 20:
+			VanishNpChar(npc);
+			SetDestroyNpCharUp(npc->x, npc->y, 0x2000, 0x40);
+			break;
+	}
+}
--- a/src/NpcAct260.cpp
+++ b/src/NpcAct260.cpp
@@ -8,6 +8,103 @@
 #include "Sound.h"
 #include "Back.h"
 #include "Triangle.h"
+#include "Caret.h"
+#include "Map.h"
+
+// Ironhead block
+void ActNpc271(NPCHAR *npc)
+{
+	if (npc->xm < 0 && npc->x < -0x2000)
+	{
+		VanishNpChar(npc);
+	}
+	else
+	{
+		if (npc->xm > 0 && npc->x > (gMap.width + 1) * 0x2000)
+		{
+			VanishNpChar(npc);
+		}
+		else
+		{
+			if (npc->act_no == 0)
+			{
+				npc->act_no = 1;
+				int a = Random(0, 9);
+
+				if (a == 9)
+				{
+					npc->rect.left = 0;
+					npc->rect.right = 0x20;
+					npc->rect.top = 0x40;
+					npc->rect.bottom = 0x60;
+					npc->view.front = 0x2000;
+					npc->view.back = 0x2000;
+					npc->view.top = 0x2000;
+					npc->view.bottom = 0x2000;
+					npc->hit.front = 0x1800;
+					npc->hit.back = 0x1800;
+					npc->hit.top = 0x1800;
+					npc->hit.bottom = 0x1800;
+				}
+				else
+				{
+					npc->rect.left = 16 * (a % 3 + 7);
+					npc->rect.top = 16 * (a / 3);
+					npc->rect.right = npc->rect.left + 16;
+					npc->rect.bottom = npc->rect.top + 16;
+				}
+
+				if (npc->direct == 0)
+					npc->xm = -2 * Random(0x100, 0x200);
+				else
+					npc->xm = 2 * Random(0x100, 0x200);
+
+				npc->ym = Random(-0x200, 0x200);
+			}
+
+			if (npc->ym < 0 && npc->y - npc->hit.top <= 0xFFF)
+			{
+				npc->ym = -npc->ym;
+				SetCaret(npc->x, npc->y - 0x1000, 13, 0);
+				SetCaret(npc->x, npc->y - 0x1000, 13, 0);
+			}
+
+			if (npc->ym > 0 && npc->y + npc->hit.bottom > 0x1D000)
+			{
+				npc->ym = -npc->ym;
+				SetCaret(npc->x, npc->y + 0x1000, 13, 0);
+				SetCaret(npc->x, npc->y + 0x1000, 13, 0);
+			}
+
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+		}
+	}
+}
+
+// Ironhead block generator
+void ActNpc272(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->act_wait = Random(0, 200);
+			// Fallthrough
+		case 1:
+			if (npc->act_wait)
+			{
+				--npc->act_wait;
+			}
+			else
+			{
+				npc->act_no = 0;
+				SetNpChar(271, npc->x, npc->y + (Random(-32, 32) * 0x200), 0, 0, npc->direct, 0, 0x100);
+			}
+
+			break;
+	}
+}
 
 //Little family
 void ActNpc278(NPCHAR *npc)
--- a/src/NpcAct320.cpp
+++ b/src/NpcAct320.cpp
@@ -54,3 +54,78 @@
 	else
 		npc->rect = rcRight[npc->ani_no];
 }
+
+//Ikachan
+void ActNpc335(NPCHAR *npc)
+{
+	RECT rc[3];
+
+	rc[0] = {0, 16, 16, 32};
+	rc[1] = {16, 16, 32, 32};
+	rc[2] = {32, 16, 48, 32};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->act_wait = Random(3, 20);
+			// Fallthrough
+		case 1:
+			if (--npc->act_wait <= 0)
+			{
+				npc->act_no = 2;
+				npc->act_wait = Random(10, 50);
+				npc->ani_no = 1;
+				npc->xm = 0x600;
+			}
+
+			break;
+
+		case 2:
+			if (--npc->act_wait <= 0)
+			{
+				npc->act_no = 3;
+				npc->act_wait = Random(40, 50);
+				npc->ani_no = 2;
+				npc->ym = Random(-0x100, 0x100);
+			}
+
+			break;
+
+		case 3:
+			if (--npc->act_wait <= 0)
+			{
+				npc->act_no = 1;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	npc->xm -= 0x10;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Ikachan generator
+void ActNpc336(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			if (gMC.shock)
+				npc->cond = 0;
+
+			break;
+
+		case 10:
+			if (++npc->act_wait % 4 == 1 )
+				SetNpChar(335, npc->x, npc->y + (Random(0, 13) * 0x2000), 0, 0, 0, 0, 0);
+
+			break;
+	}
+}
--- a/src/NpcAct340.cpp
+++ b/src/NpcAct340.cpp
@@ -10,6 +10,110 @@
 #include "Back.h"
 #include "Triangle.h"
 
+//Hoppy
+void ActNpc347(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			npc->ani_no = 0;
+
+			if (gMC.y < npc->y + 0x10000 && gMC.y > npc->y - 0x10000)
+			{
+				npc->act_no = 10;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 10:
+			if (++npc->act_wait == 4)
+				npc->ani_no = 2;
+
+			if (npc->act_wait > 12)
+			{
+				npc->act_no = 12;
+				npc->xm = 0x700;
+				PlaySoundObject(6, 1);
+				npc->ani_no = 3;
+			}
+
+			break;
+
+		case 12:
+			if (gMC.y < npc->y)
+				npc->ym = -0xAAu;
+			else
+				npc->ym = 0xAA;
+
+			if (npc->flag & 1)
+			{
+				npc->act_no = 13;
+				npc->act_wait = 0;
+				npc->ani_no = 2;
+				npc->xm = 0;
+				npc->ym = 0;
+			}
+			else
+			{
+				npc->xm -= 42;
+
+				if (npc->xm < -0x5FF)
+					npc->xm = -0x5FF;
+
+				npc->x += npc->xm;
+				npc->y += npc->ym;
+			}
+
+			break;
+
+		case 13:
+			++npc->act_wait;
+
+			if (++npc->act_wait == 2)
+				npc->ani_no = 1;
+
+			if (npc->act_wait == 6)
+				npc->ani_no = 0;
+
+			if (npc->act_wait > 16)
+				npc->act_no = 1;
+
+			break;
+	}
+
+	RECT rc[4];
+
+	rc[0] = {256, 48, 272, 64};
+	rc[1] = {272, 48, 288, 64};
+	rc[2] = {288, 48, 304, 64};
+	rc[3] = {304, 48, 320, 64};
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Statue
+void ActNpc349(NPCHAR *npc)
+{
+	RECT rect = {0, 0, 16, 16};
+
+	if (npc->act_no == 0)
+	{
+		npc->act_no = 1;
+
+		if (npc->direct == 0)
+			npc->x += 0x1000;
+		if (npc->direct == 2)
+			npc->y += 0x2000;
+	}
+
+	npc->rect = rect;
+}
+
 //Quote and Curly on Balrog's back
 void ActNpc355(NPCHAR *npc)
 {
--- a/src/NpcTbl.cpp
+++ b/src/NpcTbl.cpp
@@ -234,8 +234,8 @@
 	ActNpc175,
 	ActNpc176,
 	ActNpc177,
-	nullptr,
-	nullptr,
+	ActNpc178,
+	ActNpc179,
 	ActNpc180,
 	ActNpc181,
 	ActNpc182,
@@ -245,7 +245,7 @@
 	ActNpc186,
 	ActNpc187,
 	ActNpc188,
-	nullptr,
+	ActNpc189,
 	ActNpc190,
 	ActNpc191,
 	ActNpc192,
@@ -252,30 +252,39 @@
 	ActNpc193,
 	ActNpc194,
 	ActNpc195,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc196,
+	ActNpc197,
+	ActNpc198,
 	ActNpc199,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc200,
+	ActNpc201,
+	ActNpc202,
+	ActNpc203,
+	ActNpc204,
+	ActNpc205,
+	ActNpc206,
+	ActNpc207,
+	ActNpc208,
+	ActNpc209,
+	ActNpc210,
 	ActNpc211,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc212,
+	ActNpc213,
+	ActNpc214,
+	ActNpc215,
+	ActNpc216,
+	ActNpc217,
+	ActNpc218,
 	ActNpc219,
+	ActNpc220,
+	ActNpc221,
+	ActNpc222,
+	ActNpc223,
+	ActNpc224,
+	ActNpc225,
+	ActNpc226,
+	ActNpc227,
+	ActNpc228,
 	nullptr,
 	nullptr,
 	nullptr,
@@ -306,6 +315,7 @@
 	nullptr,
 	nullptr,
 	nullptr,
+	ActNpc259,
 	nullptr,
 	nullptr,
 	nullptr,
@@ -324,16 +334,6 @@
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
 	ActNpc278,
 	nullptr,
 	nullptr,
@@ -391,6 +391,8 @@
 	nullptr,
 	nullptr,
 	ActNpc334,
+	ActNpc335,
+	ActNpc336,
 	nullptr,
 	nullptr,
 	nullptr,
@@ -401,11 +403,9 @@
 	nullptr,
 	nullptr,
 	nullptr,
+	ActNpc347,
 	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc349,
 	nullptr,
 	nullptr,
 	nullptr,
--- a/src/TextScr.cpp
+++ b/src/TextScr.cpp
@@ -889,6 +889,16 @@
 						else
 							gTS.p_read += 13;
 					}
+					else if (IS_COMMAND('A','M','J'))
+					{
+						x = GetTextScriptNo(gTS.p_read + 4);
+						z = GetTextScriptNo(gTS.p_read + 9);
+
+						if (CheckArms(x))
+							JumpTextScript(z);
+						else
+							gTS.p_read += 13;
+					}
 					else if (IS_COMMAND('U','N','J'))
 					{
 						x = GetTextScriptNo(gTS.p_read + 4);
@@ -1186,6 +1196,12 @@
 						z = GetTextScriptNo(gTS.p_read + 4);
 						gTS.item = z;
 						gTS.item_y = WINDOW_HEIGHT - 112;
+						gTS.p_read += 8;
+					}
+					else if (IS_COMMAND('N','U','M'))
+					{
+						z = GetTextScriptNo(gTS.p_read + 4);
+						SetNumberTextScript(z);
 						gTS.p_read += 8;
 					}
 					else if (IS_COMMAND('E','S','C'))