Initial commit: OpenRA game engine
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:
BIN
mods/ra/maps/soviet-06b/map.bin
Normal file
BIN
mods/ra/maps/soviet-06b/map.bin
Normal file
Binary file not shown.
7
mods/ra/maps/soviet-06b/map.ftl
Normal file
7
mods/ra/maps/soviet-06b/map.ftl
Normal file
@@ -0,0 +1,7 @@
|
||||
## rules.yaml
|
||||
briefing =
|
||||
There is a special cargo that needs to be transported to a nearby Soviet base in the northeast.
|
||||
|
||||
Make sure the trucks reach their destination intact. Along the way, there is a bridge which the Allies have likely destroyed.
|
||||
|
||||
Use the Naval options at your disposal. Our attack subs will make short work of any Allied boats you discover.
|
||||
BIN
mods/ra/maps/soviet-06b/map.png
Normal file
BIN
mods/ra/maps/soviet-06b/map.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
512
mods/ra/maps/soviet-06b/map.yaml
Normal file
512
mods/ra/maps/soviet-06b/map.yaml
Normal file
@@ -0,0 +1,512 @@
|
||||
MapFormat: 12
|
||||
|
||||
RequiresMod: ra
|
||||
|
||||
Title: 06b: Bridge over the River VizchGoi
|
||||
|
||||
Author: Westwood Studios
|
||||
|
||||
Tileset: TEMPERAT
|
||||
|
||||
MapSize: 128,128
|
||||
|
||||
Bounds: 18,10,81,58
|
||||
|
||||
Visibility: MissionSelector
|
||||
|
||||
Categories: Campaign
|
||||
|
||||
LockPreview: True
|
||||
|
||||
Players:
|
||||
PlayerReference@Neutral:
|
||||
Name: Neutral
|
||||
OwnsWorld: True
|
||||
NonCombatant: True
|
||||
Faction: allies
|
||||
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
|
||||
|
||||
Actors:
|
||||
Actor5: sbag
|
||||
Location: 62,37
|
||||
Owner: Greece
|
||||
Actor6: sbag
|
||||
Location: 63,37
|
||||
Owner: Greece
|
||||
Actor7: sbag
|
||||
Location: 64,37
|
||||
Owner: Greece
|
||||
Actor8: sbag
|
||||
Location: 65,37
|
||||
Owner: Greece
|
||||
Actor9: sbag
|
||||
Location: 65,38
|
||||
Owner: Greece
|
||||
Actor10: sbag
|
||||
Location: 66,38
|
||||
Owner: Greece
|
||||
Actor11: sbag
|
||||
Location: 71,38
|
||||
Owner: Greece
|
||||
Actor12: sbag
|
||||
Location: 72,38
|
||||
Owner: Greece
|
||||
Actor13: sbag
|
||||
Location: 73,38
|
||||
Owner: Greece
|
||||
Actor14: sbag
|
||||
Location: 74,38
|
||||
Owner: Greece
|
||||
Actor15: sbag
|
||||
Location: 82,38
|
||||
Owner: Greece
|
||||
Actor16: sbag
|
||||
Location: 83,38
|
||||
Owner: Greece
|
||||
Actor17: sbag
|
||||
Location: 70,39
|
||||
Owner: Greece
|
||||
Actor18: sbag
|
||||
Location: 71,39
|
||||
Owner: Greece
|
||||
Actor19: sbag
|
||||
Location: 83,39
|
||||
Owner: Greece
|
||||
Actor20: sbag
|
||||
Location: 83,40
|
||||
Owner: Greece
|
||||
Actor21: sbag
|
||||
Location: 57,43
|
||||
Owner: Greece
|
||||
Actor22: sbag
|
||||
Location: 58,43
|
||||
Owner: Greece
|
||||
Actor23: sbag
|
||||
Location: 57,44
|
||||
Owner: Greece
|
||||
Actor24: sbag
|
||||
Location: 80,46
|
||||
Owner: Greece
|
||||
Actor25: sbag
|
||||
Location: 80,47
|
||||
Owner: Greece
|
||||
Actor26: sbag
|
||||
Location: 63,48
|
||||
Owner: Greece
|
||||
Actor27: sbag
|
||||
Location: 64,48
|
||||
Owner: Greece
|
||||
Actor28: sbag
|
||||
Location: 79,48
|
||||
Owner: Greece
|
||||
Actor29: sbag
|
||||
Location: 80,48
|
||||
Owner: Greece
|
||||
Actor30: sbag
|
||||
Location: 64,49
|
||||
Owner: Greece
|
||||
Actor31: sbag
|
||||
Location: 64,50
|
||||
Owner: Greece
|
||||
Actor32: sbag
|
||||
Location: 65,50
|
||||
Owner: Greece
|
||||
Actor33: t17
|
||||
Location: 66,28
|
||||
Owner: Neutral
|
||||
Actor34: t08
|
||||
Location: 83,35
|
||||
Owner: Neutral
|
||||
Actor35: t16
|
||||
Location: 82,34
|
||||
Owner: Neutral
|
||||
Actor36: tc04
|
||||
Location: 63,26
|
||||
Owner: Neutral
|
||||
Actor37: tc05
|
||||
Location: 67,30
|
||||
Owner: Neutral
|
||||
Actor38: tc01
|
||||
Location: 79,32
|
||||
Owner: Neutral
|
||||
Actor39: tc04
|
||||
Location: 34,20
|
||||
Owner: Neutral
|
||||
Actor40: tc05
|
||||
Location: 82,15
|
||||
Owner: Neutral
|
||||
Actor41: tc04
|
||||
Location: 90,17
|
||||
Owner: Neutral
|
||||
Actor42: tc01
|
||||
Location: 92,18
|
||||
Owner: Neutral
|
||||
Actor43: tc03
|
||||
Location: 82,14
|
||||
Owner: Neutral
|
||||
Actor44: tc01
|
||||
Location: 95,15
|
||||
Owner: Neutral
|
||||
Actor45: tc02
|
||||
Location: 83,12
|
||||
Owner: Neutral
|
||||
Actor46: t17
|
||||
Location: 85,12
|
||||
Owner: Neutral
|
||||
Actor47: t16
|
||||
Location: 86,13
|
||||
Owner: Neutral
|
||||
Actor48: t16
|
||||
Location: 92,24
|
||||
Owner: Neutral
|
||||
Actor49: t14
|
||||
Location: 93,24
|
||||
Owner: Neutral
|
||||
Actor50: t11
|
||||
Location: 93,21
|
||||
Owner: Neutral
|
||||
Actor51: tc05
|
||||
Location: 54,23
|
||||
Owner: Neutral
|
||||
Actor52: tc05
|
||||
Location: 74,46
|
||||
Owner: Neutral
|
||||
Actor53: tc04
|
||||
Location: 80,43
|
||||
Owner: Neutral
|
||||
Actor54: tc02
|
||||
Location: 81,42
|
||||
Owner: Neutral
|
||||
Actor55: tc01
|
||||
Location: 73,40
|
||||
Owner: Neutral
|
||||
Actor56: t17
|
||||
Location: 71,40
|
||||
Owner: Neutral
|
||||
Actor57: t15
|
||||
Location: 80,36
|
||||
Owner: Neutral
|
||||
Actor58: t12
|
||||
Location: 31,57
|
||||
Owner: Neutral
|
||||
Actor59: tc04
|
||||
Location: 54,26
|
||||
Owner: Neutral
|
||||
Actor60: t14
|
||||
Location: 50,31
|
||||
Owner: Neutral
|
||||
Actor62: t05
|
||||
Location: 48,39
|
||||
Owner: Neutral
|
||||
Actor63: t06
|
||||
Location: 47,39
|
||||
Owner: Neutral
|
||||
Actor66: t08
|
||||
Location: 49,38
|
||||
Owner: Neutral
|
||||
Actor68: t08
|
||||
Location: 50,39
|
||||
Owner: Neutral
|
||||
Actor69: tc05
|
||||
Location: 35,58
|
||||
Owner: Neutral
|
||||
Actor70: tc04
|
||||
Location: 44,55
|
||||
Owner: Neutral
|
||||
Actor71: tc02
|
||||
Location: 34,66
|
||||
Owner: Neutral
|
||||
Actor72: tc04
|
||||
Location: 56,65
|
||||
Owner: Neutral
|
||||
Actor73: t17
|
||||
Location: 49,66
|
||||
Owner: Neutral
|
||||
Actor74: t16
|
||||
Location: 50,65
|
||||
Owner: Neutral
|
||||
Actor75: tc02
|
||||
Location: 54,66
|
||||
Owner: Neutral
|
||||
Actor76: tc01
|
||||
Location: 52,66
|
||||
Owner: Neutral
|
||||
Actor77: tc02
|
||||
Location: 58,58
|
||||
Owner: Neutral
|
||||
Actor78: t15
|
||||
Location: 59,60
|
||||
Owner: Neutral
|
||||
Actor79: t14
|
||||
Location: 48,38
|
||||
Owner: Neutral
|
||||
Actor81: tc03
|
||||
Location: 49,20
|
||||
Owner: Neutral
|
||||
Actor82: tc02
|
||||
Location: 36,19
|
||||
Owner: Neutral
|
||||
Actor83: t15
|
||||
Location: 39,25
|
||||
Owner: Neutral
|
||||
Actor84: t08
|
||||
Location: 38,27
|
||||
Owner: Neutral
|
||||
Actor85: t08
|
||||
Location: 40,25
|
||||
Owner: Neutral
|
||||
Actor86: t13
|
||||
Location: 49,40
|
||||
Owner: Neutral
|
||||
Actor88: t02
|
||||
Location: 50,37
|
||||
Owner: Neutral
|
||||
Actor90: hbox
|
||||
Location: 58,46
|
||||
Owner: Greece
|
||||
Actor91: hbox
|
||||
Location: 62,47
|
||||
Owner: Greece
|
||||
Actor92: gun
|
||||
Location: 57,46
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
TurretFacing: 768
|
||||
Actor93: gun
|
||||
Location: 61,48
|
||||
Owner: Greece
|
||||
Facing: 640
|
||||
TurretFacing: 768
|
||||
Actor103: 2tnk
|
||||
Location: 76,30
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Actor104: 2tnk
|
||||
Location: 76,29
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Actor106: arty
|
||||
Location: 64,46
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Stance: Defend
|
||||
Actor107: arty
|
||||
Location: 58,44
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Stance: Defend
|
||||
Actor110: 3tnk
|
||||
Location: 43,63
|
||||
Owner: USSR
|
||||
Facing: 896
|
||||
Actor111: 3tnk
|
||||
Location: 44,62
|
||||
Owner: USSR
|
||||
Facing: 896
|
||||
Actor112: v2rl
|
||||
Location: 41,64
|
||||
Owner: USSR
|
||||
Facing: 896
|
||||
Actor113: v2rl
|
||||
Location: 43,64
|
||||
Owner: USSR
|
||||
Facing: 896
|
||||
Actor115: 2tnk
|
||||
Location: 75,30
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Actor116: 2tnk
|
||||
Location: 75,31
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Actor117: 2tnk
|
||||
Location: 83,19
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Actor118: 2tnk
|
||||
Location: 88,21
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Actor119: 2tnk
|
||||
Location: 62,44
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Actor120: 1tnk
|
||||
Location: 59,44
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Actor121: 1tnk
|
||||
Location: 63,46
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
BridgeBreaker: ca
|
||||
Location: 87,29
|
||||
Owner: Greece
|
||||
Facing: 128
|
||||
BridgeBreaker2: ca
|
||||
Location: 87,31
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
ResponseCruiser: ca
|
||||
Location: 75,25
|
||||
Owner: Greece
|
||||
Facing: 128
|
||||
Actor126: pt
|
||||
Location: 71,16
|
||||
Owner: Greece
|
||||
Facing: 128
|
||||
Actor127: pt
|
||||
Location: 65,20
|
||||
Owner: Greece
|
||||
Facing: 128
|
||||
Actor128: dd
|
||||
Location: 70,20
|
||||
Owner: Greece
|
||||
Facing: 128
|
||||
Actor129: waypoint
|
||||
Location: 46,60
|
||||
Owner: Neutral
|
||||
Actor144: silo
|
||||
Owner: Greece
|
||||
Location: 73,46
|
||||
Actor145: silo
|
||||
Owner: Greece
|
||||
Location: 73,47
|
||||
Actor146: silo
|
||||
Owner: Greece
|
||||
Location: 73,48
|
||||
Actor147: silo
|
||||
Owner: Greece
|
||||
Location: 73,49
|
||||
Actor148: sbag
|
||||
Owner: Greece
|
||||
Location: 65,51
|
||||
waypoint69: waypoint
|
||||
Location: 21,28
|
||||
Owner: Neutral
|
||||
waypoint78: waypoint
|
||||
Location: 83,23
|
||||
Owner: Neutral
|
||||
waypoint79: waypoint
|
||||
Location: 87,19
|
||||
Owner: Neutral
|
||||
waypoint80: waypoint
|
||||
Location: 84,22
|
||||
Owner: Neutral
|
||||
waypoint81: waypoint
|
||||
Location: 76,22
|
||||
Owner: Neutral
|
||||
waypoint82: waypoint
|
||||
Location: 87,29
|
||||
Owner: Neutral
|
||||
waypoint94: waypoint
|
||||
Location: 49,16
|
||||
Owner: Neutral
|
||||
AGun: agun
|
||||
Owner: Greece
|
||||
Location: 69,49
|
||||
TurretFacing: 368
|
||||
APCWaypoint1: waypoint
|
||||
Location: 39,62
|
||||
Owner: Neutral
|
||||
APCWaypoint2: waypoint
|
||||
Location: 46,66
|
||||
Owner: Neutral
|
||||
Apwr: apwr
|
||||
Location: 76,41
|
||||
Owner: Greece
|
||||
Apwr2: apwr
|
||||
Location: 77,45
|
||||
Owner: Greece
|
||||
AttackWaypoint1: waypoint
|
||||
Owner: Neutral
|
||||
Location: 26,55
|
||||
AttackWaypoint2: waypoint
|
||||
Owner: Neutral
|
||||
Location: 41,55
|
||||
Tent: tent
|
||||
Location: 67,45
|
||||
Owner: Greece
|
||||
CameraStart: camera
|
||||
Location: 46,61
|
||||
Owner: Neutral
|
||||
CYard: fact
|
||||
Location: 70,46
|
||||
Owner: Greece
|
||||
CYardLocation: waypoint
|
||||
Owner: Neutral
|
||||
Location: 71,49
|
||||
Dome: dome
|
||||
Location: 67,49
|
||||
Owner: Greece
|
||||
EnemyEntry1: waypoint
|
||||
Owner: Neutral
|
||||
Location: 53,10
|
||||
EnemyEntry2: waypoint
|
||||
Owner: Neutral
|
||||
Location: 18,62
|
||||
EnemyRally1: waypoint
|
||||
Owner: Neutral
|
||||
Location: 53,31
|
||||
EnemyRally2: waypoint
|
||||
Owner: Neutral
|
||||
Location: 25,62
|
||||
Harvester: harv
|
||||
Location: 77,39
|
||||
Owner: Greece
|
||||
IntroEnemy1: 1tnk
|
||||
Location: 55,49
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
IntroEnemy2: 2tnk
|
||||
Location: 56,50
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
IntroEnemy3: 1tnk
|
||||
Location: 58,50
|
||||
Owner: Greece
|
||||
Facing: 384
|
||||
Mcv: mcv
|
||||
Location: 51,55
|
||||
Owner: USSR
|
||||
Health: 82
|
||||
Facing: 384
|
||||
McvWaypoint: waypoint
|
||||
Location: 39,67
|
||||
Owner: Neutral
|
||||
Proc: proc
|
||||
Location: 71,41
|
||||
Owner: Greece
|
||||
FreeActor: False
|
||||
Truck1: truk
|
||||
Location: 42,66
|
||||
Owner: USSR
|
||||
Facing: 896
|
||||
Truck2: truk
|
||||
Location: 39,65
|
||||
Owner: USSR
|
||||
Facing: 896
|
||||
Weap: weap
|
||||
Location: 67,41
|
||||
Owner: Greece
|
||||
|
||||
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
|
||||
146
mods/ra/maps/soviet-06b/rules.yaml
Normal file
146
mods/ra/maps/soviet-06b/rules.yaml
Normal file
@@ -0,0 +1,146 @@
|
||||
Player:
|
||||
PlayerResources:
|
||||
DefaultCash: 11500
|
||||
|
||||
World:
|
||||
LuaScript:
|
||||
Scripts: campaign.lua, utils.lua, soviet06b.lua, soviet06b-AI.lua, soviet06b-reinforcements_teams.lua
|
||||
MissionData:
|
||||
Briefing: briefing
|
||||
BriefingVideo: soviet6.vqa
|
||||
StartVideo: onthprwl.vqa
|
||||
WinVideo: sitduck.vqa
|
||||
LossVideo: dpthchrg.vqa
|
||||
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
|
||||
|
||||
APWR:
|
||||
Buildable:
|
||||
Prerequisites: ~structures.allies
|
||||
|
||||
ARTY:
|
||||
Buildable:
|
||||
Prerequisites: ~vehicles.allies, ~techlevel.low
|
||||
|
||||
ATEK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
BRIK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
TSLA:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
SAM:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
IRON:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MECH:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MSLO:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
E3:
|
||||
Buildable:
|
||||
Prerequisites: ~tent
|
||||
|
||||
E7:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
SHOK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
SPY:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
THF:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MIG:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
FTRK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
2TNK:
|
||||
Buildable:
|
||||
Prerequisites: ~vehicles.allies, ~techlevel.low
|
||||
|
||||
4TNK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
APC:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
TRUK:
|
||||
-SpawnActorOnDeath:
|
||||
-DeliversCash:
|
||||
|
||||
QTNK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MCV:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MSUB:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
STEK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
PDOX:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MRJ:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
CA:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
HELI:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
GAP:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MNLY:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
AFLD:
|
||||
ParatroopersPower@paratroopers:
|
||||
DropItems: E1,E1,E1,E1,E1
|
||||
228
mods/ra/maps/soviet-06b/soviet06b-AI.lua
Normal file
228
mods/ra/maps/soviet-06b/soviet06b-AI.lua
Normal file
@@ -0,0 +1,228 @@
|
||||
--[[
|
||||
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.
|
||||
]]
|
||||
InfAttack = { }
|
||||
ArmorAttack = { }
|
||||
AttackPaths = { { AttackWaypoint1.Location }, { AttackWaypoint2.Location } }
|
||||
|
||||
AlliedInfantryTypes = { "e1", "e1", "e3" }
|
||||
AlliedArmorTypes = { "jeep", "jeep", "1tnk", "1tnk", "2tnk", "2tnk", "arty" }
|
||||
|
||||
ProduceInfantry = function(barracks)
|
||||
if barracks.IsDead or barracks.Owner ~= Greece then
|
||||
return
|
||||
elseif GreeceMoney() <= 299 and IsHarvesterMissing() then
|
||||
return
|
||||
end
|
||||
|
||||
local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9))
|
||||
local toBuild = { Utils.Random(AlliedInfantryTypes) }
|
||||
local path = Utils.Random(AttackPaths)
|
||||
Greece.Build(toBuild, function(units)
|
||||
InfAttack[#InfAttack + 1] = units[1]
|
||||
|
||||
if #InfAttack >= 10 then
|
||||
SendUnits(InfAttack, path)
|
||||
InfAttack = { }
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), function()
|
||||
ProduceInfantry(barracks)
|
||||
end)
|
||||
else
|
||||
Trigger.AfterDelay(delay, function()
|
||||
ProduceInfantry(barracks)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
ProduceArmor = function(factory)
|
||||
local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17))
|
||||
|
||||
if factory.IsDead or factory.Owner ~= Greece then
|
||||
return
|
||||
elseif IsHarvesterMissing() then
|
||||
ProduceHarvester(factory, delay)
|
||||
return
|
||||
end
|
||||
|
||||
local toBuild = { Utils.Random(AlliedArmorTypes) }
|
||||
local path = Utils.Random(AttackPaths)
|
||||
Greece.Build(toBuild, function(units)
|
||||
ArmorAttack[#ArmorAttack + 1] = units[1]
|
||||
|
||||
if #ArmorAttack >= 6 then
|
||||
SendUnits(ArmorAttack, path)
|
||||
ArmorAttack = { }
|
||||
Trigger.AfterDelay(DateTime.Minutes(3), function()
|
||||
ProduceArmor(factory)
|
||||
end)
|
||||
else
|
||||
Trigger.AfterDelay(delay, function()
|
||||
ProduceArmor(factory)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
ProduceHarvester = function(factory, delay)
|
||||
if GreeceMoney() < Actor.Cost("harv") then
|
||||
return
|
||||
end
|
||||
|
||||
local toBuild = { "harv" }
|
||||
Greece.Build(toBuild, function()
|
||||
Trigger.AfterDelay(delay, function()
|
||||
ProduceArmor(factory)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
SendUnits = function(units, path)
|
||||
Utils.Do(units, function(unit)
|
||||
if unit.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
unit.Patrol(path, false)
|
||||
IdleHunt(unit)
|
||||
end)
|
||||
end
|
||||
|
||||
IsHarvesterMissing = function()
|
||||
return #Greece.GetActorsByType("harv") == 0
|
||||
end
|
||||
|
||||
GreeceMoney = function()
|
||||
return Greece.Cash + Greece.Resources
|
||||
end
|
||||
|
||||
BaseBlueprints =
|
||||
{
|
||||
{ type = "apwr", actor = Apwr, cost = 500, shape = { 3, 3 }, location = CPos.New(76, 41) },
|
||||
{ type = "tent", actor = Tent, cost = 400, shape = { 2, 3 }, location = CPos.New(67, 45), onBuilt = ProduceInfantry },
|
||||
{ type = "proc", actor = Proc, cost = 1400, shape = { 3, 4 }, location = CPos.New(71, 41) },
|
||||
{ type = "weap", actor = Weap, cost = 2000, shape = { 3, 3 }, location = CPos.New(67, 41), onBuilt = ProduceArmor },
|
||||
{ type = "apwr", actor = Apwr2, cost = 500, shape = { 3, 3 }, location = CPos.New(77, 45) }
|
||||
}
|
||||
|
||||
--[[
|
||||
Similar to the original CnC/RA [BASE] and [STRUCTURES] .INI sections.
|
||||
Check a list every so often and (re)build structures missing from
|
||||
that list, in order, if circumstances allow for it.
|
||||
]]
|
||||
BuildBase = function()
|
||||
for _, blueprint in pairs(BaseBlueprints) do
|
||||
if not blueprint.actor then
|
||||
BuildBlueprint(blueprint)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), BuildBase)
|
||||
end
|
||||
|
||||
BuildBlueprint = function(blueprint)
|
||||
Trigger.AfterDelay(Actor.BuildTime(blueprint.type), function()
|
||||
if CYard.IsDead or CYard.Owner ~= Greece then
|
||||
return
|
||||
elseif GreeceMoney() <= 299 and IsHarvesterMissing() then
|
||||
return
|
||||
end
|
||||
|
||||
if IsBuildAreaBlocked(Greece, blueprint) then
|
||||
Trigger.AfterDelay(DateTime.Seconds(5), function()
|
||||
BuildBlueprint(blueprint)
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
local actor = Actor.Create(blueprint.type, true, { Owner = Greece, Location = blueprint.location })
|
||||
OnBlueprintBuilt(actor, blueprint)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), BuildBase)
|
||||
end)
|
||||
end
|
||||
|
||||
OnBlueprintBuilt = function(actor, blueprint)
|
||||
Greece.Cash = Greece.Cash - blueprint.cost
|
||||
blueprint.actor = actor
|
||||
MaintainBuilding(actor, blueprint, 0.75)
|
||||
|
||||
if blueprint.onBuilt then
|
||||
-- Build() will not work properly on producers if immediately called.
|
||||
Trigger.AfterDelay(1, function()
|
||||
blueprint.onBuilt(actor)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
IsBuildAreaBlocked = function(player, blueprint)
|
||||
local nw, se = blueprint.northwestEdge, blueprint.southeastEdge
|
||||
local blockers = Map.ActorsInBox(nw, se, function(actor)
|
||||
-- Neutral check is for ignoring trees near the refinery.
|
||||
return actor.Owner ~= Neutral and actor.CenterPosition.Z == 0 and actor.HasProperty("Health")
|
||||
end)
|
||||
|
||||
if #blockers == 0 then
|
||||
return false
|
||||
end
|
||||
|
||||
ScatterBlockers(player, blockers)
|
||||
return true
|
||||
end
|
||||
|
||||
ScatterBlockers = function(player, actors)
|
||||
Utils.Do(actors, function(actor)
|
||||
if actor.IsIdle and actor.Owner == player and actor.HasProperty("Scatter") then
|
||||
actor.Scatter()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
BeginBaseMaintenance = function()
|
||||
Utils.Do(BaseBlueprints, function(blueprint)
|
||||
MaintainBuilding(blueprint.actor, blueprint)
|
||||
end)
|
||||
|
||||
Utils.Do(Greece.GetActors(), function(actor)
|
||||
if actor.HasProperty("StartBuildingRepairs") then
|
||||
MaintainBuilding(actor, nil, 0.75)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
MaintainBuilding = function(actor, blueprint, repairThreshold)
|
||||
if blueprint then
|
||||
Trigger.OnKilled(actor, function() blueprint.actor = nil end)
|
||||
Trigger.OnSold(actor, function() blueprint.actor = nil end)
|
||||
if not blueprint.northwestEdge then
|
||||
PrepareBlueprintEdges(blueprint)
|
||||
end
|
||||
end
|
||||
|
||||
if repairThreshold then
|
||||
local original = actor.Owner
|
||||
|
||||
Trigger.OnDamaged(actor, function()
|
||||
if actor.Owner ~= original or actor.Health > actor.MaxHealth * repairThreshold then
|
||||
return
|
||||
end
|
||||
|
||||
actor.StartBuildingRepairs()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
PrepareBlueprintEdges = function(blueprint)
|
||||
local shapeX, shapeY = blueprint.shape[1], blueprint.shape[2]
|
||||
local northwestEdge = Map.CenterOfCell(blueprint.location) + WVec.New(-512, -512, 0)
|
||||
local southeastEdge = northwestEdge + WVec.New(shapeX * 1024, shapeY * 1024, 0)
|
||||
|
||||
blueprint.northwestEdge = northwestEdge
|
||||
blueprint.southeastEdge = southeastEdge
|
||||
end
|
||||
68
mods/ra/maps/soviet-06b/soviet06b-reinforcements_teams.lua
Normal file
68
mods/ra/maps/soviet-06b/soviet06b-reinforcements_teams.lua
Normal 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.
|
||||
]]
|
||||
EnemyReinforcements =
|
||||
{
|
||||
easy =
|
||||
{
|
||||
{ "e1", "e1", "e3" },
|
||||
{ "e1", "e3", "jeep" },
|
||||
{ "e1", "jeep", "1tnk" }
|
||||
},
|
||||
|
||||
normal =
|
||||
{
|
||||
{ "e1", "e1", "e3", "e3" },
|
||||
{ "e1", "e3", "jeep", "jeep" },
|
||||
{ "e1", "jeep", "1tnk", "2tnk" }
|
||||
},
|
||||
|
||||
hard =
|
||||
{
|
||||
{ "e1", "e1", "e3", "e3", "e1" },
|
||||
{ "e1", "e3", "jeep", "jeep", "1tnk" },
|
||||
{ "e1", "jeep", "1tnk", "2tnk", "arty" }
|
||||
}
|
||||
}
|
||||
|
||||
EnemyAttackDelay =
|
||||
{
|
||||
easy = DateTime.Minutes(5),
|
||||
normal = DateTime.Minutes(2) + DateTime.Seconds(40),
|
||||
hard = DateTime.Minutes(1) + DateTime.Seconds(30)
|
||||
}
|
||||
|
||||
EnemyPaths =
|
||||
{
|
||||
{ EnemyEntry1.Location, EnemyRally1.Location },
|
||||
{ EnemyEntry2.Location, EnemyRally2.Location }
|
||||
}
|
||||
|
||||
Wave = 0
|
||||
SendReinforcements = function()
|
||||
Trigger.AfterDelay(EnemyAttackDelay[Difficulty], function()
|
||||
if Dome.IsDead or Dome.Owner ~= Greece then
|
||||
return
|
||||
end
|
||||
|
||||
Wave = Wave + 1
|
||||
if Wave > 3 then
|
||||
Wave = 1
|
||||
end
|
||||
|
||||
if Wave == 1 then
|
||||
local units = Reinforcements.ReinforceWithTransport(Greece, "tran", EnemyReinforcements[Difficulty][Wave], EnemyPaths[1], { EnemyPaths[1][1] })[2]
|
||||
Utils.Do(units, IdleHunt)
|
||||
else
|
||||
local units = Reinforcements.ReinforceWithTransport(Greece, "lst", EnemyReinforcements[Difficulty][Wave], EnemyPaths[2], { EnemyPaths[2][1] })[2]
|
||||
Utils.Do(units, IdleHunt)
|
||||
end
|
||||
|
||||
SendReinforcements()
|
||||
end)
|
||||
end
|
||||
221
mods/ra/maps/soviet-06b/soviet06b.lua
Normal file
221
mods/ra/maps/soviet-06b/soviet06b.lua
Normal file
@@ -0,0 +1,221 @@
|
||||
--[[
|
||||
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.
|
||||
]]
|
||||
|
||||
Trigger.OnRemovedFromWorld(Mcv, function()
|
||||
if McvDeployed or Mcv.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
McvDeployed = true
|
||||
BuildBase()
|
||||
SendReinforcements()
|
||||
|
||||
Trigger.AfterDelay(DateTime.Minutes(1), function()
|
||||
ProduceInfantry(Tent)
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), function()
|
||||
ProduceArmor(Weap)
|
||||
end)
|
||||
end)
|
||||
|
||||
PrepareResponseCruiser = function()
|
||||
local responseBuildings = { Apwr, Tent, Weap }
|
||||
local responseOrdered = false
|
||||
|
||||
Utils.Do(responseBuildings, function(building)
|
||||
Trigger.OnDamaged(building, function()
|
||||
if responseOrdered or USSR.IsObjectiveCompleted(DisruptDome) then
|
||||
return
|
||||
end
|
||||
|
||||
responseOrdered = true
|
||||
OrderResponseCruiser()
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
OrderResponseCruiser = function()
|
||||
if ResponseCruiser.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
ResponseCruiser.AttackMove(waypoint94.Location, 2)
|
||||
ResponseCruiser.Wait(DateTime.Seconds(90))
|
||||
|
||||
Trigger.OnIdle(ResponseCruiser, function()
|
||||
ResponseCruiser.AttackMove(waypoint69.Location, 2)
|
||||
end)
|
||||
|
||||
Trigger.OnDamaged(ResponseCruiser, function(_, attacker)
|
||||
if attacker.IsDead or not ResponseCruiser.CanTarget(attacker) then
|
||||
return
|
||||
end
|
||||
|
||||
ResponseCruiser.Attack(attacker)
|
||||
ResponseCruiser.Scatter()
|
||||
end)
|
||||
end
|
||||
|
||||
PrepareBridgeBreakers = function()
|
||||
local target = Map.ActorsInCircle(waypoint78.CenterPosition, WDist.New(1536), function(actor)
|
||||
return actor.Type == "br3"
|
||||
end)[1]
|
||||
|
||||
if not target then
|
||||
Media.Debug("No bridge segment found.")
|
||||
return
|
||||
end
|
||||
|
||||
local orderSent = false
|
||||
Trigger.AfterDelay(DateTime.Seconds(30), function()
|
||||
orderSent = true
|
||||
OrderBridgeBreakers(target)
|
||||
end)
|
||||
|
||||
local bridgeEntryCells = { CPos.New(75, 30), CPos.New(76, 30), CPos.New(77, 30) }
|
||||
Trigger.OnEnteredFootprint(bridgeEntryCells, function(a, id)
|
||||
if a.Owner ~= USSR then
|
||||
return
|
||||
end
|
||||
|
||||
Trigger.RemoveFootprintTrigger(id)
|
||||
|
||||
if not orderSent then
|
||||
OrderBridgeBreakers(target, "with bridge reveal")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
OrderBridgeBreakers = function(target, reveal)
|
||||
if target.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
local breakers = { BridgeBreaker, BridgeBreaker2 }
|
||||
Utils.Do(breakers, function(breaker)
|
||||
if breaker.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
breaker.Stop()
|
||||
breaker.Attack(target, true, true)
|
||||
end)
|
||||
|
||||
if not reveal then
|
||||
return
|
||||
end
|
||||
|
||||
local camera = Actor.Create("camera", true, { Owner = USSR, Location = target.Location })
|
||||
Trigger.OnKilled(target, function()
|
||||
Trigger.AfterDelay(DateTime.Seconds(2), camera.Destroy)
|
||||
end)
|
||||
end
|
||||
|
||||
PrepareObjectives = function()
|
||||
InitObjectives(USSR)
|
||||
KillTrucks = AddPrimaryObjective(Greece, "")
|
||||
EscortConvoy = AddPrimaryObjective(USSR, "escort-convoy")
|
||||
DisruptDome = AddSecondaryObjective(USSR, "destroy-capture-radar-dome-reinforcements")
|
||||
SaveAllTrucks = AddSecondaryObjective(USSR, "keep-trucks-alive")
|
||||
|
||||
Trigger.OnKilledOrCaptured(Dome, function()
|
||||
-- Let the capture notification play first.
|
||||
Trigger.AfterDelay(DateTime.Seconds(2), function()
|
||||
USSR.MarkCompletedObjective(DisruptDome)
|
||||
Media.PlaySpeechNotification(USSR, "ObjectiveMet")
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
PrepareTrucks = function()
|
||||
local trucks = { Truck1, Truck2 }
|
||||
local goalCells = { CPos.New(85, 10), CPos.New(85, 11), CPos.New(85, 12), CPos.New(86, 13), CPos.New(87, 13), CPos.New(88, 13), CPos.New(88, 14), CPos.New(89, 14), CPos.New(90, 14), CPos.New(90, 15), CPos.New(91, 15), CPos.New(91, 16), CPos.New(91, 17), CPos.New(92, 17), CPos.New(93, 17), CPos.New(94, 17), CPos.New(94, 18), CPos.New(95, 18), CPos.New(96, 18), CPos.New(96, 19), CPos.New(97, 19), CPos.New(98, 19)}
|
||||
|
||||
local goalTriggered = false
|
||||
Trigger.OnEnteredFootprint(goalCells, function(a)
|
||||
if not goalTriggered and a.Owner == USSR and a.Type == "truk" then
|
||||
goalTriggered = true
|
||||
USSR.MarkCompletedObjective(EscortConvoy)
|
||||
USSR.MarkCompletedObjective(SaveAllTrucks)
|
||||
end
|
||||
end)
|
||||
|
||||
Trigger.OnAllKilled(trucks, function()
|
||||
Greece.MarkCompletedObjective(KillTrucks)
|
||||
end)
|
||||
|
||||
Trigger.OnAnyKilled(trucks, function()
|
||||
USSR.MarkFailedObjective(SaveAllTrucks)
|
||||
end)
|
||||
end
|
||||
|
||||
BeginIntro = function()
|
||||
local introAttackers = { IntroEnemy1, IntroEnemy2, IntroEnemy3 }
|
||||
local sovietReinforcements1 = { "e6", "e6", "e6", "e6", "e6" }
|
||||
local sovietReinforcements2 = { "e4", "e4", "e2", "e2", "e2" }
|
||||
local sovietReinforcements1Path = { McvWaypoint.Location, APCWaypoint1.Location }
|
||||
local sovietReinforcements2Path = { McvWaypoint.Location, APCWaypoint2.Location }
|
||||
|
||||
Mcv.Move(McvWaypoint.Location)
|
||||
Utils.Do(introAttackers, IdleHunt)
|
||||
Reinforcements.ReinforceWithTransport(USSR, "apc", sovietReinforcements1, sovietReinforcements1Path)
|
||||
Reinforcements.ReinforceWithTransport(USSR, "apc", sovietReinforcements2, sovietReinforcements2Path)
|
||||
end
|
||||
|
||||
PrepareIdleGuards = function()
|
||||
local lazyUnits = Utils.Where(Greece.GetGroundAttackers(), function(unit)
|
||||
return unit.Type ~= "ca" and unit.Type ~= "arty"
|
||||
end)
|
||||
|
||||
Utils.Do(lazyUnits, function(unit)
|
||||
local triggered = false
|
||||
|
||||
Trigger.OnDamaged(unit, function()
|
||||
if triggered then
|
||||
return
|
||||
end
|
||||
|
||||
triggered = true
|
||||
IdleHunt(unit)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
WorldLoaded = function()
|
||||
USSR = Player.GetPlayer("USSR")
|
||||
Greece = Player.GetPlayer("Greece")
|
||||
Neutral = Player.GetPlayer("Neutral")
|
||||
|
||||
PrepareObjectives()
|
||||
Camera.Position = CameraStart.CenterPosition
|
||||
Harvester.FindResources()
|
||||
BeginBaseMaintenance()
|
||||
|
||||
if Difficulty ~= "easy" then
|
||||
PrepareResponseCruiser()
|
||||
Trigger.AfterDelay(1, PrepareBridgeBreakers)
|
||||
end
|
||||
|
||||
PrepareTrucks()
|
||||
BeginIntro()
|
||||
PrepareIdleGuards()
|
||||
end
|
||||
|
||||
Tick = function()
|
||||
if USSR.HasNoRequiredUnits() then
|
||||
Greece.MarkCompletedObjective(KillTrucks)
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user