diff --git a/src/NpcAct.h b/src/NpcAct.h index 3bc250f9..01ad03b3 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -46,14 +46,20 @@ void ActNpc040(NPCHAR *npc); void ActNpc041(NPCHAR *npc); void ActNpc042(NPCHAR *npc); void ActNpc043(NPCHAR *npc); - +void ActNpc044(NPCHAR *npc); +void ActNpc045(NPCHAR *npc); void ActNpc046(NPCHAR *npc); - +void ActNpc047(NPCHAR *npc); void ActNpc048(NPCHAR *npc); - +void ActNpc049(NPCHAR *npc); +void ActNpc050(NPCHAR *npc); +void ActNpc051(NPCHAR *npc); +void ActNpc052(NPCHAR *npc); +void ActNpc053(NPCHAR *npc); +void ActNpc054(NPCHAR *npc); void ActNpc055(NPCHAR *npc); void ActNpc056(NPCHAR *npc); - +void ActNpc057(NPCHAR *npc); void ActNpc058(NPCHAR *npc); void ActNpc059(NPCHAR *npc); void ActNpc060(NPCHAR *npc); @@ -120,14 +126,29 @@ void ActNpc120(NPCHAR *npc); void ActNpc121(NPCHAR *npc); void ActNpc122(NPCHAR *npc); void ActNpc123(NPCHAR *npc); - +void ActNpc124(NPCHAR *npc); void ActNpc125(NPCHAR *npc); - +void ActNpc126(NPCHAR *npc); void ActNpc127(NPCHAR *npc); void ActNpc128(NPCHAR *npc); void ActNpc129(NPCHAR *npc); - +void ActNpc130(NPCHAR *npc); +void ActNpc131(NPCHAR *npc); +void ActNpc132(NPCHAR *npc); +void ActNpc133(NPCHAR *npc); +void ActNpc134(NPCHAR *npc); +void ActNpc135(NPCHAR *npc); +void ActNpc136(NPCHAR *npc); +void ActNpc137(NPCHAR *npc); +void ActNpc138(NPCHAR *npc); +void ActNpc139(NPCHAR *npc); +void ActNpc140(NPCHAR *npc); +void ActNpc141(NPCHAR *npc); +void ActNpc142(NPCHAR *npc); +void ActNpc143(NPCHAR *npc); +void ActNpc144(NPCHAR *npc); void ActNpc145(NPCHAR *npc); +void ActNpc146(NPCHAR *npc); void ActNpc150(NPCHAR *npc); void ActNpc151(NPCHAR *npc); @@ -143,10 +164,14 @@ void ActNpc219(NPCHAR *npc); void ActNpc278(NPCHAR *npc); +void ActNpc292(NPCHAR *npc); + void ActNpc298(NPCHAR *npc); void ActNpc299(NPCHAR *npc); void ActNpc300(NPCHAR *npc); +void ActNpc302(NPCHAR *npc); + void ActNpc355(NPCHAR *npc); void ActNpc359(NPCHAR *npc); diff --git a/src/NpcAct040.cpp b/src/NpcAct040.cpp index 3afdfabf..9fcf4ad2 100644 --- a/src/NpcAct040.cpp +++ b/src/NpcAct040.cpp @@ -9,6 +9,7 @@ #include "Sound.h" #include "Back.h" #include "Triangle.h" +#include "CommonDefines.h" //Santa void ActNpc040(NPCHAR *npc) @@ -412,6 +413,254 @@ void ActNpc043(NPCHAR *npc) npc->rect = rcRight[0]; } +//Polish +void ActNpc044(NPCHAR *npc) +{ + RECT rcRight[3]; + RECT rcLeft[3]; + + rcRight[0] = {0, 0, 32, 32}; + rcRight[1] = {32, 0, 64, 32}; + rcRight[2] = {64, 0, 96, 32}; + + rcLeft[0] = {0, 0, 32, 32}; + rcLeft[1] = {96, 0, 128, 32}; + rcLeft[2] = {128, 0, 160, 32}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + // Fallthrough + case 1: + npc->ani_no = 0; + + if (npc->direct == 0) + npc->act_no = 8; + else + npc->act_no = 2; + // Fallthrough + case 2: + npc->ym += 0x20; + + if (npc->ym > 0 && npc->flag & 8) + { + npc->ym = -0x100; + npc->xm += 0x100; + } + + if (npc->flag & 4) + npc->act_no = 3; + + break; + + case 3: + npc->xm += 0x20; + + if (npc->xm > 0 && npc->flag & 4) + { + npc->xm = -0x100; + npc->ym -= 0x100; + } + + if (npc->flag & 2) + npc->act_no = 4; + + break; + + case 4: + npc->ym -= 0x20; + + if (npc->ym < 0 && npc->flag & 2) + { + npc->ym = 0x100; + npc->xm -= 0x100; + } + + if (npc->flag & 1) + npc->act_no = 5; + + break; + + case 5: + npc->xm -= 0x20; + + if (npc->xm < 0 && npc->flag & 1) + { + npc->xm = 0x100; + npc->ym += 0x100; + } + + if (npc->flag & 8) + npc->act_no = 2; + + break; + + case 6: + npc->ym += 0x20; + + if (npc->ym > 0 && npc->flag & 8) + { + npc->ym = -0x100; + npc->xm -= 0x100; + } + + if (npc->flag & 1) + npc->act_no = 7; + + break; + + case 7: + npc->xm -= 0x20; + + if (npc->xm < 0 && npc->flag & 1) + { + npc->xm = 0x100; + npc->ym -= 0x100; + } + + if (npc->flag & 2) + npc->act_no = 8; + + break; + + case 8: + npc->ym -= 0x20; + + if (npc->ym < 0 && npc->flag & 2) + { + npc->ym = 0x100; + npc->xm += 0x100; + } + + if ( npc->flag & 4 ) + npc->act_no = 9; + + break; + + case 9: + npc->xm += 0x20; + + if (npc->xm > 0 && npc->flag & 4) + { + npc->xm = -0x100; + npc->ym += 0x100; + } + + if (npc->flag & 8) + npc->act_no = 6; + + break; + } + + if (npc->life <= 100) + { + for (int i = 0; i < 10; ++i) + SetNpChar(45, npc->x, npc->y, 0, 0, 0, 0, 0x100); + + SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8); + PlaySoundObject(25, 1); + npc->cond = 0; + } + + 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; + + if (npc->shock) + { + npc->x += npc->xm / 2; + npc->y += npc->ym / 2; + } + else + { + npc->x += npc->xm; + npc->y += npc->ym; + } + + if (npc->act_no >= 2 && npc->act_no <= 9 && ++npc->ani_no > 2) + npc->ani_no = 1; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Baby +void ActNpc045(NPCHAR *npc) +{ + RECT rect[3]; + + rect[0] = {0, 32, 16, 48}; + rect[1] = {16, 32, 32, 48}; + rect[2] = {32, 32, 48, 48}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 2; + + if (Random(0, 1)) + npc->xm = Random(-0x200, -0x100); + else + npc->xm = Random(0x100, 0x200); + + if (Random(0, 1)) + npc->ym = Random(-0x200, -0x100); + else + npc->ym = Random(0x100, 0x200); + + npc->xm2 = npc->xm; + npc->ym2 = npc->ym; + // Fallthrough + case 1: + if ( ++npc->ani_no > 2 ) + npc->ani_no = 1; + + break; + } + + if (npc->xm2 < 0 && npc->flag & 1) + npc->xm2 = -npc->xm2; + if (npc->xm2 > 0 && npc->flag & 4) + npc->xm2 = -npc->xm2; + + if (npc->ym2 < 0 && npc->flag & 2) + npc->ym2 = -npc->ym2; + if (npc->ym2 > 0 && npc->flag & 8) + npc->ym2 = -npc->ym2; + + if (npc->xm2 > 0x200) + npc->xm2 = 0x200; + if (npc->xm2 < -0x200) + npc->xm2 = -0x200; + + if (npc->ym2 > 0x200) + npc->ym2 = 0x200; + if (npc->ym2 < -0x200) + npc->ym2 = -0x200; + + if (npc->shock) + { + npc->x += npc->xm2 / 2; + npc->y += npc->ym2 / 2; + } + else + { + npc->x += npc->xm2; + npc->y += npc->ym2; + } + + npc->rect = rect[npc->ani_no]; +} + //H/V Trigger void ActNpc046(NPCHAR *npc) { @@ -438,6 +687,109 @@ void ActNpc046(NPCHAR *npc) npc->rect = rect[0]; } +//Sandcroc +void ActNpc047(NPCHAR *npc) +{ + switch ( npc->act_no ) + { + case 0: + npc->ani_no = 0; + npc->act_no = 1; + npc->act_wait = 0; + npc->tgt_y = npc->y; + npc->bits &= ~0x20; + npc->bits &= ~4; + npc->bits &= ~1; + npc->bits &= ~8; + // Fallthrough + case 1: + if (gMC.x > npc->x - 0x1000 && gMC.x < npc->x + 0x1000 && gMC.y > npc->y && gMC.y < npc->y + 0x1000) + { + npc->act_no = 2; + npc->act_wait = 0; + PlaySoundObject(102, 1); + } + + if (gMC.x > npc->x) + npc->x += 0x400; + + if (gMC.x < npc->x) + npc->x -= 0x400; + + break; + + case 2: + if (++npc->ani_wait > 3) + { + ++npc->ani_no; + npc->ani_wait = 0; + } + + if (npc->ani_no == 3) + npc->damage = 10; + + if (npc->ani_no == 4) + { + npc->bits |= 0x20; + npc->act_no = 3; + npc->act_wait = 0; + } + + break; + + case 3: + npc->bits |= 1; + npc->damage = 0; + ++npc->act_wait; + + if (npc->shock) + { + npc->act_no = 4; + npc->act_wait = 0; + } + + break; + + case 4: + npc->bits |= 8; + npc->y += 0x200; + + if (++npc->act_wait == 32) + { + npc->bits &= ~1; + npc->bits &= ~0x20; + npc->act_no = 5; + npc->act_wait = 0; + } + + break; + + case 5: + if (npc->act_wait < 100) + { + ++npc->act_wait; + } + else + { + npc->y = npc->tgt_y; + npc->ani_no = 0; + npc->act_no = 0; + } + + break; + } + + RECT rect[5]; + + rect[0] = {0, 48, 48, 80}; + rect[1] = {48, 48, 96, 80}; + rect[2] = {96, 48, 144, 80}; + rect[3] = {144, 48, 192, 80}; + rect[4] = {192, 48, 240, 80}; + + npc->rect = rect[npc->ani_no]; +} + //Omega projectiles void ActNpc048(NPCHAR *npc) { @@ -498,6 +850,573 @@ void ActNpc048(NPCHAR *npc) npc->rect = rcLeft[npc->ani_no]; } +//Skullhead +void ActNpc049(NPCHAR *npc) +{ + if (npc->act_no >= 10 && npc->pNpc->code_char == 3) + { + npc->act_no = 3; + npc->xm = 0; + npc->ym = 0; + npc->count2 = 1; + } + + if (npc->flag & 1) + { + npc->direct = 2; + npc->xm = 0x100; + } + + if (npc->flag & 4) + { + npc->direct = 0; + npc->xm = -0x100; + } + + switch (npc->act_no) + { + case 0: + if (npc->pNpc) + npc->act_no = 10; + else + npc->act_no = 1; + // Fallthrough + case 1: + if (++npc->act_wait > 3) + { + npc->ym = -0x400; + npc->act_no = 3; + npc->ani_no = 2; + + if (npc->count2 == 0) + { + if (npc->direct == 0) + npc->xm = -0x100; + else + npc->xm = 0x100; + } + else + { + if (npc->direct == 0) + npc->xm = -0x200; + else + npc->xm = 0x200; + } + } + + npc->ani_no = 1; + break; + + case 3: + if (npc->flag & 8) + { + npc->act_no = 1; + npc->act_wait = 0; + npc->xm = 0; + } + + if (npc->flag & 8 || npc->ym > 0) + npc->ani_no = 1; + else + npc->ani_no = 2; + + break; + + case 10: + if (npc->count1 < 50) + { + ++npc->count1; + } + else + { + if (gMC.x > npc->x - 0x10000 && gMC.x < npc->x + 0x10000 && gMC.y > npc->y - 0xC000 && gMC.y < npc->y + 0xC000) + { + npc->act_no = 11; + npc->act_wait = 0; + npc->ani_no = 2; + } + } + + break; + + case 11: + if (++npc->act_wait == 30 || npc->act_wait == 35) + { + const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y + 0x800 - gMC.y); + const int ym = 2 * GetSin(deg); + const int xm = 2 * GetCos(deg); + SetNpChar(50, npc->x, npc->y, xm, ym, 0, 0, 0x100); + PlaySoundObject(39, 1); + } + + if (npc->act_wait > 50) + { + npc->count1 = 0; + npc->act_no = 10; + npc->ani_no = 1; + } + + break; + } + + if (npc->act_no >= 10) + { + npc->x = npc->pNpc->x; + npc->y = npc->pNpc->y + 0x2000; + npc->direct = npc->pNpc->direct; + --npc->pNpc->count1; + } + + npc->ym += 0x40; + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + RECT rcLeft[3]; + RECT rcRight[3]; + + rcLeft[0] = {0, 80, 32, 104}; + rcLeft[1] = {32, 80, 64, 104}; + rcLeft[2] = {64, 80, 96, 104}; + + rcRight[0] = {0, 104, 32, 128}; + rcRight[1] = {32, 104, 64, 128}; + rcRight[2] = {64, 104, 96, 128}; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Skeleton projectile +void ActNpc050(NPCHAR *npc) +{ + switch (npc->act_no) + { + case 0: + if (npc->direct == 2) + { + npc->act_no = 2; + } + // Fallthrough + case 1: + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->flag & 1) + { + npc->act_no = 2; + npc->xm = 0x200; + ++npc->count1; + } + + if (npc->flag & 4) + { + npc->act_no = 2; + npc->xm = -0x200; + ++npc->count1; + } + + if (npc->flag & 2) + { + npc->act_no = 2; + npc->ym = 0x200; + ++npc->count1; + } + + if (npc->flag & 8) + { + npc->act_no = 2; + npc->ym = -0x200; + ++npc->count1; + } + + break; + + case 2: + npc->ym += 0x40; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->flag & 8) + { + if (++npc->count1 > 1) + { + SetCaret(npc->x, npc->y, 2, 0); + npc->cond = 0; + } + } + + break; + } + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + if (npc->ym < -0x5FF) + npc->ym = -0x5FF; + + RECT rect[4]; + + rect[0] = {48, 32, 64, 48}; + rect[1] = {64, 32, 80, 48}; + rect[2] = {80, 32, 96, 48}; + rect[3] = {96, 32, 112, 48}; + + if (npc->direct == 0) + { + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 3) + npc->ani_no = 0; + } + else + { + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + --npc->ani_no; + } + + if (npc->ani_no < 0) + npc->ani_no = 3; + } + + npc->rect = rect[npc->ani_no]; +} + +//Crow & Skullhead +void ActNpc051(NPCHAR *npc) +{ + switch (npc->act_no) + { + case 0: + if (gMC.x > npc->x - (WINDOW_WIDTH * 0x200) && gMC.x < npc->x + (WINDOW_WIDTH * 0x200) && gMC.y > npc->y - (WINDOW_WIDTH * 0x200) && gMC.y < npc->y + (WINDOW_WIDTH * 0x200)) + { + npc->tgt_x = npc->x; + npc->tgt_y = npc->y; + npc->ym = 0x400; + npc->act_no = 1; + SetNpChar(49, 0, 0, 0, 0, 0, npc, 0); + } + else + break; + + // Fallthrough + case 1: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->tgt_y < npc->y) + npc->ym -= 10; + if (npc->tgt_y > npc->y) + npc->ym += 10; + + if (npc->ym > 0x200) + npc->ym = 0x200; + if (npc->ym < -0x200) + npc->ym = -0x200; + + if (npc->count1 < 10) + ++npc->count1; + else + npc->act_no = 2; + + break; + + case 2: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->y > gMC.y + 0x4000) + { + if (gMC.x < npc->x) + npc->xm += 0x10; + if (gMC.x > npc->x) + npc->xm -= 0x10; + } + else + { + if (gMC.x < npc->x) + npc->xm -= 0x10; + if (gMC.x > npc->x) + npc->xm += 0x10; + } + + if (gMC.y < npc->y) + npc->ym -= 0x10; + if (gMC.y > npc->y) + npc->ym += 0x10; + + if (npc->shock) + { + npc->ym += 0x20; + npc->xm = 0; + } + + break; + } + + if (npc->xm < 0 && npc->flag & 1) + npc->xm = 0x100; + if (npc->xm > 0 && npc->flag & 4) + npc->xm = -0x100; + + if (npc->ym < 0 && npc->flag & 2) + npc->ym = 0x100; + if (npc->ym > 0 && npc->flag & 8) + npc->ym = -0x100; + + if (npc->xm > 0x400) + npc->xm = 0x400; + if (npc->xm < -0x400) + npc->xm = -0x400; + + if (npc->ym > 0x200) + npc->ym = 0x200; + if (npc->ym < -0x200) + npc->ym = -0x200; + + npc->x += npc->xm; + npc->y += npc->ym; + + RECT rect_left[5]; + RECT rect_right[5]; + + rect_left[0] = {96, 80, 128, 112}; + rect_left[1] = {128, 80, 160, 112}; + rect_left[2] = {160, 80, 192, 112}; + rect_left[3] = {192, 80, 224, 112}; + rect_left[4] = {224, 80, 256, 112}; + + rect_right[0] = {96, 112, 128, 144}; + rect_right[1] = {128, 112, 160, 144}; + rect_right[2] = {160, 112, 192, 144}; + rect_right[3] = {192, 112, 224, 144}; + rect_right[4] = {224, 112, 256, 144}; + + if (npc->shock) + { + npc->ani_no = 4; + } + else if (npc->act_no == 2 && npc->y < gMC.y - 0x4000) + { + npc->ani_no = 0; + } + else + { + if (npc->act_no) + { + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + } + } + + if (npc->direct == 0) + npc->rect = rect_left[npc->ani_no]; + else + npc->rect = rect_right[npc->ani_no]; +} + +//Bliue robot (sitting) +void ActNpc052(NPCHAR *npc) +{ + RECT rect[1]; + + rect[0] = {240, 96, 256, 112}; + + npc->rect = rect[0]; +} + +//Skullstep leg +void ActNpc053(NPCHAR *npc) +{ + RECT rcLeft[2]; + RECT rcRight[2]; + + rcLeft[0] = {0, 128, 24, 144}; + rcLeft[1] = {24, 128, 48, 144}; + + rcRight[0] = {48, 128, 72, 144}; + rcRight[1] = {72, 128, 96, 144}; + + if (npc->pNpc->code_char == 3) + { + VanishNpChar(npc); + SetDestroyNpChar(npc->x, npc->y, npc->view.back, 4); + return; + } + + unsigned char deg; + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->count1 = 10; + // Fallthrough + case 1: + if (npc->direct == 0 && npc->flag & 0x20) + { + npc->pNpc->y -= 0x400; + npc->pNpc->ym -= 0x100; + } + + if (npc->direct == 2 && npc->flag & 0x10) + { + npc->pNpc->y -= 0x400; + npc->pNpc->ym -= 0x100; + } + + if (npc->flag & 8) + { + npc->pNpc->y -= 0x400; + npc->pNpc->ym -= 0x100; + + if (npc->pNpc->direct == 0) + npc->pNpc->xm -= 0x80; + else + npc->pNpc->xm += 0x80; + } + + deg = npc->xm + npc->pNpc->count2; + npc->x = npc->pNpc->x + npc->count1 * GetCos(deg); + npc->y = npc->pNpc->y + npc->count1 * GetSin(deg); + npc->direct = npc->pNpc->direct; + break; + } + + npc->direct = npc->pNpc->direct; + npc->ani_no = deg < 20 || deg > 108; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Skullstep +void ActNpc054(NPCHAR *npc) +{ + RECT rcLeft[3]; + RECT rcRight[3]; + + rcLeft[0] = {0, 80, 32, 104}; + rcLeft[1] = {32, 80, 64, 104}; + rcLeft[2] = {64, 80, 96, 104}; + + rcRight[0] = {0, 104, 32, 128}; + rcRight[1] = {32, 104, 64, 128}; + rcRight[2] = {64, 104, 96, 128}; + + unsigned char deg; + switch (npc->act_no) + { + case 0: + SetNpChar(53, 0, 0, 0, 0, npc->direct, npc, 0x100); + SetNpChar(53, 0, 0, 128, 0, npc->direct, npc, 0); + npc->act_no = 1; + npc->ani_no = 1; + // Fallthrough + case 1: + deg = npc->count2; + + if (npc->direct == 0) + deg -= 6; + else + deg += 6; + + npc->count2 = deg; + + if (npc->flag & 8) + { + npc->xm = 3 * npc->xm / 4; + + if (++npc->act_wait > 60) + { + npc->act_no = 2; + npc->act_wait = 0; + } + } + else + { + npc->act_wait = 0; + } + + if (npc->direct == 0 && npc->flag & 1) + { + if (++npc->count1 > 8) + { + npc->direct = 2; + npc->xm = -npc->xm; + } + } + else if (npc->direct == 2 && npc->flag & 4) + { + if (++npc->count1 > 8) + { + npc->direct = 0; + npc->xm = -npc->xm; + } + } + else + { + npc->count1 = 0; + } + + break; + + case 2: + ++npc->act_wait; + npc->shock += npc->act_wait; + + if (npc->act_wait > 50) + { + VanishNpChar(npc); + SetDestroyNpChar(npc->x, npc->y, npc->view.back, 8); + PlaySoundObject(25, 1); + } + + break; + } + + npc->ym += 0x80; + + if (npc->xm > 0x2FF) + npc->xm = 0x2FF; + if (npc->xm < -0x2FF) + npc->xm = -0x2FF; + + if (npc->ym > 0x2FF) + npc->ym = 0x2FF; + if (npc->ym < -0x2FF) + npc->ym = -0x2FF; + + 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]; +} + //Cairn void ActNpc055(NPCHAR *npc) { @@ -680,6 +1599,162 @@ void ActNpc056(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Crow +void ActNpc057(NPCHAR *npc) +{ + unsigned char deg; + switch (npc->act_no) + { + case 0: + deg = Random(0, 0xFF); + npc->xm = GetCos(deg); + npc->tgt_x = npc->x + 8 * GetCos(deg + 0x40); + + deg = Random(0, 0xFF); + npc->ym = GetSin(deg); + npc->tgt_y = npc->y + 8 * GetSin(deg + 0x40); + + npc->act_no = 1; + npc->count1 = 120; + npc->ani_no = Random(0, 1); + npc->ani_wait = Random(0, 4); + // Fallthrough + case 1: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->tgt_x < npc->x) + npc->xm -= 0x10; + if (npc->tgt_x > npc->x) + npc->xm += 0x10; + + if (npc->tgt_y < npc->y) + npc->ym -= 0x10; + if (npc->tgt_y > npc->y) + npc->ym += 0x10; + + 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; + + if (npc->shock) + { + npc->act_no = 2; + npc->act_wait = 0; + + if (npc->direct == 2) + npc->xm = -0x200; + else + npc->xm = 0x200; + + npc->ym = 0; + } + + break; + + case 2: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->y > gMC.y + 0x6000) + { + if (gMC.x < npc->x) + npc->xm += 0x10; + if (gMC.x > npc->x) + npc->xm -= 0x10; + } + else + { + if (gMC.x < npc->x) + npc->xm -= 0x10; + if (gMC.x > npc->x) + npc->xm += 0x10; + } + + if (gMC.y < npc->y) + npc->ym -= 0x10; + if (gMC.y > npc->y) + npc->ym += 0x10; + + if (npc->shock) + { + npc->ym += 0x20; + npc->xm = 0; + } + + if (npc->xm < 0 && npc->flag & 1) + npc->xm = 0x200; + if (npc->xm > 0 && npc->flag & 4) + npc->xm = -0x200; + + if (npc->ym < 0 && npc->flag & 2) + npc->ym = 0x200; + if (npc->ym > 0 && npc->flag & 8) + npc->ym = -0x200; + + if (npc->xm > 0x5FF) + npc->xm = 0x5FF; + if (npc->xm < -0x5FF) + npc->xm = -0x5FF; + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + if (npc->ym < -0x5FF) + npc->ym = -0x5FF; + + break; + } + + npc->x += npc->xm; + npc->y += npc->ym; + + RECT rect_left[5]; + RECT rect_right[5]; + + rect_left[0] = {96, 80, 128, 112}; + rect_left[1] = {128, 80, 160, 112}; + rect_left[2] = {160, 80, 192, 112}; + rect_left[3] = {192, 80, 224, 112}; + rect_left[4] = {224, 80, 256, 112}; + + rect_right[0] = {96, 112, 128, 144}; + rect_right[1] = {128, 112, 160, 144}; + rect_right[2] = {160, 112, 192, 144}; + rect_right[3] = {192, 112, 224, 144}; + rect_right[4] = {224, 112, 256, 144}; + + if (npc->shock) + { + npc->ani_no = 4; + } + else + { + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + } + + if (npc->direct == 0) + npc->rect = rect_left[npc->ani_no]; + else + npc->rect = rect_right[npc->ani_no]; +} + //Basu (Egg Corridor) void ActNpc058(NPCHAR *npc) { diff --git a/src/NpcAct120.cpp b/src/NpcAct120.cpp index 034b550f..38efcf16 100644 --- a/src/NpcAct120.cpp +++ b/src/NpcAct120.cpp @@ -9,6 +9,9 @@ #include "Back.h" #include "Triangle.h" #include "Caret.h" +#include "KeyControl.h" +#include "Frame.h" +#include "Bullet.h" //Colon (1) void ActNpc120(NPCHAR *npc) @@ -339,6 +342,58 @@ void ActNpc123(NPCHAR *npc) npc->rect = rect[npc->direct]; } +//Sunstone +void ActNpc124(NPCHAR *npc) +{ + RECT rect[2]; + + rect[0] = {160, 0, 192, 32}; + rect[1] = {192, 0, 224, 32}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->x += 0x1000; + npc->y += 0x1000; + // Fallthrough + case 1: + npc->bits &= ~8; + npc->ani_no = 0; + break; + + case 10: + npc->act_no = 11; + npc->ani_no = 1; + npc->act_wait = 0; + npc->bits |= 8; + // Fallthrough + case 11: + switch (npc->direct) + { + case 0: + npc->x -= 0x80; + break; + case 1: + npc->y -= 0x80; + break; + case 2: + npc->x += 0x80; + break; + case 3: + npc->y += 0x80; + break; + } + if (++npc->act_wait % 8 == 0) + PlaySoundObject(26, 1); + + SetQuake(20); + break; + } + + npc->rect = rect[npc->ani_no]; +} + //Hidden item void ActNpc125(NPCHAR *npc) { @@ -366,6 +421,137 @@ void ActNpc125(NPCHAR *npc) npc->rect = rc[1]; } +//Puppy (running) +void ActNpc126(NPCHAR *npc) +{ + RECT rcLeft[6]; + RECT rcRight[6]; + + rcLeft[0] = {48, 144, 64, 160}; + rcLeft[1] = {64, 144, 80, 160}; + rcLeft[2] = {48, 144, 64, 160}; + rcLeft[3] = {80, 144, 96, 160}; + rcLeft[4] = {96, 144, 112, 160}; + rcLeft[5] = {112, 144, 128, 160}; + + rcRight[0] = {48, 160, 64, 176}; + rcRight[1] = {64, 160, 80, 176}; + rcRight[2] = {48, 160, 64, 176}; + rcRight[3] = {80, 160, 96, 176}; + rcRight[4] = {96, 160, 112, 176}; + rcRight[5] = {112, 160, 128, 176}; + + 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 - 0xC000 && gMC.x < npc->x + 0xC000 && gMC.y > npc->y - 0x4000 && gMC.y < npc->y + 0x2000) + { + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + 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 = 2; + else + npc->direct = 0; + + npc->act_no = 10; + } + + break; + + case 2: + if (++npc->act_wait > 8) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + + case 10: + npc->act_no = 11; + npc->ani_no = 4; + npc->ani_wait = 0; + // Fallthrough + case 11: + if (npc->flag & 8) + { + if (++npc->ani_wait > 2) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 5) + npc->ani_no = 4; + } + else + { + npc->ani_no = 5; + npc->ani_wait = 0; + } + + if (npc->xm < 0 && npc->flag & 1) + { + npc->xm /= -2; + npc->direct = 2; + } + + if (npc->xm > 0 && npc->flag & 4) + { + npc->xm /= -2; + npc->direct = 0; + } + + if (npc->direct == 0) + npc->xm -= 0x40; + else + npc->xm += 0x40; + + if (npc->xm > 0x5FF) + npc->xm = 0x400; + + if (npc->xm < -0x5FF) + npc->xm = -0x400; + + break; + } + + if (gKeyTrg & gKeyDown) + npc->bits |= 0x2000; + else + npc->bits &= ~0x2000; + + 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]; +} + //Machine gun trail (Level 2) void ActNpc127(NPCHAR *npc) { @@ -490,3 +676,741 @@ void ActNpc129(NPCHAR *npc) npc->rect = rect[npc->ani_no + 3 * npc->direct]; } + +//Puppy (sitting, wagging tail) +void ActNpc130(NPCHAR *npc) +{ + RECT rcLeft[4]; + RECT rcRight[4]; + + rcLeft[0] = {48, 144, 64, 160}; + rcLeft[1] = {64, 144, 80, 160}; + rcLeft[2] = {48, 144, 64, 160}; + rcLeft[3] = {80, 144, 96, 160}; + + rcRight[0] = {48, 160, 64, 176}; + rcRight[1] = {64, 160, 80, 176}; + rcRight[2] = {48, 160, 64, 176}; + rcRight[3] = {80, 160, 96, 176}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->ani_no = 0; + npc->ani_wait = 0; + npc->bits |= 0x2000; + // 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; + } + + if (gMC.x > npc->x - 0xC000 && gMC.x < npc->x + 0xC000 && 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; + } + + 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]; +} + +//Puppy (sleeping) +void ActNpc131(NPCHAR *npc) +{ + RECT rcLeft[1]; + RECT rcRight[1]; + + rcLeft[0] = {144, 144, 160, 160}; + rcRight[0] = {144, 160, 160, 176}; + + if (++npc->act_wait > 100) + { + npc->act_wait = 0; + SetCaret(npc->x, npc->y, 5, 0); + } + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Puppy (barking) +void ActNpc132(NPCHAR *npc) +{ + RECT rcLeft[5]; + RECT rcRight[5]; + + rcLeft[0] = {48, 144, 64, 160}; + rcLeft[1] = {64, 144, 80, 160}; + rcLeft[2] = {96, 144, 112, 160}; + rcLeft[3] = {96, 144, 112, 160}; + rcLeft[4] = {128, 144, 144, 160}; + + rcRight[0] = {48, 160, 64, 176}; + rcRight[1] = {64, 160, 80, 176}; + rcRight[2] = {96, 160, 112, 176}; + rcRight[3] = {96, 160, 112, 176}; + rcRight[4] = {128, 160, 144, 176}; + + if (npc->act_no < 100) + { + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + 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 - 0x2000 && gMC.y < npc->y + 0x2000) + { + if (++npc->ani_wait > 4) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 4) + npc->ani_no = 2; + + if (npc->ani_no == 4 && npc->ani_wait == 0) + PlaySoundObject(105, 1); + } + else + { + if (npc->ani_no == 4) + npc->ani_no = 2; + } + + break; + + case 2: + if (++npc->act_wait > 8) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + + case 10: + npc->act_no = 11; + npc->ani_no = 0; + npc->ani_wait = 0; + // Fallthrough + case 11: + if (Random(0, 120) == 10) + { + npc->act_no = 12; + npc->act_wait = 0; + npc->ani_no = 1; + } + + break; + + case 12: + if (++npc->act_wait > 8) + { + npc->act_no = 11; + npc->ani_no = 0; + } + + break; + + case 100: + npc->act_no = 101; + npc->count1 = 0; + // Fallthrough + case 101: + if (++npc->ani_wait > 4) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 4) + { + if (npc->count1 < 3) + { + npc->ani_no = 2; + ++npc->count1; + } + else + { + npc->ani_no = 0; + npc->count1 = 0; + } + } + + if (npc->ani_no == 4 && npc->ani_wait == 0) + PlaySoundObject(105, 1); + + break; + + case 120: + npc->ani_no = 0; + break; + } + + 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]; +} + +//Jenka +void ActNpc133(NPCHAR *npc) +{ + RECT rcLeft[2]; + RECT rcRight[2]; + + rcLeft[0] = {176, 32, 192, 48}; + rcLeft[1] = {192, 32, 208, 48}; + + rcRight[0] = {176, 48, 192, 64}; + rcRight[1] = {192, 48, 208, 64}; + + 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; + } + + break; + + case 2: + if (++npc->act_wait > 8) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + } + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Armadillo +void ActNpc134(NPCHAR *npc) +{ + RECT rcLeft[3]; + RECT rcRight[3]; + + rcLeft[0] = {224, 0, 256, 16}; + rcLeft[1] = {256, 0, 288, 16}; + rcLeft[2] = {288, 0, 320, 16}; + + rcRight[0] = {224, 16, 256, 32}; + rcRight[1] = {256, 16, 288, 32}; + rcRight[2] = {288, 16, 320, 32}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->ani_no = 2; + npc->bits &= ~0x20; + npc->bits |= 4; + // Fallthrough + case 1: + if (gMC.x > npc->x - 0x28000 && gMC.x < npc->x + 0x28000 && gMC.y > npc->y - 0x14000 && gMC.y < npc->y + 0x8000) // TODO: Maybe do something about this for widescreen/tallscreen? + { + npc->act_no = 10; + npc->bits |= 0x20; + npc->bits &= ~4; + } + + break; + + case 10: + if (++npc->ani_wait > 4) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + + if (npc->direct == 0 && npc->flag & 1) + npc->direct = 2; + if (npc->direct == 2 && npc->flag & 4) + npc->direct = 0; + + if (npc->direct == 0) + npc->x -= 0x100; + else + npc->x += 0x100; + + if (CountArmsBullet(6)) + { + npc->act_no = 20; + npc->act_wait = 0; + npc->ani_no = 2; + npc->bits &= ~0x20; + npc->bits |= 4; + } + + break; + + case 20: + if (++npc->act_wait > 100) + { + npc->act_no = 10; + npc->ani_no = 0; + npc->ani_wait = 0; + npc->bits |= 0x20; + npc->bits &= ~4; + } + + 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]; +} + +//Skeleton +void ActNpc135(NPCHAR *npc) +{ + RECT rcRight[2]; + RECT rcLeft[2]; + + rcLeft[0] = {256, 32, 288, 64}; + rcLeft[1] = {288, 32, 320, 64}; + + rcRight[0] = {256, 64, 288, 96}; + rcRight[1] = {288, 64, 320, 96}; + + if (gMC.x < npc->x - 0x2C000 || gMC.x > npc->x + 0x2C000 || gMC.y < npc->y - 0x14000 || gMC.y > npc->y + 0x8000) + npc->act_no = 0; + + switch ( npc->act_no ) + { + case 0: + npc->act_no = 1; + npc->xm = 0; + // Fallthrough + case 1: + if (gMC.x > npc->x - 0x28000 && gMC.x < npc->x + 0x28000 && gMC.y > npc->y - 0x14000 && gMC.y < npc->y + 0x8000) + npc->act_no = 10; + + if (npc->flag & 8) + npc->ani_no = 0; + + break; + + case 10: + npc->xm = 0; + npc->act_no = 11; + npc->act_wait = 0; + npc->ani_no = 0; + // Fallthrough + case 11: + if (++npc->act_wait >= 5 && npc->flag & 8) + { + npc->act_no = 20; + npc->ani_no = 1; + npc->count1 = 0; + npc->ym = -0x200 * Random(1, 3); + + if (npc->shock == 0) + { + if (gMC.x > npc->x) + npc->xm += 0x100; + else + npc->xm -= 0x100; + } + else + { + if (gMC.x > npc->x) + npc->xm -= 0x100; + else + npc->xm += 0x100; + } + } + + break; + + case 20: + if (npc->ym > 0 && npc->count1 == 0) + { + ++npc->count1; + const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y + 0x800 - gMC.y); + const int ym = 2 * GetSin(deg); + const int xm = 2 * GetCos(deg); + SetNpChar(50, npc->x, npc->y, xm, ym, 0, 0, 0x180); + PlaySoundObject(39, 1); + } + + if (npc->flag & 8) + { + npc->act_no = 10; + npc->ani_no = 0; + } + + break; + } + + if (npc->act_no >= 10) + { + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + npc->ym += 0x33; + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + if (npc->xm > 0x5FF) + npc->xm = 0x5FF; + if (npc->xm < -0x5FF) + npc->xm = -0x5FF; + + npc->y += npc->ym; + npc->x += npc->xm; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Puppy (carried) +void ActNpc136(NPCHAR *npc) +{ + RECT rcLeft[2]; + RECT rcRight[2]; + + rcLeft[0] = {48, 144, 64, 160}; + rcLeft[1] = {64, 144, 80, 160}; + + rcRight[0] = {48, 160, 64, 176}; + rcRight[1] = {64, 160, 80, 176}; + + switch (npc->act_no) + { + case 0: + npc->bits &= ~0x2000; + 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; + } + + break; + + case 2: + if (++npc->act_wait > 8) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + } + + if (gMC.direct == 0) + npc->direct = 0; + else + npc->direct = 2; + + npc->y = gMC.y - 0x1400; + + if (npc->direct == 0) + { + npc->x = gMC.x + 0x800; + npc->rect = rcLeft[npc->ani_no]; + } + else + { + npc->x = gMC.x - 0x800; + npc->rect = rcRight[npc->ani_no]; + } + + if (gMC.ani_no % 2) + ++npc->rect.top; +} + +//Large door (frame) +void ActNpc137(NPCHAR *npc) +{ + RECT rc[1]; + + rc[0] = {96, 136, 128, 188}; + + npc->rect = rc[0]; +} + +//Large door (door) +void ActNpc138(NPCHAR *npc) +{ + RECT rcLeft[1]; + RECT rcRight[1]; + + rcLeft[0] = {96, 112, 112, 136}; + rcRight[0] = {112, 112, 128, 136}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + + if (npc->direct == 0) + { + npc->rect = rcLeft[0]; + npc->x += 0x1000; + } + else + { + npc->rect = rcRight[0]; + npc->x -= 0x1000; + } + + npc->tgt_x = npc->x; + break; + + case 10: + npc->act_no = 11; + npc->ani_no = 1; + npc->act_wait = 0; + npc->bits |= 8; + // Fallthrough + case 11: + if (++npc->act_wait % 8 == 0) + PlaySoundObject(26, 1); + + if (npc->direct == 0) + { + npc->rect = rcLeft[0]; + npc->rect.left += npc->act_wait / 8; + } + else + { + npc->x = npc->tgt_x + ((npc->act_wait / 8) * 0x200); + npc->rect = rcRight[0]; + npc->rect.right -= npc->act_wait / 8; + } + + if (npc->act_wait == 104) + npc->cond = 0; + + break; + } +} + +//Doctor +void ActNpc139(NPCHAR *npc) +{ + RECT rcLeft[3]; + RECT rcRight[3]; + + rcLeft[0] = {0, 128, 24, 160}; + rcLeft[1] = {24, 128, 48, 160}; + rcLeft[2] = {48, 128, 72, 160}; + + rcRight[0] = {0, 160, 24, 192}; + rcRight[1] = {24, 160, 48, 192}; + rcRight[2] = {48, 160, 72, 192}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->xm = 0; + npc->ym = 0; + npc->y -= 0x1000; + // Fallthrough + case 1: + if (npc->flag & 8) + npc->ani_no = 0; + else + npc->ani_no = 2; + + npc->ym += 0x40; + break; + + case 10: + npc->act_no = 11; + npc->ani_no = 1; + npc->ani_wait = 0; + npc->count1 = 0; + // Fallthrough + case 11: + if (++npc->ani_wait > 6) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + { + npc->ani_no = 0; + ++npc->count1; + } + + if (npc->count1 > 8) + { + npc->ani_no = 0; + npc->act_no = 1; + } + + break; + + case 20: + npc->act_no = 21; + npc->act_wait = 0; + npc->ani_no = 2; + npc->tgt_y = npc->y - 0x4000; + // Fallthrough + case 21: + if (npc->y < npc->tgt_y) + npc->ym += 0x20; + else + npc->ym -= 0x20; + + if (npc->ym > 0x200) + npc->ym = 0x200; + if (npc->ym < -0x200) + npc->ym = -0x200; + + break; + + case 30: + npc->act_no = 31; + npc->xm = 0; + npc->ym = 0; + npc->act_wait = 2 * (npc->rect.bottom - npc->rect.top); + PlaySoundObject(29, 1); + // Fallthrough + case 31: + --npc->act_wait; + npc->ani_no = 0; + + if (npc->act_wait == 0) + npc->cond = 0; + + break; + + case 40: + npc->act_no = 41; + npc->act_wait = 0; + npc->xm = 0; + npc->ym = 0; + PlaySoundObject(29, 1); + // Fallthrough + case 41: + npc->ani_no = 2; + + if (++npc->act_wait >= 64) + npc->act_no = 20; + + break; + } + + 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 == 31 || npc->act_no == 41) + { + npc->rect.bottom = npc->rect.top + npc->act_wait / 2; + + if (npc->act_wait / 2 % 2) + ++npc->rect.left; + } +} diff --git a/src/NpcAct140.cpp b/src/NpcAct140.cpp index 125c4d5b..d670e6de 100644 --- a/src/NpcAct140.cpp +++ b/src/NpcAct140.cpp @@ -8,6 +8,653 @@ #include "Sound.h" #include "Back.h" #include "Triangle.h" +#include "Caret.h" +#include "Frame.h" +#include "Flash.h" +#include "Bullet.h" + +//Toroko (frenzied) +void ActNpc140(NPCHAR *npc) +{ + RECT rcLeft[14]; + RECT rcRight[14]; + + rcLeft[0] = {0, 0, 32, 32}; + rcLeft[1] = {32, 0, 64, 32}; + rcLeft[2] = {64, 0, 96, 32}; + rcLeft[3] = {96, 0, 128, 32}; + rcLeft[4] = {128, 0, 160, 32}; + rcLeft[5] = {160, 0, 192, 32}; + rcLeft[6] = {192, 0, 224, 32}; + rcLeft[7] = {224, 0, 256, 32}; + rcLeft[8] = {0, 64, 32, 96}; + rcLeft[9] = {32, 64, 64, 96}; + rcLeft[10] = {64, 64, 96, 96}; + rcLeft[11] = {96, 64, 128, 96}; + rcLeft[12] = {128, 64, 160, 96}; + rcLeft[13] = {0, 0, 0, 0}; + + rcRight[0] = {0, 32, 32, 64}; + rcRight[1] = {32, 32, 64, 64}; + rcRight[2] = {64, 32, 96, 64}; + rcRight[3] = {96, 32, 128, 64}; + rcRight[4] = {128, 32, 160, 64}; + rcRight[5] = {160, 32, 192, 64}; + rcRight[6] = {192, 32, 224, 64}; + rcRight[7] = {224, 32, 256, 64}; + rcRight[8] = {0, 96, 32, 128}; + rcRight[9] = {32, 96, 64, 128}; + rcRight[10] = {64, 96, 96, 128}; + rcRight[11] = {96, 96, 128, 128}; + rcRight[12] = {128, 96, 160, 128}; + rcRight[13] = {0, 0, 0, 0}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->ani_no = 9; + npc->act_wait = 0; + npc->bits &= ~0x2000; + // Fallthrough + case 1: + if (++npc->act_wait > 50) + { + npc->act_no = 2; + npc->act_wait = 0; + npc->ani_no = 8; + } + + break; + + case 2: + if (++npc->ani_no > 10) + npc->ani_no = 9; + + if (++npc->act_wait > 50) + { + npc->act_no = 3; + npc->act_wait = 0; + npc->ani_no = 0; + } + + break; + + case 3: + if (++npc->act_wait > 50) + { + npc->act_no = 10; + npc->bits |= 0x20; + } + + break; + + case 10: + npc->bits = npc->bits; + npc->act_no = 11; + npc->ani_no = 0; + npc->ani_wait = 0; + npc->act_wait = Random(20, 130); + npc->xm = 0; + // Fallthrough + case 11: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (++npc->ani_wait > 4) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + + if (CountArmsBullet(6) || CountArmsBullet(3) > 3) + npc->act_no = 20; + + if (npc->act_wait) + { + --npc->act_wait; + } + else + { + if (Random(0, 99) % 2) + npc->act_no = 20; + else + npc->act_no = 50; + } + + break; + + case 20: + npc->act_no = 21; + npc->ani_no = 2; + npc->act_wait = 0; + // Fallthrough + case 21: + if (++npc->act_wait > 10) + { + npc->act_no = 22; + npc->act_wait = 0; + npc->ani_no = 3; + npc->ym = -0x5FF; + + if (npc->direct == 0) + npc->xm = -0x200u; + else + npc->xm = 0x200; + } + + break; + + case 22: + if (++npc->act_wait > 10) + { + npc->act_no = 23; + npc->act_wait = 0; + npc->ani_no = 6; + SetNpChar(141, 0, 0, 0, 0, 0, npc, 0); + } + + break; + + case 23: + if (++npc->act_wait > 30) + { + npc->act_no = 24; + npc->act_wait = 0; + npc->ani_no = 7; + } + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + break; + + case 24: + if (++npc->act_wait > 3) + { + npc->act_no = 25; + npc->ani_no = 3; + } + + break; + + case 25: + if (npc->flag & 8) + { + npc->act_no = 26; + npc->act_wait = 0; + npc->ani_no = 2; + PlaySoundObject(26, 1); + SetQuake(20); + } + + break; + + case 26: + npc->xm = 8 * npc->xm / 9; + + if (++npc->act_wait > 20) + { + npc->act_no = 10; + npc->ani_no = 0; + } + + break; + + case 50: + npc->act_no = 51; + npc->act_wait = 0; + npc->ani_no = 4; + SetNpChar(141, 0, 0, 0, 0, 0, npc, 0); + // Fallthrough + case 51: + if (++npc->act_wait > 30) + { + npc->act_no = 52; + npc->act_wait = 0; + npc->ani_no = 5; + } + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + break; + + case 52: + if (++npc->act_wait > 3) + { + npc->act_no = 10; + npc->ani_no = 0; + } + + break; + + case 100: + npc->ani_no = 3; + npc->act_no = 101; + npc->bits &= ~0x20; + 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(-0x600u, 0), 0, 0, 0x100); + + break; + + case 101: + if (npc->flag & 8) + { + npc->act_no = 102; + npc->act_wait = 0; + npc->ani_no = 2; + PlaySoundObject(26, 1); + SetQuake(20); + } + + break; + + case 102: + npc->xm = 8 * npc->xm / 9; + + if (++npc->act_wait > 50) + { + npc->act_no = 103; + npc->act_wait = 0; + npc->ani_no = 10; + } + + break; + + case 103: + if (++npc->act_wait > 50) + { + npc->ani_no = 9; + npc->act_no = 104; + npc->act_wait = 0; + } + + break; + + case 104: + if (++npc->ani_no > 10) + npc->ani_no = 9; + + if (++npc->act_wait > 100) + { + npc->act_wait = 0; + npc->ani_no = 9; + npc->act_no = 105; + } + + break; + + case 105: + if (++npc->act_wait > 50) + { + npc->ani_wait = 0; + npc->act_no = 106; + npc->ani_no = 11; + } + + break; + + case 106: + if (++npc->ani_wait > 50) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 12) + npc->ani_no = 12; + + break; + + case 140: + npc->act_no = 141; + npc->act_wait = 0; + npc->ani_no = 12; + PlaySoundObject(29, 1); + // Fallthrough + case 141: + if (++npc->ani_no > 13) + npc->ani_no = 12; + + if (++npc->act_wait > 100) + { + 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->cond = 0; + } + + break; + } + + if (npc->act_no > 100 && npc->act_no < 105 && npc->act_wait % 9 == 0) + SetNpChar(4, npc->x + (Random(-12, 12) * 0x200), npc->y + (Random(-12, 12) * 0x200), Random(-341, 341), Random(-0x600, 0), 0, 0, 0x100); + + npc->ym += 0x20; + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + 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]; +} + +// Toroko block projectile +void ActNpc141(NPCHAR *npc) +{ + RECT rect[2]; // [sp+8h] [bp-24h]@1 + + rect[0] = {288, 32, 304, 48}; + rect[1] = {304, 32, 320, 48}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->act_wait = 0; + // Fallthrough + case 1: + if (npc->pNpc->direct == 0) + npc->x = npc->pNpc->x + 0x1400; + else + npc->x = npc->pNpc->x - 0x1400; + + npc->y = npc->pNpc->y - 0x1000; + + if (npc->pNpc->act_no == 24 || npc->pNpc->act_no == 52) + { + npc->act_no = 10; + + if (npc->pNpc->direct == 0) + npc->x = npc->pNpc->x - 0x2000; + else + npc->x = npc->pNpc->x + 0x2000; + + npc->y = npc->pNpc->y; + + const unsigned char deg = GetArktan(npc->x - gMC.x, npc->y - gMC.y); + npc->ym = 4 * GetSin(deg); + npc->xm = 4 * GetCos(deg); + + PlaySoundObject(39, 1); + } + + break; + + case 10: + if (npc->flag & 0xF) + { + npc->act_no = 20; + npc->act_wait = 0; + SetCaret(npc->x, npc->y, 2, 0); + PlaySoundObject(12, 1); + + for (int i = 0; i < 4; ++i) + SetNpChar(4, npc->x, npc->y, Random(-0x200, 0x200), Random(-0x200, 0x200), 0, 0, 0x100); + } + else + { + npc->x += npc->xm; + npc->y += npc->ym; + } + + break; + + case 20: + npc->x += npc->xm; + npc->y += npc->ym; + + if (++npc->act_wait > 4) + { + for (int i = 0; i < 4; ++i) + SetNpChar(4, npc->x, npc->y, Random(-0x200, 0x200), Random(-0x200, 0x200), 0, 0, 0x100); + + npc->code_char = 142; + npc->ani_no = 0; + npc->act_no = 20; + npc->xm = 0; + npc->bits &= ~4; + npc->bits |= 0x20; + npc->damage = 1; + } + + break; + } + + if (++npc->ani_no > 1) + npc->ani_no = 0; + + npc->rect = rect[npc->ani_no]; +} + +// Flower Cub +void ActNpc142(NPCHAR *npc) +{ + RECT rect[5]; + + rect[0] = {0, 128, 16, 144}; + rect[1] = {16, 128, 32, 144}; + rect[2] = {32, 128, 48, 144}; + rect[3] = {48, 128, 64, 144}; + rect[4] = {64, 128, 80, 144}; + + switch (npc->act_no) + { + case 10: + npc->act_no = 11; + npc->ani_no = 0; + npc->act_wait = 0; + // Fallthrough + case 11: + if (++npc->act_wait > 30) + { + npc->act_no = 12; + npc->ani_no = 1; + npc->ani_wait = 0; + } + + break; + + case 12: + if (++npc->ani_wait > 8) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no == 3) + { + npc->act_no = 20; + npc->ym = -0x200; + + if (gMC.x < npc->x) + npc->xm = -0x200; + else + npc->xm = 0x200; + } + + break; + + case 20: + if (npc->ym > -0x80) + npc->ani_no = 4; + else + npc->ani_no = 3; + + if (npc->flag & 8) + { + npc->ani_no = 2; + npc->act_no = 21; + npc->act_wait = 0; + npc->xm = 0; + PlaySoundObject(23, 1); + } + + break; + + case 21: + if (++npc->act_wait > 10) + { + npc->act_no = 10; + npc->ani_no = 0; + } + + break; + } + + npc->ym += 0x40; + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + if (npc->ym < -0x5FF) + npc->ym = -0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + npc->rect = rect[npc->ani_no]; +} + +// Jenka (collapsed) +void ActNpc143(NPCHAR *npc) +{ + RECT rcLeft[1]; + RECT rcRight[1]; + + rcLeft[0] = {208, 32, 224, 48}; + + rcRight[0] = {208, 48, 224, 64}; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Toroko (teleporting in) +void ActNpc144(NPCHAR *npc) +{ + RECT rcLeft[5]; + RECT rcRight[5]; + + rcLeft[0] = {0, 64, 16, 80}; + rcLeft[1] = {16, 64, 32, 80}; + rcLeft[2] = {32, 64, 48, 80}; + rcLeft[3] = {16, 64, 32, 80}; + rcLeft[4] = {128, 64, 144, 80}; + + rcRight[0] = {0, 80, 16, 96}; + rcRight[1] = {16, 80, 32, 96}; + rcRight[2] = {32, 80, 48, 96}; + rcRight[3] = {16, 80, 32, 96}; + rcRight[4] = {128, 80, 144, 96}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->ani_no = 0; + npc->ani_wait = 0; + npc->tgt_x = npc->x; + PlaySoundObject(29, 1); + // Fallthrough + case 1: + if (++npc->act_wait == 64) + { + npc->act_no = 2; + npc->act_wait = 0; + } + + break; + + case 2: + if (++npc->ani_wait > 2) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 3) + npc->ani_no = 2; + + if (npc->flag & 8) + { + npc->act_no = 4; + npc->act_wait = 0; + npc->ani_no = 4; + PlaySoundObject(23, 1); + } + + break; + + case 10: + npc->act_no = 11; + npc->ani_no = 0; + npc->ani_wait = 0; + // Fallthrough + case 11: + if (Random(0, 120) == 10) + { + npc->act_no = 12; + npc->act_wait = 0; + npc->ani_no = 1; + } + + break; + + case 12: + if (++npc->act_wait > 8) + { + npc->act_no = 11; + npc->ani_no = 0; + } + + break; + } + + if (npc->act_no > 1) + { + npc->ym += 0x20; + 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]; + + if (npc->act_no == 1) + { + npc->rect.bottom = npc->rect.top + npc->act_wait / 4; + + if (npc->act_wait / 2 % 2) + npc->x = npc->tgt_x; + else + npc->x = npc->tgt_x + 0x200; + } +} //King's sword void ActNpc145(NPCHAR *npc) @@ -49,6 +696,56 @@ void ActNpc145(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Lightning +void ActNpc146(NPCHAR *npc) +{ + RECT rect[5]; + + rect[0] = {0, 0, 0, 0}; + rect[1] = {256, 0, 272, 240}; + rect[2] = {272, 0, 288, 240}; + rect[3] = {288, 0, 304, 240}; + rect[4] = {304, 0, 320, 240}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + + if (npc->direct == 2) + SetFlash(0, 0, 2); + // Fallthrough + case 1: + if (++npc->act_wait > 10) + { + npc->act_no = 2; + PlaySoundObject(101, 1); + } + + break; + + case 2: + if (++npc->ani_wait > 2) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no == 2) + npc->damage = 10; + + if (npc->ani_no > 4) + { + SetDestroyNpChar(npc->x, npc->y, 0x1000, 8); + npc->cond = 0; + } + + break; + } + + npc->rect = rect[npc->ani_no]; +} + //Quote void ActNpc150(NPCHAR *npc) { diff --git a/src/NpcAct280.cpp b/src/NpcAct280.cpp index 583e4c9d..8e7119bb 100644 --- a/src/NpcAct280.cpp +++ b/src/NpcAct280.cpp @@ -8,6 +8,13 @@ #include "Sound.h" #include "Back.h" #include "Triangle.h" +#include "Frame.h" + +//Quake +void ActNpc292(NPCHAR *npc) +{ + SetQuake(10); +} //Doctor (opening) void ActNpc298(NPCHAR *npc) diff --git a/src/NpcAct300.cpp b/src/NpcAct300.cpp index fae6fa90..99035e2f 100644 --- a/src/NpcAct300.cpp +++ b/src/NpcAct300.cpp @@ -9,6 +9,7 @@ #include "Back.h" #include "Triangle.h" #include "Caret.h" +#include "Boss.h" //Demon crown (opening) void ActNpc300(NPCHAR *npc) @@ -30,3 +31,71 @@ void ActNpc300(NPCHAR *npc) npc->rect = rc[0]; } + +//Camera focus marker +void ActNpc302(NPCHAR *npc) +{ + switch (npc->act_no) + { + case 10: + npc->x = gMC.x; + npc->y = gMC.y - 0x4000; + break; + + case 20: + switch (npc->direct) + { + case 0: + npc->x -= 0x400; + break; + case 1: + npc->y -= 0x400; + break; + case 2: + npc->x += 0x400; + break; + case 3: + npc->y += 0x400; + break; + } + + gMC.x = npc->x; + gMC.y = npc->y; + break; + + case 30: + npc->x = gMC.x; + npc->y = gMC.y + 0xA000; + break; + + case 100: + npc->act_no = 101; + + if (npc->direct) + { + int i; + for (i = 0xAA; i < 0x200; ++i) + { + if (gNPC[i].cond & 0x80 && gNPC[i].code_event == npc->direct) + { + npc->pNpc = &gNPC[i]; + break; + } + } + if (i == 0x200) + { + npc->cond = 0; + break; + } + } + else + { + npc->pNpc = gBoss; + } + // Fallthrough + case 101: + npc->x = (npc->pNpc->x + gMC.x) / 2; + npc->y = (npc->pNpc->y + gMC.y) / 2; + break; + } +} diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index d14dbbcb..2a4eadfe 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -100,20 +100,20 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc041, ActNpc042, ActNpc043, - nullptr, - nullptr, + ActNpc044, + ActNpc045, ActNpc046, - nullptr, + ActNpc047, ActNpc048, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, + ActNpc049, + ActNpc050, + ActNpc051, + ActNpc052, + ActNpc053, + ActNpc054, ActNpc055, ActNpc056, - nullptr, + ActNpc057, ActNpc058, ActNpc059, ActNpc060, @@ -180,29 +180,29 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc121, ActNpc122, ActNpc123, - nullptr, + ActNpc124, ActNpc125, - nullptr, + ActNpc126, ActNpc127, ActNpc128, ActNpc129, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, + ActNpc130, + ActNpc131, + ActNpc132, + ActNpc133, + ActNpc134, + ActNpc135, + ActNpc136, + ActNpc137, + ActNpc138, + ActNpc139, + ActNpc140, + ActNpc141, + ActNpc142, + ActNpc143, + ActNpc144, ActNpc145, - nullptr, + ActNpc146, nullptr, nullptr, nullptr, @@ -348,7 +348,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = nullptr, nullptr, nullptr, - nullptr, + ActNpc292, nullptr, nullptr, nullptr, @@ -358,7 +358,7 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc299, ActNpc300, nullptr, - nullptr, + ActNpc302, nullptr, nullptr, nullptr,