diff --git a/src/Bullet.cpp b/src/Bullet.cpp index 373374f7..eac79056 100644 --- a/src/Bullet.cpp +++ b/src/Bullet.cpp @@ -2331,3 +2331,35 @@ void ActBullet() } } } + +bool IsActiveSomeBullet(void) +{ + for (int i = 0; i < 0x40; ++i) + { + if (gBul[i].cond & 0x80) + { + switch (gBul[i].code_bullet) + { + case 0xD: + case 0xE: + case 0xF: + case 0x10: + case 0x11: + case 0x12: + case 0x17: + case 0x19: + case 0x1A: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x1E: + case 0x1F: + case 0x20: + case 0x21: + return true; + } + } + } + + return false; +} \ No newline at end of file diff --git a/src/Bullet.h b/src/Bullet.h index db2b6d7e..9d91da4b 100644 --- a/src/Bullet.h +++ b/src/Bullet.h @@ -56,3 +56,4 @@ void ClearBullet(); void PutBullet(int fx, int fy); void SetBullet(int no, int x, int y, int dir); void ActBullet(); +bool IsActiveSomeBullet(void); diff --git a/src/NpcAct.h b/src/NpcAct.h index ec0d5c4d..18272292 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -250,6 +250,7 @@ void ActNpc271(NPCHAR *npc); void ActNpc272(NPCHAR *npc); void ActNpc273(NPCHAR *npc); void ActNpc274(NPCHAR *npc); +void ActNpc275(NPCHAR *npc); void ActNpc278(NPCHAR *npc); @@ -263,6 +264,10 @@ void ActNpc302(NPCHAR *npc); void ActNpc308(NPCHAR *npc); +void ActNpc313(NPCHAR *npc); +void ActNpc314(NPCHAR *npc); +void ActNpc315(NPCHAR *npc); + void ActNpc334(NPCHAR *npc); void ActNpc335(NPCHAR *npc); void ActNpc336(NPCHAR *npc); diff --git a/src/NpcAct260.cpp b/src/NpcAct260.cpp index ac0bbde3..4881dd3d 100644 --- a/src/NpcAct260.cpp +++ b/src/NpcAct260.cpp @@ -269,6 +269,65 @@ void ActNpc274(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Puppy (plantation) +void ActNpc275(NPCHAR *npc) +{ + RECT rcRight[4]; + + rcRight[0] = {272, 80, 288, 96}; + rcRight[1] = {288, 80, 304, 96}; + rcRight[2] = {272, 80, 288, 96}; + rcRight[3] = {304, 80, 320, 96}; + + switch (npc->act_no) + { + case 0: + 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 - 0x8000 && gMC.x < npc->x + 0x8000 && gMC.y > npc->y - 0x4000 && gMC.y < npc->y + 0x2000) + { + if (++npc->ani_wait > 3) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 3) + npc->ani_no = 2; + } + + break; + + case 2: + if (++npc->act_wait > 8) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + } + + npc->ym += 0x40; + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + npc->rect = rcRight[npc->ani_no]; +} + //Little family void ActNpc278(NPCHAR *npc) { diff --git a/src/NpcAct300.cpp b/src/NpcAct300.cpp index 0f17e4a0..ef556d34 100644 --- a/src/NpcAct300.cpp +++ b/src/NpcAct300.cpp @@ -10,6 +10,9 @@ #include "Triangle.h" #include "Caret.h" #include "Boss.h" +#include "Frame.h" +#include "Map.h" +#include "Bullet.h" //Demon crown (opening) void ActNpc300(NPCHAR *npc) @@ -206,3 +209,564 @@ void ActNpc308(NPCHAR *npc) else npc->rect = rcRight[npc->ani_no]; } + +//Ma Pignon +void ActNpc313(NPCHAR *npc) +{ + RECT rcLeft[14]; + RECT rcRight[14]; + + rcLeft[0] = {128, 0, 144, 16}; + rcLeft[1] = {144, 0, 160, 16}; + rcLeft[2] = {160, 0, 176, 16}; + rcLeft[3] = {176, 0, 192, 16}; + rcLeft[4] = {192, 0, 208, 16}; + rcLeft[5] = {208, 0, 224, 16}; + rcLeft[6] = {224, 0, 240, 16}; + rcLeft[7] = {240, 0, 256, 16}; + rcLeft[8] = {256, 0, 272, 16}; + rcLeft[9] = {272, 0, 288, 16}; + rcLeft[10] = {288, 0, 304, 16}; + rcLeft[11] = {128, 0, 144, 16}; + rcLeft[12] = {176, 0, 192, 16}; + rcLeft[13] = {304, 0, 320, 16}; + + rcRight[0] = {128, 16, 144, 32}; + rcRight[1] = {144, 16, 160, 32}; + rcRight[2] = {160, 16, 176, 32}; + rcRight[3] = {176, 16, 192, 32}; + rcRight[4] = {192, 16, 208, 32}; + rcRight[5] = {208, 16, 224, 32}; + rcRight[6] = {224, 16, 240, 32}; + rcRight[7] = {240, 16, 256, 32}; + rcRight[8] = {256, 16, 272, 32}; + rcRight[9] = {272, 16, 288, 32}; + rcRight[10] = {288, 16, 304, 32}; + rcRight[11] = {128, 16, 144, 32}; + rcRight[12] = {176, 16, 192, 32}; + rcRight[13] = {304, 16, 320, 32}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->ani_no = 0; + npc->ani_wait = 0; + npc->y += 0x800; + // Fallthrough + case 1: + npc->ym += 0x40; + + 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) + { + 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 100: + npc->act_no = 110; + npc->act_wait = 0; + npc->count1 = 0; + npc->bits |= 0x20; + // Fallthrough + case 110: + npc->damage = 1; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + npc->ani_no = 0; + + if (++npc->act_wait > 4) + { + npc->act_wait = 0; + npc->act_no = 120; + + if (++npc->count2 > 12) + { + npc->count2 = 0; + npc->act_no = 300; + } + } + + break; + + case 120: + npc->ani_no = 2; + + if (++npc->act_wait > 4) + { + npc->act_no = 130; + npc->ani_no = 3; + npc->xm = 2 * Random(-0x200, 0x200); + npc->ym = -0x800; + PlaySoundObject(30, 1); + ++npc->count1; + } + + break; + + case 130: + npc->ym += 0x80; + + if (npc->y > 0x10000) + npc->bits &= ~8; + + if (npc->xm < 0 && npc->flag & 1) + npc->xm = -npc->xm; + if (npc->xm > 0 && npc->flag & 4) + npc->xm = -npc->xm; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->ym < -0x200) + npc->ani_no = 3; + else if (npc->ym > 0x200) + npc->ani_no = 4; + else + npc->ani_no = 0; + + if (npc->flag & 8) + { + npc->act_no = 140; + npc->act_wait = 0; + npc->ani_no = 2; + npc->xm = 0; + } + + if (npc->count1 > 4 && gMC.y < npc->y + 0x800) + { + npc->act_no = 200; + npc->act_wait = 0; + npc->xm = 0; + npc->ym = 0; + } + + break; + + case 140: + npc->ani_no = 2; + + if (++npc->act_wait > 4) + npc->act_no = 110; + + break; + + case 200: + npc->ani_no = 5; + + if (++npc->act_wait > 10) + { + npc->act_no = 210; + npc->ani_no = 6; + + if (npc->direct == 0) + npc->xm = -0x5FF; + else + npc->xm = 0x5FF; + + PlaySoundObject(25, 1); + npc->bits &= ~0x20; + npc->bits |= 4; + npc->damage = 10; + } + + break; + + case 210: + if (++npc->ani_no > 7) + npc->ani_no = 6; + + if (npc->xm < 0 && npc->flag & 1) + npc->act_no = 220; + if (npc->xm > 0 && npc->flag & 4) + npc->act_no = 220; + + break; + + case 220: + npc->act_no = 221; + npc->act_wait = 0; + SetQuake(16); + PlaySoundObject(26, 1); + npc->damage = 4; + // Fallthrough + case 221: + if (++npc->ani_no > 7) + npc->ani_no = 6; + + if (++npc->act_wait % 6 == 0) + SetNpChar(314, Random(4, 16) * 0x2000, 0x2000, 0, 0, 0, 0, 0x100); + + if (npc->act_wait > 30) + { + npc->count1 = 0; + npc->act_no = 130; + npc->bits |= 0x20; + npc->bits &= ~4; + npc->damage = 3; + } + + break; + + case 300: + npc->act_no = 301; + npc->ani_no = 9; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + // Fallthrough + case 301: + if (++npc->ani_no > 11) + npc->ani_no = 9; + + if (npc->direct == 0) + npc->xm = -0x400; + else + npc->xm = 0x400; + + if (gMC.x > npc->x - 0x800 && gMC.x < npc->x + 0x800) + { + npc->act_no = 310; + npc->act_wait = 0; + npc->ani_no = 2; + npc->xm = 0; + } + + break; + + case 310: + npc->ani_no = 2; + + if (++npc->act_wait > 4) + { + npc->act_no = 320; + npc->ani_no = 12; + npc->ym = -0x800; + PlaySoundObject(25, 1); + npc->bits |= 8; + npc->bits &= ~0x20; + npc->bits |= 4; + npc->damage = 10; + } + + break; + + case 320: + if (++npc->ani_no > 13) + npc->ani_no = 12; + + if (npc->y < 0x2000) + npc->act_no = 330; + + break; + + case 330: + npc->ym = 0; + npc->act_no = 331; + npc->act_wait = 0; + SetQuake(16); + PlaySoundObject(26, 1); + // Fallthrough + case 331: + if (++npc->ani_no > 13) + npc->ani_no = 12; + + if (++npc->act_wait % 6 == 0) + SetNpChar(315, Random(4, 16) * 0x2000, 0, 0, 0, 0, 0, 0x100); + + if (npc->act_wait > 30) + { + npc->count1 = 0; + npc->act_no = 130; + npc->bits |= 0x20; + npc->bits &= ~4; + npc->damage = 3; + } + + break; + + case 500: + npc->bits &= ~0x20; + npc->act_no = 501; + npc->act_wait = 0; + npc->ani_no = 8; + npc->tgt_x = npc->x; + npc->damage = 0; + DeleteNpCharCode(315, 1); + // Fallthrough + case 501: + npc->ym += 0x20; + + if (++npc->act_wait % 2) + npc->x = npc->tgt_x; + else + npc->x = npc->tgt_x + 0x200; + + break; + } + + if (npc->act_no > 100 && npc->act_no < 500 && npc->act_no != 210 && npc->act_no != 320) + { + if (IsActiveSomeBullet()) + { + npc->bits &= ~0x20; + npc->bits |= 4; + } + else + { + npc->bits |= 0x20; + npc->bits &= ~4; + } + } + + 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]; +} + +//Ma Pignon rock +void ActNpc314(NPCHAR *npc) +{ + RECT rc[3]; + + rc[0] = {64, 64, 80, 80}; + rc[1] = {80, 64, 96, 80}; + rc[2] = {96, 64, 112, 80}; + + switch (npc->act_no) + { + case 0: + npc->count2 = 0; + npc->act_no = 100; + npc->bits |= 4; + npc->ani_no = Random(0, 2); + // Fallthrough + case 100: + npc->ym += 0x40; + + if (npc->ym > 0x700) + npc->ym = 0x700; + + if (npc->y > 0x10000) + npc->bits &= ~8; + + if (npc->flag & 8) + { + npc->ym = -0x200; + npc->act_no = 110; + npc->bits |= 8; + PlaySoundObject(12, 1); + SetQuake(10); + + for (int i = 0; i < 2; ++i) + SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + 0x2000, Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + } + + break; + + case 110: + npc->ym += 0x40; + + if (npc->y > (gMap.length * 0x2000) + 0x4000) + { + npc->cond = 0; + return; + } + + break; + } + + if (++npc->ani_wait > 6) + { + ++npc->ani_wait; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + npc->ani_no = 0; + + if (gMC.y > npc->y) + npc->damage = 10; + else + npc->damage = 0; + + npc->y += npc->ym; + + npc->rect = rc[npc->ani_no]; +} + +//Ma Pignon clone +void ActNpc315(NPCHAR *npc) +{ + RECT rcLeft[4]; + RECT rcRight[4]; + + rcLeft[0] = {128, 0, 144, 16}; + rcLeft[1] = {160, 0, 176, 16}; + rcLeft[2] = {176, 0, 192, 16}; + rcLeft[3] = {192, 0, 208, 16}; + + rcRight[0] = {128, 16, 144, 32}; + rcRight[1] = {160, 16, 176, 32}; + rcRight[2] = {176, 16, 192, 32}; + rcRight[3] = {192, 16, 208, 32}; + + switch (npc->act_no) + { + case 0: + npc->ani_no = 3; + npc->ym += 0x80; + + if (npc->y > 0x10000) + { + npc->act_no = 130; + npc->bits &= ~8; + } + + break; + + case 100: + npc->act_no = 110; + npc->act_wait = 0; + npc->count1 = 0; + npc->bits |= 0x20; + // Fallthrough + case 110: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + npc->ani_no = 0; + + if (++npc->act_wait > 4) + { + npc->act_wait = 0; + npc->act_no = 120; + } + + break; + + case 120: + npc->ani_no = 1; + + if (++npc->act_wait > 4) + { + npc->act_no = 130; + npc->ani_no = 3; + npc->xm = 2 * Random(-0x200, 0x200); + npc->ym = -0x800; + PlaySoundObject(30, 1); + } + + break; + + case 130: + npc->ym += 0x80; + + if (npc->xm < 0 && npc->flag & 1) + npc->xm = -npc->xm; + if (npc->xm > 0 && npc->flag & 4) + npc->xm = -npc->xm; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->ym < -0x200) + npc->ani_no = 2; + else if (npc->ym > 0x200) + npc->ani_no = 0; + else + npc->ani_no = 3; + + if (npc->flag & 8) + { + npc->act_no = 140; + npc->act_wait = 0; + npc->ani_no = 1; + npc->xm = 0; + } + + break; + + case 140: + npc->ani_no = 1; + + if (++npc->act_wait > 4) + { + npc->act_no = 110; + npc->bits |= 0x20; + } + + break; + } + + if (npc->act_no > 100) + { + if (IsActiveSomeBullet()) + { + npc->bits &= ~0x20; + npc->bits |= 4; + } + else + { + npc->bits |= 0x20; + npc->bits &= ~4; + } + } + + if (++npc->count2 > 300) + { + VanishNpChar(npc); + } + else + { + 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]; + } +} diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index 9152302a..3607ec48 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -331,7 +331,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc272, ActNpc273, ActNpc274, - nullptr, + ActNpc275, nullptr, nullptr, ActNpc278, @@ -369,9 +369,9 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, nullptr, - nullptr, - nullptr, - nullptr, + ActNpc313, + ActNpc314, + ActNpc315, nullptr, nullptr, nullptr,