Port the Co-Op Allies03 map to Lua.

This commit is contained in:
Matthias Mailänder
2015-12-27 16:48:39 +01:00
parent 9775352856
commit ad986b2fb4
6 changed files with 2002 additions and 0 deletions

View File

@@ -74,6 +74,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Red Alert Lua scripts", "Re
mods\ra\maps\fort-lonestar\fort-lonestar.lua = mods\ra\maps\fort-lonestar\fort-lonestar.lua
mods\ra\maps\intervention\intervention.lua = mods\ra\maps\intervention\intervention.lua
mods\ra\maps\monster-tank-madness\monster-tank-madness.lua = mods\ra\maps\monster-tank-madness\monster-tank-madness.lua
mods\ra\maps\evacuation\evacuation.lua = mods\ra\maps\evacuation\evacuation.lua
mods\ra\maps\exodus\exodus.lua = mods\ra\maps\exodus\exodus.lua
mods\ra\maps\soviet-01\soviet01.lua = mods\ra\maps\soviet-01\soviet01.lua
mods\ra\maps\soviet-02a\soviet02a.lua = mods\ra\maps\soviet-02a\soviet02a.lua
mods\ra\maps\soviet-02b\soviet02b.lua = mods\ra\maps\soviet-02b\soviet02b.lua

View File

@@ -0,0 +1,387 @@
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 spawnPoint = Utils.Random(SovietEntryPoints)
local rallyPoint = Utils.Random(SovietRallyPoints)
local route = { spawnPoint.Location, rallyPoint.Location }
local units = SovietUnits1
if DateTime.GameTime >= SovietUnits2Ticks[Difficulty] then
units = SovietUnits2
end
local unit = { Utils.Random(units) }
Reinforcements.Reinforce(soviets, unit, route)
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)
end
ManageSovietUnits = function()
Utils.Do(SovietRallyPoints, function(rallyPoint)
local radius = WDist.FromCells(8)
local units = Map.ActorsInCircle(rallyPoint.CenterPosition, radius, function(actor)
return actor.Owner == soviets and actor.HasProperty("Hunt")
end)
if #units > SovietGroupSize then
Utils.Do(units, IdleHunt)
end
end)
local scatteredUnits = Utils.Where(soviets.GetGroundAttackers(), function(unit)
return not Map.IsNamedActor(unit) and unit.IsIdle and unit.HasProperty("Hunt")
end)
Utils.Do(scatteredUnits, IdleHunt)
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
ManageSovietUnits()
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

BIN
mods/ra/maps/exodus/map.bin Normal file

Binary file not shown.

BIN
mods/ra/maps/exodus/map.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

1429
mods/ra/maps/exodus/map.yaml Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,184 @@
Player:
PlayerResources:
DefaultCash: 5000
World:
MissionData:
Briefing: The Allies are now being flanked from both sides. Evacuate before the remaining Allied forces in the area are wiped out. Einstein has recently developed a technology which allows us to obscure units from the enemy. Pull out at least one prototype mobile gap generator intact.
LuaScript:
Scripts: exodus.lua
ScriptLobbyDropdown@difficulty:
ID: difficulty
Label: Difficulty
Values:
easy: Easy
normal: Normal
hard: Hard
Default: normal
powerproxy.paratroopers:
ParatroopersPower:
DropItems: E1,E1,E3,E3,E4
HBOX:
Buildable:
Prerequisites: ~disabled
EditorOnlyTooltip:
Description: invalid targets for YakAttack
E7:
Buildable:
Prerequisites: ~disabled
TRAN:
Buildable:
Prerequisites: ~disabled
BARR:
Buildable:
Prerequisites: ~disabled
MIG:
Buildable:
Prerequisites: ~disabled
HELI:
Buildable:
Prerequisites: ~disabled
HIND:
Buildable:
Prerequisites: ~disabled
SS:
Buildable:
Prerequisites: ~disabled
ARTY:
Buildable:
Prerequisites: ~disabled
AGUN:
Buildable:
Prerequisites: ~disabled
MSUB:
Buildable:
Prerequisites: ~disabled
DD:
Buildable:
Prerequisites: ~disabled
CA:
Buildable:
Prerequisites: ~disabled
PT:
Buildable:
Prerequisites: ~disabled
MSLO:
Buildable:
Prerequisites: ~disabled
SPEN:
Buildable:
Prerequisites: ~disabled
SYRD:
Buildable:
Prerequisites: ~disabled
IRON:
Buildable:
Prerequisites: ~disabled
PDOX:
Buildable:
Prerequisites: ~disabled
TSLA:
Buildable:
Prerequisites: ~disabled
FTUR:
Buildable:
Prerequisites: ~disabled
SAM:
Buildable:
Prerequisites: ~disabled
HPAD:
Buildable:
Prerequisites: ~disabled
AFLD:
Buildable:
Prerequisites: ~disabled
ATEK:
Buildable:
Prerequisites: ~disabled
STEK:
Buildable:
Prerequisites: ~disabled
4TNK:
Buildable:
Prerequisites: ~disabled
MCV:
Buildable:
Prerequisites: ~disabled
APC:
Buildable:
Prerequisites: ~disabled
MNLY.AP:
Buildable:
Prerequisites: ~disabled
MNLY.AT:
Buildable:
Prerequisites: ~disabled
TRUK:
Buildable:
Prerequisites: ~disabled
TTNK:
Buildable:
Prerequisites: ~disabled
FTRK:
Buildable:
Prerequisites: ~disabled
CTNK:
Buildable:
Prerequisites: ~disabled
MRJ:
Buildable:
Prerequisites: ~disabled
MGG:
Buildable:
Prerequisites: ~disabled
CreatesShroud:
Range: 6c0
GAP:
Buildable:
Prerequisites: ~disabled
CAMERA.Large:
Inherits: CAMERA
RevealsShroud:
Range: 49c0
EditorOnlyTooltip:
Description: required for YakAttack to work