Making Production Buildings on a Map

umairazfar edited this page Nov 9, 2014 · 3 revisions
Clone this wiki locally

For this tutorial we will be adding two barracks and make them produce units. To start off, we first place the two buildings on our map. All buildings are actors, so we add two actors to the map. As always, we will be using the map from the last tutorial.

Adding production buildings

Barracks1: barr
    Location: 34,24
    Owner: INDIA
Barracks2: barr
    Location: 26,24
    Owner: INDIA

We have defined two barracks, to the left top and right top of the Pakistani construction yard. These will produce units from time to time.

tutorialmap.lua

In your lua file, first of all define what each barracks will produce. Keep in mind that I am making this tutorial for the crossfire mod, I recommend using "e1" and "e3" only as the produce-able units if you are using the RA mod.

ProducedUnitTypes =
{
    { Barracks1, { "e1", "e2", "e3" } },
    { Barracks2, { "e1", "e3", "e4", "sniper" } }
}

If you have defined other production buildings, you can type their names here and list the units that they will produce.

First of all, we write the code for producing the units. The comments within the code will elaborate what is happening.

ProduceUnits = function(t)
    local factory = t[1] --Select the production facility
    if not factory.IsDead then --If the facility has not been destroyed...
        local unitType = t[2][Utils.RandomInteger(1, #t[2] + 1)] --Select a random unit to produce
        factory.Wait(Actor.BuildTime(unitType)) --Wait the time it takes to produce that unit
        factory.Produce(unitType) --produce that unit
        factory.CallFunc(function() ProduceUnits(t) end) --restart the unit production
    end
end

We then setup the production buildings to be ready and to bind triggers to the produced units.

SetupFactories = function()
    Utils.Do(ProducedUnitTypes, function(pair)
        Trigger.OnProduction(pair[1], function(_, a) BindActorTriggers(a) end)
    end)
end

Then, in the WorldLoaded function, setup the production facilities first by calling SetupFactories() and then make the factories produce units by calling Utils.Do(ProducedUnitTypes, ProduceUnits).

As always, I am providing the complete code below. Keep in mind that in order to keep the code clean, I removed everything from tutorial 2,3 and 4. The code is not long however, so you will have no problem in figuring it out.

Complete code

JeepReinforcements = {"jeep", "jeep"}
JeepReinforcementsPath = { PakEntry.Location, PakRally.Location }
JeepDelay = 12
JeepInterval = 2


Force = { "e1", "e1", "e1", "e1", "e2"}
ForcePath = { IndiaEntry.Location, IndiaRally.Location }
ForceDelay = 15
ForceInterval = 2

ProducedUnitTypes =
{
    { Barracks1, { "e1", "e2", "e3" } },
    { Barracks2, { "e1", "e3", "e4", "sniper" } }
}

ProduceUnits = function(t)
    local factory = t[1]
    if not factory.IsDead then
        local unitType = t[2][Utils.RandomInteger(1, #t[2] + 1)]
        factory.Wait(Actor.BuildTime(unitType))
        factory.Produce(unitType)
        factory.CallFunc(function() ProduceUnits(t) end)
    end
end

SetupFactories = function()
    Utils.Do(ProducedUnitTypes, function(pair)
        Trigger.OnProduction(pair[1], function(_, a) BindActorTriggers(a) end)
    end)
end

SendJeeps = function()
    Reinforcements.Reinforce(player, JeepReinforcements, JeepReinforcementsPath, DateTime.Seconds(JeepInterval))
    Media.PlaySpeechNotification(player, "ReinforcementsArrived")
end

SendIndianInfantry = function()
    local units = Reinforcements.Reinforce(india, Force, ForcePath, ForceInterval)
    Utils.Do(units, function(unit)
        BindActorTriggers(unit)
    end)
    Trigger.AfterDelay(DateTime.Seconds(5), SendIndianInfantry)
end

BindActorTriggers = function(a)
    if a.HasProperty("Hunt") then
        if a.Owner == india then
            Trigger.OnIdle(a, a.Hunt)
        else
            Trigger.OnIdle(a, function(a) a.AttackMove(Outpost.Location) end)
        end
    end
end

OutpostDestroyed = function()
    MissionFailed()
end

MissionAccomplished = function()
    Media.PlaySpeechNotification(player, "Win")
end

MissionFailed = function()
    Media.PlaySpeechNotification(player, "Lose")
    player.MarkFailedObjective(SurviveObjective)
    india.MarkCompletedObjective(DestroyObjective)
end

WorldLoaded = function()
    player = Player.GetPlayer("PAKISTAN")
    india = Player.GetPlayer("INDIA")

    Trigger.OnObjectiveCompleted(player, function(p, id)
        Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed")
    end)

    Trigger.OnObjectiveFailed(player, function(p, id)
        Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed")
    end)

    Trigger.OnKilled(Outpost, OutpostDestroyed)

    SurviveObjective = player.AddPrimaryObjective("The outpost must survive.")
    DestroyObjective = india.AddPrimaryObjective("The Pakistani outpost must be destroyed.")
    SetupFactories()
    Trigger.AfterDelay(DateTime.Seconds(60), function()
        MissionAccomplished()
        player.MarkCompletedObjective(SurviveObjective)
        india.MarkFailedObjective(DestroyObjective)
    end)
    Trigger.AfterDelay(DateTime.Seconds(2), function() Actor.Create("camera", true, { Owner = player, Location = PakRally.Location }) end)
    Camera.Position = Outpost.CenterPosition
    Trigger.AfterDelay(DateTime.Seconds(5), SendJeeps) --Sending Allied reinforcements  
    SendIndianInfantry(IndiaEntry.Location, Force, ForceInterval) --Sending Indian ground troops every 15 seconds   
    Utils.Do(ProducedUnitTypes, ProduceUnits)
end
  • made by Umair Azfar Khan