1--[[
2   Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
3   This file is part of OpenRA, which is free software. It is made
4   available to you under the terms of the GNU General Public License
5   as published by the Free Software Foundation, either version 3 of
6   the License, or (at your option) any later version. For more
7   information, see COPYING.
8]]
9
10CheckForBase = function()
11	baseBuildings = Map.ActorsInBox(Map.TopLeft, CFBPoint.CenterPosition, function(actor)
12		return actor.Type == "fact" or actor.Type == "powr"
13	end)
14
15	return #baseBuildings >= 2
16end
17
18CheckForCYard = function()
19	ConYard = Map.ActorsInBox(mcvGGLoadPoint.CenterPosition, ReinfEastPoint.CenterPosition, function(actor)
20		return actor.Type == "fact" and actor.Owner == GoodGuy
21	end)
22
23	return #ConYard >= 1
24end
25
26CheckForSPen = function()
27	return Utils.Any(Map.ActorsInWorld, function(actor) return actor.Type == "spen" end)
28end
29
30RunInitialActivities = function()
31	if Map.LobbyOption("difficulty") == "hard" then
32		Expand()
33		ExpansionCheck = true
34	else
35		ExpansionCheck = false
36	end
37
38	Trigger.AfterDelay(1, function()
39		Harvester.FindResources()
40		IdlingUnits()
41		Media.PlaySpeechNotification(player, "ReinforcementsArrived")
42
43		local buildings = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == Greece and self.HasProperty("StartBuildingRepairs") end)
44		Utils.Do(buildings, function(actor)
45			Trigger.OnDamaged(actor, function(building)
46				if building.Owner == Greece and building.Health < building.MaxHealth * 3/4 then
47					building.StartBuildingRepairs()
48				end
49			end)
50		end)
51	end)
52
53	Reinforcements.Reinforce(player, SovietStartReinf, SovietStartToBasePath, 0, function(soldier)
54		soldier.AttackMove(SovietBasePoint.Location)
55	end)
56
57	Actor.Create("camera", true, { Owner = player, Location = GreeceBasePoint.Location })
58	Actor.Create("camera", true, { Owner = player, Location = SovietBasePoint.Location })
59
60	startmcv.Move(MCVStartMovePoint.Location)
61	Runner1.Move(RunnerPoint.Location)
62	Runner2.Move(RunnerPoint.Location)
63	Runner3.Move(RunnerPoint.Location)
64
65	ProduceInfantry()
66	Trigger.AfterDelay(DateTime.Minutes(2), ProduceShips)
67
68	if Map.LobbyOption("difficulty") == "hard" or Map.LobbyOption("difficulty") == "normal" then
69		Trigger.AfterDelay(DateTime.Seconds(25), ReinfInf)
70	end
71	Trigger.AfterDelay(DateTime.Minutes(2), ReinfInf)
72	Trigger.AfterDelay(DateTime.Minutes(3), BringDDPatrol2)
73	Trigger.AfterDelay(DateTime.Minutes(5), ReinfInf)
74	Trigger.AfterDelay(DateTime.Minutes(6), BringDDPatrol1)
75end
76
77Expand = function()
78	if ExpansionCheck or mcvtransport.IsDead or mcvGG.IsDead then
79		return
80	end
81
82	ExpansionCheck = true
83	Trigger.ClearAll(mcvGG)
84	Trigger.ClearAll(mcvtransport)
85	Media.DisplayMessage("Allied MCV detected moving to the island.")
86
87	Reinforcements.Reinforce(GoodGuy, { "dd", "dd" }, ShipArrivePath, 0, function(ddsquad)
88		ddsquad.AttackMove(NearExpPoint.Location) end)
89
90
91	mcvtransport.Move(lstBeachPoint.Location)
92
93	mcvGG.Move(mcvGGLoadPoint.Location)
94	mcvGG.EnterTransport(mcvtransport)
95
96	Trigger.AfterDelay(DateTime.Seconds(5), function()
97		if mcvtransport.IsDead or mcvGG.IsDead then
98			return
99		end
100
101		mcvtransport.Move(GGUnloadPoint.Location)
102		mcvtransport.UnloadPassengers()
103		Trigger.AfterDelay(DateTime.Seconds(12), function()
104			if mcvGG.IsDead then
105				return
106			end
107
108			mcvGG.Move(MCVDeploy.Location)
109			Trigger.AfterDelay(DateTime.Seconds(4), function()
110				if not mcvGG.IsDead then
111					mcvGG.Deploy()
112					Trigger.AfterDelay(DateTime.Seconds(4), function()
113						local fact = Map.ActorsInBox(mcvGGLoadPoint.CenterPosition, ReinfEastPoint.CenterPosition, function(actor)
114							return actor.Type == "fact" and actor.Owner == GoodGuy end)
115						if #fact == 0 then
116							return
117						else
118							Trigger.OnDamaged(fact[1], function()
119								if fact[1].Owner == GoodGuy and fact[1].Health < fact[1].MaxHealth * 3/4 then
120									fact[1].StartBuildingRepairs()
121								end
122							end)
123						end
124					end)
125
126					IslandTroops1()
127					Trigger.AfterDelay(DateTime.Minutes(3), IslandTroops2)
128					Trigger.AfterDelay(DateTime.Minutes(6), IslandTroops3)
129					Trigger.AfterDelay(DateTime.Seconds(7), BuildBase)
130				end
131
132				if not mcvtransport.IsDead then
133					mcvtransport.Move(ReinfNorthPoint.Location)
134					mcvtransport.Destroy()
135				end
136			end)
137		end)
138	end)
139end
140
141Tick = function()
142	if Greece.HasNoRequiredUnits() and GoodGuy.HasNoRequiredUnits() then
143		player.MarkCompletedObjective(KillAll)
144
145		if HoldObjective then
146			player.MarkCompletedObjective(HoldObjective)
147		end
148	end
149
150	if player.HasNoRequiredUnits() then
151		GoodGuy.MarkCompletedObjective(BeatUSSR)
152	end
153
154	if Greece.Resources >= Greece.ResourceCapacity * 0.75 then
155		Greece.Cash = Greece.Cash + Greece.Resources - Greece.ResourceCapacity * 0.25
156		Greece.Resources = Greece.ResourceCapacity * 0.25
157	end
158
159	if GoodGuy.Resources >= GoodGuy.ResourceCapacity * 0.75 then
160		GoodGuy.Cash = GoodGuy.Cash + GoodGuy.Resources - GoodGuy.ResourceCapacity * 0.25
161		GoodGuy.Resources = GoodGuy.ResourceCapacity * 0.25
162	end
163
164	if not baseEstablished and CheckForBase() then
165		baseEstablished = true
166		Para()
167	end
168
169	if not SPenEstablished and CheckForSPen() then
170		SPenEstablished = true
171
172		local units = Reinforcements.ReinforceWithTransport(Greece, "lst", ArtyReinf, SouthReinfPath, { ReinfEastPoint.Location })[2]
173		Utils.Do(units, function(unit) IdleHunt(unit) end)
174		if not ExpansionCheck then
175			Expand()
176			ExpansionCheck = true
177		end
178	end
179
180	if not RCheck then
181		RCheck = true
182		if Map.LobbyOption("difficulty") == "easy" and ReinfCheck then
183			Trigger.AfterDelay(DateTime.Minutes(6), ReinfArmor)
184		elseif Map.LobbyOption("difficulty") == "normal" then
185			Trigger.AfterDelay(DateTime.Minutes(4), ReinfArmor)
186		else
187			Trigger.AfterDelay(DateTime.Minutes(3), ReinfArmor)
188		end
189	end
190end
191
192WorldLoaded = function()
193	player = Player.GetPlayer("USSR")
194	GoodGuy = Player.GetPlayer("GoodGuy")
195	Greece = Player.GetPlayer("Greece")
196
197	Trigger.OnObjectiveAdded(player, function(p, id)
198		Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
199	end)
200	Trigger.OnObjectiveCompleted(player, function(p, id)
201		Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed")
202		Media.PlaySpeechNotification(player, "ObjectiveMet")
203	end)
204	Trigger.OnObjectiveFailed(player, function(p, id)
205		Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed")
206	end)
207
208	CaptureObjective = player.AddPrimaryObjective("Capture the Radar Dome.")
209	KillAll = player.AddPrimaryObjective("Defeat the Allied forces.")
210	BeatUSSR = GoodGuy.AddPrimaryObjective("Defeat the Soviet forces.")
211
212	RunInitialActivities()
213
214	Trigger.OnDamaged(mcvGG, Expand)
215	Trigger.OnDamaged(mcvtransport, Expand)
216
217	Trigger.OnKilled(RadarDome, function()
218		if not player.IsObjectiveCompleted(CaptureObjective) then
219			player.MarkFailedObjective(CaptureObjective)
220		end
221
222		if HoldObjective then
223			player.MarkFailedObjective(HoldObjective)
224		end
225	end)
226
227	RadarDome.GrantCondition("french")
228	Trigger.OnCapture(RadarDome, function()
229		if player.IsObjectiveCompleted(KillAll) then
230			player.MarkCompletedObjective(CaptureObjective)
231			return
232		end
233
234		HoldObjective = player.AddPrimaryObjective("Defend the Radar Dome.")
235		player.MarkCompletedObjective(CaptureObjective)
236		Beacon.New(player, MCVDeploy.CenterPosition)
237		if Map.LobbyOption("difficulty") == "easy" then
238			Actor.Create("camera", true, { Owner = player, Location = MCVDeploy.Location })
239			Media.DisplayMessage("Movement of an Allied expansion base discovered.")
240		else
241			Actor.Create("MCV.CAM", true, { Owner = player, Location = MCVDeploy.Location })
242			Media.DisplayMessage("Coordinates of an Allied expansion base discovered.")
243		end
244
245		if not ExpansionCheck then
246			Expand()
247			ExpansionCheck = true
248		end
249
250		Reinforcements.Reinforce(Greece, ArmorReinfGreece, AlliedCrossroadsToRadarPath , 0, IdleHunt)
251
252		RadarDome.RevokeCondition(1)
253		Trigger.ClearAll(RadarDome)
254		Trigger.AfterDelay(0, function()
255			Trigger.OnRemovedFromWorld(RadarDome, function()
256				player.MarkFailedObjective(HoldObjective)
257			end)
258		end)
259	end)
260
261	Trigger.OnEnteredProximityTrigger(USSRExpansionPoint.CenterPosition, WDist.New(4 * 1024), function(unit, id)
262		if unit.Owner == player and RadarDome.Owner == player then
263			Trigger.RemoveProximityTrigger(id)
264
265			Para2()
266			ProduceInfantryGG()
267			ProduceTanksGG()
268
269			local units = Reinforcements.ReinforceWithTransport(player, "lst", SovietMCVReinf, { ReinfSouthPoint.Location, USSRlstPoint.Location }, { ReinfSouthPoint.Location })[2]
270			Utils.Do(units, function(unit)
271				Trigger.OnAddedToWorld(unit, function()
272					if unit.Type == "mcv" then
273						unit.Move(USSRExpansionPoint.Location)
274					else
275						unit.AttackMove(USSRExpansionPoint.Location)
276					end
277				end)
278			end)
279
280			Media.PlaySpeechNotification(player, "ReinforcementsArrived")
281		end
282	end)
283
284	Trigger.OnPlayerLost(player, function()
285		Media.PlaySpeechNotification(player, "Lose")
286	end)
287
288	Trigger.OnPlayerWon(player, function()
289		Media.PlaySpeechNotification(player, "Win")
290	end)
291
292	Camera.Position = StartCamPoint.CenterPosition
293end
294