From dfe2ec83aea6fab9d652a8b5091e5d60cac846de Mon Sep 17 00:00:00 2001 From: Clownacy Date: Fri, 8 Feb 2019 16:35:35 +0000 Subject: [PATCH 1/4] Made Flash.cpp *really* accurate So I found out that the orignal EXE was compiled with Visual Studio .NET 2003, thanks to its Rich Header. With this compiler, I can create the exact same assembly code as the EXE. Using this, I found a bunch of inaccuracies in Flash.cpp, as a small test. I'll come back to this later, once the rest of the game is complete, but until then, here's a small taster. --- src/Flash.cpp | 143 ++++++++++++++++++++++++------------------- src/WindowsWrapper.h | 11 ++++ 2 files changed, 92 insertions(+), 62 deletions(-) diff --git a/src/Flash.cpp b/src/Flash.cpp index a9fa57f6..c6a04389 100644 --- a/src/Flash.cpp +++ b/src/Flash.cpp @@ -1,14 +1,14 @@ -#include "WindowsWrapper.h" - #include "Flash.h" -#include "Draw.h" + #include "CommonDefines.h" +#include "Draw.h" +#include "WindowsWrapper.h" static struct { int mode; int act_no; - bool flag; + BOOL flag; int cnt; int width; int x; @@ -27,7 +27,7 @@ void InitFlash(void) void SetFlash(int x, int y, int mode) { flash.act_no = 0; - flash.flag = true; + flash.flag = TRUE; flash.x = x; flash.y = y; flash.mode = mode; @@ -37,66 +37,72 @@ void SetFlash(int x, int y, int mode) void ActFlash_Explosion(int flx, int fly) { - if (flash.act_no == 0) + int left, right, top, bottom; + + switch (flash.act_no) { - flash.cnt += 0x200; - flash.width += flash.cnt; + case 0: + flash.cnt += 0x200; + flash.width += flash.cnt; - int right = (flash.x - flx - flash.width) / 0x200; - int left = (flash.y - fly - flash.width) / 0x200; - int top = (flash.width + flash.x - flx) / 0x200; - int bottom = (flash.width + flash.y - fly) / 0x200; + right = (flash.x - flx - flash.width) / 0x200; + left = (flash.y - fly - flash.width) / 0x200; + top = (flash.x - flx + flash.width) / 0x200; + bottom = (flash.y - fly + flash.width) / 0x200; - if (right < 0) - right = 0; - if (left < 0) - left = 0; - if (top > WINDOW_WIDTH) - top = WINDOW_WIDTH; - if (bottom > WINDOW_HEIGHT) - bottom = WINDOW_HEIGHT; + if (right < 0) + right = 0; + if (left < 0) + left = 0; + if (top > WINDOW_WIDTH) + top = WINDOW_WIDTH; + if (bottom > WINDOW_HEIGHT) + bottom = WINDOW_HEIGHT; - flash.rect1.left = right; - flash.rect1.right = top; - flash.rect1.top = 0; - flash.rect1.bottom = WINDOW_HEIGHT; + flash.rect1.left = right; + flash.rect1.right = top; + flash.rect1.top = 0; + flash.rect1.bottom = WINDOW_HEIGHT; - flash.rect2.left = 0; - flash.rect2.right = WINDOW_WIDTH; - flash.rect2.top = left; - flash.rect2.bottom = bottom; + flash.rect2.left = 0; + flash.rect2.right = WINDOW_WIDTH; + flash.rect2.top = left; + flash.rect2.bottom = bottom; - if (flash.width > (WINDOW_WIDTH << 11)) - { - flash.act_no = 1; - flash.cnt = 0; - flash.width = (WINDOW_HEIGHT << 9); - } - } - else if (flash.act_no == 1) - { - flash.width -= flash.width / 8; + if (flash.width > (WINDOW_WIDTH << 11)) + { + flash.act_no = 1; + flash.cnt = 0; + flash.width = (WINDOW_HEIGHT << 9); + } - if ((flash.width / 0x100) == 0) - flash.flag = false; + break; - int top = (flash.y - fly - flash.width) / 0x200; - if (top < 0) - top = 0; + case 1: + flash.width -= flash.width / 8; - int bottom = (flash.width + flash.y - fly) / 0x200; - if (bottom > WINDOW_HEIGHT) - bottom = WINDOW_HEIGHT; + if ((flash.width / 0x100) == 0) + flash.flag = FALSE; - flash.rect1.left = 0; - flash.rect1.right = 0; - flash.rect1.top = 0; - flash.rect1.bottom = 0; + top = (flash.y - fly - flash.width) / 0x200; + if (top < 0) + top = 0; - flash.rect2.top = top; - flash.rect2.bottom = bottom; - flash.rect2.left = 0; - flash.rect2.right = WINDOW_WIDTH; + bottom = (flash.y - fly + flash.width) / 0x200; + if (bottom > WINDOW_HEIGHT) + bottom = WINDOW_HEIGHT; + + flash.rect1.left = 0; + flash.rect1.right = 0; + flash.rect1.top = 0; + flash.rect1.bottom = 0; + + flash.rect2.top = top; + flash.rect2.bottom = bottom; + flash.rect2.left = 0; + flash.rect2.right = WINDOW_WIDTH; + + break; } } @@ -125,23 +131,36 @@ void ActFlash_Flash(void) } if (flash.cnt > 20) - flash.flag = false; + flash.flag = FALSE; } void ActFlash(int flx, int fly) { - if (flash.flag) + if (flash.flag == FALSE) { - if (flash.mode == 1) - ActFlash_Explosion(flx, fly); - else if (flash.mode == 2) - ActFlash_Flash(); + // Do nothing + } + else + { + switch (flash.mode) + { + case 1: + ActFlash_Explosion(flx, fly); + break; + case 2: + ActFlash_Flash(); + break; + } } } void PutFlash(void) { - if (flash.flag) + if (flash.flag == FALSE) + { + // Do nothing + } + else { CortBox(&flash.rect1, gFlashColor); CortBox(&flash.rect2, gFlashColor); @@ -150,5 +169,5 @@ void PutFlash(void) void ResetFlash(void) { - flash.flag = false; + flash.flag = FALSE; } diff --git a/src/WindowsWrapper.h b/src/WindowsWrapper.h index 1b2a963c..17918798 100644 --- a/src/WindowsWrapper.h +++ b/src/WindowsWrapper.h @@ -1,4 +1,15 @@ #pragma once + +typedef int BOOL; + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + struct RECT { union From 7a97c2c93850a3c486949fd37157821cfc317172 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Fri, 8 Feb 2019 16:38:32 +0000 Subject: [PATCH 2/4] More NPCs --- src/NpcAct.h | 13 +- src/NpcAct240.cpp | 515 ++++++++++++++++++++++++++++++++++++++++++++++ src/NpcAct260.cpp | 239 +++++++++++++++++++++ src/NpcTbl.cpp | 22 +- 4 files changed, 777 insertions(+), 12 deletions(-) diff --git a/src/NpcAct.h b/src/NpcAct.h index 18272292..2fdf68d2 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -243,6 +243,16 @@ void ActNpc237(NPCHAR *npc); void ActNpc238(NPCHAR *npc); void ActNpc239(NPCHAR *npc); void ActNpc240(NPCHAR *npc); +void ActNpc241(NPCHAR *npc); +void ActNpc242(NPCHAR *npc); +void ActNpc243(NPCHAR *npc); +void ActNpc244(NPCHAR *npc); +void ActNpc245(NPCHAR *npc); +void ActNpc246(NPCHAR *npc); + +void ActNpc253(NPCHAR *npc); +void ActNpc254(NPCHAR *npc); +void ActNpc255(NPCHAR *npc); void ActNpc259(NPCHAR *npc); @@ -251,7 +261,8 @@ void ActNpc272(NPCHAR *npc); void ActNpc273(NPCHAR *npc); void ActNpc274(NPCHAR *npc); void ActNpc275(NPCHAR *npc); - +void ActNpc276(NPCHAR *npc); +void ActNpc277(NPCHAR *npc); void ActNpc278(NPCHAR *npc); void ActNpc292(NPCHAR *npc); diff --git a/src/NpcAct240.cpp b/src/NpcAct240.cpp index 04430c50..5006cf31 100644 --- a/src/NpcAct240.cpp +++ b/src/NpcAct240.cpp @@ -8,6 +8,9 @@ #include "Sound.h" #include "Back.h" #include "Triangle.h" +#include "Caret.h" +#include "Frame.h" +#include "Map.h" //Mimiga (jailed) void ActNpc240(NPCHAR *npc) @@ -113,6 +116,518 @@ void ActNpc240(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Critter (Last Cave) +void ActNpc241(NPCHAR *npc) +{ + RECT rcLeft[3]; + RECT rcRight[3]; + + rcLeft[0] = {0, 0, 16, 16}; + rcLeft[1] = {16, 0, 32, 16}; + rcLeft[2] = {32, 0, 48, 16}; + + rcRight[0] = {0, 16, 16, 32}; + rcRight[1] = {16, 16, 32, 32}; + rcRight[2] = {32, 16, 48, 32}; + + switch (npc->act_no) + { + case 0: + npc->y += 0x600; + npc->act_no = 1; + // Fallthrough + case 1: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->act_wait >= 8 && gMC.x > npc->x - 0x12000 && gMC.x < npc->x + 0x12000 && gMC.y > npc->y - 0xA000 && gMC.y < npc->y + 0xA000) + { + npc->ani_no = 1; + } + else + { + if ( npc->act_wait < 8 ) + ++npc->act_wait; + + npc->ani_no = 0; + } + + if (npc->shock) + { + npc->act_no = 2; + npc->ani_no = 0; + npc->act_wait = 0; + } + + if (npc->act_wait >= 8 && gMC.x > npc->x - 0xC000 && gMC.x < npc->x + 0xC000 && gMC.y > npc->y - 0xA000 && gMC.y < npc->y + 0xC000) + { + npc->act_no = 2; + npc->ani_no = 0; + npc->act_wait = 0; + } + + break; + + case 2: + if (++npc->act_wait > 8) + { + npc->act_no = 3; + npc->ani_no = 2; + npc->ym = -0x5FF; + PlaySoundObject(30, 1); + + if (npc->direct == 0) + npc->xm = -0x200; + else + npc->xm = 0x200; + } + + break; + + case 3: + if (npc->flag & 8) + { + npc->xm = 0; + npc->act_wait = 0; + npc->ani_no = 0; + npc->act_no = 1; + PlaySoundObject(23, 1); + } + + break; + } + + npc->ym += 0x55; + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Bat (Last Cave) +void ActNpc242(NPCHAR *npc) +{ + if (npc->x < 0 || npc->x > gMap.width * 0x2000) + { + VanishNpChar(npc); + return; + } + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->tgt_x = npc->x; + npc->tgt_y = npc->y; + npc->act_wait = Random(0, 50); + // Fallthrough + case 1: + if (npc->act_wait) + { + --npc->act_wait; + break; + } + + npc->act_no = 2; + npc->ym = 0x400; + // Fallthrough + case 2: + if (npc->direct == 0) + npc->xm = -0x100; + else + npc->xm = 0x100; + + if (npc->tgt_y < npc->y) + npc->ym -= 0x10; + if (npc->tgt_y > npc->y) + npc->ym += 0x10; + + if (npc->ym > 0x300) + npc->ym = 0x300; + if (npc->ym < -0x300) + npc->ym = -0x300; + + break; + } + + npc->x += npc->xm; + npc->y += npc->ym; + + RECT rect_left[4]; + RECT rect_right[4]; + + rect_left[0] = {32, 32, 48, 48}; + rect_left[1] = {48, 32, 64, 48}; + rect_left[2] = {64, 32, 80, 48}; + rect_left[3] = {80, 32, 96, 48}; + + rect_right[0] = {32, 48, 48, 64}; + rect_right[1] = {48, 48, 64, 64}; + rect_right[2] = {64, 48, 80, 64}; + rect_right[3] = {80, 48, 96, 64}; + + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + npc->ani_no = 0; + + if (npc->direct == 0) + npc->rect = rect_left[npc->ani_no]; + else + npc->rect = rect_right[npc->ani_no]; +} + +//Bat generator (Last Cave) +void ActNpc243(NPCHAR *npc) +{ + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->act_wait = Random(0, 500); + // Fallthrough + case 1: + if (npc->act_wait) + { + --npc->act_wait; + } + else + { + npc->act_no = 0; + SetNpChar(242, npc->x, npc->y + (Random(-0x20, 0x20) * 0x100), 0, 0, npc->direct, 0, 0x100); + } + + break; + } +} + +//Lava drop +void ActNpc244(NPCHAR *npc) +{ + RECT rc = {96, 0, 104, 16}; + npc->ym += 0x40; + bool bHit = false; + + if (npc->flag & 0xFF) + bHit = true; + + if (npc->act_wait > 10 && npc->flag & 0x100) + bHit = true; + + if (bHit) + { + for (int i = 0; i < 3; ++i) + SetCaret(npc->x, npc->y + 0x800, 1, 2); + + if (npc->x > gMC.x - 0x20000 && npc->x < gMC.x + 0x20000 && npc->y > gMC.y - 0x14000 && npc->y < gMC.y + 0x14000) + PlaySoundObject(21, 1); + + npc->cond = 0; + } + else + { + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->y += npc->ym; + + npc->rect = rc; + } +} + +//Lava drop generator +void ActNpc245(NPCHAR *npc) +{ + RECT rc[4]; + + rc[0] = {0, 0, 0, 0}; + rc[1] = {104, 0, 112, 16}; + rc[2] = {112, 0, 120, 16}; + rc[3] = {120, 0, 128, 16}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->tgt_x = npc->x; + npc->act_wait = npc->code_event; + // Fallthrough + case 1: + npc->ani_no = 0; + + if ( npc->act_wait ) + { + --npc->act_wait; + return; + } + + npc->act_no = 10; + npc->ani_wait = 0; + break; + + case 10: + if (++npc->ani_wait > 10) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 3) + { + npc->ani_no = 0; + npc->act_no = 1; + npc->act_wait = npc->code_flag; + SetNpChar(244, npc->x, npc->y, 0, 0, 0, 0, 0x100); + } + + break; + } + + if (npc->ani_wait / 2 % 2) + npc->x = npc->tgt_x; + else + npc->x = npc->tgt_x + 0x200; + + npc->rect = rc[npc->ani_no]; +} + +//Press (proximity) +void ActNpc246(NPCHAR *npc) +{ + RECT rcLeft[3]; + + rcLeft[0] = {144, 112, 160, 136}; + rcLeft[1] = {160, 112, 176, 136}; + rcLeft[2] = {176, 112, 192, 136}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->y -= 0x800; + // Fallthrough + case 1: + if (gMC.x < npc->x + 0x1000 && gMC.x > npc->x - 0x1000 && gMC.y > npc->y + 0x1000 && gMC.y < npc->y + 0x10000) + npc->act_no = 5; + + break; + + case 5: + if ((npc->flag & 8) == 0) + { + npc->act_no = 10; + npc->ani_wait = 0; + npc->ani_no = 1; + } + + break; + + case 10: + if (++npc->ani_wait > 2) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + npc->ani_no = 2; + + if (gMC.y > npc->y) + { + npc->bits &= ~0x40; + npc->damage = 0x7F; + } + else + { + npc->bits |= 0x40; + npc->damage = 0; + } + + if (npc->flag & 8) + { + if (npc->ani_no > 1) + { + for (int i = 0; i < 4; ++i) + SetNpChar(4, npc->x, npc->y, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + PlaySoundObject(26, 1); + SetQuake(10); + } + + npc->act_no = 20; + npc->ani_no = 0; + npc->ani_wait = 0; + npc->bits |= 0x40; + npc->damage = 0; + } + + break; + } + + if (npc->act_no >= 5) + { + npc->ym += 0x80; + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->y += npc->ym; + } + + npc->rect = rcLeft[npc->ani_no]; +} + +//EXP capsule +void ActNpc253(NPCHAR *npc) +{ + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + // Fallthrough + case 1: + if (++npc->ani_wait > 4) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + + break; + } + + if (npc->life <= 100) + { + SetExpObjects(npc->x, npc->y, npc->code_flag); + SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8); + PlaySoundObject(25, 1); + npc->cond = 0; + } + + RECT rc[2]; + + rc[0] = {0, 64, 16, 80}; + rc[1] = {16, 64, 32, 80}; + + npc->rect = rc[npc->ani_no]; +} + +//Helicopter +void ActNpc254(NPCHAR *npc) +{ + RECT rc[2]; + + rc[0] = {0, 0, 128, 64}; + rc[1] = {0, 64, 128, 128}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + SetNpChar(255, npc->x + 0x2400, npc->y - 0x7200, 0, 0, 0, npc, 0x100); + SetNpChar(255, npc->x - 0x4000, npc->y - 0x6800, 0, 0, 2, npc, 0x100); + break; + case 20: + npc->act_wait = 0; + npc->count1 = 60; + npc->act_no = 21; + break; + case 30: + npc->act_no = 21; + SetNpChar(223, npc->x - 0x1600, npc->y - 0x1C00, 0, 0, 0, 0, 0x100); + break; + case 40: + npc->act_no = 21; + SetNpChar(223, npc->x - 0x1200, npc->y - 0x1C00, 0, 0, 0, 0, 0x100); + SetNpChar(40, npc->x - 0x2C00, npc->y - 0x1C00, 0, 0, 0, 0, 0x100); + SetNpChar(93, npc->x - 0x4600, npc->y - 0x1C00, 0, 0, 0, 0, 0x100); + break; + } + + if (npc->direct == 0) + npc->rect = rc[0]; + else + npc->rect = rc[1]; +} + +//Helicopter blades +void ActNpc255(NPCHAR *npc) +{ + RECT rcLeft[4]; + RECT rcRight[4]; + + rcLeft[0] = {128, 0, 240, 16}; + rcLeft[1] = {128, 16, 240, 32}; + rcLeft[2] = {128, 32, 240, 48}; + rcLeft[3] = {128, 16, 240, 32}; + + rcRight[0] = {240, 0, 320, 16}; + rcRight[1] = {240, 16, 320, 32}; + rcRight[2] = {240, 32, 320, 48}; + rcRight[3] = {240, 16, 320, 32}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + + if (npc->direct == 0) + { + npc->view.front = 0x7000; + npc->view.back = 0x7000; + } + else + { + npc->view.front = 0x5000; + npc->view.back = 0x5000; + } + // Fallthrough + case 1: + if (npc->pNpc->act_no >= 20) + npc->act_no = 10; + + break; + + case 10: + npc->act_no = 11; + // Fallthrough + case 11: + if (++npc->ani_no > 3) + npc->ani_no = 0; + + break; + } + + if (npc->direct == 0) + { + npc->x = npc->pNpc->x + 0x2400; + npc->y = npc->pNpc->y - 0x7200; + } + else + { + npc->x = npc->pNpc->x - 0x4000; + npc->y = npc->pNpc->y - 0x6800; + } + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + //Curly (carried and unconcious) void ActNpc259(NPCHAR *npc) { diff --git a/src/NpcAct260.cpp b/src/NpcAct260.cpp index 4881dd3d..02b4f57f 100644 --- a/src/NpcAct260.cpp +++ b/src/NpcAct260.cpp @@ -10,6 +10,7 @@ #include "Triangle.h" #include "Caret.h" #include "Map.h" +#include "Frame.h" // Ironhead block void ActNpc271(NPCHAR *npc) @@ -328,6 +329,244 @@ void ActNpc275(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Red Demon +void ActNpc276(NPCHAR *npc) +{ + RECT rcLeft[9]; + RECT rcRight[9]; + + rcLeft[0] = {0, 64, 32, 104}; + rcLeft[1] = {32, 64, 64, 104}; + rcLeft[2] = {64, 64, 96, 104}; + rcLeft[3] = {96, 64, 128, 104}; + rcLeft[4] = {128, 64, 160, 104}; + rcLeft[5] = {160, 64, 192, 104}; + rcLeft[6] = {192, 64, 224, 104}; + rcLeft[7] = {224, 64, 256, 104}; + rcLeft[8] = {256, 64, 288, 104}; + + rcRight[0] = {0, 104, 32, 144}; + rcRight[1] = {32, 104, 64, 144}; + rcRight[2] = {64, 104, 96, 144}; + rcRight[3] = {96, 104, 128, 144}; + rcRight[4] = {128, 104, 160, 144}; + rcRight[5] = {160, 104, 192, 144}; + rcRight[6] = {192, 104, 224, 144}; + rcRight[7] = {224, 104, 256, 144}; + rcRight[8] = {256, 104, 288, 144}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->y -= 0x1000; + // Fallthrough + case 1: + npc->xm = 0; + npc->act_no = 2; + npc->ani_no = 0; + // Fallthrough + case 2: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (++npc->ani_wait > 20) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + + if (npc->shock) + npc->act_no = 10; + + break; + + case 10: + npc->act_no = 11; + npc->act_wait = 0; + npc->ani_no = 3; + npc->bits |= 0x20u; + // Fallthrough + case 11: + switch (++npc->act_wait) + { + case 30: + case 40: + case 50: + { + npc->ani_no = 4; + const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y); + const int ym = 4 * GetSin(deg); + const int xm = 4 * GetCos(deg); + SetNpChar(277, npc->x, npc->y, xm, ym, 0, 0, 0x100); + PlaySoundObject(39, 1); + break; + } + case 34: + case 44: + case 54: + { + npc->ani_no = 3; + break; + } + } + + if (npc->act_wait > 60) + { + npc->act_no = 20; + npc->act_wait = 0; + npc->ani_no = 2; + } + + break; + + case 20: + if (++npc->act_wait > 20) + { + npc->act_no = 21; + npc->act_wait = 0; + npc->ani_no = 5; + npc->ym = -0x5FF; + if (gMC.x > npc->x) + npc->xm = 0x100; + else + npc->xm = -0x100; + } + + break; + + case 21: + switch (++npc->act_wait) + { + case 30: + case 40: + case 50: + { + npc->ani_no = 6; + const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - 0x1400 - gMC.y); + const int ym = 4 * GetSin(deg); + const int xm = 4 * GetCos(deg); + SetNpChar(277, npc->x, npc->y - 0x1400, xm, ym, 0, 0, 0x100); + PlaySoundObject(39, 1); + break; + } + case 34: + case 44: + { + npc->ani_no = 5; + break; + } + } + + if (npc->act_wait > 53) + npc->ani_no = 7; + + if (npc->flag & 8) + { + npc->act_no = 22; + npc->act_wait = 0; + npc->ani_no = 2; + SetQuake(10); + PlaySoundObject(26, 1); + } + + break; + + case 22: + npc->xm /= 2; + + if (++npc->act_wait > 22) + npc->act_no = 10; + + break; + + case 50: + npc->bits &= ~0x20; + npc->damage = 0; + + if (npc->flag & 8) + { + npc->act_no = 51; + npc->ani_no = 2; + SetQuake(10); + SetExpObjects(npc->x, npc->y, 19); + SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8); + PlaySoundObject(72, 1); + } + + break; + + case 51: + npc->xm = 7 * npc->xm / 8; + npc->ani_no = 8; + break; + } + + npc->ym += 0x20; + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->act_no < 50) + { + if (gMC.x > npc->x) + npc->direct = 2; + else + npc->direct = 0; + } + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Red Demon projectile +void ActNpc277(NPCHAR *npc) +{ + RECT rc[3]; + + rc[0] = {128, 0, 152, 24}; + rc[1] = {152, 0, 176, 24}; + rc[2] = {176, 0, 200, 24}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + // Fallthrough + case 1: + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->flag & 0xFF) + { + SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100); + SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100); + SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100); + VanishNpChar(npc); + return; + } + + if (++npc->act_wait % 5 == 0) + PlaySoundObject(110, 1); + + if (++npc->ani_no > 2) + npc->ani_no = 0; + + break; + } + + npc->rect = rc[npc->ani_no]; +} + //Little family void ActNpc278(NPCHAR *npc) { diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index 3607ec48..d4acd5d7 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -297,21 +297,21 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc238, ActNpc239, ActNpc240, + ActNpc241, + ActNpc242, + ActNpc243, + ActNpc244, + ActNpc245, + ActNpc246, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, + ActNpc253, + ActNpc254, + ActNpc255, nullptr, nullptr, nullptr, @@ -332,8 +332,8 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc273, ActNpc274, ActNpc275, - nullptr, - nullptr, + ActNpc276, + ActNpc277, ActNpc278, nullptr, nullptr, From 88947cd016699382cd99d7cbf306e18cb6a5fb50 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Fri, 8 Feb 2019 18:46:10 +0000 Subject: [PATCH 3/4] More NPCs --- src/NpcAct.h | 9 +- src/NpcAct240.cpp | 565 ++++++++++++++++++++++++++++++++++++++++++++++ src/NpcAct260.cpp | 199 ++++++++++++++++ src/NpcTbl.cpp | 14 +- 4 files changed, 779 insertions(+), 8 deletions(-) diff --git a/src/NpcAct.h b/src/NpcAct.h index 2fdf68d2..71e20c34 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -249,13 +249,20 @@ void ActNpc243(NPCHAR *npc); void ActNpc244(NPCHAR *npc); void ActNpc245(NPCHAR *npc); void ActNpc246(NPCHAR *npc); - +void ActNpc247(NPCHAR *npc); +void ActNpc248(NPCHAR *npc); +void ActNpc249(NPCHAR *npc); +void ActNpc250(NPCHAR *npc); +void ActNpc251(NPCHAR *npc); +void ActNpc252(NPCHAR *npc); void ActNpc253(NPCHAR *npc); void ActNpc254(NPCHAR *npc); void ActNpc255(NPCHAR *npc); void ActNpc259(NPCHAR *npc); +void ActNpc268(NPCHAR *npc); + void ActNpc271(NPCHAR *npc); void ActNpc272(NPCHAR *npc); void ActNpc273(NPCHAR *npc); diff --git a/src/NpcAct240.cpp b/src/NpcAct240.cpp index 5006cf31..b78e534d 100644 --- a/src/NpcAct240.cpp +++ b/src/NpcAct240.cpp @@ -488,6 +488,571 @@ void ActNpc246(NPCHAR *npc) npc->rect = rcLeft[npc->ani_no]; } +//Misery (boss) +void ActNpc247(NPCHAR *npc) +{ + RECT rcLeft[9]; + RECT rcRight[9]; + + rcLeft[0] = {0, 0, 16, 16}; + rcLeft[1] = {16, 0, 32, 16}; + rcLeft[2] = {32, 0, 48, 16}; + rcLeft[3] = {48, 0, 64, 16}; + rcLeft[4] = {64, 0, 80, 16}; + rcLeft[5] = {80, 0, 96, 16}; + rcLeft[6] = {96, 0, 112, 16}; + rcLeft[7] = {0, 0, 0, 0}; + rcLeft[8] = {112, 0, 128, 16}; + + rcRight[0] = {0, 16, 16, 32}; + rcRight[1] = {16, 16, 32, 32}; + rcRight[2] = {32, 16, 48, 32}; + rcRight[3] = {48, 16, 64, 32}; + rcRight[4] = {64, 16, 80, 32}; + rcRight[5] = {80, 16, 96, 32}; + rcRight[6] = {96, 16, 112, 32}; + rcRight[7] = {0, 0, 0, 0}; + rcRight[8] = {112, 16, 128, 32}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->y += 0xC00; + npc->tgt_y = 0x8000; + // Fallthrough + case 1: + if (Random(0, 120) == 10) + { + npc->act_no = 2; + npc->act_wait = 0; + npc->ani_no = 1; + } + + break; + + case 2: + if (++npc->act_wait > 8) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + + case 20: + npc->xm = 0; + npc->ym += 0x40; + + if (npc->flag & 8) + { + npc->act_no = 21; + npc->ani_no = 2; + } + + break; + + case 21: + if (Random(0, 120) == 10) + { + npc->act_no = 22; + npc->act_wait = 0; + npc->ani_no = 3; + } + + break; + + case 22: + if (++npc->act_wait > 8) + { + npc->act_no = 21; + npc->ani_no = 2; + } + + break; + + case 100: + npc->act_no = 101; + npc->act_wait = 0; + npc->ani_no = 0; + npc->xm = 0; + npc->bits |= 0x20; + npc->count2 = npc->life; + // Fallthrough + case 101: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->tgt_y > npc->y) + npc->ym += 0x20; + else + npc->ym -= 0x20; + + if (npc->ym < -0x200) + npc->ym = -0x200; + if (npc->ym > 0x200) + npc->ym = 0x200; + + if (++npc->act_wait > 200 || npc->life <= npc->count2 - 80) + { + npc->act_wait = 0; + npc->act_no = 110; + } + + break; + + case 110: + npc->act_no = 111; + npc->act_wait = 0; + npc->xm = 0; + npc->ym = 0; + npc->bits &= ~0x20; + // Fallthrough + case 111: + if (++npc->act_wait % 2) + npc->ani_no = 5; + else + npc->ani_no = 6; + + if (npc->act_wait > 30) + { + npc->act_wait = 0; + + if (++npc->count1 % 3) + npc->act_no = 112; + else + npc->act_no = 113; + + npc->ani_no = 4; + } + + break; + + case 112: + if (++npc->act_wait % 6 == 0) + { + const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y) + Random(-4, 4); + const int ym = 4 * GetSin(deg); + const int xm = 4 * GetCos(deg); + SetNpChar(248, npc->x, npc->y + 0x800, xm, ym, 0, 0, 0x100); + PlaySoundObject(34, 1); + } + + if (npc->act_wait > 30) + { + npc->act_wait = 0; + npc->act_no = 150; + } + + break; + + case 113: + if (++npc->act_wait == 10) + SetNpChar(279, gMC.x, gMC.y - 0x8000, 0, 0, 1, 0, 0x100); + + if (npc->act_wait > 30) + { + npc->act_wait = 0; + npc->act_no = 150; + } + + break; + + case 150: + npc->act_no = 151; + npc->act_wait = 0; + npc->ani_no = 7; + SetNpChar(249, npc->x, npc->y, 0, 0, 0, 0, 0x100); + SetNpChar(249, npc->x, npc->y, 0, 0, 2, 0, 0x100); + npc->tgt_x = Random(9, 31) * 0x2000; + npc->tgt_y = Random(5, 7) * 0x2000; + PlaySoundObject(29, 1); + // Fallthrough + case 151: + if (++npc->act_wait == 42) + { + SetNpChar(249, npc->tgt_x + 0x2000, npc->tgt_y, 0, 0, 0, 0, 0x100); + SetNpChar(249, npc->tgt_x - 0x2000, npc->tgt_y, 0, 0, 2, 0, 0x100); + } + + if (npc->act_wait > 50) + { + npc->act_wait = 0; + npc->ym = -0x200; + npc->bits |= 0x20; + npc->x = npc->tgt_x; + npc->y = npc->tgt_y; + + if (npc->life < 340) + { + SetNpChar(252, 0, 0, 0, 0, 0, npc, 0x100); + SetNpChar(252, 0, 0, 0, 0, 0x80, npc, 0x100); + } + + if (npc->life < 180) + { + SetNpChar(252, 0, 0, 0, 0, 0x40, npc, 0x100); + SetNpChar(252, 0, 0, 0, 0, 0xC0, npc, 0x100); + } + + if (gMC.x < npc->x - 0xE000 || gMC.x > npc->x + 0xE000) + npc->act_no = 160; + else + npc->act_no = 100; + } + + break; + + case 160: + npc->act_no = 161; + npc->act_wait = 0; + npc->ani_no = 4; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + // Fallthrough + case 161: + if (npc->tgt_y > npc->y) + npc->ym += 0x20; + else + npc->ym -= 0x20; + + if (npc->ym < -0x200) + npc->ym = -0x200; + if (npc->ym > 0x200) + npc->ym = 0x200; + + if (++npc->act_wait % 24 == 0) + { + SetNpChar(250, npc->x, npc->y + 0x800, 0, 0, 0, 0, 0x100); + PlaySoundObject(34, 1); + } + + if (npc->act_wait > 72) + { + npc->act_wait = 0; + npc->act_no = 100; + } + + break; + + case 1000: + npc->bits &= ~0x20; + npc->act_no = 1001; + npc->act_wait = 0; + npc->ani_no = 4; + npc->tgt_x = npc->x; + npc->tgt_y = npc->y; + npc->xm = 0; + npc->ym = 0; + DeleteNpCharCode(252, 1); + SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100); + SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100); + SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100); + // Fallthrough + case 1001: + if (++npc->act_wait / 2 % 2) + npc->x = npc->tgt_x + 0x200; + else + npc->x = npc->tgt_x; + + break; + + case 1010: + npc->ym += 0x10; + + if (npc->flag & 8) + { + npc->act_no = 1020; + npc->ani_no = 8; + } + + break; + } + + if (npc->xm < -0x200) + npc->xm = -0x200; + if (npc->xm > 0x200) + npc->xm = 0x200; + + if (npc->ym < -0x400) + npc->ym = -0x400; + if (npc->ym > 0x400) + npc->ym = 0x400; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Boss Misery (vanishing) +void ActNpc248(NPCHAR *npc) +{ + if (npc->flag & 0xFF) + { + npc->cond = 0; + SetCaret(npc->x, npc->y, 2, 0); + } + + npc->y += npc->ym; + npc->x += npc->xm; + + RECT rect_left[3]; + + rect_left[0] = {0, 48, 16, 64}; + rect_left[1] = {16, 48, 32, 64}; + rect_left[2] = {32, 48, 48, 64}; + + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + + if (++npc->ani_no > 2) + npc->ani_no = 0; + } + + npc->rect = rect_left[npc->ani_no]; + + if (++npc->count1 > 300) + { + npc->cond = 0; + SetCaret(npc->x, npc->y, 2, 0); + } +} + +//Boss Misery energy shot +void ActNpc249(NPCHAR *npc) +{ + RECT rc[2]; + + rc[0] = {48, 48, 64, 64}; + rc[1] = {64, 48, 80, 64}; + + if (++npc->act_wait > 8) + npc->cond = 0; + + if (npc->direct == 0) + { + npc->rect = rc[0]; + npc->x -= 1024; + } + else + { + npc->rect = rc[1]; + npc->x += 1024; + } +} + +//Boss Misery lightning ball +void ActNpc250(NPCHAR *npc) +{ + RECT rc[3]; + + rc[0] = {0, 32, 16, 48}; + rc[1] = {16, 32, 32, 48}; + rc[2] = {32, 32, 48, 48}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->tgt_y = npc->y; + npc->xm = 0; + npc->ym = -0x200; + // Fallthrough + case 1: + if (gMC.x > npc->x) + npc->xm += 0x10; + else + npc->xm -= 0x10; + + if (npc->tgt_y > npc->y) + npc->ym += 0x20; + else + npc->ym -= 0x20; + + if (npc->xm > 0x200) + npc->xm = 0x200; + if (npc->xm < -0x200) + npc->xm = -0x200; + + if (npc->ym > 0x200) + npc->ym = 0x200; + if (npc->ym < -0x200) + npc->ym = -0x200; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (++npc->ani_wait > 2) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + + if (gMC.x > npc->x - 0x1000 && gMC.x < npc->x + 0x1000 && gMC.y > npc->y) + npc->act_no = 10; + + break; + + case 10: + npc->act_no = 11; + npc->act_wait = 0; + // Fallthrough + case 11: + if (++npc->act_wait > 10) + { + SetNpChar(251, npc->x, npc->y, 0, 0, 0, 0, 0x100); + PlaySoundObject(101, 1); + npc->cond = 0; + return; + } + + if (npc->act_wait / 2 % 2) + npc->ani_no = 2; + else + npc->ani_no = 1; + } + + npc->rect = rc[npc->ani_no]; +} + +//Boss Misery lightning +void ActNpc251(NPCHAR *npc) +{ + RECT rc[2]; + + rc[0] = {80, 32, 96, 64}; + rc[1] = {96, 32, 112, 64}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + // Fallthrough + case 1: + if (++npc->ani_no > 1) + npc->ani_no = 0; + + npc->y += 0x1000; + + if (npc->flag & 0xFF) + { + SetDestroyNpChar(npc->x, npc->y, npc->view.back, 3); + npc->cond = 0; + } + + break; + } + + npc->rect = rc[npc->ani_no]; +} + +//Boss Misery bats +void ActNpc252(NPCHAR *npc) +{ + RECT rcLeft[4]; + RECT rcRight[4]; + + rcLeft[0] = {48, 32, 64, 48}; + rcLeft[1] = {112, 32, 128, 48}; + rcLeft[2] = {128, 32, 144, 48}; + rcLeft[3] = {144, 32, 160, 48}; + + rcRight[0] = {48, 32, 64, 48}; + rcRight[1] = {112, 48, 128, 64}; + rcRight[2] = {128, 48, 144, 64}; + rcRight[3] = {144, 48, 160, 64}; + + unsigned char deg; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->act_wait = 0; + npc->count1 = npc->direct; + // Fallthrough + case 1: + npc->count1 += 2; + npc->count1 &= 0xFF; + + deg = npc->count1; + + if ( npc->act_wait < 192 ) + ++npc->act_wait; + + npc->x = npc->pNpc->x + npc->act_wait * GetCos(deg) / 4; + npc->y = npc->pNpc->y + npc->act_wait * GetSin(deg) / 4; + + if (npc->pNpc->act_no == 151) + { + npc->act_no = 10; + npc->ani_no = 0; + } + + break; + + case 10: + npc->act_no = 11; + npc->bits |= 0x20; + npc->bits &= ~4; + npc->bits &= ~8; + + deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y); + deg += Random(-3, 3); + npc->xm = GetCos(deg); + npc->ym = GetSin(deg); + + npc->ani_no = 1; + npc->ani_wait = 0; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + // Fallthrough + case 11: + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->flag & 0xFF) + { + SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100); + SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100); + SetNpChar(4, npc->x, npc->y, 0, 0, 0, 0, 0x100); + npc->cond = 0; + } + + if (++npc->ani_wait > 4) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 3) + npc->ani_no = 1; + + break; + } + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + //EXP capsule void ActNpc253(NPCHAR *npc) { diff --git a/src/NpcAct260.cpp b/src/NpcAct260.cpp index 02b4f57f..a0a5e72a 100644 --- a/src/NpcAct260.cpp +++ b/src/NpcAct260.cpp @@ -12,6 +12,205 @@ #include "Map.h" #include "Frame.h" +//Igor (enemy) +void ActNpc268(NPCHAR *npc) +{ + RECT rcLeft[10]; + RECT rcRight[10]; + + rcLeft[0] = {0, 0, 40, 40}; + rcLeft[1] = {40, 0, 80, 40}; + rcLeft[2] = {80, 0, 120, 40}; + rcLeft[3] = {0, 0, 40, 40}; + rcLeft[4] = {120, 0, 160, 40}; + rcLeft[5] = {0, 0, 40, 40}; + rcLeft[6] = {40, 80, 80, 120}; + rcLeft[7] = {0, 80, 40, 120}; + rcLeft[8] = {240, 0, 280, 40}; + rcLeft[9] = {280, 0, 320, 40}; + + rcRight[0] = {0, 40, 40, 80}; + rcRight[1] = {40, 40, 80, 80}; + rcRight[2] = {80, 40, 120, 80}; + rcRight[3] = {0, 40, 40, 80}; + rcRight[4] = {120, 40, 160, 80}; + rcRight[5] = {0, 40, 40, 80}; + rcRight[6] = {160, 80, 200, 120}; + rcRight[7] = {120, 80, 160, 120}; + rcRight[8] = {240, 40, 280, 80}; + rcRight[9] = {280, 40, 320, 80}; + + if (npc->x < gMC.x - 0x28000 || npc->x > gMC.x + 0x28000 || npc->y < gMC.y - 0x1E000 || npc->y > gMC.y + 0x1E000) + npc->act_no = 1; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->y += 0x1000; + // Fallthrough + case 1: + if (++npc->ani_wait > 20) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + + if (npc->x < gMC.x + 0xE000 && npc->x > gMC.x - 0xE000 && npc->x < gMC.x + 0x6000 && npc->x > gMC.x - 0xE000) + npc->act_no = 10; + + if (npc->shock) + npc->act_no = 10; + + break; + + case 10: + npc->act_no = 11; + npc->act_wait = 0; + npc->ani_no = 0; + npc->ani_wait = 0; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + // Fallthrough + case 11: + if (npc->direct == 0) + npc->xm = -0x200; + else + npc->xm = 0x200; + + if (npc->x < gMC.x + 0x8000 && npc->x > gMC.x - 0x8000) + { + npc->act_no = 20; + npc->act_wait = 0; + } + + if (npc->xm < 0 && npc->flag & 1) + { + npc->act_no = 20; + npc->act_wait = 0; + } + + if (npc->xm > 0 && npc->flag & 4) + { + npc->act_no = 20; + npc->act_wait = 0; + } + + if (++npc->ani_wait > 4) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 5) + npc->ani_no = 2; + + break; + + case 20: + npc->xm = 0; + npc->ani_no = 6; + + if (++npc->act_wait > 10) + { + npc->act_no = 30; + npc->ym = -0x5FF; + + if (npc->direct == 0) + npc->xm = -0x200; + else + npc->xm = 0x200; + + PlaySoundObject(108, 1); + } + + break; + + case 30: + npc->ani_no = 7; + + if (npc->flag & 8) + { + npc->act_no = 40; + npc->act_wait = 0; + SetQuake(20); + PlaySoundObject(26, 1); + } + + break; + + case 40: + npc->xm = 0; + npc->ani_no = 6; + + if (++npc->act_wait > 30) + npc->act_no = 50; + + break; + + case 50: + npc->act_no = 51; + npc->act_wait = 0; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + // Fallthrough + case 51: + if (++npc->act_wait > 30 && npc->act_wait % 4 == 1) + { + unsigned char deg; + + if (npc->direct == 0) + deg = -120; + else + deg = -8; + + deg += Random(-0x10, 0x10); + const int ym = 5 * GetSin(deg); + const int xm = 5 * GetCos(deg); + SetNpChar(11, npc->x, npc->y + 0x800, xm, ym, 0, 0, 0x100); + PlaySoundObject(12, 1); + } + + if (npc->act_wait < 50 && npc->act_wait / 2 % 2) + npc->ani_no = 9; + else + npc->ani_no = 8; + + if (npc->act_wait > 82) + { + npc->act_no = 10; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + } + + npc->ym += 0x33; + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + // Ironhead block void ActNpc271(NPCHAR *npc) { diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index d4acd5d7..98445adb 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -303,12 +303,12 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc244, ActNpc245, ActNpc246, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, + ActNpc247, + ActNpc248, + ActNpc249, + ActNpc250, + ActNpc251, + ActNpc252, ActNpc253, ActNpc254, ActNpc255, @@ -324,7 +324,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, nullptr, - nullptr, + ActNpc268, nullptr, nullptr, ActNpc271, From 26bcbdbef7fdfbe83d9d63f6daff81a44a588ad6 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Fri, 8 Feb 2019 21:30:08 +0000 Subject: [PATCH 4/4] Added more NPCs Now with Muscle Doctor --- src/NpcAct.h | 16 +- src/NpcAct240.cpp | 161 ++++++ src/NpcAct260.cpp | 1224 +++++++++++++++++++++++++++++++++++++++++++++ src/NpcTbl.cpp | 26 +- 4 files changed, 1411 insertions(+), 16 deletions(-) diff --git a/src/NpcAct.h b/src/NpcAct.h index 71e20c34..680cc57b 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -258,11 +258,21 @@ void ActNpc252(NPCHAR *npc); void ActNpc253(NPCHAR *npc); void ActNpc254(NPCHAR *npc); void ActNpc255(NPCHAR *npc); - +void ActNpc256(NPCHAR *npc); +void ActNpc257(NPCHAR *npc); +void ActNpc258(NPCHAR *npc); void ActNpc259(NPCHAR *npc); - +void ActNpc260(NPCHAR *npc); +void ActNpc261(NPCHAR *npc); +void ActNpc262(NPCHAR *npc); +void ActNpc263(NPCHAR *npc); +void ActNpc264(NPCHAR *npc); +void ActNpc265(NPCHAR *npc); +void ActNpc266(NPCHAR *npc); +void ActNpc267(NPCHAR *npc); void ActNpc268(NPCHAR *npc); - +void ActNpc269(NPCHAR *npc); +void ActNpc270(NPCHAR *npc); void ActNpc271(NPCHAR *npc); void ActNpc272(NPCHAR *npc); void ActNpc273(NPCHAR *npc); diff --git a/src/NpcAct240.cpp b/src/NpcAct240.cpp index b78e534d..abe8b140 100644 --- a/src/NpcAct240.cpp +++ b/src/NpcAct240.cpp @@ -1193,6 +1193,167 @@ void ActNpc255(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Doctor (facing away) +void ActNpc256(NPCHAR *npc) +{ + RECT rcLeft[6]; + + rcLeft[0] = {48, 160, 72, 192}; + rcLeft[1] = {72, 160, 96, 192}; + rcLeft[2] = {0, 128, 24, 160}; + rcLeft[3] = {24, 128, 48, 160}; + rcLeft[4] = {0, 160, 24, 192}; + rcLeft[5] = {24, 160, 48, 192}; + + switch ( npc->act_no ) + { + case 0: + gSuperXpos = 0; + npc->act_no = 1; + npc->y -= 0x1000; + // Fallthrough + case 1: + npc->ani_no = 0; + break; + + case 10: + npc->act_no = 11; + npc->ani_wait = 0; + npc->ani_no = 0; + npc->count1 = 0; + // Fallthrough + case 11: + if (++npc->ani_wait > 5) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + { + npc->ani_no = 0; + ++npc->count1; + } + + if (npc->count1 > 5) + npc->act_no = 1; + + break; + + case 20: + npc->act_no = 21; + // Fallthrough + case 21: + npc->ani_no = 2; + break; + + case 40: + npc->act_no = 41; + SetNpChar(257, npc->x - 0x1C00, npc->y - 0x2000, 0, 0, 0, 0, 0x100); + SetNpChar(257, npc->x - 0x1C00, npc->y - 0x2000, 0, 0, 2, 0, 0xAA); + // Fallthrough + case 41: + npc->ani_no = 4; + break; + + case 50: + npc->act_no = 51; + npc->ani_wait = 0; + npc->ani_no = 4; + npc->count1 = 0; + // Fallthrough + case 51: + if (++npc->ani_wait > 5) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 5) + { + npc->ani_no = 4; + ++npc->count1; + } + + if (npc->count1 > 5) + npc->act_no = 41; + + break; + } + + npc->rect = rcLeft[npc->ani_no]; +} + +//Red crystal +void ActNpc257(NPCHAR *npc) +{ + RECT rc[3]; + + rc[0] = {176, 32, 184, 48}; + rc[1] = {184, 32, 192, 48}; + rc[2] = {0, 0, 0, 0}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + // Fallthrough + case 1: + if (gSuperXpos) + npc->act_no = 10; + + break; + + case 10: + if (npc->x < gSuperXpos) + npc->xm += 0x55; + if (npc->x > gSuperXpos) + npc->xm -= 0x55; + + if (npc->y < gSuperYpos) + npc->ym += 0x55; + if (npc->y > gSuperYpos) + npc->ym -= 0x55; + + if (npc->xm > 0x400) + npc->xm = 0x400; + if (npc->xm < -0x400) + npc->xm = -0x400; + + if (npc->ym > 0x400) + npc->ym = 0x400; + if (npc->ym < -0x400) + npc->ym = -0x400; + + npc->x += npc->xm; + npc->y += npc->ym; + break; + } + + if (++npc->ani_wait > 3) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + + if (npc->direct == 0 && npc->xm > 0) + npc->ani_no = 2; + if (npc->direct == 2 && npc->xm < 0) + npc->ani_no = 2; + + npc->rect = rc[npc->ani_no]; +} + +//Mimiga (sleeping) +void ActNpc258(NPCHAR *npc) +{ + RECT rc = {48, 32, 64, 48}; + npc->rect = rc; +} + //Curly (carried and unconcious) void ActNpc259(NPCHAR *npc) { diff --git a/src/NpcAct260.cpp b/src/NpcAct260.cpp index a0a5e72a..9c3f4afa 100644 --- a/src/NpcAct260.cpp +++ b/src/NpcAct260.cpp @@ -11,6 +11,1098 @@ #include "Caret.h" #include "Map.h" #include "Frame.h" +#include "MycParam.h" + +//Shovel Brigade (caged) +void ActNpc260(NPCHAR *npc) +{ + RECT rcLeft[3]; + RECT rcRight[3]; + + rcLeft[0] = {128, 64, 144, 80}; + rcLeft[1] = {144, 64, 160, 80}; + rcLeft[2] = {224, 64, 240, 80}; + + rcRight[0] = {128, 80, 144, 96}; + rcRight[1] = {144, 80, 160, 96}; + rcRight[2] = {224, 80, 240, 96}; + + switch (npc->act_no) + { + case 0: + npc->x += 0x200; + npc->y -= 0x400; + npc->act_no = 1; + npc->ani_no = 0; + npc->ani_wait = 0; + // Fallthrough + case 1: + if (Random(0, 160) == 1) + { + npc->act_no = 2; + npc->act_wait = 0; + npc->ani_no = 1; + } + + break; + + case 2: + if (++npc->act_wait > 12) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + + case 10: + npc->act_no = 11; + npc->ani_no = 2; + SetNpChar(87, npc->x, npc->y - 0x2000, 0, 0, 0, 0, 0x100); + + break; + } + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Chie (caged) +void ActNpc261(NPCHAR *npc) +{ + RECT rcLeft[2]; + RECT rcRight[2]; + + rcLeft[0] = {112, 32, 128, 48}; + rcLeft[1] = {128, 32, 144, 48}; + + rcRight[0] = {112, 48, 128, 64}; + rcRight[1] = {128, 48, 144, 64}; + + switch (npc->act_no) + { + case 0: + npc->x -= 0x200; + npc->y -= 0x400; + npc->act_no = 1; + npc->ani_no = 0; + npc->ani_wait = 0; + // Fallthrough + case 1: + if (Random(0, 160) == 1) + { + npc->act_no = 2; + npc->act_wait = 0; + npc->ani_no = 1; + } + + break; + + case 2: + if (++npc->act_wait > 12 ) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + } + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Chaco (caged) +void ActNpc262(NPCHAR *npc) +{ + RECT rcLeft[2]; + RECT rcRight[2]; + + rcLeft[0] = {128, 0, 144, 16}; + rcLeft[1] = {144, 0, 160, 16}; + + rcRight[0] = {128, 16, 144, 32}; + rcRight[1] = {144, 16, 160, 32}; + + switch (npc->act_no) + { + case 0: + npc->x -= 0x200; + npc->y -= 0x400; + npc->act_no = 1; + npc->ani_no = 0; + npc->ani_wait = 0; + // Fallthrough + case 1: + if (Random(0, 160) == 1) + { + npc->act_no = 2; + npc->act_wait = 0; + npc->ani_no = 1; + } + + break; + + case 2: + if (++npc->act_wait > 12) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + } + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Doctor (boss) +void ActNpc263(NPCHAR *npc) +{ + RECT rcLeft[9]; + RECT rcRight[9]; + + rcLeft[0] = {0, 0, 24, 32}; + rcLeft[1] = {24, 0, 48, 32}; + rcLeft[2] = {48, 0, 72, 32}; + rcLeft[3] = {0, 0, 0, 0}; + rcLeft[4] = {72, 0, 96, 32}; + rcLeft[5] = {96, 0, 120, 32}; + rcLeft[6] = {120, 0, 144, 32}; + rcLeft[7] = {144, 0, 168, 32}; + rcLeft[8] = {264, 0, 288, 32}; + + rcRight[0] = {0, 32, 24, 64}; + rcRight[1] = {24, 32, 48, 64}; + rcRight[2] = {48, 32, 72, 64}; + rcRight[3] = {0, 0, 0, 0}; + rcRight[4] = {72, 32, 96, 64}; + rcRight[5] = {96, 32, 120, 64}; + rcRight[6] = {120, 32, 144, 64}; + rcRight[7] = {144, 32, 168, 64}; + rcRight[8] = {264, 32, 288, 64}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->y += 0x1000; + npc->ani_no = 3; + break; + + case 2: + if (++npc->act_wait / 2 & 1) + npc->ani_no = 0; + else + npc->ani_no = 3; + + if (npc->act_wait > 50) + npc->act_no = 10; + + break; + + case 10: + npc->ym += 0x80; + npc->bits |= 0x20; + npc->damage = 3; + + if (npc->flag & 8) + { + npc->act_no = 20; + npc->act_wait = 0; + npc->ani_no = 0; + npc->count2 = npc->life; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + + case 20: + if (++npc->act_wait < 50 && npc->life < npc->count2 - 20) + npc->act_wait = 50; + + if (npc->act_wait == 50) + { + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + npc->ani_no = 4; + } + + if (npc->act_wait == 80) + { + npc->ani_no = 5; + PlaySoundObject(25, 1); + + if (npc->direct == 0) + { + SetNpChar(264, npc->x - 0x2000, npc->y, 0, 0, 0, 0, 0x100); + SetNpChar(264, npc->x - 0x2000, npc->y, 0, 0, 0x400, 0, 0x100); + } + else + { + SetNpChar(264, npc->x + 0x2000, npc->y, 0, 0, 2, 0, 0x100); + SetNpChar(264, npc->x + 0x2000, npc->y, 0, 0, 2 + 0x400, 0, 0x100); + } + } + + if (npc->act_wait == 120) + npc->ani_no = 0; + + if (npc->act_wait > 130 && npc->life < npc->count2 - 50) + npc->act_wait = 161; + + if (npc->act_wait > 160) + { + npc->act_no = 100; + npc->ani_no = 0; + } + + break; + + case 30: + npc->act_no = 31; + npc->act_wait = 0; + npc->ani_no = 6; + npc->tgt_x = npc->x; + npc->bits |= 0x20; + // Fallthrough + case 31: + if (++npc->act_wait / 2 & 1) + npc->x = npc->tgt_x; + else + npc->x = npc->tgt_x + 0x200; + + if (npc->act_wait > 50) + { + npc->act_no = 32; + npc->act_wait = 0; + npc->ani_no = 7; + PlaySoundObject(101, 1); + + for (int deg = 8; deg < 0x100; deg += 0x10) + { + const int xm = 2 * GetCos(deg); + const int ym = 2 * GetSin(deg); + SetNpChar(266, npc->x, npc->y, xm, ym, 0, 0, 0x100); + } + } + + break; + + case 32: + if (++npc->act_wait > 50) + npc->act_no = 100; + + break; + + case 100: + npc->act_no = 101; + npc->bits &= ~0x20; + npc->damage = 0; + npc->act_wait = 0; + PlaySoundObject(29, 1); + // Fallthrough + case 101: + npc->act_wait += 2; + + if (npc->act_wait > 16) + { + npc->act_no = 102; + npc->act_wait = 0; + npc->ani_no = 3; + npc->tgt_x = Random(5, 35) * 0x2000; + npc->tgt_y = Random(5, 7) * 0x2000; + } + + break; + + case 102: + if (++npc->act_wait > 40 ) + { + npc->act_no = 103; + npc->act_wait = 16; + npc->ani_no = 2; + npc->ym = 0; + npc->x = npc->tgt_x; + npc->y = npc->tgt_y; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + + case 103: + npc->act_wait -= 2; + + if ( npc->act_wait <= 0 ) + { + npc->bits |= 0x20; + npc->damage = 3; + + if (npc->count1 < 3) + { + ++npc->count1; + npc->act_no = 10; + } + else + { + npc->count1 = 0; + npc->act_no = 30; + } + } + + break; + + case 500: + npc->bits &= ~0x20; + npc->ani_no = 6; + npc->ym += 0x10; + + if (npc->flag & 8) + { + npc->act_no = 501; + npc->act_wait = 0; + npc->tgt_x = npc->x; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + + case 501: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + npc->ani_no = 8; + + if (++npc->act_wait / 2 & 1) + npc->x = npc->tgt_x; + else + npc->x = npc->tgt_x + 0x200; + + break; + } + + if (npc->act_no >= 10) + { + if (npc->act_no == 102) + { + gSuperXpos = npc->tgt_x; + gSuperYpos = npc->tgt_y; + } + else + { + gSuperXpos = npc->x; + gSuperYpos = npc->y; + } + } + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; + + if (npc->act_no == 101 || npc->act_no == 103) + { + npc->rect.top += npc->act_wait; + npc->rect.bottom -= npc->act_wait; + npc->view.top = (16 - npc->act_wait) << 9; + } + else + { + npc->view.top = 0x2000; + } +} + +//Doctor red wave (projectile) +void ActNpc264(NPCHAR *npc) +{ + RECT rc = {288, 0, 304, 16}; + + if (npc->x < 0 || npc->x > gMap.width * 0x2000) + { + VanishNpChar(npc); + return; + } + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->tgt_x = npc->x; + npc->tgt_y = npc->y; + npc->count1 = npc->direct / 8; + npc->direct &= 7; + // Fallthrough + case 1: + npc->count1 += 6; + npc->count1 &= 0xFF; + const unsigned char deg = npc->count1; + + if (npc->act_wait < 128) + ++npc->act_wait; + + if (npc->direct == 0) + npc->xm -= 21; + else + npc->xm += 21; + + npc->tgt_x += npc->xm; + + npc->x = npc->tgt_x + npc->act_wait * GetCos(deg) / 8; + npc->y = npc->tgt_y + npc->act_wait * GetSin(deg) / 2; + + SetNpChar(265, npc->x, npc->y, 0, 0, 0, 0, 0x100); + + break; + } + + npc->rect = rc; +} + +//Doctor red ball projectile +void ActNpc265(NPCHAR *npc) +{ + RECT rc[3]; + + rc[0] = {288, 16, 304, 32}; + rc[1] = {288, 32, 304, 48}; + rc[2] = {288, 48, 304, 64}; + + if (++npc->ani_wait > 3) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + npc->cond = 0; + else + npc->rect = rc[npc->ani_no]; +} + +//Doctor red ball projectile (bouncing) +void ActNpc266(NPCHAR *npc) +{ + RECT rc[2]; + + rc[0] = {304, 16, 320, 32}; + rc[1] = {304, 32, 320, 48}; + + if (npc->flag & 1) + npc->xm = -npc->xm; + if (npc->flag & 4) + npc->xm = -npc->xm; + + if (npc->flag & 2) + npc->ym = 0x200; + if (npc->flag & 8) + npc->ym = -0x200; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (++npc->ani_no > 1) + npc->ani_no = 0; + + npc->rect = rc[npc->ani_no]; + + if (++npc->act_wait % 4 == 1) + SetNpChar(265, npc->x, npc->y, 0, 0, 0, 0, 0x100); + + if (npc->act_wait > 250) + VanishNpChar(npc); +} + +//Muscle Doctor +void ActNpc267(NPCHAR *npc) +{ + RECT rcLeft[10]; + RECT rcRight[10]; + + rcLeft[0] = {0, 0, 0, 0}; + rcLeft[1] = {0, 64, 40, 112}; + rcLeft[2] = {40, 64, 80, 112}; + rcLeft[3] = {80, 64, 120, 112}; + rcLeft[4] = {120, 64, 160, 112}; + rcLeft[5] = {160, 64, 200, 112}; + rcLeft[6] = {200, 64, 240, 112}; + rcLeft[7] = {240, 64, 280, 112}; + rcLeft[8] = {280, 64, 320, 112}; + rcLeft[9] = {0, 160, 40, 208}; + + rcRight[0] = {0, 0, 0, 0}; + rcRight[1] = {0, 112, 40, 160}; + rcRight[2] = {40, 112, 80, 160}; + rcRight[3] = {80, 112, 120, 160}; + rcRight[4] = {120, 112, 160, 160}; + rcRight[5] = {160, 112, 200, 160}; + rcRight[6] = {200, 112, 240, 160}; + rcRight[7] = {240, 112, 280, 160}; + rcRight[8] = {280, 112, 320, 160}; + rcRight[9] = {40, 160, 80, 208}; + + switch (npc->act_no) + { + case 0: + if (gMC.x < gSuperXpos) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->direct == 0) + npc->x = gSuperXpos - 0xC00; + else + npc->x = gSuperXpos + 0xC00; + + npc->y = gSuperYpos; + // Fallthrough + case 1: + npc->act_no = 2; + // Fallthrough + case 2: + npc->ym += 0x80; + + if (++npc->act_wait / 2 % 2) + npc->ani_no = 0; + else + npc->ani_no = 3; + + break; + + case 5: + npc->act_no = 6; + npc->ani_no = 1; + npc->ani_wait = 0; + // Fallthrough + case 6: + npc->ym += 0x80; + + if (++npc->ani_wait > 40) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + npc->ani_no = 1; + + break; + + case 7: + npc->act_no = 8; + npc->act_wait = 0; + npc->ani_no = 3; + // Fallthrough + case 8: + npc->ym += 0x40; + + if (++npc->act_wait > 40) + npc->act_no = 10; + + break; + + case 10: + npc->bits |= 4; + npc->xm = 0; + npc->act_no = 11; + npc->act_wait = 0; + npc->ani_no = 1; + npc->ani_wait = 0; + npc->count2 = npc->life; + // Fallthrough + case 11: + npc->ym += 0x80; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->flag & 8) + { + if (npc->life >= npc->count2 - 20) + { + if (++npc->ani_wait > 10) + { + npc->ani_wait = 0; + + if (++npc->ani_no > 2) + npc->ani_no = 1; + } + } + else if (gMC.flag & 8 && gMC.x > npc->x - 0x6000 && gMC.x < npc->x + 0x6000 && npc->ani_no != 6) + { + npc->ani_no = 6; + DamageMyChar(5); + SetQuake(10); + PlaySoundObject(26, 1); + gMC.ym = -0x400; + + if (gMC.x < npc->x) + gMC.xm = -0x5FF; + else + gMC.xm = 0x5FF; + + for (int i = 0; i < 100; ++i) + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y + (Random(-0x10, 0x10) * 0x200), 3 * Random(-0x200, 0x200), 3 * Random(-0x200, 0x200), 3, 0, 0xAA); + } + } + else + { + npc->ani_no = 4; + } + + if (++npc->act_wait > 30 || npc->life < npc->count2 - 20) + { + if (++npc->count1 > 10) + npc->count1 = 0; + + switch (npc->count1) + { + case 8: + npc->act_no = 20; + break; + case 2: + case 7: + npc->act_no = 100; + break; + case 3: + case 6: + npc->act_no = 30; + break; + case 1: + case 9: + npc->act_no = 40; + break; + default: + npc->act_no = 15; + npc->act_wait = 0; + break; + } + } + + break; + + case 15: + npc->ani_no = 3; + ++npc->act_wait; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->act_wait > 20) + { + npc->act_no = 16; + npc->ani_no = 4; + npc->ani_wait = 0; + npc->ym = -0x600; + + if (npc->direct == 0) + npc->xm = -0x400; + else + npc->xm = 0x400; + } + + break; + + case 16: + npc->ym += 0x40; + + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 5) + npc->ani_no = 4; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->ym > 0 && npc->flag & 8) + npc->act_no = 17; + + break; + + case 17: + npc->act_no = 18; + npc->act_wait = 0; + SetQuake(10); + PlaySoundObject(26, 1); + // Fallthrough + case 18: + npc->ani_no = 3; + ++npc->act_wait; + + npc->xm = 7 * npc->xm / 8; + npc->ym += 0x80; + + if (npc->act_wait > 10) + npc->act_no = 10; + + break; + + case 20: + npc->act_no = 21; + npc->act_wait = 0; + // Fallthrough + case 21: + ++npc->act_wait; + npc->ani_no = 6; + + if (npc->act_wait > 20 && npc->act_wait % 3 == 1) + { + const int ym = Random(-0x200u, 0x200); + const int xm = 4 * Random(0x100, 0x200); + + if (npc->direct == 0) + SetNpChar(269, npc->x - 0x1000, npc->y - 0x800, -xm, ym, 0, 0, 0x100); + else + SetNpChar(269, npc->x + 0x1000, npc->y - 0x800, xm, ym, 2, 0, 0x100); + + PlaySoundObject(39, 1); + } + + if ( npc->act_wait > 90 ) + npc->act_no = 10; + + break; + + case 30: + npc->act_no = 31; + npc->act_wait = 0; + npc->bits |= 1; + npc->bits &= ~0x20; + // Fallthrough + case 31: + npc->ani_no = 3; + + if (++npc->act_wait > 20) + { + npc->act_no = 32; + npc->act_wait = 0; + npc->ani_no = 7; + npc->bits |= 0x80; + npc->damage = 10; + PlaySoundObject(25, 1); + + if (npc->direct == 0) + npc->xm = -0x5FF; + else + npc->xm = 0x5FF; + } + + break; + + case 32: + ++npc->act_wait; + npc->ym = 0; + + if (npc->act_wait / 2 % 2) + npc->ani_no = 7; + else + npc->ani_no = 8; + + if (npc->act_wait > 30) + { + npc->act_wait = 0; + npc->act_no = 18; + npc->damage = 5; + npc->bits &= ~0x81; + npc->bits |= 0x20; + } + + if (npc->flag & 1 || npc->flag & 4) + { + npc->act_no = 15; + npc->act_wait = 0; + npc->damage = 5; + npc->bits &= ~0x81; + npc->bits |= 0x20; + } + + break; + + case 40: + npc->ani_no = 3; + ++npc->act_wait; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->act_wait > 20) + { + npc->act_no = 41; + npc->ani_no = 4; + npc->ani_wait = 0; + npc->ym = -0x800; + + if (npc->direct == 0) + npc->xm = -0x400; + else + npc->xm = 0x400; + } + + break; + + case 41: + npc->ym += 0x40; + + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 5) + npc->ani_no = 4; + + if (gMC.y > npc->y && gMC.x > npc->x - 0x1000 && gMC.x < npc->x + 0x1000) + { + npc->act_no = 16; + npc->ym = 0x5FF; + npc->xm = 0; + } + + if (npc->ym > 0 && npc->flag & 8) + npc->act_no = 17; + + break; + + case 100: + npc->act_no = 101; + npc->act_wait = 0; + npc->bits &= ~0x24; + npc->damage = 0; + PlaySoundObject(29, 1); + // Fallthrough + case 101: + npc->act_wait += 2; + + if (npc->act_wait > 28) + { + npc->act_no = 102; + npc->act_wait = 0; + npc->ani_no = 0; + + npc->tgt_x = gMC.x; + npc->tgt_y = gMC.y - 0x4000; + + if ( npc->tgt_y < 0x8000 ) + npc->tgt_y = 0x8000; + + if ( npc->tgt_x < 0x8000 ) + npc->tgt_x = 0x8000; + if ( npc->tgt_x > 0x48000 ) + npc->tgt_x = 0x48000; + } + + break; + + case 102: + if (++npc->act_wait > 40) + { + npc->act_no = 103; + npc->act_wait = 28; + npc->ani_no = 4; + npc->ym = 0; + npc->x = npc->tgt_x; + npc->y = npc->tgt_y; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + + case 103: + npc->act_wait -= 2; + + if (npc->act_wait <= 0) + { + npc->bits |= 0x24; + npc->damage = 5; + npc->act_no = 16; + npc->ym = -0x200; + npc->xm = 0; + } + + break; + + case 500: + DeleteNpCharCode(269, 1); + npc->bits &= ~0x20; + npc->ani_no = 4; + npc->ym += 0x20; + npc->xm = 0; + + if (npc->flag & 8) + { + npc->act_no = 501; + npc->act_wait = 0; + npc->tgt_x = npc->x; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + + case 501: + npc->ani_no = 9; + + if (++npc->act_wait / 2 % 2) + npc->x = npc->tgt_x; + else + npc->x = npc->tgt_x + 0x200; + + break; + + case 510: + npc->act_no = 511; + npc->act_wait = 0; + npc->ani_no = 9; + npc->tgt_x = npc->x; + npc->y += 0x2000; + npc->bits |= 8; + // Fallthrough + case 511: + SetQuake(2); + + if (++npc->act_wait % 6 == 3) + PlaySoundObject(25, 1); + + if (npc->act_wait / 2 % 2) + npc->x = npc->tgt_x; + else + npc->x = npc->tgt_x + 0x200; + + if (npc->act_wait > 352) + { + npc->ani_no = 0; + npc->act_no = 0x200; + } + + break; + + case 520: + npc->damage = 0; + gSuperYpos = -0x4000; + break; + } + + if (npc->act_no >= 11 && npc->act_no < 501) + { + if (npc->act_no == 102) + { + gSuperXpos = npc->tgt_x; + gSuperYpos = npc->tgt_y; + } + else + { + gSuperXpos = npc->x; + gSuperYpos = npc->y; + } + } + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->act_no < 512) + { + if (npc->act_no >= 510) + { + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - (((336 - npc->act_wait) / 8) * 0x200), Random(-0x200, 0x200), 2 * Random(-0x200, 0), 3, 0, 0xAA); + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), Random(-0x200, 0x200), 2 * Random(-0x200, 0), 3, 0, 0xAA); + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), 0, 2 * Random(-0x200, 0), 3, 0, 0xAA); + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), 0, 2 * Random(-0x200, 0), 3, 0, 0xAA); + } + else if (npc->act_no != 102 && npc->act_no != 103 && Random(0, 3) == 2) + { + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y + (Random(-8, 4) * 0x200), npc->xm, 0, 3, 0, 0x100); + } + } + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; + + if (npc->act_no == 511) + { + npc->rect.top += npc->act_wait / 8; + npc->view.top = (44 - npc->act_wait / 8) * 0x200; + npc->view.bottom = 0x800; + } + else if (npc->act_no == 101 || npc->act_no == 103) + { + npc->rect.top += npc->act_wait; + npc->rect.bottom -= npc->act_wait; + npc->view.top = (28 - npc->act_wait) * 0x200; + } + else + { + npc->view.top = 0x3800; + } +} //Igor (enemy) void ActNpc268(NPCHAR *npc) @@ -211,6 +1303,138 @@ void ActNpc268(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Red Bat (bouncing) +void ActNpc269(NPCHAR *npc) +{ + RECT rcLeft[3]; + RECT rcRight[3]; + + rcLeft[0] = {232, 0, 248, 16}; + rcLeft[1] = {248, 0, 264, 16}; + rcLeft[2] = {248, 16, 264, 32}; + + rcRight[0] = {232, 32, 248, 48}; + rcRight[1] = {248, 32, 264, 48}; + rcRight[2] = {248, 48, 264, 64}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->xm2 = npc->xm; + npc->ym2 = npc->ym; + // Fallthrough + case 1: + if (npc->xm2 < 0 && npc->flag & 1) + { + npc->direct = 2; + npc->xm2 = -npc->xm2; + } + else if (npc->xm2 > 0 && npc->flag & 4) + { + npc->direct = 0; + npc->xm2 = -npc->xm2; + } + else if (npc->ym2 < 0 && npc->flag & 2) + { + npc->ym2 = -npc->ym2; + } + else if (npc->ym2 > 0 && npc->flag & 8) + { + npc->ym2 = -npc->ym2; + } + + npc->x += npc->xm2; + npc->y += npc->ym2; + + if (++npc->ani_wait > 2) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + npc->ani_no = 0; + + break; + } + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Doctor's blood (or """"red energy"""") +void ActNpc270(NPCHAR *npc) +{ + RECT rc[2]; + + rc[0] = {170, 34, 174, 38}; + rc[1] = {170, 42, 174, 46}; + + if (npc->direct == 3 || npc->direct == 1) + { + if (npc->direct == 3) + npc->ym += 0x40; + if (npc->direct == 1) + npc->ym -= 0x40; + + ++npc->act_wait; + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->act_wait > 50) + npc->cond = 0; + + if (npc->flag & 0xFF) + npc->cond = 0; + } + else if ( npc->direct == 2 ) + { + if (npc->act_no == 0) + { + npc->act_no = 1; + npc->bits |= 8; + + npc->xm = 3 * Random(-0x200, 0x200); + npc->ym = 3 * Random(-0x200, 0x200); + + npc->count1 = Random(0x10, 0x33); + npc->count2 = Random(0x80, 0x100); + } + + if (npc->x < npc->pNpc->x) + npc->xm += 0x200 / npc->count1; + if (npc->x > npc->pNpc->x) + npc->xm -= 0x200 / npc->count1; + + if (npc->y < npc->pNpc->y) + npc->ym += 0x200 / npc->count1; + if (npc->y > npc->pNpc->y) + npc->ym -= 0x200 / npc->count1; + + if (npc->xm > 2 * npc->count2) + npc->xm = 2 * npc->count2; + if (npc->xm < -2 * npc->count2) + npc->xm = -2 * npc->count2; + + if (npc->ym > 3 * npc->count2) + npc->ym = 3 * npc->count2; + if (npc->ym < -3 * npc->count2) + npc->ym = -3 * npc->count2; + + npc->x += npc->xm; + npc->y += npc->ym; + } + + npc->rect = rc[Random(0, 1)]; +} + // Ironhead block void ActNpc271(NPCHAR *npc) { diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index 98445adb..de290dbd 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -312,21 +312,21 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc253, ActNpc254, ActNpc255, - nullptr, - nullptr, - nullptr, + ActNpc256, + ActNpc257, + ActNpc258, ActNpc259, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, + ActNpc260, + ActNpc261, + ActNpc262, + ActNpc263, + ActNpc264, + ActNpc265, + ActNpc266, + ActNpc267, ActNpc268, - nullptr, - nullptr, + ActNpc269, + ActNpc270, ActNpc271, ActNpc272, ActNpc273,