Custom Controller Example: Having an Entity Fire Shots

From C4 Engine Wiki

Jump to: navigation, search

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();
}
Personal tools