shithub: cstory

Download patch

ref: bae577365293ba8e86d55875e9570c0772ff4c5d
parent: b92d6b4e99b639f69653cc70e54fa8eba11e598d
parent: 025a30fd41c7a4fe5d5f5000ce6a0245c0129a16
author: Cucky <44537737+cuckydev@users.noreply.github.com>
date: Tue Feb 5 11:51:07 EST 2019

Merge pull request #40 from Clownacy/master

Lotsa NPCs, and added the remaining bullet types

--- a/Makefile
+++ b/Makefile
@@ -42,6 +42,7 @@
 	ArmsItem \
 	Back \
 	Boss \
+	BossFrog \
 	BossLife \
 	BossOhm \
 	BulHit \
@@ -76,6 +77,7 @@
 	NpcAct100 \
 	NpcAct120 \
 	NpcAct140 \
+	NpcAct180 \
 	NpcAct200 \
 	NpcAct260 \
 	NpcAct280 \
--- a/src/ArmsItem.cpp
+++ b/src/ArmsItem.cpp
@@ -9,6 +9,7 @@
 #include "Sound.h"
 #include "Main.h"
 #include "Game.h"
+#include "Shoot.h"
 
 int gArmsEnergyX = 16;
 
@@ -457,7 +458,7 @@
 	if (!arms_num)
 		return 0;
 	
-	//ResetSpurCharge();
+	ResetSpurCharge();
 	
 	++gSelectedArms;
 	while (gSelectedArms < arms_num && !gArmsData[gSelectedArms].code)
@@ -479,7 +480,7 @@
 	if (!arms_num)
 		return 0;
 	
-	//ResetSpurCharge();
+	ResetSpurCharge();
 	
 	if (--gSelectedArms < 0)
 		gSelectedArms = arms_num - 1;
--- a/src/Boss.cpp
+++ b/src/Boss.cpp
@@ -4,6 +4,7 @@
 #include "WindowsWrapper.h"
 
 #include "Boss.h"
+#include "BossFrog.h"
 #include "BossOhm.h"
 #include "NpChar.h"
 #include "MyChar.h"
@@ -184,16 +185,16 @@
 
 BOSSFUNCTION gpBossFuncTbl[10] =
 {
-	&ActBossChar_0,
-	&ActBossChar_Omega,
-	nullptr, //&ActBossChar_Frog,
-	nullptr, //&ActBossChar_MonstX,
-	nullptr, //&ActBossChar_Core,
-	nullptr, //&ActBossChar_Ironhead,
-	nullptr, //&ActBossChar_Twin,
-	nullptr, //&ActBossChar_Undead,
-	nullptr, //&ActBossChar_Press,
-	nullptr, //&ActBossChar_Ballos
+	ActBossChar_0,
+	ActBossChar_Omega,
+	ActBossChar_Frog,
+	nullptr, //ActBossChar_MonstX,
+	nullptr, //ActBossChar_Core,
+	nullptr, //ActBossChar_Ironhead,
+	nullptr, //ActBossChar_Twin,
+	nullptr, //ActBossChar_Undead,
+	nullptr, //ActBossChar_Press,
+	nullptr, //ActBossChar_Ballos
 };
 
 void ActBossChar()
--- /dev/null
+++ b/src/BossFrog.cpp
@@ -1,0 +1,525 @@
+#include "BossFrog.h"
+
+#include "Boss.h"
+#include "Frame.h"
+#include "Game.h"
+#include "MyChar.h"
+#include "NpChar.h"
+#include "Sound.h"
+#include "Triangle.h"
+#include "WindowsWrapper.h"
+
+static void ActBossChar02_01(void)
+{
+	int minus;
+
+	if (gBoss[0].direct == 0)
+		minus = 1;
+	else
+		minus = -1;
+
+	switch (gBoss[0].ani_no)
+	{
+		case 0:
+			gBoss[1].hit_voice = 52;
+			gBoss[1].hit.front = 0x2000;
+			gBoss[1].hit.top = 0x2000;
+			gBoss[1].hit.back = 0x2000;
+			gBoss[1].hit.bottom = 0x2000;
+			gBoss[1].size = 3;
+			gBoss[1].bits = 4;
+			break;
+
+		case 1:
+			gBoss[1].x = gBoss[0].x + -0x3000 * minus;
+			gBoss[1].y = gBoss[0].y - 0x3000;
+			break;
+
+		case 2:
+			gBoss[1].x = gBoss[0].x + -0x3000 * minus;
+			gBoss[1].y = gBoss[0].y - 0x2800;
+			break;
+
+		case 3:
+		case 4:
+			gBoss[1].x = gBoss[0].x + -0x3000 * minus;
+			gBoss[1].y = gBoss[0].y - 0x2000;
+			break;
+
+		case 5:
+			gBoss[1].x = gBoss[0].x + -0x3000 * minus;
+			gBoss[1].y = gBoss[0].y - 0x5600;
+			break;
+	}
+}
+
+static void ActBossChar02_02(void)
+{
+	if (gBoss[0].ani_no)
+	{
+		if (gBoss[0].ani_no > 0 && gBoss[0].ani_no <= 5)
+		{
+			gBoss[2].x = gBoss[0].x;
+			gBoss[2].y = gBoss[0].y;
+		}
+	}
+	else
+	{
+		gBoss[2].hit_voice = 52;
+		gBoss[2].hit.front = 0x3000;
+		gBoss[2].hit.top = 0x2000;
+		gBoss[2].hit.back = 0x3000;
+		gBoss[2].hit.bottom = 0x2000;
+		gBoss[2].size = 3;
+		gBoss[2].bits = 4;
+	}
+}
+
+void ActBossChar_Frog(void)
+{
+	RECT rcLeft[9];
+	RECT rcRight[9];
+
+	rcLeft[0] = {0, 0, 0, 0};
+	rcLeft[1] = {0, 48, 80, 112};
+	rcLeft[2] = {0, 112, 80, 176};
+	rcLeft[3] = {0, 176, 80, 240};
+	rcLeft[4] = {160, 48, 240, 112};
+	rcLeft[5] = {160, 112, 240, 200};
+	rcLeft[6] = {200, 0, 240, 24};
+	rcLeft[7] = {80, 0, 120, 24};
+	rcLeft[8] = {120, 0, 160, 24};
+
+	rcRight[0] = {0, 0, 0, 0};
+	rcRight[1] = {80, 48, 160, 112};
+	rcRight[2] = {80, 112, 160, 176};
+	rcRight[3] = {80, 176, 160, 240};
+	rcRight[4] = {240, 48, 320, 112};
+	rcRight[5] = {240, 112, 320, 200};
+	rcRight[6] = {200, 24, 240, 48};
+	rcRight[7] = {80, 24, 120, 48};
+	rcRight[8] = {120, 24, 160, 48};
+
+	switch (gBoss[0].act_no)
+	{
+		case 0:
+			gBoss->x = 0xC000;
+			gBoss->y = 0x19000;
+			gBoss->direct = 2;
+			gBoss->view.front = 0x6000;
+			gBoss->view.top = 0x6000;
+			gBoss->view.back = 0x4000;
+			gBoss->view.bottom = 0x2000;
+			gBoss->hit_voice = 52;
+			gBoss->hit.front = 0x3000;
+			gBoss->hit.top = 0x2000;
+			gBoss->hit.back = 0x3000;
+			gBoss->hit.bottom = 0x2000;
+			gBoss->size = 3;
+			gBoss->exp = 1;
+			gBoss->code_event = 1000;
+			gBoss->bits |= 0x8200;
+			gBoss->life = 300;
+			break;
+
+		case 10:
+			gBoss->act_no = 11;
+			gBoss->ani_no = 3;
+			gBoss->cond = 0x80;
+			gBoss->rect = rcRight[0];
+			gBoss[1].cond = -112;
+			gBoss[1].code_event = 1000;
+			gBoss[2].cond = 0x80;
+			gBoss[1].damage = 5;
+			gBoss[2].damage = 5;
+
+			for (int i = 0; i < 8; ++i)
+				SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+			break;
+
+		case 20:
+			gBoss->act_no = 21;
+			gBoss->act_wait = 0;
+			// Fallthrough
+		case 21:
+			if (++gBoss->act_wait / 2 % 2)
+				gBoss->ani_no = 3;
+			else
+				gBoss->ani_no = 0;
+
+			break;
+
+		case 100:
+			gBoss->act_no = 101;
+			gBoss->act_wait = 0;
+			gBoss->ani_no = 1;
+			gBoss->xm = 0;
+			// Fallthrough
+		case 101:
+			if (++gBoss->act_wait > 50)
+			{
+				gBoss->act_no = 102;
+				gBoss->ani_wait = 0;
+				gBoss->ani_no = 2;
+			}
+
+			break;
+
+		case 102:
+			if (++gBoss->ani_wait > 10)
+			{
+				gBoss->act_no = 103;
+				gBoss->ani_wait = 0;
+				gBoss->ani_no = 1;
+			}
+
+			break;
+
+		case 103:
+			if (++gBoss->ani_wait > 4)
+			{
+				gBoss->act_no = 104;
+				gBoss->ani_no = 5;
+				gBoss->ym = -0x400;
+				PlaySoundObject(25, 1);
+
+				if (gBoss->direct == 0)
+					gBoss->xm = -0x200u;
+				else
+					gBoss->xm = 0x200;
+
+				gBoss->view.top = 0x8000;
+				gBoss->view.bottom = 0x3000;
+			}
+
+			break;
+
+		case 104:
+			if (gBoss->direct == 0 && gBoss->flag & 1)
+			{
+				gBoss->direct = 2;
+				gBoss->xm = 0x200;
+			}
+
+			if (gBoss->direct == 2 && gBoss->flag & 4)
+			{
+				gBoss->direct = 0;
+				gBoss->xm = -0x200;
+			}
+
+			if (gBoss->flag & 8)
+			{
+				PlaySoundObject(26, 1);
+				SetQuake(30);
+				gBoss->act_no = 100;
+				gBoss->ani_no = 1;
+				gBoss->view.top = 0x6000;
+				gBoss->view.bottom = 0x2000;
+
+				if (gBoss->direct == 0 && gBoss->x < gMC.x)
+				{
+					gBoss->direct = 2;
+					gBoss->act_no = 110;
+				}
+
+				if (gBoss->direct == 2 && gBoss->x > gMC.x)
+				{
+					gBoss->direct = 0;
+					gBoss->act_no = 110;
+				}
+
+				SetNpChar(110, Random(4, 16) * 0x2000, Random(0, 4) * 0x2000, 0, 0, 4, 0, 0x80);
+
+				for (int i = 0; i < 4; ++i)
+					SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + gBoss->hit.bottom, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+			}
+
+			break;
+
+		case 110:
+			gBoss->ani_no = 1;
+			gBoss->act_wait = 0;
+			gBoss->act_no = 111;
+			// Fallthrough
+		case 111:
+			++gBoss->act_wait;
+			gBoss->xm = 8 * gBoss->xm / 9;
+
+			if (gBoss->act_wait > 50)
+			{
+				gBoss->ani_no = 2;
+				gBoss->ani_wait = 0;
+				gBoss->act_no = 112;
+			}
+
+			break;
+
+		case 112:
+			if (++gBoss->ani_wait > 4)
+			{
+				gBoss->act_no = 113;
+				gBoss->act_wait = 0;
+				gBoss->ani_no = 3;
+				gBoss->count1 = 16;
+				gBoss[1].bits |= 0x20;
+				gBoss->tgt_x = gBoss->life;
+			}
+
+			break;
+
+		case 113:
+			if (gBoss->shock)
+			{
+				if (gBoss->count2++ / 2 % 2)
+					gBoss->ani_no = 4;
+				else
+					gBoss->ani_no = 3;
+			}
+			else
+			{
+				gBoss->count2 = 0;
+				gBoss->ani_no = 3;
+			}
+
+			gBoss->xm = 10 * gBoss->xm / 11;
+
+			if (++gBoss->act_wait > 16)
+			{
+				gBoss->act_wait = 0;
+				--gBoss->count1;
+
+				unsigned char deg;
+
+				if (gBoss->direct == 0)
+					deg = GetArktan(gBoss->x - 0x4000 - gMC.x, gBoss->y - 0x1000 - gMC.y);
+				else
+					deg = GetArktan(gBoss->x + 0x4000 - gMC.x, gBoss->y - 0x1000 - gMC.y);
+
+				deg += Random(-16, 16);
+
+				int ym = GetSin(deg);
+				int xm = GetCos(deg);
+
+				if (gBoss->direct == 0)
+					SetNpChar(108, gBoss->x - 0x4000, gBoss->y - 0x1000, xm, ym, 0, 0, 0x100);
+				else
+					SetNpChar(108, gBoss->x + 0x4000, gBoss->y - 0x1000, xm, ym, 0, 0, 0x100);
+
+				PlaySoundObject(39, 1);
+
+				if (gBoss->count1 == 0 || gBoss->life < gBoss->tgt_x - 90)
+				{
+					gBoss->act_no = 114;
+					gBoss->act_wait = 0;
+					gBoss->ani_no = 2;
+					gBoss->ani_wait = 0;
+					gBoss[1].bits &= ~0x20;
+				}
+			}
+
+			break;
+
+		case 114:
+			if (++gBoss->ani_wait > 10)
+			{
+				if (++gBoss[1].count1 > 2)
+				{
+					gBoss[1].count1 = 0;
+					gBoss->act_no = 120;
+				}
+				else
+				{
+					gBoss->act_no = 100;
+				}
+
+				gBoss->ani_wait = 0;
+				gBoss->ani_no = 1;
+			}
+
+			break;
+
+		case 120:
+			gBoss->act_no = 121;
+			gBoss->act_wait = 0;
+			gBoss->ani_no = 1;
+			gBoss->xm = 0;
+			// Fallthrough
+		case 121:
+			if (++gBoss->act_wait > 50)
+			{
+				gBoss->act_no = 122;
+				gBoss->ani_wait = 0;
+				gBoss->ani_no = 2;
+			}
+
+			break;
+
+		case 122:
+			if (++gBoss->ani_wait > 20)
+			{
+				gBoss->act_no = 123;
+				gBoss->ani_wait = 0;
+				gBoss->ani_no = 1;
+			}
+
+			break;
+
+		case 123:
+			if (++gBoss->ani_wait > 4)
+			{
+				gBoss->act_no = 124;
+				gBoss->ani_no = 5;
+				gBoss->ym = -0xA00;
+				gBoss->view.top = 0x8000;
+				gBoss->view.bottom = 0x3000;
+				PlaySoundObject(25, 1);
+			}
+
+			break;
+
+		case 124:
+			if (gBoss->flag & 8)
+			{
+				PlaySoundObject(26, 1);
+				SetQuake(60);
+				gBoss->act_no = 100;
+				gBoss->ani_no = 1;
+				gBoss->view.top = 0x6000;
+				gBoss->view.bottom = 0x2000;
+
+				for (int i = 0; i < 2; ++i)
+					SetNpChar(104, Random(4, 16) * 0x2000, Random(0, 4) * 0x2000, 0, 0, 4, 0, 0x80);
+
+				for (int i = 0; i < 6; ++i)
+					SetNpChar(110, Random(4, 16) * 0x2000, Random(0, 4) * 0x2000, 0, 0, 4, 0, 0x80);
+
+				for (int i = 0; i < 8; ++i)
+					SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + gBoss->hit.bottom, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+				if (gBoss->direct == 0 && gMC.x > gBoss->x)
+				{
+					gBoss->direct = 2;
+					gBoss->act_no = 110;
+				}
+
+				if ( gBoss->direct == 2 && gMC.x < gBoss->x)
+				{
+					gBoss->direct = 0;
+					gBoss->act_no = 110;
+				}
+			}
+
+			break;
+
+		case 130:
+			gBoss->act_no = 131;
+			gBoss->ani_no = 3;
+			gBoss->act_wait = 0;
+			gBoss->xm = 0;
+			PlaySoundObject(72, 1);
+
+			for (int i = 0; i < 8; ++i)
+				SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+			gBoss[1].cond = 0;
+			gBoss[2].cond = 0;
+			// Fallthrough
+		case 131:
+			if (++gBoss->act_wait % 5 == 0)
+				SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+			if (gBoss->act_wait / 2 % 2)
+				gBoss->x -= 0x200;
+			else
+				gBoss->x += 0x200;
+
+			if (gBoss->act_wait > 100)
+			{
+				gBoss->act_wait = 0;
+				gBoss->act_no = 132;
+			}
+
+			break;
+
+		case 132:
+			if (++gBoss->act_wait / 2 % 2)
+			{
+				gBoss->view.front = 0x2800;
+				gBoss->view.top = 0x1800;
+				gBoss->view.back = 0x2800;
+				gBoss->view.bottom = 0x1800;
+				gBoss->ani_no = 6;
+			}
+			else
+			{
+				gBoss->view.front = 0x6000;
+				gBoss->view.top = 0x6000;
+				gBoss->view.back = 0x4000;
+				gBoss->view.bottom = 0x2000;
+				gBoss->ani_no = 3;
+			}
+
+			if (gBoss->act_wait % 9 == 0)
+				SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+			if (gBoss->act_wait > 150)
+			{
+				gBoss->act_no = 140;
+				gBoss->hit.bottom = 0x1800;
+			}
+
+			break;
+
+		case 140:
+			gBoss->act_no = 141;
+			// Fallthrough
+		case 141:
+			if (gBoss->flag & 8)
+			{
+				gBoss->act_no = 142;
+				gBoss->act_wait = 0;
+				gBoss->ani_no = 7;
+			}
+
+			break;
+
+		case 142:
+			if (++gBoss->act_wait > 30)
+			{
+				gBoss->ani_no = 8;
+				gBoss->ym = -0xA00;
+				gBoss->bits |= 8;
+				gBoss->act_no = 143;
+			}
+
+			break;
+
+		case 143:
+			gBoss->ym = -0xA00;
+
+			if (gBoss->y < 0)
+			{
+				gBoss->cond = 0;
+				PlaySoundObject(26, 1);
+				SetQuake(30);
+			}
+
+			break;
+	}
+
+	gBoss->ym += 0x40;
+	if (gBoss->ym > 0x5FF)
+		gBoss->ym = 0x5FF;
+
+	gBoss->x += gBoss->xm;
+	gBoss->y += gBoss->ym;
+
+	if (gBoss->direct == 0)
+		gBoss->rect = rcLeft[gBoss->ani_no];
+	else
+		gBoss->rect = rcRight[gBoss->ani_no];
+
+	ActBossChar02_01();
+	ActBossChar02_02();
+}
--- /dev/null
+++ b/src/BossFrog.h
@@ -1,0 +1,3 @@
+#pragma once
+
+void ActBossChar_Frog(void);
--- a/src/Bullet.cpp
+++ b/src/Bullet.cpp
@@ -5,6 +5,7 @@
 #include "MyChar.h"
 #include "Sound.h"
 #include "Game.h"
+#include "KeyControl.h"
 
 BULLET_TABLE gBulTbl[46] =
 {
@@ -168,6 +169,198 @@
 	}
 }
 
+void ActBullet_Frontia1(BULLET *bul)
+{
+	if (++bul->count1 > bul->life_count)
+	{
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 3, 0);
+	}
+	else
+	{
+		if (bul->act_no)
+		{
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
+		else
+		{
+			bul->ani_no = Random(0, 2);
+			bul->act_no = 1;
+
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm = -0x600;
+					break;
+				case 1:
+					bul->ym = -0x600;
+					break;
+				case 2:
+					bul->xm = 0x600;
+					break;
+				case 3:
+					bul->ym = 0x600;
+					break;
+			}
+		}
+
+		if (++bul->ani_wait > 0)
+		{
+			bul->ani_wait = 0;
+			++bul->ani_no;
+		}
+
+		if (bul->ani_no > 3)
+			bul->ani_no = 0;
+
+		RECT rcLeft[4];
+		RECT rcRight[4];
+
+		rcLeft[0] = {136, 80, 152, 80};
+		rcLeft[1] = {120, 80, 136, 96};
+		rcLeft[2] = {136, 64, 152, 80};
+		rcLeft[3] = {120, 64, 136, 80};
+
+		rcRight[0] = {120, 64, 136, 80};
+		rcRight[1] = {136, 64, 152, 80};
+		rcRight[2] = {120, 80, 136, 96};
+		rcRight[3] = {136, 80, 152, 80};
+
+		if (bul->direct == 0)
+			bul->rect = rcLeft[bul->ani_no];
+		else
+			bul->rect = rcRight[bul->ani_no];
+	}
+}
+
+void ActBullet_Frontia2(BULLET *bul, int level)
+{
+	if (++bul->count1 > bul->life_count)
+	{
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 3, 0);
+	}
+	else
+	{
+		if (bul->act_no)
+		{
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm -= 0x80;
+					break;
+				case 1:
+					bul->ym -= 0x80;
+					break;
+				case 2:
+					bul->xm += 0x80;
+					break;
+				case 3:
+					bul->ym += 0x80;
+					break;
+			}
+
+			switch (bul->direct)
+			{
+				case 0:
+				case 2:
+					if (bul->count1 % 5 == 2)
+					{
+						if (bul->ym < 0)
+							bul->ym = 0x400;
+						else
+							bul->ym = -0x400;
+					}
+
+					break;
+
+				case 1u:
+				case 3u:
+					if (bul->count1 % 5 == 2)
+					{
+						if (bul->xm < 0)
+							bul->xm = 0x400;
+						else
+							bul->xm = -0x400u;
+					}
+
+					break;
+			}
+
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
+		else
+		{
+			bul->ani_no = Random(0, 2);
+			bul->act_no = 1;
+
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm = -0x200;
+					break;
+				case 1:
+					bul->ym = -0x200;
+					break;
+				case 2:
+					bul->xm = 0x200;
+					break;
+				case 3:
+					bul->ym = 0x200;
+					break;
+			}
+
+			static unsigned int inc;
+			++inc;
+
+			switch (bul->direct)
+			{
+				case 0:
+				case 2:
+					if (inc % 2)
+						bul->ym = 0x400;
+					else
+						bul->ym = -0x400;
+
+					break;
+
+				case 1:
+				case 3:
+					if (inc % 2)
+						bul->xm = -0x400;
+					else
+						bul->xm = 0x400;
+
+					break;
+			}
+		}
+
+		if ( ++bul->ani_wait > 0 )
+		{
+			bul->ani_wait = 0;
+			++bul->ani_no;
+		}
+
+		if ( bul->ani_no > 2 )
+			bul->ani_no = 0;
+
+		RECT rect[3];
+
+		rect[0] = {192, 16, 208, 32};
+		rect[1] = {208, 16, 224, 32};
+		rect[2] = {224, 16, 240, 32};
+
+		bul->rect = rect[bul->ani_no];
+
+		if (level == 2)
+			SetNpChar(129, bul->x, bul->y, 0, -0x200, bul->ani_no, 0, 0x100);
+		else
+			SetNpChar(129, bul->x, bul->y, 0, -0x200, bul->ani_no + 3, 0, 0x100);
+	}
+}
+
 void ActBullet_PoleStar(BULLET *bul, int level)
 {
 	if (++bul->count1 <= bul->life_count)
@@ -765,6 +958,657 @@
 		bul->cond = 0;
 }
 
+void ActBullet_Bubblin1(BULLET *bul)
+{
+	if (bul->flag & 0x2FF)
+	{
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 2, 0);
+	}
+	else
+	{
+		if (bul->act_no == 0)
+		{
+			bul->act_no = 1;
+
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm = -0x600;
+					break;
+				case 2:
+					bul->xm = 0x600;
+					break;
+				case 1:
+					bul->ym = -0x600;
+					break;
+				case 3:
+					bul->ym = 0x600;
+					break;
+			}
+		}
+
+		switch (bul->direct)
+		{
+			case 0:
+				bul->xm += 42;
+				break;
+			case 2:
+				bul->xm -= 42;
+				break;
+			case 1:
+				bul->ym += 42;
+				break;
+			case 3:
+				bul->ym -= 42;
+				break;
+		}
+
+		bul->x += bul->xm;
+		bul->y += bul->ym;
+
+		if (++bul->act_wait > 40)
+		{
+			bul->cond = 0;
+			SetCaret(bul->x, bul->y, 15, 0);
+		}
+
+		RECT rect[4];
+
+		rect[0] = {192, 0, 200, 8};
+		rect[1] = {200, 0, 208, 8};
+		rect[2] = {208, 0, 216, 8};
+		rect[3] = {216, 0, 224, 8};
+
+		if (++bul->ani_wait > 3)
+		{
+			bul->ani_wait = 0;
+			++bul->ani_no;
+		}
+
+		if (bul->ani_no > 3)
+			bul->ani_no = 3;
+
+		bul->rect = rect[bul->ani_no];
+	}
+}
+
+void ActBullet_Bubblin2(BULLET *bul)
+{
+	bool bDelete = false;
+
+	if (bul->direct == 0 && bul->flag & 1)
+		bDelete = true;
+	if (bul->direct == 2 && bul->flag & 4)
+		bDelete = true;
+	if (bul->direct == 1 && bul->flag & 2)
+		bDelete = true;
+	if (bul->direct == 3 && bul->flag & 8)
+		bDelete = true;
+
+	if (bDelete)
+	{
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 2, 0);
+	}
+	else
+	{
+		if (bul->act_no == 0)
+		{
+			bul->act_no = 1;
+
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm = -0x600;
+					bul->ym = Random(-0x100, 0x100);
+					break;
+				case 2:
+					bul->xm = 0x600;
+					bul->ym = Random(-0x100, 0x100);
+					break;
+				case 1:
+					bul->ym = -0x600;
+					bul->xm = Random(-0x100, 0x100);
+					break;
+				case 3:
+					bul->ym = 0x600;
+					bul->xm = Random(-0x100, 0x100);
+					break;
+			}
+		}
+
+		switch (bul->direct)
+		{
+			case 0:
+				bul->xm += 0x10;
+				break;
+			case 2:
+				bul->xm -= 0x10;
+				break;
+			case 1:
+				bul->ym += 0x10;
+				break;
+			case 3:
+				bul->ym -= 0x10;
+				break;
+		}
+
+		bul->x += bul->xm;
+		bul->y += bul->ym;
+
+		if (++bul->act_wait > 60)
+		{
+			bul->cond = 0;
+			SetCaret(bul->x, bul->y, 15, 0);
+		}
+
+		RECT rect[4];
+
+		rect[0] = {192, 8, 200, 16};
+		rect[1] = {200, 8, 208, 16};
+		rect[2] = {208, 8, 216, 16};
+		rect[3] = {216, 8, 224, 16};
+
+		if (++bul->ani_wait > 3)
+		{
+			bul->ani_wait = 0;
+			++bul->ani_no;
+		}
+
+		if (bul->ani_no > 3)
+			bul->ani_no = 3;
+
+		bul->rect = rect[bul->ani_no];
+	}
+}
+
+void ActBullet_Bubblin3(BULLET *bul)
+{
+	if (++bul->act_wait <= 100 && gKey & gKeyShot)
+	{
+		if (bul->act_no == 0)
+		{
+			bul->act_no = 1;
+
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm = Random(-0x400, -0x200);
+					bul->ym = (Random(-4, 4) * 0x200) / 2;
+					break;
+				case 2u:
+					bul->xm = Random(0x200, 0x400);
+					bul->ym = (Random(-4, 4) * 0x200) / 2;
+					break;
+				case 1u:
+					bul->ym = Random(-0x400, -0x200);
+					bul->xm = (Random(-4, 4) * 0x200) / 2;
+					break;
+				case 3u:
+					bul->ym = Random(0x80, 0x100);
+					bul->xm = (Random(-4, 4) * 0x200) / 2;
+					break;
+			}
+		}
+
+		if (gMC.x > bul->x)
+			bul->xm += 0x20;
+		if (gMC.x < bul->x)
+			bul->xm -= 0x20;
+
+		if (gMC.y > bul->y)
+			bul->ym += 0x20;
+		if (gMC.y < bul->y)
+			bul->ym -= 0x20;
+
+		if (bul->xm < 0 && bul->flag & 1)
+			bul->xm = 0x400;
+		if (bul->xm > 0 && bul->flag & 4)
+			bul->xm = -0x400;
+
+		if (bul->ym < 0 && bul->flag & 2)
+			bul->ym = 0x400;
+		if (bul->ym > 0 && bul->flag & 8)
+			bul->ym = -0x400;
+
+		bul->x += bul->xm;
+		bul->y += bul->ym;
+
+		RECT rect[4];
+
+		rect[0] = {240, 16, 248, 24};
+		rect[1] = {248, 16, 256, 24};
+		rect[2] = {240, 24, 248, 32};
+		rect[3] = {248, 24, 256, 32};
+
+		if (++bul->ani_wait > 3)
+		{
+			bul->ani_wait = 0;
+			++bul->ani_no;
+		}
+
+		if (bul->ani_no > 3)
+			bul->ani_no = 3;
+
+		bul->rect = rect[bul->ani_no];
+	}
+	else
+	{
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 2, 0);
+		PlaySoundObject(100, 1);
+
+		if (gMC.up)
+			SetBullet(22, bul->x, bul->y, 1);
+		else if (gMC.down)
+			SetBullet(22, bul->x, bul->y, 3);
+		else
+			SetBullet(22, bul->x, bul->y, gMC.direct);
+	}
+}
+
+void ActBullet_Spine(BULLET *bul)
+{
+	if (++bul->count1 > bul->life_count || bul->flag & 8)
+	{
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 3, 0);
+	}
+	else
+	{
+		if (bul->act_no)
+		{
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
+		else
+		{
+			bul->act_no = 1;
+
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm = (-0x200 * Random(10, 16)) / 2;
+					break;
+				case 1:
+					bul->ym = (-0x200 * Random(10, 16)) / 2;
+					break;
+				case 2:
+					bul->xm = (Random(10, 16) * 0x200) / 2;
+					break;
+				case 3:
+					bul->ym = (Random(10, 16) * 0x200) / 2;
+					break;
+			}
+		}
+
+		if (++bul->ani_wait > 1)
+		{
+			bul->ani_wait = 0;
+			++bul->ani_no;
+		}
+
+		if (bul->ani_no > 1)
+			bul->ani_no = 0;
+
+		RECT rcLeft[2];
+		RECT rcRight[2];
+		RECT rcDown[2];
+
+		rcLeft[0] = {224, 0, 232, 8};
+		rcLeft[1] = {232, 0, 240, 8};
+
+		rcRight[0] = {224, 0, 232, 8};
+		rcRight[1] = {232, 0, 240, 8};
+
+		rcDown[0] = {224, 8, 232, 16};
+		rcDown[1] = {232, 8, 240, 16};
+
+		switch (bul->direct)
+		{
+			case 0:
+				bul->rect = rcLeft[bul->ani_no];
+				break;
+			case 1:
+				bul->rect = rcDown[bul->ani_no];
+				break;
+			case 2:
+				bul->rect = rcRight[bul->ani_no];
+				break;
+			case 3:
+				bul->rect = rcDown[bul->ani_no];
+				break;
+		}
+	}
+}
+
+void ActBullet_Sword1(BULLET *bul)
+{
+	if (++bul->count1 > bul->life_count)
+	{
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 3, 0);
+	}
+	else
+	{
+		if (bul->count1 == 3)
+			bul->bbits &= ~4;
+
+		if (bul->count1 % 5 == 1)
+			PlaySoundObject(34, 1);
+
+		if (bul->act_no)
+		{
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
+		else
+		{
+			bul->act_no = 1;
+
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm = -0x800;
+					break;
+				case 1:
+					bul->ym = -0x800;
+					break;
+				case 2:
+					bul->xm = 0x800;
+					break;
+				case 3:
+					bul->ym = 0x800;
+					break;
+			}
+		}
+
+		RECT rcLeft[4];
+		RECT rcRight[4];
+
+		rcLeft[0] = {0, 48, 16, 64};
+		rcLeft[1] = {16, 48, 32, 64};
+		rcLeft[2] = {32, 48, 48, 64};
+		rcLeft[3] = {48, 48, 64, 64};
+
+		rcRight[0] = {64, 48, 80, 64};
+		rcRight[1] = {80, 48, 96, 64};
+		rcRight[2] = {96, 48, 112, 64};
+		rcRight[3] = {112, 48, 128, 64};
+
+		if (++bul->ani_wait > 1)
+		{
+			bul->ani_wait = 0;
+			++bul->ani_no;
+		}
+
+		if (bul->ani_no > 3)
+			bul->ani_no = 0;
+
+		if (bul->direct == 0)
+			bul->rect = rcLeft[bul->ani_no];
+		else
+			bul->rect = rcRight[bul->ani_no];
+	}
+}
+
+void ActBullet_Sword2(BULLET *bul)
+{
+	if (++bul->count1 > bul->life_count)
+	{
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 3, 0);
+	}
+	else
+	{
+		if (bul->count1 == 3)
+			bul->bbits &= ~4;
+
+		if (bul->count1 % 7 == 1)
+			PlaySoundObject(106, 1);
+
+		if (bul->act_no)
+		{
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
+		else
+		{
+			bul->act_no = 1;
+
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm = -0x800;
+					break;
+				case 1:
+					bul->ym = -0x800;
+					break;
+				case 2:
+					bul->xm = 0x800;
+					break;
+				case 3:
+					bul->ym = 0x800;
+					break;
+			}
+		}
+
+		RECT rcLeft[4];
+		RECT rcRight[4];
+
+		rcLeft[0] = {160, 48, 184, 72};
+		rcLeft[1] = {184, 48, 208, 72};
+		rcLeft[2] = {208, 48, 232, 72};
+		rcLeft[3] = {232, 48, 256, 72};
+
+		rcRight[0] = {160, 72, 184, 96};
+		rcRight[1] = {184, 72, 208, 96};
+		rcRight[2] = {208, 72, 232, 96};
+		rcRight[3] = {232, 72, 256, 96};
+
+		if (++bul->ani_wait > 1)
+		{
+			bul->ani_wait = 0;
+			++bul->ani_no;
+		}
+
+		if (bul->ani_no > 3)
+			bul->ani_no = 0;
+
+		if (bul->direct == 0)
+			bul->rect = rcLeft[bul->ani_no];
+		else
+			bul->rect = rcRight[bul->ani_no];
+	}
+}
+
+void ActBullet_Sword3(BULLET *bul)
+{
+	RECT rcLeft[2];
+	RECT rcUp[2];
+	RECT rcDown[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {272, 0, 296, 24};
+	rcLeft[1] = {296, 0, 320, 24};
+
+	rcUp[0] = {272, 48, 296, 72};
+	rcUp[1] = {296, 0, 320, 24};
+
+	rcRight[0] = {272, 24, 296, 48};
+	rcRight[1] = {296, 24, 320, 48};
+
+	rcDown[0] = {296, 48, 320, 72};
+	rcDown[1] = {296, 24, 320, 48};
+
+	switch (bul->act_no)
+	{
+		case 0:
+			bul->act_no = 1;
+			bul->xm = 0;
+			bul->ym = 0;
+			// Fallthrough
+		case 1:
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm = -0x800;
+					break;
+				case 1:
+					bul->ym = -0x800;
+					break;
+				case 2:
+					bul->xm = 0x800;
+					break;
+				case 3:
+					bul->ym = 0x800;
+					break;
+			}
+
+			if (bul->life != 100)
+			{
+				bul->act_no = 2;
+				bul->ani_no = 1;
+				bul->damage = -1;
+				bul->act_wait = 0;
+			}
+
+			if (++bul->act_wait % 4 == 1)
+			{
+				PlaySoundObject(106, 1);
+
+				if (++bul->count1 % 2)
+					SetBullet(23, bul->x, bul->y, 0);
+				else
+					SetBullet(23, bul->x, bul->y, 2);
+			}
+
+			if ( ++bul->count1 == 5 )
+				bul->bbits &= ~4u;
+
+			if (bul->count1 > bul->life_count)
+			{
+				bul->cond = 0;
+				SetCaret(bul->x, bul->y, 3, 0);
+				return;
+			}
+
+			break;
+
+		case 2:
+			bul->xm = 0;
+			bul->ym = 0;
+			++bul->act_wait;
+
+			if (Random(-1, 1) == 0)
+			{
+				PlaySoundObject(106, 1);
+
+				if (Random(0, 1) % 2)
+					SetBullet(23, bul->x + (Random(-0x40, 0x40) * 0x200), bul->y + (Random(-0x40, 0x40) * 0x200), 0);
+				else
+					SetBullet(23, bul->x + (Random(-0x40, 0x40) * 0x200), bul->y + (Random(-0x40, 0x40) * 0x200), 2);
+			}
+
+			if (bul->act_wait > 50)
+				bul->cond = 0;
+	}
+
+	bul->x += bul->xm;
+	bul->y += bul->ym;
+
+	switch (bul->direct)
+	{
+		case 0:
+			bul->rect = rcLeft[bul->ani_no];
+			break;
+		case 1:
+			bul->rect = rcUp[bul->ani_no];
+			break;
+		case 2:
+			bul->rect = rcRight[bul->ani_no];
+			break;
+		case 3:
+			bul->rect = rcDown[bul->ani_no];
+			break;
+	}
+
+	if (bul->act_wait % 2)
+		bul->rect.right = 0;
+}
+
+void ActBullet_Edge(BULLET *bul)
+{
+	RECT rcLeft[5];
+	RECT rcRight[5];
+
+	switch (bul->act_no)
+	{
+		case 0:
+			bul->act_no = 1;
+			bul->y -= 0x1800;
+
+			if (bul->direct == 0)
+				bul->x += 0x2000;
+			else
+				bul->x -= 0x2000;
+			// Fallthrough
+		case 1:
+			if (++bul->ani_wait > 2)
+			{
+				bul->ani_wait = 0;
+				++bul->ani_no;
+			}
+
+			if (bul->direct == 0)
+				bul->x -= 0x400;
+			else
+				bul->x += 0x400;
+
+			bul->y += 0x400;
+
+			if (bul->ani_no == 1)
+				bul->damage = 2;
+			else
+				bul->damage = 1;
+
+			if (bul->ani_no > 4)
+				bul->cond = 0;
+
+			break;
+	}
+
+	rcLeft[0] = {0, 64, 24, 88};
+	rcLeft[1] = {24, 64, 48, 88};
+	rcLeft[2] = {48, 64, 72, 88};
+	rcLeft[3] = {72, 64, 96, 88};
+	rcLeft[4] = {96, 64, 120, 88};
+
+	rcRight[0] = {0, 88, 24, 112};
+	rcRight[1] = {24, 88, 48, 112};
+	rcRight[2] = {48, 88, 72, 112};
+	rcRight[3] = {72, 88, 96, 112};
+	rcRight[4] = {96, 88, 120, 112};
+
+	if (bul->direct == 0)
+		bul->rect = rcLeft[bul->ani_no];
+	else
+		bul->rect = rcRight[bul->ani_no];
+}
+
+void ActBullet_Drop(BULLET *bul)
+{
+	RECT rc[1];
+
+	rc[0] = {0, 0, 0, 0};
+
+	if (++bul->act_wait > 2)
+		bul->cond = 0;
+
+	bul->rect = rc[0];
+}
+
 void ActBullet_SuperMissile(BULLET *bul, int level)
 {
 	if (++bul->count1 > bul->life_count)
@@ -1018,6 +1862,313 @@
 	}
 }
 
+void ActBullet_Nemesis(BULLET *bul, int level)
+{
+	if (++bul->count1 > bul->life_count)
+	{
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 3, 0);
+	}
+	else
+	{
+		if (bul->act_no)
+		{
+			if (level == 1 && bul->count1 % 4 == 1)
+			{
+				switch (bul->direct)
+				{
+					case 0:
+						SetNpChar(4, bul->x, bul->y, -0x200, Random(-0x200, 0x200), 2, 0, 0x100);
+						break;
+					case 1:
+						SetNpChar(4, bul->x, bul->y, Random(-0x200, 0x200), -0x200, 2, 0, 0x100);
+						break;
+					case 2:
+						SetNpChar(4, bul->x, bul->y, 0x200, Random(-0x200, 0x200), 2, 0, 0x100);
+						break;
+					case 3:
+						SetNpChar(4, bul->x, bul->y, Random(-0x200, 0x200), 0x200, 2, 0, 0x100);
+						break;
+				}
+			}
+
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
+		else
+		{
+			bul->act_no = 1;
+			bul->count1 = 0;
+
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm = -0x1000;
+					break;
+				case 1:
+					bul->ym = -0x1000;
+					break;
+				case 2:
+					bul->xm = 0x1000;
+					break;
+				case 3:
+					bul->ym = 0x1000;
+					break;
+			}
+
+			if (level == 3)
+			{
+				bul->xm /= 3;
+				bul->ym /= 3;
+			}
+		}
+
+		if (++bul->ani_no > 1)
+			bul->ani_no = 0;
+
+		RECT rcL[2];
+		RECT rcU[2];
+		RECT rcR[2];
+		RECT rcD[2];
+
+		rcL[0] = {0, 112, 32, 128};
+		rcL[1] = {0, 128, 32, 144};
+
+		rcU[0] = {32, 112, 48, 144};
+		rcU[1] = {48, 112, 64, 144};
+
+		rcR[0] = {64, 112, 96, 128};
+		rcR[1] = {64, 128, 96, 144};
+
+		rcD[0] = {96, 112, 112, 144};
+		rcD[1] = {112, 112, 128, 144};
+
+		switch (bul->direct)
+		{
+			case 0:
+				bul->rect = rcL[bul->ani_no];
+				break;
+			case 1:
+				bul->rect = rcU[bul->ani_no];
+				break;
+			case 2:
+				bul->rect = rcR[bul->ani_no];
+				break;
+			case 3:
+				bul->rect = rcD[bul->ani_no];
+				break;
+		}
+
+		bul->rect.top += 32 * ((level - 1) / 2);
+		bul->rect.bottom += 32 * ((level - 1) / 2);
+		bul->rect.left += (level - 1) % 2 << 7;
+		bul->rect.right += (level - 1) % 2 << 7;
+	}
+}
+
+void ActBullet_Spur(BULLET *bul, int level)
+{
+	if (++bul->count1 > bul->life_count)
+	{
+		bul->cond = 0;
+		SetCaret(bul->x, bul->y, 3, 0);
+	}
+	else
+	{
+		if (bul->damage && bul->life != 100)
+			bul->damage = 0;
+
+		if (bul->act_no)
+		{
+			bul->x += bul->xm;
+			bul->y += bul->ym;
+		}
+		else
+		{
+			bul->act_no = 1;
+
+			switch (bul->direct)
+			{
+				case 0:
+					bul->xm = -0x1000;
+					break;
+				case 1:
+					bul->ym = -0x1000;
+					break;
+				case 2:
+					bul->xm = 0x1000;
+					break;
+				case 3:
+					bul->ym = 0x1000;
+					break;
+			}
+
+			if (level == 1)
+			{
+				switch (bul->direct)
+				{
+					case 0:
+						bul->enemyYL = 0x400;
+						break;
+					case 1:
+						bul->enemyXL = 0x400;
+						break;
+					case 2:
+						bul->enemyYL = 0x400;
+						break;
+					case 3:
+						bul->enemyXL = 0x400;
+						break;
+				}
+			}
+			else if (level == 2)
+			{
+				switch (bul->direct)
+				{
+					case 0:
+						bul->enemyYL = 0x800;
+						break;
+					case 1:
+						bul->enemyXL = 0x800;
+						break;
+					case 2:
+						bul->enemyYL = 0x800;
+						break;
+					case 3:
+						bul->enemyXL = 0x800;
+						break;
+				}
+			}
+		}
+
+		RECT rect1[2];
+		RECT rect2[2];
+		RECT rect3[2];
+
+		rect1[0] = {128, 32, 144, 48};
+		rect1[1] = {144, 32, 160, 48};
+
+		rect2[0] = {160, 32, 176, 48};
+		rect2[1] = {176, 32, 192, 48};
+
+		rect3[0] = {128, 48, 144, 64};
+		rect3[1] = {144, 48, 160, 64};
+
+		bul->damage = bul->life;
+
+		switch (level)
+		{
+			case 1:
+				if (bul->direct == 1 || bul->direct == 3)
+					bul->rect = rect1[1];
+				else
+					bul->rect = rect1[0];
+
+				break;
+
+			case 2:
+				if (bul->direct == 1 || bul->direct == 3)
+					bul->rect = rect2[1];
+				else
+					bul->rect = rect2[0];
+
+				break;
+
+			case 3:
+				if (bul->direct == 1 || bul->direct == 3)
+					bul->rect = rect3[1];
+				else
+					bul->rect = rect3[0];
+
+				break;
+		}
+
+		SetBullet(level + 39, bul->x, bul->y, bul->direct);
+	}
+}
+
+void ActBullet_SpurTail(BULLET *bul, int level)
+{
+	if ( ++bul->count1 > 20 )
+		bul->ani_no = bul->count1 - 20;
+	if ( bul->ani_no > 2 )
+		bul->cond = 0;
+	if ( bul->damage && bul->life != 100 )
+		bul->damage = 0;
+
+	RECT rc_h_lv1[3];
+	RECT rc_v_lv1[3];
+	RECT rc_h_lv2[3];
+	RECT rc_v_lv2[3];
+	RECT rc_h_lv3[3];
+	RECT rc_v_lv3[3];
+
+	rc_h_lv1[0] = {192, 32, 200, 40};
+	rc_h_lv1[1] = {200, 32, 208, 40};
+	rc_h_lv1[2] = {208, 32, 216, 40};
+
+	rc_v_lv1[0] = {192, 40, 200, 48};
+	rc_v_lv1[1] = {200, 40, 208, 48};
+	rc_v_lv1[2] = {208, 40, 216, 48};
+
+	rc_h_lv2[0] = {216, 32, 224, 40};
+	rc_h_lv2[1] = {224, 32, 232, 40};
+	rc_h_lv2[2] = {232, 32, 240, 40};
+
+	rc_v_lv2[0] = {216, 40, 224, 48};
+	rc_v_lv2[1] = {224, 40, 232, 48};
+	rc_v_lv2[2] = {232, 40, 240, 48};
+
+	rc_h_lv3[0] = {240, 32, 248, 40};
+	rc_h_lv3[1] = {248, 32, 256, 40};
+	rc_h_lv3[2] = {256, 32, 264, 40};
+
+	rc_v_lv3[0] = {240, 32, 248, 40};
+	rc_v_lv3[1] = {248, 32, 256, 40};
+	rc_v_lv3[2] = {256, 32, 264, 40};
+
+	switch (level)
+	{
+		case 1:
+			if (bul->direct == 0 || bul->direct == 2)
+				bul->rect = rc_h_lv1[bul->ani_no];
+			else
+				bul->rect = rc_v_lv1[bul->ani_no];
+
+			break;
+
+		case 2:
+			if (bul->direct == 0 || bul->direct == 2)
+				bul->rect = rc_h_lv2[bul->ani_no];
+			else
+				bul->rect = rc_v_lv2[bul->ani_no];
+
+			break;
+
+		case 3:
+			if (bul->direct == 0 || bul->direct == 2)
+				bul->rect = rc_h_lv3[bul->ani_no];
+			else
+				bul->rect = rc_v_lv3[bul->ani_no];
+
+			break;
+	}
+}
+
+void ActBullet_EnemyClear(BULLET *bul)
+{
+	if (++bul->count1 > bul->life_count)
+	{
+		bul->cond = 0;
+	}
+	else
+	{
+		bul->damage = 10000;
+		bul->enemyXL = 0xC8000;
+		bul->enemyYL = 0xC8000;
+	}
+}
+
 void ActBullet_Star(BULLET *bul)
 {
 	if (++bul->count1 > bul->life_count)
@@ -1034,6 +2185,15 @@
 			{
 				switch (gBul[i].code_bullet)
 				{
+					case 1:
+						ActBullet_Frontia1(&gBul[i]);
+						break;
+					case 2:
+						ActBullet_Frontia2(&gBul[i], 2);
+						break;
+					case 3:
+						ActBullet_Frontia2(&gBul[i], 3);
+						break;
 					case 4:
 						ActBullet_PoleStar(&gBul[i], 1);
 						break;
@@ -1079,7 +2239,33 @@
 					case 18:
 						ActBullet_Bom(&gBul[i], 3);
 						break;
-					// TODO everything else
+					case 19:
+						ActBullet_Bubblin1(&gBul[i]);
+						break;
+					case 20:
+						ActBullet_Bubblin2(&gBul[i]);
+						break;
+					case 21:
+						ActBullet_Bubblin3(&gBul[i]);
+						break;
+					case 22:
+						ActBullet_Spine(&gBul[i]);
+						break;
+					case 23:
+						ActBullet_Edge(&gBul[i]);
+						break;
+					case 24:
+						ActBullet_Drop(&gBul[i]);
+						break;
+					case 25:
+						ActBullet_Sword1(&gBul[i]);
+						break;
+					case 26:
+						ActBullet_Sword2(&gBul[i]);
+						break;
+					case 27:
+						ActBullet_Sword3(&gBul[i]);
+						break;
 					case 28:
 						ActBullet_SuperMissile(&gBul[i], 1);
 						break;
@@ -1097,6 +2283,39 @@
 						break;
 					case 33:
 						ActBullet_SuperBom(&gBul[i], 3);
+						break;
+					case 34:
+						ActBullet_Nemesis(&gBul[i], 1);
+						break;
+					case 35:
+						ActBullet_Nemesis(&gBul[i], 2);
+						break;
+					case 36:
+						ActBullet_Nemesis(&gBul[i], 3);
+						break;
+					case 37:
+						ActBullet_Spur(&gBul[i], 1);
+						break;
+					case 38:
+						ActBullet_Spur(&gBul[i], 2);
+						break;
+					case 39:
+						ActBullet_Spur(&gBul[i], 3);
+						break;
+					case 40:
+						ActBullet_SpurTail(&gBul[i], 1);
+						break;
+					case 41:
+						ActBullet_SpurTail(&gBul[i], 2);
+						break;
+					case 42:
+						ActBullet_SpurTail(&gBul[i], 3);
+						break;
+					case 43:
+						ActBullet_Nemesis(&gBul[i], 1);
+						break;
+					case 44:
+						ActBullet_EnemyClear(&gBul[i]);
 						break;
 					case 45:
 						ActBullet_Star(&gBul[i]);
--- a/src/NpcAct.h
+++ b/src/NpcAct.h
@@ -35,9 +35,10 @@
 void ActNpc030(NPCHAR *npc);
 void ActNpc031(NPCHAR *npc);
 void ActNpc032(NPCHAR *npc);
-
+void ActNpc033(NPCHAR *npc);
 void ActNpc034(NPCHAR *npc);
-
+void ActNpc035(NPCHAR *npc);
+void ActNpc036(NPCHAR *npc);
 void ActNpc037(NPCHAR *npc);
 void ActNpc038(NPCHAR *npc);
 void ActNpc039(NPCHAR *npc);
@@ -45,11 +46,20 @@
 void ActNpc041(NPCHAR *npc);
 void ActNpc042(NPCHAR *npc);
 void ActNpc043(NPCHAR *npc);
-
+void ActNpc044(NPCHAR *npc);
+void ActNpc045(NPCHAR *npc);
 void ActNpc046(NPCHAR *npc);
-
+void ActNpc047(NPCHAR *npc);
 void ActNpc048(NPCHAR *npc);
-
+void ActNpc049(NPCHAR *npc);
+void ActNpc050(NPCHAR *npc);
+void ActNpc051(NPCHAR *npc);
+void ActNpc052(NPCHAR *npc);
+void ActNpc053(NPCHAR *npc);
+void ActNpc054(NPCHAR *npc);
+void ActNpc055(NPCHAR *npc);
+void ActNpc056(NPCHAR *npc);
+void ActNpc057(NPCHAR *npc);
 void ActNpc058(NPCHAR *npc);
 void ActNpc059(NPCHAR *npc);
 void ActNpc060(NPCHAR *npc);
@@ -92,32 +102,75 @@
 void ActNpc097(NPCHAR *npc);
 void ActNpc098(NPCHAR *npc);
 void ActNpc099(NPCHAR *npc);
-
+void ActNpc100(NPCHAR *npc);
+void ActNpc101(NPCHAR *npc);
+void ActNpc102(NPCHAR *npc);
+void ActNpc103(NPCHAR *npc);
+void ActNpc104(NPCHAR *npc);
+void ActNpc105(NPCHAR *npc);
+void ActNpc106(NPCHAR *npc);
+void ActNpc107(NPCHAR *npc);
+void ActNpc108(NPCHAR *npc);
+void ActNpc109(NPCHAR *npc);
+void ActNpc110(NPCHAR *npc);
 void ActNpc111(NPCHAR *npc);
 void ActNpc112(NPCHAR *npc);
-
+void ActNpc113(NPCHAR *npc);
+void ActNpc114(NPCHAR *npc);
+void ActNpc115(NPCHAR *npc);
 void ActNpc116(NPCHAR *npc);
-
+void ActNpc117(NPCHAR *npc);
+void ActNpc118(NPCHAR *npc);
 void ActNpc119(NPCHAR *npc);
-
+void ActNpc120(NPCHAR *npc);
+void ActNpc121(NPCHAR *npc);
+void ActNpc122(NPCHAR *npc);
+void ActNpc123(NPCHAR *npc);
+void ActNpc124(NPCHAR *npc);
 void ActNpc125(NPCHAR *npc);
-
+void ActNpc126(NPCHAR *npc);
 void ActNpc127(NPCHAR *npc);
 void ActNpc128(NPCHAR *npc);
 void ActNpc129(NPCHAR *npc);
-
+void ActNpc130(NPCHAR *npc);
+void ActNpc131(NPCHAR *npc);
+void ActNpc132(NPCHAR *npc);
+void ActNpc133(NPCHAR *npc);
+void ActNpc134(NPCHAR *npc);
+void ActNpc135(NPCHAR *npc);
+void ActNpc136(NPCHAR *npc);
+void ActNpc137(NPCHAR *npc);
+void ActNpc138(NPCHAR *npc);
+void ActNpc139(NPCHAR *npc);
+void ActNpc140(NPCHAR *npc);
+void ActNpc141(NPCHAR *npc);
+void ActNpc142(NPCHAR *npc);
+void ActNpc143(NPCHAR *npc);
+void ActNpc144(NPCHAR *npc);
 void ActNpc145(NPCHAR *npc);
+void ActNpc146(NPCHAR *npc);
 
 void ActNpc150(NPCHAR *npc);
 void ActNpc151(NPCHAR *npc);
 
+void ActNpc192(NPCHAR *npc);
+void ActNpc193(NPCHAR *npc);
+
+void ActNpc199(NPCHAR *npc);
+
 void ActNpc211(NPCHAR *npc);
 
+void ActNpc219(NPCHAR *npc);
+
 void ActNpc278(NPCHAR *npc);
 
+void ActNpc292(NPCHAR *npc);
+
 void ActNpc298(NPCHAR *npc);
 void ActNpc299(NPCHAR *npc);
 void ActNpc300(NPCHAR *npc);
+
+void ActNpc302(NPCHAR *npc);
 
 void ActNpc355(NPCHAR *npc);
 
--- a/src/NpcAct020.cpp
+++ b/src/NpcAct020.cpp
@@ -963,7 +963,47 @@
 	npc->rect = rect[npc->ani_no];
 }
 
-// Bed
+//Balrog bouncing projectile
+void ActNpc033(NPCHAR *npc)
+{
+	if (npc->flag & 5)
+	{
+		SetCaret(npc->x, npc->y, 2, 0);
+		npc->cond = 0;
+	}
+	else if (npc->flag & 8)
+	{
+		npc->ym = -0x400;
+	}
+
+	npc->ym += 0x2A;
+
+	npc->y += npc->ym;
+	npc->x += npc->xm;
+
+	RECT rect_left[2];
+
+	rect_left[0] = {240, 64, 256, 80};
+	rect_left[1] = {240, 80, 256, 96};
+
+	if (++npc->ani_wait > 2)
+	{
+		npc->ani_wait = 0;
+
+		if (++npc->ani_no > 1)
+			npc->ani_no = 0;
+	}
+
+	npc->rect = rect_left[npc->ani_no];
+
+	if (++npc->act_wait > 250)
+	{
+		SetCaret(npc->x, npc->y, 2, 0);
+		npc->cond = 0;
+	}
+}
+
+//Bed
 void ActNpc034(NPCHAR *npc)
 {
 	RECT rcLeft[1];
@@ -976,6 +1016,260 @@
 		npc->rect = rcLeft[0];
 	else
 		npc->rect = rcRight[0];
+}
+
+//Mannan
+void ActNpc035(NPCHAR *npc)
+{
+	if (npc->act_no < 3 && npc->life < 90)
+	{
+		PlaySoundObject(71, 1);
+		SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8);
+		SetExpObjects(npc->x, npc->y, npc->exp);
+		npc->act_no = 3;
+		npc->act_wait = 0;
+		npc->ani_no = 2;
+		npc->bits &= ~0x20;
+		npc->damage = 0;
+	}
+
+	switch (npc->act_no)
+	{
+		case 0:
+		case 1:
+			if (npc->shock)
+			{
+				if (npc->direct)
+					SetNpChar(103, npc->x + 0x1000, npc->y + 0x1000, 0, 0, npc->direct, 0, 0x100);
+				else
+					SetNpChar(103, npc->x - 0x1000, npc->y + 0x1000, 0, 0, npc->direct, 0, 0x100);
+
+				npc->ani_no = 1;
+				npc->act_no = 2;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 20)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 3:
+			if (++npc->act_wait == 50 || npc->act_wait == 60)
+				npc->ani_no = 3;
+
+			if (npc->act_wait == 53 || npc->act_wait == 63)
+				npc->ani_no = 2;
+
+			if (npc->act_wait > 100)
+				npc->act_no = 4;
+
+			break;
+	}
+
+	RECT rcLeft[4];
+	RECT rcRight[4];
+
+	rcLeft[0] = {96, 64, 120, 96};
+	rcLeft[1] = {120, 64, 144, 96};
+	rcLeft[2] = {144, 64, 168, 96};
+	rcLeft[3] = {168, 64, 192, 96};
+
+	rcRight[0] = {96, 96, 120, 128};
+	rcRight[1] = {120, 96, 144, 128};
+	rcRight[2] = {144, 96, 168, 128};
+	rcRight[3] = {168, 96, 192, 128};
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Balrog (hover)
+void ActNpc036(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			if (++npc->act_wait > 12)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->count1 = 3;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 16)
+			{
+				--npc->count1;
+				npc->act_wait = 0;
+
+				const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y + 0x800 - gMC.y) + Random(-16, 16);
+				const int ym = GetSin(deg);
+				const int xm = GetCos(deg);
+
+				SetNpChar(11, npc->x, npc->y + 0x800, xm, ym, 0, 0, 0x100);
+				PlaySoundObject(39, 1);
+
+				if (npc->count1 == 0)
+				{
+					npc->act_no = 3;
+					npc->act_wait = 0;
+				}
+			}
+
+			break;
+
+		case 3:
+			if (++npc->act_wait > 3)
+			{
+				npc->act_no = 4;
+				npc->act_wait = 0;
+				npc->xm = (gMC.x - npc->x) / 100;
+				npc->ym = -0x600;
+				npc->ani_no = 3;
+			}
+
+			break;
+
+		case 4:
+			if (npc->ym > -0x200)
+			{
+				if (npc->life > 60)
+				{
+					npc->act_no = 5;
+					npc->ani_no = 4;
+					npc->ani_wait = 0;
+					npc->act_wait = 0;
+					npc->tgt_y = npc->y;
+				}
+				else
+				{
+					npc->act_no = 6;
+				}
+			}
+
+			break;
+
+		case 5:
+			if (++npc->ani_wait > 1)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+			{
+				npc->ani_no = 4;
+				PlaySoundObject(47, 1);
+			}
+
+			if (++npc->act_wait > 100)
+			{
+				npc->act_no = 6;
+				npc->ani_no = 3;
+			}
+
+			if (npc->y < npc->tgt_y)
+				npc->ym += 0x40;
+			else
+				npc->ym -= 0x40;
+
+			if (npc->ym < -0x200)
+				npc->ym = -0x200;
+			if (npc->ym > 0x200)
+				npc->ym = 0x200;
+
+			break;
+
+		case 6:
+			if (gMC.y > npc->y + 0x2000)
+				npc->damage = 10;
+			else
+				npc->damage = 0;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 7;
+				npc->act_wait = 0;
+				npc->ani_no = 2;
+				PlaySoundObject(26, 1);
+				PlaySoundObject(25, 1);
+				SetQuake(30);
+				npc->damage = 0;
+
+				for (int i = 0; i < 8; ++i)
+					SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+				for (int i = 0; i < 8; ++i)
+					SetNpChar(33, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-0x400, 0x400), Random(-0x400, 0), 0, 0, 0x100);
+			}
+
+			break;
+
+		case 7:
+			npc->xm = 0;
+
+			if (++npc->act_wait > 3)
+			{
+				npc->act_no = 1;
+				npc->act_wait = 0;
+			}
+
+			break;
+	}
+
+	if (npc->act_no != 5)
+	{
+		npc->ym += 0x33;
+
+		if (gMC.x > npc->x)
+			npc->direct = 2;
+		else
+			npc->direct = 0;
+	}
+
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	RECT rect_left[6];
+	RECT rect_right[6];
+
+	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_left[4] = {160, 48, 200, 72};
+	rect_left[5] = {200, 48, 240, 72};
+
+	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};
+	rect_right[4] = {160, 72, 200, 96};
+	rect_right[5] = {200, 72, 240, 96};
+
+	if (npc->direct == 0)
+		npc->rect = rect_left[npc->ani_no];
+	else
+		npc->rect = rect_right[npc->ani_no];
 }
 
 //Signpost
--- a/src/NpcAct040.cpp
+++ b/src/NpcAct040.cpp
@@ -9,6 +9,7 @@
 #include "Sound.h"
 #include "Back.h"
 #include "Triangle.h"
+#include "CommonDefines.h"
 
 //Santa
 void ActNpc040(NPCHAR *npc)
@@ -412,6 +413,254 @@
 		npc->rect = rcRight[0];
 }
 
+//Polish
+void ActNpc044(NPCHAR *npc)
+{
+	RECT rcRight[3];
+	RECT rcLeft[3];
+
+	rcRight[0] = {0, 0, 32, 32};
+	rcRight[1] = {32, 0, 64, 32};
+	rcRight[2] = {64, 0, 96, 32};
+
+	rcLeft[0] = {0, 0, 32, 32};
+	rcLeft[1] = {96, 0, 128, 32};
+	rcLeft[2] = {128, 0, 160, 32};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			npc->ani_no = 0;
+
+			if (npc->direct == 0)
+				npc->act_no = 8;
+			else
+				npc->act_no = 2;
+			// Fallthrough
+		case 2:
+			npc->ym += 0x20;
+
+			if (npc->ym > 0 && npc->flag & 8)
+			{
+				npc->ym = -0x100;
+				npc->xm += 0x100;
+			}
+
+			if (npc->flag & 4)
+				npc->act_no = 3;
+
+			break;
+
+		case 3:
+			npc->xm += 0x20;
+
+			if (npc->xm > 0 && npc->flag & 4)
+			{
+				npc->xm = -0x100;
+				npc->ym -= 0x100;
+			}
+
+			if (npc->flag & 2)
+				npc->act_no = 4;
+
+			break;
+
+		case 4:
+			npc->ym -= 0x20;
+
+			if (npc->ym < 0 && npc->flag & 2)
+			{
+				npc->ym = 0x100;
+				npc->xm -= 0x100;
+			}
+
+			if (npc->flag & 1)
+				npc->act_no = 5;
+
+			break;
+
+		case 5:
+			npc->xm -= 0x20;
+
+			if (npc->xm < 0 && npc->flag & 1)
+			{
+				npc->xm = 0x100;
+				npc->ym += 0x100;
+			}
+
+			if (npc->flag & 8)
+				npc->act_no = 2;
+
+			break;
+
+		case 6:
+			npc->ym += 0x20;
+
+			if (npc->ym > 0 && npc->flag & 8)
+			{
+				npc->ym = -0x100;
+				npc->xm -= 0x100;
+			}
+
+			if (npc->flag & 1)
+				npc->act_no = 7;
+
+			break;
+
+		case 7:
+			npc->xm -= 0x20;
+
+			if (npc->xm < 0 && npc->flag & 1)
+			{
+				npc->xm = 0x100;
+				npc->ym -= 0x100;
+			}
+
+			if (npc->flag & 2)
+				npc->act_no = 8;
+
+			break;
+
+		case 8:
+			npc->ym -= 0x20;
+
+			if (npc->ym < 0 && npc->flag & 2)
+			{
+				npc->ym = 0x100;
+				npc->xm += 0x100;
+			}
+
+			if ( npc->flag & 4 )
+				npc->act_no = 9;
+
+			break;
+
+		case 9:
+			npc->xm += 0x20;
+
+			if (npc->xm > 0 && npc->flag & 4)
+			{
+				npc->xm = -0x100;
+				npc->ym += 0x100;
+			}
+
+			if (npc->flag & 8)
+				npc->act_no = 6;
+
+			break;
+	}
+
+	if (npc->life <= 100)
+	{
+		for (int i = 0; i < 10; ++i)
+			SetNpChar(45, npc->x, npc->y, 0, 0, 0, 0, 0x100);
+
+		SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8);
+		PlaySoundObject(25, 1);
+		npc->cond = 0;
+	}
+
+	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;
+
+	if (npc->shock)
+	{
+		npc->x += npc->xm / 2;
+		npc->y += npc->ym / 2;
+	}
+	else
+	{
+		npc->x += npc->xm;
+		npc->y += npc->ym;
+	}
+
+	if (npc->act_no >= 2 && npc->act_no <= 9 && ++npc->ani_no > 2)
+		npc->ani_no = 1;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Baby
+void ActNpc045(NPCHAR *npc)
+{
+	RECT rect[3];
+
+	rect[0] = {0, 32, 16, 48};
+	rect[1] = {16, 32, 32, 48};
+	rect[2] = {32, 32, 48, 48};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 2;
+
+			if (Random(0, 1))
+				npc->xm = Random(-0x200, -0x100);
+			else
+				npc->xm = Random(0x100, 0x200);
+
+			if (Random(0, 1))
+				npc->ym = Random(-0x200, -0x100);
+			else
+				npc->ym = Random(0x100, 0x200);
+
+			npc->xm2 = npc->xm;
+			npc->ym2 = npc->ym;
+			// Fallthrough
+		case 1:
+			if ( ++npc->ani_no > 2 )
+				npc->ani_no = 1;
+
+			break;
+	}
+
+	if (npc->xm2 < 0 && npc->flag & 1)
+		npc->xm2 = -npc->xm2;
+	if (npc->xm2 > 0 && npc->flag & 4)
+		npc->xm2 = -npc->xm2;
+
+	if (npc->ym2 < 0 && npc->flag & 2)
+		npc->ym2 = -npc->ym2;
+	if (npc->ym2 > 0 && npc->flag & 8)
+		npc->ym2 = -npc->ym2;
+
+	if (npc->xm2 > 0x200)
+		npc->xm2 = 0x200;
+	if (npc->xm2 < -0x200)
+		npc->xm2 = -0x200;
+
+	if (npc->ym2 > 0x200)
+		npc->ym2 = 0x200;
+	if (npc->ym2 < -0x200)
+		npc->ym2 = -0x200;
+
+	if (npc->shock)
+	{
+		npc->x += npc->xm2 / 2;
+		npc->y += npc->ym2 / 2;
+	}
+	else
+	{
+		npc->x += npc->xm2;
+		npc->y += npc->ym2;
+	}
+
+	npc->rect = rect[npc->ani_no];
+}
+
 //H/V Trigger
 void ActNpc046(NPCHAR *npc)
 {
@@ -438,6 +687,109 @@
 	npc->rect = rect[0];
 }
 
+//Sandcroc
+void ActNpc047(NPCHAR *npc)
+{
+	switch ( npc->act_no )
+	{
+		case 0:
+			npc->ani_no = 0;
+			npc->act_no = 1;
+			npc->act_wait = 0;
+			npc->tgt_y = npc->y;
+			npc->bits &= ~0x20;
+			npc->bits &= ~4;
+			npc->bits &= ~1;
+			npc->bits &= ~8;
+			// Fallthrough
+		case 1:
+			if (gMC.x > npc->x - 0x1000 && gMC.x < npc->x + 0x1000 && gMC.y > npc->y && gMC.y < npc->y + 0x1000)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				PlaySoundObject(102, 1);
+			}
+
+			if (gMC.x > npc->x)
+				npc->x += 0x400;
+
+			if (gMC.x < npc->x)
+				npc->x -= 0x400;
+
+			break;
+
+		case 2:
+			if (++npc->ani_wait > 3)
+			{
+				++npc->ani_no;
+				npc->ani_wait = 0;
+			}
+
+			if (npc->ani_no == 3)
+				npc->damage = 10;
+
+			if (npc->ani_no == 4)
+			{
+				npc->bits |= 0x20;
+				npc->act_no = 3;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 3:
+			npc->bits |= 1;
+			npc->damage = 0;
+			++npc->act_wait;
+
+			if (npc->shock)
+			{
+				npc->act_no = 4;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 4:
+			npc->bits |= 8;
+			npc->y += 0x200;
+
+			if (++npc->act_wait == 32)
+			{
+				npc->bits &= ~1;
+				npc->bits &= ~0x20;
+				npc->act_no = 5;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 5:
+			if (npc->act_wait < 100)
+			{
+				++npc->act_wait;
+			}
+			else
+			{
+				npc->y = npc->tgt_y;
+				npc->ani_no = 0;
+				npc->act_no = 0;
+			}
+
+			break;
+	}
+
+	RECT rect[5];
+
+	rect[0] = {0, 48, 48, 80};
+	rect[1] = {48, 48, 96, 80};
+	rect[2] = {96, 48, 144, 80};
+	rect[3] = {144, 48, 192, 80};
+	rect[4] = {192, 48, 240, 80};
+
+	npc->rect = rect[npc->ani_no];
+}
+
 //Omega projectiles
 void ActNpc048(NPCHAR *npc)
 {
@@ -498,19 +850,914 @@
 		npc->rect = rcLeft[npc->ani_no];
 }
 
+//Skullhead
+void ActNpc049(NPCHAR *npc)
+{
+	if (npc->act_no >= 10 && npc->pNpc->code_char == 3)
+	{
+		npc->act_no = 3;
+		npc->xm = 0;
+		npc->ym = 0;
+		npc->count2 = 1;
+	}
+
+	if (npc->flag & 1)
+	{
+		npc->direct = 2;
+		npc->xm = 0x100;
+	}
+
+	if (npc->flag & 4)
+	{
+		npc->direct = 0;
+		npc->xm = -0x100;
+	}
+
+	switch (npc->act_no)
+	{
+		case 0:
+			if (npc->pNpc)
+				npc->act_no = 10;
+			else
+				npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			if (++npc->act_wait > 3)
+			{
+				npc->ym = -0x400;
+				npc->act_no = 3;
+				npc->ani_no = 2;
+
+				if (npc->count2 == 0)
+				{
+					if (npc->direct == 0)
+						npc->xm = -0x100;
+					else
+						npc->xm = 0x100;
+				}
+				else
+				{
+					if (npc->direct == 0)
+						npc->xm = -0x200;
+					else
+						npc->xm = 0x200;
+				}
+			}
+
+			npc->ani_no = 1;
+			break;
+
+		case 3:
+			if (npc->flag & 8)
+			{
+				npc->act_no = 1;
+				npc->act_wait = 0;
+				npc->xm = 0;
+			}
+
+			if (npc->flag & 8 || npc->ym > 0)
+				npc->ani_no = 1;
+			else
+				npc->ani_no = 2;
+
+			break;
+
+		case 10:
+			if (npc->count1 < 50)
+			{
+				++npc->count1;
+			}
+			else
+			{
+				if (gMC.x > npc->x - 0x10000 && gMC.x < npc->x + 0x10000 && gMC.y > npc->y - 0xC000 && gMC.y < npc->y + 0xC000)
+				{
+					npc->act_no = 11;
+					npc->act_wait = 0;
+					npc->ani_no = 2;
+				}
+			}
+
+			break;
+
+		case 11:
+			if (++npc->act_wait == 30 || npc->act_wait == 35)
+			{
+				const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y + 0x800 - gMC.y);
+				const int ym = 2 * GetSin(deg);
+				const int xm = 2 * GetCos(deg);
+				SetNpChar(50, npc->x, npc->y, xm, ym, 0, 0, 0x100);
+				PlaySoundObject(39, 1);
+			}
+
+			if (npc->act_wait > 50)
+			{
+				npc->count1 = 0;
+				npc->act_no = 10;
+				npc->ani_no = 1;
+			}
+
+			break;
+	}
+
+	if (npc->act_no >= 10)
+	{
+		npc->x = npc->pNpc->x;
+		npc->y = npc->pNpc->y + 0x2000;
+		npc->direct = npc->pNpc->direct;
+		--npc->pNpc->count1;
+	}
+
+	npc->ym += 0x40;
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {0, 80, 32, 104};
+	rcLeft[1] = {32, 80, 64, 104};
+	rcLeft[2] = {64, 80, 96, 104};
+
+	rcRight[0] = {0, 104, 32, 128};
+	rcRight[1] = {32, 104, 64, 128};
+	rcRight[2] = {64, 104, 96, 128};
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Skeleton projectile
+void ActNpc050(NPCHAR *npc)
+{
+	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;
+
+			if (npc->flag & 1)
+			{
+				npc->act_no = 2;
+				npc->xm = 0x200;
+				++npc->count1;
+			}
+
+			if (npc->flag & 4)
+			{
+				npc->act_no = 2;
+				npc->xm = -0x200;
+				++npc->count1;
+			}
+
+			if (npc->flag & 2)
+			{
+				npc->act_no = 2;
+				npc->ym = 0x200;
+				++npc->count1;
+			}
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 2;
+				npc->ym = -0x200;
+				++npc->count1;
+			}
+
+			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 rect[4];
+
+	rect[0] = {48, 32, 64, 48};
+	rect[1] = {64, 32, 80, 48};
+	rect[2] = {80, 32, 96, 48};
+	rect[3] = {96, 32, 112, 48};
+
+	if (npc->direct == 0)
+	{
+		if (++npc->ani_wait > 1)
+		{
+			npc->ani_wait = 0;
+			++npc->ani_no;
+		}
+
+		if (npc->ani_no > 3)
+			npc->ani_no = 0;
+	}
+	else
+	{
+		if (++npc->ani_wait > 1)
+		{
+			npc->ani_wait = 0;
+			--npc->ani_no;
+		}
+
+		if (npc->ani_no < 0)
+			npc->ani_no = 3;
+	}
+
+	npc->rect = rect[npc->ani_no];
+}
+
+//Crow & Skullhead
+void ActNpc051(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			if (gMC.x > npc->x - (WINDOW_WIDTH * 0x200) && gMC.x < npc->x + (WINDOW_WIDTH * 0x200) && gMC.y > npc->y - (WINDOW_WIDTH * 0x200) && gMC.y < npc->y + (WINDOW_WIDTH * 0x200))
+			{
+				npc->tgt_x = npc->x;
+				npc->tgt_y = npc->y;
+				npc->ym = 0x400;
+				npc->act_no = 1;
+				SetNpChar(49, 0, 0, 0, 0, 0, npc, 0);
+			}
+			else
+				break;
+
+			// Fallthrough
+		case 1:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (npc->tgt_y < npc->y)
+				npc->ym -= 10;
+			if (npc->tgt_y > npc->y)
+				npc->ym += 10;
+
+			if (npc->ym > 0x200)
+				npc->ym = 0x200;
+			if (npc->ym < -0x200)
+				npc->ym = -0x200;
+
+			if (npc->count1 < 10)
+				++npc->count1;
+			else
+				npc->act_no = 2;
+
+			break;
+
+		case 2:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (npc->y > gMC.y + 0x4000)
+			{
+				if (gMC.x < npc->x)
+					npc->xm += 0x10;
+				if (gMC.x > npc->x)
+					npc->xm -= 0x10;
+			}
+			else
+			{
+				if (gMC.x < npc->x)
+					npc->xm -= 0x10;
+				if (gMC.x > npc->x)
+					npc->xm += 0x10;
+			}
+
+			if (gMC.y < npc->y)
+				npc->ym -= 0x10;
+			if (gMC.y > npc->y)
+				npc->ym += 0x10;
+
+			if (npc->shock)
+			{
+				npc->ym += 0x20;
+				npc->xm = 0;
+			}
+
+			break;
+	}
+
+	if (npc->xm < 0 && npc->flag & 1)
+		npc->xm = 0x100;
+	if (npc->xm > 0 && npc->flag & 4)
+		npc->xm = -0x100;
+
+	if (npc->ym < 0 && npc->flag & 2)
+		npc->ym = 0x100;
+	if (npc->ym > 0 && npc->flag & 8)
+		npc->ym = -0x100;
+
+	if (npc->xm > 0x400)
+		npc->xm = 0x400;
+	if (npc->xm < -0x400)
+		npc->xm = -0x400;
+
+	if (npc->ym > 0x200)
+		npc->ym = 0x200;
+	if (npc->ym < -0x200)
+		npc->ym = -0x200;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	RECT rect_left[5];
+	RECT rect_right[5];
+
+	rect_left[0] = {96, 80, 128, 112};
+	rect_left[1] = {128, 80, 160, 112};
+	rect_left[2] = {160, 80, 192, 112};
+	rect_left[3] = {192, 80, 224, 112};
+	rect_left[4] = {224, 80, 256, 112};
+
+	rect_right[0] = {96, 112, 128, 144};
+	rect_right[1] = {128, 112, 160, 144};
+	rect_right[2] = {160, 112, 192, 144};
+	rect_right[3] = {192, 112, 224, 144};
+	rect_right[4] = {224, 112, 256, 144};
+
+	if (npc->shock)
+	{
+		npc->ani_no = 4;
+	}
+	else if (npc->act_no == 2 && npc->y < gMC.y - 0x4000)
+	{
+		npc->ani_no = 0;
+	}
+	else
+	{
+		if (npc->act_no)
+		{
+			if (++npc->ani_wait > 1)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+		}
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rect_left[npc->ani_no];
+	else
+		npc->rect = rect_right[npc->ani_no];
+}
+
+//Bliue robot (sitting)
+void ActNpc052(NPCHAR *npc)
+{
+	RECT rect[1];
+
+	rect[0] = {240, 96, 256, 112};
+
+	npc->rect = rect[0];
+}
+
+//Skullstep leg
+void ActNpc053(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {0, 128, 24, 144};
+	rcLeft[1] = {24, 128, 48, 144};
+
+	rcRight[0] = {48, 128, 72, 144};
+	rcRight[1] = {72, 128, 96, 144};
+
+	if (npc->pNpc->code_char == 3)
+	{
+		VanishNpChar(npc);
+		SetDestroyNpChar(npc->x, npc->y, npc->view.back, 4);
+		return;
+	}
+
+	unsigned char deg;
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->count1 = 10;
+			// Fallthrough
+		case 1:
+			if (npc->direct == 0 && npc->flag & 0x20)
+			{
+				npc->pNpc->y -= 0x400;
+				npc->pNpc->ym -= 0x100;
+			}
+
+			if (npc->direct == 2 && npc->flag & 0x10)
+			{
+				npc->pNpc->y -= 0x400;
+				npc->pNpc->ym -= 0x100;
+			}
+
+			if (npc->flag & 8)
+			{
+				npc->pNpc->y -= 0x400;
+				npc->pNpc->ym -= 0x100;
+
+				if (npc->pNpc->direct == 0)
+					npc->pNpc->xm -= 0x80;
+				else
+					npc->pNpc->xm += 0x80;
+			}
+
+			deg = npc->xm + npc->pNpc->count2;
+			npc->x = npc->pNpc->x + npc->count1 * GetCos(deg);
+			npc->y = npc->pNpc->y + npc->count1 * GetSin(deg);
+			npc->direct = npc->pNpc->direct;
+			break;
+	}
+
+	npc->direct = npc->pNpc->direct;
+	npc->ani_no = deg < 20 || deg > 108;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Skullstep
+void ActNpc054(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {0, 80, 32, 104};
+	rcLeft[1] = {32, 80, 64, 104};
+	rcLeft[2] = {64, 80, 96, 104};
+
+	rcRight[0] = {0, 104, 32, 128};
+	rcRight[1] = {32, 104, 64, 128};
+	rcRight[2] = {64, 104, 96, 128};
+
+	unsigned char deg;
+	switch (npc->act_no)
+	{
+		case 0:
+			SetNpChar(53, 0, 0, 0, 0, npc->direct, npc, 0x100);
+			SetNpChar(53, 0, 0, 128, 0, npc->direct, npc, 0);
+			npc->act_no = 1;
+			npc->ani_no = 1;
+			// Fallthrough
+		case 1:
+			deg = npc->count2;
+
+			if (npc->direct == 0)
+				deg -= 6;
+			else
+				deg += 6;
+
+			npc->count2 = deg;
+
+			if (npc->flag & 8)
+			{
+				npc->xm = 3 * npc->xm / 4;
+
+				if (++npc->act_wait > 60)
+				{
+					npc->act_no = 2;
+					npc->act_wait = 0;
+				}
+			}
+			else
+			{
+				npc->act_wait = 0;
+			}
+
+			if (npc->direct == 0 && npc->flag & 1)
+			{
+				if (++npc->count1 > 8)
+				{
+					npc->direct = 2;
+					npc->xm = -npc->xm;
+				}
+			}
+			else if (npc->direct == 2 && npc->flag & 4)
+			{
+				if (++npc->count1 > 8)
+				{
+					npc->direct = 0;
+					npc->xm = -npc->xm;
+				}
+			}
+			else
+			{
+				npc->count1 = 0;
+			}
+
+			break;
+
+		case 2:
+			++npc->act_wait;
+			npc->shock += npc->act_wait;
+
+			if (npc->act_wait > 50)
+			{
+				VanishNpChar(npc);
+				SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8);
+				PlaySoundObject(25, 1);
+			}
+
+			break;
+	}
+
+	npc->ym += 0x80;
+
+	if (npc->xm > 0x2FF)
+		npc->xm = 0x2FF;
+	if (npc->xm < -0x2FF)
+		npc->xm = -0x2FF;
+
+	if (npc->ym > 0x2FF)
+		npc->ym = 0x2FF;
+	if (npc->ym < -0x2FF)
+		npc->ym = -0x2FF;
+
+	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];
+}
+
+//Cairn
+void ActNpc055(NPCHAR *npc)
+{
+	RECT rcLeft[6];
+	RECT rcRight[6];
+
+	rcLeft[0] = {192, 192, 208, 216};
+	rcLeft[1] = {208, 192, 224, 216};
+	rcLeft[2] = {192, 192, 208, 216};
+	rcLeft[3] = {224, 192, 240, 216};
+	rcLeft[4] = {192, 192, 208, 216};
+	rcLeft[5] = {240, 192, 256, 216};
+
+	rcRight[0] = {192, 216, 208, 240};
+	rcRight[1] = {208, 216, 224, 240};
+	rcRight[2] = {192, 216, 208, 240};
+	rcRight[3] = {224, 216, 240, 240};
+	rcRight[4] = {192, 216, 208, 240};
+	rcRight[5] = {240, 216, 256, 240};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			break;
+
+		case 3:
+			npc->act_no = 4;
+			npc->ani_no = 1;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 4:
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 4)
+				npc->ani_no = 1;
+
+			if (npc->direct == 0)
+				npc->x -= 0x200;
+			else
+				npc->x += 0x200;
+
+			break;
+
+		case 5:
+			npc->ani_no = 5;
+			break;
+	}
+
+	npc->ym += 0x20;
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->y += npc->ym;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Beetle (Sand Zone)
+void ActNpc056(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {0, 144, 16, 160};
+	rcLeft[1] = {16, 144, 32, 160};
+	rcLeft[2] = {32, 144, 48, 160};
+
+	rcRight[0] = {0, 160, 16, 176};
+	rcRight[1] = {16, 160, 32, 176};
+	rcRight[2] = {32, 160, 48, 176};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+
+			if (npc->direct == 0)
+				npc->act_no = 1;
+			else
+				npc->act_no = 3;
+
+			break;
+
+		case 1:
+			npc->xm -= 0x10;
+
+			if (npc->xm < -0x400)
+				npc->xm = -0x400u;
+
+			if (npc->shock)
+				npc->x += npc->xm / 2;
+			else
+				npc->x += npc->xm;
+
+			if (++npc->ani_wait > 1)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 2)
+				npc->ani_no = 1;
+
+			if (npc->flag & 1)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+				npc->xm = 0;
+				npc->direct = 2;
+			}
+
+			break;
+
+		case 2:
+			if (npc->x < gMC.x && npc->x > gMC.x - 0x20000 && npc->y < gMC.y + 0x1000 && npc->y > gMC.y - 0x1000)
+			{
+				npc->act_no = 3;
+				npc->ani_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 3:
+			npc->xm += 0x10;
+
+			if (npc->xm > 0x400)
+				npc->xm = 0x400;
+
+			if (npc->shock)
+				npc->x += npc->xm / 2;
+			else
+				npc->x += npc->xm;
+
+			if (++npc->ani_wait > 1)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 2)
+				npc->ani_no = 1;
+
+			if (npc->flag & 4)
+			{
+				npc->act_no = 4;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+				npc->xm = 0;
+				npc->direct = 0;
+			}
+
+			break;
+
+		case 4:
+			if (npc->x < gMC.x + 0x20000 && npc->x > gMC.x && npc->y < gMC.y + 0x1000 && npc->y > gMC.y - 0x1000)
+			{
+				npc->act_no = 1;
+				npc->ani_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Crow
+void ActNpc057(NPCHAR *npc)
+{
+	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->ani_no = Random(0, 1);
+			npc->ani_wait = Random(0, 4);
+			// Fallthrough
+		case 1:
+			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;
+
+			if (npc->shock)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+
+				if (npc->direct == 2)
+					npc->xm = -0x200;
+				else
+					npc->xm = 0x200;
+
+				npc->ym = 0;
+			}
+
+			break;
+
+		case 2:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (npc->y > gMC.y + 0x6000)
+			{
+				if (gMC.x < npc->x)
+					npc->xm += 0x10;
+				if (gMC.x > npc->x)
+					npc->xm -= 0x10;
+			}
+			else
+			{
+				if (gMC.x < npc->x)
+					npc->xm -= 0x10;
+				if (gMC.x > npc->x)
+					npc->xm += 0x10;
+			}
+
+			if (gMC.y < npc->y)
+				npc->ym -= 0x10;
+			if (gMC.y > npc->y)
+				npc->ym += 0x10;
+
+			if (npc->shock)
+			{
+				npc->ym += 0x20;
+				npc->xm = 0;
+			}
+
+			if (npc->xm < 0 && npc->flag & 1)
+				npc->xm = 0x200;
+			if (npc->xm > 0 && npc->flag & 4)
+				npc->xm = -0x200;
+
+			if (npc->ym < 0 && npc->flag & 2)
+				npc->ym = 0x200;
+			if (npc->ym > 0 && npc->flag & 8)
+				npc->ym = -0x200;
+
+			if (npc->xm > 0x5FF)
+				npc->xm = 0x5FF;
+			if (npc->xm < -0x5FF)
+				npc->xm = -0x5FF;
+
+			if (npc->ym > 0x5FF)
+				npc->ym = 0x5FF;
+			if (npc->ym < -0x5FF)
+				npc->ym = -0x5FF;
+
+			break;
+	}
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	RECT rect_left[5];
+	RECT rect_right[5];
+
+	rect_left[0] = {96, 80, 128, 112};
+	rect_left[1] = {128, 80, 160, 112};
+	rect_left[2] = {160, 80, 192, 112};
+	rect_left[3] = {192, 80, 224, 112};
+	rect_left[4] = {224, 80, 256, 112};
+
+	rect_right[0] = {96, 112, 128, 144};
+	rect_right[1] = {128, 112, 160, 144};
+	rect_right[2] = {160, 112, 192, 144};
+	rect_right[3] = {192, 112, 224, 144};
+	rect_right[4] = {224, 112, 256, 144};
+
+	if (npc->shock)
+	{
+		npc->ani_no = 4;
+	}
+	else
+	{
+		if (++npc->ani_wait > 1)
+		{
+			npc->ani_wait = 0;
+			++npc->ani_no;
+		}
+
+		if (npc->ani_no > 1)
+			npc->ani_no = 0;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rect_left[npc->ani_no];
+	else
+		npc->rect = rect_right[npc->ani_no];
+}
+
 //Basu (Egg Corridor)
 void ActNpc058(NPCHAR *npc)
 {
-	unsigned __int8 v1; // ST2F_1@42
-	char v2; // ST2F_1@42
-	int a5; // ST24_4@42
-	int a4; // ST28_4@42
-	RECT *v5; // edx@54
-	RECT *v6; // eax@54
-	RECT *v7; // edx@55
-	RECT *v8; // eax@55
-	int routine; // [sp+0h] [bp-70h]@1
-
 	RECT rcLeft[3];
 	RECT rcRight[3];
 
--- a/src/NpcAct100.cpp
+++ b/src/NpcAct100.cpp
@@ -8,7 +8,742 @@
 #include "Sound.h"
 #include "Back.h"
 #include "Triangle.h"
+#include "Frame.h"
+#include "Caret.h"
+#include "Bullet.h"
 
+//Grate
+void ActNpc100(NPCHAR *npc)
+{
+	RECT rc[2];
+
+	rc[0] = {272, 48, 288, 64};
+	rc[1] = {272, 48, 288, 64};
+
+	if (npc->act_no == 0)
+	{
+		npc->y += 0x2000;
+		npc->act_no = 1;
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rc[0];
+	else
+		npc->rect = rc[1];
+}
+
+//Malco computer screen
+void ActNpc101(NPCHAR *npc)
+{
+	RECT rect[3];
+
+	rect[0] = {240, 136, 256, 152};
+	rect[1] = {240, 136, 256, 152};
+	rect[2] = {256, 136, 272, 152};
+
+	if (++npc->ani_wait > 3)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	npc->rect = rect[npc->ani_no];
+}
+
+//Malco computer wave
+void ActNpc102(NPCHAR *npc)
+{
+	RECT rect[4];
+
+	rect[0] = {208, 120, 224, 136};
+	rect[1] = {224, 120, 240, 136};
+	rect[2] = {240, 120, 256, 136};
+	rect[3] = {256, 120, 272, 136};
+
+	if (npc->act_no == 0)
+	{
+		npc->act_no = 1;
+		npc->y += 0x1000;
+	}
+
+	if (++npc->ani_wait > 0)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 3)
+		npc->ani_no = 0;
+
+	npc->rect = rect[npc->ani_no];
+}
+
+//Mannan projectile
+void ActNpc103(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {192, 96, 208, 120};
+	rcLeft[1] = {208, 96, 224, 120};
+	rcLeft[2] = {224, 96, 240, 120};
+
+	rcRight[0] = {192, 120, 208, 144};
+	rcRight[1] = {208, 120, 224, 144};
+	rcRight[2] = {224, 120, 240, 144};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			// Fallthrough
+		case 1:
+			if (npc->direct == 0)
+				npc->xm -= 0x20;
+			else
+				npc->xm += 0x20;
+
+			if (++npc->ani_wait > 0)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 2)
+				npc->ani_no = 0;
+
+			break;
+	}
+
+	npc->x += npc->xm;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+
+	if (++npc->count1 > 100)
+		npc->cond = 0;
+
+	if (npc->count1 % 4 == 1)
+		PlaySoundObject(46, 1);
+}
+
+//Frog
+void ActNpc104(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {0, 112, 32, 144};
+	rcLeft[1] = {32, 112, 64, 144};
+	rcLeft[2] = {64, 112, 96, 144};
+
+	rcRight[0] = {0, 144, 32, 176};
+	rcRight[1] = {32, 144, 64, 176};
+	rcRight[2] = {64, 144, 96, 176};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->act_wait = 0;
+			npc->xm = 0;
+			npc->ym = 0;
+
+			if (npc->direct == 4)
+			{
+				if (Random(0, 1) != 0)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+
+				npc->bits |= 8;
+				npc->ani_no = 2;
+				npc->act_no = 3;
+				break;
+			}
+			else
+			{
+				npc->bits &= ~8;
+			}
+			// Fallthrough
+		case 1:
+			++npc->act_wait;
+
+			if (Random(0, 50) == 1)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+				npc->ani_wait = 0;
+			}
+
+			break;
+
+		case 2:
+			++npc->act_wait;
+
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (npc->act_wait > 18)
+			{
+				npc->act_no = 1;
+				npc->act_no = 1;
+			}
+
+			break;
+
+		case 3:
+			if (++npc->act_wait > 40)
+				npc->bits &= ~8;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 0;
+				npc->ani_no = 0;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			// Fallthrough
+		case 11:
+			if (npc->flag & 1 && npc->xm < 0)
+			{
+				npc->xm = -npc->xm;
+				npc->direct = 2;
+			}
+
+			if (npc->flag & 4 && npc->xm > 0)
+			{
+				npc->xm = -npc->xm;
+				npc->direct = 0;
+			}
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 0;
+				npc->ani_no = 0;
+				npc->act_wait = 0;
+			}
+
+			break;
+	}
+
+	bool bJump = false;
+
+	if (npc->act_no < 10 && npc->act_no != 3 && npc->act_wait > 10)
+	{
+		if (npc->shock)
+			bJump = true;
+
+		if (npc->x >= gMC.x - 0x14000 && npc->x <= gMC.x + 0x14000 && npc->y >= gMC.y - 0x8000 && npc->y <= gMC.y + 0x8000)
+		{
+			if (Random(0, 50) == 2)
+				bJump = true;
+		}
+	}
+
+	if (bJump)
+	{
+		if (gMC.x > npc->x)
+			npc->direct = 0;
+		else
+			npc->direct = 2;
+
+		npc->act_no = 10;
+		npc->ani_no = 2;
+		npc->ym = -0x5FF;
+
+		if (!(gMC.cond & 2))
+			PlaySoundObject(30, 1);
+
+		if (npc->direct == 0)
+			npc->xm = -0x200u;
+		else
+			npc->xm = 0x200;
+	}
+
+	npc->ym += 0x80;
+	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];
+}
+
+//'HEY!' speech bubble (low)
+void ActNpc105(NPCHAR *npc)
+{
+	RECT rect[2];
+
+	rect[0] = {128, 32, 144, 48};
+	rect[1] = {128, 32, 128, 32};
+
+	if (++npc->act_wait > 30)
+		npc->cond = 0;
+
+	if (npc->act_wait <= 4)
+		npc->y -= 0x200;
+
+	npc->rect = rect[npc->ani_no];
+}
+
+//'HEY!' speech bubble (high)
+void ActNpc106(NPCHAR *npc)
+{
+	if (npc->act_no == 0)
+	{
+		SetNpChar(105, npc->x, npc->y - 0x1000, 0, 0, 0, 0, 0x180);
+		npc->act_no = 1;
+	}
+}
+
+//Malco
+void ActNpc107(NPCHAR *npc)
+{
+	switch ( npc->act_no )
+	{
+		case 0:
+			npc->act_no = 1;
+
+			if (npc->direct == 2)
+				npc->ani_no = 5;
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->act_wait = 0;
+			npc->ani_wait = 0;
+
+			for (int i = 0; i < 4; ++i)
+				SetNpChar(4, npc->x, npc->y, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+			// Fallthrough
+		case 11:
+			if (++npc->ani_wait > 1)
+			{
+				PlaySoundObject(43, 1);
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (++npc->act_wait > 100)
+				npc->act_no = 12;
+
+			break;
+
+		case 12:
+			npc->act_no = 13;
+			npc->act_wait = 0;
+			npc->ani_no = 1;
+			// Fallthrough
+		case 13:
+			if (++npc->act_wait > 50)
+				npc->act_no = 14;
+
+			break;
+
+		case 14:
+			npc->act_no = 15;
+			npc->act_wait = 0;
+			// Fallthrough
+		case 15:
+			if (npc->act_wait / 2 % 2)
+			{
+				npc->x += 0x200;
+				PlaySoundObject(11, 1);
+			}
+			else
+			{
+				npc->x -= 0x200;
+			}
+
+			if (++npc->act_wait > 50)
+				npc->act_no = 16;
+
+			break;
+
+		case 16:
+			npc->act_no = 17;
+			npc->act_wait = 0;
+			npc->ani_no = 2;
+			PlaySoundObject(12, 1);
+
+			for (int i = 0; i < 8; ++i)
+				SetNpChar(4, npc->x, npc->y, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+			// Fallthrough
+		case 17:
+			if (++npc->act_wait > 150)
+				npc->act_no = 18;
+
+			break;
+
+		case 18:
+			npc->act_no = 19;
+			npc->act_wait = 0;
+			npc->ani_no = 3;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 19:
+			if (++npc->ani_wait > 3)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 4)
+			{
+				PlaySoundObject(11, 1);
+				npc->ani_no = 3;
+			}
+
+			if (++npc->act_wait > 100)
+			{
+				npc->act_no = 20;
+				PlaySoundObject(12, 1);
+
+				for (int i = 0; i < 4; ++i)
+					SetNpChar(4, npc->x, npc->y, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+			}
+
+			break;
+
+		case 20:
+			npc->ani_no = 4;
+			break;
+
+		case 21:
+			npc->act_no = 22;
+			npc->ani_no = 5;
+			PlaySoundObject(51, 1);
+			break;
+
+		case 100:
+			npc->act_no = 101;
+			npc->ani_no = 6;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 101:
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 9)
+				npc->ani_no = 6;
+
+			break;
+
+		case 110:
+			SetDestroyNpChar(npc->x, npc->y, 0x2000, 16);
+			npc->cond = 0;
+			break;
+	}
+
+	RECT rcPoweron[10];
+
+	rcPoweron[0] = {144, 0, 160, 24};
+	rcPoweron[1] = {160, 0, 176, 24};
+	rcPoweron[2] = {176, 0, 192, 24};
+	rcPoweron[3] = {192, 0, 208, 24};
+	rcPoweron[4] = {208, 0, 224, 24};
+	rcPoweron[5] = {224, 0, 240, 24};
+	rcPoweron[6] = {176, 0, 192, 24};
+	rcPoweron[7] = {192, 0, 208, 24};
+	rcPoweron[8] = {208, 0, 224, 24};
+	rcPoweron[9] = {192, 0, 208, 24};
+
+	npc->rect = rcPoweron[npc->ani_no];
+}
+
+//Balfrog projectile
+void ActNpc108(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[3];
+
+	rect_left[0] = {96, 48, 112, 64};
+	rect_left[1] = {112, 48, 128, 64};
+	rect_left[2] = {128, 48, 144, 64};
+
+	if (++npc->ani_wait > 1)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	npc->rect = rect_left[npc->ani_no];
+
+	if (++npc->count1 > 300)
+	{
+		SetCaret(npc->x, npc->y, 2, 0);
+		npc->cond = 0;
+	}
+}
+
+//Malco (broken)
+void ActNpc109(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {240, 0, 256, 24};
+	rcLeft[1] = {256, 0, 272, 24};
+
+	rcRight[0] = {240, 24, 256, 48};
+	rcRight[1] = {256, 24, 272, 48};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			if (--npc->act_wait)
+				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;
+			}
+
+			if (gMC.x > npc->x - 0x4000 && gMC.x < npc->x + 0x4000 && gMC.y > npc->y - 0x4000 && gMC.y < npc->y + 0x2000)
+			{
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->act_no = 0;
+			PlaySoundObject(12, 1);
+
+			for (int i = 0; i < 8; ++i)
+				SetNpChar(4, npc->x, npc->y, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+			break;
+	}
+
+	npc->ym += 0x40;
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->y += npc->ym;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Puchi
+void ActNpc110(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {96, 128, 112, 144};
+	rcLeft[1] = {112, 128, 128, 144};
+	rcLeft[2] = {128, 128, 144, 144};
+
+	rcRight[0] = {96, 144, 112, 160};
+	rcRight[1] = {112, 144, 128, 160};
+	rcRight[2] = {128, 144, 144, 160};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->act_wait = 0;
+			npc->xm = 0;
+			npc->ym = 0;
+
+			if (npc->direct == 4)
+			{
+				if (Random(0, 1) != 0)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+
+				npc->bits |= 8;
+				npc->ani_no = 2;
+				npc->act_no = 3;
+
+				break;
+			}
+			else
+			{
+				npc->bits &= ~8;
+			}
+			// Fallthrough
+		case 1:
+			++npc->act_wait;
+
+			if (Random(0, 50) == 1)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+				npc->ani_wait = 0;
+			}
+
+			break;
+
+		case 2:
+			++npc->act_wait;
+
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (npc->act_wait > 18)
+			{
+				npc->act_no = 1;
+				npc->act_no = 1;
+			}
+
+			break;
+
+		case 3:
+			if (++npc->act_wait > 40)
+				npc->bits &= ~8;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 0;
+				npc->ani_no = 0;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			// Fallthrough
+		case 11:
+			if (npc->flag & 1 && npc->xm < 0)
+			{
+				npc->xm = -npc->xm;
+				npc->direct = 2;
+			}
+
+			if (npc->flag & 4 && npc->xm > 0)
+			{
+				npc->xm = -npc->xm;
+				npc->direct = 0;
+			}
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 0;
+				npc->ani_no = 0;
+				npc->act_wait = 0;
+			}
+
+			break;
+	}
+
+	bool bJump = false;
+
+	if (npc->act_no < 10 && npc->act_no != 3 && npc->act_wait > 10)
+	{
+		if (npc->shock)
+			bJump = true;
+
+		if (npc->x >= gMC.x - 0x14000 && npc->x <= gMC.x + 0x14000 && npc->y >= gMC.y - 0x8000 && npc->y <= gMC.y + 0x8000)
+		{
+			if (Random(0, 50) == 2)
+				bJump = true;
+		}
+	}
+
+	if (bJump)
+	{
+		if (gMC.x > npc->x)
+			npc->direct = 2;
+		else
+			npc->direct = 0;
+
+		npc->act_no = 10;
+		npc->ani_no = 2;
+		npc->ym = -0x2FF;
+		PlaySoundObject(6, 1);
+
+		if (npc->direct == 0)
+			npc->xm = -0x100u;
+		else
+			npc->xm = 0x100;
+	}
+
+	npc->ym += 0x80;
+	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];
+}
+
 //Quote (teleport out)
 void ActNpc111(NPCHAR *npc)
 {
@@ -171,6 +906,364 @@
 	}
 }
 
+//Professor Booster
+void ActNpc113(NPCHAR *npc)
+{
+	RECT rcLeft[7];
+	RECT rcRight[7];
+
+	rcLeft[0] = {224, 0, 240, 16};
+	rcLeft[1] = {240, 0, 256, 16};
+	rcLeft[2] = {256, 0, 272, 16};
+	rcLeft[3] = {224, 0, 240, 16};
+	rcLeft[4] = {272, 0, 288, 16};
+	rcLeft[5] = {224, 0, 240, 16};
+	rcLeft[6] = {288, 0, 304, 16};
+
+	rcRight[0] = {224, 16, 240, 32};
+	rcRight[1] = {240, 16, 256, 32};
+	rcRight[2] = {256, 16, 272, 32};
+	rcRight[3] = {224, 16, 240, 32};
+	rcRight[4] = {272, 16, 288, 32};
+	rcRight[5] = {224, 16, 240, 32};
+	rcRight[6] = {288, 16, 304, 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;
+
+		case 3:
+			npc->act_no = 4;
+			npc->ani_no = 2;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 4:
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 2;
+
+			if (npc->direct == 0)
+				npc->x -= 0x200;
+			else
+				npc->x += 0x200;
+
+			break;
+
+		case 5:
+			npc->ani_no = 6;
+			break;
+
+		case 30:
+			npc->act_no = 31;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			npc->hit.bottom = 0x2000;
+			npc->x -= 0x2000;
+			npc->y += 0x1000;
+			PlaySoundObject(29, 1);
+			// Fallthrough
+		case 31:
+			if (++npc->act_wait == 64)
+			{
+				npc->act_no = 32;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 32:
+			if (++npc->act_wait > 20)
+			{
+				npc->act_no = 33;
+				npc->ani_no = 1;
+				npc->hit.bottom = 0x1000;
+			}
+
+			break;
+
+		case 33:
+			if (npc->flag & 8)
+			{
+				npc->act_no = 34;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	npc->ym += 0x40;
+	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 == 31)
+	{
+		npc->rect.bottom = npc->rect.top + npc->act_wait / 4;
+
+		if (npc->act_wait / 2 % 2)
+			++npc->rect.left;
+	}
+}
+
+//Press
+void ActNpc114(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 (!(npc->flag & 8))
+			{
+				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 = 1;
+				npc->ani_no = 0;
+				npc->damage = 0;
+				npc->bits |= 0x40;
+			}
+	}
+
+	npc->ym += 0x20;
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->y += npc->ym;
+
+	npc->rect = rcLeft[npc->ani_no];
+}
+
+//Ravil
+void ActNpc115(NPCHAR *npc)
+{
+	RECT rcLeft[6];
+	RECT rcRight[6];
+
+	rcLeft[0] = {0, 120, 24, 144};
+	rcLeft[1] = {24, 120, 48, 144};
+	rcLeft[2] = {48, 120, 72, 144};
+	rcLeft[3] = {72, 120, 96, 144};
+	rcLeft[4] = {96, 120, 120, 144};
+	rcLeft[5] = {120, 120, 144, 144};
+
+	rcRight[0] = {0, 144, 24, 168};
+	rcRight[1] = {24, 144, 48, 168};
+	rcRight[2] = {48, 144, 72, 168};
+	rcRight[3] = {72, 144, 96, 168};
+	rcRight[4] = {96, 144, 120, 168};
+	rcRight[5] = {120, 144, 144, 168};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->xm = 0;
+			npc->act_no = 1;
+			npc->act_wait = 0;
+			npc->count1 = 0;
+			// Fallthrough
+		case 1:
+			if (gMC.x < npc->x + 0xC000 && gMC.x > npc->x - 0xC000 && gMC.y < npc->y + 0x4000 && gMC.y > npc->y - 0xC000)
+				npc->act_no = 10;
+
+			if (npc->shock)
+				npc->act_no = 10;
+
+			break;
+
+		case 10:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			npc->ani_no = 1;
+
+			if (++npc->act_wait > 20)
+			{
+				npc->act_wait = 0;
+				npc->act_no = 20;
+			}
+
+			break;
+
+		case 20:
+			npc->damage = 0;
+			npc->xm = 0;
+
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 2)
+			{
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+
+				if (npc->direct == 0)
+					npc->xm = -0x200u;
+				else
+					npc->xm = 0x200;
+
+				if (++npc->count1 > 2)
+				{
+					npc->count1 = 0;
+					npc->ani_no = 4;
+					npc->act_no = 21;
+					npc->ym = -0x400u;
+					npc->xm *= 2;
+					npc->damage = 5;
+					PlaySoundObject(102, 1);
+				}
+				else
+				{
+					npc->act_no = 21;
+					npc->ym = -0x400u;
+					PlaySoundObject(30, 1);
+				}
+			}
+
+			break;
+
+		case 21:
+			if (npc->flag & 8)
+			{
+				PlaySoundObject(23, 1);
+				npc->act_no = 20;
+				npc->ani_no = 1;
+				npc->ani_wait = 0;
+				npc->damage = 0;
+
+				if (gMC.x > npc->x + 0x12000 || gMC.x < npc->x - 0x12000 || gMC.y > npc->y + 0x6000 || gMC.y < npc->y - 0x12000)
+					npc->act_no = 0;
+			}
+
+			break;
+
+		case 30:
+			for (int i = 0; i < 8; ++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->ani_no = 0;
+			npc->act_no = 0;
+
+			break;
+
+		case 50:
+			npc->act_no = 51;
+			npc->ani_no = 4;
+			npc->damage = 0;
+			npc->ym = -0x200;
+			npc->bits &= ~0x21;
+			PlaySoundObject(51, 1);
+			// Fallthrough
+		case 51:
+			if (npc->flag & 8)
+			{
+				PlaySoundObject(23, 1);
+				npc->act_no = 52;
+				npc->ani_no = 5;
+				npc->xm = 0;
+			}
+
+			break;
+	}
+
+	if (npc->act_no > 50)
+		npc->ym += 0x20;
+	else
+		npc->ym += 0x40;
+
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
 //Red petals
 void ActNpc116(NPCHAR *npc)
 {
@@ -179,6 +1272,391 @@
 	rc[0] = {272, 184, 320, 200};
 
 	npc->rect = rc[0];
+}
+
+//Curly
+void ActNpc117(NPCHAR *npc)
+{
+	RECT rcLeft[10];
+	RECT rcRight[10];
+
+	rcLeft[0] = {0, 96, 16, 112};
+	rcLeft[1] = {16, 96, 32, 112};
+	rcLeft[2] = {0, 96, 16, 112};
+	rcLeft[3] = {32, 96, 48, 112};
+	rcLeft[4] = {0, 96, 16, 112};
+	rcLeft[5] = {176, 96, 192, 112};
+	rcLeft[6] = {112, 96, 128, 112};
+	rcLeft[7] = {160, 96, 176, 112};
+	rcLeft[8] = {144, 96, 160, 112};
+	rcLeft[9] = {48, 96, 64, 112};
+
+	rcRight[0] = {0, 112, 16, 128};
+	rcRight[1] = {16, 112, 32, 128};
+	rcRight[2] = {0, 112, 16, 128};
+	rcRight[3] = {32, 112, 48, 128};
+	rcRight[4] = {0, 112, 16, 128};
+	rcRight[5] = {176, 112, 192, 128};
+	rcRight[6] = {112, 112, 128, 128};
+	rcRight[7] = {160, 112, 176, 128};
+	rcRight[8] = {144, 112, 160, 128};
+	rcRight[9] = {48, 112, 64, 128};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			if (npc->direct == 4)
+			{
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 1:
+			npc->xm = 0;
+			npc->ym += 0x40;
+			break;
+
+		case 3:
+			npc->act_no = 4;
+			npc->ani_no = 1;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 4:
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 4)
+				npc->ani_no = 1;
+
+			npc->ym += 0x40;
+
+			if (npc->direct == 0)
+				npc->xm = -0x200;
+			else
+				npc->xm = 0x200;
+
+			break;
+
+		case 5:
+			npc->act_no = 6;
+			npc->ani_no = 5;
+			SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8);
+			break;
+
+		case 6:
+			npc->ani_no = 5;
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 1;
+			npc->ani_wait = 0;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			// Fallthrough
+		case 11:
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 4)
+				npc->ani_no = 1;
+
+			if (npc->direct == 0)
+				npc->x -= 0x200;
+			else
+				npc->x += 0x200;
+
+			if (gMC.x < npc->x + 0x2800 && gMC.x > npc->x - 0x2800)
+				npc->act_no = 0;
+
+			break;
+
+		case 20:
+			npc->xm = 0;
+			npc->ani_no = 6;
+			break;
+
+		case 21:
+			npc->xm = 0;
+			npc->ani_no = 9;
+			break;
+
+		case 30:
+			npc->act_no = 31;
+			npc->act_wait = 0;
+			npc->ym = -0x400u;
+			// Fallthrough
+		case 31:
+			npc->ani_no = 7;
+
+			if (npc->direct == 0)
+				npc->xm = 0x200;
+			else
+				npc->xm = -0x200u;
+
+			npc->ym += 0x40;
+
+			if (npc->act_wait++ && npc->flag & 8)
+				npc->act_no = 32;
+
+			break;
+
+		case 32:
+			npc->ym += 0x40;
+			npc->ani_no = 8;
+			npc->xm = 0;
+			break;
+
+		case 70:
+			npc->act_no = 71;
+			npc->act_wait = 0;
+			npc->ani_no = 1;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 71:
+			if (npc->direct == 0)
+				npc->x += 0x100;
+			else
+				npc->x -= 0x100;
+
+			if (++npc->ani_wait > 8)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 4)
+				npc->ani_no = 1;
+
+			break;
+	}
+
+	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];
+}
+
+//Curly (boss)
+void ActNpc118(NPCHAR *npc)
+{
+	RECT rcLeft[9];
+	RECT rcRight[9];
+
+	rcLeft[0] = {0, 32, 32, 56};
+	rcLeft[1] = {32, 32, 64, 56};
+	rcLeft[2] = {64, 32, 96, 56};
+	rcLeft[3] = {96, 32, 128, 56};
+	rcLeft[4] = {0, 32, 32, 56};
+	rcLeft[5] = {128, 32, 160, 56};
+	rcLeft[6] = {0, 32, 32, 56};
+	rcLeft[7] = {0, 32, 32, 56};
+	rcLeft[8] = {160, 32, 192, 56};
+
+	rcRight[0] = {0, 56, 32, 80};
+	rcRight[1] = {32, 56, 64, 80};
+	rcRight[2] = {64, 56, 96, 80};
+	rcRight[3] = {96, 56, 128, 80};
+	rcRight[4] = {0, 56, 32, 80};
+	rcRight[5] = {128, 56, 160, 80};
+	rcRight[6] = {0, 56, 32, 80};
+	rcRight[7] = {0, 56, 32, 80};
+	rcRight[8] = {160, 56, 192, 80};
+
+	bool bUpper = false;
+
+	if (npc->direct == 0 && gMC.x > npc->x)
+		bUpper = true;
+	if ( npc->direct == 2 && gMC.x < npc->x)
+		bUpper = true;
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->act_wait = Random(50, 100);
+			npc->ani_no = 0;
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			npc->bits |= 0x20u;
+			npc->bits &= ~4u;
+			// Fallthrough
+		case 11:
+			if (npc->act_wait)
+				--npc->act_wait;
+			else
+				npc->act_no = 13;
+
+			break;
+
+		case 13:
+			npc->act_no = 14;
+			npc->ani_no = 3;
+			npc->act_wait = Random(50, 100);
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+			// Fallthrough
+		case 14:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 6)
+				npc->ani_no = 3;
+
+			if (npc->direct == 0)
+				npc->xm -= 0x40;
+			else
+				npc->xm += 0x40;
+
+			if (npc->act_wait)
+			{
+				--npc->act_wait;
+			}
+			else
+			{
+				npc->bits |= 0x20u;
+				npc->act_no = 20;
+				npc->act_wait = 0;
+				PlaySoundObject(103, 1);
+			}
+
+			break;
+
+		case 20:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			npc->xm = 8 * npc->xm / 9;
+
+			if (++npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (++npc->act_wait > 50)
+			{
+				npc->act_no = 21;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 21:
+			if (++npc->act_wait % 4 == 1)
+			{
+				if (npc->direct == 0)
+				{
+					if (bUpper)
+					{
+						npc->ani_no = 2;
+						SetNpChar(123, npc->x, npc->y - 0x1000, 0, 0, 1, 0, 0x100);
+					}
+					else
+					{
+						npc->ani_no = 0;
+						SetNpChar(123, npc->x - 0x1000, npc->y + 0x800, 0, 0, 0, 0, 0x100);
+						npc->x += 0x200;
+					}
+				}
+				else
+				{
+					if (bUpper)
+					{
+						npc->ani_no = 2;
+						SetNpChar(123, npc->x, npc->y - 0x1000, 0, 0, 1, 0, 0x100);
+					}
+					else
+					{
+						npc->ani_no = 0;
+						SetNpChar(123, npc->x + 0x1000, npc->y + 0x800, 0, 0, 2, 0, 0x100);
+						npc->x -= 0x200;
+					}
+				}
+			}
+
+			if (npc->act_wait > 30)
+				npc->act_no = 10;
+
+			break;
+
+		case 30:
+			if (++npc->ani_no > 8)
+				npc->ani_no = 7;
+
+			if (++npc->act_wait > 30)
+			{
+				npc->act_no = 10;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	if (npc->act_no > 10 && npc->act_no < 30 && CountArmsBullet(6))
+	{
+		npc->act_wait = 0;
+		npc->act_no = 30;
+		npc->ani_no = 7;
+		npc->bits &= ~0x20;
+		npc->bits |= 4;
+		npc->xm = 0;
+	}
+
+	npc->ym += 0x20;
+
+	if (npc->xm > 0x1FF)
+		npc->xm = 0x1FF;
+	if (npc->xm < -0x1FF)
+		npc->xm = -0x1FF;
+
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->y += npc->ym;
+	npc->x += npc->xm;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
 }
 
 //Table and chair
--- a/src/NpcAct120.cpp
+++ b/src/NpcAct120.cpp
@@ -8,7 +8,392 @@
 #include "Sound.h"
 #include "Back.h"
 #include "Triangle.h"
+#include "Caret.h"
+#include "KeyControl.h"
+#include "Frame.h"
+#include "Bullet.h"
 
+//Colon (1)
+void ActNpc120(NPCHAR *npc)
+{
+	RECT rect[2];
+
+	rect[0] = {64, 0, 80, 16};
+	rect[1] = {64, 16, 80, 32};
+
+	if (npc->direct == 0)
+		npc->rect = rect[0];
+	else
+		npc->rect = rect[1];
+}
+
+//Colon (2)
+void ActNpc121(NPCHAR *npc)
+{
+	RECT rect[3];
+
+	rect[0] = {0, 0, 16, 16};
+	rect[1] = {16, 0, 32, 16};
+	rect[2] = {112, 0, 128, 16};
+
+	if (npc->direct == 0)
+	{
+		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 = rect[npc->ani_no];
+	}
+
+	npc->rect = rect[2];
+
+	if (++npc->act_wait > 100)
+	{
+		npc->act_wait = 0;
+		SetCaret(npc->x, npc->y, 5, 0);
+	}
+}
+
+//Colon (attacking)
+void ActNpc122(NPCHAR *npc)
+{
+	RECT rcLeft[10];
+	RECT rcRight[10];
+
+	rcLeft[0] = {0, 0, 16, 16};
+	rcLeft[1] = {16, 0, 32, 16};
+	rcLeft[2] = {32, 0, 48, 16};
+	rcLeft[3] = {0, 0, 16, 16};
+	rcLeft[4] = {48, 0, 64, 16};
+	rcLeft[5] = {0, 0, 16, 16};
+	rcLeft[6] = {80, 0, 96, 16};
+	rcLeft[7] = {96, 0, 112, 16};
+	rcLeft[8] = {112, 0, 128, 16};
+	rcLeft[9] = {128, 0, 144, 16};
+
+	rcRight[0] = {0, 16, 16, 32};
+	rcRight[1] = {16, 16, 32, 32};
+	rcRight[2] = {32, 16, 48, 32};
+	rcRight[3] = {0, 16, 16, 32};
+	rcRight[4] = {48, 16, 64, 32};
+	rcRight[5] = {0, 16, 16, 32};
+	rcRight[6] = {80, 16, 96, 32};
+	rcRight[7] = {96, 16, 112, 32};
+	rcRight[8] = {112, 16, 128, 32};
+	rcRight[9] = {128, 16, 144, 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;
+			}
+
+			if (gMC.x > npc->x - 0x4000 && gMC.x < npc->x + 0x4000 && gMC.y > npc->y - 0x4000 && gMC.y < npc->y + 0x2000)
+			{
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->life = 1000;
+			npc->act_no = 11;
+			npc->act_wait = Random(0, 50);
+			npc->ani_no = 0;
+			npc->damage = 0;
+			// Fallthrough
+		case 11:
+			if (npc->act_wait)
+				--npc->act_wait;
+			else
+				npc->act_no = 13;
+
+			break;
+
+		case 13:
+			npc->act_no = 14;
+			npc->act_wait = Random(0, 50);
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+			// Fallthrough
+		case 14:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 5)
+				npc->ani_no = 2;
+
+			if (npc->direct == 0)
+				npc->xm -= 0x40;
+			else
+				npc->xm += 0x40;
+
+			if (npc->act_wait)
+			{
+				--npc->act_wait;
+			}
+			else
+			{
+				npc->bits |= 0x20;
+				npc->act_no = 15;
+				npc->ani_no = 2;
+				npc->ym = -0x200;
+				npc->damage = 2;
+			}
+
+			break;
+
+		case 15:
+			if (npc->flag & 8)
+			{
+				npc->bits |= 0x20;
+				npc->xm = 0;
+				npc->act_no = 10;
+				npc->damage = 0;
+			}
+
+			break;
+
+		case 20:
+			if (npc->flag & 8)
+			{
+				npc->xm = 0;
+				npc->act_no = 21;
+				npc->damage = 0;
+
+				if (npc->ani_no == 6)
+					npc->ani_no = 8;
+				else
+					npc->ani_no = 9;
+
+				npc->act_wait = Random(300, 400);
+			}
+
+			break;
+
+		case 21:
+			if (npc->act_wait)
+			{
+				--npc->act_wait;
+			}
+			else
+			{
+				npc->bits |= 0x20;
+				npc->life = 1000;
+				npc->act_no = 11;
+				npc->act_wait = Random(0, 50);
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	if (npc->act_no > 10 && npc->act_no < 20 && npc->life != 1000)
+	{
+		npc->act_no = 20;
+		npc->ym = -0x200;
+		npc->ani_no = Random(6, 7);
+		npc->bits &= ~0x20;
+	}
+
+	npc->ym += 0x20;
+
+	if (npc->xm > 0x1FF)
+		npc->xm = 0x1FF;
+	if (npc->xm < -0x1FF)
+		npc->xm = -0x1FF;
+
+	if (npc->ym > 0x5FF )
+		npc->ym = 0x5FF;
+
+	npc->y += npc->ym;
+	npc->x += npc->xm;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Curly boss projectile
+void ActNpc123(NPCHAR *npc)
+{
+	RECT rect[4];
+
+	rect[0] = {192, 0, 208, 16};
+	rect[1] = {208, 0, 224, 16};
+	rect[2] = {224, 0, 240, 16};
+	rect[3] = {240, 0, 256, 16};
+
+	bool bBreak = false;
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			SetCaret(npc->x, npc->y, 3, 0);
+			PlaySoundObject(32, 1);
+
+			switch (npc->direct)
+			{
+				case 0:
+					npc->xm = -0x1000;
+					npc->ym = Random(-0x80, 0x80);
+					break;
+				case 1:
+					npc->ym = -0x1000;
+					npc->xm = Random(-0x80, 0x80);
+					break;
+				case 2:
+					npc->xm = 0x1000;
+					npc->ym = Random(-0x80, 0x80);
+					break;
+				case 3:
+					npc->ym = 0x1000;
+					npc->xm = Random(-0x80, 0x80);
+					break;
+			}
+
+			break;
+
+		case 1:
+			switch (npc->direct)
+			{
+				case 0:
+					if (npc->flag & 1)
+						bBreak = true;
+					break;
+				case 1:
+					if (npc->flag & 2)
+						bBreak = true;
+					break;
+				case 2:
+					if (npc->flag & 4)
+						bBreak = true;
+					break;
+				case 3:
+					if (npc->flag & 8)
+						bBreak = true;
+					break;
+			}
+
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+
+			break;
+	}
+
+	if (bBreak)
+	{
+		SetCaret(npc->x, npc->y, 2, 2);
+		PlaySoundObject(28, 1);
+		npc->cond = 0;
+	}
+
+	npc->rect = rect[npc->direct];
+}
+
+//Sunstone
+void ActNpc124(NPCHAR *npc)
+{
+	RECT rect[2];
+
+	rect[0] = {160, 0, 192, 32};
+	rect[1] = {192, 0, 224, 32};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->x += 0x1000;
+			npc->y += 0x1000;
+			// Fallthrough
+		case 1:
+			npc->bits &= ~8;
+			npc->ani_no = 0;
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 1;
+			npc->act_wait = 0;
+			npc->bits |= 8;
+			// Fallthrough
+		case 11:
+			switch (npc->direct)
+			{
+				case 0:
+					npc->x -= 0x80;
+					break;
+				case 1:
+					npc->y -= 0x80;
+					break;
+				case 2:
+					npc->x += 0x80;
+					break;
+				case 3:
+					npc->y += 0x80;
+					break;
+			}
+			if (++npc->act_wait % 8 == 0)
+				PlaySoundObject(26, 1);
+
+			SetQuake(20);
+			break;
+	}
+
+	npc->rect = rect[npc->ani_no];
+}
+
 //Hidden item
 void ActNpc125(NPCHAR *npc)
 {
@@ -36,6 +421,137 @@
 		npc->rect = rc[1];
 }
 
+//Puppy (running)
+void ActNpc126(NPCHAR *npc)
+{
+	RECT rcLeft[6];
+	RECT rcRight[6];
+
+	rcLeft[0] = {48, 144, 64, 160};
+	rcLeft[1] = {64, 144, 80, 160};
+	rcLeft[2] = {48, 144, 64, 160};
+	rcLeft[3] = {80, 144, 96, 160};
+	rcLeft[4] = {96, 144, 112, 160};
+	rcLeft[5] = {112, 144, 128, 160};
+
+	rcRight[0] = {48, 160, 64, 176};
+	rcRight[1] = {64, 160, 80, 176};
+	rcRight[2] = {48, 160, 64, 176};
+	rcRight[3] = {80, 160, 96, 176};
+	rcRight[4] = {96, 160, 112, 176};
+	rcRight[5] = {112, 160, 128, 176};
+
+	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;
+			}
+
+			if (gMC.x > npc->x - 0xC000 && gMC.x < npc->x + 0xC000 && gMC.y > npc->y - 0x4000 && gMC.y < npc->y + 0x2000)
+			{
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			if (gMC.x > npc->x - 0x4000 && gMC.x < npc->x + 0x4000 && gMC.y > npc->y - 0x4000 && gMC.y < npc->y + 0x2000)
+			{
+				if (gMC.x < npc->x)
+					npc->direct = 2;
+				else
+					npc->direct = 0;
+
+				npc->act_no = 10;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 4;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 11:
+			if (npc->flag & 8)
+			{
+				if (++npc->ani_wait > 2)
+				{
+					npc->ani_wait = 0;
+					++npc->ani_no;
+				}
+
+				if (npc->ani_no > 5)
+					npc->ani_no = 4;
+			}
+			else
+			{
+				npc->ani_no = 5;
+				npc->ani_wait = 0;
+			}
+
+			if (npc->xm < 0 && npc->flag & 1)
+			{
+				npc->xm /= -2;
+				npc->direct = 2;
+			}
+
+			if (npc->xm > 0 && npc->flag & 4)
+			{
+				npc->xm /= -2;
+				npc->direct = 0;
+			}
+
+			if (npc->direct == 0)
+				npc->xm -= 0x40;
+			else
+				npc->xm += 0x40;
+
+			if (npc->xm > 0x5FF)
+				npc->xm = 0x400;
+
+			if (npc->xm < -0x5FF)
+				npc->xm = -0x400;
+
+			break;
+	}
+
+	if (gKeyTrg & gKeyDown)
+		npc->bits |= 0x2000;
+	else
+		npc->bits &= ~0x2000;
+
+	npc->ym += 0x40;
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
 //Machine gun trail (Level 2)
 void ActNpc127(NPCHAR *npc)
 {
@@ -159,4 +675,742 @@
 	npc->y += npc->ym;
 	
 	npc->rect = rect[npc->ani_no + 3 * npc->direct];
+}
+
+//Puppy (sitting, wagging tail)
+void ActNpc130(NPCHAR *npc)
+{
+	RECT rcLeft[4];
+	RECT rcRight[4];
+
+	rcLeft[0] = {48, 144, 64, 160};
+	rcLeft[1] = {64, 144, 80, 160};
+	rcLeft[2] = {48, 144, 64, 160};
+	rcLeft[3] = {80, 144, 96, 160};
+
+	rcRight[0] = {48, 160, 64, 176};
+	rcRight[1] = {64, 160, 80, 176};
+	rcRight[2] = {48, 160, 64, 176};
+	rcRight[3] = {80, 160, 96, 176};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			npc->bits |= 0x2000;
+			// Fallthrough
+		case 1:
+			if (Random(0, 120) == 10)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			if (gMC.x > npc->x - 0x8000 && gMC.x < npc->x + 0x8000 && gMC.y > npc->y - 0x4000 && gMC.y < npc->y + 0x2000)
+			{
+				if (++npc->ani_wait > 3)
+				{
+					npc->ani_wait = 0;
+					++npc->ani_no;
+				}
+
+				if (npc->ani_no > 3)
+					npc->ani_no = 2;
+			}
+
+			if (gMC.x > npc->x - 0xC000 && gMC.x < npc->x + 0xC000 && gMC.y > npc->y - 0x4000 && gMC.y < npc->y + 0x2000)
+			{
+				if (gMC.x < npc->x)
+					npc->direct = 0;
+				else
+					npc->direct = 2;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				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 = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Puppy (sleeping)
+void ActNpc131(NPCHAR *npc)
+{
+	RECT rcLeft[1];
+	RECT rcRight[1];
+
+	rcLeft[0] = {144, 144, 160, 160};
+	rcRight[0] = {144, 160, 160, 176};
+
+	if (++npc->act_wait > 100)
+	{
+		npc->act_wait = 0;
+		SetCaret(npc->x, npc->y, 5, 0);
+	}
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Puppy (barking)
+void ActNpc132(NPCHAR *npc)
+{
+	RECT rcLeft[5];
+	RECT rcRight[5];
+
+	rcLeft[0] = {48, 144, 64, 160};
+	rcLeft[1] = {64, 144, 80, 160};
+	rcLeft[2] = {96, 144, 112, 160};
+	rcLeft[3] = {96, 144, 112, 160};
+	rcLeft[4] = {128, 144, 144, 160};
+
+	rcRight[0] = {48, 160, 64, 176};
+	rcRight[1] = {64, 160, 80, 176};
+	rcRight[2] = {96, 160, 112, 176};
+	rcRight[3] = {96, 160, 112, 176};
+	rcRight[4] = {128, 160, 144, 176};
+
+	if (npc->act_no < 100)
+	{
+		if (gMC.x < npc->x)
+			npc->direct = 0;
+		else
+			npc->direct = 2;
+	}
+
+	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;
+			}
+
+			if (gMC.x > npc->x - 0x8000 && gMC.x < npc->x + 0x8000 && gMC.y > npc->y - 0x2000 && gMC.y < npc->y + 0x2000)
+			{
+				if (++npc->ani_wait > 4)
+				{
+					npc->ani_wait = 0;
+					++npc->ani_no;
+				}
+
+				if (npc->ani_no > 4)
+					npc->ani_no = 2;
+
+				if (npc->ani_no == 4 && npc->ani_wait == 0)
+					PlaySoundObject(105, 1);
+			}
+			else
+			{
+				if (npc->ani_no == 4)
+					npc->ani_no = 2;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 1;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 11:
+			if (Random(0, 120) == 10)
+			{
+				npc->act_no = 12;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 12:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 11;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 100:
+			npc->act_no = 101;
+			npc->count1 = 0;
+			// Fallthrough
+		case 101:
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 4)
+			{
+				if (npc->count1 < 3)
+				{
+					npc->ani_no = 2;
+					++npc->count1;
+				}
+				else
+				{
+					npc->ani_no = 0;
+					npc->count1 = 0;
+				}
+			}
+
+			if (npc->ani_no == 4 && npc->ani_wait == 0)
+				PlaySoundObject(105, 1);
+
+			break;
+
+		case 120:
+			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 = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Jenka
+void ActNpc133(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {176, 32, 192, 48};
+	rcLeft[1] = {192, 32, 208, 48};
+
+	rcRight[0] = {176, 48, 192, 64};
+	rcRight[1] = {192, 48, 208, 64};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 1:
+			if (Random(0, 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];
+}
+
+//Armadillo
+void ActNpc134(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {224, 0, 256, 16};
+	rcLeft[1] = {256, 0, 288, 16};
+	rcLeft[2] = {288, 0, 320, 16};
+
+	rcRight[0] = {224, 16, 256, 32};
+	rcRight[1] = {256, 16, 288, 32};
+	rcRight[2] = {288, 16, 320, 32};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 2;
+			npc->bits &= ~0x20;
+			npc->bits |= 4;
+			// Fallthrough
+		case 1:
+			if (gMC.x > npc->x - 0x28000 && gMC.x < npc->x + 0x28000 && gMC.y > npc->y - 0x14000 && gMC.y < npc->y + 0x8000)	// TODO: Maybe do something about this for widescreen/tallscreen?
+			{
+				npc->act_no = 10;
+				npc->bits |= 0x20;
+				npc->bits &= ~4;
+			}
+
+			break;
+
+		case 10:
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (npc->direct == 0 && npc->flag & 1)
+				npc->direct = 2;
+			if (npc->direct == 2 && npc->flag & 4)
+				npc->direct = 0;
+
+			if (npc->direct == 0)
+				npc->x -= 0x100;
+			else
+				npc->x += 0x100;
+
+			if (CountArmsBullet(6))
+			{
+				npc->act_no = 20;
+				npc->act_wait = 0;
+				npc->ani_no = 2;
+				npc->bits &= ~0x20;
+				npc->bits |= 4;
+			}
+
+			break;
+
+		case 20:
+			if (++npc->act_wait > 100)
+			{
+				npc->act_no = 10;
+				npc->ani_no = 0;
+				npc->ani_wait = 0;
+				npc->bits |= 0x20;
+				npc->bits &= ~4;
+			}
+
+			break;
+	}
+
+	npc->ym += 0x40;
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	npc->y += npc->ym;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Skeleton
+void ActNpc135(NPCHAR *npc)
+{
+	RECT rcRight[2];
+	RECT rcLeft[2];
+
+	rcLeft[0] = {256, 32, 288, 64};
+	rcLeft[1] = {288, 32, 320, 64};
+
+	rcRight[0] = {256, 64, 288, 96};
+	rcRight[1] = {288, 64, 320, 96};
+
+	if (gMC.x < npc->x - 0x2C000 || gMC.x > npc->x + 0x2C000 || gMC.y < npc->y - 0x14000 || gMC.y > npc->y + 0x8000)
+		npc->act_no = 0;
+
+	switch ( npc->act_no )
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->xm = 0;
+			// Fallthrough
+		case 1:
+			if (gMC.x > npc->x - 0x28000 && gMC.x < npc->x + 0x28000 && gMC.y > npc->y - 0x14000 && gMC.y < npc->y + 0x8000)
+				npc->act_no = 10;
+
+			if (npc->flag & 8)
+				npc->ani_no = 0;
+
+			break;
+
+		case 10:
+			npc->xm = 0;
+			npc->act_no = 11;
+			npc->act_wait = 0;
+			npc->ani_no = 0;
+			// Fallthrough
+		case 11:
+			if (++npc->act_wait >= 5 && npc->flag & 8)
+			{
+				npc->act_no = 20;
+				npc->ani_no = 1;
+				npc->count1 = 0;
+				npc->ym = -0x200 * Random(1, 3);
+
+				if (npc->shock == 0)
+				{
+					if (gMC.x > npc->x)
+						npc->xm += 0x100;
+					else
+						npc->xm -= 0x100;
+				}
+				else
+				{
+					if (gMC.x > npc->x)
+						npc->xm -= 0x100;
+					else
+						npc->xm += 0x100;
+				}
+			}
+
+			break;
+
+		case 20:
+			if (npc->ym > 0 && npc->count1 == 0)
+			{
+				++npc->count1;
+				const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y + 0x800 - gMC.y);
+				const int ym = 2 * GetSin(deg);
+				const int xm = 2 * GetCos(deg);
+				SetNpChar(50, npc->x, npc->y, xm, ym, 0, 0, 0x180);
+				PlaySoundObject(39, 1);
+			}
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 10;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	if (npc->act_no >= 10)
+	{
+		if (gMC.x < npc->x)
+			npc->direct = 0;
+		else
+			npc->direct = 2;
+	}
+
+	npc->ym += 0x33;
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+
+	if (npc->xm > 0x5FF)
+		npc->xm = 0x5FF;
+	if (npc->xm < -0x5FF)
+		npc->xm = -0x5FF;
+
+	npc->y += npc->ym;
+	npc->x += npc->xm;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Puppy (carried)
+void ActNpc136(NPCHAR *npc)
+{
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {48, 144, 64, 160};
+	rcLeft[1] = {64, 144, 80, 160};
+
+	rcRight[0] = {48, 160, 64, 176};
+	rcRight[1] = {64, 160, 80, 176};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->bits &= ~0x2000;
+			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 (gMC.direct == 0)
+		npc->direct = 0;
+	else
+		npc->direct = 2;
+
+	npc->y = gMC.y - 0x1400;
+
+	if (npc->direct == 0)
+	{
+		npc->x = gMC.x + 0x800;
+		npc->rect = rcLeft[npc->ani_no];
+	}
+	else
+	{
+		npc->x = gMC.x - 0x800;
+		npc->rect = rcRight[npc->ani_no];
+	}
+
+	if (gMC.ani_no % 2)
+		++npc->rect.top;
+}
+
+//Large door (frame)
+void ActNpc137(NPCHAR *npc)
+{
+	RECT rc[1];
+
+	rc[0] = {96, 136, 128, 188};
+
+	npc->rect = rc[0];
+}
+
+//Large door (door)
+void ActNpc138(NPCHAR *npc)
+{
+	RECT rcLeft[1];
+	RECT rcRight[1];
+
+	rcLeft[0] = {96, 112, 112, 136};
+	rcRight[0] = {112, 112, 128, 136};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+
+			if (npc->direct == 0)
+			{
+				npc->rect = rcLeft[0];
+				npc->x += 0x1000;
+			}
+			else
+			{
+				npc->rect = rcRight[0];
+				npc->x -= 0x1000;
+			}
+
+			npc->tgt_x = npc->x;
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 1;
+			npc->act_wait = 0;
+			npc->bits |= 8;
+			// Fallthrough
+		case 11:
+			if (++npc->act_wait % 8 == 0)
+				PlaySoundObject(26, 1);
+
+			if (npc->direct == 0)
+			{
+				npc->rect = rcLeft[0];
+				npc->rect.left += npc->act_wait / 8;
+			}
+			else
+			{
+				npc->x = npc->tgt_x + ((npc->act_wait / 8) * 0x200);
+				npc->rect = rcRight[0];
+				npc->rect.right -= npc->act_wait / 8;
+			}
+
+			if (npc->act_wait == 104)
+				npc->cond = 0;
+
+			break;
+	}
+}
+
+//Doctor
+void ActNpc139(NPCHAR *npc)
+{
+	RECT rcLeft[3];
+	RECT rcRight[3];
+
+	rcLeft[0] = {0, 128, 24, 160};
+	rcLeft[1] = {24, 128, 48, 160};
+	rcLeft[2] = {48, 128, 72, 160};
+
+	rcRight[0] = {0, 160, 24, 192};
+	rcRight[1] = {24, 160, 48, 192};
+	rcRight[2] = {48, 160, 72, 192};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->xm = 0;
+			npc->ym = 0;
+			npc->y -= 0x1000;
+			// Fallthrough
+		case 1:
+			if (npc->flag & 8)
+				npc->ani_no = 0;
+			else
+				npc->ani_no = 2;
+
+			npc->ym += 0x40;
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 1;
+			npc->ani_wait = 0;
+			npc->count1 = 0;
+			// Fallthrough
+		case 11:
+			if (++npc->ani_wait > 6)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+			{
+				npc->ani_no = 0;
+				++npc->count1;
+			}
+
+			if (npc->count1 > 8)
+			{
+				npc->ani_no = 0;
+				npc->act_no = 1;
+			}
+
+			break;
+
+		case 20:
+			npc->act_no = 21;
+			npc->act_wait = 0;
+			npc->ani_no = 2;
+			npc->tgt_y = npc->y - 0x4000;
+			// Fallthrough
+		case 21:
+			if (npc->y < npc->tgt_y)
+				npc->ym += 0x20;
+			else
+				npc->ym -= 0x20;
+
+			if (npc->ym > 0x200)
+				npc->ym = 0x200;
+			if (npc->ym < -0x200)
+				npc->ym = -0x200;
+
+			break;
+
+		case 30:
+			npc->act_no = 31;
+			npc->xm = 0;
+			npc->ym = 0;
+			npc->act_wait = 2 * (npc->rect.bottom - npc->rect.top);
+			PlaySoundObject(29, 1);
+			// Fallthrough
+		case 31:
+			--npc->act_wait;
+			npc->ani_no = 0;
+
+			if (npc->act_wait == 0)
+				npc->cond = 0;
+
+			break;
+
+		case 40:
+			npc->act_no = 41;
+			npc->act_wait = 0;
+			npc->xm = 0;
+			npc->ym = 0;
+			PlaySoundObject(29, 1);
+			// Fallthrough
+		case 41:
+			npc->ani_no = 2;
+
+			if (++npc->act_wait >= 64)
+				npc->act_no = 20;
+
+			break;
+	}
+
+	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 == 31 || npc->act_no == 41)
+	{
+		npc->rect.bottom = npc->rect.top + npc->act_wait / 2;
+
+		if (npc->act_wait / 2 % 2)
+			++npc->rect.left;
+	}
 }
--- a/src/NpcAct140.cpp
+++ b/src/NpcAct140.cpp
@@ -8,7 +8,654 @@
 #include "Sound.h"
 #include "Back.h"
 #include "Triangle.h"
+#include "Caret.h"
+#include "Frame.h"
+#include "Flash.h"
+#include "Bullet.h"
 
+//Toroko (frenzied)
+void ActNpc140(NPCHAR *npc)
+{
+	RECT rcLeft[14];
+	RECT rcRight[14];
+
+	rcLeft[0] = {0, 0, 32, 32};
+	rcLeft[1] = {32, 0, 64, 32};
+	rcLeft[2] = {64, 0, 96, 32};
+	rcLeft[3] = {96, 0, 128, 32};
+	rcLeft[4] = {128, 0, 160, 32};
+	rcLeft[5] = {160, 0, 192, 32};
+	rcLeft[6] = {192, 0, 224, 32};
+	rcLeft[7] = {224, 0, 256, 32};
+	rcLeft[8] = {0, 64, 32, 96};
+	rcLeft[9] = {32, 64, 64, 96};
+	rcLeft[10] = {64, 64, 96, 96};
+	rcLeft[11] = {96, 64, 128, 96};
+	rcLeft[12] = {128, 64, 160, 96};
+	rcLeft[13] = {0, 0, 0, 0};
+
+	rcRight[0] = {0, 32, 32, 64};
+	rcRight[1] = {32, 32, 64, 64};
+	rcRight[2] = {64, 32, 96, 64};
+	rcRight[3] = {96, 32, 128, 64};
+	rcRight[4] = {128, 32, 160, 64};
+	rcRight[5] = {160, 32, 192, 64};
+	rcRight[6] = {192, 32, 224, 64};
+	rcRight[7] = {224, 32, 256, 64};
+	rcRight[8] = {0, 96, 32, 128};
+	rcRight[9] = {32, 96, 64, 128};
+	rcRight[10] = {64, 96, 96, 128};
+	rcRight[11] = {96, 96, 128, 128};
+	rcRight[12] = {128, 96, 160, 128};
+	rcRight[13] = {0, 0, 0, 0};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 9;
+			npc->act_wait = 0;
+			npc->bits &= ~0x2000;
+			// Fallthrough
+		case 1:
+			if (++npc->act_wait > 50)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+				npc->ani_no = 8;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->ani_no > 10)
+				npc->ani_no = 9;
+
+			if (++npc->act_wait > 50)
+			{
+				npc->act_no = 3;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 3:
+			if (++npc->act_wait > 50)
+			{
+				npc->act_no = 10;
+				npc->bits |= 0x20;
+			}
+
+			break;
+
+		case 10:
+			npc->bits = npc->bits;
+			npc->act_no = 11;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			npc->act_wait = Random(20, 130);
+			npc->xm = 0;
+			// Fallthrough
+		case 11:
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			if (++npc->ani_wait > 4)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (CountArmsBullet(6) || CountArmsBullet(3) > 3)
+				npc->act_no = 20;
+
+			if (npc->act_wait)
+			{
+				--npc->act_wait;
+			}
+			else
+			{
+				if (Random(0, 99) % 2)
+					npc->act_no = 20;
+				else
+					npc->act_no = 50;
+			}
+
+			break;
+
+		case 20:
+			npc->act_no = 21;
+			npc->ani_no = 2;
+			npc->act_wait = 0;
+			// Fallthrough
+		case 21:
+			if (++npc->act_wait > 10)
+			{
+				npc->act_no = 22;
+				npc->act_wait = 0;
+				npc->ani_no = 3;
+				npc->ym = -0x5FF;
+
+				if (npc->direct == 0)
+					npc->xm = -0x200u;
+				else
+					npc->xm = 0x200;
+			}
+
+			break;
+
+		case 22:
+			if (++npc->act_wait > 10)
+			{
+				npc->act_no = 23;
+				npc->act_wait = 0;
+				npc->ani_no = 6;
+				SetNpChar(141, 0, 0, 0, 0, 0, npc, 0);
+			}
+
+			break;
+
+		case 23:
+			if (++npc->act_wait > 30)
+			{
+				npc->act_no = 24;
+				npc->act_wait = 0;
+				npc->ani_no = 7;
+			}
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			break;
+
+		case 24:
+			if (++npc->act_wait > 3)
+			{
+				npc->act_no = 25;
+				npc->ani_no = 3;
+			}
+
+			break;
+
+		case 25:
+			if (npc->flag & 8)
+			{
+				npc->act_no = 26;
+				npc->act_wait = 0;
+				npc->ani_no = 2;
+				PlaySoundObject(26, 1);
+				SetQuake(20);
+			}
+
+			break;
+
+		case 26:
+			npc->xm = 8 * npc->xm / 9;
+
+			if (++npc->act_wait > 20)
+			{
+				npc->act_no = 10;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 50:
+			npc->act_no = 51;
+			npc->act_wait = 0;
+			npc->ani_no = 4;
+			SetNpChar(141, 0, 0, 0, 0, 0, npc, 0);
+			// Fallthrough
+		case 51:
+			if (++npc->act_wait > 30)
+			{
+				npc->act_no = 52;
+				npc->act_wait = 0;
+				npc->ani_no = 5;
+			}
+
+			if (gMC.x < npc->x)
+				npc->direct = 0;
+			else
+				npc->direct = 2;
+
+			break;
+
+		case 52:
+			if (++npc->act_wait > 3)
+			{
+				npc->act_no = 10;
+				npc->ani_no = 0;
+			}
+
+			break;
+
+		case 100:
+			npc->ani_no = 3;
+			npc->act_no = 101;
+			npc->bits &= ~0x20;
+			npc->damage = 0;
+
+			for (int i = 0; i < 8; ++i)
+				SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600u, 0), 0, 0, 0x100);
+
+			break;
+
+		case 101:
+			if (npc->flag & 8)
+			{
+				npc->act_no = 102;
+				npc->act_wait = 0;
+				npc->ani_no = 2;
+				PlaySoundObject(26, 1);
+				SetQuake(20);
+			}
+
+			break;
+
+		case 102:
+			npc->xm = 8 * npc->xm / 9;
+
+			if (++npc->act_wait > 50)
+			{
+				npc->act_no = 103;
+				npc->act_wait = 0;
+				npc->ani_no = 10;
+			}
+
+			break;
+
+		case 103:
+			if (++npc->act_wait > 50)
+			{
+				npc->ani_no = 9;
+				npc->act_no = 104;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 104:
+			if (++npc->ani_no > 10)
+				npc->ani_no = 9;
+
+			if (++npc->act_wait > 100)
+			{
+				npc->act_wait = 0;
+				npc->ani_no = 9;
+				npc->act_no = 105;
+			}
+
+			break;
+
+		case 105:
+			if (++npc->act_wait > 50)
+			{
+				npc->ani_wait = 0;
+				npc->act_no = 106;
+				npc->ani_no = 11;
+			}
+
+			break;
+
+		case 106:
+			if (++npc->ani_wait > 50)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 12)
+				npc->ani_no = 12;
+
+			break;
+
+		case 140:
+			npc->act_no = 141;
+			npc->act_wait = 0;
+			npc->ani_no = 12;
+			PlaySoundObject(29, 1);
+			// Fallthrough
+		case 141:
+			if (++npc->ani_no > 13)
+				npc->ani_no = 12;
+
+			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;
+	}
+
+	if (npc->act_no > 100 && npc->act_no < 105 && npc->act_wait % 9 == 0)
+		SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100);
+
+	npc->ym += 0x20;
+
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+	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];
+}
+
+// Toroko block projectile
+void ActNpc141(NPCHAR *npc)
+{
+	RECT rect[2]; // [sp+8h] [bp-24h]@1
+
+	rect[0] = {288, 32, 304, 48};
+	rect[1] = {304, 32, 320, 48};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->act_wait = 0;
+			// Fallthrough
+		case 1:
+			if (npc->pNpc->direct == 0)
+				npc->x = npc->pNpc->x + 0x1400;
+			else
+				npc->x = npc->pNpc->x - 0x1400;
+
+			npc->y = npc->pNpc->y - 0x1000;
+
+			if (npc->pNpc->act_no == 24 || npc->pNpc->act_no == 52)
+			{
+				npc->act_no = 10;
+
+				if (npc->pNpc->direct == 0)
+					npc->x = npc->pNpc->x - 0x2000;
+				else
+					npc->x = npc->pNpc->x + 0x2000;
+
+				npc->y = npc->pNpc->y;
+
+				const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y);
+				npc->ym = 4 * GetSin(deg);
+				npc->xm = 4 * GetCos(deg);
+
+				PlaySoundObject(39, 1);
+			}
+
+			break;
+
+		case 10:
+			if (npc->flag & 0xF)
+			{
+				npc->act_no = 20;
+				npc->act_wait = 0;
+				SetCaret(npc->x, npc->y, 2, 0);
+				PlaySoundObject(12, 1);
+
+				for (int i = 0; i < 4; ++i)
+					SetNpChar(4, npc->x, npc->y, Random(-0x200, 0x200), Random(-0x200, 0x200), 0, 0, 0x100);
+			}
+			else
+			{
+				npc->x += npc->xm;
+				npc->y += npc->ym;
+			}
+
+			break;
+
+		case 20:
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+
+			if (++npc->act_wait > 4)
+			{
+				for (int i = 0; i < 4; ++i)
+					SetNpChar(4, npc->x, npc->y, Random(-0x200, 0x200), Random(-0x200, 0x200), 0, 0, 0x100);
+
+				npc->code_char = 142;
+				npc->ani_no = 0;
+				npc->act_no = 20;
+				npc->xm = 0;
+				npc->bits &= ~4;
+				npc->bits |= 0x20;
+				npc->damage = 1;
+			}
+
+			break;
+	}
+
+	if (++npc->ani_no > 1)
+		npc->ani_no = 0;
+
+	npc->rect = rect[npc->ani_no];
+}
+
+// Flower Cub
+void ActNpc142(NPCHAR *npc)
+{
+	RECT rect[5];
+
+	rect[0] = {0, 128, 16, 144};
+	rect[1] = {16, 128, 32, 144};
+	rect[2] = {32, 128, 48, 144};
+	rect[3] = {48, 128, 64, 144};
+	rect[4] = {64, 128, 80, 144};
+
+	switch (npc->act_no)
+	{
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 0;
+			npc->act_wait = 0;
+			// Fallthrough
+		case 11:
+			if (++npc->act_wait > 30)
+			{
+				npc->act_no = 12;
+				npc->ani_no = 1;
+				npc->ani_wait = 0;
+			}
+
+			break;
+
+		case 12:
+			if (++npc->ani_wait > 8)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no == 3)
+			{
+				npc->act_no = 20;
+				npc->ym = -0x200;
+
+				if (gMC.x < npc->x)
+					npc->xm = -0x200;
+				else
+					npc->xm = 0x200;
+			}
+
+			break;
+
+		case 20:
+			if (npc->ym > -0x80)
+				npc->ani_no = 4;
+			else
+				npc->ani_no = 3;
+
+			if (npc->flag & 8)
+			{
+				npc->ani_no = 2;
+				npc->act_no = 21;
+				npc->act_wait = 0;
+				npc->xm = 0;
+				PlaySoundObject(23, 1);
+			}
+
+			break;
+
+		case 21:
+			if (++npc->act_wait > 10)
+			{
+				npc->act_no = 10;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	npc->ym += 0x40;
+
+	if (npc->ym > 0x5FF)
+		npc->ym = 0x5FF;
+	if (npc->ym < -0x5FF)
+		npc->ym = -0x5FF;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	npc->rect = rect[npc->ani_no];
+}
+
+// Jenka (collapsed)
+void ActNpc143(NPCHAR *npc)
+{
+	RECT rcLeft[1];
+	RECT rcRight[1];
+
+	rcLeft[0] = {208, 32, 224, 48};
+
+	rcRight[0] = {208, 48, 224, 64};
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Toroko (teleporting in)
+void ActNpc144(NPCHAR *npc)
+{
+	RECT rcLeft[5];
+	RECT rcRight[5];
+
+	rcLeft[0] = {0, 64, 16, 80};
+	rcLeft[1] = {16, 64, 32, 80};
+	rcLeft[2] = {32, 64, 48, 80};
+	rcLeft[3] = {16, 64, 32, 80};
+	rcLeft[4] = {128, 64, 144, 80};
+
+	rcRight[0] = {0, 80, 16, 96};
+	rcRight[1] = {16, 80, 32, 96};
+	rcRight[2] = {32, 80, 48, 96};
+	rcRight[3] = {16, 80, 32, 96};
+	rcRight[4] = {128, 80, 144, 96};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			npc->tgt_x = npc->x;
+			PlaySoundObject(29, 1);
+			// Fallthrough
+		case 1:
+			if (++npc->act_wait == 64)
+			{
+				npc->act_no = 2;
+				npc->act_wait = 0;
+			}
+
+			break;
+
+		case 2:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 3)
+				npc->ani_no = 2;
+
+			if (npc->flag & 8)
+			{
+				npc->act_no = 4;
+				npc->act_wait = 0;
+				npc->ani_no = 4;
+				PlaySoundObject(23, 1);
+			}
+
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 0;
+			npc->ani_wait = 0;
+			// Fallthrough
+		case 11:
+			if (Random(0, 120) == 10)
+			{
+				npc->act_no = 12;
+				npc->act_wait = 0;
+				npc->ani_no = 1;
+			}
+
+			break;
+
+		case 12:
+			if (++npc->act_wait > 8)
+			{
+				npc->act_no = 11;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	if (npc->act_no > 1)
+	{
+		npc->ym += 0x20;
+		if (npc->ym > 0x5FF)
+			npc->ym = 0x5FF;
+
+		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 == 1)
+	{
+		npc->rect.bottom = npc->rect.top + npc->act_wait / 4;
+
+		if (npc->act_wait / 2 % 2)
+			npc->x = npc->tgt_x;
+		else
+			npc->x = npc->tgt_x + 0x200;
+	}
+}
+
 //King's sword
 void ActNpc145(NPCHAR *npc)
 {
@@ -47,6 +694,56 @@
 		npc->rect = rcLeft[npc->ani_no];
 	else
 		npc->rect = rcRight[npc->ani_no];
+}
+
+//Lightning
+void ActNpc146(NPCHAR *npc)
+{
+	RECT rect[5];
+
+	rect[0] = {0, 0, 0, 0};
+	rect[1] = {256, 0, 272, 240};
+	rect[2] = {272, 0, 288, 240};
+	rect[3] = {288, 0, 304, 240};
+	rect[4] = {304, 0, 320, 240};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+
+			if (npc->direct == 2)
+				SetFlash(0, 0, 2);
+			// Fallthrough
+		case 1:
+			if (++npc->act_wait > 10)
+			{
+				npc->act_no = 2;
+				PlaySoundObject(101, 1);
+			}
+
+			break;
+
+		case 2:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no == 2)
+				npc->damage = 10;
+
+			if (npc->ani_no > 4)
+			{
+				SetDestroyNpChar(npc->x, npc->y, 0x1000, 8);
+				npc->cond = 0;
+			}
+
+			break;
+	}
+
+	npc->rect = rect[npc->ani_no];
 }
 
 //Quote
--- /dev/null
+++ b/src/NpcAct180.cpp
@@ -1,0 +1,181 @@
+#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 "Caret.h"
+
+//Scooter
+void ActNpc192(NPCHAR *npc)
+{
+	switch ( npc->act_no )
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->view.back = 0x2000;
+			npc->view.front = 0x2000;
+			npc->view.top = 0x1000;
+			npc->view.bottom = 0x1000;
+			break;
+
+		case 10:
+			npc->act_no = 11;
+			npc->ani_no = 1;
+			npc->view.top = 0x2000;
+			npc->view.bottom = 0x2000;
+			npc->y -= 0xA00;
+			break;
+
+		case 20:
+			npc->act_no = 21;
+			npc->act_wait = 1;
+			npc->tgt_x = npc->x;
+			npc->tgt_y = npc->y;
+			// Fallthrough
+		case 21:
+			npc->x = npc->tgt_x + (Random(-1, 1) * 0x200);
+			npc->y = npc->tgt_y + (Random(-1, 1) * 0x200);
+
+			if (++npc->act_wait > 30)
+				npc->act_no = 30;
+
+			break;
+
+		case 30:
+			npc->act_no = 31;
+			npc->act_wait = 1;
+			npc->xm = -0x800;
+			npc->x = npc->tgt_x;
+			npc->y = npc->tgt_y;
+			PlaySoundObject(44, 1);
+			// Fallthrough
+		case 31:
+			npc->xm += 0x20;
+			npc->x += npc->xm;
+			++npc->act_wait;
+			npc->y = npc->tgt_y + (Random(-1, 1) * 0x200);
+
+			if (npc->act_wait > 10)
+				npc->direct = 2;
+
+			if (npc->act_wait > 200)
+				npc->act_no = 40;
+
+			break;
+
+		case 40:
+			npc->act_no = 41;
+			npc->act_wait = 2;
+			npc->direct = 0;
+			npc->y -= 0x6000;
+			npc->xm = -0x1000;
+			// Fallthrough
+		case 41:
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+
+			npc->act_wait += 2;
+
+			if (npc->act_wait > 1200)
+				npc->cond = 0;
+
+			break;
+	}
+
+	if (npc->act_wait % 4 == 0 && npc->act_no >= 20)
+	{
+		PlaySoundObject(34, 1);
+
+		if (npc->direct == 0)
+			SetCaret(npc->x + 5120, npc->y + 5120, 7, 2);
+		else
+			SetCaret(npc->x - 5120, npc->y + 5120, 7, 0);
+	}
+
+	RECT rcLeft[2];
+	RECT rcRight[2];
+
+	rcLeft[0] = {224, 64, 256, 80};
+	rcLeft[1] = {256, 64, 288, 96};
+
+	rcRight[0] = {224, 80, 256, 96};
+	rcRight[1] = {288, 64, 320, 96};
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft[npc->ani_no];
+	else
+		npc->rect = rcRight[npc->ani_no];
+}
+
+//Scooter (broken)
+void ActNpc193(NPCHAR *npc)
+{
+	RECT rc[1];
+
+	rc[0] = {256, 96, 320, 112};
+
+	if (npc->act_no == 0)
+	{
+		npc->act_no = 1;
+		npc->y = npc->y;
+		npc->x += 0x3000;
+	}
+
+	npc->rect = rc[0];
+}
+
+//Water/wind particles
+void ActNpc199(NPCHAR *npc)
+{
+	RECT rect[5];
+
+	rect[0] = {72, 16, 74, 18};
+	rect[1] = {74, 16, 76, 18};
+	rect[2] = {76, 16, 78, 18};
+	rect[3] = {78, 16, 80, 18};
+	rect[4] = {80, 16, 82, 18};
+
+	if (npc->act_no == 0)
+	{
+		npc->act_no = 1;
+		npc->ani_no = Random(0, 2);
+
+		switch (npc->direct)
+		{
+			case 0:
+				npc->xm = -1;
+				break;
+			case 1:
+				npc->ym = -1;
+				break;
+			case 2:
+				npc->xm = 1;
+				break;
+			case 3:
+				npc->ym = 1;
+				break;
+		}
+
+		npc->xm *= (Random(4, 8) * 0x200) / 2;
+		npc->ym *= (Random(4, 8) * 0x200) / 2;
+	}
+
+	if (++npc->ani_wait > 6)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 4)
+		npc->cond = 0;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	npc->rect = rect[npc->ani_no];
+}
--- a/src/NpcAct200.cpp
+++ b/src/NpcAct200.cpp
@@ -21,3 +21,18 @@
 
 	npc->rect = rects[npc->code_event];
 }
+
+//Smoke generator
+void ActNpc219(NPCHAR *npc)
+{
+	RECT rc[1];
+
+	rc[0] = {0, 0, 0, 0};
+
+	if ( npc->direct )
+		SetNpChar(199, npc->x + (Random(-0xA0, 0xA0) * 0x200), npc->y + (Random(-0x80, 0x80) * 0x200), 0, 0, 2, 0, 0x100);
+	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
--- a/src/NpcAct280.cpp
+++ b/src/NpcAct280.cpp
@@ -8,6 +8,13 @@
 #include "Sound.h"
 #include "Back.h"
 #include "Triangle.h"
+#include "Frame.h"
+
+//Quake
+void ActNpc292(NPCHAR *npc)
+{
+	SetQuake(10);
+}
 
 //Doctor (opening)
 void ActNpc298(NPCHAR *npc)
--- a/src/NpcAct300.cpp
+++ b/src/NpcAct300.cpp
@@ -9,6 +9,7 @@
 #include "Back.h"
 #include "Triangle.h"
 #include "Caret.h"
+#include "Boss.h"
 
 //Demon crown (opening)
 void ActNpc300(NPCHAR *npc)
@@ -29,4 +30,72 @@
 		SetCaret(npc->x + (Random(-8, 8) * 0x200), npc->y + 0x1000, 13, 1);
 
 	npc->rect = rc[0];
+}
+
+//Camera focus marker
+void ActNpc302(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 10:
+			npc->x = gMC.x;
+			npc->y = gMC.y - 0x4000;
+			break;
+
+		case 20:
+			switch (npc->direct)
+			{
+				case 0:
+					npc->x -= 0x400;
+					break;
+				case 1:
+					npc->y -= 0x400;
+					break;
+				case 2:
+					npc->x += 0x400;
+					break;
+				case 3:
+					npc->y += 0x400;
+					break;
+			}
+
+			gMC.x = npc->x;
+			gMC.y = npc->y;
+			break;
+
+		case 30:
+			npc->x = gMC.x;
+			npc->y = gMC.y + 0xA000;
+			break;
+
+		case 100:
+			npc->act_no = 101;
+
+			if (npc->direct)
+			{
+				int i;
+				for (i = 0xAA; i < 0x200; ++i)
+				{
+					if (gNPC[i].cond & 0x80 && gNPC[i].code_event == npc->direct)
+					{
+						npc->pNpc = &gNPC[i];
+						break;
+					}
+				}
+				if (i == 0x200)
+				{
+					npc->cond = 0;
+					break;
+				}
+			}
+			else
+			{
+				npc->pNpc = gBoss;
+			}
+			// Fallthrough
+		case 101:
+			npc->x = (npc->pNpc->x + gMC.x) / 2;
+			npc->y = (npc->pNpc->y + gMC.y) / 2;
+			break;
+	}
 }
--- a/src/NpcTbl.cpp
+++ b/src/NpcTbl.cpp
@@ -89,10 +89,10 @@
 	ActNpc030,
 	ActNpc031,
 	ActNpc032,
-	nullptr,
+	ActNpc033,
 	ActNpc034,
-	nullptr,
-	nullptr,
+	ActNpc035,
+	ActNpc036,
 	ActNpc037,
 	ActNpc038,
 	ActNpc039,
@@ -100,20 +100,20 @@
 	ActNpc041,
 	ActNpc042,
 	ActNpc043,
-	nullptr,
-	nullptr,
+	ActNpc044,
+	ActNpc045,
 	ActNpc046,
-	nullptr,
+	ActNpc047,
 	ActNpc048,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc049,
+	ActNpc050,
+	ActNpc051,
+	ActNpc052,
+	ActNpc053,
+	ActNpc054,
+	ActNpc055,
+	ActNpc056,
+	ActNpc057,
 	ActNpc058,
 	ActNpc059,
 	ActNpc060,
@@ -156,56 +156,56 @@
 	ActNpc097,
 	ActNpc098,
 	ActNpc099,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc100,
+	ActNpc101,
+	ActNpc102,
+	ActNpc103,
+	ActNpc104,
+	ActNpc105,
+	ActNpc106,
+	ActNpc107,
+	ActNpc108,
+	ActNpc109,
+	ActNpc110,
 	ActNpc111,
 	ActNpc112,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc113,
+	ActNpc114,
+	ActNpc115,
 	ActNpc116,
-	nullptr,
-	nullptr,
+	ActNpc117,
+	ActNpc118,
 	ActNpc119,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc120,
+	ActNpc121,
+	ActNpc122,
+	ActNpc123,
+	ActNpc124,
 	ActNpc125,
-	nullptr,
+	ActNpc126,
 	ActNpc127,
 	ActNpc128,
 	ActNpc129,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc130,
+	ActNpc131,
+	ActNpc132,
+	ActNpc133,
+	ActNpc134,
+	ActNpc135,
+	ActNpc136,
+	ActNpc137,
+	ActNpc138,
+	ActNpc139,
+	ActNpc140,
+	ActNpc141,
+	ActNpc142,
+	ActNpc143,
+	ActNpc144,
 	ActNpc145,
+	ActNpc146,
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
 	ActNpc150,
 	ActNpc151,
 	nullptr,
@@ -248,11 +248,14 @@
 	nullptr,
 	nullptr,
 	nullptr,
+	ActNpc192,
+	ActNpc193,
 	nullptr,
 	nullptr,
 	nullptr,
 	nullptr,
 	nullptr,
+	ActNpc199,
 	nullptr,
 	nullptr,
 	nullptr,
@@ -264,9 +267,6 @@
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
-	nullptr,
-	nullptr,
 	ActNpc211,
 	nullptr,
 	nullptr,
@@ -275,6 +275,7 @@
 	nullptr,
 	nullptr,
 	nullptr,
+	ActNpc219,
 	nullptr,
 	nullptr,
 	nullptr,
@@ -333,7 +334,6 @@
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
 	ActNpc278,
 	nullptr,
 	nullptr,
@@ -348,17 +348,17 @@
 	nullptr,
 	nullptr,
 	nullptr,
+	ActNpc292,
 	nullptr,
 	nullptr,
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
 	ActNpc298,
 	ActNpc299,
 	ActNpc300,
 	nullptr,
-	nullptr,
+	ActNpc302,
 	nullptr,
 	nullptr,
 	nullptr,
--- a/src/Shoot.cpp
+++ b/src/Shoot.cpp
@@ -10,6 +10,76 @@
 int empty;
 int spur_charge;
 
+void ShootBullet_Frontia1(int level)
+{
+	int bul_no;
+
+	switch (level)
+	{
+		case 1:
+			bul_no = 1;
+			break;
+		case 2:
+			bul_no = 2;
+			break;
+		case 3:
+			bul_no = 3;
+			break;
+	}
+
+	if (CountArmsBullet(1) <= 3 && gKeyTrg & gKeyShot)
+	{
+		if (!UseArmsEnergy(1))
+		{
+			ChangeToFirstArms();
+		}
+		else
+		{
+			if (gMC.up)
+			{
+				if (gMC.direct == 0)
+				{
+					SetBullet(bul_no, gMC.x - 0x600, gMC.y - 0x1400, 1);
+					SetCaret(gMC.x - 0x600, gMC.y - 0x1400, 3, 0);
+				}
+				else
+				{
+					SetBullet(bul_no, gMC.x + 0x600, gMC.y - 0x1400, 1);
+					SetCaret(gMC.x + 0x600, gMC.y - 0x1400, 3, 0);
+				}
+			}
+			else if (gMC.down)
+			{
+				if (gMC.direct == 0)
+				{
+					SetBullet(bul_no, gMC.x - 0x600, gMC.y + 0x1400, 3);
+					SetCaret(gMC.x - 0x600, gMC.y + 0x1400, 3, 0);
+				}
+				else
+				{
+					SetBullet(bul_no, gMC.x + 0x600, gMC.y + 0x1400, 3);
+					SetCaret(gMC.x + 0x600, gMC.y + 0x1400, 3, 0);
+				}
+			}
+			else
+			{
+				if (gMC.direct == 0)
+				{
+					SetBullet(bul_no, gMC.x - 0xC00, gMC.y + 0x400, 0);
+					SetCaret(gMC.x - 0x1800, gMC.y + 0x400, 3, 0);
+				}
+				else
+				{
+					SetBullet(bul_no, gMC.x + 0xC00, gMC.y + 0x400, 2);
+					SetCaret(gMC.x + 0x1800, gMC.y + 0x400, 3, 0);
+				}
+			}
+
+			PlaySoundObject(33, 1);
+		}
+	}
+}
+
 void ShootBullet_PoleStar(int level)
 {
 	int bul_no;
@@ -163,6 +233,7 @@
 	if (CountArmsBullet(4) < 5)
 	{
 		int bul_no;
+
 		switch (level)
 		{
 			case 1:
@@ -481,6 +552,427 @@
 	PlaySoundObject(32, 1);
 }
 
+void ShootBullet_Bubblin1(void)
+{
+	static int wait;
+
+	if (CountArmsBullet(7) <= 3)
+	{
+		if (gKeyTrg & gKeyShot)
+		{
+			if (!UseArmsEnergy(1))
+			{
+				PlaySoundObject(37, 1);
+				if (!empty)
+				{
+					SetCaret(gMC.x, gMC.y, 16, 0);
+					empty = 50;
+				}
+			}
+			else
+			{
+				if (gMC.up)
+				{
+					if (gMC.direct)
+					{
+						SetBullet(19, gMC.x + 0x200, gMC.y - 0x400, 1);
+						SetCaret(gMC.x + 0x200, gMC.y - 0x400, 3, 0);
+					}
+					else
+					{
+						SetBullet(19, gMC.x - 0x200, gMC.y - 0x400, 1);
+						SetCaret(gMC.x - 0x200, gMC.y - 0x400, 3, 0);
+					}
+				}
+				else if (gMC.down)
+				{
+					if (gMC.direct)
+					{
+						SetBullet(19, gMC.x + 0x200, gMC.y + 0x400, 3);
+						SetCaret(gMC.x + 0x200, gMC.y + 0x400, 3, 0);
+					}
+					else
+					{
+						SetBullet(19, gMC.x - 0x200, gMC.y + 0x400, 3);
+						SetCaret(gMC.x - 0x200, gMC.y + 0x400, 3, 0);
+					}
+				}
+				else if (gMC.direct)
+				{
+					SetBullet(19, gMC.x + 0xC00, gMC.y + 0x600, 2);
+					SetCaret(gMC.x + 0x1800, gMC.y + 0x600, 3, 0);
+				}
+				else
+				{
+					SetBullet(19, gMC.x - 0xC00, gMC.y + 0x600, 0);
+					SetCaret(gMC.x - 0x1800, gMC.y + 0x600, 3, 0);
+				}
+	
+				PlaySoundObject(48, 1);
+			}
+		}
+		else if (++wait > 20)
+		{
+			wait = 0;
+			ChargeArmsEnergy(1);
+		}
+	}
+}
+
+void ShootBullet_Bubblin2(int level)
+{
+	static int wait;
+
+	if (CountArmsBullet(7) <= 15)
+	{
+		level += 18;
+
+		if (!(gKey & gKeyShot))
+			gMC.rensha = 6;
+
+		if (gKey & gKeyShot)
+		{
+			if (++gMC.rensha >= 7)
+			{
+				gMC.rensha = 0;
+
+				if (!UseArmsEnergy(1))
+				{
+					PlaySoundObject(37, 1);
+					if (!empty)
+					{
+						SetCaret(gMC.x, gMC.y, 16, 0);
+						empty = 50;
+					}
+				}
+				else
+				{
+					if (gMC.up)
+					{
+						if (gMC.direct)
+						{
+							SetBullet(level, gMC.x + 0x600, gMC.y - 0x1000, 1);
+							SetCaret(gMC.x + 0x600, gMC.y - 0x2000, 3, 0);
+						}
+						else
+						{
+							SetBullet(level, gMC.x - 0x600, gMC.y - 0x1000, 1);
+							SetCaret(gMC.x - 0x600, gMC.y - 0x2000, 3, 0);
+						}
+					}
+					else if (gMC.down)
+					{
+						if (gMC.direct)
+						{
+							SetBullet(level, gMC.x + 0x600, gMC.y + 0x1000, 3);
+							SetCaret(gMC.x + 0x600, gMC.y + 0x2000, 3, 0);
+						}
+						else
+						{
+							SetBullet(level, gMC.x - 0x600, gMC.y + 0x1000, 3);
+							SetCaret(gMC.x - 0x600, gMC.y + 0x2000, 3, 0);
+						}
+					}
+					else if (gMC.direct)
+					{
+						SetBullet(level, gMC.x + 0xC00, gMC.y + 0x600, 2);
+						SetCaret(gMC.x + 0x1800, gMC.y + 0x600, 3, 0);
+					}
+					else
+					{
+						SetBullet(level, gMC.x - 0xC00, gMC.y + 0x600, 0);
+						SetCaret(gMC.x - 0x1800, gMC.y + 0x600, 3, 0);
+					}
+
+					PlaySoundObject(48, 1);
+				}
+			}
+		}
+		else if (++wait > 1)
+		{
+			wait = 0;
+			ChargeArmsEnergy(1);
+		}
+	}
+}
+
+void ShootBullet_Sword(int level)
+{
+	if (CountArmsBullet(9) <= 0)
+	{
+		int bul_no;
+
+		switch (level)
+		{
+			case 1:
+				bul_no = 25;
+				break;
+			case 2:
+				bul_no = 26;
+				break;
+			case 3:
+				bul_no = 27;
+				break;
+		}
+
+		if (gKeyTrg & gKeyShot)
+		{
+			if (gMC.up)
+			{
+				if (gMC.direct == 0)
+					SetBullet(bul_no, gMC.x - 0x200, gMC.y + 0x800, 1);
+				else
+					SetBullet(bul_no, gMC.x + 0x200, gMC.y + 0x800, 1);
+			}
+			else if (gMC.down)
+			{
+				if (gMC.direct == 0)
+					SetBullet(bul_no, gMC.x - 0x200, gMC.y - 0xC00, 3);
+				else
+					SetBullet(bul_no, gMC.x + 0x200, gMC.y - 0xC00, 3);
+			}
+			else
+			{
+				if (gMC.direct == 0)
+					SetBullet(bul_no, gMC.x + 0xC00, gMC.y - 0x600, 0);
+				else
+					SetBullet(bul_no, gMC.x - 0xC00, gMC.y - 0x600, 2);
+			}
+
+			PlaySoundObject(34, 1);
+		}
+	}
+}
+
+void ShootBullet_Nemesis(int level)
+{
+	int bul_no;
+
+	switch (level)
+	{
+		case 1:
+			bul_no = 34;
+			break;
+		case 2:
+			bul_no = 35;
+			break;
+		case 3:
+			bul_no = 36;
+			break;
+	}
+
+	if (CountArmsBullet(12) <= 1 && gKeyTrg & gKeyShot)
+	{
+		if (!UseArmsEnergy(1))
+		{
+			PlaySoundObject(37, 1);
+		}
+		else
+		{
+			if (gMC.up)
+			{
+				if (gMC.direct == 0)
+				{
+					SetBullet(bul_no, gMC.x - 0x200, gMC.y - 0x1800, 1);
+					SetCaret(gMC.x - 0x200, gMC.y - 0x1800, 3, 0);
+				}
+				else
+				{
+					SetBullet(bul_no, gMC.x + 0x200, gMC.y - 0x1800, 1);
+					SetCaret(gMC.x + 0x200, gMC.y - 0x1800, 3, 0);
+				}
+			}
+			else if (gMC.down)
+			{
+				if (gMC.direct == 0)
+				{
+					SetBullet(bul_no, gMC.x - 0x200, gMC.y + 0x1800, 3);
+					SetCaret(gMC.x - 0x200, gMC.y + 0x1800, 3, 0);
+				}
+				else
+				{
+					SetBullet(bul_no, gMC.x + 0x200, gMC.y + 0x1800, 3);
+					SetCaret(gMC.x + 0x200, gMC.y + 0x1800, 3, 0);
+				}
+			}
+			else
+			{
+				if (gMC.direct == 0)
+				{
+					SetBullet(bul_no, gMC.x - 0x2C00, gMC.y + 0x600, 0);
+					SetCaret(gMC.x - 0x2000, gMC.y + 0x600, 3, 0);
+				}
+				else
+				{
+					SetBullet(bul_no, gMC.x + 0x2C00, gMC.y + 0x600, 2);
+					SetCaret(gMC.x + 0x2000, gMC.y + 0x600, 3, 0);
+				}
+			}
+
+			switch (level)
+			{
+				case 1:
+					PlaySoundObject(117, 1);
+					break;
+				case 2:
+					PlaySoundObject(49, 1);
+					break;
+				case 3:
+					PlaySoundObject(60, 1);
+					break;
+			}
+		}
+	}
+}
+
+void ResetSpurCharge(void)
+{
+	spur_charge = 0;
+
+	if (gArmsData[gSelectedArms].code == 13)
+		ZeroExpMyChar();
+}
+
+void ShootBullet_Spur(int level)
+{
+	int bul_no;
+
+	bool bShot = false;
+
+	if (gKey & gKeyShot)
+	{
+		if (gMC.equip & 8)
+			AddExpMyChar(3);
+		else
+			AddExpMyChar(2);
+
+		if (++spur_charge / 2 % 2)
+		{
+			if (level == 1)
+			{
+				PlaySoundObject(59, 1);
+			}
+			else if (level == 2)
+			{
+				PlaySoundObject(60, 1);
+			}
+			else if (level == 3)
+			{
+				if (!IsMaxExpMyChar())
+					PlaySoundObject(61, 1);
+			}
+		}
+	}
+	else
+	{
+		if (spur_charge)
+			bShot = true;
+
+		spur_charge = 0;
+	}
+
+	static bool bMax;
+
+	if (IsMaxExpMyChar())
+	{
+		if (bMax == false)
+		{
+			bMax = true;
+			PlaySoundObject(65, 1);
+		}
+	}
+	else
+	{
+		bMax = false;
+	}
+
+	if (gKey & gKeyShot == 0)
+		ZeroExpMyChar();
+
+	switch (level)
+	{
+		case 1:
+			bul_no = 6;
+			bShot = false;
+			break;
+		case 2:
+			bul_no = 37;
+			break;
+		case 3:
+			if (bMax)
+				bul_no = 39;
+			else
+				bul_no = 38;
+			break;
+	}
+
+	if (CountArmsBullet(13) <= 0 && CountArmsBullet(14) <= 0 && (gKeyTrg & gKeyShot || bShot))
+	{
+		if (!UseArmsEnergy(1))
+		{
+			PlaySoundObject(37, 1);
+		}
+		else
+		{
+			if (gMC.up)
+			{
+				if (gMC.direct == 0)
+				{
+					SetBullet(bul_no, gMC.x - 0x200, gMC.y - 0x1000, 1);
+					SetCaret(gMC.x - 0x200, gMC.y - 0x1000, 3, 0);
+				}
+				else
+				{
+					SetBullet(bul_no, gMC.x + 0x200, gMC.y - 0x1000, 1);
+					SetCaret(gMC.x + 0x200, gMC.y - 0x1000, 3, 0);
+				}
+			}
+			else if (gMC.down)
+			{
+				if (gMC.direct == 0)
+				{
+					SetBullet(bul_no, gMC.x - 0x200, gMC.y + 0x1000, 3);
+					SetCaret(gMC.x - 0x200, gMC.y + 0x1000, 3, 0);
+				}
+				else
+				{
+					SetBullet(bul_no, gMC.x + 0x200, gMC.y + 0x1000, 3);
+					SetCaret(gMC.x + 0x200, gMC.y + 0x1000, 3, 0);
+				}
+			}
+			else
+			{
+				if (gMC.direct == 0)
+				{
+					SetBullet(bul_no, gMC.x - 0xC00, gMC.y + 0x600, 0);
+					SetCaret(gMC.x - 0x1800, gMC.y + 0x600, 3, 0);
+				}
+				else
+				{
+					SetBullet(bul_no, gMC.x + 0xC00, gMC.y + 0x600, 2);
+					SetCaret(gMC.x + 0x1800, gMC.y + 0x600, 3, 0);
+				}
+			}
+
+			switch (bul_no)
+			{
+				case 6:
+					PlaySoundObject(49, 1);
+					break;
+				case 37:
+					PlaySoundObject(62, 1);
+					break;
+				case 38:
+					PlaySoundObject(63, 1);
+					break;
+				case 39:
+					PlaySoundObject(64, 1);
+					break;
+			}
+		}
+	}
+}
+
 void ShootBullet()
 {
 	if (empty)
@@ -503,6 +995,9 @@
 	{
 		switch (gArmsData[gSelectedArms].code)
 		{
+			case 1:
+				ShootBullet_Frontia1(gArmsData[gSelectedArms].level);
+				break;
 			case 2:
 				ShootBullet_PoleStar(gArmsData[gSelectedArms].level);
 				break;
@@ -515,12 +1010,45 @@
 			case 5:
 				ShootBullet_Missile(gArmsData[gSelectedArms].level, false);
 				break;
+			case 7:
+				switch (gArmsData[gSelectedArms].level)
+				{
+					case 1:
+						ShootBullet_Bubblin1();
+						break;
+					case 2:
+						ShootBullet_Bubblin2(2);
+						break;
+					case 3:
+						ShootBullet_Bubblin2(3);
+						break;
+				}
+
+				break;
+			case 9:
+				switch (gArmsData[gSelectedArms].level)
+				{
+					case 1:
+						ShootBullet_Sword(1);
+						break;
+					case 2:
+						ShootBullet_Sword(2);
+						break;
+					case 3:
+						ShootBullet_Sword(3);
+						break;
+				}
+
+				break;
 			case 10:
 				ShootBullet_Missile(gArmsData[gSelectedArms].level, true);
 				break;
+			case 12:
+				ShootBullet_Nemesis(gArmsData[gSelectedArms].level);
+				break;
+			case 13:
+				ShootBullet_Spur(gArmsData[gSelectedArms].level);
+				break;
 		}
-		
-		if (!(gKeyTrg & gKeyShot))
-			return;
 	}
 }
--- a/src/Shoot.h
+++ b/src/Shoot.h
@@ -1,2 +1,3 @@
 #pragma once
+void ResetSpurCharge(void);
 void ShootBullet();
--