diff options
Diffstat (limited to '')
| -rw-r--r-- | src/bossMegaGoomba.cpp | 456 | ||||
| -rw-r--r-- | src/player.cpp | 35 | ||||
| -rw-r--r-- | src/player.h | 11 | 
3 files changed, 502 insertions, 0 deletions
| diff --git a/src/bossMegaGoomba.cpp b/src/bossMegaGoomba.cpp new file mode 100644 index 0000000..65bbdb2 --- /dev/null +++ b/src/bossMegaGoomba.cpp @@ -0,0 +1,456 @@ +#include <common.h> +#include <game.h> +#include <g3dhax.h> + +#include "player.h" + +class daMegaGoomba_c : public dEn_c { +	int onCreate(); +	int onDelete(); +	int onExecute(); +	int onDraw(); + +	mHeapAllocator_c allocator; +	m3d::mdl_c bodyModel; + +	float timer; +	nw4r::ut::Rect Bounding; +	float dying; +	 +	HermiteKey keysX[0x10]; +	unsigned int Xkey_count; +	HermiteKey keysY[0x10]; +	unsigned int Ykey_count; +//	HermiteKey keysZ[0x10]; +//	unsigned int Zkey_count; + +	char life; +	bool takeHit(char count); +	 +	void dieFall_Execute(); +	static daMegaGoomba_c *build(); + +	void updateModelMatrices(); + +//	bool preSpriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); +//	bool prePlayerCollision(ActivePhysics *apThis, ActivePhysics *apOther); +//	bool preYoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther); + +//	bool stageActorCollision(ActivePhysics *apThis, ActivePhysics *apOther); +//	void spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); +//	void playerCollision(ActivePhysics *apThis, ActivePhysics *apOther); +//	void yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther); + +	void collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther); +	bool collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat5_Mario(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat11_PipeCannon(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther); +	void collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther); +	void _vf120(ActivePhysics *apThis, ActivePhysics *apOther); +	void _vf110(ActivePhysics *apThis, ActivePhysics *apOther); +	void _vf108(ActivePhysics *apThis, ActivePhysics *apOther); + +	USING_STATES(daMegaGoomba_c); +	DECLARE_STATE(Grow); +	DECLARE_STATE(Shrink); +	DECLARE_STATE(Walk); +	DECLARE_STATE(Jump); +	DECLARE_STATE(Launch); +}; + +//extern void * HandleXSpeed(daMegaGoomba_c*); +//extern void * HandleYSpeed(daMegaGoomba_c*); + +daMegaGoomba_c *daMegaGoomba_c::build() { +	void *buffer = AllocFromGameHeap1(sizeof(daMegaGoomba_c)); +	return new(buffer) daMegaGoomba_c; +} + + +extern "C" void *HandleXSpeed(daMegaGoomba_c *); +extern "C" void *HandleYSpeed(daMegaGoomba_c *); +extern "C" void *UpdateObjectPosBasedOnSpeedValues_real(daMegaGoomba_c *); +extern "C" u32 GenerateRandomNumber(int max); +extern "C" u8 dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(daMegaGoomba_c *, Vec pos); +extern "C" dStageActor_c *CreateActor(u16 classID, int settings, Vec pos, char rot, char layer); +extern "C" dStageActor_c *GetSpecificPlayerActor(int number); + + +CREATE_STATE(daMegaGoomba_c, Grow); +CREATE_STATE(daMegaGoomba_c, Shrink); +CREATE_STATE(daMegaGoomba_c, Walk); +CREATE_STATE(daMegaGoomba_c, Jump); +CREATE_STATE(daMegaGoomba_c, Launch); + + +//TODO better fix for possible bug with sign (ex. life=120; count=-9;) +bool daMegaGoomba_c::takeHit(char count) { +	int c = count; +	int l = this->life; +	if(l - c > 127) { +		c = 127 - l; +	} +	this->life -= c; +	doStateChange(&StateID_Shrink); +	setNewActivePhysicsRect(this, &this->scale); +	return (life <= 0) ? true : false; +} + +#define ACTIVATE	1 +#define DEACTIVATE	0 + +//bool daMegaGoomba_c::preSpriteCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("preSpriteCollision\n"); return false; } +//bool daMegaGoomba_c::prePlayerCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("prePlayerCollision\n");  return false; } +//bool daMegaGoomba_c::preYoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("preYoshiCollision\n");  return false; } + + +//bool  daMegaGoomba_c::stageActorCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("stageActorCollision\n"); return true; } +//void daMegaGoomba_c::spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("spriteCollision\n"); } +/*void daMegaGoomba_c::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) {  +	this->_vf220(apOther->owner); +	OSReport("I hit Mario.\n");  +}*/ +//void  daMegaGoomba_c::yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("yoshiCollision\n"); } + + +void daMegaGoomba_c::collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("Hit Fireball\n"); } +bool daMegaGoomba_c::collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("Hit Iceball\n"); return false; } +void daMegaGoomba_c::collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("Hit StarMario\n"); } +void daMegaGoomba_c::collisionCat5_Mario(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("MarioHit\n"); } +void daMegaGoomba_c::collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther) { +	OSReport("Hit Rolling Object\n"); +	if(this->takeHit(1)) +		doStateChange(&StateID_DieFall); +} +void daMegaGoomba_c::collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("Penguin Attack\n"); } +void daMegaGoomba_c::collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("Groundpound\n"); } +void daMegaGoomba_c::collisionCat11_PipeCannon(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("PipeCannon Hit\n"); } +void daMegaGoomba_c::collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther) { +	OSReport("Hit Hammer\n"); +	if(this->takeHit(1)) +		doStateChange(&StateID_DieFall); +} +void daMegaGoomba_c::collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther) { +	OSReport("Hit Yoshi Fire\n"); +	if(this->takeHit(1)) +		doStateChange(&StateID_DieFall); +} +void daMegaGoomba_c::_vf120(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("_vf120:\n"); } +void daMegaGoomba_c::_vf110(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("_vf110:\n"); } +void daMegaGoomba_c::_vf108(ActivePhysics *apThis, ActivePhysics *apOther) { OSReport("_vf108:\n"); } + + + +//TODO make this real perty like +void daMegaGoomba_c::dieFall_Execute() { +	 +	this->timer = this->timer + 1.0; +	 +	this->dying = this->dying + 0.15; +	 +	this->pos.x = this->pos.x + 0.15; +	this->pos.y = this->pos.y + ((-0.2 * (this->dying*this->dying)) + 5); +	 +	this->dEn_c::dieFall_Execute(); +} + +int daMegaGoomba_c::onCreate() { + +	OSReport("Creating the MegaGoomba Model\n"); +	allocator.link(-1, GameHeaps[0], 0, 0x20); + +	nw4r::g3d::ResFile rf(getResource("kuribo", "g3d/t02.brres")); +	bodyModel.setup(rf.GetResMdl("kuribo"), &allocator, 0x224, 1, 0); +	SetupTextures_Enemy(&bodyModel, 0); + +	allocator.unlink(); + +	OSReport("Creating MegaGoomba's Physics Struct\n"); + +	// Keeping naming +	ActivePhysics::Info HitMeBaby; +	HitMeBaby.xDistToCenter = 0.0; +	HitMeBaby.yDistToCenter = 18.0; +	HitMeBaby.xDistToEdge   = 24.0; +	HitMeBaby.yDistToEdge   = 24.0; + +	//TODO find data for a fun, yet challenging, battle +	HitMeBaby.category1 = 0x3; +	HitMeBaby.category2 = 0x0; +	HitMeBaby.bitfield1 = 0x4f; +	HitMeBaby.bitfield2 = 0xffba7ffe; +	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(); + +	pos.y -= 20.0; +	pos.z = 3000.0; +	rot.x = rot.y = rot.z = speed.x = dying = 0.0; +	direction = 0; +	life = 3; +	//TODO 1) allow setting bounding rect with settings +	//TODO 2) don't use bounding rect. use wall/floor/ceiling detection +	Bounding.left = pos.x - 350.0; +	Bounding.top = pos.y + 500.0; +	Bounding.right = pos.x + 350.0; +	Bounding.bottom = pos.y; + +	OSReport("Setting MegaGoomba's State\n"); +	doStateChange(&StateID_Grow); + +	OSReport("Going to Execute MegaGoomba\n"); +	this->onExecute(); +	return true; +} + +int daMegaGoomba_c::onDelete() { +	return true; +} + +int daMegaGoomba_c::onExecute() { +	acState.execute(); +	updateModelMatrices(); + +	if (this->aPhysics.result1 == 1) { + +		char PlayerID = NearestPlayer(this); +		if(PlayerID > 0) { +			dStageActor_c *Player = GetSpecificPlayerActor(PlayerID); +			this->_vf220(Player); +		} +	} +	 +	return true; +} + +int daMegaGoomba_c::onDraw() { +	bodyModel.scheduleForDrawing(); +	return true; +} + + +void daMegaGoomba_c::updateModelMatrices() { +	// Bounds checking +	// TODO possibly change to a state change +	if(this->pos.x < this->Bounding.left) { +		this->direction = !this->direction; +		this->speed.x = -this->speed.x; +		this->pos.x = this->Bounding.left; +	} else if (this->pos.x > this->Bounding.right) { +		this->direction = !this->direction; +		this->speed.x = -this->speed.x; +		this->pos.x = this->Bounding.right; +	} +	if(this->pos.y < this->Bounding.bottom) { +		this->speed.y = 0.0; +		this->pos.y = this->Bounding.bottom; +	} else if (this->pos.y > this->Bounding.top) { +		this->speed.y = 0.0; +		this->pos.y = this->Bounding.bottom; +	} + +	// This won't work with wrap because I'm lazy. +	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); +} + + +// Grow State +void daMegaGoomba_c::beginState_Grow() {  +	this->timer = 1.0; + +	float start, end, shift1, shift2; +	start  = 59.0; +	shift1 = 90.0; +	shift2 = 120.0; +	end    = 139.0; +	/* keysX[i] = { frame, value, slope }; */ +	Xkey_count = 7; +	keysX[0] = (HermiteKey){ start,             1.0, 1.0 }; +	keysX[1] = (HermiteKey){ (start+shift1)/2,  2.0, 1.0 }; +	keysX[2] = (HermiteKey){ shift1,            4.0, 1.0 }; +	keysX[3] = (HermiteKey){ (shift1+shift2)/2, 3.0, 1.0 }; +	keysX[3] = (HermiteKey){ shift2,            6.0, 1.0 }; +	keysX[3] = (HermiteKey){ (shift2+end)/2,    5.0, 1.0 }; +	keysX[6] = (HermiteKey){ end,               7.0, 1.0 }; +} +void daMegaGoomba_c::executeState_Grow() {  +	 +	this->timer += 1.0; +	 +	if ((this->timer > 60.0) && (this->timer < 140.0)) { + +		float modifier = GetHermiteCurveValue(this->timer, this->keysX, Xkey_count); +		this->scale = (Vec){modifier, modifier, modifier}; +		setNewActivePhysicsRect(this, &this->scale); + +	} +	//TODO grow sound +	//if(this->timer == 60.0) +	//	playSound(SE_GROW); +	 +	if (this->timer > 170.0) { doStateChange(&StateID_Walk); } +	 +} +void daMegaGoomba_c::endState_Grow() { } + + +// Shrink State +void daMegaGoomba_c::beginState_Shrink() { +	this->timer = 1.0; +	Xkey_count = 4; +	keysX[0] = (HermiteKey){  0.0, this->scale.x,       1.0 }; +	keysX[1] = (HermiteKey){ 20.0, this->scale.x - 2.0, 1.0 }; +	keysX[2] = (HermiteKey){ 40.0, this->scale.x,       1.0 }; +	keysX[3] = (HermiteKey){ 59.0, this->scale.x - 2.0, 1.0 }; +} +void daMegaGoomba_c::executeState_Shrink() {  +	this->timer += 1.0; +	 +	float modifier = GetHermiteCurveValue(this->timer, this->keysX, Xkey_count); +	this->scale = (Vec){modifier, modifier, modifier}; +	setNewActivePhysicsRect(this, &this->scale); + +	//TODO shrink sound +	//if(this->timer == 2.0) +	//	playSound(SE_SHRINK); + +	if (this->timer > 60.0) { doStateChange(&StateID_Walk); } +} +void daMegaGoomba_c::endState_Shrink() { } + + + +// Launch State - Launches some small goombas up in arcs +void daMegaGoomba_c::beginState_Launch() {  +	this->timer = 0.0;  +} +void daMegaGoomba_c::executeState_Launch() {  +		 +	if (this->timer < 120.0) { +		// 3 shakes per second, exactly 24 shakes overall +		this->rot.y = sin(this->timer * 3.14 / 5) * 4000; + +		dStageActor_c *spawner = NULL; +		// 120ticks /  40numbers * 2cases  = 6avg kuribo +		int randChoice = GenerateRandomNumber(40); +		int randChoiceX = GenerateRandomNumber(12); +		int randChoiceY = GenerateRandomNumber(12); +		switch(randChoice) { +			case 0: +			case 1: +				spawner = CreateActor(EN_KURIBO, 0, this->pos, 0, 0); +				spawner->speed.x = randChoiceX - 6.0; +				spawner->speed.y = randChoiceY * 1.0; +				spawner->scale = (Vec){1.0, 1.0, 1.0}; +				break; +			case 2: +				spawner = CreateActor(EN_BEANS_KURIBO, 0, this->pos, 0, 0); +				spawner->speed.x = randChoiceX - 12.0; +				spawner->speed.y = randChoiceY * 1.0; +				spawner->scale = (Vec){1.0, 1.0, 1.0}; +				break; +			default: +				break; +		}; +	} + +	if (this->timer > 150.0) { doStateChange(&StateID_Walk); } +	this->timer = this->timer + 1.0; +} +void daMegaGoomba_c::endState_Launch() {  +	this->rot.y = 0; +} + +// Jump State +void daMegaGoomba_c::beginState_Jump() { +	this->timer = 1.0; + +	//Variables for choosing a curve +	float jump_height = 36.0; +	float delta = (this->direction) ? -24.0 : 24.0; +	float fullTime = 90.0; +	//Key count +	Xkey_count = 2; +	Ykey_count = 3; + +	//Initial Position +	keysX[0] = (HermiteKey){ 0.0, this->pos.x, 0.0 }; +	keysY[0] = (HermiteKey){ 0.0, this->pos.y, 0.8 }; + +	//Middle Position +	keysY[1] = (HermiteKey){ (fullTime/2.0), this->pos.y + jump_height, 0.0 }; + +	//End Position +	keysX[1] = (HermiteKey){ fullTime, this->pos.x + delta, 0.0 }; +	keysY[2] = (HermiteKey){ fullTime, this->pos.y, 0.8 }; + +} +void daMegaGoomba_c::executeState_Jump() {  + +	this->pos.x = GetHermiteCurveValue(this->timer, this->keysX, Xkey_count); +	this->pos.y = GetHermiteCurveValue(this->timer, this->keysY, Ykey_count); + +	float TimerMax = 91.0; +	if (this->timer > TimerMax) { +		doStateChange(&StateID_Walk); +	} + +	this->timer = this->timer + 1.0; + +} +void daMegaGoomba_c::endState_Jump() { } + + +// Walk State +void daMegaGoomba_c::beginState_Walk() { +	this->timer = 1.0; +	this->direction = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, this->pos); +	//TODO add rot.changing on switching directions until animations added  +} +void daMegaGoomba_c::executeState_Walk() {  + +	float delta = (this->direction) ? -0.5 : 0.5; +	this->pos.x += delta; +	 +	int Choice; +	float TimerMax = 150.0; +	if (this->timer > TimerMax) { + +		Choice = GenerateRandomNumber(4); +		switch(Choice) { +			case 0: +				doStateChange(&StateID_Jump); +				break; +			case 1: +				doStateChange(&StateID_Launch); +				break; +			case 2: +				break; +			//FIXME test case for sound effects +			//case 3: +			//	break; +			default: +				this->direction = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, pos); +				this->timer = 0; +				break; +		}; +		 +	} + +	this->timer = this->timer + 1.0; +} +void daMegaGoomba_c::endState_Walk() { } diff --git a/src/player.cpp b/src/player.cpp new file mode 100644 index 0000000..ec638d4 --- /dev/null +++ b/src/player.cpp @@ -0,0 +1,35 @@ +#include "player.h" + +// Please set your dStageActor_c's z coordinate +// Please check return for -1 +char NearestPlayer(dStageActor_c* actor) { +	char nearest = -1; +	float current = 3000000.0; + +	OSReport("FINDING NEAREST PLAYER\n"); +	for(char ii = 0; ii < 4; ii++) { +		OSReport("K, let's check out Player %d\n", ii); +		dStageActor_c* player = GetSpecificPlayerActor(ii); +		if(!player) { +			OSReport("Player %d is NULL\n", ii); +			continue; +		} +		OSReport("Player %d is ok\n", ii); +		OSReport("[%f,%f,%f] - [%f,%f,%f]\n", +				actor->pos.x, actor->pos.y, actor->pos.z, +				player->pos.x, player->pos.y, player->pos.z); +		float distance = VECDistance(&actor->pos, &player->pos); +		OSReport("Distance: %f [%f]\n", distance, current); +		if(distance < current) { +			current = distance; +			nearest = ii; +			OSReport("Nearest is now %d\n", ii); +		} +	} +	OSReport("NearestPlayer returning %d\n", nearest); +	if(nearest < 0) { +		OSReport("***FIX ME IMMEDIATELY***\n***NEED Z COORDINATES FOR ACTOR***\n"); +	} +	return nearest; +} + diff --git a/src/player.h b/src/player.h new file mode 100644 index 0000000..d225083 --- /dev/null +++ b/src/player.h @@ -0,0 +1,11 @@ +#ifndef __PLAYER_H +#define __PLAYER_H + +#include <common.h> +#include <game.h> + +extern "C" dStageActor_c* GetSpecificPlayerActor(int number); +char NearestPlayer(dStageActor_c* actor); + +#endif + | 
