Initial commit: OpenRA game engine
Some checks failed
Continuous Integration / Linux (.NET 8.0) (push) Has been cancelled
Continuous Integration / Windows (.NET 8.0) (push) Has been cancelled

Fork from OpenRA/OpenRA with one-click launch script (start-ra.cmd)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
let5sne.win10
2026-01-10 21:46:54 +08:00
commit 9cf6ebb986
4065 changed files with 635973 additions and 0 deletions

Binary file not shown.

View File

@@ -0,0 +1,9 @@
## rules.yaml
briefing =
The Brotherhood has located a huge field of Tiberium in the area.
The nearby village has laid claim to the field.
Eliminate the villagers, to prevent any risk of infection to our workers.
GDI forces are reported to be minimal, so their elimination is of secondary importance.

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -0,0 +1,603 @@
MapFormat: 12
RequiresMod: cnc
Title: 07a: Sick and Dying
Author: Westwood Studios
Tileset: DESERT
MapSize: 64,64
Bounds: 2,6,58,55
Visibility: MissionSelector
Categories: Campaign
LockPreview: True
Players:
PlayerReference@GDI:
Name: GDI
Faction: gdi
Color: F5D378
Allies: Civilians
Enemies: Nod
Bot: campaign
PlayerReference@Neutral:
Name: Neutral
OwnsWorld: True
NonCombatant: True
Faction: gdi
Bot: campaign
PlayerReference@Civilians:
Name: Civilians
NonCombatant: True
Faction: gdi
Allies: GDI
Enemies: Nod
Bot: campaign
PlayerReference@Nod:
Name: Nod
Faction: nod
AllowBots: False
Playable: True
Required: True
LockFaction: True
LockColor: True
Color: FE1100
LockSpawn: True
LockTeam: True
Enemies: GDI, Civilians
PlayerReference@NodBase:
Name: NodBase
Faction: nod
Color: FE1100
Bot: campaign
Actors:
Actor0: cycl
Location: 30,60
Owner: GDI
Actor1: cycl
Location: 29,60
Owner: GDI
Actor2: cycl
Location: 28,60
Owner: GDI
Actor3: cycl
Location: 27,60
Owner: GDI
Actor4: cycl
Location: 26,60
Owner: GDI
Actor5: cycl
Location: 25,60
Owner: GDI
Actor6: cycl
Location: 24,60
Owner: GDI
Actor7: cycl
Location: 23,60
Owner: GDI
Actor8: cycl
Location: 22,60
Owner: GDI
Actor9: cycl
Location: 21,60
Owner: GDI
Actor10: cycl
Location: 20,60
Owner: GDI
Actor11: cycl
Location: 19,60
Owner: GDI
Actor12: cycl
Location: 18,60
Owner: GDI
Actor13: cycl
Location: 17,60
Owner: GDI
Actor14: cycl
Location: 16,60
Owner: GDI
Actor15: cycl
Location: 15,60
Owner: GDI
Actor16: cycl
Location: 14,60
Owner: GDI
Actor17: cycl
Location: 13,60
Owner: GDI
Actor18: cycl
Location: 12,60
Owner: GDI
Actor19: cycl
Location: 11,60
Owner: GDI
Actor20: cycl
Location: 30,59
Owner: GDI
Actor21: cycl
Location: 11,59
Owner: GDI
Actor22: cycl
Location: 30,58
Owner: GDI
Actor23: cycl
Location: 11,58
Owner: GDI
Actor24: cycl
Location: 30,57
Owner: GDI
Actor25: cycl
Location: 11,57
Owner: GDI
Actor26: cycl
Location: 30,56
Owner: GDI
Actor27: cycl
Location: 30,55
Owner: GDI
Actor28: cycl
Location: 30,54
Owner: GDI
Actor29: cycl
Location: 30,53
Owner: GDI
Actor30: cycl
Location: 11,53
Owner: GDI
Actor31: cycl
Location: 30,52
Owner: GDI
Actor32: cycl
Location: 11,52
Owner: GDI
Actor33: cycl
Location: 30,51
Owner: GDI
Actor34: cycl
Location: 11,51
Owner: GDI
Actor35: cycl
Location: 30,50
Owner: GDI
Actor36: cycl
Location: 29,50
Owner: GDI
Actor37: cycl
Location: 28,50
Owner: GDI
Actor38: cycl
Location: 27,50
Owner: GDI
Actor39: cycl
Location: 26,50
Owner: GDI
Actor40: cycl
Location: 25,50
Owner: GDI
Actor41: cycl
Location: 24,50
Owner: GDI
Actor42: cycl
Location: 23,50
Owner: GDI
Actor43: cycl
Location: 22,50
Owner: GDI
Actor44: cycl
Location: 21,50
Owner: GDI
Actor45: cycl
Location: 20,50
Owner: GDI
Actor46: cycl
Location: 19,50
Owner: GDI
Actor47: cycl
Location: 18,50
Owner: GDI
Actor48: cycl
Location: 12,50
Owner: GDI
Actor49: cycl
Location: 11,50
Owner: GDI
Actor50: t18
Location: 44,41
Owner: Neutral
Actor51: t08
Location: 16,47
Owner: Neutral
Actor52: t08
Location: 3,47
Owner: Neutral
Actor53: t08
Location: 49,42
Owner: Neutral
Actor54: t08
Location: 44,54
Owner: Neutral
Actor55: t08
Location: 46,55
Owner: Neutral
Actor56: t08
Location: 29,19
Owner: Neutral
Actor57: t18
Location: 15,20
Owner: Neutral
Actor58: t18
Location: 13,43
Owner: Neutral
Actor59: t18
Location: 8,46
Owner: Neutral
Actor60: t18
Location: 16,48
Owner: Neutral
Actor61: t08
Location: 3,23
Owner: Neutral
Actor62: t08
Location: 6,22
Owner: Neutral
Actor63: t08
Location: 17,28
Owner: Neutral
Actor64: t08
Location: 22,16
Owner: Neutral
Actor80: hosp
Location: 4,49
Owner: GDI
Actor82: v20
Location: 17,42
Owner: Civilians
Actor83: v21
Location: 19,43
Owner: Civilians
Actor84: v22
Location: 16,46
Owner: Civilians
Actor85: v23
Location: 17,47
Owner: Civilians
Actor86: v24
Location: 12,43
Owner: Civilians
Actor87: v27
Location: 11,47
Owner: Civilians
Actor88: v27
Location: 9,48
Owner: Civilians
Actor89: v28
Location: 8,48
Owner: Civilians
Actor90: v29
Location: 14,43
Owner: Civilians
Actor91: v30
Location: 16,48
Owner: Civilians
Actor92: v28
Location: 9,46
Owner: Civilians
Actor93: v29
Location: 10,47
Owner: Civilians
Actor94: v33
Location: 54,53
Owner: Civilians
Actor95: v35
Location: 53,53
Owner: Civilians
Actor96: v36
Location: 43,53
Owner: Civilians
Actor97: v32
Location: 42,54
Owner: Civilians
Actor98: v31
Location: 45,54
Owner: Civilians
Actor99: v30
Location: 44,55
Owner: Civilians
Actor100: v29
Location: 42,53
Owner: Civilians
Actor101: v28
Location: 47,55
Owner: Civilians
Actor102: v26
Location: 47,54
Owner: Civilians
Actor106: v25
Location: 14,47
Owner: Civilians
Actor107: jeep
Location: 17,59
Owner: GDI
Actor108: jeep
Location: 29,53
Owner: GDI
Actor109: mtnk
Location: 28,59
Owner: GDI
Actor110: mtnk
Location: 12,59
Owner: GDI
Actor111: mtnk
Location: 13,59
Owner: GDI
Actor115: mtnk
Location: 18,28
Owner: GDI
Facing: 128
Actor116: mtnk
Location: 17,21
Owner: GDI
Facing: 384
Actor117: e2
Location: 20,52
Owner: GDI
SubCell: 1
Actor118: e2
Location: 13,53
Owner: GDI
SubCell: 2
Actor119: e2
Location: 12,52
Owner: GDI
SubCell: 3
Actor120: e1
Location: 21,52
Owner: GDI
SubCell: 2
Actor121: e1
Location: 13,52
Owner: GDI
SubCell: 1
Actor122: e1
Location: 20,51
Owner: GDI
SubCell: 3
Actor123: e2
Location: 8,45
Owner: GDI
SubCell: 2
Actor124: e2
Location: 9,50
Owner: GDI
SubCell: 1
Actor125: e2
Location: 9,45
Owner: GDI
SubCell: 3
Actor126: c6
Location: 18,51
Owner: Civilians
Facing: 128
SubCell: 4
Actor127: c5
Location: 10,48
Owner: Civilians
Facing: 896
SubCell: 0
Actor142: c8
Location: 48,52
Owner: Civilians
Facing: 896
SubCell: 4
Actor143: c4
Location: 52,57
Owner: Civilians
Facing: 128
SubCell: 1
Actor144: c3
Location: 11,46
Owner: Civilians
SubCell: 4
Actor145: c9
Location: 15,44
Owner: Civilians
Facing: 256
SubCell: 0
Actor146: e2
Location: 12,57
Owner: GDI
SubCell: 2
Actor147: e2
Location: 13,57
Owner: GDI
SubCell: 1
Actor148: e2
Location: 12,57
Owner: GDI
SubCell: 4
Actor149: e2
Location: 13,57
Owner: GDI
SubCell: 3
waypoint27: waypoint
Location: 32,35
Owner: Neutral
waypoint26: waypoint
Location: 47,35
Owner: Neutral
waypoint24: waypoint
Location: 52,15
Owner: Neutral
waypoint25: waypoint
Location: 54,14
Owner: Neutral
waypoint14: waypoint
Location: 13,47
Owner: Neutral
waypoint13: waypoint
Location: 52,8
Owner: Neutral
waypoint12: waypoint
Location: 14,8
Owner: Neutral
waypoint11: waypoint
Location: 9,24
Owner: Neutral
waypoint10: waypoint
Location: 22,25
Owner: Neutral
waypoint9: waypoint
Location: 31,19
Owner: Neutral
waypoint8: waypoint
Location: 53,21
Owner: Neutral
waypoint7: waypoint
Location: 58,27
Owner: Neutral
waypoint6: waypoint
Location: 39,25
Owner: Neutral
waypoint5: waypoint
Location: 35,40
Owner: Neutral
waypoint4: waypoint
Location: 22,32
Owner: Neutral
waypoint3: waypoint
Location: 9,44
Owner: Neutral
waypoint2: waypoint
Location: 7,50
Owner: Neutral
waypoint1: waypoint
Location: 9,54
Owner: Neutral
waypoint0: waypoint
Location: 15,54
Owner: Neutral
AttackPath1: waypoint
Owner: Neutral
Location: 26,25
AttackPath2: waypoint
Owner: Neutral
Location: 37,33
GDIBuilding1: gtwr
Location: 10,53
Owner: GDI
GDIBuilding2: gtwr
Location: 13,50
Owner: GDI
GDIBuilding3: gtwr
Location: 17,50
Owner: GDI
GDIBuilding4: gtwr
Location: 10,57
Owner: GDI
GDIBuilding5: nuke
Location: 2,48
Owner: GDI
GDIBuilding6: silo
Location: 25,51
Owner: GDI
GDIBuilding7: silo
Location: 14,58
Owner: GDI
GDIBuilding8: silo
Location: 25,53
Owner: GDI
GDICYard: fact
Location: 22,57
Owner: GDI
GDIHarvester: harv
Location: 13,55
Owner: GDI
Facing: 768
GDIHQ: hq
Location: 20,57
Owner: GDI
GDINuke1: nuke
Location: 16,56
Owner: GDI
GDINuke2: nuke
Location: 18,57
Owner: GDI
GDINuke3: nuke
Location: 27,51
Owner: GDI
GDIPyle: pyle
Location: 18,54
Owner: GDI
GDIProc: proc
Location: 22,51
Owner: GDI
FreeActor: False
GDISearchTopLeft: waypoint
Owner: Neutral
Location: 11,50
GDISearchBottomRight: waypoint
Owner: Neutral
Location: 30,60
GDIWeap: weap
Location: 27,55
Owner: GDI
NodBuilding1: fact
Location: 54,11
Owner: NodBase
Health: 46
NodBuilding2: proc
Location: 51,11
Owner: NodBase
Health: 45
FreeActor: False
NodBuilding3: nuke
Location: 55,14
Owner: NodBase
Health: 47
NodHarvester: harv
Owner: NodBase
Location: 46,31
Facing: 368
ReinforcementsBottomSpawn: waypoint
Owner: Neutral
Location: 59,41
ReinforcementsEngineersRally: waypoint
Owner: Neutral
Location: 52,40
ReinforcementsFlamersRally: waypoint
Owner: Neutral
Location: 54,39
ReinforcementsGDISpawn: waypoint
Owner: Neutral
Location: 8,6
ReinforcementsGunnersRally: waypoint
Owner: Neutral
Location: 54,41
ReinforcementsHelicopterSpawn: waypoint
Owner: Neutral
Location: 59,16
ReinforcementsRocketsRally: waypoint
Owner: Neutral
Location: 52,41
ReinforcementsTank1Rally: waypoint
Owner: Neutral
Location: 51,40
ReinforcementsTank2Rally: waypoint
Owner: Neutral
Location: 56,40
ReinforcementsTopSpawn: waypoint
Owner: Neutral
Location: 59,38
Rules: cnc|rules/campaign-maprules.yaml, cnc|rules/campaign-tooltips.yaml, cnc|rules/campaign-palettes.yaml, rules.yaml
Weapons: weapons.yaml
FluentMessages: cnc|fluent/lua.ftl, cnc|fluent/campaign.ftl, map.ftl

View File

@@ -0,0 +1,159 @@
--[[
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.
]]
AttackPaths = { { AttackPath1 }, { AttackPath2 } }
GDIBase = { GDICYard, GDIPyle, GDIWeap, GDIHQ, GDIProc, GDINuke1, GDINuke2, GDINuke3, GDIBuilding1, GDIBuilding2, GDIBuilding3, GDIBuilding4, GDIBuilding5, GDIBuilding6, GDIBuilding7, GDIBuilding8 }
InfantryAttackGroup = { }
InfantryGroupSize = 4
InfantryProductionCooldown = DateTime.Minutes(3)
InfantryProductionTypes = { "e1", "e1", "e2" }
HarvesterProductionType = { "harv" }
VehicleAttackGroup = { }
VehicleGroupSize = 4
VehicleProductionCooldown = DateTime.Minutes(4)
VehicleProductionTypes = { "jeep", "jeep", "mtnk", "mtnk", "mtnk" }
StartingCash = 4000
BaseProc = { type = "proc", pos = CPos.New(22, 51), cost = 1500 }
BaseNuke1 = { type = "nuke", pos = CPos.New(16, 56), cost = 500 }
BaseNuke2 = { type = "nuke", pos = CPos.New(18, 57), cost = 500 }
BaseNuke3 = { type = "nuke", pos = CPos.New(27, 51), cost = 500 }
InfantryProduction = { type = "pyle", pos = CPos.New(18, 54), cost = 500 }
VehicleProduction = { type = "weap", pos = CPos.New(27, 55), cost = 2000 }
BaseBuildings = { BaseProc, BaseNuke1, BaseNuke2, BaseNuke3, InfantryProduction, VehicleProduction }
BuildBuilding = function(building, cyard)
if CyardIsBuilding or GDI.Cash < building.cost then
Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBuilding(building, cyard) end)
return
end
CyardIsBuilding = true
GDI.Cash = GDI.Cash - building.cost
Trigger.AfterDelay(Actor.BuildTime(building.type), function()
CyardIsBuilding = false
if cyard.IsDead or cyard.Owner ~= GDI then
GDI.Cash = GDI.Cash + building.cost
return
end
local actor = Actor.Create(building.type, true, { Owner = GDI, Location = building.pos })
if actor.Type == 'pyle' or actor.Type == 'hand' then
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(actor) end)
elseif actor.Type == 'weap' or actor.Type == 'afld' then
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(actor) end)
end
Trigger.OnKilled(actor, function()
BuildBuilding(building, cyard)
end)
RepairBuilding(GDI, actor, 0.75)
end)
end
CheckForHarvester = function()
local harv = GDI.GetActorsByType("harv")
return #harv > 0
end
ProduceHarvester = function(building)
if not BuildingHarvester then
BuildingHarvester = true
building.Build(HarvesterProductionType, function()
BuildingHarvester = false
end)
end
end
ProduceInfantry = function(building)
if building.IsDead or building.Owner ~= GDI then
return
elseif not CheckForHarvester() then
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(building) end)
return
end
local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9))
local toBuild = { Utils.Random(InfantryProductionTypes) }
local Path = Utils.Random(AttackPaths)
building.Build(toBuild, function(unit)
InfantryAttackGroup[#InfantryAttackGroup + 1] = unit[1]
if #InfantryAttackGroup >= InfantryGroupSize then
MoveAndHunt(InfantryAttackGroup, Path)
InfantryAttackGroup = { }
Trigger.AfterDelay(InfantryProductionCooldown, function() ProduceInfantry(building) end)
else
Trigger.AfterDelay(delay, function() ProduceInfantry(building) end)
end
end)
end
ProduceVehicle = function(building)
if building.IsDead or building.Owner ~= GDI then
return
elseif not CheckForHarvester() then
ProduceHarvester(building)
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(building) end)
return
end
local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17))
local toBuild = { Utils.Random(VehicleProductionTypes) }
local Path = Utils.Random(AttackPaths)
building.Build(toBuild, function(unit)
VehicleAttackGroup[#VehicleAttackGroup + 1] = unit[1]
if #VehicleAttackGroup >= VehicleGroupSize then
MoveAndHunt(VehicleAttackGroup, Path)
VehicleAttackGroup = { }
Trigger.AfterDelay(VehicleProductionCooldown, function() ProduceVehicle(building) end)
else
Trigger.AfterDelay(delay, function() ProduceVehicle(building) end)
end
end)
end
StartAI = function()
RepairNamedActors(GDI, 0.75)
GDI.Cash = StartingCash
Trigger.AfterDelay(DateTime.Minutes(2), function() ProduceInfantry(GDIPyle) end)
Trigger.AfterDelay(DateTime.Minutes(3), function() ProduceVehicle(GDIWeap) end)
end
Trigger.OnKilled(GDIProc, function()
BuildBuilding(BaseProc, GDICYard)
end)
Trigger.OnKilled(GDINuke1, function()
BuildBuilding(BaseNuke1, GDICYard)
end)
Trigger.OnKilled(GDINuke2, function()
BuildBuilding(BaseNuke2, GDICYard)
end)
Trigger.OnKilled(GDINuke3, function()
BuildBuilding(BaseNuke3, GDICYard)
end)
Trigger.OnKilled(GDIPyle, function()
BuildBuilding(InfantryProduction, GDICYard)
end)
Trigger.OnKilled(GDIWeap, function()
BuildBuilding(VehicleProduction, GDICYard)
end)

View File

@@ -0,0 +1,199 @@
--[[
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.
]]
GDI1 = { teamType = "atk", units = { "e2", "e2", "e2" }, waypoints = { waypoint0, waypoint1, waypoint2, waypoint14 }, delay = 40 }
GDI2 = { teamType = "atk", units = { "mtnk", "mtnk" }, waypoints = { waypoint0, waypoint1, waypoint2, waypoint3, waypoint4, waypoint9 }, delay = 30 }
GDI3 = { teamType = "atk", units = { "e2", "e2", "e2", "e2" }, waypoints = { waypoint0, waypoint4, waypoint5, waypoint6, waypoint7, waypoint8 }, delay = 40 }
GDI4 = { teamType = "atk", units = { "e1", "e2", "e2" }, waypoints = { waypoint0, waypoint4, waypoint9 }, delay = 30 }
GDI5 = { teamType = "atk", units = { "mtnk" }, waypoints = { waypoint0, waypoint4, waypoint10, waypoint11, waypoint12, waypoint13 }, delay = 80 }
GDI6 = { teamType = "atk", units = { "mtnk" }, waypoints = { waypoint0, waypoint4, waypoint9 }, delay = 50 }
GDI7 = { teamType = "atk", units = { "jeep" }, waypoints = { waypoint0, waypoint4, waypoint5, waypoint6, waypoint7, waypoint8 }, delay = 40 }
GDI8 = { teamType = "rei", units = { "e2", "e2", "e2", "e6", "e6" }, waypoints = { waypoint12, waypoint11, waypoint10, waypoint4, waypoint5, waypoint8 }, delay = 8 }
GDI9 = { teamType = "atk", units = { "e2", "e2", "e2", "e2" }, waypoints = { waypoint8 }, delay = 80 }
GDI10 = { teamType = "atk", units = { "e2", "e2", "e2", "e2" }, waypoints = { waypoint14 }, delay = 0 }
AirstrikeDelay = DateTime.Minutes(2) + DateTime.Seconds(20)
AutoAttackWaves = { GDI3, GDI4, GDI5, GDI6, GDI7, GDI8, GDI9, GDI10 }
IntroAttackWaves = { GDI1, GDI2 }
WhitelistedStructures = { "afld", "hand", "hq", "nuke", "silo", "proc", "sam" }
NodUnitsBikes = { "bike", "bike", "bike" }
NodUnitsEngineers = { "e6", "e6" }
NodUnitsRockets = { "e3", "e3", "e3", "e3" }
NodUnitsGunners = { "e1", "e1", "e1", "e1" }
NodUnitsFlamers = { "e4", "e4", "e4", "e4" }
ReinforcementsRockets = { "e3", "e3", "e3", "e3", "e3" }
NodBase = { NodBuilding1, NodBuilding2, NodBuilding3, NodHarvester }
AbandonedBaseTrigger = { CPos.New(12, 42), CPos.New(11, 42), CPos.New(10, 42), CPos.New(13, 41), CPos.New(12, 41), CPos.New(11, 41), CPos.New(14, 40), CPos.New(13, 40), CPos.New(12, 40), CPos.New(6, 40), CPos.New(5, 40), CPos.New(4, 40), CPos.New(6, 39), CPos.New(5, 39), CPos.New(4, 39), CPos.New(6, 38), CPos.New(5, 38), CPos.New(4, 38) }
ReinforcementsTrigger = { CPos.New(35, 23), CPos.New(34, 23), CPos.New(35, 22), CPos.New(34, 22), CPos.New(35, 21), CPos.New(34, 21), CPos.New(35, 20), CPos.New(34, 20), CPos.New(35, 19), CPos.New(34, 19), CPos.New(35, 18), CPos.New(34, 18), CPos.New(35, 17), CPos.New(34, 17), CPos.New(35, 16), CPos.New(34, 16), CPos.New(35, 15), CPos.New(34, 15), CPos.New(35, 14), CPos.New(34, 14), CPos.New(35, 13), CPos.New(34, 13), CPos.New(35, 12), CPos.New(34, 12), CPos.New(47, 11), CPos.New(46, 11), CPos.New(57, 19), CPos.New(56, 19), CPos.New(55, 19), CPos.New(54, 19), CPos.New(53, 19), CPos.New(52, 19), CPos.New(51, 19), CPos.New(50, 19), CPos.New(49, 19), CPos.New(48, 19), CPos.New(47, 19), CPos.New(46, 19), CPos.New(57, 18), CPos.New(56, 18), CPos.New(55, 18), CPos.New(54, 18), CPos.New(53, 18), CPos.New(52, 18), CPos.New(51, 18), CPos.New(50, 18), CPos.New(49, 18), CPos.New(48, 18), CPos.New(47, 18), CPos.New(46, 18), CPos.New(47, 17), CPos.New(46, 17), CPos.New(47, 16), CPos.New(46, 16), CPos.New(47, 15), CPos.New(46, 15), CPos.New(47, 14), CPos.New(46, 14), CPos.New(47, 13), CPos.New(46, 13), CPos.New(47, 12), CPos.New(46, 12) }
SamSiteGoal = 3
CaptureStructures = function(actor)
for i = 1, #WhitelistedStructures do
local structures = Nod.GetActorsByType(WhitelistedStructures[i])
if #structures > 0 and not actor.IsDead and not structures[1].IsDead then
actor.Capture(structures[1])
return
end
end
end
CheckForSams = function()
local sams = Nod.GetActorsByType("sam")
return #sams >= SamSiteGoal
end
InsertNodUnits = function()
Media.PlaySpeechNotification(Nod, "Reinforce")
Reinforcements.Reinforce(Nod, { "ltnk" }, { ReinforcementsTopSpawn.Location, ReinforcementsTank1Rally.Location }, 1)
Reinforcements.Reinforce(Nod, NodUnitsEngineers, { ReinforcementsTopSpawn.Location, ReinforcementsEngineersRally.Location }, 10)
Reinforcements.Reinforce(Nod, NodUnitsRockets, { ReinforcementsTopSpawn.Location, ReinforcementsRocketsRally.Location }, 10)
Trigger.AfterDelay(DateTime.Seconds(3), function()
Reinforcements.Reinforce(Nod, NodUnitsGunners, { ReinforcementsBottomSpawn.Location, ReinforcementsGunnersRally.Location }, 10)
Reinforcements.Reinforce(Nod, NodUnitsFlamers, { ReinforcementsTopSpawn.Location, ReinforcementsFlamersRally.Location }, 10)
Reinforcements.Reinforce(Nod, { "ltnk" }, { ReinforcementsBottomSpawn.Location, ReinforcementsTank2Rally.Location }, 10)
end)
end
SendAttackWave = function(team)
Utils.Do(team.units, function(unitType)
local actors = Utils.Where(GDI.GetActorsByType(unitType), function(unit) return unit.IsIdle end)
MoveAndHunt(Utils.Take(1, actors), team.waypoints)
end)
end
SendGDIAirstrike = function(hq, delay)
if not hq.IsDead and hq.Owner == GDI then
local target = GetAirstrikeTarget(Nod)
if target then
hq.TargetAirstrike(target, Angle.NorthEast + Angle.New(16))
Trigger.AfterDelay(delay, function() SendGDIAirstrike(hq, delay) end)
else
Trigger.AfterDelay(delay/4, function() SendGDIAirstrike(hq, delay) end)
end
end
end
SendWaves = function(counter, Waves)
if counter <= #Waves then
local team = Waves[counter]
if team.teamType == "atk" then
SendAttackWave(team)
elseif team.teamType == "rei" then
SendReinforcementsWave(team)
end
Trigger.AfterDelay(DateTime.Seconds(team.delay), function() SendWaves(counter + 1, Waves) end)
end
end
SendReinforcementsWave = function(team)
Reinforcements.ReinforceWithTransport(GDI, "apc", team.units, { ReinforcementsGDISpawn.Location, waypoint12.Location }, nil, function(transport, passengers)
Utils.Do(team.waypoints, function(waypoint)
transport.Move(waypoint.Location)
end)
transport.UnloadPassengers()
Trigger.OnPassengerExited(transport, function(_, passenger)
if passenger.Type == "e6" then
Trigger.OnIdle(passenger, CaptureStructures)
else
IdleHunt(passenger)
end
if not transport.HasPassengers then
IdleHunt(transport)
end
end)
end)
end
Trigger.OnEnteredFootprint(AbandonedBaseTrigger, function(a, id)
if not AbandonedBaseTriggered and a.Owner == Nod then
AbandonedBaseTriggered = true
Trigger.RemoveFootprintTrigger(id)
FlareCamera = Actor.Create("camera", true, { Owner = Nod, Location = waypoint25.Location })
Flare = Actor.Create("flare", true, { Owner = Nod, Location = waypoint25.Location })
Utils.Do(NodBase, function(actor)
if not actor.IsDead then
actor.Owner = Nod
end
end)
Nod.MarkCompletedObjective(FindBase)
Trigger.AfterDelay(DateTime.Seconds(3), function()
Media.PlaySpeechNotification(Nod, "NewOptions")
end)
end
end)
Trigger.OnEnteredFootprint(ReinforcementsTrigger, function(a, id)
if not ReinforcementsTriggered and a.Owner == Nod and a.Type ~= "harv" then
ReinforcementsTriggered = true
Trigger.RemoveFootprintTrigger(id)
Trigger.AfterDelay(DateTime.Seconds(5), function()
Media.PlaySpeechNotification(Nod, "Reinforce")
Reinforcements.ReinforceWithTransport(Nod, "tran.in", ReinforcementsRockets, { ReinforcementsHelicopterSpawn.Location, waypoint24.Location }, { ReinforcementsHelicopterSpawn.Location })
end)
SendWaves(1, IntroAttackWaves)
Trigger.AfterDelay(AirstrikeDelay, function() SendGDIAirstrike(GDIHQ, AirstrikeDelay) end)
Trigger.AfterDelay(DateTime.Minutes(3), function() SendWaves(1, AutoAttackWaves) end)
Trigger.AfterDelay(DateTime.Minutes(2), function()
Flare.Destroy()
FlareCamera.Destroy()
end)
end
end)
WorldLoaded = function()
Nod = Player.GetPlayer("Nod")
GDI = Player.GetPlayer("GDI")
Camera.Position = waypoint26.CenterPosition
InsertNodUnits()
StartAI()
InitObjectives(Nod)
FindBase = AddPrimaryObjective(Nod, "find-nod-base")
EliminateGDI = AddPrimaryObjective(Nod, "eliminate-gdi-forces")
local buildSAMs = UserInterface.GetFluentMessage("build-sams", { ["sams"] = SamSiteGoal })
BuildSAMs = AddPrimaryObjective(Nod, buildSAMs)
GDIObjective = AddPrimaryObjective(GDI, "")
Trigger.OnKilled(GDIProc, function()
Actor.Create("moneycrate", true, { Owner = GDI, Location = CPos.New(24, 54) })
end)
end
Tick = function()
if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then
GDI.MarkCompletedObjective(GDIObjective)
end
if DateTime.GameTime > 2 and GDI.HasNoRequiredUnits() then
Nod.MarkCompletedObjective(EliminateGDI)
end
if not Nod.IsObjectiveCompleted(BuildSAMs) and CheckForSams() then
Nod.MarkCompletedObjective(BuildSAMs)
end
end

View File

@@ -0,0 +1,144 @@
World:
LuaScript:
Scripts: campaign.lua, utils.lua, nod07a.lua, nod07a-AI.lua
MusicPlaylist:
StartingMusic: justdoit
VictoryMusic: nod_win1
MissionData:
Briefing: briefing
BriefingVideo: nod7a.vqa
StartVideo: tankgo.vqa
LossVideo: visor.vqa
Player:
PlayerResources:
DefaultCash: 1000
^Bridge:
DamageMultiplier@INVULNERABLE:
Modifier: 0
^CivBuilding:
Targetable:
TargetTypes: Ground, C4, Structure, NoAutoTarget
CYCL:
Buildable:
Prerequisites: ~disabled
NUK2:
Buildable:
Prerequisites: ~disabled
HPAD:
Buildable:
Prerequisites: ~disabled
BRIK:
Buildable:
Prerequisites: ~disabled
EYE:
Buildable:
Prerequisites: ~disabled
GUN:
Buildable:
Prerequisites: ~disabled
OBLI:
Buildable:
Prerequisites: ~disabled
TMPL:
Buildable:
Prerequisites: ~disabled
E2:
Buildable:
Prerequisites: ~pyle
E5:
Buildable:
Prerequisites: ~disabled
E6:
-RepairsBridges:
HARV:
Harvester:
SearchFromProcRadius: 45
SearchFromHarvesterRadius: 45
HTNK:
Buildable:
Prerequisites: ~disabled
RMBO:
Buildable:
Prerequisites: ~disabled
MCV:
Buildable:
Prerequisites: ~disabled
MTNK:
Buildable:
Prerequisites: ~weap
FTNK:
Buildable:
Prerequisites: ~disabled
MLRS:
Buildable:
Prerequisites: ~disabled
MSAM:
Buildable:
Prerequisites: ~disabled
ATWR:
Buildable:
Prerequisites: ~disabled
HELI:
Buildable:
Prerequisites: ~disabled
STNK:
Buildable:
Prerequisites: ~disabled
ARTY:
Buildable:
Prerequisites: ~disabled
FIX:
Buildable:
Prerequisites: ~disabled
SBAG:
Buildable:
Queue: Support.GDI, Support.Nod
GTWR:
Buildable:
Queue: Support.GDI
Armament:
Weapon: HighV.in
HQ:
AirstrikePower:
Prerequisites: gdi
SquadSize: 1
TRAN.IN:
Inherits: TRAN
RejectsOrders:
-Selectable:
RenderSprites:
Image: TRAN
Buildable:
Prerequisites: ~disabled
Interactable:

View File

@@ -0,0 +1,3 @@
HighV.IN:
Inherits: HighV
Range: 4c0