Added Nod Covert Operations - Eviction Notice - scb30ea

This commit is contained in:
yamismo
2023-02-23 16:25:36 +01:00
committed by Smittytron
parent 7507333cd3
commit 8b522680e3
9 changed files with 1561 additions and 1 deletions

View File

@@ -111,7 +111,7 @@ infiltrate-barracks-factory-conyard = Infiltrate the barracks, weapon factory an
## nod07a ## nod07a
find-nod-base = Find the Nod base. find-nod-base = Find the Nod base.
## nod07ab, nod08ab, nod09 ## nod07ab, nod08ab, nod09, eviction-notice
eliminate-gdi-forces = Eliminate all GDI forces in the area. eliminate-gdi-forces = Eliminate all GDI forces in the area.
## nod07c ## nod07c
@@ -140,3 +140,13 @@ destroy-tech-center = Destroy the GDI R&D center.
destroy-capture-warfactory = Destroy or capture the Weapons Factory. destroy-capture-warfactory = Destroy or capture the Weapons Factory.
destroy-mammoth-tanks = Destroy the Mammoth tanks in the R&D base. destroy-mammoth-tanks = Destroy the Mammoth tanks in the R&D base.
keep-commando-alive = Keep your Commando alive. keep-commando-alive = Keep your Commando alive.
## eviction-notice
take-civilians-money-crates = Find all the civilians' money.
They won't need it anymore.
quickly-destroy-ion-cannon = Disable GDI Ion Cannon before
it fires two times.
nod-soldier = Nod Soldier
civilians-runs = Hey, those civilians... where are they going?
destroy-ion-cannon-advise = The GDI are preparing their ion cannon. Don't let them get used to it.
village-destruction-warning = Be careful, commander. The GDI won't stand still while we burn the entire village.

View File

@@ -0,0 +1,407 @@
--[[
Copyright (c) The OpenRA Developers and Contributors
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.
]]
GDInuke1 = { type = "nuk2", pos = CPos.New(6,3), blocked = false }
GDIproc1 = { type = "proc", pos = CPos.New(8,12), blocked = false }
GDIpyle = { type = "pyle", pos = CPos.New(17,4), blocked = false }
GDIweap = { type = "weap", pos = CPos.New(10,9), blocked = false }
GDIproc2 = { type = "proc", pos = CPos.New(12,3), blocked = false }
GDInuke2 = { type = "nuk2", pos = CPos.New(4,11), blocked = false }
GDInuke3 = { type = "nuk2", pos = CPos.New(3,14), blocked = false }
GDIdef1 = { type = "atwr", pos = CPos.New(8,5), blocked = false }
GDIdef2 = { type = "atwr", pos = CPos.New(6,10), blocked = false }
GDIdef3 = { type = "atwr", pos = CPos.New(6,16), blocked = false }
GDIdef4 = { type = "gtwr", pos = CPos.New(9,8), blocked = false }
GDInuke4 = { type = "nuk2", pos = CPos.New(13,12), blocked = false }
GDIdef5 = { type = "atwr", pos = CPos.New(15,10), blocked = false }
GDIdef6 = { type = "atwr", pos = CPos.New(13,16), blocked = false }
GDInuke5 = { type = "nuk2", pos = CPos.New(11,14), blocked = false }
GDIsilo1 = { type = "silo", pos = CPos.New(3,6), blocked = false }
GDIsilo2 = { type = "silo", pos = CPos.New(5,17), blocked = false }
GDIdef7 = { type = "atwr", pos = CPos.New(19,5), blocked = false }
GDIdef8 = { type = "atwr", pos = CPos.New(10,21), blocked = false }
GDIsilo3 = { type = "silo", pos = CPos.New(17,2), blocked = false }
GDIsilo4 = { type = "silo", pos = CPos.New(9,17), blocked = false }
GDIdef9 = { type = "atwr", pos = CPos.New(18,20), blocked = false }
GDIhpad1 = { type = "hpad", pos = CPos.New(3,18), blocked = false }
GDIBase = { GDINuke1, GDIPyle, GDIWeap, GDINuke2, GDINuke3, GDIDef1, GDIDef2, GDIDef3, GDIDef4,
GDINuke4, GDIDef5, GDIDef6, GDINuke5, GDISilo1, GDISilo2, GDIDef7, GDIDef8, GDISilo3, GDISilo4, GDIDef9 }
GDIRebuildList = { GDInuke1, GDIproc1, GDIpyle, GDIweap, GDIproc2, GDInuke2, GDInuke3, GDIdef1, GDIdef2, GDIdef3, GDIdef4,
GDInuke4, GDIdef5, GDIdef6, GDInuke5, GDIsilo1, GDIsilo2, GDIdef7, GDIdef8, GDIsilo3, GDIsilo4, GDIdef9 }
BSizes = { nuk2 = CVec.New(2,3), proc = CVec.New(3,4), pyle = CVec.New(2,3), weap = CVec.New(3,3), atwr = CVec.New(1,1), gtwr = CVec.New(1,1), silo = CVec.New(2,1), hpad = CVec.New(2,2) }
ProductionBuildings = { infantry = GDIPyle, vehicle = GDIWeap, aircraft = GDICYard }
ProductionQueue = { infantry = { }, vehicle = { }, aircraft = { } }
NewTeam = { }
TeamJob = "attack"
AT1 = { "e2", "e2", "e2", "e3", "e3", "vehicle", "jeep", "jeep", "apc" }
AT2 = { "e2", "e2", "e2", "e3", "e3", "e1", "e1", "e1", "e1" }
AT3 = { "vehicle", "mtnk", "mtnk", "jeep", "jeep" }
AT4 = { "e3", "e3", "e1", "e1", "e1", "vehicle", "mtnk", "mtnk", "msam" }
AT5 = { "vehicle", "jeep", "jeep", "jeep", "apc", "apc" }
AT6 = { "e3", "e3", "e1", "e1", "e1", "vehicle", "htnk" }
AT7 = { "vehicle", "htnk", "htnk", "mtnk" }
AT8 = { "vehicle", "htnk", "htnk", "msam" }
AT9 = { "vehicle", "mtnk", "msam", "apc", "apc" }
AT10 = { "e2", "e2", "e2", "e2", "e2", "e2", "e2", "e2", "e2", "e2" }
OT1 = { "aircraft", "orca", "orca" }
OT2 = { "aircraft", "orca", "orca", "orca", "orca" }
AttackTeams = { AT1, AT2, AT3, AT4, AT5, AT6, AT7, AT8, AT9, AT10 }
PT1 = { "vehicle", "htnk" }
PT2 = { "vehicle", "mtnk", "mtnk" }
PT3 = { "e2", "e2", "e2", "e3", "e3" }
PatrolTeams = { PT1, PT2, PT3 }
DT1 = { "vehicle", "mtnk", "mtnk", "msam", "msam" }
DT2 = { "e3", "e3", "e1", "e1", "e1", "vehicle", "mtnk", "mtnk", "msam" }
DT3 = { "vehicle", "htnk", "htnk", "msam" }
DefenseTeams = { DT1, DT2, DT3 }
AddOrcasTo = { AT1, AT2, AT5, AT6, AT9, DT1, DT2, DT3 }
AP1 = { waypoint5.Location, waypoint9.Location, waypoint8.Location, waypoint13.Location }
AP2 = { waypoint2.Location, waypoint5.Location, waypoint4.Location, waypoint6.Location }
AP3 = { waypoint2.Location, waypoint3.Location, waypoint4.Location, waypoint6.Location }
AP4 = { waypoint5.Location, waypoint9.Location, waypoint14.Location, PlayerStart.Location, waypoint13.Location }
AP5 = { waypoint5.Location, waypoint9.Location, waypoint6.Location }
AttackPaths = { AP1, AP2, AP3, AP4, AP5 }
InitAi = function()
if Difficulty == "hard" then
PBDelay = 115
PUDelay = 30
ICDelay = 800
ProdCDSecs = 30
GDI.Resources = 10000
MinHarvs = 3
ProcUpgrade = "AIHProcUpgrade"
CivsBuildingsToDestroy = 8
end
if Difficulty == "normal" then
PBDelay = 140
PUDelay = 50
ICDelay = 1000
ProdCDSecs = 40
GDI.Resources = 7000
MinHarvs = 2
ProcUpgrade = "AINProcUpgrade"
CivsBuildingsToDestroy = 11
end
if Difficulty == "easy" then
PBDelay = 180
PUDelay = 70
ICDelay = 1200
ProdCDSecs = 50
GDI.Resources = 5000
MinHarvs = 2
Nod.Resources = 3000
CivsBuildingsToDestroy = 13
end
RepairNamedActors(GDI, 0.75)
SetAutoRebuild()
Trigger.OnKilled(GDIPyle, function()
ProductionQueue["infantry"] = { }
end)
Trigger.OnKilled(GDIWeap, function()
ProductionQueue["vehicle"] = { }
end)
if ProcUpgrade then
ProcUpg = Actor.Create(ProcUpgrade, true, { Owner = GDI })
end
Trigger.AfterDelay(DateTime.Seconds(PBDelay), function()
CheckBase()
Trigger.AfterDelay(DateTime.Seconds(PUDelay), function()
ProduceUnits()
ReduceProdCD()
end)
Trigger.AfterDelay(DateTime.Seconds(ICDelay), function()
FireIonCannon(270)
end)
if not GDIAdvComCenter.IsDead then
IonCannonOnline = true
Media.DisplayMessage(UserInterface.Translate("destroy-ion-cannon-advise"))
DestroyIonCannon = AddSecondaryObjective(Nod, "quickly-destroy-ion-cannon")
end
end)
end
ReduceProdCD = function()
Trigger.AfterDelay(DateTime.Minutes(2), function()
ProdCDSecs = ProdCDSecs - 1
if ProdCDSecs > 10 then
ReduceProdCD()
end
end)
end
PrepareOrcas = function()
table.insert(GDIRebuildList, 11, GDIhpad1)
Utils.Do(AddOrcasTo, function(t)
Utils.Do(OT1, function(u)
table.insert(t, u)
end)
end)
table.insert(AttackTeams, OT2)
table.insert(PatrolTeams, OT1)
end
--Building logic
SetAutoRebuild = function()
Utils.Do(GDIBase, function(b)
Trigger.OnKilled(b, CheckBase)
end)
end
CheckBase = function()
if GDICYard.IsDead then return end
for i = 1, #GDIRebuildList do
if GDIRebuildList[i].blocked then
CheckBuildablePlace(GDIRebuildList[i])
else
local building = GDI.GetActorsByType(GDIRebuildList[i].type)
if #building < 1 then
BuildBuilding(GDIRebuildList[i], GDICYard)
return
end
for ii = 1, #building do
if not building[ii].IsDead and building[ii].Location == GDIRebuildList[i].pos then
break
end
if ii == #building then
BuildBuilding(GDIRebuildList[i], GDICYard)
return
end
end
end
end
if not CheckProgrammed then
CheckProgrammed = true
Trigger.AfterDelay(250, function()
CheckProgrammed = false
CheckBase()
end)
end
end
CheckBuildablePlace = function(b)
local actors = Map.ActorsInBox(WPos.New(b.pos.X * 1024, b.pos.Y * 1024, 0), WPos.New((b.pos.X + BSizes[b.type].X) * 1024, (b.pos.Y + BSizes[b.type].Y) * 1024, 0), function(a) return a.Owner == Nod end)
if #actors > 0 then
b.blocked = true
return false
else
b.blocked = false
return true
end
end
BuildBuilding = function(building, cyard)
if CyardIsBuilding or GDI.Resources < Actor.Cost(building.type) then
if Dontspam == true then
return
end
Dontspam = true
Trigger.AfterDelay(DateTime.Seconds(10), function()
Dontspam = false
CheckBase()
end)
return
end
CyardIsBuilding = true
GDI.Resources = GDI.Resources - Actor.Cost(building.type)
Trigger.AfterDelay(Actor.BuildTime(building.type), function()
CyardIsBuilding = false
if cyard.IsDead or cyard.Owner ~= GDI then
GDI.Resources = GDI.Resources + Actor.Cost(building.type)
return
end
if CheckBuildablePlace(building) == false then
CheckBase()
return
end
local newbuilding = Actor.Create(building.type, true, { Owner = GDI, Location = building.pos })
Trigger.OnKilled(newbuilding, function() CheckBase() end)
RepairBuilding(GDI, newbuilding, 0.75)
GuardBuilding(newbuilding)
if newbuilding.Type == "pyle" then
ProductionBuildings["infantry"] = newbuilding
Trigger.OnKilled(newbuilding, function() ProductionQueue["infantry"] = { } end)
RestartUnitProduction()
elseif newbuilding.Type == "weap" then
ProductionBuildings["vehicle"] = newbuilding
Trigger.OnKilled(newbuilding, function() ProductionQueue["vehicle"] = { } end)
RestartUnitProduction()
NeedHarv = false
elseif newbuilding.Type == "hpad" then
ProductionBuildings["aircraft"] = newbuilding
Trigger.OnKilled(newbuilding, function() ProductionQueue["aircraft"] = { } end)
RestartUnitProduction()
end
Trigger.AfterDelay(50, CheckBase)
end)
end
--Units production logic
UniqueTeamsQueue = { }
ProdCooldown = false
CheckProduction = function()
if #GDI.GetActorsByType("proc") < 1 and GDI.Resources < 6000 then
Trigger.AfterDelay(250, CheckProduction)
return
elseif ProductionBuildings["infantry"].IsDead and ProductionBuildings["vehicle"].IsDead and ProductionBuildings["aircraft"].IsDead then
return
elseif not ProductionBuildings["vehicle"].IsDead and CheckForHarvester() then
NeedHarv = true
ProductionBuildings["vehicle"].Build( { "harv" }, function()
CheckProduction()
Trigger.AfterDelay(DateTime.Seconds(5), function()
if not ProductionBuildings["vehicle"].IsDead then
ProductionBuildings["vehicle"].Build( { "harv" } )
end
end)
end)
return
end
NeedHarv = false
if #ProductionQueue["infantry"] + #ProductionQueue["vehicle"] + #ProductionQueue["aircraft"] < 1 and Producing then
Producing = false
end
if ProdCooldown or GDI.Resources < 4000 then
RestartUnitProduction()
else
ProduceUnits()
end
end
ProduceUnits = function()
if NeedHarv then
RestartUnitProduction()
return
end
if not Producing then
NewTeam = { }
CreateUnitsGroup()
if #ProductionQueue["infantry"] + #ProductionQueue["vehicle"] + #ProductionQueue["aircraft"] > 0 then
Producing = true
else
RestartUnitProduction()
return
end
end
if #ProductionQueue["infantry"] > 0 and not ProductionBuildings["infantry"].IsDead and not ProductionBuildings["infantry"].IsProducing("e2") then
ProductionBuildings["infantry"].Build( { ProductionQueue["infantry"][1] }, function(u)
table.insert(NewTeam, u[1])
table.remove(ProductionQueue["infantry"], 1)
CheckTeamCompleted()
end)
end
if #ProductionQueue["vehicle"] > 0 and not ProductionBuildings["vehicle"].IsDead and not ProductionBuildings["vehicle"].IsProducing("mtnk") then
ProductionBuildings["vehicle"].Build( { ProductionQueue["vehicle"][1] }, function(u)
table.insert(NewTeam, u[1])
table.remove(ProductionQueue["vehicle"], 1)
CheckTeamCompleted()
end)
end
if #ProductionQueue["aircraft"] > 0 and not ProductionBuildings["aircraft"].IsDead and not ProductionBuildings["aircraft"].IsProducing("orca") then
ProductionBuildings["aircraft"].Build( { ProductionQueue["aircraft"][1] }, function(u)
table.insert(NewTeam, u[1])
table.remove(ProductionQueue["aircraft"], 1)
CheckTeamCompleted()
end)
end
RestartUnitProduction()
end
CheckTeamCompleted = function()
if #ProductionQueue["infantry"] + #ProductionQueue["vehicle"] + #ProductionQueue["aircraft"] < 1 and #NewTeam > 0 then
NewTeam = Utils.Where(NewTeam, function(u) return not u.IsDead end)
if TeamJob == "attack" then
SendAttackGroup(NewTeam)
elseif TeamJob == "patrol" then
TeamJob = "attack"
PatrolTeam = NewTeam
StartPatrol()
elseif TeamJob == "defend" then
TeamJob = "attack"
BaseDefenseTeam = NewTeam
StartGuard()
end
Producing = false
ProdCooldown = true
NewTeam = { }
Trigger.AfterDelay(DateTime.Seconds(ProdCDSecs), function() ProdCooldown = false end)
else
ProduceUnits()
end
end
SendAttackGroup = function(team)
MoveAsGroup(team, Utils.Random(AttackPaths), 1, false)
end
CreateUnitsGroup = function()
local team = AttackTeams
if #UniqueTeamsQueue > 0 then
team = UniqueTeamsQueue[1].team
TeamJob = UniqueTeamsQueue[1].job
table.remove(UniqueTeamsQueue, 1)
end
local pb = "infantry"
Utils.Do(Utils.Random(team), function(u)
if u == "vehicle" or u == "aircraft" then
pb = u
elseif ProductionBuildings[pb] and not ProductionBuildings[pb].IsDead and ProductionBuildings[pb].Owner == GDI then
table.insert(ProductionQueue[pb], u)
end
end)
end
RestartUnitProduction = function()
if not Restarting then
Restarting = true
else
return
end
Trigger.AfterDelay(DateTime.Seconds(5), function()
Restarting = false
CheckProduction()
end)
end
CheckForHarvester = function()
local harv = GDI.GetActorsByType("harv")
return #harv < MinHarvs
end

View File

@@ -0,0 +1,349 @@
--[[
Copyright (c) The OpenRA Developers and Contributors
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.
]]
WelcomeTeam = { Wel1, Wel2, Wel3, Wel4, Wel5 }
Civilians = { Actor111, Actor112, Actor113, Actor114, Actor115, Actor116, Actor117, Actor118, Actor119, Actor120, Actor121 }
RunForHelpCivs = { Actor109, Actor110 }
CiviliansBuildings = { Actor35, Actor36, Actor37, Actor38, Actor39, Actor40, Actor41, Actor42, Actor43, Actor44, Actor45, Actor54, Actor55, Actor56, Actor57, Actor58 }
OilDerricks = { Actor49, Actor50, Actor51, Actor52 }
CivsMoneyBuildings = { Actor37, Actor41, Actor42, Actor44, Actor58 }
ReinforcementsMammoths = { "htnk", "htnk" }
ReinforcementsEngineers = { "e6", "e6", "e6", "e6", "e6" }
CiviliansHelpTeam = { "mtnk", "mtnk", "msam" }
BaseDefenseTeam = { Def1, Def2, Def3, Def4 }
PatrolTeam = { Actor103, Actor122, Actor123 }
PatrolPath = { waypoint2.Location, waypoint3.Location, waypoint4.Location, waypoint5.Location }
CapturableStructures = { "afld", "hand", "hq", "nuke", "silo", "proc", "sam" }
IonCannonTargets = { { "obli", "gun", "gtwr" }, { "harv" } }
WelcomeTeamCellTrigger = { CPos.New(17,59), CPos.New(18,59), CPos.New(19,59), CPos.New(17,60), CPos.New(18,60), CPos.New(19,60), CPos.New(25,53), CPos.New(25,54), CPos.New(25,55), CPos.New(26,53), CPos.New(26,54), CPos.New(26,55) }
CivsGDIHelpCellTrigger = { CPos.New(13,7) }
GDIBaseEntranceCells = { CPos.New(16,5), CPos.New(16,6), CPos.New(16,7), CPos.New(16,8), CPos.New(17,4), CPos.New(17,5), CPos.New(17,6), CPos.New(17,7), CPos.New(17,8), CPos.New(18,4), CPos.New(18,5), CPos.New(19,4), CPos.New(8,15), CPos.New(9,15), CPos.New(10,15), CPos.New(11,15), CPos.New(12,15), CPos.New(13,15), CPos.New(14,15), CPos.New(9,16), CPos.New(10,16), CPos.New(11,16), CPos.New(12,16), CPos.New(13,16), CPos.New(14,16) }
InnerGDIBaseEntranceCells = { CPos.New(7,5), CPos.New(7,6), CPos.New(7,7), CPos.New(8,6), CPos.New(8,7), CPos.New(9,6), CPos.New(9,7) }
CaptureStructures = function(actor)
local structures = Nod.GetActorsByTypes(CapturableStructures)
local distance = 500
local captst = nil
Utils.Do(structures, function(st)
if not actor.IsDead and not st.IsDead and distance > (math.abs((actor.Location - st.Location).X) + math.abs((actor.Location - st.Location).Y)) then
distance = math.abs((actor.Location - st.Location).X) + math.abs((actor.Location - st.Location).Y)
captst = st
end
end)
if captst then
actor.Capture(captst)
end
end
SendGDIAirstrike = function()
if not GDIhq.IsDead and GDIhq.Owner == GDI then
local target = GetAirstrikeTarget(Nod)
if target then
GDIhq.TargetAirstrike(target, Angle.SouthEast)
else
Trigger.AfterDelay(DateTime.Seconds(5), SendGDIAirstrike)
end
end
end
OilDerricksAstkSent = false
OilDerricksAirstrike = function()
if not OilDerricksAstkSent then
SendGDIAirstrike()
OilDerricksAstkSent = true
end
end
CivsRunning = false
RunForHelp = function()
if not CivsRunning then
Utils.Do(RunForHelpCivs, function(actor)
actor.Move(CPos.New(53,45))
actor.Move(waypoint6.Location)
actor.Move(waypoint4.Location)
actor.Move(waypoint9.Location)
actor.Move(waypoint2.Location)
actor.Move(waypoint12.Location)
actor.Move(waypoint6.Location)
end)
Trigger.OnEnteredFootprint(CivsGDIHelpCellTrigger, function(a, id)
if a == RunForHelpCivs[1] or a == RunForHelpCivs[2] then
Reinforcements.Reinforce(GDI, CiviliansHelpTeam, { CPos.New(2,9), CPos.New(3,9) }, 30, function(a)
a.AttackMove(waypoint2.Location)
a.AttackMove(waypoint9.Location)
a.AttackMove(waypoint8.Location)
IdleHunt(a)
end)
Trigger.RemoveFootprintTrigger(id)
end
end)
CivsRunning = true
local cam = Actor.Create("camera", true, { Owner = Nod, Location = CPos.New(53,44) })
Trigger.AfterDelay(125, cam.Destroy)
Media.DisplayMessage(UserInterface.Translate("civilians-runs"), UserInterface.Translate("nod-soldier"))
end
end
CivsBuildingsToDestroy = 0
CheckVillageDestruction = function()
CivsBuildingsToDestroy = CivsBuildingsToDestroy - 1
if CivsBuildingsToDestroy == 2 then
Media.DisplayMessage(UserInterface.Translate("village-destruction-warning"))
elseif CivsBuildingsToDestroy == 0 then
Reinforcements.Reinforce(GDI, ReinforcementsMammoths, { CPos.New(2,9), CPos.New(3,9) }, 40, function(a)
a.AttackMove(waypoint11.Location)
a.AttackMove(waypoint5.Location)
a.AttackMove(waypoint4.Location)
a.AttackMove(waypoint6.Location)
IdleHunt(a)
end)
end
end
GuardBase = function()
Utils.Do(GDIBase, function(building)
GuardBuilding(building)
end)
end
GuardBuilding = function(building)
Trigger.OnDamaged(building, function(slf, atk, dmg)
if atk.Type ~= "player" and not atk.IsDead and atk.Owner == Nod then
Utils.Do(BaseDefenseTeam, function(guard)
if not guard.IsDead and not building.IsDead then
if guard.Stance == "Defend" then
guard.Stop()
guard.Stance = "AttackAnything"
guard.AttackMove(atk.Location, 3)
Trigger.OnIdle(guard, function()
guard.AttackMove(waypoint12.Location, 3)
guard.Stance = "Defend"
Trigger.ClearAll(guard)
end)
end
end
end)
end
end)
end
StartGuard = function()
Trigger.OnAllKilled(BaseDefenseTeam, function()
table.insert(UniqueTeamsQueue, { team = DefenseTeams, job = "defend" })
end)
Utils.Do(BaseDefenseTeam, function(guard)
guard.Stance = "Defend"
end)
end
StartPatrol = function()
Trigger.OnAllKilled(PatrolTeam, function()
table.insert(UniqueTeamsQueue, { team = PatrolTeams, job = "patrol" })
end)
Utils.Do(PatrolTeam, function(a)
Trigger.OnKilled(a, function()
Utils.Do(PatrolTeam, function(a)
if not a.IsDead then
a.Stop()
IdleHunt(a)
end
end)
end)
end)
MoveAsGroup(PatrolTeam, PatrolPath, 1, true)
end
MoveAsGroup = function(team, path, i, loop)
if i == 1 and not loop then
Utils.Do(team, function(u)
Trigger.OnDamaged(u, function()
Utils.Do(team, function(u)
if not u.IsDead then
Trigger.Clear(u, "OnDamaged")
IdleHunt(u)
end
end)
end)
end)
end
Utils.Do(team, function(a)
if not a.IsDead then
a.Stance = "AttackAnything"
a.AttackMove(path[i], 2)
Trigger.OnIdle(a, function()
Trigger.Clear(a, "OnIdle")
a.Stance = "Defend"
local teamNumber = 0
local regrouped = false
Utils.Do(team, function(a)
if a.IsDead or a.Stance == "Defend" then
teamNumber = teamNumber + 1
if teamNumber == #team then
regrouped = true
end
end
end)
if regrouped then
if i == #path then
if loop == true then
i = 1
else
Trigger.AfterDelay(5, function()
Utils.Do(team, function(a)
if not a.IsDead then
a.Stance = "AttackAnything"
IdleHunt(a)
end
end)
end)
return
end
else
i = i + 1
end
Trigger.AfterDelay(20, function()
MoveAsGroup(team, path, i, loop)
end)
end
end)
end
end)
end
IonCannonOnline = false
ICShotsCount = 0
FireIonCannon = function(timer)
if IonCannonOnline then
local ii = Utils.RandomInteger(1, 4)
local targets = { }
if ii < 3 then
targets = Nod.GetActorsByTypes(IonCannonTargets[ii])
else
targets = Nod.GetGroundAttackers()
end
if #targets > 0 then
local rand = Utils.RandomInteger(1, #targets + 1)
if not targets[rand].IsDead then
GDIAdvComCenter.ActivateIonCannon(targets[rand].Location)
if ICShotsCount < 2 then
ICShotsCount = ICShotsCount + 1
if ICShotsCount > 1 then
Nod.MarkFailedObjective(DestroyIonCannon)
Trigger.ClearAll(GDIAdvComCenter)
end
end
Trigger.AfterDelay(DateTime.Seconds(timer), function() FireIonCannon(timer) end)
return
end
end
Trigger.AfterDelay(DateTime.Seconds(1), function() FireIonCannon(timer) end)
end
end
CheckObjectives = function()
if GDI.HasNoRequiredUnits() then Nod.MarkCompletedObjective(EliminateAllGDI) end
if Nod.HasNoRequiredUnits() then Nod.MarkFailedObjective(EliminateAllGDI) end
Trigger.AfterDelay(25, CheckObjectives)
end
WorldLoaded = function()
Nod = Player.GetPlayer("Nod")
GDI = Player.GetPlayer("GDI")
Camera.Position = PlayerStart.CenterPosition
Flare = Actor.Create("flare", true, { Owner = Nod, Location = DefaultFlareLocation.Location })
Trigger.AfterDelay(DateTime.Minutes(1), Flare.Destroy)
InitObjectives(Nod)
EliminateAllGDI = AddPrimaryObjective(Nod, "eliminate-gdi-forces")
FindAllCivMoney = AddSecondaryObjective(Nod, "take-civilians-money-crates")
CheckObjectives()
InitAi()
Trigger.OnEnteredFootprint(WelcomeTeamCellTrigger, function(a, id)
if a.Owner == Nod then
Utils.Do(WelcomeTeam, function(a)
if not a.IsDead then
a.AttackMove(PlayerStart.Location)
IdleHunt(a)
end
end)
Trigger.RemoveFootprintTrigger(id)
end
end)
Trigger.OnAllKilled(Civilians, function()
local cargo = Reinforcements.ReinforceWithTransport(GDI, "tran", ReinforcementsEngineers, { CPos.New(0,32), waypoint10.Location }, { CPos.New(0,32) })[2]
Utils.Do(cargo, function(engs)
if engs.Type == "e6" then
Trigger.OnIdle(engs, CaptureStructures)
end
end)
end)
Utils.Do(CiviliansBuildings, function(b)
Trigger.OnKilled(b, CheckVillageDestruction)
end)
Utils.Do(OilDerricks, function(actor)
Trigger.OnKilledOrCaptured(actor, OilDerricksAirstrike)
end)
Utils.Do(RunForHelpCivs, function(actor)
Trigger.OnDiscovered(actor, RunForHelp)
end)
Trigger.OnEnteredFootprint(GDIBaseEntranceCells, function(a, id)
if a.Owner == Nod and not BombTriggered then
BombTriggered = true
Trigger.AfterDelay(25, SendGDIAirstrike)
Trigger.AfterDelay(150, SendGDIAirstrike)
Trigger.AfterDelay(275, SendGDIAirstrike)
Trigger.RemoveFootprintTrigger(id)
end
end)
Trigger.OnCapture(GDIhq, function()
GDIhq.GrantCondition("captured")
end)
Trigger.OnEnteredFootprint(InnerGDIBaseEntranceCells, function(a, id)
if a.Owner == Nod and not InnerBaseEntered then
InnerBaseEntered = true
Reinforcements.Reinforce(GDI, ReinforcementsMammoths, { CPos.New(2,9), CPos.New(3,9) }, 40, IdleHunt)
Trigger.RemoveFootprintTrigger(id)
end
end)
Trigger.AfterDelay(5, function()
StartPatrol()
GuardBase()
StartGuard()
end)
Trigger.OnAllKilled(CivsMoneyBuildings, function()
Trigger.AfterDelay(1, function()
Trigger.OnAllRemovedFromWorld(Utils.Where(Map.ActorsInWorld, function(a) return a.Type == "moneycrate" or a.Type == "smallmcrate" end), function()
Nod.MarkCompletedObjective(FindAllCivMoney)
end)
end)
end)
Trigger.OnKilledOrCaptured(GDIAdvComCenter, function()
if IonCannonOnline then
IonCannonOnline = false
else
DestroyIonCannon = AddSecondaryObjective(Nod, "quickly-destroy-ion-cannon")
end
Nod.MarkCompletedObjective(DestroyIonCannon)
PrepareOrcas()
end)
end

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@@ -0,0 +1,649 @@
MapFormat: 12
RequiresMod: cnc
Title: Nod - Eviction Notice
Author: Westwood Studios
Tileset: DESERT
MapSize: 64,64
Bounds: 2,2,60,60
Visibility: MissionSelector
Categories: Campaign
Players:
PlayerReference@Neutral:
Name: Neutral
OwnsWorld: True
NonCombatant: True
Faction: gdi
PlayerReference@Civilians:
Name: Civilians
Bot: campaign
NonCombatant: True
Faction: gdi
Enemies: Nod
PlayerReference@Creeps:
Name: Creeps
NonCombatant: True
Faction: Random
PlayerReference@GDI:
Name: GDI
Bot: campaign
Faction: gdi
Color: F5D378
Allies: GDI
Enemies: Nod
PlayerReference@Nod:
Name: Nod
AllowBots: False
Playable: True
Required: True
LockFaction: True
Faction: nod
LockColor: True
Color: FE1100
LockSpawn: True
LockTeam: True
Enemies: GDI, Civilians
Actors:
Actor3: t09
Location: 42,36
Owner: Neutral
Actor4: t09
Location: 38,30
Owner: Neutral
Actor5: t18
Location: 40,31
Owner: Neutral
Actor6: rock4
Location: 40,20
Owner: Neutral
Actor7: rock3
Location: 45,21
Owner: Neutral
Actor8: rock6
Location: 25,23
Owner: Neutral
Actor9: t04
Location: 55,1
Owner: Neutral
Actor10: t08
Location: 21,57
Owner: Neutral
Actor11: t13.transformable
Location: 5,57
Owner: Neutral
Actor12: t13.transformable
Location: 9,53
Owner: Neutral
Actor13: t13.transformable
Location: 6,35
Owner: Neutral
Actor14: t13.transformable
Location: 4,42
Owner: Neutral
Actor15: t13.transformable
Location: 58,17
Owner: Neutral
Actor16: t13.transformable
Location: 57,26
Owner: Neutral
Actor17: t13.transformable
Location: 13,19
Owner: Neutral
Actor18: t13.transformable
Location: 40,12
Owner: Neutral
Actor19: t13.transformable
Location: 27,15
Owner: Neutral
Actor20: t13.transformable
Location: 27,3
Owner: Neutral
Actor21: t13.transformable
Location: 35,16
Owner: Neutral
Actor22: t13.transformable
Location: 34,11
Owner: Neutral
Actor23: t13.transformable
Location: 12,24
Owner: Neutral
Actor24: rock6
Location: 28,42
Owner: Neutral
Actor25: rock7
Location: 34,44
Owner: Neutral
Actor26: rock4
Location: 38,47
Owner: Neutral
Actor27: rock4
Location: 25,39
Owner: Neutral
Actor28: t13.transformable
Location: 32,43
Owner: Neutral
Actor29: t13.transformable
Location: 51,5
Owner: Neutral
Actor30: t13.transformable
Location: 57,3
Owner: Neutral
Actor31: t13.transformable
Location: 56,9
Owner: Neutral
Actor32: t13.transformable
Location: 26,42
Owner: Neutral
Actor33: t13.transformable
Location: 35,40
Owner: Neutral
Actor34: t13.transformable
Location: 29,45
Owner: Neutral
Actor35: v23
Location: 52,52
Owner: Civilians
Actor36: v22
Location: 55,43
Owner: Civilians
Actor37: v24
Location: 58,55
Owner: Civilians
Actor38: v31
Location: 44,57
Owner: Civilians
Actor39: v30
Location: 54,47
Owner: Civilians
Actor40: v27
Location: 50,58
Owner: Civilians
Actor41: v25
Location: 50,53
Owner: Civilians
Actor42: v26
Location: 47,49
Owner: Civilians
Actor43: v22
Location: 51,50
Owner: Civilians
Actor44: v21
Location: 47,55
Owner: Civilians
Actor45: v20
Location: 52,55
Owner: Civilians
GDICYard: fact
Location: 3,3
Owner: GDI
GDIAdvComCenter: eye
Location: 3,18
Owner: GDI
Actor49: v19
Location: 60,41
Owner: Civilians
Actor50: v19
Location: 59,41
Owner: Civilians
Actor51: v19
Location: 59,42
Owner: Civilians
Actor52: v19
Location: 60,42
Owner: Civilians
Actor54: v29
Location: 60,44
Owner: Civilians
Actor55: v28
Location: 58,46
Owner: Civilians
Actor56: v23
Location: 52,44
Owner: Civilians
Actor57: v29
Location: 52,59
Owner: Civilians
Actor58: v21
Location: 42,30
Owner: Civilians
GDIhq: hq
Location: 15,3
Owner: GDI
GDIDef13: gtwr
Location: 20,6
Owner: GDI
GDIDef10: gtwr
Location: 17,9
Owner: GDI
GDIDef11: gtwr
Location: 15,23
Owner: GDI
GDIDef12: gtwr
Location: 12,23
Owner: GDI
GDINuke1: nuk2
Location: 6,3
Owner: GDI
GDIPyle: pyle
Location: 17,4
Owner: GDI
GDISilo1: silo
Location: 3,6
Owner: GDI
GDISilo3: silo
Location: 17,2
Owner: GDI
GDINuke2: nuk2
Location: 4,11
Owner: GDI
GDIWeap: weap
Location: 10,9
Owner: GDI
GDINuke3: nuk2
Location: 3,14
Owner: GDI
GDIDef7: atwr
Location: 19,5
Owner: GDI
GDIDef5: atwr
Location: 15,10
Owner: GDI
GDIDef6: atwr
Location: 13,16
Owner: GDI
GDISilo2: silo
Location: 5,17
Owner: GDI
GDISilo4: silo
Location: 9,17
Owner: GDI
GDIDef1: atwr
Location: 8,5
Owner: GDI
GDIDef2: atwr
Location: 6,10
Owner: GDI
GDIDef3: atwr
Location: 6,16
Owner: GDI
GDIDef4: gtwr
Location: 9,8
Owner: GDI
GDIDef8: atwr
Location: 10,21
Owner: GDI
GDIDef9: atwr
Location: 18,20
Owner: GDI
GDINuke4: nuk2
Location: 13,12
Owner: GDI
GDINuke5: nuk2
Location: 11,14
Owner: GDI
Actor84: mcv
Location: 24,60
Owner: Nod
Facing: 0
Actor85: mtnk
Location: 57,20
Owner: GDI
Facing: 384
Actor86: mtnk
Location: 60,20
Owner: GDI
Facing: 512
Actor87: mtnk
Location: 13,33
Owner: GDI
Facing: 896
Actor88: mtnk
Location: 26,21
Owner: GDI
Facing: 384
Actor89: jeep
Location: 35,22
Owner: GDI
Facing: 512
Actor90: jeep
Location: 42,31
Owner: GDI
Facing: 640
Actor91: htnk
Location: 12,56
Owner: GDI
Facing: 640
Actor92: htnk
Location: 16,37
Owner: GDI
Facing: 896
Actor93: ftnk.nohusk
Location: 23,61
Owner: Nod
Facing: 384
Actor94: ftnk.nohusk
Owner: Nod
Location: 24,59
Facing: 0
Actor95: ftnk.nohusk
Location: 25,61
Owner: Nod
Facing: 640
Actor96: ftnk.nohusk
Location: 22,59
Owner: Nod
Facing: 256
Actor97: ftnk.nohusk
Location: 26,59
Owner: Nod
Facing: 768
Actor98: ftnk.nohusk
Location: 24,58
Owner: Nod
Actor99: mtnk
Location: 18,52
Owner: GDI
Facing: 640
Actor100: htnk
Location: 20,47
Owner: GDI
TurretFacing: 0
Facing: 640
Actor101: mtnk
Location: 5,49
Owner: GDI
Facing: 640
Actor102: jeep
Location: 26,26
Owner: GDI
Facing: 512
Actor103: mtnk
Location: 23,6
Owner: GDI
Facing: 768
Actor104: htnk
Location: 37,46
Owner: GDI
Facing: 640
Actor105: mtnk
Location: 19,9
Owner: GDI
Facing: 640
Actor106: mtnk
Location: 37,13
Owner: GDI
Facing: 640
Actor107: mtnk
Location: 51,12
Owner: GDI
Facing: 384
Actor108: mtnk
Location: 49,11
Owner: GDI
Facing: 640
Actor109: c8
Location: 59,45
Owner: Civilians
Facing: 512
SubCell: 1
Actor110: c5
Location: 59,45
Owner: Civilians
Facing: 640
SubCell: 4
Actor111: c7
Location: 60,47
Owner: Civilians
SubCell: 3
Facing: 384
Actor112: c7
Location: 43,51
Owner: Civilians
Facing: 256
SubCell: 2
Actor113: c4
Location: 53,57
Owner: Civilians
Facing: 512
SubCell: 4
Actor114: c3
Location: 47,53
Owner: Civilians
Facing: 896
SubCell: 0
Actor115: c3
Location: 58,42
Owner: Civilians
Facing: 512
SubCell: 3
Actor116: c2
Location: 57,56
Owner: Civilians
Facing: 256
SubCell: 0
Actor117: c2
Location: 48,58
Owner: Civilians
Facing: 384
SubCell: 0
Actor118: c2
Location: 51,51
Owner: Civilians
Facing: 256
SubCell: 1
Actor119: c1
Location: 57,46
Owner: Civilians
Facing: 256
SubCell: 1
Actor120: c1
Location: 46,50
Owner: Civilians
Facing: 512
SubCell: 2
Actor121: c1
Location: 45,56
Owner: Civilians
Facing: 128
SubCell: 1
Actor122: e2
Location: 25,6
Owner: GDI
Facing: 768
SubCell: 3
Actor123: e2
Location: 24,7
Owner: GDI
Facing: 640
SubCell: 2
Actor124: e2
Location: 26,48
Owner: GDI
Facing: 640
SubCell: 1
Actor125: e2
Location: 25,48
Owner: GDI
Facing: 384
SubCell: 0
Actor126: e2
Location: 32,50
Owner: GDI
SubCell: 3
Facing: 256
Actor127: e2
Location: 33,52
Owner: GDI
SubCell: 1
Facing: 768
Actor128: e2
Location: 32,51
Owner: GDI
SubCell: 3
Facing: 512
Actor129: e1
Location: 19,6
Owner: GDI
Facing: 640
SubCell: 0
Actor130: e1
Location: 18,10
Owner: GDI
Facing: 384
SubCell: 2
Actor131: e1
Location: 21,7
Owner: GDI
Facing: 768
SubCell: 2
Actor133: e2
Location: 16,59
Owner: GDI
SubCell: 1
Facing: 896
Actor134: e2
Location: 15,60
Owner: GDI
SubCell: 4
Facing: 384
Actor136: e2
Location: 16,58
Owner: GDI
SubCell: 0
TurretFacing: 0
Facing: 640
Actor137: e1
Location: 46,54
Owner: Nod
Health: 60
SubCell: 2
DefaultChinookTarget: waypoint
Location: 32,32
Owner: Neutral
DefaultCameraPosition: waypoint
Location: 17,54
Owner: Neutral
DefaultFlareLocation: waypoint
Location: 47,54
Owner: Neutral
waypoint13: waypoint
Owner: Neutral
Location: 29,51
waypoint12: waypoint
Location: 13,7
Owner: Neutral
waypoint11: waypoint
Location: 13,23
Owner: Neutral
waypoint10: waypoint
Location: 56,56
Owner: Neutral
waypoint9: waypoint
Location: 21,31
Owner: Neutral
waypoint8: waypoint
Location: 22,51
Owner: Neutral
waypoint7: waypoint
Location: 48,52
Owner: Neutral
waypoint6: waypoint
Location: 53,37
Owner: Neutral
waypoint5: waypoint
Location: 23,24
Owner: Neutral
waypoint4: waypoint
Location: 46,23
Owner: Neutral
waypoint3: waypoint
Location: 49,5
Owner: Neutral
waypoint2: waypoint
Location: 23,7
Owner: Neutral
waypoint1: waypoint
Location: 2,9
Owner: Neutral
PlayerStart: waypoint
Location: 24,60
Owner: Neutral
Wel1: apc
Owner: GDI
Location: 13,55
Facing: 649
Def35: e1
Location: 15,8
Owner: GDI
SubCell: 4
Facing: 896
Wel3: jeep
Owner: GDI
Location: 19,44
Facing: 617
Wel2: jeep
Owner: GDI
Location: 21,43
Facing: 384
Actor152: msam
Owner: GDI
Location: 5,18
Facing: 657
Actor153: msam
Owner: GDI
Location: 3,17
Facing: 576
Actor154: msam
Owner: GDI
Location: 15,12
Facing: 657
Actor155: htnk
Owner: GDI
Location: 4,23
Facing: 527
Actor156: htnk
Owner: GDI
Location: 3,23
Facing: 495
waypoint14: waypoint
Owner: Neutral
Location: 10,45
Def1: mtnk
Owner: GDI
Location: 14,6
Facing: 384
Def2: mtnk
Owner: GDI
Location: 12,7
Facing: 384
Def3: mtnk
Owner: GDI
Location: 14,8
Facing: 384
Def4: msam
Owner: GDI
Location: 13,8
Facing: 384
Wel4: jeep
Owner: GDI
Location: 36,53
Facing: 227
Wel5: apc
Owner: GDI
Location: 37,51
Facing: 349
Rules: cnc|rules/campaign-maprules.yaml, cnc|rules/campaign-tooltips.yaml, cnc|rules/campaign-palettes.yaml, rules.yaml
Weapons: weapons.yaml
Translations: cnc|languages/lua/en.ftl

View File

@@ -0,0 +1,139 @@
World:
MissionData:
StartVideo: consyard.vqa
LossVideo: bombaway.vqa
WinVideo: inferno.vqa
Briefing: GDI influence in this area is running rampant. Establish a well positioned strike base, and clean the area out. A nearby town may provide a suitable location for your base, if the occupants were "persuaded" to move....
LuaScript:
Scripts: campaign.lua, utils.lua, eviction-notice.lua , eviction-notice-AI.lua
ScriptLobbyDropdown@difficulty:
ID: difficulty
Label: Difficulty
Description: The difficulty of the mission
Values:
easy: Easy
normal: Normal
hard: Hard
Default: normal
Player:
EnemyWatcher:
PlayerResources:
DefaultCash: 0
# Disable husks for civilian buildings and initial flame tanks
V19:
-SpawnActorOnDeath:
V20:
-SpawnActorOnDeath:
V21:
SpawnActorOnDeath:
Actor: smallmcrate
V22:
-SpawnActorOnDeath:
V23:
-SpawnActorOnDeath:
V24:
SpawnActorOnDeath:
Actor: smallmcrate
V25:
SpawnActorOnDeath:
Actor: moneycrate
V26:
SpawnActorOnDeath:
Actor: smallmcrate
V27:
-SpawnActorOnDeath:
V28:
-SpawnActorOnDeath:
V29:
-SpawnActorOnDeath:
V30:
-SpawnActorOnDeath:
V31:
-SpawnActorOnDeath:
C5:
AnnounceOnSeen:
C8:
AnnounceOnSeen:
MoneyCrate:
ScriptTriggers:
SmallMCrate:
Inherits: MoneyCrate
ScriptTriggers:
GiveCashCrateAction:
Amount: 1000
Sequence: dollar
UseCashTick: true
# Initial flame tanks can't move due to their own husks
FTNK.nohusk:
Inherits: FTNK
-Buildable:
RenderSprites:
Image: FTNK
-SpawnActorOnDeath:
HQ:
ExternalCondition@CAPTURED:
Condition: captured
AirstrikePower:
StartFullyCharged: True
RequiresCondition: captured
PROC:
GrantConditionOnPrerequisite@AIN:
Condition: ain
Prerequisites: diffnorm
GrantConditionOnPrerequisite@AIH:
Condition: aih
Prerequisites: diffhard
ResourceValueMultiplier@AIN:
Modifier: 150
RequiresCondition: ain
ResourceValueMultiplier@AIH:
Modifier: 300
RequiresCondition: aih
AIHProcUpgrade:
ProvidesPrerequisite:
Prerequisite: diffhard
Interactable:
AlwaysVisible:
AINProcUpgrade:
ProvidesPrerequisite:
Prerequisite: diffnorm
Interactable:
AlwaysVisible:
HTNK:
Buildable:
Prerequisites: ~techlevel.high
A10:
Targetable:
FLARE:
RevealsShroud:
Range: 5c0
CAMERA:
RevealsShroud:
Range: 5c0

View File

@@ -0,0 +1,3 @@
IonCannon:
Warhead@1Dam_impact: SpreadDamage
Falloff: 1000, 60, 40, 20

View File

@@ -35,6 +35,9 @@ Nod Campaign:
nod10a nod10a
nod10b nod10b
Covert Operations:
eviction-notice
Funpark Campaign: Funpark Campaign:
funpark01 funpark01