Made NpcHit.cpp ASM-accurate

This commit is contained in:
Clownacy 2019-05-13 02:46:07 +01:00
parent fb87b8dd57
commit 3bccba6236
3 changed files with 394 additions and 267 deletions

View file

@ -2294,6 +2294,58 @@ addr = 0x4704F0
name = "CountAliveNpChar" name = "CountAliveNpChar"
addr = 0x470560 addr = 0x470560
[[func]]
name = "JadgeHitNpCharBlock"
addr = 0x4705C0
[[func]]
name = "JudgeHitNpCharTriangleA"
addr = 0x470870
[[func]]
name = "JudgeHitNpCharTriangleB"
addr = 0x470970
[[func]]
name = "JudgeHitNpCharTriangleC"
addr = 0x470A70
[[func]]
name = "JudgeHitNpCharTriangleD"
addr = 0x470B70
[[func]]
name = "JudgeHitNpCharTriangleE"
addr = 0x470C70
[[func]]
name = "JudgeHitNpCharTriangleF"
addr = 0x470D80
[[func]]
name = "JudgeHitNpCharTriangleG"
addr = 0x470E90
[[func]]
name = "JudgeHitNpCharTriangleH"
addr = 0x470FA0
[[func]]
name = "JudgeHitNpCharWater"
addr = 0x4710B0
[[func]]
name = "HitNpCharMap"
addr = 0x471160
[[func]]
name = "LoseNpChar"
addr = 0x471B80
[[func]]
name = "HitNpCharBullet"
addr = 0x471D50
[[func]] [[func]]
name = "LoadNpcTable" name = "LoadNpcTable"
addr = 0x472400 addr = 0x472400

View file

@ -1,5 +1,7 @@
#include "NpcHit.h" #include "NpcHit.h"
#include "WindowsWrapper.h"
#include "Back.h" #include "Back.h"
#include "Bullet.h" #include "Bullet.h"
#include "Caret.h" #include "Caret.h"
@ -16,40 +18,40 @@ void JadgeHitNpCharBlock(NPCHAR *npc, int x, int y)
{ {
int hit = 0; int hit = 0;
if (npc->y - npc->hit.top < ((2 * y + 1) << 12) - 0x600 if (npc->y - npc->hit.top < (y * 0x10 + 5) * 0x200
&& npc->y + npc->hit.bottom > ((2 * y - 1) << 12) + 0x600 && npc->y + npc->hit.bottom > (y * 0x10 - 5) * 0x200
&& npc->x - npc->hit.back < (2 * x + 1) << 12 && npc->x - npc->hit.back < (x * 0x10 + 8) * 0x200
&& npc->x - npc->hit.back > x << 13) && npc->x - npc->hit.back > x * 0x10 * 0x200)
{ {
npc->x = ((2 * x + 1) << 12) + npc->hit.back; npc->x = ((x * 0x10 + 8) * 0x200) + npc->hit.back;
hit |= 1; hit |= 1;
} }
if (npc->y - npc->hit.top < ((2 * y + 1) << 12) - 0x600 if (npc->y - npc->hit.top < (y * 0x10 + 5) * 0x200
&& npc->y + npc->hit.bottom > ((2 * y - 1) << 12) + 0x600 && npc->y + npc->hit.bottom > (y * 0x10 - 5) * 0x200
&& npc->hit.back + npc->x > (2 * x - 1) << 12 && npc->x + npc->hit.back > (x * 0x10 - 8) * 0x200
&& npc->hit.back + npc->x < x << 13) && npc->x + npc->hit.back < x * 0x10 * 0x200)
{ {
npc->x = ((2 * x - 1) << 12) - npc->hit.back; npc->x = ((x * 0x10 - 8) * 0x200) - npc->hit.back;
hit |= 4; hit |= 4;
} }
if (npc->x - npc->hit.back < ((2 * x + 1) << 12) - 0x600 if (npc->x - npc->hit.back < (x * 0x10 + 5) * 0x200
&& npc->hit.back + npc->x > ((2 * x - 1) << 12) + 0x600 && npc->x + npc->hit.back > (x * 0x10 - 5) * 0x200
&& npc->y - npc->hit.top < (2 * y + 1) << 12 && npc->y - npc->hit.top < (y * 0x10 + 8) * 0x200
&& npc->y - npc->hit.top > y << 13) && npc->y - npc->hit.top > y * 0x10 * 0x200)
{ {
npc->y = ((2 * y + 1) << 12) + npc->hit.top; npc->y = ((y * 0x10 + 8) * 0x200) + npc->hit.top;
npc->ym = 0; npc->ym = 0;
hit |= 2; hit |= 2;
} }
if (npc->x - npc->hit.back < ((2 * x + 1) << 12) - 0x600 if (npc->x - npc->hit.back < (x * 0x10 + 5) * 0x200
&& npc->hit.back + npc->x > ((2 * x - 1) << 12) + 0x600 && npc->x + npc->hit.back > (x * 0x10 - 5) * 0x200
&& npc->y + npc->hit.bottom > (2 * y - 1) << 12 && npc->y + npc->hit.bottom > (y * 0x10 - 8) * 0x200
&& npc->y + npc->hit.bottom < y << 13) && npc->y + npc->hit.bottom < y * 0x10 * 0x200)
{ {
npc->y = ((2 * y - 1) << 12) - npc->hit.bottom; npc->y = ((y * 0x10 - 8) * 0x200) - npc->hit.bottom;
npc->ym = 0; npc->ym = 0;
hit |= 8; hit |= 8;
} }
@ -61,20 +63,20 @@ void JudgeHitNpCharTriangleA(NPCHAR *npc, int x, int y)
{ {
int hit = 0; int hit = 0;
if (npc->x < (2 * x + 1) << 12 if (npc->x < (x * 0x10 + 8) * 0x200
&& npc->x > (2 * x - 1) << 12 && npc->x > (x * 0x10 - 8) * 0x200
&& npc->y - npc->hit.top < (y << 13) - (-0x2000 * x + npc->x) / 2 + 0x800 && npc->y - npc->hit.top < (y * 0x10 * 0x200) - ((npc->x - (x * 0x10 * 0x200)) / 2) + 0x800
&& npc->y + npc->hit.bottom > (2 * y - 1) << 12) && npc->y + npc->hit.bottom > (y * 0x10 - 8) * 0x200)
{ {
//Clip //Clip
npc->y = npc->hit.top + (y << 13) - (-0x2000 * x + npc->x) / 2 + 0x800; npc->y = (y * 0x10 * 0x200) - ((npc->x - (x * 0x10 * 0x200)) / 2) + 0x800 + npc->hit.top;
//Halt momentum //Halt momentum
if (npc->ym < 0) if (npc->ym < 0)
npc->ym = 0; npc->ym = 0;
//Set that hit a ceiling //Set that hit a ceiling
hit = 2; hit |= 2;
} }
npc->flag |= hit; npc->flag |= hit;
@ -84,20 +86,20 @@ void JudgeHitNpCharTriangleB(NPCHAR *npc, int x, int y)
{ {
int hit = 0; int hit = 0;
if (npc->x < (2 * x + 1) << 12 if (npc->x < (x * 0x10 + 8) * 0x200
&& npc->x > (2 * x - 1) << 12 && npc->x > (x * 0x10 - 8) * 0x200
&& npc->y - npc->hit.top < (y << 13) - (-0x2000 * x + npc->x) / 2 - 0x800 && npc->y - npc->hit.top < (y * 0x10 * 0x200) - ((npc->x - (x * 0x10 * 0x200)) / 2) - 0x800
&& npc->y + npc->hit.bottom > (2 * y - 1) << 12) && npc->y + npc->hit.bottom > (y * 0x10 - 8) * 0x200)
{ {
//Clip //Clip
npc->y = npc->hit.top + (y << 13) - (-0x2000 * x + npc->x) / 2 - 0x800; npc->y = (y * 0x10 * 0x200) - ((npc->x - (x * 0x10 * 0x200)) / 2) - 0x800 + npc->hit.top;
//Halt momentum //Halt momentum
if (npc->ym < 0) if (npc->ym < 0)
npc->ym = 0; npc->ym = 0;
//Set that hit a ceiling //Set that hit a ceiling
hit = 2; hit |= 2;
} }
npc->flag |= hit; npc->flag |= hit;
@ -107,20 +109,20 @@ void JudgeHitNpCharTriangleC(NPCHAR *npc, int x, int y)
{ {
int hit = 0; int hit = 0;
if (npc->x < (2 * x + 1) << 12 if (npc->x < (x * 0x10 + 8) * 0x200
&& npc->x > (2 * x - 1) << 12 && npc->x > (x * 0x10 - 8) * 0x200
&& npc->y - npc->hit.top < (y << 13) + (-0x2000 * x + npc->x) / 2 - 0x800 && npc->y - npc->hit.top < (y * 0x10 * 0x200) + ((npc->x - (x * 0x10 * 0x200)) / 2) - 0x800
&& npc->y + npc->hit.bottom > (2 * y - 1) << 12) && npc->y + npc->hit.bottom > (y * 0x10 - 8) * 0x200)
{ {
//Clip //Clip
npc->y = npc->hit.top + (y << 13) + (-0x2000 * x + npc->x) / 2 - 0x800; npc->y = (y * 0x10 * 0x200) + ((npc->x - (x * 0x10 * 0x200)) / 2) - 0x800 + npc->hit.top;
//Halt momentum //Halt momentum
if (npc->ym < 0) if (npc->ym < 0)
npc->ym = 0; npc->ym = 0;
//Set that hit a ceiling //Set that hit a ceiling
hit = 2; hit |= 2;
} }
npc->flag |= hit; npc->flag |= hit;
@ -130,20 +132,20 @@ void JudgeHitNpCharTriangleD(NPCHAR *npc, int x, int y)
{ {
int hit = 0; int hit = 0;
if (npc->x < (2 * x + 1) << 12 if (npc->x < (x * 0x10 + 8) * 0x200
&& npc->x > (2 * x - 1) << 12 && npc->x > (x * 0x10 - 8) * 0x200
&& npc->y - npc->hit.top < (y << 13) + (-0x2000 * x + npc->x) / 2 + 0x800 && npc->y - npc->hit.top < (y * 0x10 * 0x200) + ((npc->x - (x * 0x10 * 0x200)) / 2) + 0x800
&& npc->y + npc->hit.bottom > (2 * y - 1) << 12) && npc->y + npc->hit.bottom > (y * 0x10 - 8) * 0x200)
{ {
//Clip //Clip
npc->y = npc->hit.top + (y << 13) + (-0x2000 * x + npc->x) / 2 + 0x800; npc->y = (y * 0x10 * 0x200) + ((npc->x - (x * 0x10 * 0x200)) / 2) + 0x800 + npc->hit.top;
//Halt momentum //Halt momentum
if (npc->ym < 0) if (npc->ym < 0)
npc->ym = 0; npc->ym = 0;
//Set that hit a ceiling //Set that hit a ceiling
hit = 2; hit |= 2;
} }
npc->flag |= hit; npc->flag |= hit;
@ -151,22 +153,24 @@ void JudgeHitNpCharTriangleD(NPCHAR *npc, int x, int y)
void JudgeHitNpCharTriangleE(NPCHAR *npc, int x, int y) void JudgeHitNpCharTriangleE(NPCHAR *npc, int x, int y)
{ {
int hit = 0x10000; int hit = 0;
if ( npc->x < (2 * x + 1) << 12 hit |= 0x10000;
&& npc->x > (2 * x - 1) << 12
&& npc->y + npc->hit.bottom > (y << 13) + (-0x2000 * x + npc->x) / 2 - 0x800 if (npc->x < (x * 0x10 + 8) * 0x200
&& npc->y - npc->hit.top < (2 * y + 1) << 12 ) && npc->x > (x * 0x10 - 8) * 0x200
&& npc->y + npc->hit.bottom > (y * 0x10 * 0x200) + ((npc->x - (x * 0x10 * 0x200)) / 2) - 0x800
&& npc->y - npc->hit.top < (y * 0x10 + 8) * 0x200)
{ {
//Clip //Clip
npc->y = (y << 13) + (-0x2000 * x + npc->x) / 2 - 0x800 - npc->hit.bottom; npc->y = (y * 0x10 * 0x200) + ((npc->x - (x * 0x10 * 0x200)) / 2) - 0x800 - npc->hit.bottom;
//Halt momentum //Halt momentum
if (npc->ym > 0) if (npc->ym > 0)
npc->ym = 0; npc->ym = 0;
//Set that hit this slope //Set that hit this slope
hit = 0x10028; hit |= 0x28;
} }
npc->flag |= hit; npc->flag |= hit;
@ -174,22 +178,24 @@ void JudgeHitNpCharTriangleE(NPCHAR *npc, int x, int y)
void JudgeHitNpCharTriangleF(NPCHAR *npc, int x, int y) void JudgeHitNpCharTriangleF(NPCHAR *npc, int x, int y)
{ {
int hit = 0x20000; int hit = 0;
if ( npc->x < (2 * x + 1) << 12 hit |= 0x20000;
&& npc->x > (2 * x - 1) << 12
&& npc->y + npc->hit.bottom > (y << 13) + (-0x2000 * x + npc->x) / 2 + 0x800 if (npc->x < (x * 0x10 + 8) * 0x200
&& npc->y - npc->hit.top < (2 * y + 1) << 12 ) && npc->x >= (x * 0x10 - 8) * 0x200 // Note that this function uses '>='. I'm not sure if this is a bug.
&& npc->y + npc->hit.bottom > (y * 0x10 * 0x200) + ((npc->x - (x * 0x10 * 0x200)) / 2) + 0x800
&& npc->y - npc->hit.top < (y * 0x10 + 8) * 0x200)
{ {
//Clip //Clip
npc->y = (y << 13) + (-0x2000 * x + npc->x) / 2 + 0x800 - npc->hit.bottom; npc->y = (y * 0x10 * 0x200) + ((npc->x - (x * 0x10 * 0x200)) / 2) + 0x800 - npc->hit.bottom;
//Halt momentum //Halt momentum
if (npc->ym > 0) if (npc->ym > 0)
npc->ym = 0; npc->ym = 0;
//Set that hit this slope //Set that hit this slope
hit = 0x20028; hit |= 0x28;
} }
npc->flag |= hit; npc->flag |= hit;
@ -197,22 +203,24 @@ void JudgeHitNpCharTriangleF(NPCHAR *npc, int x, int y)
void JudgeHitNpCharTriangleG(NPCHAR *npc, int x, int y) void JudgeHitNpCharTriangleG(NPCHAR *npc, int x, int y)
{ {
int hit = 0x40000; int hit = 0;
if ( npc->x < (2 * x + 1) << 12 hit |= 0x40000;
&& npc->x > (2 * x - 1) << 12
&& npc->y + npc->hit.bottom > (y << 13) - (-0x2000 * x + npc->x) / 2 + 0x800 if (npc->x < (x * 0x10 + 8) * 0x200
&& npc->y - npc->hit.top < (2 * y + 1) << 12 ) && npc->x > (x * 0x10 - 8) * 0x200
&& npc->y + npc->hit.bottom > (y * 0x10 * 0x200) - ((npc->x - (x * 0x10 * 0x200)) / 2) + 0x800
&& npc->y - npc->hit.top < (y * 0x10 + 8) * 0x200)
{ {
//Clip //Clip
npc->y = (y << 13) - (-0x2000 * x + npc->x) / 2 + 0x800 - npc->hit.bottom; npc->y = (y * 0x10 * 0x200) - ((npc->x - (x * 0x10 * 0x200)) / 2) + 0x800 - npc->hit.bottom;
//Halt momentum //Halt momentum
if (npc->ym > 0) if (npc->ym > 0)
npc->ym = 0; npc->ym = 0;
//Set that hit this slope //Set that hit this slope
hit = 0x40018; hit |= 0x18;
} }
npc->flag |= hit; npc->flag |= hit;
@ -220,22 +228,24 @@ void JudgeHitNpCharTriangleG(NPCHAR *npc, int x, int y)
void JudgeHitNpCharTriangleH(NPCHAR *npc, int x, int y) void JudgeHitNpCharTriangleH(NPCHAR *npc, int x, int y)
{ {
int hit = 0x80000; int hit = 0;
if ( npc->x < (2 * x + 1) << 12 hit |= 0x80000;
&& npc->x > (2 * x - 1) << 12
&& npc->y + npc->hit.bottom > (y << 13) - (-0x2000 * x + npc->x) / 2 - 0x800 if (npc->x < (x * 0x10 + 8) * 0x200
&& npc->y - npc->hit.top < (2 * y + 1) << 12 ) && npc->x > (x * 0x10 - 8) * 0x200
&& npc->y + npc->hit.bottom > (y * 0x10 * 0x200) - ((npc->x - (x * 0x10 * 0x200)) / 2) - 0x800
&& npc->y - npc->hit.top < (y * 0x10 + 8) * 0x200)
{ {
//Clip //Clip
npc->y = (y << 13) - (-0x2000 * x + npc->x) / 2 - 0x800 - npc->hit.bottom; npc->y = (y * 0x10 * 0x200) - ((npc->x - (x * 0x10 * 0x200)) / 2) - 0x800 - npc->hit.bottom;
//Halt momentum //Halt momentum
if (npc->ym > 0) if (npc->ym > 0)
npc->ym = 0; npc->ym = 0;
//Set that hit this slope //Set that hit this slope
hit = 0x80018; hit |= 0x18;
} }
npc->flag |= hit; npc->flag |= hit;
@ -245,19 +255,24 @@ void JudgeHitNpCharWater(NPCHAR *npc, int x, int y)
{ {
int hit = 0; int hit = 0;
if (npc->x - npc->hit.back < (4 * (2 * x + 1) - 1) << 10 if (npc->x - npc->hit.back < (x * 0x10 + 6) * 0x200
&& npc->hit.back + npc->x > (4 * (2 * x - 1) + 1) << 10 && npc->x + npc->hit.back > (x * 0x10 - 6) * 0x200
&& npc->y - npc->hit.top < (4 * (2 * y + 1) - 1) << 10 && npc->y - npc->hit.top < (y * 0x10 + 6) * 0x200
&& npc->y + npc->hit.bottom > (4 * (2 * y - 1) + 1) << 10) && npc->y + npc->hit.bottom > (y * 0x10 - 6) * 0x200)
hit = 0x100; hit |= 0x100;
npc->flag |= hit; npc->flag |= hit;
} }
void HitNpCharMap() void HitNpCharMap()
{ {
int offy[9]; int judg, x, y;
int offx[9]; int offx[9];
int offy[9];
int i;
int j;
offx[0] = 0; offx[0] = 0;
offx[1] = 1; offx[1] = 1;
@ -279,37 +294,38 @@ void HitNpCharMap()
offy[7] = 2; offy[7] = 2;
offy[8] = 2; offy[8] = 2;
for (int i = 0; i < NPC_MAX; i++) for (i = 0; i < NPC_MAX; i++)
{ {
if ((gNPC[i].cond & 0x80) && !(gNPC[i].bits & 8)) if ((gNPC[i].cond & 0x80) == 0)
continue;
if (gNPC[i].bits & 8)
continue;
if (gNPC[i].size >= 3)
{ {
int judg, x, y; judg = 9;
if (gNPC[i].size <= 2) x = (gNPC[i].x - 0x1000) / 0x10 / 0x200;
{ y = (gNPC[i].y - 0x1000) / 0x10 / 0x200;
judg = 4;
x = gNPC[i].x / 0x2000;
y = gNPC[i].y / 0x2000;
} }
else else
{ {
judg = 9; judg = 4;
x = (gNPC[i].x - 0x1000) / 0x2000; x = gNPC[i].x / 0x10 / 0x200;
y = (gNPC[i].y - 0x1000) / 0x2000; y = gNPC[i].y / 0x10 / 0x200;
} }
gNPC[i].flag = 0; gNPC[i].flag = 0;
for (int j = 0; j < judg; j++) for (j = 0; j < judg; j++)
{ {
switch (GetAttribute(x + offx[j], y + offy[j])) switch (GetAttribute(x + offx[j], y + offy[j]))
{ {
//Water //No NPC block
case 0x02: case 0x44:
case 0x60: if (gNPC[i].bits & npc_ignore44)
case 0x62:
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break; break;
// Fallthrough
//Block //Block
case 0x03: case 0x03:
case 0x05: case 0x05:
@ -318,20 +334,6 @@ void HitNpCharMap()
JadgeHitNpCharBlock(&gNPC[i], x + offx[j], y + offy[j]); JadgeHitNpCharBlock(&gNPC[i], x + offx[j], y + offy[j]);
break; break;
//Water block
case 0x04:
case 0x61:
case 0x64:
JadgeHitNpCharBlock(&gNPC[i], x + offx[j], y + offy[j]);
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
//No NPC block
case 0x44:
if (!(gNPC[i].bits & npc_ignore44))
JadgeHitNpCharBlock(&gNPC[i], x + offx[j], y + offy[j]);
break;
//Slopes //Slopes
case 0x50: case 0x50:
JudgeHitNpCharTriangleA(&gNPC[i], x + offx[j], y + offy[j]); JudgeHitNpCharTriangleA(&gNPC[i], x + offx[j], y + offy[j]);
@ -365,6 +367,21 @@ void HitNpCharMap()
JudgeHitNpCharTriangleH(&gNPC[i], x + offx[j], y + offy[j]); JudgeHitNpCharTriangleH(&gNPC[i], x + offx[j], y + offy[j]);
break; break;
//Water
case 0x02:
case 0x60:
case 0x62:
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
//Water block
case 0x04:
case 0x61:
case 0x64:
JadgeHitNpCharBlock(&gNPC[i], x + offx[j], y + offy[j]);
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
//Water slopes //Water slopes
case 0x70: case 0x70:
JudgeHitNpCharTriangleA(&gNPC[i], x + offx[j], y + offy[j]); JudgeHitNpCharTriangleA(&gNPC[i], x + offx[j], y + offy[j]);
@ -405,7 +422,34 @@ void HitNpCharMap()
JudgeHitNpCharTriangleH(&gNPC[i], x + offx[j], y + offy[j]); JudgeHitNpCharTriangleH(&gNPC[i], x + offx[j], y + offy[j]);
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]); JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break; break;
}
case 0xA0:
gNPC[i].flag |= 0x100;
// Fallthrough
case 0x80:
gNPC[i].flag |= 0x1000;
break;
case 0xA1:
gNPC[i].flag |= 0x100;
// Fallthrough
case 0x81:
gNPC[i].flag |= 0x2000;
break;
case 0xA2:
gNPC[i].flag |= 0x100;
// Fallthrough
case 0x82:
gNPC[i].flag |= 0x4000;
break;
case 0xA3:
gNPC[i].flag |= 0x100;
// Fallthrough
case 0x83:
gNPC[i].flag |= 0x8000;
break;
} }
if (gNPC[i].y > gWaterY + 0x800) if (gNPC[i].y > gWaterY + 0x800)
@ -414,7 +458,7 @@ void HitNpCharMap()
} }
} }
void LoseNpChar(NPCHAR *npc, bool bVanish) void LoseNpChar(NPCHAR *npc, BOOL bVanish)
{ {
//Play death sound //Play death sound
PlaySoundObject(npc->destroy_voice, 1); PlaySoundObject(npc->destroy_voice, 1);
@ -436,18 +480,34 @@ void LoseNpChar(NPCHAR *npc, bool bVanish)
//Create drop //Create drop
if (npc->exp) if (npc->exp)
{ {
int v3 = Random(1, 5); int val;
char v4;
if (v3 == 1) switch (Random(1, 5))
{ {
if (npc->exp <= 6) case 1:
SetLifeObject(npc->x, npc->y, 2); // Spawn health
if (npc->exp > 6)
val = 6;
else else
SetLifeObject(npc->x, npc->y, 6); val = 2;
}
else if (v3 != 2 || (npc->exp <= 6 ? (v4 = SetBulletObject(npc->x, npc->y, 1)) : (v4 = SetBulletObject(npc->x, npc->y, 3)), !v4)) //TODO: what the FUCK SetLifeObject(npc->x, npc->y, val);
{
break;
case 2:
// Spawn missile launcher ammo
if (npc->exp > 6)
val = 3;
else
val = 1;
if (SetBulletObject(npc->x, npc->y, val))
break;
// Fallthrough
default:
// Spawn weapon energy
SetExpObjects(npc->x, npc->y, npc->exp); SetExpObjects(npc->x, npc->y, npc->exp);
} }
} }
@ -456,43 +516,55 @@ void LoseNpChar(NPCHAR *npc, bool bVanish)
SetNPCFlag(npc->code_flag); SetNPCFlag(npc->code_flag);
//Create value view //Create value view
if (!(npc->bits & npc_showDamage)) if (npc->bits & npc_showDamage)
{
npc->cond = 0;
}
else
{ {
if ((npc->bits & npc_showDamage) && npc->damage_view) if ((npc->bits & npc_showDamage) && npc->damage_view)
SetValueView(&npc->x, &npc->y, npc->damage_view); SetValueView(&npc->x, &npc->y, npc->damage_view);
if (bVanish) if (bVanish)
VanishNpChar(npc); VanishNpChar(npc);
} }
else
{
npc->cond = 0;
}
} }
void HitNpCharBullet() void HitNpCharBullet()
{ {
for (int n = 0; n < NPC_MAX; n++) int n;
int b;
BOOL bHit;
for (n = 0; n < NPC_MAX; n++)
{ {
if ((gNPC[n].cond & 0x80) && (!(gNPC[n].bits & npc_shootable) || !(gNPC[n].bits & npc_interact))) if ((gNPC[n].cond & 0x80) == 0)
{ continue;
for (int b = 0; b < BULLET_MAX; b++)
{ if (gNPC[n].bits & npc_shootable && gNPC[n].bits & npc_interact)
if (gBul[b].cond & 0x80 && gBul[b].damage != -1) continue;
for (b = 0; b < BULLET_MAX; b++)
{ {
if ((gBul[b].cond & 0x80) == 0)
continue;
if (gBul[b].damage == -1)
continue;
//Check if bullet touches npc //Check if bullet touches npc
bool bHit = false; bHit = FALSE;
if (gNPC[n].bits & npc_shootable if (gNPC[n].bits & npc_shootable
&& gNPC[n].x - gNPC[n].hit.back < gBul[b].x + gBul[b].enemyXL && gNPC[n].x - gNPC[n].hit.back < gBul[b].x + gBul[b].enemyXL
&& gNPC[n].x + gNPC[n].hit.back > gBul[b].x - gBul[b].enemyXL && gNPC[n].x + gNPC[n].hit.back > gBul[b].x - gBul[b].enemyXL
&& gNPC[n].y - gNPC[n].hit.top < gBul[b].y + gBul[b].enemyYL && gNPC[n].y - gNPC[n].hit.top < gBul[b].y + gBul[b].enemyYL
&& gNPC[n].y + gNPC[n].hit.bottom > gBul[b].y - gBul[b].enemyYL) && gNPC[n].y + gNPC[n].hit.bottom > gBul[b].y - gBul[b].enemyYL)
bHit = true; bHit = TRUE;
else if (gNPC[n].bits & npc_invulnerable else if (gNPC[n].bits & npc_invulnerable
&& gNPC[n].x - gNPC[n].hit.back < gBul[b].x + gBul[b].blockXL && gNPC[n].x - gNPC[n].hit.back < gBul[b].x + gBul[b].blockXL
&& gNPC[n].x + gNPC[n].hit.back > gBul[b].x - gBul[b].blockXL && gNPC[n].x + gNPC[n].hit.back > gBul[b].x - gBul[b].blockXL
&& gNPC[n].y - gNPC[n].hit.top < gBul[b].y + gBul[b].blockYL && gNPC[n].y - gNPC[n].hit.top < gBul[b].y + gBul[b].blockYL
&& gNPC[n].y + gNPC[n].hit.bottom > gBul[b].y - gBul[b].blockYL) && gNPC[n].y + gNPC[n].hit.bottom > gBul[b].y - gBul[b].blockYL)
bHit = true; bHit = TRUE;
if (bHit) if (bHit)
{ {
@ -501,7 +573,19 @@ void HitNpCharBullet()
{ {
gNPC[n].life -= gBul[b].damage; gNPC[n].life -= gBul[b].damage;
if (gNPC[n].life > 0) if (gNPC[n].life < 1)
{
gNPC[n].life = 0;
if (gNPC[n].bits & npc_showDamage)
gNPC[n].damage_view -= gBul[b].damage;
if ((gMC.cond & 0x80) && gNPC[n].bits & npc_eventDie)
StartTextScript(gNPC[n].code_event);
else
gNPC[n].cond |= 8;
}
else
{ {
if (gNPC[n].shock < 14) if (gNPC[n].shock < 14)
{ {
@ -515,28 +599,19 @@ void HitNpCharBullet()
if (gNPC[n].bits & npc_showDamage) if (gNPC[n].bits & npc_showDamage)
gNPC[n].damage_view -= gBul[b].damage; gNPC[n].damage_view -= gBul[b].damage;
} }
else }
else if (gBul[b].code_bullet == 13
|| gBul[b].code_bullet == 14
|| gBul[b].code_bullet == 15
|| gBul[b].code_bullet == 28
|| gBul[b].code_bullet == 29
|| gBul[b].code_bullet == 30)
{ {
gNPC[n].life = 0; // Strange empty case that's needed for accurate assembly
if (gNPC[n].bits & npc_showDamage)
gNPC[n].damage_view -= gBul[b].damage;
if ((gMC.cond & 0x80) && gNPC[n].bits & npc_eventDie)
StartTextScript(gNPC[n].code_event);
else
gNPC[n].cond |= 8;
}
} }
else if ((gBul[b].bbits & 0x10) == 0)
{
//Hit invulnerable NPC //Hit invulnerable NPC
else if (gBul[b].code_bullet != 13
&& gBul[b].code_bullet != 14
&& gBul[b].code_bullet != 15
&& gBul[b].code_bullet != 28
&& gBul[b].code_bullet != 29
&& gBul[b].code_bullet != 30
&& !(gBul[b].bbits & 0x10))
{
SetCaret((gBul[b].x + gNPC[n].x) / 2, (gBul[b].y + gNPC[n].y) / 2, 2, 2); SetCaret((gBul[b].x + gNPC[n].x) / 2, (gBul[b].y + gNPC[n].y) / 2, 2, 2);
PlaySoundObject(31, 1); PlaySoundObject(31, 1);
gBul[b].life = 0; gBul[b].life = 0;
@ -546,10 +621,8 @@ void HitNpCharBullet()
--gBul[b].life; --gBul[b].life;
} }
} }
}
if (gNPC[n].cond & 8) if (gNPC[n].cond & 8)
LoseNpChar(&gNPC[n], true); LoseNpChar(&gNPC[n], TRUE);
}
} }
} }

View file

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "WindowsWrapper.h"
#include "NpChar.h" #include "NpChar.h"
void JadgeHitNpCharBlock(NPCHAR *npc, int x, int y); void JadgeHitNpCharBlock(NPCHAR *npc, int x, int y);
@ -13,5 +15,5 @@ void JudgeHitNpCharTriangleG(NPCHAR *npc, int x, int y);
void JudgeHitNpCharTriangleH(NPCHAR *npc, int x, int y); void JudgeHitNpCharTriangleH(NPCHAR *npc, int x, int y);
void JudgeHitNpCharWater(NPCHAR *npc, int x, int y); void JudgeHitNpCharWater(NPCHAR *npc, int x, int y);
void HitNpCharMap(); void HitNpCharMap();
void LoseNpChar(NPCHAR *npc, bool bVanish); void LoseNpChar(NPCHAR *npc, BOOL bVanish);
void HitNpCharBullet(); void HitNpCharBullet();