diff --git a/src/NpcAct.h b/src/NpcAct.h index 71e20c34..680cc57b 100644 --- a/src/NpcAct.h +++ b/src/NpcAct.h @@ -258,11 +258,21 @@ void ActNpc252(NPCHAR *npc); void ActNpc253(NPCHAR *npc); void ActNpc254(NPCHAR *npc); void ActNpc255(NPCHAR *npc); - +void ActNpc256(NPCHAR *npc); +void ActNpc257(NPCHAR *npc); +void ActNpc258(NPCHAR *npc); void ActNpc259(NPCHAR *npc); - +void ActNpc260(NPCHAR *npc); +void ActNpc261(NPCHAR *npc); +void ActNpc262(NPCHAR *npc); +void ActNpc263(NPCHAR *npc); +void ActNpc264(NPCHAR *npc); +void ActNpc265(NPCHAR *npc); +void ActNpc266(NPCHAR *npc); +void ActNpc267(NPCHAR *npc); void ActNpc268(NPCHAR *npc); - +void ActNpc269(NPCHAR *npc); +void ActNpc270(NPCHAR *npc); void ActNpc271(NPCHAR *npc); void ActNpc272(NPCHAR *npc); void ActNpc273(NPCHAR *npc); diff --git a/src/NpcAct240.cpp b/src/NpcAct240.cpp index b78e534d..abe8b140 100644 --- a/src/NpcAct240.cpp +++ b/src/NpcAct240.cpp @@ -1193,6 +1193,167 @@ void ActNpc255(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Doctor (facing away) +void ActNpc256(NPCHAR *npc) +{ + RECT rcLeft[6]; + + rcLeft[0] = {48, 160, 72, 192}; + rcLeft[1] = {72, 160, 96, 192}; + rcLeft[2] = {0, 128, 24, 160}; + rcLeft[3] = {24, 128, 48, 160}; + rcLeft[4] = {0, 160, 24, 192}; + rcLeft[5] = {24, 160, 48, 192}; + + switch ( npc->act_no ) + { + case 0: + gSuperXpos = 0; + npc->act_no = 1; + npc->y -= 0x1000; + // Fallthrough + case 1: + npc->ani_no = 0; + break; + + case 10: + npc->act_no = 11; + npc->ani_wait = 0; + npc->ani_no = 0; + npc->count1 = 0; + // Fallthrough + case 11: + if (++npc->ani_wait > 5) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + { + npc->ani_no = 0; + ++npc->count1; + } + + if (npc->count1 > 5) + npc->act_no = 1; + + break; + + case 20: + npc->act_no = 21; + // Fallthrough + case 21: + npc->ani_no = 2; + break; + + case 40: + npc->act_no = 41; + SetNpChar(257, npc->x - 0x1C00, npc->y - 0x2000, 0, 0, 0, 0, 0x100); + SetNpChar(257, npc->x - 0x1C00, npc->y - 0x2000, 0, 0, 2, 0, 0xAA); + // Fallthrough + case 41: + npc->ani_no = 4; + break; + + case 50: + npc->act_no = 51; + npc->ani_wait = 0; + npc->ani_no = 4; + npc->count1 = 0; + // Fallthrough + case 51: + if (++npc->ani_wait > 5) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 5) + { + npc->ani_no = 4; + ++npc->count1; + } + + if (npc->count1 > 5) + npc->act_no = 41; + + break; + } + + npc->rect = rcLeft[npc->ani_no]; +} + +//Red crystal +void ActNpc257(NPCHAR *npc) +{ + RECT rc[3]; + + rc[0] = {176, 32, 184, 48}; + rc[1] = {184, 32, 192, 48}; + rc[2] = {0, 0, 0, 0}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + // Fallthrough + case 1: + if (gSuperXpos) + npc->act_no = 10; + + break; + + case 10: + if (npc->x < gSuperXpos) + npc->xm += 0x55; + if (npc->x > gSuperXpos) + npc->xm -= 0x55; + + if (npc->y < gSuperYpos) + npc->ym += 0x55; + if (npc->y > gSuperYpos) + npc->ym -= 0x55; + + if (npc->xm > 0x400) + npc->xm = 0x400; + if (npc->xm < -0x400) + npc->xm = -0x400; + + if (npc->ym > 0x400) + npc->ym = 0x400; + if (npc->ym < -0x400) + npc->ym = -0x400; + + npc->x += npc->xm; + npc->y += npc->ym; + break; + } + + if (++npc->ani_wait > 3) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 1) + npc->ani_no = 0; + + if (npc->direct == 0 && npc->xm > 0) + npc->ani_no = 2; + if (npc->direct == 2 && npc->xm < 0) + npc->ani_no = 2; + + npc->rect = rc[npc->ani_no]; +} + +//Mimiga (sleeping) +void ActNpc258(NPCHAR *npc) +{ + RECT rc = {48, 32, 64, 48}; + npc->rect = rc; +} + //Curly (carried and unconcious) void ActNpc259(NPCHAR *npc) { diff --git a/src/NpcAct260.cpp b/src/NpcAct260.cpp index a0a5e72a..9c3f4afa 100644 --- a/src/NpcAct260.cpp +++ b/src/NpcAct260.cpp @@ -11,6 +11,1098 @@ #include "Caret.h" #include "Map.h" #include "Frame.h" +#include "MycParam.h" + +//Shovel Brigade (caged) +void ActNpc260(NPCHAR *npc) +{ + RECT rcLeft[3]; + RECT rcRight[3]; + + rcLeft[0] = {128, 64, 144, 80}; + rcLeft[1] = {144, 64, 160, 80}; + rcLeft[2] = {224, 64, 240, 80}; + + rcRight[0] = {128, 80, 144, 96}; + rcRight[1] = {144, 80, 160, 96}; + rcRight[2] = {224, 80, 240, 96}; + + switch (npc->act_no) + { + case 0: + npc->x += 0x200; + npc->y -= 0x400; + npc->act_no = 1; + npc->ani_no = 0; + npc->ani_wait = 0; + // Fallthrough + case 1: + if (Random(0, 160) == 1) + { + npc->act_no = 2; + npc->act_wait = 0; + npc->ani_no = 1; + } + + break; + + case 2: + if (++npc->act_wait > 12) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + + case 10: + npc->act_no = 11; + npc->ani_no = 2; + SetNpChar(87, npc->x, npc->y - 0x2000, 0, 0, 0, 0, 0x100); + + break; + } + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Chie (caged) +void ActNpc261(NPCHAR *npc) +{ + RECT rcLeft[2]; + RECT rcRight[2]; + + rcLeft[0] = {112, 32, 128, 48}; + rcLeft[1] = {128, 32, 144, 48}; + + rcRight[0] = {112, 48, 128, 64}; + rcRight[1] = {128, 48, 144, 64}; + + switch (npc->act_no) + { + case 0: + npc->x -= 0x200; + npc->y -= 0x400; + npc->act_no = 1; + npc->ani_no = 0; + npc->ani_wait = 0; + // Fallthrough + case 1: + if (Random(0, 160) == 1) + { + npc->act_no = 2; + npc->act_wait = 0; + npc->ani_no = 1; + } + + break; + + case 2: + if (++npc->act_wait > 12 ) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + } + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Chaco (caged) +void ActNpc262(NPCHAR *npc) +{ + RECT rcLeft[2]; + RECT rcRight[2]; + + rcLeft[0] = {128, 0, 144, 16}; + rcLeft[1] = {144, 0, 160, 16}; + + rcRight[0] = {128, 16, 144, 32}; + rcRight[1] = {144, 16, 160, 32}; + + switch (npc->act_no) + { + case 0: + npc->x -= 0x200; + npc->y -= 0x400; + npc->act_no = 1; + npc->ani_no = 0; + npc->ani_wait = 0; + // Fallthrough + case 1: + if (Random(0, 160) == 1) + { + npc->act_no = 2; + npc->act_wait = 0; + npc->ani_no = 1; + } + + break; + + case 2: + if (++npc->act_wait > 12) + { + npc->act_no = 1; + npc->ani_no = 0; + } + + break; + } + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Doctor (boss) +void ActNpc263(NPCHAR *npc) +{ + RECT rcLeft[9]; + RECT rcRight[9]; + + rcLeft[0] = {0, 0, 24, 32}; + rcLeft[1] = {24, 0, 48, 32}; + rcLeft[2] = {48, 0, 72, 32}; + rcLeft[3] = {0, 0, 0, 0}; + rcLeft[4] = {72, 0, 96, 32}; + rcLeft[5] = {96, 0, 120, 32}; + rcLeft[6] = {120, 0, 144, 32}; + rcLeft[7] = {144, 0, 168, 32}; + rcLeft[8] = {264, 0, 288, 32}; + + rcRight[0] = {0, 32, 24, 64}; + rcRight[1] = {24, 32, 48, 64}; + rcRight[2] = {48, 32, 72, 64}; + rcRight[3] = {0, 0, 0, 0}; + rcRight[4] = {72, 32, 96, 64}; + rcRight[5] = {96, 32, 120, 64}; + rcRight[6] = {120, 32, 144, 64}; + rcRight[7] = {144, 32, 168, 64}; + rcRight[8] = {264, 32, 288, 64}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->y += 0x1000; + npc->ani_no = 3; + break; + + case 2: + if (++npc->act_wait / 2 & 1) + npc->ani_no = 0; + else + npc->ani_no = 3; + + if (npc->act_wait > 50) + npc->act_no = 10; + + break; + + case 10: + npc->ym += 0x80; + npc->bits |= 0x20; + npc->damage = 3; + + if (npc->flag & 8) + { + npc->act_no = 20; + npc->act_wait = 0; + npc->ani_no = 0; + npc->count2 = npc->life; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + + case 20: + if (++npc->act_wait < 50 && npc->life < npc->count2 - 20) + npc->act_wait = 50; + + if (npc->act_wait == 50) + { + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + npc->ani_no = 4; + } + + if (npc->act_wait == 80) + { + npc->ani_no = 5; + PlaySoundObject(25, 1); + + if (npc->direct == 0) + { + SetNpChar(264, npc->x - 0x2000, npc->y, 0, 0, 0, 0, 0x100); + SetNpChar(264, npc->x - 0x2000, npc->y, 0, 0, 0x400, 0, 0x100); + } + else + { + SetNpChar(264, npc->x + 0x2000, npc->y, 0, 0, 2, 0, 0x100); + SetNpChar(264, npc->x + 0x2000, npc->y, 0, 0, 2 + 0x400, 0, 0x100); + } + } + + if (npc->act_wait == 120) + npc->ani_no = 0; + + if (npc->act_wait > 130 && npc->life < npc->count2 - 50) + npc->act_wait = 161; + + if (npc->act_wait > 160) + { + npc->act_no = 100; + npc->ani_no = 0; + } + + break; + + case 30: + npc->act_no = 31; + npc->act_wait = 0; + npc->ani_no = 6; + npc->tgt_x = npc->x; + npc->bits |= 0x20; + // Fallthrough + case 31: + if (++npc->act_wait / 2 & 1) + npc->x = npc->tgt_x; + else + npc->x = npc->tgt_x + 0x200; + + if (npc->act_wait > 50) + { + npc->act_no = 32; + npc->act_wait = 0; + npc->ani_no = 7; + PlaySoundObject(101, 1); + + for (int deg = 8; deg < 0x100; deg += 0x10) + { + const int xm = 2 * GetCos(deg); + const int ym = 2 * GetSin(deg); + SetNpChar(266, npc->x, npc->y, xm, ym, 0, 0, 0x100); + } + } + + break; + + case 32: + if (++npc->act_wait > 50) + npc->act_no = 100; + + break; + + case 100: + npc->act_no = 101; + npc->bits &= ~0x20; + npc->damage = 0; + npc->act_wait = 0; + PlaySoundObject(29, 1); + // Fallthrough + case 101: + npc->act_wait += 2; + + if (npc->act_wait > 16) + { + npc->act_no = 102; + npc->act_wait = 0; + npc->ani_no = 3; + npc->tgt_x = Random(5, 35) * 0x2000; + npc->tgt_y = Random(5, 7) * 0x2000; + } + + break; + + case 102: + if (++npc->act_wait > 40 ) + { + npc->act_no = 103; + npc->act_wait = 16; + npc->ani_no = 2; + npc->ym = 0; + npc->x = npc->tgt_x; + npc->y = npc->tgt_y; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + + case 103: + npc->act_wait -= 2; + + if ( npc->act_wait <= 0 ) + { + npc->bits |= 0x20; + npc->damage = 3; + + if (npc->count1 < 3) + { + ++npc->count1; + npc->act_no = 10; + } + else + { + npc->count1 = 0; + npc->act_no = 30; + } + } + + break; + + case 500: + npc->bits &= ~0x20; + npc->ani_no = 6; + npc->ym += 0x10; + + if (npc->flag & 8) + { + npc->act_no = 501; + npc->act_wait = 0; + npc->tgt_x = npc->x; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + + case 501: + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + npc->ani_no = 8; + + if (++npc->act_wait / 2 & 1) + npc->x = npc->tgt_x; + else + npc->x = npc->tgt_x + 0x200; + + break; + } + + if (npc->act_no >= 10) + { + if (npc->act_no == 102) + { + gSuperXpos = npc->tgt_x; + gSuperYpos = npc->tgt_y; + } + else + { + gSuperXpos = npc->x; + gSuperYpos = npc->y; + } + } + + 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]; + + if (npc->act_no == 101 || npc->act_no == 103) + { + npc->rect.top += npc->act_wait; + npc->rect.bottom -= npc->act_wait; + npc->view.top = (16 - npc->act_wait) << 9; + } + else + { + npc->view.top = 0x2000; + } +} + +//Doctor red wave (projectile) +void ActNpc264(NPCHAR *npc) +{ + RECT rc = {288, 0, 304, 16}; + + if (npc->x < 0 || npc->x > gMap.width * 0x2000) + { + VanishNpChar(npc); + return; + } + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->tgt_x = npc->x; + npc->tgt_y = npc->y; + npc->count1 = npc->direct / 8; + npc->direct &= 7; + // Fallthrough + case 1: + npc->count1 += 6; + npc->count1 &= 0xFF; + const unsigned char deg = npc->count1; + + if (npc->act_wait < 128) + ++npc->act_wait; + + if (npc->direct == 0) + npc->xm -= 21; + else + npc->xm += 21; + + npc->tgt_x += npc->xm; + + npc->x = npc->tgt_x + npc->act_wait * GetCos(deg) / 8; + npc->y = npc->tgt_y + npc->act_wait * GetSin(deg) / 2; + + SetNpChar(265, npc->x, npc->y, 0, 0, 0, 0, 0x100); + + break; + } + + npc->rect = rc; +} + +//Doctor red ball projectile +void ActNpc265(NPCHAR *npc) +{ + RECT rc[3]; + + rc[0] = {288, 16, 304, 32}; + rc[1] = {288, 32, 304, 48}; + rc[2] = {288, 48, 304, 64}; + + if (++npc->ani_wait > 3) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + npc->cond = 0; + else + npc->rect = rc[npc->ani_no]; +} + +//Doctor red ball projectile (bouncing) +void ActNpc266(NPCHAR *npc) +{ + RECT rc[2]; + + rc[0] = {304, 16, 320, 32}; + rc[1] = {304, 32, 320, 48}; + + if (npc->flag & 1) + npc->xm = -npc->xm; + if (npc->flag & 4) + npc->xm = -npc->xm; + + if (npc->flag & 2) + npc->ym = 0x200; + if (npc->flag & 8) + npc->ym = -0x200; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (++npc->ani_no > 1) + npc->ani_no = 0; + + npc->rect = rc[npc->ani_no]; + + if (++npc->act_wait % 4 == 1) + SetNpChar(265, npc->x, npc->y, 0, 0, 0, 0, 0x100); + + if (npc->act_wait > 250) + VanishNpChar(npc); +} + +//Muscle Doctor +void ActNpc267(NPCHAR *npc) +{ + RECT rcLeft[10]; + RECT rcRight[10]; + + rcLeft[0] = {0, 0, 0, 0}; + rcLeft[1] = {0, 64, 40, 112}; + rcLeft[2] = {40, 64, 80, 112}; + rcLeft[3] = {80, 64, 120, 112}; + rcLeft[4] = {120, 64, 160, 112}; + rcLeft[5] = {160, 64, 200, 112}; + rcLeft[6] = {200, 64, 240, 112}; + rcLeft[7] = {240, 64, 280, 112}; + rcLeft[8] = {280, 64, 320, 112}; + rcLeft[9] = {0, 160, 40, 208}; + + rcRight[0] = {0, 0, 0, 0}; + rcRight[1] = {0, 112, 40, 160}; + rcRight[2] = {40, 112, 80, 160}; + rcRight[3] = {80, 112, 120, 160}; + rcRight[4] = {120, 112, 160, 160}; + rcRight[5] = {160, 112, 200, 160}; + rcRight[6] = {200, 112, 240, 160}; + rcRight[7] = {240, 112, 280, 160}; + rcRight[8] = {280, 112, 320, 160}; + rcRight[9] = {40, 160, 80, 208}; + + switch (npc->act_no) + { + case 0: + if (gMC.x < gSuperXpos) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->direct == 0) + npc->x = gSuperXpos - 0xC00; + else + npc->x = gSuperXpos + 0xC00; + + npc->y = gSuperYpos; + // Fallthrough + case 1: + npc->act_no = 2; + // Fallthrough + case 2: + npc->ym += 0x80; + + if (++npc->act_wait / 2 % 2) + npc->ani_no = 0; + else + npc->ani_no = 3; + + break; + + case 5: + npc->act_no = 6; + npc->ani_no = 1; + npc->ani_wait = 0; + // Fallthrough + case 6: + npc->ym += 0x80; + + if (++npc->ani_wait > 40) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + npc->ani_no = 1; + + break; + + case 7: + npc->act_no = 8; + npc->act_wait = 0; + npc->ani_no = 3; + // Fallthrough + case 8: + npc->ym += 0x40; + + if (++npc->act_wait > 40) + npc->act_no = 10; + + break; + + case 10: + npc->bits |= 4; + npc->xm = 0; + npc->act_no = 11; + npc->act_wait = 0; + npc->ani_no = 1; + npc->ani_wait = 0; + npc->count2 = npc->life; + // Fallthrough + case 11: + npc->ym += 0x80; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->flag & 8) + { + if (npc->life >= npc->count2 - 20) + { + if (++npc->ani_wait > 10) + { + npc->ani_wait = 0; + + if (++npc->ani_no > 2) + npc->ani_no = 1; + } + } + else if (gMC.flag & 8 && gMC.x > npc->x - 0x6000 && gMC.x < npc->x + 0x6000 && npc->ani_no != 6) + { + npc->ani_no = 6; + DamageMyChar(5); + SetQuake(10); + PlaySoundObject(26, 1); + gMC.ym = -0x400; + + if (gMC.x < npc->x) + gMC.xm = -0x5FF; + else + gMC.xm = 0x5FF; + + for (int i = 0; i < 100; ++i) + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y + (Random(-0x10, 0x10) * 0x200), 3 * Random(-0x200, 0x200), 3 * Random(-0x200, 0x200), 3, 0, 0xAA); + } + } + else + { + npc->ani_no = 4; + } + + if (++npc->act_wait > 30 || npc->life < npc->count2 - 20) + { + if (++npc->count1 > 10) + npc->count1 = 0; + + switch (npc->count1) + { + case 8: + npc->act_no = 20; + break; + case 2: + case 7: + npc->act_no = 100; + break; + case 3: + case 6: + npc->act_no = 30; + break; + case 1: + case 9: + npc->act_no = 40; + break; + default: + npc->act_no = 15; + npc->act_wait = 0; + break; + } + } + + break; + + case 15: + npc->ani_no = 3; + ++npc->act_wait; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->act_wait > 20) + { + npc->act_no = 16; + npc->ani_no = 4; + npc->ani_wait = 0; + npc->ym = -0x600; + + if (npc->direct == 0) + npc->xm = -0x400; + else + npc->xm = 0x400; + } + + break; + + case 16: + npc->ym += 0x40; + + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 5) + npc->ani_no = 4; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->ym > 0 && npc->flag & 8) + npc->act_no = 17; + + break; + + case 17: + npc->act_no = 18; + npc->act_wait = 0; + SetQuake(10); + PlaySoundObject(26, 1); + // Fallthrough + case 18: + npc->ani_no = 3; + ++npc->act_wait; + + npc->xm = 7 * npc->xm / 8; + npc->ym += 0x80; + + if (npc->act_wait > 10) + npc->act_no = 10; + + break; + + case 20: + npc->act_no = 21; + npc->act_wait = 0; + // Fallthrough + case 21: + ++npc->act_wait; + npc->ani_no = 6; + + if (npc->act_wait > 20 && npc->act_wait % 3 == 1) + { + const int ym = Random(-0x200u, 0x200); + const int xm = 4 * Random(0x100, 0x200); + + if (npc->direct == 0) + SetNpChar(269, npc->x - 0x1000, npc->y - 0x800, -xm, ym, 0, 0, 0x100); + else + SetNpChar(269, npc->x + 0x1000, npc->y - 0x800, xm, ym, 2, 0, 0x100); + + PlaySoundObject(39, 1); + } + + if ( npc->act_wait > 90 ) + npc->act_no = 10; + + break; + + case 30: + npc->act_no = 31; + npc->act_wait = 0; + npc->bits |= 1; + npc->bits &= ~0x20; + // Fallthrough + case 31: + npc->ani_no = 3; + + if (++npc->act_wait > 20) + { + npc->act_no = 32; + npc->act_wait = 0; + npc->ani_no = 7; + npc->bits |= 0x80; + npc->damage = 10; + PlaySoundObject(25, 1); + + if (npc->direct == 0) + npc->xm = -0x5FF; + else + npc->xm = 0x5FF; + } + + break; + + case 32: + ++npc->act_wait; + npc->ym = 0; + + if (npc->act_wait / 2 % 2) + npc->ani_no = 7; + else + npc->ani_no = 8; + + if (npc->act_wait > 30) + { + npc->act_wait = 0; + npc->act_no = 18; + npc->damage = 5; + npc->bits &= ~0x81; + npc->bits |= 0x20; + } + + if (npc->flag & 1 || npc->flag & 4) + { + npc->act_no = 15; + npc->act_wait = 0; + npc->damage = 5; + npc->bits &= ~0x81; + npc->bits |= 0x20; + } + + break; + + case 40: + npc->ani_no = 3; + ++npc->act_wait; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + + if (npc->act_wait > 20) + { + npc->act_no = 41; + npc->ani_no = 4; + npc->ani_wait = 0; + npc->ym = -0x800; + + if (npc->direct == 0) + npc->xm = -0x400; + else + npc->xm = 0x400; + } + + break; + + case 41: + npc->ym += 0x40; + + if (++npc->ani_wait > 1) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 5) + npc->ani_no = 4; + + if (gMC.y > npc->y && gMC.x > npc->x - 0x1000 && gMC.x < npc->x + 0x1000) + { + npc->act_no = 16; + npc->ym = 0x5FF; + npc->xm = 0; + } + + if (npc->ym > 0 && npc->flag & 8) + npc->act_no = 17; + + break; + + case 100: + npc->act_no = 101; + npc->act_wait = 0; + npc->bits &= ~0x24; + npc->damage = 0; + PlaySoundObject(29, 1); + // Fallthrough + case 101: + npc->act_wait += 2; + + if (npc->act_wait > 28) + { + npc->act_no = 102; + npc->act_wait = 0; + npc->ani_no = 0; + + npc->tgt_x = gMC.x; + npc->tgt_y = gMC.y - 0x4000; + + if ( npc->tgt_y < 0x8000 ) + npc->tgt_y = 0x8000; + + if ( npc->tgt_x < 0x8000 ) + npc->tgt_x = 0x8000; + if ( npc->tgt_x > 0x48000 ) + npc->tgt_x = 0x48000; + } + + break; + + case 102: + if (++npc->act_wait > 40) + { + npc->act_no = 103; + npc->act_wait = 28; + npc->ani_no = 4; + npc->ym = 0; + npc->x = npc->tgt_x; + npc->y = npc->tgt_y; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + + case 103: + npc->act_wait -= 2; + + if (npc->act_wait <= 0) + { + npc->bits |= 0x24; + npc->damage = 5; + npc->act_no = 16; + npc->ym = -0x200; + npc->xm = 0; + } + + break; + + case 500: + DeleteNpCharCode(269, 1); + npc->bits &= ~0x20; + npc->ani_no = 4; + npc->ym += 0x20; + npc->xm = 0; + + if (npc->flag & 8) + { + npc->act_no = 501; + npc->act_wait = 0; + npc->tgt_x = npc->x; + + if (gMC.x < npc->x) + npc->direct = 0; + else + npc->direct = 2; + } + + break; + + case 501: + npc->ani_no = 9; + + if (++npc->act_wait / 2 % 2) + npc->x = npc->tgt_x; + else + npc->x = npc->tgt_x + 0x200; + + break; + + case 510: + npc->act_no = 511; + npc->act_wait = 0; + npc->ani_no = 9; + npc->tgt_x = npc->x; + npc->y += 0x2000; + npc->bits |= 8; + // Fallthrough + case 511: + SetQuake(2); + + if (++npc->act_wait % 6 == 3) + PlaySoundObject(25, 1); + + if (npc->act_wait / 2 % 2) + npc->x = npc->tgt_x; + else + npc->x = npc->tgt_x + 0x200; + + if (npc->act_wait > 352) + { + npc->ani_no = 0; + npc->act_no = 0x200; + } + + break; + + case 520: + npc->damage = 0; + gSuperYpos = -0x4000; + break; + } + + if (npc->act_no >= 11 && npc->act_no < 501) + { + if (npc->act_no == 102) + { + gSuperXpos = npc->tgt_x; + gSuperYpos = npc->tgt_y; + } + else + { + gSuperXpos = npc->x; + gSuperYpos = npc->y; + } + } + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->act_no < 512) + { + if (npc->act_no >= 510) + { + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - (((336 - npc->act_wait) / 8) * 0x200), Random(-0x200, 0x200), 2 * Random(-0x200, 0), 3, 0, 0xAA); + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), Random(-0x200, 0x200), 2 * Random(-0x200, 0), 3, 0, 0xAA); + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), 0, 2 * Random(-0x200, 0), 3, 0, 0xAA); + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y - ((336 - npc->act_wait) / 8 * 0x200), 0, 2 * Random(-0x200, 0), 3, 0, 0xAA); + } + else if (npc->act_no != 102 && npc->act_no != 103 && Random(0, 3) == 2) + { + SetNpChar(270, npc->x + (Random(-0x10, 0x10) * 0x200), npc->y + (Random(-8, 4) * 0x200), npc->xm, 0, 3, 0, 0x100); + } + } + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; + + if (npc->act_no == 511) + { + npc->rect.top += npc->act_wait / 8; + npc->view.top = (44 - npc->act_wait / 8) * 0x200; + npc->view.bottom = 0x800; + } + else if (npc->act_no == 101 || npc->act_no == 103) + { + npc->rect.top += npc->act_wait; + npc->rect.bottom -= npc->act_wait; + npc->view.top = (28 - npc->act_wait) * 0x200; + } + else + { + npc->view.top = 0x3800; + } +} //Igor (enemy) void ActNpc268(NPCHAR *npc) @@ -211,6 +1303,138 @@ void ActNpc268(NPCHAR *npc) npc->rect = rcRight[npc->ani_no]; } +//Red Bat (bouncing) +void ActNpc269(NPCHAR *npc) +{ + RECT rcLeft[3]; + RECT rcRight[3]; + + rcLeft[0] = {232, 0, 248, 16}; + rcLeft[1] = {248, 0, 264, 16}; + rcLeft[2] = {248, 16, 264, 32}; + + rcRight[0] = {232, 32, 248, 48}; + rcRight[1] = {248, 32, 264, 48}; + rcRight[2] = {248, 48, 264, 64}; + + switch (npc->act_no) + { + case 0: + npc->act_no = 1; + npc->xm2 = npc->xm; + npc->ym2 = npc->ym; + // Fallthrough + case 1: + if (npc->xm2 < 0 && npc->flag & 1) + { + npc->direct = 2; + npc->xm2 = -npc->xm2; + } + else if (npc->xm2 > 0 && npc->flag & 4) + { + npc->direct = 0; + npc->xm2 = -npc->xm2; + } + else if (npc->ym2 < 0 && npc->flag & 2) + { + npc->ym2 = -npc->ym2; + } + else if (npc->ym2 > 0 && npc->flag & 8) + { + npc->ym2 = -npc->ym2; + } + + npc->x += npc->xm2; + npc->y += npc->ym2; + + if (++npc->ani_wait > 2) + { + npc->ani_wait = 0; + ++npc->ani_no; + } + + if (npc->ani_no > 2) + npc->ani_no = 0; + + break; + } + + if (npc->direct == 0) + npc->rect = rcLeft[npc->ani_no]; + else + npc->rect = rcRight[npc->ani_no]; +} + +//Doctor's blood (or """"red energy"""") +void ActNpc270(NPCHAR *npc) +{ + RECT rc[2]; + + rc[0] = {170, 34, 174, 38}; + rc[1] = {170, 42, 174, 46}; + + if (npc->direct == 3 || npc->direct == 1) + { + if (npc->direct == 3) + npc->ym += 0x40; + if (npc->direct == 1) + npc->ym -= 0x40; + + ++npc->act_wait; + + if (npc->ym > 0x5FF) + npc->ym = 0x5FF; + + npc->x += npc->xm; + npc->y += npc->ym; + + if (npc->act_wait > 50) + npc->cond = 0; + + if (npc->flag & 0xFF) + npc->cond = 0; + } + else if ( npc->direct == 2 ) + { + if (npc->act_no == 0) + { + npc->act_no = 1; + npc->bits |= 8; + + npc->xm = 3 * Random(-0x200, 0x200); + npc->ym = 3 * Random(-0x200, 0x200); + + npc->count1 = Random(0x10, 0x33); + npc->count2 = Random(0x80, 0x100); + } + + if (npc->x < npc->pNpc->x) + npc->xm += 0x200 / npc->count1; + if (npc->x > npc->pNpc->x) + npc->xm -= 0x200 / npc->count1; + + if (npc->y < npc->pNpc->y) + npc->ym += 0x200 / npc->count1; + if (npc->y > npc->pNpc->y) + npc->ym -= 0x200 / npc->count1; + + if (npc->xm > 2 * npc->count2) + npc->xm = 2 * npc->count2; + if (npc->xm < -2 * npc->count2) + npc->xm = -2 * npc->count2; + + if (npc->ym > 3 * npc->count2) + npc->ym = 3 * npc->count2; + if (npc->ym < -3 * npc->count2) + npc->ym = -3 * npc->count2; + + npc->x += npc->xm; + npc->y += npc->ym; + } + + npc->rect = rc[Random(0, 1)]; +} + // Ironhead block void ActNpc271(NPCHAR *npc) { diff --git a/src/NpcTbl.cpp b/src/NpcTbl.cpp index 98445adb..de290dbd 100644 --- a/src/NpcTbl.cpp +++ b/src/NpcTbl.cpp @@ -312,21 +312,21 @@ NPCFUNCTION gpNpcFuncTbl[361] = ActNpc253, ActNpc254, ActNpc255, - nullptr, - nullptr, - nullptr, + ActNpc256, + ActNpc257, + ActNpc258, ActNpc259, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, + ActNpc260, + ActNpc261, + ActNpc262, + ActNpc263, + ActNpc264, + ActNpc265, + ActNpc266, + ActNpc267, ActNpc268, - nullptr, - nullptr, + ActNpc269, + ActNpc270, ActNpc271, ActNpc272, ActNpc273,