Compare commits
33 Commits
devtest-20
...
playtest-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
00ddf82e85 | ||
|
|
c10ebb455b | ||
|
|
d999a0534b | ||
|
|
02454fb764 | ||
|
|
df81857abe | ||
|
|
ae0745b542 | ||
|
|
89b5e34320 | ||
|
|
47cc6eda7e | ||
|
|
6da23ed3d7 | ||
|
|
3ee4613a98 | ||
|
|
616bfbe553 | ||
|
|
ecbcc9c8bb | ||
|
|
068ce9b215 | ||
|
|
170bcd500c | ||
|
|
6efb40c9a6 | ||
|
|
3c92c2d789 | ||
|
|
f823d20a86 | ||
|
|
ca4b97cd03 | ||
|
|
8b5e322891 | ||
|
|
70e1c4bb0c | ||
|
|
8690ad4e19 | ||
|
|
a01233c3df | ||
|
|
d0d55b3fc1 | ||
|
|
2a26a07ce6 | ||
|
|
65e088204f | ||
|
|
77e38ceea9 | ||
|
|
989d1475b9 | ||
|
|
580a96cda4 | ||
|
|
5a8964aabe | ||
|
|
c9dcf305c9 | ||
|
|
5489d6909c | ||
|
|
85412a6d98 | ||
|
|
b69806123a |
@@ -19,6 +19,11 @@ namespace OpenRA.Graphics
|
||||
[Flags]
|
||||
public enum ScrollDirection { None = 0, Up = 1, Left = 2, Down = 4, Right = 8 }
|
||||
|
||||
public interface INotifyViewportZoomExtentsChanged
|
||||
{
|
||||
void ViewportZoomExtentsChanged(float minZoom, float maxZoom);
|
||||
}
|
||||
|
||||
public static class ViewportExts
|
||||
{
|
||||
public static bool Includes(this ScrollDirection d, ScrollDirection s)
|
||||
@@ -237,6 +242,9 @@ namespace OpenRA.Graphics
|
||||
Zoom = minZoom;
|
||||
else
|
||||
Zoom = Zoom.Clamp(minZoom, maxZoom);
|
||||
|
||||
foreach (var t in worldRenderer.World.WorldActor.TraitsImplementing<INotifyViewportZoomExtentsChanged>())
|
||||
t.ViewportZoomExtentsChanged(minZoom, maxZoom);
|
||||
}
|
||||
|
||||
public CPos ViewToWorld(int2 view)
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace OpenRA.Orders
|
||||
public virtual bool InputOverridesSelection(World world, int2 xy, MouseInput mi)
|
||||
{
|
||||
var actor = world.ScreenMap.ActorsAtMouse(xy)
|
||||
.Where(a => !a.Actor.IsDead)
|
||||
.Where(a => !a.Actor.IsDead && a.Actor.Info.HasTraitInfo<SelectableInfo>() && (a.Actor.Owner.IsAlliedWith(world.RenderPlayer) || !world.FogObscures(a.Actor)))
|
||||
.WithHighestSelectionPriority(xy, mi.Modifiers);
|
||||
|
||||
if (actor == null)
|
||||
|
||||
@@ -228,7 +228,8 @@ namespace OpenRA
|
||||
public int MouseScrollDeadzone = 8;
|
||||
|
||||
public bool UseClassicMouseStyle = false;
|
||||
public bool ClassicMouseMiddleScroll = false;
|
||||
public bool UseAlternateScrollButton = false;
|
||||
|
||||
public StatusBarsType StatusBars = StatusBarsType.Standard;
|
||||
public TargetLinesType TargetLines = TargetLinesType.Manual;
|
||||
public bool UsePlayerStanceColors = false;
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace OpenRA.Mods.Cnc.Activities
|
||||
{
|
||||
var positionable = (IPositionable)movement;
|
||||
minefield.RemoveAll(c => self.World.ActorMap.GetActorsAt(c)
|
||||
.Any(a => a.Info.Name == minelayer.Info.Mine.ToLowerInvariant()) ||
|
||||
.Any(a => a.Info.Name == minelayer.Info.Mine.ToLowerInvariant() && a.CanBeViewedByPlayer(self.Owner)) ||
|
||||
(!positionable.CanEnterCell(c, null, BlockedByActor.Immovable) && !self.World.FogObscures(c)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,15 +25,11 @@ namespace OpenRA.Mods.Cnc
|
||||
Sprite[] border;
|
||||
float2 nodPos, gdiPos, evaPos;
|
||||
Rectangle bounds;
|
||||
|
||||
SpriteFont loadingFont, versionFont;
|
||||
string loadingText, versionText;
|
||||
float2 loadingPos, versionPos;
|
||||
string versionText;
|
||||
|
||||
Sheet lastSheet;
|
||||
int lastDensity;
|
||||
Size lastResolution;
|
||||
IReadOnlyDictionary<string, SpriteFont> lastFonts;
|
||||
|
||||
public override void Init(ModData modData, Dictionary<string, string> info)
|
||||
{
|
||||
@@ -82,20 +78,6 @@ namespace OpenRA.Mods.Cnc
|
||||
|
||||
var barY = bounds.Height - 78;
|
||||
|
||||
// The fonts dictionary may change when switching between the mod and content installer
|
||||
if (r.Fonts != lastFonts)
|
||||
{
|
||||
lastFonts = r.Fonts;
|
||||
|
||||
loadingFont = lastFonts["BigBold"];
|
||||
loadingText = Info["Text"];
|
||||
loadingPos = new float2((bounds.Width - loadingFont.Measure(loadingText).X) / 2, barY);
|
||||
|
||||
versionFont = lastFonts["Regular"];
|
||||
var versionSize = versionFont.Measure(versionText);
|
||||
versionPos = new float2(bounds.Width - 107 - versionSize.X / 2, 115 - versionSize.Y / 2);
|
||||
}
|
||||
|
||||
loadTick = ++loadTick % 8;
|
||||
|
||||
r.RgbaSpriteRenderer.DrawSprite(gdiLogo, gdiPos);
|
||||
@@ -104,11 +86,18 @@ namespace OpenRA.Mods.Cnc
|
||||
|
||||
WidgetUtils.DrawPanel(bounds, border);
|
||||
|
||||
if (loadingFont != null)
|
||||
if (r.Fonts != null)
|
||||
{
|
||||
var loadingFont = r.Fonts["BigBold"];
|
||||
var loadingText = Info["Text"];
|
||||
var loadingPos = new float2((bounds.Width - loadingFont.Measure(loadingText).X) / 2, barY);
|
||||
loadingFont.DrawText(loadingText, loadingPos, Color.Gray);
|
||||
|
||||
if (versionFont != null)
|
||||
var versionFont = r.Fonts["Regular"];
|
||||
var versionSize = versionFont.Measure(versionText);
|
||||
var versionPos = new float2(bounds.Width - 107 - versionSize.X / 2, 115 - versionSize.Y / 2);
|
||||
versionFont.DrawTextWithContrast(versionText, versionPos, Color.White, Color.Black, 2);
|
||||
}
|
||||
|
||||
for (var i = 0; i <= 8; i++)
|
||||
{
|
||||
|
||||
@@ -305,7 +305,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
var newCell = path[path.Count - 1];
|
||||
path.RemoveAt(path.Count - 1);
|
||||
|
||||
return Pair.New(newCell, mobile.GetAvailableSubCell(nextCell, SubCell.Any, ignoreActor));
|
||||
return Pair.New(newCell, mobile.GetAvailableSubCell(nextCell, mobile.FromSubCell, ignoreActor));
|
||||
}
|
||||
else if (mobile.IsBlocking)
|
||||
{
|
||||
@@ -316,7 +316,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
if ((nextCell - newCell).Value.LengthSquared > 2)
|
||||
path.Add(mobile.ToCell);
|
||||
|
||||
return Pair.New(newCell.Value, mobile.GetAvailableSubCell(newCell.Value, SubCell.Any, ignoreActor));
|
||||
return Pair.New(newCell.Value, mobile.GetAvailableSubCell(newCell.Value, mobile.FromSubCell, ignoreActor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
hasWaited = false;
|
||||
path.RemoveAt(path.Count - 1);
|
||||
|
||||
return Pair.New(nextCell, mobile.GetAvailableSubCell(nextCell, SubCell.Any, ignoreActor));
|
||||
return Pair.New(nextCell, mobile.GetAvailableSubCell(nextCell, mobile.FromSubCell, ignoreActor));
|
||||
}
|
||||
|
||||
protected override void OnLastRun(Actor self)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
@@ -119,15 +120,23 @@ namespace OpenRA.Mods.Common.Activities
|
||||
return TickChild(self);
|
||||
}
|
||||
|
||||
List<CPos> searchCells = new List<CPos>();
|
||||
int searchCellsTick = -1;
|
||||
|
||||
List<CPos> CalculatePathToTarget(Actor self, BlockedByActor check)
|
||||
{
|
||||
var targetCells = CandidateMovementCells(self);
|
||||
var searchCells = new List<CPos>();
|
||||
var loc = self.Location;
|
||||
|
||||
foreach (var cell in targetCells)
|
||||
if (domainIndex.IsPassable(loc, cell, Mobile.Info.LocomotorInfo) && Mobile.CanEnterCell(cell))
|
||||
searchCells.Add(cell);
|
||||
// PERF: Assume that CandidateMovementCells doesn't change within a tick to avoid repeated queries
|
||||
// when Move enumerates different BlockedByActor values
|
||||
if (searchCellsTick != self.World.WorldTick)
|
||||
{
|
||||
searchCells.Clear();
|
||||
searchCellsTick = self.World.WorldTick;
|
||||
foreach (var cell in CandidateMovementCells(self))
|
||||
if (domainIndex.IsPassable(loc, cell, Mobile.Info.LocomotorInfo) && Mobile.CanEnterCell(cell))
|
||||
searchCells.Add(cell);
|
||||
}
|
||||
|
||||
if (!searchCells.Any())
|
||||
return NoPath;
|
||||
|
||||
@@ -62,16 +62,18 @@ namespace OpenRA.Mods.Common.Effects
|
||||
world.ScreenMap.Add(this, pos, anim.Image);
|
||||
initialized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
anim.Tick();
|
||||
|
||||
anim.Tick();
|
||||
|
||||
pos = posFunc();
|
||||
world.ScreenMap.Update(this, pos, anim.Image);
|
||||
pos = posFunc();
|
||||
world.ScreenMap.Update(this, pos, anim.Image);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IRenderable> Render(WorldRenderer wr)
|
||||
{
|
||||
if (!visibleThroughFog && world.FogObscures(pos))
|
||||
if (!initialized || (!visibleThroughFog && world.FogObscures(pos)))
|
||||
return SpriteRenderable.None;
|
||||
|
||||
return anim.Render(pos, wr.Palette(palette));
|
||||
|
||||
@@ -66,18 +66,17 @@ namespace OpenRA.Mods.Common.Graphics
|
||||
public IFinalizedRenderable PrepareRender(WorldRenderer wr) { return this; }
|
||||
public void Render(WorldRenderer wr)
|
||||
{
|
||||
var wcr = Game.Renderer.WorldRgbaColorRenderer;
|
||||
var center = wr.Screen3DPosition(centerPosition);
|
||||
var cr = Game.Renderer.RgbaColorRenderer;
|
||||
var center = wr.Viewport.WorldToViewPx(wr.Screen3DPosition(centerPosition));
|
||||
|
||||
for (var i = 0; i < trailCount; i++)
|
||||
{
|
||||
var angle = trailAngle - new WAngle(i * (trailSeparation.Angle <= 512 ? 1 : -1));
|
||||
var length = radius.Length * new WVec(angle.Cos(), angle.Sin(), 0) / 1024;
|
||||
var end = wr.Screen3DPosition(centerPosition + length);
|
||||
var end = wr.Viewport.WorldToViewPx(wr.Screen3DPosition(centerPosition + length));
|
||||
var alpha = color.A - i * color.A / trailCount;
|
||||
|
||||
wcr.DrawLine(center, end, 3, Color.FromArgb(alpha, contrastColor));
|
||||
wcr.DrawLine(center, end, 1, Color.FromArgb(alpha, color));
|
||||
cr.DrawLine(center, end, 3, Color.FromArgb(alpha, contrastColor));
|
||||
cr.DrawLine(center, end, 1, Color.FromArgb(alpha, color));
|
||||
}
|
||||
|
||||
RangeCircleAnnotationRenderable.DrawRangeCircle(wr, centerPosition, radius, 1, color, 3, contrastColor);
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
if (reservedForAircraft.GetActorBelow() == self)
|
||||
{
|
||||
if (rallyPoint != null)
|
||||
if (rallyPoint != null && rallyPoint.Path.Count > 0)
|
||||
foreach (var cell in rallyPoint.Path)
|
||||
reservedFor.QueueActivity(reservedForAircraft.MoveTo(cell, 1, targetLineColor: Color.Green));
|
||||
else
|
||||
|
||||
@@ -35,9 +35,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
ConditionManager conditionManager;
|
||||
int conditionToken = ConditionManager.InvalidConditionToken;
|
||||
|
||||
string cachedTerrain;
|
||||
CPos cachedLocation;
|
||||
|
||||
public GrantConditionOnTerrain(ActorInitializer init, GrantConditionOnTerrainInfo info)
|
||||
{
|
||||
@@ -53,9 +51,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
void ITick.Tick(Actor self)
|
||||
{
|
||||
var loc = self.Location;
|
||||
if (conditionManager == null || loc == cachedLocation)
|
||||
if (conditionManager == null)
|
||||
return;
|
||||
|
||||
// The terrain type may change between ticks without the actor moving
|
||||
var currentTerrain = loc.Layer == 0 ? self.World.Map.GetTerrainInfo(loc).Type :
|
||||
tileSet[self.World.GetCustomMovementLayers()[loc.Layer].GetTerrainIndex(loc)].Type;
|
||||
|
||||
@@ -69,7 +68,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
|
||||
cachedTerrain = currentTerrain;
|
||||
cachedLocation = loc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public SubCell FreeSubCell(CPos cell, SubCell preferredSubCell = SubCell.Any, bool checkTransient = true)
|
||||
{
|
||||
if (preferredSubCell > SubCell.Any && !AnyActorsAt(cell, preferredSubCell, checkTransient))
|
||||
if (preferredSubCell != SubCell.Any && !AnyActorsAt(cell, preferredSubCell, checkTransient))
|
||||
return preferredSubCell;
|
||||
|
||||
if (!AnyActorsAt(cell))
|
||||
@@ -291,7 +291,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public SubCell FreeSubCell(CPos cell, SubCell preferredSubCell, Func<Actor, bool> checkIfBlocker)
|
||||
{
|
||||
if (preferredSubCell > SubCell.Any && !AnyActorsAt(cell, preferredSubCell, checkIfBlocker))
|
||||
if (preferredSubCell != SubCell.Any && !AnyActorsAt(cell, preferredSubCell, checkIfBlocker))
|
||||
return preferredSubCell;
|
||||
|
||||
if (!AnyActorsAt(cell))
|
||||
|
||||
@@ -133,12 +133,13 @@ namespace OpenRA.Mods.Common.Traits
|
||||
if (!preview.Bounds.IsEmpty)
|
||||
screenMap.Add(preview, preview.Bounds);
|
||||
|
||||
foreach (var kv in preview.Footprint)
|
||||
AddPreviewLocation(preview, kv.Key);
|
||||
|
||||
// Fallback to the actor's CenterPosition for the ActorMap if it has no Footprint
|
||||
if (!preview.Footprint.Any())
|
||||
AddPreviewLocation(preview, worldRenderer.World.Map.CellContaining(preview.CenterPosition));
|
||||
var footprint = preview.Footprint.Select(kv => kv.Key).ToArray();
|
||||
if (!footprint.Any())
|
||||
footprint = new[] { worldRenderer.World.Map.CellContaining(preview.CenterPosition) };
|
||||
|
||||
foreach (var cell in footprint)
|
||||
AddPreviewLocation(preview, cell);
|
||||
|
||||
if (!initialSetup)
|
||||
{
|
||||
@@ -154,16 +155,21 @@ namespace OpenRA.Mods.Common.Traits
|
||||
previews.Remove(preview);
|
||||
screenMap.Remove(preview);
|
||||
|
||||
foreach (var kv in preview.Footprint)
|
||||
// Fallback to the actor's CenterPosition for the ActorMap if it has no Footprint
|
||||
var footprint = preview.Footprint.Select(kv => kv.Key).ToArray();
|
||||
if (!footprint.Any())
|
||||
footprint = new[] { worldRenderer.World.Map.CellContaining(preview.CenterPosition) };
|
||||
|
||||
foreach (var cell in footprint)
|
||||
{
|
||||
List<EditorActorPreview> list;
|
||||
if (!cellMap.TryGetValue(kv.Key, out list))
|
||||
if (!cellMap.TryGetValue(cell, out list))
|
||||
continue;
|
||||
|
||||
list.Remove(preview);
|
||||
|
||||
if (!list.Any())
|
||||
cellMap.Remove(kv.Key);
|
||||
cellMap.Remove(cell);
|
||||
}
|
||||
|
||||
UpdateNeighbours(preview.Footprint);
|
||||
|
||||
@@ -304,7 +304,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
var otherActors = subCell == SubCell.FullCell ? world.ActorMap.GetActorsAt(cell) : world.ActorMap.GetActorsAt(cell, subCell);
|
||||
foreach (var otherActor in otherActors)
|
||||
if (IsBlockedBy(actor, otherActor, ignoreActor, check, cellFlag))
|
||||
if (IsBlockedBy(actor, otherActor, ignoreActor, cell, check, cellFlag))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -322,7 +322,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
if (check > BlockedByActor.None)
|
||||
{
|
||||
Func<Actor, bool> checkTransient = otherActor => IsBlockedBy(self, otherActor, ignoreActor, check, GetCache(cell).CellFlag);
|
||||
Func<Actor, bool> checkTransient = otherActor => IsBlockedBy(self, otherActor, ignoreActor, cell, check, GetCache(cell).CellFlag);
|
||||
|
||||
if (!sharesCell)
|
||||
return world.ActorMap.AnyActorsAt(cell, SubCell.FullCell, checkTransient) ? SubCell.Invalid : SubCell.FullCell;
|
||||
@@ -336,14 +336,14 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return world.ActorMap.FreeSubCell(cell, preferredSubCell);
|
||||
}
|
||||
|
||||
bool IsBlockedBy(Actor self, Actor otherActor, Actor ignoreActor, BlockedByActor check, CellFlag cellFlag)
|
||||
bool IsBlockedBy(Actor actor, Actor otherActor, Actor ignoreActor, CPos cell, BlockedByActor check, CellFlag cellFlag)
|
||||
{
|
||||
if (otherActor == ignoreActor)
|
||||
return false;
|
||||
|
||||
// If the check allows: We are not blocked by units that we can force to move out of the way.
|
||||
if (check <= BlockedByActor.Immovable && cellFlag.HasCellFlag(CellFlag.HasMovableActor) &&
|
||||
self.Owner.Stances[otherActor.Owner] == Stance.Ally)
|
||||
actor.Owner.Stances[otherActor.Owner] == Stance.Ally)
|
||||
{
|
||||
var mobile = otherActor.TraitOrDefault<Mobile>();
|
||||
if (mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.IsImmovable)
|
||||
@@ -352,14 +352,22 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
// If the check allows: we are not blocked by moving units.
|
||||
if (check <= BlockedByActor.Stationary && cellFlag.HasCellFlag(CellFlag.HasMovingActor) &&
|
||||
IsMoving(self, otherActor))
|
||||
IsMoving(actor, otherActor))
|
||||
return false;
|
||||
|
||||
if (cellFlag.HasCellFlag(CellFlag.HasTemporaryBlocker))
|
||||
{
|
||||
// If there is a temporary blocker in our path, but we can remove it, we are not blocked.
|
||||
var temporaryBlocker = otherActor.TraitOrDefault<ITemporaryBlocker>();
|
||||
if (temporaryBlocker != null && temporaryBlocker.CanRemoveBlockage(otherActor, self))
|
||||
if (temporaryBlocker != null && temporaryBlocker.CanRemoveBlockage(otherActor, actor))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cellFlag.HasCellFlag(CellFlag.HasTransitOnlyActor))
|
||||
{
|
||||
// Transit only tiles should not block movement
|
||||
var building = otherActor.TraitOrDefault<Building>();
|
||||
if (building != null && building.TransitOnlyCells().Contains(cell))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -371,7 +379,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
// PERF: Avoid LINQ.
|
||||
var crushables = otherActor.TraitsImplementing<ICrushable>();
|
||||
foreach (var crushable in crushables)
|
||||
if (crushable.CrushableBy(otherActor, self, Info.Crushes))
|
||||
if (crushable.CrushableBy(otherActor, actor, Info.Crushes))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Support;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
@@ -70,245 +71,178 @@ namespace OpenRA.Mods.Common.Traits
|
||||
public object Create(ActorInitializer init) { return new WeatherOverlay(init.World, this); }
|
||||
}
|
||||
|
||||
public class WeatherOverlay : ITick, IRenderAboveWorld
|
||||
public class WeatherOverlay : ITick, IRenderAboveWorld, INotifyViewportZoomExtentsChanged
|
||||
{
|
||||
readonly WeatherOverlayInfo info;
|
||||
readonly World world;
|
||||
struct Particle
|
||||
{
|
||||
public float PosX;
|
||||
public float PosY;
|
||||
public int Size;
|
||||
public float DirectionScatterX;
|
||||
public float Gravity;
|
||||
public float SwingOffset;
|
||||
public float SwingSpeed;
|
||||
public int SwingDirection;
|
||||
public float SwingAmplitude;
|
||||
public Color Color;
|
||||
public Color TailColor;
|
||||
public readonly float2 Pos;
|
||||
public readonly int Size;
|
||||
public readonly float DirectionScatterX;
|
||||
public readonly float Gravity;
|
||||
public readonly float SwingOffset;
|
||||
public readonly float SwingSpeed;
|
||||
public readonly int SwingDirection;
|
||||
public readonly float SwingAmplitude;
|
||||
public readonly Color Color;
|
||||
public readonly Color TailColor;
|
||||
|
||||
public Particle(WeatherOverlayInfo info, MersenneTwister r, Rectangle viewport)
|
||||
{
|
||||
var x = r.Next(viewport.Left, viewport.Right);
|
||||
var y = r.Next(viewport.Top, viewport.Bottom);
|
||||
|
||||
Pos = new int2(x, y);
|
||||
Size = r.Next(info.ParticleSize[0], info.ParticleSize[1] + 1);
|
||||
DirectionScatterX = info.ScatterDirection[0] + r.Next(info.ScatterDirection[1] - info.ScatterDirection[0]);
|
||||
Gravity = float2.Lerp(info.Gravity[0], info.Gravity[1], r.NextFloat());
|
||||
SwingOffset = float2.Lerp(info.SwingOffset[0], info.SwingOffset[1], r.NextFloat());
|
||||
SwingSpeed = float2.Lerp(info.SwingSpeed[0], info.SwingSpeed[1], r.NextFloat());
|
||||
SwingDirection = r.Next(2) == 0 ? 1 : -1;
|
||||
SwingAmplitude = float2.Lerp(info.SwingAmplitude[0], info.SwingAmplitude[1], r.NextFloat());
|
||||
Color = info.ParticleColors.Random(r);
|
||||
TailColor = Color.FromArgb(info.LineTailAlphaValue, Color.R, Color.G, Color.B);
|
||||
}
|
||||
|
||||
Particle(Particle source)
|
||||
{
|
||||
Pos = source.Pos;
|
||||
Size = source.Size;
|
||||
DirectionScatterX = source.DirectionScatterX;
|
||||
Gravity = source.Gravity;
|
||||
SwingOffset = source.SwingOffset;
|
||||
SwingSpeed = source.SwingSpeed;
|
||||
SwingDirection = source.SwingDirection;
|
||||
SwingAmplitude = source.SwingAmplitude;
|
||||
Color = source.Color;
|
||||
TailColor = source.TailColor;
|
||||
}
|
||||
|
||||
public Particle(Particle source, float2 pos)
|
||||
: this(source)
|
||||
{
|
||||
Pos = pos;
|
||||
}
|
||||
|
||||
public Particle(Particle source, float2 pos, int swingDirection, float swingOffset)
|
||||
: this(source)
|
||||
{
|
||||
Pos = pos;
|
||||
SwingDirection = swingDirection;
|
||||
SwingOffset = swingOffset;
|
||||
}
|
||||
}
|
||||
|
||||
readonly List<Particle> particleList = new List<Particle>();
|
||||
readonly int maxParticleCount;
|
||||
readonly WeatherOverlayInfo info;
|
||||
readonly World world;
|
||||
|
||||
enum ParticleCountFaderType { Hold, FadeIn, FadeOut }
|
||||
ParticleCountFaderType particleCountFader = ParticleCountFaderType.FadeIn;
|
||||
|
||||
float targetWindXOffset = 0f;
|
||||
float currentWindXOffset = 0f;
|
||||
int currentWindIndex = 0;
|
||||
long windTickCountdown = 1500;
|
||||
float2 antiScrollPrevTopLeft;
|
||||
float windStrength;
|
||||
int targetWindStrengthIndex;
|
||||
long windUpdateCountdown;
|
||||
Particle[] particles;
|
||||
Size viewportSize;
|
||||
|
||||
public WeatherOverlay(World world, WeatherOverlayInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
this.world = world;
|
||||
currentWindIndex = info.WindLevels.Length / 2;
|
||||
targetWindXOffset = info.WindLevels[0];
|
||||
maxParticleCount = CalculateParticleCount(Game.Renderer.Resolution.Width, Game.Renderer.Resolution.Height);
|
||||
targetWindStrengthIndex = info.ChangingWindLevel ? world.LocalRandom.Next(info.WindLevels.Length) : 0;
|
||||
windUpdateCountdown = world.LocalRandom.Next(info.WindTick[0], info.WindTick[1]);
|
||||
windStrength = info.WindLevels[targetWindStrengthIndex];
|
||||
}
|
||||
|
||||
int CalculateParticleCount(int x, int y)
|
||||
void INotifyViewportZoomExtentsChanged.ViewportZoomExtentsChanged(float minZoom, float maxZoom)
|
||||
{
|
||||
return (int)(x * y * info.ParticleDensityFactor / 10000);
|
||||
}
|
||||
// Track particles in a viewport fixed to the minimum zoom level
|
||||
var s = (1f / minZoom * new float2(Game.Renderer.NativeResolution)).ToInt2();
|
||||
viewportSize = new Size(s.X, s.Y);
|
||||
|
||||
void SpawnParticles(int count, int rangeY, int spawnChancePercent)
|
||||
{
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
if (Game.CosmeticRandom.Next(100) < spawnChancePercent)
|
||||
{
|
||||
var tempColor = info.ParticleColors.Random(Game.CosmeticRandom);
|
||||
var tempColorTail = Color.FromArgb(info.LineTailAlphaValue, tempColor.R, tempColor.G, tempColor.B);
|
||||
var tempSwingDirection = Game.CosmeticRandom.Next(2) == 0 ? 1 : -1;
|
||||
|
||||
particleList.Add(
|
||||
new Particle
|
||||
{
|
||||
PosX = Game.CosmeticRandom.Next(Game.Renderer.Resolution.Width),
|
||||
PosY = Game.CosmeticRandom.Next(rangeY),
|
||||
Size = Game.CosmeticRandom.Next(info.ParticleSize[0], info.ParticleSize[1] + 1),
|
||||
DirectionScatterX = info.ScatterDirection[0] + Game.CosmeticRandom.Next(info.ScatterDirection[1] - info.ScatterDirection[0]),
|
||||
Gravity = float2.Lerp(info.Gravity[0], info.Gravity[1], Game.CosmeticRandom.NextFloat()),
|
||||
SwingOffset = float2.Lerp(info.SwingOffset[0], info.SwingOffset[1], Game.CosmeticRandom.NextFloat()),
|
||||
SwingSpeed = float2.Lerp(info.SwingSpeed[0], info.SwingSpeed[1], Game.CosmeticRandom.NextFloat()),
|
||||
SwingDirection = tempSwingDirection,
|
||||
SwingAmplitude = float2.Lerp(info.SwingAmplitude[0], info.SwingAmplitude[1], Game.CosmeticRandom.NextFloat()),
|
||||
Color = tempColor,
|
||||
TailColor = tempColorTail
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParticlesCountLogic(WorldRenderer wr)
|
||||
{
|
||||
// Logic to switch between the states of the particleCountFader
|
||||
if (particleCountFader == ParticleCountFaderType.Hold && particleList.Count < maxParticleCount)
|
||||
particleCountFader = ParticleCountFaderType.FadeIn;
|
||||
else if (particleCountFader == ParticleCountFaderType.FadeIn && particleList.Count >= maxParticleCount)
|
||||
particleCountFader = ParticleCountFaderType.Hold;
|
||||
else if (particleCountFader == ParticleCountFaderType.FadeOut && particleList.Count == 0)
|
||||
particleCountFader = ParticleCountFaderType.Hold;
|
||||
|
||||
// Do the fade functions
|
||||
if (particleCountFader == ParticleCountFaderType.FadeIn)
|
||||
FadeInParticleCount(wr);
|
||||
else if (particleCountFader == ParticleCountFaderType.FadeOut)
|
||||
FadeOutParticleCount(wr);
|
||||
}
|
||||
|
||||
void FadeInParticleCount(WorldRenderer wr)
|
||||
{
|
||||
SpawnParticles(1, 0, 100);
|
||||
|
||||
// Remove Particles, which are getting replaced from the top to the bottom by the "EdgeCheckReplace",
|
||||
// when scrolling down, as long as the FadeIn is not completed,
|
||||
// to avoid having particles at the top and bottom, but not in the middle of the screen.
|
||||
for (var i = 0; i < particleList.Count; i++)
|
||||
if (particleList[i].PosY < 0)
|
||||
particleList.RemoveAt(i);
|
||||
|
||||
// Add Particles when the weather is fading in and scrolling up, to fill areas above
|
||||
if (antiScrollPrevTopLeft.Y > wr.Viewport.TopLeft.Y)
|
||||
{
|
||||
// Get delta Y and limit to the max value
|
||||
var tempRangeY = antiScrollPrevTopLeft.Y - wr.Viewport.TopLeft.Y;
|
||||
var tempParticleCount = CalculateParticleCount(Game.Renderer.Resolution.Width, (int)tempRangeY);
|
||||
if (particleList.Count + tempParticleCount > maxParticleCount)
|
||||
tempParticleCount = maxParticleCount - particleList.Count;
|
||||
|
||||
SpawnParticles(tempParticleCount, (int)tempRangeY, 50);
|
||||
}
|
||||
}
|
||||
|
||||
void FadeOutParticleCount(WorldRenderer wr)
|
||||
{
|
||||
for (var i = 0; i < particleList.Count; i++)
|
||||
if (particleList[i].PosY > (Game.Renderer.Resolution.Height - particleList[i].Gravity))
|
||||
particleList.RemoveAt(i);
|
||||
}
|
||||
|
||||
void XAxisSwing(ref Particle tempParticle)
|
||||
{
|
||||
// Direction turn
|
||||
if (tempParticle.SwingOffset < -tempParticle.SwingAmplitude || tempParticle.SwingOffset > tempParticle.SwingAmplitude)
|
||||
tempParticle.SwingDirection *= -1;
|
||||
|
||||
// Perform the X-Axis-Swing
|
||||
tempParticle.SwingOffset += tempParticle.SwingDirection * tempParticle.SwingSpeed;
|
||||
// Randomly distribute particles within the initial viewport
|
||||
var particleCount = viewportSize.Width * viewportSize.Height * info.ParticleDensityFactor / 10000;
|
||||
particles = new Particle[particleCount];
|
||||
var rect = new Rectangle(int2.Zero, viewportSize);
|
||||
for (var i = 0; i < particles.Length; i++)
|
||||
particles[i] = new Particle(info, world.LocalRandom, rect);
|
||||
}
|
||||
|
||||
void ITick.Tick(Actor self)
|
||||
{
|
||||
windTickCountdown--;
|
||||
}
|
||||
if (!info.ChangingWindLevel || info.WindLevels.Length == 1)
|
||||
return;
|
||||
|
||||
void WindLogic(ref Particle tempParticle)
|
||||
{
|
||||
if (!info.ChangingWindLevel)
|
||||
targetWindXOffset = info.WindLevels[0];
|
||||
else if (windTickCountdown <= 0)
|
||||
if (--windUpdateCountdown <= 0)
|
||||
{
|
||||
windTickCountdown = Game.CosmeticRandom.Next(info.WindTick[0], info.WindTick[1]);
|
||||
if (Game.CosmeticRandom.Next(2) == 1 && currentWindIndex > 0)
|
||||
{
|
||||
currentWindIndex--;
|
||||
targetWindXOffset = info.WindLevels[currentWindIndex];
|
||||
}
|
||||
else if (currentWindIndex < info.WindLevels.Length - 1)
|
||||
{
|
||||
currentWindIndex++;
|
||||
targetWindXOffset = info.WindLevels[currentWindIndex];
|
||||
}
|
||||
windUpdateCountdown = self.World.LocalRandom.Next(info.WindTick[0], info.WindTick[1]);
|
||||
if (targetWindStrengthIndex > 0 && self.World.LocalRandom.Next(2) == 1)
|
||||
targetWindStrengthIndex--;
|
||||
else if (targetWindStrengthIndex < info.WindLevels.Length - 1)
|
||||
targetWindStrengthIndex++;
|
||||
}
|
||||
|
||||
// Fading the wind in little steps towards the TargetWindOffset
|
||||
var targetWindLevel = info.WindLevels[targetWindStrengthIndex];
|
||||
if (info.InstantWindChanges)
|
||||
currentWindXOffset = targetWindXOffset;
|
||||
else if (currentWindXOffset != targetWindXOffset)
|
||||
windStrength = targetWindLevel;
|
||||
else if (Math.Abs(windStrength - targetWindLevel) > 0.01f)
|
||||
{
|
||||
if (currentWindXOffset > targetWindXOffset)
|
||||
currentWindXOffset -= 0.00001f;
|
||||
else if (currentWindXOffset < targetWindXOffset)
|
||||
currentWindXOffset += 0.00001f;
|
||||
}
|
||||
}
|
||||
|
||||
void Movement(ref Particle tempParticle)
|
||||
{
|
||||
tempParticle.PosX += tempParticle.DirectionScatterX + tempParticle.SwingOffset + currentWindXOffset;
|
||||
tempParticle.PosY += tempParticle.Gravity;
|
||||
}
|
||||
|
||||
// AntiScroll keeps the particles in place when scrolling the viewport
|
||||
void AntiScroll(ref Particle tempParticle, WorldRenderer wr)
|
||||
{
|
||||
tempParticle.PosX += antiScrollPrevTopLeft.X - wr.Viewport.TopLeft.X;
|
||||
tempParticle.PosY += antiScrollPrevTopLeft.Y - wr.Viewport.TopLeft.Y;
|
||||
}
|
||||
|
||||
void EdgeCheckReplace(ref Particle tempParticle, WorldRenderer wr)
|
||||
{
|
||||
tempParticle.PosX %= Game.Renderer.Resolution.Width;
|
||||
if (tempParticle.PosX < 0)
|
||||
tempParticle.PosX += Game.Renderer.Resolution.Width;
|
||||
|
||||
tempParticle.PosY %= Game.Renderer.Resolution.Height;
|
||||
if (tempParticle.PosY < 0 && particleCountFader != ParticleCountFaderType.FadeIn)
|
||||
tempParticle.PosY += Game.Renderer.Resolution.Height;
|
||||
}
|
||||
|
||||
void UpdateWeatherOverlay(WorldRenderer wr)
|
||||
{
|
||||
if (!world.Paused)
|
||||
ParticlesCountLogic(wr);
|
||||
|
||||
for (var i = 0; i < particleList.Count; i++)
|
||||
{
|
||||
Particle tempParticle = particleList[i];
|
||||
|
||||
if (!world.Paused)
|
||||
{
|
||||
XAxisSwing(ref tempParticle);
|
||||
WindLogic(ref tempParticle);
|
||||
Movement(ref tempParticle);
|
||||
}
|
||||
|
||||
AntiScroll(ref tempParticle, wr);
|
||||
EdgeCheckReplace(ref tempParticle, wr);
|
||||
|
||||
particleList[i] = tempParticle;
|
||||
}
|
||||
|
||||
antiScrollPrevTopLeft = wr.Viewport.TopLeft;
|
||||
}
|
||||
|
||||
void DrawWeatherOverlay(WorldRenderer wr)
|
||||
{
|
||||
var topLeft = wr.Viewport.TopLeft;
|
||||
foreach (var item in particleList)
|
||||
{
|
||||
var tempPos = new float2(item.PosX + topLeft.X, item.PosY + topLeft.Y);
|
||||
|
||||
if (info.UseSquares)
|
||||
Game.Renderer.WorldRgbaColorRenderer.FillRect(tempPos, tempPos + new float2(item.Size, item.Size), item.Color);
|
||||
else
|
||||
{
|
||||
var tempPosTail = new float2(topLeft.X + item.PosX - currentWindXOffset, item.PosY - (item.Gravity * 2 / 3) + topLeft.Y);
|
||||
Game.Renderer.WorldRgbaColorRenderer.DrawLine(tempPos, tempPosTail, item.Size, item.TailColor);
|
||||
}
|
||||
if (windStrength > targetWindLevel)
|
||||
windStrength -= 0.01f;
|
||||
else if (windStrength < targetWindLevel)
|
||||
windStrength += 0.01f;
|
||||
}
|
||||
}
|
||||
|
||||
void IRenderAboveWorld.RenderAboveWorld(Actor self, WorldRenderer wr)
|
||||
{
|
||||
UpdateWeatherOverlay(wr);
|
||||
var center = wr.Viewport.CenterLocation;
|
||||
var viewport = new Rectangle(center - new int2(viewportSize) / 2, viewportSize);
|
||||
var wcr = Game.Renderer.WorldRgbaColorRenderer;
|
||||
|
||||
DrawWeatherOverlay(wr);
|
||||
for (var i = 0; i < particles.Length; i++)
|
||||
{
|
||||
// Simulate wind and gravity effects on the particle
|
||||
var p = particles[i];
|
||||
if (!world.Paused)
|
||||
{
|
||||
var swingDirection = p.SwingDirection;
|
||||
if (p.SwingOffset < -p.SwingAmplitude || p.SwingOffset > p.SwingAmplitude)
|
||||
swingDirection *= -1;
|
||||
|
||||
var swingOffset = p.SwingOffset + p.SwingDirection * p.SwingSpeed;
|
||||
var pos = p.Pos + new float2(p.DirectionScatterX + p.SwingOffset + windStrength, p.Gravity);
|
||||
particles[i] = p = new Particle(p, pos, swingDirection, swingOffset);
|
||||
}
|
||||
|
||||
// Move the particle back inside the viewport if necessary
|
||||
if (!viewport.Contains(p.Pos.ToInt2()))
|
||||
{
|
||||
var dx = (p.Pos.X - viewport.Left) % viewport.Width;
|
||||
var dy = (p.Pos.Y - viewport.Top) % viewport.Height;
|
||||
|
||||
if (dx < 0)
|
||||
dx += viewport.Width;
|
||||
|
||||
if (dy < 0)
|
||||
dy += viewport.Height;
|
||||
|
||||
particles[i] = p = new Particle(p, new float2(viewport.Left + dx, viewport.Top + dy));
|
||||
}
|
||||
|
||||
// Render the particle
|
||||
// We must provide a z coordinate to stop the GL near and far Z limits from culling the geometry
|
||||
var a = new float3(p.Pos.X, p.Pos.Y, p.Pos.Y);
|
||||
if (info.UseSquares)
|
||||
{
|
||||
var b = a + new float2(p.Size, p.Size);
|
||||
wcr.FillRect(a, b, p.Color);
|
||||
}
|
||||
else
|
||||
{
|
||||
var tail = p.Pos + new float2(-windStrength, -p.Gravity * 2 / 3);
|
||||
|
||||
var b = new float3(tail.X, tail.Y, tail.Y);
|
||||
wcr.DrawLine(a, b, p.Size, p.TailColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,12 +77,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
var mouseControlDescClassic = widget.Get("MOUSE_CONTROL_DESC_CLASSIC");
|
||||
mouseControlDescClassic.IsVisible = () => gs.UseClassicMouseStyle;
|
||||
|
||||
var classicScrollRight = mouseControlDescClassic.Get("DESC_SCROLL_RIGHT");
|
||||
classicScrollRight.IsVisible = () => !gs.ClassicMouseMiddleScroll;
|
||||
|
||||
var classicScrollMiddle = mouseControlDescClassic.Get("DESC_SCROLL_MIDDLE");
|
||||
classicScrollMiddle.IsVisible = () => gs.ClassicMouseMiddleScroll;
|
||||
|
||||
var mouseControlDescModern = widget.Get("MOUSE_CONTROL_DESC_MODERN");
|
||||
mouseControlDescModern.IsVisible = () => !gs.UseClassicMouseStyle;
|
||||
|
||||
@@ -92,6 +86,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
foreach (var container in new[] { mouseControlDescClassic, mouseControlDescModern })
|
||||
{
|
||||
var classicScrollRight = container.Get("DESC_SCROLL_RIGHT");
|
||||
classicScrollRight.IsVisible = () => gs.UseClassicMouseStyle ^ gs.UseAlternateScrollButton;
|
||||
|
||||
var classicScrollMiddle = container.Get("DESC_SCROLL_MIDDLE");
|
||||
classicScrollMiddle.IsVisible = () => !gs.UseClassicMouseStyle ^ gs.UseAlternateScrollButton;
|
||||
|
||||
var zoomDesc = container.Get("DESC_ZOOM");
|
||||
zoomDesc.IsVisible = () => gs.ZoomModifier == Modifiers.None;
|
||||
|
||||
|
||||
@@ -505,7 +505,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
var gs = Game.Settings.Game;
|
||||
|
||||
BindCheckboxPref(panel, "CLASSIC_MOUSE_MIDDLE_SCROLL_CHECKBOX", gs, "ClassicMouseMiddleScroll");
|
||||
BindCheckboxPref(panel, "ALTERNATE_SCROLL_CHECKBOX", gs, "UseAlternateScrollButton");
|
||||
BindCheckboxPref(panel, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll");
|
||||
BindCheckboxPref(panel, "LOCKMOUSE_CHECKBOX", gs, "LockMouseWindow");
|
||||
BindSliderPref(panel, "ZOOMSPEED_SLIDER", gs, "ZoomSpeed");
|
||||
@@ -520,23 +520,20 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
mouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(mouseScrollDropdown, gs);
|
||||
mouseScrollDropdown.GetText = () => gs.MouseScroll.ToString();
|
||||
|
||||
var classicMouseMiddleScrollCheckbox = panel.Get<CheckboxWidget>("CLASSIC_MOUSE_MIDDLE_SCROLL_CHECKBOX");
|
||||
classicMouseMiddleScrollCheckbox.IsVisible = () => gs.UseClassicMouseStyle;
|
||||
|
||||
var mouseControlDescClassic = panel.Get("MOUSE_CONTROL_DESC_CLASSIC");
|
||||
mouseControlDescClassic.IsVisible = () => gs.UseClassicMouseStyle;
|
||||
|
||||
var classicScrollRight = mouseControlDescClassic.Get("DESC_SCROLL_RIGHT");
|
||||
classicScrollRight.IsVisible = () => !gs.ClassicMouseMiddleScroll;
|
||||
|
||||
var classicScrollMiddle = mouseControlDescClassic.Get("DESC_SCROLL_MIDDLE");
|
||||
classicScrollMiddle.IsVisible = () => gs.ClassicMouseMiddleScroll;
|
||||
|
||||
var mouseControlDescModern = panel.Get("MOUSE_CONTROL_DESC_MODERN");
|
||||
mouseControlDescModern.IsVisible = () => !gs.UseClassicMouseStyle;
|
||||
|
||||
foreach (var container in new[] { mouseControlDescClassic, mouseControlDescModern })
|
||||
{
|
||||
var classicScrollRight = container.Get("DESC_SCROLL_RIGHT");
|
||||
classicScrollRight.IsVisible = () => gs.UseClassicMouseStyle ^ gs.UseAlternateScrollButton;
|
||||
|
||||
var classicScrollMiddle = container.Get("DESC_SCROLL_MIDDLE");
|
||||
classicScrollMiddle.IsVisible = () => !gs.UseClassicMouseStyle ^ gs.UseAlternateScrollButton;
|
||||
|
||||
var zoomDesc = container.Get("DESC_ZOOM");
|
||||
zoomDesc.IsVisible = () => gs.ZoomModifier == Modifiers.None;
|
||||
|
||||
@@ -635,7 +632,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
gs.UseClassicMouseStyle = dgs.UseClassicMouseStyle;
|
||||
gs.MouseScroll = dgs.MouseScroll;
|
||||
gs.ClassicMouseMiddleScroll = dgs.ClassicMouseMiddleScroll;
|
||||
gs.UseAlternateScrollButton = dgs.UseAlternateScrollButton;
|
||||
gs.LockMouseWindow = dgs.LockMouseWindow;
|
||||
gs.ViewportEdgeScroll = dgs.ViewportEdgeScroll;
|
||||
gs.ViewportEdgeScrollStep = dgs.ViewportEdgeScrollStep;
|
||||
|
||||
@@ -146,13 +146,16 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
UpdateSmoothScrolling();
|
||||
|
||||
var rb = RenderBounds;
|
||||
|
||||
var scrollbarHeight = rb.Height - 2 * ScrollbarWidth;
|
||||
|
||||
var thumbHeight = ContentHeight == 0 ? 0 : Math.Max(MinimumThumbSize, (int)(scrollbarHeight * Math.Min(rb.Height * 1f / ContentHeight, 1f)));
|
||||
var thumbOrigin = rb.Y + ScrollbarWidth + (int)((scrollbarHeight - thumbHeight) * (-1f * currentListOffset / (ContentHeight - rb.Height)));
|
||||
if (thumbHeight == scrollbarHeight)
|
||||
thumbHeight = 0;
|
||||
// Scroll thumb is only visible if the content does not fit within the panel bounds
|
||||
var thumbHeight = 0;
|
||||
var thumbOrigin = rb.Y + ScrollbarWidth;
|
||||
if (ContentHeight > rb.Height)
|
||||
{
|
||||
thumbHeight = Math.Max(MinimumThumbSize, scrollbarHeight * rb.Height / ContentHeight);
|
||||
thumbOrigin += (int)((scrollbarHeight - thumbHeight) * currentListOffset / (rb.Height - ContentHeight));
|
||||
}
|
||||
|
||||
switch (ScrollBar)
|
||||
{
|
||||
|
||||
@@ -318,7 +318,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
}
|
||||
|
||||
var gs = Game.Settings.Game;
|
||||
var scrollButton = gs.UseClassicMouseStyle && !gs.ClassicMouseMiddleScroll ? MouseButton.Right : MouseButton.Middle;
|
||||
var scrollButton = gs.UseClassicMouseStyle ^ gs.UseAlternateScrollButton ? MouseButton.Right : MouseButton.Middle;
|
||||
var scrollType = mi.Button.HasFlag(scrollButton) ? gs.MouseScroll : MouseScrollType.Disabled;
|
||||
|
||||
if (scrollType == MouseScrollType.Disabled)
|
||||
|
||||
@@ -124,19 +124,13 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
{
|
||||
if (useClassicMouseStyle && HasMouseFocus)
|
||||
{
|
||||
if (!IsValidDragbox && World.Selection.Actors.Any() && !multiClick)
|
||||
if (!IsValidDragbox && World.Selection.Actors.Any() && !multiClick && uog.InputOverridesSelection(World, mousePos, mi))
|
||||
{
|
||||
var selectableActor = World.ScreenMap.ActorsAtMouse(mousePos).Select(a => a.Actor).Any(x =>
|
||||
x.Info.HasTraitInfo<SelectableInfo>() && (x.Owner.IsAlliedWith(World.RenderPlayer) || !World.FogObscures(x)));
|
||||
|
||||
if (!selectableActor || uog.InputOverridesSelection(World, mousePos, mi))
|
||||
{
|
||||
// Order units instead of selecting
|
||||
ApplyOrders(World, mi);
|
||||
isDragging = false;
|
||||
YieldMouseFocus(mi);
|
||||
return true;
|
||||
}
|
||||
// Order units instead of selecting
|
||||
ApplyOrders(World, mi);
|
||||
isDragging = false;
|
||||
YieldMouseFocus(mi);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
158
OpenRA.sln
@@ -17,165 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenRA.Platforms.Default",
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenRA.Mods.Common", "OpenRA.Mods.Common\OpenRA.Mods.Common.csproj", "{FE6C8CC0-2F07-442A-B29F-17617B3B7FC6}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tiberian Dawn Lua scripts", "Tiberian Dawn Lua scripts", "{62FCD0D0-6D24-435D-9DD8-3CCADCF7ECAB}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
mods\cnc\maps\cnc64gdi01\cnc64gdi01.lua = mods\cnc\maps\cnc64gdi01\cnc64gdi01.lua
|
||||
mods\cnc\maps\gdi01\gdi01.lua = mods\cnc\maps\gdi01\gdi01.lua
|
||||
mods\cnc\maps\gdi02\gdi02.lua = mods\cnc\maps\gdi02\gdi02.lua
|
||||
mods\cnc\maps\gdi03\gdi03.lua = mods\cnc\maps\gdi03\gdi03.lua
|
||||
mods\cnc\maps\gdi04a\gdi04a.lua = mods\cnc\maps\gdi04a\gdi04a.lua
|
||||
mods\cnc\maps\gdi04b\gdi04b.lua = mods\cnc\maps\gdi04b\gdi04b.lua
|
||||
mods\cnc\maps\gdi04c\gdi04c.lua = mods\cnc\maps\gdi04c\gdi04c.lua
|
||||
mods\cnc\maps\gdi05a\gdi05a.lua = mods\cnc\maps\gdi05a\gdi05a.lua
|
||||
mods\cnc\maps\gdi05b\gdi05b.lua = mods\cnc\maps\gdi05b\gdi05b.lua
|
||||
mods\cnc\maps\gdi06\gdi06.lua = mods\cnc\maps\gdi06\gdi06.lua
|
||||
mods\cnc\maps\gdi07\gdi07.lua = mods\cnc\maps\gdi07\gdi07.lua
|
||||
mods\cnc\maps\nod01\nod01.lua = mods\cnc\maps\nod01\nod01.lua
|
||||
mods\cnc\maps\nod02a\nod02a.lua = mods\cnc\maps\nod02a\nod02a.lua
|
||||
mods\cnc\maps\nod02b\nod02b.lua = mods\cnc\maps\nod02b\nod02b.lua
|
||||
mods\cnc\maps\nod03a\nod03a.lua = mods\cnc\maps\nod03a\nod03a.lua
|
||||
mods\cnc\maps\nod03b\nod03b.lua = mods\cnc\maps\nod03b\nod03b.lua
|
||||
mods\cnc\maps\nod04a\nod04a.lua = mods\cnc\maps\nod04a\nod04a.lua
|
||||
mods\cnc\maps\nod04b\nod04b.lua = mods\cnc\maps\nod04b\nod04b.lua
|
||||
mods\cnc\maps\nod05\nod05.lua = mods\cnc\maps\nod05\nod05.lua
|
||||
mods\cnc\maps\nod06a\nod06a.lua = mods\cnc\maps\nod06a\nod06a.lua
|
||||
mods\cnc\maps\nod06b\nod06b.lua = mods\cnc\maps\nod06b\nod06b.lua
|
||||
mods\cnc\maps\nod06c\nod06c.lua = mods\cnc\maps\nod06c\nod06c.lua
|
||||
mods\cnc\maps\nod07a\nod07a-AI.lua = mods\cnc\maps\nod07a\nod07a-AI.lua
|
||||
mods\cnc\maps\nod07a\nod07a.lua = mods\cnc\maps\nod07a\nod07a.lua
|
||||
mods\cnc\maps\nod07b\nod07b-AI.lua = mods\cnc\maps\nod07b\nod07b-AI.lua
|
||||
mods\cnc\maps\nod07b\nod07b.lua = mods\cnc\maps\nod07b\nod07b.lua
|
||||
mods\cnc\maps\nod07c\nod07c.lua = mods\cnc\maps\nod07c\nod07c.lua
|
||||
mods\cnc\maps\nod08a\nod08a-AI.lua = mods\cnc\maps\nod08a\nod08a-AI.lua
|
||||
mods\cnc\maps\nod08a\nod08a.lua = mods\cnc\maps\nod08a\nod08a.lua
|
||||
mods\cnc\maps\nod08b\nod08b-AI.lua = mods\cnc\maps\nod08b\nod08b-AI.lua
|
||||
mods\cnc\maps\nod08b\nod08b.lua = mods\cnc\maps\nod08b\nod08b.lua
|
||||
mods\cnc\maps\nod09\nod09-AI.lua = mods\cnc\maps\nod09\nod09-AI.lua
|
||||
mods\cnc\maps\nod09\nod09.lua = mods\cnc\maps\nod09\nod09.lua
|
||||
mods\cnc\maps\funpark01\scj01ea.lua = mods\cnc\maps\funpark01\scj01ea.lua
|
||||
mods\cnc\maps\shellmap\shellmap.lua = mods\cnc\maps\shellmap\shellmap.lua
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Red Alert Lua scripts", "Red Alert Lua scripts", "{B35D533F-BEB6-4674-A466-324EEFD97259}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
mods\ra\maps\allies-01\allies01.lua = mods\ra\maps\allies-01\allies01.lua
|
||||
mods\ra\maps\allies-02\allies02.lua = mods\ra\maps\allies-02\allies02.lua
|
||||
mods\ra\maps\allies-03a\allies03a.lua = mods\ra\maps\allies-03a\allies03a.lua
|
||||
mods\ra\maps\allies-03b\allies03b.lua = mods\ra\maps\allies-03b\allies03b.lua
|
||||
mods\ra\maps\allies-05a\allies05a-AI.lua = mods\ra\maps\allies-05a\allies05a-AI.lua
|
||||
mods\ra\maps\allies-05a\allies05a.lua = mods\ra\maps\allies-05a\allies05a.lua
|
||||
mods\ra\maps\allies-06a\allies06a-AI.lua = mods\ra\maps\allies-06a\allies06a-AI.lua
|
||||
mods\ra\maps\allies-06a\allies06a.lua = mods\ra\maps\allies-06a\allies06a.lua
|
||||
mods\ra\maps\allies-06b\allies06b-AI.lua = mods\ra\maps\allies-06b\allies06b-AI.lua
|
||||
mods\ra\maps\allies-06b\allies06b.lua = mods\ra\maps\allies-06b\allies06b.lua
|
||||
mods\ra\maps\desert-shellmap\desert-shellmap.lua = mods\ra\maps\desert-shellmap\desert-shellmap.lua
|
||||
mods\ra\maps\evacuation\evacuation.lua = mods\ra\maps\evacuation\evacuation.lua
|
||||
mods\ra\maps\exodus\exodus.lua = mods\ra\maps\exodus\exodus.lua
|
||||
mods\ra\maps\fort-lonestar\fort-lonestar-AI.lua = mods\ra\maps\fort-lonestar\fort-lonestar-AI.lua
|
||||
mods\ra\maps\fort-lonestar\fort-lonestar.lua = mods\ra\maps\fort-lonestar\fort-lonestar.lua
|
||||
mods\ra\maps\infiltration\infiltration.lua = mods\ra\maps\infiltration\infiltration.lua
|
||||
mods\ra\maps\intervention\intervention.lua = mods\ra\maps\intervention\intervention.lua
|
||||
mods\ra\maps\monster-tank-madness\monster-tank-madness.lua = mods\ra\maps\monster-tank-madness\monster-tank-madness.lua
|
||||
mods\ra\maps\soviet-soldier-volkov-n-chitzkoi\scu35ea-AI.lua = mods\ra\maps\soviet-soldier-volkov-n-chitzkoi\scu35ea-AI.lua
|
||||
mods\ra\maps\soviet-soldier-volkov-n-chitzkoi\scu35ea.lua = mods\ra\maps\soviet-soldier-volkov-n-chitzkoi\scu35ea.lua
|
||||
mods\ra\maps\top-o-the-world\scu36ea.lua = mods\ra\maps\top-o-the-world\scu36ea.lua
|
||||
mods\ra\maps\soviet-01\soviet01.lua = mods\ra\maps\soviet-01\soviet01.lua
|
||||
mods\ra\maps\soviet-02a\soviet02a.lua = mods\ra\maps\soviet-02a\soviet02a.lua
|
||||
mods\ra\maps\soviet-02b\soviet02b.lua = mods\ra\maps\soviet-02b\soviet02b.lua
|
||||
mods\ra\maps\soviet-03\soviet03.lua = mods\ra\maps\soviet-03\soviet03.lua
|
||||
mods\ra\maps\soviet-04a\soviet04a-AI.lua = mods\ra\maps\soviet-04a\soviet04a-AI.lua
|
||||
mods\ra\maps\soviet-04a\soviet04a-reinforcements_teams.lua = mods\ra\maps\soviet-04a\soviet04a-reinforcements_teams.lua
|
||||
mods\ra\maps\soviet-04a\soviet04a.lua = mods\ra\maps\soviet-04a\soviet04a.lua
|
||||
mods\ra\maps\soviet-04b\soviet04b-AI.lua = mods\ra\maps\soviet-04b\soviet04b-AI.lua
|
||||
mods\ra\maps\soviet-04b\soviet04b-reinforcements_teams.lua = mods\ra\maps\soviet-04b\soviet04b-reinforcements_teams.lua
|
||||
mods\ra\maps\soviet-04b\soviet04b.lua = mods\ra\maps\soviet-04b\soviet04b.lua
|
||||
mods\ra\maps\soviet-05\soviet05-AI.lua = mods\ra\maps\soviet-05\soviet05-AI.lua
|
||||
mods\ra\maps\soviet-05\soviet05-reinforcements_teams.lua = mods\ra\maps\soviet-05\soviet05-reinforcements_teams.lua
|
||||
mods\ra\maps\soviet-05\soviet05.lua = mods\ra\maps\soviet-05\soviet05.lua
|
||||
mods\ra\maps\soviet-06a\soviet06a-AI.lua = mods\ra\maps\soviet-06a\soviet06a-AI.lua
|
||||
mods\ra\maps\soviet-06a\soviet06a-reinforcements_teams.lua = mods\ra\maps\soviet-06a\soviet06a-reinforcements_teams.lua
|
||||
mods\ra\maps\soviet-06a\soviet06a.lua = mods\ra\maps\soviet-06a\soviet06a.lua
|
||||
mods\ra\maps\soviet-06b\soviet06b-AI.lua = mods\ra\maps\soviet-06b\soviet06b-AI.lua
|
||||
mods\ra\maps\soviet-06b\soviet06b-reinforcements_teams.lua = mods\ra\maps\soviet-06b\soviet06b-reinforcements_teams.lua
|
||||
mods\ra\maps\soviet-06b\soviet06b.lua = mods\ra\maps\soviet-06b\soviet06b.lua
|
||||
mods\ra\maps\soviet-07\soviet07.lua = mods\ra\maps\soviet-07\soviet07.lua
|
||||
mods\ra\maps\survival01\survival01.lua = mods\ra\maps\survival01\survival01.lua
|
||||
mods\ra\maps\survival02\survival02.lua = mods\ra\maps\survival02\survival02.lua
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dune 2000 Lua scripts", "Dune 2000 Lua scripts", "{06B1AE07-DDB0-4287-8700-A8CD9A0E652E}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
mods\d2k\maps\atreides-01a\atreides01a.lua = mods\d2k\maps\atreides-01a\atreides01a.lua
|
||||
mods\d2k\maps\atreides-01b\atreides01b.lua = mods\d2k\maps\atreides-01b\atreides01b.lua
|
||||
mods\d2k\maps\atreides-02a\atreides02a-AI.lua = mods\d2k\maps\atreides-02a\atreides02a-AI.lua
|
||||
mods\d2k\maps\atreides-02a\atreides02a.lua = mods\d2k\maps\atreides-02a\atreides02a.lua
|
||||
mods\d2k\maps\atreides-02b\atreides02b-AI.lua = mods\d2k\maps\atreides-02b\atreides02b-AI.lua
|
||||
mods\d2k\maps\atreides-02b\atreides02b.lua = mods\d2k\maps\atreides-02b\atreides02b.lua
|
||||
mods\d2k\maps\atreides-03a\atreides03a-AI.lua = mods\d2k\maps\atreides-03a\atreides03a-AI.lua
|
||||
mods\d2k\maps\atreides-03a\atreides03a.lua = mods\d2k\maps\atreides-03a\atreides03a.lua
|
||||
mods\d2k\maps\atreides-03b\atreides03b-AI.lua = mods\d2k\maps\atreides-03b\atreides03b-AI.lua
|
||||
mods\d2k\maps\atreides-03b\atreides03b.lua = mods\d2k\maps\atreides-03b\atreides03b.lua
|
||||
mods\d2k\maps\atreides-04\atreides04-AI.lua = mods\d2k\maps\atreides-04\atreides04-AI.lua
|
||||
mods\d2k\maps\atreides-04\atreides04.lua = mods\d2k\maps\atreides-04\atreides04.lua
|
||||
mods\d2k\maps\atreides-05\atreides05-AI.lua = mods\d2k\maps\atreides-05\atreides05-AI.lua
|
||||
mods\d2k\maps\atreides-05\atreides05.lua = mods\d2k\maps\atreides-05\atreides05.lua
|
||||
mods\d2k\bits\scripts\campaign-global.lua = mods\d2k\bits\scripts\campaign-global.lua
|
||||
mods\d2k\maps\harkonnen-01a\harkonnen01a.lua = mods\d2k\maps\harkonnen-01a\harkonnen01a.lua
|
||||
mods\d2k\maps\harkonnen-01b\harkonnen01b.lua = mods\d2k\maps\harkonnen-01b\harkonnen01b.lua
|
||||
mods\d2k\maps\harkonnen-02a\harkonnen02a-AI.lua = mods\d2k\maps\harkonnen-02a\harkonnen02a-AI.lua
|
||||
mods\d2k\maps\harkonnen-02a\harkonnen02a.lua = mods\d2k\maps\harkonnen-02a\harkonnen02a.lua
|
||||
mods\d2k\maps\harkonnen-02b\harkonnen02b-AI.lua = mods\d2k\maps\harkonnen-02b\harkonnen02b-AI.lua
|
||||
mods\d2k\maps\harkonnen-02b\harkonnen02b.lua = mods\d2k\maps\harkonnen-02b\harkonnen02b.lua
|
||||
mods\d2k\maps\harkonnen-03a\harkonnen03a-AI.lua = mods\d2k\maps\harkonnen-03a\harkonnen03a-AI.lua
|
||||
mods\d2k\maps\harkonnen-03a\harkonnen03a.lua = mods\d2k\maps\harkonnen-03a\harkonnen03a.lua
|
||||
mods\d2k\maps\harkonnen-03b\harkonnen03b-AI.lua = mods\d2k\maps\harkonnen-03b\harkonnen03b-AI.lua
|
||||
mods\d2k\maps\harkonnen-03b\harkonnen03b.lua = mods\d2k\maps\harkonnen-03b\harkonnen03b.lua
|
||||
mods\d2k\maps\harkonnen-04\harkonnen04-AI.lua = mods\d2k\maps\harkonnen-04\harkonnen04-AI.lua
|
||||
mods\d2k\maps\harkonnen-04\harkonnen04.lua = mods\d2k\maps\harkonnen-04\harkonnen04.lua
|
||||
mods\d2k\maps\harkonnen-05\harkonnen05-AI.lua = mods\d2k\maps\harkonnen-05\harkonnen05-AI.lua
|
||||
mods\d2k\maps\harkonnen-05\harkonnen05.lua = mods\d2k\maps\harkonnen-05\harkonnen05.lua
|
||||
mods\d2k\maps\harkonnen-06a\harkonnen06a-AI.lua = mods\d2k\maps\harkonnen-06a\harkonnen06a-AI.lua
|
||||
mods\d2k\maps\harkonnen-06a\harkonnen06a.lua = mods\d2k\maps\harkonnen-06a\harkonnen06a.lua
|
||||
mods\d2k\maps\harkonnen-06b\harkonnen06b-AI.lua = mods\d2k\maps\harkonnen-06b\harkonnen06b-AI.lua
|
||||
mods\d2k\maps\harkonnen-06b\harkonnen06b.lua = mods\d2k\maps\harkonnen-06b\harkonnen06b.lua
|
||||
mods\d2k\maps\harkonnen-07\harkonnen07-AI.lua = mods\d2k\maps\harkonnen-07\harkonnen07-AI.lua
|
||||
mods\d2k\maps\harkonnen-07\harkonnen07.lua = mods\d2k\maps\harkonnen-07\harkonnen07.lua
|
||||
mods\d2k\maps\harkonnen-08\harkonnen08-AI.lua = mods\d2k\maps\harkonnen-08\harkonnen08-AI.lua
|
||||
mods\d2k\maps\harkonnen-08\harkonnen08.lua = mods\d2k\maps\harkonnen-08\harkonnen08.lua
|
||||
mods\d2k\maps\harkonnen-09a\harkonnen09a-AI.lua = mods\d2k\maps\harkonnen-09a\harkonnen09a-AI.lua
|
||||
mods\d2k\maps\harkonnen-09a\harkonnen09a.lua = mods\d2k\maps\harkonnen-09a\harkonnen09a.lua
|
||||
mods\d2k\maps\harkonnen-09b\harkonnen09b-AI.lua = mods\d2k\maps\harkonnen-09b\harkonnen09b-AI.lua
|
||||
mods\d2k\maps\harkonnen-09b\harkonnen09b.lua = mods\d2k\maps\harkonnen-09b\harkonnen09b.lua
|
||||
mods\d2k\maps\ordos-01a\ordos01a.lua = mods\d2k\maps\ordos-01a\ordos01a.lua
|
||||
mods\d2k\maps\ordos-01b\ordos01b.lua = mods\d2k\maps\ordos-01b\ordos01b.lua
|
||||
mods\d2k\maps\ordos-02a\ordos02a-AI.lua = mods\d2k\maps\ordos-02a\ordos02a-AI.lua
|
||||
mods\d2k\maps\ordos-02a\ordos02a.lua = mods\d2k\maps\ordos-02a\ordos02a.lua
|
||||
mods\d2k\maps\ordos-02b\ordos02b-AI.lua = mods\d2k\maps\ordos-02b\ordos02b-AI.lua
|
||||
mods\d2k\maps\ordos-02b\ordos02b.lua = mods\d2k\maps\ordos-02b\ordos02b.lua
|
||||
mods\d2k\maps\ordos-03a\ordos03a-AI.lua = mods\d2k\maps\ordos-03a\ordos03a-AI.lua
|
||||
mods\d2k\maps\ordos-03a\ordos03a.lua = mods\d2k\maps\ordos-03a\ordos03a.lua
|
||||
mods\d2k\maps\ordos-03b\ordos03b-AI.lua = mods\d2k\maps\ordos-03b\ordos03b-AI.lua
|
||||
mods\d2k\maps\ordos-03b\ordos03b.lua = mods\d2k\maps\ordos-03b\ordos03b.lua
|
||||
mods\d2k\maps\ordos-04\ordos04-AI.lua = mods\d2k\maps\ordos-04\ordos04-AI.lua
|
||||
mods\d2k\maps\ordos-04\ordos04.lua = mods\d2k\maps\ordos-04\ordos04.lua
|
||||
mods\d2k\maps\ordos-05\ordos05-AI.lua = mods\d2k\maps\ordos-05\ordos05-AI.lua
|
||||
mods\d2k\maps\ordos-05\ordos05.lua = mods\d2k\maps\ordos-05\ordos05.lua
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "System Lua scripts", "System Lua scripts", "{A4D6AEA4-8009-4256-903B-8D227E50452B}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
lua\sandbox.lua = lua\sandbox.lua
|
||||
lua\scriptwrapper.lua = lua\scriptwrapper.lua
|
||||
lua\stacktraceplus.lua = lua\stacktraceplus.lua
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenRA.Test", "OpenRA.Test\OpenRA.Test.csproj", "{6CB8E1B7-6B36-4D93-8633-7C573E194AC4}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tiberian Sun Lua scripts", "Tiberian Sun Lua scripts", "{85159569-F5BD-458E-B5C0-EB16690C432B}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
mods\ts\maps\fields-of-green\fields-of-green.lua = mods\ts\maps\fields-of-green\fields-of-green.lua
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenRA.PostProcess", "OpenRA.PostProcess\OpenRA.PostProcess.csproj", "{EE63AF7E-92EA-48FB-81E2-53D7D92F8050}"
|
||||
EndProject
|
||||
Global
|
||||
@@ -201,7 +44,6 @@ Global
|
||||
{F33337BE-CB69-4B24-850F-07D23E408DDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F33337BE-CB69-4B24-850F-07D23E408DDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F33337BE-CB69-4B24-850F-07D23E408DDF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F33337BE-CB69-4B24-850F-07D23E408DDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F33337BE-CB69-4B24-850F-07D23E408DDF}.Release-x86|Any CPU.ActiveCfg = Release-x86|Any CPU
|
||||
{F33337BE-CB69-4B24-850F-07D23E408DDF}.Release-x86|Any CPU.Build.0 = Release-x86|Any CPU
|
||||
{76F621A1-3D8E-4A99-9F7E-B071EB657817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
|
||||
@@ -388,7 +388,7 @@ sidebar-bits:
|
||||
production-tooltip-time: 904, 51, 16, 16
|
||||
production-tooltip-power: 870, 51, 16, 16
|
||||
production-tooltip-cost: 836, 51, 16, 16
|
||||
indicator-muted: 918, 221, 24, 24
|
||||
indicator-muted: 918, 221, 26, 24
|
||||
|
||||
vertical-bars:
|
||||
Inherits: ^Chrome
|
||||
|
||||
@@ -182,8 +182,10 @@ Container@SAVE_MAP_PANEL:
|
||||
Font: Bold
|
||||
|
||||
ScrollPanel@MAP_SAVE_VISIBILITY_PANEL:
|
||||
TopBottomSpacing: 5
|
||||
ItemSpacing: 5
|
||||
Width: 220
|
||||
Height: 64
|
||||
Height: 55
|
||||
Children:
|
||||
Checkbox@VISIBILITY_TEMPLATE:
|
||||
X: 5
|
||||
@@ -642,29 +644,30 @@ Container@EDITOR_WORLD_ROOT:
|
||||
Contrast: true
|
||||
|
||||
ScrollPanel@CATEGORY_FILTER_PANEL:
|
||||
Width: 190
|
||||
Width: 230
|
||||
TopBottomSpacing: 5
|
||||
ItemSpacing: 5
|
||||
Children:
|
||||
Container@SELECT_CATEGORIES_BUTTONS:
|
||||
Width: PARENT_RIGHT
|
||||
Height: 30
|
||||
Height: 25
|
||||
Children:
|
||||
Button@SELECT_ALL:
|
||||
X: 10
|
||||
Y: 2
|
||||
Width: 60
|
||||
Y: 0 - 5
|
||||
Width: 88
|
||||
Height: 25
|
||||
Text: All
|
||||
Button@SELECT_NONE:
|
||||
X: PARENT_RIGHT - WIDTH - 34
|
||||
Y: 2
|
||||
Width: 60
|
||||
X: 10 + 88 + 10
|
||||
Y: 0 - 5
|
||||
Width: 88
|
||||
Height: 25
|
||||
Text: None
|
||||
Checkbox@CATEGORY_TEMPLATE:
|
||||
X: 5
|
||||
Y: 5
|
||||
Width: PARENT_RIGHT - 29
|
||||
Height: 22
|
||||
Height: 20
|
||||
Visible: false
|
||||
|
||||
ScrollPanel@COPY_FILTER_PANEL:
|
||||
|
||||
@@ -148,7 +148,7 @@ Container@LOBBY_PLAYER_BIN:
|
||||
Height: 25
|
||||
Font: Regular
|
||||
Image@STATUS_IMAGE:
|
||||
X: 521
|
||||
X: 529
|
||||
Y: 4
|
||||
Width: 20
|
||||
Height: 20
|
||||
@@ -198,7 +198,6 @@ Container@LOBBY_PLAYER_BIN:
|
||||
Template: ANONYMOUS_PLAYER_TOOLTIP
|
||||
Label@NAME:
|
||||
X: 39
|
||||
Y: 0 - 1
|
||||
Width: 161
|
||||
Height: 25
|
||||
DropDownButton@PLAYER_ACTION:
|
||||
@@ -233,8 +232,8 @@ Container@LOBBY_PLAYER_BIN:
|
||||
Height: 25
|
||||
Children:
|
||||
Image@FACTIONFLAG:
|
||||
X: 5
|
||||
Y: 5
|
||||
X: 4
|
||||
Y: 4
|
||||
Width: 30
|
||||
Height: 15
|
||||
Label@FACTIONNAME:
|
||||
@@ -265,7 +264,7 @@ Container@LOBBY_PLAYER_BIN:
|
||||
Font: Regular
|
||||
Visible: false
|
||||
Image@STATUS_IMAGE:
|
||||
X: 527
|
||||
X: 529
|
||||
Y: 4
|
||||
Width: 20
|
||||
Height: 20
|
||||
@@ -287,7 +286,6 @@ Container@LOBBY_PLAYER_BIN:
|
||||
Visible: false
|
||||
Label@NAME:
|
||||
X: 20
|
||||
Y: 0 - 1
|
||||
Width: 195
|
||||
Height: 25
|
||||
Visible: false
|
||||
@@ -348,7 +346,7 @@ Container@LOBBY_PLAYER_BIN:
|
||||
Align: Center
|
||||
Font: Bold
|
||||
Image@STATUS_IMAGE:
|
||||
X: 521
|
||||
X: 529
|
||||
Y: 4
|
||||
Width: 20
|
||||
Height: 20
|
||||
@@ -398,7 +396,6 @@ Container@LOBBY_PLAYER_BIN:
|
||||
Template: ANONYMOUS_PLAYER_TOOLTIP
|
||||
Label@NAME:
|
||||
X: 39
|
||||
Y: 0 - 1
|
||||
Width: 161
|
||||
Height: 25
|
||||
DropDownButton@PLAYER_ACTION:
|
||||
|
||||
@@ -190,7 +190,13 @@ Container@MAINMENU_INTRODUCTION_PROMPT:
|
||||
Height: 16
|
||||
Font: Small
|
||||
Text: - Zoom the battlefield using {MODIFIER + Scroll Wheel}
|
||||
LabelWithHighlight@DESC_SCROLL:
|
||||
LabelWithHighlight@DESC_SCROLL_RIGHT:
|
||||
X: 265
|
||||
Y: 34
|
||||
Height: 16
|
||||
Font: Small
|
||||
Text: - Pan the battlefield using the {Right} mouse button
|
||||
LabelWithHighlight@DESC_SCROLL_MIDDLE:
|
||||
X: 265
|
||||
Y: 34
|
||||
Height: 16
|
||||
|
||||
@@ -484,7 +484,12 @@ Container@SETTINGS_PANEL:
|
||||
Height: 16
|
||||
Font: Small
|
||||
Text: - Zoom the battlefield using {MODIFIER + Scroll Wheel}
|
||||
LabelWithHighlight@DESC_SCROLL:
|
||||
LabelWithHighlight@DESC_SCROLL_RIGHT:
|
||||
Y: 85
|
||||
Height: 16
|
||||
Font: Small
|
||||
Text: - Pan the battlefield using the {Right} mouse button
|
||||
LabelWithHighlight@DESC_SCROLL_MIDDLE:
|
||||
Y: 85
|
||||
Height: 16
|
||||
Font: Small
|
||||
@@ -537,13 +542,13 @@ Container@SETTINGS_PANEL:
|
||||
Height: 20
|
||||
Font: Regular
|
||||
Text: Screen Edge Panning
|
||||
Checkbox@CLASSIC_MOUSE_MIDDLE_SCROLL_CHECKBOX:
|
||||
Checkbox@ALTERNATE_SCROLL_CHECKBOX:
|
||||
X: 360
|
||||
Y: 133
|
||||
Width: 180
|
||||
Height: 20
|
||||
Font: Regular
|
||||
Text: Middle Mouse Panning
|
||||
Text: Alternate Mouse Panning
|
||||
Label@SCROLL_SPEED_LABEL:
|
||||
X: 310
|
||||
Y: 210
|
||||
@@ -634,7 +639,7 @@ Container@SETTINGS_PANEL:
|
||||
Width: 80
|
||||
Height: 25
|
||||
Align: Left
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
TooltipContainer: SETTINGS_TOOLTIP_CONTAINER
|
||||
Container@THREE_COLUMN:
|
||||
Width: 173
|
||||
Height: 25
|
||||
@@ -650,7 +655,7 @@ Container@SETTINGS_PANEL:
|
||||
Width: 80
|
||||
Height: 25
|
||||
Align: Left
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
TooltipContainer: SETTINGS_TOOLTIP_CONTAINER
|
||||
Background@HOTKEY_DIALOG_ROOT:
|
||||
X: 15
|
||||
Y: 230
|
||||
@@ -700,7 +705,7 @@ Container@SETTINGS_PANEL:
|
||||
Width: 25
|
||||
Height: 25
|
||||
TooltipText: Unbind the hotkey
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
TooltipContainer: SETTINGS_TOOLTIP_CONTAINER
|
||||
TooltipTemplate: SIMPLE_TOOLTIP
|
||||
Children:
|
||||
Image:
|
||||
@@ -715,7 +720,7 @@ Container@SETTINGS_PANEL:
|
||||
Width: 25
|
||||
Height: 25
|
||||
TooltipText: Reset to default
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
TooltipContainer: SETTINGS_TOOLTIP_CONTAINER
|
||||
TooltipTemplate: SIMPLE_TOOLTIP
|
||||
Children:
|
||||
Image@IMAGE_RELOAD:
|
||||
@@ -860,4 +865,4 @@ Container@SETTINGS_PANEL:
|
||||
Width: 140
|
||||
Height: 35
|
||||
Text: Reset
|
||||
TooltipContainer@TOOLTIP_CONTAINER:
|
||||
TooltipContainer@SETTINGS_TOOLTIP_CONTAINER:
|
||||
|
||||
194
mods/cnc/maps/gdi08a/gdi08a-AI.lua
Normal file
@@ -0,0 +1,194 @@
|
||||
--[[
|
||||
Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
|
||||
This file is part of OpenRA, which is free software. It is made
|
||||
available to you under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version. For more
|
||||
information, see COPYING.
|
||||
]]
|
||||
|
||||
AttackPaths = { WaypointGroup3, WaypointGroup4, WaypointGroup5 }
|
||||
NodBase = { handofnod, nodairfield, nodrefinery, NodYard, nodpower1, nodpower2, nodpower3, nodpower4, gun1, gun2, nodsilo1, nodsilo2, nodsilo3, nodsilo4}
|
||||
|
||||
PatrolProductionQueue = { }
|
||||
|
||||
InfantryAttackGroup = { }
|
||||
InfantryGroupSize = 5
|
||||
InfantryProductionCooldown = DateTime.Minutes(3)
|
||||
InfantryProductionTypes = { "e1", "e1", "e1", "e3", "e3", "e4" }
|
||||
HarvesterProductionType = { "harv" }
|
||||
|
||||
VehicleAttackGroup = { }
|
||||
VehicleGroupSize = 5
|
||||
VehicleProductionCooldown = DateTime.Minutes(3)
|
||||
VehicleProductionTypes = { "bggy", "bggy", "bike", "ltnk", "ltnk" }
|
||||
|
||||
StartingCash = 14000
|
||||
|
||||
BaseRefinery = { type = "proc", pos = CPos.New(24, 16), cost = 1500 }
|
||||
BaseGun1 = { type = "gun", pos = CPos.New( 21, 19), cost = 600 }
|
||||
BaseGun2 = { type = "gun", pos = CPos.New( 26, 21), cost = 600 }
|
||||
BaseNuke1 = { type = "nuke", pos = CPos.New( 23, 14), cost = 500 }
|
||||
BaseNuke2 = { type = "nuke", pos = CPos.New( 10, 9), cost = 500 }
|
||||
BaseNuke3 = { type = "nuke", pos = CPos.New( 6, 8), cost = 500 }
|
||||
BaseNuke4 = { type = "nuke", pos = CPos.New( 8, 8), cost = 500 }
|
||||
InfantryProduction = { type = "hand", pos = CPos.New(27, 17), cost = 500 }
|
||||
VehicleProduction = { type = "afld", pos = CPos.New(27, 14), cost = 2000 }
|
||||
|
||||
NodGuards = { Actor154, Actor155, Actor218, Actor219 }
|
||||
|
||||
BaseBuildings = { BaseRefinery, BaseNuke1, BaseNuke2, BaseNuke3, BaseNuke4, InfantryProduction, VehicleProduction, BaseGun1, BaseGun2 }
|
||||
|
||||
BuildBuilding = function(building, cyard)
|
||||
if CyardIsBuilding or Nod.Cash < building.cost then
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBuilding(building, cyard) end)
|
||||
return
|
||||
end
|
||||
|
||||
CyardIsBuilding = true
|
||||
|
||||
Nod.Cash = Nod.Cash - building.cost
|
||||
Trigger.AfterDelay(Actor.BuildTime(building.type), function()
|
||||
CyardIsBuilding = false
|
||||
|
||||
if cyard.IsDead or cyard.Owner ~= Nod then
|
||||
Nod.Cash = Nod.Cash + building.cost
|
||||
return
|
||||
end
|
||||
|
||||
local actor = Actor.Create(building.type, true, { Owner = Nod, Location = building.pos })
|
||||
|
||||
if actor.Type == 'hand' or actor.Type == 'pyle' then
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(actor) end)
|
||||
elseif actor.Type == 'afld' or actor.Type == 'weap' then
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(actor) end)
|
||||
end
|
||||
|
||||
Trigger.OnKilled(actor, function()
|
||||
BuildBuilding(building, cyard)
|
||||
end)
|
||||
|
||||
RepairBuilding(GDI, actor, 0.75)
|
||||
end)
|
||||
end
|
||||
|
||||
CheckForHarvester = function()
|
||||
local harv = Nod.GetActorsByType("harv")
|
||||
return #harv > 0
|
||||
end
|
||||
|
||||
GuardBase = function()
|
||||
Utils.Do(NodBase, function(building)
|
||||
Trigger.OnDamaged(building, function()
|
||||
Utils.Do(NodGuards, function(guard)
|
||||
if not guard.IsDead and not building.IsDead then
|
||||
guard.Stop()
|
||||
guard.Guard(building)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
ProduceHarvester = function(building)
|
||||
if not buildingHarvester then
|
||||
buildingHarvester = true
|
||||
building.Build(HarvesterProductionType, function()
|
||||
buildingHarvester = false
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
ProduceInfantry = function(building)
|
||||
if building.IsDead or building.Owner ~= Nod then
|
||||
return
|
||||
elseif not CheckForHarvester() then
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(building) end)
|
||||
return
|
||||
end
|
||||
|
||||
local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9))
|
||||
local toBuild = { Utils.Random(InfantryProductionTypes) }
|
||||
local Path = Utils.Random(AttackPaths)
|
||||
building.Build(toBuild, function(unit)
|
||||
InfantryAttackGroup[#InfantryAttackGroup + 1] = unit[1]
|
||||
|
||||
if #InfantryAttackGroup >= InfantryGroupSize then
|
||||
MoveAndHunt(InfantryAttackGroup, Path)
|
||||
InfantryAttackGroup = { }
|
||||
Trigger.AfterDelay(InfantryProductionCooldown, function() ProduceInfantry(building) end)
|
||||
else
|
||||
Trigger.AfterDelay(delay, function() ProduceInfantry(building) end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
ProduceVehicle = function(building)
|
||||
if building.IsDead or building.Owner ~= Nod then
|
||||
return
|
||||
elseif not CheckForHarvester() then
|
||||
ProduceHarvester(building)
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(building) end)
|
||||
return
|
||||
end
|
||||
|
||||
local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17))
|
||||
local toBuild = { Utils.Random(VehicleProductionTypes) }
|
||||
local Path = Utils.Random(AttackPaths)
|
||||
building.Build(toBuild, function(unit)
|
||||
VehicleAttackGroup[#VehicleAttackGroup + 1] = unit[1]
|
||||
|
||||
if #VehicleAttackGroup >= VehicleGroupSize then
|
||||
MoveAndHunt(VehicleAttackGroup, Path)
|
||||
VehicleAttackGroup = { }
|
||||
Trigger.AfterDelay(VehicleProductionCooldown, function() ProduceVehicle(building) end)
|
||||
else
|
||||
Trigger.AfterDelay(delay, function() ProduceVehicle(building) end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
StartAI = function()
|
||||
Nod.Cash = StartingCash
|
||||
GuardBase()
|
||||
end
|
||||
|
||||
Trigger.OnAllKilledOrCaptured(NodBase, function()
|
||||
Utils.Do(Nod.GetGroundAttackers(), IdleHunt)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodrefinery, function()
|
||||
BuildBuilding(BaseRefinery, NodYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodpower1, function()
|
||||
BuildBuilding(BaseNuke1, NodYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodpower2, function()
|
||||
BuildBuilding(BaseNuke2, NodYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodpower3, function()
|
||||
BuildBuilding(BaseNuke3, NodYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodpower4, function()
|
||||
BuildBuilding(BaseNuke4, NodYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(gun1, function()
|
||||
BuildBuilding(BaseGun1, NodYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(gun2, function()
|
||||
BuildBuilding(BaseGun2, NodYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(handofnod, function()
|
||||
BuildBuilding(InfantryProduction, NodYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodairfield, function()
|
||||
BuildBuilding(VehicleProduction, NodYard)
|
||||
end)
|
||||
152
mods/cnc/maps/gdi08a/gdi08a.lua
Normal file
@@ -0,0 +1,152 @@
|
||||
--[[
|
||||
Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
|
||||
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.
|
||||
]]
|
||||
|
||||
SamSites = { sam1, sam2, sam3 }
|
||||
|
||||
WaypointGroup1 = { waypoint4, waypoint5, waypoint6, waypoint7, waypoint10, waypoint11, waypoint12 }
|
||||
WaypointGroup2 = { waypoint4, waypoint5, waypoint13, waypoint16 }
|
||||
WaypointGroup3 = { waypoint4, waypoint5, waypoint6, waypoint8 }
|
||||
WaypointGroup4 = { waypoint4, waypoint5, waypoint6, waypoint7, waypoint9 }
|
||||
WaypointGroup5 = { waypoint4, waypoint5, waypoint6 }
|
||||
WaypointGroup6 = { waypoint4, waypoint5, waypoint6, waypoint7, waypoint14, waypoint15 }
|
||||
WaypointGroup7 = { waypoint4, waypoint5 }
|
||||
WaypointGroupCiv = { waypoint0, waypoint1, waypoint2, waypoint3 }
|
||||
|
||||
Atk1 = { units = { ['ltnk'] = 1 }, waypoints = WaypointGroup1, delay = 0 }
|
||||
Atk2 = { units = { ['ltnk'] = 1 }, waypoints = WaypointGroup2, delay = 0 }
|
||||
Civ1 = { units = { ['c3'] = 1 }, waypoints = WaypointGroupCiv, delay = 0 }
|
||||
Nod1 = { units = { ['e1'] = 2, ['e2'] = 2, ['e4'] = 2 }, waypoints = WaypointGroup3, delay = 90 }
|
||||
Nod2 = { units = { ['e3'] = 2, ['e4'] = 2 }, waypoints = WaypointGroup3, delay = 130 }
|
||||
Nod3 = { units = { ['e1'] = 2, ['e3'] = 3 }, waypoints = WaypointGroup3, delay = 50 }
|
||||
Nod4 = { units = { ['bggy'] = 2 }, waypoints = WaypointGroup3, delay = 200 }
|
||||
Nod5 = { units = { ['e4'] = 2, ['ltnk'] = 1 }, waypoints = WaypointGroup1, delay = 250 }
|
||||
Nod6 = { units = { ['arty'] = 1 }, waypoints = WaypointGroup4, delay = 40 }
|
||||
Nod7 = { units = { ['e3'] = 2, ['e4'] = 2 }, waypoints = WaypointGroup4, delay = 40 }
|
||||
Nod8 = { units = { ['ltnk'] = 1, ['bggy'] = 1 }, waypoints = WaypointGroup3, delay = 170 }
|
||||
Auto1 = { units = { ['e1'] = 2, ['e2'] = 2 }, waypoints = WaypointGroup5, delay = 50 }
|
||||
Auto2 = { units = { ['e3'] = 3, ['e4'] = 2 }, waypoints = WaypointGroup3, delay = 50 }
|
||||
Auto3 = { units = { ['ltnk'] = 1, ['bggy'] = 1 }, waypoints = WaypointGroup3, delay = 50 }
|
||||
Auto4 = { units = { ['bggy'] = 2 }, waypoints = WaypointGroup7, delay = 50 }
|
||||
Auto5 = { units = { ['ltnk'] = 1 }, waypoints = WaypointGroup6, delay = 50 }
|
||||
Auto6 = { units = { ['arty'] = 1 }, waypoints = WaypointGroup4, delay = 50 }
|
||||
Auto7 = { units = { ['e3'] = 3, ['e4'] = 2 }, waypoints = WaypointGroup6, delay = 50 }
|
||||
|
||||
AutoAttackWaves = { Atk1, Atk2, Nod1, Nod2, Nod3, Nod4, Nod5, Nod6, Nod7, Nod8, Auto1, Auto2, Auto3, Auto4, Auto5, Auto6, Auto7 }
|
||||
|
||||
StationaryGuardUnits = { Actor181, Actor182, Actor183, Actor184, Actor198, Actor199, Actor157, Actor175, Actor176, Actor173, Actor174, Actor158, Actor200, Actor159, Actor179, Actor180, Actor184, Actor185, Actor216, Actor217, Actor153, Actor215, Actor214, Actor213}
|
||||
|
||||
DamagedGDIAssets = { Actor126, Actor127, Actor128, Actor129, Actor130,Actor131, Actor132, Actor133, Actor134, Actor135, Actor136, Actor137, Actor138, Actor160, Actor161, Actor162, Actor163, Actor164, Actor165, Actor166, Actor168, Actor169, Actor170}
|
||||
|
||||
StartStationaryGuards = function(StationaryGuards)
|
||||
Utils.Do(StationaryGuards, function(unit)
|
||||
if not unit.IsDead then
|
||||
unit.Patrol( { unit.Location } , true, 20)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
SendWaves = function(counter, Waves)
|
||||
if counter <= #Waves then
|
||||
local team = Waves[counter]
|
||||
|
||||
for type, amount in pairs(team.units) do
|
||||
MoveAndHunt(Utils.Take(amount, Nod.GetActorsByType(type)), team.waypoints)
|
||||
end
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(team.delay), function() SendWaves(counter + 1, Waves) end)
|
||||
end
|
||||
end
|
||||
|
||||
SendAttackWave = function(team)
|
||||
for type, amount in pairs(team.units) do
|
||||
count = 0
|
||||
local actors = Nod.GetActorsByType(type)
|
||||
Utils.Do(actors, function(actor)
|
||||
if actor.IsIdle and count < amount then
|
||||
SetAttackWaypoints(actor, team.waypoints)
|
||||
IdleHunt(actor)
|
||||
count = count + 1
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
SetAttackWaypoints = function(actor, waypoints)
|
||||
if not actor.IsDead then
|
||||
Utils.Do(waypoints, function(waypoint)
|
||||
actor.AttackMove(waypoint.Location)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
CeckRepairGDIAssetsObjective = function()
|
||||
local failed = false
|
||||
local repaired = true
|
||||
Utils.Do(DamagedGDIAssets, function(actor)
|
||||
if actor.IsDead then
|
||||
failed = true
|
||||
elseif actor.Health < actor.MaxHealth then
|
||||
repaired = false
|
||||
end
|
||||
end)
|
||||
|
||||
if failed then
|
||||
GDI.MarkFailedObjective(RepairAssets)
|
||||
return
|
||||
elseif repaired then
|
||||
GDI.MarkCompletedObjective(RepairAssets)
|
||||
return
|
||||
end
|
||||
Trigger.AfterDelay(DateTime.Seconds(3), function() CeckRepairGDIAssetsObjective() end)
|
||||
end
|
||||
|
||||
WorldLoaded = function()
|
||||
GDI = Player.GetPlayer("GDI")
|
||||
Nod = Player.GetPlayer("Nod")
|
||||
|
||||
Camera.Position = DefaultCameraPosition.CenterPosition
|
||||
|
||||
StartStationaryGuards(StationaryGuardUnits)
|
||||
|
||||
StartAI()
|
||||
|
||||
InitObjectives(GDI)
|
||||
|
||||
SecureArea = GDI.AddObjective("Destroy the Nod strike force.")
|
||||
KillGDI = Nod.AddObjective("Kill all enemies!")
|
||||
|
||||
RepairAssets = GDI.AddObjective("Repair GDI base and vehicles.", "Secondary", false)
|
||||
Trigger.AfterDelay(DateTime.Seconds(5), function() CeckRepairGDIAssetsObjective() end)
|
||||
|
||||
AirSupport = GDI.AddObjective("Destroy the SAM sites to receive air support.", "Secondary", false)
|
||||
Trigger.OnAllKilled(SamSites, function()
|
||||
GDI.MarkCompletedObjective(AirSupport)
|
||||
Actor.Create("airstrike.proxy", true, { Owner = GDI })
|
||||
end)
|
||||
|
||||
local InitialArrivingUnits = { Actor166 }
|
||||
Utils.Do(InitialArrivingUnits, function(unit)
|
||||
unit.Move(unit.Location + CVec.New(1, 1), 0)
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Minutes(1), function() SendWaves(1, AutoAttackWaves) end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), function() ProduceInfantry(handofnod) end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(2), function() ProduceVehicle(nodairfield) end)
|
||||
end
|
||||
|
||||
Tick = function()
|
||||
if DateTime.GameTime > DateTime.Seconds(5) then
|
||||
if GDI.HasNoRequiredUnits() then
|
||||
Nod.MarkCompletedObjective(KillGDI)
|
||||
end
|
||||
if Nod.HasNoRequiredUnits() then
|
||||
GDI.MarkCompletedObjective(SecureArea)
|
||||
end
|
||||
end
|
||||
end
|
||||
BIN
mods/cnc/maps/gdi08a/map.bin
Normal file
BIN
mods/cnc/maps/gdi08a/map.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
886
mods/cnc/maps/gdi08a/map.yaml
Normal file
@@ -0,0 +1,886 @@
|
||||
MapFormat: 11
|
||||
|
||||
RequiresMod: cnc
|
||||
|
||||
Title: 08a: Restore GDI Presence Near Salzburg
|
||||
|
||||
Author: Westwood Studios
|
||||
|
||||
Tileset: WINTER
|
||||
|
||||
MapSize: 64,64
|
||||
|
||||
Bounds: 3,7,51,50
|
||||
|
||||
Visibility: MissionSelector
|
||||
|
||||
Categories: Campaign
|
||||
|
||||
LockPreview: True
|
||||
|
||||
Players:
|
||||
PlayerReference@Neutral:
|
||||
Name: Neutral
|
||||
OwnsWorld: True
|
||||
NonCombatant: True
|
||||
Faction: gdi
|
||||
PlayerReference@Nod:
|
||||
Name: Nod
|
||||
Faction: nod
|
||||
Color: FF1400
|
||||
Allies: Nod
|
||||
Enemies: GDI
|
||||
Bot: campaign
|
||||
PlayerReference@GDI:
|
||||
Name: GDI
|
||||
AllowBots: False
|
||||
Playable: True
|
||||
Required: True
|
||||
LockFaction: True
|
||||
Faction: gdi
|
||||
LockColor: True
|
||||
Color: F5D378
|
||||
LockSpawn: True
|
||||
LockTeam: True
|
||||
Allies: GDI
|
||||
Enemies: Nod
|
||||
|
||||
Actors:
|
||||
Actor0: sbag
|
||||
Location: 53,56
|
||||
Owner: Neutral
|
||||
Actor1: sbag
|
||||
Location: 52,56
|
||||
Owner: Neutral
|
||||
Actor2: sbag
|
||||
Location: 51,56
|
||||
Owner: Neutral
|
||||
Actor3: sbag
|
||||
Location: 50,56
|
||||
Owner: Neutral
|
||||
Actor4: sbag
|
||||
Location: 49,56
|
||||
Owner: Neutral
|
||||
Actor5: sbag
|
||||
Location: 48,56
|
||||
Owner: Neutral
|
||||
Actor6: sbag
|
||||
Location: 47,56
|
||||
Owner: Neutral
|
||||
Actor7: sbag
|
||||
Location: 46,56
|
||||
Owner: Neutral
|
||||
Actor8: sbag
|
||||
Location: 45,56
|
||||
Owner: Neutral
|
||||
Actor9: sbag
|
||||
Location: 44,56
|
||||
Owner: Neutral
|
||||
Actor10: sbag
|
||||
Location: 43,56
|
||||
Owner: Neutral
|
||||
Actor11: sbag
|
||||
Location: 41,56
|
||||
Owner: Neutral
|
||||
Actor12: sbag
|
||||
Location: 40,56
|
||||
Owner: Neutral
|
||||
Actor13: wood
|
||||
Location: 5,56
|
||||
Owner: Neutral
|
||||
Actor14: wood
|
||||
Location: 4,56
|
||||
Owner: Neutral
|
||||
Actor15: wood
|
||||
Location: 3,56
|
||||
Owner: Neutral
|
||||
Actor16: sbag
|
||||
Location: 53,55
|
||||
Owner: Neutral
|
||||
Actor17: sbag
|
||||
Location: 40,55
|
||||
Owner: Neutral
|
||||
Actor18: v18
|
||||
Location: 5,55
|
||||
Owner: Neutral
|
||||
Actor19: v17
|
||||
Location: 4,55
|
||||
Owner: Neutral
|
||||
Actor20: sbag
|
||||
Location: 53,54
|
||||
Owner: Neutral
|
||||
Actor21: sbag
|
||||
Location: 40,54
|
||||
Owner: Neutral
|
||||
Actor22: wood
|
||||
Location: 17,54
|
||||
Owner: Neutral
|
||||
Actor23: wood
|
||||
Location: 16,54
|
||||
Owner: Neutral
|
||||
Actor24: wood
|
||||
Location: 15,54
|
||||
Owner: Neutral
|
||||
Actor25: wood
|
||||
Location: 14,54
|
||||
Owner: Neutral
|
||||
Actor26: wood
|
||||
Location: 11,54
|
||||
Owner: Neutral
|
||||
Actor27: wood
|
||||
Location: 10,54
|
||||
Owner: Neutral
|
||||
Actor28: v14
|
||||
Location: 6,54
|
||||
Owner: Neutral
|
||||
Actor29: v15
|
||||
Location: 5,54
|
||||
Owner: Neutral
|
||||
Actor30: v16
|
||||
Location: 4,54
|
||||
Owner: Neutral
|
||||
Actor31: sbag
|
||||
Location: 53,53
|
||||
Owner: Neutral
|
||||
Actor32: wood
|
||||
Location: 6,53
|
||||
Owner: Neutral
|
||||
Actor33: wood
|
||||
Location: 17,52
|
||||
Owner: Neutral
|
||||
Actor34: wood
|
||||
Location: 16,52
|
||||
Owner: Neutral
|
||||
Actor35: wood
|
||||
Location: 15,52
|
||||
Owner: Neutral
|
||||
Actor36: wood
|
||||
Location: 14,52
|
||||
Owner: Neutral
|
||||
Actor37: wood
|
||||
Location: 11,52
|
||||
Owner: Neutral
|
||||
Actor38: wood
|
||||
Location: 10,52
|
||||
Owner: Neutral
|
||||
Actor39: sbag
|
||||
Location: 53,51
|
||||
Owner: Neutral
|
||||
Actor40: sbag
|
||||
Location: 53,50
|
||||
Owner: Neutral
|
||||
Actor41: sbag
|
||||
Location: 40,50
|
||||
Owner: Neutral
|
||||
Actor42: sbag
|
||||
Location: 53,49
|
||||
Owner: Neutral
|
||||
Actor43: sbag
|
||||
Location: 40,49
|
||||
Owner: Neutral
|
||||
Actor44: sbag
|
||||
Location: 53,48
|
||||
Owner: Neutral
|
||||
Actor45: sbag
|
||||
Location: 53,47
|
||||
Owner: Neutral
|
||||
Actor46: sbag
|
||||
Location: 40,47
|
||||
Owner: Neutral
|
||||
Actor47: sbag
|
||||
Location: 53,46
|
||||
Owner: Neutral
|
||||
Actor48: sbag
|
||||
Location: 52,46
|
||||
Owner: Neutral
|
||||
Actor49: sbag
|
||||
Location: 51,46
|
||||
Owner: Neutral
|
||||
Actor50: sbag
|
||||
Location: 50,46
|
||||
Owner: Neutral
|
||||
Actor51: sbag
|
||||
Location: 49,46
|
||||
Owner: Neutral
|
||||
Actor52: sbag
|
||||
Location: 48,46
|
||||
Owner: Neutral
|
||||
Actor53: sbag
|
||||
Location: 42,46
|
||||
Owner: Neutral
|
||||
Actor54: sbag
|
||||
Location: 41,46
|
||||
Owner: Neutral
|
||||
Actor55: sbag
|
||||
Location: 40,46
|
||||
Owner: Neutral
|
||||
Actor56: t01
|
||||
Location: 33,32
|
||||
Owner: Neutral
|
||||
Actor57: t01
|
||||
Location: 33,34
|
||||
Owner: Neutral
|
||||
Actor58: tc01
|
||||
Location: 47,27
|
||||
Owner: Neutral
|
||||
Actor59: t01
|
||||
Location: 42,18
|
||||
Owner: Neutral
|
||||
Actor60: t01
|
||||
Location: 41,16
|
||||
Owner: Neutral
|
||||
Actor61: t01
|
||||
Location: 36,18
|
||||
Owner: Neutral
|
||||
Actor62: t01
|
||||
Location: 15,50
|
||||
Owner: Neutral
|
||||
Actor63: t01
|
||||
Location: 6,54
|
||||
Owner: Neutral
|
||||
Actor64: t01
|
||||
Location: 11,48
|
||||
Owner: Neutral
|
||||
Actor65: tc01
|
||||
Location: 14,33
|
||||
Owner: Neutral
|
||||
Actor66: tc04
|
||||
Location: 17,35
|
||||
Owner: Neutral
|
||||
Actor67: tc01
|
||||
Location: 9,19
|
||||
Owner: Neutral
|
||||
Actor68: tc04
|
||||
Location: 11,20
|
||||
Owner: Neutral
|
||||
Actor69: t06
|
||||
Location: 37,8
|
||||
Owner: Neutral
|
||||
Actor70: t03
|
||||
Location: 33,8
|
||||
Owner: Neutral
|
||||
Actor71: t02
|
||||
Location: 36,9
|
||||
Owner: Neutral
|
||||
Actor72: t01
|
||||
Location: 32,7
|
||||
Owner: Neutral
|
||||
Actor73: tc04
|
||||
Location: 50,9
|
||||
Owner: Neutral
|
||||
Actor74: tc01
|
||||
Location: 45,7
|
||||
Owner: Neutral
|
||||
Actor75: tc01
|
||||
Location: 38,13
|
||||
Owner: Neutral
|
||||
Actor76: tc02
|
||||
Location: 35,22
|
||||
Owner: Neutral
|
||||
Actor77: tc05
|
||||
Location: 32,21
|
||||
Owner: Neutral
|
||||
Actor78: t10
|
||||
Location: 17,47
|
||||
Owner: Neutral
|
||||
Actor79: t13
|
||||
Location: 16,50
|
||||
Owner: Neutral
|
||||
Actor80: tc01
|
||||
Location: 15,48
|
||||
Owner: Neutral
|
||||
Actor81: tc02
|
||||
Location: 6,51
|
||||
Owner: Neutral
|
||||
Actor82: tc02
|
||||
Location: 3,47
|
||||
Owner: Neutral
|
||||
Actor83: tc04
|
||||
Location: 3,51
|
||||
Owner: Neutral
|
||||
Actor84: tc04
|
||||
Location: 5,47
|
||||
Owner: Neutral
|
||||
Actor85: tc04
|
||||
Location: 9,54
|
||||
Owner: Neutral
|
||||
Actor86: tc04
|
||||
Location: 3,40
|
||||
Owner: Neutral
|
||||
Actor87: t13
|
||||
Location: 4,42
|
||||
Owner: Neutral
|
||||
Actor88: t11
|
||||
Location: 10,12
|
||||
Owner: Neutral
|
||||
Actor89: t15
|
||||
Location: 4,10
|
||||
Owner: Neutral
|
||||
Actor90: t16
|
||||
Location: 3,9
|
||||
Owner: Neutral
|
||||
Actor91: tc02
|
||||
Location: 5,12
|
||||
Owner: Neutral
|
||||
Actor92: tc01
|
||||
Location: 4,7
|
||||
Owner: Neutral
|
||||
Actor93: tc04
|
||||
Location: 20,11
|
||||
Owner: Neutral
|
||||
Actor94: tc04
|
||||
Location: 19,47
|
||||
Owner: Neutral
|
||||
Actor95: tc05
|
||||
Location: 20,49
|
||||
Owner: Neutral
|
||||
Actor96: tc04
|
||||
Location: 40,17
|
||||
Owner: Neutral
|
||||
Actor97: tc01
|
||||
Location: 44,36
|
||||
Owner: Neutral
|
||||
Actor98: tc04
|
||||
Location: 39,37
|
||||
Owner: Neutral
|
||||
Actor99: tc02
|
||||
Location: 40,30
|
||||
Owner: Neutral
|
||||
Actor100: tc02
|
||||
Location: 30,32
|
||||
Owner: Neutral
|
||||
Actor101: t10
|
||||
Location: 32,33
|
||||
Owner: Neutral
|
||||
Actor102: tc04
|
||||
Location: 37,54
|
||||
Owner: Neutral
|
||||
Actor103: tc02
|
||||
Location: 34,53
|
||||
Owner: Neutral
|
||||
Actor104: t01
|
||||
Location: 31,53
|
||||
Owner: Neutral
|
||||
Actor105: t01
|
||||
Location: 16,54
|
||||
Owner: Neutral
|
||||
Actor106: t02
|
||||
Location: 18,55
|
||||
Owner: Neutral
|
||||
Actor107: t11
|
||||
Location: 25,32
|
||||
Owner: Neutral
|
||||
Actor108: t11
|
||||
Location: 41,44
|
||||
Owner: Neutral
|
||||
Actor109: tc01
|
||||
Location: 51,44
|
||||
Owner: Neutral
|
||||
Actor110: tc04
|
||||
Location: 27,40
|
||||
Owner: Neutral
|
||||
Actor111: tc05
|
||||
Location: 30,42
|
||||
Owner: Neutral
|
||||
Actor112: t07
|
||||
Location: 31,39
|
||||
Owner: Neutral
|
||||
Actor113: t06
|
||||
Location: 26,42
|
||||
Owner: Neutral
|
||||
Actor114: t03
|
||||
Location: 28,43
|
||||
Owner: Neutral
|
||||
sam1: sam
|
||||
Location: 11,20
|
||||
Owner: Nod
|
||||
sam2: sam
|
||||
Location: 33,18
|
||||
Owner: Nod
|
||||
sam3: sam
|
||||
Location: 16,7
|
||||
Owner: Nod
|
||||
Actor118: v05
|
||||
Location: 17,49
|
||||
Owner: Neutral
|
||||
Actor119: v07
|
||||
Location: 9,49
|
||||
Owner: Neutral
|
||||
Actor120: v06
|
||||
Location: 4,53
|
||||
Owner: Neutral
|
||||
Actor121: v05
|
||||
Location: 6,49
|
||||
Owner: Neutral
|
||||
Actor122: v04
|
||||
Location: 4,50
|
||||
Owner: Neutral
|
||||
Actor123: v03
|
||||
Location: 10,50
|
||||
Owner: Neutral
|
||||
Actor124: v01
|
||||
Location: 3,48
|
||||
Owner: Neutral
|
||||
Actor125: v06
|
||||
Location: 20,49
|
||||
Owner: Neutral
|
||||
Actor126: gtwr
|
||||
Location: 41,54
|
||||
Owner: GDI
|
||||
Health: 41
|
||||
Actor127: gtwr
|
||||
Location: 41,50
|
||||
Owner: GDI
|
||||
Health: 16
|
||||
Actor128: hq
|
||||
Location: 51,47
|
||||
Owner: GDI
|
||||
Health: 39
|
||||
Actor129: proc
|
||||
Location: 44,46
|
||||
Owner: GDI
|
||||
Health: 33
|
||||
FreeActor: False
|
||||
Actor130: silo
|
||||
Location: 49,54
|
||||
Owner: GDI
|
||||
Health: 53
|
||||
Actor131: silo
|
||||
Location: 47,47
|
||||
Owner: GDI
|
||||
Health: 20
|
||||
Actor132: silo
|
||||
Location: 47,53
|
||||
Owner: GDI
|
||||
Health: 13
|
||||
Actor133: silo
|
||||
Location: 51,54
|
||||
Owner: GDI
|
||||
Health: 28
|
||||
Actor134: nuke
|
||||
Location: 49,51
|
||||
Owner: GDI
|
||||
Health: 14
|
||||
Actor135: nuke
|
||||
Location: 49,48
|
||||
Owner: GDI
|
||||
Health: 20
|
||||
Actor136: nuke
|
||||
Location: 51,50
|
||||
Owner: GDI
|
||||
Health: 35
|
||||
Actor137: pyle
|
||||
Location: 47,49
|
||||
Owner: GDI
|
||||
Health: 18
|
||||
Actor138: fix
|
||||
Location: 44,52
|
||||
Owner: GDI
|
||||
Health: 28
|
||||
gun1: gun
|
||||
Location: 21,19
|
||||
Owner: Nod
|
||||
NodYard: fact
|
||||
Location: 7,11
|
||||
Owner: Nod
|
||||
nodrefinery: proc
|
||||
Location: 24,16
|
||||
Owner: Nod
|
||||
FreeActor: False
|
||||
nodsilo1: silo
|
||||
Location: 29,17
|
||||
Owner: Nod
|
||||
nodsilo2: silo
|
||||
Location: 9,7
|
||||
Owner: Nod
|
||||
nodsilo3: silo
|
||||
Location: 12,9
|
||||
Owner: Nod
|
||||
nodsilo4: silo
|
||||
Location: 11,7
|
||||
Owner: Nod
|
||||
nodairfield: afld
|
||||
Location: 27,14
|
||||
Owner: Nod
|
||||
nodpower1: nuke
|
||||
Location: 23,14
|
||||
Owner: Nod
|
||||
nodpower2: nuke
|
||||
Location: 10,9
|
||||
Owner: Nod
|
||||
nodpower3: nuke
|
||||
Location: 6,8
|
||||
Owner: Nod
|
||||
nodpower4: nuke
|
||||
Location: 8,8
|
||||
Owner: Nod
|
||||
handofnod: hand
|
||||
Location: 27,17
|
||||
Owner: Nod
|
||||
gun2: gun
|
||||
Location: 26,21
|
||||
Owner: Nod
|
||||
Actor153: arty
|
||||
Location: 4,12
|
||||
Owner: Nod
|
||||
Facing: 127
|
||||
Actor154: bggy
|
||||
Location: 20,18
|
||||
Owner: Nod
|
||||
Actor155: ltnk
|
||||
Location: 19,18
|
||||
Owner: Nod
|
||||
Actor156: bggy
|
||||
Location: 10,21
|
||||
Owner: Nod
|
||||
Facing: 95
|
||||
Actor157: ltnk
|
||||
Location: 40,35
|
||||
Owner: Nod
|
||||
Facing: 159
|
||||
Actor158: ltnk
|
||||
Location: 45,23
|
||||
Owner: Nod
|
||||
Facing: 95
|
||||
Actor159: ltnk
|
||||
Location: 41,14
|
||||
Owner: Nod
|
||||
Facing: 159
|
||||
Actor160: mtnk
|
||||
Location: 42,55
|
||||
Owner: GDI
|
||||
Health: 35
|
||||
Facing: 223
|
||||
Actor161: mtnk
|
||||
Location: 33,52
|
||||
Owner: GDI
|
||||
Health: 43
|
||||
Facing: 31
|
||||
Actor162: apc
|
||||
Location: 37,50
|
||||
Owner: GDI
|
||||
Health: 68
|
||||
Facing: 127
|
||||
Actor163: apc
|
||||
Location: 39,48
|
||||
Owner: GDI
|
||||
Health: 45
|
||||
Facing: 127
|
||||
Actor164: msam
|
||||
Location: 42,49
|
||||
Owner: GDI
|
||||
Health: 40
|
||||
Facing: 95
|
||||
Actor165: msam
|
||||
Location: 41,51
|
||||
Owner: GDI
|
||||
Health: 50
|
||||
Facing: 159
|
||||
Actor166: msam
|
||||
Location: 33,48
|
||||
Owner: GDI
|
||||
Health: 65
|
||||
Facing: 159
|
||||
Actor167: harv
|
||||
Location: 23,23
|
||||
Owner: Nod
|
||||
Facing: 95
|
||||
Actor168: harv
|
||||
Location: 38,53
|
||||
Owner: GDI
|
||||
Health: 51
|
||||
Facing: 31
|
||||
Actor169: jeep
|
||||
Location: 36,52
|
||||
Owner: GDI
|
||||
Health: 72
|
||||
Facing: 95
|
||||
Actor170: jeep
|
||||
Location: 34,51
|
||||
Owner: GDI
|
||||
Health: 31
|
||||
Facing: 159
|
||||
Actor171: arty
|
||||
Location: 19,17
|
||||
Owner: Nod
|
||||
Actor172: ltnk
|
||||
Location: 22,11
|
||||
Owner: Nod
|
||||
Facing: 159
|
||||
Actor173: e1
|
||||
Location: 45,36
|
||||
Owner: Nod
|
||||
SubCell: 3
|
||||
Actor174: e1
|
||||
Location: 44,36
|
||||
Owner: Nod
|
||||
SubCell: 4
|
||||
Actor175: e3
|
||||
Location: 41,36
|
||||
Owner: Nod
|
||||
Facing: 159
|
||||
SubCell: 2
|
||||
Actor176: e3
|
||||
Location: 41,36
|
||||
Owner: Nod
|
||||
Facing: 159
|
||||
SubCell: 3
|
||||
Actor177: e3
|
||||
Location: 42,17
|
||||
Owner: Nod
|
||||
Facing: 159
|
||||
SubCell: 0
|
||||
Actor178: e3
|
||||
Location: 40,17
|
||||
Owner: Nod
|
||||
Facing: 159
|
||||
SubCell: 4
|
||||
Actor179: e4
|
||||
Location: 42,15
|
||||
Owner: Nod
|
||||
Facing: 159
|
||||
SubCell: 2
|
||||
Actor180: e4
|
||||
Location: 42,15
|
||||
Owner: Nod
|
||||
Facing: 159
|
||||
SubCell: 3
|
||||
Actor181: e1
|
||||
Location: 16,53
|
||||
Owner: Nod
|
||||
Facing: 191
|
||||
SubCell: 3
|
||||
Actor182: e1
|
||||
Location: 15,53
|
||||
Owner: Nod
|
||||
Facing: 191
|
||||
SubCell: 2
|
||||
Actor183: e1
|
||||
Location: 17,53
|
||||
Owner: Nod
|
||||
Facing: 191
|
||||
SubCell: 3
|
||||
Actor184: e1
|
||||
Location: 16,53
|
||||
Owner: Nod
|
||||
Facing: 191
|
||||
SubCell: 2
|
||||
Actor185: c3
|
||||
Location: 18,50
|
||||
Owner: Neutral
|
||||
Facing: 159
|
||||
SubCell: 1
|
||||
Actor186: e1
|
||||
Location: 46,51
|
||||
Owner: GDI
|
||||
Facing: 159
|
||||
SubCell: 1
|
||||
Actor187: e1
|
||||
Location: 44,52
|
||||
Owner: GDI
|
||||
Health: 87
|
||||
Facing: 223
|
||||
SubCell: 2
|
||||
Actor188: e1
|
||||
Location: 43,53
|
||||
Owner: GDI
|
||||
Health: 31
|
||||
Facing: 31
|
||||
SubCell: 4
|
||||
Actor189: e1
|
||||
Location: 42,54
|
||||
Owner: GDI
|
||||
Health: 75
|
||||
SubCell: 2
|
||||
Actor190: e1
|
||||
Location: 39,52
|
||||
Owner: GDI
|
||||
Health: 77
|
||||
Facing: 159
|
||||
SubCell: 4
|
||||
Actor191: e1
|
||||
Location: 42,53
|
||||
Owner: GDI
|
||||
Health: 69
|
||||
Facing: 159
|
||||
SubCell: 0
|
||||
Actor192: e2
|
||||
Location: 40,53
|
||||
Owner: GDI
|
||||
Health: 75
|
||||
Facing: 31
|
||||
SubCell: 2
|
||||
Actor193: e2
|
||||
Location: 45,51
|
||||
Owner: GDI
|
||||
Facing: 127
|
||||
SubCell: 1
|
||||
Actor194: e2
|
||||
Location: 38,50
|
||||
Owner: GDI
|
||||
Health: 27
|
||||
Facing: 223
|
||||
SubCell: 0
|
||||
Actor195: e2
|
||||
Location: 46,52
|
||||
Owner: GDI
|
||||
Facing: 31
|
||||
SubCell: 1
|
||||
Actor196: e2
|
||||
Location: 36,53
|
||||
Owner: GDI
|
||||
Health: 57
|
||||
Facing: 159
|
||||
SubCell: 0
|
||||
Actor197: e2
|
||||
Location: 37,54
|
||||
Owner: GDI
|
||||
Facing: 31
|
||||
SubCell: 1
|
||||
Actor198: e3
|
||||
Location: 27,40
|
||||
Owner: Nod
|
||||
SubCell: 4
|
||||
Actor199: e3
|
||||
Location: 29,40
|
||||
Owner: Nod
|
||||
SubCell: 3
|
||||
Actor200: e3
|
||||
Location: 48,27
|
||||
Owner: Nod
|
||||
SubCell: 3
|
||||
Actor201: e1
|
||||
Location: 27,21
|
||||
Owner: Nod
|
||||
SubCell: 3
|
||||
Actor202: e1
|
||||
Location: 27,21
|
||||
Owner: Nod
|
||||
SubCell: 4
|
||||
Actor203: e1
|
||||
Location: 27,21
|
||||
Owner: Nod
|
||||
SubCell: 2
|
||||
Actor204: e1
|
||||
Location: 27,21
|
||||
Owner: Nod
|
||||
SubCell: 1
|
||||
Actor205: e3
|
||||
Location: 28,21
|
||||
Owner: Nod
|
||||
SubCell: 4
|
||||
Actor206: e3
|
||||
Location: 28,21
|
||||
Owner: Nod
|
||||
SubCell: 2
|
||||
Actor207: e3
|
||||
Location: 29,21
|
||||
Owner: Nod
|
||||
SubCell: 1
|
||||
Actor208: e3
|
||||
Location: 29,21
|
||||
Owner: Nod
|
||||
SubCell: 3
|
||||
Actor209: e4
|
||||
Location: 30,21
|
||||
Owner: Nod
|
||||
SubCell: 1
|
||||
Actor210: e4
|
||||
Location: 30,21
|
||||
Owner: Nod
|
||||
SubCell: 3
|
||||
Actor211: e4
|
||||
Location: 30,21
|
||||
Owner: Nod
|
||||
SubCell: 2
|
||||
Actor212: e4
|
||||
Location: 30,21
|
||||
Owner: Nod
|
||||
SubCell: 4
|
||||
Actor213: e1
|
||||
Location: 13,12
|
||||
Owner: Nod
|
||||
SubCell: 3
|
||||
Actor214: e1
|
||||
Location: 14,12
|
||||
Owner: Nod
|
||||
SubCell: 1
|
||||
Actor215: e1
|
||||
Location: 15,11
|
||||
Owner: Nod
|
||||
SubCell: 0
|
||||
Actor216: e3
|
||||
Location: 5,7
|
||||
Owner: Nod
|
||||
SubCell: 3
|
||||
Actor217: e3
|
||||
Location: 7,7
|
||||
Owner: Nod
|
||||
SubCell: 3
|
||||
Actor218: e3
|
||||
Location: 19,15
|
||||
Owner: Nod
|
||||
SubCell: 1
|
||||
Actor219: e3
|
||||
Location: 20,16
|
||||
Owner: Nod
|
||||
SubCell: 1
|
||||
DefaultChinookTarget: waypoint
|
||||
Location: 41,56
|
||||
Owner: Neutral
|
||||
DefaultCameraPosition: waypoint
|
||||
Location: 41,49
|
||||
Owner: Neutral
|
||||
waypoint16: waypoint
|
||||
Location: 10,22
|
||||
Owner: Neutral
|
||||
waypoint15: waypoint
|
||||
Location: 53,45
|
||||
Owner: Neutral
|
||||
waypoint14: waypoint
|
||||
Location: 53,40
|
||||
Owner: Neutral
|
||||
waypoint13: waypoint
|
||||
Location: 13,26
|
||||
Owner: Neutral
|
||||
waypoint12: waypoint
|
||||
Location: 52,25
|
||||
Owner: Neutral
|
||||
waypoint11: waypoint
|
||||
Location: 36,27
|
||||
Owner: Neutral
|
||||
waypoint10: waypoint
|
||||
Location: 38,32
|
||||
Owner: Neutral
|
||||
waypoint9: waypoint
|
||||
Location: 47,43
|
||||
Owner: Neutral
|
||||
waypoint8: waypoint
|
||||
Location: 24,55
|
||||
Owner: Neutral
|
||||
waypoint7: waypoint
|
||||
Location: 43,40
|
||||
Owner: Neutral
|
||||
waypoint6: waypoint
|
||||
Location: 24,38
|
||||
Owner: Neutral
|
||||
waypoint5: waypoint
|
||||
Location: 20,29
|
||||
Owner: Neutral
|
||||
waypoint4: waypoint
|
||||
Location: 23,24
|
||||
Owner: Neutral
|
||||
waypoint3: waypoint
|
||||
Location: 5,43
|
||||
Owner: Neutral
|
||||
waypoint2: waypoint
|
||||
Location: 8,47
|
||||
Owner: Neutral
|
||||
waypoint1: waypoint
|
||||
Location: 8,53
|
||||
Owner: Neutral
|
||||
waypoint0: waypoint
|
||||
Location: 19,53
|
||||
Owner: Neutral
|
||||
|
||||
Rules: cnc|rules/campaign-maprules.yaml, cnc|rules/campaign-tooltips.yaml, cnc|rules/campaign-palettes.yaml, rules.yaml
|
||||
154
mods/cnc/maps/gdi08a/rules.yaml
Normal file
@@ -0,0 +1,154 @@
|
||||
World:
|
||||
LuaScript:
|
||||
Scripts: campaign-global.lua, gdi08a.lua, gdi08a-AI.lua
|
||||
MusicPlaylist:
|
||||
StartingMusic: march
|
||||
VictoryMusic: gdi_win1
|
||||
MissionData:
|
||||
Briefing: U.N. Sanction has cut funding to the Global Defense Initiative. Field Units are helpless.\n\nUse the repair facility to keep your units in the field long enough to destroy the Nod base in this region.\n\nAll Nod units and structures must be destroyed.
|
||||
BriefingVideo: gdi8a.vqa
|
||||
BackgroundVideo: tbrinfo1.vqa
|
||||
WinVideo: paratrop.vqa
|
||||
LossVideo: gameover.vqa
|
||||
SmudgeLayer@SCORCH:
|
||||
InitialSmudges:
|
||||
42,56: sc1,0
|
||||
41,52: sc6,0
|
||||
38,51: sc2,0
|
||||
43,50: sc3,0
|
||||
40,48: sc4,0
|
||||
47,46: sc5,0
|
||||
|
||||
ATWR:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
NUK2:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
HPAD:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
BRIK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
EYE:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
OBLI:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
TMPL:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
HTNK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
TRAN:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
ORCA:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
RMBO:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MSAM:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MCV:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
BOAT:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
FTNK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
STNK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
HELI:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
LTNK:
|
||||
Buildable:
|
||||
Prerequisites: ~afld
|
||||
|
||||
ARTY:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
E4:
|
||||
Buildable:
|
||||
Prerequisites: barracks
|
||||
|
||||
E5:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MLRS:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
CYCL:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
GTWR:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
SBAG:
|
||||
Buildable:
|
||||
Queue: Defence.GDI, Defence.Nod
|
||||
|
||||
GUN:
|
||||
Buildable:
|
||||
Queue: Defence.GDI, Defence.Nod
|
||||
|
||||
C3:
|
||||
Tooltip:
|
||||
Name: Farmer Mike
|
||||
|
||||
SAM:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
^Bridge:
|
||||
DamageMultiplier@INVULNERABLE:
|
||||
Modifier: 0
|
||||
|
||||
BRIDGEHUT:
|
||||
-Targetable:
|
||||
|
||||
airstrike.proxy:
|
||||
AirstrikePower:
|
||||
SquadSize: 2
|
||||
SquadOffset: -1536, 1024, 0
|
||||
|
||||
HQ:
|
||||
Tooltip:
|
||||
-AirstrikePower:
|
||||
Buildable:
|
||||
Description: Provides an overview of the battlefield.\n Requires power to operate.
|
||||
|
||||
AFLD:
|
||||
RallyPoint:
|
||||
Offset: -5, 2
|
||||
204
mods/cnc/maps/gdi09/gdi09-AI.lua
Normal file
@@ -0,0 +1,204 @@
|
||||
--[[
|
||||
Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
|
||||
This file is part of OpenRA, which is free software. It is made
|
||||
available to you under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version. For more
|
||||
information, see COPYING.
|
||||
]]
|
||||
|
||||
AttackPaths = { { waypoint7 }, { waypoint8 } }
|
||||
NodBase = { handofnod, nodairfield, nodrefinery, NodCYard, nodpower1, nodpower2, nodpower3, nodpower4, nodpower5, gun5, gun6, gun7, gun8, nodsilo1, nodsilo2, nodsilo3, nodsilo4, nodobelisk }
|
||||
|
||||
PatrolProductionQueue = { }
|
||||
InfantryAttackGroup = { }
|
||||
InfantryGroupSize = 5
|
||||
InfantryProductionCooldown = DateTime.Minutes(3)
|
||||
InfantryProductionTypes = { "e1", "e1", "e1", "e3", "e3", "e4" }
|
||||
HarvesterProductionType = { "harv" }
|
||||
VehicleAttackGroup = { }
|
||||
VehicleGroupSize = 5
|
||||
VehicleProductionCooldown = DateTime.Minutes(3)
|
||||
VehicleProductionTypes = { "bggy", "bggy", "bggy", "ltnk", "ltnk", "arty" }
|
||||
StartingCash = 14000
|
||||
|
||||
BaseRefinery = { type = "proc", pos = CPos.New(12, 25) }
|
||||
BaseNuke1 = { type = "nuke", pos = CPos.New(5, 24) }
|
||||
BaseNuke2 = { type = "nuke", pos = CPos.New(3, 24) }
|
||||
BaseNuke3 = { type = "nuke", pos = CPos.New(16, 30) }
|
||||
BaseNuke4 = { type = "nuke", pos = CPos.New(14, 30) }
|
||||
BaseNuke5 = { type = "nuke", pos = CPos.New(12, 30) }
|
||||
InfantryProduction = { type = "hand", pos = CPos.New(15, 24) }
|
||||
VehicleProduction = { type = "afld", pos = CPos.New(3, 27) }
|
||||
|
||||
NodGuards = { Actor168, Actor169, Actor170, Actor171, Actor172, Actor181, Actor177, Actor188, Actor189, Actor190 }
|
||||
|
||||
BaseBuildings = { BaseRefinery, BaseNuke1, BaseNuke2, BaseNuke3, BaseNuke4, InfantryProduction, VehicleProduction }
|
||||
|
||||
BuildBuilding = function(building, cyard)
|
||||
local buildingCost = Actor.Cost(building.type)
|
||||
if CyardIsBuilding or Nod.Cash < buildingCost then
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBuilding(building, cyard) end)
|
||||
return
|
||||
end
|
||||
|
||||
CyardIsBuilding = true
|
||||
|
||||
Nod.Cash = Nod.Cash - buildingCost
|
||||
Trigger.AfterDelay(Actor.BuildTime(building.type), function()
|
||||
CyardIsBuilding = false
|
||||
|
||||
if cyard.IsDead or cyard.Owner ~= Nod then
|
||||
Nod.Cash = Nod.Cash + buildingCost
|
||||
return
|
||||
end
|
||||
|
||||
local actor = Actor.Create(building.type, true, { Owner = Nod, Location = building.pos })
|
||||
|
||||
if actor.Type == 'hand' or actor.Type == 'pyle' then
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(actor) end)
|
||||
elseif actor.Type == 'afld' or actor.Type == 'weap' then
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(actor) end)
|
||||
end
|
||||
|
||||
Trigger.OnKilled(actor, function()
|
||||
BuildBuilding(building, cyard)
|
||||
end)
|
||||
|
||||
RepairBuilding(Nod, actor, 0.75)
|
||||
end)
|
||||
end
|
||||
|
||||
HasHarvester = function()
|
||||
local harv = Nod.GetActorsByType("harv")
|
||||
return #harv > 0
|
||||
end
|
||||
|
||||
GuardBase = function()
|
||||
Utils.Do(NodBase, function(building)
|
||||
Trigger.OnDamaged(building, function()
|
||||
if not building.IsDead then
|
||||
Utils.Do(NodGuards, function(guard)
|
||||
if not guard.IsDead then
|
||||
guard.Stop()
|
||||
guard.Guard(building)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
ProduceHarvester = function(building)
|
||||
if not buildingHarvester then
|
||||
buildingHarvester = true
|
||||
building.Build(HarvesterProductionType, function()
|
||||
buildingHarvester = false
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
ProduceInfantry = function(building)
|
||||
if building.IsDead or building.Owner ~= Nod then
|
||||
return
|
||||
elseif not HasHarvester() then
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(building) end)
|
||||
return
|
||||
end
|
||||
|
||||
if #PatrolProductionQueue >= 1 then
|
||||
local inQueue = PatrolProductionQueue[1]
|
||||
local toBuild = { inQueue.unit[1] }
|
||||
local patrolPath = inQueue.waypoints
|
||||
building.Build(toBuild, function(unit)
|
||||
ReplenishPatrolUnit(unit[1], handofnod, patrolPath, 40)
|
||||
table.remove(PatrolProductionQueue, 1)
|
||||
end)
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(building) end)
|
||||
return
|
||||
end
|
||||
|
||||
local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9))
|
||||
local toBuild = { Utils.Random(InfantryProductionTypes) }
|
||||
local Path = Utils.Random(AttackPaths)
|
||||
building.Build(toBuild, function(unit)
|
||||
InfantryAttackGroup[#InfantryAttackGroup + 1] = unit[1]
|
||||
|
||||
if #InfantryAttackGroup >= InfantryGroupSize then
|
||||
MoveAndHunt(InfantryAttackGroup, Path)
|
||||
InfantryAttackGroup = { }
|
||||
Trigger.AfterDelay(InfantryProductionCooldown, function() ProduceInfantry(building) end)
|
||||
else
|
||||
Trigger.AfterDelay(delay, function() ProduceInfantry(building) end)
|
||||
end
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
ProduceVehicle = function(building)
|
||||
if building.IsDead or building.Owner ~= Nod then
|
||||
return
|
||||
elseif not HasHarvester() then
|
||||
ProduceHarvester(building)
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(building) end)
|
||||
return
|
||||
end
|
||||
|
||||
local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17))
|
||||
local toBuild = { Utils.Random(VehicleProductionTypes) }
|
||||
local Path = Utils.Random(AttackPaths)
|
||||
building.Build(toBuild, function(unit)
|
||||
VehicleAttackGroup[#VehicleAttackGroup + 1] = unit[1]
|
||||
|
||||
if #VehicleAttackGroup >= VehicleGroupSize then
|
||||
MoveAndHunt(VehicleAttackGroup, Path)
|
||||
VehicleAttackGroup = { }
|
||||
Trigger.AfterDelay(VehicleProductionCooldown, function() ProduceVehicle(building) end)
|
||||
else
|
||||
Trigger.AfterDelay(delay, function() ProduceVehicle(building) end)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
StartAI = function()
|
||||
RepairNamedActors(Nod, 0.75)
|
||||
|
||||
Nod.Cash = StartingCash
|
||||
GuardBase()
|
||||
end
|
||||
|
||||
Trigger.OnAllKilledOrCaptured(NodBase, function()
|
||||
Utils.Do(Nod.GetGroundAttackers(), IdleHunt)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodrefinery, function(building)
|
||||
BuildBuilding(BaseRefinery, NodCYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodpower1, function(building)
|
||||
BuildBuilding(BaseNuke1, NodCYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodpower2, function(building)
|
||||
BuildBuilding(BaseNuke2, NodCYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodpower3, function(building)
|
||||
BuildBuilding(BaseNuke3, NodCYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodpower4, function(building)
|
||||
BuildBuilding(BaseNuke4, NodCYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodpower5, function(building)
|
||||
BuildBuilding(BaseNuke5, NodCYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(handofnod, function(building)
|
||||
BuildBuilding(InfantryProduction, NodCYard)
|
||||
end)
|
||||
|
||||
Trigger.OnKilled(nodairfield, function(building)
|
||||
BuildBuilding(VehicleProduction, NodCYard)
|
||||
end)
|
||||
170
mods/cnc/maps/gdi09/gdi09.lua
Normal file
@@ -0,0 +1,170 @@
|
||||
--[[
|
||||
Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
|
||||
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.
|
||||
]]
|
||||
|
||||
InsertionHelicopterType = "tran.insertion"
|
||||
GDIHeliReinfUnits = { "e2", "e2", "e2", "e3", "e3" }
|
||||
|
||||
SamSites = { sam1, sam2, sam3, sam4 }
|
||||
NodBunkersNorth = { gun3, gun4 }
|
||||
NodBunkersSouth = { gun1, gun2 }
|
||||
|
||||
BoatEscapeTrigger = { CPos.New(2,37) }
|
||||
|
||||
WaypointGroup1 = { waypoint1, waypoint2, waypoint8 }
|
||||
WaypointGroup2 = { waypoint1, waypoint2, waypoint3, waypoint9 }
|
||||
WaypointGroup3 = { waypoint1, waypoint2, waypoint3, waypoint10, waypoint11, waypoint12, waypoint6, waypoint13 }
|
||||
WaypointGroup4 = { waypoint1, waypoint2, waypoint3, waypoint4 }
|
||||
Patrol1Waypoints = { waypoint11.Location, waypoint10.Location }
|
||||
Patrol2Waypoints = { waypoint1.Location, waypoint2.Location, waypoint3.Location, waypoint4.Location, waypoint5.Location, waypoint4.Location, waypoint3.Location, waypoint2.Location, waypoint1.Location, waypoint6.Location }
|
||||
|
||||
Nod1 = { units = { ['e1'] = 2, ['e3'] = 2 }, waypoints = WaypointGroup1, delay = 40 }
|
||||
Nod2 = { units = { ['e3'] = 2, ['e4'] = 2 }, waypoints = WaypointGroup2, delay = 50 }
|
||||
Nod3 = { units = { ['e1'] = 2, ['e3'] = 3, ['e4'] = 2 }, waypoints = WaypointGroup1, delay = 50 }
|
||||
Nod4 = { units = { ['bggy'] = 2 }, waypoints = WaypointGroup2, delay = 50 }
|
||||
Nod5 = { units = { ['e4'] = 2, ['ltnk'] = 1 }, waypoints = WaypointGroup1, delay = 50 }
|
||||
Auto1 = { units = { ['e4'] = 2, ['arty'] = 1 }, waypoints = WaypointGroup1, delay = 50 }
|
||||
Auto2 = { units = { ['e1'] = 2, ['e3'] = 2 }, waypoints = WaypointGroup2, delay = 50 }
|
||||
Auto3 = { units = { ['e3'] = 2, ['e4'] = 2 }, waypoints = WaypointGroup1, delay = 50 }
|
||||
Auto4 = { units = { ['e1'] = 3, ['e4'] = 1 }, waypoints = WaypointGroup1, delay = 50 }
|
||||
Auto5 = { units = { ['ltnk'] = 1, ['bggy'] = 1 }, waypoints = WaypointGroup1, delay = 60 }
|
||||
Auto6 = { units = { ['bggy'] = 1 }, waypoints = WaypointGroup2, delay = 50 }
|
||||
Auto7 = { units = { ['ltnk'] = 1 }, waypoints = WaypointGroup2, delay = 50 }
|
||||
Auto8 = { units = { ['e4'] = 2, ['bggy'] = 1 }, waypoints = WaypointGroup4, delay = 0 }
|
||||
|
||||
Patrols = {
|
||||
grd1 = { units = { ['e3'] = 3 }, waypoints = Patrol1Waypoints, wait = 40, initialWaypointPlacement = { 1 } },
|
||||
grd2 = { units = { ['e1'] = 2, ['e3'] = 2, ['e4'] = 2 }, waypoints = Patrol2Waypoints, wait = 20, initialWaypointPlacement = { 4, 10, 1 } }
|
||||
}
|
||||
|
||||
AutoAttackWaves = { Nod1, Nod2, Nod3, Nod4, Nod5, Auto1, Auto2, Auto3, Auto4, Auto5, Auto6, Auto7, Auto8 }
|
||||
|
||||
StationaryGuards = { Actor174, Actor173, Actor182, Actor183, Actor184, Actor185, Actor186, Actor187 , Actor199, Actor200, Actor201, Actor202, Actor203, Actor204 }
|
||||
|
||||
StartStationaryGuards = function()
|
||||
Utils.Do(StationaryGuards, function(unit)
|
||||
if not unit.IsDead then
|
||||
unit.Patrol( { unit.Location } , true, 20)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
SendWaves = function(counter, Waves)
|
||||
if counter <= #Waves then
|
||||
local team = Waves[counter]
|
||||
|
||||
for type, amount in pairs(team.units) do
|
||||
MoveAndHunt(Utils.Take(amount, Nod.GetActorsByType(type)), team.waypoints)
|
||||
end
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(team.delay), function() SendWaves(counter + 1, Waves) end)
|
||||
end
|
||||
end
|
||||
|
||||
StartPatrols = function()
|
||||
for k, team in pairs(Patrols) do
|
||||
local group = 1
|
||||
for type, amount in pairs(team.units) do
|
||||
for i = 1, amount do
|
||||
Reinforcements.Reinforce(Nod, { type }, { team.waypoints[team.initialWaypointPlacement[group]] }, 0, function(unit)
|
||||
ReplenishPatrolUnit(unit, handofnod, team.waypoints, team.wait)
|
||||
end)
|
||||
end
|
||||
group = group + 1
|
||||
end
|
||||
end
|
||||
Patrols = nil
|
||||
end
|
||||
|
||||
ReplenishPatrolUnit = function(unit, building, waypoints, waitatwaypoint)
|
||||
unit.Patrol(waypoints, true, waitatwaypoint)
|
||||
Trigger.OnKilled(unit, function()
|
||||
local queueUnit = { unit = { unit.Type }, atbuilding = { building }, waypoints = waypoints }
|
||||
PatrolProductionQueue[#PatrolProductionQueue + 1] = queueUnit
|
||||
end)
|
||||
end
|
||||
|
||||
SendGDIReinforcements = function()
|
||||
Media.PlaySpeechNotification(GDI, "Reinforce")
|
||||
Reinforcements.ReinforceWithTransport(GDI, InsertionHelicopterType, GDIHeliReinfUnits, { GDIHeliEntryNorth.Location, GDIHeliLZ.Location }, { GDIHeliLZ.Location + CVec.New(20, 0) })
|
||||
end
|
||||
|
||||
SendGDIReinforcementChinook = function()
|
||||
Reinforcements.ReinforceWithTransport(GDI, 'tran', nil, { GDIHeliEntryNorth.Location, GDIHeliLZ.Location })
|
||||
end
|
||||
|
||||
SpawnGunboat = function()
|
||||
Media.PlaySpeechNotification(GDI, "Reinforce")
|
||||
Actor.Create("boat", true, { Owner = GDI, Facing = 0, Location = CPos.New(62,37) })
|
||||
end
|
||||
|
||||
WorldLoaded = function()
|
||||
GDI = Player.GetPlayer("GDI")
|
||||
Nod = Player.GetPlayer("Nod")
|
||||
|
||||
Camera.Position = DefaultCameraPosition.CenterPosition
|
||||
|
||||
DestroyBunkers = GDI.AddObjective("Destroy the Nod bunkers to allow Carter's\nconvoy to pass through safely.")
|
||||
Trigger.OnAllKilled(NodBunkersNorth, function()
|
||||
GDI.MarkCompletedObjective(DestroyBunkers)
|
||||
Trigger.AfterDelay(DateTime.Seconds(1), SpawnGunboat)
|
||||
end)
|
||||
Trigger.OnAllKilled(NodBunkersSouth, function()
|
||||
GDI.MarkCompletedObjective(DestroyBunkers)
|
||||
SendGDIReinforcementChinook()
|
||||
Trigger.AfterDelay(DateTime.Seconds(1), SpawnGunboat)
|
||||
end)
|
||||
Trigger.OnEnteredFootprint(BoatEscapeTrigger, function(a, id)
|
||||
if a.Type == "boat" then
|
||||
a.Destroy()
|
||||
Media.DisplayMessage("Part of Carter's convoy passed through!")
|
||||
Media.PlaySoundNotification(GDI, "AlertBleep")
|
||||
end
|
||||
end)
|
||||
|
||||
SecureArea = GDI.AddObjective("Destroy the Nod strike force.")
|
||||
KillGDI = Nod.AddObjective("Kill all enemies!")
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(5), SendGDIReinforcements)
|
||||
|
||||
AirSupport = GDI.AddObjective("Destroy the SAM sites to receive air support.", "Secondary", false)
|
||||
Trigger.OnAllKilled(SamSites, function()
|
||||
GDI.MarkCompletedObjective(AirSupport)
|
||||
Actor.Create("airstrike.proxy", true, { Owner = GDI })
|
||||
end)
|
||||
|
||||
Actor.Create("flare", true, { Owner = GDI, Location = DefaultFlareLocation.Location })
|
||||
|
||||
StartStationaryGuards()
|
||||
|
||||
StartAI()
|
||||
|
||||
StartPatrols()
|
||||
|
||||
InitObjectives(GDI)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Minutes(1), function() SendWaves(1, AutoAttackWaves) end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(3), function() ProduceInfantry(handofnod) end)
|
||||
Trigger.AfterDelay(DateTime.Minutes(3), function() ProduceVehicle(nodairfield) end)
|
||||
|
||||
local initialArrivingUnits = { Actor175, Actor191, Actor192, Actor193, Actor194, Actor195, Actor196, Actor197, Actor198 }
|
||||
Utils.Do(initialArrivingUnits, function(unit)
|
||||
unit.Move(unit.Location + CVec.New(0, 1), 0)
|
||||
end)
|
||||
end
|
||||
|
||||
Tick = function()
|
||||
if DateTime.GameTime > DateTime.Seconds(5) then
|
||||
if GDI.HasNoRequiredUnits() then
|
||||
Nod.MarkCompletedObjective(KillGDI)
|
||||
end
|
||||
if Nod.HasNoRequiredUnits() then
|
||||
GDI.MarkCompletedObjective(SecureArea)
|
||||
end
|
||||
end
|
||||
end
|
||||
BIN
mods/cnc/maps/gdi09/map.bin
Normal file
BIN
mods/cnc/maps/gdi09/map.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
782
mods/cnc/maps/gdi09/map.yaml
Normal file
@@ -0,0 +1,782 @@
|
||||
MapFormat: 11
|
||||
|
||||
RequiresMod: cnc
|
||||
|
||||
Title: 09: Secure the Danube
|
||||
|
||||
Author: Westwood Studios
|
||||
|
||||
Tileset: WINTER
|
||||
|
||||
MapSize: 64,64
|
||||
|
||||
Bounds: 2,3,60,48
|
||||
|
||||
Visibility: MissionSelector
|
||||
|
||||
Categories: Campaign
|
||||
|
||||
LockPreview: True
|
||||
|
||||
Players:
|
||||
PlayerReference@Neutral:
|
||||
Name: Neutral
|
||||
OwnsWorld: True
|
||||
NonCombatant: True
|
||||
Faction: gdi
|
||||
PlayerReference@Nod:
|
||||
Name: Nod
|
||||
Faction: nod
|
||||
Color: FF1400
|
||||
Allies: Nod
|
||||
Enemies: GDI
|
||||
Bot: campaign
|
||||
PlayerReference@GDI:
|
||||
Name: GDI
|
||||
AllowBots: False
|
||||
Playable: True
|
||||
Required: True
|
||||
LockFaction: True
|
||||
Faction: gdi
|
||||
LockColor: True
|
||||
Color: F5D378
|
||||
LockSpawn: True
|
||||
LockTeam: True
|
||||
Allies: GDI
|
||||
Enemies: Nod
|
||||
|
||||
Actors:
|
||||
Actor0: sbag
|
||||
Location: 30,43
|
||||
Owner: Neutral
|
||||
Actor1: sbag
|
||||
Location: 29,43
|
||||
Owner: Neutral
|
||||
Actor2: sbag
|
||||
Location: 28,43
|
||||
Owner: Neutral
|
||||
Actor3: sbag
|
||||
Location: 27,43
|
||||
Owner: Neutral
|
||||
Actor4: sbag
|
||||
Location: 26,43
|
||||
Owner: Neutral
|
||||
Actor5: sbag
|
||||
Location: 30,42
|
||||
Owner: Neutral
|
||||
Actor6: sbag
|
||||
Location: 28,42
|
||||
Owner: Neutral
|
||||
Actor7: sbag
|
||||
Location: 26,42
|
||||
Owner: Neutral
|
||||
Actor8: sbag
|
||||
Location: 35,33
|
||||
Owner: Neutral
|
||||
Actor9: sbag
|
||||
Location: 33,33
|
||||
Owner: Neutral
|
||||
Actor10: sbag
|
||||
Location: 31,33
|
||||
Owner: Neutral
|
||||
Actor11: brik
|
||||
Location: 21,33
|
||||
Owner: Neutral
|
||||
Actor12: brik
|
||||
Location: 20,33
|
||||
Owner: Neutral
|
||||
Actor13: brik
|
||||
Location: 19,33
|
||||
Owner: Neutral
|
||||
Actor14: brik
|
||||
Location: 18,33
|
||||
Owner: Neutral
|
||||
Actor15: brik
|
||||
Location: 17,33
|
||||
Owner: Neutral
|
||||
Actor16: brik
|
||||
Location: 16,33
|
||||
Owner: Neutral
|
||||
Actor17: brik
|
||||
Location: 15,33
|
||||
Owner: Neutral
|
||||
Actor18: brik
|
||||
Location: 14,33
|
||||
Owner: Neutral
|
||||
Actor19: brik
|
||||
Location: 13,33
|
||||
Owner: Neutral
|
||||
Actor20: brik
|
||||
Location: 12,33
|
||||
Owner: Neutral
|
||||
Actor21: brik
|
||||
Location: 11,33
|
||||
Owner: Neutral
|
||||
Actor22: brik
|
||||
Location: 10,33
|
||||
Owner: Neutral
|
||||
Actor23: brik
|
||||
Location: 9,33
|
||||
Owner: Neutral
|
||||
Actor24: brik
|
||||
Location: 8,33
|
||||
Owner: Neutral
|
||||
Actor25: brik
|
||||
Location: 7,33
|
||||
Owner: Neutral
|
||||
Actor26: brik
|
||||
Location: 6,33
|
||||
Owner: Neutral
|
||||
Actor27: brik
|
||||
Location: 5,33
|
||||
Owner: Neutral
|
||||
Actor28: brik
|
||||
Location: 4,33
|
||||
Owner: Neutral
|
||||
Actor29: brik
|
||||
Location: 3,33
|
||||
Owner: Neutral
|
||||
Actor30: brik
|
||||
Location: 2,33
|
||||
Owner: Neutral
|
||||
Actor31: sbag
|
||||
Location: 35,32
|
||||
Owner: Neutral
|
||||
Actor32: sbag
|
||||
Location: 34,32
|
||||
Owner: Neutral
|
||||
Actor33: sbag
|
||||
Location: 33,32
|
||||
Owner: Neutral
|
||||
Actor34: sbag
|
||||
Location: 32,32
|
||||
Owner: Neutral
|
||||
Actor35: sbag
|
||||
Location: 31,32
|
||||
Owner: Neutral
|
||||
Actor36: brik
|
||||
Location: 21,32
|
||||
Owner: Neutral
|
||||
Actor37: brik
|
||||
Location: 2,32
|
||||
Owner: Neutral
|
||||
Actor38: brik
|
||||
Location: 21,31
|
||||
Owner: Neutral
|
||||
Actor39: brik
|
||||
Location: 20,31
|
||||
Owner: Neutral
|
||||
Actor40: brik
|
||||
Location: 2,31
|
||||
Owner: Neutral
|
||||
Actor41: brik
|
||||
Location: 21,30
|
||||
Owner: Neutral
|
||||
Actor42: brik
|
||||
Location: 20,30
|
||||
Owner: Neutral
|
||||
Actor43: brik
|
||||
Location: 2,30
|
||||
Owner: Neutral
|
||||
Actor44: wood
|
||||
Location: 31,29
|
||||
Owner: Neutral
|
||||
Actor45: brik
|
||||
Location: 2,29
|
||||
Owner: Neutral
|
||||
Actor46: wood
|
||||
Location: 31,28
|
||||
Owner: Neutral
|
||||
Actor47: brik
|
||||
Location: 2,28
|
||||
Owner: Neutral
|
||||
Actor48: wood
|
||||
Location: 42,27
|
||||
Owner: Neutral
|
||||
Actor49: wood
|
||||
Location: 41,27
|
||||
Owner: Neutral
|
||||
Actor50: wood
|
||||
Location: 40,27
|
||||
Owner: Neutral
|
||||
Actor51: wood
|
||||
Location: 39,27
|
||||
Owner: Neutral
|
||||
Actor52: brik
|
||||
Location: 2,27
|
||||
Owner: Neutral
|
||||
Actor53: wood
|
||||
Location: 42,26
|
||||
Owner: Neutral
|
||||
Actor54: v16
|
||||
Location: 41,26
|
||||
Owner: Neutral
|
||||
Actor55: v18
|
||||
Location: 40,26
|
||||
Owner: Neutral
|
||||
Actor56: wood
|
||||
Location: 39,26
|
||||
Owner: Neutral
|
||||
Actor57: brik
|
||||
Location: 21,26
|
||||
Owner: Neutral
|
||||
Actor58: brik
|
||||
Location: 20,26
|
||||
Owner: Neutral
|
||||
Actor59: brik
|
||||
Location: 2,26
|
||||
Owner: Neutral
|
||||
Actor60: wood
|
||||
Location: 42,25
|
||||
Owner: Neutral
|
||||
Actor61: v14
|
||||
Location: 41,25
|
||||
Owner: Neutral
|
||||
Actor62: v15
|
||||
Location: 40,25
|
||||
Owner: Neutral
|
||||
Actor63: wood
|
||||
Location: 39,25
|
||||
Owner: Neutral
|
||||
Actor64: brik
|
||||
Location: 21,25
|
||||
Owner: Neutral
|
||||
Actor65: brik
|
||||
Location: 20,25
|
||||
Owner: Neutral
|
||||
Actor66: brik
|
||||
Location: 2,25
|
||||
Owner: Neutral
|
||||
Actor67: wood
|
||||
Location: 42,24
|
||||
Owner: Neutral
|
||||
Actor68: wood
|
||||
Location: 39,24
|
||||
Owner: Neutral
|
||||
Actor69: brik
|
||||
Location: 21,24
|
||||
Owner: Neutral
|
||||
Actor70: brik
|
||||
Location: 14,24
|
||||
Owner: Neutral
|
||||
Actor71: brik
|
||||
Location: 13,24
|
||||
Owner: Neutral
|
||||
Actor72: brik
|
||||
Location: 8,24
|
||||
Owner: Neutral
|
||||
Actor73: brik
|
||||
Location: 7,24
|
||||
Owner: Neutral
|
||||
Actor74: brik
|
||||
Location: 2,24
|
||||
Owner: Neutral
|
||||
Actor75: brik
|
||||
Location: 21,23
|
||||
Owner: Neutral
|
||||
Actor76: brik
|
||||
Location: 20,23
|
||||
Owner: Neutral
|
||||
Actor77: brik
|
||||
Location: 19,23
|
||||
Owner: Neutral
|
||||
Actor78: brik
|
||||
Location: 18,23
|
||||
Owner: Neutral
|
||||
Actor79: brik
|
||||
Location: 17,23
|
||||
Owner: Neutral
|
||||
Actor80: brik
|
||||
Location: 16,23
|
||||
Owner: Neutral
|
||||
Actor81: brik
|
||||
Location: 15,23
|
||||
Owner: Neutral
|
||||
Actor82: brik
|
||||
Location: 14,23
|
||||
Owner: Neutral
|
||||
Actor83: brik
|
||||
Location: 13,23
|
||||
Owner: Neutral
|
||||
Actor84: brik
|
||||
Location: 8,23
|
||||
Owner: Neutral
|
||||
Actor85: brik
|
||||
Location: 7,23
|
||||
Owner: Neutral
|
||||
Actor86: brik
|
||||
Location: 6,23
|
||||
Owner: Neutral
|
||||
Actor87: brik
|
||||
Location: 5,23
|
||||
Owner: Neutral
|
||||
Actor88: brik
|
||||
Location: 4,23
|
||||
Owner: Neutral
|
||||
Actor89: brik
|
||||
Location: 3,23
|
||||
Owner: Neutral
|
||||
Actor90: brik
|
||||
Location: 2,23
|
||||
Owner: Neutral
|
||||
Actor91: t02
|
||||
Location: 46,27
|
||||
Owner: Neutral
|
||||
Actor92: t02
|
||||
Location: 14,19
|
||||
Owner: Neutral
|
||||
Actor93: t01
|
||||
Location: 18,19
|
||||
Owner: Neutral
|
||||
Actor94: t14
|
||||
Location: 44,27
|
||||
Owner: Neutral
|
||||
Actor95: tc01
|
||||
Location: 43,24
|
||||
Owner: Neutral
|
||||
Actor96: tc02
|
||||
Location: 42,27
|
||||
Owner: Neutral
|
||||
Actor97: tc04
|
||||
Location: 45,24
|
||||
Owner: Neutral
|
||||
Actor98: split2
|
||||
Location: 55,23
|
||||
Owner: Neutral
|
||||
Actor99: split2
|
||||
Location: 60,28
|
||||
Owner: Neutral
|
||||
Actor100: tc04
|
||||
Location: 34,26
|
||||
Owner: Neutral
|
||||
Actor101: tc02
|
||||
Location: 37,25
|
||||
Owner: Neutral
|
||||
Actor102: t10
|
||||
Location: 32,27
|
||||
Owner: Neutral
|
||||
Actor103: t01
|
||||
Location: 34,25
|
||||
Owner: Neutral
|
||||
Actor104: t17
|
||||
Location: 35,24
|
||||
Owner: Neutral
|
||||
Actor105: tc01
|
||||
Location: 31,26
|
||||
Owner: Neutral
|
||||
Actor106: tc04
|
||||
Location: 51,15
|
||||
Owner: Neutral
|
||||
Actor107: tc04
|
||||
Location: 37,5
|
||||
Owner: Neutral
|
||||
Actor108: tc04
|
||||
Location: 39,14
|
||||
Owner: Neutral
|
||||
Actor109: tc04
|
||||
Location: 30,6
|
||||
Owner: Neutral
|
||||
Actor110: tc02
|
||||
Location: 29,14
|
||||
Owner: Neutral
|
||||
Actor111: tc01
|
||||
Location: 44,12
|
||||
Owner: Neutral
|
||||
Actor112: tc01
|
||||
Location: 32,9
|
||||
Owner: Neutral
|
||||
Actor113: t03
|
||||
Location: 34,17
|
||||
Owner: Neutral
|
||||
Actor114: t02
|
||||
Location: 44,20
|
||||
Owner: Neutral
|
||||
Actor115: t01
|
||||
Location: 42,19
|
||||
Owner: Neutral
|
||||
Actor116: t01
|
||||
Location: 43,10
|
||||
Owner: Neutral
|
||||
Actor117: t01
|
||||
Location: 35,15
|
||||
Owner: Neutral
|
||||
Actor118: t01
|
||||
Location: 31,10
|
||||
Owner: Neutral
|
||||
Actor119: tc02
|
||||
Location: 22,42
|
||||
Owner: Neutral
|
||||
Actor120: tc04
|
||||
Location: 2,47
|
||||
Owner: Neutral
|
||||
Actor121: tc05
|
||||
Location: 15,52
|
||||
Owner: Neutral
|
||||
Actor122: tc02
|
||||
Location: 27,53
|
||||
Owner: Neutral
|
||||
Actor123: t01
|
||||
Location: 30,50
|
||||
Owner: Neutral
|
||||
Actor124: t02
|
||||
Location: 23,52
|
||||
Owner: Neutral
|
||||
Actor125: t03
|
||||
Location: 33,45
|
||||
Owner: Neutral
|
||||
Actor126: tc01
|
||||
Location: 22,22
|
||||
Owner: Neutral
|
||||
Actor127: t07
|
||||
Location: 5,5
|
||||
Owner: Neutral
|
||||
Actor128: tc04
|
||||
Location: 8,4
|
||||
Owner: Neutral
|
||||
Actor129: tc01
|
||||
Location: 3,4
|
||||
Owner: Neutral
|
||||
Actor130: t07
|
||||
Location: 38,23
|
||||
Owner: Neutral
|
||||
Actor131: t11
|
||||
Location: 30,43
|
||||
Owner: Neutral
|
||||
Actor132: tc04
|
||||
Location: 24,43
|
||||
Owner: Neutral
|
||||
Actor133: tc04
|
||||
Location: 25,29
|
||||
Owner: Neutral
|
||||
Actor134: tc05
|
||||
Location: 52,22
|
||||
Owner: Neutral
|
||||
gun1: gun
|
||||
Location: 27,42
|
||||
Owner: Nod
|
||||
gun2: gun
|
||||
Location: 29,42
|
||||
Owner: Nod
|
||||
gun3: gun
|
||||
Location: 34,33
|
||||
Owner: Nod
|
||||
Facing: 159
|
||||
gun4: gun
|
||||
Location: 32,33
|
||||
Owner: Nod
|
||||
Facing: 159
|
||||
Actor139: v04
|
||||
Location: 45,26
|
||||
Owner: Neutral
|
||||
Actor140: v07
|
||||
Location: 51,24
|
||||
Owner: Neutral
|
||||
Actor141: v06
|
||||
Location: 40,24
|
||||
Owner: Neutral
|
||||
Actor142: v05
|
||||
Location: 43,26
|
||||
Owner: Neutral
|
||||
Actor143: v03
|
||||
Location: 35,25
|
||||
Owner: Neutral
|
||||
Actor144: v01
|
||||
Location: 37,26
|
||||
Owner: Neutral
|
||||
sam1: sam
|
||||
Location: 3,4
|
||||
Owner: Nod
|
||||
sam2: sam
|
||||
Location: 19,24
|
||||
Owner: Nod
|
||||
sam3: sam
|
||||
Location: 2,22
|
||||
Owner: Nod
|
||||
sam4: sam
|
||||
Location: 19,32
|
||||
Owner: Nod
|
||||
nodpower1: nuke
|
||||
Location: 5,24
|
||||
Owner: Nod
|
||||
nodpower2: nuke
|
||||
Location: 3,24
|
||||
Owner: Nod
|
||||
gun5: gun
|
||||
Location: 13,22
|
||||
Owner: Nod
|
||||
gun6: gun
|
||||
Location: 8,22
|
||||
Owner: Nod
|
||||
NodCYard: fact
|
||||
Location: 7,30
|
||||
Owner: Nod
|
||||
nodobelisk: obli
|
||||
Location: 18,32
|
||||
Owner: Nod
|
||||
nodpower3: nuke
|
||||
Location: 16,30
|
||||
Owner: Nod
|
||||
nodpower4: nuke
|
||||
Location: 14,30
|
||||
Owner: Nod
|
||||
nodsilo1: silo
|
||||
Location: 5,31
|
||||
Owner: Nod
|
||||
nodsilo2: silo
|
||||
Location: 10,31
|
||||
Owner: Nod
|
||||
nodsilo3: silo
|
||||
Location: 3,31
|
||||
Owner: Nod
|
||||
nodrefinery: proc
|
||||
Location: 12,25
|
||||
Owner: Nod
|
||||
FreeActor: False
|
||||
nodairfield: afld
|
||||
Location: 3,27
|
||||
Owner: Nod
|
||||
handofnod: hand
|
||||
Location: 15,25
|
||||
Owner: Nod
|
||||
nodsilo4: silo
|
||||
Location: 17,24
|
||||
Owner: Nod
|
||||
nodpower5: nuke
|
||||
Location: 12,30
|
||||
Owner: Nod
|
||||
gun7: gun
|
||||
Location: 22,25
|
||||
Owner: Nod
|
||||
Facing: 191
|
||||
gun8: gun
|
||||
Location: 22,31
|
||||
Owner: Nod
|
||||
Facing: 191
|
||||
Actor167: harv
|
||||
Location: 20,28
|
||||
Owner: Nod
|
||||
Facing: 191
|
||||
Actor168: ltnk
|
||||
Location: 19,26
|
||||
Owner: Nod
|
||||
Facing: 127
|
||||
Actor169: ltnk
|
||||
Location: 18,26
|
||||
Owner: Nod
|
||||
Facing: 127
|
||||
Actor170: ltnk
|
||||
Location: 8,28
|
||||
Owner: Nod
|
||||
Facing: 127
|
||||
Actor171: bggy
|
||||
Location: 18,31
|
||||
Owner: Nod
|
||||
Actor172: bggy
|
||||
Location: 19,31
|
||||
Owner: Nod
|
||||
Actor173: bggy
|
||||
Location: 40,14
|
||||
Owner: Nod
|
||||
Actor174: arty
|
||||
Location: 8,15
|
||||
Owner: Nod
|
||||
Facing: 31
|
||||
Actor175: mcv
|
||||
Location: 54,4
|
||||
Owner: GDI
|
||||
Facing: 127
|
||||
Actor176: e3
|
||||
Location: 19,25
|
||||
Owner: Nod
|
||||
SubCell: 1
|
||||
Actor177: e3
|
||||
Location: 17,26
|
||||
Owner: Nod
|
||||
SubCell: 3
|
||||
Actor178: e3
|
||||
Location: 8,25
|
||||
Owner: Nod
|
||||
SubCell: 1
|
||||
Actor179: e3
|
||||
Location: 10,29
|
||||
Owner: Nod
|
||||
SubCell: 0
|
||||
Actor180: e1
|
||||
Location: 5,30
|
||||
Owner: Nod
|
||||
SubCell: 0
|
||||
Actor181: e1
|
||||
Location: 8,26
|
||||
Owner: Nod
|
||||
SubCell: 4
|
||||
Actor182: e4
|
||||
Location: 7,14
|
||||
Owner: Nod
|
||||
Facing: 31
|
||||
SubCell: 3
|
||||
Actor183: e4
|
||||
Location: 7,14
|
||||
Owner: Nod
|
||||
Facing: 31
|
||||
SubCell: 2
|
||||
Actor184: e4
|
||||
Location: 25,6
|
||||
Owner: Nod
|
||||
Facing: 191
|
||||
SubCell: 1
|
||||
Actor185: e4
|
||||
Location: 25,4
|
||||
Owner: Nod
|
||||
Facing: 191
|
||||
SubCell: 3
|
||||
Actor186: e3
|
||||
Location: 33,9
|
||||
Owner: Nod
|
||||
SubCell: 0
|
||||
Actor187: e3
|
||||
Location: 31,6
|
||||
Owner: Nod
|
||||
SubCell: 3
|
||||
Actor188: e3
|
||||
Location: 17,27
|
||||
Owner: Nod
|
||||
SubCell: 2
|
||||
Actor189: e3
|
||||
Location: 17,26
|
||||
Owner: Nod
|
||||
SubCell: 2
|
||||
Actor190: e3
|
||||
Location: 17,27
|
||||
Owner: Nod
|
||||
SubCell: 0
|
||||
Actor191: e2
|
||||
Location: 53,6
|
||||
Owner: GDI
|
||||
Facing: 127
|
||||
SubCell: 4
|
||||
Actor192: e2
|
||||
Location: 54,6
|
||||
Owner: GDI
|
||||
Facing: 127
|
||||
SubCell: 3
|
||||
Actor193: e2
|
||||
Location: 53,7
|
||||
Owner: GDI
|
||||
Facing: 127
|
||||
SubCell: 2
|
||||
Actor194: e3
|
||||
Location: 54,6
|
||||
Owner: GDI
|
||||
Facing: 127
|
||||
SubCell: 4
|
||||
Actor195: e3
|
||||
Location: 55,6
|
||||
Owner: GDI
|
||||
Facing: 127
|
||||
SubCell: 3
|
||||
Actor196: e3
|
||||
Location: 55,7
|
||||
Owner: GDI
|
||||
Facing: 127
|
||||
SubCell: 1
|
||||
Actor197: e3
|
||||
Location: 54,7
|
||||
Owner: GDI
|
||||
Facing: 127
|
||||
SubCell: 2
|
||||
Actor198: e2
|
||||
Location: 54,7
|
||||
Owner: GDI
|
||||
Facing: 127
|
||||
SubCell: 1
|
||||
Actor199: e3
|
||||
Location: 25,34
|
||||
Owner: Nod
|
||||
Facing: 127
|
||||
SubCell: 4
|
||||
Actor200: e3
|
||||
Location: 25,34
|
||||
Owner: Nod
|
||||
Facing: 127
|
||||
SubCell: 3
|
||||
Actor201: e3
|
||||
Location: 24,34
|
||||
Owner: Nod
|
||||
Facing: 127
|
||||
SubCell: 4
|
||||
Actor202: e3
|
||||
Location: 25,34
|
||||
Owner: Nod
|
||||
Facing: 127
|
||||
SubCell: 1
|
||||
Actor203: e3
|
||||
Location: 24,34
|
||||
Owner: Nod
|
||||
Facing: 127
|
||||
SubCell: 2
|
||||
Actor204: e3
|
||||
Location: 25,34
|
||||
Owner: Nod
|
||||
Facing: 127
|
||||
SubCell: 2
|
||||
GDIHeliEntryNorth: waypoint
|
||||
Location: 57,6
|
||||
Owner: Neutral
|
||||
DefaultCameraPosition: waypoint
|
||||
Location: 48,3
|
||||
Owner: Neutral
|
||||
DefaultFlareLocation: waypoint
|
||||
Location: 33,31
|
||||
Owner: Neutral
|
||||
waypoint23: waypoint
|
||||
Location: 53,37
|
||||
Owner: Neutral
|
||||
waypoint19: waypoint
|
||||
Location: 52,42
|
||||
Owner: Neutral
|
||||
waypoint18: waypoint
|
||||
Location: 52,19
|
||||
Owner: Neutral
|
||||
waypoint17: waypoint
|
||||
Location: 9,30
|
||||
Owner: Neutral
|
||||
waypoint11: waypoint
|
||||
Location: 23,24
|
||||
Owner: Neutral
|
||||
waypoint10: waypoint
|
||||
Location: 23,32
|
||||
Owner: Neutral
|
||||
waypoint9: waypoint
|
||||
Location: 43,5
|
||||
Owner: Neutral
|
||||
waypoint8: waypoint
|
||||
Location: 60,18
|
||||
Owner: Neutral
|
||||
waypoint7: waypoint
|
||||
Location: 52,6
|
||||
Owner: Neutral
|
||||
waypoint6: waypoint
|
||||
Location: 9,16
|
||||
Owner: Neutral
|
||||
waypoint5: waypoint
|
||||
Location: 4,10
|
||||
Owner: Neutral
|
||||
waypoint4: waypoint
|
||||
Location: 12,5
|
||||
Owner: Neutral
|
||||
waypoint3: waypoint
|
||||
Location: 28,5
|
||||
Owner: Neutral
|
||||
waypoint2: waypoint
|
||||
Location: 30,20
|
||||
Owner: Neutral
|
||||
waypoint1: waypoint
|
||||
Location: 23,28
|
||||
Owner: Neutral
|
||||
GDIHeliLZ: waypoint
|
||||
Location: 41,44
|
||||
Owner: Neutral
|
||||
|
||||
Rules: cnc|rules/campaign-maprules.yaml, cnc|rules/campaign-tooltips.yaml, cnc|rules/campaign-palettes.yaml, rules.yaml
|
||||
|
||||
Weapons: weapons.yaml
|
||||
146
mods/cnc/maps/gdi09/rules.yaml
Normal file
@@ -0,0 +1,146 @@
|
||||
World:
|
||||
LuaScript:
|
||||
Scripts: campaign-global.lua, gdi09.lua, gdi09-AI.lua
|
||||
MusicPlaylist:
|
||||
StartingMusic: march
|
||||
VictoryMusic: gdi_win1
|
||||
MissionData:
|
||||
Briefing: Take out Nod turrets along shore so Gunboats can move in safely on the Nod base.\n\nThe Nod base must be destroyed.\n\nIf gunboats can get in, they should be able to destroy the base with no difficulty.\n\nKeep an eye out for the new weapon Nod is rumored to be working on.
|
||||
BriefingVideo: gdi9.vqa
|
||||
WinVideo: gunboat.vqa
|
||||
LossVideo: gameover.vqa
|
||||
|
||||
ATWR:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
NUK2:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
HPAD:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
BRIK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
EYE:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
GUN:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
OBLI:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
TMPL:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
HTNK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
TRAN:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
ORCA:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
RMBO:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MSAM:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MCV:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
BOAT:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
FTNK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
STNK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
HELI:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
LTNK:
|
||||
Buildable:
|
||||
Prerequisites: ~afld
|
||||
|
||||
ARTY:
|
||||
Buildable:
|
||||
Prerequisites: ~afld
|
||||
|
||||
E4:
|
||||
Buildable:
|
||||
Prerequisites: barracks
|
||||
|
||||
E5:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
MLRS:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
SAM:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
^Bridge:
|
||||
DamageMultiplier@INVULNERABLE:
|
||||
Modifier: 0
|
||||
|
||||
BRIDGEHUT:
|
||||
-Targetable:
|
||||
|
||||
TRAN.Extraction:
|
||||
Inherits: TRAN
|
||||
RevealsShroud:
|
||||
Range: 0c0
|
||||
RejectsOrders:
|
||||
-Selectable:
|
||||
RenderSprites:
|
||||
Image: tran
|
||||
Interactable:
|
||||
|
||||
TRAN.Insertion:
|
||||
Inherits: TRAN.Extraction
|
||||
Cargo:
|
||||
MaxWeight: 0
|
||||
|
||||
HQ:
|
||||
Tooltip:
|
||||
-AirstrikePower:
|
||||
Buildable:
|
||||
Description: Provides an overview of the battlefield.\n Requires power to operate.
|
||||
|
||||
airstrike.proxy:
|
||||
AirstrikePower:
|
||||
SquadSize: 2
|
||||
SquadOffset: -1536, 1024, 0
|
||||
|
||||
BOAT:
|
||||
AutoTarget:
|
||||
InitialStance: AttackAnything
|
||||
RejectsOrders:
|
||||
Except: Attack
|
||||
13
mods/cnc/maps/gdi09/weapons.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
BoatMissile:
|
||||
Warhead@Bonus: SpreadDamage
|
||||
Spread: 128
|
||||
Damage: 2000
|
||||
Versus:
|
||||
None: 50
|
||||
Wood: 100
|
||||
Light: 100
|
||||
Heavy: 100
|
||||
DamageTypes: Prone50Percent, TriggerProne, ExplosionDeath
|
||||
|
||||
TurretGun:
|
||||
ReloadDelay: 40
|
||||
@@ -9,6 +9,8 @@ GDI Campaign:
|
||||
gdi05b
|
||||
gdi06
|
||||
gdi07
|
||||
gdi08a
|
||||
gdi09
|
||||
|
||||
Nod Campaign:
|
||||
nod01
|
||||
|
||||
@@ -425,7 +425,7 @@ AFLD:
|
||||
Queue: Building.Nod
|
||||
Description: Provides a dropzone\nfor vehicle reinforcements
|
||||
Building:
|
||||
Footprint: XXXX xxxx ====
|
||||
Footprint: XXX+ xxx+ ====
|
||||
Dimensions: 4,3
|
||||
LocalCenterOffset: 0,-512,0
|
||||
Health:
|
||||
|
||||
|
Before Width: | Height: | Size: 409 KiB After Width: | Height: | Size: 410 KiB |
|
Before Width: | Height: | Size: 991 KiB After Width: | Height: | Size: 735 KiB |
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 168 KiB |
@@ -173,8 +173,10 @@ Background@SAVE_MAP_PANEL:
|
||||
Key: escape
|
||||
|
||||
ScrollPanel@MAP_SAVE_VISIBILITY_PANEL:
|
||||
TopBottomSpacing: 5
|
||||
ItemSpacing: 5
|
||||
Width: 220
|
||||
Height: 64
|
||||
Height: 55
|
||||
Children:
|
||||
Checkbox@VISIBILITY_TEMPLATE:
|
||||
X: 5
|
||||
@@ -618,29 +620,30 @@ Container@EDITOR_WORLD_ROOT:
|
||||
Contrast: true
|
||||
|
||||
ScrollPanel@CATEGORY_FILTER_PANEL:
|
||||
Width: 170
|
||||
Width: 240
|
||||
TopBottomSpacing: 5
|
||||
ItemSpacing: 5
|
||||
Children:
|
||||
Container@SELECT_CATEGORIES_BUTTONS:
|
||||
Width: PARENT_RIGHT
|
||||
Height: 29
|
||||
Height: 25
|
||||
Children:
|
||||
Button@SELECT_ALL:
|
||||
X: 10
|
||||
Y: 2
|
||||
Width: 60
|
||||
Y: 0 - 5
|
||||
Width: 93
|
||||
Height: 25
|
||||
Text: All
|
||||
Font: Bold
|
||||
Button@SELECT_NONE:
|
||||
X: PARENT_RIGHT - WIDTH - 34
|
||||
Y: 2
|
||||
Width: 60
|
||||
X: 10 + 93 + 10
|
||||
Y: 0 - 5
|
||||
Width: 93
|
||||
Height: 25
|
||||
Text: None
|
||||
Font: Bold
|
||||
Checkbox@CATEGORY_TEMPLATE:
|
||||
X: 5
|
||||
Y: 5
|
||||
Width: PARENT_RIGHT - 29
|
||||
Height: 20
|
||||
Visible: false
|
||||
|
||||
@@ -185,7 +185,13 @@ Background@MAINMENU_INTRODUCTION_PROMPT:
|
||||
Height: 16
|
||||
Font: Small
|
||||
Text: - Zoom the battlefield using {MODIFIER + Scroll Wheel}
|
||||
LabelWithHighlight@DESC_SCROLL:
|
||||
LabelWithHighlight@DESC_SCROLL_RIGHT:
|
||||
X: 265
|
||||
Y: 34
|
||||
Height: 16
|
||||
Font: Small
|
||||
Text: - Pan the battlefield using the {Right} mouse button
|
||||
LabelWithHighlight@DESC_SCROLL_MIDDLE:
|
||||
X: 265
|
||||
Y: 34
|
||||
Height: 16
|
||||
|
||||
@@ -491,7 +491,12 @@ Background@SETTINGS_PANEL:
|
||||
Height: 16
|
||||
Font: Small
|
||||
Text: - Zoom the battlefield using {MODIFIER + Scroll Wheel}
|
||||
LabelWithHighlight@DESC_SCROLL:
|
||||
LabelWithHighlight@DESC_SCROLL_RIGHT:
|
||||
Y: 85
|
||||
Height: 16
|
||||
Font: Small
|
||||
Text: - Pan the battlefield using the {Right} mouse button
|
||||
LabelWithHighlight@DESC_SCROLL_MIDDLE:
|
||||
Y: 85
|
||||
Height: 16
|
||||
Font: Small
|
||||
@@ -544,13 +549,13 @@ Background@SETTINGS_PANEL:
|
||||
Height: 20
|
||||
Font: Regular
|
||||
Text: Screen Edge Panning
|
||||
Checkbox@CLASSIC_MOUSE_MIDDLE_SCROLL_CHECKBOX:
|
||||
Checkbox@ALTERNATE_SCROLL_CHECKBOX:
|
||||
X: 360
|
||||
Y: 133
|
||||
Width: 180
|
||||
Height: 20
|
||||
Font: Regular
|
||||
Text: Middle Mouse Panning
|
||||
Text: Alternate Mouse Panning
|
||||
Label@SCROLL_SPEED_LABEL:
|
||||
X: 305
|
||||
Y: 210
|
||||
@@ -648,7 +653,7 @@ Background@SETTINGS_PANEL:
|
||||
Width: 80
|
||||
Height: 25
|
||||
Align: Left
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
TooltipContainer: SETTINGS_TOOLTIP_CONTAINER
|
||||
Container@THREE_COLUMN:
|
||||
Width: 173
|
||||
Height: 25
|
||||
@@ -664,7 +669,7 @@ Background@SETTINGS_PANEL:
|
||||
Width: 80
|
||||
Height: 25
|
||||
Align: Left
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
TooltipContainer: SETTINGS_TOOLTIP_CONTAINER
|
||||
Background@HOTKEY_DIALOG_ROOT:
|
||||
X: 15
|
||||
Y: 230
|
||||
@@ -716,7 +721,7 @@ Background@SETTINGS_PANEL:
|
||||
Text: Clear
|
||||
Font: Bold
|
||||
TooltipText: Unbind the hotkey
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
TooltipContainer: SETTINGS_TOOLTIP_CONTAINER
|
||||
TooltipTemplate: SIMPLE_TOOLTIP
|
||||
Button@RESET_HOTKEY_BUTTON:
|
||||
X: PARENT_RIGHT - WIDTH - 20
|
||||
@@ -726,7 +731,7 @@ Background@SETTINGS_PANEL:
|
||||
Text: Reset
|
||||
Font: Bold
|
||||
TooltipText: Reset to default
|
||||
TooltipContainer: TOOLTIP_CONTAINER
|
||||
TooltipContainer: SETTINGS_TOOLTIP_CONTAINER
|
||||
TooltipTemplate: SIMPLE_TOOLTIP
|
||||
Container@ADVANCED_PANEL:
|
||||
X: 5
|
||||
@@ -846,4 +851,4 @@ Background@SETTINGS_PANEL:
|
||||
Height: 20
|
||||
Font: Regular
|
||||
Text: Enable Debug Commands in Replays
|
||||
TooltipContainer@TOOLTIP_CONTAINER:
|
||||
TooltipContainer@SETTINGS_TOOLTIP_CONTAINER:
|
||||
|
||||
@@ -39,7 +39,7 @@ InitObjectives = function(player)
|
||||
end)
|
||||
end
|
||||
|
||||
SendCarryallReinforcements = function(player, currentWave, totalWaves, delay, pathFunction, unitTypes, customCondition, customHuntFunction)
|
||||
SendCarryallReinforcements = function(player, currentWave, totalWaves, delay, pathFunction, unitTypes, customCondition, customHuntFunction, announcementFunction)
|
||||
Trigger.AfterDelay(delay, function()
|
||||
if customCondition and customCondition() then
|
||||
return
|
||||
@@ -50,6 +50,10 @@ SendCarryallReinforcements = function(player, currentWave, totalWaves, delay, pa
|
||||
return
|
||||
end
|
||||
|
||||
if announcementFunction then
|
||||
announcementFunction(currentWave)
|
||||
end
|
||||
|
||||
local path = pathFunction()
|
||||
local units = Reinforcements.ReinforceWithTransport(player, "carryall.reinforce", unitTypes[currentWave], path, { path[1] })[2]
|
||||
|
||||
@@ -78,6 +82,10 @@ TriggerCarryallReinforcements = function(triggeringPlayer, reinforcingPlayer, ar
|
||||
end)
|
||||
end
|
||||
|
||||
DestroyCarryalls = function(player)
|
||||
Utils.Do(player.GetActorsByType("carryall"), function(actor) actor.Kill() end)
|
||||
end
|
||||
|
||||
-- Used for the AI:
|
||||
|
||||
IdlingUnits = { }
|
||||
|
||||
@@ -48,7 +48,7 @@ sidebar-bits:
|
||||
production-tooltip-time: 136, 51, 16, 16
|
||||
production-tooltip-power: 102, 51, 16, 16
|
||||
production-tooltip-cost: 68, 51, 16, 16
|
||||
indicator-muted: 0, 119, 24, 24
|
||||
indicator-muted: 0, 119, 26, 24
|
||||
|
||||
commandbar:
|
||||
Inherits: ^Chrome
|
||||
|
||||
BIN
mods/d2k/maps/ordos-06a/map.bin
Normal file
BIN
mods/d2k/maps/ordos-06a/map.png
Normal file
|
After Width: | Height: | Size: 301 KiB |
578
mods/d2k/maps/ordos-06a/map.yaml
Normal file
@@ -0,0 +1,578 @@
|
||||
MapFormat: 11
|
||||
|
||||
RequiresMod: d2k
|
||||
|
||||
Title: Ordos 06a
|
||||
|
||||
Author: Westwood Studios
|
||||
|
||||
Tileset: ARRAKIS
|
||||
|
||||
MapSize: 84,84
|
||||
|
||||
Bounds: 2,2,80,80
|
||||
|
||||
Visibility: MissionSelector
|
||||
|
||||
Categories: Campaign
|
||||
|
||||
LockPreview: True
|
||||
|
||||
Players:
|
||||
PlayerReference@Neutral:
|
||||
Name: Neutral
|
||||
OwnsWorld: True
|
||||
NonCombatant: True
|
||||
Faction: Random
|
||||
PlayerReference@Creeps:
|
||||
Name: Creeps
|
||||
NonCombatant: True
|
||||
Faction: Random
|
||||
Enemies: Atreides, Ordos, Harkonnen
|
||||
PlayerReference@Ordos:
|
||||
Name: Ordos
|
||||
Playable: True
|
||||
LockFaction: True
|
||||
Faction: ordos
|
||||
LockColor: True
|
||||
Color: B3EAA5
|
||||
Enemies: Atreides, Harkonnen, Creeps
|
||||
PlayerReference@Atreides:
|
||||
Name: Atreides
|
||||
LockFaction: True
|
||||
Faction: atreides
|
||||
LockColor: True
|
||||
Color: 9191FF
|
||||
Allies: Harkonnen
|
||||
Enemies: Ordos, Creeps
|
||||
PlayerReference@Harkonnen:
|
||||
Name: Harkonnen
|
||||
LockFaction: True
|
||||
Faction: harkonnen
|
||||
LockColor: True
|
||||
Color: FE0000
|
||||
Allies: Atreides
|
||||
Enemies: Ordos, Creeps
|
||||
|
||||
Actors:
|
||||
Actor0: wall
|
||||
Location: 65,2
|
||||
Owner: Ordos
|
||||
AHeavyFactory: heavy_factory
|
||||
Location: 3,3
|
||||
Owner: Atreides
|
||||
AConyard: construction_yard
|
||||
Location: 8,3
|
||||
Owner: Atreides
|
||||
APower1: wind_trap
|
||||
Location: 11,3
|
||||
Owner: Atreides
|
||||
APower2: wind_trap
|
||||
Location: 13,3
|
||||
Owner: Atreides
|
||||
ALightFactory: light_factory
|
||||
Location: 16,3
|
||||
Owner: Atreides
|
||||
Actor6: wall
|
||||
Location: 65,3
|
||||
Owner: Ordos
|
||||
OOutpost: outpost
|
||||
Location: 66,3
|
||||
Owner: Ordos
|
||||
OPower1: wind_trap
|
||||
Location: 72,3
|
||||
Owner: Ordos
|
||||
OPower2: wind_trap
|
||||
Location: 74,3
|
||||
Owner: Ordos
|
||||
OConyard: construction_yard
|
||||
Location: 76,3
|
||||
Owner: Ordos
|
||||
OBarracks: barracks
|
||||
Location: 79,3
|
||||
Owner: Ordos
|
||||
Actor12: wall
|
||||
Location: 65,4
|
||||
Owner: Ordos
|
||||
ARock1: large_gun_turret
|
||||
Location: 20,5
|
||||
Facing: 160
|
||||
Owner: Atreides
|
||||
Actor14: wall
|
||||
Location: 65,5
|
||||
Owner: Ordos
|
||||
Actor15: combat_tank_a
|
||||
Location: 13,6
|
||||
Owner: Atreides
|
||||
Actor16: wall
|
||||
Location: 65,6
|
||||
Owner: Ordos
|
||||
APower3: wind_trap
|
||||
Location: 7,7
|
||||
Owner: Atreides
|
||||
APower4: wind_trap
|
||||
Location: 9,7
|
||||
Owner: Atreides
|
||||
APower5: wind_trap
|
||||
Location: 11,7
|
||||
Owner: Atreides
|
||||
APower6: wind_trap
|
||||
Location: 13,7
|
||||
Owner: Atreides
|
||||
APower7: wind_trap
|
||||
Location: 15,7
|
||||
Owner: Atreides
|
||||
Actor22: wall
|
||||
Location: 65,7
|
||||
Owner: Ordos
|
||||
Actor23: trooper
|
||||
Location: 4,8
|
||||
Owner: Atreides
|
||||
Actor24: wall
|
||||
Location: 65,8
|
||||
Owner: Ordos
|
||||
Actor25: wall
|
||||
Location: 66,8
|
||||
Owner: Ordos
|
||||
Actor26: wall
|
||||
Location: 67,8
|
||||
Owner: Ordos
|
||||
Actor27: wall
|
||||
Location: 68,8
|
||||
Owner: Ordos
|
||||
Actor28: wall
|
||||
Location: 69,8
|
||||
Owner: Ordos
|
||||
Actor29: wall
|
||||
Location: 70,8
|
||||
Owner: Ordos
|
||||
ABarracks: barracks
|
||||
Location: 2,9
|
||||
Owner: Atreides
|
||||
Actor31: wall
|
||||
Location: 70,9
|
||||
Owner: Ordos
|
||||
Actor32: wall
|
||||
Location: 79,9
|
||||
Owner: Ordos
|
||||
Actor33: wall
|
||||
Location: 80,9
|
||||
Owner: Ordos
|
||||
Actor34: wall
|
||||
Location: 81,9
|
||||
Owner: Ordos
|
||||
APower8: wind_trap
|
||||
Location: 10,10
|
||||
Owner: Atreides
|
||||
Actor36: wall
|
||||
Location: 70,10
|
||||
Owner: Ordos
|
||||
Actor37: wall
|
||||
Location: 79,10
|
||||
Owner: Ordos
|
||||
AResearch: research_centre
|
||||
Location: 5,11
|
||||
Owner: Atreides
|
||||
Actor39: wall
|
||||
Location: 70,11
|
||||
Owner: Ordos
|
||||
Actor40: wall
|
||||
Location: 79,11
|
||||
Owner: Ordos
|
||||
APower9: wind_trap
|
||||
Location: 2,12
|
||||
Owner: Atreides
|
||||
Actor42: combat_tank_a
|
||||
Location: 8,12
|
||||
Owner: Atreides
|
||||
ARepair: repair_pad
|
||||
Location: 13,12
|
||||
Owner: Atreides
|
||||
ARock2: large_gun_turret
|
||||
Location: 16,12
|
||||
Facing: 160
|
||||
Owner: Atreides
|
||||
Actor45: wall
|
||||
Location: 70,12
|
||||
Owner: Ordos
|
||||
OGunt1: medium_gun_turret
|
||||
Location: 71,12
|
||||
Owner: Ordos
|
||||
OGunt2: medium_gun_turret
|
||||
Location: 78,12
|
||||
Owner: Ordos
|
||||
Actor48: wall
|
||||
Location: 79,12
|
||||
Owner: Ordos
|
||||
APower10: wind_trap
|
||||
Location: 2,15
|
||||
Owner: Atreides
|
||||
APower11: wind_trap
|
||||
Location: 4,15
|
||||
Owner: Atreides
|
||||
APower12: wind_trap
|
||||
Location: 6,15
|
||||
Owner: Atreides
|
||||
Actor52: combat_tank_a
|
||||
Location: 11,17
|
||||
Owner: Atreides
|
||||
Actor53: combat_tank_a
|
||||
Location: 8,18
|
||||
Owner: Atreides
|
||||
Actor54: wall
|
||||
Location: 10,19
|
||||
Owner: Atreides
|
||||
Actor55: wall
|
||||
Location: 11,19
|
||||
Owner: Atreides
|
||||
ARefinery: refinery
|
||||
Location: 2,20
|
||||
Owner: Atreides
|
||||
Actor57: wall
|
||||
Location: 10,20
|
||||
Owner: Atreides
|
||||
Actor58: combat_tank_a
|
||||
Location: 6,21
|
||||
Owner: Atreides
|
||||
Actor59: wall
|
||||
Location: 10,21
|
||||
Owner: Atreides
|
||||
Actor60: spicebloom.spawnpoint
|
||||
Location: 38,21
|
||||
Owner: Neutral
|
||||
Actor61: wall
|
||||
Location: 10,22
|
||||
Owner: Atreides
|
||||
Actor62: carryall
|
||||
Location: 4,23
|
||||
Owner: Atreides
|
||||
Actor63: harvester
|
||||
Location: 5,23
|
||||
Owner: Atreides
|
||||
ARock3: large_gun_turret
|
||||
Location: 10,23
|
||||
Facing: 192
|
||||
Owner: Atreides
|
||||
Actor65: wall
|
||||
Location: 11,23
|
||||
Owner: Atreides
|
||||
AGunt1: medium_gun_turret
|
||||
Location: 12,23
|
||||
Facing: 192
|
||||
Owner: Atreides
|
||||
Actor67: wormspawner
|
||||
Location: 26,23
|
||||
Owner: Creeps
|
||||
Actor68: siege_tank
|
||||
Location: 5,24
|
||||
Owner: Atreides
|
||||
Actor69: spicebloom.spawnpoint
|
||||
Location: 67,24
|
||||
Owner: Neutral
|
||||
Actor70: wall
|
||||
Location: 2,25
|
||||
Owner: Atreides
|
||||
Actor71: wall
|
||||
Location: 3,25
|
||||
Owner: Atreides
|
||||
Actor72: wall
|
||||
Location: 4,25
|
||||
Owner: Atreides
|
||||
Actor73: wall
|
||||
Location: 5,25
|
||||
Owner: Atreides
|
||||
Actor74: wall
|
||||
Location: 6,25
|
||||
Owner: Atreides
|
||||
ARock4: large_gun_turret
|
||||
Location: 7,25
|
||||
Owner: Atreides
|
||||
Actor76: wall
|
||||
Location: 7,26
|
||||
Owner: Atreides
|
||||
AGunt2: medium_gun_turret
|
||||
Location: 7,27
|
||||
Owner: Atreides
|
||||
Actor78: spicebloom.spawnpoint
|
||||
Location: 76,30
|
||||
Owner: Neutral
|
||||
Actor79: spicebloom.spawnpoint
|
||||
Location: 32,33
|
||||
Owner: Neutral
|
||||
Actor80: spicebloom.spawnpoint
|
||||
Location: 56,33
|
||||
Owner: Neutral
|
||||
Actor81: spicebloom.spawnpoint
|
||||
Location: 7,37
|
||||
Owner: Neutral
|
||||
Actor82: spicebloom.spawnpoint
|
||||
Location: 44,48
|
||||
Owner: Neutral
|
||||
Actor83: spicebloom.spawnpoint
|
||||
Location: 77,48
|
||||
Owner: Neutral
|
||||
Actor84: trooper
|
||||
Location: 78,50
|
||||
Owner: Ordos
|
||||
Actor85: trooper
|
||||
Location: 76,53
|
||||
Owner: Ordos
|
||||
Actor86: trooper
|
||||
Location: 77,53
|
||||
Owner: Ordos
|
||||
OStarport: starport
|
||||
Location: 79,53
|
||||
Owner: Ordos
|
||||
Actor88: trooper
|
||||
Location: 77,55
|
||||
Owner: Ordos
|
||||
Actor89: raider
|
||||
Location: 78,56
|
||||
Owner: Ordos
|
||||
HGunt1: medium_gun_turret
|
||||
Location: 30,57
|
||||
Facing: 0
|
||||
Owner: Harkonnen
|
||||
HGunt2: medium_gun_turret
|
||||
Location: 34,57
|
||||
Facing: 0
|
||||
Owner: Harkonnen
|
||||
Actor92: wall
|
||||
Location: 30,58
|
||||
Owner: Harkonnen
|
||||
Actor93: combat_tank_h
|
||||
Location: 32,58
|
||||
Owner: Harkonnen
|
||||
Actor94: wall
|
||||
Location: 34,58
|
||||
Owner: Harkonnen
|
||||
Actor95: wall
|
||||
Location: 30,59
|
||||
Owner: Harkonnen
|
||||
Actor96: trooper
|
||||
Location: 33,59
|
||||
Owner: Harkonnen
|
||||
Actor97: wall
|
||||
Location: 34,59
|
||||
Owner: Harkonnen
|
||||
Actor98: wall
|
||||
Location: 30,60
|
||||
Owner: Harkonnen
|
||||
Actor99: trooper
|
||||
Location: 31,60
|
||||
Owner: Harkonnen
|
||||
Actor100: wall
|
||||
Location: 34,60
|
||||
Owner: Harkonnen
|
||||
Actor101: wall
|
||||
Location: 29,61
|
||||
Owner: Harkonnen
|
||||
Actor102: wall
|
||||
Location: 30,61
|
||||
Owner: Harkonnen
|
||||
Actor103: wall
|
||||
Location: 34,61
|
||||
Owner: Harkonnen
|
||||
Actor104: wall
|
||||
Location: 35,61
|
||||
Owner: Harkonnen
|
||||
Actor105: wall
|
||||
Location: 29,62
|
||||
Owner: Harkonnen
|
||||
Actor106: wall
|
||||
Location: 35,62
|
||||
Owner: Harkonnen
|
||||
Actor107: wall
|
||||
Location: 29,63
|
||||
Owner: Harkonnen
|
||||
Actor108: wall
|
||||
Location: 35,63
|
||||
Owner: Harkonnen
|
||||
Actor109: wall
|
||||
Location: 36,63
|
||||
Owner: Harkonnen
|
||||
Actor110: wall
|
||||
Location: 37,63
|
||||
Owner: Harkonnen
|
||||
Actor111: harvester
|
||||
Location: 31,65
|
||||
Owner: Harkonnen
|
||||
HSilo1: silo
|
||||
Location: 35,65
|
||||
Owner: Harkonnen
|
||||
Actor113: carryall
|
||||
Location: 32,66
|
||||
Owner: Harkonnen
|
||||
HSilo2: silo
|
||||
Location: 35,66
|
||||
Owner: Harkonnen
|
||||
HRefinery: refinery
|
||||
Location: 30,67
|
||||
Owner: Harkonnen
|
||||
HSilo3: silo
|
||||
Location: 35,67
|
||||
Owner: Harkonnen
|
||||
Actor117: spicebloom.spawnpoint
|
||||
Location: 22,68
|
||||
Owner: Neutral
|
||||
HOutpost: outpost
|
||||
Location: 35,70
|
||||
Owner: Harkonnen
|
||||
HPower1: wind_trap
|
||||
Location: 31,71
|
||||
Owner: Harkonnen
|
||||
HPower2: wind_trap
|
||||
Location: 34,73
|
||||
Owner: Harkonnen
|
||||
HPower3: wind_trap
|
||||
Location: 36,73
|
||||
Owner: Harkonnen
|
||||
HPower4: wind_trap
|
||||
Location: 38,73
|
||||
Owner: Harkonnen
|
||||
Actor123: wall
|
||||
Location: 24,74
|
||||
Owner: Harkonnen
|
||||
HPower5: wind_trap
|
||||
Location: 26,74
|
||||
Owner: Harkonnen
|
||||
HPower6: wind_trap
|
||||
Location: 28,74
|
||||
Owner: Harkonnen
|
||||
HPower7: wind_trap
|
||||
Location: 30,74
|
||||
Owner: Harkonnen
|
||||
Actor127: wall
|
||||
Location: 24,75
|
||||
Owner: Harkonnen
|
||||
Actor128: spicebloom.spawnpoint
|
||||
Location: 58,75
|
||||
Owner: Neutral
|
||||
HGunt3: medium_gun_turret
|
||||
Location: 19,76
|
||||
Facing: 32
|
||||
Owner: Harkonnen
|
||||
Actor130: wall
|
||||
Location: 20,76
|
||||
Owner: Harkonnen
|
||||
Actor131: wall
|
||||
Location: 21,76
|
||||
Owner: Harkonnen
|
||||
Actor132: wall
|
||||
Location: 22,76
|
||||
Owner: Harkonnen
|
||||
Actor133: wall
|
||||
Location: 23,76
|
||||
Owner: Harkonnen
|
||||
Actor134: wall
|
||||
Location: 24,76
|
||||
Owner: Harkonnen
|
||||
Actor135: wall
|
||||
Location: 19,77
|
||||
Owner: Harkonnen
|
||||
HHeavyFactory: heavy_factory
|
||||
Location: 33,77
|
||||
Owner: Harkonnen
|
||||
HRock: large_gun_turret
|
||||
Location: 38,77
|
||||
Facing: 192
|
||||
Owner: Harkonnen
|
||||
HPower8: wind_trap
|
||||
Location: 23,78
|
||||
Owner: Harkonnen
|
||||
HConyard: construction_yard
|
||||
Location: 25,78
|
||||
Owner: Harkonnen
|
||||
HPower9: wind_trap
|
||||
Location: 28,78
|
||||
Owner: Harkonnen
|
||||
HPower10: wind_trap
|
||||
Location: 30,78
|
||||
Owner: Harkonnen
|
||||
Actor142: combat_tank_h
|
||||
Location: 20,79
|
||||
Owner: Harkonnen
|
||||
HBarracks: barracks
|
||||
Location: 36,79
|
||||
Owner: Harkonnen
|
||||
HGunt4: medium_gun_turret
|
||||
Location: 19,80
|
||||
Facing: 64
|
||||
Owner: Harkonnen
|
||||
Actor145: wall
|
||||
Location: 39,80
|
||||
Owner: Harkonnen
|
||||
Actor146: wall
|
||||
Location: 19,81
|
||||
Owner: Harkonnen
|
||||
Actor147: wall
|
||||
Location: 39,81
|
||||
Owner: Harkonnen
|
||||
AtreidesRally1: waypoint
|
||||
Owner: Neutral
|
||||
Location: 8,22
|
||||
AtreidesEntry1: waypoint
|
||||
Owner: Neutral
|
||||
Location: 2,22
|
||||
HarkonnenRally1: waypoint
|
||||
Owner: Neutral
|
||||
Location: 32,64
|
||||
HarkonnenEntry1: waypoint
|
||||
Owner: Neutral
|
||||
Location: 32,81
|
||||
AtreidesRally2: waypoint
|
||||
Owner: Neutral
|
||||
Location: 77,76
|
||||
AtreidesEntry2: waypoint
|
||||
Owner: Neutral
|
||||
Location: 77,81
|
||||
AtreidesRally3: waypoint
|
||||
Owner: Neutral
|
||||
Location: 36,34
|
||||
AtreidesEntry3: waypoint
|
||||
Owner: Neutral
|
||||
Location: 36,2
|
||||
AtreidesRally4: waypoint
|
||||
Owner: Neutral
|
||||
Location: 68,41
|
||||
AtreidesEntry4: waypoint
|
||||
Owner: Neutral
|
||||
Location: 81,41
|
||||
HarkonnenRally2: waypoint
|
||||
Owner: Neutral
|
||||
Location: 44,59
|
||||
HarkonnenEntry2: waypoint
|
||||
Owner: Neutral
|
||||
Location: 44,81
|
||||
HarkonnenRally3: waypoint
|
||||
Owner: Neutral
|
||||
Location: 77,77
|
||||
HarkonnenEntry3: waypoint
|
||||
Owner: Neutral
|
||||
Location: 81,77
|
||||
HarkonnenRally4: waypoint
|
||||
Owner: Neutral
|
||||
Location: 56,50
|
||||
HarkonnenEntry4: waypoint
|
||||
Owner: Neutral
|
||||
Location: 56,81
|
||||
HarkonnenRally5: waypoint
|
||||
Owner: Neutral
|
||||
Location: 54,41
|
||||
HarkonnenEntry5: waypoint
|
||||
Owner: Neutral
|
||||
Location: 81,41
|
||||
HarkonnenRally6: waypoint
|
||||
Owner: Neutral
|
||||
Location: 52,33
|
||||
HarkonnenEntry6: waypoint
|
||||
Owner: Neutral
|
||||
Location: 81,33
|
||||
HarkonnenRally7: waypoint
|
||||
Owner: Neutral
|
||||
Location: 34,26
|
||||
HarkonnenEntry7: waypoint
|
||||
Owner: Neutral
|
||||
Location: 34,2
|
||||
|
||||
Rules: d2k|rules/campaign-rules.yaml, d2k|rules/campaign-tooltips.yaml, d2k|rules/campaign-palettes.yaml, rules.yaml
|
||||
54
mods/d2k/maps/ordos-06a/ordos06a-AI.lua
Normal file
@@ -0,0 +1,54 @@
|
||||
--[[
|
||||
Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
|
||||
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.
|
||||
]]
|
||||
|
||||
AttackGroupSize =
|
||||
{
|
||||
easy = 6,
|
||||
normal = 8,
|
||||
hard = 10
|
||||
}
|
||||
|
||||
ProductionDelays =
|
||||
{
|
||||
easy = { DateTime.Seconds(16), DateTime.Seconds(30) },
|
||||
normal = { DateTime.Seconds(2), DateTime.Seconds(5) },
|
||||
hard = { DateTime.Seconds(1), DateTime.Seconds(3) }
|
||||
}
|
||||
|
||||
EnemyInfantryTypes = { "light_inf", "light_inf", "light_inf", "trooper", "trooper" }
|
||||
EnemyVehicleTypes = { "trike", "trike", "quad" }
|
||||
|
||||
AtreidesTankTypes = { "combat_tank_a", "siege_tank", "missile_tank" }
|
||||
HarkonnenTankTypes = { "combat_tank_h", "siege_tank" }
|
||||
|
||||
InitAIUnits = function(house)
|
||||
LastHarvesterEaten[house] = true
|
||||
IdlingUnits[house] = Reinforcements.Reinforce(house, InitialReinforcements[house.InternalName], InitialReinforcementsPaths[house.InternalName])
|
||||
|
||||
DefendAndRepairBase(house, Base[house.InternalName], 0.75, AttackGroupSize[Difficulty])
|
||||
end
|
||||
|
||||
ActivateAI = function()
|
||||
InitAIUnits(atreides)
|
||||
InitAIUnits(harkonnen)
|
||||
|
||||
local delay = function() return Utils.RandomInteger(ProductionDelays[Difficulty][1], ProductionDelays[Difficulty][2] + 1) end
|
||||
local infantryToBuild = function() return { Utils.Random(EnemyInfantryTypes) } end
|
||||
local vehiclesToBuild = function() return { Utils.Random(EnemyVehicleTypes) } end
|
||||
local tanksToBuildAtreides = function() return { Utils.Random(AtreidesTankTypes) } end
|
||||
local tanksToBuildHarkonnen = function() return { Utils.Random(HarkonnenTankTypes) } end
|
||||
local attackTresholdSize = AttackGroupSize[Difficulty] * 2.5
|
||||
|
||||
ProduceUnits(atreides, ABarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackTresholdSize)
|
||||
ProduceUnits(atreides, ALightFactory, delay, vehiclesToBuild, AttackGroupSize[Difficulty], attackTresholdSize)
|
||||
ProduceUnits(atreides, AHeavyFactory, delay, tanksToBuildAtreides, AttackGroupSize[Difficulty], attackTresholdSize)
|
||||
|
||||
ProduceUnits(harkonnen, HBarracks, delay, infantryToBuild, AttackGroupSize[Difficulty], attackTresholdSize)
|
||||
ProduceUnits(harkonnen, HHeavyFactory, delay, tanksToBuildHarkonnen, AttackGroupSize[Difficulty], attackTresholdSize)
|
||||
end
|
||||
275
mods/d2k/maps/ordos-06a/ordos06a.lua
Normal file
@@ -0,0 +1,275 @@
|
||||
--[[
|
||||
Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
|
||||
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.
|
||||
]]
|
||||
|
||||
Base =
|
||||
{
|
||||
Atreides = { AConyard, APower1, APower2, APower3, APower4, APower5, APower6, APower7, APower8, APower9, APower10, APower11, APower12, ABarracks, ARefinery, ALightFactory, AHeavyFactory, ARepair, AResearch, AGunt1, AGunt2, ARock1, ARock2, ARock3, ARock4 },
|
||||
Harkonnen = { HConyard, HPower1, HPower2, HPower3, HPower4, HPower5, HPower6, HPower7, HPower8, HPower9, HPower10, HBarracks, HRefinery, HOutpost, HHeavyFactory, HGunt1, HGunt2, HGunt3, HGunt4, HRock, HSilo1, HSilo2, HSilo3 }
|
||||
}
|
||||
|
||||
AtreidesReinforcements =
|
||||
{
|
||||
easy =
|
||||
{
|
||||
{ "light_inf", "light_inf", "light_inf", "trooper", "trooper" },
|
||||
{ "quad", "quad", "combat_tank_a" },
|
||||
{ "light_inf", "light_inf", "light_inf", "trooper", "trooper", "quad", "quad" }
|
||||
},
|
||||
|
||||
normal =
|
||||
{
|
||||
{ "light_inf", "light_inf", "light_inf", "trooper", "trooper", "quad", "quad" },
|
||||
{ "quad", "quad", "combat_tank_a", "combat_tank_a" },
|
||||
{ "light_inf", "light_inf", "light_inf", "trooper", "trooper", "quad", "quad", "quad" },
|
||||
{ "combat_tank_a", "combat_tank_a", "combat_tank_a" }
|
||||
},
|
||||
|
||||
hard =
|
||||
{
|
||||
{ "light_inf", "light_inf", "light_inf", "trooper", "trooper", "trooper", "quad", "quad" },
|
||||
{ "quad", "quad", "quad", "combat_tank_a", "combat_tank_a" },
|
||||
{ "light_inf", "light_inf", "light_inf", "trooper", "trooper", "quad", "quad", "quad", "quad" },
|
||||
{ "combat_tank_a", "combat_tank_a", "combat_tank_a", "quad" },
|
||||
{ "combat_tank_a", "combat_tank_a", "missile_tank", "siege_tank" }
|
||||
}
|
||||
}
|
||||
|
||||
HarkonnenReinforcements =
|
||||
{
|
||||
easy =
|
||||
{
|
||||
{ "quad", "trike", "trike" },
|
||||
{ "light_inf", "light_inf", "light_inf", "trooper", "trooper" },
|
||||
{ "combat_tank_h", "quad" },
|
||||
{ "trooper", "trooper", "trooper", "trooper", "trooper" }
|
||||
},
|
||||
|
||||
normal =
|
||||
{
|
||||
{ "combat_tank_h", "combat_tank_h", "trike", "trike" },
|
||||
{ "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "trooper", "trooper" },
|
||||
{ "combat_tank_h", "quad", "quad" },
|
||||
{ "trooper", "trooper", "trooper", "trooper", "trooper", "trooper", "trooper" },
|
||||
{ "trike", "trike", "quad", "siege_tank" }
|
||||
},
|
||||
|
||||
hard =
|
||||
{
|
||||
{ "combat_tank_h", "combat_tank_h", "trike", "trike", "trike" },
|
||||
{ "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "light_inf", "trooper", "trooper" },
|
||||
{ "combat_tank_h", "combat_tank_h", "quad", "quad" },
|
||||
{ "trooper", "trooper", "trooper", "trooper", "trooper", "trooper", "trooper", "trooper" },
|
||||
{ "trike", "trike", "quad", "quad", "siege_tank" },
|
||||
{ "missile_tank", "missile_tank", "missile_tank", "missile_tank" }
|
||||
}
|
||||
}
|
||||
|
||||
IxianReinforcements =
|
||||
{
|
||||
easy = { "deviator", "deviator", "missile_tank", "missile_tank", "missile_tank", "siege_tank", "siege_tank", "combat_tank_o", "combat_tank_o" },
|
||||
normal = { "deviator", "deviator", "missile_tank", "missile_tank", "missile_tank", "siege_tank", "siege_tank", "combat_tank_o" },
|
||||
hard = { "deviator", "deviator", "missile_tank", "missile_tank", "siege_tank", "siege_tank", "combat_tank_o" }
|
||||
}
|
||||
|
||||
EnemyAttackDelay =
|
||||
{
|
||||
easy = DateTime.Minutes(5) + DateTime.Seconds(15),
|
||||
normal = DateTime.Minutes(3) + DateTime.Seconds(15),
|
||||
hard = DateTime.Minutes(1) + DateTime.Seconds(30)
|
||||
}
|
||||
|
||||
AtreidesPaths =
|
||||
{
|
||||
{ AtreidesEntry2.Location, AtreidesRally2.Location },
|
||||
{ AtreidesEntry3.Location, AtreidesRally3.Location },
|
||||
{ AtreidesEntry4.Location, AtreidesRally4.Location }
|
||||
}
|
||||
|
||||
HarkonnenPaths =
|
||||
{
|
||||
{ HarkonnenEntry2.Location, HarkonnenRally2.Location },
|
||||
{ HarkonnenEntry3.Location, HarkonnenRally3.Location },
|
||||
{ HarkonnenEntry4.Location, HarkonnenRally4.Location },
|
||||
{ HarkonnenEntry5.Location, HarkonnenRally5.Location },
|
||||
{ HarkonnenEntry6.Location, HarkonnenRally6.Location },
|
||||
{ HarkonnenEntry7.Location, HarkonnenRally7.Location }
|
||||
}
|
||||
|
||||
AtreidesAttackWaves =
|
||||
{
|
||||
easy = 3,
|
||||
normal = 4,
|
||||
hard = 5
|
||||
}
|
||||
|
||||
HarkonnenAttackWaves =
|
||||
{
|
||||
easy = 4,
|
||||
normal = 5,
|
||||
hard = 6
|
||||
}
|
||||
|
||||
InitialReinforcements =
|
||||
{
|
||||
Atreides = { "combat_tank_a", "quad", "quad", "trike", "trike" },
|
||||
Harkonnen = { "trooper", "trooper", "trooper", "trooper", "trooper", "combat_tank_h" }
|
||||
}
|
||||
|
||||
InitialReinforcementsPaths =
|
||||
{
|
||||
Atreides = { AtreidesEntry1.Location, AtreidesRally1.Location },
|
||||
Harkonnen = { HarkonnenEntry1.Location, HarkonnenRally1.Location }
|
||||
}
|
||||
|
||||
InitialContrabandTimes =
|
||||
{
|
||||
easy = DateTime.Minutes(10),
|
||||
normal = DateTime.Minutes(15),
|
||||
hard = DateTime.Minutes(20)
|
||||
}
|
||||
|
||||
ContrabandTimes =
|
||||
{
|
||||
easy = DateTime.Minutes(4),
|
||||
normal = DateTime.Minutes(6),
|
||||
hard = DateTime.Minutes(7)
|
||||
}
|
||||
|
||||
SendContraband = function()
|
||||
Media.PlaySpeechNotification(player, "Reinforce")
|
||||
|
||||
for i = 0, 6 do
|
||||
local c = player.Color
|
||||
if i % 2 == 0 then
|
||||
c = HSLColor.White
|
||||
end
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(i), function() UserInterface.SetMissionText("Ixian reinforcements have arrived!", c) end)
|
||||
end
|
||||
Trigger.AfterDelay(DateTime.Seconds(6), function()
|
||||
TimerTicks = ContrabandTimes[Difficulty]
|
||||
end)
|
||||
|
||||
local entryPath = { CPos.New(82, OStarport.Location.Y + 1), OStarport.Location + CVec.New(1, 1) }
|
||||
local exitPath = { CPos.New(2, OStarport.Location.Y + 1) }
|
||||
Reinforcements.ReinforceWithTransport(player, "frigate", IxianReinforcements[Difficulty], entryPath, exitPath)
|
||||
end
|
||||
|
||||
Hunt = function(house)
|
||||
Trigger.OnAllKilledOrCaptured(Base[house.InternalName], function()
|
||||
Utils.Do(house.GetGroundAttackers(), IdleHunt)
|
||||
end)
|
||||
end
|
||||
|
||||
CheckHarvester = function(house)
|
||||
if DateTime.GameTime % DateTime.Seconds(10) == 0 and LastHarvesterEaten[house] then
|
||||
local units = house.GetActorsByType("harvester")
|
||||
|
||||
if #units > 0 then
|
||||
LastHarvesterEaten[house] = false
|
||||
ProtectHarvester(units[1], house, AttackGroupSize[Difficulty])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Tick = function()
|
||||
if not player.IsObjectiveCompleted(KillAtreides) and atreides.HasNoRequiredUnits() then
|
||||
Media.DisplayMessage("The Atreides have been annihilated!", "Mentat")
|
||||
player.MarkCompletedObjective(KillAtreides)
|
||||
DestroyCarryalls(atreides)
|
||||
|
||||
if player.IsObjectiveCompleted(KillHarkonnen) then
|
||||
player.MarkCompletedObjective(GuardStarport)
|
||||
end
|
||||
end
|
||||
|
||||
if not player.IsObjectiveCompleted(KillHarkonnen) and harkonnen.HasNoRequiredUnits() then
|
||||
Media.DisplayMessage("The Harkonnen have been annihilated!", "Mentat")
|
||||
player.MarkCompletedObjective(KillHarkonnen)
|
||||
DestroyCarryalls(harkonnen)
|
||||
|
||||
if player.IsObjectiveCompleted(KillAtreides) then
|
||||
player.MarkCompletedObjective(GuardStarport)
|
||||
end
|
||||
end
|
||||
|
||||
if TimerTicks and TimerTicks > 0 then
|
||||
TimerTicks = TimerTicks - 1
|
||||
|
||||
if TimerTicks == 0 then
|
||||
if not FirstIxiansArrived then
|
||||
Media.DisplayMessage("Deliveries beginning to arrive. Massive reinforcements expected!", "Mentat")
|
||||
end
|
||||
|
||||
FirstIxiansArrived = true
|
||||
SendContraband()
|
||||
else
|
||||
local text = "Initial"
|
||||
if FirstIxiansArrived then
|
||||
text = "Additional"
|
||||
end
|
||||
|
||||
UserInterface.SetMissionText(text .. " reinforcements will arrive in " .. Utils.FormatTime(TimerTicks), player.Color)
|
||||
end
|
||||
end
|
||||
|
||||
CheckHarvester(atreides)
|
||||
CheckHarvester(harkonnen)
|
||||
end
|
||||
|
||||
WorldLoaded = function()
|
||||
atreides = Player.GetPlayer("Atreides")
|
||||
harkonnen = Player.GetPlayer("Harkonnen")
|
||||
player = Player.GetPlayer("Ordos")
|
||||
|
||||
InitObjectives(player)
|
||||
GuardStarport = player.AddObjective("Defend the Starport.")
|
||||
KillAtreides = player.AddObjective("Destroy the Atreides.")
|
||||
KillHarkonnen = player.AddObjective("Destroy the Harkonnen.")
|
||||
|
||||
Camera.Position = OConyard.CenterPosition
|
||||
EnemyAttackLocations = { OConyard.Location, OStarport.Location }
|
||||
|
||||
Trigger.OnRemovedFromWorld(OStarport, function()
|
||||
player.MarkFailedObjective(GuardStarport)
|
||||
end)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(2), function()
|
||||
TimerTicks = InitialContrabandTimes[Difficulty]
|
||||
Media.DisplayMessage("The first batch of Ixian reinforcements will arrive in " .. Utils.FormatTime(TimerTicks) .. ".", "Mentat")
|
||||
end)
|
||||
|
||||
Hunt(atreides)
|
||||
Hunt(harkonnen)
|
||||
|
||||
local atreidesPath = function() return Utils.Random(AtreidesPaths) end
|
||||
local harkonnenPath = function() return Utils.Random(HarkonnenPaths) end
|
||||
local atreidesCondition = function() return player.IsObjectiveCompleted(KillAtreides) end
|
||||
local harkonnenCondition = function() return player.IsObjectiveCompleted(KillHarkonnen) end
|
||||
local huntFunction = function(unit)
|
||||
unit.AttackMove(Utils.Random(EnemyAttackLocations))
|
||||
IdleHunt(unit)
|
||||
end
|
||||
local announcementFunction = function()
|
||||
Media.DisplayMessage("Enemy reinforcements have arrived.", "Mentat")
|
||||
end
|
||||
|
||||
SendCarryallReinforcements(atreides, 0, AtreidesAttackWaves[Difficulty], EnemyAttackDelay[Difficulty], atreidesPath, AtreidesReinforcements[Difficulty], atreidesCondition, huntFunction, announcementFunction)
|
||||
|
||||
Trigger.AfterDelay(Utils.RandomInteger(DateTime.Seconds(45), DateTime.Minutes(1) + DateTime.Seconds(15)), function()
|
||||
SendCarryallReinforcements(harkonnen, 0, HarkonnenAttackWaves[Difficulty], EnemyAttackDelay[Difficulty], harkonnenPath, HarkonnenReinforcements[Difficulty], harkonnenCondition, huntFunction, announcementFunction)
|
||||
end)
|
||||
|
||||
Actor.Create("upgrade.barracks", true, { Owner = atreides })
|
||||
Actor.Create("upgrade.light", true, { Owner = atreides })
|
||||
Actor.Create("upgrade.heavy", true, { Owner = atreides })
|
||||
Actor.Create("upgrade.barracks", true, { Owner = harkonnen })
|
||||
Actor.Create("upgrade.heavy", true, { Owner = harkonnen })
|
||||
Trigger.AfterDelay(0, ActivateAI)
|
||||
end
|
||||
60
mods/d2k/maps/ordos-06a/rules.yaml
Normal file
@@ -0,0 +1,60 @@
|
||||
Player:
|
||||
PlayerResources:
|
||||
DefaultCash: 6000
|
||||
|
||||
World:
|
||||
LuaScript:
|
||||
Scripts: campaign-global.lua, ordos06a.lua, ordos06a-AI.lua
|
||||
MissionData:
|
||||
Briefing: The Starport must be protected. All other efforts are secondary. No House will be allowed to interfere with the arrival of our Ixian weaponry.\n\nOnce we possess these illegal technologies, we will confuse and crush our opponents. Until then, survive. This will give you a higher probability of success.
|
||||
BriefingVideo: O_BR06_E.VQA
|
||||
MapOptions:
|
||||
TechLevel: medium
|
||||
ScriptLobbyDropdown@difficulty:
|
||||
ID: difficulty
|
||||
Label: Difficulty
|
||||
Values:
|
||||
easy: Easy
|
||||
normal: Normal
|
||||
hard: Hard
|
||||
Default: easy
|
||||
|
||||
carryall.reinforce:
|
||||
Cargo:
|
||||
MaxWeight: 10
|
||||
|
||||
frigate:
|
||||
Aircraft:
|
||||
LandableTerrainTypes: Sand, Rock, Transition, Spice, SpiceSand, Dune, Concrete
|
||||
|
||||
concreteb:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
upgrade.conyard:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
starport:
|
||||
Buildable:
|
||||
Prerequisites: heavy_factory, outpost
|
||||
|
||||
missile_tank:
|
||||
Buildable:
|
||||
Prerequisites: ~heavy.missile_tank, upgrade.heavy, research_centre
|
||||
|
||||
grenadier:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
stealth_raider:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
sardaukar:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
large_gun_turret:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
@@ -17,6 +17,7 @@ Ordos Campaign:
|
||||
ordos-03b
|
||||
ordos-04
|
||||
ordos-05
|
||||
ordos-06a
|
||||
|
||||
Harkonnen Campaign:
|
||||
harkonnen-01a
|
||||
|
||||
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@@ -135,7 +135,7 @@ sidebar-bits:
|
||||
production-tooltip-time: 136, 51, 16, 16
|
||||
production-tooltip-power: 102, 51, 16, 16
|
||||
production-tooltip-cost: 68, 51, 16, 16
|
||||
indicator-muted: 68, 145, 24, 24
|
||||
indicator-muted: 68, 145, 26, 24
|
||||
|
||||
commandbar:
|
||||
Inherits: ^Sidebar
|
||||
|
||||
@@ -95,7 +95,7 @@ MIG:
|
||||
UpdatesPlayerStatistics:
|
||||
AddToArmyValue: true
|
||||
Health:
|
||||
HP: 7500
|
||||
HP: 10000
|
||||
RevealsShroud:
|
||||
MinRange: 11c0
|
||||
Range: 13c0
|
||||
@@ -112,6 +112,7 @@ MIG:
|
||||
AttackAircraft:
|
||||
FacingTolerance: 20
|
||||
PersistentTargeting: false
|
||||
OpportunityFire: False
|
||||
Aircraft:
|
||||
CruiseAltitude: 2560
|
||||
InitialFacing: 192
|
||||
@@ -120,7 +121,6 @@ MIG:
|
||||
RepulsionSpeed: 40
|
||||
MaximumPitch: 56
|
||||
AutoTarget:
|
||||
ScanOnIdle: false
|
||||
InitialStance: HoldFire
|
||||
InitialStanceAI: HoldFire
|
||||
AmmoPool:
|
||||
@@ -183,6 +183,7 @@ YAK:
|
||||
AttackAircraft:
|
||||
FacingTolerance: 20
|
||||
PersistentTargeting: false
|
||||
OpportunityFire: False
|
||||
Aircraft:
|
||||
CruiseAltitude: 2560
|
||||
InitialFacing: 192
|
||||
@@ -191,7 +192,6 @@ YAK:
|
||||
RepulsionSpeed: 40
|
||||
MaximumPitch: 56
|
||||
AutoTarget:
|
||||
ScanOnIdle: false
|
||||
InitialStance: HoldFire
|
||||
InitialStanceAI: HoldFire
|
||||
AmmoPool:
|
||||
@@ -230,7 +230,7 @@ TRAN:
|
||||
UpdatesPlayerStatistics:
|
||||
AddToArmyValue: true
|
||||
Health:
|
||||
HP: 14000
|
||||
HP: 20000
|
||||
RevealsShroud:
|
||||
MinRange: 6c0
|
||||
Range: 8c0
|
||||
@@ -307,6 +307,7 @@ HELI:
|
||||
FacingTolerance: 20
|
||||
PersistentTargeting: false
|
||||
AttackType: Hover
|
||||
OpportunityFire: False
|
||||
Aircraft:
|
||||
TurnSpeed: 4
|
||||
Speed: 149
|
||||
@@ -376,6 +377,7 @@ HIND:
|
||||
FacingTolerance: 20
|
||||
PersistentTargeting: false
|
||||
AttackType: Hover
|
||||
OpportunityFire: False
|
||||
Aircraft:
|
||||
TurnSpeed: 4
|
||||
Speed: 112
|
||||
|
||||
@@ -514,6 +514,8 @@ MNLY:
|
||||
Image: MNLY
|
||||
Rearmable:
|
||||
RearmActors: fix
|
||||
Targetable:
|
||||
TargetTypes: Ground, Vehicle, Mine
|
||||
|
||||
TRUK:
|
||||
Inherits: ^Vehicle
|
||||
@@ -760,11 +762,11 @@ CTNK:
|
||||
AddToArmyValue: true
|
||||
SelectionDecorations:
|
||||
Health:
|
||||
HP: 45000
|
||||
HP: 40000
|
||||
Armor:
|
||||
Type: Light
|
||||
Mobile:
|
||||
Speed: 113
|
||||
Speed: 96
|
||||
Locomotor: heavywheeled
|
||||
RevealsShroud:
|
||||
MinRange: 4c0
|
||||
@@ -862,7 +864,7 @@ STNK:
|
||||
InitialStance: HoldFire
|
||||
InitialStanceAI: ReturnFire
|
||||
Armament:
|
||||
Weapon: APTusk
|
||||
Weapon: APTusk.stnk
|
||||
LocalOffset: 192,0,176
|
||||
Turreted:
|
||||
TurnSpeed: 5
|
||||
@@ -870,7 +872,7 @@ STNK:
|
||||
WithSpriteTurret:
|
||||
Cargo:
|
||||
Types: Infantry
|
||||
MaxWeight: 4
|
||||
MaxWeight: 5
|
||||
PipCount: 4
|
||||
LoadingCondition: notmobile
|
||||
Cloak:
|
||||
|
||||
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
@@ -72,10 +72,10 @@ Dragon:
|
||||
|
||||
HellfireAG:
|
||||
Inherits: ^AntiGroundMissile
|
||||
ReloadDelay: 60
|
||||
ReloadDelay: 30
|
||||
MinRange: 1c256
|
||||
Burst: 4
|
||||
BurstDelays: 14
|
||||
Burst: 2
|
||||
BurstDelays: 7
|
||||
Projectile: Missile
|
||||
Speed: 256
|
||||
HorizontalRateOfTurn: 10
|
||||
@@ -90,15 +90,17 @@ HellfireAG:
|
||||
|
||||
HellfireAA:
|
||||
Inherits: ^AntiAirMissile
|
||||
ReloadDelay: 60
|
||||
ReloadDelay: 30
|
||||
MinRange: 1c256
|
||||
Range: 4c0
|
||||
Burst: 2
|
||||
BurstDelays: 10
|
||||
Projectile: Missile
|
||||
Speed: 384
|
||||
Speed: 492
|
||||
Inaccuracy: 128
|
||||
HorizontalRateOfTurn: 10
|
||||
HorizontalRateOfTurn: 25
|
||||
RangeLimit: 7c0
|
||||
CloseEnough: 0c600
|
||||
Warhead@1Dam: SpreadDamage
|
||||
Damage: 4000
|
||||
ValidTargets: Air
|
||||
@@ -211,14 +213,10 @@ APTusk:
|
||||
TrailImage: smokey
|
||||
HorizontalRateOfTurn: 10
|
||||
RangeLimit: 7c204
|
||||
Warhead@1Dam: SpreadDamage
|
||||
Damage: 2500
|
||||
Versus:
|
||||
None: 28
|
||||
Wood: 88
|
||||
Light: 88
|
||||
Heavy: 120
|
||||
Concrete: 60
|
||||
|
||||
APTusk.stnk:
|
||||
Inherits: APTusk
|
||||
ReloadDelay: 100
|
||||
|
||||
TorpTube:
|
||||
ReloadDelay: 100
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
Range: 8c0
|
||||
Report: aacanon3.aud
|
||||
ValidTargets: Air
|
||||
Projectile: Bullet
|
||||
Speed: 1c682
|
||||
Blockable: false
|
||||
Projectile: InstantHit
|
||||
Warhead@1Dam: SpreadDamage
|
||||
Spread: 213
|
||||
Damage: 2000
|
||||
@@ -27,8 +25,6 @@ ZSU-23:
|
||||
BurstDelays: 0
|
||||
ReloadDelay: 6
|
||||
Range: 10c0
|
||||
Projectile: Bullet
|
||||
Speed: 3c340
|
||||
Warhead@1Dam: SpreadDamage
|
||||
Damage: 1200
|
||||
Versus:
|
||||
@@ -47,8 +43,8 @@ FLAK-23-AG:
|
||||
Inherits: ^AACannon
|
||||
Range: 6c0
|
||||
ValidTargets: Ground, Water
|
||||
Projectile: Bullet
|
||||
Blockable: True
|
||||
Projectile: InstantHit
|
||||
Blockable: true
|
||||
Warhead@1Dam: SpreadDamage
|
||||
ValidTargets: Air, Ground, Water
|
||||
Warhead@2Eff: CreateEffect
|
||||
@@ -63,8 +59,8 @@ FLAK-23-AG:
|
||||
ReloadDelay: 30
|
||||
Range: 6c0
|
||||
Report: gun13.aud
|
||||
Projectile: Bullet
|
||||
Speed: 1c682
|
||||
Projectile: InstantHit
|
||||
Blockable: true
|
||||
Warhead@1Dam: SpreadDamage
|
||||
Spread: 128
|
||||
Damage: 2500
|
||||
@@ -211,7 +207,7 @@ ChainGun:
|
||||
ReloadDelay: 10
|
||||
Range: 5c0
|
||||
MinRange: 0c768
|
||||
Projectile: Bullet
|
||||
Projectile: InstantHit
|
||||
Blockable: false
|
||||
Warhead@1Dam: SpreadDamage
|
||||
Versus:
|
||||
@@ -222,7 +218,7 @@ ChainGun.Yak:
|
||||
ReloadDelay: 3
|
||||
Range: 5c0
|
||||
MinRange: 3c0
|
||||
Projectile: Bullet
|
||||
Projectile: InstantHit
|
||||
Blockable: false
|
||||
Warhead@1Dam: SpreadDamage
|
||||
Damage: 4000
|
||||
@@ -272,8 +268,8 @@ M60mg:
|
||||
Report: gun5.aud
|
||||
ValidTargets: Ground, Infantry
|
||||
InvalidTargets: Vehicle, Water, Structure, Wall, Husk, Mine
|
||||
Projectile: Bullet
|
||||
Speed: 1c682
|
||||
Projectile: InstantHit
|
||||
Blockable: true
|
||||
Warhead@1Dam: SpreadDamage
|
||||
Spread: 42
|
||||
Damage: 15000
|
||||
|
||||
@@ -445,7 +445,7 @@ sidebar-bits:
|
||||
production-tooltip-time: 136, 51, 16, 16
|
||||
production-tooltip-power: 102, 51, 16, 16
|
||||
production-tooltip-cost: 68, 51, 16, 16
|
||||
indicator-muted: 0, 119, 24, 24
|
||||
indicator-muted: 0, 119, 26, 24
|
||||
|
||||
flags:
|
||||
Inherits: ^Glyphs
|
||||
|
||||
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -13,7 +13,7 @@
|
||||
# MACOS_DEVELOPER_PASSWORD: App-specific password for the developer account
|
||||
#
|
||||
|
||||
LAUNCHER_TAG="osx-launcher-20200209"
|
||||
LAUNCHER_TAG="osx-launcher-20200316"
|
||||
|
||||
if [ $# -ne "2" ]; then
|
||||
echo "Usage: $(basename "$0") tag outputdir"
|
||||
|
||||
7
thirdparty/fetch-thirdparty-deps-osx.sh
vendored
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
LAUNCHER_TAG="osx-launcher-20200209"
|
||||
LAUNCHER_TAG="osx-launcher-20200316"
|
||||
|
||||
download_dir="${0%/*}/download/osx"
|
||||
mkdir -p "$download_dir"
|
||||
@@ -25,3 +25,8 @@ if [ ! -f libfreetype.6.dylib ]; then
|
||||
echo "Fetching OS X FreeType library from GitHub."
|
||||
curl -LOs https://github.com/OpenRA/OpenRALauncherOSX/releases/download/${LAUNCHER_TAG}/libfreetype.6.dylib
|
||||
fi
|
||||
|
||||
if [ ! -f libopenal.1.dylib ]; then
|
||||
echo "Fetching OS X OpenAL Soft library from GitHub."
|
||||
curl -LOs https://github.com/OpenRA/OpenRALauncherOSX/releases/download/${LAUNCHER_TAG}/libopenal.1.dylib
|
||||
fi
|
||||
|
||||
8
thirdparty/fetch-thirdparty-deps.sh
vendored
@@ -71,11 +71,11 @@ fi
|
||||
if [ ! -f OpenAL-CS.dll ] || [ ! -f OpenAL-CS.dll.config ]; then
|
||||
echo "Fetching OpenAL-CS from GitHub."
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -s -L -O https://github.com/OpenRA/OpenAL-CS/releases/download/20190907/OpenAL-CS.dll
|
||||
curl -s -L -O https://github.com/OpenRA/OpenAL-CS/releases/download/20190907/OpenAL-CS.dll.config
|
||||
curl -s -L -O https://github.com/OpenRA/OpenAL-CS/releases/download/20200316/OpenAL-CS.dll
|
||||
curl -s -L -O https://github.com/OpenRA/OpenAL-CS/releases/download/20200316/OpenAL-CS.dll.config
|
||||
else
|
||||
wget -cq https://github.com/OpenRA/OpenAL-CS/releases/download/20190907/OpenAL-CS.dll
|
||||
wget -cq https://github.com/OpenRA/OpenAL-CS/releases/download/20190907/OpenAL-CS.dll.config
|
||||
wget -cq https://github.com/OpenRA/OpenAL-CS/releases/download/20200316/OpenAL-CS.dll
|
||||
wget -cq https://github.com/OpenRA/OpenAL-CS/releases/download/20200316/OpenAL-CS.dll.config
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||