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
10Difficulty = Map.LobbyOption("difficulty")
11
12IdleHunt = function(actor)
13	if actor.HasProperty("Hunt") and not actor.IsDead then
14		Trigger.OnIdle(actor, actor.Hunt)
15	end
16end
17
18InitObjectives = function(player)
19	Trigger.OnObjectiveAdded(player, function(p, id)
20		Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
21	end)
22
23	Trigger.OnObjectiveCompleted(player, function(p, id)
24		Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed")
25	end)
26	Trigger.OnObjectiveFailed(player, function(p, id)
27		Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed")
28	end)
29
30	Trigger.OnPlayerLost(player, function()
31		Trigger.AfterDelay(DateTime.Seconds(1), function()
32			Media.PlaySpeechNotification(player, "Lose")
33		end)
34	end)
35	Trigger.OnPlayerWon(player, function()
36		Trigger.AfterDelay(DateTime.Seconds(1), function()
37			Media.PlaySpeechNotification(player, "Win")
38		end)
39	end)
40end
41
42ReinforceWithLandingCraft = function(player, units, transportStart, transportUnload, rallypoint)
43	local transport = Actor.Create("oldlst", true, { Owner = player, Facing = 0, Location = transportStart })
44	local subcell = 0
45	Utils.Do(units, function(a)
46		transport.LoadPassenger(Actor.Create(a, false, { Owner = transport.Owner, Facing = transport.Facing, Location = transportUnload, SubCell = subcell }))
47		subcell = subcell + 1
48	end)
49
50	transport.ScriptedMove(transportUnload)
51
52	transport.CallFunc(function()
53		Utils.Do(units, function()
54			local a = transport.UnloadPassenger()
55			a.IsInWorld = true
56			a.MoveIntoWorld(transport.Location - CVec.New(0, 1))
57
58			if rallypoint then
59				a.Move(rallypoint)
60			end
61		end)
62	end)
63
64	transport.Wait(5)
65	transport.ScriptedMove(transportStart)
66	transport.Destroy()
67end
68
69RepairBuilding = function(owner, actor, modifier)
70	Trigger.OnDamaged(actor, function(building)
71		if building.Owner == owner and building.Health < building.MaxHealth * modifier then
72			building.StartBuildingRepairs()
73		end
74	end)
75end
76
77RepairNamedActors = function(owner, modifier)
78	Utils.Do(Map.NamedActors, function(actor)
79		if actor.Owner == owner and actor.HasProperty("StartBuildingRepairs") then
80			RepairBuilding(owner, actor, modifier)
81		end
82	end)
83end
84
85ProduceUnits = function(player, factory, delay, toBuild, after)
86	if factory.IsDead or factory.Owner ~= player then
87		return
88	end
89
90	factory.Build(toBuild(), function(units)
91		if delay and delay() > 0 then
92			Trigger.AfterDelay(delay(), function() ProduceUnits(player, factory, delay, toBuild, after) end)
93		end
94
95		if after then
96			after(units)
97		end
98	end)
99end
100
101CheckForBase = function(player, buildingTypes)
102	local count = 0
103
104	Utils.Do(buildingTypes, function(name)
105		if #player.GetActorsByType(name) > 0 then
106			count = count + 1
107		end
108	end)
109
110	return count == #buildingTypes
111end
112
113RebuildUnit = function(unit, player, factory)
114	Trigger.OnKilled(unit[1], function()
115		ProduceUnits(player, factory, nil, function() return { unit[1].Type } end, function(actors)
116			RebuildUnit(actors, player, factory)
117		end)
118	end)
119end
120
121MoveAndHunt = function(actors, path)
122	Utils.Do(actors, function(actor)
123		if not actor or actor.IsDead then
124			return
125		end
126
127		Utils.Do(path, function(point)
128			actor.AttackMove(point.Location)
129		end)
130
131		IdleHunt(actor)
132	end)
133end
134
135Searches = 0
136GetAirstrikeTarget = function(player)
137	local list = player.GetGroundAttackers()
138
139	if #list == 0 then
140		return
141	end
142
143	local target = list[DateTime.GameTime % #list + 1].CenterPosition
144
145	local sams = Map.ActorsInCircle(target, WDist.New(8 * 1024), function(actor)
146		return actor.Type == "sam" end)
147
148	if #sams == 0 then
149		Searches = 0
150		return target
151	elseif Searches < 6 then
152		Searches = Searches + 1
153		return GetAirstrikeTarget(player)
154	else
155		Searches = 0
156		return nil
157	end
158end
159