shithub: cstory

Download patch

ref: aa08331c36a4f40ebb81040abc5f1db8870c750d
parent: f47f036e3661b3224ee8f3c7147facc0a6e958c1
author: Clownacy <[email protected]>
date: Thu Feb 7 10:10:46 EST 2019

Added IronHead and relevant NPCs

Also added the AMJ TSC command, so getting the Spur works

--- a/Makefile
+++ b/Makefile
@@ -43,6 +43,7 @@
 	Boss \
 	BossAlmo1 \
 	BossFrog \
+	BossIronH \
 	BossLife \
 	BossOhm \
 	BossX \
--- a/src/Boss.cpp
+++ b/src/Boss.cpp
@@ -6,6 +6,7 @@
 #include "Boss.h"
 #include "BossAlmo1.h"
 #include "BossFrog.h"
+#include "BossIronH.h"
 #include "BossOhm.h"
 #include "BossX.h"
 #include "NpChar.h"
@@ -192,7 +193,7 @@
 	ActBossChar_Frog,
 	ActBossChar_MonstX,
 	ActBossChar_Core,
-	nullptr, //ActBossChar_Ironhead,
+	ActBossChar_Ironhead,
 	nullptr, //ActBossChar_Twin,
 	nullptr, //ActBossChar_Undead,
 	nullptr, //ActBossChar_Press,
--- /dev/null
+++ b/src/BossIronH.cpp
@@ -1,0 +1,207 @@
+#include "BossIronH.h"
+
+#include "Boss.h"
+#include "Frame.h"
+#include "Game.h"
+#include "MyChar.h"
+#include "Sound.h"
+#include "WindowsWrapper.h"
+
+void ActBossChar_Ironhead(void)
+{
+	switch (gBoss[0].act_no)
+	{
+		case 0:
+			gBoss[0].cond = 0x80;
+			gBoss[0].exp = 1;
+			gBoss[0].direct = 2;
+			gBoss[0].act_no = 100;
+			gBoss[0].x = 0x14000;
+			gBoss[0].y = 0x10000;
+			gBoss[0].view.front = 0x5000;
+			gBoss[0].view.top = 0x1800;
+			gBoss[0].view.back = 0x3000;
+			gBoss[0].view.bottom = 0x1800;
+			gBoss[0].hit_voice = 54;
+			gBoss[0].hit.front = 0x2000;
+			gBoss[0].hit.top = 0x1400;
+			gBoss[0].hit.back = 0x2000;
+			gBoss[0].hit.bottom = 0x1400;
+			gBoss[0].bits = 0x8228;
+			gBoss[0].size = 3;
+			gBoss[0].damage = 10;
+			gBoss[0].code_event = 1000;
+			gBoss[0].life = 400;
+			break;
+
+		case 100:
+			gBoss[0].act_no = 101;
+			gBoss[0].bits &= ~0x20;
+			gBoss[0].act_wait = 0;
+			// Fallthrough
+		case 101:
+			if (++gBoss[0].act_wait > 50)
+			{
+				gBoss[0].act_no = 250;
+				gBoss[0].act_wait = 0;
+			}
+
+			if (gBoss[0].act_wait % 4 == 0)
+				SetNpChar(197, Random(15, 18) * 0x2000, Random(2, 13) * 0x2000, 0, 0, 0, 0, 0x100);
+
+			break;
+
+		case 250:
+			gBoss[0].act_no = 251;
+
+			if (gBoss[0].direct == 2)
+			{
+				gBoss[0].x = 0x1E000;
+				gBoss[0].y = gMC.y;
+			}
+			else
+			{
+				gBoss[0].x = 0x5A000;
+				gBoss[0].y = Random(2, 13) * 0x2000;
+			}
+
+			gBoss[0].tgt_x = gBoss[0].x;
+			gBoss[0].tgt_y = gBoss[0].y;
+
+			gBoss[0].ym = Random(-0x200, 0x200);
+			gBoss[0].xm = Random(-0x200, 0x200);
+
+			gBoss[0].bits |= 0x20;
+			// Fallthrough
+		case 251:
+			if (gBoss[0].direct == 2)
+			{
+				gBoss[0].tgt_x += 0x400;
+			}
+			else
+			{
+				gBoss[0].tgt_x -= 0x200;
+
+				if (gMC.y > gBoss[0].tgt_y)
+					gBoss[0].tgt_y += 0x200;
+				else
+					gBoss[0].tgt_y -= 0x200;
+			}
+
+			if (gBoss[0].tgt_x > gBoss[0].x)
+				gBoss[0].xm += 8;
+			else
+				gBoss[0].xm -= 8;
+
+			if (gBoss[0].tgt_y > gBoss[0].y)
+				gBoss[0].ym += 8;
+			else
+				gBoss[0].ym -= 8;
+
+			if (gBoss[0].ym > 0x200)
+				gBoss[0].ym = 0x200;
+			if (gBoss[0].ym < -0x200)
+				gBoss[0].ym = -0x200;
+
+			gBoss[0].x += gBoss[0].xm;
+			gBoss[0].y += gBoss[0].ym;
+
+			if (gBoss[0].direct == 2)
+			{
+				if (gBoss[0].x > 0x5A000)
+				{
+					gBoss[0].direct = 0;
+					gBoss[0].act_no = 100;
+				}
+			}
+			else
+			{
+				if (gBoss[0].x < 0x22000)
+				{
+					gBoss[0].direct = 2;
+					gBoss[0].act_no = 100;
+				}
+			}
+
+			if (gBoss[0].direct == 0 && (++gBoss[0].act_wait == 300 || gBoss[0].act_wait == 310 || gBoss[0].act_wait == 320))
+			{
+				PlaySoundObject(39, 1);
+				SetNpChar(198, gBoss[0].x + 0x1400, gBoss[0].y + 0x200, Random(-3, 0) * 0x200, Random(-3, 3) * 0x200, 2, 0, 0x100);
+			}
+
+			if (++gBoss[0].ani_wait > 2)
+			{
+				gBoss[0].ani_wait = 0;
+				++gBoss[0].ani_no;
+			}
+
+			if (gBoss[0].ani_no > 7)
+				gBoss[0].ani_no = 0;
+
+			break;
+
+		case 1000:
+			gBoss[0].bits &= ~0x20;
+			gBoss[0].ani_no = 8;
+			gBoss[0].damage = 0;
+			gBoss[0].act_no = 1001;
+			gBoss[0].tgt_x = gBoss[0].x;
+			gBoss[0].tgt_y = gBoss[0].y;
+			SetQuake(20);
+
+			for (int i = 0; i < 0x20; ++i)
+				SetNpChar(4, gBoss[0].x + (Random(-0x80, 0x80) * 0x200), gBoss[0].y + (Random(-0x40, 0x40) * 0x200), Random(-0x80, 0x80) * 0x200, Random(-0x80, 0x80) * 0x200, 0, 0, 0x100);
+
+			DeleteNpCharCode(197, 1);
+			DeleteNpCharCode(271, 1);
+			DeleteNpCharCode(272, 1);
+			// Fallthrough
+		case 1001:
+			gBoss[0].tgt_x -= 0x200;
+
+			gBoss[0].x = gBoss[0].tgt_x + (Random(-1, 1) * 0x200);
+			gBoss[0].y = gBoss[0].tgt_y + (Random(-1, 1) * 0x200);
+
+			if (++gBoss[0].act_wait % 4 == 0)
+				SetNpChar(4, gBoss[0].x + (Random(-0x80u, 0x80) * 0x200), gBoss[0].y + (Random(-0x40u, 0x40) * 0x200), Random(-0x80, 0x80) * 0x200, Random(-0x80, 0x80) * 0x200, 0, 0, 0x100);
+
+			break;
+	}
+
+	RECT rc[9];
+	RECT rcDamage[9];
+
+	rc[0] = {0, 0, 64, 24};
+	rc[1] = {64, 0, 128, 24};
+	rc[2] = {128, 0, 192, 24};
+	rc[3] = {64, 0, 128, 24};
+	rc[4] = {0, 0, 64, 24};
+	rc[5] = {192, 0, 256, 24};
+	rc[6] = {256, 0, 320, 24};
+	rc[7] = {192, 0, 256, 24};
+	rc[8] = {256, 48, 320, 72};
+
+	rcDamage[0] = {0, 24, 64, 48};
+	rcDamage[1] = {64, 24, 128, 48};
+	rcDamage[2] = {128, 24, 192, 48};
+	rcDamage[3] = {64, 24, 128, 48};
+	rcDamage[4] = {0, 24, 64, 48};
+	rcDamage[5] = {192, 24, 256, 48};
+	rcDamage[6] = {256, 24, 320, 48};
+	rcDamage[7] = {192, 24, 256, 48};
+	rcDamage[8] = {256, 48, 320, 72};
+
+	if (gBoss[0].shock)
+	{
+		static unsigned char flash;
+
+		if ((++flash >> 1) % 2)
+			gBoss[0].rect = rc[gBoss[0].ani_no];
+		else
+			gBoss[0].rect = rcDamage[gBoss[0].ani_no];
+	}
+	else
+	{
+		gBoss[0].rect = rc[gBoss[0].ani_no];
+	}
+}
\ No newline at end of file
--- /dev/null
+++ b/src/BossIronH.h
@@ -1,0 +1,3 @@
+#pragma once
+
+void ActBossChar_Ironhead(void);
--- a/src/NpcAct.h
+++ b/src/NpcAct.h
@@ -198,7 +198,9 @@
 void ActNpc193(NPCHAR *npc);
 void ActNpc194(NPCHAR *npc);
 void ActNpc195(NPCHAR *npc);
-
+void ActNpc196(NPCHAR *npc);
+void ActNpc197(NPCHAR *npc);
+void ActNpc198(NPCHAR *npc);
 void ActNpc199(NPCHAR *npc);
 
 void ActNpc211(NPCHAR *npc);
@@ -208,6 +210,9 @@
 
 void ActNpc259(NPCHAR *npc);
 
+void ActNpc271(NPCHAR *npc);
+void ActNpc272(NPCHAR *npc);
+
 void ActNpc278(NPCHAR *npc);
 
 void ActNpc292(NPCHAR *npc);
@@ -219,6 +224,8 @@
 void ActNpc302(NPCHAR *npc);
 
 void ActNpc334(NPCHAR *npc);
+void ActNpc335(NPCHAR *npc);
+void ActNpc336(NPCHAR *npc);
 
 void ActNpc355(NPCHAR *npc);
 
--- a/src/NpcAct180.cpp
+++ b/src/NpcAct180.cpp
@@ -12,6 +12,7 @@
 #include "Frame.h"
 #include "Bullet.h"
 #include "Flags.h"
+#include "NpcHit.h"
 
 //Curly AI
 void ActNpc180(NPCHAR *npc)
@@ -1173,7 +1174,143 @@
 //Grate
 void ActNpc195(NPCHAR *npc)
 {
-	npc->rect = {112, 64, 128, 80};
+	RECT rc = {112, 64, 128, 80};
+	npc->rect = rc;
+}
+
+//Ironhead motion wall
+void ActNpc196(NPCHAR *npc)
+{
+	RECT rcLeft = {112, 64, 144, 80};
+	RECT rcRight = {112, 80, 144, 96};
+
+	npc->x -= 0xC00;
+
+	if (npc->x <= 0x26000)
+		npc->x += 0x2C000;
+
+	if (npc->direct == 0)
+		npc->rect = rcLeft;
+	else
+		npc->rect = rcRight;
+}
+
+//Porcupine Fish
+void ActNpc197(NPCHAR *npc)
+{
+	RECT rc[4];
+
+	rc[0] = {0, 0, 16, 16};
+	rc[1] = {16, 0, 32, 16};
+	rc[2] = {32, 0, 48, 16};
+	rc[3] = {48, 0, 64, 16};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 10;
+			npc->ani_wait = 0;
+			npc->ym = Random(-0x200, 0x200);
+			npc->xm = 0x800;
+			// Fallthrough
+		case 10:
+			if (++npc->ani_wait > 2)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 1)
+				npc->ani_no = 0;
+
+			if (npc->xm < 0)
+			{
+				npc->damage = 3;
+				npc->act_no = 20;
+			}
+
+			break;
+
+		case 20:
+			npc->damage = 3;
+
+			if (++npc->ani_wait > 0)
+			{
+				npc->ani_wait = 0;
+				++npc->ani_no;
+			}
+
+			if (npc->ani_no > 3)
+				npc->ani_no = 2;
+
+			if (npc->x < 0x6000)
+			{
+				npc->destroy_voice = 0;
+				LoseNpChar(npc, 1);
+			}
+
+			break;
+	}
+
+	if (npc->flag & 2)
+		npc->ym = 0x200;
+	if (npc->flag & 8)
+		npc->ym = -0x200;
+
+	npc->xm -= 12;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Ironhead projectile
+void ActNpc198(NPCHAR *npc)
+{
+	RECT rcRight[3];
+
+	rcRight[0] = {208, 48, 224, 72};
+	rcRight[1] = {224, 48, 240, 72};
+	rcRight[2] = {240, 48, 256, 72};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			if (++npc->act_wait > 20)
+			{
+				npc->act_no = 1;
+				npc->xm = 0;
+				npc->ym = 0;
+				npc->count1 = 0;
+			}
+
+			break;
+
+		case 1:
+			npc->xm += 0x20;
+			break;
+	}
+
+	if (++npc->ani_wait > 0)
+	{
+		npc->ani_wait = 0;
+		++npc->ani_no;
+	}
+
+	if (npc->ani_no > 2)
+		npc->ani_no = 0;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	npc->rect = rcRight[npc->ani_no];
+
+	if (++npc->count1 > 100)
+		npc->cond = 0;
+
+	if (npc->count1 % 4 == 1)
+		PlaySoundObject(46, 1);
 }
 
 //Water/wind particles
--- a/src/NpcAct260.cpp
+++ b/src/NpcAct260.cpp
@@ -8,6 +8,103 @@
 #include "Sound.h"
 #include "Back.h"
 #include "Triangle.h"
+#include "Caret.h"
+#include "Map.h"
+
+// Ironhead block
+void ActNpc271(NPCHAR *npc)
+{
+	if (npc->xm < 0 && npc->x < -0x2000)
+	{
+		VanishNpChar(npc);
+	}
+	else
+	{
+		if (npc->xm > 0 && npc->x > (gMap.width + 1) * 0x2000)
+		{
+			VanishNpChar(npc);
+		}
+		else
+		{
+			if (npc->act_no == 0)
+			{
+				npc->act_no = 1;
+				int a = Random(0, 9);
+
+				if (a == 9)
+				{
+					npc->rect.left = 0;
+					npc->rect.right = 0x20;
+					npc->rect.top = 0x40;
+					npc->rect.bottom = 0x60;
+					npc->view.front = 0x2000;
+					npc->view.back = 0x2000;
+					npc->view.top = 0x2000;
+					npc->view.bottom = 0x2000;
+					npc->hit.front = 0x1800;
+					npc->hit.back = 0x1800;
+					npc->hit.top = 0x1800;
+					npc->hit.bottom = 0x1800;
+				}
+				else
+				{
+					npc->rect.left = 16 * (a % 3 + 7);
+					npc->rect.top = 16 * (a / 3);
+					npc->rect.right = npc->rect.left + 16;
+					npc->rect.bottom = npc->rect.top + 16;
+				}
+
+				if (npc->direct == 0)
+					npc->xm = -2 * Random(0x100, 0x200);
+				else
+					npc->xm = 2 * Random(0x100, 0x200);
+
+				npc->ym = Random(-0x200, 0x200);
+			}
+
+			if (npc->ym < 0 && npc->y - npc->hit.top <= 0xFFF)
+			{
+				npc->ym = -npc->ym;
+				SetCaret(npc->x, npc->y - 0x1000, 13, 0);
+				SetCaret(npc->x, npc->y - 0x1000, 13, 0);
+			}
+
+			if (npc->ym > 0 && npc->y + npc->hit.bottom > 0x1D000)
+			{
+				npc->ym = -npc->ym;
+				SetCaret(npc->x, npc->y + 0x1000, 13, 0);
+				SetCaret(npc->x, npc->y + 0x1000, 13, 0);
+			}
+
+			npc->x += npc->xm;
+			npc->y += npc->ym;
+		}
+	}
+}
+
+// Ironhead block generator
+void ActNpc272(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->act_wait = Random(0, 200);
+			// Fallthrough
+		case 1:
+			if (npc->act_wait)
+			{
+				--npc->act_wait;
+			}
+			else
+			{
+				npc->act_no = 0;
+				SetNpChar(271, npc->x, npc->y + (Random(-32, 32) * 0x200), 0, 0, npc->direct, 0, 0x100);
+			}
+
+			break;
+	}
+}
 
 //Little family
 void ActNpc278(NPCHAR *npc)
--- a/src/NpcAct320.cpp
+++ b/src/NpcAct320.cpp
@@ -54,3 +54,78 @@
 	else
 		npc->rect = rcRight[npc->ani_no];
 }
+
+//Ikachan
+void ActNpc335(NPCHAR *npc)
+{
+	RECT rc[3];
+
+	rc[0] = {0, 16, 16, 32};
+	rc[1] = {16, 16, 32, 32};
+	rc[2] = {32, 16, 48, 32};
+
+	switch (npc->act_no)
+	{
+		case 0:
+			npc->act_no = 1;
+			npc->act_wait = Random(3, 20);
+			// Fallthrough
+		case 1:
+			if (--npc->act_wait <= 0)
+			{
+				npc->act_no = 2;
+				npc->act_wait = Random(10, 50);
+				npc->ani_no = 1;
+				npc->xm = 0x600;
+			}
+
+			break;
+
+		case 2:
+			if (--npc->act_wait <= 0)
+			{
+				npc->act_no = 3;
+				npc->act_wait = Random(40, 50);
+				npc->ani_no = 2;
+				npc->ym = Random(-0x100, 0x100);
+			}
+
+			break;
+
+		case 3:
+			if (--npc->act_wait <= 0)
+			{
+				npc->act_no = 1;
+				npc->act_wait = 0;
+				npc->ani_no = 0;
+			}
+
+			break;
+	}
+
+	npc->xm -= 0x10;
+
+	npc->x += npc->xm;
+	npc->y += npc->ym;
+
+	npc->rect = rc[npc->ani_no];
+}
+
+//Ikachan generator
+void ActNpc336(NPCHAR *npc)
+{
+	switch (npc->act_no)
+	{
+		case 0:
+			if (gMC.shock)
+				npc->cond = 0;
+
+			break;
+
+		case 10:
+			if (++npc->act_wait % 4 == 1 )
+				SetNpChar(335, npc->x, npc->y + (Random(0, 13) * 0x2000), 0, 0, 0, 0, 0);
+
+			break;
+	}
+}
--- a/src/NpcTbl.cpp
+++ b/src/NpcTbl.cpp
@@ -252,9 +252,9 @@
 	ActNpc193,
 	ActNpc194,
 	ActNpc195,
-	nullptr,
-	nullptr,
-	nullptr,
+	ActNpc196,
+	ActNpc197,
+	ActNpc198,
 	ActNpc199,
 	nullptr,
 	nullptr,
@@ -391,8 +391,8 @@
 	nullptr,
 	nullptr,
 	ActNpc334,
-	nullptr,
-	nullptr,
+	ActNpc335,
+	ActNpc336,
 	nullptr,
 	nullptr,
 	nullptr,
--- a/src/TextScr.cpp
+++ b/src/TextScr.cpp
@@ -889,6 +889,16 @@
 						else
 							gTS.p_read += 13;
 					}
+					else if (IS_COMMAND('A','M','J'))
+					{
+						x = GetTextScriptNo(gTS.p_read + 4);
+						z = GetTextScriptNo(gTS.p_read + 9);
+
+						if (CheckArms(x))
+							JumpTextScript(z);
+						else
+							gTS.p_read += 13;
+					}
 					else if (IS_COMMAND('U','N','J'))
 					{
 						x = GetTextScriptNo(gTS.p_read + 4);