diff options
| author | Colin Noga <Tempus@chronometry.ca> | 2012-03-06 21:50:10 -0600 | 
|---|---|---|
| committer | Colin Noga <Tempus@chronometry.ca> | 2012-03-06 21:50:10 -0600 | 
| commit | 19632e9b183402bb9a05030e12d0f1003765c31a (patch) | |
| tree | 36fd2cd8141539e2811ed016f3e2f85de6055eb4 /src | |
| parent | 31fa0c0911000444af0e3b668caf51f061517689 (diff) | |
| download | kamek-19632e9b183402bb9a05030e12d0f1003765c31a.tar.gz kamek-19632e9b183402bb9a05030e12d0f1003765c31a.zip  | |
Improvements to ThwompaDomp, game.h, added Poodle, topman sprite
Diffstat (limited to '')
| -rw-r--r-- | src/bossPodouble.cpp | 706 | ||||
| -rw-r--r-- | src/bossThwompaDomp.cpp | 223 | ||||
| -rw-r--r-- | src/soundPlayer.S | 28 | ||||
| -rw-r--r-- | src/topman.cpp | 480 | 
4 files changed, 1332 insertions, 105 deletions
diff --git a/src/bossPodouble.cpp b/src/bossPodouble.cpp new file mode 100644 index 0000000..663781e --- /dev/null +++ b/src/bossPodouble.cpp @@ -0,0 +1,706 @@ +#include <common.h> +#include <game.h> +#include <g3dhax.h> +#include <sfx.h> +#include <stage.h> +#include "effects.h" +#include "player.h" + +void poodleCollisionCallback(ActivePhysics *apThis, ActivePhysics *apOther);	 + +void poodleCollisionCallback(ActivePhysics *apThis, ActivePhysics *apOther) { +		if (apOther->owner->name == BROS_FIREBALL) { return; } +		else if (apOther->owner->name == BROS_ICEBALL) { return; } +		else { dEn_c::collisionCallback(apThis, apOther); } +	} + +class daPodouble : public dEn_c { +	int onCreate(); +	int onDelete(); +	int onExecute(); +	int onDraw(); + +	mHeapAllocator_c allocator; +	nw4r::g3d::ResFile resFile; + +	m3d::mdl_c bodyModel; +	m3d::mdl_c fogModel; +	m3d::mdl_c fog2Model; + +	m3d::anmTexSrt_c body; + +	m3d::anmChr_c fogChr; +	m3d::anmTexSrt_c fogSRT; + +	m3d::anmChr_c fog2Chr; +	m3d::anmTexSrt_c fog2SRT; + + +	char isFire; +	char goingUp; +	int timer; +	float dying; +	int damage; +	float Baseline; +	char isInvulnerable; +	int countdown; + +	dEn_c *Kameck; + +	static daPodouble *build(); + +	// void spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); +	void playerCollision(ActivePhysics *apThis, ActivePhysics *apOther); +	void yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther); + +	void collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat7_WMWaggleWater(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat7_WMWaggleWaterYoshi(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther); +	bool collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther); + + +	USING_STATES(daPodouble); +	DECLARE_STATE(Bounce); +	DECLARE_STATE(Spit); +	DECLARE_STATE(Damage); + +	DECLARE_STATE(Grow); +	DECLARE_STATE(Outro); +	DECLARE_STATE(SyncDie); + +}; + +daPodouble *daPodouble::build() { +	void *buffer = AllocFromGameHeap1(sizeof(daPodouble)); +	return new(buffer) daPodouble; +} + +/////////////////////// +// Externs and States +/////////////////////// +	extern "C" void *PlaySound(dStageActor_c *, int soundID); +	extern "C" void *PlaySoundAsync(dStageActor_c *, int soundID); + +	extern "C" u32 GenerateRandomNumber(int max); +	extern "C" dStageActor_c *GetSpecificPlayerActor(int num); +	extern "C" int SmoothRotation(short* rot, u16 amt, int unk2); +	extern "C" void* WaterManager; +	extern "C" u32 CheckforLiquid(void*, Vec, int, int, int, int layer); + +	extern "C" void *StopBGMMusic(); +	extern "C" void *StartBGMMusic(); + +	extern "C" void *MakeMarioEnterDemoMode(); +	extern "C" void *MakeMarioExitDemoMode(); +	extern "C" void *UpdateGameMgr(); + + +	CREATE_STATE(daPodouble, Bounce); +	CREATE_STATE(daPodouble, Spit); +	CREATE_STATE(daPodouble, Damage); + +	CREATE_STATE(daPodouble, Grow); +	CREATE_STATE(daPodouble, Outro); +	CREATE_STATE(daPodouble, SyncDie); + + +//////////////////////// +// Collision Functions +//////////////////////// + +	void daPodouble::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) { +		this->dEn_c::playerCollision(apThis, apOther); +		this->_vf220(apOther->owner); + +		// fix multiple player collisions via megazig +		this->isDead = 0; +		this->flags_4FC |= (1<<(31-7)); +		if(apOther->owner->which_player < 3) { +			this->counter_504[apOther->owner->which_player] = 0; +		} +	} + +	void daPodouble::yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther) 					 { this->playerCollision(apThis, apOther); } +	void daPodouble::collisionCat7_WMWaggleWater(ActivePhysics *apThis, ActivePhysics *apOther) 	 { this->playerCollision(apThis, apOther); } +	void daPodouble::collisionCat7_WMWaggleWaterYoshi(ActivePhysics *apThis, ActivePhysics *apOther) { this->playerCollision(apThis, apOther); } +	void daPodouble::collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther)		 { this->playerCollision(apThis, apOther); } + +	void daPodouble::collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther) 	{ return; } +	void daPodouble::collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther) { return; } +	void daPodouble::collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther)		{ return; } + +	void daPodouble::collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther) {	 +		apOther->owner->kill(); +		if (this->isInvulnerable) { return; } + +		this->damage += 2; + +		if (this->damage < 12)  { doStateChange(&StateID_Damage); } +		else 				   { doStateChange(&StateID_Outro); } +	} + +	void daPodouble::collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther){ +		apOther->owner->Delete(1); +		if (this->isInvulnerable) { return; } + +		if (this->isFire == 0) {  +			this->damage += 3;  + +			if (this->damage < 12)  { doStateChange(&StateID_Damage); } +			else 				    { doStateChange(&StateID_Outro); } +		} +	} + +	void daPodouble::collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther) { +		if (this->isInvulnerable) { return; } + +		if (this->isFire == 0) {  +			this->damage += 2;  + +			if (this->damage < 12)  { doStateChange(&StateID_Damage); } +			else 				    { doStateChange(&StateID_Outro); } +		} +	} + +	bool daPodouble::collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther) { +		apOther->owner->Delete(1); +		if (this->isInvulnerable) { return true; } + +		if (this->isFire == 1) {  +			if (apOther->owner->name == 104) { this->damage += 2; } +			else 						     { this->damage += 3; } +		 +			if (this->damage < 12)  { doStateChange(&StateID_Damage); } +			else 				    { doStateChange(&StateID_Outro); } + +			return true; +		} +		else { return false; } +	} + + +int daPodouble::onCreate() { + +	this->isFire = this->settings >> 28; +	this->Baseline = this->pos.y - (float)((this->settings & 0xFF) * 0.8); + + +	OSReport("Creating the Podouble Model\n"); +	allocator.link(-1, GameHeaps[0], 0, 0x20); + +	// Fire or Ice +	if (this->isFire == 1) { +		this->resFile.data = getResource("bubble", "g3d/t00.brres"); +	} +	else { +		this->resFile.data = getResource("bubble", "g3d/t05.brres"); +	} + +	// Body and anms +	nw4r::g3d::ResMdl mdl = this->resFile.GetResMdl("bubble"); +	bodyModel.setup(mdl, &allocator, 0x224, 1, 0); + +	nw4r::g3d::ResAnmTexSrt anmRes = this->resFile.GetResAnmTexSrt("bubble"); +	this->body.setup(mdl, anmRes, &this->allocator, 0, 1); +	this->body.bindEntry(&this->bodyModel, anmRes, 0, 0); +	this->bodyModel.bindAnim(&this->body, 0.0); + + +	// Fog up and anms +	mdl = this->resFile.GetResMdl("bubble_fog"); +	fogModel.setup(mdl, &allocator, 0x124, 1, 0); + +	nw4r::g3d::ResAnmChr anmChr = this->resFile.GetResAnmChr("bubble_fog"); +	this->fogChr.setup(mdl, anmChr, &this->allocator, 0); +	this->fogChr.bind(&this->fogModel, anmChr, 1); +	this->fogModel.bindAnim(&this->fogChr, 0.0); +	this->fogChr.setUpdateRate(1.0); + +	anmRes = this->resFile.GetResAnmTexSrt("bubble_fog"); +	this->fogSRT.setup(mdl, anmRes, &this->allocator, 0, 1); +	this->fogSRT.bindEntry(&this->fogModel, anmRes, 0, 0); +	this->fogModel.bindAnim(&this->fogSRT, 0.0); + + +	// Fog down and anms +	mdl = this->resFile.GetResMdl("bubble_fog2"); +	fog2Model.setup(mdl, &allocator, 0x124, 1, 0); + +	anmChr = this->resFile.GetResAnmChr("bubble_fog2"); +	this->fog2Chr.setup(mdl, anmChr, &this->allocator, 0); +	this->fog2Chr.bind(&this->fog2Model, anmChr, 1); +	this->fogModel.bindAnim(&this->fog2Chr, 0.0); +	this->fog2Chr.setUpdateRate(1.0); + +	anmRes = this->resFile.GetResAnmTexSrt("bubble_fog"); +	this->fog2SRT.setup(mdl, anmRes, &this->allocator, 0, 1); +	this->fog2SRT.bindEntry(&this->fog2Model, anmRes, 0, 0); +	this->fog2Model.bindAnim(&this->fog2SRT, 0.0); + + + +	allocator.unlink(); + + +	// Stuff I do understand +	OSReport("Setting Podouble's Size to 1.0\n"); +	this->scale = (Vec){1.0, 1.0, 1.0}; + + +	this->direction = (this->isFire) ? 0 : 1; +	this->countdown = (this->isFire) ? 90 : 0; + +	this->rot.x = 0; // X is vertical axis +	this->rot.y = (direction) ? 0xD800 : 0x2800; +	this->rot.z = 0; // Z is ... an axis >.> +	 +	this->speed.x = 0.0; +	this->speed.y = 0.0; +	this->max_speed.x = 0.0; +	this->x_speed_inc = 0.0; + +	this->goingUp = 0; + + +	OSReport("Creating Podouble's Physics Struct\n"); + +	ActivePhysics::Info HitMeBaby; + +	HitMeBaby.xDistToCenter = 0.0; +	HitMeBaby.yDistToCenter = 0.0; + +	HitMeBaby.xDistToEdge = 40.0; +	HitMeBaby.yDistToEdge = 40.0;		 + +	HitMeBaby.category1 = 0x3; +	HitMeBaby.category2 = 0x0; +	HitMeBaby.bitfield1 = 0x4F; +	HitMeBaby.bitfield2 = (this->isFire) ? 0x388626 : 0x388626; +	HitMeBaby.unkShort1C = 0; +	HitMeBaby.callback = &poodleCollisionCallback; + +	OSReport("Making the Physics Class and adding to the list\n"); +	this->aPhysics.initWithStruct(this, &HitMeBaby); +	this->aPhysics.addToList(); + +	this->disableEatIn(); + +	doStateChange(&StateID_Grow); + +	OSReport("Going to Execute Podouble\n"); +	this->onExecute(); +	return true; +} + +int daPodouble::onDelete() { +	return true; +} + +int daPodouble::onExecute() { +	acState.execute(); +	 +	return true; +} + +int daPodouble::onDraw() { +	if (this->speed.y >= 0) { +		matrix.translation(pos.x, pos.y, pos.z); + +		fogModel.setDrawMatrix(matrix); +		fogModel.setScale(&scale); +		fogModel.calcWorld(false); + +		fogModel.scheduleForDrawing(); +		fogModel._vf1C(); + +		if(this->fogChr.isAnimationDone()) +			this->fogChr.setCurrentFrame(0.0); + +		this->fogSRT.process(); +	} +	else { +		matrix.translation(pos.x, pos.y, pos.z); + +		fog2Model.setDrawMatrix(matrix); +		fog2Model.setScale(&scale); +		fog2Model.calcWorld(false); + +		fog2Model.scheduleForDrawing(); +		fog2Model._vf1C(); + +		if(this->fog2Chr.isAnimationDone()) +			this->fog2Chr.setCurrentFrame(0.0); + +		this->fog2SRT.process(); +	} + +	matrix.translation(pos.x, pos.y, pos.z); +	matrix.applyRotationYXZ(&rot.x, &rot.y, &rot.z); + +	bodyModel.setDrawMatrix(matrix); +	bodyModel.setScale(&scale); +	bodyModel.calcWorld(false); + +	bodyModel.scheduleForDrawing(); +	this->body.process(); + +	return true; +} + + +/////////////// +// Grow State +/////////////// +	void daPodouble::beginState_Grow() {  +		this->timer = 0; +		if (isFire) { return; } + +		// Stop the BGM Music +		StopBGMMusic(); + +		// Set the necessary Flags and make Mario enter Demo Mode +		dStage32C_c::instance->freezeMarioBossFlag = 1; +		WLClass::instance->_4 = 4; +		WLClass::instance->_8 = 0; + +		MakeMarioEnterDemoMode(); + +		// Make sure to use the correct position +		Vec pos = (Vec){this->pos.x - 124.0, this->pos.y + 104.0, 3564.0}; +		S16Vec rot = (S16Vec){0, 0, 0}; + +		// Create And use Kameck +		Kameck = (daKameckDemo*)createChild(KAMECK_FOR_CASTLE_DEMO, (dStageActor_c*)this, 0, &pos, &rot, 0); +		Kameck->doStateChange(&daKameckDemo::StateID_DemoWait); + +		this->scale = (Vec){1.0, 1.0, 1.0}; +	} + +	void daPodouble::executeState_Grow() {  +		 +		this->timer = this->timer + 1; +		 +		float scaleSpeed, yPosScaling; + +		 +		if ((this->timer > 150) && (this->timer < 230)) { + +			scaleSpeed = 0.03125; +			yPosScaling = 18; +		 +			float modifier; + +			modifier = 1.0 + ((this->timer - 150) * scaleSpeed); +			 +			this->scale = (Vec){modifier, modifier, modifier}; +			this->pos.y = this->pos.y + (yPosScaling/80); +			 +		} +		if (this->timer > 420) {  +			PlaySound(this, SE_EMY_CS_MOVE_W8_BUBBLE_APP); +			doStateChange(&StateID_Bounce);  +		} + +		if (isFire) { return; } +		if (this->timer == 130) { Kameck->doStateChange(&daKameckDemo::StateID_DemoSt); } +		if (this->timer == 150) { PlaySound(this, SE_BOSS_IGGY_WANWAN_TO_L); } +		if (this->timer == 400) { Kameck->doStateChange(&daKameckDemo::StateID_DemoSt2); } +		if (this->timer == 360) {  +			Vec tempPos = (Vec){this->pos.x - 40.0, this->pos.y + 120.0, 3564.0}; +			CreateEffect(&tempPos, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}, 175);  // 400 & 401 // 564 // 583 // 754 // 958 +			CreateEffect(&tempPos, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}, 400);  // 400 & 401 // 564 // 583 // 754 // 958 +			CreateEffect(&tempPos, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}, 401);  // 400 & 401 // 564 // 583 // 754 // 958 +			CreateEffect(&tempPos, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}, 564);  // 400 & 401 // 564 // 583 // 754 // 958 +			CreateEffect(&tempPos, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}, 583);  // 400 & 401 // 564 // 583 // 754 // 958 +			CreateEffect(&tempPos, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}, 754);  // 400 & 401 // 564 // 583 // 754 // 958 +			CreateEffect(&tempPos, &(S16Vec){0,0,0}, &(Vec){1.0, 1.0, 1.0}, 958);  // 400 & 401 // 564 // 583 // 754 // 958 +		} +	} +	void daPodouble::endState_Grow() {  +		this->Baseline = this->pos.y; +		if (isFire) { return; } + +		// Clean up the flags and Kameck +		dStage32C_c::instance->freezeMarioBossFlag = 0; +		WLClass::instance->_8 = 1; + +		MakeMarioExitDemoMode(); +		StartBGMMusic(); + +		Kameck->Delete(1); +	} + + +/////////////// +// Bounce State +/////////////// +	void daPodouble::beginState_Bounce() {  +		this->rot.y = (direction) ? 0xD800 : 0x2800; +		this->rot.x = 0; + +		this->max_speed.y = -5.0; +		this->speed.y = -1.0; +		this->y_speed_inc = -0.1875; + +		this->goingUp = 0; +	} +	void daPodouble::executeState_Bounce() {  + +		if (this->countdown) {  +			this->countdown--;  +			return; } + +		HandleYSpeed(); +		doSpriteMovement(); + +		if (this->pos.y < this->Baseline) {  +			this->speed.y = 8.0; 		 +			this->goingUp = 1; } + +		if (-0.1 < this->speed.y < 0.1) {  +			if (this->goingUp == 1) { doStateChange(&StateID_Spit); } } + + +		// Check for stupid liquid junk +		float ydest; +		ydest = (this->pos.y > this->last_pos.y) ? this->last_pos.y : this->pos.y; + +		int liquid = CheckforLiquid(WaterManager, this->pos, 0, 0, 0, this->currentLayerID); + +		OSReport("Liquid type %d", liquid); + +		if (liquid == 1) {  +			CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){3.0, 3.0, 3.0}, 415); +			PlaySoundAsync(this, SE_EMY_BUBBLE_SPLASH); +		} +		if (liquid == 0) {  +			CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){3.0, 3.0, 3.0}, 422); +			PlaySoundAsync(this, SE_OBJ_CMN_SPLASH); +		} + +	} +	void daPodouble::endState_Bounce() {  +		this->speed.y = 0.0; +		this->y_speed_inc = 0.0; +	} + + +/////////////// +// Spit State +/////////////// +	void daPodouble::beginState_Spit() { this->timer = 0; } +	void daPodouble::executeState_Spit() {  + +		if (this->timer < 0x40) { +			this->rot.x -= 0x80; +		} + +		else if (this->timer < 0x48) { +			this->rot.x += 0x400; +		} + +		else if (this->timer == 0x48) { +			if (this->isFire == 0) { +				dStageActor_c *spawner = create(BROS_ICEBALL, 0x10, &this->pos, &(S16Vec){0,0,0}, 0); +				*((u32 *) (((char *) spawner) + 0x3DC)) = this->id; +				PlaySoundAsync(this, SE_EMY_ICE_BROS_ICE); +				doStateChange(&StateID_Bounce); +			} +			else { +				create(BROS_FIREBALL, 0, &this->pos, &(S16Vec){0,0,0}, 0); +				PlaySoundAsync(this, SE_EMY_FIRE_BROS_FIRE); +				doStateChange(&StateID_Bounce); +			} +		} + +		this->timer += 1; +	} +	void daPodouble::endState_Spit() {  +		this->speed.y = -1.0; +		this->y_speed_inc = -0.1875; +	} + + +/////////////// +// Damage State +/////////////// +	void daPodouble::beginState_Damage() {  +		this->timer = 0; +		this->isInvulnerable = 1; + +		if (this->isFire == 0) { +			PlaySoundAsync(this, SE_OBJ_PNGN_ICE_THAW); +			CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 243); } +		else { +			PlaySoundAsync(this, SE_EMY_FIRE_SNAKE_EXTINCT); +			CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){3.0, 3.0, 3.0}, 252); } +	} +	void daPodouble::executeState_Damage() {  + +		int amt; +		amt = sin(this->timer * 3.14 / 4.0) * 0x2000; + +		this->rot.y = amt; +		this->rot.y += (direction) ? 0xD800 : 0x2800; + + +		if (this->timer > 180) { +			doStateChange(&StateID_Bounce); +		} +		 +		if ((this->timer == 60) || (this->timer == 80) || (this->timer == 100)) { +			if (this->isFire == 0) { +				dStageActor_c *spawner = create(BROS_ICEBALL, 0x10, &this->pos, &(S16Vec){0,0,0}, 0); +				*((u32 *) (((char *) spawner) + 0x3DC)) = this->id; +				PlaySoundAsync(this, SE_EMY_ICE_BROS_ICE); +			} +			else { +				create(BROS_FIREBALL, 0, &this->pos, &(S16Vec){0,0,0}, 0); +				PlaySoundAsync(this, SE_EMY_FIRE_BROS_FIRE); +			} +		} + +		this->timer += 1; + +	} +	void daPodouble::endState_Damage() {  +		this->isInvulnerable = 0; +	} + + +/////////////// +// Outro State +/////////////// +	void daPodouble::beginState_Outro() {  + +		daPodouble *other = (daPodouble*)FindActorByType(SHIP_WINDOW, (Actor*)this); +		if (other != 0) { other->doStateChange(&StateID_SyncDie); } + +		WLClass::instance->_4 = 5; +		WLClass::instance->_8 = 0; + +		this->removeMyActivePhysics(); +		this->timer = 0; +		StopBGMMusic(); + +		dStage32C_c::instance->freezeMarioBossFlag = 1; + +	} +	void daPodouble::executeState_Outro() { + +		if (this->dying == 1) {  +			if (this->timer > 180) { +				ExitStage(WORLD_MAP, 0, BEAT_LEVEL, MARIO_WIPE); +			} +			 +			if (this->timer == 60) { +				 +				UpdateGameMgr(); + +				if (GetSpecificPlayerActor(0) != 0) { +					PlaySound(this, SE_VOC_MA_CLEAR_BOSS); +					// Send PlBase into DemoGoal State here, kthxbai +				} +				 +				if (GetSpecificPlayerActor(1) != 0) { +					PlaySound(this, SE_VOC_LU_CLEAR_BOSS); +					// Send PlBase into DemoGoal State here, kthxbai +				} + +				if (GetSpecificPlayerActor(2) != 0) { +					PlaySound(this, SE_VOC_KO_CLEAR_BOSS); +					// Send PlBase into DemoGoal State here, kthxbai +				} + +				if (GetSpecificPlayerActor(3) != 0) { +					PlaySound(this, SE_VOC_KO2_CLEAR_BOSS); +					// Send PlBase into DemoGoal State here, kthxbai +				} +			}	 +			 +			this->timer += 1; +			return;  +		}	 + +		if (this->scale.x > 0.1) { + +			PlaySound(this, SE_EMY_BUBBLE_EXTINCT); + +			// Adjust this to equal the scale of your boss / 80. +			this->scale.x -= 0.04375; +			this->scale.y -= 0.04375; +			this->scale.z -= 0.04375; + +			if (this->timer == 30) {   +				CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 756);  +				CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 801);  +				CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 957);  +				this->timer = 0; +			} + +			this->timer += 1; +		} +		else { +			this->scale.x = 0.0; +			this->scale.y = 0.0; +			this->scale.z = 0.0; +			 +			CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 588); +			this->dying = 1; +			this->timer = 0; + +			PlaySound(this, STRM_BGM_SHIRO_BOSS_CLEAR); +			MakeMarioEnterDemoMode(); +		} +	} +	void daPodouble::endState_Outro() { } + + + +/////////////// +// SyncDie State +/////////////// +	void daPodouble::beginState_SyncDie() {  + +		this->removeMyActivePhysics(); +		this->timer = 0; +	} +	void daPodouble::executeState_SyncDie() { + +		if (this->dying == 1) { return; } + +		if (this->scale.x > 0.1) { + +			PlaySound(this, SE_EMY_BUBBLE_EXTINCT); + +			// Adjust this to equal the scale of your boss / 80. +			this->scale.x -= 0.04375; +			this->scale.y -= 0.04375; +			this->scale.z -= 0.04375; + +			if (this->timer == 30) {   +				CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 756);  +				CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 801);  +				CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 957);  +				this->timer = 0; +			} + +			this->timer += 1; +		} +		else { +			this->scale.x = 0.0; +			this->scale.y = 0.0; +			this->scale.z = 0.0; +			 +			CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 588); +			this->dying = 1; +			this->timer = 0; +		} +	} +	void daPodouble::endState_SyncDie() { } diff --git a/src/bossThwompaDomp.cpp b/src/bossThwompaDomp.cpp index 3a1b0c7..fb8d59e 100644 --- a/src/bossThwompaDomp.cpp +++ b/src/bossThwompaDomp.cpp @@ -5,26 +5,26 @@  #include <stage.h>  #include "effects.h" +// Externs +	extern "C" int posIsInZone(Vec,float*,float*,u8 zone); +	extern "C" void* ScreenPositionClass; +	extern "C" void ShakeScreen(void*,int,int,int,int); // (ScreenPositionClass, some other ints - set the second one to 1 to shake it)  +	extern "C" int SpawnThwompEffects(dEn_c *); -extern "C" int posIsInZone(Vec,float*,float*,u8 zone); -extern "C" void* ScreenPositionClass; -extern "C" void ShakeScreen(void*,int,int,int,int); // (ScreenPositionClass, some other ints - set the second one to 1 to shake it)  -extern "C" int SpawnThwompEffects(dEn_c *); +	extern "C" void* SoundRelatedClass; +	extern "C" Vec ConvertStagePositionIntoScreenPosition__Maybe(Vec); +	extern "C" void AnotherSoundRelatedFunction(void*,SFX,Vec,int); -extern "C" void* SoundRelatedClass; -extern "C" Vec ConvertStagePositionIntoScreenPosition__Maybe(Vec); -extern "C" void AnotherSoundRelatedFunction(void*,SFX,Vec,int); +	extern "C" void *PlaySound(dEn_c *, int soundID); +	extern "C" void *PlaySoundAsync(dEn_c *, int soundID); +	extern "C" dStageActor_c *GetSpecificPlayerActor(int number); -extern "C" void *PlaySound(dEn_c *, int soundID); -extern "C" void *PlaySoundAsync(dEn_c *, int soundID); -extern "C" dStageActor_c *GetSpecificPlayerActor(int number); +	extern "C" void *StopBGMMusic(); +	extern "C" void *StartBGMMusic(); -extern "C" void *StopBGMMusic(); -extern "C" void *StartBGMMusic(); - -extern "C" void *MakeMarioEnterDemoMode(); -extern "C" void *MakeMarioExitDemoMode(); -extern "C" void *UpdateGameMgr(); +	extern "C" void *MakeMarioEnterDemoMode(); +	extern "C" void *MakeMarioExitDemoMode(); +	extern "C" void *UpdateGameMgr();  class daEnMegaDosun_c : public dEn_c { @@ -53,6 +53,8 @@ class daEnMegaDosun_c : public dEn_c {  	float leftBuffer;  	float rightBuffer;  	float topBuffer; +	bool isOutofScreen; +	Vec OutOfScreenPosition;  	dEn_c *Kameck; @@ -77,14 +79,15 @@ class daEnMegaDosun_c : public dEn_c {  	DECLARE_STATE(Outro);  }; -CREATE_STATE(daEnMegaDosun_c, UpWait); -CREATE_STATE(daEnMegaDosun_c, DownMoveWait); -CREATE_STATE(daEnMegaDosun_c, PuruMove); -CREATE_STATE(daEnMegaDosun_c, DownMove); -CREATE_STATE(daEnMegaDosun_c, DownWait); -CREATE_STATE(daEnMegaDosun_c, UpMove); -CREATE_STATE(daEnMegaDosun_c, Grow); -CREATE_STATE(daEnMegaDosun_c, Outro); +// States +	CREATE_STATE(daEnMegaDosun_c, UpWait); +	CREATE_STATE(daEnMegaDosun_c, DownMoveWait); +	CREATE_STATE(daEnMegaDosun_c, PuruMove); +	CREATE_STATE(daEnMegaDosun_c, DownMove); +	CREATE_STATE(daEnMegaDosun_c, DownWait); +	CREATE_STATE(daEnMegaDosun_c, UpMove); +	CREATE_STATE(daEnMegaDosun_c, Grow); +	CREATE_STATE(daEnMegaDosun_c, Outro);  daEnMegaDosun_c *daEnMegaDosun_c::build() {  	void *buffer = AllocFromGameHeap1(sizeof(daEnMegaDosun_c)); @@ -102,18 +105,17 @@ daEnMegaDosun_c *daEnMegaDosun_c::build() {  	void daEnMegaDosun_c::collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther) { } -  void daEnMegaDosun_c::setupBodyModel() {  	allocator.link(-1, GameHeaps[0], 0, 0x20); -	this->resFile.data = getResource("dossun", "g3d/dossun.brres"); +	this->resFile.data = getResource("dossun", "g3d/t00.brres");  	nw4r::g3d::ResMdl mdl = this->resFile.GetResMdl("dossun_big");  	bodyModel.setup(mdl, &allocator, 0x60, 1, 0);  	SetupTextures_Enemy(&bodyModel, 0); -	// nw4r::g3d::ResAnmVis anmRes = this->resFile.GetResAnmVis("dossun_big"); -	// this->anmVis.setup(mdl, anmRes, &this->allocator, 0); -	// this->anmVis.bind(&bodyModel, anmRes, 1); +	nw4r::g3d::ResAnmVis anmRes = this->resFile.GetResAnmVis("dossun_big"); +	this->anmVis.setup(mdl, anmRes, &this->allocator, 0); +	this->anmVis.bind(&bodyModel, anmRes, 1);  	allocator.unlink();  } @@ -153,9 +155,9 @@ int daEnMegaDosun_c::onCreate() {  	OSReport("this->collMgr.Init(this,(u8*)&this->collision_struct,(u8*)&s3,0);\n");  	this->collMgr.Init(this,(u8*)&this->collision_struct,(u8*)&s3,0); -	// this->pos_delta2.x = 0.0; -	// this->pos_delta2.y = 36.0; -	// this->pos_delta2.z = 0.0; +	this->pos_delta2.x = 0.0; +	this->pos_delta2.y = 36.0; +	this->pos_delta2.z = 0.0;  	this->_320 = 0.0;  	this->_324 = 48.0; @@ -175,11 +177,20 @@ int daEnMegaDosun_c::onCreate() {  	this->notFalling = 0;  	this->direction = 0;  	this->countdownTimer = 0; +	this->isOutofScreen = false;  	// Measured in half tiles -	this->leftBuffer	= this->pos.x - ((float)((this->settings >> 24) & 0xFF) * 8.0);  //nyb 5-6 LEFT -	this->rightBuffer	= this->pos.x + ((float)((this->settings >> 16) & 0xFF) * 8.0);  //nyb 7-8 RIGHT -	this->topBuffer		= this->pos.y + ((float)((this->settings >> 8) & 0xFF) * 8.0);   //nyb 9-10 TOP +	this->leftBuffer	= this->pos.x - (((float)((this->settings >> 24) & 0xFF) - 5.0) * 8.0);  //nyb 5-6 LEFT +	this->rightBuffer	= this->pos.x + (((float)((this->settings >> 16) & 0xFF) - 3.0) * 8.0);  //nyb 7-8 RIGHT +	this->topBuffer		= this->pos.y + (((float)((this->settings >> 8) & 0xFF) - 8.0) * 8.0);   //nyb 9-10 TOP + + +	// Boss Thwomp settings +	// +	//	nybble 5-6 		- Left Buffer in half tiles (minimum is 5 due to thwomp width) +	//	nybble 7-8 		- Left Buffer in half tiles (minimum is 3 due to thwomp width) +	//	nybble 9-10		- Top Buffer in half tiles (minimum is 8 due to thwomp height) +	//  	this->doStateChange(&StateID_Grow); @@ -188,14 +199,19 @@ int daEnMegaDosun_c::onCreate() {  	return true;  } -  int daEnMegaDosun_c::onExecute() {  	acState.execute(); -	int ret = this->checkZoneBoundaries(0); -	if(ret) { -		OSReport("daEnMegaDosun_c has left the building\n"); -		doStateChange(&StateID_Outro); +	if (this->isOutofScreen == false) { +		float rect[] = {this->_320, this->_324, this->spriteSomeRectX, this->spriteSomeRectY}; +		int ret = this->outOfZone(this->pos, (float*)&rect, this->currentZoneID); +		if(ret) { +			OSReport("daEnMegaDosun_c has left the building\n"); +			this->OutOfScreenPosition = this->pos; + +			this->isOutofScreen = true; +			doStateChange(&StateID_Outro); +		}  	}  	return true; @@ -214,6 +230,7 @@ int daEnMegaDosun_c::onDraw() {  }  int daEnMegaDosun_c::onDelete() { +	OSReport("Deleting Thwompy\n");  	return true;  } @@ -307,14 +324,20 @@ int daEnMegaDosun_c::onDelete() {  		}  		if (this->pos.x > this->rightBuffer) { +			CreateEffect(&(Vec){this->pos.x + 38.0, this->pos.y + 32.0, 5500.0}, &(S16Vec){0,0,0x4000}, &(Vec){1.0, 1.0, 1.0}, 364);  +			PlaySoundAsync(this, SE_OBJ_TEKKYU_G_CRASH); +			  			this->direction = 0;  		}  		if (this->pos.x < this->leftBuffer) { +			CreateEffect(&(Vec){this->pos.x - 40.0, this->pos.y + 32.0, 5500.0}, &(S16Vec){0,0,0xC000}, &(Vec){1.0, 1.0, 1.0}, 364);  +			PlaySoundAsync(this, SE_OBJ_TEKKYU_G_CRASH); +  			this->direction = 1;  		} -		this->pos.x += (direction) ? -0.5 : 0.5; +		this->pos.x += (direction) ? 0.9 : -0.9;  		if (this->notFalling == 0) {  			if(this->CheckIfPlayerBelow(40.0, 256.0)) { @@ -336,13 +359,13 @@ int daEnMegaDosun_c::onDelete() {  // StateID_DownMoveWait  	void daEnMegaDosun_c::beginState_DownMoveWait() { -		// this->anmVis.playState = 1; +		this->anmVis.playState = 1;  		this->bodyModel.bindAnim(&this->anmVis, 0.5);  	}  	void daEnMegaDosun_c::executeState_DownMoveWait() { -		// if(this->anmVis.isAnimationDone()) -		// 	this->doStateChange(&StateID_PuruMove); -		// this->anmVis.process(); +		if(this->anmVis.isAnimationDone()) +			this->doStateChange(&StateID_PuruMove); +		this->anmVis.process();  	}  	void daEnMegaDosun_c::endState_DownMoveWait() {  		return; @@ -421,13 +444,14 @@ int daEnMegaDosun_c::onDelete() {  		if(this->countdownTimer == 0) {  			this->doStateChange(&StateID_UpMove);  		} -		else{ +		else {  			this->countdownTimer--; -			// if(this->countdownTimer & 0xff == 0x20) -			// 	this->anmVis.playState = 3; +			if(this->countdownTimer == 0x20) { +				this->anmVis.playState = 3; +			}  		} -		// this->anmVis.process(); +		this->anmVis.process();  	}  	void daEnMegaDosun_c::endState_DownWait() {  		return; @@ -443,10 +467,11 @@ int daEnMegaDosun_c::onDelete() {  		if (this->pos.y > this->topBuffer) {  			this->doStateChange(&StateID_UpWait); +			PlaySoundAsync(this, SE_OBJ_TEKKYU_L_CRASH);  			this->countdownTimer = 0xc;  		}  		else { -			this->pos.y += 0.5; +			this->pos.y += 1.5;  		}  	}  	void daEnMegaDosun_c::endState_UpMove() { @@ -455,6 +480,7 @@ int daEnMegaDosun_c::onDelete() {  // Outro  	void daEnMegaDosun_c::beginState_Outro() {  +		OSReport("Outro Being\n");  		WLClass::instance->_4 = 5;  		WLClass::instance->_8 = 0; @@ -465,72 +491,59 @@ int daEnMegaDosun_c::onDelete() {  		dStage32C_c::instance->freezeMarioBossFlag = 1; +		this->speed.y = 0.0; +		this->y_speed_inc = 0.0;  	}  	void daEnMegaDosun_c::executeState_Outro() { -		if (this->dying == 1) {  -			if (this->timer > 180) { -				ExitStage(WORLD_MAP, 0, BEAT_LEVEL, MARIO_WIPE); -			} -			 -			if (this->timer == 60) { -				 -				UpdateGameMgr(); - -				if (GetSpecificPlayerActor(0) != 0) { -					PlaySound(this, SE_VOC_MA_CLEAR_BOSS); -					// Send PlBase into DemoGoal State here, kthxbai -				} -				 -				if (GetSpecificPlayerActor(1) != 0) { -					PlaySound(this, SE_VOC_LU_CLEAR_BOSS); -					// Send PlBase into DemoGoal State here, kthxbai -				} - -				if (GetSpecificPlayerActor(2) != 0) { -					PlaySound(this, SE_VOC_KO_CLEAR_BOSS); -					// Send PlBase into DemoGoal State here, kthxbai -				} - -				if (GetSpecificPlayerActor(3) != 0) { -					PlaySound(this, SE_VOC_KO2_CLEAR_BOSS); -					// Send PlBase into DemoGoal State here, kthxbai -				} -			}	 -			 -			this->timer += 1; -			return;  -		}	 +		this->pos.y = this->OutOfScreenPosition.y + 280.0; -		if (this->scale.x > 0.1) { +		if (this->timer == 0) { +			OSReport("Outro Play Sound\n");  			PlaySound(this, SE_EMY_BIG_DOSSUN_DEAD); -			// Adjust this to equal the scale of your boss / 80. -			this->scale.x -= 0.015; -			this->scale.y -= 0.015; -			this->scale.z -= 0.015; - -			if (this->timer == 30) {   -				CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 756);  -				CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 801);  -				CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 957);  -				this->timer = 0; -			} - -			this->timer += 1; +			CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 988);  +			CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 989);   		} -		else { -			this->scale.x = 0.0; -			this->scale.y = 0.0; -			this->scale.z = 0.0; -			 -			CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){2.0, 2.0, 2.0}, 588); -			this->dying = 1; -			this->timer = 0; +		if (this->timer == 60) { +			OSReport("Outro Play Fanfare\n");  			PlaySound(this, STRM_BGM_SHIRO_BOSS_CLEAR);  			MakeMarioEnterDemoMode();  		} +		 +		if (this->timer == 120) { +			OSReport("Outro Play Victory Cry\n"); +			 +			UpdateGameMgr(); + +			if (GetSpecificPlayerActor(0) != 0) { +				PlaySound(this, SE_VOC_MA_CLEAR_BOSS); +				// Send PlBase into DemoGoal State here, kthxbai +			} +			 +			if (GetSpecificPlayerActor(1) != 0) { +				PlaySound(this, SE_VOC_LU_CLEAR_BOSS); +				// Send PlBase into DemoGoal State here, kthxbai +			} + +			if (GetSpecificPlayerActor(2) != 0) { +				PlaySound(this, SE_VOC_KO_CLEAR_BOSS); +				// Send PlBase into DemoGoal State here, kthxbai +			} + +			if (GetSpecificPlayerActor(3) != 0) { +				PlaySound(this, SE_VOC_KO2_CLEAR_BOSS); +				// Send PlBase into DemoGoal State here, kthxbai +			} +		}	 +				 +		if (this->timer > 240) { +			OSReport("Outro Out\n"); +			ExitStage(WORLD_MAP, 0, BEAT_LEVEL, MARIO_WIPE); +		} + +		this->timer += 1;  	}  	void daEnMegaDosun_c::endState_Outro() { } diff --git a/src/soundPlayer.S b/src/soundPlayer.S index 8866460..1cf7cbd 100644 --- a/src/soundPlayer.S +++ b/src/soundPlayer.S @@ -137,3 +137,31 @@ StopSound:  	mtlr      r0  	blr + + + + +# No where else to put this at the time, fuckit +.global KnockMarioBack +KnockMarioBack: + +    stwu      r1, -0x10(r1) +    mflr      r0 +    stw       r0, 0x14(r1) +    stw       r31, 0xC(r1) +    stw       r30, 0x8(r1) + +	lwz       r3, 4(r3) +	mr        r4, r4 +	li        r5, 3 +	lwz       r12, 0x60(r3) +	lwz       r12, 0x3F4(r12) +	mtctr     r12 +	bctrl + +    lwz       r0, 0x14(r1) +    lwz       r4, 0xC(r1) +    lwz       r3, 0x8(r1) +    mtlr      r0 +    addi      r1, r1, 0x10 +	blr
\ No newline at end of file diff --git a/src/topman.cpp b/src/topman.cpp new file mode 100644 index 0000000..4509272 --- /dev/null +++ b/src/topman.cpp @@ -0,0 +1,480 @@ +#include <common.h> +#include <game.h> +#include <g3dhax.h> +#include <sfx.h> +#include <stage.h> +#include "effects.h" +#include "player.h" + +class daTopman : public dEn_c { +	int onCreate(); +	int onDelete(); +	int onExecute(); +	int onDraw(); + +	mHeapAllocator_c allocator; +	nw4r::g3d::ResFile resFile; + +	m3d::mdl_c bodyModel; + +	m3d::anmChr_c chrAnimation; + +	int timer; +	char damage; +	char isDown; +	float XSpeed; +	u32 cmgr_returnValue; +	bool isBouncing; +	char isInSpace; +	char fromBehind; + +	static daTopman *build(); + +	void bindAnimChr_and_setUpdateRate(const char* name, int unk, float unk2, float rate); +	void updateModelMatrices(); +	bool calculateTileCollisions(); + +	// void spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); +	void playerCollision(ActivePhysics *apThis, ActivePhysics *apOther); +	void yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther); + +	void collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat7_WMWaggleWater(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat7_WMWaggleWaterYoshi(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther); +	// bool collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther); + +	void _vf148(); +	void _vf14C(); + +	USING_STATES(daTopman); +	DECLARE_STATE(Walk); +	DECLARE_STATE(Turn); +	DECLARE_STATE(KnockBack); +	DECLARE_STATE(Die); +}; + +daTopman *daTopman::build() { +	void *buffer = AllocFromGameHeap1(sizeof(daTopman)); +	return new(buffer) daTopman; +} + +/////////////////////// +// Externs and States +/////////////////////// +	extern "C" void *PlaySound(dStageActor_c *, int soundID); +	extern "C" void *PlaySoundAsync(dStageActor_c *, int soundID); +	extern "C" void *EN_LandbarrelPlayerCollision(dEn_c* t, ActivePhysics *apThis, ActivePhysics *apOther); + +	extern "C" dStageActor_c *CreateActor(u16 classID, int settings, Vec pos, char rot, char layer); +	extern "C" u8 dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(daTopman *, Vec pos); + +	//FIXME make this dEn_c->used... +	extern "C" char usedForDeterminingStatePress_or_playerCollision(dEn_c* t, ActivePhysics *apThis, ActivePhysics *apOther, int unk1); +	extern "C" int SmoothRotation(short* rot, u16 amt, int unk2); + + +	CREATE_STATE(daTopman, Walk); +	CREATE_STATE(daTopman, Turn); +	CREATE_STATE(daTopman, KnockBack); +	CREATE_STATE(daTopman, Die); + +	// 	begoman_attack2"	// wobble back and forth tilted forwards +	// 	begoman_attack3"	// Leaned forward, antennae extended +	// 	begoman_damage"		// Bounces back slightly +	// 	begoman_damage2"	// Stops spinning and wobbles to the ground like a top +	// 	begoman_stand"		// Stands still, waiting +	// 	begoman_wait"		// Dizzily Wobbles +	// 	begoman_wait2"		// spins around just slightly +	// 	begoman_attack"		// Rocks backwards, and then attacks to an upright position, pulsing out his antennae + + +//////////////////////// +// Collision Functions +//////////////////////// + +	// Collision callback to help shy guy not die at inappropriate times and ruin the dinner + +	void daTopman::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) { + +		char hitType; +		hitType = usedForDeterminingStatePress_or_playerCollision(this, apThis, apOther, 0); + +		if(hitType == 1) {	// regular jump +			apOther->someFlagByte |= 2; +			this->dEn_c::playerCollision(apThis, apOther); +			this->_vf220(apOther->owner); +		}  +		else if(hitType == 3) {	// spinning jump or whatever? +			apOther->someFlagByte |= 2; +			this->dEn_c::playerCollision(apThis, apOther); +			this->_vf220(apOther->owner); +		}  +		else if(hitType == 0) { +			EN_LandbarrelPlayerCollision(this, apThis, apOther); +			if (this->direction == apOther->owner->direction) { +				this->direction ^= 1; +				this->fromBehind = 1; +			} +			doStateChange(&StateID_KnockBack); +		}  + +		// fix multiple player collisions via megazig +		this->isDead = 0; +		this->flags_4FC |= (1<<(31-7)); +		if(apOther->owner->which_player < 4) { +			this->counter_504[apOther->owner->which_player] = 0; +		} +	} + +	void daTopman::yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther) { +		this->playerCollision(apThis, apOther); +	} + +	void daTopman::collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther) { +		this->dEn_c::playerCollision(apThis, apOther); +		this->_vf220(apOther->owner); + +		this->isDead = 0; +		this->flags_4FC |= (1<<(31-7)); +		if(apOther->owner->which_player < 4) { +			this->counter_504[apOther->owner->which_player] = 0; +		} +	} + +	void daTopman::collisionCat7_WMWaggleWater(ActivePhysics *apThis, ActivePhysics *apOther) { +		this->collisionCatD_GroundPound(apThis, apOther); +	} + +	void daTopman::collisionCat7_WMWaggleWaterYoshi(ActivePhysics *apThis, ActivePhysics *apOther) { +		this->collisionCatD_GroundPound(apThis, apOther); +	} + +	void daTopman::collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther) { +		doStateChange(&StateID_KnockBack); +	} + +	void daTopman::collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther){ +		doStateChange(&StateID_Die); +	} + +	void daTopman::collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther){ +		doStateChange(&StateID_KnockBack); +	} + +	void daTopman::collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther){ +		doStateChange(&StateID_KnockBack); +	} + +	void daTopman::collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther) { +		doStateChange(&StateID_KnockBack); +	} + +	// void daTopman::collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther) { +	// 	doStateChange(&StateID_DieFall); +	// } + +	// These handle the ice crap +	void daTopman::_vf148() { +		dEn_c::_vf148(); +		doStateChange(&StateID_Die); +	} +	void daTopman::_vf14C() { +		dEn_c::_vf14C(); +		doStateChange(&StateID_Die); +	} + +	void daTopman::collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther) { +		doStateChange(&StateID_Die); +	} + +bool daTopman::calculateTileCollisions() { +	// Returns true if sprite should turn, false if not. + +	HandleXSpeed(); +	HandleYSpeed(); +	doSpriteMovement(); + +	cmgr_returnValue = collMgr.CollidedWithTile(); +	collMgr.execute(); + +	if (isBouncing) { +		stuffRelatingToCollisions(0.1875f, 1.0f, 0.5f); +		if (speed.y != 0.0f) +			isBouncing = false; +	} + +	float xDelta = pos.x - last_pos.x; +	if (xDelta >= 0.0f) +		direction = 0; +	else +		direction = 1; + +	if (collMgr.CollidedWithTile()) { +		// Walking into a tile branch + +		if (cmgr_returnValue == 0) +			isBouncing = true; + +		if (speed.x != 0.0f) { +			//playWmEnIronEffect(); +		} + +		speed.y = 0.0f; + +		// u32 blah = collMgr.s_80070760(); +		// u8 one = (blah & 0xFF); +		// static const float incs[5] = {0.00390625f, 0.0078125f, 0.015625f, 0.0234375f, 0.03125f}; +		// x_speed_inc = incs[one]; +		max_speed.x = (direction == 1) ? -1.0f : 1.0f; +	} else { +		x_speed_inc = 0.0f; +	} + +	// Bouncing checks +	if (_34A & 4) { +		Vec v = (Vec){0.0f, 1.0f, 0.0f}; +		collMgr.parent_speed_ptr = &v; + +		if (collMgr.SomethingSemiImportant(collMgr.bitfield_for_checks)) +			speed.y = 0.0f; + +		collMgr.parent_speed_ptr = &speed; + +	} else { +		if (collMgr.SomethingSemiImportant(collMgr.bitfield_for_checks)) +			speed.y = 0.0f; +	} + +	collMgr.s_8006FA40(0); + +	// Switch Direction +	if (collMgr.bitfield_for_checks & (0x15 << direction)) { +		if (collMgr.CollidedWithTile()) { +			isBouncing = true; +		} +		return true; +	} +	return false; +} + +void daTopman::bindAnimChr_and_setUpdateRate(const char* name, int unk, float unk2, float rate) { +	nw4r::g3d::ResAnmChr anmChr = this->resFile.GetResAnmChr(name); +	this->chrAnimation.bind(&this->bodyModel, anmChr, unk); +	this->bodyModel.bindAnim(&this->chrAnimation, unk2); +	this->chrAnimation.setUpdateRate(rate); +} + +int daTopman::onCreate() { +	 +	// Model creation	 +	allocator.link(-1, GameHeaps[0], 0, 0x20); + +	this->resFile.data = getResource("ben", "g3d/begoman_spike.brres"); +	nw4r::g3d::ResMdl mdl = this->resFile.GetResMdl("begoman"); +	bodyModel.setup(mdl, &allocator, 0x224, 1, 0); +	SetupTextures_Map(&bodyModel, 0); + + +	// Animations start here +	nw4r::g3d::ResAnmChr anmChr = this->resFile.GetResAnmChr("begoman_wait"); +	this->chrAnimation.setup(mdl, anmChr, &this->allocator, 0); + +	allocator.unlink(); + +	// Stuff I do understand +	this->scale = (Vec){0.2, 0.2, 0.2}; + +	// this->pos.y = this->pos.y + 30.0; // X is vertical axis +	this->rot.x = 0; // X is vertical axis +	this->rot.y = 0xD800; // Y is horizontal axis +	this->rot.z = 0; // Z is ... an axis >.> +	this->direction = 1; // Heading left. +	 +	this->speed.x = 0.0; +	this->speed.y = 0.0; +	this->max_speed.x = 0.8; +	this->x_speed_inc = 0.0; +	this->XSpeed = 0.8; + +	this->isInSpace = this->settings & 0xF; +	this->fromBehind = 0; + +	ActivePhysics::Info HitMeBaby; + +	HitMeBaby.xDistToCenter = 0.0; +	HitMeBaby.yDistToCenter = 12.0; + +	HitMeBaby.xDistToEdge = 14.0; +	HitMeBaby.yDistToEdge = 12.0;		 + +	HitMeBaby.category1 = 0x3; +	HitMeBaby.category2 = 0x0; +	HitMeBaby.bitfield1 = 0x4F; +	HitMeBaby.bitfield2 = 0xffbafffe; +	HitMeBaby.unkShort1C = 0; +	HitMeBaby.callback = &dEn_c::collisionCallback; + +	OSReport("Making the Physics Class and adding to the list\n"); +	this->aPhysics.initWithStruct(this, &HitMeBaby); +	this->aPhysics.addToList(); + + +	// Tile collider +	OSReport("Making the Tile collider Class\n"); + +	// These fucking rects do something for the tile rect +	spriteSomeRectX = 28.0f; +	spriteSomeRectY = 32.0f; +	_320 = 0.0f; +	_324 = 16.0f; + +	// These structs tell stupid collider what to collide with - these are from koopa troopa +	static const u8 one[16] = {0,0,0,1, 0,0,0xC0,0, 0,0,0x40,0, 0,0,0,0}; +	static const u8 two[12] = {0,0,0,0, 0,0,0,0, 0,0,0xC0,0}; +	static const u8 three[16] = {0,0,0,1, 0,0,0x60,0, 0,0,0x90,0, 0,0,0x60,0}; + +	collMgr.Init(this, one, two, three); +	collMgr.execute(); + +	cmgr_returnValue = collMgr.CollidedWithTile(); + +	if (collMgr.CollidedWithTile()) +		isBouncing = false; +	else +		isBouncing = true; + + +	// State Changers +	bindAnimChr_and_setUpdateRate("begoman_wait2", 1, 0.0, 1.0);  +	doStateChange(&StateID_Walk); + +	this->onExecute(); +	return true; +} + +int daTopman::onDelete() { +	return true; +} + +int daTopman::onExecute() { +	acState.execute(); +	updateModelMatrices(); +	 +	return true; +} + +int daTopman::onDraw() { +	bodyModel.scheduleForDrawing(); +	bodyModel._vf1C(); + +	return true; +} + +void daTopman::updateModelMatrices() { +	matrix.translation(pos.x, pos.y - 2.0, pos.z); +	matrix.applyRotationYXZ(&rot.x, &rot.y, &rot.z); + +	bodyModel.setDrawMatrix(matrix); +	bodyModel.setScale(&scale); +	bodyModel.calcWorld(false); +} + + +/////////////// +// Walk State +/////////////// +	void daTopman::beginState_Walk() { +		this->max_speed.x = (this->direction) ? -this->XSpeed : this->XSpeed; +		this->speed.x = (direction) ? -0.8f : 0.8f; + +		this->max_speed.y = (this->isInSpace) ? -2.0 : -4.0; +		this->speed.y = 	(this->isInSpace) ? -2.0 : -4.0; +		this->y_speed_inc = (this->isInSpace) ? -0.09375 : -0.1875; +	} +	void daTopman::executeState_Walk() {  + +		bool ret = calculateTileCollisions(); +		if (ret) { +			doStateChange(&StateID_Turn); +		} + +		if(this->chrAnimation.isAnimationDone()) { +			this->chrAnimation.setCurrentFrame(0.0); +		} +	} +	void daTopman::endState_Walk() { } + +/////////////// +// Turn State +/////////////// +	void daTopman::beginState_Turn() { +		this->direction ^= 1; +		this->speed.x = 0.0; +	} +	void daTopman::executeState_Turn() {  + +		if(this->chrAnimation.isAnimationDone()) { +			this->chrAnimation.setCurrentFrame(0.0); +		} + +		u16 amt = (this->direction == 0) ? 0x2800 : 0xD800; +		int done = SmoothRotation(&this->rot.y, amt, 0x800); + +		if(done) { +			this->doStateChange(&StateID_Walk); +		} +	} +	void daTopman::endState_Turn() { } + + +/////////////// +// Die State +/////////////// +	void daTopman::beginState_Die() { +		dEn_c::dieFall_Begin(); + +		bindAnimChr_and_setUpdateRate("begoman_damage2", 1, 0.0, 1.0);  +		this->timer = 0; +	} +	void daTopman::executeState_Die() {  + +		if(this->chrAnimation.isAnimationDone()) { +			this->kill(); +			this->Delete(1); +		} +	} +	void daTopman::endState_Die() { } + + +/////////////// +// Knockback State +/////////////// +	void daTopman::beginState_KnockBack() { +		bindAnimChr_and_setUpdateRate("begoman_damage", 1, 0.0, 0.75);  +		this->timer = 0; +		this->max_speed.x = (this->direction) ? this->XSpeed*5.0 : -this->XSpeed*5.0; +		this->speed.x = (direction) ? 4.0f : -4.0f; +	} +	void daTopman::executeState_KnockBack() {  + +		bool ret = calculateTileCollisions(); +		this->speed.x = this->speed.x / 1.1; + +		if(this->chrAnimation.isAnimationDone()) { +			doStateChange(&StateID_Walk); +		} + +	} +	void daTopman::endState_KnockBack() {  +		if (this->fromBehind == 0) { +			this->direction ^= 1; } +		this->fromBehind = 0; +		bindAnimChr_and_setUpdateRate("begoman_wait2", 1, 0.0, 1.0);  +	} +	
\ No newline at end of file  | 
