Add Scott's Allies02 multiplayer mission as "Evacuation"

This commit is contained in:
Oliver Brakmann
2016-03-20 23:15:36 +01:00
parent ebba7fdaf1
commit b3dd62b891
6 changed files with 2338 additions and 0 deletions

View File

@@ -68,6 +68,7 @@ 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\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,363 @@
DeathThreshold =
{
Easy = 200,
Normal = 100,
}
TanyaType = "e7"
TanyaStance = "AttackAnything"
if Map.Difficulty ~= "Easy" then
TanyaType = "e7.noautotarget"
TanyaStance = "HoldFire"
end
RepairTriggerThreshold =
{
Easy = 50,
Normal = 75,
}
Sams = { Sam1, Sam2, Sam3, Sam4 }
TownUnits =
{
Einstein, Engineer,
TownUnit01, TownUnit02, TownUnit03, TownUnit04, TownUnit05, TownUnit06, TownUnit07,
TownUnit08, TownUnit09, TownUnit10, TownUnit11, TownUnit12, TownUnit13, TownUnit14,
}
ParabombDelay = DateTime.Seconds(30)
ParatroopersDelay = DateTime.Minutes(5)
Paratroopers =
{
{
proxy = "powerproxy.paras1",
entry = BadgerEntryPoint1.Location,
drop = BadgerDropPoint1.Location,
},
{
proxy = "powerproxy.paras2",
entry = BadgerEntryPoint1.Location + CVec.New(3, 0),
drop = BadgerDropPoint2.Location,
},
{
proxy = "powerproxy.paras2",
entry = BadgerEntryPoint1.Location + CVec.New(6, 0),
drop = BadgerDropPoint3.Location,
},
}
AttackGroup = { }
AttackGroupSize = 5
SovietInfantry = { "e1", "e2", "e3" }
SovietVehiclesUpgradeDelay = DateTime.Minutes(4)
SovietVehicleType = "Normal"
SovietVehicles =
{
Normal = { "3tnk" },
Upgraded = { "3tnk", "v2rl" },
}
ProductionInterval =
{
Easy = DateTime.Seconds(10),
Normal = DateTime.Seconds(2),
}
ReinforcementsDelay = DateTime.Minutes(16)
ReinforcementsUnits = { "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "1tnk", "1tnk", "jeep", "e1",
"e1", "e1", "e1", "e3", "e3", "mcv", "truk", "truk", "truk", "truk", "truk", "truk" }
SpawnAlliedReinforcements = function()
if allies2.IsLocalPlayer then
UserInterface.SetMissionText("")
Media.PlaySpeechNotification(allies2, "AlliedReinforcementsArrived")
end
Reinforcements.Reinforce(allies2, ReinforcementsUnits, { ReinforcementsEntryPoint.Location, Allies2BasePoint.Location })
end
Yak = nil
YakAttack = function(yak)
local targets = Map.ActorsInCircle(YakAttackPoint.CenterPosition, WDist.FromCells(10), function(a)
return a.Owner == allies1 and not a.IsDead and a ~= Einstein and a ~= Tanya and a ~= Engineer
end)
if (#targets > 0) then
yak.Attack(Utils.Random(targets))
end
yak.Move(Map.ClosestEdgeCell(yak.Location))
yak.Destroy()
Trigger.OnRemovedFromWorld(Yak, function()
Yak = nil
end)
end
SovietTownAttack = function()
local units = Utils.Shuffle(Utils.Where(Map.ActorsWithTag("TownAttacker"), function(a) return not a.IsDead end))
Utils.Do(Utils.Take(5, units), function(unit)
unit.AttackMove(TownPoint.Location)
Trigger.OnIdle(unit, unit.Hunt)
end)
end
SendParabombs = function()
local proxy = Actor.Create("powerproxy.parabombs", false, { Owner = soviets })
proxy.SendAirstrikeFrom(BadgerEntryPoint2.Location, ParabombPoint1.Location)
proxy.SendAirstrikeFrom(BadgerEntryPoint2.Location + CVec.New(0, 3), ParabombPoint2.Location)
proxy.Destroy()
end
SendParatroopers = function()
Utils.Do(Paratroopers, function(para)
local proxy = Actor.Create(para.proxy, false, { Owner = soviets })
local units = proxy.SendParatroopersFrom(para.entry, para.drop)
proxy.Destroy()
Utils.Do(units, function(unit)
Trigger.OnIdle(unit, function(a)
if a.IsInWorld then
a.Hunt()
end
end)
end)
end)
end
SendAttackGroup = function()
if #AttackGroup < AttackGroupSize then
return
end
Utils.Do(AttackGroup, function(unit)
if not unit.IsDead then
Trigger.OnIdle(unit, unit.Hunt)
end
end)
AttackGroup = { }
end
ProduceInfantry = function()
if SovietBarracks.IsDead or SovietBarracks.Owner ~= soviets then
return
end
soviets.Build({ Utils.Random(SovietInfantry) }, function(units)
table.insert(AttackGroup, units[1])
SendAttackGroup()
Trigger.AfterDelay(ProductionInterval[Map.Difficulty], ProduceInfantry)
end)
end
ProduceVehicles = function()
if SovietWarFactory.IsDead or SovietWarFactory.Owner ~= soviets then
return
end
soviets.Build({ Utils.Random(SovietVehicles[SovietVehicleType]) }, function(units)
table.insert(AttackGroup, units[1])
SendAttackGroup()
Trigger.AfterDelay(ProductionInterval[Map.Difficulty], ProduceVehicles)
end)
end
NumBaseBuildings = function()
local buildings = Map.ActorsInBox(AlliedBaseTopLeft.CenterPosition, AlliedBaseBottomRight.CenterPosition, function(a)
return not a.IsDead and a.Owner == allies2 and a.HasProperty("StartBuildingRepairs")
end)
return #buildings
end
Tick = function()
if DateTime.GameTime > 1 and DateTime.GameTime % 25 == 0 and NumBaseBuildings() == 0 then
allies2.MarkFailedObjective(objHoldPosition)
end
if not allies2.IsObjectiveCompleted(objCutSovietPower) and soviets.PowerState ~= "Normal" then
allies2.MarkCompletedObjective(objCutSovietPower)
end
if not allies2.IsObjectiveCompleted(objLimitLosses) and allies2.UnitsLost > DeathThreshold[Map.Difficulty] then
allies2.MarkFailedObjective(objLimitLosses)
end
if allies2.IsLocalPlayer and DateTime.GameTime <= ReinforcementsDelay then
UserInterface.SetMissionText("Allied reinforcements arrive in " .. Utils.FormatTime(ReinforcementsDelay - DateTime.GameTime))
else
UserInterface.SetMissionText("")
end
end
SetupSoviets = function()
soviets.Cash = 1000
if Map.Difficulty == "Easy" then
Utils.Do(Sams, function(sam)
local camera = Actor.Create("Camera.SAM", true, { Owner = allies1, Location = sam.Location })
Trigger.OnKilledOrCaptured(sam, function()
camera.Destroy()
end)
end)
end
local buildings = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == soviets and self.HasProperty("StartBuildingRepairs") end)
Utils.Do(buildings, function(actor)
Trigger.OnDamaged(actor, function(building)
if building.Owner == soviets and building.Health < (building.MaxHealth * RepairTriggerThreshold[Map.Difficulty] / 100) then
building.StartBuildingRepairs()
end
end)
end)
SovietBarracks.IsPrimaryBuilding = true
SovietBarracks.RallyPoint = SovietRallyPoint.Location
SovietWarFactory.IsPrimaryBuilding = true
SovietWarFactory.RallyPoint = SovietRallyPoint.Location
Trigger.AfterDelay(SovietVehiclesUpgradeDelay, function() SovietVehicleType = "Upgraded" end)
Trigger.AfterDelay(0, function()
ProduceInfantry()
ProduceVehicles()
end)
end
SetupTriggers = function()
Trigger.OnKilled(Tanya, function()
allies1.MarkFailedObjective(objTanyaMustSurvive)
end)
Trigger.OnAllKilledOrCaptured(Sams, function()
allies1.MarkCompletedObjective(objDestroySamSites)
objExtractEinstein = allies1.AddPrimaryObjective("Wait for a helicopter at the LZ and extract Einstein.")
Actor.Create("flare", true, { Owner = allies1, Location = ExtractionLZ.Location + CVec.New(1, -1) })
Beacon.New(allies1, ExtractionLZ.CenterPosition)
Media.PlaySpeechNotification(allies1, "SignalFlareNorth")
ExtractionHeli = Reinforcements.ReinforceWithTransport(allies1, "tran", nil, { ExtractionLZEntryPoint.Location, ExtractionLZ.Location })[1]
Trigger.OnKilled(ExtractionHeli, function()
allies1.MarkFailedObjective(objExtractEinstein)
end)
Trigger.OnPassengerEntered(ExtractionHeli, function(heli, passenger)
if passenger == Einstein then
heli.Move(ExtractionLZEntryPoint.Location)
heli.Destroy()
Trigger.OnRemovedFromWorld(heli, function()
allies2.MarkCompletedObjective(objLimitLosses)
allies2.MarkCompletedObjective(objHoldPosition)
allies1.MarkCompletedObjective(objTanyaMustSurvive)
allies1.MarkCompletedObjective(objEinsteinSurvival)
allies1.MarkCompletedObjective(objExtractEinstein)
end)
end
end)
end)
Trigger.OnEnteredProximityTrigger(TownPoint.CenterPosition, WDist.FromCells(15), function(actor, trigger)
if actor.Owner == allies1 then
ReassignActors(TownUnits, neutral, allies1)
Utils.Do(TownUnits, function(a) a.Stance = "Defend" end)
allies1.MarkCompletedObjective(objFindEinstein)
objEinsteinSurvival = allies1.AddPrimaryObjective("Keep Einstein alive at all costs.")
Trigger.OnKilled(Einstein, function()
allies1.MarkFailedObjective(objEinsteinSurvival)
end)
Trigger.RemoveProximityTrigger(trigger)
SovietTownAttack()
end
end)
Trigger.OnEnteredProximityTrigger(YakAttackPoint.CenterPosition, WDist.FromCells(5), function(actor, trigger)
if not (Yak == nil or Yak.IsDead) or actor.Owner ~= allies1 then
return
end
Yak = Reinforcements.Reinforce(soviets, { "yak" }, { YakEntryPoint.Location, YakAttackPoint.Location + CVec.New(0, -10) }, 0, YakAttack)[1]
end)
Trigger.AfterDelay(ParabombDelay, SendParabombs)
Trigger.AfterDelay(ParatroopersDelay, SendParatroopers)
Trigger.AfterDelay(ReinforcementsDelay, SpawnAlliedReinforcements)
end
SpawnTanya = function()
Tanya = Actor.Create(TanyaType, true, { Owner = allies1, Location = TanyaLocation.Location })
Tanya.Stance = TanyaStance
if Map.Difficulty ~= "Easy" and allies1.IsLocalPlayer then
Trigger.AfterDelay(DateTime.Seconds(2), function()
Media.DisplayMessage("According to the rules of engagement I need your explicit orders to fire, Commander!", "Tanya")
end)
end
end
ReassignActors = function(actors, from, to)
Utils.Do(actors, function(a)
if a.Owner == from then
a.Owner = to
a.Stance = "Defend"
end
end)
end
WorldLoaded = function()
neutral = Player.GetPlayer("Neutral")
-- Allies is the pre-set owner of units that get assigned to either the second player, if any, or the first player otherwise.
allies = Player.GetPlayer("Allies")
-- Allies1 is the player starting on the right, controlling Tanya
allies1 = Player.GetPlayer("Allies1")
-- Allies2 is the player starting on the left, defending the base
allies2 = Player.GetPlayer("Allies2")
soviets = Player.GetPlayer("Soviets")
Utils.Do({ allies1, allies2 }, 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)
end
end)
if not allies2 or allies2.IsLocalPlayer then
Camera.Position = Allies2BasePoint.CenterPosition
else
Camera.Position = ChinookHusk.CenterPosition
end
if not allies2 then
allies2 = allies1
end
ReassignActors(Map.ActorsInWorld, allies, allies2)
SpawnTanya()
objTanyaMustSurvive = allies1.AddPrimaryObjective("Tanya must survive.")
objFindEinstein = allies1.AddPrimaryObjective("Find Einstein's crashed helicopter.")
objDestroySamSites = allies1.AddPrimaryObjective("Destroy the SAM sites.")
objHoldPosition = allies2.AddPrimaryObjective("Hold your position and protect the base.")
objLimitLosses = allies2.AddSecondaryObjective("Do not lose more than " .. DeathThreshold[Map.Difficulty] .. " units.")
objCutSovietPower = allies2.AddSecondaryObjective("Take out the Soviet power grid.")
SetupTriggers()
SetupSoviets()
end

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,217 @@
Player:
MissionObjectives:
Cooperative: True
PlayerResources:
DefaultCash: 5000
DeveloperMode:
Locked: True
World:
MissionData:
Briefing: One of our outposts is under heavy attack by a nearby Soviet base. Einstein, Tanya and many of our forces have been evacuated via helicopters, but those were shot down on the other side of the river. Fortunately they survived the crash, but are now in enemy territory. Tanya and the rest of the surviving forces need to fight their way out of there. The air defenses must be eliminated before another Search & Rescue helicopter can arrive.\n\nMeanwhile, the forces remaining at the base need to fend off the Soviet attacks.\n
LuaScript:
Scripts: evacuation.lua
MapOptions:
TechLevelLocked: True
Difficulties: Easy, Normal
Difficulty: Normal
^Tanks:
Demolishable:
^Vehicles:
Demolishable:
E1:
ScriptTags:
E2:
ScriptTags:
DOG:
ScriptTags:
3TNK:
ScriptTags:
TRAN.Husk1:
Burns:
Damage: 0
TRAN.Husk2:
Burns:
Damage: 0
E7:
Passenger:
Weight: 0
Buildable:
Prerequisites: ~disabled
EINSTEIN:
Passenger:
Weight: 0
V01:
SpawnActorOnDeath:
Actor: healcrate
TRAN:
-Selectable:
Buildable:
Prerequisites: ~disabled
RevealsShroud:
Range: 0c0
2TNK:
Buildable:
Prerequisites: ~vehicles.allies
MECH:
Buildable:
Prerequisites: ~disabled
SPEN:
Buildable:
Prerequisites: ~disabled
SYRD:
Buildable:
Prerequisites: ~disabled
TSLA:
Buildable:
Prerequisites: ~disabled
AGUN:
Buildable:
Prerequisites: ~disabled
SAM:
Buildable:
Prerequisites: ~disabled
ATEK:
Buildable:
Prerequisites: ~disabled
HPAD:
Buildable:
Prerequisites: ~disabled
AFLD:
Buildable:
Prerequisites: ~disabled
STEK:
Buildable:
Prerequisites: ~disabled
GAP:
Buildable:
Prerequisites: ~disabled
PDOX:
Buildable:
Prerequisites: ~disabled
IRON:
Buildable:
Prerequisites: ~disabled
MSLO:
Buildable:
Prerequisites: ~disabled
MIG:
Buildable:
Prerequisites: ~disabled
HELI:
Buildable:
Prerequisites: ~disabled
4TNK:
Buildable:
Prerequisites: ~disabled
MCV:
Buildable:
Prerequisites: ~disabled
ARTY:
Buildable:
Prerequisites: ~disabled
APC:
Buildable:
Prerequisites: ~disabled
MNLY.AP:
Buildable:
Prerequisites: ~disabled
MNLY.AT:
Buildable:
Prerequisites: ~disabled
TRUK:
Buildable:
Prerequisites: ~disabled
FTRK:
Buildable:
Prerequisites: ~disabled
MRJ:
Buildable:
Prerequisites: ~disabled
MGG:
Buildable:
Prerequisites: ~disabled
TTNK:
Buildable:
Prerequisites: ~disabled
QTNK:
Buildable:
Prerequisites: ~disabled
DTRK:
Buildable:
Prerequisites: ~disabled
CTNK:
Buildable:
Prerequisites: ~disabled
STNK:
Buildable:
Prerequisites: ~disabled
MSUB:
Buildable:
Prerequisites: ~disabled
CAMERA.Large:
Inherits: CAMERA
RevealsShroud:
Range: 1000c0
Camera.SAM:
Inherits: CAMERA
RevealsShroud:
Range: 2c0
powerproxy.paras1:
AlwaysVisible:
ParatroopersPower:
DropItems: E1,E1,E1,E2,3TNK
powerproxy.paras2:
AlwaysVisible:
ParatroopersPower:
DropItems: E1,E1,E1,E2,E2