Add Mousetrap (scu33ea).

This commit is contained in:
JovialFeline
2023-06-03 15:02:37 -04:00
committed by Matthias Mailänder
parent 02a7ff87db
commit b18c2fe855
9 changed files with 1849 additions and 0 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -0,0 +1,754 @@
MapFormat: 12
RequiresMod: ra
Title: Mousetrap
Author: Westwood Studios
Tileset: INTERIOR
MapSize: 128,128
Bounds: 28,32,82,52
Visibility: MissionSelector
Categories: Mission
LockPreview: True
Players:
PlayerReference@Neutral:
Name: Neutral
OwnsWorld: True
NonCombatant: True
Faction: england
PlayerReference@Creeps:
Name: Creeps
NonCombatant: True
Faction: england
Enemies: USSR, Greece, GoodGuy, England
PlayerReference@USSR:
Name: USSR
Playable: True
LockFaction: True
Faction: soviet
LockColor: True
Color: FE1100
Enemies: Creeps, Greece, GoodGuy
PlayerReference@Greece:
Name: Greece
Bot: campaign
Faction: allies
Color: ABB7E4
Enemies: Creeps, USSR
PlayerReference@GoodGuy:
Name: GoodGuy
Bot: campaign
Faction: allies
Color: ABB7E4
Allies: Greece
Enemies: Creeps, USSR
PlayerReference@England:
Name: England
Faction: allies
Color: A1EF8C
Actors:
Actor0: cycl
Location: 44,34
Owner: Neutral
Actor1: cycl
Location: 45,34
Owner: Neutral
Actor2: cycl
Location: 46,34
Owner: Neutral
Actor3: cycl
Location: 47,34
Owner: Neutral
Actor4: cycl
Location: 48,34
Owner: Neutral
Actor5: cycl
Location: 53,34
Owner: Neutral
Actor6: cycl
Location: 54,34
Owner: Neutral
Actor7: cycl
Location: 55,34
Owner: Neutral
Actor8: cycl
Location: 56,34
Owner: Neutral
Actor9: cycl
Location: 57,34
Owner: Neutral
Actor10: healcrate
Location: 77,34
Owner: Neutral
Actor11: healcrate
Location: 78,34
Owner: Neutral
Actor12: cycl
Location: 44,35
Owner: Neutral
Actor13: cycl
Location: 48,35
Owner: Neutral
Actor14: cycl
Location: 53,35
Owner: Neutral
Actor15: cycl
Location: 57,35
Owner: Neutral
Actor16: cycl
Location: 44,36
Owner: Neutral
Actor17: cycl
Location: 48,36
Owner: Neutral
Actor18: cycl
Location: 53,36
Owner: Neutral
Actor19: cycl
Location: 57,36
Owner: Neutral
Actor20: cycl
Location: 44,37
Owner: Neutral
Actor21: cycl
Location: 48,37
Owner: Neutral
Actor22: cycl
Location: 53,37
Owner: Neutral
Actor23: cycl
Location: 57,37
Owner: Neutral
Actor24: cycl
Location: 44,38
Owner: Neutral
Actor25: cycl
Location: 48,38
Owner: Neutral
Actor26: cycl
Location: 53,38
Owner: Neutral
Actor27: cycl
Location: 57,38
Owner: Neutral
Actor28: cycl
Location: 44,39
Owner: Neutral
Actor29: cycl
Location: 48,39
Owner: Neutral
Actor30: cycl
Location: 53,39
Owner: Neutral
Actor31: cycl
Location: 57,39
Owner: Neutral
Actor32: cycl
Location: 44,40
Owner: Neutral
Actor33: cycl
Location: 48,40
Owner: Neutral
Actor34: cycl
Location: 53,40
Owner: Neutral
Actor35: cycl
Location: 57,40
Owner: Neutral
Actor36: cycl
Location: 44,41
Owner: Neutral
Actor37: cycl
Location: 45,41
Owner: Neutral
Actor38: cycl
Location: 46,41
Owner: Neutral
Actor39: cycl
Location: 47,41
Owner: Neutral
Actor40: cycl
Location: 48,41
Owner: Neutral
Actor41: cycl
Location: 53,41
Owner: Neutral
Actor42: cycl
Location: 54,41
Owner: Neutral
Actor43: cycl
Location: 55,41
Owner: Neutral
Actor44: cycl
Location: 56,41
Owner: Neutral
Actor45: cycl
Location: 57,41
Owner: Neutral
Actor46: barb
Location: 79,48
Owner: Neutral
Actor47: barb
Location: 82,48
Owner: Neutral
Actor48: barb
Location: 80,49
Owner: Neutral
Actor49: barb
Location: 81,49
Owner: Neutral
Actor50: ironcrate
Location: 42,50
Owner: Neutral
Actor51: barb
Location: 106,60
Owner: Neutral
Actor52: barb
Location: 107,60
Owner: Neutral
Actor53: barb
Location: 108,61
Owner: Neutral
Actor54: barb
Location: 108,62
Owner: Neutral
Actor55: barb
Location: 55,63
Owner: Neutral
Actor56: barb
Location: 58,63
Owner: Neutral
Actor57: barb
Location: 106,63
Owner: Neutral
Actor58: barb
Location: 107,63
Owner: Neutral
Actor59: barb
Location: 44,65
Owner: Neutral
Actor60: barb
Location: 47,65
Owner: Neutral
Actor61: barb
Location: 54,65
Owner: Neutral
Actor62: barb
Location: 55,65
Owner: Neutral
Actor63: barb
Location: 58,65
Owner: Neutral
Actor64: barb
Location: 59,65
Owner: Neutral
Actor65: barb
Location: 43,67
Owner: Neutral
Actor66: barb
Location: 48,67
Owner: Neutral
Actor67: barb
Location: 32,71
Owner: Neutral
Actor68: barb
Location: 35,71
Owner: Neutral
Actor69: barb
Location: 31,73
Owner: Neutral
Actor70: barb
Location: 36,73
Owner: Neutral
Actor71: barb
Location: 108,73
Owner: Neutral
Actor72: barb
Location: 108,74
Owner: Neutral
Actor73: ironcrate
Location: 63,81
Owner: Neutral
Actor74: boxes01
Location: 42,47
Owner: Neutral
Actor75: boxes02
Location: 43,48
Owner: Neutral
Actor76: boxes02
Location: 44,50
Owner: Neutral
Actor77: boxes03
Location: 64,82
Owner: Neutral
Actor78: boxes05
Location: 62,80
Owner: Neutral
Actor79: boxes01
Location: 76,33
Owner: Neutral
Actor80: boxes02
Location: 79,35
Owner: Neutral
Actor81: boxes03
Location: 79,33
Owner: Neutral
Actor82: boxes04
Location: 76,35
Owner: Neutral
Actor83: boxes01
Location: 68,79
Owner: Neutral
Actor84: boxes02
Location: 66,80
Owner: Neutral
Actor85: boxes03
Location: 68,80
Owner: Neutral
Actor86: boxes04
Location: 68,82
Owner: Neutral
Actor87: boxes04
Location: 67,79
Owner: Neutral
NorthwestPower: apwr
Location: 45,35
Owner: Greece
SoutheastPower: apwr
Location: 54,38
Owner: GoodGuy
SouthwestPower: apwr
Location: 45,38
Owner: GoodGuy
NortheastPower: apwr
Location: 54,35
Owner: Greece
StartSphere: pdox
Location: 45,66
Owner: Greece
SouthwestSphere: pdox
Location: 33,72
Owner: Greece
ControlSphere: pdox
Location: 73,73
Owner: Greece
CenterSphere: pdox
Location: 56,64
Owner: Greece
EastSphere: pdox
Location: 106,61
Owner: Greece
GasSphere: pdox
Location: 85,67
Owner: Greece
SoutheastSphere: pdox
Location: 106,73
Owner: Greece
DamagedSphere: pdox.capturable
Location: 43,59
Owner: Greece
Health: 12
NorthwestSphere: pdox
Location: 43,52
Owner: Greece
NorthSphere: pdox
Location: 80,47
Owner: Greece
EndingSphereRight: pdox
Location: 102,46
Owner: Greece
EndingSphereLeft: pdox
Location: 95,46
Owner: Greece
Actor104: e1
Location: 45,79
Owner: USSR
SubCell: 0
Actor105: e1
Location: 46,79
Owner: USSR
SubCell: 0
Actor106: e4
Location: 44,80
Owner: USSR
SubCell: 0
Actor107: e4
Location: 47,80
Owner: USSR
SubCell: 0
Actor108: e4
Location: 45,80
Owner: USSR
SubCell: 0
Actor109: e4
Location: 46,80
Owner: USSR
SubCell: 0
Stavros: stavros.start
Location: 46,75
Owner: GoodGuy
SubCell: 1
Actor111: dog
Location: 48,81
Owner: USSR
SubCell: 4
Actor112: dog
Location: 48,80
Owner: USSR
SubCell: 4
Actor113: dog
Location: 43,80
Owner: USSR
SubCell: 4
Actor114: dog
Location: 43,81
Owner: USSR
SubCell: 4
Actor115: e1
Location: 44,79
Owner: USSR
SubCell: 0
Actor116: e1
Location: 47,79
Owner: USSR
SubCell: 0
Actor117: e6
Location: 45,81
Owner: USSR
SubCell: 2
Actor118: e6
Location: 46,81
Owner: USSR
SubCell: 1
Actor119: e1
Location: 71,35
Owner: Greece
Facing: 256
SubCell: 0
Actor120: e1
Location: 72,35
Owner: Greece
Facing: 256
SubCell: 2
Actor121: e1
Location: 71,34
Owner: Greece
Facing: 256
SubCell: 4
Actor122: e1
Location: 78,46
Owner: Greece
Facing: 256
SubCell: 3
Actor123: e1
Location: 78,47
Owner: Greece
Facing: 256
SubCell: 0
Actor124: e1
Location: 65,56
Owner: Greece
SubCell: 2
Facing: 512
Actor125: e1
Location: 69,56
Owner: Greece
SubCell: 1
Facing: 512
Actor126: e1
Location: 74,59
Owner: Greece
Facing: 256
SubCell: 2
Actor127: e1
Location: 74,60
Owner: Greece
Facing: 256
SubCell: 4
Actor128: e1
Location: 90,61
Owner: Greece
Facing: 256
SubCell: 0
Actor129: e1
Location: 90,62
Owner: Greece
Facing: 256
SubCell: 4
StartSphereEntrance: waypoint
Location: 45,67
Owner: Neutral
StartSphereRally: waypoint
Location: 46,70
Owner: Neutral
waypoint2: waypoint
Location: 34,72
Owner: Neutral
SouthwestSphereRally: waypoint
Location: 32,75
Owner: Neutral
ControlReveal: waypoint
Location: 74,74
Owner: Neutral
ControlNortheast: waypoint
Location: 76,71
Owner: Neutral
SelfDestructReveal: waypoint
Location: 50,38
Owner: Neutral
NorthwestGas2: waypoint
Location: 50,43
Owner: Neutral
NorthwestGas1: waypoint
Location: 51,42
Owner: Neutral
CenterSphereEntrance: waypoint
Location: 57,64
Owner: Neutral
ControlNorthwest: waypoint
Location: 71,71
Owner: Neutral
GasSphereEntrance: waypoint
Location: 85,68
Owner: Neutral
GasSphereRally: waypoint
Location: 83,63
Owner: Neutral
GasSphereReveal: camera.small
Location: 83,67
Owner: Neutral
ScriptTags: Gas
ControlEast: waypoint
Location: 79,73
Owner: Neutral
EastGas1: waypoint
Location: 92,61
Owner: Neutral
EastGas2: waypoint
Location: 92,62
Owner: Neutral
FlamerEntry: waypoint
Location: 45,83
Owner: Neutral
FlamerRally: waypoint
Location: 44,82
Owner: Neutral
SovietEntry: waypoint
Location: 46,83
Owner: Neutral
SovietRally: waypoint
Location: 47,82
Owner: Neutral
SouthwestSphereEntrance: waypoint
Location: 33,73
Owner: Neutral
waypoint57: waypoint
Location: 98,74
Owner: Neutral
waypoint63: waypoint
Location: 103,62
Owner: Neutral
EastSphereEntrance: waypoint
Location: 106,62
Owner: Neutral
waypoint65: waypoint
Location: 102,47
Owner: Neutral
EndingSphereRally: waypoint
Location: 99,53
Owner: Neutral
waypoint68: waypoint
Location: 33,86
Owner: Neutral
SoutheastSphereRally: waypoint
Location: 99,70
Owner: Neutral
EndingIntersection: waypoint
Location: 99,62
Owner: Neutral
EndingConsole: waypoint
Location: 99,47
Owner: Neutral
ControlWest: waypoint
Location: 68,73
Owner: Neutral
waypoint73: waypoint
Location: 96,47
Owner: Neutral
waypoint74: waypoint
Location: 70,73
Owner: Neutral
ControlSouth3: waypoint
Location: 80,79
Owner: Neutral
ControlSouth2: waypoint
Location: 78,79
Owner: Neutral
ControlSouth1: waypoint
Location: 76,79
Owner: Neutral
EscapeRally: waypoint
Location: 33,81
Owner: Neutral
EscapeEntry: waypoint
Location: 33,83
Owner: Neutral
EscapeGas2: waypoint
Location: 34,81
Owner: Neutral
EscapeGas1: waypoint
Location: 32,81
Owner: Neutral
waypoint85: waypoint
Location: 106,73
Owner: Neutral
NorthwestSphereEntrance: waypoint
Location: 43,53
Owner: Neutral
NorthwestSphereRally: waypoint
Location: 41,52
Owner: Neutral
NorthwestSphereReveal: waypoint
Location: 47,54
Owner: Neutral
waypoint92: waypoint
Location: 66,81
Owner: Neutral
DefaultCameraPosition: waypoint
Location: 41,79
Owner: Neutral
ShiftedSovietRally: waypoint
Location: 65,59
Owner: Neutral
CenterSphereConsole: waypoint
Owner: Neutral
Location: 67,63
ReinforcementConsole1: waypoint
Owner: Neutral
Location: 64,55
ReinforcementConsole2: waypoint
Owner: Neutral
Location: 70,55
SelfDestructConsole1: waypoint
Owner: Neutral
Location: 50,33
SelfDestructConsole2: waypoint
Owner: Neutral
Location: 51,33
StartConsole: waypoint
Owner: Neutral
Location: 41,72
NorthSphereConsole: waypoint
Owner: Neutral
Location: 83,46
SoutheastSphereEntrance: waypoint
Owner: Neutral
Location: 106,74
NorthSphereEntrance: waypoint
Owner: Neutral
Location: 80,48
PillboxSpawn: waypoint
Owner: Neutral
Location: 62,70
PillboxSpotter2: camera.tiny
Location: 62,74
Faction: england
Owner: GoodGuy
PillboxSpotter1: camera.tiny
Location: 62,66
Faction: england
Owner: GoodGuy
NorthSphereRally2: waypoint
Owner: Neutral
Location: 76,46
DamagedSphereProximity: waypoint
Owner: Neutral
Location: 53,57
SoutheastSphereProximity: waypoint
Owner: Neutral
Location: 99,67
EastHallProximity: waypoint
Owner: Neutral
Location: 76,60
EastHallProximity2: waypoint
Owner: Neutral
Location: 79,60
SouthHallProximity: waypoint
Owner: Neutral
Location: 62,77
CenterSphereRally: waypoint
Owner: Neutral
Location: 56,66
HiddenSphere: pdox
Owner: Neutral
Location: 30,33
ChronoDummyTarget: waypoint
Owner: Neutral
Location: 33,37
EscapeGuy: e1
SubCell: 5
Owner: Greece
Location: 32,81
Facing: 384
StartReveal: camera
Owner: USSR
Location: 46,72
ScriptTags: Start
Actor204: camera
Owner: Neutral
Location: 29,73
ScriptTags: Southwest
Actor205: camera
Owner: Neutral
Location: 31,81
ScriptTags: Southwest
Actor208: camera.small
Owner: Neutral
Location: 77,72
ScriptTags: Control
Actor209: camera
Owner: Neutral
Location: 81,79
ScriptTags: Control
Actor210: camera.small
Owner: Neutral
Location: 74,79
ScriptTags: Control
Actor211: camera.small
Owner: Neutral
Location: 73,71
ScriptTags: Control
Actor212: camera.small
Owner: Neutral
Location: 69,73
ScriptTags: Control
Actor213: camera.small
Owner: Neutral
Location: 83,62
ScriptTags: Gas
ChronoDummyEntry: waypoint
Owner: Neutral
Location: 30,37
NorthSphereReveal: camera
Owner: Neutral
Location: 82,47
NorthSphereRally: waypoint
Owner: Neutral
Location: 79,49
Rules: ra|rules/campaign-rules.yaml, ra|rules/campaign-tooltips.yaml, ra|rules/campaign-palettes.yaml, rules.yaml
Notifications: notifications.yaml
Weapons: weapons.yaml
Translations: ra|languages/lua/en.ftl, ra|languages/difficulties/en.ftl

View File

@@ -0,0 +1,924 @@
--[[
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.
]]
AlliedReinforcements =
{
start = { "e1", "e1", "e1" },
southHall = { "e1", "e1", "e1", "e1", "e1" },
northHall = { "e1", "e1", "e1" },
northEnding = { "e1", "e1", "e1", "e1", "e1", "e1", "e1", "e1" },
southEnding = { "e1", "e1", "e1", "e1", "medi", "medi" },
}
SovietReinforcements =
{
constant = { "e1", "e1", "e1" },
sphere = { "e1", "e1", "e1", "e1", "e1" },
selfDestructFlamers = { "e4", "e4", "e4", "e4" },
selfDestructRifles = { "e1", "e1", "e1", "e1" },
}
USSR = Player.GetPlayer("USSR")
Greece = Player.GetPlayer("Greece")
GoodGuy = Player.GetPlayer("GoodGuy")
England = Player.GetPlayer("England")
Neutral = Player.GetPlayer("Neutral")
ConsoleTouchDistance = WDist.New(512)
ShiftDelay = DateTime.Seconds(2)
AttackerShiftDelay = DateTime.Seconds(1)
GeneralType = "stavros"
GeneralTypeHard = "stavros.hard"
EscapeBlocked = false
SelfDestructStarted = false
EngineersKilled = false
EastHallEntered = false
CurrentGeneralSphere = StartSphere
WorldLoaded = function()
Camera.Position = DefaultCameraPosition.CenterPosition
if Difficulty == "hard" then
GeneralType = GeneralTypeHard
ShiftSouthEndingReinforcements()
SpawnPillbox()
Trigger.AfterDelay(DateTime.Minutes(1), function()
ShiftNorthReinforcements(DateTime.Minutes(1))
end)
end
Trigger.AfterDelay(5, GeneralStart)
SetObjectives()
CheckRequiredUnits()
InitialTriggers()
end
SetObjectives = function()
InitObjectives(USSR)
DefendStavros = AddPrimaryObjective(Greece, "")
KillStavros = AddPrimaryObjective(USSR, "kill-stavros")
SabotageFacility = AddPrimaryObjective(USSR, "sabotage-facility")
end
AlliedWin = function()
if AlliesHaveWon then
return
end
AlliesHaveWon = true
Media.PlaySpeechNotification(USSR, "ObjectiveNotMet")
Trigger.AfterDelay(DateTime.Seconds(1), function()
Greece.MarkCompletedObjective(DefendStavros)
end)
end
CheckRequiredUnits = function()
if not SovietsHaveWon and USSR.HasNoRequiredUnits() then
AlliedWin()
return
end
Trigger.AfterDelay(DateTime.Seconds(2), CheckRequiredUnits)
end
OnStartingEngineersKilled = function()
EngineersKilled = true
if SelfDestructStarted then
return
end
Media.PlaySoundNotification(USSR, "AlertBleep")
Media.DisplayMessage(UserInterface.Translate("all-engineers-killed"))
Trigger.AfterDelay(DateTime.Seconds(1), AlliedWin)
end
OnShiftedEngineerKilled = function()
if not SelfDestructStarted then
USSR.MarkFailedObjective(SabotageFacility)
end
end
OnStavrosKilled = function()
SovietsHaveWon = true
Media.PlaySpeechNotification(USSR, "ObjectiveMet")
Trigger.AfterDelay(DateTime.Seconds(1), function()
USSR.MarkCompletedObjective(KillStavros)
end)
end
-- Sphere movement functions.
EnterSphere = function(actor, sphere, onArrived)
actor = actor or GetGeneral()
-- Nil should only be an issue if self-destruct or escape gas triggers while Stavros shifts.
-- SelfDestructSequence, GeneralControlHiding, and GeneralSouthwest account for this.
if not actor then
return
end
CurrentGeneralSphere = sphere
actor.Infiltrate(sphere)
Trigger.OnInfiltrated(sphere, function()
Trigger.Clear(sphere, "OnInfiltrated")
Trigger.AfterDelay(ShiftDelay, function()
ChronoEffect(sphere)
end)
Trigger.AfterDelay(ShiftDelay * 2, onArrived)
end)
end
ReinforceAtSphere = function(sphere, owner, types, onArrived)
if sphere.IsDead then
return { }
end
local exit = sphere.Location + CVec.New(0, 1)
local troops = Reinforcements.Reinforce(owner, types, { exit }, 10, function(actor)
if onArrived then
onArrived(actor)
end
end)
return troops
end
ReinforceGeneralAtSphere = function(sphere, onArrived)
CurrentGeneralSphere = sphere
local stavros = ReinforceAtSphere(sphere, GoodGuy, { GeneralType }, onArrived)[1]
if sphere == ControlSphere then
-- It's still possible to barely hit him with flamethrower spread damage.
stavros.GrantCondition("invulnerability")
end
Trigger.OnKilled(stavros, OnStavrosKilled)
return stavros
end
--[[
These control Stavros' actions near each sphere.
Start -> Southwest -> Control -> Gas.
From there, different routes depending on the player's actions:
Gas -> Escape.
Gas -> Control (until self-destruct) -> Ending.
Gas -> Ending.
]]--
GeneralStart = function()
Trigger.AfterDelay(DateTime.Seconds(3), SpawnEscapeVehicle)
Trigger.AfterDelay(DateTime.Seconds(20), function()
HideCameras("Start")
end)
Media.PlaySpeechNotification(USSR, "StavrosCommander")
Stavros.Move(StartSphere.Location + CVec.New(0, 2))
EnterSphere(Stavros, StartSphere, GeneralSouthwest)
end
GeneralSouthwest = function()
ShowCameras("Southwest")
ReinforceGeneralAtSphere(SouthwestSphere, function(stavros)
stavros.Move(SouthwestSphereRally.Location)
stavros.CallFunc(function()
if EscapeBlocked then
GeneralSouthwestToControlAndGas()
end
ShiftStartReinforcements()
end)
end)
end
GeneralSouthwestToControlAndGas = function()
EnterSphere(GetGeneral(), SouthwestSphere, function()
ShowCameras("Control")
ReinforceGeneralAtSphere(ControlSphere, function(stavros)
stavros.Move(ControlNortheast.Location)
stavros.CallFunc(SpawnNorthwestGas)
if not EscapeBlocked then
stavros.CallFunc(SpawnStartGas)
end
stavros.Wait(DateTime.Seconds(3))
stavros.Move(ControlNorthwest.Location)
stavros.CallFunc(function()
Media.PlaySoundNotification(USSR, "ConsoleBeep")
ShiftCenterReinforcements()
Trigger.AfterDelay(DateTime.Seconds(6), GeneralControlToGas)
end)
end)
end)
end
GeneralControlToGas = function()
EnterSphere(GetGeneral(), ControlSphere, function()
HideCameras("Control")
ShowCameras("Gas")
ReinforceGeneralAtSphere(GasSphere, function(stavros)
if EastHallEntered then
GeneralGasToControl()
return
end
stavros.Move(GasSphereReveal.Location)
stavros.Move(GasSphereRally.Location)
stavros.CallFunc(function()
if EastHallEntered then
GeneralGasToControl()
end
end)
end)
end)
end
GeneralGasToControl = function()
EnterSphere(GetGeneral(), GasSphere, GeneralControlHiding)
end
GeneralControlHiding = function()
HideCameras("Gas")
ShowCameras("Control")
ReinforceGeneralAtSphere(ControlSphere, function(stavros)
stavros.Move(ControlWest.Location)
stavros.CallFunc(function()
if not SelfDestructStarted then
return
end
GeneralControlToEnding()
end)
end)
end
GeneralGasToEscape = function()
EnterSphere(GetGeneral(), GasSphere, GeneralEscape)
end
GeneralEscape = function()
HideCameras("Gas")
ReinforceGeneralAtSphere(SouthwestSphere, function(stavros)
local carrier = GoodGuy.GetActorsByType("apc")[1]
Trigger.AfterDelay(DateTime.Seconds(1), function()
EscapeGuy.EnterTransport(carrier)
end)
stavros.CallFunc(function()
Media.PlaySoundNotification(USSR, "AlertBleep")
Camera.Position = EscapeRally.CenterPosition
end)
stavros.Move(SouthwestSphereRally.Location)
stavros.Move(EscapeGas1.Location)
stavros.CallFunc(function()
Media.PlaySpeechNotification(USSR, "StavrosMoveOut")
end)
stavros.EnterTransport(carrier)
end)
end
GeneralGasToEnding = function()
Trigger.AfterDelay(DateTime.Seconds(2), function()
HideCameras("Gas")
end)
local stavros = GetGeneral()
stavros.Move(EastGas2.Location)
stavros.AttackMove(EndingIntersection.Location)
stavros.AttackMove(EndingConsole.Location)
end
GeneralControlToEnding = function()
EnterSphere(GetGeneral(), ControlSphere, function()
HideCameras("Control")
SpawnPlayerCamera(EndingSphereLeft.Location, nil, 0, "camera.small")
ReinforceGeneralAtSphere(EndingSphereLeft, function(stavros)
stavros.AttackMove(EndingConsole.Location)
end)
end)
end
GeneralEnding = function()
ShiftNorthEndingReinforcements()
Media.PlaySoundNotification(USSR, "ConsoleBeep")
local stavros = GetGeneral()
SpawnPlayerCamera(stavros.Location)
stavros.Wait(DateTime.Seconds(1))
stavros.AttackMove(EndingConsole.Location + CVec.New(0, 1))
stavros.Stance = "AttackAnything"
end
-- Reinforcements.
InsertSovietReinforcements = function(team, entry, rally, delay)
Trigger.AfterDelay(delay or 0, function()
Reinforcements.Reinforce(USSR, SovietReinforcements[team], { entry, rally } )
end)
if team ~= "constant" then
return
end
Media.PlaySpeechNotification(USSR, "ReinforcementsArrived")
Trigger.AfterDelay(DateTime.Minutes(4), function()
InsertSovietReinforcements(team, entry, rally)
end)
end
ShiftSovietReinforcements = function()
if SovietReinforcementsShifted or CenterSphere.IsDead then
return
end
SovietReinforcementsShifted = true
Media.PlaySoundNotification(USSR, "ConsoleBeep")
ChronoEffect()
Trigger.AfterDelay(AttackerShiftDelay, function()
ReinforceAtSphere(CenterSphere, USSR, SovietReinforcements.sphere, function(actor)
actor.AttackMove(ShiftedSovietRally.Location)
end)
SpawnPlayerCamera(CenterSphere.Location, DateTime.Seconds(2), 0, "camera.small")
end)
end
ShiftCenterReinforcements = function()
SpawnPlayerCamera(CenterSphere.Location, nil, 0, "camera.small")
ChronoEffect()
Trigger.AfterDelay(AttackerShiftDelay, function()
local southHallRifles = ReinforceAtSphere(CenterSphere, Greece, AlliedReinforcements.southHall)
GroupHuntFromRally(southHallRifles, CenterSphereRally.Location, SovietEntry.Location)
end)
end
ShiftNorthReinforcements = function(interval)
if NorthSphere.IsDead then
return
end
SpawnPlayerCamera(NorthSphereReveal.Location, nil, 0, "camera.small")
ChronoEffect(NorthSphere)
Trigger.AfterDelay(AttackerShiftDelay, function()
local northRifles = ReinforceAtSphere(NorthSphere, Greece, AlliedReinforcements.northHall)
GroupHuntFromRally(northRifles, NorthSphereRally.Location)
end)
Trigger.AfterDelay(interval, function()
ShiftNorthReinforcements(interval)
end)
end
ShiftStartReinforcements = function()
ChronoEffect()
Trigger.AfterDelay(AttackerShiftDelay, function()
local startRifles = ReinforceAtSphere(StartSphere, Greece, AlliedReinforcements.start)
GroupHuntFromRally(startRifles, StartSphereRally.Location)
end)
end
ShiftNorthEndingReinforcements = function()
ChronoEffect()
Trigger.AfterDelay(AttackerShiftDelay, function()
local norts = ReinforceAtSphere(EndingSphereRight, Greece, AlliedReinforcements.northEnding, function(actor)
actor.AddTag("Ending Group")
actor.AttackMove(EndingSphereRally.Location)
end)
PrepareEndingTeam(norts)
end)
Trigger.AfterDelay(AttackerShiftDelay + DateTime.Seconds(4), function()
DestroyBuilding(EndingSphereRight, nil, 0, "hidden")
end)
end
ShiftSouthEndingReinforcements = function()
local southers = ReinforceAtSphere(SoutheastSphere, Greece, AlliedReinforcements.southEnding, function(actor)
actor.AddTag("Ending Group")
actor.Move(SoutheastSphereRally.Location)
if actor.Type == "medi" then
actor.Move(SoutheastSphereRally.Location + CVec.New(0, 1))
end
end)
PrepareEndingTeam(southers)
end
-- Supporting actors.
SpawnPlayerCamera = function(location, duration, delay, cameraType)
duration = duration or DateTime.Seconds(6)
cameraType = cameraType or "camera"
Trigger.AfterDelay(delay or 0, function()
local camera = Actor.Create(cameraType, true, { Owner = USSR, Location = location } )
if duration < 0 then
return
end
Trigger.AfterDelay(duration, camera.Destroy)
end)
end
SetCameraGroupOwner = function(tag, owner)
local cameras = Map.ActorsWithTag(tag)
Utils.Do(cameras, function(camera)
camera.Owner = owner
end)
end
ShowCameras = function(tag)
SetCameraGroupOwner(tag, USSR)
end
HideCameras = function(tag)
SetCameraGroupOwner(tag, Neutral)
end
SpawnGas = function(waypoint, delay, sound)
Trigger.AfterDelay(delay or 0, function()
Actor.Create("flare", true, { Owner = England, Location = waypoint.Location } )
end)
if sound then
Media.PlaySoundNotification(USSR, sound)
end
end
SpawnEastGas = function()
SpawnGas(EastGas1, 15, "GasHiss")
SpawnGas(EastGas2)
end
SpawnNorthwestGas = function()
SpawnPlayerCamera(SelfDestructReveal.Location, DateTime.Seconds(20))
SpawnGas(NorthwestGas1, 15, "GasHiss")
SpawnGas(NorthwestGas2)
end
SpawnStartGas = function()
SpawnGas(StartConsole)
end
SpawnEscapeGas = function()
EscapeBlocked = true
SpawnGas(EscapeGas1, 0, "GasHiss")
SpawnGas(EscapeGas2, 15)
EscapeGuy.Scatter()
if IsStavrosIdle() and CurrentGeneralSphere == SouthwestSphere then
GeneralSouthwestToControlAndGas()
end
end
SpawnEscapeVehicle = function()
local vehiclePath = { EscapeEntry.Location, EscapeRally.Location }
Reinforcements.Reinforce(GoodGuy, { "apc" }, vehiclePath, 0, function(vehicle)
Trigger.OnKilled(EscapeGuy, function()
ExitEscapeVehicle(vehicle)
end)
Trigger.OnPassengerEntered(vehicle, function(_, passenger)
if not IsStavros(passenger) then
return
end
ExitEscapeVehicle(vehicle, "stavros")
end)
end)
end
ExitEscapeVehicle = function(vehicle, stavros)
vehicle.Move(EscapeEntry.Location)
vehicle.CallFunc(function()
if stavros then
AlliedWin()
end
Trigger.AfterDelay(DateTime.Seconds(2), function()
HideCameras("Southwest")
end)
end)
vehicle.Destroy()
end
-- Hard's spy behavior and pillboxes.
SpawnSpy = function(sphere)
sphere = sphere or StartSphere
if Difficulty ~= "hard" or sphere.IsDead then
return
end
ChronoEffect()
Trigger.AfterDelay(ShiftDelay, function()
local spy = ReinforceAtSphere(sphere, Greece, { "spy" } )[1]
Trigger.OnAddedToWorld(spy, function()
spy.DisguiseAsType("e1", USSR)
end)
Trigger.OnIdle(spy, function()
SpyIdle(spy)
end)
end)
end
SpyIdle = function(spy)
if SelfDestructStarted then
SpyEscape(spy)
return
end
local targets = Map.ActorsInCircle(spy.CenterPosition, WDist.FromCells(3), function(nearby)
return nearby.Type == "e6"
end)
if targets and #targets > 0 then
SpyAttack(spy, targets[1])
return
end
SpySearch(spy)
end
SpyAttack = function(spy, target)
spy.AttackMove(target.Location)
spy.CallFunc(function()
if EngineersKilled and not SelfDestructStarted then
SpyPostMortem(spy)
end
end)
spy.Wait(DateTime.Seconds(1))
spy.CallFunc(function()
spy.DisguiseAsType(target.Type, target.Owner)
end)
spy.Wait(DateTime.Seconds(1))
end
SpySearch = function(spy)
local targets = Utils.Where(USSR.GetActorsByType("e6"), function(actor)
return not actor.HasTag("shifted")
end)
if targets and #targets > 0 then
local goal = Utils.Random(targets)
spy.Move(goal.Location, 2)
return
end
SpyEscape(spy)
end
SpyEscape = function(spy)
spy.Move(SovietRally.Location, 1)
spy.Move(SovietEntry.Location)
spy.Destroy()
end
-- Avoid the spy killing both engineers, ending the mission, and being left in fog.
SpyPostMortem = function(spy)
Media.PlaySpeechNotification(USSR, "SpyCommander")
SpawnPlayerCamera(spy.Location, -1, 0, "camera.small")
spy.Stop()
spy.Wait(DateTime.Minutes(1))
end
SpawnPillbox = function()
Actor.Create("pbox", true, { Owner = GoodGuy, Location = PillboxSpawn.Location } )
CreateProximityOneShot(SouthHallProximity, WDist.FromCells(3), IsSoviet, function()
SpawnPlayerCamera(PillboxSpawn.Location, nil, 0 ,"camera.tiny")
end)
end
-- Group activities.
IsGroupIdle = function(actors)
return Utils.All(actors, function(actor)
return actor.IsIdle
end)
end
GroupHunt = function(actors, goal, delay)
Utils.Do(actors, function(actor)
if actor.IsDead then
return
end
Trigger.Clear(actor, "OnIdle")
actor.Wait(delay)
actor.AttackMove(goal or actor.Location, 1)
actor.Hunt()
end)
end
GroupHuntFromRally = function(actors, rally, goal, delay)
if not actors or #actors < 1 then
return
end
delay = delay or 10
Utils.Do(actors, function(actor)
Trigger.OnIdle(actor, function()
if actor.Location == rally then
if IsGroupIdle(actors) then
GroupHunt(actors, goal, delay)
end
else
actor.AttackMove(rally)
end
end)
end)
end
PrepareEndingTeam = function(actors)
OnAnyDamaged(actors, function()
local defenders = Map.ActorsWithTag("Ending Group")
local path = { EndingIntersection.Location, EndingSphereRally.Location }
Utils.Do(defenders, function(actor)
if actor.IsDead then
return
end
Trigger.ClearAll(actor)
actor.Patrol(path, true, DateTime.Seconds(1))
end)
end)
end
-- Starting trigger setups.
CreateProximityOneShot = function(waypoint, range, filter, func)
Trigger.OnEnteredProximityTrigger(waypoint.CenterPosition, range, function(actor, id)
if not filter(actor) then
return
end
Trigger.RemoveProximityTrigger(id)
func(actor)
func = function()
print("Duplicate event at " .. tostring(waypoint) .. " skipped.")
end
end)
end
InitialTriggers = function()
Trigger.OnAllKilled(USSR.GetActorsByType("e6"), OnStartingEngineersKilled)
Trigger.AfterDelay(DateTime.Minutes(4), function()
InsertSovietReinforcements("constant", SovietEntry.Location, SovietRally.Location)
end)
Trigger.OnKilled(NorthSphere, function()
SpawnPlayerCamera(NorthSphereReveal.Location, nil, 0, "camera.small")
end)
PrepareConsoles()
PrepareOtherProximities()
PrepareDamagedChronosphere()
end
PrepareConsole = function(waypoint, filter, func)
CreateProximityOneShot(waypoint, ConsoleTouchDistance, filter, func)
end
PrepareConsoles = function()
PrepareConsole(CenterSphereConsole, IsSovietHuman, function()
DestroyBuilding(CenterSphere, "ConsoleBeep", 10)
end)
PrepareConsole(NorthSphereConsole, IsSovietHuman, function()
DestroyBuilding(NorthSphere, "ConsoleBeep", 10, "hidden")
end)
PrepareConsole(StartConsole, IsSovietHuman, SpawnEscapeGas)
PrepareConsole(ReinforcementConsole1, IsSovietHuman, ShiftSovietReinforcements)
PrepareConsole(ReinforcementConsole2, IsSovietHuman, ShiftSovietReinforcements)
PrepareConsole(SelfDestructConsole1, IsSovietHuman, BeginSelfDestruct)
PrepareConsole(SelfDestructConsole2, IsSovietHuman, BeginSelfDestruct)
PrepareConsole(EndingConsole, IsStavros, GeneralEnding)
end
PrepareOtherProximities= function()
CreateProximityOneShot(DamagedSphereProximity, WDist.FromCells(3), IsSoviet, function()
SpawnPlayerCamera(DamagedSphere.Location)
end)
CreateProximityOneShot(SoutheastSphereProximity, WDist.FromCells(3), IsSoviet, function()
SpawnPlayerCamera(SoutheastSphereRally.Location)
end)
CreateProximityOneShot(SouthHallProximity, WDist.FromCells(2), IsSoviet, function()
if not EscapeBlocked and CurrentGeneralSphere == SouthwestSphere then
GeneralSouthwestToControlAndGas()
end
Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(60, 91)), SpawnSpy)
end)
CreateProximityOneShot(EastHallProximity, WDist.FromCells(2), IsSoviet, function()
EastHallEntered = true
Trigger.AfterDelay(DateTime.Seconds(3), SpawnEastGas)
local stavros = GetGeneral()
if not (IsStavrosIdle(stavros) and stavros.Location == GasSphereRally.Location) then
return
end
if SelfDestructStarted then
GeneralGasToEnding()
return
end
GeneralGasToControl()
end)
end
PrepareDamagedChronosphere = function()
Trigger.OnCapture(DamagedSphere, function(sphere)
Trigger.AfterDelay(ShiftDelay, function()
if sphere.IsInWorld then
ChronoEffect(sphere)
end
end)
Trigger.AfterDelay(ShiftDelay * 2, function()
ReinforceAtSphere(NorthwestSphere, USSR, { "e6" }, function(newEngineer)
Trigger.OnKilled(newEngineer, OnShiftedEngineerKilled)
newEngineer.AddTag("shifted")
newEngineer.CallFunc(function()
SpawnPlayerCamera(NorthwestSphere.Location)
end)
newEngineer.Move(NorthwestSphereRally.Location)
end)
end)
Trigger.AfterDelay(ShiftDelay * 3, function()
if sphere.IsInWorld then
ChronoEffect(sphere)
DestroyBuilding(sphere, nil, DateTime.Seconds(1))
end
end)
end)
end
-- Filters, fetchers, and such.
IsSoviet = function(actor)
return actor.Owner == USSR
end
IsSovietHuman = function(actor)
return actor.Owner == USSR and actor.Type ~= "dog"
end
IsStavros = function(actor)
return actor.Type == GeneralType
end
IsStavrosIdle = function(stavros)
stavros = stavros or GetGeneral()
return stavros and stavros.IsIdle
end
IsEscapePossible = function()
return not EscapeBlocked and CurrentGeneralSphere == GasSphere
end
GetGeneral = function()
local generals = GoodGuy.GetActorsByType(GeneralType)
if generals and #generals > 0 then
return generals[1]
end
end
-- Self-destruct and building effects.
BeginSelfDestruct = function()
if SelfDestructStarted then
return
end
SelfDestructStarted = true
USSR.MarkCompletedObjective(SabotageFacility)
Media.PlaySoundNotification(USSR, "ConsoleBuzz")
Trigger.AfterDelay(DateTime.Seconds(1), function()
SelfDestructAlarm()
if IsEscapePossible() then
GeneralGasToEscape()
end
if IsStavrosIdle() and CurrentGeneralSphere == ControlSphere then
GeneralControlToEnding()
end
end)
Trigger.AfterDelay(DateTime.Seconds(2), SelfDestructSequence)
end
SelfDestructSequence = function()
DestroyBuilding(NorthwestPower)
DestroyBuilding(SoutheastPower)
local pillboxes = GoodGuy.GetActorsByType("pbox")
Utils.Do(pillboxes, function(pillbox)
DestroyBuilding(pillbox)
end)
Trigger.AfterDelay(DateTime.Seconds(3), function()
if IsEscapePossible() then
return
end
Media.PlaySpeechNotification(USSR, "ReinforcementsArrived")
InsertSovietReinforcements("selfDestructFlamers", FlamerEntry.Location, FlamerRally.Location)
InsertSovietReinforcements("selfDestructRifles", SovietEntry.Location, SovietRally.Location, DateTime.Seconds(1))
end)
Trigger.AfterDelay(DateTime.Seconds(9), function()
DestroyBuilding(NortheastPower)
DestroyBuilding(SouthwestPower)
end)
Trigger.AfterDelay(DateTime.Seconds(15), function()
DestroyBuilding(CenterSphere)
DestroyBuilding(NorthSphere, nil, nil, "hidden")
end)
Trigger.AfterDelay(DateTime.Seconds(21), function()
DestroyBuilding(NorthwestSphere)
DestroyBuilding(GasSphere)
DestroyBuilding(EndingSphereLeft)
DestroyBuilding(EastSphere)
DestroyBuilding(SoutheastSphere)
DestroyBuilding(ControlSphere)
end)
end
SelfDestructAlarm = function()
Media.PlaySoundNotification(USSR, "AlertBuzzer")
Trigger.AfterDelay(DateTime.Seconds(6), SelfDestructAlarm)
end
DestroyBuilding = function(actor, sound, delay, hidden)
if actor.IsDead then
return
end
delay = delay or Utils.RandomInteger(0, DateTime.Seconds(1))
Trigger.AfterDelay(delay, function()
if actor.IsDead then
return
end
actor.Kill()
if not hidden then
SpawnPlayerCamera(actor.Location, nil, nil, "camera.small")
end
end)
if sound then
Media.PlaySoundNotification(USSR, sound)
end
end
ChronoEffect = function(sphere)
Media.PlaySoundNotification(USSR, "Chronoshift")
if not sphere then
return
end
local units = { }
local target = ChronoDummyTarget.Location
local dummy = Reinforcements.Reinforce(Neutral, { "1tnk" }, { ChronoDummyEntry.Location } )[1]
units[dummy] = target
sphere.Chronoshift(units, 0)
Trigger.AfterDelay(1, dummy.Destroy)
end

View File

@@ -0,0 +1,12 @@
Sounds:
Notifications:
ConsoleBeep: rabeep1
ConsoleBuzz: buzzy1
GasHiss: hydrod1
Chronoshift: chrono2
Speech:
Notifications:
SpyCommander: scomnd1
StavrosMoveOut: stavmov
StavrosCommander: stavcmdr

View File

@@ -0,0 +1,142 @@
World:
LuaScript:
Scripts: campaign.lua, utils.lua, mousetrap.lua
MissionData:
Briefing: A longtime thorn in our side, the Greek commander Stavros, has finally been cornered. He has taken refuge in an underground bunker full of his Chronosphere technology. Prove to him that no Allied tricks can stop the wrath of the Soviet Union. Track him down, and eliminate him.\n\nReturn with results -- we do not want to hear of his escape... only the creative manner of his demise.\n\nWe have provided you with engineers that, given the opportunity, can use Chronosphere technology. Do not squander them.
BackgroundVideo: sovexp1.vqa
WinVideo: sovexp1w.vqa
LossVideo: apcescpe.vqa
ScriptLobbyDropdown@difficulty:
ID: difficulty
Label: dropdown-difficulty.label
Description: dropdown-difficulty.description
Values:
normal: options-difficulty.normal
hard: options-difficulty.hard
Default: normal
# Stavros' opening line makes this feel redundant.
-StartGameNotification:
# Give our Chrono dummy the ability to move (and be shifted) within the void.
Locomotor@TRACKED:
TerrainSpeeds:
ClearNoSmudges: 100
^Palettes:
-ChronoshiftPaletteEffect:
# Used in ChronoEffect.
1TNK:
Chronoshiftable:
ChronoshiftSound:
^Soldier:
ScriptTags:
Inherits@IronCurtain: ^IronCurtainable
ExternalCondition@GAS:
Condition: gassed
TotalCap: 1
DamagedByTerrain:
RequiresCondition: gassed
Damage: 300
DamageInterval: 1
DamageTypes: ExplosionDeath
Terrain: Clear
FLARE:
ProximityExternalCondition@GAS:
Condition: gassed
Range: 1c512
ValidRelationships: Neutral, Enemy
RevealsShroud:
Range: 1c512
ValidRelationships: Ally, Neutral, Enemy
Tooltip:
Name: Gas
IRONCRATE:
Inherits: ^Crate
GrantExternalConditionCrateAction:
SelectionShares: 1
Sequence: invuln
Sound: ironcur9.aud
Condition: invulnerability
Duration: 600
Range: 2c512
RenderSprites:
Image: wcrate
CAMERA:
ScriptTags:
CAMERA.tiny:
Inherits: CAMERA
RevealsShroud:
Range: 2c0
CAMERA.small:
Inherits: CAMERA
RevealsShroud:
Range: 4c0
PBOX:
# Reduced vision to avoid shooting beyond the hallway.
RevealsShroudMultiplier:
Modifier: 50
PDOX:
DamageMultiplier:
Modifier: 0
Power:
Amount: 0
# Couldn't avoid engineers falsely reporting they could capture chronospheres under fog. Made a new type.
PDOX.capturable:
Inherits: PDOX
RenderSprites:
Image: PDOX
Capturable:
Types: predamaged
-ChronoshiftPower@chronoshift:
-SpawnActorsOnSell:
E6:
Captures:
CaptureTypes: predamaged
STAVROS:
Inherits: GNRL
Inherits@IronCurtain: ^IronCurtainable
-WithColoredOverlay@IRONCURTAIN:
RenderSprites:
Image: GNRL
Tooltip:
Name: Stavros
Infiltrates:
Types: SpyInfiltrate
Voice: Move
ValidRelationships: Ally, Neutral
SpeedMultiplier:
# Original is 8 speed v. E1's 4 speed.
Modifier: 200
Valued:
Cost: 2000
STAVROS.hard:
Inherits: STAVROS
RenderSprites:
Image: GNRL
Armament:
Weapon: Colt45
AutoTarget:
InitialStanceAI: ReturnFire
RevealsShroud:
Range: 4c0
STAVROS.start:
Inherits: STAVROS
RenderSprites:
Image: GNRL
-Targetable:
BARB:
-Tooltip:

View File

@@ -0,0 +1,11 @@
Colt45:
ReloadDelay: 21
Range: 4c0
Warhead@1Dam: SpreadDamage
Warhead@2Eff: CreateEffect
M1Carbine:
Range: 4c0
Flamer:
Range: 4c0