diff --git a/src/NpcAct.h b/src/NpcAct.h index 4e7472b5..607e117a 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -11,9 +11,12 @@ void ActNpc005(NPCHAR *npc); void ActNpc006(NPCHAR *npc); void ActNpc007(NPCHAR *npc); void ActNpc008(NPCHAR *npc); - +void ActNpc009(NPCHAR *npc); +void ActNpc010(NPCHAR *npc); +void ActNpc011(NPCHAR *npc); void ActNpc012(NPCHAR *npc); - +void ActNpc013(NPCHAR *npc); +void ActNpc014(NPCHAR *npc); void ActNpc015(NPCHAR *npc); void ActNpc016(NPCHAR *npc); void ActNpc017(NPCHAR *npc); @@ -68,13 +71,15 @@ void ActNpc078(NPCHAR *npc); void ActNpc079(NPCHAR *npc); void ActNpc080(NPCHAR *npc); void ActNpc081(NPCHAR *npc); - +void ActNpc082(NPCHAR *npc); void ActNpc083(NPCHAR *npc); void ActNpc084(NPCHAR *npc); void ActNpc085(NPCHAR *npc); void ActNpc086(NPCHAR *npc); void ActNpc087(NPCHAR *npc); +void ActNpc091(NPCHAR *npc); + void ActNpc116(NPCHAR *npc); void ActNpc119(NPCHAR *npc); diff --git a/src/NpcAct000.cpp b/src/NpcAct000.cpp index c4e670a9..7b677fe3 100644 --- a/src/NpcAct000.cpp +++ b/src/NpcAct000.cpp @@ -12,6 +12,7 @@ #include "Triangle.h" #include "Frame.h" #include "Map.h" +#include "Caret.h" //Null void ActNpc000(NPCHAR *npc) @@ -806,6 +807,231 @@ void ActNpc008(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Balrog (drop-in) +void ActNpc009(NPCHAR *npc) +{ + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->ani_no = 2; + // Fallthrough + case 1: + npc->ym += 0x20; + + if (npc->count1 >= 40) + { + npc->bits &= ~8; + npc->bits |= 1; + } + else + { + ++npc->count1; + } + + if (npc->flag & 8) + { + 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->act_no = 2; + npc->ani_no = 1; + npc->act_wait = 0; + PlaySoundObject(26, 1); + SetQuake(30); + } + + break; + + case 2: + if (++npc->act_wait > 16) + { + npc->act_no = 3; + npc->ani_no = 0; + npc->ani_wait = 0; + } + + break; + } + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + if (npc->ym < -0x5FF) + npc->ym = -0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + RECT rect_left[3]; + RECT rect_right[3]; + + rect_left[0] = {0, 0, 40, 24}; + rect_left[1] = {80, 0, 120, 24}; + rect_left[2] = {120, 0, 160, 24}; + + rect_right[0] = {0, 24, 40, 48}; + rect_right[1] = {80, 24, 120, 48}; + rect_right[2] = {120, 24, 160, 48}; + + if (npc->direct == 0) + npc->rect = rect_left[npc->ani_no]; + else + npc->rect = rect_right[npc->ani_no]; +} + +//Balrog (shooting) (super-secret version from prototype) +void ActNpc010(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; + + unsigned char deg = GetArktan(npc->x - gMC.x, npc->y + 0x800 - gMC.y); + deg += Random(-0x10, 0x10); + int ym = GetSin(deg); + 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->flag & 5) + npc->xm = 0; + + if (gMC.y > npc->y + 0x2000) + npc->damage = 5; + else + npc->damage = 0; + + if (npc->flag & 8) + { + npc->act_no = 5; + npc->act_wait = 0; + npc->ani_no = 2; + PlaySoundObject(26, 1); + SetQuake(30); + npc->damage = 0; + } + + break; + + case 5: + npc->xm = 0; + + if (++npc->act_wait > 3) + { + npc->act_no = 1; + npc->act_wait = 0; + } + + break; + } + + npc->ym += 0x20; + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + RECT rect_left[4]; + RECT rect_right[4]; + + 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_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}; + + if (gMC.x > npc->x) + npc->direct = 2; + else + npc->direct = 0; + + if (npc->direct == 0) + npc->rect = rect_left[npc->ani_no]; + else + npc->rect = rect_right[npc->ani_no]; +} + +//Proto-Balrog's projectile +void ActNpc011(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] = {208, 104, 224, 120}; + rect_left[1] = {224, 104, 240, 120}; + rect_left[2] = {240, 104, 256, 120}; + + 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 > 150) + { + SetCaret(npc->x, npc->y, 2, 0); + npc->cond = 0; + } +} + //Balrog (cutscene) void ActNpc012(NPCHAR *npc) { @@ -1134,6 +1360,75 @@ void ActNpc012(NPCHAR *npc) } } +//Forcefield +void ActNpc013(NPCHAR *npc) +{ + RECT rect[4]; + + rect[0] = {128, 0, 144, 16}; + rect[1] = {144, 0, 160, 16}; + rect[2] = {160, 0, 176, 16}; + rect[3] = {176, 0, 192, 16}; + + 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]; +} + +//Santa's Key +void ActNpc014(NPCHAR *npc) +{ + int v2; // ST0C_4@5 + int v3; // ST08_4@5 + int v4; // eax@5 + RECT *v5; // eax@12 + RECT *v6; // ecx@12 + signed int i; // [sp+4h] [bp-34h]@3 + + RECT rect[3]; + + rect[0] = {192, 0, 208, 16}; + rect[1] = {208, 0, 224, 16}; + rect[2] = {224, 0, 240, 16}; + + if (npc->act_no == 0) + { + npc->act_no = 1; + + if (npc->direct == 2) + { + npc->ym = -0x200; + + for (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); + } + } + + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + npc->ani_no = 0; + + npc->ym += 0x40; + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->y += npc->ym; + + npc->rect = rect[npc->ani_no]; +} + //Chest (closed) void ActNpc015(NPCHAR *npc) { diff --git a/src/NpcAct080.cpp b/src/NpcAct080.cpp index 429ba103..009d137b 100644 --- a/src/NpcAct080.cpp +++ b/src/NpcAct080.cpp @@ -9,6 +9,7 @@ #include "Back.h" #include "Triangle.h" #include "Caret.h" +#include "Flash.h" //Gravekeeper void ActNpc080(NPCHAR *npc) @@ -302,6 +303,209 @@ void ActNpc081(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Misery (standing) +void ActNpc082(NPCHAR *npc) +{ + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->ani_no = 2; + // Fallthrough + case 1: + if (Random(0, 120) == 10) + { + npc->act_no = 2; + npc->act_wait = 0; + npc->ani_no = 3; + } + + break; + + case 2: + if (++npc->act_wait > 8) + { + npc->act_no = 1; + npc->ani_no = 2; + } + + break; + + case 15: + npc->act_no = 16; + npc->act_wait = 0; + npc->ani_no = 4; + // Fallthrough + case 16: + if (++npc->act_wait == 30) + { + PlaySoundObject(21, 1); + SetNpChar(66, npc->x, npc->y - 0x2000, 0, 0, 0, npc, 0); + } + + if (npc->act_wait == 50) + npc->act_no = 14; + + break; + + case 20: + npc->act_no = 21; + npc->ani_no = 0; + npc->ym = 0; + npc->bits |= 8; + // Fallthrough + case 21: + npc->ym -= 0x20; + + if (npc->y < -0x1000) + npc->cond = 0; + + break; + + case 25: + npc->act_no = 26; + npc->act_wait = 0; + npc->ani_no = 5; + npc->ani_wait = 0; + // Fallthrough + case 26: + if (++npc->ani_no > 7) + npc->ani_no = 5; + + if (++npc->act_wait == 30) + { + PlaySoundObject(101, 1); + SetFlash(0, 0, 2); + npc->act_no = 27; + npc->ani_no = 7; + } + + break; + + case 27: + if (++npc->act_wait == 50) + { + npc->act_no = 0; + npc->ani_no = 0; + } + + break; + + case 30: + npc->act_no = 31; + npc->ani_no = 3; + npc->ani_wait = 0; + // Fallthrough + case 31: + if (++npc->ani_wait > 10) + { + npc->act_no = 32; + npc->ani_no = 4; + npc->ani_wait = 0; + } + + break; + + case 32: + if (++npc->ani_wait > 100) + { + npc->act_no = 1; + npc->ani_no = 2; + } + + break; + + case 40: + npc->act_no = 41; + npc->act_wait = 0; + // Fallthrough + case 41: + npc->ani_no = 4; + + switch (++npc->act_wait) + { + case 30: + case 40: + case 50: + SetNpChar(11, npc->x + 0x1000, npc->y - 0x1000, 0x600, Random(-0x200, 0), 0, 0, 0x100); + PlaySoundObject(33, 1); + break; + } + + if (npc->act_wait > 50) + npc->act_no = 0; + + break; + + case 50: + npc->ani_no = 8; + break; + } + + npc->x += npc->xm; + npc->y += npc->ym; + + RECT rcLeft[9]; + RECT rcRight[9]; + + rcLeft[0] = {80, 0, 96, 16}; + rcLeft[1] = {96, 0, 112, 16}; + rcLeft[2] = {112, 0, 128, 16}; + rcLeft[3] = {128, 0, 144, 16}; + rcLeft[4] = {144, 0, 160, 16}; + rcLeft[5] = {160, 0, 176, 16}; + rcLeft[6] = {176, 0, 192, 16}; + rcLeft[7] = {144, 0, 160, 16}; + rcLeft[8] = {208, 64, 224, 80}; + + rcRight[0] = {80, 16, 96, 32}; + rcRight[1] = {96, 16, 112, 32}; + rcRight[2] = {112, 16, 128, 32}; + rcRight[3] = {128, 16, 144, 32}; + rcRight[4] = {144, 16, 160, 32}; + rcRight[5] = {160, 16, 176, 32}; + rcRight[6] = {176, 16, 192, 32}; + rcRight[7] = {144, 16, 160, 32}; + rcRight[8] = {208, 80, 224, 96}; + + if (npc->act_no == 11) + { + if (npc->ani_wait) + { + --npc->ani_wait; + npc->ani_no = 1; + } + else + { + if (Random(0, 100) == 1) + npc->ani_wait = 30; + + npc->ani_no = 0; + } + } + + if (npc->act_no == 14) + { + if (npc->ani_wait) + { + --npc->ani_wait; + npc->ani_no = 3; + } + else + { + if (Random(0, 100) == 1) + npc->ani_wait = 30; + + npc->ani_no = 2; + } + } + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + //Igor (cutscene) void ActNpc083(NPCHAR *npc) { @@ -650,3 +854,19 @@ void ActNpc087(NPCHAR *npc) if (npc->count1 > 547) npc->rect = rcLast[0]; } + +// Cage +void ActNpc091(NPCHAR *npc) +{ + RECT rect[1]; + + rect[0] = {96, 88, 128, 112}; + + if (npc->act_no == 0) + { + ++npc->act_no; + npc->y += 0x10 * 0x200; + } + + npc->rect = rect[0]; +} diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index de822259..b448a5aa 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -65,12 +65,12 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc006, ActNpc007, ActNpc008, - nullptr, - nullptr, - nullptr, + ActNpc009, + ActNpc010, + ActNpc011, ActNpc012, - nullptr, - nullptr, + ActNpc013, + ActNpc014, ActNpc015, ActNpc016, ActNpc017, @@ -138,7 +138,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc079, ActNpc080, ActNpc081, - nullptr, + ActNpc082, ActNpc083, ActNpc084, ActNpc085, @@ -147,7 +147,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, nullptr, - nullptr, + ActNpc091, nullptr, nullptr, nullptr,