Add base failure, Nod defense to gdi05b & gdi05c
This commit is contained in:
@@ -12,8 +12,8 @@ AllToHuntTrigger =
|
|||||||
Silo1, Proc1, Silo2, Silo3, Silo4, Afld1, Hand1, Nuke1, Nuke2, Nuke3, Fact1
|
Silo1, Proc1, Silo2, Silo3, Silo4, Afld1, Hand1, Nuke1, Nuke2, Nuke3, Fact1
|
||||||
}
|
}
|
||||||
|
|
||||||
AtkRoute1 = { waypoint4.Location, waypoint5.Location, waypoint6.Location, waypoint7.Location, waypoint8.Location }
|
AtkRoute1 = { waypoint4, waypoint5, waypoint6, waypoint7, waypoint8, GDIBaseCenter }
|
||||||
AtkRoute2 = { waypoint0.Location, waypoint1.Location, waypoint2.Location, waypoint3.Location }
|
AtkRoute2 = { waypoint0, waypoint1, waypoint2, waypoint3, GDIBaseCenter }
|
||||||
|
|
||||||
AutoCreateTeams =
|
AutoCreateTeams =
|
||||||
{
|
{
|
||||||
@@ -44,27 +44,35 @@ Atk5CellTriggers =
|
|||||||
CPos.New(49,53), CPos.New(48,53), CPos.New(50,52), CPos.New(49,52)
|
CPos.New(49,53), CPos.New(48,53), CPos.New(50,52), CPos.New(49,52)
|
||||||
}
|
}
|
||||||
|
|
||||||
GDIBase = { GdiNuke1, GdiProc1, GdiWeap1, GdiNuke2, GdiPyle1, GdiSilo1, GdiSilo2, GdiHarv }
|
GDIBase = { GdiNuke1, GdiProc1, GdiWeap1, GdiNuke2, GdiPyle1, GdiSilo1, GdiSilo2 }
|
||||||
GDIUnits = { "e2", "e2", "e2", "e2", "e1", "e1", "e1", "e1", "mtnk", "mtnk", "jeep", "jeep", "apc" }
|
GDIUnits = { "e2", "e2", "e2", "e2", "e1", "e1", "e1", "e1", "mtnk", "mtnk", "jeep", "jeep", "apc" }
|
||||||
NodSams = { Sam1, Sam2, Sam3, Sam4 }
|
NodSams = { Sam1, Sam2, Sam3, Sam4 }
|
||||||
|
NodAttackers = { }
|
||||||
|
EarlyAttackTimer = 0
|
||||||
|
|
||||||
MoveThenHunt = function(actors, path)
|
SendAttackers = function(actors, path)
|
||||||
Utils.Do(actors, function(actor)
|
Utils.Do(actors, function(actor)
|
||||||
actor.Patrol(path, false)
|
local id = #NodAttackers + 1
|
||||||
IdleHunt(actor)
|
NodAttackers[id] = actor
|
||||||
|
|
||||||
|
Trigger.OnKilled(actor, function()
|
||||||
|
NodAttackers[id] = nil
|
||||||
end)
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
MoveAndHunt(actors, path)
|
||||||
end
|
end
|
||||||
|
|
||||||
AutoCreateTeam = function()
|
AutoCreateTeam = function()
|
||||||
local team = Utils.Random(AutoCreateTeams)
|
local team = Utils.Random(AutoCreateTeams)
|
||||||
for type, count in pairs(team.types) do
|
for type, count in pairs(team.types) do
|
||||||
MoveThenHunt(Utils.Take(count, Nod.GetActorsByType(type)), team.route)
|
SendAttackers(Utils.Take(count, Nod.GetActorsByType(type)), team.route)
|
||||||
end
|
end
|
||||||
|
|
||||||
Trigger.AfterDelay(Utils.RandomInteger(AutoAtkMinDelay, AutoAtkMaxDelay), AutoCreateTeam)
|
Trigger.AfterDelay(Utils.RandomInteger(AutoAtkMinDelay, AutoAtkMaxDelay), AutoCreateTeam)
|
||||||
end
|
end
|
||||||
|
|
||||||
DiscoverGDIBase = function(actor, discoverer)
|
DiscoverGDIBase = function(_, discoverer)
|
||||||
if BaseDiscovered or not discoverer == GDI then
|
if BaseDiscovered or not discoverer == GDI then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -77,28 +85,44 @@ DiscoverGDIBase = function(actor, discoverer)
|
|||||||
|
|
||||||
EliminateNod = AddPrimaryObjective(GDI, "eliminate-nod")
|
EliminateNod = AddPrimaryObjective(GDI, "eliminate-nod")
|
||||||
GDI.MarkCompletedObjective(FindBase)
|
GDI.MarkCompletedObjective(FindBase)
|
||||||
|
|
||||||
|
-- Delay spawn to avoid wasted tiberium and enemy attention.
|
||||||
|
if not GdiProc1.IsDead then
|
||||||
|
local origin = GdiProc1.Location + CVec.New(2, 3)
|
||||||
|
Reinforcements.Reinforce(GDI, { "harv" }, { origin, origin + CVec.New(-2, 0) })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
LoseGDIBase = function(location)
|
||||||
|
if BaseDiscovered then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
GDI.MarkFailedObjective(FindBase)
|
||||||
|
Actor.Create("camera", true, { Owner = GDI, Location = location })
|
||||||
|
Camera.Position = Map.CenterOfCell(location)
|
||||||
end
|
end
|
||||||
|
|
||||||
Atk1TriggerFunction = function()
|
Atk1TriggerFunction = function()
|
||||||
MoveThenHunt(Utils.Take(2, Nod.GetActorsByType('e1')), AtkRoute1)
|
SendAttackers(Utils.Take(2, Nod.GetActorsByType('e1')), AtkRoute1)
|
||||||
MoveThenHunt(Utils.Take(3, Nod.GetActorsByType('e3')), AtkRoute1)
|
SendAttackers(Utils.Take(3, Nod.GetActorsByType('e3')), AtkRoute1)
|
||||||
end
|
end
|
||||||
|
|
||||||
Atk2TriggerFunction = function()
|
Atk2TriggerFunction = function()
|
||||||
MoveThenHunt(Utils.Take(3, Nod.GetActorsByType('e1')), AtkRoute2)
|
SendAttackers(Utils.Take(3, Nod.GetActorsByType('e1')), AtkRoute2)
|
||||||
MoveThenHunt(Utils.Take(3, Nod.GetActorsByType('e3')), AtkRoute2)
|
SendAttackers(Utils.Take(3, Nod.GetActorsByType('e3')), AtkRoute2)
|
||||||
end
|
end
|
||||||
|
|
||||||
Atk3TriggerFunction = function()
|
Atk3TriggerFunction = function()
|
||||||
MoveThenHunt(Utils.Take(1, Nod.GetActorsByType('bggy')), AtkRoute1)
|
SendAttackers(Utils.Take(1, Nod.GetActorsByType('bggy')), AtkRoute1)
|
||||||
end
|
end
|
||||||
|
|
||||||
Atk4TriggerFunction = function()
|
Atk4TriggerFunction = function()
|
||||||
MoveThenHunt(Utils.Take(1, Nod.GetActorsByType('bggy')), AtkRoute2)
|
SendAttackers(Utils.Take(1, Nod.GetActorsByType('bggy')), AtkRoute2)
|
||||||
end
|
end
|
||||||
|
|
||||||
Atk5TriggerFunction = function()
|
Atk5TriggerFunction = function()
|
||||||
MoveThenHunt(Utils.Take(1, Nod.GetActorsByType('ltnk')), AtkRoute2)
|
SendAttackers(Utils.Take(1, Nod.GetActorsByType('ltnk')), AtkRoute2)
|
||||||
end
|
end
|
||||||
|
|
||||||
InsertGDIUnits = function()
|
InsertGDIUnits = function()
|
||||||
@@ -106,6 +130,78 @@ InsertGDIUnits = function()
|
|||||||
Reinforcements.Reinforce(GDI, GDIUnits, { UnitsEntry.Location, UnitsRally.Location }, 15)
|
Reinforcements.Reinforce(GDI, GDIUnits, { UnitsEntry.Location, UnitsRally.Location }, 15)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ScheduleNodAttacks = function()
|
||||||
|
Trigger.AfterDelay(Atk1Delay, Atk1TriggerFunction)
|
||||||
|
Trigger.AfterDelay(Atk2Delay, Atk2TriggerFunction)
|
||||||
|
Trigger.AfterDelay(Atk3Delay, Atk3TriggerFunction)
|
||||||
|
Trigger.AfterDelay(Atk4Delay, Atk4TriggerFunction)
|
||||||
|
Trigger.OnEnteredFootprint(Atk5CellTriggers, function(a, id)
|
||||||
|
if a.Owner == GDI then
|
||||||
|
Atk5TriggerFunction()
|
||||||
|
Trigger.RemoveFootprintTrigger(id)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
Trigger.AfterDelay(AutoAtkStartDelay, AutoCreateTeam)
|
||||||
|
|
||||||
|
Trigger.AfterDelay(DateTime.Seconds(40), function()
|
||||||
|
local delay = function() return DateTime.Seconds(30) end
|
||||||
|
local toBuild = function() return { "e1" } end
|
||||||
|
ProduceUnits(Nod, Hand1, delay, toBuild)
|
||||||
|
end)
|
||||||
|
|
||||||
|
Trigger.OnAllRemovedFromWorld(AllToHuntTrigger, function()
|
||||||
|
Utils.Do(Nod.GetGroundAttackers(), IdleHunt)
|
||||||
|
end)
|
||||||
|
|
||||||
|
local baseDefenses = Nod.GetActorsByTypes({ "sam", "gun" })
|
||||||
|
local pullBuildings = Utils.Concat(AllToHuntTrigger, baseDefenses)
|
||||||
|
|
||||||
|
Utils.Do(pullBuildings, function(building)
|
||||||
|
-- Skip the lone SAM that is not part of the Nod base.
|
||||||
|
if building == Sam4 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
Trigger.OnDamaged(building, OnNodBaseDamaged)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
OnNodBaseDamaged = function(building, attacker)
|
||||||
|
if BaseDiscovered then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if EarlyAttackTimer > 0 or attacker.Owner ~= GDI then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
EarlyAttackTimer = DateTime.Seconds(10)
|
||||||
|
|
||||||
|
if attacker.IsDead then
|
||||||
|
PullAttackers(building.Location)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
PullAttackers(attacker.Location)
|
||||||
|
end
|
||||||
|
|
||||||
|
PullAttackers = function(location)
|
||||||
|
Utils.Do(NodAttackers, function(attacker)
|
||||||
|
if attacker.IsDead or attacker.Stance == "Defend" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Ignore structures.
|
||||||
|
attacker.Stance = "Defend"
|
||||||
|
attacker.Stop()
|
||||||
|
attacker.AttackMove(location, 2)
|
||||||
|
attacker.CallFunc(function()
|
||||||
|
-- No targets nearby. Reset stance for IdleHunt.
|
||||||
|
attacker.Stance = "AttackAnything"
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
WorldLoaded = function()
|
WorldLoaded = function()
|
||||||
GDI = Player.GetPlayer("GDI")
|
GDI = Player.GetPlayer("GDI")
|
||||||
AbandonedBase = Player.GetPlayer("AbandonedBase")
|
AbandonedBase = Player.GetPlayer("AbandonedBase")
|
||||||
@@ -119,30 +215,13 @@ WorldLoaded = function()
|
|||||||
DestroySAMs = AddSecondaryObjective(GDI, "destroy-sams")
|
DestroySAMs = AddSecondaryObjective(GDI, "destroy-sams")
|
||||||
NodObjective = AddPrimaryObjective(Nod, "")
|
NodObjective = AddPrimaryObjective(Nod, "")
|
||||||
|
|
||||||
Trigger.AfterDelay(Atk1Delay, Atk1TriggerFunction)
|
|
||||||
Trigger.AfterDelay(Atk2Delay, Atk2TriggerFunction)
|
|
||||||
Trigger.AfterDelay(Atk3Delay, Atk3TriggerFunction)
|
|
||||||
Trigger.AfterDelay(Atk4Delay, Atk4TriggerFunction)
|
|
||||||
Trigger.OnEnteredFootprint(Atk5CellTriggers, function(a, id)
|
|
||||||
if a.Owner == GDI then
|
|
||||||
Atk5TriggerFunction()
|
|
||||||
Trigger.RemoveFootprintTrigger(id)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
Trigger.AfterDelay(AutoAtkStartDelay, AutoCreateTeam)
|
|
||||||
|
|
||||||
Trigger.OnAllRemovedFromWorld(AllToHuntTrigger, function()
|
|
||||||
Utils.Do(Nod.GetGroundAttackers(), IdleHunt)
|
|
||||||
end)
|
|
||||||
|
|
||||||
Trigger.AfterDelay(DateTime.Seconds(40), function()
|
|
||||||
local delay = function() return DateTime.Seconds(30) end
|
|
||||||
local toBuild = function() return { "e1" } end
|
|
||||||
ProduceUnits(Nod, Hand1, delay, toBuild)
|
|
||||||
end)
|
|
||||||
|
|
||||||
Trigger.OnPlayerDiscovered(AbandonedBase, DiscoverGDIBase)
|
Trigger.OnPlayerDiscovered(AbandonedBase, DiscoverGDIBase)
|
||||||
|
|
||||||
|
local revealCell = GdiNuke1.Location
|
||||||
|
Trigger.OnAllKilled(GDIBase, function()
|
||||||
|
LoseGDIBase(revealCell)
|
||||||
|
end)
|
||||||
|
|
||||||
Trigger.OnAllKilled(NodSams, function()
|
Trigger.OnAllKilled(NodSams, function()
|
||||||
GDI.MarkCompletedObjective(DestroySAMs)
|
GDI.MarkCompletedObjective(DestroySAMs)
|
||||||
Actor.Create("airstrike.proxy", true, { Owner = GDI })
|
Actor.Create("airstrike.proxy", true, { Owner = GDI })
|
||||||
@@ -151,6 +230,7 @@ WorldLoaded = function()
|
|||||||
Camera.Position = UnitsRally.CenterPosition
|
Camera.Position = UnitsRally.CenterPosition
|
||||||
|
|
||||||
InsertGDIUnits()
|
InsertGDIUnits()
|
||||||
|
ScheduleNodAttacks()
|
||||||
end
|
end
|
||||||
|
|
||||||
Tick = function()
|
Tick = function()
|
||||||
@@ -158,7 +238,12 @@ Tick = function()
|
|||||||
Nod.MarkCompletedObjective(NodObjective)
|
Nod.MarkCompletedObjective(NodObjective)
|
||||||
end
|
end
|
||||||
|
|
||||||
if BaseDiscovered and Nod.HasNoRequiredUnits() then
|
if not BaseDiscovered then
|
||||||
|
EarlyAttackTimer = EarlyAttackTimer - 1
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if Nod.HasNoRequiredUnits() then
|
||||||
GDI.MarkCompletedObjective(EliminateNod)
|
GDI.MarkCompletedObjective(EliminateNod)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -567,7 +567,7 @@ Actors:
|
|||||||
Fact1: fact
|
Fact1: fact
|
||||||
Location: 51,17
|
Location: 51,17
|
||||||
Owner: Nod
|
Owner: Nod
|
||||||
GdiNuke1: nuke
|
GdiNuke2: nuke
|
||||||
Location: 33,51
|
Location: 33,51
|
||||||
Owner: AbandonedBase
|
Owner: AbandonedBase
|
||||||
Health: 46
|
Health: 46
|
||||||
@@ -576,15 +576,11 @@ Actors:
|
|||||||
Owner: AbandonedBase
|
Owner: AbandonedBase
|
||||||
Health: 48
|
Health: 48
|
||||||
FreeActor: False
|
FreeActor: False
|
||||||
GdiHarv: harv
|
|
||||||
Location: 27,55
|
|
||||||
Owner: AbandonedBase
|
|
||||||
Facing: 256
|
|
||||||
GdiWeap1: weap
|
GdiWeap1: weap
|
||||||
Location: 35,52
|
Location: 35,52
|
||||||
Owner: AbandonedBase
|
Owner: AbandonedBase
|
||||||
Health: 41
|
Health: 41
|
||||||
GdiNuke2: nuke
|
GdiNuke1: nuke
|
||||||
Location: 31,51
|
Location: 31,51
|
||||||
Owner: AbandonedBase
|
Owner: AbandonedBase
|
||||||
Health: 39
|
Health: 39
|
||||||
@@ -611,6 +607,9 @@ Actors:
|
|||||||
Sam4: sam
|
Sam4: sam
|
||||||
Location: 26,37
|
Location: 26,37
|
||||||
Owner: Nod
|
Owner: Nod
|
||||||
|
GDIBaseCenter: waypoint
|
||||||
|
Owner: Neutral
|
||||||
|
Location: 32,53
|
||||||
|
|
||||||
Rules: cnc|rules/campaign-maprules.yaml, cnc|rules/campaign-tooltips.yaml, cnc|rules/campaign-palettes.yaml, rules.yaml
|
Rules: cnc|rules/campaign-maprules.yaml, cnc|rules/campaign-tooltips.yaml, cnc|rules/campaign-palettes.yaml, rules.yaml
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ ActorRemovals =
|
|||||||
|
|
||||||
AllToHuntTrigger = { Silo1, Proc1, Silo2, Radar1, Afld1, Hand1, Nuke1, Nuke2, Nuke3, Fact1 }
|
AllToHuntTrigger = { Silo1, Proc1, Silo2, Radar1, Afld1, Hand1, Nuke1, Nuke2, Nuke3, Fact1 }
|
||||||
|
|
||||||
AtkRoute1 = { waypoint0, waypoint1, waypoint2, waypoint3, waypoint4 }
|
AtkRoute1 = { waypoint0, waypoint1, waypoint2, waypoint3, waypoint4, GDIBaseCenter }
|
||||||
AtkRoute2 = { waypoint0, waypoint8, waypoint4 }
|
AtkRoute2 = { waypoint0, waypoint8, waypoint4, GDIBaseCenter }
|
||||||
AtkRoute3 = { waypoint0, waypoint1, waypoint2, waypoint5, waypoint6, waypoint7 }
|
AtkRoute3 = { waypoint0, waypoint1, waypoint2, waypoint5, waypoint6, waypoint7, GDIBaseCenter }
|
||||||
AtkRoute4 = { waypoint0, waypoint8, waypoint9, waypoint10, waypoint11 }
|
AtkRoute4 = { waypoint0, waypoint8, waypoint9, waypoint10, waypoint11, GDIBaseCenter }
|
||||||
|
|
||||||
AutoCreateTeams =
|
AutoCreateTeams =
|
||||||
{
|
{
|
||||||
@@ -46,17 +46,32 @@ GDIBase = { GdiNuke1, GdiProc1, GdiWeap1, GdiNuke2, GdiNuke3, GdiPyle1, GdiSilo1
|
|||||||
GDIUnits = { "e2", "e2", "e2", "e2", "e1", "e1", "e1", "e1", "mtnk", "mtnk", "jeep", "apc", "apc" }
|
GDIUnits = { "e2", "e2", "e2", "e2", "e1", "e1", "e1", "e1", "mtnk", "mtnk", "jeep", "apc", "apc" }
|
||||||
GDIHarvester = { "harv" }
|
GDIHarvester = { "harv" }
|
||||||
NodSams = { Sam1, Sam2, Sam3 }
|
NodSams = { Sam1, Sam2, Sam3 }
|
||||||
|
NodAttackers = { }
|
||||||
|
EarlyAttackTimer = 0
|
||||||
|
|
||||||
|
SendAttackers = function(actors, path)
|
||||||
|
Utils.Do(actors, function(actor)
|
||||||
|
local id = #NodAttackers + 1
|
||||||
|
NodAttackers[id] = actor
|
||||||
|
|
||||||
|
Trigger.OnKilled(actor, function()
|
||||||
|
NodAttackers[id] = nil
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
MoveAndHunt(actors, path)
|
||||||
|
end
|
||||||
|
|
||||||
AutoCreateTeam = function()
|
AutoCreateTeam = function()
|
||||||
local team = Utils.Random(AutoCreateTeams)
|
local team = Utils.Random(AutoCreateTeams)
|
||||||
for type, count in pairs(team.types) do
|
for type, count in pairs(team.types) do
|
||||||
MoveAndHunt(Utils.Take(count, Nod.GetActorsByType(type)), team.route)
|
SendAttackers(Utils.Take(count, Nod.GetActorsByType(type)), team.route)
|
||||||
end
|
end
|
||||||
|
|
||||||
Trigger.AfterDelay(Utils.RandomInteger(AutoAtkMinDelay[Difficulty], AutoAtkMaxDelay[Difficulty]), AutoCreateTeam)
|
Trigger.AfterDelay(Utils.RandomInteger(AutoAtkMinDelay[Difficulty], AutoAtkMaxDelay[Difficulty]), AutoCreateTeam)
|
||||||
end
|
end
|
||||||
|
|
||||||
DiscoverGDIBase = function(actor, discoverer)
|
DiscoverGDIBase = function(_, discoverer)
|
||||||
if BaseDiscovered or not discoverer == GDI then
|
if BaseDiscovered or not discoverer == GDI then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -76,22 +91,32 @@ DiscoverGDIBase = function(actor, discoverer)
|
|||||||
GDI.MarkCompletedObjective(FindBase)
|
GDI.MarkCompletedObjective(FindBase)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
LoseGDIBase = function(location)
|
||||||
|
if BaseDiscovered then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
GDI.MarkFailedObjective(FindBase)
|
||||||
|
Actor.Create("camera", true, { Owner = GDI, Location = location })
|
||||||
|
Camera.Position = Map.CenterOfCell(location)
|
||||||
|
end
|
||||||
|
|
||||||
Atk1TriggerFunction = function()
|
Atk1TriggerFunction = function()
|
||||||
MoveAndHunt(Utils.Take(2, Nod.GetActorsByType('e1')), AtkRoute1)
|
SendAttackers(Utils.Take(2, Nod.GetActorsByType('e1')), AtkRoute1)
|
||||||
MoveAndHunt(Utils.Take(2, Nod.GetActorsByType('e3')), AtkRoute1)
|
SendAttackers(Utils.Take(2, Nod.GetActorsByType('e3')), AtkRoute1)
|
||||||
end
|
end
|
||||||
|
|
||||||
Atk2TriggerFunction = function()
|
Atk2TriggerFunction = function()
|
||||||
MoveAndHunt(Utils.Take(4, Nod.GetActorsByType('e3')), AtkRoute2)
|
SendAttackers(Utils.Take(4, Nod.GetActorsByType('e3')), AtkRoute2)
|
||||||
end
|
end
|
||||||
|
|
||||||
Atk3TriggerFunction = function()
|
Atk3TriggerFunction = function()
|
||||||
MoveAndHunt(Utils.Take(1, Nod.GetActorsByType('bggy')), AtkRoute2)
|
SendAttackers(Utils.Take(1, Nod.GetActorsByType('bggy')), AtkRoute2)
|
||||||
end
|
end
|
||||||
|
|
||||||
Atk4TriggerFunction = function()
|
Atk4TriggerFunction = function()
|
||||||
MoveAndHunt(Utils.Take(2, Nod.GetActorsByType('e1')), AtkRoute1)
|
SendAttackers(Utils.Take(2, Nod.GetActorsByType('e1')), AtkRoute1)
|
||||||
MoveAndHunt(Utils.Take(1, Nod.GetActorsByType('ltnk')), AtkRoute1)
|
SendAttackers(Utils.Take(1, Nod.GetActorsByType('ltnk')), AtkRoute1)
|
||||||
end
|
end
|
||||||
|
|
||||||
InsertGDIUnits = function()
|
InsertGDIUnits = function()
|
||||||
@@ -99,6 +124,69 @@ InsertGDIUnits = function()
|
|||||||
Reinforcements.Reinforce(GDI, GDIUnits, { UnitsEntry.Location, UnitsRally.Location }, 15)
|
Reinforcements.Reinforce(GDI, GDIUnits, { UnitsEntry.Location, UnitsRally.Location }, 15)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ScheduleNodAttacks = function()
|
||||||
|
Trigger.AfterDelay(Atk1Delay[Difficulty], Atk1TriggerFunction)
|
||||||
|
Trigger.AfterDelay(Atk2Delay[Difficulty], Atk2TriggerFunction)
|
||||||
|
Trigger.AfterDelay(Atk3Delay[Difficulty], Atk3TriggerFunction)
|
||||||
|
Trigger.AfterDelay(Atk4Delay[Difficulty], Atk4TriggerFunction)
|
||||||
|
|
||||||
|
Trigger.AfterDelay(AutoAtkStartDelay[Difficulty], AutoCreateTeam)
|
||||||
|
|
||||||
|
Trigger.OnAllKilledOrCaptured(AllToHuntTrigger, function()
|
||||||
|
Utils.Do(Nod.GetGroundAttackers(), IdleHunt)
|
||||||
|
end)
|
||||||
|
|
||||||
|
Trigger.AfterDelay(DateTime.Seconds(40), function()
|
||||||
|
local delay = function() return DateTime.Seconds(30) end
|
||||||
|
local toBuild = function() return { "e1" } end
|
||||||
|
ProduceUnits(Nod, Hand1, delay, toBuild)
|
||||||
|
end)
|
||||||
|
|
||||||
|
local baseDefenses = Nod.GetActorsByTypes({ "sam", "gun" })
|
||||||
|
local pullBuildings = Utils.Concat(AllToHuntTrigger, baseDefenses)
|
||||||
|
|
||||||
|
Utils.Do(pullBuildings, function(building)
|
||||||
|
Trigger.OnDamaged(building, OnNodBaseDamaged)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
OnNodBaseDamaged = function(building, attacker)
|
||||||
|
if BaseDiscovered then
|
||||||
|
Trigger.Clear(building, "OnDamaged")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if EarlyAttackTimer > 0 or attacker.Owner ~= GDI then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
EarlyAttackTimer = DateTime.Seconds(10)
|
||||||
|
|
||||||
|
if attacker.IsDead then
|
||||||
|
PullAttackers(building.Location)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
PullAttackers(attacker.Location)
|
||||||
|
end
|
||||||
|
|
||||||
|
PullAttackers = function(location)
|
||||||
|
Utils.Do(NodAttackers, function(attacker)
|
||||||
|
if attacker.IsDead or attacker.Stance == "Defend" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Ignore structures.
|
||||||
|
attacker.Stance = "Defend"
|
||||||
|
attacker.Stop()
|
||||||
|
attacker.AttackMove(location, 2)
|
||||||
|
attacker.CallFunc(function()
|
||||||
|
-- No targets nearby. Reset stance for IdleHunt.
|
||||||
|
attacker.Stance = "AttackAnything"
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
WorldLoaded = function()
|
WorldLoaded = function()
|
||||||
GDI = Player.GetPlayer("GDI")
|
GDI = Player.GetPlayer("GDI")
|
||||||
AbandonedBase = Player.GetPlayer("AbandonedBase")
|
AbandonedBase = Player.GetPlayer("AbandonedBase")
|
||||||
@@ -116,25 +204,13 @@ WorldLoaded = function()
|
|||||||
unit.Destroy()
|
unit.Destroy()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Trigger.AfterDelay(Atk1Delay[Difficulty], Atk1TriggerFunction)
|
|
||||||
Trigger.AfterDelay(Atk2Delay[Difficulty], Atk2TriggerFunction)
|
|
||||||
Trigger.AfterDelay(Atk3Delay[Difficulty], Atk3TriggerFunction)
|
|
||||||
Trigger.AfterDelay(Atk4Delay[Difficulty], Atk4TriggerFunction)
|
|
||||||
|
|
||||||
Trigger.AfterDelay(AutoAtkStartDelay[Difficulty], AutoCreateTeam)
|
|
||||||
|
|
||||||
Trigger.OnAllKilledOrCaptured(AllToHuntTrigger, function()
|
|
||||||
Utils.Do(Nod.GetGroundAttackers(), IdleHunt)
|
|
||||||
end)
|
|
||||||
|
|
||||||
Trigger.AfterDelay(DateTime.Seconds(40), function()
|
|
||||||
local delay = function() return DateTime.Seconds(30) end
|
|
||||||
local toBuild = function() return { "e1" } end
|
|
||||||
ProduceUnits(Nod, Hand1, delay, toBuild)
|
|
||||||
end)
|
|
||||||
|
|
||||||
Trigger.OnPlayerDiscovered(AbandonedBase, DiscoverGDIBase)
|
Trigger.OnPlayerDiscovered(AbandonedBase, DiscoverGDIBase)
|
||||||
|
|
||||||
|
local revealCell = GdiRadar1.Location + CVec.New(0, 5)
|
||||||
|
Trigger.OnAllKilled(GDIBase, function()
|
||||||
|
LoseGDIBase(revealCell)
|
||||||
|
end)
|
||||||
|
|
||||||
Trigger.OnAllKilled(NodSams, function()
|
Trigger.OnAllKilled(NodSams, function()
|
||||||
GDI.MarkCompletedObjective(DestroySAMs)
|
GDI.MarkCompletedObjective(DestroySAMs)
|
||||||
Actor.Create("airstrike.proxy", true, { Owner = GDI })
|
Actor.Create("airstrike.proxy", true, { Owner = GDI })
|
||||||
@@ -143,6 +219,7 @@ WorldLoaded = function()
|
|||||||
Camera.Position = UnitsRally.CenterPosition
|
Camera.Position = UnitsRally.CenterPosition
|
||||||
|
|
||||||
InsertGDIUnits()
|
InsertGDIUnits()
|
||||||
|
ScheduleNodAttacks()
|
||||||
end
|
end
|
||||||
|
|
||||||
Tick = function()
|
Tick = function()
|
||||||
@@ -150,7 +227,12 @@ Tick = function()
|
|||||||
Nod.MarkCompletedObjective(NodObjective)
|
Nod.MarkCompletedObjective(NodObjective)
|
||||||
end
|
end
|
||||||
|
|
||||||
if BaseDiscovered and Nod.HasNoRequiredUnits() then
|
if not BaseDiscovered then
|
||||||
|
EarlyAttackTimer = EarlyAttackTimer - 1
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if Nod.HasNoRequiredUnits() then
|
||||||
GDI.MarkCompletedObjective(EliminateNod)
|
GDI.MarkCompletedObjective(EliminateNod)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -764,6 +764,9 @@ Actors:
|
|||||||
UnitsRally: waypoint
|
UnitsRally: waypoint
|
||||||
Location: 51,42
|
Location: 51,42
|
||||||
Owner: Neutral
|
Owner: Neutral
|
||||||
|
GDIBaseCenter: waypoint
|
||||||
|
Owner: Neutral
|
||||||
|
Location: 29,6
|
||||||
|
|
||||||
Rules: cnc|rules/campaign-maprules.yaml, cnc|rules/campaign-tooltips.yaml, cnc|rules/campaign-palettes.yaml, rules.yaml
|
Rules: cnc|rules/campaign-maprules.yaml, cnc|rules/campaign-tooltips.yaml, cnc|rules/campaign-palettes.yaml, rules.yaml
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user