shithub: cstory

ref: 17b0b503a940ef0cfb70ed1506a3132c0b6146d6
dir: /src/MyChar.cpp/

View raw version
#include <string>
#include <stdint.h>

#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;

void InitMyChar()
{
	memset(&gMC, 0, sizeof(MYCHAR));
	gMC.cond = 0x80;
	gMC.direct = 2;
	gMC.view = {0x1000, 0x1000, 0x1000, 0x1000};
	gMC.hit = {0xA00, 0x1000, 0xA00, 0x1000};
	gMC.life = 3;
	gMC.max_life = 3;
	gMC.unit = 0;
}

void AnimationMyChar(bool bKey)
{
	RECT rcLeft[12];
	RECT rcRight[12];
	
	rcLeft[0] = {0, 0, 16, 16};
	rcLeft[1] = {16, 0, 32, 16};
	rcLeft[2] = {0, 0, 16, 16};
	rcLeft[3] = {32, 0, 48, 16};
	rcLeft[4] = {0, 0, 16, 16};
	rcLeft[5] = {48, 0, 64, 16};
	rcLeft[6] = {64, 0, 80, 16};
	rcLeft[7] = {48, 0, 64, 16};
	rcLeft[8] = {80, 0, 96, 16};
	rcLeft[9] = {48, 0, 64, 16};
	rcLeft[10] = {96, 0, 112, 16};
	rcLeft[11] = {112, 0, 128, 16};

	rcRight[0] = {0, 16, 16, 32};
	rcRight[1] = {16, 16, 32, 32};
	rcRight[2] = {0, 16, 16, 32};
	rcRight[3] = {32, 16, 48, 32};
	rcRight[4] = {0, 16, 16, 32};
	rcRight[5] = {48, 16, 64, 32};
	rcRight[6] = {64, 16, 80, 32};
	rcRight[7] = {48, 16, 64, 32};
	rcRight[8] = {80, 16, 96, 32};
	rcRight[9] = {48, 16, 64, 32};
	rcRight[10] = {96, 16, 112, 32};
	rcRight[11] = {112, 16, 128, 32};
	
	if (!(gMC.cond & 2))
	{
		if (gMC.flag & 8)
		{
			if (gMC.cond & 1)
			{
				gMC.ani_no = 11;
			}
			else if (gKey & gKeyUp && (gKeyRight | gKeyLeft) & gKey && bKey)
			{
				gMC.cond |= 4;
				
				if (++gMC.ani_wait > 4)
				{
					gMC.ani_wait = 0;
					if (++gMC.ani_no == 7 || gMC.ani_no == 9)
						PlaySoundObject(24, 1);
				}
				
				if (gMC.ani_no > 9 || gMC.ani_no < 6)
					gMC.ani_no = 6;
			}
			else if ((gKeyRight | gKeyLeft) & gKey && bKey)
			{
				gMC.cond |= 4;
				
				if (++gMC.ani_wait > 4)
				{
					gMC.ani_wait = 0;
					if (++gMC.ani_no == 2 || gMC.ani_no == 4)
						PlaySoundObject(24, 1);
				}
				
				if (gMC.ani_no > 4 || gMC.ani_no < 1)
					gMC.ani_no = 1;
			}
			else if ( gKey & gKeyUp && bKey )
			{
				if (gMC.cond & 4)
					PlaySoundObject(24, 1);
				
				gMC.cond &= ~4;
				gMC.ani_no = 5;
			}
			else
			{
				if (gMC.cond & 4)
					PlaySoundObject(24, 1);
				
				gMC.cond &= ~4;
				gMC.ani_no = 0;
			}
		}
		else if (gMC.up)
		{
			gMC.ani_no = 6;
		}
		else if (gMC.down)
		{
			gMC.ani_no = 10;
		}
		else if ( gMC.ym <= 0 )
		{
			gMC.ani_no = 3;
		}
		else
		{
			gMC.ani_no = 1;
		}
		
		if (gMC.direct)
			gMC.rect = rcRight[gMC.ani_no];
		else
			gMC.rect = rcLeft[gMC.ani_no];
	}
}

void ShowMyChar(bool bShow)
{
	if (bShow)
		gMC.cond &= ~2;
	else
		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;
	*y = gMC.y;
}

void SetMyCharPosition(int x, int y)
{
	gMC.x = x;
	gMC.y = y;
	gMC.tgt_x = x;
	gMC.tgt_y = y;
	gMC.index_x = 0;
	gMC.index_y = 0;
	gMC.xm = 0;
	gMC.ym = 0;
	gMC.cond &= ~1;
	//InitStar();
}

void MoveMyChar(int x, int y)
{
	gMC.x = x;
	gMC.y = y;
}