ArduinoRGB Amp
TutorialArduino has fast become one of my favourite hobbies. A cheap and reliable board based on an ATMEL microprocessor that allows for easy and quick prototyping.
One use is to control a strip of LEDs, check out my tutorial on controlling a RGB strip with IR for more information!
D.M.A. Distributing
VisitThe website is heavily based off this one but is a demonstration of my ability to use and maintain websites involcing xHTML and CSS
SQL Sample
Code DownloadCreate a database named "SE4M03" to test, run create, data, show, query in sequence
Tested on a IBM DB2 system
Project T
Doxygen DownloadProject T was a final year project completed by me and 3 others. A majority of the C++ codeing was done by myself. Above you can find the documentation as well as a download link for the game.
To start, Extract, Open C4.exe, Press '~', and type 'start intro'
Below is a sample of the code.
Platform Controller
platform.h
/** * @file PTPlatform.h * PLatform controller * * @brief Platform controller * * This controller pushes an object in any combination of forward directions in the world * Due to a design flaw it is nesecary to comensate for negative shifts by placing the object * at the destination and setting the current position to the maximum distance traveled. * The platforms rely on the engines gravity to move the models along the Z axis. The X and Y * movements are applied to models that fall with in the bounds of the platform. * * @author Daryl Dippel * @version 1 * */ // ================================================================================================ #ifndef PTPlatform_h #define PTPlatform_h #include "C4Controller.h" #include "C4Properties.h" #include "C4Effects.h" #include "PTControllers.h" #include "PTPlayer.h" namespace C4 { /** * @brief Controller class for Vector Platform * * Takes a x,y,z distance and x,y,z speed and oscilates with that data * */ class VectorPlatformController : public Controller { private: float spinRate; // In radians per millisecond float spinAngle; // The current angle, in radians float push; // Are we pushing float count; // reduce number of contacts float xMoveRate; float yMoveRate; float zMoveRate; float xMoveDistance; float yMoveDistance; float zMoveDistance; int xFlip; int yFlip; int zFlip; float xCurPos; // The current position along X path float yCurPos; // The current position along Y path float zCurPos; // The current position along Z path Transform4D originalTransform; // The targets original transform VectorPlatformController(const VectorPlatformController& tpinController); Controller *Replicate(void) const; public: VectorPlatformController(); VectorPlatformController(float rate, float xr, float yr, float zr, float x, float y, float z, float xc, float yc, float zc); ~VectorPlatformController(); float GetSpinRate(void) const { return (spinRate); } void SetSpinRate(float rate) { spinRate = rate; } static bool ValidNode(const Node *node); // Serialization functions void Pack(Packer& data, unsigned long packFlags) const; void Unpack(Unpacker& data, unsigned long unpackFlags); // User interface functions long GetSettingCount(void) const; Setting *GetSetting(long index) const; void SetSetting(const Setting *setting); void Preprocess(void); // The function that moves the target node void Move(void); }; } #endif }
platform.cpp
/** * @file PTPlatform.cpp * PLatform controller * * @brief Platform controller * * This controller pushes an object in any combination of forward directions in the world * Due to a design flaw it is nesecary to comensate for negative shifts by placing the object * at the destination and setting the current position to the maximum distance traveled. * The platforms rely on the engines gravity to move the models along the Z axis. The X and Y * movements are applied to models that fall with in the bounds of the platform. * * @author Group 1 4GP6 * @version 1 * */ // ================================================================================================ #include "PTGame.h" #include "PTPlatform.h" #include "PTControllers.h" using namespace C4; ////////////////// VectorPlatform VectorPlatformController::VectorPlatformController() : Controller(kControllerVectorPlatform) { spinRate = 0.0F; spinAngle = 0.0F; // must initialize with movement or div by 0 explodes world ankd sets fire to souls xMoveRate = 100.0F; yMoveRate = 100.0F; zMoveRate = 100.0F; xMoveDistance = 10.0F; yMoveDistance = 10.0F; zMoveDistance = 10.0F; xCurPos = 0.0F; yCurPos = 0.0F; zCurPos = 0.0F; xFlip = 0; yFlip = 0; zFlip = 0; count =0; } VectorPlatformController::VectorPlatformController(float rate, float xr,float yr,float zr, float x, float y, float z, float xc, float yc, float zc) : Controller(kControllerVectorPlatform) { spinRate = rate; spinAngle = 0.0F; xMoveRate = xr; yMoveRate = yr; zMoveRate = zr; xMoveDistance = x; yMoveDistance = y; zMoveDistance = z; xCurPos = xc; yCurPos = yc; zCurPos = zc; xFlip = 0; yFlip = 0; zFlip = 0; count =0; } VectorPlatformController::~VectorPlatformController() { } VectorPlatformController::VectorPlatformController(const VectorPlatformController& VectorPlatformController) : Controller(VectorPlatformController) { spinRate = VectorPlatformController.spinRate; spinAngle = 0.0F; xMoveRate = VectorPlatformController.xMoveRate; yMoveRate = VectorPlatformController.yMoveRate; zMoveRate = VectorPlatformController.zMoveRate; xMoveDistance = VectorPlatformController.xMoveDistance; yMoveDistance = VectorPlatformController.yMoveDistance; zMoveDistance = VectorPlatformController.zMoveDistance; xCurPos = VectorPlatformController.xCurPos; yCurPos = VectorPlatformController.yCurPos; zCurPos = VectorPlatformController.zCurPos; xFlip = 0; yFlip = 0; zFlip = 0; } Controller *VectorPlatformController::Replicate(void) const { return (new VectorPlatformController(*this)); } bool VectorPlatformController::ValidNode(const Node *node) { return (node->GetNodeType() == kNodeGeometry); } void VectorPlatformController::Pack(Packer& data, unsigned long packFlags) const { Controller::Pack(data, packFlags); // Write the spin rate data << spinRate; // Write the current angle data << spinAngle; // Write the original transform data << originalTransform; // Write moar data << xMoveRate; data << yMoveRate; data << zMoveRate; data << xMoveDistance; data << yMoveDistance; data << zMoveDistance; data << xCurPos; data << yCurPos; data << zCurPos; } void VectorPlatformController::Unpack(Unpacker& data, unsigned long unpackFlags) { Controller::Unpack(data, unpackFlags); // Read the spin rate data >> spinRate; // Read the current angle data >> spinAngle; // Read the original transform data >> originalTransform; data >> xMoveRate; data >> yMoveRate; data >> zMoveRate; data >> xMoveDistance; data >> yMoveDistance; data >> zMoveDistance; data >> xCurPos; data >> yCurPos; data >> zCurPos; } long VectorPlatformController::GetSettingCount(void) const { // Theres only one setting return (10); } Setting *VectorPlatformController::GetSetting(long index) const { if (index == 0) { // spin value in revolutions per second return (new TextSetting('rate', Text::FloatToString(spinRate * 1000.0F / K::two_pi), "Spin rate", 7, &EditableTextElement::FloatNumberFilter)); } if (index == 1) { // move rate value return (new TextSetting('mvrx', Text::FloatToString(xMoveRate), "X Move Rate", 7, &EditableTextElement::FloatNumberFilter)); } if (index == 2) { // move rate value return (new TextSetting('mvry', Text::FloatToString(yMoveRate), "Y Move Rate", 7, &EditableTextElement::FloatNumberFilter)); } if (index == 3) { // move rate value return (new TextSetting('mvrz', Text::FloatToString(zMoveRate), "Z Move Rate", 7, &EditableTextElement::FloatNumberFilter)); } if (index == 4) { // move dist value return (new TextSetting('mvdx', Text::FloatToString(xMoveDistance), "X Move Distance", 7, &EditableTextElement::FloatNumberFilter)); } if (index == 5) { // move dist value return (new TextSetting('mvdy', Text::FloatToString(yMoveDistance), "Y Move Distance", 7, &EditableTextElement::FloatNumberFilter)); } if (index == 6) { // move dist valur return (new TextSetting('mvdz', Text::FloatToString(zMoveDistance), "Z Move Distance", 7, &EditableTextElement::FloatNumberFilter)); } if (index == 7) { // move dist value return (new TextSetting('mvcx', Text::FloatToString(xCurPos), "X Start Distance", 7, &EditableTextElement::FloatNumberFilter)); } if (index == 8) { // move dist value return (new TextSetting('mvcy', Text::FloatToString(yCurPos), "Y Start Distance", 7, &EditableTextElement::FloatNumberFilter)); } if (index == 9) { // move dist valur return (new TextSetting('mvcz', Text::FloatToString(zCurPos), "Z Start Distance", 7, &EditableTextElement::FloatNumberFilter)); } return (nullptr); } void VectorPlatformController::SetSetting(const Setting *setting) { if (setting->GetSettingIdentifier() == 'rate') { // get spin and convert const char *text = static_cast(setting)->GetText(); spinRate = Text::StringToFloat(text) * K::two_pi / 1000.0F; } if (setting->GetSettingIdentifier() == 'mvrx') { // get move rate const char *text = static_cast (setting)->GetText(); xMoveRate = Text::StringToFloat(text); } if (setting->GetSettingIdentifier() == 'mvry') { // get move rate const char *text = static_cast (setting)->GetText(); yMoveRate = Text::StringToFloat(text); } if (setting->GetSettingIdentifier() == 'mvrz') { // get move rate const char *text = static_cast (setting)->GetText(); zMoveRate = Text::StringToFloat(text); } if (setting->GetSettingIdentifier() == 'mvdx') { // get move dist const char *text = static_cast (setting)->GetText(); xMoveDistance = Text::StringToFloat(text); } if (setting->GetSettingIdentifier() == 'mvdy') { // get move dist const char *text = static_cast (setting)->GetText(); yMoveDistance = Text::StringToFloat(text); } if (setting->GetSettingIdentifier() == 'mvdz') { // get move dist const char *text = static_cast (setting)->GetText(); zMoveDistance = Text::StringToFloat(text); } if (setting->GetSettingIdentifier() == 'mvcx') { // get move dist const char *text = static_cast (setting)->GetText(); xCurPos = Text::StringToFloat(text); } if (setting->GetSettingIdentifier() == 'mvcy') { // get move dist const char *text = static_cast (setting)->GetText(); yCurPos = Text::StringToFloat(text); } if (setting->GetSettingIdentifier() == 'mvcz') { // get move dist const char *text = static_cast (setting)->GetText(); zCurPos = Text::StringToFloat(text); } } void VectorPlatformController::Preprocess(void) { Controller::Preprocess(); // Grab the original transform of the target node const Node *target = GetTargetNode(); originalTransform = target->GetNodeTransform(); // Set the kGeometryDynamic flag for any geometry nodes const Node *node = target; do { if (node->GetNodeType() == kNodeGeometry) { // Node is a geometry, so grab its object GeometryObject *object = static_cast (node)->GetObject(); // Set the kGeometryDynamic flag object->SetGeometryFlags(object->GetGeometryFlags() | kGeometryDynamic); } // Iterate through entire subtree node = target->GetNextNode(node); } while (node); } void VectorPlatformController::Move(void) { Matrix3D rotator; // Calculate the new spin angle based on how much time has passed float angle = spinAngle + spinRate * TheTimeMgr->GetFloatDeltaTime(); // Make sure its in the [-pi, pi] range if (angle > K::pi) angle -= K::two_pi; else if (angle < -K::pi) angle += K::two_pi; spinAngle = angle; // Now make a 3x3 rotation matrix rotator.SetRotationAboutZ(angle); // We'll rotate about the center of the target node's bounding sphere Node *target = GetTargetNode(); const Point3D& worldCenter = target->GetBoundingSphere()->GetCenter(); Point3D objectCenter = target->GetInverseWorldTransform() * worldCenter; const float& platRadius = target->GetBoundingSphere()->GetRadius(); // Make a 3x4 transform that rotates about the center point Transform4D transform(rotator, objectCenter - rotator * objectCenter); // Apply the rotation transform to the original transform and // assign it to the node as its new transform //Code added for a translation along the y axis // /moveRate + curPos Transform4D translation; Point3D myTranslation; Node *block = this->GetTargetNode(); Point3D blockPosition = block->GetNodePosition(); Object *blockObj = block->GetObject(); // Grab PLayer Info PlayerController *player = TheGame->GetPlayerController(); Point3D p = player->GetTargetNode()->GetNodePosition(); Point3D pnew = player->GetTargetNode()->GetNodePosition(); /*TheEngine->Report(String<16>(objectCenter.x + xCurPos)); TheEngine->Report(String<16>(objectCenter.y + yCurPos)); TheEngine->Report(String<16>(objectCenter.z + zCurPos)); TheEngine->Report(String<16>("Block Cord")); TheEngine->Report(String<16>(blockPosition.x + xCurPos)); TheEngine->Report(String<16>(blockPosition.y + yCurPos)); TheEngine->Report(String<16>(blockPosition.z + zCurPos));*/ float sampler = 5; push = 4.0; //////// TODO MOVE PLAYER if ((p.z < (15+ blockPosition.z)) && (p.z > (blockPosition.z)) ) {if ((p.y < (blockPosition.y + (objectCenter.y * 2))) && (p.y > (blockPosition.y )) ) {if ((p.x < (blockPosition.x + (objectCenter.x * 2))) && (p.x > (blockPosition.x)) ) { if (count == 0) {push = 1.0; if (xFlip == 0) {pnew.x = p.x + sampler * (xMoveRate);} if (xFlip == 1) {pnew.x = p.x - sampler * (xMoveRate);} if (yFlip == 0) {pnew.y = p.y + sampler * (yMoveRate);} if (yFlip == 1) {pnew.y = p.y - sampler * (yMoveRate);} player->SetRigidBodyPosition(pnew); } if (count == (sampler-1)) { count = 0;} else {count++;} } } } TheDebugInterface->UpdateTmpVar((blockPosition.x),(blockPosition.y),(yCurPos), (blockPosition.x + (objectCenter.x * 2)),(blockPosition.y + (objectCenter.y * 2)),push); //TheEngine->Report(String<16>("Bounding")); //TheEngine->Report(String<16>(push)); // Positive Move Dist if (xCurPos > xMoveDistance) { xFlip = 1; } if (xCurPos < 0) { xFlip = 0; } // Check Direction and Move if (xFlip == 0) { xCurPos = xCurPos + xMoveRate; } if (xFlip == 1) { xCurPos = xCurPos - xMoveRate; } // Update Object Translation myTranslation.x = xCurPos; // Y Transform if (yCurPos > yMoveDistance) { yFlip = 1; } if (yCurPos < 0) { yFlip = 0; } if (yFlip == 0) { yCurPos = yCurPos + yMoveRate; } if (yFlip == 1) { yCurPos = yCurPos - yMoveRate; } myTranslation.y = yCurPos; //Debugging output to demonstrate platform variables //TheEngine->Report(String<16>(yCurPos)); //TheEngine->Report(String<16>(yFlip)); //TheEngine->Report(String<16>(yMoveDistance)); // Z Transform if (zCurPos > zMoveDistance) { zFlip = 1; } if (zCurPos < 0) { zFlip = 0; } if (zFlip == 0) { zCurPos = zCurPos + zMoveRate; } if (zFlip == 1) { zCurPos = zCurPos - zMoveRate; } myTranslation.z = zCurPos; translation.SetIdentity(); translation.SetTranslation(myTranslation); //apply the rotation and the translation to the original transform target->SetNodeTransform(originalTransform * translation * transform); // Invalidate the target node so that it gets updated properly target->Invalidate(); } * @brief Main player controller * * This is the main player controller that the player uses to interact with our world. * It includes variables to track position, as well as direction, player mode, frame animation * health, speed and point states as well as various attack moves. * * @author Daryl Dippel * @version 1 * */ // ================================================================================================ #include "PTPlayer.h" #include "PTCamera.h" #include "PTGame.h" // Player constants static const long CANNON_LOAD_TIME = 3000; // Time between each cannon shot in milliseconds PlayerController::PlayerController(float azimuth) : CharacterController(kControllerPlayer) { playerAnimation = kAnimationNone; // -------------------------------- movementFlags = 0; modelAzimuth = azimuth; modelAltitude = 0.0f; state.Health = 100; state.EnergyBlue = 100; state.EnergyRed = 100; state.Mode = kModeNormal; state.Speed = 50.0f; state.Strength = 50.0f; state.Score = 0; strengthMod = 1.0f; speedMod = 1.0f; canFireCannon = true; cannonTimer = new Timer(&PlayerController::HandleCannonTimer, this); TheTimeMgr->AddEvent(cannonTimer); isBrawling = false; isExploding = false; playedDeathSound = false; } PlayerController::~PlayerController(void) { } void PlayerController::SendInitialStateMessages(Player *player) const { // Ignore if this machine isnt server if (!TheMessageMgr->Server()) return; PlayerSpawnMessage msg(TheMessageMgr->GetLocalPlayerKey(), this->GetControllerIndex(), this->GetTargetNode()->GetNodePosition(), this->GetModelAzimuth(), this->GetModelAltitude(), this->GetMovementFlags(), this->GetMode()); TheMessageMgr->SendMessage(player->GetPlayerKey(), msg); } void PlayerController::Preprocess(void) { CharacterController::Preprocess(); this->SetRigidBodyFlags(kRigidBodyKeepAwake | kRigidBodyFixedOrientation); this->SetFrictionCoefficient(0.0f); Model *player = this->GetTargetNode(); frameAnimator.SetTargetModel(player); player->SetRootAnimator(&frameAnimator); this->redFlareEffect = this->GetRedFlareEffect(); this->blueFlareEffect = this->GetBlueFlareEffect(); this->redFlareEffect->GetObject()->SetOcclusionRadius(0.3f); this->blueFlareEffect->GetObject()->SetOcclusionRadius(0.3f); this->MAX_HEALTH = 100.0f; this->MIN_HEALTH = 0.0f; this->MAX_ENERGY = 100.0f; this->MIN_ENERGY = 0.0f; this->ENERGY_DEPLETION_RATE = 0.05f; this->SetMode(kModeNormal); (this->state).Health = MAX_HEALTH; (this->state).EnergyBlue = MAX_ENERGY; (this->state).EnergyRed = MAX_ENERGY; } void PlayerController::Move(void) { Model *model = this->GetTargetNode(); Point3D oldPosition = model->GetNodePosition(); // Kill the player if theyre below certain height if (model->GetNodePosition().z <= -50.0f) { this->RemoveHealth(999999.0f); } // Set movement matrix static const unsigned char movementIndexTable[16] = { 8, 0, 1, 8, 2, 4, 6, 2, 3, 5, 7, 3, 8, 0, 1, 8 }; // Calculate model azimuth and altitude float azm = modelAzimuth + TheInputMgr->GetMouseDeltaX(); if (azm < -K::pi) azm += K::two_pi; else if (azm > K::pi) azm -= K::two_pi; float alt = modelAltitude + TheInputMgr->GetMouseDeltaY(); if (alt < -1.45F) alt = -1.45F; else if (alt > 1.45F) alt = 1.45F; modelAzimuth = azm; modelAltitude = alt; // Only do these if player is alive if (this->GetHealth() > 0.99f) { long animation = playerAnimation; Vector3D propel(0.0f, 0.0f, 0.0f); // Set movement and select appropriate animation long index = movementIndexTable[movementFlags & kMovementPlanarMask]; if (index < 8) { static const float movementDirectionTable[8] = { 0.0F, 4.0F, 2.0F, -2.0F, 1.0F, -1.0F, 3.0F, -3.0F }; float direction = movementDirectionTable[index] * K::pi_over_4 + modelAzimuth; propel.x = Cos(direction) * this->GetSpeed() * this->GetSpeedMod(); propel.y = Sin(direction) * this->GetSpeed() * this->GetSpeedMod(); animation = ((index == 1) || (index >= 6)) ? kAnimationBackward : kAnimationForward; } else { animation = kAnimationStand; } if (movementFlags >= 16) { animation = kAnimationJump; propel.z = this->GetStrength() * this->GetStrengthMod() * 1.2f; // Jump Modifier = 0.80f } if (GroundContact()) { SetExternalLinearResistance(Vector3D(10.0f, 10.0f, 0.0f)); SetExternalForce(propel); } else { SetExternalLinearResistance(Vector3D(0.0f, 0.0f, 0.0f)); propel.x *= 0.0001f * this->GetStrength(); propel.y *= 0.0001f * this->GetStrength(); propel.z *= 0.02f; SetExternalForce(propel); // Air Control Modifier = 0.02f } SetCharacterOrientation(modelAzimuth); // Attack animations if (this->IsBrawling()) animation = kAnimationBrawl; else if (this->IsExploding()) animation = kAnimationExplode; if (animation != playerAnimation) SetPlayerAnimation(animation); GetTargetNode()->Animate(); // Check for any triggers the player might be activating model->GetWorld()->ActivateTriggers(oldPosition, model->GetNodePosition(), 0.5f, model); // Mode dependant effects if (this->GetMode() == kModeRed) { this->RemoveRedEnergy(this->ENERGY_DEPLETION_RATE); if (this->GetRedEnergy() <= 0.0f) this->SetMode(kModeNormal); } else if (this->GetMode() == kModeBlue) { this->RemoveBlueEnergy(this->ENERGY_DEPLETION_RATE); if (this->GetBlueEnergy() <= 0.0f) this->SetMode(kModeNormal); } else { // Do nothing } //DD Debug Cord Update TheDebugInterface->UpdatePlayerPos(); } else { // If player is dead, play the death sound only once if (!playedDeathSound) { playedDeathSound = true; Sound *sound = new Sound; sound->Load("sound/death"); sound->Play(); } TheDeathInterface->Open(); } TheHudInterface->UpdateInterface(); } void PlayerController::SetMode(ModeType m) { state.Mode = m; World *world = TheWorldMgr->GetWorld(); Zone *zone = world->GetRootNode(); Sound *sound = new Sound; switch (m) { case kModeRed: if (TheBlueInterface) { TheBlueInterface->Close(); } this->SetStrength(40.0f); this->SetSpeed(120.0f); sound->Load("sound/gun_change01"); sound->Play(); this->redFlareEffect->Enable(); this->blueFlareEffect->Disable(); //spiral->ChangeColor(ColorRGB(1.0f,0.0f,0.0f)); TheRedInterface->Open(); break; case kModeBlue: if (TheRedInterface) { TheRedInterface->Close(); } this->SetStrength(150.0f); this->SetSpeed(25.0f); sound->Load("sound/gun_change01"); sound->Play(); this->redFlareEffect->Disable(); this->blueFlareEffect->Enable(); TheBlueInterface->Open(); break; case kModeNormal: default: if (TheRedInterface) { TheRedInterface->Close(); } if (TheBlueInterface) { TheBlueInterface->Close(); } this->SetStrength(90.0f); this->SetSpeed(50.0f); sound->Load("sound/gun_change02"); sound->Play(); this->redFlareEffect->Disable(); this->blueFlareEffect->Disable(); break; } } bool PlayerController::Collect(DynamicObjectController *dyno) { // Get all DynObj modifiers and add them to the player this->AddHealth(dyno->GetHealthModifier()); this->AddBlueEnergy(dyno->GetBlueEnergyModifier()); this->AddRedEnergy(dyno->GetRedEnergyModifier()); this->AddScore(dyno->GetScoreModifier()); int i = dyno->GetKeyNum(); /* //TODO : Key Collection if (i == 1) {TheRedDoor->Key();} */ Sound *sound = new Sound; sound->Load("sound/pop"); sound->Play(); // Interface Update TheDebugInterface->UpdatePlayerScore(); TheDebugInterface->UpdatePlayerHealth(); return true; } void PlayerController::SetPlayerAnimation(long animation) { Interpolator *interpolator = frameAnimator.GetFrameInterpolator(); if (animation == kAnimationStand) { frameAnimator.SetAnimation("model/Idle"); interpolator->SetMode(kInterpolatorForward | kInterpolatorLoop); } else if (animation == kAnimationForward) { frameAnimator.SetAnimation("model/Walk"); interpolator->SetMode(kInterpolatorForward | kInterpolatorLoop); } else if (animation == kAnimationBackward) { frameAnimator.SetAnimation("model/Walk"); interpolator->SetMode(kInterpolatorForward | kInterpolatorLoop); } else if (animation == kAnimationJump) { frameAnimator.SetAnimation("model/Jump"); interpolator->SetMode(kInterpolatorForward); } else if (animation == kAnimationBrawl) { frameAnimator.SetAnimation("model/Brawl"); interpolator->SetMode(kInterpolatorForward); } else if (animation == kAnimationExplode) { frameAnimator.SetAnimation("model/Explode"); interpolator->SetMode(kInterpolatorForward); } playerAnimation = animation; } void PlayerController::FireCannon(void) { if (this->CanFireCannon()) { World *world = TheWorldMgr->GetWorld(); Point3D position = this->GetTargetNode()->GetNodePosition(); Vector3D positionOffset(Cos(this->modelAzimuth), Sin(this->modelAzimuth), 1.6f); position += positionOffset; Model *model = Model::Get(kModelCannonball); CannonballController *controller = new CannonballController(this->modelAzimuth, this->modelAltitude); model->SetController(controller); Zone *zone = world->GetRootNode(); zone->AddNewSubnode(model); controller->SetRigidBodyPosition(position); controller->Fire(); // TODO Put a setting that can disable camera shake PTCamera *camera = static_cast (world->GetCamera()); camera->Shake(); this->DisableCannonFire(); cannonTimer->SetTime(CANNON_LOAD_TIME); // Recoil float k = -(controller->GetKickbackForce()); // If in air, reduce the recoil if (!this->GroundContact()) k /= 4.0f; Vector3D v(k, 0.0f, 0.0f); Sound *sound = new Sound; sound->Load("sound/cannon"); sound->Play(); this->ApplyImpulse(v); //Particle Effects! Point3D effectPos = this->GetTargetNode()->GetNodePosition() + Point3D(0.0f,0.0f,this->modelAltitude+1.6f); SparksSystem *sparks = new SparksSystem(20); sparks->SetNodePosition(effectPos); zone->AddNewSubnode(sparks); const ConstColorRGBA smokeColor = {0.6F,0.6F,0.6F,0.7F}; SmokeTrail *smoke = new SmokeTrail(smokeColor, "texture/Trail"); smoke->SetNodePosition(effectPos); zone->AddNewSubnode(smoke); float smokeDrift = 0.00f; int count = 4 + Math::Random(20); Point3D delta = Point3D(Cos(this->modelAzimuth),sin(this->modelAzimuth),smokeDrift); do { smoke->CreateSmoke(effectPos + delta, Math::Random(1000) + 1000, 0.01F); delta += Point3D(Cos(this->modelAzimuth),sin(this->modelAzimuth),smokeDrift); } while ((count -= 1.0F) > 0.0F); } } void PlayerController::Brawl(void) { if (!this->isBrawling) { this->isBrawling = true; Point3D p1 = this->GetTargetNode()->GetNodePosition() + Point3D(Cos(this->GetModelAzimuth())*3, Sin(this->GetModelAzimuth())*3, 1.0f); Point3D p2 = p1 + Point3D(0.0f, 0.0, 1.0f); CollisionData *data = new CollisionData(); CollisionState s = TheWorldMgr->GetWorld()->QueryWorld(p1, p2, 0.8f, kCollisionProjectile, data); // Very messy and dirty fix if (s == kCollisionStateRigidBody) { if (data) { if (data->rigidBody->GetControllerType() == kControllerTurret) { TheEngine->Report("Turret!"); TurretController *turret = static_cast (data->rigidBody); float h = 30.0f; if (this->GetMode() == kModeBlue) { h = 10.0f; } turret->RemoveHealth(h); } } } else if (s == kCollisionStateGeometry) { if (data) { const char *name = data->geometry->GetNodeName(); TheEngine->Report(name); } } else { TheEngine->Report("No Collision!"); } } } void PlayerController::UnBrawl(void) { this->isBrawling = false; } void PlayerController::Explode(void) { this->isExploding = true; World *world = TheWorldMgr->GetWorld(); Zone *zone = world->GetRootNode(); } void PlayerController::UnExplode(void) { this->isExploding = false; } void PlayerController::HandleCannonTimer(DeferredEvent *timer, void *data) { PlayerController *player = static_cast (data); if (!player->CanFireCannon()) player->EnableCannonFire(); } FlareEffect *PlayerController::GetRedFlareEffect(void) const { Node *root = this->GetTargetNode(); Node *node = root; String<31> name; name = "red"; String<31> nodeName(""); do { if (node->GetNodeName()) nodeName = node->GetNodeName(); if (name == static_cast (nodeName)) { break; } node = root->GetNextNode(node); } while (node); FlareEffect *effect = static_cast (node); return effect; } FlareEffect *PlayerController::GetBlueFlareEffect(void) const { Node *root = this->GetTargetNode(); Node *node = root; String<31> name; name = "blue"; String<31> nodeName(""); do { if (node->GetNodeName()) nodeName = node->GetNodeName(); if (name == static_cast (nodeName)) { break; } node = root->GetNextNode(node); } while (node); FlareEffect *effect = static_cast (node); return effect; } void PlayerController::print_stats(void) { TheEngine->Report(String<16>("Health: ") + String<16>(this->GetHealth())); } }