Files
OpenRA/mods/ra/maps/exodus/exodus.lua
abcdefg30 d828e709d6 Fix soviet units not attack moving to their rally points
and remove unnecessary (duplicated) code from the tick function
(the call to IdleHunt inside SpawnSovietUnits is enough)
2016-10-09 22:05:41 +02:00

373 lines
9.4 KiB
Lua

Difficulty = Map.LobbyOption("difficulty")
UnitsEvacuatedThreshold =
{
hard = 200,
normal = 100,
easy = 50
}
AttackAtFrame =
{
hard = 500,
normal = 500,
easy = 600
}
MinAttackAtFrame =
{
hard = 100,
normal = 100,
easy = 150
}
MaxSovietYaks =
{
hard = 4,
normal = 2,
easy = 0
}
SovietParadrops =
{
hard = 40,
normal = 20,
easy = 0
}
SovietParadropTicks =
{
hard = DateTime.Minutes(17),
normal = DateTime.Minutes(20),
easy = DateTime.Minutes(20)
}
SovietUnits2Ticks =
{
hard = DateTime.Minutes(12),
normal = DateTime.Minutes(15),
easy = DateTime.Minutes(15)
}
SovietEntryPoints =
{
SovietEntryPoint1, SovietEntryPoint2, SovietEntryPoint3, SovietEntryPoint4, SovietEntryPoint5, SovietEntryPoint6
}
SovietRallyPoints =
{
SovietRallyPoint1, SovietRallyPoint2, SovietRallyPoint3, SovietRallyPoint4, SovietRallyPoint5, SovietRallyPoint6
}
SovietAirfields =
{
SovietAirfield1, SovietAirfield2, SovietAirfield3, SovietAirfield4,
SovietAirfield5, SovietAirfield6, SovietAirfield7, SovietAirfield8
}
MountainEntry =
{
MountainEntry1.Location, MountainEntry2.Location, MountainEntry3.Location, MountainEntry4.Location,
MountainEntry5.Location, MountainEntry6.Location, MountainEntry7.Location, MountainEntry8.Location
}
BridgeEntry =
{
BridgeEntry1.Location, BridgeEntry2.Location, BridgeEntry3.Location, BridgeEntry4.Location
}
MobileConstructionVehicle = { "mcv" }
Yak = { "yak" }
ReinforcementsTicks1 = DateTime.Minutes(5)
Reinforcements1 =
{
"mgg", "2tnk", "2tnk", "2tnk", "2tnk", "1tnk", "1tnk",
"jeep", "jeep", "e1", "e1", "e1", "e1", "e3", "e3"
}
ReinforcementsTicks2 = DateTime.Minutes(10)
Reinforcements2 =
{
"mgg", "2tnk", "2tnk", "2tnk", "2tnk", "truk", "truk", "truk",
"truk", "truk", "truk", "1tnk", "1tnk", "jeep", "jeep"
}
SovietUnits1 =
{
"3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "3tnk", "v2rl", "v2rl", "ftrk",
"apc", "e1", "e1", "e2", "e3", "e3", "e4"
}
SovietUnits2 =
{
"4tnk", "4tnk", "4tnk", "4tnk", "3tnk", "3tnk", "3tnk", "3tnk", "v2rl",
"v2rl", "ftrk", "apc", "e1", "e1", "e2", "e3", "e3", "e4"
}
CurrentReinforcement1 = 0
CurrentReinforcement2 = 0
SpawnAlliedUnit = function(units)
Reinforcements.Reinforce(allies1, units, { Allies1EntryPoint.Location, Allies1MovePoint.Location })
if allies2 then
Reinforcements.Reinforce(allies2, units, { Allies2EntryPoint.Location, Allies2MovePoint.Location })
end
Utils.Do(humans, function(player)
Trigger.AfterDelay(DateTime.Seconds(2), function()
Media.PlaySpeechNotification(player, "AlliedReinforcementsNorth")
end)
end)
if CurrentReinforcement1 < #Reinforcements1 then
CurrentReinforcement1 = CurrentReinforcement1 + 1
Trigger.AfterDelay(ReinforcementsTicks1, function()
reinforcements1 = { Reinforcements1[CurrentReinforcement1] }
SpawnAlliedUnit(reinforcements1)
end)
end
if CurrentReinforcement2 < #Reinforcements2 then
CurrentReinforcement2 = CurrentReinforcement2 + 1
Trigger.AfterDelay(ReinforcementsTicks2, function()
reinforcements2 = { Reinforcements2[CurrentReinforcement2] }
SpawnAlliedUnit(reinforcements2)
end)
end
end
SovietGroupSize = 5
SpawnSovietUnits = function()
local units = SovietUnits1
if DateTime.GameTime >= SovietUnits2Ticks[Difficulty] then
units = SovietUnits2
end
local unitType = Utils.Random(units)
local spawnPoint = Utils.Random(SovietEntryPoints)
local rallyPoint = Utils.Random(SovietRallyPoints)
local actor = Actor.Create(unitType, true, { Owner = soviets, Location = spawnPoint.Location })
actor.AttackMove(rallyPoint.Location)
IdleHunt(actor)
local delay = math.max(attackAtFrame - 5, minAttackAtFrame)
Trigger.AfterDelay(delay, SpawnSovietUnits)
end
SovietParadrop = 0
SendSovietParadrop = function()
local sovietParadrops = SovietParadrops[Difficulty]
if (SovietParadrop > sovietParadrops) then
return
end
SovietParadrop = SovietParadrop + 1
Utils.Do(humans, function(player)
Media.PlaySpeechNotification(player, "SovietForcesApproaching")
end)
local x = Utils.RandomInteger(ParadropBoxTopLeft.Location.X, ParadropBoxBottomRight.Location.X)
local y = Utils.RandomInteger(ParadropBoxBottomRight.Location.Y, ParadropBoxTopLeft.Location.Y)
local randomParadropCell = CPos.New(x, y)
local lz = Map.CenterOfCell(randomParadropCell)
local powerproxy = Actor.Create("powerproxy.paratroopers", false, { Owner = soviets })
powerproxy.SendParatroopers(lz)
powerproxy.Destroy()
Trigger.AfterDelay(sovietParadropTicks, SendSovietParadrop)
end
IdleHunt = function(unit)
Trigger.OnIdle(unit, unit.Hunt)
Trigger.OnCapture(unit, function()
Trigger.ClearAll(unit)
end)
end
AircraftTargets = function()
local targets = Utils.Where(Map.ActorsInWorld, function(a)
return (a.Owner == allies1 or a.Owner == allies2) and a.HasProperty("Health")
end)
-- prefer mobile units
table.sort(targets, function(a, b) return a.HasProperty("Move") and not b.HasProperty("Move") end)
return targets
end
YakAttack = function(yak, target)
if not target or target.IsDead or (not target.IsInWorld) then
local targets = AircraftTargets()
if #targets > 0 then
target = Utils.Random(targets)
else
yak.Wait(DateTime.Seconds(5))
end
end
if target and yak.AmmoCount() > 0 then
yak.Attack(target)
else
yak.ReturnToBase() -- includes yak.Resupply()
end
yak.CallFunc(function()
YakAttack(yak, target)
end)
end
ManageSovietAircraft = function()
if allies1.IsObjectiveCompleted(destroyAirbases) then
return
end
local maxSovietYaks = MaxSovietYaks[Difficulty]
local sovietYaks = soviets.GetActorsByType('yak')
if #sovietYaks < maxSovietYaks then
soviets.Build(Yak, function(units)
local yak = units[1]
YakAttack(yak)
end)
end
end
UnitsEvacuated = 0
EvacuateAlliedUnit = function(unit)
if (unit.Owner == allies1 or unit.Owner == allies2) and unit.HasProperty("Move") then
unit.Stop()
unit.Owner = allies
if unit.Type == 'mgg' then
Utils.Do(humans, function(player)
if player then
player.MarkCompletedObjective(evacuateMgg)
end
end)
end
UnitsEvacuated = UnitsEvacuated + 1
if unit.HasProperty("HasPassengers") then
UnitsEvacuated = UnitsEvacuated + unit.PassengerCount
end
local exitCell = Map.ClosestEdgeCell(unit.Location)
Trigger.OnIdle(unit, function()
unit.ScriptedMove(exitCell)
end)
local exit = Map.CenterOfCell(exitCell)
Trigger.OnEnteredProximityTrigger(exit, WDist.FromCells(1), function(a)
a.Destroy()
end)
UserInterface.SetMissionText(UnitsEvacuated .. "/" .. unitsEvacuatedThreshold .. " units evacuated.", TextColor)
if UnitsEvacuated >= unitsEvacuatedThreshold then
Utils.Do(humans, function(player)
if player then
player.MarkCompletedObjective(evacuateUnits)
end
end)
end
end
end
Tick = function()
if DateTime.GameTime % 100 == 0 then
ManageSovietAircraft()
Utils.Do(humans, function(player)
if player and player.HasNoRequiredUnits() then
soviets.MarkCompletedObjective(sovietObjective)
end
end)
end
end
WorldLoaded = function()
-- NPC
neutral = Player.GetPlayer("Neutral")
allies = Player.GetPlayer("Allies")
soviets = Player.GetPlayer("Soviets")
-- Player controlled
allies1 = Player.GetPlayer("Allies1")
allies2 = Player.GetPlayer("Allies2")
humans = { allies1, allies2 }
Utils.Do(humans, function(player)
if player and player.IsLocalPlayer then
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
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.OnPlayerWon(player, function()
Media.PlaySpeechNotification(player, "MissionAccomplished")
end)
Trigger.OnPlayerLost(player, function()
Media.PlaySpeechNotification(player, "MissionFailed")
end)
TextColor = player.Color
end
end)
unitsEvacuatedThreshold = UnitsEvacuatedThreshold[Difficulty]
UserInterface.SetMissionText(UnitsEvacuated .. "/" .. unitsEvacuatedThreshold .. " units evacuated.", TextColor)
Utils.Do(humans, function(player)
if player then
evacuateUnits = player.AddPrimaryObjective("Evacuate " .. unitsEvacuatedThreshold .. " units.")
destroyAirbases = player.AddSecondaryObjective("Destroy the nearby Soviet airbases.")
evacuateMgg = player.AddSecondaryObjective("Evacuate at least one mobile gap generator.")
end
end)
Trigger.OnAllKilledOrCaptured(SovietAirfields, function()
Utils.Do(humans, function(player)
if player then
player.MarkCompletedObjective(destroyAirbases)
end
end)
end)
sovietObjective = soviets.AddPrimaryObjective("Eradicate all allied troops.")
if not allies2 or allies1.IsLocalPlayer then
Camera.Position = Allies1EntryPoint.CenterPosition
else
Camera.Position = Allies2EntryPoint.CenterPosition
end
if not allies2 then
allies1.Cash = 10000
Media.DisplayMessage("Transferring funds.", "Co-Commander is missing")
end
SpawnAlliedUnit(MobileConstructionVehicle)
minAttackAtFrame = MinAttackAtFrame[Difficulty]
attackAtFrame = AttackAtFrame[Difficulty]
Trigger.AfterDelay(attackAtFrame, SpawnSovietUnits)
sovietParadropTicks = SovietParadropTicks[Difficulty]
Trigger.AfterDelay(sovietParadropTicks, SendSovietParadrop)
Trigger.OnEnteredFootprint(MountainEntry, EvacuateAlliedUnit)
Trigger.OnEnteredFootprint(BridgeEntry, EvacuateAlliedUnit)
end