Add a global script for campaign missions in d2k

This commit is contained in:
abcdefg30
2017-06-21 16:25:53 +02:00
committed by reaperrr
parent 7f0c7cee0d
commit a942ca8f57
63 changed files with 1168 additions and 3476 deletions

View File

@@ -100,6 +100,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Red Alert Lua scripts", "Re
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dune 2000 Lua scripts", "Dune 2000 Lua scripts", "{06B1AE07-DDB0-4287-8700-A8CD9A0E652E}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dune 2000 Lua scripts", "Dune 2000 Lua scripts", "{06B1AE07-DDB0-4287-8700-A8CD9A0E652E}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
mods\d2k\bits\scripts\campaign-global.lua = mods\d2k\bits\scripts\campaign-global.lua
mods\d2k\maps\atreides-01a\atreides01a.lua = mods\d2k\maps\atreides-01a\atreides01a.lua mods\d2k\maps\atreides-01a\atreides01a.lua = mods\d2k\maps\atreides-01a\atreides01a.lua
mods\d2k\maps\atreides-01b\atreides01b.lua = mods\d2k\maps\atreides-01b\atreides01b.lua mods\d2k\maps\atreides-01b\atreides01b.lua = mods\d2k\maps\atreides-01b\atreides01b.lua
mods\d2k\maps\atreides-02a\atreides02a-AI.lua = mods\d2k\maps\atreides-02a\atreides02a-AI.lua mods\d2k\maps\atreides-02a\atreides02a-AI.lua = mods\d2k\maps\atreides-02a\atreides02a-AI.lua

View File

@@ -0,0 +1,192 @@
--[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
Difficulty = Map.LobbyOption("difficulty")
IdleHunt = function(actor)
if not actor.IsDead then
Trigger.OnIdle(actor, actor.Hunt)
end
end
InitObjectives = function(player)
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end
SendCarryallReinforcements = function(player, currentWave, totalWaves, delay, pathFunction, unitTypes, customCondition, customHuntFunction)
Trigger.AfterDelay(delay, function()
if customCondition and customCondition() then
return
end
currentWave = currentWave + 1
if currentWave > totalWaves then
return
end
local path = pathFunction()
local units = Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", unitTypes[currentWave], path, { path[1] })[2]
if not customHuntFunction then
customHuntFunction = IdleHunt
end
Utils.Do(units, customHuntFunction)
SendCarryallReinforcements(player, currentWave, totalWaves, delay, pathFunction, unitTypes, customCondition, customHuntFunction)
end)
end
TriggerCarryallReinforcements = function(triggeringPlayer, reinforcingPlayer, area, unitTypes, path, customCondition)
local fired = false
Trigger.OnEnteredFootprint(area, function(a, id)
if customCondition and customCondition() then
return
end
if not fired and a.Owner == triggeringPlayer and a.Type ~= "carryall" then
fired = true
Trigger.RemoveFootprintTrigger(id)
local units = Reinforcements.ReinforceWithTransport(reinforcingPlayer, "carryall.reinforce", unitTypes, path, { path[1] })[2]
Utils.Do(units, IdleHunt)
end
end)
end
-- Used for the AI:
IdlingUnits = { }
Attacking = { }
HoldProduction = { }
HarvesterKilled = { }
SetupAttackGroup = function(owner, size)
local units = { }
for i = 0, size, 1 do
if #IdlingUnits[owner] == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits[owner] + 1)
if IdlingUnits[owner][number] and not IdlingUnits[owner][number].IsDead then
units[i] = IdlingUnits[owner][number]
table.remove(IdlingUnits[owner], number)
end
end
return units
end
SendAttack = function(owner, size)
if Attacking[owner] then
return
end
Attacking[owner] = true
HoldProduction[owner] = true
local units = SetupAttackGroup(owner, size)
Utils.Do(units, IdleHunt)
Trigger.OnAllRemovedFromWorld(units, function()
Attacking[owner] = false
HoldProduction[owner] = false
end)
end
DefendActor = function(unit, defendingPlayer, defenderCount)
Trigger.OnDamaged(unit, function(self, attacker)
-- Don't try to attack spiceblooms
if attacker and attacker.Type == "spicebloom" then
return
end
if Attacking[defendingPlayer] then
return
end
Attacking[defendingPlayer] = true
local Guards = SetupAttackGroup(defendingPlayer, defenderCount)
if #Guards <= 0 then
Attacking[defendingPlayer] = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() Attacking[defendingPlayer] = false end)
end)
end
ProtectHarvester = function(unit, owner, defenderCount)
DefendActor(unit, owner, defenderCount)
Trigger.OnKilled(unit, function() HarvesterKilled[unit.Owner] = true end)
end
RepairBuilding = function(owner, actor, modifier)
Trigger.OnDamaged(actor, function(building)
if building.Owner == owner and building.Health < building.MaxHealth * modifier then
building.StartBuildingRepairs()
end
end)
end
DefendAndRepairBase = function(owner, baseBuildings, modifier, defenderCount)
Utils.Do(baseBuildings, function(actor)
DefendActor(actor, owner, defenderCount)
RepairBuilding(owner, actor, modifier)
end)
end
ProduceUnits = function(player, factory, delay, toBuild, attackSize, attackThresholdSize)
if factory.IsDead or factory.Owner ~= player then
return
end
if HoldProduction[player] then
Trigger.AfterDelay(DateTime.Minutes(1), function() ProduceUnits(player, factory, delay, toBuild, attackSize, attackThresholdSize) end)
return
end
player.Build(toBuild(), function(unit)
IdlingUnits[player][#IdlingUnits[player] + 1] = unit[1]
Trigger.AfterDelay(delay(), function() ProduceUnits(player, factory, delay, toBuild, attackSize, attackThresholdSize) end)
if #IdlingUnits[player] >= attackThresholdSize then
SendAttack(player, attackSize)
end
end)
end

View File

@@ -7,40 +7,46 @@
information, see COPYING. information, see COPYING.
]] ]]
HarkonnenReinforcements = { } HarkonnenReinforcements =
HarkonnenReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "light_inf" } { "light_inf", "light_inf" }
} },
HarkonnenReinforcements["normal"] = normal =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
HarkonnenReinforcements["hard"] = hard =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
HarkonnenEntryWaypoints = { HarkonnenWaypoint1.Location, HarkonnenWaypoint2.Location, HarkonnenWaypoint3.Location, HarkonnenWaypoint4.Location } HarkonnenEntryWaypoints = { HarkonnenWaypoint1.Location, HarkonnenWaypoint2.Location, HarkonnenWaypoint3.Location, HarkonnenWaypoint4.Location }
HarkonnenAttackDelay = DateTime.Seconds(30) HarkonnenAttackDelay = DateTime.Seconds(30)
HarkonnenAttackWaves = { } HarkonnenAttackWaves =
HarkonnenAttackWaves["easy"] = 1 {
HarkonnenAttackWaves["normal"] = 5 easy = 1,
HarkonnenAttackWaves["hard"] = 12 normal = 5,
hard = 12
}
ToHarvest = { } ToHarvest =
ToHarvest["easy"] = 2500 {
ToHarvest["normal"] = 3000 easy = 2500,
ToHarvest["hard"] = 3500 normal = 3000,
hard = 3500
}
AtreidesReinforcements = { "light_inf", "light_inf", "light_inf" } AtreidesReinforcements = { "light_inf", "light_inf", "light_inf" }
AtreidesEntryPath = { AtreidesWaypoint.Location, AtreidesRally.Location } AtreidesEntryPath = { AtreidesWaypoint.Location, AtreidesRally.Location }
@@ -53,19 +59,12 @@ Messages =
"Build a Silo to store additional Spice." "Build a Silo to store additional Spice."
} }
IdleHunt = function(actor)
if not actor.IsDead then
Trigger.OnIdle(actor, actor.Hunt)
end
end
Tick = function() Tick = function()
if HarkonnenArrived and harkonnen.HasNoRequiredUnits() then if HarkonnenArrived and harkonnen.HasNoRequiredUnits() then
player.MarkCompletedObjective(KillHarkonnen) player.MarkCompletedObjective(KillHarkonnen)
end end
if player.Resources > ToHarvest[Map.LobbyOption("difficulty")] - 1 then if player.Resources > SpiceToHarvest - 1 then
player.MarkCompletedObjective(GatherSpice) player.MarkCompletedObjective(GatherSpice)
end end
@@ -86,14 +85,19 @@ Tick = function()
Media.DisplayMessage(Messages[4], "Mentat") Media.DisplayMessage(Messages[4], "Mentat")
end end
UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. ToHarvest[Map.LobbyOption("difficulty")], player.Color) UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. SpiceToHarvest, player.Color)
end end
WorldLoaded = function() WorldLoaded = function()
player = Player.GetPlayer("Atreides") player = Player.GetPlayer("Atreides")
harkonnen = Player.GetPlayer("Harkonnen") harkonnen = Player.GetPlayer("Harkonnen")
InitObjectives() SpiceToHarvest = ToHarvest[Difficulty]
InitObjectives(player)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(SpiceToHarvest) .. " Solaris worth of Spice.")
KillHarkonnen = player.AddSecondaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
Trigger.OnRemovedFromWorld(AtreidesConyard, function() Trigger.OnRemovedFromWorld(AtreidesConyard, function()
local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end) local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end)
@@ -114,12 +118,12 @@ WorldLoaded = function()
Reinforcements.Reinforce(player, AtreidesReinforcements, AtreidesEntryPath) Reinforcements.Reinforce(player, AtreidesReinforcements, AtreidesEntryPath)
end) end)
WavesLeft = HarkonnenAttackWaves[Map.LobbyOption("difficulty")] WavesLeft = HarkonnenAttackWaves[Difficulty]
SendReinforcements() SendReinforcements()
end end
SendReinforcements = function() SendReinforcements = function()
local units = HarkonnenReinforcements[Map.LobbyOption("difficulty")] local units = HarkonnenReinforcements[Difficulty]
local delay = Utils.RandomInteger(HarkonnenAttackDelay - DateTime.Seconds(2), HarkonnenAttackDelay) local delay = Utils.RandomInteger(HarkonnenAttackDelay - DateTime.Seconds(2), HarkonnenAttackDelay)
HarkonnenAttackDelay = HarkonnenAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1) HarkonnenAttackDelay = HarkonnenAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1)
if HarkonnenAttackDelay < 0 then HarkonnenAttackDelay = 0 end if HarkonnenAttackDelay < 0 then HarkonnenAttackDelay = 0 end
@@ -135,31 +139,3 @@ SendReinforcements = function()
end end
end) end)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(ToHarvest[Map.LobbyOption("difficulty")]) .. " Solaris worth of Spice.")
KillHarkonnen = player.AddSecondaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: atreides01a.lua Scripts: campaign-global.lua, atreides01a.lua
MissionData: MissionData:
Briefing: Harvest Spice from the Imperial Basin. Construct a Spice Refinery and defend it against the Harkonnen troops scattered throughout the basin. You have been assigned only limited offensive forces - use them wisely.\n\nYou will have to learn the subtleties of mining as you go, but remember to build Silos to store the Spice. When you run out of storage space you can not gather more Spice. Also, any building without adequate concrete foundation will need immediate repair and be vulnerable to erosive damage from the harsh environment. Your greatest adversary may be the elements.\n\nGood luck.\n Briefing: Harvest Spice from the Imperial Basin. Construct a Spice Refinery and defend it against the Harkonnen troops scattered throughout the basin. You have been assigned only limited offensive forces - use them wisely.\n\nYou will have to learn the subtleties of mining as you go, but remember to build Silos to store the Spice. When you run out of storage space you can not gather more Spice. Also, any building without adequate concrete foundation will need immediate repair and be vulnerable to erosive damage from the harsh environment. Your greatest adversary may be the elements.\n\nGood luck.\n
BriefingVideo: A_BR01_E.VQA BriefingVideo: A_BR01_E.VQA

View File

@@ -7,40 +7,46 @@
information, see COPYING. information, see COPYING.
]] ]]
HarkonnenReinforcements = { } HarkonnenReinforcements =
HarkonnenReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "light_inf" } { "light_inf", "light_inf" }
} },
HarkonnenReinforcements["normal"] = normal =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
HarkonnenReinforcements["hard"] = hard =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
HarkonnenEntryWaypoints = { HarkonnenWaypoint1.Location, HarkonnenWaypoint2.Location, HarkonnenWaypoint3.Location, HarkonnenWaypoint4.Location } HarkonnenEntryWaypoints = { HarkonnenWaypoint1.Location, HarkonnenWaypoint2.Location, HarkonnenWaypoint3.Location, HarkonnenWaypoint4.Location }
HarkonnenAttackDelay = DateTime.Seconds(30) HarkonnenAttackDelay = DateTime.Seconds(30)
HarkonnenAttackWaves = { } HarkonnenAttackWaves =
HarkonnenAttackWaves["easy"] = 1 {
HarkonnenAttackWaves["normal"] = 5 easy = 1,
HarkonnenAttackWaves["hard"] = 12 normal = 5,
hard = 12
}
ToHarvest = { } ToHarvest =
ToHarvest["easy"] = 2500 {
ToHarvest["normal"] = 3000 easy = 2500,
ToHarvest["hard"] = 3500 normal = 3000,
hard = 3500
}
AtreidesReinforcements = { "light_inf", "light_inf", "light_inf", "light_inf" } AtreidesReinforcements = { "light_inf", "light_inf", "light_inf", "light_inf" }
AtreidesEntryPath = { AtreidesWaypoint.Location, AtreidesRally.Location } AtreidesEntryPath = { AtreidesWaypoint.Location, AtreidesRally.Location }
@@ -53,19 +59,12 @@ Messages =
"Build a Silo to store additional Spice." "Build a Silo to store additional Spice."
} }
IdleHunt = function(actor)
if not actor.IsDead then
Trigger.OnIdle(actor, actor.Hunt)
end
end
Tick = function() Tick = function()
if HarkonnenArrived and harkonnen.HasNoRequiredUnits() then if HarkonnenArrived and harkonnen.HasNoRequiredUnits() then
player.MarkCompletedObjective(KillHarkonnen) player.MarkCompletedObjective(KillHarkonnen)
end end
if player.Resources > ToHarvest[Map.LobbyOption("difficulty")] - 1 then if player.Resources > SpiceToHarvest - 1 then
player.MarkCompletedObjective(GatherSpice) player.MarkCompletedObjective(GatherSpice)
end end
@@ -86,14 +85,19 @@ Tick = function()
Media.DisplayMessage(Messages[4], "Mentat") Media.DisplayMessage(Messages[4], "Mentat")
end end
UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. ToHarvest[Map.LobbyOption("difficulty")], player.Color) UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. SpiceToHarvest, player.Color)
end end
WorldLoaded = function() WorldLoaded = function()
player = Player.GetPlayer("Atreides") player = Player.GetPlayer("Atreides")
harkonnen = Player.GetPlayer("Harkonnen") harkonnen = Player.GetPlayer("Harkonnen")
InitObjectives() SpiceToHarvest = ToHarvest[Difficulty]
InitObjectives(player)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(SpiceToHarvest) .. " Solaris worth of Spice.")
KillHarkonnen = player.AddSecondaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
Trigger.OnRemovedFromWorld(AtreidesConyard, function() Trigger.OnRemovedFromWorld(AtreidesConyard, function()
local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end) local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end)
@@ -114,12 +118,12 @@ WorldLoaded = function()
Reinforcements.Reinforce(player, AtreidesReinforcements, AtreidesEntryPath) Reinforcements.Reinforce(player, AtreidesReinforcements, AtreidesEntryPath)
end) end)
WavesLeft = HarkonnenAttackWaves[Map.LobbyOption("difficulty")] WavesLeft = HarkonnenAttackWaves[Difficulty]
SendReinforcements() SendReinforcements()
end end
SendReinforcements = function() SendReinforcements = function()
local units = HarkonnenReinforcements[Map.LobbyOption("difficulty")] local units = HarkonnenReinforcements[Difficulty]
local delay = Utils.RandomInteger(HarkonnenAttackDelay - DateTime.Seconds(2), HarkonnenAttackDelay) local delay = Utils.RandomInteger(HarkonnenAttackDelay - DateTime.Seconds(2), HarkonnenAttackDelay)
HarkonnenAttackDelay = HarkonnenAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1) HarkonnenAttackDelay = HarkonnenAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1)
if HarkonnenAttackDelay < 0 then HarkonnenAttackDelay = 0 end if HarkonnenAttackDelay < 0 then HarkonnenAttackDelay = 0 end
@@ -135,31 +139,3 @@ SendReinforcements = function()
end end
end) end)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(ToHarvest[Map.LobbyOption("difficulty")]) .. " Solaris worth of Spice.")
KillHarkonnen = player.AddSecondaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: atreides01b.lua Scripts: campaign-global.lua, atreides01b.lua
MissionData: MissionData:
Briefing: Harvest Spice from the Imperial Basin. Construct a Spice Refinery and defend it against the Harkonnen troops scattered throughout the basin. You have been assigned only limited offensive forces - use them wisely.\n\nYou will have to learn the subtleties of mining as you go, but remember to build Silos to store the Spice. When you run out of storage space you can not gather more Spice. Also, any building without adequate concrete foundation will need immediate repair and be vulnerable to erosive damage from the harsh environment. Your greatest adversary may be the elements.\n\nGood luck.\n Briefing: Harvest Spice from the Imperial Basin. Construct a Spice Refinery and defend it against the Harkonnen troops scattered throughout the basin. You have been assigned only limited offensive forces - use them wisely.\n\nYou will have to learn the subtleties of mining as you go, but remember to build Silos to store the Spice. When you run out of storage space you can not gather more Spice. Also, any building without adequate concrete foundation will need immediate repair and be vulnerable to erosive damage from the harsh environment. Your greatest adversary may be the elements.\n\nGood luck.\n
BriefingVideo: A_BR01_E.VQA BriefingVideo: A_BR01_E.VQA

View File

@@ -6,7 +6,6 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
IdlingUnits = { }
AttackGroupSize = AttackGroupSize =
{ {
@@ -14,6 +13,7 @@ AttackGroupSize =
normal = 8, normal = 8,
hard = 10 hard = 10
} }
AttackDelays = AttackDelays =
{ {
easy = { DateTime.Seconds(4), DateTime.Seconds(9) }, easy = { DateTime.Seconds(4), DateTime.Seconds(9) },
@@ -23,108 +23,12 @@ AttackDelays =
HarkonnenInfantryTypes = { "light_inf" } HarkonnenInfantryTypes = { "light_inf" }
AttackOnGoing = false
HoldProduction = false
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Map.LobbyOption("difficulty")], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if Attacking then
return
end
Attacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
Attacking = false
HoldProduction = false
end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function()
Utils.Do(HarkonnenBase, function(actor)
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if HBarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(HarkonnenInfantryTypes) }
harkonnen.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ActivateAI = function() ActivateAI = function()
InitAIUnits() IdlingUnits[harkonnen] = { }
ProduceInfantry() DefendAndRepairBase(harkonnen, HarkonnenBase, 0.75, AttackGroupSize[Difficulty])
local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local toBuild = function() return HarkonnenInfantryTypes end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
ProduceUnits(harkonnen, HBarracks, delay, toBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end end

View File

@@ -9,26 +9,27 @@
HarkonnenBase = { HConyard, HPower1, HPower2, HBarracks } HarkonnenBase = { HConyard, HPower1, HPower2, HBarracks }
HarkonnenReinforcements = { } HarkonnenReinforcements =
HarkonnenReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" } { "light_inf", "light_inf", "light_inf", "trike", "trike" }
} },
HarkonnenReinforcements["normal"] = normal =
{ {
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" }, { "light_inf", "light_inf", "light_inf", "trike", "trike" },
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
HarkonnenReinforcements["hard"] = hard =
{ {
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
@@ -38,6 +39,7 @@ HarkonnenReinforcements["hard"] =
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
HarkonnenAttackPaths = HarkonnenAttackPaths =
@@ -48,35 +50,19 @@ HarkonnenAttackPaths =
{ HarkonnenEntry2.Location, HarkonnenRally4.Location } { HarkonnenEntry2.Location, HarkonnenRally4.Location }
} }
HarkonnenAttackDelay = { } HarkonnenAttackDelay =
HarkonnenAttackDelay["easy"] = DateTime.Minutes(5) {
HarkonnenAttackDelay["normal"] = DateTime.Minutes(2) + DateTime.Seconds(40) easy = DateTime.Minutes(5),
HarkonnenAttackDelay["hard"] = DateTime.Minutes(1) + DateTime.Seconds(20) normal = DateTime.Minutes(2) + DateTime.Seconds(40),
hard = DateTime.Minutes(1) + DateTime.Seconds(20)
}
HarkonnenAttackWaves = { } HarkonnenAttackWaves =
HarkonnenAttackWaves["easy"] = 3 {
HarkonnenAttackWaves["normal"] = 6 easy = 3,
HarkonnenAttackWaves["hard"] = 9 normal = 6,
hard = 9
wave = 0 }
SendHarkonnen = function()
Trigger.AfterDelay(HarkonnenAttackDelay[Map.LobbyOption("difficulty")], function()
wave = wave + 1
if wave > HarkonnenAttackWaves[Map.LobbyOption("difficulty")] then
return
end
local path = Utils.Random(HarkonnenAttackPaths)
local units = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", HarkonnenReinforcements[Map.LobbyOption("difficulty")][wave], path, { path[1] })[2]
Utils.Do(units, IdleHunt)
SendHarkonnen()
end)
end
IdleHunt = function(unit)
Trigger.OnIdle(unit, unit.Hunt)
end
Tick = function() Tick = function()
if player.HasNoRequiredUnits() then if player.HasNoRequiredUnits() then
@@ -93,7 +79,9 @@ WorldLoaded = function()
harkonnen = Player.GetPlayer("Harkonnen") harkonnen = Player.GetPlayer("Harkonnen")
player = Player.GetPlayer("Atreides") player = Player.GetPlayer("Atreides")
InitObjectives() InitObjectives(player)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
KillHarkonnen = player.AddPrimaryObjective("Destroy all Harkonnen forces.")
Camera.Position = AConyard.CenterPosition Camera.Position = AConyard.CenterPosition
@@ -101,33 +89,7 @@ WorldLoaded = function()
Utils.Do(harkonnen.GetGroundAttackers(), IdleHunt) Utils.Do(harkonnen.GetGroundAttackers(), IdleHunt)
end) end)
SendHarkonnen() local path = function() return Utils.Random(HarkonnenAttackPaths) end
SendCarryallReinforcements(harkonnen, 0, HarkonnenAttackWaves[Difficulty], HarkonnenAttackDelay[Difficulty], path, HarkonnenReinforcements[Difficulty])
Trigger.AfterDelay(0, ActivateAI) Trigger.AfterDelay(0, ActivateAI)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
KillHarkonnen = player.AddPrimaryObjective("Destroy all Harkonnen forces.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: atreides02a.lua, atreides02a-AI.lua Scripts: campaign-global.lua, atreides02a.lua, atreides02a-AI.lua
MissionData: MissionData:
Briefing: Infiltrate the Imperial Basin and build up our forces until they are strong enough to eradicate the local Harkonnen presence.\n\nThe Harkonnen are reinforcing their troops by air, so be on your guard. Use the Outpost's radar to detect attacks from unexpected quarters.\n\nBe careful when mining the Spice. Spice mounds grow out of the sand. While a vital source of Spice, Spice mounds can damage or destroy any unit that blunders into them.\n\nGood luck.\n Briefing: Infiltrate the Imperial Basin and build up our forces until they are strong enough to eradicate the local Harkonnen presence.\n\nThe Harkonnen are reinforcing their troops by air, so be on your guard. Use the Outpost's radar to detect attacks from unexpected quarters.\n\nBe careful when mining the Spice. Spice mounds grow out of the sand. While a vital source of Spice, Spice mounds can damage or destroy any unit that blunders into them.\n\nGood luck.\n
BriefingVideo: A_BR02_E.VQA BriefingVideo: A_BR02_E.VQA

View File

@@ -6,7 +6,6 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
IdlingUnits = { }
AttackGroupSize = AttackGroupSize =
{ {
@@ -14,6 +13,7 @@ AttackGroupSize =
normal = 8, normal = 8,
hard = 10 hard = 10
} }
AttackDelays = AttackDelays =
{ {
easy = { DateTime.Seconds(4), DateTime.Seconds(9) }, easy = { DateTime.Seconds(4), DateTime.Seconds(9) },
@@ -23,108 +23,12 @@ AttackDelays =
HarkonnenInfantryTypes = { "light_inf" } HarkonnenInfantryTypes = { "light_inf" }
AttackOnGoing = false
HoldProduction = false
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Map.LobbyOption("difficulty")], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if Attacking then
return
end
Attacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
Attacking = false
HoldProduction = false
end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function()
Utils.Do(HarkonnenBase, function(actor)
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if HBarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(HarkonnenInfantryTypes) }
harkonnen.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ActivateAI = function() ActivateAI = function()
InitAIUnits() IdlingUnits[harkonnen] = { }
ProduceInfantry() DefendAndRepairBase(harkonnen, HarkonnenBase, 0.75, AttackGroupSize[Difficulty])
local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local toBuild = function() return HarkonnenInfantryTypes end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
ProduceUnits(harkonnen, HBarracks, delay, toBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end end

View File

@@ -9,26 +9,27 @@
HarkonnenBase = { HConyard, HOutpost, HBarracks } HarkonnenBase = { HConyard, HOutpost, HBarracks }
HarkonnenReinforcements = { } HarkonnenReinforcements =
HarkonnenReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" } { "light_inf", "light_inf", "light_inf", "trike", "trike" }
} },
HarkonnenReinforcements["normal"] = normal =
{ {
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" }, { "light_inf", "light_inf", "light_inf", "trike", "trike" },
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
HarkonnenReinforcements["hard"] = hard =
{ {
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
@@ -38,6 +39,7 @@ HarkonnenReinforcements["hard"] =
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
HarkonnenAttackPaths = HarkonnenAttackPaths =
@@ -62,26 +64,6 @@ HarkonnenAttackWaves =
hard = 9 hard = 9
} }
wave = 0
SendHarkonnen = function()
Trigger.AfterDelay(HarkonnenAttackDelay[Map.LobbyOption("difficulty")], function()
wave = wave + 1
if wave > HarkonnenAttackWaves[Map.LobbyOption("difficulty")] then
return
end
local path = Utils.Random(HarkonnenAttackPaths)
local units = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", HarkonnenReinforcements[Map.LobbyOption("difficulty")][wave], path, { path[1] })[2]
Utils.Do(units, IdleHunt)
SendHarkonnen()
end)
end
IdleHunt = function(unit)
Trigger.OnIdle(unit, unit.Hunt)
end
Tick = function() Tick = function()
if player.HasNoRequiredUnits() then if player.HasNoRequiredUnits() then
harkonnen.MarkCompletedObjective(KillAtreides) harkonnen.MarkCompletedObjective(KillAtreides)
@@ -97,7 +79,9 @@ WorldLoaded = function()
harkonnen = Player.GetPlayer("Harkonnen") harkonnen = Player.GetPlayer("Harkonnen")
player = Player.GetPlayer("Atreides") player = Player.GetPlayer("Atreides")
InitObjectives() InitObjectives(player)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
KillHarkonnen = player.AddPrimaryObjective("Destroy all Harkonnen forces.")
Camera.Position = AConyard.CenterPosition Camera.Position = AConyard.CenterPosition
@@ -105,33 +89,7 @@ WorldLoaded = function()
Utils.Do(harkonnen.GetGroundAttackers(), IdleHunt) Utils.Do(harkonnen.GetGroundAttackers(), IdleHunt)
end) end)
SendHarkonnen() local path = function() return Utils.Random(HarkonnenAttackPaths) end
SendCarryallReinforcements(harkonnen, 0, HarkonnenAttackWaves[Difficulty], HarkonnenAttackDelay[Difficulty], path, HarkonnenReinforcements[Difficulty])
Trigger.AfterDelay(0, ActivateAI) Trigger.AfterDelay(0, ActivateAI)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
KillHarkonnen = player.AddPrimaryObjective("Destroy all Harkonnen forces.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: atreides02b.lua, atreides02b-AI.lua Scripts: campaign-global.lua, atreides02b.lua, atreides02b-AI.lua
MissionData: MissionData:
Briefing: Infiltrate the Imperial Basin and build up our forces until they are strong enough to eradicate the local Harkonnen presence.\n\nThe Harkonnen are reinforcing their troops by air, so be on your guard. Use the Outpost's radar to detect attacks from unexpected quarters.\n\nBe careful when mining the Spice. Spice mounds grow out of the sand. While a vital source of Spice, Spice mounds can damage or destroy any unit that blunders into them.\n\nGood luck.\n Briefing: Infiltrate the Imperial Basin and build up our forces until they are strong enough to eradicate the local Harkonnen presence.\n\nThe Harkonnen are reinforcing their troops by air, so be on your guard. Use the Outpost's radar to detect attacks from unexpected quarters.\n\nBe careful when mining the Spice. Spice mounds grow out of the sand. While a vital source of Spice, Spice mounds can damage or destroy any unit that blunders into them.\n\nGood luck.\n
BriefingVideo: A_BR02_E.VQA BriefingVideo: A_BR02_E.VQA

View File

@@ -6,7 +6,6 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
IdlingUnits = { }
AttackGroupSize = AttackGroupSize =
{ {
@@ -24,148 +23,30 @@ AttackDelays =
OrdosInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" } OrdosInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" }
OrdosVehicleTypes = { "raider", "raider", "quad" } OrdosVehicleTypes = { "raider", "raider", "quad" }
AttackOnGoing = false
HoldProduction = false
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Map.LobbyOption("difficulty")], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if Attacking then
return
end
Attacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
Attacking = false
HoldProduction = false
end)
end
ProtectHarvester = function(unit)
DefendActor(unit)
Trigger.OnKilled(unit, function() HarvesterKilled = true end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function() InitAIUnits = function()
IdlingUnits = Reinforcements.Reinforce(ordos, InitialOrdosReinforcements, OrdosPaths[2]) IdlingUnits[ordos] = Reinforcements.Reinforce(ordos, InitialOrdosReinforcements, OrdosPaths[2])
IdlingUnits[#IdlingUnits + 1] = OTrooper1 IdlingUnits[ordos][#IdlingUnits + 1] = OTrooper1
IdlingUnits[#IdlingUnits + 1] = OTrooper2 IdlingUnits[ordos][#IdlingUnits + 1] = OTrooper2
IdlingUnits[#IdlingUnits + 1] = ORaider IdlingUnits[ordos][#IdlingUnits + 1] = ORaider
Utils.Do(OrdosBase, function(actor) DefendAndRepairBase(ordos, OrdosBase, 0.75, AttackGroupSize[Difficulty])
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if OBarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(OrdosInfantryTypes) }
ordos.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ProduceVehicles = function()
if OLightFactory.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceVehicles)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(OrdosVehicleTypes) }
ordos.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceVehicles)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end end
ActivateAI = function() ActivateAI = function()
HarvesterKilled[ordos] = true
Trigger.AfterDelay(0, InitAIUnits) Trigger.AfterDelay(0, InitAIUnits)
OConyard.Produce(AtreidesUpgrades[1]) OConyard.Produce(AtreidesUpgrades[1])
OConyard.Produce(AtreidesUpgrades[2]) OConyard.Produce(AtreidesUpgrades[2])
local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local infantryToBuild = function() return { Utils.Random(OrdosInfantryTypes) } end
local vehiclesToBuild = function() return { Utils.Random(OrdosVehicleTypes) } end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
-- Finish the upgrades first before trying to build something -- Finish the upgrades first before trying to build something
Trigger.AfterDelay(DateTime.Seconds(14), function() Trigger.AfterDelay(DateTime.Seconds(14), function()
ProduceInfantry() ProduceUnits(ordos, OBarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
ProduceVehicles() ProduceUnits(ordos, OLightFactory, delay, vehiclesToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end) end)
end end

View File

@@ -6,6 +6,7 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
OrdosBase = { OBarracks, OWindTrap1, OWindTrap2, OWindTrap3, OWindTrap4, OLightFactory, OOutpost, OConyard, ORefinery, OSilo1, OSilo2, OSilo3, OSilo4 } OrdosBase = { OBarracks, OWindTrap1, OWindTrap2, OWindTrap3, OWindTrap4, OLightFactory, OOutpost, OConyard, ORefinery, OSilo1, OSilo2, OSilo3, OSilo4 }
OrdosReinforcements = OrdosReinforcements =
@@ -76,25 +77,6 @@ AtreidesPath = { AtreidesEntry.Location, AtreidesRally.Location }
AtreidesBaseBuildings = { "barracks", "light_factory" } AtreidesBaseBuildings = { "barracks", "light_factory" }
AtreidesUpgrades = { "upgrade.barracks", "upgrade.light" } AtreidesUpgrades = { "upgrade.barracks", "upgrade.light" }
wave = 0
SendOrdos = function()
Trigger.AfterDelay(OrdosAttackDelay[Map.LobbyOption("difficulty")], function()
if player.IsObjectiveCompleted(KillOrdos) then
return
end
wave = wave + 1
if wave > OrdosAttackWaves[Map.LobbyOption("difficulty")] then
return
end
local units = Reinforcements.ReinforceWithTransport(ordos, "carryall.reinforce", OrdosReinforcements[Map.LobbyOption("difficulty")][wave], OrdosPaths[1], { OrdosPaths[1][1] })[2]
Utils.Do(units, IdleHunt)
SendOrdos()
end)
end
MessageCheck = function(index) MessageCheck = function(index)
return #player.GetActorsByType(AtreidesBaseBuildings[index]) > 0 and not player.HasPrerequisites({ AtreidesUpgrades[index] }) return #player.GetActorsByType(AtreidesBaseBuildings[index]) > 0 and not player.HasPrerequisites({ AtreidesUpgrades[index] })
end end
@@ -109,16 +91,16 @@ Tick = function()
player.MarkCompletedObjective(KillOrdos) player.MarkCompletedObjective(KillOrdos)
end end
if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled then if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled[ordos] then
local units = ordos.GetActorsByType("harvester") local units = ordos.GetActorsByType("harvester")
if #units > 0 then if #units > 0 then
HarvesterKilled = false HarvesterKilled[ordos] = false
ProtectHarvester(units[1]) ProtectHarvester(units[1], ordos, AttackGroupSize[Difficulty])
end end
end end
if player.Resources > ToHarvest[Map.LobbyOption("difficulty")] - 1 then if player.Resources > SpiceToHarvest - 1 then
player.MarkCompletedObjective(GatherSpice) player.MarkCompletedObjective(GatherSpice)
end end
@@ -126,14 +108,19 @@ Tick = function()
Media.DisplayMessage("Upgrade barracks and light factory to produce more advanced units.", "Mentat") Media.DisplayMessage("Upgrade barracks and light factory to produce more advanced units.", "Mentat")
end end
UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. ToHarvest[Map.LobbyOption("difficulty")], player.Color) UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. SpiceToHarvest, player.Color)
end end
WorldLoaded = function() WorldLoaded = function()
ordos = Player.GetPlayer("Ordos") ordos = Player.GetPlayer("Ordos")
player = Player.GetPlayer("Atreides") player = Player.GetPlayer("Atreides")
InitObjectives() SpiceToHarvest = ToHarvest[Difficulty]
InitObjectives(player)
KillAtreides = ordos.AddPrimaryObjective("Kill all Atreides units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(SpiceToHarvest) .. " Solaris worth of Spice.")
KillOrdos = player.AddSecondaryObjective("Eliminate all Ordos units and reinforcements\nin the area.")
Camera.Position = AConyard.CenterPosition Camera.Position = AConyard.CenterPosition
@@ -141,38 +128,13 @@ WorldLoaded = function()
Utils.Do(ordos.GetGroundAttackers(), IdleHunt) Utils.Do(ordos.GetGroundAttackers(), IdleHunt)
end) end)
SendOrdos() local path = function() return OrdosPaths[1] end
local waveCondition = function() return player.IsObjectiveCompleted(KillOrdos) end
SendCarryallReinforcements(ordos, 0, OrdosAttackWaves[Difficulty], OrdosAttackDelay[Difficulty], path, OrdosReinforcements[Difficulty], waveCondition)
ActivateAI() ActivateAI()
Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), function() Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), function()
Media.PlaySpeechNotification(player, "Reinforce")
Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", AtreidesReinforcements, AtreidesPath, { AtreidesPath[1] }) Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", AtreidesReinforcements, AtreidesPath, { AtreidesPath[1] })
end) end)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillAtreides = ordos.AddPrimaryObjective("Kill all Atreides units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(ToHarvest[Map.LobbyOption("difficulty")]) .. " Solaris worth of Spice.")
KillOrdos = player.AddSecondaryObjective("Eliminate all Ordos units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: atreides03a.lua, atreides03a-AI.lua Scripts: campaign-global.lua, atreides03a.lua, atreides03a-AI.lua
MissionData: MissionData:
Briefing: Bring the Atreides forces up to combat strength - quickly. Guard against surprise attacks and ensure Spice production.\n\nThe Ordos forces are light but numerous. To combat the Ordos, you have been granted license to produce Quads, which have a greater anti-vehicle capability than Trikes. Upgrade your Light Factories to allow production of these units.\n\nMeet any agression with overwhelming force.\n\nGood luck.\n Briefing: Bring the Atreides forces up to combat strength - quickly. Guard against surprise attacks and ensure Spice production.\n\nThe Ordos forces are light but numerous. To combat the Ordos, you have been granted license to produce Quads, which have a greater anti-vehicle capability than Trikes. Upgrade your Light Factories to allow production of these units.\n\nMeet any agression with overwhelming force.\n\nGood luck.\n
BriefingVideo: A_BR03_E.VQA BriefingVideo: A_BR03_E.VQA

View File

@@ -6,7 +6,6 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
IdlingUnits = { }
AttackGroupSize = AttackGroupSize =
{ {
@@ -24,117 +23,23 @@ AttackDelays =
OrdosInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" } OrdosInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" }
AttackOnGoing = false
HoldProduction = false
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Difficulty], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if Attacking then
return
end
Attacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, IdleHunt)
Trigger.OnAllRemovedFromWorld(units, function()
Attacking = false
HoldProduction = false
end)
end
ProtectHarvester = function(unit)
DefendActor(unit)
Trigger.OnKilled(unit, function() HarvesterKilled = true end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function() InitAIUnits = function()
IdlingUnits = Reinforcements.Reinforce(ordos, InitialOrdosReinforcements, OrdosPaths[2]) IdlingUnits[ordos] = Reinforcements.Reinforce(ordos, InitialOrdosReinforcements, OrdosPaths[2])
DefendAndRepairBase(ordos, OrdosBase, 0.75, AttackGroupSize[Difficulty])
Utils.Do(OrdosBase, function(actor)
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if OBarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Seconds(30), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1)
local toBuild = { Utils.Random(OrdosInfantryTypes) }
ordos.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then
SendAttack()
end
end)
end end
ActivateAI = function() ActivateAI = function()
HarvesterKilled[ordos] = true
Trigger.AfterDelay(0, InitAIUnits) Trigger.AfterDelay(0, InitAIUnits)
OConyard.Produce(AtreidesUpgrades[1]) OConyard.Produce(AtreidesUpgrades[1])
local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local toBuild = function() return { Utils.Random(OrdosInfantryTypes) } end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
-- Finish the upgrades first before trying to build something -- Finish the upgrades first before trying to build something
Trigger.AfterDelay(DateTime.Seconds(14), ProduceInfantry) Trigger.AfterDelay(DateTime.Seconds(14), function()
ProduceUnits(ordos, OBarracks, delay, toBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end)
end end

View File

@@ -6,6 +6,7 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
OrdosBase = { OBarracks, OWindTrap1, OWindTrap2, OOutpost, OConyard, ORefinery, OSilo } OrdosBase = { OBarracks, OWindTrap1, OWindTrap2, OOutpost, OConyard, ORefinery, OSilo }
OrdosReinforcements = OrdosReinforcements =
@@ -76,25 +77,6 @@ AtreidesPath = { AtreidesEntry.Location, AtreidesRally.Location }
AtreidesBaseBuildings = { "barracks", "light_factory" } AtreidesBaseBuildings = { "barracks", "light_factory" }
AtreidesUpgrades = { "upgrade.barracks", "upgrade.light" } AtreidesUpgrades = { "upgrade.barracks", "upgrade.light" }
wave = 0
SendOrdos = function()
Trigger.AfterDelay(OrdosAttackDelay[Difficulty], function()
if player.IsObjectiveCompleted(KillOrdos) then
return
end
wave = wave + 1
if wave > OrdosAttackWaves[Difficulty] then
return
end
local units = Reinforcements.ReinforceWithTransport(ordos, "carryall.reinforce", OrdosReinforcements[Difficulty][wave], OrdosPaths[1], { OrdosPaths[1][1] })[2]
Utils.Do(units, IdleHunt)
SendOrdos()
end)
end
MessageCheck = function(index) MessageCheck = function(index)
return #player.GetActorsByType(AtreidesBaseBuildings[index]) > 0 and not player.HasPrerequisites({ AtreidesUpgrades[index] }) return #player.GetActorsByType(AtreidesBaseBuildings[index]) > 0 and not player.HasPrerequisites({ AtreidesUpgrades[index] })
end end
@@ -109,12 +91,12 @@ Tick = function()
player.MarkCompletedObjective(KillOrdos) player.MarkCompletedObjective(KillOrdos)
end end
if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled then if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled[ordos] then
local units = ordos.GetActorsByType("harvester") local units = ordos.GetActorsByType("harvester")
if #units > 0 then if #units > 0 then
HarvesterKilled = false HarvesterKilled[ordos] = false
ProtectHarvester(units[1]) ProtectHarvester(units[1], ordos, AttackGroupSize[Difficulty])
end end
end end
@@ -133,10 +115,12 @@ WorldLoaded = function()
ordos = Player.GetPlayer("Ordos") ordos = Player.GetPlayer("Ordos")
player = Player.GetPlayer("Atreides") player = Player.GetPlayer("Atreides")
Difficulty = Map.LobbyOption("difficulty")
SpiceToHarvest = ToHarvest[Difficulty] SpiceToHarvest = ToHarvest[Difficulty]
InitObjectives() InitObjectives(player)
KillAtreides = ordos.AddPrimaryObjective("Kill all Atreides units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(SpiceToHarvest) .. " Solaris worth of Spice.")
KillOrdos = player.AddSecondaryObjective("Eliminate all Ordos units and reinforcements\nin the area.")
Camera.Position = AConyard.CenterPosition Camera.Position = AConyard.CenterPosition
@@ -144,38 +128,13 @@ WorldLoaded = function()
Utils.Do(ordos.GetGroundAttackers(), IdleHunt) Utils.Do(ordos.GetGroundAttackers(), IdleHunt)
end) end)
SendOrdos() local path = function() return OrdosPaths[1] end
local waveCondition = function() return player.IsObjectiveCompleted(KillOrdos) end
SendCarryallReinforcements(ordos, 0, OrdosAttackWaves[Difficulty], OrdosAttackDelay[Difficulty], path, OrdosReinforcements[Difficulty], waveCondition)
ActivateAI() ActivateAI()
Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), function() Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), function()
Media.PlaySpeechNotification(player, "Reinforce")
Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", AtreidesReinforcements, AtreidesPath, { AtreidesPath[1] }) Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", AtreidesReinforcements, AtreidesPath, { AtreidesPath[1] })
end) end)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillAtreides = ordos.AddPrimaryObjective("Kill all Atreides units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(SpiceToHarvest) .. " Solaris worth of Spice.")
KillOrdos = player.AddSecondaryObjective("Eliminate all Ordos units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: atreides03b.lua, atreides03b-AI.lua Scripts: campaign-global.lua, atreides03b.lua, atreides03b-AI.lua
MissionData: MissionData:
Briefing: Bring the Atreides forces up to combat strength - quickly. Guard against surprise attacks and ensure Spice production.\n\nThe Ordos forces are light but numerous. To combat the Ordos, you have been granted license to produce Quads, which have a greater anti-vehicle capability than Trikes. Upgrade your Light Factories to allow production of these units.\n\nMeet any agression with overwhelming force.\n\nGood luck.\n Briefing: Bring the Atreides forces up to combat strength - quickly. Guard against surprise attacks and ensure Spice production.\n\nThe Ordos forces are light but numerous. To combat the Ordos, you have been granted license to produce Quads, which have a greater anti-vehicle capability than Trikes. Upgrade your Light Factories to allow production of these units.\n\nMeet any agression with overwhelming force.\n\nGood luck.\n
BriefingVideo: A_BR03_E.VQA BriefingVideo: A_BR03_E.VQA

View File

@@ -6,7 +6,6 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
IdlingUnits = { }
AttackGroupSize = AttackGroupSize =
{ {
@@ -25,37 +24,15 @@ AttackDelays =
HarkonnenInfantryTypes = { "light_inf", "light_inf", "trooper", "trooper", "trooper" } HarkonnenInfantryTypes = { "light_inf", "light_inf", "trooper", "trooper", "trooper" }
HarkonnenTankType = { "combat_tank_h" } HarkonnenTankType = { "combat_tank_h" }
HarvesterKilled = true -- Overwrite the template function because of the message
SendAttack = function(owner, size)
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end if Attacking[owner] then
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Difficulty] do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if Attacking then
return return
end end
Attacking = true Attacking[owner] = true
HoldProduction = true HoldProduction[owner] = true
local units = SetupAttackGroup() local units = SetupAttackGroup(owner, size)
Utils.Do(units, IdleHunt) Utils.Do(units, IdleHunt)
if #units > 0 then if #units > 0 then
@@ -63,107 +40,27 @@ SendAttack = function()
end end
Trigger.OnAllRemovedFromWorld(units, function() Trigger.OnAllRemovedFromWorld(units, function()
Attacking = false Attacking[owner] = false
HoldProduction = false HoldProduction[owner] = false
end)
end
ProtectHarvester = function(unit)
DefendActor(unit)
Trigger.OnKilled(unit, function() HarvesterKilled = true end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if Defending then
return
end
Defending = true
-- Don't try to attack spiceblooms
if attacker and attacker.Type == "spicebloom" then
return
end
local Guards = SetupAttackGroup()
if #Guards <= 0 then
Defending = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() Defending = false end)
end) end)
end end
InitAIUnits = function() InitAIUnits = function()
IdlingUnits = Reinforcements.Reinforce(harkonnen, InitialHarkonnenReinforcements, HarkonnenPaths[1]) IdlingUnits[harkonnen] = Reinforcements.Reinforce(harkonnen, InitialHarkonnenReinforcements, HarkonnenPaths[1])
Utils.Do(HarkonnenBase, function(actor) DefendAndRepairBase(harkonnen, HarkonnenBase, 0.75, AttackGroupSize[Difficulty])
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Owner == harkonnen and building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if HarkonnenBarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Seconds(30), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1)
local toBuild = { Utils.Random(HarkonnenInfantryTypes) }
harkonnen.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then
SendAttack()
end
end)
end
ProduceTanks = function()
if HarkonnenHeavyFact.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Seconds(30), ProduceTanks)
return
end
local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1)
harkonnen.Build(HarkonnenTankType, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceTanks)
if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then
SendAttack()
end
end)
end end
ActivateAI = function() ActivateAI = function()
HarvesterKilled[harkonnen] = true
InitAIUnits() InitAIUnits()
FremenProduction() FremenProduction()
ProduceInfantry() local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
ProduceTanks() local infantryToBuild = function() return { Utils.Random(HarkonnenInfantryTypes) } end
local tanksToBuild = function() return HarkonnenTankType end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
ProduceUnits(harkonnen, HarkonnenBarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
ProduceUnits(harkonnen, HarkonnenHeavyFact, delay, tanksToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end end

View File

@@ -6,6 +6,7 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
HarkonnenBase = { HarkonnenOutpost, HarkonnenRefinery, HarkonnenHeavyFact, HarkonnenTurret1, HarkonnenTurret2, HarkonnenBarracks, HarkonnenSilo1, HarkonnenSilo2, HarkonnenWindTrap1, HarkonnenWindTrap2, HarkonnenWindTrap3, HarkonnenWindTrap4, HarkonnenWindTrap5 } HarkonnenBase = { HarkonnenOutpost, HarkonnenRefinery, HarkonnenHeavyFact, HarkonnenTurret1, HarkonnenTurret2, HarkonnenBarracks, HarkonnenSilo1, HarkonnenSilo2, HarkonnenWindTrap1, HarkonnenWindTrap2, HarkonnenWindTrap3, HarkonnenWindTrap4, HarkonnenWindTrap5 }
HarkonnenReinforcements = HarkonnenReinforcements =
@@ -89,29 +90,6 @@ IntegrityLevel =
hard = 100 hard = 100
} }
wave = 0
SendHarkonnen = function()
Trigger.AfterDelay(HarkonnenAttackDelay[Difficulty], function()
if player.IsObjectiveCompleted(KillHarkonnen) then
return
end
wave = wave + 1
if wave > HarkonnenAttackWaves[Difficulty] then
return
end
local entryPath = Utils.Random(HarkonnenPaths)
local units = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", HarkonnenReinforcements[Difficulty][wave], entryPath, { entryPath[1] })[2]
Utils.Do(units, function(unit)
unit.AttackMove(HarkonnenAttackLocation)
IdleHunt(unit)
end)
SendHarkonnen()
end)
end
FremenProduction = function() FremenProduction = function()
if Sietch.IsDead then if Sietch.IsDead then
return return
@@ -119,7 +97,7 @@ FremenProduction = function()
local delay = Utils.RandomInteger(FremenInterval[Difficulty][1], FremenInterval[Difficulty][2] + 1) local delay = Utils.RandomInteger(FremenInterval[Difficulty][1], FremenInterval[Difficulty][2] + 1)
fremen.Build({ "nsfremen" }, function() fremen.Build({ "nsfremen" }, function()
Trigger.AfterDelay(delay, ProduceInfantry) Trigger.AfterDelay(delay, FremenProduction)
end) end)
end end
@@ -136,12 +114,12 @@ Tick = function()
player.MarkCompletedObjective(KeepIntegrity) player.MarkCompletedObjective(KeepIntegrity)
end end
if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled then if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled[harkonnen] then
local units = harkonnen.GetActorsByType("harvester") local units = harkonnen.GetActorsByType("harvester")
if #units > 0 then if #units > 0 then
HarvesterKilled = false HarvesterKilled[harkonnen] = false
ProtectHarvester(units[1]) ProtectHarvester(units[1], harkonnen, AttackGroupSize[Difficulty])
end end
end end
@@ -161,9 +139,11 @@ WorldLoaded = function()
fremen = Player.GetPlayer("Fremen") fremen = Player.GetPlayer("Fremen")
player = Player.GetPlayer("Atreides") player = Player.GetPlayer("Atreides")
Difficulty = Map.LobbyOption("difficulty") InitObjectives(player)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
InitObjectives() ProtectFremen = player.AddPrimaryObjective("Protect the Fremen Sietch.")
KillHarkonnen = player.AddPrimaryObjective("Destroy the Harkonnen.")
KeepIntegrity = player.AddSecondaryObjective("Keep the Sietch " .. IntegrityLevel[Difficulty] .. "% intact!")
Camera.Position = AConyard.CenterPosition Camera.Position = AConyard.CenterPosition
HarkonnenAttackLocation = AConyard.Location HarkonnenAttackLocation = AConyard.Location
@@ -196,7 +176,14 @@ WorldLoaded = function()
end end
end) end)
SendHarkonnen() local path = function() return Utils.Random(HarkonnenPaths) end
local waveCondition = function() return player.IsObjectiveCompleted(KillHarkonnen) end
local huntFunction = function(unit)
unit.AttackMove(HarkonnenAttackLocation)
IdleHunt(unit)
end
SendCarryallReinforcements(harkonnen, 0, HarkonnenAttackWaves[Difficulty], HarkonnenAttackDelay[Difficulty], path, HarkonnenReinforcements[Difficulty], waveCondition, huntFunction)
Actor.Create("upgrade.barracks", true, { Owner = harkonnen }) Actor.Create("upgrade.barracks", true, { Owner = harkonnen })
Trigger.AfterDelay(0, ActivateAI) Trigger.AfterDelay(0, ActivateAI)
@@ -217,32 +204,3 @@ WorldLoaded = function()
end end
end) end)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
ProtectFremen = player.AddPrimaryObjective("Protect the Fremen Sietch.")
KillHarkonnen = player.AddPrimaryObjective("Destroy the Harkonnen.")
KeepIntegrity = player.AddSecondaryObjective("Keep the Sietch " .. IntegrityLevel[Difficulty] .. "% intact!")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: atreides04.lua, atreides04-AI.lua Scripts: campaign-global.lua, atreides04.lua, atreides04-AI.lua
MissionData: MissionData:
Briefing: Our scouts have discovered the hidden Fremen base. The Harkonnen blockade of the Fremen must be broken.\n\nPowerful Harkonnen forces to the South are massing for an assault on the Fremen. Heavy forces have been allocated to you to smash through the Harkonnen fortifications and come to the aid of the Fremen.\n\nGood luck.\n Briefing: Our scouts have discovered the hidden Fremen base. The Harkonnen blockade of the Fremen must be broken.\n\nPowerful Harkonnen forces to the South are massing for an assault on the Fremen. Heavy forces have been allocated to you to smash through the Harkonnen fortifications and come to the aid of the Fremen.\n\nGood luck.\n
BriefingVideo: A_BR04_E.VQA BriefingVideo: A_BR04_E.VQA

View File

@@ -1,4 +1,11 @@
IdlingUnits = { } --[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
AttackGroupSize = AttackGroupSize =
{ {
@@ -18,114 +25,26 @@ HarkonnenInfantryTypes = { "light_inf", "light_inf", "trooper", "trooper", "troo
HarkonnenVehicleTypes = { "trike", "trike", "trike", "quad", "quad" } HarkonnenVehicleTypes = { "trike", "trike", "trike", "quad", "quad" }
HarkonnenTankType = { "combat_tank_h" } HarkonnenTankType = { "combat_tank_h" }
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Difficulty] do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if Attacking then
return
end
Attacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
unit.AttackMove(HarkonnenAttackLocation)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
Attacking = false
HoldProduction = false
end)
end
ProtectHarvester = function(unit)
DefendActor(unit)
Trigger.OnKilled(unit, function() HarvesterKilled = true end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if Defending then
return
end
Defending = true
-- Don't try to attack spiceblooms
if attacker and attacker.Type == "spicebloom" then
return
end
local Guards = SetupAttackGroup()
if #Guards <= 0 then
Defending = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() Defending = false end)
end)
end
RepairBuilding = function(owner, actor)
Trigger.OnDamaged(actor, function(building)
if building.Owner == owner and building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end
InitAIUnits = function() InitAIUnits = function()
IdlingUnits = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", InitialHarkonnenReinforcements, HarkonnenPaths[1], { HarkonnenPaths[1][1] })[2] IdlingUnits[harkonnen] = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", InitialHarkonnenReinforcements, HarkonnenPaths[1], { HarkonnenPaths[1][1] })[2]
Utils.Do(HarkonnenBase, function(actor) DefendAndRepairBase(harkonnen, HarkonnenBase, 0.75, AttackGroupSize[Difficulty])
DefendActor(actor) DefendActor(HarkonnenBarracks, harkonnen, AttackGroupSize[Difficulty])
RepairBuilding(harkonnen, actor) RepairBuilding(harkonnen, HarkonnenBarracks, 0.75)
end)
DefendActor(HarkonnenBarracks)
RepairBuilding(harkonnen, HarkonnenBarracks)
Utils.Do(SmugglerBase, function(actor) Utils.Do(SmugglerBase, function(actor)
RepairBuilding(smuggler, actor) RepairBuilding(smuggler, actor, 0.75)
end) end)
RepairBuilding(smuggler, Starport) RepairBuilding(smuggler, Starport, 0.75)
end end
-- Not using ProduceUnits because of the custom StopInfantryProduction condition
ProduceInfantry = function() ProduceInfantry = function()
if StopInfantryProduction or HarkonnenBarracks.IsDead or HarkonnenBarracks.Owner ~= harkonnen then if StopInfantryProduction or HarkonnenBarracks.IsDead or HarkonnenBarracks.Owner ~= harkonnen then
return return
end end
if HoldProduction then if HoldProduction[harkonnen] then
Trigger.AfterDelay(DateTime.Seconds(30), ProduceInfantry) Trigger.AfterDelay(DateTime.Seconds(30), ProduceInfantry)
return return
end end
@@ -133,63 +52,26 @@ ProduceInfantry = function()
local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1)
local toBuild = { Utils.Random(HarkonnenInfantryTypes) } local toBuild = { Utils.Random(HarkonnenInfantryTypes) }
harkonnen.Build(toBuild, function(unit) harkonnen.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1] IdlingUnits[harkonnen][#IdlingUnits[harkonnen] + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry) Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then if #IdlingUnits[harkonnen] >= (AttackGroupSize[Difficulty] * 2.5) then
SendAttack() SendAttack(harkonnen, AttackGroupSize[Difficulty])
end
end)
end
ProduceVehicles = function()
if HarkonnenLightFactory.IsDead or HarkonnenLightFactory.Owner ~= harkonnen then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Seconds(30), ProduceVehicles)
return
end
local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1)
local toBuild = { Utils.Random(HarkonnenVehicleTypes) }
harkonnen.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceVehicles)
if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then
SendAttack()
end
end)
end
ProduceTanks = function()
if HarkonnenHeavyFactory.IsDead or HarkonnenHeavyFactory.Owner ~= harkonnen then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Seconds(30), ProduceTanks)
return
end
local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1)
harkonnen.Build(HarkonnenTankType, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceTanks)
if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then
SendAttack()
end end
end) end)
end end
ActivateAI = function() ActivateAI = function()
harkonnen.Cash = 15000 harkonnen.Cash = 15000
HarvesterKilled[harkonnen] = true
InitAIUnits() InitAIUnits()
local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local vehilcesToBuild = function() return { Utils.Random(HarkonnenVehicleTypes) } end
local tanksToBuild = function() return HarkonnenTankType end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
ProduceInfantry() ProduceInfantry()
ProduceVehicles() ProduceUnits(harkonnen, HarkonnenLightFactory, delay, vehilcesToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
ProduceTanks() ProduceUnits(harkonnen, HarkonnenHeavyFactory, delay, tanksToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end end

View File

@@ -1,3 +1,12 @@
--[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
HarkonnenBase = { HarkonnenConstructionYard, HarkonnenWindTrap1, HarkonnenWindTrap2, HarkonnenWindTrap3, HarkonnenWindTrap4, HarkonnenWindTrap5, HarkonnenWindTrap6, HarkonnenWindTrap7, HarkonnenWindTrap8, HarkonnenSilo1, HarkonnenSilo2, HarkonnenSilo3, HarkonnenSilo4, HarkonnenGunTurret1, HarkonnenGunTurret2, HarkonnenGunTurret3, HarkonnenGunTurret4, HarkonnenGunTurret5, HarkonnenGunTurret6, HarkonnenGunTurret7, HarkonnenHeavyFactory, HarkonnenRefinery, HarkonnenOutpost, HarkonnenLightFactory } HarkonnenBase = { HarkonnenConstructionYard, HarkonnenWindTrap1, HarkonnenWindTrap2, HarkonnenWindTrap3, HarkonnenWindTrap4, HarkonnenWindTrap5, HarkonnenWindTrap6, HarkonnenWindTrap7, HarkonnenWindTrap8, HarkonnenSilo1, HarkonnenSilo2, HarkonnenSilo3, HarkonnenSilo4, HarkonnenGunTurret1, HarkonnenGunTurret2, HarkonnenGunTurret3, HarkonnenGunTurret4, HarkonnenGunTurret5, HarkonnenGunTurret6, HarkonnenGunTurret7, HarkonnenHeavyFactory, HarkonnenRefinery, HarkonnenOutpost, HarkonnenLightFactory }
SmugglerBase = { SmugglerWindTrap1, SmugglerWindTrap2 } SmugglerBase = { SmugglerWindTrap1, SmugglerWindTrap2 }
@@ -251,12 +260,12 @@ Tick = function()
player.MarkCompletedObjective(KillSmuggler) player.MarkCompletedObjective(KillSmuggler)
end end
if HarvesterKilled and DateTime.GameTime % DateTime.Seconds(30) then if HarvesterKilled[harkonnen] and DateTime.GameTime % DateTime.Seconds(30) then
local units = harkonnen.GetActorsByType("harvester") local units = harkonnen.GetActorsByType("harvester")
if #units > 0 then if #units > 0 then
HarvesterKilled = false HarvesterKilled[harkonnen] = false
ProtectHarvester(units[1]) ProtectHarvester(units[1], harkonnen, AttackGroupSize[Difficulty])
end end
end end
@@ -278,10 +287,13 @@ WorldLoaded = function()
mercenary = Player.GetPlayer("Mercenaries") mercenary = Player.GetPlayer("Mercenaries")
player = Player.GetPlayer("Atreides") player = Player.GetPlayer("Atreides")
Difficulty = Map.LobbyOption("difficulty")
InfantryReinforcements = Difficulty ~= "easy" InfantryReinforcements = Difficulty ~= "easy"
InitObjectives() InitObjectives(player)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
CaptureBarracks = player.AddPrimaryObjective("Capture the Barracks at Sietch Tabr.")
KillHarkonnen = player.AddSecondaryObjective("Annihilate all other Harkonnen units\nand reinforcements.")
CaptureStarport = player.AddSecondaryObjective("Capture the Smuggler Starport and\nconfiscate the contraband.")
Camera.Position = ARefinery.CenterPosition Camera.Position = ARefinery.CenterPosition
HarkonnenAttackLocation = AtreidesRally.Location HarkonnenAttackLocation = AtreidesRally.Location
@@ -412,32 +424,3 @@ WorldLoaded = function()
end end
end) end)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Atreides units.")
CaptureBarracks = player.AddPrimaryObjective("Capture the Barracks at Sietch Tabr.")
KillHarkonnen = player.AddSecondaryObjective("Annihilate all other Harkonnen units\nand reinforcements.")
CaptureStarport = player.AddSecondaryObjective("Capture the Smuggler Starport and\nconfiscate the contraband.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: atreides05.lua, atreides05-AI.lua Scripts: campaign-global.lua, atreides05.lua, atreides05-AI.lua
MissionData: MissionData:
Briefing: According to our spies, the Fremen are being held at the far Northwest corner of Sietch Tabr. Push your way through the Harkonnen ranks to rescue the hostages.\n\nScout the terrain before you launch the main assault. Our Engineers must reach the Barracks and capture it intact. The rest of the base can be razed to the ground.\n\nAdditionally, there are rumors of an illegal Smuggling operation in the area. A large shipment of contraband is expected at the Smuggler's Starport. If you can the Starport before the contraband arrives, you will be able to confiscate it for the Atreides war effort.\n\nBe warned, the Smugglers have Mercenary allies who may assist them if you interfere.\n\nGood luck.\n Briefing: According to our spies, the Fremen are being held at the far Northwest corner of Sietch Tabr. Push your way through the Harkonnen ranks to rescue the hostages.\n\nScout the terrain before you launch the main assault. Our Engineers must reach the Barracks and capture it intact. The rest of the base can be razed to the ground.\n\nAdditionally, there are rumors of an illegal Smuggling operation in the area. A large shipment of contraband is expected at the Smuggler's Starport. If you can the Starport before the contraband arrives, you will be able to confiscate it for the Atreides war effort.\n\nBe warned, the Smugglers have Mercenary allies who may assist them if you interfere.\n\nGood luck.\n
BriefingVideo: A_BR05_E.VQA BriefingVideo: A_BR05_E.VQA

View File

@@ -7,40 +7,46 @@
information, see COPYING. information, see COPYING.
]] ]]
AtreidesReinforcements = { } AtreidesReinforcements =
AtreidesReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "light_inf" } { "light_inf", "light_inf" }
} },
AtreidesReinforcements["normal"] = normal =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
AtreidesReinforcements["hard"] = hard =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
AtreidesEntryWaypoints = { AtreidesWaypoint1.Location, AtreidesWaypoint2.Location, AtreidesWaypoint3.Location, AtreidesWaypoint4.Location } AtreidesEntryWaypoints = { AtreidesWaypoint1.Location, AtreidesWaypoint2.Location, AtreidesWaypoint3.Location, AtreidesWaypoint4.Location }
AtreidesAttackDelay = DateTime.Seconds(30) AtreidesAttackDelay = DateTime.Seconds(30)
AtreidesAttackWaves = { } AtreidesAttackWaves =
AtreidesAttackWaves["easy"] = 1 {
AtreidesAttackWaves["normal"] = 5 easy = 1,
AtreidesAttackWaves["hard"] = 12 normal = 5,
hard = 12
}
ToHarvest = { } ToHarvest =
ToHarvest["easy"] = 2500 {
ToHarvest["normal"] = 3000 easy = 2500,
ToHarvest["hard"] = 3500 normal = 3000,
hard = 3500
}
HarkonnenReinforcements = { "light_inf", "light_inf", "light_inf", "trike" } HarkonnenReinforcements = { "light_inf", "light_inf", "light_inf", "trike" }
HarkonnenEntryPath = { HarkonnenWaypoint.Location, HarkonnenRally.Location } HarkonnenEntryPath = { HarkonnenWaypoint.Location, HarkonnenRally.Location }
@@ -53,19 +59,12 @@ Messages =
"Build a Silo to store additional Spice." "Build a Silo to store additional Spice."
} }
IdleHunt = function(actor)
if not actor.IsDead then
Trigger.OnIdle(actor, actor.Hunt)
end
end
Tick = function() Tick = function()
if AtreidesArrived and atreides.HasNoRequiredUnits() then if AtreidesArrived and atreides.HasNoRequiredUnits() then
player.MarkCompletedObjective(KillAtreides) player.MarkCompletedObjective(KillAtreides)
end end
if player.Resources > ToHarvest[Map.LobbyOption("difficulty")] - 1 then if player.Resources > SpiceToHarvest - 1 then
player.MarkCompletedObjective(GatherSpice) player.MarkCompletedObjective(GatherSpice)
end end
@@ -86,14 +85,19 @@ Tick = function()
Media.DisplayMessage(Messages[4], "Mentat") Media.DisplayMessage(Messages[4], "Mentat")
end end
UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. ToHarvest[Map.LobbyOption("difficulty")], player.Color) UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. SpiceToHarvest, player.Color)
end end
WorldLoaded = function() WorldLoaded = function()
player = Player.GetPlayer("Harkonnen") player = Player.GetPlayer("Harkonnen")
atreides = Player.GetPlayer("Atreides") atreides = Player.GetPlayer("Atreides")
InitObjectives() SpiceToHarvest = ToHarvest[Difficulty]
InitObjectives(player)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(SpiceToHarvest) .. " Solaris worth of Spice.")
KillAtreides = player.AddSecondaryObjective("Eliminate all Atreides units and reinforcements\nin the area.")
Trigger.OnRemovedFromWorld(HarkonnenConyard, function() Trigger.OnRemovedFromWorld(HarkonnenConyard, function()
local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end) local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end)
@@ -114,12 +118,12 @@ WorldLoaded = function()
Reinforcements.Reinforce(player, HarkonnenReinforcements, HarkonnenEntryPath) Reinforcements.Reinforce(player, HarkonnenReinforcements, HarkonnenEntryPath)
end) end)
WavesLeft = AtreidesAttackWaves[Map.LobbyOption("difficulty")] WavesLeft = AtreidesAttackWaves[Difficulty]
SendReinforcements() SendReinforcements()
end end
SendReinforcements = function() SendReinforcements = function()
local units = AtreidesReinforcements[Map.LobbyOption("difficulty")] local units = AtreidesReinforcements[Difficulty]
local delay = Utils.RandomInteger(AtreidesAttackDelay - DateTime.Seconds(2), AtreidesAttackDelay) local delay = Utils.RandomInteger(AtreidesAttackDelay - DateTime.Seconds(2), AtreidesAttackDelay)
AtreidesAttackDelay = AtreidesAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1) AtreidesAttackDelay = AtreidesAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1)
if AtreidesAttackDelay < 0 then AtreidesAttackDelay = 0 end if AtreidesAttackDelay < 0 then AtreidesAttackDelay = 0 end
@@ -135,31 +139,3 @@ SendReinforcements = function()
end end
end) end)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(ToHarvest[Map.LobbyOption("difficulty")]) .. " Solaris worth of Spice.")
KillAtreides = player.AddSecondaryObjective("Eliminate all Atreides units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: harkonnen01a.lua Scripts: campaign-global.lua, harkonnen01a.lua
MissionData: MissionData:
Briefing: Mine the Spice from the Imperial Basin, before the Atreides try to seize the area. Execute anyone who tries to stop you.\n\nBuild Silos to store the Spice. Remember to place buildings on concrete foundations to prevent erosion and gradual decline. To build without concrete would be inefficient. Inefficiency will not be tolerated.\n Briefing: Mine the Spice from the Imperial Basin, before the Atreides try to seize the area. Execute anyone who tries to stop you.\n\nBuild Silos to store the Spice. Remember to place buildings on concrete foundations to prevent erosion and gradual decline. To build without concrete would be inefficient. Inefficiency will not be tolerated.\n
BriefingVideo: H_BR01_E.VQA BriefingVideo: H_BR01_E.VQA

View File

@@ -7,40 +7,46 @@
information, see COPYING. information, see COPYING.
]] ]]
AtreidesReinforcements = { } AtreidesReinforcements =
AtreidesReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "light_inf" } { "light_inf", "light_inf" }
} },
AtreidesReinforcements["normal"] = normal =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
AtreidesReinforcements["hard"] = hard =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
AtreidesEntryWaypoints = { AtreidesWaypoint1.Location, AtreidesWaypoint2.Location, AtreidesWaypoint3.Location, AtreidesWaypoint4.Location } AtreidesEntryWaypoints = { AtreidesWaypoint1.Location, AtreidesWaypoint2.Location, AtreidesWaypoint3.Location, AtreidesWaypoint4.Location }
AtreidesAttackDelay = DateTime.Seconds(30) AtreidesAttackDelay = DateTime.Seconds(30)
AtreidesAttackWaves = { } AtreidesAttackWaves =
AtreidesAttackWaves["easy"] = 1 {
AtreidesAttackWaves["normal"] = 5 easy = 1,
AtreidesAttackWaves["hard"] = 12 normal = 5,
hard = 12
}
ToHarvest = { } ToHarvest =
ToHarvest["easy"] = 2500 {
ToHarvest["normal"] = 3000 easy = 2500,
ToHarvest["hard"] = 3500 normal = 3000,
hard = 3500
}
HarkonnenReinforcements = { "light_inf", "light_inf", "light_inf", "trike" } HarkonnenReinforcements = { "light_inf", "light_inf", "light_inf", "trike" }
HarkonnenEntryPath = { HarkonnenWaypoint.Location, HarkonnenRally.Location } HarkonnenEntryPath = { HarkonnenWaypoint.Location, HarkonnenRally.Location }
@@ -53,19 +59,12 @@ Messages =
"Build a Silo to store additional Spice." "Build a Silo to store additional Spice."
} }
IdleHunt = function(actor)
if not actor.IsDead then
Trigger.OnIdle(actor, actor.Hunt)
end
end
Tick = function() Tick = function()
if AtreidesArrived and atreides.HasNoRequiredUnits() then if AtreidesArrived and atreides.HasNoRequiredUnits() then
player.MarkCompletedObjective(KillAtreides) player.MarkCompletedObjective(KillAtreides)
end end
if player.Resources > ToHarvest[Map.LobbyOption("difficulty")] - 1 then if player.Resources > SpiceToHarvest - 1 then
player.MarkCompletedObjective(GatherSpice) player.MarkCompletedObjective(GatherSpice)
end end
@@ -86,14 +85,19 @@ Tick = function()
Media.DisplayMessage(Messages[4], "Mentat") Media.DisplayMessage(Messages[4], "Mentat")
end end
UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. ToHarvest[Map.LobbyOption("difficulty")], player.Color) UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. SpiceToHarvest, player.Color)
end end
WorldLoaded = function() WorldLoaded = function()
player = Player.GetPlayer("Harkonnen") player = Player.GetPlayer("Harkonnen")
atreides = Player.GetPlayer("Atreides") atreides = Player.GetPlayer("Atreides")
InitObjectives() SpiceToHarvest = ToHarvest[Difficulty]
InitObjectives(player)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(SpiceToHarvest) .. " Solaris worth of Spice.")
KillAtreides = player.AddSecondaryObjective("Eliminate all Atreides units and reinforcements\nin the area.")
Trigger.OnRemovedFromWorld(HarkonnenConyard, function() Trigger.OnRemovedFromWorld(HarkonnenConyard, function()
local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end) local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end)
@@ -114,12 +118,12 @@ WorldLoaded = function()
Reinforcements.Reinforce(player, HarkonnenReinforcements, HarkonnenEntryPath) Reinforcements.Reinforce(player, HarkonnenReinforcements, HarkonnenEntryPath)
end) end)
WavesLeft = AtreidesAttackWaves[Map.LobbyOption("difficulty")] WavesLeft = AtreidesAttackWaves[Difficulty]
SendReinforcements() SendReinforcements()
end end
SendReinforcements = function() SendReinforcements = function()
local units = AtreidesReinforcements[Map.LobbyOption("difficulty")] local units = AtreidesReinforcements[Difficulty]
local delay = Utils.RandomInteger(AtreidesAttackDelay - DateTime.Seconds(2), AtreidesAttackDelay) local delay = Utils.RandomInteger(AtreidesAttackDelay - DateTime.Seconds(2), AtreidesAttackDelay)
AtreidesAttackDelay = AtreidesAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1) AtreidesAttackDelay = AtreidesAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1)
if AtreidesAttackDelay < 0 then AtreidesAttackDelay = 0 end if AtreidesAttackDelay < 0 then AtreidesAttackDelay = 0 end
@@ -135,31 +139,3 @@ SendReinforcements = function()
end end
end) end)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(ToHarvest[Map.LobbyOption("difficulty")]) .. " Solaris worth of Spice.")
KillAtreides = player.AddSecondaryObjective("Eliminate all Atreides units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: harkonnen01b.lua Scripts: campaign-global.lua, harkonnen01b.lua
MissionData: MissionData:
Briefing: Mine the Spice from the Imperial Basin, before the Atreides try to seize the area. Execute anyone who tries to stop you.\n\nBuild Silos to store the Spice. Remember to place buildings on concrete foundations to prevent erosion and gradual decline. To build without concrete would be inefficient. Inefficiency will not be tolerated.\n Briefing: Mine the Spice from the Imperial Basin, before the Atreides try to seize the area. Execute anyone who tries to stop you.\n\nBuild Silos to store the Spice. Remember to place buildings on concrete foundations to prevent erosion and gradual decline. To build without concrete would be inefficient. Inefficiency will not be tolerated.\n
BriefingVideo: H_BR01_E.VQA BriefingVideo: H_BR01_E.VQA

View File

@@ -6,7 +6,6 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
IdlingUnits = { }
AttackGroupSize = AttackGroupSize =
{ {
@@ -14,6 +13,7 @@ AttackGroupSize =
normal = 8, normal = 8,
hard = 10 hard = 10
} }
AttackDelays = AttackDelays =
{ {
easy = { DateTime.Seconds(4), DateTime.Seconds(9) }, easy = { DateTime.Seconds(4), DateTime.Seconds(9) },
@@ -23,108 +23,12 @@ AttackDelays =
AtreidesInfantryTypes = { "light_inf" } AtreidesInfantryTypes = { "light_inf" }
AttackOnGoing = false
HoldProduction = false
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Map.LobbyOption("difficulty")], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if Attacking then
return
end
Attacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
Attacking = false
HoldProduction = false
end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function()
Utils.Do(AtreidesBase, function(actor)
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if ABarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(AtreidesInfantryTypes) }
atreides.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ActivateAI = function() ActivateAI = function()
InitAIUnits() IdlingUnits[atreides] = { }
ProduceInfantry() local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local toBuild = function() return AtreidesInfantryTypes end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
DefendAndRepairBase(atreides, AtreidesBase, 0.75, AttackGroupSize[Difficulty])
ProduceUnits(atreides, ABarracks, delay, toBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end end

View File

@@ -9,26 +9,27 @@
AtreidesBase = { AConyard, APower1, APower2, ABarracks, AOutpost } AtreidesBase = { AConyard, APower1, APower2, ABarracks, AOutpost }
AtreidesReinforcements = { } AtreidesReinforcements =
AtreidesReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" } { "light_inf", "light_inf", "light_inf", "trike", "trike" }
} },
AtreidesReinforcements["normal"] = normal =
{ {
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" }, { "light_inf", "light_inf", "light_inf", "trike", "trike" },
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
AtreidesReinforcements["hard"] = hard =
{ {
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
@@ -38,6 +39,7 @@ AtreidesReinforcements["hard"] =
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
AtreidesAttackPaths = AtreidesAttackPaths =
@@ -48,35 +50,19 @@ AtreidesAttackPaths =
{ AtreidesEntry2.Location, AtreidesRally3.Location } { AtreidesEntry2.Location, AtreidesRally3.Location }
} }
AtreidesAttackDelay = { } AtreidesAttackDelay =
AtreidesAttackDelay["easy"] = DateTime.Minutes(5) {
AtreidesAttackDelay["normal"] = DateTime.Minutes(2) + DateTime.Seconds(40) easy = DateTime.Minutes(5),
AtreidesAttackDelay["hard"] = DateTime.Minutes(1) + DateTime.Seconds(20) normal = DateTime.Minutes(2) + DateTime.Seconds(40),
hard = DateTime.Minutes(1) + DateTime.Seconds(20)
}
AtreidesAttackWaves = { } AtreidesAttackWaves =
AtreidesAttackWaves["easy"] = 3 {
AtreidesAttackWaves["normal"] = 6 easy = 3,
AtreidesAttackWaves["hard"] = 9 normal = 6,
hard = 9
wave = 0 }
SendAtreides = function()
Trigger.AfterDelay(AtreidesAttackDelay[Map.LobbyOption("difficulty")], function()
wave = wave + 1
if wave > AtreidesAttackWaves[Map.LobbyOption("difficulty")] then
return
end
local path = Utils.Random(AtreidesAttackPaths)
local units = Reinforcements.ReinforceWithTransport(atreides, "carryall.reinforce", AtreidesReinforcements[Map.LobbyOption("difficulty")][wave], path, { path[1] })[2]
Utils.Do(units, IdleHunt)
SendAtreides()
end)
end
IdleHunt = function(unit)
Trigger.OnIdle(unit, unit.Hunt)
end
Tick = function() Tick = function()
if player.HasNoRequiredUnits() then if player.HasNoRequiredUnits() then
@@ -93,7 +79,9 @@ WorldLoaded = function()
atreides = Player.GetPlayer("Atreides") atreides = Player.GetPlayer("Atreides")
player = Player.GetPlayer("Harkonnen") player = Player.GetPlayer("Harkonnen")
InitObjectives() InitObjectives(player)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
KillAtreides = player.AddPrimaryObjective("Destroy all Atreides forces.")
Camera.Position = HConyard.CenterPosition Camera.Position = HConyard.CenterPosition
@@ -101,33 +89,7 @@ WorldLoaded = function()
Utils.Do(atreides.GetGroundAttackers(), IdleHunt) Utils.Do(atreides.GetGroundAttackers(), IdleHunt)
end) end)
SendAtreides() local path = function() return Utils.Random(AtreidesAttackPaths) end
SendCarryallReinforcements(atreides, 0, AtreidesAttackWaves[Difficulty], AtreidesAttackDelay[Difficulty], path, AtreidesReinforcements[Difficulty])
Trigger.AfterDelay(0, ActivateAI) Trigger.AfterDelay(0, ActivateAI)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
KillAtreides = player.AddPrimaryObjective("Destroy all Atreides forces.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: harkonnen02a.lua, harkonnen02a-AI.lua Scripts: campaign-global.lua, harkonnen02a.lua, harkonnen02a-AI.lua
MissionData: MissionData:
Briefing: Strengthen your forces at our mining camp in the Imperial Basin. We must punish the Atreides for their insolence. Teach them the consequences of opposing House Harkonnen.\n\nOur radar will help you find your targets.\n Briefing: Strengthen your forces at our mining camp in the Imperial Basin. We must punish the Atreides for their insolence. Teach them the consequences of opposing House Harkonnen.\n\nOur radar will help you find your targets.\n
BriefingVideo: H_BR02_E.VQA BriefingVideo: H_BR02_E.VQA

View File

@@ -6,7 +6,6 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
IdlingUnits = { }
AttackGroupSize = AttackGroupSize =
{ {
@@ -14,6 +13,7 @@ AttackGroupSize =
normal = 8, normal = 8,
hard = 10 hard = 10
} }
AttackDelays = AttackDelays =
{ {
easy = { DateTime.Seconds(4), DateTime.Seconds(9) }, easy = { DateTime.Seconds(4), DateTime.Seconds(9) },
@@ -24,131 +24,14 @@ AttackDelays =
AtreidesInfantryTypes = { "light_inf" } AtreidesInfantryTypes = { "light_inf" }
AtreidesVehicleTypes = { "trike" } AtreidesVehicleTypes = { "trike" }
AttackOnGoing = false
HoldProduction = false
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Map.LobbyOption("difficulty")], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if Attacking then
return
end
Attacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
Attacking = false
HoldProduction = false
end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function()
Utils.Do(AtreidesBase, function(actor)
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if ABarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(AtreidesInfantryTypes) }
atreides.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ProduceVehicles = function()
if ALightFactory.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceVehicles)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(AtreidesVehicleTypes) }
atreides.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceVehicles)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ActivateAI = function() ActivateAI = function()
InitAIUnits() IdlingUnits[atreides] = { }
ProduceInfantry() local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
ProduceVehicles() local infantryToBuild = function() return AtreidesInfantryTypes end
local vehilcesToBuild = function() return AtreidesVehicleTypes end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
DefendAndRepairBase(atreides, AtreidesBase, 0.75, AttackGroupSize[Difficulty])
ProduceUnits(atreides, ABarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
ProduceUnits(atreides, ALightFactory, delay, vehilcesToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end end

View File

@@ -9,26 +9,27 @@
AtreidesBase = { AConyard, APower1, APower2, ABarracks, ALightFactory } AtreidesBase = { AConyard, APower1, APower2, ABarracks, ALightFactory }
AtreidesReinforcements = { } AtreidesReinforcements =
AtreidesReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" } { "light_inf", "light_inf", "light_inf", "trike", "trike" }
} },
AtreidesReinforcements["normal"] = normal =
{ {
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" }, { "light_inf", "light_inf", "light_inf", "trike", "trike" },
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
AtreidesReinforcements["hard"] = hard =
{ {
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
@@ -38,6 +39,7 @@ AtreidesReinforcements["hard"] =
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
AtreidesAttackPaths = AtreidesAttackPaths =
@@ -48,35 +50,19 @@ AtreidesAttackPaths =
{ AtreidesEntry2.Location, AtreidesRally3.Location } { AtreidesEntry2.Location, AtreidesRally3.Location }
} }
AtreidesAttackDelay = { } AtreidesAttackDelay =
AtreidesAttackDelay["easy"] = DateTime.Minutes(5) {
AtreidesAttackDelay["normal"] = DateTime.Minutes(2) + DateTime.Seconds(40) easy = DateTime.Minutes(5),
AtreidesAttackDelay["hard"] = DateTime.Minutes(1) + DateTime.Seconds(20) normal = DateTime.Minutes(2) + DateTime.Seconds(40),
hard = DateTime.Minutes(1) + DateTime.Seconds(20)
}
AtreidesAttackWaves = { } AtreidesAttackWaves =
AtreidesAttackWaves["easy"] = 3 {
AtreidesAttackWaves["normal"] = 6 easy = 3,
AtreidesAttackWaves["hard"] = 9 normal = 6,
hard = 9
wave = 0 }
SendAtreides = function()
Trigger.AfterDelay(AtreidesAttackDelay[Map.LobbyOption("difficulty")], function()
wave = wave + 1
if wave > AtreidesAttackWaves[Map.LobbyOption("difficulty")] then
return
end
local path = Utils.Random(AtreidesAttackPaths)
local units = Reinforcements.ReinforceWithTransport(atreides, "carryall.reinforce", AtreidesReinforcements[Map.LobbyOption("difficulty")][wave], path, { path[1] })[2]
Utils.Do(units, IdleHunt)
SendAtreides()
end)
end
IdleHunt = function(unit)
Trigger.OnIdle(unit, unit.Hunt)
end
Tick = function() Tick = function()
if player.HasNoRequiredUnits() then if player.HasNoRequiredUnits() then
@@ -93,7 +79,9 @@ WorldLoaded = function()
atreides = Player.GetPlayer("Atreides") atreides = Player.GetPlayer("Atreides")
player = Player.GetPlayer("Harkonnen") player = Player.GetPlayer("Harkonnen")
InitObjectives() InitObjectives(player)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
KillAtreides = player.AddPrimaryObjective("Destroy all Atreides forces.")
Camera.Position = HConyard.CenterPosition Camera.Position = HConyard.CenterPosition
@@ -101,33 +89,7 @@ WorldLoaded = function()
Utils.Do(atreides.GetGroundAttackers(), IdleHunt) Utils.Do(atreides.GetGroundAttackers(), IdleHunt)
end) end)
SendAtreides() local path = function() return Utils.Random(AtreidesAttackPaths) end
SendCarryallReinforcements(atreides, 0, AtreidesAttackWaves[Difficulty], AtreidesAttackDelay[Difficulty], path, AtreidesReinforcements[Difficulty])
Trigger.AfterDelay(0, ActivateAI) Trigger.AfterDelay(0, ActivateAI)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
KillAtreides = player.AddPrimaryObjective("Destroy all Atreides forces.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: harkonnen02b.lua, harkonnen02b-AI.lua Scripts: campaign-global.lua, harkonnen02b.lua, harkonnen02b-AI.lua
MissionData: MissionData:
Briefing: Strengthen your forces at our mining camp in the Imperial Basin. We must punish the Atreides for their insolence. Teach them the consequences of opposing House Harkonnen.\n\nOur radar will help you find your targets.\n Briefing: Strengthen your forces at our mining camp in the Imperial Basin. We must punish the Atreides for their insolence. Teach them the consequences of opposing House Harkonnen.\n\nOur radar will help you find your targets.\n
BriefingVideo: H_BR02_E.VQA BriefingVideo: H_BR02_E.VQA

View File

@@ -1,4 +1,11 @@
IdlingUnits = { } --[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
AttackGroupSize = AttackGroupSize =
{ {
@@ -17,141 +24,22 @@ AttackDelays =
AtreidesInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" } AtreidesInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" }
AtreidesVehicleTypes = { "trike", "trike", "quad" } AtreidesVehicleTypes = { "trike", "trike", "quad" }
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Map.LobbyOption("difficulty")], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if IsAttacking then
return
end
IsAttacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
IsAttacking = false
HoldProduction = false
end)
end
ProtectHarvester = function(unit)
DefendActor(unit)
Trigger.OnKilled(unit, function() HarvesterKilled = true end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function()
Utils.Do(AtreidesBase, function(actor)
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if ABarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(AtreidesInfantryTypes) }
atreides.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ProduceVehicles = function()
if ALightFactory.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceVehicles)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(AtreidesVehicleTypes) }
atreides.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceVehicles)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ActivateAI = function() ActivateAI = function()
Trigger.AfterDelay(0, InitAIUnits) IdlingUnits[atreides] = { }
HarvesterKilled[atreides] = true
DefendAndRepairBase(atreides, AtreidesBase, 0.75, AttackGroupSize[Difficulty])
AConyard.Produce(HarkonnenUpgrades[1]) AConyard.Produce(HarkonnenUpgrades[1])
AConyard.Produce(HarkonnenUpgrades[2]) AConyard.Produce(HarkonnenUpgrades[2])
local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local infantryToBuild = function() return { Utils.Random(AtreidesInfantryTypes) } end
local vehilcesToBuild = function() return { Utils.Random(AtreidesVehicleTypes) } end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
-- Finish the upgrades first before trying to build something -- Finish the upgrades first before trying to build something
Trigger.AfterDelay(DateTime.Seconds(14), function() Trigger.AfterDelay(DateTime.Seconds(14), function()
ProduceInfantry() ProduceUnits(atreides, ABarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
ProduceVehicles() ProduceUnits(atreides, ALightFactory, delay, vehilcesToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end) end)
end end

View File

@@ -1,3 +1,12 @@
--[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
AtreidesBase = { ABarracks, AWindTrap1, AWindTrap2, ALightFactory, AOutpost, AConyard, ARefinery, ASilo } AtreidesBase = { ABarracks, AWindTrap1, AWindTrap2, ALightFactory, AOutpost, AConyard, ARefinery, ASilo }
AtreidesBaseAreaTriggers = AtreidesBaseAreaTriggers =
{ {
@@ -84,40 +93,10 @@ HarkonnenPath = { HarkonnenEntry.Location, HarkonnenRally.Location }
HarkonnenBaseBuildings = { "barracks", "light_factory" } HarkonnenBaseBuildings = { "barracks", "light_factory" }
HarkonnenUpgrades = { "upgrade.barracks", "upgrade.light" } HarkonnenUpgrades = { "upgrade.barracks", "upgrade.light" }
wave = 0
SendAtreides = function()
Trigger.AfterDelay(AtreidesAttackDelay[Map.LobbyOption("difficulty")], function()
if player.IsObjectiveCompleted(KillAtreides) then
return
end
wave = wave + 1
if wave > AtreidesAttackWaves[Map.LobbyOption("difficulty")] then
return
end
local path = Utils.Random(AtreidesPaths)
local units = Reinforcements.ReinforceWithTransport(atreides, "carryall.reinforce", AtreidesReinforcements[Map.LobbyOption("difficulty")][wave], path, { path[1] })[2]
Utils.Do(units, IdleHunt)
SendAtreides()
end)
end
MessageCheck = function(index) MessageCheck = function(index)
return #player.GetActorsByType(HarkonnenBaseBuildings[index]) > 0 and not player.HasPrerequisites({ HarkonnenUpgrades[index] }) return #player.GetActorsByType(HarkonnenBaseBuildings[index]) > 0 and not player.HasPrerequisites({ HarkonnenUpgrades[index] })
end end
SendHunters = function(areaTrigger, unit, path, check)
Trigger.OnEnteredFootprint(areaTrigger, function(a, id)
if not check and a.Owner == player then
local units = Reinforcements.ReinforceWithTransport(atreides, "carryall.reinforce", unit, path, { path[1] })[2]
Utils.Do(units, IdleHunt)
check = true
end
end)
end
Tick = function() Tick = function()
if player.HasNoRequiredUnits() then if player.HasNoRequiredUnits() then
atreides.MarkCompletedObjective(KillHarkonnen) atreides.MarkCompletedObjective(KillHarkonnen)
@@ -128,12 +107,12 @@ Tick = function()
player.MarkCompletedObjective(KillAtreides) player.MarkCompletedObjective(KillAtreides)
end end
if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled then if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled[atreides] then
local units = atreides.GetActorsByType("harvester") local units = atreides.GetActorsByType("harvester")
if #units > 0 then if #units > 0 then
HarvesterKilled = false HarvesterKilled[atreides] = false
ProtectHarvester(units[1]) ProtectHarvester(units[1], atreides, AttackGroupSize[Difficulty])
end end
end end
@@ -146,7 +125,9 @@ WorldLoaded = function()
atreides = Player.GetPlayer("Atreides") atreides = Player.GetPlayer("Atreides")
player = Player.GetPlayer("Harkonnen") player = Player.GetPlayer("Harkonnen")
InitObjectives() InitObjectives(player)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
KillAtreides = player.AddPrimaryObjective("Eliminate all Atreides units and reinforcements\nin the area.")
Camera.Position = HConyard.CenterPosition Camera.Position = HConyard.CenterPosition
@@ -154,43 +135,18 @@ WorldLoaded = function()
Utils.Do(atreides.GetGroundAttackers(), IdleHunt) Utils.Do(atreides.GetGroundAttackers(), IdleHunt)
end) end)
SendAtreides() local path = function() return Utils.Random(AtreidesPaths) end
ActivateAI() local waveCondition = function() return player.IsObjectiveCompleted(KillAtreides) end
SendCarryallReinforcements(atreides, 0, AtreidesAttackWaves[Difficulty], AtreidesAttackDelay[Difficulty], path, AtreidesReinforcements[Difficulty], waveCondition)
Trigger.AfterDelay(0, ActivateAI)
Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), function() Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), function()
Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", HarkonnenReinforcements, HarkonnenPath, { HarkonnenPath[1] }) Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", HarkonnenReinforcements, HarkonnenPath, { HarkonnenPath[1] })
end) end)
SendHunters(AtreidesBaseAreaTriggers[1], AtreidesHunters[1], AtreidesHunterPaths[1], HuntersSent1) TriggerCarryallReinforcements(player, atreides, AtreidesBaseAreaTriggers[1], AtreidesHunters[1], AtreidesHunterPaths[1])
SendHunters(AtreidesBaseAreaTriggers[1], AtreidesHunters[2], AtreidesHunterPaths[2], HuntersSent2) TriggerCarryallReinforcements(player, atreides, AtreidesBaseAreaTriggers[1], AtreidesHunters[2], AtreidesHunterPaths[2])
SendHunters(AtreidesBaseAreaTriggers[2], AtreidesHunters[3], AtreidesHunterPaths[3], HuntersSent3) TriggerCarryallReinforcements(player, atreides, AtreidesBaseAreaTriggers[2], AtreidesHunters[3], AtreidesHunterPaths[3])
SendHunters(AtreidesBaseAreaTriggers[2], AtreidesHunters[4], AtreidesHunterPaths[4], HuntersSent4) TriggerCarryallReinforcements(player, atreides, AtreidesBaseAreaTriggers[2], AtreidesHunters[4], AtreidesHunterPaths[4])
SendHunters(AtreidesBaseAreaTriggers[3], AtreidesHunters[5], AtreidesHunterPaths[5], HuntersSent5) TriggerCarryallReinforcements(player, atreides, AtreidesBaseAreaTriggers[3], AtreidesHunters[5], AtreidesHunterPaths[5])
end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
KillAtreides = player.AddPrimaryObjective("Eliminate all Atreides units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: harkonnen03a.lua, harkonnen03a-AI.lua Scripts: campaign-global.lua, harkonnen03a.lua, harkonnen03a-AI.lua
MissionData: MissionData:
Briefing: Attack and destroy the Atreides base at Sietch Tabr. Strike hard and eliminate all resistance.\n\nHeavier Quad vehicles will be made available for your attack. Upgrade your Light Factory to gain access to these vehicles.\n Briefing: Attack and destroy the Atreides base at Sietch Tabr. Strike hard and eliminate all resistance.\n\nHeavier Quad vehicles will be made available for your attack. Upgrade your Light Factory to gain access to these vehicles.\n
BriefingVideo: H_BR03_E.VQA BriefingVideo: H_BR03_E.VQA

View File

@@ -1,4 +1,11 @@
IdlingUnits = { } --[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
AttackGroupSize = AttackGroupSize =
{ {
@@ -17,143 +24,27 @@ AttackDelays =
AtreidesInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" } AtreidesInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" }
AtreidesVehicleTypes = { "trike", "trike", "quad" } AtreidesVehicleTypes = { "trike", "trike", "quad" }
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Map.LobbyOption("difficulty")], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if IsAttacking then
return
end
IsAttacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
IsAttacking = false
HoldProduction = false
end)
end
ProtectHarvester = function(unit)
DefendActor(unit)
Trigger.OnKilled(unit, function() HarvesterKilled = true end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function() InitAIUnits = function()
IdlingUnits = Reinforcements.Reinforce(atreides, AtreidesInitialReinforcements, AtreidesInitialPath) IdlingUnits[atreides] = Reinforcements.Reinforce(atreides, AtreidesInitialReinforcements, AtreidesInitialPath)
Utils.Do(AtreidesBase, function(actor) DefendAndRepairBase(atreides, AtreidesBase, 0.75, AttackGroupSize[Difficulty])
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if ABarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(AtreidesInfantryTypes) }
atreides.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ProduceVehicles = function()
if ALightFactory.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceVehicles)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(AtreidesVehicleTypes) }
atreides.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceVehicles)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end end
ActivateAI = function() ActivateAI = function()
HarvesterKilled[atreides] = true
Trigger.AfterDelay(0, InitAIUnits) Trigger.AfterDelay(0, InitAIUnits)
AConyard.Produce(HarkonnenUpgrades[1]) AConyard.Produce(HarkonnenUpgrades[1])
AConyard.Produce(HarkonnenUpgrades[2]) AConyard.Produce(HarkonnenUpgrades[2])
local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local infantryToBuild = function() return { Utils.Random(AtreidesInfantryTypes) } end
local vehilcesToBuild = function() return { Utils.Random(AtreidesVehicleTypes) } end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
-- Finish the upgrades first before trying to build something -- Finish the upgrades first before trying to build something
Trigger.AfterDelay(DateTime.Seconds(14), function() Trigger.AfterDelay(DateTime.Seconds(14), function()
ProduceInfantry() ProduceUnits(atreides, ABarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
ProduceVehicles() ProduceUnits(atreides, ALightFactory, delay, vehilcesToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end) end)
end end

View File

@@ -1,3 +1,12 @@
--[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
AtreidesBase = { ABarracks, AWindTrap1, AWindTrap2, AWindTrap3, ALightFactory, AOutpost, AConyard, ARefinery, ASilo1, ASilo2, ASilo3, ASilo4 } AtreidesBase = { ABarracks, AWindTrap1, AWindTrap2, AWindTrap3, ALightFactory, AOutpost, AConyard, ARefinery, ASilo1, ASilo2, ASilo3, ASilo4 }
AtreidesBaseAreaTriggers = AtreidesBaseAreaTriggers =
{ {
@@ -86,40 +95,10 @@ HarkonnenPath = { HarkonnenEntry.Location, HarkonnenRally.Location }
HarkonnenBaseBuildings = { "barracks", "light_factory" } HarkonnenBaseBuildings = { "barracks", "light_factory" }
HarkonnenUpgrades = { "upgrade.barracks", "upgrade.light" } HarkonnenUpgrades = { "upgrade.barracks", "upgrade.light" }
wave = 0
SendAtreides = function()
Trigger.AfterDelay(AtreidesAttackDelay[Map.LobbyOption("difficulty")], function()
if player.IsObjectiveCompleted(KillAtreides) then
return
end
wave = wave + 1
if wave > AtreidesAttackWaves[Map.LobbyOption("difficulty")] then
return
end
local path = Utils.Random(AtreidesPaths)
local units = Reinforcements.ReinforceWithTransport(atreides, "carryall.reinforce", AtreidesReinforcements[Map.LobbyOption("difficulty")][wave], path, { path[1] })[2]
Utils.Do(units, IdleHunt)
SendAtreides()
end)
end
MessageCheck = function(index) MessageCheck = function(index)
return #player.GetActorsByType(HarkonnenBaseBuildings[index]) > 0 and not player.HasPrerequisites({ HarkonnenUpgrades[index] }) return #player.GetActorsByType(HarkonnenBaseBuildings[index]) > 0 and not player.HasPrerequisites({ HarkonnenUpgrades[index] })
end end
SendHunters = function(areaTrigger, unit, path, check)
Trigger.OnEnteredFootprint(areaTrigger, function(a, id)
if not check and a.Owner == player then
local units = Reinforcements.ReinforceWithTransport(atreides, "carryall.reinforce", unit, path, { path[1] })[2]
Utils.Do(units, IdleHunt)
check = true
end
end)
end
Tick = function() Tick = function()
if player.HasNoRequiredUnits() then if player.HasNoRequiredUnits() then
atreides.MarkCompletedObjective(KillHarkonnen) atreides.MarkCompletedObjective(KillHarkonnen)
@@ -130,12 +109,12 @@ Tick = function()
player.MarkCompletedObjective(KillAtreides) player.MarkCompletedObjective(KillAtreides)
end end
if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled then if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled[atreides] then
local units = atreides.GetActorsByType("harvester") local units = atreides.GetActorsByType("harvester")
if #units > 0 then if #units > 0 then
HarvesterKilled = false HarvesterKilled[atreides] = false
ProtectHarvester(units[1]) ProtectHarvester(units[1], atreides, AttackGroupSize[Difficulty])
end end
end end
@@ -148,7 +127,9 @@ WorldLoaded = function()
atreides = Player.GetPlayer("Atreides") atreides = Player.GetPlayer("Atreides")
player = Player.GetPlayer("Harkonnen") player = Player.GetPlayer("Harkonnen")
InitObjectives() InitObjectives(player)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
KillAtreides = player.AddPrimaryObjective("Eliminate all Atreides units and reinforcements\nin the area.")
Camera.Position = HConyard.CenterPosition Camera.Position = HConyard.CenterPosition
@@ -156,42 +137,17 @@ WorldLoaded = function()
Utils.Do(atreides.GetGroundAttackers(), IdleHunt) Utils.Do(atreides.GetGroundAttackers(), IdleHunt)
end) end)
SendAtreides() local path = function() return Utils.Random(AtreidesPaths) end
local waveCondition = function() return player.IsObjectiveCompleted(KillAtreides) end
SendCarryallReinforcements(atreides, 0, AtreidesAttackWaves[Difficulty], AtreidesAttackDelay[Difficulty], path, AtreidesReinforcements[Difficulty], waveCondition)
ActivateAI() ActivateAI()
Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), function() Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), function()
Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", HarkonnenReinforcements, HarkonnenPath, { HarkonnenPath[1] }) Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", HarkonnenReinforcements, HarkonnenPath, { HarkonnenPath[1] })
end) end)
SendHunters(AtreidesBaseAreaTriggers[1], AtreidesHunters[1], AtreidesHunterPaths[1], HuntersSent1) TriggerCarryallReinforcements(player, atreides, AtreidesBaseAreaTriggers[1], AtreidesHunters[1], AtreidesHunterPaths[1])
SendHunters(AtreidesBaseAreaTriggers[2], AtreidesHunters[2], AtreidesHunterPaths[2], HuntersSent2) TriggerCarryallReinforcements(player, atreides, AtreidesBaseAreaTriggers[2], AtreidesHunters[2], AtreidesHunterPaths[2])
SendHunters(AtreidesBaseAreaTriggers[3], AtreidesHunters[3], AtreidesHunterPaths[3], HuntersSent3) TriggerCarryallReinforcements(player, atreides, AtreidesBaseAreaTriggers[3], AtreidesHunters[3], AtreidesHunterPaths[3])
SendHunters(AtreidesBaseAreaTriggers[4], AtreidesHunters[4], AtreidesHunterPaths[4], HuntersSent4) TriggerCarryallReinforcements(player, atreides, AtreidesBaseAreaTriggers[4], AtreidesHunters[4], AtreidesHunterPaths[4])
end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
KillAtreides = player.AddPrimaryObjective("Eliminate all Atreides units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: harkonnen03b.lua, harkonnen03b-AI.lua Scripts: campaign-global.lua, harkonnen03b.lua, harkonnen03b-AI.lua
MissionData: MissionData:
Briefing: Attack and destroy the Atreides base at Sietch Tabr. Strike hard and eliminate all resistance.\n\nHeavier Quad vehicles will be made available for your attack. Upgrade your Light Factory to gain access to these vehicles.\n Briefing: Attack and destroy the Atreides base at Sietch Tabr. Strike hard and eliminate all resistance.\n\nHeavier Quad vehicles will be made available for your attack. Upgrade your Light Factory to gain access to these vehicles.\n
BriefingVideo: H_BR03_E.VQA BriefingVideo: H_BR03_E.VQA

View File

@@ -1,4 +1,11 @@
IdlingUnits = { } --[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
AttackGroupSize = AttackGroupSize =
{ {
@@ -18,168 +25,21 @@ AtreidesInfantryTypes = { "light_inf", "light_inf", "trooper", "trooper", "troop
AtreidesVehicleTypes = { "trike", "trike", "quad" } AtreidesVehicleTypes = { "trike", "trike", "quad" }
AtreidesTankType = { "combat_tank_a" } AtreidesTankType = { "combat_tank_a" }
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Difficulty] do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if Attacking then
return
end
Attacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, IdleHunt)
Trigger.OnAllRemovedFromWorld(units, function()
Attacking = false
HoldProduction = false
end)
end
ProtectHarvester = function(unit)
DefendActor(unit)
Trigger.OnKilled(unit, function() HarvesterKilled = true end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if Defending then
return
end
Defending = true
-- Don't try to attack spiceblooms
if attacker and attacker.Type == "spicebloom" then
return
end
local Guards = SetupAttackGroup()
if #Guards <= 0 then
Defending = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() Defending = false end)
end)
end
InitAIUnits = function()
IdlingUnits = Reinforcements.Reinforce(atreides, InitialAtreidesReinforcements[1], AtreidesPaths[2]), Reinforcements.Reinforce(atreides, InitialAtreidesReinforcements[2], AtreidesPaths[3])
end
RepairBase = function(house)
Utils.Do(Base[house.Name], function(actor)
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Owner == house and building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if ABarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Seconds(30), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1)
local toBuild = { Utils.Random(AtreidesInfantryTypes) }
atreides.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then
SendAttack()
end
end)
end
ProduceVehicles = function()
if ALightFactory.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Seconds(30), ProduceVehicles)
return
end
local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1)
local toBuild = { Utils.Random(AtreidesVehicleTypes) }
atreides.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceVehicles)
if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then
SendAttack()
end
end)
end
ProduceTanks = function()
if AHeavyFactory.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Seconds(30), ProduceTanks)
return
end
local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1)
atreides.Build(AtreidesTankType, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceTanks)
if #IdlingUnits >= (AttackGroupSize[Difficulty] * 2.5) then
SendAttack()
end
end)
end
ActivateAI = function() ActivateAI = function()
InitAIUnits() IdlingUnits[fremen] = { }
IdlingUnits[atreides] = Reinforcements.Reinforce(atreides, InitialAtreidesReinforcements[1], AtreidesPaths[2]), Reinforcements.Reinforce(atreides, InitialAtreidesReinforcements[2], AtreidesPaths[3])
FremenProduction() FremenProduction()
RepairBase(atreides) DefendAndRepairBase(atreides, AtreidesBase, 0.75, AttackGroupSize[Difficulty])
RepairBase(fremen) DefendAndRepairBase(fremen, FremenBase, 0.75, AttackGroupSize[Difficulty])
ProduceInfantry() local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
ProduceVehicles() local infantryToBuild = function() return { Utils.Random(AtreidesInfantryTypes) } end
ProduceTanks() local vehilcesToBuild = function() return { Utils.Random(AtreidesVehicleTypes) } end
local tanksToBuild = function() return AtreidesTankType end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
ProduceUnits(atreides, ABarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
ProduceUnits(atreides, ALightFactory, delay, vehilcesToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
ProduceUnits(atreides, AHeavyFactory, delay, tanksToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end end

View File

@@ -1,8 +1,14 @@
Base = --[[
{ Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
Atreides = { AConyard, AOutpost, ARefinery, AHeavyFactory, ALightFactory, AGunt1, AGunt2, ABarracks, ASilo, APower1, APower2, APower3, APower4, APower5, APower6 }, This file is part of OpenRA, which is free software. It is made
Fremen = { FGunt1, FGunt2 } available to you under the terms of the GNU General Public License
} as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
AtreidesBase = { AConyard, AOutpost, ARefinery, AHeavyFactory, ALightFactory, AGunt1, AGunt2, ABarracks, ASilo, APower1, APower2, APower3, APower4, APower5, APower6 }
FremenBase = { FGunt1, FGunt2 }
BaseAreaTriggers = BaseAreaTriggers =
{ {
@@ -110,55 +116,14 @@ FremenInterval =
hard = { DateTime.Minutes(3) + DateTime.Seconds(40), DateTime.Minutes(4) } hard = { DateTime.Minutes(3) + DateTime.Seconds(40), DateTime.Minutes(4) }
} }
wave = 0
SendFremen = function()
Trigger.AfterDelay(FremenAttackDelay[Difficulty], function()
if player.IsObjectiveCompleted(KillFremen) then
return
end
wave = wave + 1
if wave > FremenAttackWaves[Difficulty] then
return
end
local entryPath = Utils.Random(FremenPaths)
local units = Reinforcements.ReinforceWithTransport(fremen, "carryall.reinforce", FremenReinforcements[Difficulty][wave], entryPath, { entryPath[1] })[2]
Utils.Do(units, function(unit)
unit.AttackMove(FremenAttackLocation)
IdleHunt(unit)
end)
SendFremen()
end)
end
SendHunters = function(areaTrigger, unit, path, house, objective, check)
Trigger.OnEnteredFootprint(areaTrigger, function(a, id)
if player.IsObjectiveCompleted(objective) then
return
end
if not check and a.Owner == player then
local units = Reinforcements.ReinforceWithTransport(house, "carryall.reinforce", unit, path, { path[1] })[2]
Utils.Do(units, IdleHunt)
check = true
end
end)
end
FremenProduction = function() FremenProduction = function()
Trigger.OnAllKilled(Sietches, function()
SietchesAreDestroyed = true
end)
if SietchesAreDestroyed then if SietchesAreDestroyed then
return return
end end
local delay = Utils.RandomInteger(FremenInterval[Difficulty][1], FremenInterval[Difficulty][2] + 1) local delay = Utils.RandomInteger(FremenInterval[Difficulty][1], FremenInterval[Difficulty][2] + 1)
fremen.Build({ "nsfremen" }, function() fremen.Build({ "nsfremen" }, function()
Trigger.AfterDelay(delay, ProduceInfantry) Trigger.AfterDelay(delay, FremenProduction)
end) end)
end end
@@ -177,12 +142,12 @@ Tick = function()
player.MarkCompletedObjective(KillFremen) player.MarkCompletedObjective(KillFremen)
end end
if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled then if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled[atreides] then
local units = atreides.GetActorsByType("harvester") local units = atreides.GetActorsByType("harvester")
if #units > 0 then if #units > 0 then
HarvesterKilled = false HarvesterKilled[atreides] = false
ProtectHarvester(units[1]) ProtectHarvester(units[1], atreides, AttackGroupSize[Difficulty])
end end
end end
end end
@@ -192,18 +157,30 @@ WorldLoaded = function()
fremen = Player.GetPlayer("Fremen") fremen = Player.GetPlayer("Fremen")
player = Player.GetPlayer("Harkonnen") player = Player.GetPlayer("Harkonnen")
Difficulty = Map.LobbyOption("difficulty") InitObjectives(player)
KillAtreides = player.AddPrimaryObjective("Destroy the Atreiedes.")
InitObjectives() KillFremen = player.AddPrimaryObjective("Destroy the Fremen.")
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
Camera.Position = HConyard.CenterPosition Camera.Position = HConyard.CenterPosition
FremenAttackLocation = HConyard.Location FremenAttackLocation = HConyard.Location
Trigger.OnAllKilledOrCaptured(Base[atreides.Name], function() Trigger.OnAllKilledOrCaptured(AtreidesBase, function()
Utils.Do(atreides.GetGroundAttackers(), IdleHunt) Utils.Do(atreides.GetGroundAttackers(), IdleHunt)
end) end)
SendFremen() Trigger.OnAllKilled(Sietches, function()
SietchesAreDestroyed = true
end)
local path = function() return Utils.Random(FremenPaths) end
local waveCondition = function() return player.IsObjectiveCompleted(KillFremen) end
local huntFunction = function(unit)
unit.AttackMove(FremenAttackLocation)
IdleHunt(unit)
end
SendCarryallReinforcements(fremen, 0, FremenAttackWaves[Difficulty], FremenAttackDelay[Difficulty], path, FremenReinforcements[Difficulty], waveCondition, huntFunction)
Actor.Create("upgrade.barracks", true, { Owner = atreides }) Actor.Create("upgrade.barracks", true, { Owner = atreides })
Actor.Create("upgrade.light", true, { Owner = atreides }) Actor.Create("upgrade.light", true, { Owner = atreides })
Trigger.AfterDelay(0, ActivateAI) Trigger.AfterDelay(0, ActivateAI)
@@ -217,36 +194,11 @@ WorldLoaded = function()
Media.DisplayMessage("Fremen concentrations spotted to the North and Southwest.", "Mentat") Media.DisplayMessage("Fremen concentrations spotted to the North and Southwest.", "Mentat")
end) end)
SendHunters(BaseAreaTriggers[1], AtreidesHunters, AtreidesPaths[1], atreides, KillAtreides, HuntersSent1) local atreidesCondition = function() return player.IsObjectiveCompleted(KillAtreides) end
SendHunters(BaseAreaTriggers[1], FremenHunters[1], FremenHunterPaths[3], fremen, KillFremen, HuntersSent2) TriggerCarryallReinforcements(player, atreides, BaseAreaTriggers[1], AtreidesHunters, AtreidesPaths[1], atreidesCondition)
SendHunters(BaseAreaTriggers[2], FremenHunters[2], FremenHunterPaths[2], fremen, KillFremen, HuntersSent3)
SendHunters(BaseAreaTriggers[3], FremenHunters[3], FremenHunterPaths[1], fremen, KillFremen, HuntersSent4) local fremenCondition = function() return player.IsObjectiveCompleted(KillFremen) end
end TriggerCarryallReinforcements(player, fremen, BaseAreaTriggers[1], FremenHunters[1], FremenHunterPaths[3], fremenCondition)
TriggerCarryallReinforcements(player, fremen, BaseAreaTriggers[2], FremenHunters[2], FremenHunterPaths[2], fremenCondition)
InitObjectives = function() TriggerCarryallReinforcements(player, fremen, BaseAreaTriggers[3], FremenHunters[3], FremenHunterPaths[1], fremenCondition)
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillAtreides = player.AddPrimaryObjective("Destroy the Atreiedes.")
KillFremen = player.AddPrimaryObjective("Destroy the Fremen.")
KillHarkonnen = atreides.AddPrimaryObjective("Kill all Harkonnen units.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: harkonnen04.lua, harkonnen04-AI.lua Scripts: campaign-global.lua, harkonnen04.lua, harkonnen04-AI.lua
MissionData: MissionData:
Briefing: The native Fremen must be dealt with. Assemble a strike force to lead a sweep through the mountains. Seek out the Fremen hold, and destroy it. If any House responds, destroy it.\n\nTanks have been deployed to grind the Fremen beneath their treads. Demonstrate the power of House Harkonnen. Briefing: The native Fremen must be dealt with. Assemble a strike force to lead a sweep through the mountains. Seek out the Fremen hold, and destroy it. If any House responds, destroy it.\n\nTanks have been deployed to grind the Fremen beneath their treads. Demonstrate the power of House Harkonnen.
BriefingVideo: H_BR04_E.VQA BriefingVideo: H_BR04_E.VQA

View File

@@ -7,40 +7,46 @@
information, see COPYING. information, see COPYING.
]] ]]
HarkonnenReinforcements = { } HarkonnenReinforcements =
HarkonnenReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "light_inf" } { "light_inf", "light_inf" }
} },
HarkonnenReinforcements["normal"] = normal =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
HarkonnenReinforcements["hard"] = hard =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
HarkonnenEntryWaypoints = { HarkonnenWaypoint1.Location, HarkonnenWaypoint2.Location, HarkonnenWaypoint3.Location } HarkonnenEntryWaypoints = { HarkonnenWaypoint1.Location, HarkonnenWaypoint2.Location, HarkonnenWaypoint3.Location }
HarkonnenAttackDelay = DateTime.Seconds(30) HarkonnenAttackDelay = DateTime.Seconds(30)
HarkonnenAttackWaves = { } HarkonnenAttackWaves =
HarkonnenAttackWaves["easy"] = 1 {
HarkonnenAttackWaves["normal"] = 5 easy = 1,
HarkonnenAttackWaves["hard"] = 12 normal = 5,
hard = 12
}
ToHarvest = { } ToHarvest =
ToHarvest["easy"] = 2500 {
ToHarvest["normal"] = 3000 easy = 2500,
ToHarvest["hard"] = 3500 normal = 3000,
hard = 3500
}
OrdosReinforcements = { "light_inf", "light_inf", "light_inf", "light_inf", "raider" } OrdosReinforcements = { "light_inf", "light_inf", "light_inf", "light_inf", "raider" }
OrdosEntryPath = { OrdosWaypoint.Location, OrdosRally.Location } OrdosEntryPath = { OrdosWaypoint.Location, OrdosRally.Location }
@@ -53,19 +59,12 @@ Messages =
"Build a Silo to store additional Spice." "Build a Silo to store additional Spice."
} }
IdleHunt = function(actor)
if not actor.IsDead then
Trigger.OnIdle(actor, actor.Hunt)
end
end
Tick = function() Tick = function()
if HarkonnenArrived and harkonnen.HasNoRequiredUnits() then if HarkonnenArrived and harkonnen.HasNoRequiredUnits() then
player.MarkCompletedObjective(KillHarkonnen) player.MarkCompletedObjective(KillHarkonnen)
end end
if player.Resources > ToHarvest[Map.LobbyOption("difficulty")] - 1 then if player.Resources > SpiceToHarvest - 1 then
player.MarkCompletedObjective(GatherSpice) player.MarkCompletedObjective(GatherSpice)
end end
@@ -86,14 +85,19 @@ Tick = function()
Media.DisplayMessage(Messages[4], "Mentat") Media.DisplayMessage(Messages[4], "Mentat")
end end
UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. ToHarvest[Map.LobbyOption("difficulty")], player.Color) UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. SpiceToHarvest, player.Color)
end end
WorldLoaded = function() WorldLoaded = function()
player = Player.GetPlayer("Ordos") player = Player.GetPlayer("Ordos")
harkonnen = Player.GetPlayer("Harkonnen") harkonnen = Player.GetPlayer("Harkonnen")
InitObjectives() SpiceToHarvest = ToHarvest[Difficulty]
InitObjectives(player)
KillOrdos = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(SpiceToHarvest) .. " Solaris worth of Spice.")
KillHarkonnen = player.AddSecondaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
Trigger.OnRemovedFromWorld(OrdosConyard, function() Trigger.OnRemovedFromWorld(OrdosConyard, function()
local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end) local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end)
@@ -114,12 +118,12 @@ WorldLoaded = function()
Reinforcements.Reinforce(player, OrdosReinforcements, OrdosEntryPath) Reinforcements.Reinforce(player, OrdosReinforcements, OrdosEntryPath)
end) end)
WavesLeft = HarkonnenAttackWaves[Map.LobbyOption("difficulty")] WavesLeft = HarkonnenAttackWaves[Difficulty]
SendReinforcements() SendReinforcements()
end end
SendReinforcements = function() SendReinforcements = function()
local units = HarkonnenReinforcements[Map.LobbyOption("difficulty")] local units = HarkonnenReinforcements[Difficulty]
local delay = Utils.RandomInteger(HarkonnenAttackDelay - DateTime.Seconds(2), HarkonnenAttackDelay) local delay = Utils.RandomInteger(HarkonnenAttackDelay - DateTime.Seconds(2), HarkonnenAttackDelay)
HarkonnenAttackDelay = HarkonnenAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1) HarkonnenAttackDelay = HarkonnenAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1)
if HarkonnenAttackDelay < 0 then HarkonnenAttackDelay = 0 end if HarkonnenAttackDelay < 0 then HarkonnenAttackDelay = 0 end
@@ -135,31 +139,3 @@ SendReinforcements = function()
end end
end) end)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillOrdos = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(ToHarvest[Map.LobbyOption("difficulty")]) .. " Solaris worth of Spice.")
KillHarkonnen = player.AddSecondaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: ordos01a.lua Scripts: campaign-global.lua, ordos01a.lua
MissionData: MissionData:
Briefing: Spice is wealth. Serve the Ordos by harvesting Spice in the Imperial Basin. If Harkonnen forces attempt to interrupt the flow of the Spice - neutralize them.\n\nEfficiency dictates that Silos must be built to avoid loss of Spice. Build concrete foundations to avoid unnecessary damage from the elements. To do otherwise is wasteful. Briefing: Spice is wealth. Serve the Ordos by harvesting Spice in the Imperial Basin. If Harkonnen forces attempt to interrupt the flow of the Spice - neutralize them.\n\nEfficiency dictates that Silos must be built to avoid loss of Spice. Build concrete foundations to avoid unnecessary damage from the elements. To do otherwise is wasteful.
BriefingVideo: O_BR01_E.VQA BriefingVideo: O_BR01_E.VQA

View File

@@ -7,40 +7,46 @@
information, see COPYING. information, see COPYING.
]] ]]
HarkonnenReinforcements = { } HarkonnenReinforcements =
HarkonnenReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "light_inf" } { "light_inf", "light_inf" }
} },
HarkonnenReinforcements["normal"] = normal =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
HarkonnenReinforcements["hard"] = hard =
{ {
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
HarkonnenEntryWaypoints = { HarkonnenWaypoint1.Location, HarkonnenWaypoint2.Location, HarkonnenWaypoint3.Location, HarkonnenWaypoint4.Location } HarkonnenEntryWaypoints = { HarkonnenWaypoint1.Location, HarkonnenWaypoint2.Location, HarkonnenWaypoint3.Location, HarkonnenWaypoint4.Location }
HarkonnenAttackDelay = DateTime.Seconds(30) HarkonnenAttackDelay = DateTime.Seconds(30)
HarkonnenAttackWaves = { } HarkonnenAttackWaves =
HarkonnenAttackWaves["easy"] = 1 {
HarkonnenAttackWaves["normal"] = 5 easy = 1,
HarkonnenAttackWaves["hard"] = 12 normal = 5,
hard = 12
}
ToHarvest = { } ToHarvest =
ToHarvest["easy"] = 2500 {
ToHarvest["normal"] = 3000 easy = 2500,
ToHarvest["hard"] = 3500 normal = 3000,
hard = 3500
}
OrdosReinforcements = { "light_inf", "light_inf", "light_inf", "light_inf", "raider" } OrdosReinforcements = { "light_inf", "light_inf", "light_inf", "light_inf", "raider" }
OrdosEntryPath = { OrdosWaypoint.Location, OrdosRally.Location } OrdosEntryPath = { OrdosWaypoint.Location, OrdosRally.Location }
@@ -53,19 +59,12 @@ Messages =
"Build a Silo to store additional Spice." "Build a Silo to store additional Spice."
} }
IdleHunt = function(actor)
if not actor.IsDead then
Trigger.OnIdle(actor, actor.Hunt)
end
end
Tick = function() Tick = function()
if HarkonnenArrived and harkonnen.HasNoRequiredUnits() then if HarkonnenArrived and harkonnen.HasNoRequiredUnits() then
player.MarkCompletedObjective(KillHarkonnen) player.MarkCompletedObjective(KillHarkonnen)
end end
if player.Resources > ToHarvest[Map.LobbyOption("difficulty")] - 1 then if player.Resources > SpiceToHarvest - 1 then
player.MarkCompletedObjective(GatherSpice) player.MarkCompletedObjective(GatherSpice)
end end
@@ -86,14 +85,19 @@ Tick = function()
Media.DisplayMessage(Messages[4], "Mentat") Media.DisplayMessage(Messages[4], "Mentat")
end end
UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. ToHarvest[Map.LobbyOption("difficulty")], player.Color) UserInterface.SetMissionText("Harvested resources: " .. player.Resources .. "/" .. SpiceToHarvest, player.Color)
end end
WorldLoaded = function() WorldLoaded = function()
player = Player.GetPlayer("Ordos") player = Player.GetPlayer("Ordos")
harkonnen = Player.GetPlayer("Harkonnen") harkonnen = Player.GetPlayer("Harkonnen")
InitObjectives() SpiceToHarvest = ToHarvest[Difficulty]
InitObjectives(player)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(SpiceToHarvest) .. " Solaris worth of Spice.")
KillHarkonnen = player.AddSecondaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
Trigger.OnRemovedFromWorld(OrdosConyard, function() Trigger.OnRemovedFromWorld(OrdosConyard, function()
local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end) local refs = Utils.Where(Map.ActorsInWorld, function(actor) return actor.Type == "refinery" end)
@@ -114,12 +118,12 @@ WorldLoaded = function()
Reinforcements.Reinforce(player, OrdosReinforcements, OrdosEntryPath) Reinforcements.Reinforce(player, OrdosReinforcements, OrdosEntryPath)
end) end)
WavesLeft = HarkonnenAttackWaves[Map.LobbyOption("difficulty")] WavesLeft = HarkonnenAttackWaves[Difficulty]
SendReinforcements() SendReinforcements()
end end
SendReinforcements = function() SendReinforcements = function()
local units = HarkonnenReinforcements[Map.LobbyOption("difficulty")] local units = HarkonnenReinforcements[Difficulty]
local delay = Utils.RandomInteger(HarkonnenAttackDelay - DateTime.Seconds(2), HarkonnenAttackDelay) local delay = Utils.RandomInteger(HarkonnenAttackDelay - DateTime.Seconds(2), HarkonnenAttackDelay)
HarkonnenAttackDelay = HarkonnenAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1) HarkonnenAttackDelay = HarkonnenAttackDelay - (#units * 3 - 3 - WavesLeft) * DateTime.Seconds(1)
if HarkonnenAttackDelay < 0 then HarkonnenAttackDelay = 0 end if HarkonnenAttackDelay < 0 then HarkonnenAttackDelay = 0 end
@@ -135,31 +139,3 @@ SendReinforcements = function()
end end
end) end)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillAtreides = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
GatherSpice = player.AddPrimaryObjective("Harvest " .. tostring(ToHarvest[Map.LobbyOption("difficulty")]) .. " Solaris worth of Spice.")
KillHarkonnen = player.AddSecondaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: ordos01b.lua Scripts: campaign-global.lua, ordos01b.lua
MissionData: MissionData:
Briefing: Spice is wealth. Serve the Ordos by harvesting Spice in the Imperial Basin. If Harkonnen forces attempt to interrupt the flow of the Spice - neutralize them.\n\nEfficiency dictates that Silos must be built to avoid loss of Spice. Build concrete foundations to avoid unnecessary damage from the elements. To do otherwise is wasteful. Briefing: Spice is wealth. Serve the Ordos by harvesting Spice in the Imperial Basin. If Harkonnen forces attempt to interrupt the flow of the Spice - neutralize them.\n\nEfficiency dictates that Silos must be built to avoid loss of Spice. Build concrete foundations to avoid unnecessary damage from the elements. To do otherwise is wasteful.
BriefingVideo: O_BR01_E.VQA BriefingVideo: O_BR01_E.VQA

View File

@@ -6,7 +6,6 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
IdlingUnits = { }
AttackGroupSize = AttackGroupSize =
{ {
@@ -14,6 +13,7 @@ AttackGroupSize =
normal = 8, normal = 8,
hard = 10 hard = 10
} }
AttackDelays = AttackDelays =
{ {
easy = { DateTime.Seconds(4), DateTime.Seconds(9) }, easy = { DateTime.Seconds(4), DateTime.Seconds(9) },
@@ -23,108 +23,12 @@ AttackDelays =
HarkonnenInfantryTypes = { "light_inf" } HarkonnenInfantryTypes = { "light_inf" }
AttackOnGoing = false
HoldProduction = false
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Map.LobbyOption("difficulty")], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if Attacking then
return
end
Attacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
Attacking = false
HoldProduction = false
end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function()
Utils.Do(HarkonnenBase, function(actor)
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if HBarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(HarkonnenInfantryTypes) }
harkonnen.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ActivateAI = function() ActivateAI = function()
InitAIUnits() IdlingUnits[harkonnen] = { }
ProduceInfantry() local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local toBuild = function() return HarkonnenInfantryTypes end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
DefendAndRepairBase(harkonnen, HarkonnenBase, 0.75, AttackGroupSize[Difficulty])
ProduceUnits(harkonnen, HBarracks, delay, toBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end end

View File

@@ -10,26 +10,27 @@
HarkonnenBase = { HConyard, HPower1, HPower2, HBarracks, HOutpost } HarkonnenBase = { HConyard, HPower1, HPower2, HBarracks, HOutpost }
HarkonnenBaseAreaTrigger = { CPos.New(31, 37), CPos.New(32, 37), CPos.New(33, 37), CPos.New(34, 37), CPos.New(35, 37), CPos.New(36, 37), CPos.New(37, 37), CPos.New(38, 37), CPos.New(39, 37), CPos.New(40, 37), CPos.New(41, 37), CPos.New(42, 37), CPos.New(42, 38), CPos.New(42, 39), CPos.New(42, 40), CPos.New(42, 41), CPos.New(42, 42), CPos.New(42, 43), CPos.New(42, 44), CPos.New(42, 45), CPos.New(42, 46), CPos.New(42, 47), CPos.New(42, 48), CPos.New(42, 49) } HarkonnenBaseAreaTrigger = { CPos.New(31, 37), CPos.New(32, 37), CPos.New(33, 37), CPos.New(34, 37), CPos.New(35, 37), CPos.New(36, 37), CPos.New(37, 37), CPos.New(38, 37), CPos.New(39, 37), CPos.New(40, 37), CPos.New(41, 37), CPos.New(42, 37), CPos.New(42, 38), CPos.New(42, 39), CPos.New(42, 40), CPos.New(42, 41), CPos.New(42, 42), CPos.New(42, 43), CPos.New(42, 44), CPos.New(42, 45), CPos.New(42, 46), CPos.New(42, 47), CPos.New(42, 48), CPos.New(42, 49) }
HarkonnenReinforcements = { } HarkonnenReinforcements =
HarkonnenReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" } { "light_inf", "light_inf", "light_inf", "trike", "trike" }
} },
HarkonnenReinforcements["normal"] = normal =
{ {
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" }, { "light_inf", "light_inf", "light_inf", "trike", "trike" },
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
HarkonnenReinforcements["hard"] = hard =
{ {
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
@@ -39,6 +40,7 @@ HarkonnenReinforcements["hard"] =
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
HarkonnenAttackPaths = HarkonnenAttackPaths =
@@ -61,49 +63,23 @@ InitialHarkonnenReinforcements =
{ "light_inf", "light_inf" } { "light_inf", "light_inf" }
} }
HarkonnenAttackDelay = { } HarkonnenAttackDelay =
HarkonnenAttackDelay["easy"] = DateTime.Minutes(5) {
HarkonnenAttackDelay["normal"] = DateTime.Minutes(2) + DateTime.Seconds(40) easy = DateTime.Minutes(5),
HarkonnenAttackDelay["hard"] = DateTime.Minutes(1) + DateTime.Seconds(20) normal = DateTime.Minutes(2) + DateTime.Seconds(40),
hard = DateTime.Minutes(1) + DateTime.Seconds(20)
}
HarkonnenAttackWaves = { } HarkonnenAttackWaves =
HarkonnenAttackWaves["easy"] = 3 {
HarkonnenAttackWaves["normal"] = 6 easy = 3,
HarkonnenAttackWaves["hard"] = 9 normal = 6,
hard = 9
}
OrdosReinforcements = { "light_inf", "light_inf", "raider" } OrdosReinforcements = { "light_inf", "light_inf", "raider" }
OrdosEntryPath = { OrdosEntry.Location, OrdosRally.Location } OrdosEntryPath = { OrdosEntry.Location, OrdosRally.Location }
wave = 0
SendHarkonnen = function()
Trigger.AfterDelay(HarkonnenAttackDelay[Map.LobbyOption("difficulty")], function()
wave = wave + 1
if wave > HarkonnenAttackWaves[Map.LobbyOption("difficulty")] then
return
end
local path = Utils.Random(HarkonnenAttackPaths)
local units = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", HarkonnenReinforcements[Map.LobbyOption("difficulty")][wave], path, { path[1] })[2]
Utils.Do(units, IdleHunt)
SendHarkonnen()
end)
end
IdleHunt = function(unit)
Trigger.OnIdle(unit, unit.Hunt)
end
SendInitialUnits = function(areaTrigger, unit, path, check)
Trigger.OnEnteredFootprint(areaTrigger, function(a, id)
if not check and a.Owner == player then
local units = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", unit, path, { path[1] })[2]
Utils.Do(units, IdleHunt)
check = true
end
end)
end
Tick = function() Tick = function()
if player.HasNoRequiredUnits() then if player.HasNoRequiredUnits() then
harkonnen.MarkCompletedObjective(KillOrdos) harkonnen.MarkCompletedObjective(KillOrdos)
@@ -119,7 +95,9 @@ WorldLoaded = function()
harkonnen = Player.GetPlayer("Harkonnen") harkonnen = Player.GetPlayer("Harkonnen")
player = Player.GetPlayer("Ordos") player = Player.GetPlayer("Ordos")
InitObjectives() InitObjectives(player)
KillOrdos = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
KillHarkonnen = player.AddPrimaryObjective("Destroy all Harkonnen forces.")
Camera.Position = OConyard.CenterPosition Camera.Position = OConyard.CenterPosition
@@ -132,36 +110,10 @@ WorldLoaded = function()
Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", OrdosReinforcements, OrdosEntryPath, { OrdosEntryPath[1] }) Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", OrdosReinforcements, OrdosEntryPath, { OrdosEntryPath[1] })
end) end)
SendInitialUnits(HarkonnenBaseAreaTrigger, InitialHarkonnenReinforcements[1], InitialHarkonnenReinforcementsPaths[1], InitialReinforcementsSent1) TriggerCarryallReinforcements(player, harkonnen, HarkonnenBaseAreaTrigger, InitialHarkonnenReinforcements[1], InitialHarkonnenReinforcementsPaths[1])
SendInitialUnits(HarkonnenBaseAreaTrigger, InitialHarkonnenReinforcements[2], InitialHarkonnenReinforcementsPaths[2], InitialReinforcementsSent2) TriggerCarryallReinforcements(player, harkonnen, HarkonnenBaseAreaTrigger, InitialHarkonnenReinforcements[2], InitialHarkonnenReinforcementsPaths[2])
SendHarkonnen() local path = function() return Utils.Random(HarkonnenAttackPaths) end
SendCarryallReinforcements(harkonnen, 0, HarkonnenAttackWaves[Difficulty], HarkonnenAttackDelay[Difficulty], path, HarkonnenReinforcements[Difficulty])
Trigger.AfterDelay(0, ActivateAI) Trigger.AfterDelay(0, ActivateAI)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillOrdos = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
KillHarkonnen = player.AddPrimaryObjective("Destroy all Harkonnen forces.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: ordos02a.lua, ordos02a-AI.lua Scripts: campaign-global.lua, ordos02a.lua, ordos02a-AI.lua
MissionData: MissionData:
Briefing: Harkonnen forces are weakened in the Imperial Basin. Use the sensors in our Outpost to find them. Strike hard and destroy everything.\n Briefing: Harkonnen forces are weakened in the Imperial Basin. Use the sensors in our Outpost to find them. Strike hard and destroy everything.\n
BriefingVideo: O_BR02_E.VQA BriefingVideo: O_BR02_E.VQA

View File

@@ -6,7 +6,6 @@
the License, or (at your option) any later version. For more the License, or (at your option) any later version. For more
information, see COPYING. information, see COPYING.
]] ]]
IdlingUnits = { }
AttackGroupSize = AttackGroupSize =
{ {
@@ -14,6 +13,7 @@ AttackGroupSize =
normal = 8, normal = 8,
hard = 10 hard = 10
} }
AttackDelays = AttackDelays =
{ {
easy = { DateTime.Seconds(4), DateTime.Seconds(9) }, easy = { DateTime.Seconds(4), DateTime.Seconds(9) },
@@ -23,108 +23,12 @@ AttackDelays =
HarkonnenInfantryTypes = { "light_inf" } HarkonnenInfantryTypes = { "light_inf" }
AttackOnGoing = false
HoldProduction = false
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Map.LobbyOption("difficulty")], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if Attacking then
return
end
Attacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
Attacking = false
HoldProduction = false
end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function()
Utils.Do(HarkonnenBase, function(actor)
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if HBarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(HarkonnenInfantryTypes) }
harkonnen.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ActivateAI = function() ActivateAI = function()
InitAIUnits() IdlingUnits[harkonnen] = { }
ProduceInfantry() local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local toBuild = function() return HarkonnenInfantryTypes end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
DefendAndRepairBase(harkonnen, HarkonnenBase, 0.75, AttackGroupSize[Difficulty])
ProduceUnits(harkonnen, HBarracks, delay, toBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end end

View File

@@ -9,26 +9,27 @@
HarkonnenBase = { HConyard, HPower1, HPower2, HBarracks, HOutpost } HarkonnenBase = { HConyard, HPower1, HPower2, HBarracks, HOutpost }
HarkonnenReinforcements = { } HarkonnenReinforcements =
HarkonnenReinforcements["easy"] =
{ {
easy =
{
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" } { "light_inf", "light_inf", "light_inf", "trike", "trike" }
} },
HarkonnenReinforcements["normal"] = normal =
{ {
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "light_inf", "light_inf", "trike", "trike" }, { "light_inf", "light_inf", "light_inf", "trike", "trike" },
{ "light_inf", "light_inf" }, { "light_inf", "light_inf" },
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" }
} },
HarkonnenReinforcements["hard"] = hard =
{ {
{ "trike", "trike" }, { "trike", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
@@ -38,6 +39,7 @@ HarkonnenReinforcements["hard"] =
{ "light_inf", "light_inf", "light_inf" }, { "light_inf", "light_inf", "light_inf" },
{ "light_inf", "trike" }, { "light_inf", "trike" },
{ "trike", "trike" } { "trike", "trike" }
}
} }
HarkonnenAttackPaths = HarkonnenAttackPaths =
@@ -62,26 +64,6 @@ HarkonnenAttackWaves =
hard = 9 hard = 9
} }
wave = 0
SendHarkonnen = function()
Trigger.AfterDelay(HarkonnenAttackDelay[Map.LobbyOption("difficulty")], function()
wave = wave + 1
if wave > HarkonnenAttackWaves[Map.LobbyOption("difficulty")] then
return
end
local path = Utils.Random(HarkonnenAttackPaths)
local units = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", HarkonnenReinforcements[Map.LobbyOption("difficulty")][wave], path, { path[1] })[2]
Utils.Do(units, IdleHunt)
SendHarkonnen()
end)
end
IdleHunt = function(unit)
Trigger.OnIdle(unit, unit.Hunt)
end
Tick = function() Tick = function()
if player.HasNoRequiredUnits() then if player.HasNoRequiredUnits() then
harkonnen.MarkCompletedObjective(KillOrdos) harkonnen.MarkCompletedObjective(KillOrdos)
@@ -97,7 +79,9 @@ WorldLoaded = function()
harkonnen = Player.GetPlayer("Harkonnen") harkonnen = Player.GetPlayer("Harkonnen")
player = Player.GetPlayer("Ordos") player = Player.GetPlayer("Ordos")
InitObjectives() InitObjectives(player)
KillOrdos = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
KillHarkonnen = player.AddPrimaryObjective("Destroy all Harkonnen forces.")
Camera.Position = OConyard.CenterPosition Camera.Position = OConyard.CenterPosition
@@ -105,33 +89,7 @@ WorldLoaded = function()
Utils.Do(harkonnen.GetGroundAttackers(), IdleHunt) Utils.Do(harkonnen.GetGroundAttackers(), IdleHunt)
end) end)
SendHarkonnen() local path = function() return Utils.Random(HarkonnenAttackPaths) end
SendCarryallReinforcements(harkonnen, 0, HarkonnenAttackWaves[Difficulty], HarkonnenAttackDelay[Difficulty], path, HarkonnenReinforcements[Difficulty])
Trigger.AfterDelay(0, ActivateAI) Trigger.AfterDelay(0, ActivateAI)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillOrdos = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
KillHarkonnen = player.AddPrimaryObjective("Destroy all Harkonnen forces.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: ordos02b.lua, ordos02b-AI.lua Scripts: campaign-global.lua, ordos02b.lua, ordos02b-AI.lua
MissionData: MissionData:
Briefing: Harkonnen forces are weakened in the Imperial Basin. Use the sensors in our Outpost to find them. Strike hard and destroy everything.\n Briefing: Harkonnen forces are weakened in the Imperial Basin. Use the sensors in our Outpost to find them. Strike hard and destroy everything.\n
BriefingVideo: O_BR02_E.VQA BriefingVideo: O_BR02_E.VQA

View File

@@ -1,4 +1,11 @@
IdlingUnits = { } --[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
AttackGroupSize = AttackGroupSize =
{ {
@@ -17,143 +24,27 @@ AttackDelays =
HarkonnenInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" } HarkonnenInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" }
HarkonnenVehicleTypes = { "trike", "trike", "quad" } HarkonnenVehicleTypes = { "trike", "trike", "quad" }
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Map.LobbyOption("difficulty")], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if IsAttacking then
return
end
IsAttacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
IsAttacking = false
HoldProduction = false
end)
end
ProtectHarvester = function(unit)
DefendActor(unit)
Trigger.OnKilled(unit, function() HarvesterKilled = true end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function() InitAIUnits = function()
IdlingUnits = Reinforcements.Reinforce(harkonnen, HarkonnenInitialReinforcements, HarkonnenInitialPath) IdlingUnits[harkonnen] = Reinforcements.Reinforce(harkonnen, HarkonnenInitialReinforcements, HarkonnenInitialPath)
Utils.Do(HarkonnenBase, function(actor) DefendAndRepairBase(harkonnen, HarkonnenBase, 0.75, AttackGroupSize[Difficulty])
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if HBarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(HarkonnenInfantryTypes) }
harkonnen.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ProduceVehicles = function()
if HLightFactory.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceVehicles)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(HarkonnenVehicleTypes) }
harkonnen.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceVehicles)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end end
ActivateAI = function() ActivateAI = function()
HarvesterKilled[harkonnen] = true
Trigger.AfterDelay(0, InitAIUnits) Trigger.AfterDelay(0, InitAIUnits)
HConyard.Produce(OrdosUpgrades[1]) HConyard.Produce(OrdosUpgrades[1])
HConyard.Produce(OrdosUpgrades[2]) HConyard.Produce(OrdosUpgrades[2])
local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local infantryToBuild = function() return { Utils.Random(HarkonnenInfantryTypes) } end
local vehilcesToBuild = function() return { Utils.Random(HarkonnenVehicleTypes) } end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
-- Finish the upgrades first before trying to build something -- Finish the upgrades first before trying to build something
Trigger.AfterDelay(DateTime.Seconds(14), function() Trigger.AfterDelay(DateTime.Seconds(14), function()
ProduceInfantry() ProduceUnits(harkonnen, HBarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
ProduceVehicles() ProduceUnits(harkonnen, HLightFactory, delay, vehilcesToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end) end)
end end

View File

@@ -1,3 +1,12 @@
--[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
HarkonnenBase = { HBarracks, HWindTrap1, HWindTrap2, HLightFactory, HOutpost, HConyard, HRefinery, HSilo1, HSilo2, HSilo3, HSilo4 } HarkonnenBase = { HBarracks, HWindTrap1, HWindTrap2, HLightFactory, HOutpost, HConyard, HRefinery, HSilo1, HSilo2, HSilo3, HSilo4 }
HarkonnenBaseAreaTrigger = { CPos.New(2, 58), CPos.New(3, 58), CPos.New(4, 58), CPos.New(5, 58), CPos.New(6, 58), CPos.New(7, 58), CPos.New(8, 58), CPos.New(9, 58), CPos.New(10, 58), CPos.New(11, 58), CPos.New(12, 58), CPos.New(13, 58), CPos.New(14, 58), CPos.New(15, 58), CPos.New(16, 58), CPos.New(16, 59), CPos.New(16, 60) } HarkonnenBaseAreaTrigger = { CPos.New(2, 58), CPos.New(3, 58), CPos.New(4, 58), CPos.New(5, 58), CPos.New(6, 58), CPos.New(7, 58), CPos.New(8, 58), CPos.New(9, 58), CPos.New(10, 58), CPos.New(11, 58), CPos.New(12, 58), CPos.New(13, 58), CPos.New(14, 58), CPos.New(15, 58), CPos.New(16, 58), CPos.New(16, 59), CPos.New(16, 60) }
@@ -67,40 +76,10 @@ OrdosPath = { OrdosEntry.Location, OrdosRally.Location }
OrdosBaseBuildings = { "barracks", "light_factory" } OrdosBaseBuildings = { "barracks", "light_factory" }
OrdosUpgrades = { "upgrade.barracks", "upgrade.light" } OrdosUpgrades = { "upgrade.barracks", "upgrade.light" }
wave = 0
SendHarkonnen = function()
Trigger.AfterDelay(HarkonnenAttackDelay[Map.LobbyOption("difficulty")], function()
if player.IsObjectiveCompleted(KillHarkonnen) then
return
end
wave = wave + 1
if wave > HarkonnenAttackWaves[Map.LobbyOption("difficulty")] then
return
end
local path = Utils.Random(HarkonnenPaths)
local units = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", HarkonnenReinforcements[Map.LobbyOption("difficulty")][wave], path, { path[1] })[2]
Utils.Do(units, IdleHunt)
SendHarkonnen()
end)
end
MessageCheck = function(index) MessageCheck = function(index)
return #player.GetActorsByType(OrdosBaseBuildings[index]) > 0 and not player.HasPrerequisites({ OrdosUpgrades[index] }) return #player.GetActorsByType(OrdosBaseBuildings[index]) > 0 and not player.HasPrerequisites({ OrdosUpgrades[index] })
end end
SendHunters = function(areaTrigger, unit, path, check)
Trigger.OnEnteredFootprint(areaTrigger, function(a, id)
if not check and a.Owner == player then
local units = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", unit, path, { path[1] })[2]
Utils.Do(units, IdleHunt)
check = true
end
end)
end
Tick = function() Tick = function()
if player.HasNoRequiredUnits() then if player.HasNoRequiredUnits() then
harkonnen.MarkCompletedObjective(KillOrdos) harkonnen.MarkCompletedObjective(KillOrdos)
@@ -111,12 +90,12 @@ Tick = function()
player.MarkCompletedObjective(KillHarkonnen) player.MarkCompletedObjective(KillHarkonnen)
end end
if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled then if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled[harkonnen] then
local units = harkonnen.GetActorsByType("harvester") local units = harkonnen.GetActorsByType("harvester")
if #units > 0 then if #units > 0 then
HarvesterKilled = false HarvesterKilled[harkonnen] = false
ProtectHarvester(units[1]) ProtectHarvester(units[1], harkonnen, AttackGroupSize[Difficulty])
end end
end end
@@ -129,7 +108,9 @@ WorldLoaded = function()
harkonnen = Player.GetPlayer("Harkonnen") harkonnen = Player.GetPlayer("Harkonnen")
player = Player.GetPlayer("Ordos") player = Player.GetPlayer("Ordos")
InitObjectives() InitObjectives(player)
KillOrdos = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
KillHarkonnen = player.AddPrimaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
Camera.Position = OConyard.CenterPosition Camera.Position = OConyard.CenterPosition
@@ -137,39 +118,14 @@ WorldLoaded = function()
Utils.Do(harkonnen.GetGroundAttackers(), IdleHunt) Utils.Do(harkonnen.GetGroundAttackers(), IdleHunt)
end) end)
SendHarkonnen() local path = function() return Utils.Random(HarkonnenPaths) end
local waveCondition = function() return player.IsObjectiveCompleted(KillHarkonnen) end
SendCarryallReinforcements(harkonnen, 0, HarkonnenAttackWaves[Difficulty], HarkonnenAttackDelay[Difficulty], path, HarkonnenReinforcements[Difficulty], waveCondition)
ActivateAI() ActivateAI()
Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), function() Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), function()
Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", OrdosReinforcements, OrdosPath, { OrdosPath[1] }) Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", OrdosReinforcements, OrdosPath, { OrdosPath[1] })
end) end)
SendHunters(HarkonnenBaseAreaTrigger, HarkonnenHunters, HarkonnenHunterPath, HuntersSent) TriggerCarryallReinforcements(player, harkonnen, HarkonnenBaseAreaTrigger, HarkonnenHunters, HarkonnenHunterPath)
end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillOrdos = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
KillHarkonnen = player.AddPrimaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: ordos03a.lua, ordos03a-AI.lua Scripts: campaign-global.lua, ordos03a.lua, ordos03a-AI.lua
MissionData: MissionData:
Briefing: The Harkonnen hinder the production of Spice. A Harkonnen attack will disrupt efficient production. Inefficiency cannot be tolerated. The Harkonnen must be eliminated.\n\nNew weapons are available - the Quads. Newer weapons are more powerful. Powerful weapons ensure victory. Briefing: The Harkonnen hinder the production of Spice. A Harkonnen attack will disrupt efficient production. Inefficiency cannot be tolerated. The Harkonnen must be eliminated.\n\nNew weapons are available - the Quads. Newer weapons are more powerful. Powerful weapons ensure victory.
BriefingVideo: O_BR03_E.VQA BriefingVideo: O_BR03_E.VQA

View File

@@ -1,4 +1,11 @@
IdlingUnits = { } --[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
AttackGroupSize = AttackGroupSize =
{ {
@@ -17,143 +24,27 @@ AttackDelays =
HarkonnenInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" } HarkonnenInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" }
HarkonnenVehicleTypes = { "trike", "trike", "quad" } HarkonnenVehicleTypes = { "trike", "trike", "quad" }
HarvesterKilled = true
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function()
local units = { }
for i = 0, AttackGroupSize[Map.LobbyOption("difficulty")], 1 do
if #IdlingUnits == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits + 1)
if IdlingUnits[number] and not IdlingUnits[number].IsDead then
units[i] = IdlingUnits[number]
table.remove(IdlingUnits, number)
end
end
return units
end
SendAttack = function()
if IsAttacking then
return
end
IsAttacking = true
HoldProduction = true
local units = SetupAttackGroup()
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
IsAttacking = false
HoldProduction = false
end)
end
ProtectHarvester = function(unit)
DefendActor(unit)
Trigger.OnKilled(unit, function() HarvesterKilled = true end)
end
DefendActor = function(unit)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing then
return
end
AttackOnGoing = true
local Guards = SetupAttackGroup()
if #Guards <= 0 then
AttackOnGoing = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing = false end)
end)
end
InitAIUnits = function() InitAIUnits = function()
IdlingUnits = Reinforcements.Reinforce(harkonnen, HarkonnenInitialReinforcements, HarkonnenInitialPath) IdlingUnits[harkonnen] = Reinforcements.Reinforce(harkonnen, HarkonnenInitialReinforcements, HarkonnenInitialPath)
Utils.Do(HarkonnenBase, function(actor) DefendAndRepairBase(harkonnen, HarkonnenBase, 0.75, AttackGroupSize[Difficulty])
DefendActor(actor)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end
ProduceInfantry = function()
if HBarracks.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceInfantry)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(HarkonnenInfantryTypes) }
harkonnen.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceInfantry)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end
ProduceVehicles = function()
if HLightFactory.IsDead then
return
end
if HoldProduction then
Trigger.AfterDelay(DateTime.Minutes(1), ProduceVehicles)
return
end
local delay = Utils.RandomInteger(AttackDelays[Map.LobbyOption("difficulty")][1], AttackDelays[Map.LobbyOption("difficulty")][2] + 1)
local toBuild = { Utils.Random(HarkonnenVehicleTypes) }
harkonnen.Build(toBuild, function(unit)
IdlingUnits[#IdlingUnits + 1] = unit[1]
Trigger.AfterDelay(delay, ProduceVehicles)
if #IdlingUnits >= (AttackGroupSize[Map.LobbyOption("difficulty")] * 2.5) then
SendAttack()
end
end)
end end
ActivateAI = function() ActivateAI = function()
HarvesterKilled[harkonnen] = true
Trigger.AfterDelay(0, InitAIUnits) Trigger.AfterDelay(0, InitAIUnits)
HConyard.Produce(OrdosUpgrades[1]) HConyard.Produce(OrdosUpgrades[1])
HConyard.Produce(OrdosUpgrades[2]) HConyard.Produce(OrdosUpgrades[2])
local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
local infantryToBuild = function() return { Utils.Random(HarkonnenInfantryTypes) } end
local vehilcesToBuild = function() return { Utils.Random(HarkonnenVehicleTypes) } end
local attackThresholdSize = AttackGroupSize[Difficulty] * 2.5
-- Finish the upgrades first before trying to build something -- Finish the upgrades first before trying to build something
Trigger.AfterDelay(DateTime.Seconds(14), function() Trigger.AfterDelay(DateTime.Seconds(14), function()
ProduceInfantry() ProduceUnits(harkonnen, HBarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
ProduceVehicles() ProduceUnits(harkonnen, HLightFactory, delay, vehilcesToBuild, AttackGroupSize[Difficulty], attackThresholdSize)
end) end)
end end

View File

@@ -1,3 +1,12 @@
--[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
HarkonnenBase = { HBarracks, HWindTrap1, HWindTrap2, HWindTrap3, HWindTrap4, HLightFactory, HOutpost, HConyard, HRefinery, HSilo1, HSilo2, HSilo3, HSilo4 } HarkonnenBase = { HBarracks, HWindTrap1, HWindTrap2, HWindTrap3, HWindTrap4, HLightFactory, HOutpost, HConyard, HRefinery, HSilo1, HSilo2, HSilo3, HSilo4 }
HarkonnenBaseAreaTrigger = { CPos.New(2, 58), CPos.New(3, 58), CPos.New(4, 58), CPos.New(5, 58), CPos.New(6, 58), CPos.New(7, 58), CPos.New(8, 58), CPos.New(9, 58), CPos.New(10, 58), CPos.New(11, 58), CPos.New(12, 58), CPos.New(13, 58), CPos.New(14, 58), CPos.New(15, 58), CPos.New(16, 58), CPos.New(16, 59), CPos.New(16, 60) } HarkonnenBaseAreaTrigger = { CPos.New(2, 58), CPos.New(3, 58), CPos.New(4, 58), CPos.New(5, 58), CPos.New(6, 58), CPos.New(7, 58), CPos.New(8, 58), CPos.New(9, 58), CPos.New(10, 58), CPos.New(11, 58), CPos.New(12, 58), CPos.New(13, 58), CPos.New(14, 58), CPos.New(15, 58), CPos.New(16, 58), CPos.New(16, 59), CPos.New(16, 60) }
@@ -96,40 +105,10 @@ OrdosReinforcementDelays =
OrdosBaseBuildings = { "barracks", "light_factory" } OrdosBaseBuildings = { "barracks", "light_factory" }
OrdosUpgrades = { "upgrade.barracks", "upgrade.light" } OrdosUpgrades = { "upgrade.barracks", "upgrade.light" }
wave = 0
SendHarkonnen = function()
Trigger.AfterDelay(HarkonnenAttackDelay[Map.LobbyOption("difficulty")], function()
if player.IsObjectiveCompleted(KillHarkonnen) then
return
end
wave = wave + 1
if wave > HarkonnenAttackWaves[Map.LobbyOption("difficulty")] then
return
end
local path = Utils.Random(HarkonnenPaths)
local units = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", HarkonnenReinforcements[Map.LobbyOption("difficulty")][wave], path, { path[1] })[2]
Utils.Do(units, IdleHunt)
SendHarkonnen()
end)
end
MessageCheck = function(index) MessageCheck = function(index)
return #player.GetActorsByType(OrdosBaseBuildings[index]) > 0 and not player.HasPrerequisites({ OrdosUpgrades[index] }) return #player.GetActorsByType(OrdosBaseBuildings[index]) > 0 and not player.HasPrerequisites({ OrdosUpgrades[index] })
end end
SendHunters = function(areaTrigger, unit, path, check)
Trigger.OnEnteredFootprint(areaTrigger, function(a, id)
if not check and a.Owner == player then
local units = Reinforcements.ReinforceWithTransport(harkonnen, "carryall.reinforce", unit, path, { path[1] })[2]
Utils.Do(units, IdleHunt)
check = true
end
end)
end
SendOrdosReinforcements = function(timer, unit, path) SendOrdosReinforcements = function(timer, unit, path)
Trigger.AfterDelay(timer, function() Trigger.AfterDelay(timer, function()
Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", unit, path, { path[1] }) Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", unit, path, { path[1] })
@@ -148,12 +127,12 @@ Tick = function()
player.MarkCompletedObjective(KillHarkonnen) player.MarkCompletedObjective(KillHarkonnen)
end end
if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled then if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled[harkonnen] then
local units = harkonnen.GetActorsByType("harvester") local units = harkonnen.GetActorsByType("harvester")
if #units > 0 then if #units > 0 then
HarvesterKilled = false HarvesterKilled[harkonnen] = false
ProtectHarvester(units[1]) ProtectHarvester(units[1], harkonnen, AttackGroupSize[Difficulty])
end end
end end
@@ -166,7 +145,9 @@ WorldLoaded = function()
harkonnen = Player.GetPlayer("Harkonnen") harkonnen = Player.GetPlayer("Harkonnen")
player = Player.GetPlayer("Ordos") player = Player.GetPlayer("Ordos")
InitObjectives() InitObjectives(player)
KillOrdos = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
KillHarkonnen = player.AddPrimaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
Camera.Position = OConyard.CenterPosition Camera.Position = OConyard.CenterPosition
@@ -174,7 +155,9 @@ WorldLoaded = function()
Utils.Do(harkonnen.GetGroundAttackers(), IdleHunt) Utils.Do(harkonnen.GetGroundAttackers(), IdleHunt)
end) end)
SendHarkonnen() local path = function() return Utils.Random(HarkonnenPaths) end
local waveCondition = function() return player.IsObjectiveCompleted(KillHarkonnen) end
SendCarryallReinforcements(harkonnen, 0, HarkonnenAttackWaves[Difficulty], HarkonnenAttackDelay[Difficulty], path, HarkonnenReinforcements[Difficulty], waveCondition)
ActivateAI() ActivateAI()
SendOrdosReinforcements(OrdosReinforcementDelays[1], OrdosReinforcements[1], OrdosPaths[1]) SendOrdosReinforcements(OrdosReinforcementDelays[1], OrdosReinforcements[1], OrdosPaths[1])
@@ -184,34 +167,7 @@ WorldLoaded = function()
Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", OrdosReinforcements[2], OrdosPaths[2], { OrdosPaths[2][1] }) Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", OrdosReinforcements[2], OrdosPaths[2], { OrdosPaths[2][1] })
end) end)
SendHunters(HarkonnenBaseAreaTrigger, HarkonnenHunters[1], HarkonnenHunterPaths[1], HuntersSent1) TriggerCarryallReinforcements(player, harkonnen, HarkonnenBaseAreaTrigger, HarkonnenHunters[1], HarkonnenHunterPaths[1])
SendHunters(HarkonnenBaseAreaTrigger, HarkonnenHunters[2], HarkonnenHunterPaths[2], HuntersSent2) TriggerCarryallReinforcements(player, harkonnen, HarkonnenBaseAreaTrigger, HarkonnenHunters[2], HarkonnenHunterPaths[2])
SendHunters(HarkonnenBaseAreaTrigger, HarkonnenHunters[3], HarkonnenHunterPaths[3], HuntersSent3) TriggerCarryallReinforcements(player, harkonnen, HarkonnenBaseAreaTrigger, HarkonnenHunters[3], HarkonnenHunterPaths[3])
end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillOrdos = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
KillHarkonnen = player.AddPrimaryObjective("Eliminate all Harkonnen units and reinforcements\nin the area.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: ordos03b.lua, ordos03b-AI.lua Scripts: campaign-global.lua, ordos03b.lua, ordos03b-AI.lua
MissionData: MissionData:
Briefing: The Harkonnen hinder the production of Spice. A Harkonnen attack will disrupt efficient production. Inefficiency cannot be tolerated. The Harkonnen must be eliminated.\n\nNew weapons are available - the Quads. Newer weapons are more powerful. Powerful weapons ensure victory. Briefing: The Harkonnen hinder the production of Spice. A Harkonnen attack will disrupt efficient production. Inefficiency cannot be tolerated. The Harkonnen must be eliminated.\n\nNew weapons are available - the Quads. Newer weapons are more powerful. Powerful weapons ensure victory.
BriefingVideo: O_BR03_E.VQA BriefingVideo: O_BR03_E.VQA

View File

@@ -1,8 +1,11 @@
IdlingUnits = --[[
{ Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
Harkonnen = { }, This file is part of OpenRA, which is free software. It is made
Smugglers = { } available to you under the terms of the GNU General Public License
} as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
AttackGroupSize = AttackGroupSize =
{ {
@@ -26,155 +29,30 @@ HarkonnenTankType = { "combat_tank_h" }
SmugglerVehicleTypes = { "raider", "raider", "quad" } SmugglerVehicleTypes = { "raider", "raider", "quad" }
SmugglerTankType = { "combat_tank_o" } SmugglerTankType = { "combat_tank_o" }
IsAttacking =
{
Harkonnen = false,
Smugglers = false
}
AttackOnGoing =
{
Harkonnen = false,
Smugglers = false
}
HoldProduction =
{
Harkonnen = false,
Smugglers = false
}
HarvesterKilled =
{
Harkonnen = true,
Smugglers = true
}
IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, unit.Hunt) end end
SetupAttackGroup = function(house)
local units = { }
for i = 0, AttackGroupSize[Difficulty], 1 do
if #IdlingUnits[house.Name] == 0 then
return units
end
local number = Utils.RandomInteger(1, #IdlingUnits[house.Name])
if IdlingUnits[house.Name][number] and not IdlingUnits[house.Name][number].IsDead then
units[i] = IdlingUnits[house.Name][number]
table.remove(IdlingUnits[house.Name], number)
end
end
return units
end
SendAttack = function(house)
if IsAttacking[house.Name] then
return
end
IsAttacking[house.Name] = true
HoldProduction[house.Name] = true
local units = SetupAttackGroup(house)
Utils.Do(units, function(unit)
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(units, function()
IsAttacking[house.Name] = false
HoldProduction[house.Name] = false
end)
end
ProtectHarvester = function(unit, house)
DefendActor(unit, house)
Trigger.OnKilled(unit, function() HarvesterKilled[house.Name] = true end)
end
DefendActor = function(unit, house)
Trigger.OnDamaged(unit, function(self, attacker)
if AttackOnGoing[house.Name] then
return
end
AttackOnGoing[house.Name] = true
-- Don't try to attack spiceblooms
if attacker and attacker.Type == "spicebloom" then
return
end
local Guards = SetupAttackGroup(house)
if #Guards <= 0 then
AttackOnGoing[house.Name] = false
return
end
Utils.Do(Guards, function(unit)
if not self.IsDead then
unit.AttackMove(self.Location)
end
IdleHunt(unit)
end)
Trigger.OnAllRemovedFromWorld(Guards, function() AttackOnGoing[house.Name] = false end)
end)
end
InitAIUnits = function(house) InitAIUnits = function(house)
IdlingUnits[house.Name] = Reinforcements.Reinforce(house, InitialReinforcements[house.Name], InitialReinforcementsPaths[house.Name]) HarvesterKilled[house] = true
IdlingUnits[house] = Reinforcements.Reinforce(house, InitialReinforcements[house.Name], InitialReinforcementsPaths[house.Name])
Utils.Do(Base[house.Name], function(actor) DefendAndRepairBase(house, Base[house.Name], 0.75, AttackGroupSize[Difficulty])
DefendActor(actor, house)
Trigger.OnDamaged(actor, function(building)
if building.Health < building.MaxHealth * 3/4 and building.Owner.Name == house.Name then
building.StartBuildingRepairs()
end
end)
end)
end
Produce = function(house, units, factory)
if factory.IsDead then
return
end
if HoldProduction[house.Name] then
Trigger.AfterDelay(DateTime.Seconds(30), function() Produce(house, units, factory) end)
return
end
local delay = Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1)
local toBuild = { Utils.Random(units) }
house.Build(toBuild, function(unit)
local unitCount = 1
if IdlingUnits[house.Name] then
unitCount = 1 + #IdlingUnits[house.Name]
end
IdlingUnits[house.Name][unitCount] = unit[1]
Trigger.AfterDelay(delay, function() Produce(house, units, factory) end)
if unitCount >= (AttackGroupSize[Difficulty] * 2.5) then
SendAttack(house)
end
end)
end end
ActivateAI = function() ActivateAI = function()
InitAIUnits(harkonnen) InitAIUnits(harkonnen)
InitAIUnits(smuggler) InitAIUnits(smuggler)
-- Finish the upgrades first before trying to build something local delay = function() return Utils.RandomInteger(AttackDelays[Difficulty][1], AttackDelays[Difficulty][2] + 1) end
Trigger.AfterDelay(DateTime.Seconds(14), function() local infantryToBuild = function() return { Utils.Random(EnemyInfantryTypes) } end
Produce(harkonnen, EnemyInfantryTypes, HBarracks) local hVehiclesToBuild = function() return { Utils.Random(HarkonnenVehicleTypes) } end
Produce(harkonnen, HarkonnenVehicleTypes, HLightFactory) local hTanksToBuild = function() return HarkonnenTankType end
Produce(harkonnen, HarkonnenTankType, HHeavyFactory) local sVehiclesToBuild = function() return { Utils.Random(SmugglerVehicleTypes) } end
local sTanksToBuild = function() return SmugglerTankType end
local attackTresholdSize = AttackGroupSize[Difficulty] * 2.5
Produce(smuggler, EnemyInfantryTypes, SBarracks) ProduceUnits(harkonnen, HBarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackTresholdSize)
Produce(smuggler, SmugglerVehicleTypes, SLightFactory) ProduceUnits(harkonnen, HLightFactory, delay, hVehiclesToBuild, AttackGroupSize[Difficulty], attackTresholdSize)
Produce(smuggler, SmugglerTankType, SHeavyFactory) ProduceUnits(harkonnen, HHeavyFactory, delay, hTanksToBuild, AttackGroupSize[Difficulty], attackTresholdSize)
end)
ProduceUnits(smuggler, SBarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackTresholdSize)
ProduceUnits(smuggler, SLightFactory, delay, sVehiclesToBuild, AttackGroupSize[Difficulty], attackTresholdSize)
ProduceUnits(smuggler, SHeavyFactory, delay, sTanksToBuild, AttackGroupSize[Difficulty], attackTresholdSize)
end end

View File

@@ -1,3 +1,12 @@
--[[
Copyright 2007-2017 The OpenRA Developers (see AUTHORS)
This file is part of OpenRA, which is free software. It is made
available to you under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version. For more
information, see COPYING.
]]
Base = Base =
{ {
Harkonnen = { HRefinery, SHeavyFactory, SLightFactory, HGunTurret1, HGunTurret2, HGunTurret3, HGunTurret4, HGunTurret5, SBarracks, HPower1, HPower2, HPower3, HPower4 }, Harkonnen = { HRefinery, SHeavyFactory, SLightFactory, HGunTurret1, HGunTurret2, HGunTurret3, HGunTurret4, HGunTurret5, SBarracks, HPower1, HPower2, HPower3, HPower4 },
@@ -62,12 +71,12 @@ Hunt = function(house)
end end
CheckHarvester = function(house) CheckHarvester = function(house)
if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled[house.Name] then if DateTime.GameTime % DateTime.Seconds(30) and HarvesterKilled[house] then
local units = house.GetActorsByType("harvester") local units = house.GetActorsByType("harvester")
if #units > 0 then if #units > 0 then
HarvesterKilled[house.Name] = false HarvesterKilled[house] = false
ProtectHarvester(units[1], house) ProtectHarvester(units[1], house, AttackGroupSize[Difficulty])
end end
end end
end end
@@ -86,15 +95,6 @@ Tick = function()
CheckHarvester(harkonnen) CheckHarvester(harkonnen)
CheckHarvester(smuggler) CheckHarvester(smuggler)
if SOutpost.IsDead then
player.MarkFailedObjective(CaptureOutpost)
end
if SOutpost.Owner == player then
player.MarkCompletedObjective(CaptureOutpost)
smuggler.MarkFailedObjective(DefendOutpost)
end
end end
WorldLoaded = function() WorldLoaded = function()
@@ -102,9 +102,12 @@ WorldLoaded = function()
smuggler = Player.GetPlayer("Smugglers") smuggler = Player.GetPlayer("Smugglers")
player = Player.GetPlayer("Ordos") player = Player.GetPlayer("Ordos")
Difficulty = Map.LobbyOption("difficulty") InitObjectives(player)
KillOrdosH = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
InitObjectives() KillOrdosS = smuggler.AddSecondaryObjective("Kill all Ordos units.")
DefendOutpost = smuggler.AddPrimaryObjective("Don't let the outpost to be captured or destroyed.")
CaptureOutpost = player.AddPrimaryObjective("Capture the Smuggler Outpost.")
KillHarkonnen = player.AddSecondaryObjective("Destroy the Harkonnen.")
Camera.Position = OConyard.CenterPosition Camera.Position = OConyard.CenterPosition
HarkonnenAttackLocation = OConyard.Location HarkonnenAttackLocation = OConyard.Location
@@ -115,12 +118,22 @@ WorldLoaded = function()
SendHarkonnen(LightInfantryRushersPaths[1]) SendHarkonnen(LightInfantryRushersPaths[1])
SendHarkonnen(LightInfantryRushersPaths[2]) SendHarkonnen(LightInfantryRushersPaths[2])
SendHarkonnen(LightInfantryRushersPaths[3]) SendHarkonnen(LightInfantryRushersPaths[3])
ActivateAI()
Actor.Create("upgrade.barracks", true, { Owner = harkonnen }) Actor.Create("upgrade.barracks", true, { Owner = harkonnen })
Actor.Create("upgrade.light", true, { Owner = harkonnen }) Actor.Create("upgrade.light", true, { Owner = harkonnen })
Actor.Create("upgrade.barracks", true, { Owner = smuggler }) Actor.Create("upgrade.barracks", true, { Owner = smuggler })
Actor.Create("upgrade.light", true, { Owner = smuggler }) Actor.Create("upgrade.light", true, { Owner = smuggler })
Trigger.AfterDelay(0, ActivateAI)
Trigger.OnKilled(SOutpost, function()
player.MarkFailedObjective(CaptureOutpost)
end)
Trigger.OnCapture(SOutpost, function()
Trigger.AfterDelay(DateTime.Seconds(2), function()
player.MarkCompletedObjective(CaptureOutpost)
smuggler.MarkFailedObjective(DefendOutpost)
end)
end)
Trigger.AfterDelay(HarkonnenAttackDelay[Difficulty] - DateTime.Seconds(5), function() Trigger.AfterDelay(HarkonnenAttackDelay[Difficulty] - DateTime.Seconds(5), function()
Media.PlaySpeechNotification(player, "Reinforce") Media.PlaySpeechNotification(player, "Reinforce")
@@ -131,33 +144,3 @@ WorldLoaded = function()
Media.DisplayMessage("WARNING: Large force approaching!", "Mentat") Media.DisplayMessage("WARNING: Large force approaching!", "Mentat")
end) end)
end end
InitObjectives = function()
Trigger.OnObjectiveAdded(player, function(p, id)
Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective")
end)
KillOrdosH = harkonnen.AddPrimaryObjective("Kill all Ordos units.")
KillOrdosS = smuggler.AddSecondaryObjective("Kill all Ordos units.")
DefendOutpost = smuggler.AddPrimaryObjective("Don't let the outpost to be captured or destroyed.")
CaptureOutpost = player.AddPrimaryObjective("Capture the Smuggler Outpost.")
KillHarkonnen = player.AddSecondaryObjective("Destroy the Harkonnen.")
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.OnPlayerLost(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Lose")
end)
end)
Trigger.OnPlayerWon(player, function()
Trigger.AfterDelay(DateTime.Seconds(1), function()
Media.PlaySpeechNotification(player, "Win")
end)
end)
end

View File

@@ -4,7 +4,7 @@ Player:
World: World:
LuaScript: LuaScript:
Scripts: ordos04.lua, ordos04-AI.lua Scripts: campaign-global.lua, ordos04.lua, ordos04-AI.lua
MissionData: MissionData:
Briefing: The Smugglers at Sietch Tabr must be neutralized. Capture the Outpost where their families have taken shelter as insurance. The children's lives will assure the loyalties of their fathers. Use an Engineer to enter and capture the building.\n\nThe Smugglers' new partners, the Harkonnen, may attempt to protect them. Harkonnen firepower is great, but we have recently acquired tanks that may counter this.\n\nEnsure our investment is used wisely.\n Briefing: The Smugglers at Sietch Tabr must be neutralized. Capture the Outpost where their families have taken shelter as insurance. The children's lives will assure the loyalties of their fathers. Use an Engineer to enter and capture the building.\n\nThe Smugglers' new partners, the Harkonnen, may attempt to protect them. Harkonnen firepower is great, but we have recently acquired tanks that may counter this.\n\nEnsure our investment is used wisely.\n
BriefingVideo: O_BR04_E.VQA BriefingVideo: O_BR04_E.VQA

View File

@@ -15,6 +15,7 @@ Packages:
~SOUND.RS ~SOUND.RS
d2k|bits d2k|bits
d2k|bits/scripts
d2k|bits/tex d2k|bits/tex
d2k|uibits d2k|uibits