Custom Controller Example: Having an Entity Fire Shots
From C4 Engine Wiki
Getting an Entity to Fire Shots
You can get an entity to fire shots (eg FireBalls) within your custom controller.
Here is an example following on from the "Add a Translation" example, which assumes you want your entity to fire shots at you. Just use the following (test) code for the SpinController::Move() method.
Note that this section assumes you are using the Game Application or that your application has Fireballs or other ammunition which you can fire.
Note also that this was last tested with Builds 145 and 146.
--Jimbobjames 04 February 2008
void SpinController::Move(void) { Matrix3D rotator; World *world = TheWorldMgr->GetWorld(); // Calculate the new spin angle based on how much time has passed float angle = spinAngle + spinRate * TheTimeMgr->GetFloatDeltaTime(); if (angle > 100.0F) angle -= 200.0F; else if (angle < -100.0F) angle += 200.0F; spinAngle = angle; Node *target = GetTargetNode(); Point3D startPos = target->GetNodePosition(); //you dont want the ammo to start inside the plane - this is just in front of the plane startPos.y += 5.0F; const Point3D& worldCenter = target->GetBoundingSphere()->GetCenter(); Point3D objectCenter = target->GetInverseWorldTransform() * worldCenter; //This fires forward and down - should really use the direction the plane is facing //Point3D objectVelocity = Point3D(0.0f, 1.0f, -0.1f); //This firing direction points along the local y axis - ie the direction the entity (plane) is heading Point3D objectVelocity = Point3D(-originalTransform[1].x,-originalTransform[1].y,-originalTransform[1].z); //You can hard code the starting pos of the fireball if you want //startPos = Point3D(5.0f, 5.0f, 2.0f); // Now make a 3x3 rotation matrix rotator.SetRotationAboutY(angle/10.0F); //Firing if (world) { Controller *controller; Entity *entity = nullptr; //Fire on some condition - here is just an example for a quick test if (((int)angle) % 30 == 0)//fire every x seconds { //create fireball!! controller = new FireballController(startPos, objectVelocity); entity = Entity::Get(kEntityFireball); if (entity) { entity->SetController(controller); Zone *zone = world->FindZone(startPos); Point3D zonePosition = zone->GetInverseWorldTransform() * startPos; entity->SetNodePosition(zonePosition); zone->AddNewSubnode(entity); entity->Update(); controller->EnterWorld(zone, zonePosition); } } } //end Firing // Make a 3x4 transform that rotates about the center point Transform4D transform(rotator, objectCenter - rotator * objectCenter); //Code added for a translation along the y axis Transform4D translation; Point3D myTranslation; myTranslation.x = 0.0F; myTranslation.z = 0.0F; myTranslation.y = -angle; 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(); }
