added first 6 npcs, npc map collision, player map collision, fixed huge issue with map drawing, causing there to be 50+% cpu usage. bluh

This commit is contained in:
cuckydev 2019-01-25 22:38:50 -05:00
parent f8791a7d39
commit c04092df89
14 changed files with 2200 additions and 30 deletions

View file

@ -45,7 +45,10 @@ SOURCES = \
Map \
MapName \
MyChar \
MycHit \
NpcAct000 \
NpChar \
NpcHit \
NpcTbl \
Organya \
PixTone \

View file

@ -11,6 +11,7 @@ struct BACK
int fx;
};
extern BACK gBack;
extern int gWaterY;
bool InitBack(char *fName, int type);

View file

@ -23,9 +23,9 @@ void MoveFrame3()
if (gFrame.y <= -0x200)
gFrame.y = 0;
if (gFrame.x > ((((map_w - 1) << 4) - WINDOW_WIDTH)) << 9);
if (gFrame.x > ((((map_w - 1) << 4) - WINDOW_WIDTH)) << 9)
gFrame.x = (((map_w - 1) << 4) - WINDOW_WIDTH) << 9;
if (gFrame.y > ((((map_l - 1) << 4) - WINDOW_HEIGHT)) << 9);
if (gFrame.y > ((((map_l - 1) << 4) - WINDOW_HEIGHT)) << 9)
gFrame.y = (((map_l - 1) << 4) - WINDOW_HEIGHT) << 9;
//Quake
@ -74,9 +74,9 @@ void SetFramePosition(int fx, int fy)
if (gFrame.y <= -0x200)
gFrame.y = 0;
if (gFrame.x > ((((map_w - 1) << 4) - WINDOW_WIDTH)) << 9);
if (gFrame.x > ((((map_w - 1) << 4) - WINDOW_WIDTH)) << 9)
gFrame.x = (((map_w - 1) << 4) - WINDOW_WIDTH) << 9;
if (gFrame.y > ((((map_l - 1) << 4) - WINDOW_HEIGHT)) << 9);
if (gFrame.y > ((((map_l - 1) << 4) - WINDOW_HEIGHT)) << 9)
gFrame.y = (((map_l - 1) << 4) - WINDOW_HEIGHT) << 9;
}
@ -89,8 +89,8 @@ void SetFrameMyChar()
int16_t map_w, map_l;
GetMapData(0, &map_w, &map_l);
gFrame.x = mc_x - 81920;
gFrame.y = mc_y - 61440;
gFrame.x = mc_x - (WINDOW_WIDTH << 9);
gFrame.y = mc_y - (WINDOW_HEIGHT << 9);
//Keep in bounds
if (gFrame.x <= -0x200)
@ -98,16 +98,16 @@ void SetFrameMyChar()
if (gFrame.y <= -0x200)
gFrame.y = 0;
if (gFrame.x > ((((map_w - 1) << 4) - WINDOW_WIDTH)) << 9);
if (gFrame.x > ((((map_w - 1) << 4) - WINDOW_WIDTH)) << 9)
gFrame.x = (((map_w - 1) << 4) - WINDOW_WIDTH) << 9;
if (gFrame.y > ((((map_l - 1) << 4) - WINDOW_HEIGHT)) << 9);
if (gFrame.y > ((((map_l - 1) << 4) - WINDOW_HEIGHT)) << 9)
gFrame.y = (((map_l - 1) << 4) - WINDOW_HEIGHT) << 9;
}
void SetFrameTargetMyChar(int wait)
{
gFrame.tgt_x = &gMC.x;
gFrame.tgt_y = &gMC.y;
gFrame.tgt_x = &gMC.tgt_x;
gFrame.tgt_y = &gMC.tgt_y;
gFrame.wait = wait;
}

View file

@ -7,6 +7,7 @@
#include "Tags.h"
#include "NpcTbl.h"
#include "NpChar.h"
#include "NpcHit.h"
#include "Generic.h"
#include "GenericLoad.h"
#include "TextScr.h"
@ -16,6 +17,7 @@
#include "Escape.h"
#include "Stage.h"
#include "MyChar.h"
#include "MycHit.h"
#include "Caret.h"
#include "Map.h"
#include "Main.h"
@ -132,11 +134,11 @@ int ModeOpening()
ActNpChar();
//ActBossChar();
ActBack();
//ResetMyCharFlag();
//HitMyCharMap();
ResetMyCharFlag();
HitMyCharMap();
//HitMyCharNpChar();
//HitMyCharBoss();
//HitNpCharMap();
HitNpCharMap();
//HitBossMap();
//HitBossBullet();
//ActCaret();
@ -321,7 +323,7 @@ int ModeTitle()
}
//Update carets
//ActCaret();
ActCaret();
//Animate character cursor
if ( ++anime >= 40 )
@ -384,7 +386,7 @@ int ModeTitle()
PutBitmap3(&grcGame, 116, char_y, &char_rc, char_surf);
//Draw carets
//PutCaret(0, 0);
PutCaret(0, 0);
//if (time_counter)
// PutTimeCounter(16, 8);
@ -408,6 +410,124 @@ int ModeTitle()
return 0;
}
return 3;
}
int ModeAction()
{
int frame_x = 0;
int frame_y = 0;
bool swPlay = true;
//Reset stuff
gCounter = 0;
grcGame.left = 0;
g_GameFlags = 3;
//Initialize everything
InitMyChar();
InitNpChar();
//InitBullet();
InitCaret();
//InitStar();
InitFade();
//InitFlash();
//ClearArmsData();
//ClearItemData();
//ClearPermitStage();
//StartMapping();
InitFlags();
//InitBossLife();
TransferStage(2, 94, 5, 6);
ChangeMusic(mus_MischievousRobot);
SetFrameTargetMyChar(16);
SetFrameMyChar();
while (true)
{
//Get pressed keys
GetTrg();
//Escape menu
if (gKey & KEY_ESCAPE)
{
int escRet = Call_Escape();
if (escRet == 0)
return 0;
if (escRet == 2)
return 1;
}
if (swPlay & 1 && g_GameFlags & 1)
{
if (g_GameFlags & 2)
ActMyChar(true);
else
ActMyChar(false);
//ActStar();
ActNpChar();
//ActBossChar();
//ActValueView();
ActBack();
ResetMyCharFlag();
HitMyCharMap();
//HitMyCharNpChar();
//HitMyCharBoss();
HitNpCharMap();
//HitBossMap();
//HitBulletMap();
//HitNpCharBullet();
//HitBossBullet();
//if (g_GameFlags & 2)
// ShootBullet();
//ActBullet();
ActCaret();
MoveFrame3();
//ActFlash(frame_x, frame_y);
if (g_GameFlags & 2)
AnimationMyChar(true);
else
AnimationMyChar(false);
}
if (g_GameFlags & 8)
{
ActionCredit();
ActionIllust();
ActionStripper();
}
ProcFade();
CortBox(&grcFull, 0x000020);
GetFramePosition(&frame_x, &frame_y);
PutBack(frame_x, frame_y);
PutStage_Back(frame_x, frame_y);
//PutBossChar(frame_x, frame_y);
PutNpChar(frame_x, frame_y);
//PutBullet(frame_x, frame_y);
PutMyChar(frame_x, frame_y);
//PutStar(frame_x, frame_y);
PutMapDataVector(frame_x, frame_y);
PutStage_Front(frame_x, frame_y);
PutFront(frame_x, frame_y);
//PutFlash();
PutCaret(frame_x, frame_y);
//PutValueView(frame_x, frame_y);
//PutBossLife();
PutFade();
PutMapName(false);
PutFramePerSecound();
if (!Flip_SystemTask())
break;
++gCounter;
}
return 0;
}
@ -432,8 +552,8 @@ bool Game()
mode = ModeOpening();
if (mode == 2)
mode = ModeTitle();
//if (mode == 3)
// mode = ModeAction();
if (mode == 3)
mode = ModeAction();
}
EndMapData();

View file

@ -132,8 +132,8 @@ bool ChangeMapParts(int x, int y, uint8_t no)
void PutStage_Back(int fx, int fy)
{
//Get range to draw
int num_x = WINDOW_WIDTH / 2 + 1;
int num_y = WINDOW_HEIGHT / 2 + 1;
int num_x = (WINDOW_WIDTH >> 4) + 1;
int num_y = (WINDOW_HEIGHT >> 4) + 1;
int put_x = (fx / 0x200 + 8) / 16;
int put_y = (fy / 0x200 + 8) / 16;
@ -165,8 +165,8 @@ void PutStage_Front(int fx, int fy)
RECT rcSnack = {256, 48, 272, 64};
//Get range to draw
int num_x = WINDOW_WIDTH / 2 + 1;
int num_y = WINDOW_HEIGHT / 2 + 1;
int num_x = (WINDOW_WIDTH >> 4) + 1;
int num_y = (WINDOW_HEIGHT >> 4) + 1;
int put_x = (fx / 0x200 + 8) / 16;
int put_y = (fy / 0x200 + 8) / 16;
@ -199,8 +199,8 @@ void PutStage_Front(int fx, int fy)
void PutMapDataVector(int fx, int fy)
{
//Get range to draw
int num_x = WINDOW_WIDTH / 2 + 1;
int num_y = WINDOW_HEIGHT / 2 + 1;
int num_x = (WINDOW_WIDTH >> 4) + 1;
int num_y = (WINDOW_HEIGHT >> 4) + 1;
int put_x = (fx / 0x200 + 8) / 16;
int put_y = (fy / 0x200 + 8) / 16;

View file

@ -4,9 +4,12 @@
#include "WindowsWrapper.h"
#include "MyChar.h"
#include "NpChar.h"
#include "Draw.h"
#include "Sound.h"
#include "KeyControl.h"
#include "Game.h"
#include "Caret.h"
MYCHAR gMC;
@ -138,6 +141,577 @@ void ShowMyChar(bool bShow)
gMC.cond |= 2;
}
void PutMyChar(int fx, int fy)
{
if ((gMC.cond & 0x80u) && !(gMC.cond & 2))
{
//Draw weapon
gMC.rect_arms.left = 24 * 0;//(gArmsData[gSelectedArms].code % 13);
gMC.rect_arms.right = gMC.rect_arms.left + 24;
gMC.rect_arms.top = 96 * 0;//(gArmsData[gSelectedArms].code / 13);
gMC.rect_arms.bottom = gMC.rect_arms.top + 16;
if (gMC.direct == 2)
{
gMC.rect_arms.top += 16;
gMC.rect_arms.bottom += 16;
}
int arms_offset_y;
if (gMC.up)
{
arms_offset_y = -4;
gMC.rect_arms.top += 32;
gMC.rect_arms.bottom += 32;
}
else if (gMC.down)
{
arms_offset_y = 4;
gMC.rect_arms.top += 64;
gMC.rect_arms.bottom += 64;
}
else
{
arms_offset_y = 0;
}
if (gMC.ani_no == 1 || gMC.ani_no == 3 || gMC.ani_no == 6 || gMC.ani_no == 8)
++gMC.rect_arms.top;
if (gMC.direct)
PutBitmap3(
&grcGame,
(gMC.x - gMC.view.left) / 0x200 - fx / 0x200,
arms_offset_y + (gMC.y - gMC.view.top) / 0x200 - fy / 0x200,
&gMC.rect_arms,
11);
else
PutBitmap3(
&grcGame,
(gMC.x - gMC.view.left) / 0x200 - fx / 0x200 - 8,
arms_offset_y + (gMC.y - gMC.view.top) / 0x200 - fy / 0x200,
&gMC.rect_arms,
11);
if (!((gMC.shock >> 1) & 1))
{
//Draw player
RECT rect = gMC.rect;
if (gMC.equip & 0x40)
{
rect.top += 32;
rect.bottom += 32;
}
PutBitmap3(&grcGame, (gMC.x - gMC.view.left) / 0x200 - fx / 0x200, (gMC.y - gMC.view.top) / 0x200 - fy / 0x200, &rect, 16);
//Draw airtank
RECT rcBubble[2];
rcBubble[0] = {56, 96, 80, 120};
rcBubble[1] = {80, 96, 104, 120};
++gMC.bubble;
if (gMC.equip & 0x10 && gMC.flag & 0x100)
PutBitmap3(&grcGame, gMC.x / 0x200 - 12 - fx / 0x200, gMC.y / 0x200 - 12 - fy / 0x200, &rcBubble[(gMC.bubble >> 1) & 1], 19);
else if (gMC.unit == 1)
PutBitmap3(&grcGame, gMC.x / 0x200 - 12 - fx / 0x200, gMC.y / 0x200 - 12 - fy / 0x200, &rcBubble[(gMC.bubble >> 1) & 1], 19);
}
}
}
void ActMyChar_Normal(bool bKey)
{
if (!(gMC.cond & 2))
{
//Get speeds and accelerations
int max_dash;
int gravity1;
int gravity2;
int jump;
int dash1;
int dash2;
int resist;
if (gMC.flag & 0x100)
{
max_dash = 0x196;
gravity1 = 0x28;
gravity2 = 0x10;
jump = 0x280;
dash1 = 0x2A;
dash2 = 0x10;
resist = 0x19;
}
else
{
max_dash = 0x32C;
gravity1 = 0x50;
gravity2 = 0x20;
jump = 0x500;
dash1 = 0x55;
dash2 = 0x20;
resist = 0x33;
}
//Don't create "?" effect
gMC.ques = 0;
//If can't control player, stop boosting
if (!bKey)
gMC.boost_sw = 0;
//Movement on the ground
if (gMC.flag & 8 || gMC.flag & 0x10 || gMC.flag & 0x20)
{
//Stop boosting and refuel
gMC.boost_sw = 0;
if (gMC.equip & 1)
{
gMC.boost_cnt = 50;
}
else if (gMC.equip & 0x20)
{
gMC.boost_cnt = 50;
}
else
{
gMC.boost_cnt = 0;
}
//Move in direction held
if (bKey)
{
if (gKeyTrg != gKeyDown || gKey != gKeyDown || (gMC.cond & 1) || g_GameFlags & 4)
{
if (gKey != gKeyDown)
{
if (gKey & gKeyLeft && gMC.xm > -max_dash)
gMC.xm -= dash1;
if (gKey & gKeyRight && gMC.xm < max_dash)
gMC.xm += dash1;
if (gKey & gKeyLeft)
gMC.direct = 0;
if (gKey & gKeyRight)
gMC.direct = 2;
}
}
else
{
gMC.cond |= 1;
gMC.ques = 1;
}
}
//Friction
if (!(gMC.cond & 0x20))
{
if (gMC.xm < 0)
{
if (gMC.xm <= -resist)
gMC.xm += resist;
else
gMC.xm = 0;
}
if (gMC.xm > 0)
{
if (gMC.xm >= resist)
gMC.xm -= resist;
else
gMC.xm = 0;
}
}
}
else
{
//Start boosting
if (bKey)
{
if (gMC.equip & 0x21 && gKeyTrg & gKeyJump && gMC.boost_cnt)
{
//Booster 0.8
if (gMC.equip & 1)
{
gMC.boost_sw = 1;
if (gMC.ym > 0x100)
gMC.ym /= 2;
}
//Booster 2.0
if (gMC.equip & 0x20)
{
if (gKey & gKeyUp)
{
gMC.boost_sw = 2;
gMC.xm = 0;
gMC.ym = -0x5FF;
}
else if ( gKey & gKeyLeft )
{
gMC.boost_sw = 1;
gMC.ym = 0;
gMC.xm = -0x5FF;
}
else if ( gKey & gKeyRight )
{
gMC.boost_sw = 1;
gMC.ym = 0;
gMC.xm = 0x5FF;
}
else if ( gKey & gKeyDown )
{
gMC.boost_sw = 3;
gMC.xm = 0;
gMC.ym = 0x5FF;
}
else
{
gMC.boost_sw = 2;
gMC.xm = 0;
gMC.ym = -0x5FF;
}
}
}
//Move left and right
if ( gKey & gKeyLeft && gMC.xm > -max_dash )
gMC.xm -= dash2;
if ( gKey & gKeyRight && gMC.xm < max_dash )
gMC.xm += dash2;
if ( gKey & gKeyLeft )
gMC.direct = 0;
if ( gKey & gKeyRight )
gMC.direct = 2;
}
//Slow down when stopped boosting (Booster 2.0)
if (gMC.equip & 0x20 && gMC.boost_sw && (!(gKey & gKeyJump) || !gMC.boost_cnt))
{
if (gMC.boost_sw == 1)
gMC.xm /= 2;
else if (gMC.boost_sw == 2)
gMC.ym /= 2;
}
//Stop boosting
if (!gMC.boost_cnt || !(gKey & gKeyJump))
gMC.boost_sw = 0;
}
//Jumping
if ( bKey )
{
//Look up and down
gMC.up = (gKey & gKeyUp) != 0;
gMC.down = gKey & gKeyDown && !(gMC.flag & 8);
if (gKeyTrg & gKeyJump
&& (gMC.flag & 8 || gMC.flag & 0x10 || gMC.flag & 0x20)
&& !(gMC.flag & 0x2000))
{
gMC.ym = -jump;
PlaySoundObject(15, 1);
}
}
//Stop interacting when moved
if (bKey && (gKeyShot | gKeyJump | gKeyUp | gKeyRight | gKeyLeft) & gKey)
gMC.cond &= ~1;
//Booster losing fuel
if (gMC.boost_sw && gMC.boost_cnt)
--gMC.boost_cnt;
//Wind / current forces
if (gMC.flag & 0x1000)
gMC.xm -= 0x88;
if (gMC.flag & 0x2000)
gMC.ym -= 0x80;
if (gMC.flag & 0x4000)
gMC.xm += 0x88;
if (gMC.flag & 0x8000)
gMC.ym += 0x55;
//Booster 2.0 forces and effects
if (gMC.equip & 0x20 && gMC.boost_sw)
{
if (gMC.boost_sw == 1)
{
//Go up when going into a wall
if (gMC.flag & 5)
gMC.ym = -0x100;
//Move in direction facing
if (!gMC.direct)
gMC.xm -= 0x20;
if (gMC.direct == 2)
gMC.xm += 0x20;
//Boost particles (and sound)
if (gKeyTrg & gKeyJump || gMC.boost_cnt % 3 == 1)
{
if (!gMC.direct)
SetCaret(gMC.x + 0x400, gMC.y + 0x400, 7, 2);
if (gMC.direct == 2)
SetCaret(gMC.x - 0x400, gMC.y + 0x400, 7, 0);
PlaySoundObject(113, 1);
}
}
else if (gMC.boost_sw == 2)
{
//Move upwards
gMC.ym -= 0x20;
//Boost particles (and sound)
if (gKeyTrg & gKeyJump || gMC.boost_cnt % 3 == 1)
{
SetCaret(gMC.x, gMC.y + 0xC00, 7, 3);
PlaySoundObject(113, 1);
}
}
else if (gMC.boost_sw == 3 && (gKeyTrg & gKeyJump || gMC.boost_cnt % 3 == 1))
{
//Boost particles (and sound)
SetCaret(gMC.x, gMC.y - 0xC00, 7, 1);
PlaySoundObject(113, 1);
}
}
//Upwards wind/current
else if (gMC.flag & 0x2000)
{
gMC.ym += gravity1;
}
//Booster 0.8
else if (gMC.equip & 1 && gMC.boost_sw && gMC.ym > -0x400)
{
//Upwards force
gMC.ym -= 0x20;
if (!(gMC.boost_cnt % 3))
{
SetCaret(gMC.x, gMC.hit.bottom / 2 + gMC.y, 7, 3);
PlaySoundObject(113, 1);
}
//Bounce off of ceiling
if (gMC.flag & 2)
gMC.ym = 0x200;
}
//Gravity while jump is held
else if (gMC.ym < 0 && bKey && gKey & gKeyJump)
{
gMC.ym += gravity2;
}
//Normal gravity
else
{
gMC.ym += gravity1;
}
//Keep player on slopes
if (bKey && !(gKeyTrg & gKeyJump))
{
if (gMC.flag & 0x10 && gMC.xm < 0)
gMC.ym = -gMC.xm;
if (gMC.flag & 0x20 && gMC.xm > 0)
gMC.ym = gMC.xm;
if (gMC.flag & 8 && gMC.flag & 0x80000 && gMC.xm < 0)
gMC.ym = 0x400;
if (gMC.flag & 8 && gMC.flag & 0x10000 && gMC.xm > 0)
gMC.ym = 0x400;
if (gMC.flag & 8 && gMC.flag & 0x20000 && gMC.flag & 0x40000)
gMC.ym = 0x400;
}
//Limit speed
if (!(gMC.flag & 0x100) || gMC.flag & 0xF000)
{
if (gMC.xm < -0x5FF)
gMC.xm = -0x5FF;
if (gMC.xm > 0x5FF)
gMC.xm = 0x5FF;
if (gMC.ym < -0x5FF)
gMC.ym = -0x5FF;
if (gMC.ym > 0x5FF)
gMC.ym = 0x5FF;
}
else
{
if (gMC.xm < -0x2FF)
gMC.xm = -0x2FF;
if (gMC.xm > 0x2FF)
gMC.xm = 0x2FF;
if (gMC.ym < -0x2FF)
gMC.ym = -0x2FF;
if (gMC.ym > 0x2FF)
gMC.ym = 0x2FF;
}
//Water splashing
if (!gMC.sprash && gMC.flag & 0x100)
{
int dir;
if (gMC.flag & 0x800)
dir = 2;
else
dir = 0;
if (gMC.flag & 8 || gMC.ym <= 0x200)
{
if (gMC.xm > 0x200 || gMC.xm < -0x200)
{
for (int a = 0; a < 8; a++)
SetNpChar(73, gMC.x + (Random(-8, 8) << 9), gMC.y, gMC.xm + Random(-0x200, 0x200), gMC.ym + Random(-0x200, 0x80), dir, 0, 0);
PlaySoundObject(56, 1);
}
}
else
{
for (int a = 0; a < 8; a++)
SetNpChar(73, gMC.x + (Random(-8, 8) << 9), gMC.y, gMC.xm + Random(-0x200, 0x200), Random(-0x200, 0x80) - gMC.ym / 2, dir, 0, 0);
PlaySoundObject(56, 1);
}
gMC.sprash = 1;
}
if (!(gMC.flag & 0x100))
gMC.sprash = 0;
//Spike damage
//if (gMC.flag & 0x400)
// DamageMyChar(10);
//Camera
if (gMC.direct)
{
gMC.index_x += 0x200;
if (gMC.index_x > 0x8000)
gMC.index_x = 0x8000;
}
else
{
gMC.index_x -= 0x200;
if (gMC.index_x < -0x8000)
gMC.index_x = -0x8000;
}
if (gKey & gKeyUp && bKey)
{
gMC.index_y -= 0x200;
if (gMC.index_y < -0x8000)
gMC.index_y = -0x8000;
}
else if (gKey & gKeyDown && bKey)
{
gMC.index_y += 0x200;
if (gMC.index_y > 0x8000)
gMC.index_y = 0x8000;
}
else
{
if (gMC.index_y > 0x200)
gMC.index_y -= 0x200;
if (gMC.index_y < -0x200)
gMC.index_y += 0x200;
}
gMC.tgt_x = gMC.x + gMC.index_x;
gMC.tgt_y = gMC.y + gMC.index_y;
//Change position
if (gMC.xm > resist || gMC.xm < -resist)
gMC.x += gMC.xm;
gMC.y += gMC.ym;
}
}
void AirProcess()
{
/*
if ( unk_81C8598 & 0x10 )
{
unk_81C8624 = 1000;
unk_81C8628 = 0;
}
else
{
if ( gMC.flag & 0x100 )
{
if ( --unk_81C8624 <= 0 )
{
if ( (unsigned __int8)GetNPCFlag(4000) )
{
StartTextScript(1100);
}
else
{
StartTextScript(41);
if ( dir )
SetCaret(x, y, 8, 2);
else
SetCaret(x, y, 8, 0);
gMC.cond &= 0x7Fu;
}
}
}
else
{
unk_81C8624 = 1000;
}
if ( gMC.flag & 0x100 )
{
unk_81C8628 = 60;
}
else if ( unk_81C8628 )
{
--unk_81C8628;
}
}
*/
}
void ActMyChar(bool bKey)
{
if (gMC.cond & 0x80)
{
if (gMC.exp_wait)
--gMC.exp_wait;
if (gMC.shock)
{
--gMC.shock;
}
else if (gMC.exp_count)
{
//SetValueView(&x, &y, gMC.exp_count);
gMC.exp_count = 0;
}
switch (gMC.unit)
{
case 0:
if (!(g_GameFlags & 4) && bKey)
AirProcess();
ActMyChar_Normal(bKey);
break;
case 1:
//ActMyChar_Stream(bKey);
break;
default:
break;
}
gMC.cond &= ~0x20;
}
}
void GetMyCharPosition(int *x, int *y)
{
*x = gMC.x;

View file

@ -51,6 +51,9 @@ extern MYCHAR gMC;
void InitMyChar();
void AnimationMyChar(bool bKey);
void ShowMyChar(bool bShow);
void PutMyChar(int fx, int fy);
void ActMyChar_Normal(bool bKey);
void ActMyChar(bool bKey);
void GetMyCharPosition(int *x, int *y);
void SetMyCharPosition(int x, int y);
void MoveMyChar(int x, int y);

567
src/MycHit.cpp Normal file
View file

@ -0,0 +1,567 @@
#include <stdint.h>
#include "WindowsWrapper.h"
#include "MyChar.h"
#include "Map.h"
#include "Sound.h"
#include "Caret.h"
#include "Back.h"
#include "KeyControl.h"
void ResetMyCharFlag()
{
gMC.flag = 0;
}
void PutlittleStar()
{
if (!(gMC.cond & 2) && gMC.ym < -0x200)
{
PlaySoundObject(3, 1);
SetCaret(gMC.x, gMC.y - gMC.hit.top, 13, 0);
SetCaret(gMC.x, gMC.y - gMC.hit.top, 13, 0);
}
}
int JudgeHitMyCharBlock(int x, int y)
{
int hit = 0;
//Left wall
if (gMC.y - gMC.hit.top < (2 * (2 * y + 1) - 1) << 11
&& gMC.y + gMC.hit.bottom > (2 * (2 * y - 1) + 1) << 11
&& gMC.x - gMC.hit.left < (2 * x + 1) << 12
&& gMC.x - gMC.hit.left > x << 13)
{
//Clip
gMC.x = ((2 * x + 1) << 12) + gMC.hit.left;
//Halt momentum
if (gMC.xm < -0x180)
gMC.xm = -0x180;
if (!(gKey & gKeyLeft) && gMC.xm < 0)
gMC.xm = 0;
//Set that a left wall was hit
hit |= 1;
}
//Right wall
if (gMC.y - gMC.hit.top < (2 * (2 * y + 1) - 1) << 11
&& gMC.y + gMC.hit.bottom > (2 * (2 * y - 1) + 1) << 11
&& gMC.x + gMC.hit.right > (2 * x - 1) << 12
&& gMC.x + gMC.hit.left < x << 13)
{
//Clip
gMC.x = ((2 * x - 1) << 12) - gMC.hit.right;
//Halt momentum
if (gMC.xm > 0x180)
gMC.xm = 0x180;
if (!(gKey & gKeyRight) && gMC.xm > 0)
gMC.xm = 0;
//Set that a right wall was hit
hit |= 4;
}
//Ceiling
if (gMC.x - gMC.hit.right < ((2 * x + 1) << 12) - 0x600
&& gMC.x + gMC.hit.right > ((2 * x - 1) << 12) + 0x600
&& gMC.y - gMC.hit.top < (2 * y + 1) << 12
&& gMC.y - gMC.hit.top > y << 13)
{
//Clip
gMC.y = ((2 * y + 1) << 12) + gMC.hit.top;
//Halt momentum
if (!(gMC.cond & 2) && gMC.ym < -0x200)
PutlittleStar();
if (gMC.ym < 0)
gMC.ym = 0;
//Set that a ceiling was hit
hit |= 2;
}
//Floor
if (gMC.x - gMC.hit.right < ((2 * x + 1) << 12) - 0x600
&& gMC.x + gMC.hit.right > ((2 * x - 1) << 12) + 0x600
&& gMC.y + gMC.hit.bottom > (2 * y - 1) << 12
&& gMC.y + gMC.hit.bottom < y << 13)
{
//Clip
gMC.y = ((2 * y - 1) << 12) - gMC.hit.bottom;
//Halt momentum
if (gMC.ym > 0x400)
PlaySoundObject(23, 1);
if (gMC.ym > 0)
gMC.ym = 0;
//Set that a floor was hit
hit |= 8;
}
return hit;
}
int JudgeHitMyCharTriangleA(int x, int y)
{
int hit = 0;
if (gMC.x < (2 * x + 1) << 12
&& gMC.x > (2 * x - 1) << 12
&& gMC.y - gMC.hit.top < (y << 13) - (-0x2000 * x + gMC.x) / 2 + 0x800
&& gMC.y + gMC.hit.bottom > (2 * y - 1) << 12)
{
//Clip
gMC.y = (y << 13) - (-0x2000 * x + gMC.x) / 2 + 0x800 + gMC.hit.top;
//Halt momentum
if (!(gMC.cond & 2) && gMC.ym < -0x200)
PutlittleStar();
if (gMC.ym < 0)
gMC.ym = 0;
//Set that hit a ceiling
hit |= 2;
}
return hit;
}
int JudgeHitMyCharTriangleB(int x, int y)
{
int hit = 0;
if (gMC.x < (2 * x + 1) << 12
&& gMC.x > (2 * x - 1) << 12
&& gMC.y - gMC.hit.top < (y << 13) - (-0x2000 * x + gMC.x) / 2 - 0x800
&& gMC.y + gMC.hit.bottom > (2 * y - 1) << 12)
{
//Clip
gMC.y = (y << 13) - (-0x2000 * x + gMC.x) / 2 - 0x800 + gMC.hit.top;
//Halt momentum
if (!(gMC.cond & 2) && gMC.ym < -0x200)
PutlittleStar();
if (gMC.ym < 0)
gMC.ym = 0;
//Set that hit a ceiling
hit |= 2;
}
return hit;
}
int JudgeHitMyCharTriangleC(int x, int y)
{
int hit = 0;
if (gMC.x < (2 * x + 1) << 12
&& gMC.x > (2 * x - 1) << 12
&& gMC.y - gMC.hit.top < (y << 13) + (-0x2000 * x + gMC.x) / 2 - 0x800
&& gMC.y + gMC.hit.bottom > (2 * y - 1) << 12)
{
//Clip
gMC.y = (y << 13) - (-0x2000 * x + gMC.x) / 2 - 0x800 + gMC.hit.top;
//Halt momentum
if (!(gMC.cond & 2) && gMC.ym < -0x200)
PutlittleStar();
if (gMC.ym < 0)
gMC.ym = 0;
//Set that hit a ceiling
hit |= 2;
}
return hit;
}
int JudgeHitMyCharTriangleD(int x, int y)
{
int hit = 0;
if (gMC.x < (2 * x + 1) << 12
&& gMC.x > (2 * x - 1) << 12
&& gMC.y - gMC.hit.top < (y << 13) + (-0x2000 * x + gMC.x) / 2 + 0x800
&& gMC.y + gMC.hit.bottom > (2 * y - 1) << 12)
{
//Clip
gMC.y = (y << 13) + (-0x2000 * x + gMC.x) / 2 + 0x800 + gMC.hit.top;
//Halt momentum
if (!(gMC.cond & 2) && gMC.ym < -0x200)
PutlittleStar();
if (gMC.ym < 0)
gMC.ym = 0;
//Set that hit a ceiling
hit |= 2;
}
return hit;
}
int JudgeHitMyCharTriangleE(int x, int y)
{
int hit = 0x10000;
if (gMC.x < (2 * x + 1) << 12
&& gMC.x > (2 * x - 1) << 12
&& gMC.y + gMC.hit.bottom > (y << 13) + (-0x2000 * x + gMC.x) / 2 - 0x800
&& gMC.y - gMC.hit.top < (2 * y + 1) << 12)
{
//Clip
gMC.y = (y << 13) + (-0x2000 * x + gMC.x) / 2 - 0x800 - gMC.hit.bottom;
//Halt momentum
if (gMC.ym > 0x400)
PlaySoundObject(23, 1);
if (gMC.ym > 0)
gMC.ym = 0;
//Set that hit this slope
hit = 0x10028;
}
return hit;
}
int JudgeHitMyCharTriangleF(int x, int y)
{
int hit = 0x20000;
if (gMC.x < (2 * x + 1) << 12
&& gMC.x > (2 * x - 1) << 12
&& gMC.y + gMC.hit.bottom > (y << 13) + (-0x2000 * x + gMC.x) / 2 + 0x800
&& gMC.y - gMC.hit.top < (2 * y + 1) << 12)
{
//Clip
gMC.y = (y << 13) + (-0x2000 * x + gMC.x) / 2 + 0x800 - gMC.hit.bottom;
//Halt momentum
if (gMC.ym > 0x400)
PlaySoundObject(23, 1);
if (gMC.ym > 0)
gMC.ym = 0;
//Set that hit this slope
hit = 0x20028;
}
return hit;
}
int JudgeHitMyCharTriangleG(int x, int y)
{
int hit = 0x40000;
if (gMC.x < (2 * x + 1) << 12
&& gMC.x > (2 * x - 1) << 12
&& gMC.y + gMC.hit.bottom > (y << 13) - (-0x2000 * x + gMC.x) / 2 + 0x800
&& gMC.y - gMC.hit.top < (2 * y + 1) << 12)
{
//Clip
gMC.y = (y << 13) - (-0x2000 * x + gMC.x) / 2 + 0x800 - gMC.hit.bottom;
//Halt momentum
if (gMC.ym > 0x400)
PlaySoundObject(23, 1);
if (gMC.ym > 0)
gMC.ym = 0;
//Set that hit this slope
hit = 0x40018;
}
return hit;
}
int JudgeHitMyCharTriangleH(int x, int y)
{
int hit = 0x80000;
if (gMC.x < (2 * x + 1) << 12
&& gMC.x > (2 * x - 1) << 12
&& gMC.y + gMC.hit.bottom > (y << 13) - (-0x2000 * x + gMC.x) / 2 - 0x800
&& gMC.y - gMC.hit.top < (2 * y + 1) << 12)
{
//Clip
gMC.y = (y << 13) - (-0x2000 * x + gMC.x) / 2 - 0x800 - gMC.hit.bottom;
//Halt momentum
if (gMC.ym > 0x400)
PlaySoundObject(23, 1);
if (gMC.ym > 0)
gMC.ym = 0;
//Set that hit this slope
hit = 0x80018;
}
return hit;
}
int JudgeHitMyCharWater(int x, int y)
{
int hit = 0;
if (gMC.x - gMC.hit.right < ((2 * x + 1) << 12) - 0x600
&& gMC.x + gMC.hit.right > ((2 * x - 1) << 12) + 0x600
&& gMC.y - gMC.hit.top < ((2 * y + 1) << 12) - 0x600
&& gMC.y + gMC.hit.bottom > y << 13)
hit = 0x100;
return hit;
}
int JudgeHitMyCharDamage(int x, int y)
{
int hit = 0;
if (gMC.x - 0x800 < (4 * x + 1) << 11
&& gMC.x + 0x800 > (4 * x - 1) << 11
&& gMC.y - 0x800 < (y << 13) + 0x600
&& gMC.y + 0x800 > (y << 13) - 0x600)
hit = 0x400;
return hit;
}
int JudgeHitMyCharDamageW(int x, int y)
{
int hit = 0;
if (gMC.x - 0x800 < (4 * x + 1) << 11
&& gMC.x + 0x800 > (4 * x - 1) << 11
&& gMC.y - 0x800 < (y << 13) + 0x600
&& gMC.y + 0x800 > (y << 13) - 0x600)
hit = 0xD00;
return hit;
}
int JudgeHitMyCharVectLeft(int x, int y)
{
int hit = 0;
if (gMC.x - gMC.hit.right < (4 * (2 * x + 1) - 1) << 10
&& gMC.x + gMC.hit.right > (4 * (2 * x - 1) + 1) << 10
&& gMC.y - gMC.hit.top < (4 * (2 * y + 1) - 1) << 10
&& gMC.y + gMC.hit.bottom > (4 * (2 * y - 1) + 1) << 10)
hit = 0x1000;
return hit;
}
int JudgeHitMyCharVectUp(int x, int y)
{
int hit = 0;
if (gMC.x - gMC.hit.right < (4 * (2 * x + 1) - 1) << 10
&& gMC.x + gMC.hit.right > (4 * (2 * x - 1) + 1) << 10
&& gMC.y - gMC.hit.top < (4 * (2 * y + 1) - 1) << 10
&& gMC.y + gMC.hit.bottom > (4 * (2 * y - 1) + 1) << 10)
hit = 0x2000;
return hit;
}
int JudgeHitMyCharVectRight(int x, int y)
{
int hit = 0;
if (gMC.x - gMC.hit.right < (4 * (2 * x + 1) - 1) << 10
&& gMC.x + gMC.hit.right > (4 * (2 * x - 1) + 1) << 10
&& gMC.y - gMC.hit.top < (4 * (2 * y + 1) - 1) << 10
&& gMC.y + gMC.hit.bottom > (4 * (2 * y - 1) + 1) << 10)
hit = 0x4000;
return hit;
}
int JudgeHitMyCharVectDown(int x, int y)
{
int hit = 0;
if (gMC.x - gMC.hit.right < (4 * (2 * x + 1) - 1) << 10
&& gMC.x + gMC.hit.right > (4 * (2 * x - 1) + 1) << 10
&& gMC.y - gMC.hit.top < (4 * (2 * y + 1) - 1) << 10
&& gMC.y + gMC.hit.bottom > (4 * (2 * y - 1) + 1) << 10)
hit = 0x8000;
return hit;
}
void HitMyCharMap()
{
int x = gMC.x / 0x2000;
int y = gMC.y / 0x2000;
int offy[4];
int offx[4];
offx[0] = 0;
offx[1] = 1;
offx[2] = 0;
offx[3] = 1;
offy[0] = 0;
offy[1] = 0;
offy[2] = 1;
offy[3] = 1;
uint8_t atrb[4];
for (int i = 0; i < 4; i++)
{
atrb[i] = GetAttribute(x + offx[i], y + offy[i]);
switch (atrb[i])
{
//Water
case 0x02:
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
//Block
case 0x05:
case 0x41:
case 0x43:
case 0x46:
gMC.flag |= JudgeHitMyCharBlock(x + offx[i], y + offy[i]);
break;
//Slopes
case 0x50:
gMC.flag |= JudgeHitMyCharTriangleA(x + offx[i], y + offy[i]);
break;
case 0x51:
gMC.flag |= JudgeHitMyCharTriangleB(x + offx[i], y + offy[i]);
break;
case 0x52:
gMC.flag |= JudgeHitMyCharTriangleC(x + offx[i], y + offy[i]);
break;
case 0x53:
gMC.flag |= JudgeHitMyCharTriangleD(x + offx[i], y + offy[i]);
break;
case 0x54:
gMC.flag |= JudgeHitMyCharTriangleE(x + offx[i], y + offy[i]);
break;
case 0x55:
gMC.flag |= JudgeHitMyCharTriangleF(x + offx[i], y + offy[i]);
break;
case 0x56:
gMC.flag |= JudgeHitMyCharTriangleG(x + offx[i], y + offy[i]);
break;
case 0x57:
gMC.flag |= JudgeHitMyCharTriangleH(x + offx[i], y + offy[i]);
break;
//Water and water blocks
case 0x60:
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
case 0x61:
gMC.flag |= JudgeHitMyCharBlock(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
//Spikes
case 0x62:
gMC.flag |= JudgeHitMyCharDamageW(x + offx[i], y + offy[i]);
break;
//Water slopes
case 0x70:
gMC.flag |= JudgeHitMyCharTriangleA(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
case 0x71:
gMC.flag |= JudgeHitMyCharTriangleB(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
case 0x72:
gMC.flag |= JudgeHitMyCharTriangleC(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
case 0x73:
gMC.flag |= JudgeHitMyCharTriangleD(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
case 0x74:
gMC.flag |= JudgeHitMyCharTriangleE(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
case 0x75:
gMC.flag |= JudgeHitMyCharTriangleF(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
case 0x76:
gMC.flag |= JudgeHitMyCharTriangleG(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
case 0x77:
gMC.flag |= JudgeHitMyCharTriangleH(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
//Wind
case 0x80:
gMC.flag |= JudgeHitMyCharVectLeft(x + offx[i], y + offy[i]);
break;
case 0x81:
gMC.flag |= JudgeHitMyCharVectUp(x + offx[i], y + offy[i]);
break;
case 0x82:
gMC.flag |= JudgeHitMyCharVectRight(x + offx[i], y + offy[i]);
break;
case 0x83:
gMC.flag |= JudgeHitMyCharVectDown(x + offx[i], y + offy[i]);
break;
//Water current
case 0xA0:
gMC.flag |= JudgeHitMyCharVectLeft(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
case 0xA1:
gMC.flag |= JudgeHitMyCharVectUp(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
case 0xA2:
gMC.flag |= JudgeHitMyCharVectRight(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
case 0xA3:
gMC.flag |= JudgeHitMyCharVectDown(x + offx[i], y + offy[i]);
gMC.flag |= JudgeHitMyCharWater(x + offx[i], y + offy[i]);
break;
default:
break;
}
}
if (gMC.y > gWaterY + 0x800)
gMC.flag |= 0x100;
}

3
src/MycHit.h Normal file
View file

@ -0,0 +1,3 @@
#pragma once
void ResetMyCharFlag();
void HitMyCharMap();

7
src/NpcAct.h Normal file
View file

@ -0,0 +1,7 @@
#include "NpChar.h"
void ActNpc000(NPCHAR *npc);
void ActNpc001(NPCHAR *npc);
void ActNpc002(NPCHAR *npc);
void ActNpc003(NPCHAR *npc);
void ActNpc004(NPCHAR *npc);
void ActNpc005(NPCHAR *npc);

486
src/NpcAct000.cpp Normal file
View file

@ -0,0 +1,486 @@
#include "WindowsWrapper.h"
#include "MyChar.h"
#include "NpChar.h"
#include "Game.h"
#include "Sound.h"
#include "Back.h"
#include "Triangle.h"
//Null
void ActNpc000(NPCHAR *npc)
{
if (!npc->act_no)
{
npc->act_no = 1;
if (npc->direct == 2)
npc->y += 0x2000;
}
npc->rect = {0, 0, 16, 16};
}
//Experience
void ActNpc001(NPCHAR *npc)
{
//When not in wind
if (gBack.type != 5 && gBack.type != 6)
{
if (!npc->act_no)
{
//Set state
npc->act_no = 1;
npc->ani_no = Random(0, 4);
//Random speed
npc->xm = Random(-0x200, 0x200);
npc->ym = Random(-0x400, 0);
//Random direction (reverse animation or not)
if (Random(0, 1) != 0)
npc->direct = 0;
else
npc->direct = 2;
}
//Gravity
if (npc->flag & 0x100)
npc->ym += 21;
else
npc->ym += 42;
//Bounce off walls
if (npc->flag & 1 && npc->xm < 0)
npc->xm = -npc->xm;
if (npc->flag & 4 && npc->xm > 0)
npc->xm = -npc->xm;
//Bounce off ceiling
if (npc->flag & 2 && npc->ym < 0)
npc->ym = -npc->ym;
//Bounce off floor
if (npc->flag & 8)
{
PlaySoundObject(45, 1);
npc->ym = -0x280;
npc->xm = 2 * npc->xm / 3;
}
//Play bounce song (and try to clip out of floor if stuck)
if (npc->flag & 0xD)
{
PlaySoundObject(45, 1);
if (++npc->count2 > 2)
npc->y -= 512;
}
else
{
npc->count2 = 0;
}
//Limit speed
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;
}
//In wind
else
{
if (!npc->act_no)
{
//Set state
npc->act_no = 1;
//Set random speed
npc->ym = Random(-0x80, 0x80);
npc->xm = Random(0x7F, 0x100);
}
//Blow to the left
npc->xm -= 8;
//Destroy when off-screen
if (npc->x <= 0x9FFF)
npc->cond = 0;
//Limit speed (except pixel applied it to the X position)
if (npc->x < -0x5FF)
npc->x = -0x5FF;
//Bounce off walls
if (npc->flag & 1)
npc->xm = 0x100;
if (npc->flag & 2)
npc->ym = 0x40;
if (npc->flag & 8)
npc->ym = -0x40;
}
//Move
npc->x += npc->xm;
npc->y += npc->ym;
//Get framerects
RECT rect[6];
rect[0] = {0x00, 0x10, 0x10, 0x20};
rect[1] = {0x10, 0x10, 0x20, 0x20};
rect[2] = {0x20, 0x10, 0x30, 0x20};
rect[3] = {0x30, 0x10, 0x40, 0x20};
rect[4] = {0x40, 0x10, 0x50, 0x20};
rect[5] = {0x50, 0x10, 0x60, 0x20};
RECT rcNo = {0, 0, 0, 0};
//Animate
++npc->ani_wait;
if (npc->direct)
{
if (npc->ani_wait > 2)
{
npc->ani_wait = 0;
if (--npc->ani_no < 0)
npc->ani_no = 5;
}
}
else if (npc->ani_wait > 2)
{
npc->ani_wait = 0;
if (++npc->ani_no > 5)
npc->ani_no = 0;
}
npc->rect = rect[npc->ani_no];
//Size
if (npc->act_no)
{
if (npc->exp == 5)
{
npc->rect.top += 16;
npc->rect.bottom += 16;
}
else if (npc->exp == 20)
{
npc->rect.top += 32;
npc->rect.bottom += 32;
}
npc->act_no = 1;
}
//Delete after 500 frames
if (++npc->count1 > 500 && npc->ani_no == 5 && npc->ani_wait == 2)
npc->cond = 0;
//Blink after 400 frames
if (npc->count1 > 400)
{
if (npc->count1 / 2 & 1)
npc->rect = rcNo;
}
}
//Behemoth
void ActNpc002(NPCHAR *npc)
{
//Rects
RECT rcLeft[7];
rcLeft[0] = {32, 0, 64, 24};
rcLeft[1] = {0, 0, 32, 24};
rcLeft[2] = {32, 0, 64, 24};
rcLeft[3] = {64, 0, 96, 24};
rcLeft[4] = {96, 0, 128, 24};
rcLeft[5] = {128, 0, 160, 24};
rcLeft[6] = {160, 0, 192, 24};
RECT rcUp[7];
rcUp[0] = {32, 24, 64, 48};
rcUp[1] = {0, 24, 32, 48};
rcUp[2] = {32, 24, 64, 48};
rcUp[3] = {64, 24, 96, 48};
rcUp[4] = {96, 24, 128, 48};
rcUp[5] = {128, 24, 160, 48};
rcUp[6] = {160, 24, 192, 48};
//Turn when touching a wall
if (npc->flag & 1)
npc->direct = 2;
else if (npc->flag & 4)
npc->direct = 0;
switch (npc->act_no)
{
case 1: //Shot
npc->xm = 7 * npc->xm / 8;
if (++npc->count1 > 40)
{
if (npc->shock)
{
npc->count1 = 0;
npc->act_no = 2;
npc->ani_no = 6;
npc->ani_wait = 0;
npc->damage = 5;
}
else
{
npc->act_no = 0;
npc->ani_wait = 0;
}
}
break;
case 2: //Charge
if (npc->direct)
npc->xm = 0x400;
else
npc->xm = -0x400;
if (++npc->count1 > 200)
{
npc->act_no = 0;
npc->damage = 1;
}
if (++npc->ani_wait > 5)
{
npc->ani_wait = 0;
++npc->ani_no;
}
if (npc->ani_no > 6)
npc->ani_no = 5;
break;
case 0: //Walking
if (npc->direct)
npc->xm = 0x100;
else
npc->xm = -0x100;
if (++npc->ani_wait > 8)
{
npc->ani_wait = 0;
++npc->ani_no;
}
if (npc->ani_no > 3)
npc->ani_no = 0;
if (npc->shock)
{
npc->count1 = 0;
npc->act_no = 1;
npc->ani_no = 4;
}
break;
}
//Gravity
npc->ym += 0x40;
if (npc->ym > 0x5FF)
npc->ym = 0x5FF;
//Move
npc->x += npc->xm;
npc->y += npc->ym;
//Set framerect
if (npc->direct)
npc->rect = rcUp[npc->ani_no];
else
npc->rect = rcLeft[npc->ani_no];
}
//Dead enemy (make sure damage shown doesn't teleport to a new loaded npc)
void ActNpc003(NPCHAR *npc)
{
if (++npc->count1 > 100)
npc->cond = 0;
npc->rect = {0, 0, 0, 0};
}
//Smoke
void ActNpc004(NPCHAR *npc)
{
RECT rcLeft[8];
RECT rcUp[8];
rcLeft[0] = {16, 0, 17, 1};
rcLeft[1] = {16, 0, 32, 16};
rcLeft[2] = {32, 0, 48, 16};
rcLeft[3] = {48, 0, 64, 16};
rcLeft[4] = {64, 0, 80, 16};
rcLeft[5] = {80, 0, 96, 16};
rcLeft[6] = {96, 0, 112, 16};
rcLeft[7] = {112, 0, 128, 16};
rcUp[0] = {16, 0, 17, 1};
rcUp[1] = {80, 48, 96, 64};
rcUp[2] = {0, 128, 16, 144};
rcUp[3] = {16, 128, 32, 144};
rcUp[4] = {32, 128, 48, 144};
rcUp[5] = {48, 128, 64, 144};
rcUp[6] = {64, 128, 80, 144};
rcUp[7] = {80, 128, 96, 144};
if (npc->act_no)
{
//Slight drag
npc->xm = 20 * npc->xm / 21;
npc->ym = 20 * npc->ym / 21;
//Move
npc->x += npc->xm;
npc->y += npc->ym;
}
else
{
//Move in random direction at random speed
if (!npc->direct || npc->direct == 1)
{
uint8_t deg = Random(0, 0xFF);
npc->xm = GetCos(deg) * Random(0x200, 0x5FF) / 0x200;
npc->ym = GetSin(deg) * Random(0x200, 0x5FF) / 0x200;
}
//Set state
npc->ani_no = Random(0, 4);
npc->ani_wait = Random(0, 3);
npc->act_no = 1;
}
//Animate
if (++npc->ani_wait > 4)
{
npc->ani_wait = 0;
npc->ani_no++;
}
//Set framerect
if (npc->ani_no < 8)
{
if (npc->direct == 1)
npc->rect = rcUp[npc->ani_no];
if (!npc->direct)
npc->rect = rcLeft[npc->ani_no];
if (npc->direct == 2)
npc->rect = rcLeft[npc->ani_no];
}
else
{
//Destroy if over
npc->cond = 0;
}
}
//Critter (Green, Egg Corridor)
void ActNpc005(NPCHAR *npc)
{
RECT rcLeft[3];
RECT rcRight[3];
rcLeft[0] = {0, 48, 16, 64};
rcLeft[1] = {16, 48, 32, 64};
rcLeft[2] = {32, 48, 48, 64};
rcRight[0] = {0, 64, 16, 80};
rcRight[1] = {16, 64, 32, 80};
rcRight[2] = {32, 64, 48, 80};
switch (npc->act_no)
{
case 0: //Init
npc->y += 0x600;
npc->act_no = 1;
case 1: //Waiting
//Look at player
if (npc->x <= gMC.x)
npc->direct = 2;
else
npc->direct = 0;
//Open eyes near player
if (npc->act_wait < 8 || npc->x - 0xE000 >= gMC.x || npc->x + 0xE000 <= gMC.x || npc->y - 0xA000 >= gMC.y || npc->y + 0xA000 <= gMC.y)
{
if (npc->act_wait < 8)
++npc->act_wait;
npc->ani_no = 0;
}
else
{
npc->ani_no = 1;
}
//Jump if attacked
if (npc->shock)
{
npc->act_no = 2;
npc->ani_no = 0;
npc->act_wait = 0;
}
//Jump if player is nearby
if (npc->act_wait >= 8 && npc->x - 0x6000 < gMC.x && npc->x + 0x6000 > gMC.x && npc->y - 0xA000 < gMC.y && npc->y + 0x6000 > gMC.y)
{
npc->act_no = 2;
npc->ani_no = 0;
npc->act_wait = 0;
}
break;
case 2: //Going to jump
if (++npc->act_wait > 8)
{
//Set jump state
npc->act_no = 3;
npc->ani_no = 2;
//Jump
npc->ym = -0x5FF;
PlaySoundObject(30, 1);
//Jump in facing direction
if (npc->direct)
npc->xm = 0x100;
else
npc->xm = -0x100;
}
break;
case 3: //Jumping
//Land
if (npc->flag & 8)
{
npc->xm = 0;
npc->act_wait = 0;
npc->ani_no = 0;
npc->act_no = 1;
PlaySoundObject(23, 1);
}
break;
}
//Gravity
npc->ym += 64;
if (npc->ym > 0x5FF)
npc->ym = 0x5FF;
//Move
npc->x += npc->xm;
npc->y += npc->ym;
//Set framerect
if (npc->direct)
npc->rect = rcRight[npc->ani_no];
else
npc->rect = rcLeft[npc->ani_no];
}

401
src/NpcHit.cpp Normal file
View file

@ -0,0 +1,401 @@
#include "NpChar.h"
#include "Map.h"
void JadgeHitNpCharBlock(NPCHAR *npc, int x, int y)
{
int hit = 0;
if (npc->y - npc->hit.top < ((2 * y + 1) << 12) - 0x600
&& npc->y + npc->hit.bottom > ((2 * y - 1) << 12) + 0x600
&& npc->x - npc->hit.back < (2 * x + 1) << 12
&& npc->x - npc->hit.back > x << 13)
{
npc->x = ((2 * x + 1) << 12) + npc->hit.back;
hit |= 1;
}
if (npc->y - npc->hit.top < ((2 * y + 1) << 12) - 0x600
&& npc->y + npc->hit.bottom > ((2 * y - 1) << 12) + 0x600
&& npc->hit.back + npc->x > (2 * x - 1) << 12
&& npc->hit.back + npc->x < x << 13)
{
npc->x = ((2 * x - 1) << 12) - npc->hit.back;
hit |= 4;
}
if (npc->x - npc->hit.back < ((2 * x + 1) << 12) - 0x600
&& npc->hit.back + npc->x > ((2 * x - 1) << 12) + 0x600
&& npc->y - npc->hit.top < (2 * y + 1) << 12
&& npc->y - npc->hit.top > y << 13)
{
npc->y = ((2 * y + 1) << 12) + npc->hit.top;
npc->ym = 0;
hit |= 2;
}
if (npc->x - npc->hit.back < ((2 * x + 1) << 12) - 0x600
&& npc->hit.back + npc->x > ((2 * x - 1) << 12) + 0x600
&& npc->y + npc->hit.bottom > (2 * y - 1) << 12
&& npc->y + npc->hit.bottom < y << 13)
{
npc->y = ((2 * y - 1) << 12) - npc->hit.bottom;
npc->ym = 0;
hit |= 8;
}
npc->flag |= hit;
}
void JudgeHitNpCharTriangleA(NPCHAR *npc, int x, int y)
{
int hit = 0;
if (npc->x < (2 * x + 1) << 12
&& npc->x > (2 * x - 1) << 12
&& npc->y - npc->hit.top < (y << 13) - (-0x2000 * x + npc->x) / 2 + 0x800
&& npc->y + npc->hit.bottom > (2 * y - 1) << 12)
{
//Clip
npc->y = npc->hit.top + (y << 13) - (-0x2000 * x + npc->x) / 2 + 0x800;
//Halt momentum
if (npc->ym < 0)
npc->ym = 0;
//Set that hit a ceiling
hit = 2;
}
npc->flag |= hit;
}
void JudgeHitNpCharTriangleB(NPCHAR *npc, int x, int y)
{
int hit = 0;
if (npc->x < (2 * x + 1) << 12
&& npc->x > (2 * x - 1) << 12
&& npc->y - npc->hit.top < (y << 13) - (-0x2000 * x + npc->x) / 2 - 0x800
&& npc->y + npc->hit.bottom > (2 * y - 1) << 12)
{
//Clip
npc->y = npc->hit.top + (y << 13) - (-0x2000 * x + npc->x) / 2 - 0x800;
//Halt momentum
if (npc->ym < 0)
npc->ym = 0;
//Set that hit a ceiling
hit = 2;
}
npc->flag |= hit;
}
void JudgeHitNpCharTriangleC(NPCHAR *npc, int x, int y)
{
int hit = 0;
if (npc->x < (2 * x + 1) << 12
&& npc->x > (2 * x - 1) << 12
&& npc->y - npc->hit.top < (y << 13) + (-0x2000 * x + npc->x) / 2 - 0x800
&& npc->y + npc->hit.bottom > (2 * y - 1) << 12)
{
//Clip
npc->y = npc->hit.top + (y << 13) + (-0x2000 * x + npc->x) / 2 - 0x800;
//Halt momentum
if (npc->ym < 0)
npc->ym = 0;
//Set that hit a ceiling
hit = 2;
}
npc->flag |= hit;
}
void JudgeHitNpCharTriangleD(NPCHAR *npc, int x, int y)
{
int hit = 0;
if (npc->x < (2 * x + 1) << 12
&& npc->x > (2 * x - 1) << 12
&& npc->y - npc->hit.top < (y << 13) + (-0x2000 * x + npc->x) / 2 + 0x800
&& npc->y + npc->hit.bottom > (2 * y - 1) << 12)
{
//Clip
npc->y = npc->hit.top + (y << 13) + (-0x2000 * x + npc->x) / 2 + 0x800;
//Halt momentum
if (npc->ym < 0)
npc->ym = 0;
//Set that hit a ceiling
hit = 2;
}
npc->flag |= hit;
}
void JudgeHitNpCharTriangleE(NPCHAR *npc, int x, int y)
{
int hit = 0x10000;
if ( npc->x < (2 * x + 1) << 12
&& npc->x > (2 * x - 1) << 12
&& npc->y + npc->hit.bottom > (y << 13) + (-0x2000 * x + npc->x) / 2 - 0x800
&& npc->y - npc->hit.top < (2 * y + 1) << 12 )
{
//Clip
npc->y = (y << 13) + (-0x2000 * x + npc->x) / 2 - 0x800 - npc->hit.bottom;
//Halt momentum
if (npc->ym > 0)
npc->ym = 0;
//Set that hit this slope
hit = 0x10028;
}
npc->flag |= hit;
}
void JudgeHitNpCharTriangleF(NPCHAR *npc, int x, int y)
{
int hit = 0x20000;
if ( npc->x < (2 * x + 1) << 12
&& npc->x > (2 * x - 1) << 12
&& npc->y + npc->hit.bottom > (y << 13) + (-0x2000 * x + npc->x) / 2 + 0x800
&& npc->y - npc->hit.top < (2 * y + 1) << 12 )
{
//Clip
npc->y = (y << 13) + (-0x2000 * x + npc->x) / 2 + 0x800 - npc->hit.bottom;
//Halt momentum
if (npc->ym > 0)
npc->ym = 0;
//Set that hit this slope
hit = 0x20028;
}
npc->flag |= hit;
}
void JudgeHitNpCharTriangleG(NPCHAR *npc, int x, int y)
{
int hit = 0x40000;
if ( npc->x < (2 * x + 1) << 12
&& npc->x > (2 * x - 1) << 12
&& npc->y + npc->hit.bottom > (y << 13) - (-0x2000 * x + npc->x) / 2 + 0x800
&& npc->y - npc->hit.top < (2 * y + 1) << 12 )
{
//Clip
npc->y = (y << 13) - (-0x2000 * x + npc->x) / 2 + 0x800 - npc->hit.bottom;
//Halt momentum
if (npc->ym > 0)
npc->ym = 0;
//Set that hit this slope
hit = 0x40018;
}
npc->flag |= hit;
}
void JudgeHitNpCharTriangleH(NPCHAR *npc, int x, int y)
{
int hit = 0x80000;
if ( npc->x < (2 * x + 1) << 12
&& npc->x > (2 * x - 1) << 12
&& npc->y + npc->hit.bottom > (y << 13) - (-0x2000 * x + npc->x) / 2 - 0x800
&& npc->y - npc->hit.top < (2 * y + 1) << 12 )
{
//Clip
npc->y = (y << 13) - (-0x2000 * x + npc->x) / 2 - 0x800 - npc->hit.bottom;
//Halt momentum
if (npc->ym > 0)
npc->ym = 0;
//Set that hit this slope
hit = 0x80018;
}
npc->flag |= hit;
}
void JudgeHitNpCharWater(NPCHAR *npc, int x, int y)
{
int hit = 0;
if (npc->x - npc->hit.back < (4 * (2 * x + 1) - 1) << 10
&& npc->hit.back + npc->x > (4 * (2 * x - 1) + 1) << 10
&& npc->y - npc->hit.top < (4 * (2 * y + 1) - 1) << 10
&& npc->y + npc->hit.bottom > (4 * (2 * y - 1) + 1) << 10)
hit = 0x100;
npc->flag |= hit;
}
void HitNpCharMap()
{
int offy[9];
int offx[9];
offx[0] = 0;
offx[1] = 1;
offx[2] = 0;
offx[3] = 1;
offx[4] = 2;
offx[5] = 2;
offx[6] = 2;
offx[7] = 0;
offx[8] = 1;
offy[0] = 0;
offy[1] = 0;
offy[2] = 1;
offy[3] = 1;
offy[4] = 0;
offy[5] = 1;
offy[6] = 2;
offy[7] = 2;
offy[8] = 2;
for (int i = 0; i < NPC_MAX; i++)
{
if ((gNPC[i].cond & 0x80) && !(gNPC[i].bits & 8))
{
int judg, x, y;
if (gNPC[i].size <= 2)
{
judg = 4;
x = gNPC[i].x / 0x2000;
y = gNPC[i].y / 0x2000;
}
else
{
judg = 9;
x = (gNPC[i].x - 0x1000) / 0x2000;
y = (gNPC[i].y - 0x1000) / 0x2000;
}
gNPC[i].flag = 0;
for (int j = 0; j < judg; j++)
{
switch (GetAttribute(x + offx[j], y + offy[j]))
{
//Water
case 0x02:
case 0x60:
case 0x62:
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
//Block
case 0x03:
case 0x05:
case 0x41:
case 0x43:
JadgeHitNpCharBlock(&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;
//No NPC block
case 0x44:
if (!(gNPC[i].bits & npc_ignore44))
JadgeHitNpCharBlock(&gNPC[i], x + offx[j], y + offy[j]);
break;
//Slopes
case 0x50:
JudgeHitNpCharTriangleA(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x51:
JudgeHitNpCharTriangleB(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x52:
JudgeHitNpCharTriangleC(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x53:
JudgeHitNpCharTriangleD(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x54:
JudgeHitNpCharTriangleE(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x55:
JudgeHitNpCharTriangleF(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x56:
JudgeHitNpCharTriangleG(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x57:
JudgeHitNpCharTriangleH(&gNPC[i], x + offx[j], y + offy[j]);
break;
//Water slopes
case 0x70:
JudgeHitNpCharTriangleA(&gNPC[i], x + offx[j], y + offy[j]);
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x71:
JudgeHitNpCharTriangleB(&gNPC[i], x + offx[j], y + offy[j]);
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x72:
JudgeHitNpCharTriangleC(&gNPC[i], x + offx[j], y + offy[j]);
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x73:
JudgeHitNpCharTriangleD(&gNPC[i], x + offx[j], y + offy[j]);
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x74:
JudgeHitNpCharTriangleE(&gNPC[i], x + offx[j], y + offy[j]);
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x75:
JudgeHitNpCharTriangleF(&gNPC[i], x + offx[j], y + offy[j]);
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x76:
JudgeHitNpCharTriangleG(&gNPC[i], x + offx[j], y + offy[j]);
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
case 0x77:
JudgeHitNpCharTriangleH(&gNPC[i], x + offx[j], y + offy[j]);
JudgeHitNpCharWater(&gNPC[i], x + offx[j], y + offy[j]);
break;
}
}
}
}
}

4
src/NpcHit.h Normal file
View file

@ -0,0 +1,4 @@
#pragma once
#include "NpChar.h"
void HitNpCharMap();

View file

@ -3,6 +3,7 @@
#include <SDL_rwops.h>
#include "NpcTbl.h"
#include "NpcAct.h"
NPC_TABLE *gNpcTable;
@ -55,12 +56,12 @@ void ReleaseNpcTable()
//Npc function table
NPCFUNCTION gpNpcFuncTbl[] =
{
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
&ActNpc000,
&ActNpc001,
&ActNpc002,
&ActNpc003,
&ActNpc004,
&ActNpc005,
nullptr,
nullptr,
nullptr,