diff --git a/mods/ra/maps/allies-05a/AI.lua b/mods/ra/maps/allies-05a/AI.lua index 4e2861eff2..9ebcb53622 100644 --- a/mods/ra/maps/allies-05a/AI.lua +++ b/mods/ra/maps/allies-05a/AI.lua @@ -5,6 +5,7 @@ AttackGroupSize = 6 Barracks = { Barracks2, Barracks3 } Rallypoints = { VehicleRallypoint1, VehicleRallypoint2, VehicleRallypoint3, VehicleRallypoint4, VehicleRallypoint5 } +WaterLZs = { WaterLZ1, WaterLZ2 } Airfields = { Airfield1, Airfield2 } Yaks = { } @@ -23,6 +24,10 @@ SetupAttackGroup = function() local units = { } for i = 0, AttackGroupSize, 1 do + if #IdlingUnits == 0 then + return units + end + local number = Utils.RandomInteger(1, #IdlingUnits) if IdlingUnits[number] and not IdlingUnits[number].IsDead then @@ -35,19 +40,45 @@ SetupAttackGroup = function() end SendAttack = function() - if not Attacking then + if Attacking then return end - Attacking = false - HoldProduction = false + Attacking = true + HoldProduction = true - local units = SetupAttackGroup() - Utils.Do(units, function(unit) - IdleHunt(unit) - end) + local units = { } + if SendWaterTransports and Utils.RandomInteger(0,2) == 1 then + units = WaterAttack() - Trigger.AfterDelay(DateTime.Minutes(1), function() Attacking = true end) - Trigger.AfterDelay(DateTime.Minutes(2), function() HoldProduction = true end) + Utils.Do(units, function(unit) + Trigger.OnAddedToWorld(unit, function() + Trigger.OnIdle(unit, unit.Hunt) + end) + end) + + Trigger.AfterDelay(DateTime.Seconds(20), function() + Attacking = false + HoldProduction = false + end) + else + units = SetupAttackGroup() + + Utils.Do(units, function(unit) + IdleHunt(unit) + end) + + Trigger.AfterDelay(DateTime.Minutes(1), function() Attacking = false end) + Trigger.AfterDelay(DateTime.Minutes(2), function() HoldProduction = false end) + end +end + +WaterAttack = function() + local types = { } + for i = 1, 5, 1 do + types[i] = Utils.Random(SovietInfantryTypes) + end + + return Reinforcements.ReinforceWithTransport(ussr, InsertionTransport, types, { WaterTransportSpawn.Location, Utils.Random(WaterLZs).Location }, { WaterTransportSpawn.Location })[2] end ProtectHarvester = function(unit) @@ -113,17 +144,21 @@ InitProductionBuildings = function() TrainInfantry = false end end) - end - - if not Barracks3.IsDead then - Trigger.OnKilled(Barracks3, function() if Barracks2.IsDead then TrainInfantry = false end end) - end - - if Barracks2.IsDead and Barracks3.IsDead then + elseif not Barracks3.IsDead then + Barracks3.IsPrimaryBuilding = true + else TrainInfantry = false end - if Map.Difficulty == "Normal" then + if not Barracks3.IsDead then + Trigger.OnKilled(Barracks3, function() + if Barracks2.IsDead then + TrainInfantry = false + end + end) + end + + if Map.Difficulty ~= "Easy" then if not Airfield1.IsDead then Trigger.OnKilled(Airfield1, function() diff --git a/mods/ra/maps/allies-05a/allies05a.lua b/mods/ra/maps/allies-05a/allies05a.lua index 12f37daccf..a90da28896 100644 --- a/mods/ra/maps/allies-05a/allies05a.lua +++ b/mods/ra/maps/allies-05a/allies05a.lua @@ -2,19 +2,30 @@ if Map.Difficulty == "Easy" then TanyaType = "e7" ReinforceCash = 5000 HoldAITime = DateTime.Minutes(3) + SpecialCameras = true +elseif Map.Difficulty == "Normal" then + TanyaType = "e7.noautotarget" + ChangeStance = true + ReinforceCash = 2250 + HoldAITime = DateTime.Minutes(2) + SpecialCameras = true else TanyaType = "e7.noautotarget" ChangeStance = true - ReinforceCash = 2500 - HoldAITime = DateTime.Minutes(2) + ReinforceCash = 1500 + HoldAITime = DateTime.Minutes(1) + DateTime.Seconds(30) + SendWaterTransports = true end SpyType = { "spy" } SpyEntryPath = { SpyEntry.Location, SpyLoadout.Location } -InsertionTransport = "lst" +InsertionTransport = "lst.in" +ExtractionTransport = "lst" TrukPath = { TrukWaypoint1, TrukWaypoint2, TrukWaypoint3, TrukWaypoint4, TrukWaypoint5, TrukWaypoint6 } ExtractionHeliType = "tran" +InsertionHeliType = "tran.in" ExtractionPath = { ExtractionEntry.Location, ExtractionLZ.Location } +HeliReinforcements = { "medi", "mech", "mech" } GreeceReinforcements = { @@ -32,6 +43,7 @@ PatrolAPath = { PatrolRally.Location, PatrolARally1.Location, PatrolARally2.Loca PatrolBPath = { PatrolBRally1.Location, PatrolBRally2.Location, PatrolBRally3.Location, PatrolRally.Location } TanyaVoices = { "tuffguy", "bombit", "laugh", "gotit", "lefty", "keepem" } +SpyVoice = "sking" SamSites = { Sam1, Sam2, Sam3, Sam4 } GroupPatrol = function(units, waypoints, delay) @@ -71,12 +83,20 @@ Tick = function() end if ussr.HasNoRequiredUnits() then + if not greece.IsObjectiveCompleted(KillAll) and Map.Difficulty == "Real tough guy" then + SendWaterExtraction() + end greece.MarkCompletedObjective(KillAll) end if GreeceReinforcementsArrived and greece.HasNoRequiredUnits() then ussr.MarkCompletedObjective(ussrObj) end + + if ussr.Resources >= ussr.ResourceCapacity * 0.75 then + ussr.Cash = ussr.Cash + ussr.Resources - ussr.ResourceCapacity * 0.25 + ussr.Resources = ussr.ResourceCapacity * 0.25 + end end SendReinforcements = function() @@ -93,18 +113,32 @@ SendReinforcements = function() ActivateAI() end -ExtractTanya = function() - if ExtractionHeli.IsDead or not ExtractionHeli.HasPassengers then +ExtractUnits = function(extractionUnit, pos, after) + if extractionUnit.IsDead or not extractionUnit.HasPassengers then return end - ExtractionHeli.Move(CPos.New(ExtractionPath[1].X, ExtractionHeli.Location.Y)) - ExtractionHeli.Destroy() + extractionUnit.Move(pos) + extractionUnit.Destroy() - Trigger.OnRemovedFromWorld(ExtractionHeli, function() - greece.MarkCompletedObjective(mainObj) - SendReinforcements() - PrisonCamera.Destroy() + Trigger.OnRemovedFromWorld(extractionUnit, after) +end + +SendWaterExtraction = function() + local flare = Actor.Create("flare", true, { Owner = greece, Location = SpyEntryPath[2] + CVec.New(2, 0) }) + Trigger.AfterDelay(DateTime.Seconds(5), flare.Destroy) + Media.PlaySpeechNotification(greece, "SignalFlareNorth") + Camera.Position = flare.CenterPosition + + WaterExtractionTran = Reinforcements.ReinforceWithTransport(greece, ExtractionTransport, nil, SpyEntryPath)[1] + ExtractObj = greece.AddPrimaryObjective("Get all your forces into the transport.") + + Trigger.OnKilled(WaterExtractionTran, function() ussr.MarkCompletedObjective(ussrObj) end) + Trigger.OnAllRemovedFromWorld(greece.GetGroundAttackers(), function() + ExtractUnits(WaterExtractionTran, SpyEntryPath[1], function() + greece.MarkCompletedObjective(ExtractObj) + greece.MarkCompletedObjective(surviveObj) + end) end) end @@ -117,10 +151,12 @@ WarfactoryInfiltrated = function() Truk.Move(waypoint.Location) end) - Trigger.AfterDelay(DateTime.Seconds(2), function() - SpyCameraA.Destroy() - SpyCameraB.Destroy() - end) + if SpecialCameras then + Trigger.AfterDelay(DateTime.Seconds(2), function() + SpyCameraA.Destroy() + SpyCameraB.Destroy() + end) + end end MissInfiltrated = function() @@ -152,7 +188,21 @@ FreeTanya = function() Trigger.OnKilled(Tanya, function() ussr.MarkCompletedObjective(ussrObj) end) - KillSams = greece.AddPrimaryObjective("Destroy all four SAM sites that block\nthe extraction helicopter.") + if Map.Difficulty == "Real tough guy" then + KillSams = greece.AddPrimaryObjective("Destroy all four SAM Sites that block\nour reinforcements' helicopter.") + + greece.MarkCompletedObjective(mainObj) + surviveObj = greece.AddPrimaryObjective("Tanya must not die!") + Media.PlaySpeechNotification(greece, "TanyaRescued") + else + KillSams = greece.AddPrimaryObjective("Destroy all four SAM sites that block\nthe extraction helicopter.") + + Media.PlaySpeechNotification(greece, "TargetFreed") + end + + if not SpecialCameras then + PrisonCamera.Destroy() + end end SendSpy = function() @@ -161,8 +211,10 @@ SendSpy = function() Trigger.OnKilled(Spy, function() ussr.MarkCompletedObjective(ussrObj) end) - SpyCameraA = Actor.Create("camera", true, { Owner = greece, Location = SpyCamera1.Location }) - SpyCameraB = Actor.Create("camera", true, { Owner = greece, Location = SpyCamera2.Location }) + if SpecialCameras then + SpyCameraA = Actor.Create("camera", true, { Owner = greece, Location = SpyCamera1.Location }) + SpyCameraB = Actor.Create("camera", true, { Owner = greece, Location = SpyCamera2.Location }) + end end ActivatePatrols = function() @@ -200,10 +252,16 @@ InitTriggers = function() Spy = Actor.Create("spy", true, { Owner = greece, Location = TrukWaypoint5.Location }) Spy.Move(SpyWaypoint.Location) Spy.Infiltrate(Prison) + Media.PlaySoundNotification(greece, SpyVoice) FollowTruk = false TrukCamera.Destroy() - PrisonCamera = Actor.Create("camera", true, { Owner = greece, Location = TrukWaypoint5.Location }) + + if SpecialCameras then + PrisonCamera = Actor.Create("camera", true, { Owner = greece, Location = TrukWaypoint5.Location }) + else + PrisonCamera = Actor.Create("camera.truk", true, { Owner = greece, Location = Prison.Location + CVec.New(1, 1) }) + end Trigger.OnKilled(Spy, function() ussr.MarkCompletedObjective(ussrObj) end) end @@ -218,10 +276,12 @@ InitTriggers = function() end end) - Trigger.OnKilled(Mammoth, function() - Trigger.AfterDelay(HoldAITime - DateTime.Seconds(45), function() HoldProduction = false end) - Trigger.AfterDelay(HoldAITime, function() Attacking = true end) - end) + if Map.Difficulty ~= "Real tough guy" then + Trigger.OnKilled(Mammoth, function() + Trigger.AfterDelay(HoldAITime - DateTime.Seconds(45), function() HoldProduction = false end) + Trigger.AfterDelay(HoldAITime, function() Attacking = true end) + end) + end Trigger.OnKilled(FlameBarrel, function() if not FlameTower.IsDead then @@ -237,10 +297,31 @@ InitTriggers = function() local flare = Actor.Create("flare", true, { Owner = greece, Location = ExtractionPath[2] + CVec.New(0, -1) }) Trigger.AfterDelay(DateTime.Seconds(7), flare.Destroy) Media.PlaySpeechNotification(greece, "SignalFlare") - ExtractionHeli = Reinforcements.ReinforceWithTransport(greece, ExtractionHeliType, nil, ExtractionPath)[1] - Trigger.OnKilled(ExtractionHeli, function() ussr.MarkCompletedObjective(ussrObj) end) - Trigger.OnRemovedFromWorld(Tanya, ExtractTanya) + if Map.Difficulty == "Real tough guy" then + Reinforcements.ReinforceWithTransport(greece, InsertionHeliType, HeliReinforcements, ExtractionPath, { ExtractionPath[1] }) + if not Harvester.IsDead then + Harvester.FindResources() + end + + else + ExtractionHeli = Reinforcements.ReinforceWithTransport(greece, ExtractionHeliType, nil, ExtractionPath)[1] + local exitPos = CPos.New(ExtractionPath[1].X, ExtractionPath[2].Y) + + Trigger.OnKilled(ExtractionHeli, function() ussr.MarkCompletedObjective(ussrObj) end) + Trigger.OnRemovedFromWorld(Tanya, function() + ExtractUnits(ExtractionHeli, exitPos, function() + + Media.PlaySpeechNotification(greece, "TanyaRescued") + greece.MarkCompletedObjective(mainObj) + SendReinforcements() + + if SpecialCameras then + PrisonCamera.Destroy() + end + end) + end) + end end) end diff --git a/mods/ra/maps/allies-05a/map.yaml b/mods/ra/maps/allies-05a/map.yaml index ad134ce93b..aca6603176 100644 --- a/mods/ra/maps/allies-05a/map.yaml +++ b/mods/ra/maps/allies-05a/map.yaml @@ -33,7 +33,7 @@ Options: StartingCash: 0 TechLevel: Medium ConfigurableStartingUnits: False - Difficulties: Easy, Normal + Difficulties: Easy, Normal, Hard, Real tough guy ShortGame: False Players: @@ -1569,6 +1569,15 @@ Actors: VehicleRallypoint5: waypoint Location: 47,84 Owner: Neutral + WaterTransportSpawn: waypoint + Owner: Neutral + Location: 71,48 + WaterLZ1: waypoint + Owner: Neutral + Location: 52,53 + WaterLZ2: waypoint + Owner: Neutral + Location: 63,63 Smudges: @@ -1608,8 +1617,6 @@ Rules: Tooltip: GenericVisibility: Enemy ShowOwnerRow: false - MustBeDestroyed: - RequiredForShortGame: false ^Wall: Tooltip: ShowOwnerRow: false @@ -1644,12 +1651,31 @@ Rules: Prerequisites: ~disabled LST: -Selectable: + TargetableUnit: + TargetTypes: Ground, Water + Tooltip: + GenericVisibility: Enemy + ShowOwnerRow: false + LST.IN: + Inherits: LST + RenderLandingCraft: + Image: LST + Cargo: + Types: disabled TRAN: -Selectable: RevealsShroud: - Range: 0c0 + Range: 4c0 Tooltip: ShowOwnerRow: false + TargetableAircraft: + GroundedTargetTypes: Ground + TRAN.IN: + Inherits: TRAN + RenderSprites: + Image: TRAN + Cargo: + Types: disabled FLARE: Tooltip: ShowOwnerRow: false @@ -1749,6 +1775,8 @@ Rules: Prerequisites: ~disabled ParatroopersPower@paratroopers: Prerequisites: ~disabled + FCOM: + MustBeDestroyed: 4TNK: Buildable: Prerequisites: ~disabled @@ -1832,5 +1860,6 @@ Notifications: lefty: lefty1 keepem: keepem1 tuffguy: tuffguy1 + sking: sking1 Translations: