From 7a97c2c93850a3c486949fd37157821cfc317172 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Fri, 8 Feb 2019 16:38:32 +0000 Subject: [PATCH] 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,