diff --git a/Makefile b/Makefile index 6f4d8946..4c28f375 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ SOURCES = \ ArmsItem \ Back \ Boss \ + BossFrog \ BossLife \ BossOhm \ BulHit \ @@ -76,6 +77,7 @@ SOURCES = \ NpcAct100 \ NpcAct120 \ NpcAct140 \ + NpcAct180 \ NpcAct200 \ NpcAct260 \ NpcAct280 \ diff --git a/src/Boss.cpp b/src/Boss.cpp index 7f07df81..c75202cd 100644 --- a/src/Boss.cpp +++ b/src/Boss.cpp @@ -4,6 +4,7 @@ #include "WindowsWrapper.h" #include "Boss.h" +#include "BossFrog.h" #include "BossOhm.h" #include "NpChar.h" #include "MyChar.h" @@ -184,16 +185,16 @@ void ActBossChar_0() BOSSFUNCTION gpBossFuncTbl[10] = { - &ActBossChar_0, - &ActBossChar_Omega, - nullptr, //&ActBossChar_Frog, - nullptr, //&ActBossChar_MonstX, - nullptr, //&ActBossChar_Core, - nullptr, //&ActBossChar_Ironhead, - nullptr, //&ActBossChar_Twin, - nullptr, //&ActBossChar_Undead, - nullptr, //&ActBossChar_Press, - nullptr, //&ActBossChar_Ballos + ActBossChar_0, + ActBossChar_Omega, + ActBossChar_Frog, + nullptr, //ActBossChar_MonstX, + nullptr, //ActBossChar_Core, + nullptr, //ActBossChar_Ironhead, + nullptr, //ActBossChar_Twin, + nullptr, //ActBossChar_Undead, + nullptr, //ActBossChar_Press, + nullptr, //ActBossChar_Ballos }; void ActBossChar() diff --git a/src/BossFrog.cpp b/src/BossFrog.cpp new file mode 100644 index 00000000..1e34a0a5 --- /dev/null +++ b/src/BossFrog.cpp @@ -0,0 +1,525 @@ +#include "BossFrog.h" + +#include "Boss.h" +#include "Frame.h" +#include "Game.h" +#include "MyChar.h" +#include "NpChar.h" +#include "Sound.h" +#include "Triangle.h" +#include "WindowsWrapper.h" + +static void ActBossChar02_01(void) +{ + int minus; + + if (gBoss[0].direct == 0) + minus = 1; + else + minus = -1; + + switch (gBoss[0].ani_no) + { + case 0: + gBoss[1].hit_voice = 52; + gBoss[1].hit.front = 0x2000; + gBoss[1].hit.top = 0x2000; + gBoss[1].hit.back = 0x2000; + gBoss[1].hit.bottom = 0x2000; + gBoss[1].size = 3; + gBoss[1].bits = 4; + break; + + case 1: + gBoss[1].x = gBoss[0].x + -0x3000 * minus; + gBoss[1].y = gBoss[0].y - 0x3000; + break; + + case 2: + gBoss[1].x = gBoss[0].x + -0x3000 * minus; + gBoss[1].y = gBoss[0].y - 0x2800; + break; + + case 3: + case 4: + gBoss[1].x = gBoss[0].x + -0x3000 * minus; + gBoss[1].y = gBoss[0].y - 0x2000; + break; + + case 5: + gBoss[1].x = gBoss[0].x + -0x3000 * minus; + gBoss[1].y = gBoss[0].y - 0x5600; + break; + } +} + +static void ActBossChar02_02(void) +{ + if (gBoss[0].ani_no) + { + if (gBoss[0].ani_no > 0 && gBoss[0].ani_no <= 5) + { + gBoss[2].x = gBoss[0].x; + gBoss[2].y = gBoss[0].y; + } + } + else + { + gBoss[2].hit_voice = 52; + gBoss[2].hit.front = 0x3000; + gBoss[2].hit.top = 0x2000; + gBoss[2].hit.back = 0x3000; + gBoss[2].hit.bottom = 0x2000; + gBoss[2].size = 3; + gBoss[2].bits = 4; + } +} + +void ActBossChar_Frog(void) +{ + RECT rcLeft[9]; + RECT rcRight[9]; + + rcLeft[0] = {0, 0, 0, 0}; + rcLeft[1] = {0, 48, 80, 112}; + rcLeft[2] = {0, 112, 80, 176}; + rcLeft[3] = {0, 176, 80, 240}; + rcLeft[4] = {160, 48, 240, 112}; + rcLeft[5] = {160, 112, 240, 200}; + rcLeft[6] = {200, 0, 240, 24}; + rcLeft[7] = {80, 0, 120, 24}; + rcLeft[8] = {120, 0, 160, 24}; + + rcRight[0] = {0, 0, 0, 0}; + rcRight[1] = {80, 48, 160, 112}; + rcRight[2] = {80, 112, 160, 176}; + rcRight[3] = {80, 176, 160, 240}; + rcRight[4] = {240, 48, 320, 112}; + rcRight[5] = {240, 112, 320, 200}; + rcRight[6] = {200, 24, 240, 48}; + rcRight[7] = {80, 24, 120, 48}; + rcRight[8] = {120, 24, 160, 48}; + + switch (gBoss[0].act_no) + { + case 0: + gBoss->x = 0xC000; + gBoss->y = 0x19000; + gBoss->direct = 2; + gBoss->view.front = 0x6000; + gBoss->view.top = 0x6000; + gBoss->view.back = 0x4000; + gBoss->view.bottom = 0x2000; + gBoss->hit_voice = 52; + gBoss->hit.front = 0x3000; + gBoss->hit.top = 0x2000; + gBoss->hit.back = 0x3000; + gBoss->hit.bottom = 0x2000; + gBoss->size = 3; + gBoss->exp = 1; + gBoss->code_event = 1000; + gBoss->bits |= 0x8200; + gBoss->life = 300; + break; + + case 10: + gBoss->act_no = 11; + gBoss->ani_no = 3; + gBoss->cond = 0x80; + gBoss->rect = rcRight[0]; + gBoss[1].cond = -112; + gBoss[1].code_event = 1000; + gBoss[2].cond = 0x80; + gBoss[1].damage = 5; + gBoss[2].damage = 5; + + for (int i = 0; i < 8; ++i) + SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + break; + + case 20: + gBoss->act_no = 21; + gBoss->act_wait = 0; + // Fallthrough + case 21: + if (++gBoss->act_wait / 2 % 2) + gBoss->ani_no = 3; + else + gBoss->ani_no = 0; + + break; + + case 100: + gBoss->act_no = 101; + gBoss->act_wait = 0; + gBoss->ani_no = 1; + gBoss->xm = 0; + // Fallthrough + case 101: + if (++gBoss->act_wait > 50) + { + gBoss->act_no = 102; + gBoss->ani_wait = 0; + gBoss->ani_no = 2; + } + + break; + + case 102: + if (++gBoss->ani_wait > 10) + { + gBoss->act_no = 103; + gBoss->ani_wait = 0; + gBoss->ani_no = 1; + } + + break; + + case 103: + if (++gBoss->ani_wait > 4) + { + gBoss->act_no = 104; + gBoss->ani_no = 5; + gBoss->ym = -0x400; + PlaySoundObject(25, 1); + + if (gBoss->direct == 0) + gBoss->xm = -0x200u; + else + gBoss->xm = 0x200; + + gBoss->view.top = 0x8000; + gBoss->view.bottom = 0x3000; + } + + break; + + case 104: + if (gBoss->direct == 0 && gBoss->flag & 1) + { + gBoss->direct = 2; + gBoss->xm = 0x200; + } + + if (gBoss->direct == 2 && gBoss->flag & 4) + { + gBoss->direct = 0; + gBoss->xm = -0x200; + } + + if (gBoss->flag & 8) + { + PlaySoundObject(26, 1); + SetQuake(30); + gBoss->act_no = 100; + gBoss->ani_no = 1; + gBoss->view.top = 0x6000; + gBoss->view.bottom = 0x2000; + + if (gBoss->direct == 0 && gBoss->x < gMC.x) + { + gBoss->direct = 2; + gBoss->act_no = 110; + } + + if (gBoss->direct == 2 && gBoss->x > gMC.x) + { + gBoss->direct = 0; + gBoss->act_no = 110; + } + + SetNpChar(110, Random(4, 16) * 0x2000, Random(0, 4) * 0x2000, 0, 0, 4, 0, 0x80); + + for (int i = 0; i < 4; ++i) + SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + gBoss->hit.bottom, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + } + + break; + + case 110: + gBoss->ani_no = 1; + gBoss->act_wait = 0; + gBoss->act_no = 111; + // Fallthrough + case 111: + ++gBoss->act_wait; + gBoss->xm = 8 * gBoss->xm / 9; + + if (gBoss->act_wait > 50) + { + gBoss->ani_no = 2; + gBoss->ani_wait = 0; + gBoss->act_no = 112; + } + + break; + + case 112: + if (++gBoss->ani_wait > 4) + { + gBoss->act_no = 113; + gBoss->act_wait = 0; + gBoss->ani_no = 3; + gBoss->count1 = 16; + gBoss[1].bits |= 0x20; + gBoss->tgt_x = gBoss->life; + } + + break; + + case 113: + if (gBoss->shock) + { + if (gBoss->count2++ / 2 % 2) + gBoss->ani_no = 4; + else + gBoss->ani_no = 3; + } + else + { + gBoss->count2 = 0; + gBoss->ani_no = 3; + } + + gBoss->xm = 10 * gBoss->xm / 11; + + if (++gBoss->act_wait > 16) + { + gBoss->act_wait = 0; + --gBoss->count1; + + unsigned char deg; + + if (gBoss->direct == 0) + deg = GetArktan(gBoss->x - 0x4000 - gMC.x, gBoss->y - 0x1000 - gMC.y); + else + deg = GetArktan(gBoss->x + 0x4000 - gMC.x, gBoss->y - 0x1000 - gMC.y); + + deg += Random(-16, 16); + + int ym = GetSin(deg); + int xm = GetCos(deg); + + if (gBoss->direct == 0) + SetNpChar(108, gBoss->x - 0x4000, gBoss->y - 0x1000, xm, ym, 0, 0, 0x100); + else + SetNpChar(108, gBoss->x + 0x4000, gBoss->y - 0x1000, xm, ym, 0, 0, 0x100); + + PlaySoundObject(39, 1); + + if (gBoss->count1 == 0 || gBoss->life < gBoss->tgt_x - 90) + { + gBoss->act_no = 114; + gBoss->act_wait = 0; + gBoss->ani_no = 2; + gBoss->ani_wait = 0; + gBoss[1].bits &= ~0x20; + } + } + + break; + + case 114: + if (++gBoss->ani_wait > 10) + { + if (++gBoss[1].count1 > 2) + { + gBoss[1].count1 = 0; + gBoss->act_no = 120; + } + else + { + gBoss->act_no = 100; + } + + gBoss->ani_wait = 0; + gBoss->ani_no = 1; + } + + break; + + case 120: + gBoss->act_no = 121; + gBoss->act_wait = 0; + gBoss->ani_no = 1; + gBoss->xm = 0; + // Fallthrough + case 121: + if (++gBoss->act_wait > 50) + { + gBoss->act_no = 122; + gBoss->ani_wait = 0; + gBoss->ani_no = 2; + } + + break; + + case 122: + if (++gBoss->ani_wait > 20) + { + gBoss->act_no = 123; + gBoss->ani_wait = 0; + gBoss->ani_no = 1; + } + + break; + + case 123: + if (++gBoss->ani_wait > 4) + { + gBoss->act_no = 124; + gBoss->ani_no = 5; + gBoss->ym = -0xA00; + gBoss->view.top = 0x8000; + gBoss->view.bottom = 0x3000; + PlaySoundObject(25, 1); + } + + break; + + case 124: + if (gBoss->flag & 8) + { + PlaySoundObject(26, 1); + SetQuake(60); + gBoss->act_no = 100; + gBoss->ani_no = 1; + gBoss->view.top = 0x6000; + gBoss->view.bottom = 0x2000; + + for (int i = 0; i < 2; ++i) + SetNpChar(104, Random(4, 16) * 0x2000, Random(0, 4) * 0x2000, 0, 0, 4, 0, 0x80); + + for (int i = 0; i < 6; ++i) + SetNpChar(110, Random(4, 16) * 0x2000, Random(0, 4) * 0x2000, 0, 0, 4, 0, 0x80); + + for (int i = 0; i < 8; ++i) + SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + gBoss->hit.bottom, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + if (gBoss->direct == 0 && gMC.x > gBoss->x) + { + gBoss->direct = 2; + gBoss->act_no = 110; + } + + if ( gBoss->direct == 2 && gMC.x < gBoss->x) + { + gBoss->direct = 0; + gBoss->act_no = 110; + } + } + + break; + + case 130: + gBoss->act_no = 131; + gBoss->ani_no = 3; + gBoss->act_wait = 0; + gBoss->xm = 0; + PlaySoundObject(72, 1); + + for (int i = 0; i < 8; ++i) + SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + gBoss[1].cond = 0; + gBoss[2].cond = 0; + // Fallthrough + case 131: + if (++gBoss->act_wait % 5 == 0) + SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + if (gBoss->act_wait / 2 % 2) + gBoss->x -= 0x200; + else + gBoss->x += 0x200; + + if (gBoss->act_wait > 100) + { + gBoss->act_wait = 0; + gBoss->act_no = 132; + } + + break; + + case 132: + if (++gBoss->act_wait / 2 % 2) + { + gBoss->view.front = 0x2800; + gBoss->view.top = 0x1800; + gBoss->view.back = 0x2800; + gBoss->view.bottom = 0x1800; + gBoss->ani_no = 6; + } + else + { + gBoss->view.front = 0x6000; + gBoss->view.top = 0x6000; + gBoss->view.back = 0x4000; + gBoss->view.bottom = 0x2000; + gBoss->ani_no = 3; + } + + if (gBoss->act_wait % 9 == 0) + SetNpChar(4, gBoss->x + (Random(-12, 12) * 0x200), gBoss->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + if (gBoss->act_wait > 150) + { + gBoss->act_no = 140; + gBoss->hit.bottom = 0x1800; + } + + break; + + case 140: + gBoss->act_no = 141; + // Fallthrough + case 141: + if (gBoss->flag & 8) + { + gBoss->act_no = 142; + gBoss->act_wait = 0; + gBoss->ani_no = 7; + } + + break; + + case 142: + if (++gBoss->act_wait > 30) + { + gBoss->ani_no = 8; + gBoss->ym = -0xA00; + gBoss->bits |= 8; + gBoss->act_no = 143; + } + + break; + + case 143: + gBoss->ym = -0xA00; + + if (gBoss->y < 0) + { + gBoss->cond = 0; + PlaySoundObject(26, 1); + SetQuake(30); + } + + break; + } + + gBoss->ym += 0x40; + if (gBoss->ym > 0x5FF) + gBoss->ym = 0x5FF; + + gBoss->x += gBoss->xm; + gBoss->y += gBoss->ym; + + if (gBoss->direct == 0) + gBoss->rect = rcLeft[gBoss->ani_no]; + else + gBoss->rect = rcRight[gBoss->ani_no]; + + ActBossChar02_01(); + ActBossChar02_02(); +} diff --git a/src/BossFrog.h b/src/BossFrog.h new file mode 100644 index 00000000..f22dc45f --- /dev/null +++ b/src/BossFrog.h @@ -0,0 +1,3 @@ +#pragma once + +void ActBossChar_Frog(void); diff --git a/src/NpcAct.h b/src/NpcAct.h index 3f87114a..60eed8fc 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -35,10 +35,10 @@ void ActNpc029(NPCHAR *npc); void ActNpc030(NPCHAR *npc); void ActNpc031(NPCHAR *npc); void ActNpc032(NPCHAR *npc); - +void ActNpc033(NPCHAR *npc); void ActNpc034(NPCHAR *npc); void ActNpc035(NPCHAR *npc); - +void ActNpc036(NPCHAR *npc); void ActNpc037(NPCHAR *npc); void ActNpc038(NPCHAR *npc); void ActNpc039(NPCHAR *npc); @@ -94,17 +94,21 @@ void ActNpc097(NPCHAR *npc); void ActNpc098(NPCHAR *npc); void ActNpc099(NPCHAR *npc); void ActNpc100(NPCHAR *npc); - +void ActNpc101(NPCHAR *npc); +void ActNpc102(NPCHAR *npc); void ActNpc103(NPCHAR *npc); void ActNpc104(NPCHAR *npc); void ActNpc105(NPCHAR *npc); void ActNpc106(NPCHAR *npc); +void ActNpc107(NPCHAR *npc); + +void ActNpc109(NPCHAR *npc); void ActNpc111(NPCHAR *npc); void ActNpc112(NPCHAR *npc); void ActNpc114(NPCHAR *npc); - +void ActNpc115(NPCHAR *npc); void ActNpc116(NPCHAR *npc); void ActNpc119(NPCHAR *npc); @@ -120,6 +124,8 @@ void ActNpc145(NPCHAR *npc); void ActNpc150(NPCHAR *npc); void ActNpc151(NPCHAR *npc); +void ActNpc199(NPCHAR *npc); + void ActNpc211(NPCHAR *npc); void ActNpc278(NPCHAR *npc); diff --git a/src/NpcAct020.cpp b/src/NpcAct020.cpp index 9cac5030..0d33f377 100644 --- a/src/NpcAct020.cpp +++ b/src/NpcAct020.cpp @@ -963,6 +963,46 @@ void ActNpc032(NPCHAR *npc) npc->rect = rect[npc->ani_no]; } +//Balrog bouncing projectile +void ActNpc033(NPCHAR *npc) +{ + if (npc->flag & 5) + { + SetCaret(npc->x, npc->y, 2, 0); + npc->cond = 0; + } + else if (npc->flag & 8) + { + npc->ym = -0x400; + } + + npc->ym += 0x2A; + + npc->y += npc->ym; + npc->x += npc->xm; + + RECT rect_left[2]; + + rect_left[0] = {240, 64, 256, 80}; + rect_left[1] = {240, 80, 256, 96}; + + if (++npc->ani_wait > 2) + { + npc->ani_wait = 0; + + if (++npc->ani_no > 1) + npc->ani_no = 0; + } + + npc->rect = rect_left[npc->ani_no]; + + if (++npc->act_wait > 250) + { + SetCaret(npc->x, npc->y, 2, 0); + npc->cond = 0; + } +} + //Bed void ActNpc034(NPCHAR *npc) { @@ -1053,6 +1093,185 @@ void ActNpc035(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Balrog (hover) +void ActNpc036(NPCHAR *npc) +{ + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + // Fallthrough + case 1: + if (++npc->act_wait > 12) + { + npc->act_no = 2; + npc->act_wait = 0; + npc->count1 = 3; + npc->ani_no = 1; + } + + break; + + case 2: + if (++npc->act_wait > 16) + { + --npc->count1; + npc->act_wait = 0; + + const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y + 0x800 - gMC.y) + Random(-16, 16); + const int ym = GetSin(deg); + const int xm = GetCos(deg); + + SetNpChar(11, npc->x, npc->y + 0x800, xm, ym, 0, 0, 0x100); + PlaySoundObject(39, 1); + + if (npc->count1 == 0) + { + npc->act_no = 3; + npc->act_wait = 0; + } + } + + break; + + case 3: + if (++npc->act_wait > 3) + { + npc->act_no = 4; + npc->act_wait = 0; + npc->xm = (gMC.x - npc->x) / 100; + npc->ym = -0x600; + npc->ani_no = 3; + } + + break; + + case 4: + if (npc->ym > -0x200) + { + if (npc->life > 60) + { + npc->act_no = 5; + npc->ani_no = 4; + npc->ani_wait = 0; + npc->act_wait = 0; + npc->tgt_y = npc->y; + } + else + { + npc->act_no = 6; + } + } + + break; + + case 5: + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 5) + { + npc->ani_no = 4; + PlaySoundObject(47, 1); + } + + if (++npc->act_wait > 100) + { + npc->act_no = 6; + npc->ani_no = 3; + } + + if (npc->y < npc->tgt_y) + npc->ym += 0x40; + else + npc->ym -= 0x40; + + if (npc->ym < -0x200) + npc->ym = -0x200; + if (npc->ym > 0x200) + npc->ym = 0x200; + + break; + + case 6: + if (gMC.y > npc->y + 0x2000) + npc->damage = 10; + else + npc->damage = 0; + + if (npc->flag & 8) + { + npc->act_no = 7; + npc->act_wait = 0; + npc->ani_no = 2; + PlaySoundObject(26, 1); + PlaySoundObject(25, 1); + SetQuake(30); + npc->damage = 0; + + for (int i = 0; i < 8; ++i) + SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + for (int i = 0; i < 8; ++i) + SetNpChar(33, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-0x400, 0x400), Random(-0x400, 0), 0, 0, 0x100); + } + + break; + + case 7: + npc->xm = 0; + + if (++npc->act_wait > 3) + { + npc->act_no = 1; + npc->act_wait = 0; + } + + break; + } + + if (npc->act_no != 5) + { + npc->ym += 0x33; + + if (gMC.x > npc->x) + npc->direct = 2; + else + npc->direct = 0; + } + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + RECT rect_left[6]; + RECT rect_right[6]; + + rect_left[0] = {0, 0, 40, 24}; + rect_left[1] = {40, 0, 80, 24}; + rect_left[2] = {80, 0, 120, 24}; + rect_left[3] = {120, 0, 160, 24}; + rect_left[4] = {160, 48, 200, 72}; + rect_left[5] = {200, 48, 240, 72}; + + rect_right[0] = {0, 24, 40, 48}; + rect_right[1] = {40, 24, 80, 48}; + rect_right[2] = {80, 24, 120, 48}; + rect_right[3] = {120, 24, 160, 48}; + rect_right[4] = {160, 72, 200, 96}; + rect_right[5] = {200, 72, 240, 96}; + + if (npc->direct == 0) + npc->rect = rect_left[npc->ani_no]; + else + npc->rect = rect_right[npc->ani_no]; +} + //Signpost void ActNpc037(NPCHAR *npc) { diff --git a/src/NpcAct100.cpp b/src/NpcAct100.cpp index 454a7ed9..1f1c1be4 100644 --- a/src/NpcAct100.cpp +++ b/src/NpcAct100.cpp @@ -8,8 +8,9 @@ #include "Sound.h" #include "Back.h" #include "Triangle.h" +#include "Frame.h" -// Grate +//Grate void ActNpc100(NPCHAR *npc) { RECT rc[2]; @@ -29,6 +30,55 @@ void ActNpc100(NPCHAR *npc) npc->rect = rc[1]; } +//Malco computer screen +void ActNpc101(NPCHAR *npc) +{ + RECT rect[3]; + + rect[0] = {240, 136, 256, 152}; + rect[1] = {240, 136, 256, 152}; + rect[2] = {256, 136, 272, 152}; + + if (++npc->ani_wait > 3) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + npc->ani_no = 0; + + npc->rect = rect[npc->ani_no]; +} + +//Malco computer wave +void ActNpc102(NPCHAR *npc) +{ + RECT rect[4]; + + rect[0] = {208, 120, 224, 136}; + rect[1] = {224, 120, 240, 136}; + rect[2] = {240, 120, 256, 136}; + rect[3] = {256, 120, 272, 136}; + + if (npc->act_no == 0) + { + npc->act_no = 1; + npc->y += 0x1000; + } + + if (++npc->ani_wait > 0) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 3) + npc->ani_no = 0; + + npc->rect = rect[npc->ani_no]; +} + //Mannan projectile void ActNpc103(NPCHAR *npc) { @@ -265,6 +315,240 @@ void ActNpc106(NPCHAR *npc) } } +//Malco +void ActNpc107(NPCHAR *npc) +{ + switch ( npc->act_no ) + { + case 0: + npc->act_no = 1; + + if (npc->direct == 2) + npc->ani_no = 5; + + break; + + case 10: + npc->act_no = 11; + npc->act_wait = 0; + npc->ani_wait = 0; + + for (int i = 0; i < 4; ++i) + SetNpChar(4, npc->x, npc->y, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + // Fallthrough + case 11: + if (++npc->ani_wait > 1) + { + PlaySoundObject(43, 1); + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + + if (++npc->act_wait > 100) + npc->act_no = 12; + + break; + + case 12: + npc->act_no = 13; + npc->act_wait = 0; + npc->ani_no = 1; + // Fallthrough + case 13: + if (++npc->act_wait > 50) + npc->act_no = 14; + + break; + + case 14: + npc->act_no = 15; + npc->act_wait = 0; + // Fallthrough + case 15: + if (npc->act_wait / 2 % 2) + { + npc->x += 0x200; + PlaySoundObject(11, 1); + } + else + { + npc->x -= 0x200; + } + + if (++npc->act_wait > 50) + npc->act_no = 16; + + break; + + case 16: + npc->act_no = 17; + npc->act_wait = 0; + npc->ani_no = 2; + PlaySoundObject(12, 1); + + for (int i = 0; i < 8; ++i) + SetNpChar(4, npc->x, npc->y, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + // Fallthrough + case 17: + if (++npc->act_wait > 150) + npc->act_no = 18; + + break; + + case 18: + npc->act_no = 19; + npc->act_wait = 0; + npc->ani_no = 3; + npc->ani_wait = 0; + // Fallthrough + case 19: + if (++npc->ani_wait > 3) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 4) + { + PlaySoundObject(11, 1); + npc->ani_no = 3; + } + + if (++npc->act_wait > 100) + { + npc->act_no = 20; + PlaySoundObject(12, 1); + + for (int i = 0; i < 4; ++i) + SetNpChar(4, npc->x, npc->y, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + } + + break; + + case 20: + npc->ani_no = 4; + break; + + case 21: + npc->act_no = 22; + npc->ani_no = 5; + PlaySoundObject(51, 1); + break; + + case 100: + npc->act_no = 101; + npc->ani_no = 6; + npc->ani_wait = 0; + // Fallthrough + case 101: + if (++npc->ani_wait > 4) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 9) + npc->ani_no = 6; + + break; + + case 110: + SetDestroyNpChar(npc->x, npc->y, 0x2000, 16); + npc->cond = 0; + break; + } + + RECT rcPoweron[10]; + + rcPoweron[0] = {144, 0, 160, 24}; + rcPoweron[1] = {160, 0, 176, 24}; + rcPoweron[2] = {176, 0, 192, 24}; + rcPoweron[3] = {192, 0, 208, 24}; + rcPoweron[4] = {208, 0, 224, 24}; + rcPoweron[5] = {224, 0, 240, 24}; + rcPoweron[6] = {176, 0, 192, 24}; + rcPoweron[7] = {192, 0, 208, 24}; + rcPoweron[8] = {208, 0, 224, 24}; + rcPoweron[9] = {192, 0, 208, 24}; + + npc->rect = rcPoweron[npc->ani_no]; +} + +//Malco (broken) +void ActNpc109(NPCHAR *npc) +{ + RECT rcLeft[2]; + RECT rcRight[2]; + + rcLeft[0] = {240, 0, 256, 24}; + rcLeft[1] = {256, 0, 272, 24}; + + rcRight[0] = {240, 24, 256, 48}; + rcRight[1] = {256, 24, 272, 48}; + + switch (npc->act_no) + { + case 0: + if (--npc->act_wait) + npc->act_no = 1; + + npc->ani_no = 0; + npc->ani_wait = 0; + // Fallthrough + case 1: + if (Random(0, 120) == 10) + { + npc->act_no = 2; + npc->act_wait = 0; + npc->ani_no = 1; + } + + if (gMC.x > npc->x - 0x4000 && gMC.x < npc->x + 0x4000 && gMC.y > npc->y - 0x4000 && gMC.y < npc->y + 0x2000) + { + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + + case 2: + if (++npc->act_wait > 8) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + + case 10: + npc->act_no = 0; + PlaySoundObject(12, 1); + + for (int i = 0; i < 8; ++i) + SetNpChar(4, npc->x, npc->y, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + break; + } + + npc->ym += 0x40; + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->y += npc->ym; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + //Quote (teleport out) void ActNpc111(NPCHAR *npc) { @@ -499,6 +783,162 @@ void ActNpc114(NPCHAR *npc) npc->rect = rcLeft[npc->ani_no]; } +//Ravil +void ActNpc115(NPCHAR *npc) +{ + RECT rcLeft[6]; + RECT rcRight[6]; + + rcLeft[0] = {0, 120, 24, 144}; + rcLeft[1] = {24, 120, 48, 144}; + rcLeft[2] = {48, 120, 72, 144}; + rcLeft[3] = {72, 120, 96, 144}; + rcLeft[4] = {96, 120, 120, 144}; + rcLeft[5] = {120, 120, 144, 144}; + + rcRight[0] = {0, 144, 24, 168}; + rcRight[1] = {24, 144, 48, 168}; + rcRight[2] = {48, 144, 72, 168}; + rcRight[3] = {72, 144, 96, 168}; + rcRight[4] = {96, 144, 120, 168}; + rcRight[5] = {120, 144, 144, 168}; + + switch (npc->act_no) + { + case 0: + npc->xm = 0; + npc->act_no = 1; + npc->act_wait = 0; + npc->count1 = 0; + // Fallthrough + case 1: + if (gMC.x < npc->x + 0xC000 && gMC.x > npc->x - 0xC000 && gMC.y < npc->y + 0x4000 && gMC.y > npc->y - 0xC000) + npc->act_no = 10; + + if (npc->shock) + npc->act_no = 10; + + break; + + case 10: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + npc->ani_no = 1; + + if (++npc->act_wait > 20) + { + npc->act_wait = 0; + npc->act_no = 20; + } + + break; + + case 20: + npc->damage = 0; + npc->xm = 0; + + if (++npc->ani_wait > 2) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + { + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->direct == 0) + npc->xm = -0x200u; + else + npc->xm = 0x200; + + if (++npc->count1 > 2) + { + npc->count1 = 0; + npc->ani_no = 4; + npc->act_no = 21; + npc->ym = -0x400u; + npc->xm *= 2; + npc->damage = 5; + PlaySoundObject(102, 1); + } + else + { + npc->act_no = 21; + npc->ym = -0x400u; + PlaySoundObject(30, 1); + } + } + + break; + + case 21: + if (npc->flag & 8) + { + PlaySoundObject(23, 1); + npc->act_no = 20; + npc->ani_no = 1; + npc->ani_wait = 0; + npc->damage = 0; + + if (gMC.x > npc->x + 0x12000 || gMC.x < npc->x - 0x12000 || gMC.y > npc->y + 0x6000 || gMC.y < npc->y - 0x12000) + npc->act_no = 0; + } + + break; + + case 30: + for (int i = 0; i < 8; ++i) + SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + npc->ani_no = 0; + npc->act_no = 0; + + break; + + case 50: + npc->act_no = 51; + npc->ani_no = 4; + npc->damage = 0; + npc->ym = -0x200; + npc->bits &= ~0x21; + PlaySoundObject(51, 1); + // Fallthrough + case 51: + if (npc->flag & 8) + { + PlaySoundObject(23, 1); + npc->act_no = 52; + npc->ani_no = 5; + npc->xm = 0; + } + + break; + } + + if (npc->act_no > 50) + npc->ym += 0x20; + else + npc->ym += 0x40; + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + //Red petals void ActNpc116(NPCHAR *npc) { diff --git a/src/NpcAct180.cpp b/src/NpcAct180.cpp new file mode 100644 index 00000000..d1483ecd --- /dev/null +++ b/src/NpcAct180.cpp @@ -0,0 +1,61 @@ +#include "WindowsWrapper.h" + +#include "NpcAct.h" + +#include "MyChar.h" +#include "NpChar.h" +#include "Game.h" +#include "Sound.h" +#include "Back.h" +#include "Triangle.h" + +//Water/wind particles +void ActNpc199(NPCHAR *npc) +{ + RECT rect[5]; + + rect[0] = {72, 16, 74, 18}; + rect[1] = {74, 16, 76, 18}; + rect[2] = {76, 16, 78, 18}; + rect[3] = {78, 16, 80, 18}; + rect[4] = {80, 16, 82, 18}; + + if (npc->act_no == 0) + { + npc->act_no = 1; + npc->ani_no = Random(0, 2); + + switch (npc->direct) + { + case 0: + npc->xm = -1; + break; + case 1: + npc->ym = -1; + break; + case 2: + npc->xm = 1; + break; + case 3: + npc->ym = 1; + break; + } + + npc->xm *= (Random(4, 8) * 0x200) / 2; + npc->ym *= (Random(4, 8) * 0x200) / 2; + } + + if (++npc->ani_wait > 6) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 4) + npc->cond = 0; + + npc->x += npc->xm; + npc->y += npc->ym; + + npc->rect = rect[npc->ani_no]; +} diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index e31796ee..76e2872e 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -89,10 +89,10 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc030, ActNpc031, ActNpc032, - nullptr, + ActNpc033, ActNpc034, ActNpc035, - nullptr, + ActNpc036, ActNpc037, ActNpc038, ActNpc039, @@ -157,21 +157,21 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc098, ActNpc099, ActNpc100, - nullptr, - nullptr, + ActNpc101, + ActNpc102, ActNpc103, ActNpc104, ActNpc105, ActNpc106, + ActNpc107, nullptr, - nullptr, - nullptr, + ActNpc109, nullptr, ActNpc111, ActNpc112, nullptr, ActNpc114, - nullptr, + ActNpc115, ActNpc116, nullptr, nullptr, @@ -255,7 +255,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, nullptr, - nullptr, + ActNpc199, nullptr, nullptr, nullptr,