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,5 @@
## rules.yaml
briefing =
Tomorrow, the attack on Germany begins, but today, we must protect our facility from Allied attacks.
Keep the Command Center intact at all costs, and destroy any Allied fortifications you might find.

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1,495 @@
MapFormat: 12
RequiresMod: ra
Title: 02b: The Thin Red Line
Author: Westwood Studios
Tileset: TEMPERAT
MapSize: 128,128
Bounds: 36,52,54,35
Visibility: MissionSelector
Categories: Campaign
LockPreview: True
Players:
PlayerReference@Neutral:
Name: Neutral
OwnsWorld: True
NonCombatant: True
Faction: allies
PlayerReference@Creeps:
Name: Creeps
NonCombatant: True
Enemies: USSR
PlayerReference@Greece:
Name: Greece
Faction: allies
Color: E2E6F5
Enemies: USSR
Bot: campaign
PlayerReference@USSR:
Name: USSR
AllowBots: False
Playable: True
Required: True
LockFaction: True
Faction: soviet
LockColor: True
Color: FE1100
LockSpawn: True
LockTeam: True
Enemies: Greece, Creeps
Actors:
Actor0: sbag
Location: 53,52
Owner: Greece
Actor1: sbag
Location: 54,52
Owner: Greece
Actor2: sbag
Location: 53,53
Owner: Neutral
Actor3: sbag
Location: 54,53
Owner: Greece
Actor4: sbag
Location: 53,56
Owner: Greece
Actor5: sbag
Location: 54,56
Owner: Greece
Actor6: sbag
Location: 53,57
Owner: Greece
Actor7: sbag
Location: 54,57
Owner: Greece
Actor8: sbag
Location: 81,68
Owner: Greece
Actor9: sbag
Location: 83,68
Owner: Greece
Actor10: sbag
Location: 87,68
Owner: Greece
Actor11: sbag
Location: 89,68
Owner: Greece
Actor12: sbag
Location: 81,69
Owner: Greece
Actor13: sbag
Location: 82,69
Owner: Greece
Actor14: sbag
Location: 83,69
Owner: Greece
Actor15: sbag
Location: 87,69
Owner: Greece
Actor16: sbag
Location: 88,69
Owner: Greece
Actor17: sbag
Location: 89,69
Owner: Greece
Actor18: v14
Location: 87,84
Owner: Neutral
Actor19: v15
Location: 88,84
Owner: Neutral
Actor20: v16
Location: 86,85
Owner: Neutral
Actor21: v17
Location: 87,85
Owner: Neutral
Actor22: v18
Location: 88,85
Owner: Neutral
Actor23: tc05
Location: 75,63
Owner: Neutral
Actor24: tc02
Location: 82,58
Owner: Neutral
Actor25: tc01
Location: 85,57
Owner: Neutral
Actor26: t07
Location: 83,60
Owner: Neutral
Actor27: tc04
Location: 36,55
Owner: Neutral
Actor28: tc05
Location: 41,52
Owner: Neutral
Actor29: t01
Location: 73,62
Owner: Neutral
Actor30: tc01
Location: 64,63
Owner: Neutral
Actor31: t06
Location: 69,62
Owner: Neutral
Actor32: t07
Location: 67,63
Owner: Neutral
Actor33: tc02
Location: 73,57
Owner: Neutral
Actor34: t07
Location: 74,55
Owner: Neutral
Actor35: tc05
Location: 61,60
Owner: Neutral
Actor36: tc01
Location: 69,72
Owner: Neutral
Actor37: tc05
Location: 36,81
Owner: Neutral
Actor38: tc02
Location: 43,85
Owner: Neutral
Actor39: tc01
Location: 47,85
Owner: Neutral
Actor40: tc01
Location: 39,84
Owner: Neutral
Actor41: tc04
Location: 51,65
Owner: Neutral
Actor42: tc05
Location: 47,66
Owner: Neutral
Actor43: tc02
Location: 88,65
Owner: Neutral
Actor44: tc04
Location: 79,84
Owner: Neutral
Actor45: tc04
Location: 66,72
Owner: Neutral
Actor46: weap
Location: 84,59
Owner: Greece
Actor47: dome
Location: 72,55
Owner: Greece
Actor50: fact
Location: 75,55
Owner: Greece
Actor51: proc
Location: 80,59
Owner: Greece
Actor52: powr
Location: 83,55
Owner: Greece
Actor53: powr
Location: 85,55
Owner: Greece
Actor54: brl3
Location: 69,64
Owner: Creeps
Actor55: brl3
Location: 68,65
Owner: Creeps
Actor57: barl
Location: 73,64
Owner: Creeps
Actor58: barl
Location: 72,63
Owner: Creeps
Actor59: barl
Location: 70,63
Owner: Creeps
Actor61: brl3
Location: 70,56
Owner: Creeps
Actor62: brl3
Location: 71,56
Owner: Creeps
Actor63: brl3
Location: 70,55
Owner: Creeps
Actor64: barl
Location: 69,54
Owner: Creeps
Actor65: brl3
Location: 68,54
Owner: Creeps
Actor66: barl
Location: 67,53
Owner: Creeps
Actor68: v03
Location: 81,85
Owner: Creeps
Actor69: v06
Location: 87,83
Owner: Creeps
Actor70: fact
Location: 41,76
Owner: USSR
Actor71: powr
Location: 46,80
Owner: USSR
Actor72: powr
Location: 49,80
Owner: USSR
Actor73: powr
Location: 43,80
Owner: USSR
Actor75: afld
Location: 45,77
Owner: USSR
Actor76: afld
Location: 49,77
Owner: USSR
Actor78: brl3
Location: 82,70
Owner: Greece
Actor79: brl3
Location: 83,70
Owner: Greece
Actor80: brl3
Location: 88,70
Owner: Greece
Actor81: barl
Location: 87,70
Owner: Greece
Actor82: barl
Location: 84,69
Owner: Greece
Tent: tent
Location: 70,57
Owner: Greece
Actor84: barl
Location: 74,55
Owner: Creeps
Actor85: powr
Location: 52,80
Owner: USSR
Actor86: jeep
Location: 85,66
Owner: Greece
Facing: 512
Actor89: jeep
Location: 55,56
Owner: Greece
Facing: 896
Actor90: jeep
Location: 79,54
Owner: Greece
Facing: 512
Actor92: e1
Location: 47,75
Owner: USSR
Facing: 256
SubCell: 4
Actor93: e1
Location: 48,75
Owner: USSR
Facing: 256
SubCell: 3
Actor94: e1
Location: 47,76
Owner: USSR
Facing: 256
SubCell: 2
Actor95: e1
Location: 48,76
Owner: USSR
Facing: 256
SubCell: 1
Actor96: dog
Location: 49,73
Owner: USSR
Facing: 256
SubCell: 3
Actor97: dog
Location: 49,76
Owner: USSR
Facing: 256
SubCell: 1
Actor98: dog
Location: 49,75
Owner: USSR
Facing: 256
SubCell: 3
Actor99: dog
Location: 49,74
Owner: USSR
Facing: 256
SubCell: 1
Actor100: e3
Location: 88,68
Owner: Greece
Facing: 640
SubCell: 3
Actor103: e1
Location: 79,64
Owner: Greece
Facing: 384
SubCell: 3
Actor104: e1
Location: 79,64
Owner: Greece
Facing: 384
SubCell: 4
Actor105: e3
Location: 78,57
Owner: Greece
Facing: 640
SubCell: 4
Actor106: e2
Location: 47,73
Owner: USSR
Facing: 256
SubCell: 4
Actor107: e2
Location: 47,74
Owner: USSR
Facing: 256
SubCell: 2
Actor108: e2
Location: 48,74
Owner: USSR
Facing: 256
SubCell: 1
Actor109: e2
Location: 48,73
Owner: USSR
Facing: 256
SubCell: 3
Actor110: e1
Location: 72,61
Owner: Greece
Facing: 640
SubCell: 0
Actor111: e1
Location: 40,54
Owner: Greece
Facing: 384
SubCell: 0
Actor112: e1
Location: 83,85
Owner: Greece
Facing: 896
SubCell: 3
Actor113: e1
Location: 82,68
Owner: Greece
Facing: 384
SubCell: 4
Actor114: e1
Location: 69,55
Owner: Greece
Facing: 640
SubCell: 0
BarrelBase: brl3
Location: 71,55
Owner: Creeps
BarrelBridge: brl3
Location: 72,65
Owner: Creeps
BridgeCheck1: waypoint
Owner: Neutral
Location: 60,60
BridgeCheck2: waypoint
Owner: Neutral
Location: 80,75
CameraStart: Camera
Location: 60,77
Owner: Neutral
CameraBridge: Camera
Location: 69,67
Owner: Neutral
CameraBase1: Camera
Location: 70,56
Owner: Neutral
CameraBase2: Camera
Location: 82,58
Owner: Neutral
CameraBaseEntrance: Camera
Location: 85,67
Owner: Neutral
Church1: v01
Location: 67,73
Owner: Creeps
Church2: v01
Location: 86,81
Owner: Creeps
ForwardCommand: fcom
Location: 45,73
Owner: USSR
BridgeGun1: gun
Location: 68,64
Owner: Greece
Facing: 640
BridgeGun2: gun
Location: 74,64
Owner: Greece
Facing: 640
IntroSoldier1: e1
Location: 71,65
Owner: Greece
Facing: 640
SubCell: 3
IntroSoldier2: e1
Location: 71,60
Owner: Greece
Facing: 512
SubCell: 3
IntroSoldier3: e1
Location: 70,60
Owner: Greece
Facing: 512
SubCell: 4
ParachuteBase1: waypoint
Location: 66,54
Owner: Neutral
ParachuteBase2: waypoint
Location: 66,56
Owner: Neutral
ParachuteBaseEntrance: waypoint
Location: 85,68
Owner: Neutral
TransportTruck: truk
Location: 75,58
Owner: Greece
Facing: 768
TransportWaypoint1: waypoint
Location: 75,58
Owner: Neutral
TransportWaypoint2: waypoint
Location: 86,83
Owner: Neutral
TransportWaypoint3: waypoint
Location: 67,75
Owner: Neutral
AttackWaypoint1: waypoint
Location: 52,55
Owner: Neutral
AttackWaypoint2: waypoint
Location: 80,83
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,107 @@
Player:
PlayerResources:
DefaultCash: 5000
World:
LuaScript:
Scripts: campaign.lua, utils.lua, soviet02b.lua
MissionData:
Briefing: briefing
BriefingVideo: soviet2.vqa
StartVideo: spotter.vqa
WinVideo: sovtstar.vqa
LossVideo: sovcemet.vqa
SPEN:
Buildable:
Prerequisites: ~disabled
DOME:
Buildable:
Prerequisites: ~disabled
WEAP:
Buildable:
Prerequisites: ~disabled
FIX:
Buildable:
Prerequisites: ~disabled
APWR:
Buildable:
Prerequisites: ~disabled
STEK:
Buildable:
Prerequisites: ~disabled
BRIK:
Buildable:
Prerequisites: ~disabled
TSLA:
Buildable:
Prerequisites: ~disabled
SAM:
Buildable:
Prerequisites: ~disabled
IRON:
Buildable:
Prerequisites: ~disabled
MSLO:
Buildable:
Prerequisites: ~disabled
E3:
Buildable:
Prerequisites: ~tent
E4:
Buildable:
Prerequisites: ~disabled
E6:
Buildable:
Prerequisites: ~disabled
SHOK:
Buildable:
Prerequisites: ~disabled
THF:
Buildable:
Prerequisites: ~disabled
MIG:
Buildable:
Prerequisites: ~disabled
AFLD:
Buildable:
Prerequisites: ~disabled
AirstrikePower@spyplane:
Prerequisites: ~disabled
ParatroopersPower@paratroopers:
Prerequisites: ~disabled
GUN:
-RepairableBuilding:
-WithBuildingRepairDecoration:
powerproxy.paratroopers:
ParatroopersPower:
DropItems: E1,E1,E2,E2,E2
powerproxy.paratroopers2:
Inherits: powerproxy.paratroopers
ParatroopersPower:
DropItems: E2,E2,E2,E2,E2
powerproxy.paratroopers3:
Inherits: powerproxy.paratroopers
ParatroopersPower:
DropItems: E1,E1,E1,E1,E1

View File

@@ -0,0 +1,205 @@
--[[
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.
]]
IntroAttackers = { IntroSoldier1, IntroSoldier2, IntroSoldier3 }
BridgeShroudTrigger = { CPos.New(63, 71), CPos.New(64, 71), CPos.New(65, 71), CPos.New(69, 65), CPos.New(70, 65), CPos.New(71, 65) }
BridgeExplosionTrigger = { CPos.New(66, 69), CPos.New(67, 69), CPos.New(68, 69) }
TransportTrigger = { CPos.New(75, 58) }
EnemyBaseShroudTrigger = { CPos.New(64, 52), CPos.New(64, 53), CPos.New(64, 54), CPos.New(64, 55), CPos.New(64, 56), CPos.New(64, 57), CPos.New(64, 58), CPos.New(64, 59), CPos.New(64, 60), CPos.New(64, 61), CPos.New(64, 62), CPos.New(64, 63), CPos.New(64, 64) }
ParachuteTrigger = { CPos.New(80, 66), CPos.New(81, 66), CPos.New(82, 66), CPos.New(83, 66), CPos.New(84, 66), CPos.New(85, 66),CPos.New(86, 66), CPos.New(87, 66), CPos.New(88, 66), CPos.New(89, 66) }
EnemyBaseEntranceShroudTrigger = { CPos.New(80, 73), CPos.New(81, 73), CPos.New(82, 73), CPos.New(83, 73), CPos.New(84, 73), CPos.New(85, 73),CPos.New(86, 73), CPos.New(87, 73), CPos.New(88, 73), CPos.New(89, 73) }
AttackWaypoints = { AttackWaypoint1, AttackWaypoint2 }
AttackGroup = { }
AttackGroupSize = 3
AlliedInfantry = { "e1", "e1", "e3" }
SendAttackGroup = function()
if #AttackGroup < AttackGroupSize then
return
end
local way = Utils.Random(AttackWaypoints)
Utils.Do(AttackGroup, function(unit)
if not unit.IsDead then
unit.AttackMove(way.Location)
Trigger.OnIdle(unit, unit.Hunt)
end
end)
AttackGroup = { }
end
ProduceInfantry = function()
if Tent.IsDead then
return
end
Greece.Build({ Utils.Random(AlliedInfantry) }, function(units)
table.insert(AttackGroup, units[1])
SendAttackGroup()
Trigger.AfterDelay(DateTime.Seconds(10), ProduceInfantry)
end)
end
SendUSSRParadrops = function()
local paraproxy1 = Actor.Create("powerproxy.paratroopers", false, { Owner = USSR })
paraproxy1.TargetParatroopers(ParachuteBaseEntrance.CenterPosition, Angle.North)
paraproxy1.Destroy()
end
SendUSSRParadropsBase = function()
local paraproxy2 = Actor.Create("powerproxy.paratroopers2", false, { Owner = USSR })
paraproxy2.TargetParatroopers(ParachuteBase1.CenterPosition, Angle.East)
paraproxy2.Destroy()
local paraproxy3 = Actor.Create("powerproxy.paratroopers3", false, { Owner = USSR })
paraproxy3.TargetParatroopers(ParachuteBase2.CenterPosition, Angle.East)
paraproxy3.Destroy()
end
Trigger.OnEnteredFootprint(BridgeShroudTrigger, function(a)
if not BridgeShroudTriggered and a.Owner == USSR then
BridgeShroudTriggered = true
local cameraBridge = Actor.Create("camera", true, { Owner = USSR, Location = CameraBridge.Location })
Trigger.AfterDelay(DateTime.Seconds(15), function()
cameraBridge.Destroy()
end)
end
end)
Trigger.OnEnteredFootprint(BridgeExplosionTrigger, function(a)
if not BridgeExplosionTriggered and a.Owner == USSR then
BridgeExplosionTriggered = true
if not BarrelBridge.IsDead then
BarrelBridge.Kill()
end
end
end)
Trigger.OnEnteredFootprint(EnemyBaseEntranceShroudTrigger, function(a)
if not EnemyBaseEntranceShroudTriggered and a.Owner == USSR then
EnemyBaseEntranceShroudTriggered = true
local cameraBaseEntrance = Actor.Create("camera", true, { Owner = USSR, Location = CameraBaseEntrance.Location })
Trigger.AfterDelay(DateTime.Seconds(15), function()
cameraBaseEntrance.Destroy()
end)
end
end)
Trigger.OnEnteredFootprint(EnemyBaseShroudTrigger, function(a)
if not EnemyBaseShroudTriggered and a.Owner == USSR then
EnemyBaseShroudTriggered = true
local cameraBase1 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase1.Location })
local cameraBase2 = Actor.Create("camera", true, { Owner = USSR, Location = CameraBase2.Location })
Trigger.AfterDelay(DateTime.Seconds(15), function()
cameraBase1.Destroy()
cameraBase2.Destroy()
end)
end
end)
Trigger.OnEnteredFootprint(ParachuteTrigger, function(a)
if not ParachuteTriggered and a.Owner == USSR then
ParachuteTriggered = true
SendUSSRParadrops()
Media.PlaySpeechNotification(USSR, "ReinforcementsArrived")
end
end)
Trigger.OnEnteredFootprint(TransportTrigger, function(a, id)
if not TransportTriggered and a.Type == "truk" then
TransportTriggered = true
if not TransportTruck.IsDead then
TransportTruck.Wait(DateTime.Seconds(5))
TransportTruck.Move(TransportWaypoint2.Location)
TransportTruck.Wait(DateTime.Seconds(5))
TransportTruck.Move(TransportWaypoint3.Location)
TransportTruck.Wait(DateTime.Seconds(5))
TransportTruck.Move(TransportWaypoint1.Location)
end
Trigger.AfterDelay(DateTime.Seconds(10), function()
TransportTriggered = false
end)
end
end)
Trigger.OnKilled(BarrelBase, function()
SendUSSRParadropsBase()
Media.PlaySpeechNotification(USSR, "ReinforcementsArrived")
end)
Trigger.OnKilled(BarrelBridge, function()
local bridgepart = Map.ActorsInBox(BridgeCheck1.CenterPosition, BridgeCheck2.CenterPosition, function(self) return self.Type == "br1" end)[1]
if not bridgepart.IsDead then
bridgepart.Kill()
end
end)
Trigger.OnKilled(Church1, function()
Actor.Create("moneycrate", true, { Owner = USSR, Location = TransportWaypoint3.Location })
end)
Trigger.OnKilled(Church2, function()
Actor.Create("healcrate", true, { Owner = USSR, Location = Church2.Location })
end)
Trigger.OnKilled(ForwardCommand, function()
Greece.MarkCompletedObjective(AlliedObjective)
end)
Trigger.OnKilled(IntroSoldier1, function()
local cameraIntro = Actor.Create("camera", true, { Owner = USSR, Location = CameraStart.Location })
Trigger.AfterDelay(DateTime.Seconds(15), function()
cameraIntro.Destroy()
end)
end)
WorldLoaded = function()
USSR = Player.GetPlayer("USSR")
Greece = Player.GetPlayer("Greece")
Utils.Do(IntroAttackers, function(actor)
if not actor.IsDead then
Trigger.OnIdle(actor, actor.Hunt)
end
end)
Trigger.AfterDelay(0, function()
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 * 0.8 then
building.StartBuildingRepairs()
end
end)
end)
end)
InitObjectives(USSR)
AlliedObjective = AddPrimaryObjective(Greece, "")
SovietObjective1 = AddPrimaryObjective(USSR, "protect-command-center")
SovietObjective2 = AddPrimaryObjective(USSR, "destroy-allied-units-structures")
Greece.Resources = 2000
Trigger.AfterDelay(DateTime.Seconds(30), ProduceInfantry)
end
Tick = function()
if USSR.HasNoRequiredUnits() then
Greece.MarkCompletedObjective(AlliedObjective)
end
if Greece.HasNoRequiredUnits() then
USSR.MarkCompletedObjective(SovietObjective1)
USSR.MarkCompletedObjective(SovietObjective2)
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
end