
@@Game Tutorials
 

@@Tutorial: Capture The Flags
* Overview *
To implement the GameRules for a Capture The Flags gameplay,
a new GameRules scripts need to be written.



* New files to be added *
Two new files needs to be created.



    * Game/Scripts/GameRules/CaptureTheFlags.lua
    * Game/Scripts/Entities/Multiplayer/Flag_CTF.lua



* GameRules implementation *
Crysis already provides several base GameRules
implementations, including <I>Singleplayer</I>, <I>DeathMatch</I>,
<I>TeamDeathMatch</I>. It's possible to derive from these
GameRules to reuse their core functionalities.



To implemement the Capture The Flags GameRules, we will
derive from the TeamDeathMatch GameRules. We need to write
the following lines at the beginning of our GameRules
implementation.


<CODE>
Script.ReloadScript("scripts/gamerules/teamdeathmatch.lua");
CaptureTheFlags = new(TeamDeathMatch);
</CODE>


In order to have a fast access to the the flags located in
the level, we will add a table inside the GameRuls class keep
all their EntityId.


<CODE>
CaptureTheFlags.Server.FlagIds = {};
</CODE>


We will add a new function in the GameRules to allow the flag
entities to register themselves into the GameRules.


<CODE>
function CaptureTheFlags.Server:AddFlag(flag)
    table.insert(self.Server.Flags, flag.id);
end
</CODE>


To update the scores based on the flags which have been
captures by all teams, we will need a function to be called
at a predetermined time period. This time periode is defined
by the CaptureTheFlags.TICK_TIME variable.


<CODE>
function CaptureTheFlags.Server.InGame:OnTick()
    CaptureTheFlags.Server.UpdateScores(self);
end

function CaptureTheFlags.Server:UpdateScores()
    for i,flagId in pairs(self.Server.FlagIds) do
        local teamId = self.game:GetTeam(flagId);

        if (teamId) then
            self:SetTeamScore(teamId, self:GetTeamScore(teamId) + 1);
        end
    end
end
</CODE>


* Flag entity implementation *
We will place some code inside the OnSpawn function of the
flag entity to have some initalization task being executed
after the flag has been spawned.



The following lines will register the recently spawned
entity.


<CODE>
CryAction.CreateGameObjectForEntity(self.id);
CryAction.BindGameObjectToNetwork(self.id);
CryAction.ForceGameObjectUpdate(self.id, true);
self:Activate(1);
</CODE>


To register the flag to our GameRules, we will use the
AddFlag we wrote inside the GameRules class.


<CODE>
if (g_gameRules.Server.AddFlag) then
    g_gameRules.Server.AddFlag(g_gameRules, self);
end
</CODE>


In order to have the flags to become a new spawngroup after
it has been captured by one team, we will register all the
spawn location which are linked to the flag.


<CODE>
function Flag_CTF:Enable(enable)
    if (not g_gameRules) then
        return;
    end

    if (enable) then
        g_gameRules.game:AddSpawnGroup(self.id);

        local i = 0;
        local linkName = "spawnpoint";
        local link = self:GetLinkTarget(linkName, i);

        while (link) do
            i = i + 1;
            g_gameRules.game:AddSpawnLocationToSpawnGroup(self.id, link.id);
            link = self:GetLinkTarget(linkName, i);
        end
    else
        g_gameRules.game:RemoveSpawnGroup(self.id);
    end
end
</CODE>


* Registering with the GameRules system *
During the game startup, every file in the GameRules script
directory will be parsed. Adding the following line will
allow the GameRules to register itself.


<CODE>
GameRules.RegisterGameRules("CaptureTheFlags", "GameRules");
</CODE>


The first parameter must match both the name of the GameRules
and also the filename excluding the lua extension.The second
parameter will make use of the stardard GameRules c++ class
which handle most of the lower level side of the GameRules
such as network synchronization and player spawning.



The GameRules can now simply be started by typing
"sv_gamerules CaptureTheFlags" in the console of the server
or game.

@@Tutorial: Landmine weapon


Mods/CTF/Code/LandMine.cpp

Mods/CTF/Code/LandMine.cpp

Mods/CTF/Code/Game/Scripts/Entities/Items/XML/Weapons/LandMine.xml

Mods/CTF/Code/Game/Scripts/Entities/Items/XML/Ammo/LandMineCharge.xml



* Implementing a new Projectile class *
To define the way our new landmine is detonated, we need to
implement a new projectile class. To do so, we need to derive
from the CProjectile class.



Here is our new projectile class implementation:


<CODE>
class CMineCharge : public CProjectile
{
public:

    CMineCharge();
    virtual ~CMineCharge() {}

    // CProjectile
    virtual void Launch(const Vec3 &pos, const Vec3 &dir, const Vec3 &velocity, float speedScale);
    virtual void HandleEvent(const SGameObjectEvent &);

    void ProcessEvent(SEntityEvent& entityEvent);
    // ~CProjectile

};
</CODE>


The Launch function is called once a projectile has been shot
by the weapon. In the case of the landmine, it's the point
were the charge as been dropped that this function gets
called.



The <LINK IGameObjectExtension::HandleEvent@const SGameObjectEvent&, HandleEvent>
function is usually used in the Projectile class to handle
the collision.


<CODE>
if (!strcmpi(event.event, "oncollision"))
{
    EventPhysCollision *pCollision = (EventPhysCollision *)event.ptr;

    IEntity* pE1 = gEnv-\>pEntitySystem-\>GetEntityFromPhysics(pCollision-\>pEntity[0]);
    IEntity* pE2 = gEnv-\>pEntitySystem-\>GetEntityFromPhysics(pCollision-\>pEntity[1]);

    if (m_isReady && pE1 && pE2)
        Explode(true, true, pCollision-\>pt, pCollision-\>n, pCollision-\>vloc[0]);
}
</CODE>


In the collision part of the HandleEvent, we only want to
explode the mine at the time it collide with another entity,
but never when it collide with the ground.



Implementing



* Registering a new weapon *
To registers a new ammo class

@@Tutorial: Helicopter
