shithub: cstory

Download patch

ref: 2c502f3821a9e5fba7b5bbd910f6b2e719f38ef1
parent: d6da832f889ded238c01c0fde56adcfa153c35d2
parent: b461211fb539286a826ab790985f769a647fc053
author: Cucky <44537737+cuckydev@users.noreply.github.com>
date: Wed Feb 6 11:10:55 EST 2019

Merge pull request #41 from Clownacy/master

NPCs and fixes

--- a/Makefile
+++ b/Makefile
@@ -45,6 +45,7 @@
 	BossFrog \
 	BossLife \
 	BossOhm \
+	BossX \
 	BulHit \
 	Bullet \
 	Caret \
@@ -77,11 +78,13 @@
 	NpcAct100 \
 	NpcAct120 \
 	NpcAct140 \
+	NpcAct160 \
 	NpcAct180 \
 	NpcAct200 \
 	NpcAct260 \
 	NpcAct280 \
 	NpcAct300 \
+	NpcAct320 \
 	NpcAct340 \
 	NpChar \
 	NpcHit \
--- a/src/ArmsItem.cpp
+++ b/src/ArmsItem.cpp
@@ -267,8 +267,8 @@
 	int y;
 	PutBitmap3(&rcView, (WINDOW_WIDTH - 244) / 2, (WINDOW_HEIGHT - 224) / 2, &rcBoxTop, 26);
 	for (y = 1; y < 18; y++)
-		PutBitmap3(&rcView, (WINDOW_WIDTH - 244) / 2, (WINDOW_HEIGHT - 224) / 2 * (y + 1), &rcBoxBody, 26);
-	PutBitmap3(&rcView, (WINDOW_WIDTH - 244) / 2, (WINDOW_HEIGHT - 224) / 2 * (y + 1), &rcBoxBottom, 26);
+		PutBitmap3(&rcView, (WINDOW_WIDTH - 244) / 2, ((WINDOW_HEIGHT - 240) / 2) + (8 * (y + 1)), &rcBoxBody, 26);
+	PutBitmap3(&rcView, (WINDOW_WIDTH - 244) / 2, ((WINDOW_HEIGHT - 240) / 2) + (8 * (y + 1)), &rcBoxBottom, 26);
 	
 	//Move titles
 	if (gCampTitleY > (WINDOW_HEIGHT - 208) / 2)
@@ -283,9 +283,9 @@
 	++flash;
 	
 	if (gCampActive)
-		PutBitmap3(&rcView, 40 * gSelectedArms + (WINDOW_WIDTH - 224) / 2, 24, &rcCur1[1], 26);
+		PutBitmap3(&rcView, 40 * gSelectedArms + (WINDOW_WIDTH - 224) / 2, (WINDOW_HEIGHT / 2) - 96, &rcCur1[1], 26);
 	else
-		PutBitmap3(&rcView, 40 * gSelectedArms + (WINDOW_WIDTH - 224) / 2, 24, &rcCur1[(flash >> 1) & 1], 26);
+		PutBitmap3(&rcView, 40 * gSelectedArms + (WINDOW_WIDTH - 224) / 2, (WINDOW_HEIGHT / 2) - 96, &rcCur1[(flash >> 1) & 1], 26);
 	
 	//Draw arms
 	for (int i = 0; i < ARMS_MAX && gArmsData[i].code; i++)
--- a/src/Boss.cpp
+++ b/src/Boss.cpp
@@ -6,6 +6,7 @@
 #include "Boss.h"
 #include "BossFrog.h"
 #include "BossOhm.h"
+#include "BossX.h"
 #include "NpChar.h"
 #include "MyChar.h"
 #include "Sound.h"
@@ -188,7 +189,7 @@
 	ActBossChar_0,
 	ActBossChar_Omega,
 	ActBossChar_Frog,
-	nullptr, //ActBossChar_MonstX,
+	ActBossChar_MonstX,
 	nullptr, //ActBossChar_Core,
 	nullptr, //ActBossChar_Ironhead,
 	nullptr, //ActBossChar_Twin,
--- a/src/BossOhm.cpp
+++ b/src/BossOhm.cpp
@@ -51,6 +51,7 @@
 		{
 			case 0:
 				gBoss[i].act_no = 1;
+				// Fallthrough
 			case 1:
 				if (i == 3)
 					gBoss[i].x = gBoss[0].x - 0x2000;
@@ -150,6 +151,7 @@
 		gBoss[0].act_no = 30;
 		gBoss[0].act_wait = 0;
 		gBoss[0].ani_no = 0;
+		// Fallthrough
 	case 30:
 		SetQuake(2);
 		gBoss[0].y -= 0x200;
--- /dev/null
+++ b/src/BossX.cpp
@@ -1,0 +1,851 @@
+#include "BossX.h"
+
+#include "Boss.h"
+#include "Flash.h"
+#include "Frame.h"
+#include "Game.h"
+#include "MyChar.h"
+#include "NpChar.h"
+#include "Sound.h"
+#include "Triangle.h"
+#include "WindowsWrapper.h"
+
+static void ActBossChar03_01(NPCHAR *npc)
+{
+	RECT rcUp[6];
+	RECT rcDown[6];
+
+	rcUp[0] = {0, 0, 72, 32};
+	rcUp[1] = {0, 32, 72, 64};
+	rcUp[2] = {72, 0, 144, 32};
+	rcUp[3] = {144, 0, 216, 32};
+	rcUp[4] = {72, 32, 144, 64};
+	rcUp[5] = {144, 32, 216, 64};
+
+	rcDown[0] = {0, 64, 72, 96};
+	rcDown[1] = {0, 96, 72, 128};
+	rcDown[2] = {72, 64, 144, 96};
+	rcDown[3] = {144, 64, 216, 96};
+	rcDown[4] = {72, 96, 144, 128};
+	rcDown[5] = {144, 96, 216, 128};
+
+	switch (npc->act_no)
+	{
+		case 10:
+			npc->ani_no = 0;
+			npc->bits &= ~0x10;
+			break;
+
+		case 100:
+			npc->bits |= 0x10;
+			npc->act_no = 101;
+			npc->act_wait = 0;
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 101:
+			if (++npc->act_wait > 30)
+				npc->act_no = 102;
+
+			if (++npc->ani_wait > 0)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if ( npc->ani_no > 3 )
+				npc->ani_no = 2;
+
+			npc->xm -= 0x20;
+			break;
+
+		case 102:
+			npc->bits &= ~0x10;
+			npc->act_no = 103;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 103:
+			++npc->act_wait;
+
+			if (++npc->ani_wait > 1)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			npc->xm -= 0x20;
+			break;
+
+		case 200:
+			npc->bits |= 0x10;
+			npc->bits |= 0x80;
+			npc->act_no = 201;
+			npc->act_wait = 0;
+			npc->ani_no = 4;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 201:
+			if (++npc->act_wait > 30)
+				npc->act_no = 202;
+
+			if (++npc->ani_wait > 0)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if ( npc->ani_no > 5 )
+				npc->ani_no = 4;
+
+			npc->xm += 0x20;
+			break;
+
+		case 202:
+			npc->bits &= ~0x10;
+			npc->act_no = 203;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 203:
+			++npc->act_wait;
+
+			if (++npc->ani_wait > 1)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			npc->xm += 0x20;
+			break;
+
+		case 300:
+			npc->act_no = 301;
+			npc->ani_no = 4;
+			npc->ani_wait = 0;
+			npc->bits |= 0x10;
+			// Fallthrough
+		case 301:
+			if (++npc->ani_wait > 0)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 4;
+
+			npc->xm += 0x20;
+
+			if (npc->xm > 0)
+			{
+				npc->xm = 0;
+				npc->act_no = 10;
+			}
+
+			break;
+
+		case 400:
+			npc->act_no = 401;
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+			npc->bits |= 0x10;
+			// Fallthrough
+		case 401:
+			if (++npc->ani_wait > 0)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 3)
+				npc->ani_no = 2;
+
+			npc->xm -= 0x20;
+
+			if (npc->xm < 0)
+			{
+				npc->xm = 0;
+				npc->act_no = 10;
+			}
+
+			break;
+	}
+
+	if ((npc->act_no == 101 || npc->act_no == 201 || npc->act_no == 301 || npc->act_no == 401) && npc->act_wait % 2 == 1)
+		PlaySoundObject(112, 1);
+
+	if ((npc->act_no == 103 || npc->act_no == 203) && npc->act_wait % 4 == 1)
+		PlaySoundObject(111, 1);
+
+	if (npc->act_no < 100 || gMC.y >= npc->y + 0x800 || gMC.y <= npc->y - 0x800)
+	{
+		npc->damage = 0;
+		npc->bits &= ~0x80;
+	}
+	else
+	{
+		npc->damage = 10;
+		npc->bits |= 0x80;
+	}
+
+	if (npc->xm > 0x400)
+		npc->xm = 0x400;
+	if (npc->xm < -0x400)
+		npc->xm = -0x400;
+
+	npc->x += npc->xm;
+
+	if (npc->direct == 1)
+		npc->rect = rcUp[npc->ani_no];
+	else
+		npc->rect = rcDown[npc->ani_no];
+}
+
+static void ActBossChar03_02(NPCHAR *npc)
+{
+	RECT rect[4];
+
+	rect[0] = {0, 128, 72, 160};
+	rect[1] = {72, 128, 144, 160};
+	rect[2] = {0, 160, 72, 192};
+	rect[3] = {72, 160, 144, 192};
+
+	switch (npc->act_no)
+	{
+		case 10:
+			npc->act_no = 11;
+			npc->act_wait = 30 * npc->ani_no + 30;
+			break;
+
+		case 11:
+			if (npc->act_wait)
+			{
+				--npc->act_wait;
+			}
+			else
+			{
+				int x;
+				int y;
+				int direct;
+
+				switch (npc->ani_no)
+				{
+					case 0:
+						direct = 3;
+						x = -0x3C00;
+						y = 0xC00;
+						break;
+					case 1:
+						direct = 2;
+						x = 0x3C00;
+						y = 0xC00;
+						break;
+					case 2:
+						direct = 0;
+						x = -0x3C00;
+						y = -0xC00;
+						break;
+					case 3:
+						direct = 1;
+						x = 0x3C00;
+						y = -0xC00;
+						break;
+				}
+
+				SetNpChar(158, npc->x + x, npc->y + y, 0, 0, direct, 0, 0x100);
+				PlaySoundObject(39, 1);
+				npc->act_wait = 120;
+			}
+
+			break;
+	}
+
+	npc->x = (gBoss[0].x + gBoss[npc->count1].x) / 2;
+	npc->y = (gBoss[0].y + gBoss[npc->count1].y) / 2;
+
+	npc->rect = rect[npc->ani_no];
+}
+
+static void ActBossChar03_03(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 10:
+			npc->tgt_x += 0x200;
+
+			if (npc->tgt_x > 0x4000)
+			{
+				npc->tgt_x = 0x4000;
+				npc->act_no = 0;
+				gBoss[3].act_no = 10;
+				gBoss[4].act_no = 10;
+				gBoss[5].act_no = 10;
+				gBoss[6].act_no = 10;
+			}
+
+			break;
+
+		case 20:
+			npc->tgt_x -= 0x200;
+
+			if (npc->tgt_x < 0)
+			{
+				npc->tgt_x = 0;
+				npc->act_no = 0;
+				gBoss[3].act_no = 0;
+				gBoss[4].act_no = 0;
+				gBoss[5].act_no = 0;
+				gBoss[6].act_no = 0;
+			}
+
+			break;
+
+		case 30:
+			npc->tgt_x += 0x200;
+
+			if (npc->tgt_x > 0x2800)
+			{
+				npc->tgt_x = 0x2800;
+				npc->act_no = 0;
+				gBoss[7].act_no = 10;
+				gBoss[13].act_no = 10;
+				gBoss[14].act_no = 10;
+				gBoss[15].act_no = 10;
+				gBoss[16].act_no = 10;
+			}
+
+			break;
+
+		case 40:
+			npc->tgt_x -= 0x200;
+
+			if (npc->tgt_x < 0)
+			{
+				npc->tgt_x = 0;
+				npc->act_no = 0;
+				gBoss[7].act_no = 0;
+				gBoss[13].act_no = 0;
+				gBoss[14].act_no = 0;
+				gBoss[15].act_no = 0;
+				gBoss[16].act_no = 0;
+			}
+
+			break;
+	}
+
+	RECT rcLeft = {216, 96, 264, 144};
+	RECT rcRight = {264, 96, 312, 144};
+
+	if (npc->direct == 0)
+	{
+		npc->rect = rcLeft;
+		npc->x = gBoss[0].x - npc->tgt_x - 0x3000;
+		npc->y = gBoss[0].y;
+	}
+	else
+	{
+		npc->rect = rcRight;
+		npc->x = gBoss[0].x + npc->tgt_x + 0x3000;
+		npc->y = gBoss[0].y;
+	}
+}
+
+static void ActBossChar03_04(NPCHAR *npc)
+{
+	RECT rect[8];
+
+	rect[0] = {0, 192, 16, 208};
+	rect[1] = {16, 192, 32, 208};
+	rect[2] = {32, 192, 48, 208};
+	rect[3] = {48, 192, 64, 208};
+	rect[4] = {0, 208, 16, 224};
+	rect[5] = {16, 208, 32, 224};
+	rect[6] = {32, 208, 48, 224};
+	rect[7] = {48, 208, 64, 224};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->bits &= ~0x20;
+			npc->ani_no = 0;
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->act_wait = 10 * npc->tgt_x + 40;
+			npc->bits |= 0x20;
+			// Fallthrough
+		case 11:
+			npc->ani_no = npc->act_wait < 16 && npc->act_wait / 2 % 2;
+
+			if (npc->act_wait)
+			{
+				--npc->act_wait;
+			}
+			else
+			{
+				const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y) + Random(-2, 2);
+				const int ym = 3 * GetSin(deg);
+				const int xm = 3 * GetCos(deg);
+				SetNpChar(156, npc->x, npc->y, xm, ym, 0, 0, 0x100);
+				PlaySoundObject(39, 1);
+				npc->act_wait = 40;
+			}
+
+			break;
+	}
+
+	switch (npc->tgt_x)
+	{
+		case 0:
+			npc->x = gBoss[0].x - 0x2C00;
+			npc->y = gBoss[0].y - 0x2000;
+			break;
+		case 1:
+			npc->x = gBoss[0].x + 0x3800;
+			npc->y = gBoss[0].y - 0x2000;
+			break;
+		case 2:
+			npc->x = gBoss[0].x - 0x1E00;
+			npc->y = gBoss[0].y + 0x1C00;
+			break;
+		case 3:
+			npc->x = gBoss[0].x + 0x2200;
+			npc->y = gBoss[0].y + 0x1C00;
+			break;
+	}
+
+	npc->rect = rect[npc->tgt_x + 4 * npc->ani_no];
+}
+
+static void ActBossChar03_face(NPCHAR *npc)
+{
+	RECT rect[3];
+
+	rect[0] = {216, 0, 320, 48};
+	rect[1] = {216, 48, 320, 96};
+	rect[2] = {216, 144, 320, 192};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			gBoss[0].bits &= ~0x20;
+			npc->ani_no = 0;
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->act_wait = 10 * npc->tgt_x + 40;
+			gBoss[0].bits |= 0x20;
+			// Fallthrough
+		case 11:
+			if (gBoss[0].shock)
+			{
+				static unsigned char flash;
+
+				if ((flash++ >> 1) & 1)
+					npc->ani_no = 1;
+				else
+					npc->ani_no = 0;
+			}
+			else
+			{
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	gBoss[7].x = gBoss[0].x;
+	gBoss[7].y = gBoss[0].y;
+
+	if (gBoss[0].act_no <= 10)
+		npc->ani_no = 2;
+
+	npc->rect = rect[npc->ani_no];
+}
+
+void ActBossChar_MonstX(void)
+{
+	switch (gBoss[0].act_no)
+	{
+		case 0:
+			gBoss[0].life = 1;
+			gBoss[0].x = -0x28000;
+			break;
+
+		case 1:
+			gBoss[0].life = 700;
+			gBoss[0].exp = 1;
+			gBoss[0].act_no = 1;
+			gBoss[0].x = 0x100000;
+			gBoss[0].y = 102400;
+			gBoss[0].hit_voice = 54;
+			gBoss[0].hit.front = 0x3000;
+			gBoss[0].hit.top = 0x3000;
+			gBoss[0].hit.back = 0x3000;
+			gBoss[0].hit.bottom = 0x3000;
+			gBoss[0].bits = 0x8208;
+			gBoss[0].size = 3;
+			gBoss[0].code_event = 1000;
+			gBoss[0].ani_no = 0;
+			gBoss[1].cond = 0x80;
+			gBoss[1].size = 3;
+			gBoss[1].direct = 0;
+			gBoss[1].view.front = 0x3000;
+			gBoss[1].view.top = 0x3000;
+			gBoss[1].view.back = 0x3000;
+			gBoss[1].view.bottom = 0x3000;
+			gBoss[1].bits = 8;
+			gBoss[2] = gBoss[1];
+			gBoss[2].direct = 2;
+			gBoss[3].cond = 0x80;
+			gBoss[3].life = 60;
+			gBoss[3].hit_voice = 54;
+			gBoss[3].destroy_voice = 71;
+			gBoss[3].size = 2;
+			gBoss[3].view.front = 0x1000;
+			gBoss[3].view.top = 0x1000;
+			gBoss[3].view.back = 0x1000;
+			gBoss[3].view.bottom = 0x1000;
+			gBoss[3].hit.front = 0xA00;
+			gBoss[3].hit.back = 0xA00;
+			gBoss[3].hit.top = 0xA00;
+			gBoss[3].hit.bottom = 0xA00;
+			gBoss[3].bits = 8;
+			gBoss[3].tgt_x = 0;
+			gBoss[4] = gBoss[3];
+			gBoss[4].tgt_x = 1;
+			gBoss[5] = gBoss[3];
+			gBoss[5].tgt_x = 2;
+			gBoss[5].life = 100;
+			gBoss[6] = gBoss[3];
+			gBoss[6].tgt_x = 3;
+			gBoss[6].life = 100;
+			gBoss[7].cond = 0x80;
+			gBoss[7].x = 0x100000;
+			gBoss[7].y = 0x19000;
+			gBoss[7].view.front = 0x6800;
+			gBoss[7].view.top = 0x3000;
+			gBoss[7].view.back = 0x6800;
+			gBoss[7].view.bottom = 0x3000;
+			gBoss[7].hit_voice = 52;
+			gBoss[7].hit.front = 0x1000;
+			gBoss[7].hit.top = 0x3000;
+			gBoss[7].hit.back = 0x1000;
+			gBoss[7].hit.bottom = 0x2000;
+			gBoss[7].bits = 8;
+			gBoss[7].size = 3;
+			gBoss[7].ani_no = 0;
+			gBoss[9].cond = 0x80;
+			gBoss[9].act_no = 0;
+			gBoss[9].direct = 1;
+			gBoss[9].x = 0xF8000;
+			gBoss[9].y = 0x12000;
+			gBoss[9].view.front = 0x4800;
+			gBoss[9].view.top = 0x1000;
+			gBoss[9].view.back = 0x4800;
+			gBoss[9].view.bottom = 0x3000;
+			gBoss[9].hit_voice = 52;
+			gBoss[9].hit.front = 0x3800;
+			gBoss[9].hit.top = 0x1000;
+			gBoss[9].hit.back = 0x3800;
+			gBoss[9].hit.bottom = 0x2000;
+			gBoss[9].bits = 141;
+			gBoss[9].size = 3;
+			gBoss[10] = gBoss[9];
+			gBoss[10].x = 0x108000;
+			gBoss[11] = gBoss[9];
+			gBoss[11].direct = 3;
+			gBoss[11].x = 0xF8000;
+			gBoss[11].y = 0x20000;
+			gBoss[11].view.top = 0x3000;
+			gBoss[11].view.bottom = 0x1000;
+			gBoss[11].hit.top = 0x2000;
+			gBoss[11].hit.bottom = 0x1000;
+			gBoss[12] = gBoss[11];
+			gBoss[12].x = 0x108000;
+			gBoss[13] = gBoss[9];
+			gBoss[13].cond = 0x80;
+			gBoss[13].view.top = 0x2000;
+			gBoss[13].view.bottom = 0x2000;
+			gBoss[13].view.front = 0x3C00;
+			gBoss[13].view.back = 0x5400;
+			gBoss[13].count1 = 9;
+			gBoss[13].ani_no = 0;
+			gBoss[13].bits = 8;
+			gBoss[14] = gBoss[13];
+			gBoss[14].view.front = 0x5400;
+			gBoss[14].view.back = 0x3C00;
+			gBoss[14].count1 = 10;
+			gBoss[14].ani_no = 1;
+			gBoss[14].bits = 8;
+			gBoss[15] = gBoss[13];
+			gBoss[15].view.top = 0x2000;
+			gBoss[15].view.bottom = 0x2000;
+			gBoss[15].count1 = 11;
+			gBoss[15].ani_no = 2;
+			gBoss[15].bits = 8;
+			gBoss[16] = gBoss[15];
+			gBoss[16].view.front = 0x5400;
+			gBoss[16].view.back = 0x3C00;
+			gBoss[16].count1 = 12;
+			gBoss[16].ani_no = 3;
+			gBoss[16].bits = 8;
+			gBoss[0].act_no = 2;
+			break;
+
+		case 10:
+			gBoss[0].act_no = 11;
+			gBoss[0].act_wait = 0;
+			gBoss[0].count1 = 0;
+			// Fallthrough
+		case 11:
+			if (++gBoss[0].act_wait > 100)
+			{
+				gBoss[0].act_wait = 0;
+
+				if (gMC.x < gBoss[0].x)
+					gBoss[0].act_no = 100;
+				else
+					gBoss[0].act_no = 200;
+			}
+
+			break;
+
+		case 100:
+			gBoss[0].act_wait = 0;
+			gBoss[0].act_no = 101;
+			++gBoss[0].count1;
+			// Fallthrough
+		case 101:
+			if (++gBoss[0].act_wait == 4)
+				gBoss[9].act_no = 100;
+			if (gBoss[0].act_wait == 8)
+				gBoss[10].act_no = 100;
+			if (gBoss[0].act_wait == 10)
+				gBoss[11].act_no = 100;
+			if (gBoss[0].act_wait == 12)
+				gBoss[12].act_no = 100;
+			if (gBoss[0].act_wait > 120 && gBoss[0].count1 > 2)
+				gBoss[0].act_no = 300;
+			if (gBoss[0].act_wait > 121 && gMC.x > gBoss[0].x)
+				gBoss[0].act_no = 200;
+
+			break;
+
+		case 200:
+			gBoss[0].act_wait = 0;
+			gBoss[0].act_no = 201;
+			++gBoss[0].count1;
+			// Fallthrough
+		case 201:
+			if (++gBoss[0].act_wait == 4)
+				gBoss[9].act_no = 200;
+			if (gBoss[0].act_wait == 8)
+				gBoss[10].act_no = 200;
+			if (gBoss[0].act_wait == 10)
+				gBoss[11].act_no = 200;
+			if (gBoss[0].act_wait == 12)
+				gBoss[12].act_no = 200;
+			if (gBoss[0].act_wait > 120 && gBoss[0].count1 > 2)
+				gBoss[0].act_no = 400;
+			if (gBoss[0].act_wait > 121 && gMC.x < gBoss[0].x)
+				gBoss[0].act_no = 100;
+
+			break;
+
+		case 300:
+			gBoss[0].act_wait = 0;
+			gBoss[0].act_no = 301;
+			// Fallthrough
+		case 301:
+			if (++gBoss[0].act_wait == 4)
+				gBoss[9].act_no = 300;
+			if (gBoss[0].act_wait == 8)
+				gBoss[10].act_no = 300;
+			if (gBoss[0].act_wait == 10)
+				gBoss[11].act_no = 300;
+			if (gBoss[0].act_wait == 12)
+				gBoss[12].act_no = 300;
+			if (gBoss[0].act_wait > 50)
+			{
+				if (gBoss[3].cond || gBoss[4].cond || gBoss[5].cond || gBoss[6].cond)
+					gBoss[0].act_no = 500;
+				else
+					gBoss[0].act_no = 600;
+			}
+			break;
+
+		case 400:
+			gBoss[0].act_wait = 0;
+			gBoss[0].act_no = 401;
+			// Fallthrough
+		case 401:
+			if (++gBoss[0].act_wait == 4)
+				gBoss[9].act_no = 400;
+			if (gBoss[0].act_wait == 8)
+				gBoss[10].act_no = 400;
+			if (gBoss[0].act_wait == 10)
+				gBoss[11].act_no = 400;
+			if (gBoss[0].act_wait == 12)
+				gBoss[12].act_no = 400;
+			if (gBoss[0].act_wait > 50)
+			{
+				if (gBoss[3].cond || gBoss[4].cond || gBoss[5].cond || gBoss[6].cond)
+					gBoss[0].act_no = 500;
+				else
+					gBoss[0].act_no = 600;
+			}
+
+			break;
+
+		case 500:
+			gBoss[0].act_no = 501;
+			gBoss[0].act_wait = 0;
+			gBoss[1].act_no = 10;
+			gBoss[2].act_no = 10;
+			// Fallthrough
+		case 501:
+			if (++gBoss[0].act_wait > 300)
+			{
+				gBoss[0].act_no = 502;
+				gBoss[0].act_wait = 0;
+			}
+
+			if (gBoss[3].cond == 0 && gBoss[4].cond == 0 && gBoss[5].cond == 0 && gBoss[6].cond == 0)
+			{
+				gBoss[0].act_no = 502;
+				gBoss[0].act_wait = 0;
+			}
+
+			break;
+
+		case 502:
+			gBoss[0].act_no = 503;
+			gBoss[0].act_wait = 0;
+			gBoss[0].count1 = 0;
+			gBoss[1].act_no = 20;
+			gBoss[2].act_no = 20;
+			// Fallthrough
+		case 503:
+			if (++gBoss[0].act_wait > 50)
+			{
+				if (gMC.x < gBoss[0].x)
+					gBoss[0].act_no = 100;
+				else
+					gBoss[0].act_no = 200;
+			}
+
+			break;
+
+		case 600:
+			gBoss[0].act_no = 601;
+			gBoss[0].act_wait = 0;
+			gBoss[0].count2 = gBoss[0].life;
+			gBoss[1].act_no = 30;
+			gBoss[2].act_no = 30;
+			// Fallthrough
+		case 601:
+			++gBoss[0].act_wait;
+
+			if (gBoss[0].life < gBoss[0].count2 - 200 || gBoss[0].act_wait > 300)
+			{
+				gBoss[0].act_no = 602;
+				gBoss[0].act_wait = 0;
+			}
+
+			break;
+
+		case 602:
+			gBoss[0].act_no = 603;
+			gBoss[0].act_wait = 0;
+			gBoss[0].count1 = 0;
+			gBoss[1].act_no = 40;
+			gBoss[2].act_no = 40;
+			break;
+
+		case 603:
+			if (++gBoss[0].act_wait > 50)
+			{
+				if (gMC.x < gBoss[0].x)
+					gBoss[0].act_no = 100;
+				else
+					gBoss[0].act_no = 200;
+			}
+
+			break;
+
+		case 1000:
+			SetQuake(2);
+
+			if (++gBoss[0].act_wait % 8 == 0)
+				PlaySoundObject(52, 1);
+
+			SetDestroyNpChar(gBoss[0].x + (Random(-0x48, 0x48) * 0x200), gBoss[0].y + (Random(-0x40, 0x40) * 0x200), 1, 1);
+
+			if (gBoss[0].act_wait > 100)
+			{
+				gBoss[0].act_wait = 0;
+				gBoss[0].act_no = 1001;
+				SetFlash(gBoss[0].x, gBoss[0].y, 1);
+				PlaySoundObject(35, 1);
+			}
+
+			break;
+
+		case 1001:
+			SetQuake(40);
+
+			if (++gBoss[0].act_wait > 50)
+			{
+				for (int i = 0; i < 20; ++i)
+					gBoss[i].cond = 0;
+
+				DeleteNpCharCode(158, 1);
+				SetNpChar(159, gBoss[0].x, gBoss[0].y - 0x3000, 0, 0, 0, 0, 0);
+			}
+
+			break;
+	}
+
+	ActBossChar03_01(&gBoss[9]);
+	ActBossChar03_01(&gBoss[10]);
+	ActBossChar03_01(&gBoss[11]);
+	ActBossChar03_01(&gBoss[12]);
+	gBoss[0].x += ((gBoss[11].x + gBoss[10].x + gBoss[9].x + gBoss[12].x) / 4 - gBoss[0].x) / 16;
+	ActBossChar03_face(&gBoss[7]);
+	ActBossChar03_02(&gBoss[13]);
+	ActBossChar03_02(&gBoss[14]);
+	ActBossChar03_02(&gBoss[15]);
+	ActBossChar03_02(&gBoss[16]);
+	ActBossChar03_03(&gBoss[1]);
+	ActBossChar03_03(&gBoss[2]);
+
+	if (gBoss[3].cond)
+		ActBossChar03_04(&gBoss[3]);
+	if (gBoss[4].cond)
+		ActBossChar03_04(&gBoss[4]);
+	if (gBoss[5].cond)
+		ActBossChar03_04(&gBoss[5]);
+	if (gBoss[6].cond)
+		ActBossChar03_04(&gBoss[6]);
+
+	if (gBoss[0].life == 0 && gBoss[0].act_no < 1000)
+	{
+		gBoss[0].act_no = 1000;
+		gBoss[0].act_wait = 0;
+		gBoss[0].shock = 0x96;
+		gBoss[9].act_no = 300;
+		gBoss[10].act_no = 300;
+		gBoss[11].act_no = 300;
+		gBoss[12].act_no = 300;
+	}
+}
\ No newline at end of file
--- /dev/null
+++ b/src/BossX.h
@@ -1,0 +1,3 @@
+#pragma once
+
+void ActBossChar_MonstX(void);
--- a/src/Bullet.cpp
+++ b/src/Bullet.cpp
@@ -915,7 +915,7 @@
 			}
 			
 			PlaySoundObject(44, 1);
-			
+			// Fallthrough
 		case 1:
 			if (level == 1)
 			{
--- a/src/Caret.cpp
+++ b/src/Caret.cpp
@@ -17,7 +17,7 @@
 
 void ActCaret00(CARET *crt)
 {
-	;
+	(void)crt;
 }
 
 void ActCaret01(CARET *crt)
--- a/src/CommonDefines.h
+++ b/src/CommonDefines.h
@@ -1,5 +1,5 @@
 #pragma once
 #define PATH_LENGTH 260 //Pixel had the path size locked to 260 (dangerously low), if you tried to open the executable in a path with more than around 220 characters, it'd crash.
 
-#define WINDOW_WIDTH 320
-#define WINDOW_HEIGHT 240
+#define WINDOW_WIDTH ((320*16)/9)
+#define WINDOW_HEIGHT 320
--- a/src/Draw.cpp
+++ b/src/Draw.cpp
@@ -145,9 +145,9 @@
 	unsigned char (*src_pixels)[surf[surf_no].surface->pitch / 4][4] = (unsigned char (*)[surf[surf_no].surface->pitch/ 4][4])surf[surf_no].surface->pixels;
 	unsigned char (*dst_pixels)[pitch / 4][4] = (unsigned char (*)[pitch/ 4][4])raw_pixels;
 
-	for (unsigned int h = 0; h < surf[surf_no].surface->h; ++h)
+	for (int h = 0; h < surf[surf_no].surface->h; ++h)
 	{
-		for (unsigned int w = 0; w < surf[surf_no].surface->w; ++w)
+		for (int w = 0; w < surf[surf_no].surface->w; ++w)
 		{
 			dst_pixels[h][w][0] = src_pixels[h][w][0];
 			dst_pixels[h][w][1] = src_pixels[h][w][1];
--- a/src/Escape.cpp
+++ b/src/Escape.cpp
@@ -10,7 +10,7 @@
 {
 	RECT rc = {0, 128, 208, 144};
 	
-	while (Flip_SystemTask())
+	while (1)
 	{
 		//Get pressed keys
 		GetTrg();
@@ -35,9 +35,14 @@
 		CortBox(&grcFull, 0x000000);
 		PutBitmap3(&grcFull, (WINDOW_WIDTH - 208) / 2, (WINDOW_HEIGHT - 16) / 2, &rc, 26);
 		PutFramePerSecound();
+
+		if (!Flip_SystemTask())
+		{
+			//Quit if window is closed
+			gKeyTrg = 0;
+			return 0;
+		}
 	}
 	
-	//Quit if window is closed
-	gKeyTrg = 0;
 	return 0;
 }
--- a/src/Font.cpp
+++ b/src/Font.cpp
@@ -58,7 +58,7 @@
 		case 3:
 		case 4:
 			length = zero_bit;
-			charcode = string[0] & (1 << (8 - zero_bit)) - 1;
+			charcode = (string[0] & (1 << (8 - zero_bit))) - 1;
 
 			for (unsigned int i = 1; i < zero_bit; ++i)
 			{
@@ -230,7 +230,7 @@
 			const int letter_x = x + pen_x + face->glyph->bitmap_left;
 			const int letter_y = y + ((FT_MulFix(face->ascender, face->size->metrics.y_scale) - face->glyph->metrics.horiBearingY + (64 / 2)) / 64);
 
-			for (int iy = MAX(-letter_y, 0); letter_y + iy < MIN(letter_y + converted.rows, surface->h); ++iy)
+			for (int iy = MAX(-letter_y, 0); letter_y + iy < MIN(letter_y + converted.rows, (unsigned int)surface->h); ++iy)
 			{
 				if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD)
 				{
--- a/src/Frame.cpp
+++ b/src/Frame.cpp
@@ -6,6 +6,7 @@
 #include "NpChar.h"
 #include "Game.h"
 #include "CommonDefines.h"
+#include "Boss.h"
 
 FRAME gFrame;
 
@@ -148,8 +149,8 @@
 
 void SetFrameTargetBoss(int no, int wait)
 {
-	//gFrame.tgt_x = &gBoss[no].x;
-	//gFrame.tgt_y = &gBoss[no].y;
+	gFrame.tgt_x = &gBoss[no].x;
+	gFrame.tgt_y = &gBoss[no].y;
 	gFrame.wait = wait;
 }
 
--- a/src/Game.cpp
+++ b/src/Game.cpp
@@ -92,7 +92,7 @@
 		}
 		
 		//Draw digit
-		if ( bZero && offset == 2 || sw != 0 || offset == 3 )
+		if ((bZero && offset == 2) || sw != 0 || offset == 3 )
 			PutBitmap3(&rcClient, x + 8 * offset, y, &rect[a], SURFACE_ID_TEXT_BOX);
 		
 		//Go to next digit
@@ -119,7 +119,7 @@
 	
 	CutNoise();
 	
-	int wait = 0;
+	unsigned int wait = 0;
 	while (wait < 500)
 	{
 		//Increase timer
@@ -295,7 +295,7 @@
 	gMC.equip |= 0x100;
 	
 	//Start loop
-	int wait = 0;
+	unsigned int wait = 0;
 	
 	while (true)
 	{
--- a/src/NpcAct.h
+++ b/src/NpcAct.h
@@ -149,12 +149,37 @@
 void ActNpc144(NPCHAR *npc);
 void ActNpc145(NPCHAR *npc);
 void ActNpc146(NPCHAR *npc);
-
+void ActNpc147(NPCHAR *npc);
+void ActNpc148(NPCHAR *npc);
+void ActNpc149(NPCHAR *npc);
 void ActNpc150(NPCHAR *npc);
 void ActNpc151(NPCHAR *npc);
 
+void ActNpc153(NPCHAR *npc);
+void ActNpc154(NPCHAR *npc);
+void ActNpc155(NPCHAR *npc);
+void ActNpc156(NPCHAR *npc);
+void ActNpc157(NPCHAR *npc);
+void ActNpc158(NPCHAR *npc);
+void ActNpc159(NPCHAR *npc);
+void ActNpc160(NPCHAR *npc);
+void ActNpc161(NPCHAR *npc);
+void ActNpc162(NPCHAR *npc);
+void ActNpc163(NPCHAR *npc);
+void ActNpc164(NPCHAR *npc);
+void ActNpc165(NPCHAR *npc);
+void ActNpc166(NPCHAR *npc);
+void ActNpc167(NPCHAR *npc);
+void ActNpc168(NPCHAR *npc);
+void ActNpc169(NPCHAR *npc);
+void ActNpc170(NPCHAR *npc);
+
+void ActNpc173(NPCHAR *npc);
+void ActNpc174(NPCHAR *npc);
+
 void ActNpc192(NPCHAR *npc);
 void ActNpc193(NPCHAR *npc);
+void ActNpc194(NPCHAR *npc);
 
 void ActNpc199(NPCHAR *npc);
 
@@ -171,6 +196,8 @@
 void ActNpc300(NPCHAR *npc);
 
 void ActNpc302(NPCHAR *npc);
+
+void ActNpc334(NPCHAR *npc);
 
 void ActNpc355(NPCHAR *npc);
 
--- a/src/NpcAct000.cpp
+++ b/src/NpcAct000.cpp
@@ -414,7 +414,7 @@
 		case 0: //Init
 			npc->y += 0x600;
 			npc->act_no = 1;
-
+			// Fallthrough
 		case 1: //Waiting
 			//Look at player
 			if (npc->x <= gMC.x)
--- a/src/NpcAct020.cpp
+++ b/src/NpcAct020.cpp
@@ -52,7 +52,7 @@
 			break;
 	}
 
-	RECT rect[0];
+	RECT rect[1];
 
 	rect[0]	= {224, 40, 240, 48};
 
--- a/src/NpcAct040.cpp
+++ b/src/NpcAct040.cpp
@@ -39,6 +39,7 @@
 			npc->act_no = 1;
 			npc->ani_no = 0;
 			npc->ani_wait = 0;
+			// Fallthrough
 		case 1:
 			if (Random(0, 120) == 10)
 			{
@@ -65,6 +66,7 @@
 			npc->act_no = 4;
 			npc->ani_no = 2;
 			npc->ani_wait = 0;
+			// Fallthrough
 		case 4:
 			if (++npc->ani_wait > 4)
 			{
--- a/src/NpcAct060.cpp
+++ b/src/NpcAct060.cpp
@@ -639,7 +639,7 @@
 		case 0: //Init
 			npc->y += 0x600;
 			npc->act_no = 1;
-
+			// Fallthrough
 		case 1: //Waiting
 			//Look at player
 			if (npc->x <= gMC.x)
--- a/src/NpcAct140.cpp
+++ b/src/NpcAct140.cpp
@@ -12,6 +12,7 @@
 #include "Frame.h"
 #include "Flash.h"
 #include "Bullet.h"
+#include "CommonDefines.h"
 
 //Toroko (frenzied)
 void ActNpc140(NPCHAR *npc)
@@ -746,6 +747,338 @@
 	npc->rect = rect[npc->ani_no];
 }
 
+//Critter (purple)
+void ActNpc147(NPCHAR *npc)
+{
+	RECT rcLeft[6];
+	RECT rcRight[6];
+
+	rcLeft[0] = {0, 96, 16, 112};
+	rcLeft[1] = {16, 96, 32, 112};
+	rcLeft[2] = {32, 96, 48, 112};
+	rcLeft[3] = {48, 96, 64, 112};
+	rcLeft[4] = {64, 96, 80, 112};
+	rcLeft[5] = {80, 96, 96, 112};
+
+	rcRight[0] = {0, 112, 16, 128};
+	rcRight[1] = {16, 112, 32, 128};
+	rcRight[2] = {32, 112, 48, 128};
+	rcRight[3] = {48, 112, 64, 128};
+	rcRight[4] = {64, 112, 80, 128};
+	rcRight[5] = {80, 112, 96, 128};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->y += 0x600;
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			if (npc->act_wait >= 8 && gMC.x > npc->x - 0xC000 && gMC.x < npc->x + 0xC000 && gMC.y > npc->y - 0xC000 && gMC.y < npc->y + 0x4000)
+			{
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+
+				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 - 0xC000 && gMC.y < npc->y + 0x4000)
+			{
+				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;
+				PlaySoundObject(30, 1);
+
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			break;
+
+		case 3:
+			if (npc->ym > 0x100)
+			{
+				npc->tgt_y = npc->y;
+				npc->act_no = 4;
+				npc->ani_no = 3;
+				npc->act_wait = 0;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 4:
+			if (gMC.x > npc->x)
+				npc->direct = 2;
+			else
+				npc->direct = 0;
+
+			++npc->act_wait;
+
+			if (npc->flag & 7 || npc->act_wait > 60)
+			{
+				npc->damage = 3;
+				npc->act_no = 5;
+				npc->ani_no = 2;
+			}
+			else
+			{
+				if (npc->act_wait % 4 == 1)
+					PlaySoundObject(109, 1);
+
+				if (npc->flag & 8)
+					npc->ym = -0x200;
+
+				if (npc->act_wait % 30 == 6)
+				{
+					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(148, npc->x, npc->y, xm, ym, 0, 0, 0x100);
+					PlaySoundObject(39, 1);
+				}
+
+				if (++npc->ani_wait > 0)
+				{
+					npc->ani_wait = 0;
+					++npc->ani_no;
+				}
+
+				if (npc->ani_no > 5)
+					npc->ani_no = 3;
+			}
+
+			break;
+
+		case 5:
+			if (npc->flag & 8)
+			{
+				npc->damage = 2;
+				npc->xm = 0;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+				npc->act_no = 1;
+				PlaySoundObject(23, 1);
+			}
+
+			break;
+	}
+
+	if (npc->act_no == 4)
+	{
+		if (npc->tgt_y < npc->y)
+			npc->ym -= 0x10;
+		else
+			npc->ym += 0x10;
+
+		if (npc->ym > 0x200)
+			npc->ym = 0x200;
+		if (npc->ym < -0x200)
+			npc->ym = -0x200;
+
+		if (npc->xm > 0x200)
+			npc->xm = 0x200;
+		if (npc->xm < -0x200)
+			npc->xm = -0x200;
+	}
+	else
+	{
+		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];
+}
+
+//Purple Critter's projectile
+void ActNpc148(NPCHAR *npc)
+{
+	if (npc->flag & 0xFF)
+	{
+		SetCaret(npc->x, npc->y, 2, 0);
+		npc->cond = 0;
+	}
+
+	npc->y += npc->ym;
+	npc->x += npc->xm;
+
+	RECT rect_left[2];
+
+	rect_left[0] = {96, 96, 104, 104};
+	rect_left[1] = {104, 96, 112, 104};
+
+	if (++npc->ani_no > 1)
+		npc->ani_no = 0;
+
+	npc->rect = rect_left[npc->ani_no];
+
+	if (++npc->count1 > 300)
+	{
+		SetCaret(npc->x, npc->y, 2, 0);
+		npc->cond = 0;
+	}
+}
+
+//Moving block (horizontal)
+void ActNpc149(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->x += 0x1000;
+			npc->y += 0x1000;
+
+			if (npc->direct == 0)
+				npc->act_no = 10;
+			else
+				npc->act_no = 20;
+
+			npc->xm = 0;
+			npc->ym = 0;
+
+			npc->bits |= 0x40;
+			break;
+
+		case 10:
+			npc->bits &= ~0x80;
+			npc->damage = 0;
+
+			if (gMC.x < npc->x + 0x3200 && gMC.x > npc->x - 0x32000 && gMC.y < npc->y + 0x3200 && gMC.y > npc->y - 0x3200)
+			{
+				npc->act_no = 11;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 11:
+			if (++npc->act_wait % 10 == 6)
+				PlaySoundObject(107, 1);
+
+			if (npc->flag & 1)
+			{
+				npc->xm = 0;
+				npc->direct = 2;
+				npc->act_no = 20;
+				SetQuake(10);
+				PlaySoundObject(26, 1);
+
+				for (int i = 0; i < 4; ++i)
+					SetNpChar(4, npc->x - 0x2000, npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+			}
+			else
+			{
+				if (gMC.flag & 1)
+				{
+					npc->bits |= 0x80;
+					npc->damage = 100;
+				}
+				else
+				{
+					npc->bits &= ~0x80;
+					npc->damage = 0;
+				}
+
+				npc->xm -= 0x20;
+			}
+
+			break;
+
+		case 20:
+			npc->bits &= ~0x80;
+			npc->damage = 0;
+
+			if (gMC.x > npc->x - 0x3200 && gMC.x < npc->x + 0x32000 && gMC.y < npc->y + 0x3200 && gMC.y > npc->y - 0x3200)
+			{
+				npc->act_no = 21;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 21:
+			if (++npc->act_wait % 10 == 6)
+				PlaySoundObject(107, 1);
+
+			if (npc->flag & 4)
+			{
+				npc->xm = 0;
+				npc->direct = 0;
+				npc->act_no = 10;
+				SetQuake(10);
+				PlaySoundObject(26, 1);
+
+				for (int i = 0; i < 4; ++i)
+					SetNpChar(4, npc->x + 0x2000, npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+			}
+			else
+			{
+				if (gMC.flag & 4)
+				{
+					npc->bits |= 0x80;
+					npc->damage = 100;
+				}
+				else
+				{
+					npc->bits &= ~0x80;
+					npc->damage = 0;
+				}
+
+				npc->xm += 0x20;
+			}
+
+			break;
+	}
+
+	if (npc->xm > 0x200)
+		npc->xm = 0x200;
+	if (npc->xm < -0x200)
+		npc->xm = -0x200;
+
+	npc->x += npc->xm;
+
+	RECT rect[1];
+
+	rect[0] = {16, 0, 48, 32};
+
+	npc->rect = rect[0];
+}
+
 //Quote
 void ActNpc150(NPCHAR *npc)
 {
@@ -793,6 +1126,7 @@
 			for (int i = 0; i < 4; i++)
 				SetNpChar(4, npc->x, npc->y, Random(-0x155, 0x155), Random(-0x600, 0), 0, 0, 0x100);
 			PlaySoundObject(71, 1);
+			// Fallthrough
 		case 11:
 			npc->ani_no = 2;
 			break;
@@ -800,6 +1134,7 @@
 			npc->act_no = 21;
 			npc->act_wait = 64;
 			PlaySoundObject(29, 1);
+			// Fallthrough
 		case 21:
 			if (!--npc->act_wait)
 				npc->cond = 0;
@@ -808,6 +1143,7 @@
 			npc->act_no = 51;
 			npc->ani_no = 3;
 			npc->ani_wait = 0;
+			// Fallthrough
 		case 51:
 			if (++npc->ani_wait > 4)
 			{
@@ -827,6 +1163,7 @@
 			npc->ani_no = 7;
 			npc->tgt_x = npc->x;
 			npc->tgt_y = npc->y;
+			// Fallthrough
 		case 61:
 			npc->tgt_y += 0x100;
 			npc->x = npc->tgt_x + (Random(-1, 1) << 9);
@@ -837,6 +1174,7 @@
 			npc->act_wait = 0;
 			npc->ani_no = 3;
 			npc->ani_wait = 0;
+			// Fallthrough
 		case 0x47:
 			if ( npc->direct )
 				npc->x -= 0x100;
@@ -859,6 +1197,7 @@
 			npc->act_no = 101;
 			npc->ani_no = 3;
 			npc->ani_wait = 0;
+			// Fallthrough
 		case 101:
 			npc->ym += 0x40;
 			if (npc->ym > 0x5FF)
@@ -946,4 +1285,664 @@
 		npc->rect = rcLeft[npc->ani_no];
 	else
 		npc->rect = rcRight[npc->ani_no];
+}
+
+static const RECT grcKitL[21] = {
+	{0, 0, 24, 24},
+	{24, 0, 48, 24},
+	{48, 0, 72, 24},
+	{0, 0, 24, 24},
+	{72, 0, 96, 24},
+	{0, 0, 24, 24},
+	{96, 0, 120, 24},
+	{120, 0, 144, 24},
+	{144, 0, 168, 24},
+	{168, 0, 192, 24},
+	{192, 0, 216, 24},
+	{216, 0, 240, 24},
+	{240, 0, 264, 24},
+	{264, 0, 288, 24},
+	{0, 48, 24, 72},
+	{24, 48, 48, 72},
+	{48, 48, 72, 72},
+	{72, 48, 96, 72},
+	{288, 0, 312, 24},
+	{24, 48, 48, 72},
+	{96, 48, 120, 72}
+};
+
+static const RECT grcKitR[21] = {
+	{0, 24, 24, 48},
+	{24, 24, 48, 48},
+	{48, 24, 72, 48},
+	{0, 24, 24, 48},
+	{72, 24, 96, 48},
+	{0, 24, 24, 48},
+	{96, 24, 120, 48},
+	{120, 24, 144, 48},
+	{144, 24, 168, 48},
+	{168, 24, 192, 48},
+	{192, 24, 216, 48},
+	{216, 24, 240, 48},
+	{240, 24, 264, 48},
+	{264, 24, 288, 48},
+	{0, 72, 24, 96},
+	{24, 72, 48, 96},
+	{48, 72, 72, 96},
+	{72, 72, 96, 96},
+	{288, 24, 312, 48},
+	{24, 72, 48, 96},
+	{96, 72, 120, 96}
+};
+
+//Gaudi
+void ActNpc153(NPCHAR *npc)
+{
+	if (npc->x <= gMC.x + (WINDOW_WIDTH * 0x200) && npc->x >= gMC.x - (WINDOW_WIDTH * 0x200) && npc->y <= gMC.y + (WINDOW_HEIGHT * 0x200) && npc->y >= gMC.y - (WINDOW_HEIGHT * 0x200))
+	{
+		switch (npc->act_no)
+		{
+			case 0:
+				npc->act_no = 1;
+				npc->xm = 0;
+				npc->ani_no = 0;
+				npc->y += 0x600;
+				// Fallthrough
+			case 1:
+				if (Random(0, 100) == 1)
+				{
+					npc->act_no = 2;
+					npc->ani_no = 1;
+					npc->act_wait = 0;
+				}
+
+				if (Random(0, 100) == 1)
+				{
+					if (npc->direct == 0)
+						npc->direct = 2;
+					else
+						npc->direct = 0;
+				}
+
+				if (Random(0, 100) == 1)
+					npc->act_no = 10;
+
+				break;
+
+			case 2:
+				if ( ++npc->act_wait > 20 )
+				{
+					npc->act_no = 1;
+					npc->ani_no = 0;
+				}
+
+				break;
+
+			case 10:
+				npc->act_no = 11;
+				npc->act_wait = Random(25, 100);
+				npc->ani_no = 2;
+				npc->ani_wait = 0;
+				// Fallthrough
+			case 11:
+				if (++npc->ani_wait > 3)
+				{
+					npc->ani_wait = 0;
+					++npc->ani_no;
+				}
+
+				if (npc->ani_no > 5)
+					npc->ani_no = 2;
+
+				if (npc->direct == 0)
+					npc->xm = -0x200;
+				else
+					npc->xm = 0x200;
+
+				if (npc->act_wait)
+				{
+					--npc->act_wait;
+				}
+				else
+				{
+					npc->act_no = 1;
+					npc->ani_no = 0;
+					npc->xm = 0;
+				}
+
+				if (npc->direct == 0 && npc->flag & 1)
+				{
+					npc->ani_no = 2;
+					npc->ym = -0x5FF;
+					npc->act_no = 20;
+
+					if ((gMC.cond & 2) == 0)
+						PlaySoundObject(30, 1);
+				}
+				else
+				{
+					if (npc->direct == 2)
+					{
+						if (npc->flag & 4)
+						{
+							npc->ani_no = 2;
+							npc->ym = -0x5FF;
+							npc->act_no = 20;
+
+							if ((gMC.cond & 2) == 0)
+								PlaySoundObject(30, 1);
+						}
+					}
+				}
+
+				break;
+
+			case 20:
+				if (npc->direct == 0 && npc->flag & 1)
+					++npc->count1;
+				else if (npc->direct == 2 && npc->flag & 4)
+					++npc->count1;
+				else
+					npc->count1 = 0;
+
+				if (npc->count1 > 10)
+				{
+					if (npc->direct == 0)
+						npc->direct = 2;
+					else
+						npc->direct = 0;
+				}
+
+				if (npc->direct == 0)
+					npc->xm = -0x100;
+				else
+					npc->xm = 0x100;
+
+				if (npc->flag & 8)
+				{
+					npc->act_no = 21;
+					npc->ani_no = 20;
+					npc->act_wait = 0;
+					npc->xm = 0;
+
+					if ((gMC.cond & 2) == 0)
+						PlaySoundObject(23, 1);
+				}
+
+				break;
+
+			case 21:
+				if (++npc->act_wait > 10)
+				{
+					npc->act_no = 1;
+					npc->ani_no = 0;
+				}
+
+				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 = grcKitL[npc->ani_no];
+		else
+			npc->rect = grcKitR[npc->ani_no];
+
+		if (npc->life <= 985)
+		{
+			npc->code_char = 154;
+			npc->act_no = 0;
+		}
+	}
+}
+
+//Gaudi (dead)
+void ActNpc154(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->bits &= ~0x20;
+			npc->bits &= ~8;
+			npc->damage = 0;
+			npc->act_no = 1;
+			npc->ani_no = 9;
+			npc->ym = -0x200;
+
+			if (npc->direct == 0)
+				npc->xm = 0x100;
+			else
+				npc->xm = -0x100;
+
+			PlaySoundObject(53, 1);
+			break;
+
+		case 1:
+			if (npc->flag & 8)
+			{
+				npc->ani_no = 10;
+				npc->ani_wait = 0;
+				npc->act_no = 2;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 2:
+			npc->xm = 8 * npc->xm / 9;
+
+			if (++npc->ani_wait > 3)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 11)
+				npc->ani_no = 10;
+
+			if (++npc->act_wait > 50)
+				npc->cond |= 8;
+
+			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 = grcKitL[npc->ani_no];
+	else
+		npc->rect = grcKitR[npc->ani_no];
+}
+
+//Gaudi (flying)
+void ActNpc155(NPCHAR *npc)
+{
+	if (npc->x > gMC.x + (WINDOW_WIDTH * 0x200) || npc->x < gMC.x - (WINDOW_WIDTH * 0x200) || npc->y > gMC.y + (WINDOW_HEIGHT * 0x200) || npc->y < gMC.y - (WINDOW_HEIGHT * 0x200))
+		return;
+
+	unsigned char deg;
+	switch (npc->act_no)
+	{
+		case 0:
+			deg = Random(0, 0xFF);
+			npc->xm = GetCos(deg);
+			npc->tgt_x = npc->x + 8 * GetCos(deg + 0x40);
+
+			deg = Random(0, 0xFF);
+			npc->ym = GetSin(deg);
+			npc->tgt_y = npc->y + 8 * GetSin(deg + 0x40);
+
+			npc->act_no = 1;
+			npc->count1 = 120;
+			npc->act_wait = Random(70, 150);
+			npc->ani_no = 14;
+			// Fallthrough
+		case 1:
+			if (++npc->ani_no > 15)
+				npc->ani_no = 14;
+
+			if (npc->act_wait)
+			{
+				--npc->act_wait;
+			}
+			else
+			{
+				npc->act_no = 2;
+				npc->ani_no = 18;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->ani_no > 19)
+				npc->ani_no = 18;
+
+			if (++npc->act_wait > 30)
+			{
+				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(156, npc->x, npc->y, xm, ym, 0, 0, 0x100);
+
+				if ((gMC.cond & 2) == 0)
+					PlaySoundObject(39, 1);
+
+				npc->act_no = 1;
+				npc->act_wait = Random(70, 150);
+				npc->ani_no = 14;
+				npc->ani_wait = 0;
+			}
+
+			break;
+	}
+
+	if (gMC.x < npc->x)
+		npc->direct = 0;
+	else
+		npc->direct = 2;
+
+	if (npc->tgt_x < npc->x)
+		npc->xm -= 0x10;
+	if (npc->tgt_x > npc->x)
+		npc->xm += 0x10;
+
+	if (npc->tgt_y < npc->y)
+		npc->ym -= 0x10;
+	if (npc->tgt_y > npc->y)
+		npc->ym += 0x10;
+
+	if (npc->xm > 0x200)
+		npc->xm = 0x200;
+	if (npc->xm < -0x200)
+		npc->xm = -0x200;
+
+	if (npc->ym > 0x200)
+		npc->ym = 0x200;
+	if (npc->ym < -0x200)
+		npc->ym = -0x200;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	if (npc->direct == 0)
+		npc->rect = grcKitL[npc->ani_no];
+	else
+		npc->rect = grcKitR[npc->ani_no];
+
+	if (npc->life <= 985)
+	{
+		npc->code_char = 154;
+		npc->act_no = 0;
+	}
+}
+
+//Gaudi projectile
+void ActNpc156(NPCHAR *npc)
+{
+	RECT rect_left[3];
+
+	if (npc->flag & 0xFF)
+	{
+		SetCaret(npc->x, npc->y, 2, 0);
+		npc->cond = 0;
+	}
+
+	npc->y += npc->ym;
+	npc->x += npc->xm;
+
+	rect_left[0] = {96, 112, 112, 128};
+	rect_left[1] = {112, 112, 128, 128};
+	rect_left[2] = {128, 112, 144, 128};
+
+	if (++npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	npc->rect = rect_left[npc->ani_no];
+
+	if (++npc->count1 > 300)
+	{
+		SetCaret(npc->x, npc->y, 2, 0);
+		npc->cond = 0;
+	}
+}
+
+//Moving block (vertical)
+void ActNpc157(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->x += 0x1000;
+			npc->y += 0x1000;
+
+			if (npc->direct == 0)
+				npc->act_no = 10;
+			else
+				npc->act_no = 20;
+
+			npc->xm = 0;
+			npc->ym = 0;
+			npc->bits |= 0x40;
+			break;
+
+		case 10:
+			npc->bits &= ~0x80;
+			npc->damage = 0;
+
+			if (gMC.y < npc->y + 0x3200 && gMC.y > npc->y - 0x32000 && gMC.x < npc->x + 0x3200 && gMC.x > npc->x - 0x3200)
+			{
+				npc->act_no = 11;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 11:
+			if (++npc->act_wait % 10 == 6)
+				PlaySoundObject(107, 1);
+
+			if (npc->flag & 2)
+			{
+				npc->ym = 0;
+				npc->direct = 2;
+				npc->act_no = 20;
+				SetQuake(10);
+				PlaySoundObject(26, 1);
+
+				for (int i = 0; i < 4; ++i)
+					SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y - 0x2000, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+			}
+			else
+			{
+				if (gMC.flag & 2)
+				{
+					npc->bits |= 0x80;
+					npc->damage = 100;
+				}
+				else
+				{
+					npc->bits &= ~0x80;
+					npc->damage = 0;
+				}
+
+				npc->ym -= 0x20;
+			}
+
+			break;
+
+		case 20:
+			npc->bits &= ~0x80;
+			npc->damage = 0;
+
+			if (gMC.y > npc->y - 0x3200 && gMC.y < npc->y + 0x32000 && gMC.x < npc->x + 0x3200 && gMC.x > npc->x - 0x3200)
+			{
+				npc->act_no = 21;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 21:
+			if (++npc->act_wait % 10 == 6)
+				PlaySoundObject(107, 1);
+
+			if (npc->flag & 8)
+			{
+				npc->ym = 0;
+				npc->direct = 0;
+				npc->act_no = 10;
+				SetQuake(10);
+				PlaySoundObject(26, 1);
+
+				for (int i = 0; i < 4; ++i)
+					SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + 0x2000, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+			}
+			else
+			{
+				if (gMC.flag & 8)
+				{
+					npc->bits |= 0x80;
+					npc->damage = 100;
+				}
+				else
+				{
+					npc->bits &= ~0x80;
+					npc->damage = 0;
+				}
+
+				npc->ym += 0x20;
+			}
+
+			break;
+	}
+
+	if (npc->ym > 0x200)
+		npc->ym = 0x200;
+	if (npc->ym < -0x200)
+		npc->ym = -0x200;
+
+	npc->y += npc->ym;
+
+	RECT rect[1];
+
+	rect[0] = {16, 0, 48, 32};
+
+	npc->rect = rect[0];
+}
+
+//Fish Missile
+void ActNpc158(NPCHAR *npc)
+{
+	RECT rect[8];
+
+	rect[0] = {0, 224, 16, 240};
+	rect[1] = {16, 224, 32, 240};
+	rect[2] = {32, 224, 48, 240};
+	rect[3] = {48, 224, 64, 240};
+	rect[4] = {64, 224, 80, 240};
+	rect[5] = {80, 224, 96, 240};
+	rect[6] = {96, 224, 112, 240};
+	rect[7] = {112, 224, 128, 240};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+
+			switch (npc->direct)
+			{
+				case 0:
+					npc->count1 = 0xA0;
+					break;
+				case 1:
+					npc->count1 = 0xE0;
+					break;
+				case 2:
+					npc->count1 = 0x20;
+					break;
+				case 3:
+					npc->count1 = 0x60;
+					break;
+			}
+			// Fallthrough
+		case 1:
+			npc->xm = 2 * GetCos(npc->count1);
+			npc->ym = 2 * GetSin(npc->count1);
+			npc->y += npc->ym;
+			npc->x += npc->xm;
+			const int dir = GetArktan(npc->x - gMC.x, npc->y - gMC.y);
+
+			if (dir < npc->count1)
+			{
+				if (npc->count1 - dir < 0x80)
+					--npc->count1;
+				else
+					++npc->count1;
+			}
+			else
+			{
+				if (dir - npc->count1 < 0x80)
+					++npc->count1;
+				else
+					--npc->count1;
+			}
+
+			if (npc->count1 > 0xFF)
+				npc->count1 -= 0x100;
+			if (npc->count1 < 0)
+				npc->count1 += 0x100;
+
+			break;
+	}
+
+	if (++npc->ani_wait > 2)
+	{
+		npc->ani_wait = 0;
+		SetCaret(npc->x, npc->y, 7, 4);
+	}
+
+	npc->ani_no = (npc->count1 + 0x10) / 0x20;
+
+	if (npc->ani_no > 7)
+		npc->ani_no = 7;
+
+	npc->rect = rect[npc->ani_no];
+}
+
+//Monster X (defeated)
+void ActNpc159(NPCHAR *npc)
+{
+	RECT rect[1];
+
+	rect[0] = {144, 128, 192, 200};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+
+			for (int i = 0; i < 8; ++i)
+				SetNpChar(4, npc->x + (Random(-16, 16) * 0x200), npc->y + (Random(-16, 16) * 0x200), Random(-341, 341), Random(-341, 341), 0, 0, 0x100);
+			// Fallthrough
+		case 1:
+			if (++npc->act_wait > 50)
+			{
+				npc->act_no = 2;
+				npc->xm = -0x100;
+			}
+
+			if (npc->act_wait / 2 % 2)
+				npc->x += 0x200;
+			else
+				npc->x -= 0x200;
+
+			break;
+
+		case 2:
+			++npc->act_wait;
+			npc->ym += 0x40;
+
+			if (npc->y > 0x50000)
+				npc->cond = 0;
+
+			break;
+	}
+
+	npc->y += npc->ym;
+	npc->x += npc->xm;
+
+	npc->rect = rect[0];
+
+	if (npc->act_wait % 8 == 1)
+		SetNpChar(4, npc->x + (Random(-16, 16) * 0x200), npc->y + (Random(-16, 16) * 0x200), Random(-341, 341), Random(-341, 341), 0, 0, 0x100);
 }
--- /dev/null
+++ b/src/NpcAct160.cpp
@@ -1,0 +1,1154 @@
+#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 "Frame.h"
+#include "Caret.h"
+#include "MycParam.h"
+#include "CommonDefines.h"
+
+//Puu Black
+void ActNpc160(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->bits &= ~1;
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			if (gMC.x > npc->x)
+				npc->direct = 2;
+			else
+				npc->direct = 0;
+
+			npc->ym = 0xA00;
+
+			if (npc->y < 0x10000)
+			{
+				++npc->count1;
+			}
+			else
+			{
+				npc->bits &= ~8;
+				npc->act_no = 2;
+			}
+
+			break;
+
+		case 2:
+			npc->ym = 0xA00;
+
+			if (npc->flag & 8)
+			{
+				DeleteNpCharCode(161, 1);
+
+				for (int i = 0; i < 4; ++i)
+					SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+				npc->act_no = 3;
+				npc->act_wait = 0;
+				SetQuake(30);
+				PlaySoundObject(26, 1);
+				PlaySoundObject(72, 1);
+			}
+
+			if (gMC.y > npc->y && gMC.flag & 8)
+				npc->damage = 20;
+			else
+				npc->damage = 0;
+
+			break;
+
+		case 3:
+			npc->damage = 20;
+			npc->damage = 0;	// Smart code
+
+			if (++npc->act_wait > 24)
+			{
+				npc->act_no = 4;
+				npc->count1 = 0;
+				npc->count2 = 0;
+			}
+
+			break;
+
+		case 4:
+			gSuperXpos = npc->x;
+			gSuperYpos = npc->y;
+
+			if (npc->shock % 2 == 1)
+			{
+				SetNpChar(161, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-0x600, 0x600), Random(-0x600, 0x600), 0, 0, 0x100);
+
+				if (++npc->count1 > 30)
+				{
+					npc->count1 = 0;
+					npc->act_no = 5;
+					npc->ym = -0xC00;
+					npc->bits |= 8;
+				}
+			}
+
+			break;
+
+		case 5:
+			gSuperXpos = npc->x;
+			gSuperYpos = npc->y;
+
+			if (++npc->count1 > 60)
+			{
+				npc->count1 = 0;
+				npc->act_no = 6;
+			}
+
+			break;
+
+		case 6:
+			gSuperXpos = gMC.x;
+			gSuperYpos = 0x320000;
+
+			if (++npc->count1 > 110)
+			{
+				npc->count1 = 10;
+				npc->x = gMC.x;
+				npc->y = 0;
+				npc->ym = 0x5FF;
+				npc->act_no = 1;
+			}
+
+			break;
+	}
+
+	npc->y += npc->ym;
+
+	switch (npc->act_no)
+	{
+		case 0:
+		case 1:
+			npc->ani_no = 3;
+			break;
+		case 2:
+			npc->ani_no = 3;
+			break;
+		case 3:
+			npc->ani_no = 2;
+			break;
+		case 4:
+			npc->ani_no = 0;
+			break;
+		case 5:
+			npc->ani_no = 3;
+			break;
+		case 6:
+			npc->ani_no = 3;
+			break;
+	}
+
+	RECT rect_left[4];
+	RECT rect_right[4];
+
+	rect_left[0] = {0, 0, 40, 24};
+	rect_left[1] = {40, 0, 80, 24};
+	rect_left[2] = {80, 0, 120, 24};
+	rect_left[3] = {120, 0, 160, 24};
+
+	rect_right[0] = {0, 24, 40, 48};
+	rect_right[1] = {40, 24, 80, 48};
+	rect_right[2] = {80, 24, 120, 48};
+	rect_right[3] = {120, 24, 160, 48};
+
+	if (npc->direct == 0)
+		npc->rect = rect_left[npc->ani_no];
+	else
+		npc->rect = rect_right[npc->ani_no];
+}
+
+//Puu Black projectile
+void ActNpc161(NPCHAR *npc)
+{
+	RECT rect[3];
+
+	npc->exp = 0;
+
+	if (gSuperXpos > npc->x)
+		npc->xm += 0x40;
+	else
+		npc->xm -= 0x40;
+
+	if (gSuperYpos > npc->y)
+		npc->ym += 0x40;
+	else
+		npc->ym -= 0x40;
+
+	if (npc->xm < -4605)
+		npc->xm = -4605;
+	if (npc->xm > 4605)
+		npc->xm = 4605;
+
+	if (npc->ym < -4605)
+		npc->ym = -4605;
+	if (npc->ym > 4605)
+		npc->ym = 4605;
+
+	if (npc->life < 100)
+	{
+		npc->bits &= ~0x20;
+		npc->bits &= ~4;
+		npc->damage = 0;
+		npc->ani_no = 2;
+	}
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	if (npc->ani_no < 2)
+	{
+		if (Random(0, 10) == 2)
+			npc->ani_no = 0;
+		else
+			npc->ani_no = 1;
+	}
+
+	rect[0] = {0, 48, 16, 64};
+	rect[1] = {16, 48, 32, 64};
+	rect[2] = {32, 48, 48, 64};
+
+	npc->rect = rect[npc->ani_no];
+}
+
+//Puu Black (dead)
+void ActNpc162(NPCHAR *npc)
+{
+	RECT rect_left = {40, 0, 80, 24};
+	RECT rect_right = {40, 24, 80, 48};
+	RECT rect_end = {0, 0, 0, 0};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			DeleteNpCharCode(161, 1);
+			PlaySoundObject(72, 1);
+
+			for (int i = 0; i < 10; ++i)
+				SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-0x600, 0x600), Random(-0x600, 0x600), 0, 0, 0x100);
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (npc->direct == 0)
+				npc->rect = rect_left;
+			else
+				npc->rect = rect_right;
+
+			npc->count1 = 0;
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			if (++npc->count1 % 4 == 0)
+				SetNpChar(161, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), 0, 0, 0, 0, 0x100);
+
+			if (npc->count1 > 160)
+			{
+				npc->count1 = 0;
+				npc->act_no = 2;
+				npc->tgt_y = npc->y;
+			}
+
+			break;
+
+		case 2:
+			SetQuake(2);
+
+			if (++npc->count1 > 240)
+			{
+				npc->rect = rect_end;
+
+				npc->count1 = 0;
+				npc->act_no = 3;
+			}
+			else
+			{
+				if (npc->direct == 0)
+					npc->rect = rect_left;
+				else
+					npc->rect = rect_right;
+
+				npc->rect.top += npc->count1 / 8;
+				npc->y = npc->tgt_y + ((npc->count1 / 8) * 0x200);
+				npc->rect.left -= (npc->count1 / 2) % 2;
+			}
+
+			if (npc->count1 % 3 == 2)
+				SetNpChar(161, npc->x + (Random(-12, 12) * 0x200), npc->y - 0x1800, Random(-0x200, 0x200), 0x100, 0, 0, 0x100);
+
+			if (npc->count1 % 4 == 2)
+				PlaySoundObject(21, 1);
+
+			break;
+
+		case 3:
+			if (++npc->count1 >= 60)
+			{
+				DeleteNpCharCode(161, 1);
+				npc->cond = 0;
+			}
+
+			break;
+
+	}
+
+	gSuperXpos = npc->x;
+	gSuperYpos = -0x7D000;
+}
+
+//Dr Gero
+void ActNpc163(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {192, 0, 208, 16};
+	rcLeft[1] = {208, 0, 224, 16};
+
+	rcRight[0] = {192, 16, 208, 32};
+	rcRight[1] = {208, 16, 224, 32};
+
+	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];
+}
+
+//Nurse Hasumi
+void ActNpc164(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {224, 0, 240, 16};
+	rcLeft[1] = {240, 0, 256, 16};
+
+	rcRight[0] = {224, 16, 240, 32};
+	rcRight[1] = {240, 16, 256, 32};
+
+	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];
+}
+
+//Curly (collapsed)
+void ActNpc165(NPCHAR *npc)
+{
+	RECT rcRight[2];
+	RECT rcLeft[1];
+
+	rcRight[0] = {192, 96, 208, 112};
+	rcRight[1] = {208, 96, 224, 112};
+
+	rcLeft[0] = {144, 96, 160, 112};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->y += 0x1400;
+			// Fallthrough
+		case 1:
+			if (npc->direct == 2 && gMC.x > npc->x - 0x4000 && gMC.x < npc->x + 0x4000 && gMC.y > npc->y - 0x2000 && gMC.y < npc->y + 0x2000)
+				npc->ani_no = 1;
+			else
+				npc->ani_no = 0;
+
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[0];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Chaba
+void ActNpc166(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+
+	rcLeft[0] = {144, 104, 184, 128};
+	rcLeft[1] = {184, 104, 224, 128};
+
+	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;
+	}
+
+	npc->rect = rcLeft[npc->ani_no];
+}
+
+//Professor Booster (falling)
+void ActNpc167(NPCHAR *npc)
+{
+	RECT rect[3];
+
+	rect[0] = {304, 0, 320, 16};
+	rect[1] = {304, 16, 320, 32};
+	rect[2] = {0, 0, 0, 0};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 1;
+			break;
+		case 10:
+			npc->ani_no = 0;
+
+			npc->ym += 0x40;
+			if (npc->ym > 0x5FF)
+				npc->ym = 0x5FF;
+
+			npc->y += npc->ym;
+			break;
+		case 20:
+			npc->act_no = 21;
+			npc->act_wait = 0;
+			npc->ani_no = 0;
+			PlaySoundObject(29, 1);
+			// Fallthrough
+		case 21:
+			if (++npc->ani_no > 2)
+				npc->ani_no = 1;
+
+			if (++npc->act_wait > 100)
+			{
+				for (int i = 0; i < 4; ++i)
+					SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+				npc->cond = 0;
+			}
+
+			break;
+	}
+
+	npc->rect = rect[npc->ani_no];
+}
+
+//Boulder
+void ActNpc168(NPCHAR *npc)
+{
+	RECT rect[1];
+
+	rect[0] = {264, 56, 320, 96};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->act_wait = 0;
+			npc->tgt_x = npc->x;
+			// Fallthrough
+		case 11:
+			++npc->act_wait;
+			npc->x = npc->tgt_x;
+
+			if (npc->act_wait / 3 % 2)
+				npc->x += 0x200;
+
+			break;
+
+		case 20:
+			npc->act_no = 21;
+			npc->act_wait = 0;
+			npc->ym = -0x400;
+			npc->xm = 0x100;
+			PlaySoundObject(25, 1);
+			// Fallthrough
+		case 21:
+			npc->ym += 0x10;
+
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+
+			if (npc->act_wait && npc->flag & 8)
+			{
+				PlaySoundObject(35, 1);
+				SetQuake(40);
+				npc->act_no = 0;
+			}
+
+			if (npc->act_wait == 0)
+				++npc->act_wait;
+
+			break;
+	}
+
+	npc->rect = rect[0];
+}
+
+//Balrog (missile)
+void ActNpc169(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->act_wait = 30;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+			// Fallthrough
+		case 1:
+			if (--npc->act_wait == 0)
+			{
+				npc->act_no = 2;
+				++npc->count1;
+			}
+
+			break;
+
+		case 2:
+			npc->act_no = 3;
+			npc->act_wait = 0;
+			npc->ani_no = 1;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 3:
+			if (++npc->ani_wait > 3)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+
+				if (npc->ani_no == 2 || npc->ani_no == 4)
+					PlaySoundObject(23, 1);
+			}
+
+			if (npc->ani_no > 4)
+				npc->ani_no = 1;
+
+			if (npc->direct == 0)
+				npc->xm -= 0x20;
+			else
+				npc->xm += 0x20;
+
+			if (npc->act_wait >= 8 && gMC.x > npc->x - 0x1800 && gMC.x < npc->x + 0x1800 && gMC.y > npc->y - 0x1800 && gMC.y < npc->y + 0x1000)
+			{
+				npc->act_no = 10;
+				npc->ani_no = 5;
+				gMC.cond |= 2;
+				DamageMyChar(5);
+			}
+			else
+			{
+				if (++npc->act_wait > 75)
+				{
+					npc->act_no = 9;
+					npc->ani_no = 0;
+				}
+				else
+				{
+					if (npc->flag & 5)
+					{
+						if (npc->count2 < 5)
+						{
+							++npc->count2;
+						}
+						else
+						{
+							npc->act_no = 4;
+							npc->act_wait = 0;
+							npc->ani_no = 7;
+							npc->ym = -0x5FF;
+						}
+					}
+					else
+					{
+						npc->count2 = 0;
+					}
+
+					if (npc->count1 % 2 == 0 && npc->act_wait > 25)
+					{
+						npc->act_no = 4;
+						npc->act_wait = 0;
+						npc->ani_no = 7;
+						npc->ym = -0x5FF;
+					}
+				}
+			}
+
+			break;
+
+		case 4:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			++npc->act_wait;
+
+			if (npc->act_wait < 30 && npc->act_wait % 6 == 1)
+			{
+				PlaySoundObject(39, 1);
+				SetNpChar(170, npc->x, npc->y, 0, 0, npc->direct, 0, 0x100);
+			}
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 9;
+				npc->ani_no = 8;
+				SetQuake(30);
+				PlaySoundObject(26, 1);
+			}
+
+			if (npc->act_wait >= 8 && gMC.x > npc->x - 0x1800 && gMC.x < npc->x + 0x1800 && gMC.y > npc->y - 0x1800 && gMC.y < npc->y + 0x1000)
+			{
+				npc->act_no = 10;
+				npc->ani_no = 5;
+				gMC.cond |= 2;
+				DamageMyChar(10);
+			}
+
+			break;
+
+		case 9:
+			npc->xm = 4 * npc->xm / 5;
+
+			if (npc->xm == 0)
+				npc->act_no = 0;
+
+			break;
+
+		case 10:
+			gMC.x = npc->x;
+			gMC.y = npc->y;
+
+			npc->xm = 4 * npc->xm / 5;
+
+			if (npc->xm == 0)
+			{
+				npc->act_no = 11;
+				npc->act_wait = 0;
+				npc->ani_no = 5;
+				npc->ani_wait = 0;
+			}
+
+			break;
+
+		case 11:
+			gMC.x = npc->x;
+			gMC.y = npc->y;
+
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 6)
+				npc->ani_no = 5;
+
+			if (++npc->act_wait > 100)
+				npc->act_no = 20;
+
+			break;
+
+		case 20:
+			PlaySoundObject(25, 1);
+			gMC.cond &= ~2;
+
+			if (npc->direct == 0)
+			{
+				gMC.x += 0x800;
+				gMC.y -= 0x1000;
+				gMC.xm = 0x5FF;
+				gMC.ym = -0x200;
+				gMC.direct = 2;
+				npc->direct = 2;
+			}
+			else
+			{
+				gMC.x -= 0x800;
+				gMC.y -= 0x1000;
+				gMC.xm = -0x5FF;
+				gMC.ym = -0x200;
+				gMC.direct = 0;
+				npc->direct = 0;
+			}
+
+			npc->act_no = 21;
+			npc->act_wait = 0;
+			npc->ani_no = 7;
+			// Fallthrough
+		case 21:
+			if (++npc->act_wait >= 50)
+				npc->act_no = 0;
+
+			break;
+	}
+
+	npc->ym += 0x20;
+
+	if (npc->xm < -0x300)
+		npc->xm = -0x300;
+	if (npc->xm > 0x300)
+		npc->xm = 0x300;
+
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	RECT rect_left[9];
+	RECT rect_right[9];
+
+	rect_left[0] = {0, 0, 40, 24};
+	rect_left[1] = {0, 48, 40, 72};
+	rect_left[2] = {0, 0, 40, 24};
+	rect_left[3] = {40, 48, 80, 72};
+	rect_left[4] = {0, 0, 40, 24};
+	rect_left[5] = {80, 48, 120, 72};
+	rect_left[6] = {120, 48, 160, 72};
+	rect_left[7] = {120, 0, 160, 24};
+	rect_left[8] = {80, 0, 120, 24};
+
+	rect_right[0] = {0, 24, 40, 48};
+	rect_right[1] = {0, 72, 40, 96};
+	rect_right[2] = {0, 24, 40, 48};
+	rect_right[3] = {40, 72, 80, 96};
+	rect_right[4] = {0, 24, 40, 48};
+	rect_right[5] = {80, 72, 120, 96};
+	rect_right[6] = {120, 72, 160, 96};
+	rect_right[7] = {120, 24, 160, 48};
+	rect_right[8] = {80, 24, 120, 48};
+
+	if (npc->direct == 0)
+		npc->rect = rect_left[npc->ani_no];
+	else
+		npc->rect = rect_right[npc->ani_no];
+}
+
+//Balrog missile
+void ActNpc170(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {112, 96, 128, 104};
+	rcLeft[1] = {128, 96, 144, 104};
+
+	rcRight[0] = {112, 104, 128, 112};
+	rcRight[1] = {128, 104, 144, 112};
+
+	bool bHit = false;
+
+	if (npc->direct == 0 && npc->flag & 1)
+		bHit = true;
+	if (npc->direct == 2 && npc->flag & 4)
+		bHit = true;
+
+	if (bHit)
+	{
+		PlaySoundObject(44, 1);
+		SetDestroyNpChar(npc->x, npc->y, 0, 3);
+		VanishNpChar(npc);
+		return;
+	}
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+
+			if (npc->direct == 0)
+				npc->xm = Random(1, 2) * 0x200;
+			else
+				npc->xm = Random(-2, -1) * 0x200;
+
+			npc->ym = Random(-2, 0) * 0x200;
+			// Fallthrough
+		case 1:
+			++npc->count1;
+
+			if (npc->direct == 0)
+			{
+				npc->xm -= 0x20;
+
+				if (npc->count1 % 3 == 1)
+					SetCaret(npc->x + 0x1000, npc->y, 7, 2);
+			}
+			else
+			{
+				npc->xm += 0x20;
+
+				if (npc->count1 % 3 == 1)
+					SetCaret(npc->x - 0x1000, npc->y, 7, 0);
+			}
+
+			if (npc->count1 >= 50)
+			{
+				npc->ym = 0;
+			}
+			else
+			{
+				if (gMC.y > npc->y)
+					npc->ym += 0x20;
+				else
+					npc->ym -= 0x20;
+			}
+
+			if (++npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			break;
+	}
+
+	if (npc->xm < -0x400)
+		npc->xm = -0x600;
+	if (npc->xm > 0x400)
+		npc->xm = 0x600;
+
+	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];
+}
+
+//Gaudi (armoured)
+void ActNpc173(NPCHAR *npc)
+{
+	RECT rcLeft[4];
+	RECT rcRight[4];
+
+	rcLeft[0] = {0, 128, 24, 152};
+	rcLeft[1] = {24, 128, 48, 152};
+	rcLeft[2] = {48, 128, 72, 152};
+	rcLeft[3] = {72, 128, 96, 152};
+
+	rcRight[0] = {0, 152, 24, 176};
+	rcRight[1] = {24, 152, 48, 176};
+	rcRight[2] = {48, 152, 72, 176};
+	rcRight[3] = {72, 152, 96, 176};
+
+	if (npc->x <= gMC.x + (WINDOW_WIDTH * 0x200) && npc->x >= gMC.x - (WINDOW_WIDTH * 0x200) && npc->y <= gMC.y + (WINDOW_HEIGHT * 0x200) && npc->y >= gMC.y - (WINDOW_HEIGHT * 0x200))
+	{
+		switch (npc->act_no)
+		{
+			case 0:
+				npc->tgt_x = npc->x;
+				npc->act_no = 1;
+				// Fallthrough
+			case 1:
+				npc->ani_no = 0;
+				npc->xm = 0;
+
+				if (npc->act_wait < 5)
+				{
+					++npc->act_wait;
+				}
+				else
+				{
+					if (gMC.x > npc->x - 0x18000 && gMC.x < npc->x + 0x18000 && gMC.y > npc->y - 0x14000 && gMC.y < npc->y + 0x14000)
+					{
+						npc->act_no = 10;
+						npc->act_wait = 0;
+						npc->ani_no = 1;
+					}
+				}
+
+				break;
+
+			case 10:
+				if (++npc->act_wait > 3)
+				{
+					if (++npc->count1 == 3)
+					{
+						PlaySoundObject(30, 1);
+						npc->count1 = 0;
+						npc->act_no = 25;
+						npc->act_wait = 0;
+						npc->ani_no = 2;
+						npc->ym = -0x600;
+
+						if (npc->tgt_x > npc->x)
+							npc->xm = 0x80;
+						else
+							npc->xm = -0x80;
+					}
+					else
+					{
+						PlaySoundObject(30, 1);
+						npc->act_no = 20;
+						npc->ani_no = 2;
+						npc->ym = -0x200;
+
+						if (npc->tgt_x > npc->x)
+							npc->xm = 0x200;
+						else
+							npc->xm = -0x200;
+					}
+				}
+
+				break;
+
+			case 20:
+				++npc->act_wait;
+
+				if (npc->flag & 8)
+				{
+					PlaySoundObject(23, 1);
+					npc->ani_no = 1;
+					npc->act_no = 30;
+					npc->act_wait = 0;
+				}
+
+				break;
+
+			case 25:
+				if (++npc->act_wait == 30 || npc->act_wait == 40)
+				{
+					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(174, npc->x, npc->y, xm, ym, 0, 0, 0x100);
+
+					PlaySoundObject(39, 1);
+					npc->ani_no = 3;
+
+					gCurlyShoot_wait = Random(80, 100);
+					gCurlyShoot_x = npc->x;
+					gCurlyShoot_y = npc->y;
+				}
+
+				if (npc->act_wait == 35 || npc->act_wait == 45)
+					npc->ani_no = 2;
+
+				if (npc->flag & 8)
+				{
+					PlaySoundObject(23, 1);
+					npc->ani_no = 1;
+					npc->act_no = 30;
+					npc->act_wait = 0;
+				}
+
+				break;
+
+			case 30:
+				npc->xm = 7 * npc->xm / 8;
+
+				if (++npc->act_wait > 3)
+				{
+					npc->ani_no = 0;
+					npc->act_no = 1;
+					npc->act_wait = 0;
+				}
+
+				break;
+		}
+
+		npc->ym += 51;
+
+		if (gMC.x < npc->x)
+			npc->direct = 0;
+		else
+			npc->direct = 2;
+
+		if (npc->ym > 0x5FF)
+			npc->ym = 0x5FF;
+		if ( npc->ym < -0x5FFu )
+			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->life <= 985)
+		{
+			SetDestroyNpChar(npc->x, npc->y, 0, 2);
+			npc->code_char = 154;
+			npc->act_no = 0;
+		}
+	}
+}
+
+//Armoured-Gaudi projectile
+void ActNpc174(NPCHAR *npc)
+{
+	RECT rect_left[3];
+
+	bool bHit;
+	switch (npc->act_no)
+	{
+		case 0:
+			if (npc->direct == 2)
+				npc->act_no = 2;
+			// Fallthrough
+		case 1:
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+
+			bHit = false;
+
+			if (npc->flag & 1)
+			{
+				bHit = true;
+				npc->xm = 0x200;
+			}
+
+			if (npc->flag & 4)
+			{
+				bHit = true;
+				npc->xm = -0x200;
+			}
+
+			if (npc->flag & 2)
+			{
+				bHit = true;
+				npc->ym = 0x200;
+			}
+
+			if (npc->flag & 8)
+			{
+				bHit = true;
+				npc->ym = -0x200;
+			}
+
+			if (bHit)
+			{
+				npc->act_no = 2;
+				++npc->count1;
+				PlaySoundObject(31, 1);
+			}
+
+			break;
+
+		case 2:
+			npc->ym += 0x40;
+
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+
+			if (npc->flag & 8)
+			{
+				if (++npc->count1 > 1)
+				{
+					SetCaret(npc->x, npc->y, 2, 0);
+					npc->cond = 0;
+				}
+			}
+
+			break;
+	}
+
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+	if (npc->ym < -0x5FF)
+		npc->ym = -0x5FF;
+
+	rect_left[0] = {120, 80, 136, 96};
+	rect_left[1] = {136, 80, 152, 96};
+	rect_left[2] = {152, 80, 168, 96};
+
+	if (++npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	npc->rect = rect_left[npc->ani_no];
+}
--- a/src/NpcAct180.cpp
+++ b/src/NpcAct180.cpp
@@ -129,6 +129,22 @@
 	npc->rect = rc[0];
 }
 
+//Blue robot (broken)
+void ActNpc194(NPCHAR *npc)
+{
+	RECT rc[1];
+
+	rc[0] = {192, 120, 224, 128};
+
+	if (npc->act_no == 0)
+	{
+		npc->act_no = 1;
+		npc->y += 0x800;
+	}
+
+	npc->rect = rc[0];
+}
+
 //Water/wind particles
 void ActNpc199(NPCHAR *npc)
 {
--- a/src/NpcAct200.cpp
+++ b/src/NpcAct200.cpp
@@ -34,5 +34,5 @@
 	else if (Random(0, 40) == 1)
 		SetNpChar(4, npc->x + (Random(-20, 20) * 0x200), npc->y, 0, -0x200, 0, 0, 0x100);
 
-	npc->rect = rc[1];
-}
\ No newline at end of file
+	npc->rect = rc[0];
+}
--- a/src/NpcAct280.cpp
+++ b/src/NpcAct280.cpp
@@ -13,6 +13,8 @@
 //Quake
 void ActNpc292(NPCHAR *npc)
 {
+	(void)npc;
+
 	SetQuake(10);
 }
 
--- /dev/null
+++ b/src/NpcAct320.cpp
@@ -1,0 +1,56 @@
+#include "WindowsWrapper.h"
+
+#include "NpcAct.h"
+
+#include "MyChar.h"
+#include "NpChar.h"
+#include "Game.h"
+#include "Sound.h"
+#include "Back.h"
+#include "Triangle.h"
+
+//Sweat
+void ActNpc334(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {160, 184, 168, 200};
+	rcLeft[1] = {168, 184, 176, 200};
+
+	rcRight[0] = {176, 184, 184, 200};
+	rcRight[1] = {184, 184, 192, 200};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 10;
+
+			if (npc->direct == 0)
+			{
+				npc->x += 0x1400;
+				npc->y -= 0x2400;
+			}
+			else
+			{
+				npc->x = gMC.x - 0x1400;
+				npc->y = gMC.y - 0x400;
+			}
+			// Fallthrough
+		case 10:
+			if (++npc->act_wait / 8 & 1)
+				npc->ani_no = 0;
+			else
+				npc->ani_no = 1;
+
+			if (npc->act_wait >= 64)
+				npc->cond = 0;
+
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
--- a/src/NpcTbl.cpp
+++ b/src/NpcTbl.cpp
@@ -19,7 +19,7 @@
 
 	const size_t tblSize = SDL_RWsize(fp);
 
-	const int npcCount = tblSize / 0x18;
+	const size_t npcCount = tblSize / 0x18;
 	gNpcTable = (NPC_TABLE*)malloc(npcCount * sizeof(NPC_TABLE));
 
 	for (size_t i = 0; i < npcCount; i++) //bits
@@ -203,14 +203,34 @@
 	ActNpc144,
 	ActNpc145,
 	ActNpc146,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc147,
+	ActNpc148,
+	ActNpc149,
 	ActNpc150,
 	ActNpc151,
 	nullptr,
+	ActNpc153,
+	ActNpc154,
+	ActNpc155,
+	ActNpc156,
+	ActNpc157,
+	ActNpc158,
+	ActNpc159,
+	ActNpc160,
+	ActNpc161,
+	ActNpc162,
+	ActNpc163,
+	ActNpc164,
+	ActNpc165,
+	ActNpc166,
+	ActNpc167,
+	ActNpc168,
+	ActNpc169,
+	ActNpc170,
 	nullptr,
 	nullptr,
+	ActNpc173,
+	ActNpc174,
 	nullptr,
 	nullptr,
 	nullptr,
@@ -228,33 +248,13 @@
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
 	ActNpc192,
 	ActNpc193,
+	ActNpc194,
 	nullptr,
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
 	ActNpc199,
 	nullptr,
 	nullptr,
@@ -390,7 +390,7 @@
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
+	ActNpc334,
 	nullptr,
 	nullptr,
 	nullptr,
--- a/src/Organya.cpp
+++ b/src/Organya.cpp
@@ -123,7 +123,7 @@
 			uint8_t *wp_sub = wp;
 			size_t wav_tp = 0;
 			
-			for (int i = 0; i < data_size; i++)
+			for (size_t i = 0; i < data_size; i++)
 			{
 				uint8_t work = *(wavep+wav_tp);
 				work += 0x80;
--- a/src/SelStage.cpp
+++ b/src/SelStage.cpp
@@ -97,15 +97,15 @@
 	RECT rcCur[2];
 	RECT rcTitle1;
 
-	rcView = {0, 0, 320, 240};
+	rcView = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT};
 	rcCur[0] = {80, 88, 112, 104};
 	rcCur[1] = {80, 104, 112, 120};
 	rcTitle1 = {80, 64, 144, 72};
 
-	if (gStageSelectTitleY > 46)
+	if (gStageSelectTitleY > (WINDOW_HEIGHT / 2) - 74)
 		--gStageSelectTitleY;
 
-	PutBitmap3(&rcView, 128, gStageSelectTitleY, &rcTitle1, SURFACE_ID_TEXT_BOX);
+	PutBitmap3(&rcView, (WINDOW_WIDTH / 2) - 32, gStageSelectTitleY, &rcTitle1, SURFACE_ID_TEXT_BOX);
 
 	int stage_num;
 	for (stage_num = 0; gPermitStage[stage_num].index; ++stage_num);
@@ -114,9 +114,9 @@
 
 	if (stage_num)
 	{
-		int stage_x = (320 - 40 * stage_num) / 2;
+		int stage_x = (WINDOW_WIDTH - 40 * stage_num) / 2;
 
-		PutBitmap3(&rcView, stage_x + 40 * gSelectedStage, 64, &rcCur[(flash >> 1) % 2], SURFACE_ID_TEXT_BOX);
+		PutBitmap3(&rcView, stage_x + 40 * gSelectedStage, (WINDOW_HEIGHT / 2) - 56, &rcCur[(flash >> 1) % 2], SURFACE_ID_TEXT_BOX);
 
 		for (int i = 0; i < 8 && gPermitStage[i].index; ++i)
 		{
@@ -126,7 +126,7 @@
 			rcStage.top = 16 * (gPermitStage[i].index / 8);
 			rcStage.bottom = rcStage.top + 16;
 
-			PutBitmap3(&rcView, stage_x + 40 * i, 64, &rcStage, SURFACE_ID_STAGE_ITEM);
+			PutBitmap3(&rcView, stage_x + 40 * i, (WINDOW_HEIGHT / 2) - 56, &rcStage, SURFACE_ID_STAGE_ITEM);
 		}
 	}
 }
@@ -135,13 +135,13 @@
 {
 	char old_script_path[260];
 
-	RECT rcView = {0, 0, 320, 240};
+	RECT rcView = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT};
 
 	gSelectedStage = 0;
 	BackupSurface(10, &grcFull);
 	GetTextScriptPath(old_script_path);
 	LoadTextScript2("StageSelect.tsc");
-	gStageSelectTitleY = 54;
+	gStageSelectTitleY = (WINDOW_HEIGHT / 2) - 66;
 	StartTextScript(gPermitStage[gSelectedStage].index + 1000);
 
 	do
--- a/src/Shoot.cpp
+++ b/src/Shoot.cpp
@@ -886,7 +886,7 @@
 		bMax = false;
 	}
 
-	if (gKey & gKeyShot == 0)
+	if (!(gKey & gKeyShot))
 		ZeroExpMyChar();
 
 	switch (level)
--- a/src/Sound.cpp
+++ b/src/Sound.cpp
@@ -76,9 +76,6 @@
 
 void SOUNDBUFFER::Release()
 {
-	if (this == NULL)
-		return;
-	
 	//TODO: find a better and more stable(?) way to handle this function
 	delete this;
 }
@@ -85,9 +82,6 @@
 
 void SOUNDBUFFER::Lock(uint8_t **outBuffer, size_t *outSize)
 {
-	if (this == NULL)
-		return;
-	
 	SDL_LockAudioDevice(audioDevice);
 
 	if (outBuffer != nullptr)
@@ -99,17 +93,11 @@
 
 void SOUNDBUFFER::Unlock()
 {
-	if (this == NULL)
-		return;
-	
 	SDL_UnlockAudioDevice(audioDevice);
 }
 
 void SOUNDBUFFER::SetCurrentPosition(uint32_t dwNewPosition)
 {
-	if (this == NULL)
-		return;
-	
 	SDL_LockAudioDevice(audioDevice);
 	samplePosition = dwNewPosition;
 	SDL_UnlockAudioDevice(audioDevice);
@@ -117,9 +105,6 @@
 
 void SOUNDBUFFER::SetFrequency(uint32_t dwFrequency)
 {
-	if (this == NULL)
-		return;
-	
 	SDL_LockAudioDevice(audioDevice);
 	frequency = (double)dwFrequency;
 	SDL_UnlockAudioDevice(audioDevice);
@@ -134,9 +119,6 @@
 
 void SOUNDBUFFER::SetVolume(int32_t lVolume)
 {
-	if (this == NULL)
-		return;
-	
 	SDL_LockAudioDevice(audioDevice);
 	volume = MillibelToVolume(lVolume);
 	SDL_UnlockAudioDevice(audioDevice);
@@ -144,9 +126,6 @@
 
 void SOUNDBUFFER::SetPan(int32_t lPan)
 {
-	if (this == NULL)
-		return;
-	
 	SDL_LockAudioDevice(audioDevice);
 	volume_l = MillibelToVolume(-lPan);
 	volume_r = MillibelToVolume(lPan);
@@ -155,9 +134,6 @@
 
 void SOUNDBUFFER::Play(bool bLooping)
 {
-	if (this == NULL)
-		return;
-	
 	SDL_LockAudioDevice(audioDevice);
 	playing = true;
 	looping = bLooping;
@@ -166,9 +142,6 @@
 
 void SOUNDBUFFER::Stop()
 {
-	if (this == NULL)
-		return;
-	
 	SDL_LockAudioDevice(audioDevice);
 	playing = false;
 	SDL_UnlockAudioDevice(audioDevice);
@@ -176,9 +149,6 @@
 
 void SOUNDBUFFER::Mix(float (*buffer)[2], size_t samples)
 {
-	if (this == NULL)
-		return;
-	
 	if (!playing) //This sound buffer isn't playing
 		return;
 
@@ -225,6 +195,8 @@
 //Sound mixer
 void AudioCallback(void *userdata, uint8_t *stream, int len)
 {
+	(void)userdata;
+
 	float (*buffer)[2] = (float(*)[2])stream;
 	const size_t samples = len / (sizeof(float) * 2);
 
--- a/src/TextScr.cpp
+++ b/src/TextScr.cpp
@@ -27,6 +27,7 @@
 #include "Map.h"
 #include "BossLife.h"
 #include "SelStage.h"
+#include "Flash.h"
 
 #define IS_COMMAND(c1, c2, c3) gTS.data[gTS.p_read + 1] == c1 && gTS.data[gTS.p_read + 2] == c2 && gTS.data[gTS.p_read + 3] == c3
 
@@ -472,7 +473,7 @@
 			
 			PutBitmap3(&grcFull, (WINDOW_WIDTH + 112) / 2, i, &rect_yesno, 26);
 			if (gTS.wait == 16)
-				PutBitmap3(&grcFull, 41 * gTS.select + (WINDOW_WIDTH + 102) / 2, 154, &rect_cur, 26);
+				PutBitmap3(&grcFull, 41 * gTS.select + (WINDOW_WIDTH + 102) / 2, WINDOW_HEIGHT - 86, &rect_cur, 26);
 		}
 	}
 }
@@ -521,7 +522,6 @@
 					else if (gTS.flags & 0x10)
 					{
 						//SAT/CAT/TUR printing
-						x;
 						for (x = gTS.p_read; ; x++)
 						{
 							//Break if reaches command, or new-line
@@ -673,6 +673,14 @@
 						SubArmsData(z);
 						gTS.p_read += 8;
 					}
+					else if (IS_COMMAND('T','A','M'))
+					{
+						x = GetTextScriptNo(gTS.p_read + 4);
+						y = GetTextScriptNo(gTS.p_read + 9);
+						z = GetTextScriptNo(gTS.p_read + 14);
+						TradeArms(x, y, z);
+						gTS.p_read += 18;
+					}
 					else if (IS_COMMAND('P','S','+'))
 					{
 						x = GetTextScriptNo(gTS.p_read + 4);
@@ -943,6 +951,11 @@
 						SetQuake(z);
 						gTS.p_read += 8;
 					}
+					else if (IS_COMMAND('F','L','A'))
+					{
+						SetFlash(0, 0, 2);
+						gTS.p_read += 4;
+					}
 					else if (IS_COMMAND('F','A','I'))
 					{
 						z = GetTextScriptNo(gTS.p_read + 4);
@@ -975,6 +988,13 @@
 						x = GetTextScriptNo(gTS.p_read + 4);
 						y = GetTextScriptNo(gTS.p_read + 9);
 						SetFrameTargetNpChar(x, y);
+						gTS.p_read += 13;
+					}
+					else if (IS_COMMAND('F','O','B'))
+					{
+						x = GetTextScriptNo(gTS.p_read + 4);
+						y = GetTextScriptNo(gTS.p_read + 9);
+						SetFrameTargetBoss(x, y);
 						gTS.p_read += 13;
 					}
 					else if (IS_COMMAND('S','O','U'))
--- a/src/ValueView.cpp
+++ b/src/ValueView.cpp
@@ -21,7 +21,7 @@
 	int i;
 	
 	//TODO: Boi I'm reaaaally boutta getcho pickle chin aah boi, egg head like collard greens head ass boi, ol' hell dat bell dirt aaah boi stank ah boi afro head ass, lip gloss chin ah boi ugly ahhh boi *snort* uglaaaa
-	for (i = 0; i < VALUEVIEW_MAX && (!gVV[i].flag || gVV[i].px != px || (gVV[i].value >= 0 || value >= 0) && (gVV[i].value <= 0 || value <= 0)); i++);
+	for (i = 0; i < VALUEVIEW_MAX && (!gVV[i].flag || gVV[i].px != px || ((gVV[i].value >= 0 || value >= 0) && (gVV[i].value <= 0 || value <= 0))); i++);
 	
 	int index;
 	if (i == VALUEVIEW_MAX)