Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add polish to Intervention #21398

Merged
merged 1 commit into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
228 changes: 177 additions & 51 deletions mods/ra/maps/intervention/intervention.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ BeachheadTrigger =
CPos.New(137, 104), CPos.New(137, 105), CPos.New(137, 106), CPos.New(136, 106), CPos.New(136, 107)
}

if Difficulty == "normal" then
if Difficulty == "easy" then
BaseRaidInterval = DateTime.Minutes(4)
BaseFrontAttackInterval = DateTime.Minutes(4) + DateTime.Seconds(30)
BaseRearAttackInterval = DateTime.Minutes(8)
UBoatPatrolDelay = DateTime.Minutes(3)
BaseFrontAttackWpts = { PatrolWpt1.Location, BaseRaidWpt1.Location }
elseif Difficulty == "normal" then
BaseRaidInterval = DateTime.Minutes(3)
BaseFrontAttackInterval = DateTime.Minutes(3) + DateTime.Seconds(30)
BaseRearAttackInterval = DateTime.Minutes(8)
Expand Down Expand Up @@ -63,9 +69,9 @@ GroundPatrolUnits =

ParadropSovietUnits = function()
local powerproxy = Actor.Create("powerproxy.paratroopers", false, { Owner = Soviets })
local aircraft = powerproxy.TargetParatroopers(MCVDeployLocation.CenterPosition, Angle.New(812))
local aircraft = powerproxy.TargetParatroopers(MCVRally.CenterPosition, Angle.New(812))
Utils.Do(aircraft, function(a)
Trigger.OnPassengerExited(a, function(t, p)
Trigger.OnPassengerExited(a, function(_, p)
IdleHunt(p)
end)
end)
Expand All @@ -90,8 +96,8 @@ AirRaid = function(planeTypes, ingress, target)
end

BaseRaid = function()
local targets = Map.ActorsInBox(AlliedAreaTopLeft.CenterPosition, AlliedAreaBottomRight.CenterPosition, function(actor)
return actor.Owner == Allies and actor.HasProperty("StartBuildingRepairs")
local targets = Utils.Where(Allies.GetActors(), function(actor)
return actor.HasProperty("StartBuildingRepairs") and IsInAlliedBaseArea(actor.CenterPosition.X, actor.CenterPosition.Y)
end)

if #targets == 0 then
Expand Down Expand Up @@ -137,8 +143,8 @@ SendUboatPatrol = function(team)
end

SendGroundPatrol = function(team)
Utils.Do(team, function(unit) unit.Patrol(GroundPatrolWpts, true, DateTime.Seconds(3)) end)
Utils.Do(team, function(unit)
unit.Patrol(GroundPatrolWpts, true, DateTime.Seconds(3))
Trigger.OnIdle(unit, function(actor) actor.Hunt() end)
end)
Trigger.OnAllKilled(team, function()
Expand All @@ -147,16 +153,16 @@ SendGroundPatrol = function(team)
end

BaseFrontAttack = function(team)
Utils.Do(team, function(unit) unit.Patrol(BaseFrontAttackWpts, false) end)
Utils.Do(team, function(unit)
unit.Patrol(BaseFrontAttackWpts, false)
Trigger.OnIdle(unit, function(actor) actor.Hunt() end)
end)
Trigger.AfterDelay(BaseFrontAttackInterval, function() Build(BaseFrontAttackUnits, BaseFrontAttack) end)
end

BaseRearAttack = function(team)
Utils.Do(team, function(unit) unit.Patrol(BaseRearAttackWpts, false) end)
Utils.Do(team, function(unit)
unit.Patrol(BaseRearAttackWpts, false)
Trigger.OnIdle(unit, function(actor) actor.Hunt() end)
end)
Trigger.AfterDelay(BaseRearAttackInterval, function() Build(BaseRearAttackUnits, BaseRearAttack) end)
Expand All @@ -171,9 +177,8 @@ Build = function(units, action)
end

SetupWorld = function()
Utils.Do(SovietHarvesters, function(a) a.FindResources() end)

Utils.Do(SovietHarvesters, function(harvester)
harvester.FindResources()
Trigger.OnDamaged(harvester, function(h)
Utils.Do(HarvesterGuard, function(g)
if not g.IsDead then
Expand Down Expand Up @@ -258,63 +263,184 @@ WorldLoaded = function()
if not BeachheadTriggered and a.Owner == Allies and a.Type == "mcv" then
BeachheadTriggered = true
Trigger.RemoveFootprintTrigger(id)
Allies.MarkCompletedObjective(BeachheadObjective)
OnBeachheadReached()
end
end)

Trigger.OnAllKilled(Village, function()
-- There is a small time gap between the HQ capture and victory.
-- Ensure aircraft can't trigger defeat within that gap.
if not AirForceHQ.IsDead and AirForceHQ.Owner == Allies then
return
end

Allies.MarkFailedObjective(VillageObjective)
end)

SetupWorld()
SetupMissionText()
ReinforceBuilder()
Trigger.AfterDelay(VillageRaidInterval, VillageRaid)
Trigger.AfterDelay(1, function() Build(UBoatPatrolUnits, SendUboatPatrol) end)
Trigger.AfterDelay(1, function() Build(Utils.Random(GroundPatrolUnits), SendGroundPatrol) end)

Camera.Position = CameraSpot.CenterPosition
Trigger.AfterDelay(DateTime.Seconds(5), function() CameraSpot.Destroy() end)
end

ReinforceBuilder = function()
Reinforcements.Reinforce(Allies, { "mcv" }, { MCVEntry.Location, MCVRally.Location }, 0, function(mcv)
mcv.Deploy()
end)

CaptureObjective = AddPrimaryObjective(Allies, "capture-air-force-hq")
Trigger.AfterDelay(1, function()
CheckBuilder(Allies)

if AirForceHQ.IsDead then
Allies.MarkFailedObjective(CaptureObjective)
if Difficulty ~= "easy" then
return
end

CheckNavalYard(Allies)
local cam = Actor.Create("camera.hq", true, { Owner = Allies, Location = AirForceHQ.Location + CVec.New(1, 1) })
Trigger.AfterDelay(1, cam.Destroy)
end)
end

CheckBuilder = function(player)
if BeachheadTriggered then
return
end

local builders = player.GetActorsByTypes( { "mcv", "fact" } )

Utils.Do(builders, function(builder)
Trigger.OnKilled(builder, OnBuilderLost)
Trigger.OnSold(builder, OnBuilderLost)

-- The MCV deploy/undeploy creates a new actor each time,
-- so add these triggers to the newer actor as needed.
Trigger.OnRemovedFromWorld(builder, function()
local transported = builder.Type == "mcv" and IsBuilderTransported(builder)
if transported then
-- Actors inside transports are temporarily removed from the world.
-- In that case, more triggers are not necessary.
return
end
if AirForceHQ.Owner == Allies then
Allies.MarkCompletedObjective(CaptureObjective)
Allies.MarkCompletedObjective(VillageObjective)
return

CheckBuilder(player)
end)
end)
end

OnBuilderLost = function(builder)
if BeachheadTriggered then
return
end

local speechTime = 36
-- Let "Unit lost"/"Naval unit lost" play first.
Trigger.AfterDelay(DateTime.Seconds(2), function()
Media.PlaySpeechNotification(builder.Owner, "ObjectiveNotReached")
end)

Trigger.AfterDelay(DateTime.Seconds(2) + speechTime, function()
builder.Owner.MarkFailedObjective(BeachheadObjective)
end)
end

IsBuilderTransported = function(builder)
local found = false
local boats = builder.Owner.GetActorsByType("lst")

Utils.Do(boats, function(boat)
if found or not boat.HasPassengers then
return
end

Utils.Do(boat.Passengers, function(passenger)
if passenger == builder then
found = true
end
end)
end)

Trigger.OnCapture(AirForceHQ, function()
Trigger.AfterDelay(DateTime.Seconds(3), function()
Allies.MarkCompletedObjective(CaptureObjective)
Allies.MarkCompletedObjective(VillageObjective)
end)
end)
Trigger.OnKilled(AirForceHQ, function() Allies.MarkFailedObjective(CaptureObjective) end)
return found
end

CheckNavalYard = function(player)
if player.HasPrerequisites({ "syrd" }) then
OnNavalYardBuilt()
return
end

Actor.Create("mainland", true, { Owner = Allies })
Trigger.AfterDelay(DateTime.Seconds(1), function()
CheckNavalYard(player)
end)
end

Trigger.AfterDelay(BaseFrontAttackInterval, function()
Build(BaseFrontAttackUnits, BaseFrontAttack)
ParadropSovietUnits()
end)
Trigger.AfterDelay(BaseRearAttackInterval, function()
Build(BaseRearAttackUnits, BaseRearAttack)
end)
Trigger.AfterDelay(BaseRaidInterval, BaseRaid)
OnNavalYardBuilt = function()
local flare = Actor.Create("flare", true, { Owner = Allies, Location = BeachheadFlare.Location })

Trigger.AfterDelay(UBoatPatrolDelay, function()
Build(HunterSubs, function(subs)
Utils.Do(subs, function(sub)
Trigger.OnIdle(sub, function(s) s.Hunt() end)
end)
end)
end)
Trigger.AfterDelay(DateTime.Seconds(2), function()
Media.PlaySpeechNotification(Allies, "SignalFlareEast")
end)

Trigger.OnObjectiveCompleted(Allies, function(_, objective)
if objective ~= BeachheadObjective then
return
end

Trigger.AfterDelay(DateTime.Minutes(2), function()
if flare.IsInWorld then
flare.Destroy()
end
end)
end)
end

Trigger.OnAllKilled(Village, function() Allies.MarkFailedObjective(VillageObjective) end)
IsInAlliedBaseArea = function(x, y)
local top, bottom = AlliedAreaTopLeft.CenterPosition, AlliedAreaBottomRight.CenterPosition
-- Skip bottom.X since it is on the east edge.
return x > top.X and y > top.Y and y < bottom.Y
end

SetupWorld()
SetupMissionText()
OnBeachheadReached = function()
Media.PlaySpeechNotification(Allies, "ObjectiveReached")
Allies.MarkCompletedObjective(BeachheadObjective)
CaptureObjective = AddPrimaryObjective(Allies, "capture-air-force-hq")

Trigger.AfterDelay(VillageRaidInterval, VillageRaid)
Actor.Create("mainland", true, { Owner = Allies })

Trigger.AfterDelay(1, function() Build(UBoatPatrolUnits, SendUboatPatrol) end)
Trigger.AfterDelay(1, function() Build(Utils.Random(GroundPatrolUnits), SendGroundPatrol) end)
if AirForceHQ.IsDead then
Allies.MarkFailedObjective(CaptureObjective)
return
end
if AirForceHQ.Owner == Allies then
Allies.MarkCompletedObjective(CaptureObjective)
Allies.MarkCompletedObjective(VillageObjective)
return
end

Reinforcements.Reinforce(Allies, { "mcv" }, { MCVInsertLocation.Location, MCVDeployLocation.Location }, 0, function(mcv)
mcv.Deploy()
Trigger.OnCapture(AirForceHQ, function()
Trigger.AfterDelay(DateTime.Seconds(3), function()
Allies.MarkCompletedObjective(CaptureObjective)
Allies.MarkCompletedObjective(VillageObjective)
end)
end)
Trigger.OnKilled(AirForceHQ, function() Allies.MarkFailedObjective(CaptureObjective) end)

Camera.Position = CameraSpot.CenterPosition
Trigger.AfterDelay(DateTime.Seconds(5), function() CameraSpot.Destroy() end)
Trigger.AfterDelay(BaseFrontAttackInterval, function()
Build(BaseFrontAttackUnits, BaseFrontAttack)
ParadropSovietUnits()
end)
Trigger.AfterDelay(BaseRearAttackInterval, function()
Build(BaseRearAttackUnits, BaseRearAttack)
end)
Trigger.AfterDelay(BaseRaidInterval, BaseRaid)

Trigger.AfterDelay(UBoatPatrolDelay, function()
Build(HunterSubs, function(subs)
Utils.Do(subs, IdleHunt)
end)
end)
end
7 changes: 5 additions & 2 deletions mods/ra/maps/intervention/map.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2130,10 +2130,10 @@ Actors:
GroundAttackWpt1: waypoint
Location: 29,64
Owner: Soviets
MCVInsertLocation: waypoint
MCVEntry: waypoint
Location: 71,143
Owner: Allies
MCVDeployLocation: waypoint
MCVRally: waypoint
Location: 73,133
Owner: Allies
AlliedAreaTopLeft: waypoint
Expand Down Expand Up @@ -2199,6 +2199,9 @@ Actors:
BaseRearAttackWpt3: waypoint
Location: 129,57
Owner: Soviets
BeachheadFlare: waypoint
Owner: Neutral
Location: 130,89

Rules: ra|rules/campaign-rules.yaml, ra|rules/campaign-tooltips.yaml, ra|rules/campaign-palettes.yaml, rules.yaml

Expand Down
13 changes: 12 additions & 1 deletion mods/ra/maps/intervention/rules.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Player:
PlayerResources:
DefaultCash: 2000
DefaultCash: 2400

World:
LuaScript:
Expand All @@ -12,6 +12,7 @@ World:
Label: dropdown-difficulty.label
Description: dropdown-difficulty.description
Values:
easy: options-difficulty.easy
normal: options-difficulty.normal
hard: options-difficulty.hard
Default: normal
Expand All @@ -20,6 +21,15 @@ CAMERA:
RevealsShroud:
Range: 18c0

CAMERA.hq:
Inherits: CAMERA
RevealsShroud:
Range: 8c0

FLARE:
RevealsShroud:
Range: 5c0

MISS:
Tooltip:
Name: actor-air-force-hq-name
Expand Down Expand Up @@ -73,6 +83,7 @@ MIG.SCRIPTED:
Ammo: 2
Aircraft:
IdleBehavior: LeaveMapAtClosestEdge
NumberOfTicksToVerifyAvailableAirport: 25

HELI:
Buildable:
Expand Down