shithub: cstory

Download patch

ref: 32dd3bef65cce8bb969944253cd5f01300e0697a
parent: 6086cccbe4579cd964a797b57ff0816bc71cd121
parent: 525cf58b7f487af0ba7b4560a707360fa3233e15
author: Cucky <44537737+cuckydev@users.noreply.github.com>
date: Fri Feb 8 11:43:35 EST 2019

Merge pull request #45 from Clownacy/master

More NPCs

--- a/src/Flash.cpp
+++ b/src/Flash.cpp
@@ -1,14 +1,14 @@
-#include "WindowsWrapper.h"
-
 #include "Flash.h"
-#include "Draw.h"
+
 #include "CommonDefines.h"
+#include "Draw.h"
+#include "WindowsWrapper.h"
 
 static struct
 {
 	int mode;
 	int act_no;
-	bool flag;
+	BOOL flag;
 	int cnt;
 	int width;
 	int x;
@@ -27,7 +27,7 @@
 void SetFlash(int x, int y, int mode)
 {
 	flash.act_no = 0;
-	flash.flag = true;
+	flash.flag = TRUE;
 	flash.x = x;
 	flash.y = y;
 	flash.mode = mode;
@@ -37,66 +37,72 @@
 
 void ActFlash_Explosion(int flx, int fly)
 {
-	if (flash.act_no == 0)
+	int left, right, top, bottom;
+
+	switch (flash.act_no)
 	{
-		flash.cnt += 0x200;
-		flash.width += flash.cnt;
+		case 0:
+			flash.cnt += 0x200;
+			flash.width += flash.cnt;
 
-		int right = (flash.x - flx - flash.width) / 0x200;
-		int left = (flash.y - fly - flash.width) / 0x200;
-		int top = (flash.width + flash.x - flx) / 0x200;
-		int bottom = (flash.width + flash.y - fly) / 0x200;
+			right = (flash.x - flx - flash.width) / 0x200;
+			left = (flash.y - fly - flash.width) / 0x200;
+			top = (flash.x - flx + flash.width) / 0x200;
+			bottom = (flash.y - fly + flash.width) / 0x200;
 
-		if (right < 0)
-			right = 0;
-		if (left < 0)
-			left = 0;
-		if (top > WINDOW_WIDTH)
-			top = WINDOW_WIDTH;
-		if (bottom > WINDOW_HEIGHT)
-			bottom = WINDOW_HEIGHT;
+			if (right < 0)
+				right = 0;
+			if (left < 0)
+				left = 0;
+			if (top > WINDOW_WIDTH)
+				top = WINDOW_WIDTH;
+			if (bottom > WINDOW_HEIGHT)
+				bottom = WINDOW_HEIGHT;
 
-		flash.rect1.left = right;
-		flash.rect1.right = top;
-		flash.rect1.top = 0;
-		flash.rect1.bottom = WINDOW_HEIGHT;
+			flash.rect1.left = right;
+			flash.rect1.right = top;
+			flash.rect1.top = 0;
+			flash.rect1.bottom = WINDOW_HEIGHT;
 
-		flash.rect2.left = 0;
-		flash.rect2.right = WINDOW_WIDTH;
-		flash.rect2.top = left;
-		flash.rect2.bottom = bottom;
+			flash.rect2.left = 0;
+			flash.rect2.right = WINDOW_WIDTH;
+			flash.rect2.top = left;
+			flash.rect2.bottom = bottom;
 
-		if (flash.width > (WINDOW_WIDTH << 11))
-		{
-			flash.act_no = 1;
-			flash.cnt = 0;
-			flash.width = (WINDOW_HEIGHT << 9);
-		}
-	}
-	else if (flash.act_no == 1)
-	{
-		flash.width -= flash.width / 8;
+			if (flash.width > (WINDOW_WIDTH << 11))
+			{
+				flash.act_no = 1;
+				flash.cnt = 0;
+				flash.width = (WINDOW_HEIGHT << 9);
+			}
 
-		if ((flash.width / 0x100) == 0)
-			flash.flag = false;
+			break;
 
-		int top = (flash.y - fly - flash.width) / 0x200;
-		if (top < 0)
-			top = 0;
+		case 1:
+			flash.width -= flash.width / 8;
 
-		int bottom = (flash.width + flash.y - fly) / 0x200;
-		if (bottom > WINDOW_HEIGHT)
-			bottom = WINDOW_HEIGHT;
+			if ((flash.width / 0x100) == 0)
+				flash.flag = FALSE;
 
-		flash.rect1.left = 0;
-		flash.rect1.right = 0;
-		flash.rect1.top = 0;
-		flash.rect1.bottom = 0;
+			top = (flash.y - fly - flash.width) / 0x200;
+			if (top < 0)
+				top = 0;
 
-		flash.rect2.top = top;
-		flash.rect2.bottom = bottom;
-		flash.rect2.left = 0;
-		flash.rect2.right = WINDOW_WIDTH;
+			bottom = (flash.y - fly + flash.width) / 0x200;
+			if (bottom > WINDOW_HEIGHT)
+				bottom = WINDOW_HEIGHT;
+
+			flash.rect1.left = 0;
+			flash.rect1.right = 0;
+			flash.rect1.top = 0;
+			flash.rect1.bottom = 0;
+
+			flash.rect2.top = top;
+			flash.rect2.bottom = bottom;
+			flash.rect2.left = 0;
+			flash.rect2.right = WINDOW_WIDTH;
+
+			break;
 	}
 }
 
@@ -125,24 +131,37 @@
 	}
 
 	if (flash.cnt > 20)
-		flash.flag = false;
+		flash.flag = FALSE;
 }
 
 void ActFlash(int flx, int fly)
 {
-	if (flash.flag)
+	if (flash.flag == FALSE)
 	{
-		if (flash.mode == 1)
-			ActFlash_Explosion(flx, fly);
-		else if (flash.mode == 2)
-			ActFlash_Flash();
+		// Do nothing
 	}
+	else
+	{
+		switch (flash.mode)
+		{
+			case 1:
+				ActFlash_Explosion(flx, fly);
+				break;
+			case 2:
+				ActFlash_Flash();
+				break;
+		}
+	}
 }
 
 void PutFlash(void)
 {
-	if (flash.flag)
+	if (flash.flag == FALSE)
 	{
+		// Do nothing
+	}
+	else
+	{
 		CortBox(&flash.rect1, gFlashColor);
 		CortBox(&flash.rect2, gFlashColor);
 	}
@@ -150,5 +169,5 @@
 
 void ResetFlash(void)
 {
-	flash.flag = false;
+	flash.flag = FALSE;
 }
--- a/src/NpcAct.h
+++ b/src/NpcAct.h
@@ -243,15 +243,43 @@
 void ActNpc238(NPCHAR *npc);
 void ActNpc239(NPCHAR *npc);
 void ActNpc240(NPCHAR *npc);
-
+void ActNpc241(NPCHAR *npc);
+void ActNpc242(NPCHAR *npc);
+void ActNpc243(NPCHAR *npc);
+void ActNpc244(NPCHAR *npc);
+void ActNpc245(NPCHAR *npc);
+void ActNpc246(NPCHAR *npc);
+void ActNpc247(NPCHAR *npc);
+void ActNpc248(NPCHAR *npc);
+void ActNpc249(NPCHAR *npc);
+void ActNpc250(NPCHAR *npc);
+void ActNpc251(NPCHAR *npc);
+void ActNpc252(NPCHAR *npc);
+void ActNpc253(NPCHAR *npc);
+void ActNpc254(NPCHAR *npc);
+void ActNpc255(NPCHAR *npc);
+void ActNpc256(NPCHAR *npc);
+void ActNpc257(NPCHAR *npc);
+void ActNpc258(NPCHAR *npc);
 void ActNpc259(NPCHAR *npc);
-
+void ActNpc260(NPCHAR *npc);
+void ActNpc261(NPCHAR *npc);
+void ActNpc262(NPCHAR *npc);
+void ActNpc263(NPCHAR *npc);
+void ActNpc264(NPCHAR *npc);
+void ActNpc265(NPCHAR *npc);
+void ActNpc266(NPCHAR *npc);
+void ActNpc267(NPCHAR *npc);
+void ActNpc268(NPCHAR *npc);
+void ActNpc269(NPCHAR *npc);
+void ActNpc270(NPCHAR *npc);
 void ActNpc271(NPCHAR *npc);
 void ActNpc272(NPCHAR *npc);
 void ActNpc273(NPCHAR *npc);
 void ActNpc274(NPCHAR *npc);
 void ActNpc275(NPCHAR *npc);
-
+void ActNpc276(NPCHAR *npc);
+void ActNpc277(NPCHAR *npc);
 void ActNpc278(NPCHAR *npc);
 
 void ActNpc292(NPCHAR *npc);
--- a/src/NpcAct240.cpp
+++ b/src/NpcAct240.cpp
@@ -8,6 +8,9 @@
 #include "Sound.h"
 #include "Back.h"
 #include "Triangle.h"
+#include "Caret.h"
+#include "Frame.h"
+#include "Map.h"
 
 //Mimiga (jailed)
 void ActNpc240(NPCHAR *npc)
@@ -111,6 +114,1244 @@
 		npc->rect = rcLeft[npc->ani_no];
 	else
 		npc->rect = rcRight[npc->ani_no];
+}
+
+//Critter (Last Cave)
+void ActNpc241(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {0, 0, 16, 16};
+	rcLeft[1] = {16, 0, 32, 16};
+	rcLeft[2] = {32, 0, 48, 16};
+
+	rcRight[0] = {0, 16, 16, 32};
+	rcRight[1] = {16, 16, 32, 32};
+	rcRight[2] = {32, 16, 48, 32};
+
+	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 - 0x12000 && gMC.x < npc->x + 0x12000 && 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 - 0xC000 && gMC.x < npc->x + 0xC000 && gMC.y > npc->y - 0xA000 && gMC.y < npc->y + 0xC000)
+			{
+				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 (npc->direct == 0)
+					npc->xm = -0x200;
+				else
+					npc->xm = 0x200;
+			}
+
+			break;
+
+		case 3:
+			if (npc->flag & 8)
+			{
+				npc->xm = 0;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+				npc->act_no = 1;
+				PlaySoundObject(23, 1);
+			}
+
+			break;
+	}
+
+	npc->ym += 0x55;
+	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];
+}
+
+//Bat (Last Cave)
+void ActNpc242(NPCHAR *npc)
+{
+	if (npc->x < 0 || npc->x > gMap.width * 0x2000)
+	{
+		VanishNpChar(npc);
+		return;
+	}
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->tgt_x = npc->x;
+			npc->tgt_y = npc->y;
+			npc->act_wait = Random(0, 50);
+			// Fallthrough
+		case 1:
+			if (npc->act_wait)
+			{
+				--npc->act_wait;
+				break;
+			}
+
+			npc->act_no = 2;
+			npc->ym = 0x400;
+			// Fallthrough
+		case 2:
+			if (npc->direct == 0)
+				npc->xm = -0x100;
+			else
+				npc->xm = 0x100;
+
+			if (npc->tgt_y < npc->y)
+				npc->ym -= 0x10;
+			if (npc->tgt_y > npc->y)
+				npc->ym += 0x10;
+
+			if (npc->ym > 0x300)
+				npc->ym = 0x300;
+			if (npc->ym < -0x300)
+				npc->ym = -0x300;
+
+			break;
+	}
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	RECT rect_left[4];
+	RECT rect_right[4];
+
+	rect_left[0] = {32, 32, 48, 48};
+	rect_left[1] = {48, 32, 64, 48};
+	rect_left[2] = {64, 32, 80, 48};
+	rect_left[3] = {80, 32, 96, 48};
+
+	rect_right[0] = {32, 48, 48, 64};
+	rect_right[1] = {48, 48, 64, 64};
+	rect_right[2] = {64, 48, 80, 64};
+	rect_right[3] = {80, 48, 96, 64};
+
+	if (++npc->ani_wait > 1)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	if (npc->direct == 0)
+		npc->rect = rect_left[npc->ani_no];
+	else
+		npc->rect = rect_right[npc->ani_no];
+}
+
+//Bat generator (Last Cave)
+void ActNpc243(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->act_wait = Random(0, 500);
+			// Fallthrough
+		case 1:
+			if (npc->act_wait)
+			{
+				--npc->act_wait;
+			}
+			else
+			{
+				npc->act_no = 0;
+				SetNpChar(242, npc->x, npc->y + (Random(-0x20, 0x20) * 0x100), 0, 0, npc->direct, 0, 0x100);
+			}
+
+			break;
+	}
+}
+
+//Lava drop
+void ActNpc244(NPCHAR *npc)
+{
+	RECT rc = {96, 0, 104, 16};
+	npc->ym += 0x40;
+	bool bHit = false;
+
+	if (npc->flag & 0xFF)
+		bHit = true;
+
+	if (npc->act_wait > 10 && npc->flag & 0x100)
+		bHit = true;
+
+	if (bHit)
+	{
+		for (int i = 0; i < 3; ++i)
+			SetCaret(npc->x, npc->y + 0x800, 1, 2);
+
+		if (npc->x > gMC.x - 0x20000 && npc->x < gMC.x + 0x20000 && npc->y > gMC.y - 0x14000 && npc->y < gMC.y + 0x14000)
+			PlaySoundObject(21, 1);
+
+		npc->cond = 0;
+	}
+	else
+	{
+		if (npc->ym > 0x5FF)
+			npc->ym = 0x5FF;
+
+		npc->y += npc->ym;
+
+		npc->rect = rc;
+	}
+}
+
+//Lava drop generator
+void ActNpc245(NPCHAR *npc)
+{
+	RECT rc[4];
+
+	rc[0] = {0, 0, 0, 0};
+	rc[1] = {104, 0, 112, 16};
+	rc[2] = {112, 0, 120, 16};
+	rc[3] = {120, 0, 128, 16};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->tgt_x = npc->x;
+			npc->act_wait = npc->code_event;
+			// Fallthrough
+		case 1:
+			npc->ani_no = 0;
+
+			if ( npc->act_wait )
+			{
+				--npc->act_wait;
+				return;
+			}
+
+			npc->act_no = 10;
+			npc->ani_wait = 0;
+			break;
+
+		case 10:
+			if (++npc->ani_wait > 10)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 3)
+			{
+				npc->ani_no = 0;
+				npc->act_no = 1;
+				npc->act_wait = npc->code_flag;
+				SetNpChar(244, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+			}
+
+			break;
+	}
+
+	if (npc->ani_wait / 2 % 2)
+		npc->x = npc->tgt_x;
+	else
+		npc->x = npc->tgt_x + 0x200;
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Press (proximity)
+void ActNpc246(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+
+	rcLeft[0] = {144, 112, 160, 136};
+	rcLeft[1] = {160, 112, 176, 136};
+	rcLeft[2] = {176, 112, 192, 136};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->y -= 0x800;
+			// Fallthrough
+		case 1:
+			if (gMC.x < npc->x + 0x1000 && gMC.x > npc->x - 0x1000 && gMC.y > npc->y + 0x1000 && gMC.y < npc->y + 0x10000)
+				npc->act_no = 5;
+
+			break;
+
+		case 5:
+			if ((npc->flag & 8) == 0)
+			{
+				npc->act_no = 10;
+				npc->ani_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 10:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 2)
+				npc->ani_no = 2;
+
+			if (gMC.y > npc->y)
+			{
+				npc->bits &= ~0x40;
+				npc->damage = 0x7F;
+			}
+			else
+			{
+				npc->bits |= 0x40;
+				npc->damage = 0;
+			}
+
+			if (npc->flag & 8)
+			{
+				if (npc->ani_no > 1)
+				{
+					for (int i = 0; i < 4; ++i)
+						SetNpChar(4, npc->x, npc->y, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+					PlaySoundObject(26, 1);
+					SetQuake(10);
+				}
+
+				npc->act_no = 20;
+				npc->ani_no = 0;
+				npc->ani_wait = 0;
+				npc->bits |= 0x40;
+				npc->damage = 0;
+			}
+
+			break;
+	}
+
+	if (npc->act_no >= 5)
+	{
+		npc->ym += 0x80;
+		if (npc->ym > 0x5FF)
+			npc->ym = 0x5FF;
+
+		npc->y += npc->ym;
+	}
+
+	npc->rect = rcLeft[npc->ani_no];
+}
+
+//Misery (boss)
+void ActNpc247(NPCHAR *npc)
+{
+	RECT rcLeft[9];
+	RECT rcRight[9];
+
+	rcLeft[0] = {0, 0, 16, 16};
+	rcLeft[1] = {16, 0, 32, 16};
+	rcLeft[2] = {32, 0, 48, 16};
+	rcLeft[3] = {48, 0, 64, 16};
+	rcLeft[4] = {64, 0, 80, 16};
+	rcLeft[5] = {80, 0, 96, 16};
+	rcLeft[6] = {96, 0, 112, 16};
+	rcLeft[7] = {0, 0, 0, 0};
+	rcLeft[8] = {112, 0, 128, 16};
+
+	rcRight[0] = {0, 16, 16, 32};
+	rcRight[1] = {16, 16, 32, 32};
+	rcRight[2] = {32, 16, 48, 32};
+	rcRight[3] = {48, 16, 64, 32};
+	rcRight[4] = {64, 16, 80, 32};
+	rcRight[5] = {80, 16, 96, 32};
+	rcRight[6] = {96, 16, 112, 32};
+	rcRight[7] = {0, 0, 0, 0};
+	rcRight[8] = {112, 16, 128, 32};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->y += 0xC00;
+			npc->tgt_y = 0x8000;
+			// 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 20:
+			npc->xm = 0;
+			npc->ym += 0x40;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 21;
+				npc->ani_no = 2;
+			}
+
+			break;
+
+		case 21:
+			if (Random(0, 120) == 10)
+			{
+				npc->act_no = 22;
+				npc->act_wait = 0;
+				npc->ani_no = 3;
+			}
+
+			break;
+
+		case 22:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 21;
+				npc->ani_no = 2;
+			}
+
+			break;
+
+		case 100:
+			npc->act_no = 101;
+			npc->act_wait = 0;
+			npc->ani_no = 0;
+			npc->xm = 0;
+			npc->bits |= 0x20;
+			npc->count2 = npc->life;
+			// Fallthrough
+		case 101:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (npc->tgt_y > npc->y)
+				npc->ym += 0x20;
+			else
+				npc->ym -= 0x20;
+
+			if (npc->ym < -0x200)
+				npc->ym = -0x200;
+			if (npc->ym > 0x200)
+				npc->ym = 0x200;
+
+			if (++npc->act_wait > 200 || npc->life <= npc->count2 - 80)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 110;
+			}
+
+			break;
+
+		case 110:
+			npc->act_no = 111;
+			npc->act_wait = 0;
+			npc->xm = 0;
+			npc->ym = 0;
+			npc->bits &= ~0x20;
+			// Fallthrough
+		case 111:
+			if (++npc->act_wait % 2)
+				npc->ani_no = 5;
+			else
+				npc->ani_no = 6;
+
+			if (npc->act_wait > 30)
+			{
+				npc->act_wait = 0;
+
+				if (++npc->count1 % 3)
+					npc->act_no = 112;
+				else
+					npc->act_no = 113;
+
+				npc->ani_no = 4;
+			}
+
+			break;
+
+		case 112:
+			if (++npc->act_wait % 6 == 0)
+			{
+				const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y) + Random(-4, 4);
+				const int ym = 4 * GetSin(deg);
+				const int xm = 4 * GetCos(deg);
+				SetNpChar(248, npc->x, npc->y + 0x800, xm, ym, 0, 0, 0x100);
+				PlaySoundObject(34, 1);
+			}
+
+			if (npc->act_wait > 30)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 150;
+			}
+
+			break;
+
+		case 113:
+			if (++npc->act_wait == 10)
+				SetNpChar(279, gMC.x, gMC.y - 0x8000, 0, 0, 1, 0, 0x100);
+
+			if (npc->act_wait > 30)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 150;
+			}
+
+			break;
+
+		case 150:
+			npc->act_no = 151;
+			npc->act_wait = 0;
+			npc->ani_no = 7;
+			SetNpChar(249, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+			SetNpChar(249, npc->x, npc->y, 0, 0, 2, 0, 0x100);
+			npc->tgt_x = Random(9, 31) * 0x2000;
+			npc->tgt_y = Random(5, 7) * 0x2000;
+			PlaySoundObject(29, 1);
+			// Fallthrough
+		case 151:
+			if (++npc->act_wait == 42)
+			{
+				SetNpChar(249, npc->tgt_x + 0x2000, npc->tgt_y, 0, 0, 0, 0, 0x100);
+				SetNpChar(249, npc->tgt_x - 0x2000, npc->tgt_y, 0, 0, 2, 0, 0x100);
+			}
+
+			if (npc->act_wait > 50)
+			{
+				npc->act_wait = 0;
+				npc->ym = -0x200;
+				npc->bits |= 0x20;
+				npc->x = npc->tgt_x;
+				npc->y = npc->tgt_y;
+
+				if (npc->life < 340)
+				{
+					SetNpChar(252, 0, 0, 0, 0, 0, npc, 0x100);
+					SetNpChar(252, 0, 0, 0, 0, 0x80, npc, 0x100);
+				}
+
+				if (npc->life < 180)
+				{
+					SetNpChar(252, 0, 0, 0, 0, 0x40, npc, 0x100);
+					SetNpChar(252, 0, 0, 0, 0, 0xC0, npc, 0x100);
+				}
+
+				if (gMC.x < npc->x - 0xE000 || gMC.x > npc->x + 0xE000)
+					npc->act_no = 160;
+				else
+					npc->act_no = 100;
+			}
+
+			break;
+
+		case 160:
+			npc->act_no = 161;
+			npc->act_wait = 0;
+			npc->ani_no = 4;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+			// Fallthrough
+		case 161:
+			if (npc->tgt_y > npc->y)
+				npc->ym += 0x20;
+			else
+				npc->ym -= 0x20;
+
+			if (npc->ym < -0x200)
+				npc->ym = -0x200;
+			if (npc->ym > 0x200)
+				npc->ym = 0x200;
+
+			if (++npc->act_wait % 24 == 0)
+			{
+				SetNpChar(250, npc->x, npc->y + 0x800, 0, 0, 0, 0, 0x100);
+				PlaySoundObject(34, 1);
+			}
+
+			if (npc->act_wait > 72)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 100;
+			}
+
+			break;
+
+		case 1000:
+			npc->bits &= ~0x20;
+			npc->act_no = 1001;
+			npc->act_wait = 0;
+			npc->ani_no = 4;
+			npc->tgt_x = npc->x;
+			npc->tgt_y = npc->y;
+			npc->xm = 0;
+			npc->ym = 0;
+			DeleteNpCharCode(252, 1);
+			SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+			SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+			SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+			// Fallthrough
+		case 1001:
+			if (++npc->act_wait / 2 % 2)
+				npc->x = npc->tgt_x + 0x200;
+			else
+				npc->x = npc->tgt_x;
+
+			break;
+
+		case 1010:
+			npc->ym += 0x10;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 1020;
+				npc->ani_no = 8;
+			}
+
+			break;
+	}
+
+	if (npc->xm < -0x200)
+		npc->xm = -0x200;
+	if (npc->xm > 0x200)
+		npc->xm = 0x200;
+
+	if (npc->ym < -0x400)
+		npc->ym = -0x400;
+	if (npc->ym > 0x400)
+		npc->ym = 0x400;
+
+	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];
+}
+
+//Boss Misery (vanishing)
+void ActNpc248(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[3];
+
+	rect_left[0] = {0, 48, 16, 64};
+	rect_left[1] = {16, 48, 32, 64};
+	rect_left[2] = {32, 48, 48, 64};
+
+	if (++npc->ani_wait > 1)
+	{
+		npc->ani_wait = 0;
+
+		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);
+	}
+}
+
+//Boss Misery energy shot
+void ActNpc249(NPCHAR *npc)
+{
+	RECT rc[2];
+
+	rc[0] = {48, 48, 64, 64};
+	rc[1] = {64, 48, 80, 64};
+
+	if (++npc->act_wait > 8)
+		npc->cond = 0;
+
+	if (npc->direct == 0)
+	{
+		npc->rect = rc[0];
+		npc->x -= 1024;
+	}
+	else
+	{
+		npc->rect = rc[1];
+		npc->x += 1024;
+	}
+}
+
+//Boss Misery lightning ball
+void ActNpc250(NPCHAR *npc)
+{
+	RECT rc[3];
+
+	rc[0] = {0, 32, 16, 48};
+	rc[1] = {16, 32, 32, 48};
+	rc[2] = {32, 32, 48, 48};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->tgt_y = npc->y;
+			npc->xm = 0;
+			npc->ym = -0x200;
+			// Fallthrough
+		case 1:
+			if (gMC.x > npc->x)
+				npc->xm += 0x10;
+			else
+				npc->xm -= 0x10;
+
+			if (npc->tgt_y > npc->y)
+				npc->ym += 0x20;
+			else
+				npc->ym -= 0x20;
+
+			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->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (gMC.x > npc->x - 0x1000 && gMC.x < npc->x + 0x1000 && gMC.y > npc->y)
+				npc->act_no = 10;
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->act_wait = 0;
+			// Fallthrough
+		case 11:
+			if (++npc->act_wait > 10)
+			{
+				SetNpChar(251, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+				PlaySoundObject(101, 1);
+				npc->cond = 0;
+				return;
+			}
+
+			if (npc->act_wait / 2 % 2)
+				npc->ani_no = 2;
+			else
+				npc->ani_no = 1;
+	}
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Boss Misery lightning
+void ActNpc251(NPCHAR *npc)
+{
+	RECT rc[2];
+
+	rc[0] = {80, 32, 96, 64};
+	rc[1] = {96, 32, 112, 64};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			if (++npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			npc->y += 0x1000;
+
+			if (npc->flag & 0xFF)
+			{
+				SetDestroyNpChar(npc->x, npc->y, npc->view.back, 3);
+				npc->cond = 0;
+			}
+
+			break;
+	}
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Boss Misery bats
+void ActNpc252(NPCHAR *npc)
+{
+	RECT rcLeft[4];
+	RECT rcRight[4];
+
+	rcLeft[0] = {48, 32, 64, 48};
+	rcLeft[1] = {112, 32, 128, 48};
+	rcLeft[2] = {128, 32, 144, 48};
+	rcLeft[3] = {144, 32, 160, 48};
+
+	rcRight[0] = {48, 32, 64, 48};
+	rcRight[1] = {112, 48, 128, 64};
+	rcRight[2] = {128, 48, 144, 64};
+	rcRight[3] = {144, 48, 160, 64};
+
+	unsigned char deg;
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->act_wait = 0;
+			npc->count1 = npc->direct;
+			// Fallthrough
+		case 1:
+			npc->count1 += 2;
+			npc->count1 &= 0xFF;
+
+			deg = npc->count1;
+
+			if ( npc->act_wait < 192 )
+				++npc->act_wait;
+
+			npc->x = npc->pNpc->x + npc->act_wait * GetCos(deg) / 4;
+			npc->y = npc->pNpc->y + npc->act_wait * GetSin(deg) / 4;
+
+			if (npc->pNpc->act_no == 151)
+			{
+				npc->act_no = 10;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->bits |= 0x20;
+			npc->bits &= ~4;
+			npc->bits &= ~8;
+
+			deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y);
+			deg += Random(-3, 3);
+			npc->xm = GetCos(deg);
+			npc->ym = GetSin(deg);
+
+			npc->ani_no = 1;
+			npc->ani_wait = 0;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+			// Fallthrough
+		case 11:
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+
+			if (npc->flag & 0xFF)
+			{
+				SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+				SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+				SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+				npc->cond = 0;
+			}
+
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 3)
+				npc->ani_no = 1;
+
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//EXP capsule
+void ActNpc253(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			break;
+	}
+
+	if (npc->life <= 100)
+	{
+		SetExpObjects(npc->x, npc->y, npc->code_flag);
+		SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8);
+		PlaySoundObject(25, 1);
+		npc->cond = 0;
+	}
+
+	RECT rc[2];
+
+	rc[0] = {0, 64, 16, 80};
+	rc[1] = {16, 64, 32, 80};
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Helicopter
+void ActNpc254(NPCHAR *npc)
+{
+	RECT rc[2];
+
+	rc[0] = {0, 0, 128, 64};
+	rc[1] = {0, 64, 128, 128};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			SetNpChar(255, npc->x + 0x2400, npc->y - 0x7200, 0, 0, 0, npc, 0x100);
+			SetNpChar(255, npc->x - 0x4000, npc->y - 0x6800, 0, 0, 2, npc, 0x100);
+			break;
+		case 20:
+			npc->act_wait = 0;
+			npc->count1 = 60;
+			npc->act_no = 21;
+			break;
+		case 30:
+			npc->act_no = 21;
+			SetNpChar(223, npc->x - 0x1600, npc->y - 0x1C00, 0, 0, 0, 0, 0x100);
+			break;
+		case 40:
+			npc->act_no = 21;
+			SetNpChar(223, npc->x - 0x1200, npc->y - 0x1C00, 0, 0, 0, 0, 0x100);
+			SetNpChar(40, npc->x - 0x2C00, npc->y - 0x1C00, 0, 0, 0, 0, 0x100);
+			SetNpChar(93, npc->x - 0x4600, npc->y - 0x1C00, 0, 0, 0, 0, 0x100);
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rc[0];
+	else
+		npc->rect = rc[1];
+}
+
+//Helicopter blades
+void ActNpc255(NPCHAR *npc)
+{
+	RECT rcLeft[4];
+	RECT rcRight[4];
+
+	rcLeft[0] = {128, 0, 240, 16};
+	rcLeft[1] = {128, 16, 240, 32};
+	rcLeft[2] = {128, 32, 240, 48};
+	rcLeft[3] = {128, 16, 240, 32};
+
+	rcRight[0] = {240, 0, 320, 16};
+	rcRight[1] = {240, 16, 320, 32};
+	rcRight[2] = {240, 32, 320, 48};
+	rcRight[3] = {240, 16, 320, 32};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+
+			if (npc->direct == 0)
+			{
+				npc->view.front = 0x7000;
+				npc->view.back = 0x7000;
+			}
+			else
+			{
+				npc->view.front = 0x5000;
+				npc->view.back = 0x5000;
+			}
+			// Fallthrough
+		case 1:
+			if (npc->pNpc->act_no >= 20)
+				npc->act_no = 10;
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			// Fallthrough
+		case 11:
+			if (++npc->ani_no > 3)
+				npc->ani_no = 0;
+
+			break;
+	}
+
+	if (npc->direct == 0)
+	{
+		npc->x = npc->pNpc->x + 0x2400;
+		npc->y = npc->pNpc->y - 0x7200;
+	}
+	else
+	{
+		npc->x = npc->pNpc->x - 0x4000;
+		npc->y = npc->pNpc->y - 0x6800;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Doctor (facing away)
+void ActNpc256(NPCHAR *npc)
+{
+	RECT rcLeft[6];
+
+	rcLeft[0] = {48, 160, 72, 192};
+	rcLeft[1] = {72, 160, 96, 192};
+	rcLeft[2] = {0, 128, 24, 160};
+	rcLeft[3] = {24, 128, 48, 160};
+	rcLeft[4] = {0, 160, 24, 192};
+	rcLeft[5] = {24, 160, 48, 192};
+
+	switch ( npc->act_no )
+	{
+		case 0:
+			gSuperXpos = 0;
+			npc->act_no = 1;
+			npc->y -= 0x1000;
+			// Fallthrough
+		case 1:
+			npc->ani_no = 0;
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_wait = 0;
+			npc->ani_no = 0;
+			npc->count1 = 0;
+			// Fallthrough
+		case 11:
+			if (++npc->ani_wait > 5)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+			{
+				npc->ani_no = 0;
+				++npc->count1;
+			}
+
+			if (npc->count1 > 5)
+				npc->act_no = 1;
+
+			break;
+
+		case 20:
+			npc->act_no = 21;
+			// Fallthrough
+		case 21:
+			npc->ani_no = 2;
+			break;
+
+		case 40:
+			npc->act_no = 41;
+			SetNpChar(257, npc->x - 0x1C00, npc->y - 0x2000, 0, 0, 0, 0, 0x100);
+			SetNpChar(257, npc->x - 0x1C00, npc->y - 0x2000, 0, 0, 2, 0, 0xAA);
+			// Fallthrough
+		case 41:
+			npc->ani_no = 4;
+			break;
+
+		case 50:
+			npc->act_no = 51;
+			npc->ani_wait = 0;
+			npc->ani_no = 4;
+			npc->count1 = 0;
+			// Fallthrough
+		case 51:
+			if (++npc->ani_wait > 5)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+			{
+				npc->ani_no = 4;
+				++npc->count1;
+			}
+
+			if (npc->count1 > 5)
+				npc->act_no = 41;
+
+			break;
+	}
+
+	npc->rect = rcLeft[npc->ani_no];
+}
+
+//Red crystal
+void ActNpc257(NPCHAR *npc)
+{
+	RECT rc[3];
+
+	rc[0] = {176, 32, 184, 48};
+	rc[1] = {184, 32, 192, 48};
+	rc[2] = {0, 0, 0, 0};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			if (gSuperXpos)
+				npc->act_no = 10;
+
+			break;
+
+		case 10:
+			if (npc->x < gSuperXpos)
+				npc->xm += 0x55;
+			if (npc->x > gSuperXpos)
+				npc->xm -= 0x55;
+
+			if (npc->y < gSuperYpos)
+				npc->ym += 0x55;
+			if (npc->y > gSuperYpos)
+				npc->ym -= 0x55;
+
+			if (npc->xm > 0x400)
+				npc->xm = 0x400;
+			if (npc->xm < -0x400)
+				npc->xm = -0x400;
+
+			if (npc->ym > 0x400)
+				npc->ym = 0x400;
+			if (npc->ym < -0x400)
+				npc->ym = -0x400;
+
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+			break;
+	}
+
+	if (++npc->ani_wait > 3)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 1)
+		npc->ani_no = 0;
+
+	if (npc->direct == 0 && npc->xm > 0)
+		npc->ani_no = 2;
+	if (npc->direct == 2 && npc->xm < 0)
+		npc->ani_no = 2;
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Mimiga (sleeping)
+void ActNpc258(NPCHAR *npc)
+{
+	RECT rc = {48, 32, 64, 48};
+	npc->rect = rc;
 }
 
 //Curly (carried and unconcious)
--- a/src/NpcAct260.cpp
+++ b/src/NpcAct260.cpp
@@ -10,7 +10,1431 @@
 #include "Triangle.h"
 #include "Caret.h"
 #include "Map.h"
+#include "Frame.h"
+#include "MycParam.h"
 
+//Shovel Brigade (caged)
+void ActNpc260(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {128, 64, 144, 80};
+	rcLeft[1] = {144, 64, 160, 80};
+	rcLeft[2] = {224, 64, 240, 80};
+
+	rcRight[0] = {128, 80, 144, 96};
+	rcRight[1] = {144, 80, 160, 96};
+	rcRight[2] = {224, 80, 240, 96};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->x += 0x200;
+			npc->y -= 0x400;
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 1:
+			if (Random(0, 160) == 1)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 12)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 2;
+			SetNpChar(87, npc->x, npc->y - 0x2000, 0, 0, 0, 0, 0x100);
+
+			break;
+	}
+
+	if (gMC.x < npc->x)
+		npc->direct = 0;
+	else
+		npc->direct = 2;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Chie (caged)
+void ActNpc261(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {112, 32, 128, 48};
+	rcLeft[1] = {128, 32, 144, 48};
+
+	rcRight[0] = {112, 48, 128, 64};
+	rcRight[1] = {128, 48, 144, 64};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->x -= 0x200;
+			npc->y -= 0x400;
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 1:
+			if (Random(0, 160) == 1)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 12 )
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	if (gMC.x < npc->x)
+		npc->direct = 0;
+	else
+		npc->direct = 2;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Chaco (caged)
+void ActNpc262(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {128, 0, 144, 16};
+	rcLeft[1] = {144, 0, 160, 16};
+
+	rcRight[0] = {128, 16, 144, 32};
+	rcRight[1] = {144, 16, 160, 32};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->x -= 0x200;
+			npc->y -= 0x400;
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 1:
+			if (Random(0, 160) == 1)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 12)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	if (gMC.x < npc->x)
+		npc->direct = 0;
+	else
+		npc->direct = 2;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Doctor (boss)
+void ActNpc263(NPCHAR *npc)
+{
+	RECT rcLeft[9];
+	RECT rcRight[9];
+
+	rcLeft[0] = {0, 0, 24, 32};
+	rcLeft[1] = {24, 0, 48, 32};
+	rcLeft[2] = {48, 0, 72, 32};
+	rcLeft[3] = {0, 0, 0, 0};
+	rcLeft[4] = {72, 0, 96, 32};
+	rcLeft[5] = {96, 0, 120, 32};
+	rcLeft[6] = {120, 0, 144, 32};
+	rcLeft[7] = {144, 0, 168, 32};
+	rcLeft[8] = {264, 0, 288, 32};
+
+	rcRight[0] = {0, 32, 24, 64};
+	rcRight[1] = {24, 32, 48, 64};
+	rcRight[2] = {48, 32, 72, 64};
+	rcRight[3] = {0, 0, 0, 0};
+	rcRight[4] = {72, 32, 96, 64};
+	rcRight[5] = {96, 32, 120, 64};
+	rcRight[6] = {120, 32, 144, 64};
+	rcRight[7] = {144, 32, 168, 64};
+	rcRight[8] = {264, 32, 288, 64};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->y += 0x1000;
+			npc->ani_no = 3;
+			break;
+
+		case 2:
+			if (++npc->act_wait / 2 & 1)
+				npc->ani_no = 0;
+			else
+				npc->ani_no = 3;
+
+			if (npc->act_wait > 50)
+				npc->act_no = 10;
+
+			break;
+
+		case 10:
+			npc->ym += 0x80;
+			npc->bits |= 0x20;
+			npc->damage = 3;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 20;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+				npc->count2 = npc->life;
+
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			break;
+
+		case 20:
+			if (++npc->act_wait < 50 && npc->life < npc->count2 - 20)
+				npc->act_wait = 50;
+
+			if (npc->act_wait == 50)
+			{
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+
+				npc->ani_no = 4;
+			}
+
+			if (npc->act_wait == 80)
+			{
+				npc->ani_no = 5;
+				PlaySoundObject(25, 1);
+
+				if (npc->direct == 0)
+				{
+					SetNpChar(264, npc->x - 0x2000, npc->y, 0, 0, 0, 0, 0x100);
+					SetNpChar(264, npc->x - 0x2000, npc->y, 0, 0, 0x400, 0, 0x100);
+				}
+				else
+				{
+					SetNpChar(264, npc->x + 0x2000, npc->y, 0, 0, 2, 0, 0x100);
+					SetNpChar(264, npc->x + 0x2000, npc->y, 0, 0, 2 + 0x400, 0, 0x100);
+				}
+			}
+
+			if (npc->act_wait == 120)
+				npc->ani_no = 0;
+
+			if (npc->act_wait > 130 && npc->life < npc->count2 - 50)
+				npc->act_wait = 161;
+
+			if (npc->act_wait > 160)
+			{
+				npc->act_no = 100;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 30:
+			npc->act_no = 31;
+			npc->act_wait = 0;
+			npc->ani_no = 6;
+			npc->tgt_x = npc->x;
+			npc->bits |= 0x20;
+			// Fallthrough
+		case 31:
+			if (++npc->act_wait / 2 & 1)
+				npc->x = npc->tgt_x;
+			else
+				npc->x = npc->tgt_x + 0x200;
+
+			if (npc->act_wait > 50)
+			{
+				npc->act_no = 32;
+				npc->act_wait = 0;
+				npc->ani_no = 7;
+				PlaySoundObject(101, 1);
+
+				for (int deg = 8; deg < 0x100; deg += 0x10)
+				{
+					const int xm = 2 * GetCos(deg);
+					const int ym = 2 * GetSin(deg);
+					SetNpChar(266, npc->x, npc->y, xm, ym, 0, 0, 0x100);
+				}
+			}
+
+			break;
+
+		case 32:
+			if (++npc->act_wait > 50)
+				npc->act_no = 100;
+
+			break;
+
+		case 100:
+			npc->act_no = 101;
+			npc->bits &= ~0x20;
+			npc->damage = 0;
+			npc->act_wait = 0;
+			PlaySoundObject(29, 1);
+			// Fallthrough
+		case 101:
+			npc->act_wait += 2;
+
+			if (npc->act_wait > 16)
+			{
+				npc->act_no = 102;
+				npc->act_wait = 0;
+				npc->ani_no = 3;
+				npc->tgt_x = Random(5, 35) * 0x2000;
+				npc->tgt_y = Random(5, 7) * 0x2000;
+			}
+
+			break;
+
+		case 102:
+			if (++npc->act_wait > 40 )
+			{
+				npc->act_no = 103;
+				npc->act_wait = 16;
+				npc->ani_no = 2;
+				npc->ym = 0;
+				npc->x = npc->tgt_x;
+				npc->y = npc->tgt_y;
+
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			break;
+
+		case 103:
+			npc->act_wait -= 2;
+
+			if ( npc->act_wait <= 0 )
+			{
+				npc->bits |= 0x20;
+				npc->damage = 3;
+
+				if (npc->count1 < 3)
+				{
+					++npc->count1;
+					npc->act_no = 10;
+				}
+				else
+				{
+					npc->count1 = 0;
+					npc->act_no = 30;
+				}
+			}
+
+			break;
+
+		case 500:
+			npc->bits &= ~0x20;
+			npc->ani_no = 6;
+			npc->ym += 0x10;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 501;
+				npc->act_wait = 0;
+				npc->tgt_x = npc->x;
+
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			break;
+
+		case 501:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			npc->ani_no = 8;
+
+			if (++npc->act_wait / 2 & 1)
+				npc->x = npc->tgt_x;
+			else
+				npc->x = npc->tgt_x + 0x200;
+
+			break;
+	}
+
+	if (npc->act_no >= 10)
+	{
+		if (npc->act_no == 102)
+		{
+			gSuperXpos = npc->tgt_x;
+			gSuperYpos = npc->tgt_y;
+		}
+		else
+		{
+			gSuperXpos = npc->x;
+			gSuperYpos = npc->y;
+		}
+	}
+
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+
+	if (npc->act_no == 101 || npc->act_no == 103)
+	{
+		npc->rect.top += npc->act_wait;
+		npc->rect.bottom -= npc->act_wait;
+		npc->view.top = (16 - npc->act_wait) << 9;
+	}
+	else
+	{
+		npc->view.top = 0x2000;
+	}
+}
+
+//Doctor red wave (projectile)
+void ActNpc264(NPCHAR *npc)
+{
+	RECT rc = {288, 0, 304, 16};
+
+	if (npc->x < 0 || npc->x > gMap.width * 0x2000)
+	{
+		VanishNpChar(npc);
+		return;
+	}
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->tgt_x = npc->x;
+			npc->tgt_y = npc->y;
+			npc->count1 = npc->direct / 8;
+			npc->direct &= 7;
+			// Fallthrough
+		case 1:
+			npc->count1 += 6;
+			npc->count1 &= 0xFF;
+			const unsigned char deg = npc->count1;
+
+			if (npc->act_wait < 128)
+				++npc->act_wait;
+
+			if (npc->direct == 0)
+				npc->xm -= 21;
+			else
+				npc->xm += 21;
+
+			npc->tgt_x += npc->xm;
+
+			npc->x = npc->tgt_x + npc->act_wait * GetCos(deg) / 8;
+			npc->y = npc->tgt_y + npc->act_wait * GetSin(deg) / 2;
+
+			SetNpChar(265, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+
+			break;
+	}
+
+	npc->rect = rc;
+}
+
+//Doctor red ball projectile
+void ActNpc265(NPCHAR *npc)
+{
+	RECT rc[3];
+
+	rc[0] = {288, 16, 304, 32};
+	rc[1] = {288, 32, 304, 48};
+	rc[2] = {288, 48, 304, 64};
+
+	if (++npc->ani_wait > 3)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->cond = 0;
+	else
+		npc->rect = rc[npc->ani_no];
+}
+
+//Doctor red ball projectile (bouncing)
+void ActNpc266(NPCHAR *npc)
+{
+	RECT rc[2];
+
+	rc[0] = {304, 16, 320, 32};
+	rc[1] = {304, 32, 320, 48};
+
+	if (npc->flag & 1)
+		npc->xm = -npc->xm;
+	if (npc->flag & 4)
+		npc->xm = -npc->xm;
+
+	if (npc->flag & 2)
+		npc->ym = 0x200;
+	if (npc->flag & 8)
+		npc->ym = -0x200;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	if (++npc->ani_no > 1)
+		npc->ani_no = 0;
+
+	npc->rect = rc[npc->ani_no];
+
+	if (++npc->act_wait % 4 == 1)
+		SetNpChar(265, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+
+	if (npc->act_wait > 250)
+		VanishNpChar(npc);
+}
+
+//Muscle Doctor
+void ActNpc267(NPCHAR *npc)
+{
+	RECT rcLeft[10];
+	RECT rcRight[10];
+
+	rcLeft[0] = {0, 0, 0, 0};
+	rcLeft[1] = {0, 64, 40, 112};
+	rcLeft[2] = {40, 64, 80, 112};
+	rcLeft[3] = {80, 64, 120, 112};
+	rcLeft[4] = {120, 64, 160, 112};
+	rcLeft[5] = {160, 64, 200, 112};
+	rcLeft[6] = {200, 64, 240, 112};
+	rcLeft[7] = {240, 64, 280, 112};
+	rcLeft[8] = {280, 64, 320, 112};
+	rcLeft[9] = {0, 160, 40, 208};
+
+	rcRight[0] = {0, 0, 0, 0};
+	rcRight[1] = {0, 112, 40, 160};
+	rcRight[2] = {40, 112, 80, 160};
+	rcRight[3] = {80, 112, 120, 160};
+	rcRight[4] = {120, 112, 160, 160};
+	rcRight[5] = {160, 112, 200, 160};
+	rcRight[6] = {200, 112, 240, 160};
+	rcRight[7] = {240, 112, 280, 160};
+	rcRight[8] = {280, 112, 320, 160};
+	rcRight[9] = {40, 160, 80, 208};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			if (gMC.x < gSuperXpos)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (npc->direct == 0)
+				npc->x = gSuperXpos - 0xC00;
+			else
+				npc->x = gSuperXpos + 0xC00;
+
+			npc->y = gSuperYpos;
+			// Fallthrough
+		case 1:
+			npc->act_no = 2;
+			// Fallthrough
+		case 2:
+			npc->ym += 0x80;
+
+			if (++npc->act_wait / 2 % 2)
+				npc->ani_no = 0;
+			else
+				npc->ani_no = 3;
+
+			break;
+
+		case 5:
+			npc->act_no = 6;
+			npc->ani_no = 1;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 6:
+			npc->ym += 0x80;
+
+			if (++npc->ani_wait > 40)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 2)
+				npc->ani_no = 1;
+
+			break;
+
+		case 7:
+			npc->act_no = 8;
+			npc->act_wait = 0;
+			npc->ani_no = 3;
+			// Fallthrough
+		case 8:
+			npc->ym += 0x40;
+
+			if (++npc->act_wait > 40)
+				npc->act_no = 10;
+
+			break;
+
+		case 10:
+			npc->bits |= 4;
+			npc->xm = 0;
+			npc->act_no = 11;
+			npc->act_wait = 0;
+			npc->ani_no = 1;
+			npc->ani_wait = 0;
+			npc->count2 = npc->life;
+			// Fallthrough
+		case 11:
+			npc->ym += 0x80;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (npc->flag & 8)
+			{
+				if (npc->life >= npc->count2 - 20)
+				{
+					if (++npc->ani_wait > 10)
+					{
+						npc->ani_wait = 0;
+
+						if (++npc->ani_no > 2)
+							npc->ani_no = 1;
+					}
+				}
+				else if (gMC.flag & 8 && gMC.x > npc->x - 0x6000 && gMC.x < npc->x + 0x6000 && npc->ani_no != 6)
+				{
+					npc->ani_no = 6;
+					DamageMyChar(5);
+					SetQuake(10);
+					PlaySoundObject(26, 1);
+					gMC.ym = -0x400;
+
+					if (gMC.x < npc->x)
+						gMC.xm = -0x5FF;
+					else
+						gMC.xm = 0x5FF;
+
+					for (int i = 0; i < 100; ++i)
+						SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y + (Random(-0x10, 0x10) * 0x200), 3 * Random(-0x200, 0x200), 3 * Random(-0x200, 0x200), 3, 0, 0xAA);
+				}
+			}
+			else
+			{
+				npc->ani_no = 4;
+			}
+
+			if (++npc->act_wait > 30 || npc->life < npc->count2 - 20)
+			{
+				if (++npc->count1 > 10)
+					npc->count1 = 0;
+
+				switch (npc->count1)
+				{
+					case 8:
+						npc->act_no = 20;
+						break;
+					case 2:
+					case 7:
+						npc->act_no = 100;
+						break;
+					case 3:
+					case 6:
+						npc->act_no = 30;
+						break;
+					case 1:
+					case 9:
+						npc->act_no = 40;
+						break;
+					default:
+						npc->act_no = 15;
+						npc->act_wait = 0;
+						break;
+				}
+			}
+
+			break;
+
+		case 15:
+			npc->ani_no = 3;
+			++npc->act_wait;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (npc->act_wait > 20)
+			{
+				npc->act_no = 16;
+				npc->ani_no = 4;
+				npc->ani_wait = 0;
+				npc->ym = -0x600;
+
+				if (npc->direct == 0)
+					npc->xm = -0x400;
+				else
+					npc->xm = 0x400;
+			}
+
+			break;
+
+		case 16:
+			npc->ym += 0x40;
+
+			if (++npc->ani_wait > 1)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 4;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (npc->ym > 0 && npc->flag & 8)
+				npc->act_no = 17;
+
+			break;
+
+		case 17:
+			npc->act_no = 18;
+			npc->act_wait = 0;
+			SetQuake(10);
+			PlaySoundObject(26, 1);
+			// Fallthrough
+		case 18:
+			npc->ani_no = 3;
+			++npc->act_wait;
+
+			npc->xm = 7 * npc->xm / 8;
+			npc->ym += 0x80;
+
+			if (npc->act_wait > 10)
+				npc->act_no = 10;
+
+			break;
+
+		case 20:
+			npc->act_no = 21;
+			npc->act_wait = 0;
+			// Fallthrough
+		case 21:
+			++npc->act_wait;
+			npc->ani_no = 6;
+
+			if (npc->act_wait > 20 && npc->act_wait % 3 == 1)
+			{
+				const int ym = Random(-0x200u, 0x200);
+				const int xm = 4 * Random(0x100, 0x200);
+
+				if (npc->direct == 0)
+					SetNpChar(269, npc->x - 0x1000, npc->y - 0x800, -xm, ym, 0, 0, 0x100);
+				else
+					SetNpChar(269, npc->x + 0x1000, npc->y - 0x800, xm, ym, 2, 0, 0x100);
+
+				PlaySoundObject(39, 1);
+			}
+
+			if ( npc->act_wait > 90 )
+				npc->act_no = 10;
+
+			break;
+
+		case 30:
+			npc->act_no = 31;
+			npc->act_wait = 0;
+			npc->bits |= 1;
+			npc->bits &= ~0x20;
+			// Fallthrough
+		case 31:
+			npc->ani_no = 3;
+
+			if (++npc->act_wait > 20)
+			{
+				npc->act_no = 32;
+				npc->act_wait = 0;
+				npc->ani_no = 7;
+				npc->bits |= 0x80;
+				npc->damage = 10;
+				PlaySoundObject(25, 1);
+
+				if (npc->direct == 0)
+					npc->xm = -0x5FF;
+				else
+					npc->xm = 0x5FF;
+			}
+
+			break;
+
+		case 32:
+			++npc->act_wait;
+			npc->ym = 0;
+
+			if (npc->act_wait / 2 % 2)
+				npc->ani_no = 7;
+			else
+				npc->ani_no = 8;
+
+			if (npc->act_wait > 30)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 18;
+				npc->damage = 5;
+				npc->bits &= ~0x81;
+				npc->bits |= 0x20;
+			}
+
+			if (npc->flag & 1 || npc->flag & 4)
+			{
+				npc->act_no = 15;
+				npc->act_wait = 0;
+				npc->damage = 5;
+				npc->bits &= ~0x81;
+				npc->bits |= 0x20;
+			}
+
+			break;
+
+		case 40:
+			npc->ani_no = 3;
+			++npc->act_wait;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (npc->act_wait > 20)
+			{
+				npc->act_no = 41;
+				npc->ani_no = 4;
+				npc->ani_wait = 0;
+				npc->ym = -0x800;
+
+				if (npc->direct == 0)
+					npc->xm = -0x400;
+				else
+					npc->xm = 0x400;
+			}
+
+			break;
+
+		case 41:
+			npc->ym += 0x40;
+
+			if (++npc->ani_wait > 1)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 4;
+
+			if (gMC.y > npc->y && gMC.x > npc->x - 0x1000 && gMC.x < npc->x + 0x1000)
+			{
+				npc->act_no = 16;
+				npc->ym = 0x5FF;
+				npc->xm = 0;
+			}
+
+			if (npc->ym > 0 && npc->flag & 8)
+				npc->act_no = 17;
+
+			break;
+
+		case 100:
+			npc->act_no = 101;
+			npc->act_wait = 0;
+			npc->bits &= ~0x24;
+			npc->damage = 0;
+			PlaySoundObject(29, 1);
+			// Fallthrough
+		case 101:
+			npc->act_wait += 2;
+
+			if (npc->act_wait > 28)
+			{
+				npc->act_no = 102;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+
+				npc->tgt_x = gMC.x;
+				npc->tgt_y = gMC.y - 0x4000;
+
+				if ( npc->tgt_y < 0x8000 )
+					npc->tgt_y = 0x8000;
+
+				if ( npc->tgt_x < 0x8000 )
+					npc->tgt_x = 0x8000;
+				if ( npc->tgt_x > 0x48000 )
+					npc->tgt_x = 0x48000;
+			}
+
+			break;
+
+		case 102:
+			if (++npc->act_wait > 40)
+			{
+				npc->act_no = 103;
+				npc->act_wait = 28;
+				npc->ani_no = 4;
+				npc->ym = 0;
+				npc->x = npc->tgt_x;
+				npc->y = npc->tgt_y;
+
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			break;
+
+		case 103:
+			npc->act_wait -= 2;
+
+			if (npc->act_wait <= 0)
+			{
+				npc->bits |= 0x24;
+				npc->damage = 5;
+				npc->act_no = 16;
+				npc->ym = -0x200;
+				npc->xm = 0;
+			}
+
+			break;
+
+		case 500:
+			DeleteNpCharCode(269, 1);
+			npc->bits &= ~0x20;
+			npc->ani_no = 4;
+			npc->ym += 0x20;
+			npc->xm = 0;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 501;
+				npc->act_wait = 0;
+				npc->tgt_x = npc->x;
+
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			break;
+
+		case 501:
+			npc->ani_no = 9;
+
+			if (++npc->act_wait / 2 % 2)
+				npc->x = npc->tgt_x;
+			else
+				npc->x = npc->tgt_x + 0x200;
+
+			break;
+
+		case 510:
+			npc->act_no = 511;
+			npc->act_wait = 0;
+			npc->ani_no = 9;
+			npc->tgt_x = npc->x;
+			npc->y += 0x2000;
+			npc->bits |= 8;
+			// Fallthrough
+		case 511:
+			SetQuake(2);
+
+			if (++npc->act_wait % 6 == 3)
+				PlaySoundObject(25, 1);
+
+			if (npc->act_wait / 2 % 2)
+				npc->x = npc->tgt_x;
+			else
+				npc->x = npc->tgt_x + 0x200;
+
+			if (npc->act_wait > 352)
+			{
+				npc->ani_no = 0;
+				npc->act_no = 0x200;
+			}
+
+			break;
+
+		case 520:
+			npc->damage = 0;
+			gSuperYpos = -0x4000;
+			break;
+	}
+
+	if (npc->act_no >= 11 && npc->act_no < 501)
+	{
+		if (npc->act_no == 102)
+		{
+			gSuperXpos = npc->tgt_x;
+			gSuperYpos = npc->tgt_y;
+		}
+		else
+		{
+			gSuperXpos = npc->x;
+			gSuperYpos = npc->y;
+		}
+	}
+
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	if (npc->act_no < 512)
+	{
+		if (npc->act_no >= 510)
+		{
+			SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - (((336 - npc->act_wait) / 8) * 0x200), Random(-0x200, 0x200), 2 * Random(-0x200, 0), 3, 0, 0xAA);
+			SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), Random(-0x200, 0x200), 2 * Random(-0x200, 0), 3, 0, 0xAA);
+			SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), 0, 2 * Random(-0x200, 0), 3, 0, 0xAA);
+			SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), 0, 2 * Random(-0x200, 0), 3, 0, 0xAA);
+		}
+		else if (npc->act_no != 102 && npc->act_no != 103 && Random(0, 3) == 2)
+		{
+			SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y + (Random(-8, 4) * 0x200), npc->xm, 0, 3, 0, 0x100);
+		}
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+
+	if (npc->act_no == 511)
+	{
+		npc->rect.top += npc->act_wait / 8;
+		npc->view.top = (44 - npc->act_wait / 8) * 0x200;
+		npc->view.bottom = 0x800;
+	}
+	else if (npc->act_no == 101 || npc->act_no == 103)
+	{
+		npc->rect.top += npc->act_wait;
+		npc->rect.bottom -= npc->act_wait;
+		npc->view.top = (28 - npc->act_wait) * 0x200;
+	}
+	else
+	{
+		npc->view.top = 0x3800;
+	}
+}
+
+//Igor (enemy)
+void ActNpc268(NPCHAR *npc)
+{
+	RECT rcLeft[10];
+	RECT rcRight[10];
+
+	rcLeft[0] = {0, 0, 40, 40};
+	rcLeft[1] = {40, 0, 80, 40};
+	rcLeft[2] = {80, 0, 120, 40};
+	rcLeft[3] = {0, 0, 40, 40};
+	rcLeft[4] = {120, 0, 160, 40};
+	rcLeft[5] = {0, 0, 40, 40};
+	rcLeft[6] = {40, 80, 80, 120};
+	rcLeft[7] = {0, 80, 40, 120};
+	rcLeft[8] = {240, 0, 280, 40};
+	rcLeft[9] = {280, 0, 320, 40};
+
+	rcRight[0] = {0, 40, 40, 80};
+	rcRight[1] = {40, 40, 80, 80};
+	rcRight[2] = {80, 40, 120, 80};
+	rcRight[3] = {0, 40, 40, 80};
+	rcRight[4] = {120, 40, 160, 80};
+	rcRight[5] = {0, 40, 40, 80};
+	rcRight[6] = {160, 80, 200, 120};
+	rcRight[7] = {120, 80, 160, 120};
+	rcRight[8] = {240, 40, 280, 80};
+	rcRight[9] = {280, 40, 320, 80};
+
+	if (npc->x < gMC.x - 0x28000 || npc->x > gMC.x + 0x28000 || npc->y < gMC.y - 0x1E000 || npc->y > gMC.y + 0x1E000)
+		npc->act_no = 1;
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->y += 0x1000;
+			// Fallthrough
+		case 1:
+			if (++npc->ani_wait > 20)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (npc->x < gMC.x + 0xE000 && npc->x > gMC.x - 0xE000 && npc->x < gMC.x + 0x6000 && npc->x > gMC.x - 0xE000)
+				npc->act_no = 10;
+
+			if (npc->shock)
+				npc->act_no = 10;
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->act_wait = 0;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+			// Fallthrough
+		case 11:
+			if (npc->direct == 0)
+				npc->xm = -0x200;
+			else
+				npc->xm = 0x200;
+
+			if (npc->x < gMC.x + 0x8000 && npc->x > gMC.x - 0x8000)
+			{
+				npc->act_no = 20;
+				npc->act_wait = 0;
+			}
+
+			if (npc->xm < 0 && npc->flag & 1)
+			{
+				npc->act_no = 20;
+				npc->act_wait = 0;
+			}
+
+			if (npc->xm > 0 && npc->flag & 4)
+			{
+				npc->act_no = 20;
+				npc->act_wait = 0;
+			}
+
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 2;
+
+			break;
+
+		case 20:
+			npc->xm = 0;
+			npc->ani_no = 6;
+
+			if (++npc->act_wait > 10)
+			{
+				npc->act_no = 30;
+				npc->ym = -0x5FF;
+
+				if (npc->direct == 0)
+					npc->xm = -0x200;
+				else
+					npc->xm = 0x200;
+
+				PlaySoundObject(108, 1);
+			}
+
+			break;
+
+		case 30:
+			npc->ani_no = 7;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 40;
+				npc->act_wait = 0;
+				SetQuake(20);
+				PlaySoundObject(26, 1);
+			}
+
+			break;
+
+		case 40:
+			npc->xm = 0;
+			npc->ani_no = 6;
+
+			if (++npc->act_wait > 30)
+				npc->act_no = 50;
+
+			break;
+
+		case 50:
+			npc->act_no = 51;
+			npc->act_wait = 0;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+			// Fallthrough
+		case 51:
+			if (++npc->act_wait > 30 && npc->act_wait % 4 == 1)
+			{
+				unsigned char deg;
+
+				if (npc->direct == 0)
+					deg = -120;
+				else
+					deg = -8;
+
+				deg += Random(-0x10, 0x10);
+				const int ym = 5 * GetSin(deg);
+				const int xm = 5 * GetCos(deg);
+				SetNpChar(11, npc->x, npc->y + 0x800, xm, ym, 0, 0, 0x100);
+				PlaySoundObject(12, 1);
+			}
+
+			if (npc->act_wait < 50 && npc->act_wait / 2 % 2)
+				npc->ani_no = 9;
+			else
+				npc->ani_no = 8;
+
+			if (npc->act_wait > 82)
+			{
+				npc->act_no = 10;
+
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			break;
+	}
+
+	npc->ym += 0x33;
+	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];
+}
+
+//Red Bat (bouncing)
+void ActNpc269(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {232, 0, 248, 16};
+	rcLeft[1] = {248, 0, 264, 16};
+	rcLeft[2] = {248, 16, 264, 32};
+
+	rcRight[0] = {232, 32, 248, 48};
+	rcRight[1] = {248, 32, 264, 48};
+	rcRight[2] = {248, 48, 264, 64};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->xm2 = npc->xm;
+			npc->ym2 = npc->ym;
+			// Fallthrough
+		case 1:
+			if (npc->xm2 < 0 && npc->flag & 1)
+			{
+				npc->direct = 2;
+				npc->xm2 = -npc->xm2;
+			}
+			else if (npc->xm2 > 0 && npc->flag & 4)
+			{
+				npc->direct = 0;
+				npc->xm2 = -npc->xm2;
+			}
+			else if (npc->ym2 < 0 && npc->flag & 2)
+			{
+				npc->ym2 = -npc->ym2;
+			}
+			else if (npc->ym2 > 0 && npc->flag & 8)
+			{
+				npc->ym2 = -npc->ym2;
+			}
+
+			npc->x += npc->xm2;
+			npc->y += npc->ym2;
+
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 2)
+				npc->ani_no = 0;
+
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Doctor's blood (or """"red energy"""")
+void ActNpc270(NPCHAR *npc)
+{
+	RECT rc[2];
+
+	rc[0] = {170, 34, 174, 38};
+	rc[1] = {170, 42, 174, 46};
+
+	if (npc->direct == 3 || npc->direct == 1)
+	{
+		if (npc->direct == 3)
+			npc->ym += 0x40;
+		if (npc->direct == 1)
+			npc->ym -= 0x40;
+
+		++npc->act_wait;
+
+		if (npc->ym > 0x5FF)
+			npc->ym = 0x5FF;
+
+		npc->x += npc->xm;
+		npc->y += npc->ym;
+
+		if (npc->act_wait > 50)
+			npc->cond = 0;
+
+		if (npc->flag & 0xFF)
+			npc->cond = 0;
+	}
+	else if ( npc->direct == 2 )
+	{
+		if (npc->act_no == 0)
+		{
+			npc->act_no = 1;
+			npc->bits |= 8;
+
+			npc->xm = 3 * Random(-0x200, 0x200);
+			npc->ym = 3 * Random(-0x200, 0x200);
+
+			npc->count1 = Random(0x10, 0x33);
+			npc->count2 = Random(0x80, 0x100);
+		}
+
+		if (npc->x < npc->pNpc->x)
+			npc->xm += 0x200 / npc->count1;
+		if (npc->x > npc->pNpc->x)
+			npc->xm -= 0x200 / npc->count1;
+
+		if (npc->y < npc->pNpc->y)
+			npc->ym += 0x200 / npc->count1;
+		if (npc->y > npc->pNpc->y)
+			npc->ym -= 0x200 / npc->count1;
+
+		if (npc->xm > 2 * npc->count2)
+			npc->xm = 2 * npc->count2;
+		if (npc->xm < -2 * npc->count2)
+			npc->xm = -2 * npc->count2;
+
+		if (npc->ym > 3 * npc->count2)
+			npc->ym = 3 * npc->count2;
+		if (npc->ym < -3 * npc->count2)
+			npc->ym = -3 * npc->count2;
+
+		npc->x += npc->xm;
+		npc->y += npc->ym;
+	}
+
+	npc->rect = rc[Random(0, 1)];
+}
+
 // Ironhead block
 void ActNpc271(NPCHAR *npc)
 {
@@ -326,6 +1750,244 @@
 	npc->y += npc->ym;
 
 	npc->rect = rcRight[npc->ani_no];
+}
+
+//Red Demon
+void ActNpc276(NPCHAR *npc)
+{
+	RECT rcLeft[9];
+	RECT rcRight[9];
+
+	rcLeft[0] = {0, 64, 32, 104};
+	rcLeft[1] = {32, 64, 64, 104};
+	rcLeft[2] = {64, 64, 96, 104};
+	rcLeft[3] = {96, 64, 128, 104};
+	rcLeft[4] = {128, 64, 160, 104};
+	rcLeft[5] = {160, 64, 192, 104};
+	rcLeft[6] = {192, 64, 224, 104};
+	rcLeft[7] = {224, 64, 256, 104};
+	rcLeft[8] = {256, 64, 288, 104};
+
+	rcRight[0] = {0, 104, 32, 144};
+	rcRight[1] = {32, 104, 64, 144};
+	rcRight[2] = {64, 104, 96, 144};
+	rcRight[3] = {96, 104, 128, 144};
+	rcRight[4] = {128, 104, 160, 144};
+	rcRight[5] = {160, 104, 192, 144};
+	rcRight[6] = {192, 104, 224, 144};
+	rcRight[7] = {224, 104, 256, 144};
+	rcRight[8] = {256, 104, 288, 144};
+
+	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 > 20)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (npc->shock)
+				npc->act_no = 10;
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->act_wait = 0;
+			npc->ani_no = 3;
+			npc->bits |= 0x20u;
+			// Fallthrough
+		case 11:
+			switch (++npc->act_wait)
+			{
+				case 30:
+				case 40:
+				case 50:
+				{
+					npc->ani_no = 4;
+					const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y);
+					const int ym = 4 * GetSin(deg);
+					const int xm = 4 * GetCos(deg);
+					SetNpChar(277, npc->x, npc->y, xm, ym, 0, 0, 0x100);
+					PlaySoundObject(39, 1);
+					break;
+				}
+				case 34:
+				case 44:
+				case 54:
+				{
+					npc->ani_no = 3;
+					break;
+				}
+			}
+
+			if (npc->act_wait > 60)
+			{
+				npc->act_no = 20;
+				npc->act_wait = 0;
+				npc->ani_no = 2;
+			}
+
+			break;
+
+		case 20:
+			if (++npc->act_wait > 20)
+			{
+				npc->act_no = 21;
+				npc->act_wait = 0;
+				npc->ani_no = 5;
+				npc->ym = -0x5FF;
+				if (gMC.x > npc->x)
+					npc->xm = 0x100;
+				else
+					npc->xm = -0x100;
+			}
+
+			break;
+
+		case 21:
+			switch (++npc->act_wait)
+			{
+				case 30:
+				case 40:
+				case 50:
+				{
+					npc->ani_no = 6;
+					const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - 0x1400 - gMC.y);
+					const int ym = 4 * GetSin(deg);
+					const int xm = 4 * GetCos(deg);
+					SetNpChar(277, npc->x, npc->y - 0x1400, xm, ym, 0, 0, 0x100);
+					PlaySoundObject(39, 1);
+					break;
+				}
+				case 34:
+				case 44:
+				{
+					npc->ani_no = 5;
+					break;
+				}
+			}
+
+			if (npc->act_wait > 53)
+				npc->ani_no = 7;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 22;
+				npc->act_wait = 0;
+				npc->ani_no = 2;
+				SetQuake(10);
+				PlaySoundObject(26, 1);
+			}
+
+			break;
+
+		case 22:
+			npc->xm /= 2;
+
+			if (++npc->act_wait > 22)
+				npc->act_no = 10;
+
+			break;
+
+		case 50:
+			npc->bits &= ~0x20;
+			npc->damage = 0;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 51;
+				npc->ani_no = 2;
+				SetQuake(10);
+				SetExpObjects(npc->x, npc->y, 19);
+				SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8);
+				PlaySoundObject(72, 1);
+			}
+
+			break;
+
+		case 51:
+			npc->xm = 7 * npc->xm / 8;
+			npc->ani_no = 8;
+			break;
+	}
+
+	npc->ym += 0x20;
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	if (npc->act_no < 50)
+	{
+		if (gMC.x > npc->x)
+			npc->direct = 2;
+		else
+			npc->direct = 0;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Red Demon projectile
+void ActNpc277(NPCHAR *npc)
+{
+	RECT rc[3];
+
+	rc[0] = {128, 0, 152, 24};
+	rc[1] = {152, 0, 176, 24};
+	rc[2] = {176, 0, 200, 24};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+
+			if (npc->flag & 0xFF)
+			{
+				SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+				SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+				SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+				VanishNpChar(npc);
+				return;
+			}
+
+			if (++npc->act_wait % 5 == 0)
+				PlaySoundObject(110, 1);
+
+			if (++npc->ani_no > 2)
+				npc->ani_no = 0;
+
+			break;
+	}
+
+	npc->rect = rc[npc->ani_no];
 }
 
 //Little family
--- a/src/NpcTbl.cpp
+++ b/src/NpcTbl.cpp
@@ -297,43 +297,43 @@
 	ActNpc238,
 	ActNpc239,
 	ActNpc240,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc241,
+	ActNpc242,
+	ActNpc243,
+	ActNpc244,
+	ActNpc245,
+	ActNpc246,
+	ActNpc247,
+	ActNpc248,
+	ActNpc249,
+	ActNpc250,
+	ActNpc251,
+	ActNpc252,
+	ActNpc253,
+	ActNpc254,
+	ActNpc255,
+	ActNpc256,
+	ActNpc257,
+	ActNpc258,
 	ActNpc259,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc260,
+	ActNpc261,
+	ActNpc262,
+	ActNpc263,
+	ActNpc264,
+	ActNpc265,
+	ActNpc266,
+	ActNpc267,
+	ActNpc268,
+	ActNpc269,
+	ActNpc270,
 	ActNpc271,
 	ActNpc272,
 	ActNpc273,
 	ActNpc274,
 	ActNpc275,
-	nullptr,
-	nullptr,
+	ActNpc276,
+	ActNpc277,
 	ActNpc278,
 	nullptr,
 	nullptr,
--- a/src/WindowsWrapper.h
+++ b/src/WindowsWrapper.h
@@ -1,4 +1,15 @@
 #pragma once
+
+typedef int BOOL;
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
 struct RECT
 {
 	union