#include #include #include #include "player.h" #include "effects.h" #include class daWrench : public dEn_c { int onCreate(); int onExecute(); int onDelete(); int onDraw(); mHeapAllocator_c allocator; m3d::mdl_c bodyModel; int timer; char homing; char direction; char front; float ymod; int lifespan; static daWrench *build(); void updateModelMatrices(); void playerCollision(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther); bool collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther); void collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther); USING_STATES(daWrench); DECLARE_STATE(HandThrow); DECLARE_STATE(Homing); DECLARE_STATE(Straight); }; CREATE_STATE(daWrench, HandThrow); CREATE_STATE(daWrench, Homing); CREATE_STATE(daWrench, Straight); extern "C" void *PlaySound(dEn_c *, int soundID); extern "C" void *UpdateObjectPosBasedOnSpeedValues_real(daWrench *); extern "C" dStageActor_c *GetSpecificPlayerActor(int number); extern "C" void *HandleXSpeed(daWrench *); extern "C" void *HandleYSpeed(daWrench *); void daWrench::playerCollision(ActivePhysics *apThis, ActivePhysics *apOther) { this->_vf220(apOther->owner); this->isDead = 0; this->flags_4FC |= (1<<(31-7)); if(apOther->owner->_38D > 3) { OSReport("!!!ATTENTION!!!\napOther->owner->_38D > 3\n"); }else{ this->counter_504[apOther->owner->_38D] = 0; } } void daWrench::collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther) { } bool daWrench::collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther) { return false; } void daWrench::collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther) {} void daWrench::collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther) { CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){0.5, 0.5, 0.5}, 48); PlaySound(this, SE_BOSS_JR_FLOOR_BREAK); this->Delete(); } void daWrench::collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther) {} daWrench *daWrench::build() { void *buffer = AllocFromGameHeap1(sizeof(daWrench)); return new(buffer) daWrench; } int daWrench::onCreate() { allocator.link(-1, GameHeaps[0], 0, 0x20); nw4r::g3d::ResFile rf(getResource("choropoo", "g3d/choropoo.brres")); bodyModel.setup(rf.GetResMdl("spanner"), &allocator, 0x224, 1, 0); SetupTextures_Enemy(&bodyModel, 0); allocator.unlink(); this->direction = this->settings & 0xF; this->homing = (this->settings >> 4) & 0xF; this->front = (this->settings >> 8) & 0xF; ActivePhysics::Info HitMeBaby; if (this->homing == 0) { HitMeBaby.xDistToCenter = 0.0; HitMeBaby.yDistToCenter = 0.0; HitMeBaby.xDistToEdge = 6.0; HitMeBaby.yDistToEdge = 6.0; this->scale.x = 1.5; this->scale.y = 1.5; this->scale.z = 1.5; } else { HitMeBaby.xDistToCenter = 0.0; HitMeBaby.yDistToCenter = 0.0; HitMeBaby.xDistToEdge = 12.0; HitMeBaby.yDistToEdge = 12.0; this->scale.x = 3.0; this->scale.y = 3.0; this->scale.z = 3.0; } HitMeBaby.category1 = 0x3; HitMeBaby.category2 = 0x0; HitMeBaby.bitfield1 = 0x47; HitMeBaby.bitfield2 = 0xFFFFFFFF; HitMeBaby.unkShort1C = 0; HitMeBaby.callback = &dEn_c::collisionCallback; this->aPhysics.initWithStruct(this, &HitMeBaby); this->aPhysics.addToList(); this->pos.z = 3300.0; doStateChange(&StateID_HandThrow); this->onExecute(); return true; } int daWrench::onDelete() { return true; } int daWrench::onDraw() { bodyModel.scheduleForDrawing(); return true; } void daWrench::updateModelMatrices() { 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); } int daWrench::onExecute() { acState.execute(); updateModelMatrices(); return true; } void daWrench::beginState_HandThrow() { if (this->direction == 0) { // Ground Facing Left this->pos.x += 32.0; this->pos.y += 48.0; this->rot.z = 0x4000; } else if (this->direction == 1) { // Ground Facing Right this->pos.x -= 32.0; this->pos.y += 48.0; this->rot.z = 0xC000; } else if (this->direction == 2) { // Upside Down Facing Left this->pos.x += 32.0; this->pos.y -= 48.0; this->rot.z = 0x4000; } else if (this->direction == 3) { // Upside Down Facing Right this->pos.x -= 32.0; this->pos.y -= 48.0; this->rot.z = 0xC000; } if (this->front == 1) { this->pos.z = -1804.0; } this->lifespan = 0; } void daWrench::executeState_HandThrow() { if (this->lifespan > 30) { if (this->homing == 0) { doStateChange(&StateID_Straight); } else { doStateChange(&StateID_Homing); } } this->lifespan += 1; } void daWrench::endState_HandThrow() { } void daWrench::beginState_Homing() { this->lifespan = 360; Vec tempPos = this->pos; char PlayerID = NearestPlayer(this); dStageActor_c *Player = GetSpecificPlayerActor(PlayerID); if ((Player->pos.y >= tempPos.y - 16.0) && (Player->pos.y <= tempPos.y + 16.0)) { this->ymod = 0.0; } else if ((Player->pos.y >= tempPos.y - 106.0) && (Player->pos.y < tempPos.y - 16.0)) { this->ymod = -0.6; } else if ((Player->pos.y <= tempPos.y + 106.0) && (Player->pos.y > tempPos.y + 16.0)) { this->ymod = 0.6; } else if (Player->pos.y < tempPos.y - 106.0) { this->ymod = -1.2; } else if (Player->pos.y > tempPos.y + 106.0) { this->ymod = 1.2; } else { this->ymod = 0.0; } if (this->direction & 1) { this->speed.x = -1.5; } else { this->speed.x = 1.5; } this->speed.y = 0; } void daWrench::executeState_Homing() { if (this->direction && 1) { // directions 1 and 3 spin clockwise, fly rightwards this->rot.z -= 0x1000; } else { // directions 0 and 2 spin anti-clockwise, fly leftwards this->rot.z += 0x1000; } this->pos.y += this->ymod * this->lifespan / 360; UpdateObjectPosBasedOnSpeedValues_real(this); if (this->lifespan < 1) { PlaySound(this, SE_OBJ_HAMMER_HIT_BOTH); CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){1.5, 1.5, 1.5}, 242); this->Delete(); } PlaySound(this, SE_EMY_CHOROPU_M_SPANNER); this->lifespan -= 1; } void daWrench::endState_Homing() { } void daWrench::beginState_Straight() { char PlayerID = NearestPlayer(this); dStageActor_c *Player = GetSpecificPlayerActor(PlayerID); float slope = ( (this->pos.y - Player->pos.y) / (this->pos.x - Player->pos.x) ); Vec tempPos = this->pos; if (this->direction & 1) { this->speed.x = -2.0; this->speed.y = 2.0 * slope; } else { this->speed.x = 2.0; this->speed.y = 2.0 * slope; } } void daWrench::executeState_Straight() { this->lifespan = 360; if (this->direction && 1) { // directions 1 and 3 spin clockwise, fly rightwards this->rot.z -= 0x1000; } else { // directions 0 and 2 spin anti-clockwise, fly leftwards this->rot.z += 0x1000; } UpdateObjectPosBasedOnSpeedValues_real(this); PlaySound(this, SE_EMY_CHOROPU_M_SPANNER); if (this->lifespan == (360-45)) { this->pos.z = 3300.0; } if (this->lifespan < 1) { PlaySound(this, SE_OBJ_HAMMER_HIT_BOTH); CreateEffect(&this->pos, &(S16Vec){0,0,0}, &(Vec){0.75, 0.75, 0.75}, 242); this->Delete(); } this->lifespan -= 1; } void daWrench::endState_Straight() { }