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,7 @@
## rules.yaml
briefing =
Khalkis island contains a large quantity of ore that we need.
The Allies are well aware of our plans, and intend to establish their own base there. See to it that they fail.
Additionally, capture their radar center so we can track Allied activity in the area.

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1,594 @@
MapFormat: 12
RequiresMod: ra
Title: 05: Distant Thunder
Author: Westwood Studios
Tileset: TEMPERAT
MapSize: 128,128
Bounds: 20,42,90,50
Visibility: MissionSelector
Categories: Campaign
LockPreview: True
Players:
PlayerReference@Neutral:
Name: Neutral
OwnsWorld: True
NonCombatant: True
Faction: england
PlayerReference@Greece:
Name: Greece
Faction: allies
Color: E2E6F5
Allies: GoodGuy, France
Enemies: USSR
Bot: campaign
PlayerReference@USSR:
Name: USSR
Faction: soviet
Playable: True
AllowBots: False
Required: True
LockFaction: True
LockColor: True
Color: FE1100
LockSpawn: True
LockTeam: True
Enemies: Greece, GoodGuy, France
PlayerReference@GoodGuy:
Name: GoodGuy
Faction: allies
Color: E2E6F5
Allies: Greece, France
Enemies: USSR
Bot: campaign
PlayerReference@France:
Name: France
Faction: allies
Color: 0CF7B2
Allies: Greece, GoodGuy
Enemies: USSR
Bot: campaign
Actors:
Actor0: sbag
Location: 60,42
Owner: Neutral
Actor1: sbag
Location: 61,42
Owner: Neutral
Actor2: sbag
Location: 60,43
Owner: Neutral
Actor3: sbag
Location: 60,44
Owner: Neutral
Actor4: sbag
Location: 60,48
Owner: Neutral
Actor5: sbag
Location: 60,49
Owner: Neutral
Actor6: sbag
Location: 60,50
Owner: Neutral
Actor7: sbag
Location: 61,50
Owner: Neutral
Actor8: tc01
Location: 33,41
Owner: Neutral
Actor9: tc03
Location: 20,52
Owner: Neutral
Actor10: tc02
Location: 24,62
Owner: Neutral
Actor11: t06
Location: 62,84
Owner: Neutral
Actor12: t07
Location: 85,78
Owner: Neutral
Actor13: t14
Location: 84,77
Owner: Neutral
Actor14: t12
Location: 95,77
Owner: Neutral
Actor15: t07
Location: 78,77
Owner: Neutral
Actor16: t02
Location: 81,74
Owner: Neutral
Actor17: t16
Location: 46,79
Owner: Neutral
Actor18: tc03
Location: 47,78
Owner: Neutral
Actor19: t10
Location: 45,78
Owner: Neutral
Actor20: t14
Location: 45,77
Owner: Neutral
Actor21: t17
Location: 45,76
Owner: Neutral
Actor22: t08
Location: 60,83
Owner: Neutral
Actor23: t17
Location: 81,71
Owner: Neutral
Actor24: tc02
Location: 45,48
Owner: Neutral
Actor25: tc01
Location: 32,90
Owner: Neutral
Actor26: tc03
Location: 33,89
Owner: Neutral
Actor27: tc05
Location: 20,83
Owner: Neutral
Actor28: t11
Location: 25,88
Owner: Neutral
Actor29: t17
Location: 20,90
Owner: Neutral
Actor30: tc01
Location: 24,90
Owner: Neutral
Actor31: tc04
Location: 23,89
Owner: Neutral
Actor32: tc05
Location: 20,89
Owner: Neutral
Actor33: t01
Location: 28,47
Owner: Neutral
Actor34: t05
Location: 24,42
Owner: Neutral
Actor35: tc04
Location: 36,54
Owner: Neutral
Actor36: tc01
Location: 36,51
Owner: Neutral
Actor37: tc02
Location: 61,42
Owner: Neutral
Actor38: tc02
Location: 63,70
Owner: Neutral
Actor39: t12
Location: 73,79
Owner: Neutral
Actor40: tc03
Location: 82,64
Owner: Neutral
Actor41: t03
Location: 46,58
Owner: Neutral
Actor42: tc05
Location: 57,50
Owner: Neutral
Actor43: t16
Location: 59,41
Owner: Neutral
Actor44: tc01
Location: 56,51
Owner: Neutral
Actor45: t11
Location: 47,48
Owner: Neutral
Actor46: t05
Location: 51,48
Owner: Neutral
Actor47: mine
Location: 27,48
Owner: Neutral
Actor48: t01
Location: 71,81
Owner: Neutral
Actor49: t02
Location: 71,82
Owner: Neutral
Actor50: t02
Location: 81,61
Owner: Neutral
Actor51: t03
Location: 80,57
Owner: Neutral
Actor52: t05
Location: 80,58
Owner: Neutral
Actor53: tc01
Location: 78,61
Owner: Neutral
Actor54: agun
Location: 73,46
Owner: Greece
Actor55: gun
Location: 69,49
Owner: Greece
Facing: 128
RadarDome: dome
Location: 70,45
Owner: France
Actor57: fact
Location: 67,42
Owner: Greece
Actor58: powr
Location: 74,47
Owner: Greece
Actor59: brl3
Location: 66,42
Owner: Greece
Actor60: brl3
Location: 71,42
Owner: Greece
Actor61: brl3
Location: 71,43
Owner: Greece
Actor62: brl3
Location: 76,43
Owner: Greece
Actor63: barl
Location: 71,44
Owner: Greece
Actor64: brl3
Location: 73,47
Owner: Greece
Actor65: barl
Location: 66,43
Owner: Greece
Actor66: brl3
Location: 70,42
Owner: Greece
Actor67: gun
Location: 61,44
Owner: Greece
Facing: 768
Actor68: gun
Location: 61,48
Owner: Greece
Facing: 640
Actor69: agun
Location: 68,47
Owner: Greece
Actor70: proc
Location: 63,42
Owner: Greece
FreeActor: False
Barr: tent
Location: 63,47
Owner: Greece
Navalyard: syrd
Location: 78,48
Owner: Greece
Actor73: powr
Location: 74,42
Owner: Greece
Actor74: powr
Location: 72,42
Owner: Greece
Actor75: powr
Location: 72,48
Owner: Greece
startmcv: mcv
Location: 22,80
Owner: USSR
Facing: 768
Actor77: 2tnk
Location: 59,43
Owner: Greece
Facing: 128
Actor78: 1tnk
Location: 58,48
Owner: Greece
Facing: 128
Actor79: 1tnk
Location: 57,44
Owner: Greece
Facing: 384
Actor80: 1tnk
Location: 67,49
Owner: Greece
Facing: 896
Harvester: harv
Location: 45,45
Owner: Greece
Facing: 384
mcvGG: mcv
Location: 75,46
Owner: Greece
Facing: 768
Actor83: 1tnk
Location: 43,47
Owner: Greece
Facing: 896
TurretFacing: 384
Actor84: e1
Location: 61,45
Owner: Greece
Facing: 640
SubCell: 1
Actor85: e1
Location: 62,46
Owner: Greece
Facing: 640
SubCell: 0
Actor86: e1
Location: 61,49
Owner: Greece
Facing: 896
SubCell: 2
Runner1: e1
Location: 25,75
Owner: Greece
SubCell: 0
Runner2: e1
Location: 25,76
Owner: Greece
SubCell: 2
Runner3: e1
Location: 26,75
Owner: Greece
SubCell: 0
Actor90: e1
Location: 64,49
Owner: Greece
Facing: 384
SubCell: 2
Actor91: e3
Location: 66,44
Owner: Greece
Facing: 640
SubCell: 4
Actor92: e3
Location: 63,49
Owner: Greece
Facing: 640
SubCell: 4
Actor93: e1
Location: 58,46
Owner: Greece
Facing: 640
SubCell: 2
Actor94: e1
Location: 60,48
Owner: Greece
SubCell: 2
Actor96: e3
Location: 41,45
Owner: Greece
SubCell: 4
Facing: 256
TurretFacing: 256
Actor97: e3
Location: 41,44
Owner: Greece
SubCell: 1
Facing: 384
TurretFacing: 256
Actor98: e3
Location: 40,45
Owner: Greece
SubCell: 4
Facing: 256
TurretFacing: 384
Actor99: e3
Location: 40,43
Owner: Greece
SubCell: 1
Facing: 384
TurretFacing: 256
Actor100: e1
Location: 39,45
Owner: Greece
Facing: 640
SubCell: 0
Actor101: e1
Location: 39,44
Owner: Greece
SubCell: 1
Facing: 384
TurretFacing: 384
Minelayer: mnly
Owner: Greece
Location: 67,45
Facing: 368
Actor166: pt
Owner: Greece
Location: 67,54
Facing: 368
Actor167: pt
Owner: Greece
Location: 67,59
Facing: 240
Actor168: pt
Owner: Greece
Location: 83,56
Facing: 112
Actor169: pt
Owner: Greece
Location: 83,51
Facing: 368
mcvtransport: lst
Owner: Greece
Location: 80,45
Facing: 368
Actor171: dd
Owner: Greece
Location: 91,51
Facing: 112
Actor172: dd
Owner: Greece
Location: 84,44
Facing: 368
Actor173: dd
Owner: Greece
Location: 96,44
Facing: 368
Actor174: pt
Owner: Greece
Location: 96,51
Facing: 368
Actor175: dd
Owner: Greece
Location: 101,49
Facing: 240
Actor176: pt
Owner: Greece
Location: 107,70
Facing: 752
Actor177: pt
Owner: Greece
Location: 58,89
Facing: 240
Actor181: mine
Owner: Neutral
Location: 63,65
Actor182: mine
Owner: Neutral
Location: 81,78
StartPoint: waypoint
Location: 20,80
Owner: Neutral
SovietBasePoint: waypoint
Location: 24,77
Owner: Neutral
MCVStartMovePoint: waypoint
Location: 28,76
Owner: Neutral
CrossroadPoint: waypoint
Location: 52,46
Owner: Neutral
GreeceBaseEPoint: waypoint
Location: 60,46
Owner: Neutral
NReinfPathPoint1: waypoint
Location: 107,68
Owner: Neutral
SReinfPathPoint1: waypoint
Location: 100,81
Owner: Neutral
SReinfPathPoint2: waypoint
Location: 83,90
Owner: Neutral
NearExpPoint: waypoint
Location: 94,49
Owner: Neutral
CoastGuardPoint: waypoint
Location: 96,56
Owner: Neutral
MCVDeploy: waypoint
Location: 96,60
Owner: Neutral
ReinfSouthPoint: waypoint
Location: 44,91
Owner: Neutral
WIslandPoint: waypoint
Location: 41,61
Owner: Neutral
NearDockPoint: waypoint
Location: 85,46
Owner: Neutral
SReinfPathPoint4: waypoint
Location: 58,88
Owner: Neutral
PatrolPoint1: waypoint
Location: 91,69
Owner: Neutral
PatrolPoint4: waypoint
Location: 73,70
Owner: Neutral
SReinfPathPoint3: waypoint
Location: 69,90
Owner: Neutral
PatrolPoint2: waypoint
Location: 89,80
Owner: Neutral
BetweenBasesPoint: waypoint
Location: 78,73
Owner: Neutral
PatrolPoint3: waypoint
Location: 78,80
Owner: Neutral
USSRExpansionPoint: waypoint
Location: 56,77
Owner: Neutral
PrepGGArmyPoint: waypoint
Location: 71,74
Owner: Neutral
ReinfNorthPoint: waypoint
Location: 81,42
Owner: Neutral
ReinfEastPoint: waypoint
Location: 109,75
Owner: Neutral
NWOrefieldPoint: waypoint
Location: 32,49
Owner: Neutral
AtUSSRBasePoint: waypoint
Location: 27,61
Owner: Neutral
DDAttackPoint: waypoint
Location: 40,78
Owner: Neutral
RunnerPoint: waypoint
Location: 28,50
Owner: Neutral
USSRlstPoint: waypoint
Location: 48,83
Owner: Neutral
BaseRectBR: waypoint
Location: 42,90
Owner: Neutral
BaseRectTL: waypoint
Location: 20,42
Owner: Neutral
GreeceBasePoint: waypoint
Location: 69,46
Owner: Neutral
ReinfRoadPoint: waypoint
Location: 52,42
Owner: Neutral
EIslandPoint: waypoint
Location: 51,58
Owner: Neutral
mcvGGLoadPoint: waypoint
Location: 77,45
Owner: Neutral
lstBeachPoint: waypoint
Location: 78,45
Owner: Neutral
GGUnloadPoint: waypoint
Location: 94,54
Owner: Neutral
ParaPoint: waypoint
Location: 29,75
Owner: Neutral
StartCamPoint: waypoint
Location: 21,80
Owner: Neutral
Rules: ra|rules/campaign-rules.yaml, ra|rules/campaign-tooltips.yaml, ra|rules/campaign-palettes.yaml, rules.yaml
FluentMessages: ra|fluent/lua.ftl, ra|fluent/campaign.ftl, map.ftl

View File

@@ -0,0 +1,157 @@
Player:
PlayerResources:
DefaultCash: 5000
ExternalCondition@luaAI:
Condition: ai-active
HarvesterBotModule:
RequiresCondition: ai-active
BuildingRepairBotModule:
RequiresCondition: ai-active
McvManagerBotModule:
RequiresCondition: ai-active
BaseBuilderBotModule@campaign:
RequiresCondition: ai-active
MinimumExcessPower: 60
MaximumExcessPower: 160
ExcessPowerIncrement: 40
ExcessPowerIncreaseThreshold: 4
ConstructionYardTypes: fact
RefineryTypes: proc
PowerTypes: powr
ProductionTypes: tent, weap
SiloTypes: silo
BuildingLimits:
powr: 6
tent: 1
hbox: 3
proc: 3
weap: 1
gun: 6
agun: 2
silo: 1
BuildingFractions:
tent: 50
hbox: 50
proc: 90
weap: 20
gun: 30
agun: 20
silo: 10
SquadManagerBotModule@campaign:
RequiresCondition: ai-active
SquadSize: 10
ExcludeFromSquadsTypes: harv, mcv
NavalUnitsTypes: dd, ca, lst, pt
ConstructionYardTypes: fact
IgnoredEnemyTargetTypes: AirborneActor
UnitBuilderBotModule@campaign:
RequiresCondition: ai-active
UnitsToBuild:
e1: 60
e3: 30
jeep: 50
1tnk: 50
harv: 30
UnitLimits:
e1: 20
e3: 10
harv: 6
jeep: 10
1tnk: 10
World:
LuaScript:
Scripts: campaign.lua, utils.lua, soviet05.lua, soviet05-AI.lua, soviet05-reinforcements_teams.lua
MissionData:
Briefing: briefing
BriefingVideo: soviet5.vqa
StartVideo: double.vqa
WinVideo: strafe.vqa
LossVideo: sovbatl.vqa
MapOptions:
TechLevel: medium
ScriptLobbyDropdown@difficulty:
ID: difficulty
Label: dropdown-difficulty.label
Description: dropdown-difficulty.description
Values:
easy: options-difficulty.easy
normal: options-difficulty.normal
hard: options-difficulty.hard
Default: normal
MCV.CAM:
Inherits: CAMERA
RevealsShroud:
Range: 4c0
Type: CenterPosition
AFLD:
ParatroopersPower@paratroopers:
DropItems: E1,E1,E1,E2,E2
TSLA:
Buildable:
Prerequisites: ~disabled
SAM:
Buildable:
Prerequisites: ~disabled
HPAD:
Buildable:
Prerequisites: ~disabled
APWR:
Buildable:
Prerequisites: ~disabled
BRIK:
Buildable:
Prerequisites: ~disabled
E3:
Buildable:
Prerequisites: ~tent
E4:
Buildable:
Prerequisites: ~disabled
THF:
Buildable:
Prerequisites: ~disabled
SPY:
Buildable:
Prerequisites: ~disabled
MECH:
Buildable:
Prerequisites: ~disabled
MCV:
Buildable:
Prerequisites: ~disabled
FTRK:
Buildable:
Prerequisites: ~disabled
APC:
Buildable:
Prerequisites: ~disabled
DOME:
ExternalCondition@lua:
Condition: french
WithColoredOverlay@IDISABLE:
RequiresCondition: !french && disabled
powerproxy.paratroopers:
ParatroopersPower:
DropItems: E1,E1,E1,E1,E1
AGUN:
Buildable:
Prerequisites: ~disabled

View File

@@ -0,0 +1,68 @@
--[[
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.
]]
IdlingUnits = function()
local lazyUnits = Utils.Where(Map.ActorsInWorld, function(actor)
return actor.HasProperty("Hunt") and actor.Owner == Greece end)
Utils.Do(lazyUnits, function(unit)
Trigger.OnDamaged(unit, function()
Trigger.ClearAll(unit)
Trigger.AfterDelay(0, function() IdleHunt(unit) end)
end)
end)
end
ProduceInfantry = function()
if Barr.IsDead then
return
end
local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9))
local toBuild = { Utils.Random(AlliedInfantryTypes) }
Greece.Build(toBuild, function(unit)
GreeceInfAttack[#GreeceInfAttack + 1] = unit[1]
if #GreeceInfAttack >= 7 then
SendUnits(GreeceInfAttack, InfantryWaypoints)
GreeceInfAttack = { }
Trigger.AfterDelay(DateTime.Minutes(2), ProduceInfantry)
else
Trigger.AfterDelay(delay, ProduceInfantry)
end
end)
end
ProduceShips = function()
if Navalyard.IsDead then
return
end
Greece.Build( {"dd"}, function(unit)
Ships[#Ships + 1] = unit[1]
if #Ships >= 2 then
SendUnits(Ships, ShipWaypoints)
Ships = { }
Trigger.AfterDelay(DateTime.Minutes(6), ProduceShips)
else
Trigger.AfterDelay(Actor.BuildTime("dd"), ProduceShips)
end
end)
end
SendUnits = function(units, waypoints)
Utils.Do(units, function(unit)
if not unit.IsDead then
Utils.Do(waypoints, function(waypoint)
unit.AttackMove(waypoint.Location)
end)
unit.Hunt()
end
end)
end

View File

@@ -0,0 +1,177 @@
--[[
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.
]]
SovietStartReinf = { "e2", "e2" }
SovietStartToBasePath = { StartPoint.Location, SovietBasePoint.Location }
SovietMCVReinf = { "mcv", "3tnk", "3tnk", "e1", "e1" }
SovExpansionPointGuard = { "2tnk", "2tnk", "e3", "e3", "e3" }
if Difficulty == "easy" then
ArmorReinfGreece = { "jeep", "1tnk", "1tnk" }
else
ArmorReinfGreece = { "jeep", "jeep", "1tnk", "1tnk", "1tnk" }
end
InfantryReinfGreece = { "e1", "e1", "e1", "e1", "e1" }
CrossroadsReinfPath = { ReinfRoadPoint.Location }
ArtyReinf = { "e3", "e3", "e3", "arty", "arty" }
CoastGuardReinf = { "e1", "e1", "e3", "e1", "e3" }
DDPatrol1 = { "dd", "dd", "dd" }
DDPatrol1Path = { EIslandPoint.Location, WIslandPoint.Location, DDAttackPoint.Location, SReinfPathPoint4.Location, DDAttackPoint.Location, WIslandPoint.Location, EIslandPoint.Location, NearDockPoint.Location }
DDPatrol2 = { "dd", "dd" }
DDPatrol2Path = { NReinfPathPoint1.Location, SReinfPathPoint1.Location, SReinfPathPoint2.Location, SReinfPathPoint1.Location, NReinfPathPoint1.Location, NearDockPoint.Location }
ShipArrivePath = { ReinfNorthPoint.Location, NearDockPoint.Location }
AlliedInfantryTypes = { "e1", "e3" }
AlliedTankTypes = { "jeep", "1tnk" }
AlliedAttackPath = { GreeceBaseEPoint.Location, CrossroadPoint.Location, NWOrefieldPoint.Location, AtUSSRBasePoint.Location }
AlliedCrossroadsToRadarPath = { ReinfRoadPoint.Location, CrossroadPoint.Location, GreeceBaseEPoint.Location, GreeceBasePoint.Location }
SouthReinfPath = { ReinfEastPoint.Location, SReinfPathPoint1.Location, SReinfPathPoint2.Location, SReinfPathPoint3.Location, SReinfPathPoint4.Location, USSRlstPoint.Location }
NorthReinfPath = { ReinfEastPoint.Location, NReinfPathPoint1.Location, GGUnloadPoint.Location }
GoodGuyOrefieldPatrolPath = { PatrolPoint1.Location, PatrolPoint2.Location, PatrolPoint3.Location, PatrolPoint4.Location }
Ships = { }
GreeceInfAttack = { }
GGInfAttack = { }
TankAttackGG = { }
ShipWaypoints = { EIslandPoint, WIslandPoint, DDAttackPoint }
InfantryWaypoints = { CrossroadPoint, NWOrefieldPoint, AtUSSRBasePoint, SovietBasePoint }
InfantryGGWaypoints = { PatrolPoint2, BetweenBasesPoint, PrepGGArmyPoint }
TanksGGWaypoints = { PatrolPoint2, BetweenBasesPoint, PrepGGArmyPoint }
Para = function()
local powerproxy = Actor.Create("powerproxy.paratroopers", false, { Owner = USSR })
powerproxy.TargetParatroopers(ParaPoint.CenterPosition, Angle.New(112))
powerproxy.Destroy()
end
Para2 = function()
local powerproxy = Actor.Create("powerproxy.paratroopers", false, { Owner = USSR })
powerproxy.TargetParatroopers(USSRExpansionPoint.CenterPosition, Angle.New(112))
powerproxy.Destroy()
end
ReinfInf = function()
Reinforcements.Reinforce(Greece, InfantryReinfGreece, CrossroadsReinfPath, 0, function(soldier)
soldier.Hunt()
end)
end
ReinfArmor = function()
RCheck = false
Reinforcements.Reinforce(Greece, ArmorReinfGreece, CrossroadsReinfPath, 0, function(soldier)
soldier.Hunt()
end)
end
IslandTroops1 = function()
local units = Reinforcements.ReinforceWithTransport(GoodGuy, "lst", CoastGuardReinf, { ReinfEastPoint.Location, NReinfPathPoint1.Location, GGUnloadPoint.Location }, { ReinfEastPoint.Location })[2]
Utils.Do(units, function(unit)
Trigger.OnIdle(unit, function(coastguard)
coastguard.AttackMove(CoastGuardPoint.Location)
end)
end)
if not CheckForCYard() then
return
elseif Difficulty == "easy" then
return
else
Trigger.OnAllKilled(units, function()
if Difficulty == "hard" then
Trigger.AfterDelay(DateTime.Minutes(3), IslandTroops1)
else
Trigger.AfterDelay(DateTime.Minutes(5), IslandTroops1)
end
end)
end
end
IslandTroops2 = function()
local units = Reinforcements.ReinforceWithTransport(Greece, "lst", ArmorReinfGreece, NorthReinfPath, { ReinfEastPoint.Location })[2]
Utils.Do(units, function(unit)
Trigger.OnIdle(unit, function(patrols)
patrols.Patrol(GoodGuyOrefieldPatrolPath, true, 150)
end)
end)
if not CheckForCYard() then
return
elseif Difficulty == "easy" then
return
else
Trigger.OnAllKilled(units, function()
if Difficulty == "hard" then
Trigger.AfterDelay(DateTime.Minutes(3), IslandTroops2)
else
Trigger.AfterDelay(DateTime.Minutes(5), IslandTroops2)
end
end)
end
end
IslandTroops3 = function()
local units = Reinforcements.ReinforceWithTransport(Greece, "lst", SovExpansionPointGuard, SouthReinfPath, { ReinfEastPoint.Location })[2]
Utils.Do(units, function(unit)
Trigger.OnIdle(unit, function(guards)
guards.AttackMove(USSRExpansionPoint.Location)
end)
end)
if not CheckForCYard() then
return
elseif Difficulty == "easy" then
return
else
Trigger.OnAllKilled(units, function()
if Difficulty == "hard" then
Trigger.AfterDelay(DateTime.Minutes(3), IslandTroops3)
else
Trigger.AfterDelay(DateTime.Minutes(5), IslandTroops3)
end
end)
end
end
BringDDPatrol1 = function()
local units = Reinforcements.Reinforce(Greece, DDPatrol1, ShipArrivePath, 0)
Utils.Do(units, function(unit)
Trigger.OnIdle(unit, function(patrols)
patrols.Patrol(DDPatrol1Path, true, 250)
end)
end)
if not CheckForCYard() then
return
else
Trigger.OnAllKilled(units, function()
if Difficulty == "hard" then
Trigger.AfterDelay(DateTime.Minutes(4), BringDDPatrol1)
else
Trigger.AfterDelay(DateTime.Minutes(7), BringDDPatrol1)
end
end)
end
end
BringDDPatrol2 = function()
local units = Reinforcements.Reinforce(Greece, DDPatrol2, ShipArrivePath, 0)
Utils.Do(units, function(unit)
Trigger.OnIdle(unit, function(patrols)
patrols.Patrol(DDPatrol2Path, true, 250)
end)
end)
if not CheckForCYard() then
return
else
Trigger.OnAllKilled(units, function()
if Difficulty == "hard" then
Trigger.AfterDelay(DateTime.Minutes(4), BringDDPatrol2)
else
Trigger.AfterDelay(DateTime.Minutes(7), BringDDPatrol2)
end
end)
end
end

View File

@@ -0,0 +1,266 @@
--[[
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.
]]
CheckForBase = function()
local baseBuildings = Map.ActorsInBox(BaseRectTL.CenterPosition, BaseRectBR.CenterPosition, function(actor)
return (actor.Type == "fact" or actor.Type == "powr") and actor.Owner == player
end)
return #baseBuildings >= 2
end
CheckForCYard = function()
ConYard = Map.ActorsInBox(mcvGGLoadPoint.CenterPosition, ReinfEastPoint.CenterPosition, function(actor)
return actor.Type == "fact" and actor.Owner == GoodGuy
end)
return #ConYard >= 1
end
CheckForSPen = function()
return Utils.Any(Map.ActorsInWorld, function(actor) return actor.Type == "spen" end)
end
RunInitialActivities = function()
if Difficulty == "hard" then
Expand()
ExpansionCheck = true
else
ExpansionCheck = false
end
Trigger.AfterDelay(1, function()
Harvester.FindResources()
IdlingUnits()
Media.PlaySpeechNotification(USSR, "ReinforcementsArrived")
local buildings = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == Greece and self.HasProperty("StartBuildingRepairs") end)
Utils.Do(buildings, function(actor)
Trigger.OnDamaged(actor, function(building)
if building.Owner == Greece and building.Health < building.MaxHealth * 3/4 then
building.StartBuildingRepairs()
end
end)
end)
end)
Reinforcements.Reinforce(USSR, SovietStartReinf, SovietStartToBasePath, 0, function(soldier)
soldier.AttackMove(SovietBasePoint.Location)
end)
Actor.Create("camera", true, { Owner = USSR, Location = GreeceBasePoint.Location })
Actor.Create("camera", true, { Owner = USSR, Location = SovietBasePoint.Location })
startmcv.Move(MCVStartMovePoint.Location)
Runner1.Move(RunnerPoint.Location)
Runner2.Move(RunnerPoint.Location)
Runner3.Move(RunnerPoint.Location)
ProduceInfantry()
Trigger.AfterDelay(DateTime.Minutes(2), ProduceShips)
if Difficulty == "hard" or Difficulty == "normal" then
Trigger.AfterDelay(DateTime.Seconds(25), ReinfInf)
end
Trigger.AfterDelay(DateTime.Minutes(2), ReinfInf)
Trigger.AfterDelay(DateTime.Minutes(3), BringDDPatrol2)
Trigger.AfterDelay(DateTime.Minutes(5), ReinfInf)
Trigger.AfterDelay(DateTime.Minutes(6), BringDDPatrol1)
end
Expand = function()
if ExpansionCheck or mcvtransport.IsDead or mcvGG.IsDead then
return
end
ExpansionCheck = true
Trigger.ClearAll(mcvGG)
Trigger.ClearAll(mcvtransport)
Media.DisplayMessage(UserInterface.GetFluentMessage("allied-mcv-island"))
Reinforcements.Reinforce(GoodGuy, { "dd", "dd" }, ShipArrivePath, 0, function(ddsquad)
ddsquad.AttackMove(NearExpPoint.Location) end)
mcvtransport.Move(lstBeachPoint.Location)
mcvGG.Move(mcvGGLoadPoint.Location)
mcvGG.EnterTransport(mcvtransport)
Trigger.AfterDelay(DateTime.Seconds(5), function()
if mcvtransport.IsDead or mcvGG.IsDead then
return
end
mcvtransport.Move(GGUnloadPoint.Location)
mcvtransport.UnloadPassengers()
mcvtransport.CallFunc(function()
if mcvGG.IsDead then
return
end
mcvGG.Move(MCVDeploy.Location)
mcvGG.CallFunc(function()
-- Avoid crashing through modifying the actor list from mcvGG's tick
Trigger.AfterDelay(0, function()
mcvGG.Owner = GoodGuy
IslandTroops1()
Trigger.AfterDelay(DateTime.Minutes(3), IslandTroops2)
Trigger.AfterDelay(DateTime.Minutes(6), IslandTroops3)
if not mcvtransport.IsDead then
mcvtransport.Move(ReinfNorthPoint.Location)
mcvtransport.Destroy()
end
end)
Trigger.AfterDelay(DateTime.Seconds(1), function()
GoodGuy.GrantCondition("ai-active")
end)
end)
end)
end)
end
Tick = function()
if Greece.HasNoRequiredUnits() and GoodGuy.HasNoRequiredUnits() then
USSR.MarkCompletedObjective(KillAll)
if HoldObjective then
USSR.MarkCompletedObjective(HoldObjective)
end
end
if USSR.HasNoRequiredUnits() then
GoodGuy.MarkCompletedObjective(BeatUSSR)
end
if Greece.Resources >= Greece.ResourceCapacity * 0.75 then
Greece.Cash = Greece.Cash + Greece.Resources - Greece.ResourceCapacity * 0.25
Greece.Resources = Greece.ResourceCapacity * 0.25
end
if GoodGuy.Resources >= GoodGuy.ResourceCapacity * 0.75 then
GoodGuy.Cash = GoodGuy.Cash + GoodGuy.Resources - GoodGuy.ResourceCapacity * 0.25
GoodGuy.Resources = GoodGuy.ResourceCapacity * 0.25
end
if not BaseEstablished and CheckForBase() then
BaseEstablished = true
Para()
end
if not SPenEstablished and CheckForSPen() then
SPenEstablished = true
local units = Reinforcements.ReinforceWithTransport(Greece, "lst", ArtyReinf, SouthReinfPath, { ReinfEastPoint.Location })[2]
Utils.Do(units, function(unit) IdleHunt(unit) end)
if not ExpansionCheck then
Expand()
ExpansionCheck = true
end
end
if not RCheck then
RCheck = true
if Difficulty == "easy" then
Trigger.AfterDelay(DateTime.Minutes(6), ReinfArmor)
elseif Difficulty == "normal" then
Trigger.AfterDelay(DateTime.Minutes(4), ReinfArmor)
else
Trigger.AfterDelay(DateTime.Minutes(3), ReinfArmor)
end
end
end
WorldLoaded = function()
USSR = Player.GetPlayer("USSR")
GoodGuy = Player.GetPlayer("GoodGuy")
Greece = Player.GetPlayer("Greece")
InitObjectives(USSR)
CaptureObjective = AddPrimaryObjective(USSR, "capture-radar-dome")
KillAll = AddPrimaryObjective(USSR, "defeat-allied-forces")
BeatUSSR = AddPrimaryObjective(Greece, "")
RunInitialActivities()
Trigger.OnDamaged(mcvGG, Expand)
Trigger.OnDamaged(mcvtransport, Expand)
Trigger.OnKilled(RadarDome, function()
if not USSR.IsObjectiveCompleted(CaptureObjective) then
USSR.MarkFailedObjective(CaptureObjective)
end
if HoldObjective then
USSR.MarkFailedObjective(HoldObjective)
end
end)
RadarDome.GrantCondition("french")
Trigger.OnCapture(RadarDome, function()
if USSR.IsObjectiveCompleted(KillAll) then
USSR.MarkCompletedObjective(CaptureObjective)
return
end
HoldObjective = AddPrimaryObjective(USSR, "defend-radar-dome")
USSR.MarkCompletedObjective(CaptureObjective)
Beacon.New(USSR, MCVDeploy.CenterPosition)
if Difficulty == "easy" then
Actor.Create("camera", true, { Owner = USSR, Location = MCVDeploy.Location })
Media.DisplayMessage(UserInterface.GetFluentMessage("allied-expansion-movement-detected"))
else
Actor.Create("MCV.CAM", true, { Owner = USSR, Location = MCVDeploy.Location })
Media.DisplayMessage(UserInterface.GetFluentMessage("coordinates-allied-expansion-discovered"))
end
if not ExpansionCheck then
Expand()
ExpansionCheck = true
end
Reinforcements.Reinforce(Greece, ArmorReinfGreece, AlliedCrossroadsToRadarPath , 0, IdleHunt)
RadarDome.RevokeCondition(1)
Trigger.ClearAll(RadarDome)
Trigger.AfterDelay(0, function()
Trigger.OnRemovedFromWorld(RadarDome, function()
USSR.MarkFailedObjective(HoldObjective)
end)
end)
end)
Trigger.OnEnteredProximityTrigger(USSRExpansionPoint.CenterPosition, WDist.New(4 * 1024), function(unit, id)
if unit.Owner == USSR and RadarDome.Owner == USSR then
Trigger.RemoveProximityTrigger(id)
Para2()
local units = Reinforcements.ReinforceWithTransport(USSR, "lst", SovietMCVReinf, { ReinfSouthPoint.Location, USSRlstPoint.Location }, { ReinfSouthPoint.Location })[2]
Utils.Do(units, function(unit)
Trigger.OnAddedToWorld(unit, function()
if unit.Type == "mcv" then
unit.Move(USSRExpansionPoint.Location)
else
unit.AttackMove(USSRExpansionPoint.Location)
end
end)
end)
Media.PlaySpeechNotification(USSR, "ReinforcementsArrived")
end
end)
Camera.Position = StartCamPoint.CenterPosition
end