Compare commits
20 Commits
devtest-20
...
devtest-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
759dc34e03 | ||
|
|
668ab78b1b | ||
|
|
c754d6a892 | ||
|
|
e9108479b5 | ||
|
|
857da21b0f | ||
|
|
73bba97aaa | ||
|
|
d6e9cdab5b | ||
|
|
1a177bc2de | ||
|
|
e0b3e631fe | ||
|
|
2518a353af | ||
|
|
989800efff | ||
|
|
c02846e2cb | ||
|
|
09db4a0e25 | ||
|
|
a85da9d86c | ||
|
|
920d00bbae | ||
|
|
62475279ee | ||
|
|
d8e979d283 | ||
|
|
299b8880dd | ||
|
|
61027e4067 | ||
|
|
a7249c10dc |
13
.github/workflows/ci.yaml
vendored
13
.github/workflows/ci.yaml
vendored
@@ -18,7 +18,6 @@ jobs:
|
||||
run: |
|
||||
mono --version
|
||||
make check
|
||||
mono ~/.nuget/packages/nunit.consolerunner/3.11.1/tools/nunit3-console.exe --noresult bin/OpenRA.Test.dll
|
||||
|
||||
- name: Check Mods
|
||||
run: |
|
||||
@@ -27,18 +26,26 @@ jobs:
|
||||
make test
|
||||
|
||||
windows:
|
||||
name: Windows (Framework 4.7)
|
||||
name: Windows (Net 5.0)
|
||||
runs-on: windows-2019
|
||||
|
||||
steps:
|
||||
- name: Clone Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install .NET 5
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '5.0.x'
|
||||
|
||||
- name: Check Code
|
||||
shell: powershell
|
||||
run: |
|
||||
# Work around runtime failures on the GH Actions runner
|
||||
dotnet nuget locals all --clear
|
||||
.\make.ps1 check
|
||||
Invoke-Expression "$home\.nuget\packages\nunit.consolerunner\3.11.1\tools\nunit3-console.exe --noresult bin/OpenRA.Test.dll"
|
||||
dotnet build OpenRA.Test\OpenRA.Test.csproj -c Debug --nologo -p:TargetPlatform=win-x64
|
||||
dotnet test bin\OpenRA.Test.dll --test-adapter-path:.
|
||||
|
||||
- name: Check Mods
|
||||
run: |
|
||||
|
||||
24
.github/workflows/documentation.yml
vendored
24
.github/workflows/documentation.yml
vendored
@@ -60,31 +60,39 @@ jobs:
|
||||
if: github.repository == 'openra/openra'
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Clone Repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.inputs.tag }}
|
||||
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
make all
|
||||
|
||||
- name: Clone docs.openra.net
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: openra/docs.git
|
||||
repository: openra/docs
|
||||
token: ${{ secrets.DOCS_TOKEN }}
|
||||
path: docs
|
||||
ref: ${{ github.event.inputs.tag }}
|
||||
|
||||
- name: Update docs.openra.net (Playtest)
|
||||
if: startsWith(github.event.inputs.tag, 'playtest-')
|
||||
env:
|
||||
GIT_TAG: ${{ github.event.inputs.tag }}
|
||||
run: |
|
||||
./utility.sh all --docs "${GIT_TAG}" > "docs/playtest/traits.md"
|
||||
./utility.sh all --weapon-docs "${GIT_TAG}" > "docs/playtest/weapons.md"
|
||||
./utility.sh all --lua-docs "${GIT_TAG}" > "docs/playtest/lua.md"
|
||||
./utility.sh all --docs "${GIT_TAG}" > "docs/api/playtest/traits.md"
|
||||
./utility.sh all --weapon-docs "${GIT_TAG}" > "docs/api/playtest/weapons.md"
|
||||
./utility.sh all --lua-docs "${GIT_TAG}" > "docs/api/playtest/lua.md"
|
||||
|
||||
- name: Update docs.openra.net (Release)
|
||||
if: startsWith(github.event.inputs.tag, 'release-')
|
||||
env:
|
||||
GIT_TAG: ${{ github.event.inputs.tag }}
|
||||
run: |
|
||||
./utility.sh all --docs "${GIT_TAG}" > "docs/release/traits.md"
|
||||
./utility.sh all --weapon-docs "${GIT_TAG}" > "docs/release/weapons.md"
|
||||
./utility.sh all --lua-docs "${GIT_TAG}" > "docs/release/lua.md"
|
||||
./utility.sh all --docs "${GIT_TAG}" > "docs/api/release/traits.md"
|
||||
./utility.sh all --weapon-docs "${GIT_TAG}" > "docs/api/release/weapons.md"
|
||||
./utility.sh all --lua-docs "${GIT_TAG}" > "docs/api/release/lua.md"
|
||||
|
||||
- name: Push docs.openra.net
|
||||
env:
|
||||
|
||||
12
.github/workflows/packaging.yml
vendored
12
.github/workflows/packaging.yml
vendored
@@ -39,6 +39,11 @@ jobs:
|
||||
- name: Clone Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install .NET 5
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '5.0.x'
|
||||
|
||||
- name: Prepare Environment
|
||||
run: echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> ${GITHUB_ENV}
|
||||
|
||||
@@ -69,10 +74,15 @@ jobs:
|
||||
- name: Clone Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install .NET 5
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '5.0.x'
|
||||
|
||||
- name: Prepare Environment
|
||||
run: |
|
||||
echo "GIT_TAG=${GITHUB_REF#refs/tags/}" >> ${GITHUB_ENV}
|
||||
sudo apt install nsis
|
||||
sudo apt install nsis wine64
|
||||
|
||||
- name: Package Installers
|
||||
run: |
|
||||
|
||||
10
INSTALL.md
10
INSTALL.md
@@ -8,18 +8,16 @@ Windows
|
||||
|
||||
Compiling OpenRA requires the following dependencies:
|
||||
* [Windows PowerShell >= 4.0](http://microsoft.com/powershell) (included by default in recent Windows 10 versions)
|
||||
* [.NET Framework 4.7.2 (Developer Pack)](https://dotnet.microsoft.com/download/dotnet-framework/net472) (or via Visual Studio 2017)
|
||||
* [.NET Core 2.2 SDK](https://dotnet.microsoft.com/download/dotnet-core/2.2) (or via Visual Studio 2017)
|
||||
* [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0) (or via Visual Studio)
|
||||
|
||||
|
||||
To compile OpenRA, open the `OpenRA.sln` solution in the main folder, build it from the command-line with MSBuild or use the Makefile analogue command `make all` scripted in PowerShell syntax.
|
||||
To compile OpenRA, open the `OpenRA.sln` solution in the main folder, build it from the command-line with `dotnet` or use the Makefile analogue command `make all` scripted in PowerShell syntax.
|
||||
|
||||
Run the game with `launch-game.cmd`. It can be handed arguments that specify the exact mod one wishes to run, for example, run `launch-game.cmd Game.Mod=ra` to launch Red Alert, `launch-game.cmd Game.Mod=cnc` to start Tiberian dawn or `launch-game.cmd Game.Mod=d2k` to launch Dune 2000.
|
||||
|
||||
Linux
|
||||
=====
|
||||
|
||||
Mono, version 5.18 or later, is required to compile OpenRA. You can add the [upstream mono repository](https://www.mono-project.com/download/stable/#download-lin) for your distro to obtain the latest version if your system packages are not sufficient.
|
||||
Mono, version 6.4 or later, is required to compile OpenRA. You can add the [upstream mono repository](https://www.mono-project.com/download/stable/#download-lin) for your distro to obtain the latest version if your system packages are not sufficient.
|
||||
|
||||
To compile OpenRA, run `make` from the command line. After this one can run the game with `./launch-game.sh`. It is also possible to specify the mod you wish to run from the command line, e.g. with `./launch-game.sh Game.Mod=ts` if you wish to try the experimental Tiberian Sun mod.
|
||||
|
||||
@@ -99,7 +97,7 @@ macOS
|
||||
=====
|
||||
|
||||
Before compiling OpenRA you must install the following dependencies:
|
||||
* [Mono >= 5.18](https://www.mono-project.com/download/stable/#download-mac)
|
||||
* [Mono >= 6.4](https://www.mono-project.com/download/stable/#download-mac)
|
||||
|
||||
To compile OpenRA, run `make` from the command line. Run with `./launch-game.sh`.
|
||||
|
||||
|
||||
12
Makefile
12
Makefile
@@ -28,14 +28,14 @@
|
||||
############################## TOOLCHAIN ###############################
|
||||
#
|
||||
# List of .NET assemblies that we can guarantee exist
|
||||
WHITELISTED_OPENRA_ASSEMBLIES = OpenRA.exe OpenRA.Utility.exe OpenRA.Server.exe OpenRA.Platforms.Default.dll OpenRA.Game.dll OpenRA.Mods.Common.dll OpenRA.Mods.Cnc.dll OpenRA.Mods.D2k.dll
|
||||
WHITELISTED_OPENRA_ASSEMBLIES = OpenRA.dll OpenRA.Utility.dll OpenRA.Server.dll OpenRA.Platforms.Default.dll OpenRA.Game.dll OpenRA.Mods.Common.dll OpenRA.Mods.Cnc.dll OpenRA.Mods.D2k.dll
|
||||
|
||||
# These are explicitly shipped alongside our core files by the packaging script
|
||||
WHITELISTED_THIRDPARTY_ASSEMBLIES = ICSharpCode.SharpZipLib.dll FuzzyLogicLibrary.dll Eluant.dll BeaconLib.dll Open.Nat.dll SDL2-CS.dll OpenAL-CS.Core.dll DiscordRPC.dll Newtonsoft.Json.dll
|
||||
|
||||
# These are shipped in our custom minimal mono runtime and also available in the full system-installed .NET/mono stack
|
||||
# This list *must* be kept in sync with the files packaged by the AppImageSupport and OpenRALauncherOSX repositories
|
||||
WHITELISTED_CORE_ASSEMBLIES = mscorlib.dll System.dll System.Configuration.dll System.Core.dll System.Numerics.dll System.Security.dll System.Xml.dll Mono.Security.dll netstandard.dll
|
||||
WHITELISTED_CORE_ASSEMBLIES = mscorlib.dll System.dll System.Configuration.dll System.Core.dll System.Numerics.dll System.Security.dll System.Xml.dll Mono.Security.dll netstandard.dll Microsoft.Win32.Registry.dll System.Security.AccessControl.dll System.Security.Principal.Windows.dll System.Xml.Linq.dll System.Runtime.Serialization.dll
|
||||
|
||||
######################### UTILITIES/SETTINGS ###########################
|
||||
#
|
||||
@@ -78,13 +78,13 @@ endif
|
||||
endif
|
||||
endif
|
||||
|
||||
OPENRA_UTILITY = ENGINE_DIR=".." $(MONO) --debug bin/OpenRA.Utility.exe
|
||||
OPENRA_UTILITY = ENGINE_DIR=".." $(MONO) --debug bin/OpenRA.Utility.dll
|
||||
|
||||
##################### DEVELOPMENT BUILDS AND TESTS #####################
|
||||
#
|
||||
all:
|
||||
@command -v $(firstword $(MSBUILD)) >/dev/null || (echo "OpenRA requires the '$(MSBUILD)' tool provided by Mono >= 5.18."; exit 1)
|
||||
@$(MSBUILD) -t:Build -restore -p:Configuration=Release -p:TargetPlatform=$(TARGETPLATFORM)
|
||||
@$(MSBUILD) -t:Build -restore -p:Configuration=Release -p:TargetPlatform=$(TARGETPLATFORM) -p:Mono=true -p:DefineConstants="MONO"
|
||||
ifeq ($(TARGETPLATFORM), unix-generic)
|
||||
@./configure-system-libraries.sh
|
||||
endif
|
||||
@@ -92,13 +92,13 @@ endif
|
||||
|
||||
clean:
|
||||
@-$(RM_RF) ./bin ./*/bin ./*/obj
|
||||
@$(MSBUILD) -t:Clean
|
||||
@$(MSBUILD) -t:Clean -p:Mono=true
|
||||
@-$(RM_F) IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP
|
||||
|
||||
check:
|
||||
@echo
|
||||
@echo "Compiling in debug mode..."
|
||||
@$(MSBUILD) -t:build -restore -p:Configuration=Debug
|
||||
@$(MSBUILD) -t:build -restore -p:Configuration=Debug -p:TargetPlatform=$(TARGETPLATFORM) -p:Mono=true -p:DefineConstants="MONO"
|
||||
@echo
|
||||
@echo "Checking runtime assemblies..."
|
||||
@$(OPENRA_UTILITY) all --check-runtime-assemblies $(WHITELISTED_OPENRA_ASSEMBLIES) $(WHITELISTED_THIRDPARTY_ASSEMBLIES) $(WHITELISTED_CORE_ASSEMBLIES)
|
||||
|
||||
@@ -297,6 +297,7 @@ namespace OpenRA
|
||||
EngineVersion = "Unknown";
|
||||
|
||||
Console.WriteLine("Engine version is {0}", EngineVersion);
|
||||
Console.WriteLine("Runtime: {0}", Platform.RuntimeVersion);
|
||||
|
||||
// Special case handling of Game.Mod argument: if it matches a real filesystem path
|
||||
// then we use this to override the mod search path, and replace it with the mod id
|
||||
@@ -329,9 +330,16 @@ namespace OpenRA
|
||||
try
|
||||
{
|
||||
var rendererPath = Path.Combine(Platform.BinDir, "OpenRA.Platforms." + p + ".dll");
|
||||
var assembly = Assembly.LoadFile(rendererPath);
|
||||
|
||||
#if !MONO
|
||||
var loader = new AssemblyLoader(rendererPath);
|
||||
var platformType = loader.LoadDefaultAssembly().GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
|
||||
|
||||
#else
|
||||
var assembly = Assembly.LoadFile(rendererPath);
|
||||
var platformType = assembly.GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
|
||||
#endif
|
||||
|
||||
if (platformType == null)
|
||||
throw new InvalidOperationException("Platform dll must include exactly one IPlatform implementation.");
|
||||
|
||||
|
||||
@@ -168,10 +168,7 @@ namespace OpenRA.Graphics
|
||||
for (var x = 0; x < template.Size.X; x++)
|
||||
{
|
||||
var tile = new TerrainTile(template.Id, (byte)(i++));
|
||||
var tileInfo = tileset.GetTileInfo(tile);
|
||||
|
||||
// Empty tile
|
||||
if (tileInfo == null)
|
||||
if (!tileset.TryGetTileInfo(tile, out var tileInfo))
|
||||
continue;
|
||||
|
||||
var sprite = TileSprite(tile);
|
||||
|
||||
@@ -206,6 +206,8 @@ namespace OpenRA
|
||||
public readonly MiniYaml NotificationDefinitions;
|
||||
public readonly MiniYaml TranslationDefinitions;
|
||||
|
||||
public readonly Dictionary<CPos, TerrainTile> ReplacedInvalidTerrainTiles = new Dictionary<CPos, TerrainTile>();
|
||||
|
||||
// Generated data
|
||||
public readonly MapGrid Grid;
|
||||
public IReadOnlyPackage Package { get; private set; }
|
||||
@@ -287,7 +289,6 @@ namespace OpenRA
|
||||
this.modData = modData;
|
||||
var size = new Size(width, height);
|
||||
Grid = modData.Manifest.Get<MapGrid>();
|
||||
var tileRef = new TerrainTile(tileset.Templates.First().Key, 0);
|
||||
|
||||
Title = "Name your map here";
|
||||
Author = "Your name here";
|
||||
@@ -310,7 +311,7 @@ namespace OpenRA
|
||||
Tiles.CellEntryChanged += UpdateRamp;
|
||||
}
|
||||
|
||||
Tiles.Clear(tileRef);
|
||||
Tiles.Clear(tileset.DefaultTerrainTile);
|
||||
|
||||
PostInit();
|
||||
}
|
||||
@@ -430,12 +431,18 @@ namespace OpenRA
|
||||
foreach (var uv in AllCells.MapCoords)
|
||||
CustomTerrain[uv] = byte.MaxValue;
|
||||
|
||||
// Cache initial ramp state
|
||||
// Replace invalid tiles and cache ramp state
|
||||
var tileset = Rules.TileSet;
|
||||
foreach (var uv in AllCells)
|
||||
foreach (var uv in AllCells.MapCoords)
|
||||
{
|
||||
var tile = tileset.GetTileInfo(Tiles[uv]);
|
||||
Ramp[uv] = tile != null ? tile.RampType : (byte)0;
|
||||
if (!tileset.TryGetTileInfo(Tiles[uv], out var info))
|
||||
{
|
||||
ReplacedInvalidTerrainTiles[uv.ToCPos(this)] = Tiles[uv];
|
||||
Tiles[uv] = tileset.DefaultTerrainTile;
|
||||
info = tileset.GetTileInfo(tileset.DefaultTerrainTile);
|
||||
}
|
||||
|
||||
Ramp[uv] = info.RampType;
|
||||
}
|
||||
|
||||
AllEdgeCells = UpdateEdgeCells();
|
||||
@@ -443,8 +450,7 @@ namespace OpenRA
|
||||
|
||||
void UpdateRamp(CPos cell)
|
||||
{
|
||||
var tile = Rules.TileSet.GetTileInfo(Tiles[cell]);
|
||||
Ramp[cell] = tile != null ? tile.RampType : (byte)0;
|
||||
Ramp[cell] = Rules.TileSet.GetTileInfo(Tiles[cell]).RampType;
|
||||
}
|
||||
|
||||
void InitializeCellProjection()
|
||||
@@ -670,32 +676,26 @@ namespace OpenRA
|
||||
Color left, right;
|
||||
var tileset = Rules.TileSet;
|
||||
var type = tileset.GetTileInfo(Tiles[uv]);
|
||||
if (type != null)
|
||||
if (type.MinColor != type.MaxColor)
|
||||
{
|
||||
if (type.MinColor != type.MaxColor)
|
||||
{
|
||||
left = Exts.ColorLerp(Game.CosmeticRandom.NextFloat(), type.MinColor, type.MaxColor);
|
||||
right = Exts.ColorLerp(Game.CosmeticRandom.NextFloat(), type.MinColor, type.MaxColor);
|
||||
}
|
||||
else
|
||||
left = right = type.MinColor;
|
||||
|
||||
if (tileset.MinHeightColorBrightness != 1.0f || tileset.MaxHeightColorBrightness != 1.0f)
|
||||
{
|
||||
var scale = float2.Lerp(tileset.MinHeightColorBrightness, tileset.MaxHeightColorBrightness, Height[uv] * 1f / Grid.MaximumTerrainHeight);
|
||||
left = Color.FromArgb((int)(scale * left.R).Clamp(0, 255), (int)(scale * left.G).Clamp(0, 255), (int)(scale * left.B).Clamp(0, 255));
|
||||
right = Color.FromArgb((int)(scale * right.R).Clamp(0, 255), (int)(scale * right.G).Clamp(0, 255), (int)(scale * right.B).Clamp(0, 255));
|
||||
}
|
||||
left = Exts.ColorLerp(Game.CosmeticRandom.NextFloat(), type.MinColor, type.MaxColor);
|
||||
right = Exts.ColorLerp(Game.CosmeticRandom.NextFloat(), type.MinColor, type.MaxColor);
|
||||
}
|
||||
else
|
||||
left = right = Color.Black;
|
||||
left = right = type.MinColor;
|
||||
|
||||
if (tileset.MinHeightColorBrightness != 1.0f || tileset.MaxHeightColorBrightness != 1.0f)
|
||||
{
|
||||
var scale = float2.Lerp(tileset.MinHeightColorBrightness, tileset.MaxHeightColorBrightness, Height[uv] * 1f / Grid.MaximumTerrainHeight);
|
||||
left = Color.FromArgb((int)(scale * left.R).Clamp(0, 255), (int)(scale * left.G).Clamp(0, 255), (int)(scale * left.B).Clamp(0, 255));
|
||||
right = Color.FromArgb((int)(scale * right.R).Clamp(0, 255), (int)(scale * right.G).Clamp(0, 255), (int)(scale * right.B).Clamp(0, 255));
|
||||
}
|
||||
|
||||
return (left, right);
|
||||
}
|
||||
|
||||
public byte[] SavePreview()
|
||||
{
|
||||
var tileset = Rules.TileSet;
|
||||
var actorTypes = Rules.Actors.Values.Where(a => a.HasTraitInfo<IMapPreviewSignatureInfo>());
|
||||
var actors = ActorDefinitions.Where(a => actorTypes.Where(ai => ai.Name == a.Value.Value).Any());
|
||||
var positions = new List<(MPos Position, Color Color)>();
|
||||
@@ -715,76 +715,73 @@ namespace OpenRA
|
||||
foreach (var worldimpsi in worldimpsis)
|
||||
worldimpsi.PopulateMapPreviewSignatureCells(this, worldActorInfo, null, positions);
|
||||
|
||||
using (var stream = new MemoryStream())
|
||||
var isRectangularIsometric = Grid.Type == MapGridType.RectangularIsometric;
|
||||
|
||||
// Fudge the heightmap offset by adding as much extra as we need / can.
|
||||
// This tries to correct for our incorrect assumption that MPos == PPos
|
||||
var heightOffset = Math.Min(Grid.MaximumTerrainHeight, MapSize.Y - Bounds.Bottom);
|
||||
var width = Bounds.Width;
|
||||
var height = Bounds.Height + heightOffset;
|
||||
|
||||
var bitmapWidth = width;
|
||||
if (isRectangularIsometric)
|
||||
bitmapWidth = 2 * bitmapWidth - 1;
|
||||
|
||||
var stride = bitmapWidth * 4;
|
||||
var pxStride = 4;
|
||||
var minimapData = new byte[stride * height];
|
||||
(Color Left, Color Right) terrainColor = default((Color, Color));
|
||||
|
||||
for (var y = 0; y < height; y++)
|
||||
{
|
||||
var isRectangularIsometric = Grid.Type == MapGridType.RectangularIsometric;
|
||||
|
||||
// Fudge the heightmap offset by adding as much extra as we need / can.
|
||||
// This tries to correct for our incorrect assumption that MPos == PPos
|
||||
var heightOffset = Math.Min(Grid.MaximumTerrainHeight, MapSize.Y - Bounds.Bottom);
|
||||
var width = Bounds.Width;
|
||||
var height = Bounds.Height + heightOffset;
|
||||
|
||||
var bitmapWidth = width;
|
||||
if (isRectangularIsometric)
|
||||
bitmapWidth = 2 * bitmapWidth - 1;
|
||||
|
||||
var stride = bitmapWidth * 4;
|
||||
var pxStride = 4;
|
||||
var minimapData = new byte[stride * height];
|
||||
(Color Left, Color Right) terrainColor = default((Color, Color));
|
||||
|
||||
for (var y = 0; y < height; y++)
|
||||
for (var x = 0; x < width; x++)
|
||||
{
|
||||
for (var x = 0; x < width; x++)
|
||||
var uv = new MPos(x + Bounds.Left, y + Bounds.Top);
|
||||
|
||||
// FirstOrDefault will return a (MPos.Zero, Color.Transparent) if positions is empty
|
||||
var actorColor = positions.FirstOrDefault(ap => ap.Position == uv).Color;
|
||||
if (actorColor.A == 0)
|
||||
terrainColor = GetTerrainColorPair(uv);
|
||||
|
||||
if (isRectangularIsometric)
|
||||
{
|
||||
var uv = new MPos(x + Bounds.Left, y + Bounds.Top);
|
||||
|
||||
// FirstOrDefault will return a (MPos.Zero, Color.Transparent) if positions is empty
|
||||
var actorColor = positions.FirstOrDefault(ap => ap.Position == uv).Color;
|
||||
if (actorColor.A == 0)
|
||||
terrainColor = GetTerrainColorPair(uv);
|
||||
|
||||
if (isRectangularIsometric)
|
||||
// Odd rows are shifted right by 1px
|
||||
var dx = uv.V & 1;
|
||||
var xOffset = pxStride * (2 * x + dx);
|
||||
if (x + dx > 0)
|
||||
{
|
||||
// Odd rows are shifted right by 1px
|
||||
var dx = uv.V & 1;
|
||||
var xOffset = pxStride * (2 * x + dx);
|
||||
if (x + dx > 0)
|
||||
{
|
||||
var z = y * stride + xOffset - pxStride;
|
||||
var c = actorColor.A == 0 ? terrainColor.Left : actorColor;
|
||||
minimapData[z++] = c.R;
|
||||
minimapData[z++] = c.G;
|
||||
minimapData[z++] = c.B;
|
||||
minimapData[z] = c.A;
|
||||
}
|
||||
|
||||
if (xOffset < stride)
|
||||
{
|
||||
var z = y * stride + xOffset;
|
||||
var c = actorColor.A == 0 ? terrainColor.Right : actorColor;
|
||||
minimapData[z++] = c.R;
|
||||
minimapData[z++] = c.G;
|
||||
minimapData[z++] = c.B;
|
||||
minimapData[z] = c.A;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var z = y * stride + pxStride * x;
|
||||
var z = y * stride + xOffset - pxStride;
|
||||
var c = actorColor.A == 0 ? terrainColor.Left : actorColor;
|
||||
minimapData[z++] = c.R;
|
||||
minimapData[z++] = c.G;
|
||||
minimapData[z++] = c.B;
|
||||
minimapData[z] = c.A;
|
||||
}
|
||||
|
||||
if (xOffset < stride)
|
||||
{
|
||||
var z = y * stride + xOffset;
|
||||
var c = actorColor.A == 0 ? terrainColor.Right : actorColor;
|
||||
minimapData[z++] = c.R;
|
||||
minimapData[z++] = c.G;
|
||||
minimapData[z++] = c.B;
|
||||
minimapData[z] = c.A;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var z = y * stride + pxStride * x;
|
||||
var c = actorColor.A == 0 ? terrainColor.Left : actorColor;
|
||||
minimapData[z++] = c.R;
|
||||
minimapData[z++] = c.G;
|
||||
minimapData[z++] = c.B;
|
||||
minimapData[z] = c.A;
|
||||
}
|
||||
}
|
||||
|
||||
var png = new Png(minimapData, bitmapWidth, height);
|
||||
return png.Save();
|
||||
}
|
||||
|
||||
var png = new Png(minimapData, bitmapWidth, height);
|
||||
return png.Save();
|
||||
}
|
||||
|
||||
public bool Contains(CPos cell)
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace OpenRA
|
||||
}
|
||||
|
||||
public override int GetHashCode() { return Type.GetHashCode() ^ Index.GetHashCode(); }
|
||||
|
||||
public override string ToString() { return Type + "," + Index; }
|
||||
}
|
||||
|
||||
public struct ResourceTile
|
||||
|
||||
@@ -221,25 +221,30 @@ namespace OpenRA
|
||||
|
||||
public byte GetTerrainIndex(TerrainTile r)
|
||||
{
|
||||
if (!Templates.TryGetValue(r.Type, out var tpl))
|
||||
return defaultWalkableTerrainIndex;
|
||||
|
||||
if (tpl.Contains(r.Index))
|
||||
{
|
||||
var tile = tpl[r.Index];
|
||||
if (tile != null && tile.TerrainType != byte.MaxValue)
|
||||
return tile.TerrainType;
|
||||
}
|
||||
var tile = Templates[r.Type][r.Index];
|
||||
if (tile.TerrainType != byte.MaxValue)
|
||||
return tile.TerrainType;
|
||||
|
||||
return defaultWalkableTerrainIndex;
|
||||
}
|
||||
|
||||
public TerrainTileInfo GetTileInfo(TerrainTile r)
|
||||
{
|
||||
if (!Templates.TryGetValue(r.Type, out var tpl))
|
||||
return null;
|
||||
|
||||
return tpl.Contains(r.Index) ? tpl[r.Index] : null;
|
||||
return Templates[r.Type][r.Index];
|
||||
}
|
||||
|
||||
public bool TryGetTileInfo(TerrainTile r, out TerrainTileInfo info)
|
||||
{
|
||||
if (!Templates.TryGetValue(r.Type, out var tpl) || !tpl.Contains(r.Index))
|
||||
{
|
||||
info = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
info = tpl[r.Index];
|
||||
return info != null;
|
||||
}
|
||||
|
||||
public TerrainTile DefaultTerrainTile { get { return new TerrainTile(Templates.First().Key, 0); } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Support;
|
||||
|
||||
namespace OpenRA
|
||||
{
|
||||
@@ -41,26 +42,49 @@ namespace OpenRA
|
||||
var resolvedPath = FileSystem.FileSystem.ResolveAssemblyPath(path, manifest, mods);
|
||||
if (resolvedPath == null)
|
||||
throw new FileNotFoundException("Assembly `{0}` not found.".F(path));
|
||||
#if !MONO
|
||||
var loader = new AssemblyLoader(resolvedPath);
|
||||
var platformType = loader.LoadDefaultAssembly();
|
||||
assemblyList.Add(platformType);
|
||||
|
||||
// .NET doesn't provide any way of querying the metadata of an assembly without either:
|
||||
// (a) loading duplicate data into the application domain, breaking the world.
|
||||
// (b) crashing if the assembly has already been loaded.
|
||||
// We can't check the internal name of the assembly, so we'll work off the data instead
|
||||
var hash = CryptoUtil.SHA1Hash(File.ReadAllBytes(resolvedPath));
|
||||
|
||||
if (!ResolvedAssemblies.TryGetValue(hash, out var assembly))
|
||||
{
|
||||
assembly = Assembly.LoadFile(resolvedPath);
|
||||
ResolvedAssemblies.Add(hash, assembly);
|
||||
}
|
||||
|
||||
assemblyList.Add(assembly);
|
||||
#else
|
||||
LoadAssembly(assemblyList, resolvedPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
|
||||
assemblies = assemblyList.SelectMany(asm => asm.GetNamespaces().Select(ns => (asm, ns))).ToArray();
|
||||
}
|
||||
|
||||
void LoadAssembly(List<Assembly> assemblyList, string resolvedPath)
|
||||
{
|
||||
// .NET doesn't provide any way of querying the metadata of an assembly without either:
|
||||
// (a) loading duplicate data into the application domain, breaking the world.
|
||||
// (b) crashing if the assembly has already been loaded.
|
||||
// We can't check the internal name of the assembly, so we'll work off the data instead
|
||||
var hash = CryptoUtil.SHA1Hash(File.ReadAllBytes(resolvedPath));
|
||||
|
||||
if (!ResolvedAssemblies.TryGetValue(hash, out var assembly))
|
||||
{
|
||||
assembly = Assembly.LoadFile(resolvedPath);
|
||||
ResolvedAssemblies.Add(hash, assembly);
|
||||
|
||||
// Allow mods to use libraries.
|
||||
var assemblyPath = Path.GetDirectoryName(resolvedPath);
|
||||
if (assemblyPath != null)
|
||||
{
|
||||
foreach (var referencedAssembly in assembly.GetReferencedAssemblies())
|
||||
{
|
||||
var depedencyPath = Path.Combine(assemblyPath, referencedAssembly.Name + ".dll");
|
||||
if (File.Exists(depedencyPath))
|
||||
LoadAssembly(assemblyList, depedencyPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assemblyList.Add(assembly);
|
||||
}
|
||||
|
||||
Assembly ResolveAssembly(object sender, ResolveEventArgs e)
|
||||
{
|
||||
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
@@ -39,6 +39,11 @@
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
|
||||
<AdditionalFiles Include="../stylecop.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Mono)' == ''">
|
||||
<PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="3.1.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="5.0.0-preview.3-runtime.20214.6" />
|
||||
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
<Target Name="DisableAnalyzers" BeforeTargets="CoreCompile" Condition="'$(Configuration)'=='Release'">
|
||||
<!-- Disable code style analysis on Release builds to improve compile-time performance -->
|
||||
<ItemGroup Condition="'$(Configuration)'=='Release'">
|
||||
|
||||
362
OpenRA.Game/Support/AssemblyLoader.cs
Normal file
362
OpenRA.Game/Support/AssemblyLoader.cs
Normal file
@@ -0,0 +1,362 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
// Not used/usable on Mono. Only used for Dotnet Core. Based on https://github.com/natemcmaster/DotNetCorePlugins
|
||||
#if !MONO
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Loader;
|
||||
using Microsoft.Extensions.DependencyModel;
|
||||
|
||||
namespace OpenRA.Support
|
||||
{
|
||||
public class AssemblyLoader
|
||||
{
|
||||
readonly string mainAssembly;
|
||||
readonly AssemblyLoadContext context;
|
||||
|
||||
public Assembly LoadDefaultAssembly() => context.LoadFromAssemblyPath(mainAssembly);
|
||||
|
||||
public AssemblyLoader(string assemblyFile)
|
||||
{
|
||||
mainAssembly = assemblyFile;
|
||||
var baseDir = Path.GetDirectoryName(assemblyFile);
|
||||
|
||||
context = CreateLoadContext(baseDir, assemblyFile);
|
||||
}
|
||||
|
||||
static AssemblyLoadContext CreateLoadContext(string baseDir, string assemblyFile)
|
||||
{
|
||||
var depsJsonFile = Path.Combine(baseDir, Path.GetFileNameWithoutExtension(assemblyFile) + ".deps.json");
|
||||
|
||||
var builder = new AssemblyLoadContextBuilder();
|
||||
|
||||
builder.TryAddDependencyContext(depsJsonFile, out _);
|
||||
builder.SetBaseDirectory(baseDir);
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
|
||||
public class AssemblyLoadContextBuilder
|
||||
{
|
||||
readonly Dictionary<string, ManagedLibrary> managedLibraries = new Dictionary<string, ManagedLibrary>(StringComparer.Ordinal);
|
||||
readonly Dictionary<string, NativeLibrary> nativeLibraries = new Dictionary<string, NativeLibrary>(StringComparer.Ordinal);
|
||||
string basePath;
|
||||
|
||||
public AssemblyLoadContext Build()
|
||||
{
|
||||
return new ManagedLoadContext(basePath, managedLibraries, nativeLibraries);
|
||||
}
|
||||
|
||||
public AssemblyLoadContextBuilder SetBaseDirectory(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
throw new ArgumentException("Argument must not be null or empty.", nameof(path));
|
||||
|
||||
if (!Path.IsPathRooted(path))
|
||||
throw new ArgumentException("Argument must be a full path.", nameof(path));
|
||||
|
||||
basePath = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AssemblyLoadContextBuilder AddManagedLibrary(ManagedLibrary library)
|
||||
{
|
||||
managedLibraries.Add(library.Name.Name, library);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AssemblyLoadContextBuilder AddNativeLibrary(NativeLibrary library)
|
||||
{
|
||||
ValidateRelativePath(library.AppLocalPath);
|
||||
nativeLibraries.Add(library.Name, library);
|
||||
return this;
|
||||
}
|
||||
|
||||
static void ValidateRelativePath(string probingPath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(probingPath))
|
||||
throw new ArgumentException("Value must not be null or empty.", nameof(probingPath));
|
||||
|
||||
if (Path.IsPathRooted(probingPath))
|
||||
throw new ArgumentException("Argument must be a relative path.", nameof(probingPath));
|
||||
}
|
||||
}
|
||||
|
||||
class ManagedLoadContext : AssemblyLoadContext
|
||||
{
|
||||
readonly string basePath;
|
||||
readonly Dictionary<string, ManagedLibrary> managedAssemblies;
|
||||
readonly Dictionary<string, NativeLibrary> nativeLibraries;
|
||||
|
||||
static readonly string[] NativeLibraryExtensions;
|
||||
static readonly string[] NativeLibraryPrefixes;
|
||||
|
||||
static readonly string[] ManagedAssemblyExtensions =
|
||||
{
|
||||
".dll",
|
||||
".ni.dll",
|
||||
".exe",
|
||||
".ni.exe"
|
||||
};
|
||||
|
||||
static ManagedLoadContext()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
NativeLibraryPrefixes = new[] { "" };
|
||||
NativeLibraryExtensions = new[] { ".dll" };
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
NativeLibraryPrefixes = new[] { "", "lib", };
|
||||
NativeLibraryExtensions = new[] { ".dylib" };
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
NativeLibraryPrefixes = new[] { "", "lib" };
|
||||
NativeLibraryExtensions = new[] { ".so", ".so.1" };
|
||||
}
|
||||
else
|
||||
{
|
||||
NativeLibraryPrefixes = Array.Empty<string>();
|
||||
NativeLibraryExtensions = Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public ManagedLoadContext(string baseDirectory, Dictionary<string, ManagedLibrary> managedAssemblies, Dictionary<string, NativeLibrary> nativeLibraries)
|
||||
{
|
||||
basePath = baseDirectory ?? throw new ArgumentNullException(nameof(baseDirectory));
|
||||
this.managedAssemblies = managedAssemblies ?? throw new ArgumentNullException(nameof(managedAssemblies));
|
||||
this.nativeLibraries = nativeLibraries ?? throw new ArgumentNullException(nameof(nativeLibraries));
|
||||
}
|
||||
|
||||
protected override Assembly Load(AssemblyName assemblyName)
|
||||
{
|
||||
// If default context is preferred, check first for types in the default context unless the dependency has been declared as private
|
||||
try
|
||||
{
|
||||
var defaultAssembly = Default.LoadFromAssemblyName(assemblyName);
|
||||
if (defaultAssembly != null)
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Swallow errors in loading from the default context
|
||||
}
|
||||
|
||||
if (managedAssemblies.TryGetValue(assemblyName.Name, out var library) && SearchForLibrary(library, out var path))
|
||||
return LoadFromAssemblyPath(path);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
|
||||
{
|
||||
foreach (var prefix in NativeLibraryPrefixes)
|
||||
if (nativeLibraries.TryGetValue(prefix + unmanagedDllName, out var library) && SearchForLibrary(library, prefix, out var path))
|
||||
return LoadUnmanagedDllFromPath(path);
|
||||
|
||||
return base.LoadUnmanagedDll(unmanagedDllName);
|
||||
}
|
||||
|
||||
bool SearchForLibrary(ManagedLibrary library, out string path)
|
||||
{
|
||||
// 1. Search in base path
|
||||
foreach (var ext in ManagedAssemblyExtensions)
|
||||
{
|
||||
var local = Path.Combine(basePath, library.Name.Name + ext);
|
||||
if (File.Exists(local))
|
||||
{
|
||||
path = local;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
path = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SearchForLibrary(NativeLibrary library, string prefix, out string path)
|
||||
{
|
||||
// 1. Search in base path
|
||||
foreach (var ext in NativeLibraryExtensions)
|
||||
{
|
||||
var candidate = Path.Combine(basePath, $"{prefix}{library.Name}{ext}");
|
||||
if (File.Exists(candidate))
|
||||
{
|
||||
path = candidate;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Search in base path + app local (for portable deployments of netcoreapp)
|
||||
var local = Path.Combine(basePath, library.AppLocalPath);
|
||||
if (File.Exists(local))
|
||||
{
|
||||
path = local;
|
||||
return true;
|
||||
}
|
||||
|
||||
path = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class ManagedLibrary
|
||||
{
|
||||
public AssemblyName Name { get; private set; }
|
||||
|
||||
public static ManagedLibrary CreateFromPackage(string assetPath)
|
||||
{
|
||||
return new ManagedLibrary
|
||||
{
|
||||
Name = new AssemblyName(Path.GetFileNameWithoutExtension(assetPath))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public class NativeLibrary
|
||||
{
|
||||
public string Name { get; private set; }
|
||||
|
||||
public string AppLocalPath { get; private set; }
|
||||
|
||||
public static NativeLibrary CreateFromPackage(string assetPath)
|
||||
{
|
||||
return new NativeLibrary
|
||||
{
|
||||
Name = Path.GetFileNameWithoutExtension(assetPath),
|
||||
AppLocalPath = assetPath
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class DependencyContextExtensions
|
||||
{
|
||||
public static AssemblyLoadContextBuilder TryAddDependencyContext(this AssemblyLoadContextBuilder builder, string depsFilePath, out Exception error)
|
||||
{
|
||||
error = null;
|
||||
try
|
||||
{
|
||||
builder.AddDependencyContext(depsFilePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
error = ex;
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static AssemblyLoadContextBuilder AddDependencyContext(this AssemblyLoadContextBuilder builder, string depsFilePath)
|
||||
{
|
||||
var reader = new DependencyContextJsonReader();
|
||||
using (var file = File.OpenRead(depsFilePath))
|
||||
{
|
||||
var deps = reader.Read(file);
|
||||
builder.SetBaseDirectory(Path.GetDirectoryName(depsFilePath));
|
||||
builder.AddDependencyContext(deps);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
static string GetFallbackRid()
|
||||
{
|
||||
string ridBase;
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
ridBase = "win10";
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
ridBase = "linux";
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
ridBase = "osx.10.12";
|
||||
else
|
||||
return "any";
|
||||
|
||||
switch (RuntimeInformation.OSArchitecture)
|
||||
{
|
||||
case Architecture.X86:
|
||||
return ridBase + "-x86";
|
||||
case Architecture.X64:
|
||||
return ridBase + "-x64";
|
||||
case Architecture.Arm:
|
||||
return ridBase + "-arm";
|
||||
case Architecture.Arm64:
|
||||
return ridBase + "-arm64";
|
||||
}
|
||||
|
||||
return ridBase;
|
||||
}
|
||||
|
||||
public static AssemblyLoadContextBuilder AddDependencyContext(this AssemblyLoadContextBuilder builder, DependencyContext dependencyContext)
|
||||
{
|
||||
var ridGraph = dependencyContext.RuntimeGraph.Any()
|
||||
? dependencyContext.RuntimeGraph
|
||||
: DependencyContext.Default.RuntimeGraph;
|
||||
|
||||
var rid = Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.GetRuntimeIdentifier();
|
||||
var fallbackRid = GetFallbackRid();
|
||||
var fallbackGraph = ridGraph.FirstOrDefault(g => g.Runtime == rid)
|
||||
?? ridGraph.FirstOrDefault(g => g.Runtime == fallbackRid)
|
||||
?? new RuntimeFallbacks("any");
|
||||
|
||||
foreach (var managed in dependencyContext.ResolveRuntimeAssemblies(fallbackGraph))
|
||||
builder.AddManagedLibrary(managed);
|
||||
|
||||
foreach (var native in dependencyContext.ResolveNativeAssets(fallbackGraph))
|
||||
builder.AddNativeLibrary(native);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
static IEnumerable<ManagedLibrary> ResolveRuntimeAssemblies(this DependencyContext depContext, RuntimeFallbacks runtimeGraph)
|
||||
{
|
||||
var rids = GetRids(runtimeGraph);
|
||||
return from library in depContext.RuntimeLibraries
|
||||
from assetPath in SelectAssets(rids, library.RuntimeAssemblyGroups)
|
||||
select ManagedLibrary.CreateFromPackage(assetPath);
|
||||
}
|
||||
|
||||
static IEnumerable<NativeLibrary> ResolveNativeAssets(this DependencyContext depContext, RuntimeFallbacks runtimeGraph)
|
||||
{
|
||||
var rids = GetRids(runtimeGraph);
|
||||
return from library in depContext.RuntimeLibraries
|
||||
from assetPath in SelectAssets(rids, library.NativeLibraryGroups)
|
||||
where !assetPath.EndsWith(".a", StringComparison.Ordinal)
|
||||
select NativeLibrary.CreateFromPackage(assetPath);
|
||||
}
|
||||
|
||||
static IEnumerable<string> GetRids(RuntimeFallbacks runtimeGraph)
|
||||
{
|
||||
return Enumerable.Concat(new[] { runtimeGraph.Runtime }, runtimeGraph?.Fallbacks ?? Enumerable.Empty<string>());
|
||||
}
|
||||
|
||||
static IEnumerable<string> SelectAssets(IEnumerable<string> rids, IEnumerable<RuntimeAssetGroup> groups)
|
||||
{
|
||||
foreach (var rid in rids)
|
||||
{
|
||||
var group = groups.FirstOrDefault(g => g.Runtime == rid);
|
||||
if (group != null)
|
||||
return group.AssetPaths;
|
||||
}
|
||||
|
||||
return groups.GetDefaultAssets();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,7 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFramework Condition="'$(Mono)' == ''">net5.0</TargetFramework>
|
||||
<TargetFramework Condition="'$(Mono)' != ''">netstandard2.1</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
@@ -17,6 +18,8 @@
|
||||
<CodeAnalysisRuleSet>..\OpenRA.ruleset</CodeAnalysisRuleSet>
|
||||
<Configurations>Release;Debug</Configurations>
|
||||
<AssemblyName>OpenRA</AssemblyName>
|
||||
<IsPublishable Condition="'$(CopyGenericLauncher)' == 'False'">false</IsPublishable>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetPlatform Condition="$([MSBuild]::IsOsPlatform('Windows'))">win-x64</TargetPlatform>
|
||||
@@ -62,4 +65,8 @@
|
||||
<Analyzer Remove="@(Analyzer)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="netstandard" />
|
||||
<TrimmerRootAssembly Include="System.IO.Pipes" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -32,11 +32,6 @@ namespace OpenRA.Mods.Cnc.FileFormats
|
||||
|
||||
public static class AudReader
|
||||
{
|
||||
public static byte[] LoadSound(byte[] raw, ref int index)
|
||||
{
|
||||
return ImaAdpcmReader.LoadImaAdpcmSound(raw, ref index);
|
||||
}
|
||||
|
||||
public static float SoundLength(Stream s)
|
||||
{
|
||||
var sampleRate = s.ReadUInt16();
|
||||
|
||||
138
OpenRA.Mods.Cnc/FileSystem/MegFile.cs
Normal file
138
OpenRA.Mods.Cnc/FileSystem/MegFile.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Mods.Cnc.FileSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// This class supports loading unencrypted V3 .meg files using
|
||||
/// reference documentation from here https://modtools.petrolution.net/docs/MegFileFormat
|
||||
/// </summary>
|
||||
public class MegV3Loader : IPackageLoader
|
||||
{
|
||||
const uint UnencryptedMegID = 0xFFFFFFFF;
|
||||
|
||||
// Float value 0.99, but it is simpler to read and compare as an integer
|
||||
const uint MegVersion = 0x3F7D70A4;
|
||||
|
||||
public bool TryParsePackage(Stream s, string filename, OpenRA.FileSystem.FileSystem context, out IReadOnlyPackage package)
|
||||
{
|
||||
var position = s.Position;
|
||||
|
||||
var id = s.ReadUInt32();
|
||||
var version = s.ReadUInt32();
|
||||
|
||||
s.Position = position;
|
||||
|
||||
if (id != UnencryptedMegID || version != MegVersion)
|
||||
{
|
||||
package = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
package = new MegFile(s, filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
public sealed class MegFile : IReadOnlyPackage
|
||||
{
|
||||
readonly Stream s;
|
||||
|
||||
readonly Dictionary<string, (uint Offset, int Length)> contents = new Dictionary<string, (uint Offset, int Length)>();
|
||||
|
||||
public MegFile(Stream s, string filename)
|
||||
{
|
||||
Name = filename;
|
||||
this.s = s;
|
||||
|
||||
var id = s.ReadUInt32();
|
||||
var version = s.ReadUInt32();
|
||||
|
||||
if (id != UnencryptedMegID || version != MegVersion)
|
||||
throw new Exception("Invalid file signature for meg file");
|
||||
|
||||
var headerSize = s.ReadUInt32();
|
||||
var numStrings = s.ReadUInt32();
|
||||
var numFiles = s.ReadUInt32();
|
||||
var stringsSize = s.ReadUInt32();
|
||||
var stringsStart = s.Position;
|
||||
|
||||
var filenames = new List<string>();
|
||||
|
||||
// The file names are an indexed array of strings
|
||||
for (var i = 0; i < numStrings; i++)
|
||||
{
|
||||
var length = s.ReadUInt16();
|
||||
filenames.Add(s.ReadASCII(length));
|
||||
}
|
||||
|
||||
// The header indicates where we should be, so verify it
|
||||
if (s.Position != stringsSize + stringsStart)
|
||||
throw new Exception("File name table in .meg file inconsistent");
|
||||
|
||||
// Now we load each file entry and associated info
|
||||
for (var i = 0; i < numFiles; i++)
|
||||
{
|
||||
// Ignore flags, crc, index
|
||||
s.Position += 10;
|
||||
var size = s.ReadUInt32();
|
||||
var offset = s.ReadUInt32();
|
||||
var nameIndex = s.ReadUInt16();
|
||||
contents[filenames[nameIndex]] = (offset, (int)size);
|
||||
}
|
||||
|
||||
if (s.Position != headerSize)
|
||||
throw new Exception("Expected to be at data start offset");
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public IEnumerable<string> Contents => contents.Keys;
|
||||
|
||||
public bool Contains(string filename)
|
||||
{
|
||||
return contents.ContainsKey(filename);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
s.Dispose();
|
||||
}
|
||||
|
||||
public Stream GetStream(string filename)
|
||||
{
|
||||
// Look up the index of the filename
|
||||
if (!contents.TryGetValue(filename, out var index))
|
||||
return null;
|
||||
|
||||
return SegmentStream.CreateWithoutOwningStream(s, index.Offset, index.Length);
|
||||
}
|
||||
|
||||
public IReadOnlyPackage OpenPackage(string filename, OpenRA.FileSystem.FileSystem context)
|
||||
{
|
||||
var childStream = GetStream(filename);
|
||||
if (childStream == null)
|
||||
return null;
|
||||
|
||||
if (context.TryParsePackage(childStream, filename, out var package))
|
||||
return package;
|
||||
|
||||
childStream.Dispose();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
@@ -11,6 +11,7 @@
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<CodeAnalysisRuleSet>..\OpenRA.ruleset</CodeAnalysisRuleSet>
|
||||
<IsPublishable Condition="'$(CopyCncDll)' == 'False'">false</IsPublishable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Work around an issue where Rider does not detect files in the project root using the default glob -->
|
||||
@@ -37,4 +38,4 @@
|
||||
<Analyzer Remove="@(Analyzer)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -89,9 +89,6 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
var tile = world.Map.Tiles[cell];
|
||||
var tileInfo = world.Map.Rules.TileSet.GetTileInfo(tile);
|
||||
if (tileInfo == null)
|
||||
return false;
|
||||
|
||||
var terrainType = world.Map.Rules.TileSet.TerrainInfo[tileInfo.TerrainType];
|
||||
|
||||
if (mapResources[cell].Type == ResourceType.ResourceType)
|
||||
|
||||
25
OpenRA.Mods.Common/Lint/CheckMapTiles.cs
Normal file
25
OpenRA.Mods.Common/Lint/CheckMapTiles.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenRA.Mods.Common.Lint
|
||||
{
|
||||
public class CheckMapTiles : ILintMapPass
|
||||
{
|
||||
public void Run(Action<string> emitError, Action<string> emitWarning, ModData modData, Map map)
|
||||
{
|
||||
foreach (var kv in map.ReplacedInvalidTerrainTiles)
|
||||
emitError("Cell {0} references invalid terrain tile {1}.".F(kv.Key, kv.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
@@ -11,6 +11,7 @@
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<CodeAnalysisRuleSet>..\OpenRA.ruleset</CodeAnalysisRuleSet>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Work around an issue where Rider does not detect files in the project root using the default glob -->
|
||||
@@ -24,6 +25,7 @@
|
||||
<ProjectReference Include="..\OpenRA.Game\OpenRA.Game.csproj">
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="4.7.0" />
|
||||
<PackageReference Include="OpenRA-FuzzyLogicLibrary" Version="1.0.1" />
|
||||
<PackageReference Include="DiscordRichPresence" Version="1.0.150" />
|
||||
<PackageReference Include="rix0rrr.BeaconLib" Version="1.0.2" />
|
||||
|
||||
@@ -13,6 +13,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using BeaconLib;
|
||||
using OpenRA.Network;
|
||||
using OpenRA.Server;
|
||||
@@ -107,7 +108,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
{
|
||||
isBusy = true;
|
||||
|
||||
Action a = () =>
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -160,9 +161,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
}
|
||||
|
||||
isBusy = false;
|
||||
};
|
||||
|
||||
a.BeginInvoke(null, null);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,10 +78,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
for (var x = 0; x < TerrainTemplate.Size.X; x++)
|
||||
{
|
||||
var tile = new TerrainTile(TerrainTemplate.Id, (byte)i++);
|
||||
var tileInfo = world.Map.Rules.TileSet.GetTileInfo(tile);
|
||||
|
||||
// Empty tile
|
||||
if (tileInfo == null)
|
||||
if (!world.Map.Rules.TileSet.TryGetTileInfo(tile, out var tileInfo))
|
||||
continue;
|
||||
|
||||
var sprite = wr.Theater.TileSprite(tile, 0);
|
||||
|
||||
@@ -104,6 +104,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
||||
" for (var j = 0; j < ctx.canvas.height / 4; j++)",
|
||||
" for (var i = j % 2; i < ctx.canvas.width / 4; i += 2)",
|
||||
" ctx.fillRect(4 * i, 4 * j, 4, 4);",
|
||||
" ctx.imageSmoothingEnabled = false;",
|
||||
" ctx.drawImage(image, 0, 0, c.width, c.height);",
|
||||
" ctx.strokeStyle = \"#ffff00\";",
|
||||
" ctx.lineWidth = 1;",
|
||||
|
||||
@@ -81,10 +81,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
for (var x = 0; x < Template.Size.X; x++)
|
||||
{
|
||||
var tile = new TerrainTile(Template.Id, (byte)(i++));
|
||||
var tileInfo = tileset.GetTileInfo(tile);
|
||||
|
||||
// Empty tile
|
||||
if (tileInfo == null)
|
||||
if (!tileset.TryGetTileInfo(tile, out var tileInfo))
|
||||
continue;
|
||||
|
||||
var sprite = worldRenderer.Theater.TileSprite(tile, 0);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
@@ -11,6 +11,7 @@
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<CodeAnalysisRuleSet>..\OpenRA.ruleset</CodeAnalysisRuleSet>
|
||||
<IsPublishable Condition="'$(CopyD2kDll)' == 'False'">false</IsPublishable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Work around an issue where Rider does not detect files in the project root using the default glob -->
|
||||
@@ -37,4 +38,4 @@
|
||||
<Analyzer Remove="@(Analyzer)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
@@ -11,6 +11,7 @@
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<CodeAnalysisRuleSet>..\OpenRA.ruleset</CodeAnalysisRuleSet>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetPlatform Condition="$([MSBuild]::IsOsPlatform('Windows'))">win-x64</TargetPlatform>
|
||||
|
||||
@@ -59,7 +59,6 @@ namespace OpenRA.Platforms.Default
|
||||
Name = "ThreadedGraphicsContext RenderThread",
|
||||
IsBackground = true
|
||||
};
|
||||
renderThread.SetApartmentState(ApartmentState.STA);
|
||||
lock (syncObject)
|
||||
{
|
||||
// Start and wait for the rendering thread to have initialized before returning.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFramework Condition="'$(Mono)' == ''">net5.0</TargetFramework>
|
||||
<TargetFramework Condition="'$(Mono)' != ''">netstandard2.1</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
@@ -39,4 +40,8 @@
|
||||
<Analyzer Remove="@(Analyzer)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="netstandard" />
|
||||
<TrimmerRootAssembly Include="System.IO.Pipes" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -10,6 +10,7 @@
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<CodeAnalysisRuleSet>..\OpenRA.ruleset</CodeAnalysisRuleSet>
|
||||
<IsPublishable>false</IsPublishable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Work around an issue where Rider does not detect files in the project root using the default glob -->
|
||||
@@ -22,14 +23,12 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\OpenRA.Game\OpenRA.Game.csproj" />
|
||||
<ProjectReference Include="..\OpenRA.Mods.Common\OpenRA.Mods.Common.csproj">
|
||||
<Private>False</Private>
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit.Console" Version="3.11.1" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0-beta.1" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
|
||||
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
|
||||
<AdditionalFiles Include="../stylecop.json" />
|
||||
@@ -40,4 +39,4 @@
|
||||
<Analyzer Remove="@(Analyzer)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFramework Condition="'$(Mono)' == ''">net5.0</TargetFramework>
|
||||
<TargetFramework Condition="'$(Mono)' != ''">netstandard2.1</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
@@ -39,4 +40,8 @@
|
||||
<Analyzer Remove="@(Analyzer)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="netstandard" />
|
||||
<TrimmerRootAssembly Include="System.IO.Pipes" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>winexe</OutputType>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<ApplicationIcon>$(LauncherIcon)</ApplicationIcon>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
@@ -10,14 +12,12 @@
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
|
||||
<OutputPath>../bin</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ExternalConsole>false</ExternalConsole>
|
||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||
<CodeAnalysisRuleSet>..\OpenRA.ruleset</CodeAnalysisRuleSet>
|
||||
<Configurations>Release;Debug</Configurations>
|
||||
<AssemblyName>$(LauncherName)</AssemblyName>
|
||||
<ApplicationIcon>$(LauncherIcon)</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- Work around an issue where Rider does not detect files in the project root using the default glob -->
|
||||
@@ -58,4 +58,8 @@
|
||||
<Analyzer Remove="@(Analyzer)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="netstandard" />
|
||||
<TrimmerRootAssembly Include="System.IO.Pipes" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -58,9 +58,7 @@ Global
|
||||
{FE6C8CC0-2F07-442A-B29F-17617B3B7FC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FE6C8CC0-2F07-442A-B29F-17617B3B7FC6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6CB8E1B7-6B36-4D93-8633-7C573E194AC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6CB8E1B7-6B36-4D93-8633-7C573E194AC4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6CB8E1B7-6B36-4D93-8633-7C573E194AC4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6CB8E1B7-6B36-4D93-8633-7C573E194AC4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{54DAE0E0-3125-49D3-992E-A0E931EB5FC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{54DAE0E0-3125-49D3-992E-A0E931EB5FC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{54DAE0E0-3125-49D3-992E-A0E931EB5FC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
||||
@@ -25,7 +25,7 @@ ShareAnonymizedIPs="${ShareAnonymizedIPs:-"True"}"
|
||||
SupportDir="${SupportDir:-""}"
|
||||
|
||||
while true; do
|
||||
mono --debug bin/OpenRA.Server.exe Engine.EngineDir=".." Game.Mod="$Mod" \
|
||||
mono --debug bin/OpenRA.Server.dll Engine.EngineDir=".." Game.Mod="$Mod" \
|
||||
Server.Name="$Name" \
|
||||
Server.ListenPort="$ListenPort" \
|
||||
Server.AdvertiseOnline="$AdvertiseOnline" \
|
||||
|
||||
@@ -25,7 +25,7 @@ then
|
||||
fi
|
||||
|
||||
# Launch the engine with the appropriate arguments
|
||||
mono bin/OpenRA.exe Engine.EngineDir=".." Engine.LaunchPath="$MODLAUNCHER" $MODARG "$@"
|
||||
mono --debug bin/OpenRA.dll Engine.EngineDir=".." Engine.LaunchPath="$MODLAUNCHER" $MODARG "$@"
|
||||
|
||||
# Show a crash dialog if something went wrong
|
||||
if [ $? != 0 ] && [ $? != 1 ]; then
|
||||
|
||||
4
make.ps1
4
make.ps1
@@ -10,7 +10,7 @@ function All-Command
|
||||
return
|
||||
}
|
||||
|
||||
dotnet build /p:Configuration=Release /nologo
|
||||
dotnet build -c Release --nologo -p:TargetPlatform=win-x64
|
||||
if ($lastexitcode -ne 0)
|
||||
{
|
||||
Write-Host "Build failed. If just the development tools failed to build, try installing Visual Studio. You may also still be able to run the game." -ForegroundColor Red
|
||||
@@ -111,7 +111,7 @@ function Test-Command
|
||||
function Check-Command
|
||||
{
|
||||
Write-Host "Compiling in debug configuration..." -ForegroundColor Cyan
|
||||
dotnet build /p:Configuration=Debug /nologo
|
||||
dotnet build -c Debug --nologo -p:TargetPlatform=win-x64
|
||||
if ($lastexitcode -ne 0)
|
||||
{
|
||||
Write-Host "Build failed." -ForegroundColor Red
|
||||
|
||||
@@ -366,23 +366,18 @@ scrollpanel-decorations:
|
||||
Inherits: ^Chrome
|
||||
Regions:
|
||||
down: 836, 17, 16, 16
|
||||
down-pressed: 836, 17, 16, 16
|
||||
down-disabled: 853, 17, 16, 16
|
||||
up: 870, 17, 16, 16
|
||||
up-pressed: 870, 17, 16, 16
|
||||
up-disabled: 887, 17, 16, 16
|
||||
right: 904, 17, 16, 16
|
||||
right-pressed: 904, 17, 16, 16
|
||||
right-disabled: 921, 17, 16, 16
|
||||
left: 938, 17, 16, 16
|
||||
left-pressed: 938, 17, 16, 16
|
||||
left-disabled: 955, 17, 16, 16
|
||||
|
||||
dropdown-decorations:
|
||||
Inherits: ^Chrome
|
||||
Regions:
|
||||
marker: 836, 17, 16, 16
|
||||
marker-pressed: 836, 17, 16, 16
|
||||
marker-disabled: 853, 17, 16, 16
|
||||
|
||||
dropdown-separators:
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -558,23 +558,18 @@ scrollpanel-decorations:
|
||||
Inherits: ^Glyphs
|
||||
Regions:
|
||||
down: 68, 17, 16, 16
|
||||
down-pressed: 68, 17, 16, 16
|
||||
down-disabled: 85, 17, 16, 16
|
||||
up: 102, 17, 16, 16
|
||||
up-pressed: 102, 17, 16, 16
|
||||
up-disabled: 119, 17, 16, 16
|
||||
right: 136, 17, 16, 16
|
||||
right-pressed: 136, 17, 16, 16
|
||||
right-disabled: 153, 17, 16, 16
|
||||
left: 170, 17, 16, 16
|
||||
left-pressed: 170, 17, 16, 16
|
||||
left-disabled: 187, 17, 16, 16
|
||||
|
||||
dropdown-decorations:
|
||||
Inherits: ^Glyphs
|
||||
Regions:
|
||||
marker: 68, 17, 16, 16
|
||||
marker-pressed: 68, 17, 16, 16
|
||||
marker-disabled: 85, 17, 16, 16
|
||||
|
||||
dropdown-separators:
|
||||
|
||||
BIN
mods/ra/maps/oil-spill/map.bin
Normal file
BIN
mods/ra/maps/oil-spill/map.bin
Normal file
Binary file not shown.
BIN
mods/ra/maps/oil-spill/map.png
Normal file
BIN
mods/ra/maps/oil-spill/map.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
309
mods/ra/maps/oil-spill/map.yaml
Normal file
309
mods/ra/maps/oil-spill/map.yaml
Normal file
@@ -0,0 +1,309 @@
|
||||
MapFormat: 11
|
||||
|
||||
RequiresMod: ra
|
||||
|
||||
Title: Oil Spill
|
||||
|
||||
Author: Super Newbie
|
||||
|
||||
Tileset: DESERT
|
||||
|
||||
MapSize: 120,120
|
||||
|
||||
Bounds: 1,1,118,118
|
||||
|
||||
Visibility: Lobby
|
||||
|
||||
Categories: Minigame
|
||||
|
||||
Players:
|
||||
PlayerReference@Neutral:
|
||||
Name: Neutral
|
||||
OwnsWorld: True
|
||||
NonCombatant: True
|
||||
Faction: england
|
||||
PlayerReference@Creeps:
|
||||
Name: Creeps
|
||||
NonCombatant: True
|
||||
Faction: england
|
||||
Enemies: Multi0, Multi1, Multi2, Multi3
|
||||
PlayerReference@Multi0:
|
||||
Name: Multi0
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: allies
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi1:
|
||||
Name: Multi1
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: allies
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi2:
|
||||
Name: Multi2
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: allies
|
||||
Enemies: Creeps
|
||||
PlayerReference@Multi3:
|
||||
Name: Multi3
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockFaction: True
|
||||
Faction: allies
|
||||
Enemies: Creeps
|
||||
|
||||
Actors:
|
||||
Actor1: rock1
|
||||
Owner: Neutral
|
||||
Location: 112,21
|
||||
Actor2: tc01
|
||||
Owner: Neutral
|
||||
Location: 50,4
|
||||
Actor3: tc01
|
||||
Owner: Neutral
|
||||
Location: 117,23
|
||||
Actor4: tc01
|
||||
Owner: Neutral
|
||||
Location: 115,31
|
||||
Actor5: tc01
|
||||
Owner: Neutral
|
||||
Location: 113,13
|
||||
Actor6: tc01
|
||||
Owner: Neutral
|
||||
Location: 108,3
|
||||
Actor7: v37
|
||||
Owner: Neutral
|
||||
Location: 66,3
|
||||
Actor8: v30
|
||||
Owner: Neutral
|
||||
Location: 69,2
|
||||
Actor9: v31
|
||||
Owner: Neutral
|
||||
Location: 48,3
|
||||
Actor10: v24
|
||||
Owner: Neutral
|
||||
Location: 46,3
|
||||
Actor12: v24
|
||||
Owner: Neutral
|
||||
Location: 117,102
|
||||
Actor13: tc01
|
||||
Owner: Neutral
|
||||
Location: 94,116
|
||||
Actor14: tc01
|
||||
Owner: Neutral
|
||||
Location: 102,111
|
||||
Actor15: t08
|
||||
Owner: Neutral
|
||||
Location: 105,4
|
||||
Actor18: rock6
|
||||
Owner: Neutral
|
||||
Location: 15,114
|
||||
Actor19: rock7
|
||||
Owner: Neutral
|
||||
Location: 41,112
|
||||
Actor20: rock6
|
||||
Owner: Neutral
|
||||
Location: 74,113
|
||||
Actor21: tc01
|
||||
Owner: Neutral
|
||||
Location: 31,113
|
||||
Actor22: tc01
|
||||
Owner: Neutral
|
||||
Location: 62,113
|
||||
Actor23: t08
|
||||
Owner: Neutral
|
||||
Location: 74,112
|
||||
Actor24: v25
|
||||
Owner: Neutral
|
||||
Location: 116,99
|
||||
Actor26: tc01
|
||||
Owner: Neutral
|
||||
Location: 3,30
|
||||
Actor25: tc01
|
||||
Owner: Neutral
|
||||
Location: 4,36
|
||||
Actor27: rock2
|
||||
Owner: Neutral
|
||||
Location: 5,81
|
||||
Actor28: v21
|
||||
Owner: Neutral
|
||||
Location: 3,88
|
||||
Actor29: v30
|
||||
Owner: Neutral
|
||||
Location: 2,91
|
||||
Actor30: t08
|
||||
Owner: Neutral
|
||||
Location: 5,41
|
||||
Actor31: tc01
|
||||
Owner: Neutral
|
||||
Location: 72,34
|
||||
Actor32: t08
|
||||
Owner: Neutral
|
||||
Location: 71,34
|
||||
Actor33: tc01
|
||||
Owner: Neutral
|
||||
Location: 82,44
|
||||
Actor36: oilb
|
||||
Owner: Neutral
|
||||
Location: 51,51
|
||||
Actor37: oilb
|
||||
Owner: Neutral
|
||||
Location: 67,51
|
||||
Actor38: oilb
|
||||
Owner: Neutral
|
||||
Location: 51,67
|
||||
Actor39: oilb
|
||||
Owner: Neutral
|
||||
Location: 67,67
|
||||
Actor44: oilb
|
||||
Owner: Neutral
|
||||
Location: 46,82
|
||||
Actor45: oilb
|
||||
Owner: Neutral
|
||||
Location: 36,72
|
||||
Actor46: oilb
|
||||
Owner: Neutral
|
||||
Location: 72,82
|
||||
Actor47: oilb
|
||||
Owner: Neutral
|
||||
Location: 36,46
|
||||
Actor48: oilb
|
||||
Owner: Neutral
|
||||
Location: 46,36
|
||||
Actor49: oilb
|
||||
Owner: Neutral
|
||||
Location: 82,46
|
||||
Actor50: oilb
|
||||
Owner: Neutral
|
||||
Location: 72,36
|
||||
Actor53: oilb
|
||||
Owner: Neutral
|
||||
Location: 59,34
|
||||
Actor54: oilb
|
||||
Owner: Neutral
|
||||
Location: 34,59
|
||||
Actor55: oilb
|
||||
Owner: Neutral
|
||||
Location: 59,84
|
||||
Actor56: oilb
|
||||
Owner: Neutral
|
||||
Location: 84,59
|
||||
OilBottomLeft2: oilb
|
||||
Location: 18,96
|
||||
Owner: Neutral
|
||||
OilBottomLeft1: oilb
|
||||
Location: 22,100
|
||||
Owner: Neutral
|
||||
OilBottomRight2: oilb
|
||||
Owner: Neutral
|
||||
Location: 96,100
|
||||
OilBottomRight1: oilb
|
||||
Owner: Neutral
|
||||
Location: 100,96
|
||||
OilTopLeft2: oilb
|
||||
Owner: Neutral
|
||||
Location: 22,18
|
||||
OilTopLeft1: oilb
|
||||
Owner: Neutral
|
||||
Location: 18,22
|
||||
OilTopRight2: oilb
|
||||
Location: 100,22
|
||||
Owner: Neutral
|
||||
OilTopRight1: oilb
|
||||
Location: 96,18
|
||||
Owner: Neutral
|
||||
Actor65: fcom
|
||||
Owner: Neutral
|
||||
Location: 48,96
|
||||
Actor69: fcom
|
||||
Owner: Neutral
|
||||
Location: 70,96
|
||||
Actor70: fcom
|
||||
Owner: Neutral
|
||||
Location: 22,70
|
||||
Actor72: fcom
|
||||
Owner: Neutral
|
||||
Location: 22,48
|
||||
Actor73: fcom
|
||||
Owner: Neutral
|
||||
Location: 48,22
|
||||
Actor71: fcom
|
||||
Owner: Neutral
|
||||
Location: 70,22
|
||||
Actor74: fcom
|
||||
Owner: Neutral
|
||||
Location: 96,48
|
||||
Actor75: fcom
|
||||
Owner: Neutral
|
||||
Location: 96,70
|
||||
Actor77: oilb
|
||||
Owner: Neutral
|
||||
Location: 82,72
|
||||
Actor80: oilb
|
||||
Owner: Neutral
|
||||
Location: 46,20
|
||||
Actor81: oilb
|
||||
Owner: Neutral
|
||||
Location: 72,20
|
||||
Actor82: oilb
|
||||
Owner: Neutral
|
||||
Location: 46,98
|
||||
Actor83: oilb
|
||||
Owner: Neutral
|
||||
Location: 72,98
|
||||
Actor84: oilb
|
||||
Owner: Neutral
|
||||
Location: 20,72
|
||||
Actor85: oilb
|
||||
Owner: Neutral
|
||||
Location: 20,46
|
||||
Actor86: oilb
|
||||
Owner: Neutral
|
||||
Location: 98,46
|
||||
Actor87: oilb
|
||||
Owner: Neutral
|
||||
Location: 98,72
|
||||
OilTopLeft3: oilb
|
||||
Owner: Neutral
|
||||
Location: 29,29
|
||||
OilBottomLeft3: oilb
|
||||
Location: 29,89
|
||||
Owner: Neutral
|
||||
OilTopRight3: oilb
|
||||
Location: 89,29
|
||||
Owner: Neutral
|
||||
OilBottomRight3: oilb
|
||||
Owner: Neutral
|
||||
Location: 89,89
|
||||
Spawn0: mpspawn
|
||||
Owner: Neutral
|
||||
Location: 31,31
|
||||
Spawn1: mpspawn
|
||||
Owner: Neutral
|
||||
Location: 87,31
|
||||
Spawn2: mpspawn
|
||||
Owner: Neutral
|
||||
Location: 31,87
|
||||
Spawn3: mpspawn
|
||||
Owner: Neutral
|
||||
Location: 87,87
|
||||
FCOMTopLeft: fcom
|
||||
Owner: Neutral
|
||||
Location: 31,31
|
||||
FCOMTopRight: fcom
|
||||
Owner: Neutral
|
||||
Location: 87,31
|
||||
FCOMBottomLeft: fcom
|
||||
Owner: Neutral
|
||||
Location: 31,87
|
||||
FCOMBottomRight: fcom
|
||||
Owner: Neutral
|
||||
Location: 87,87
|
||||
|
||||
Rules: rules.yaml
|
||||
|
||||
Sequences: sequences.yaml
|
||||
27
mods/ra/maps/oil-spill/oil-spill.lua
Normal file
27
mods/ra/maps/oil-spill/oil-spill.lua
Normal file
@@ -0,0 +1,27 @@
|
||||
--[[
|
||||
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.
|
||||
]]
|
||||
|
||||
SpawnBuildings =
|
||||
{
|
||||
{ FCOMTopLeft, OilTopLeft1, OilTopLeft2, OilTopLeft3 },
|
||||
{ FCOMTopRight, OilTopRight1, OilTopRight2, OilTopRight3 },
|
||||
{ FCOMBottomLeft, OilBottomLeft1, OilBottomLeft2, OilBottomLeft3 },
|
||||
{ FCOMBottomRight, OilBottomRight1, OilBottomRight2, OilBottomRight3 },
|
||||
}
|
||||
|
||||
WorldLoaded = function()
|
||||
for i = 0, 4 do
|
||||
local player = Player.GetPlayer("Multi" .. i)
|
||||
if player then
|
||||
Utils.Do(SpawnBuildings[player.Spawn], function(actor)
|
||||
actor.Owner = player
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
215
mods/ra/maps/oil-spill/rules.yaml
Normal file
215
mods/ra/maps/oil-spill/rules.yaml
Normal file
@@ -0,0 +1,215 @@
|
||||
World:
|
||||
LuaScript:
|
||||
Scripts: oil-spill.lua
|
||||
SpawnMPUnits:
|
||||
DropdownVisible: False
|
||||
MPStartUnits@mcvonly:
|
||||
BaseActor: fcom
|
||||
|
||||
FCOM:
|
||||
MustBeDestroyed:
|
||||
RequiredForShortGame: true
|
||||
Power:
|
||||
Amount: 50
|
||||
Health:
|
||||
HP: 110000
|
||||
Production:
|
||||
Produces: Building, Defense
|
||||
RepairableBuilding:
|
||||
RepairStep: 700
|
||||
PlayerExperience: 25
|
||||
RepairingNotification: Repairing
|
||||
WithBuildingRepairDecoration:
|
||||
Image: allyrepair
|
||||
Sequence: repair
|
||||
Position: Center
|
||||
Palette: player
|
||||
IsPlayerPalette: True
|
||||
ProductionBar@Building:
|
||||
ProductionType: Building
|
||||
ProductionBar@Defense:
|
||||
ProductionType: Defense
|
||||
Color: 8A8A8A
|
||||
BaseBuilding:
|
||||
ProvidesPrerequisite@buildingname:
|
||||
|
||||
OILB:
|
||||
CashTrickler:
|
||||
Interval: 250
|
||||
Amount: 100
|
||||
SpawnActorOnDeath:
|
||||
Actor: OILB.Husk
|
||||
OwnerType: InternalName
|
||||
|
||||
OILB.Husk:
|
||||
Inherits: ^TechBuilding
|
||||
Inherits@shape: ^2x2Shape
|
||||
Selectable:
|
||||
Priority: 0
|
||||
Bounds: 48,48
|
||||
CapturableProgressBar:
|
||||
CapturableProgressBlink:
|
||||
Building:
|
||||
Footprint: xx xx
|
||||
Dimensions: 2,2
|
||||
Tooltip:
|
||||
Name: Husk (Oil Derrick)
|
||||
CaptureManager:
|
||||
Capturable:
|
||||
Types: building-husk
|
||||
TransformOnCapture:
|
||||
IntoActor: OILB
|
||||
ForceHealthPercentage: 50
|
||||
Targetable:
|
||||
TargetTypes: building-husk
|
||||
|
||||
E6:
|
||||
Captures@husk:
|
||||
RequiresCondition: !global-reusable-engineers
|
||||
CaptureTypes: building-husk
|
||||
PlayerExperience: 25
|
||||
CaptureDelay: 200
|
||||
EnterCursor: goldwrench
|
||||
Captures@husk-reusable:
|
||||
RequiresCondition: global-reusable-engineers
|
||||
CaptureTypes: building-husk
|
||||
PlayerExperience: 25
|
||||
CaptureDelay: 375
|
||||
EnterCursor: goldwrench
|
||||
ConsumedByCapture: False
|
||||
|
||||
WEAP:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
PROC:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
SILO:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
BRIK:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
POWR:
|
||||
Power:
|
||||
Amount: 125
|
||||
-SpawnActorsOnSell:
|
||||
-MustBeDestroyed:
|
||||
|
||||
APWR:
|
||||
Power:
|
||||
Amount: 250
|
||||
-SpawnActorsOnSell:
|
||||
-MustBeDestroyed:
|
||||
|
||||
TENT:
|
||||
Buildable:
|
||||
Prerequisites: fcom
|
||||
-SpawnActorsOnSell:
|
||||
-MustBeDestroyed:
|
||||
|
||||
DOME:
|
||||
Buildable:
|
||||
Prerequisites: anypower
|
||||
-SpawnActorsOnSell:
|
||||
-MustBeDestroyed:
|
||||
|
||||
SYRD:
|
||||
Buildable:
|
||||
Prerequisites: fcom
|
||||
-MustBeDestroyed:
|
||||
|
||||
SPEN:
|
||||
Buildable:
|
||||
Prerequisites: fcom
|
||||
-MustBeDestroyed:
|
||||
|
||||
STEK:
|
||||
Buildable:
|
||||
Prerequisites: dome, tent
|
||||
-SpawnActorsOnSell:
|
||||
-MustBeDestroyed:
|
||||
|
||||
AFLD:
|
||||
Buildable:
|
||||
Prerequisites: dome
|
||||
-SpawnActorsOnSell:
|
||||
-MustBeDestroyed:
|
||||
AirstrikePower@spyplane:
|
||||
Prerequisites: afld
|
||||
AirstrikePower@parabombs:
|
||||
Prerequisites: afld
|
||||
|
||||
HPAD:
|
||||
Buildable:
|
||||
Prerequisites: dome
|
||||
-SpawnActorsOnSell:
|
||||
-MustBeDestroyed:
|
||||
|
||||
FIX:
|
||||
Buildable:
|
||||
Prerequisites: dome
|
||||
-SpawnActorsOnSell:
|
||||
-MustBeDestroyed:
|
||||
|
||||
IRON:
|
||||
Buildable:
|
||||
Prerequisites: stek
|
||||
|
||||
PDOX:
|
||||
Buildable:
|
||||
Prerequisites: atek
|
||||
ChronoshiftPower@chronoshift:
|
||||
-Prerequisites:
|
||||
-ChronoshiftPower@advancedchronoshift:
|
||||
|
||||
ATEK:
|
||||
Buildable:
|
||||
Prerequisites: dome, tent
|
||||
-SpawnActorsOnSell:
|
||||
-MustBeDestroyed:
|
||||
|
||||
FTUR:
|
||||
Buildable:
|
||||
Prerequisites: tent
|
||||
-SpawnActorsOnSell:
|
||||
|
||||
GUN:
|
||||
Buildable:
|
||||
Prerequisites: tent
|
||||
-SpawnActorsOnSell:
|
||||
|
||||
GAP:
|
||||
Buildable:
|
||||
Prerequisites: atek
|
||||
-SpawnActorsOnSell:
|
||||
|
||||
AGUN:
|
||||
Buildable:
|
||||
Prerequisites: dome
|
||||
-SpawnActorsOnSell:
|
||||
|
||||
TSLA:
|
||||
Buildable:
|
||||
Prerequisites: dome
|
||||
-SpawnActorsOnSell:
|
||||
|
||||
MECH:
|
||||
Buildable:
|
||||
Prerequisites: dome
|
||||
|
||||
E1:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
E3:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
|
||||
E7:
|
||||
Buildable:
|
||||
Prerequisites: ~disabled
|
||||
4
mods/ra/maps/oil-spill/sequences.yaml
Normal file
4
mods/ra/maps/oil-spill/sequences.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
oilb.husk: oilb
|
||||
idle: oilb
|
||||
Start: 1
|
||||
Offset: 0,-6
|
||||
Binary file not shown.
Binary file not shown.
@@ -680,23 +680,18 @@ scrollpanel-decorations:
|
||||
Inherits: ^Glyphs
|
||||
Regions:
|
||||
down: 68, 17, 16, 16
|
||||
down-pressed: 68, 17, 16, 16
|
||||
down-disabled: 85, 17, 16, 16
|
||||
up: 102, 17, 16, 16
|
||||
up-pressed: 102, 17, 16, 16
|
||||
up-disabled: 119, 17, 16, 16
|
||||
right: 136, 17, 16, 16
|
||||
right-pressed: 136, 17, 16, 16
|
||||
right-disabled: 153, 17, 16, 16
|
||||
left: 170, 17, 16, 16
|
||||
left-pressed: 170, 17, 16, 16
|
||||
left-disabled: 187, 17, 16, 16
|
||||
|
||||
dropdown-decorations:
|
||||
Inherits: ^Glyphs
|
||||
Regions:
|
||||
marker: 68, 17, 16, 16
|
||||
marker-pressed: 68, 17, 16, 16
|
||||
marker-disabled: 85, 17, 16, 16
|
||||
|
||||
dropdown-separators:
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
# Makefile (install target for local installs and downstream packaging)
|
||||
# Linux AppImage packaging
|
||||
# macOS packaging
|
||||
# Windows packaging
|
||||
# Mod SDK Linux AppImage packaging
|
||||
# Mod SDK macOS packaging
|
||||
# Mod SDK Windows packaging
|
||||
@@ -33,26 +32,27 @@ install_assemblies_mono() {
|
||||
echo "Building assemblies"
|
||||
ORIG_PWD=$(pwd)
|
||||
cd "${SRC_PATH}" || exit 1
|
||||
msbuild -verbosity:m -nologo -t:Clean
|
||||
|
||||
rm -rf "${SRC_PATH}/OpenRA."*/obj
|
||||
rm -rf "${SRC_PATH:?}/bin"
|
||||
msbuild -verbosity:m -nologo -t:Build -restore -p:Configuration=Release -p:TargetPlatform="${TARGETPLATFORM}"
|
||||
|
||||
msbuild -verbosity:m -nologo -t:Build -restore -p:Configuration=Release -p:TargetPlatform="${TARGETPLATFORM}" -p:Mono=true -p:DefineConstants="MONO"
|
||||
if [ "${TARGETPLATFORM}" = "unix-generic" ]; then
|
||||
./configure-system-libraries.sh
|
||||
fi
|
||||
|
||||
./fetch-geoip.sh
|
||||
cd "${ORIG_PWD}" || exit 1
|
||||
|
||||
echo "Installing engine to ${DEST_PATH}"
|
||||
install -d "${DEST_PATH}"
|
||||
|
||||
# Core engine
|
||||
install -m755 "${SRC_PATH}/bin/OpenRA.Server.exe" "${DEST_PATH}"
|
||||
install -m755 "${SRC_PATH}/bin/OpenRA.Utility.exe" "${DEST_PATH}"
|
||||
install -m755 "${SRC_PATH}/bin/OpenRA.Server.dll" "${DEST_PATH}"
|
||||
install -m755 "${SRC_PATH}/bin/OpenRA.Utility.dll" "${DEST_PATH}"
|
||||
install -m644 "${SRC_PATH}/bin/OpenRA.Game.dll" "${DEST_PATH}"
|
||||
install -m644 "${SRC_PATH}/bin/OpenRA.Platforms.Default.dll" "${DEST_PATH}"
|
||||
if [ "${COPY_GENERIC_LAUNCHER}" = "True" ]; then
|
||||
install -m755 "${SRC_PATH}/bin/OpenRA.exe" "${DEST_PATH}"
|
||||
install -m755 "${SRC_PATH}/bin/OpenRA.dll" "${DEST_PATH}"
|
||||
fi
|
||||
|
||||
# Mod dlls
|
||||
@@ -97,6 +97,32 @@ install_assemblies_mono() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Compile and publish the core engine and specified mod assemblies to the target directory
|
||||
# Arguments:
|
||||
# SRC_PATH: Path to the root OpenRA directory
|
||||
# DEST_PATH: Path to the root of the install destination (will be created if necessary)
|
||||
# TARGETPLATFORM: Platform type (win-x86, win-x64, osx-x64, linux-x64, unix-generic)
|
||||
# COPY_GENERIC_LAUNCHER: If set to True the OpenRA.exe will also be copied (True, False)
|
||||
# COPY_CNC_DLL: If set to True the OpenRA.Mods.Cnc.dll will also be copied (True, False)
|
||||
# COPY_D2K_DLL: If set to True the OpenRA.Mods.D2k.dll will also be copied (True, False)
|
||||
# Used by:
|
||||
# Windows packaging
|
||||
install_assemblies() {
|
||||
SRC_PATH="${1}"
|
||||
DEST_PATH="${2}"
|
||||
TARGETPLATFORM="${3}"
|
||||
COPY_GENERIC_LAUNCHER="${4}"
|
||||
COPY_CNC_DLL="${5}"
|
||||
COPY_D2K_DLL="${6}"
|
||||
|
||||
ORIG_PWD=$(pwd)
|
||||
cd "${SRC_PATH}" || exit 1
|
||||
|
||||
dotnet publish -c Release -p:TargetPlatform="${TARGETPLATFORM}" -p:PublishTrimmed=true -p:CopyGenericLauncher="${COPY_GENERIC_LAUNCHER}" -p:CopyCncDll="${COPY_CNC_DLL}" -p:CopyD2kDll="${COPY_D2K_DLL}" -r "${TARGETPLATFORM}" -o "${DEST_PATH}"
|
||||
|
||||
cd "${ORIG_PWD}" || exit 1
|
||||
}
|
||||
|
||||
# Copy the core engine and specified mod data to the target directory
|
||||
# Arguments:
|
||||
# SRC_PATH: Path to the root OpenRA directory
|
||||
@@ -115,6 +141,8 @@ install_data() {
|
||||
DEST_PATH="${2}"
|
||||
shift 2
|
||||
|
||||
"${SRC_PATH}"/fetch-geoip.sh
|
||||
|
||||
echo "Installing engine files to ${DEST_PATH}"
|
||||
for FILE in VERSION AUTHORS COPYING IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP "global mix database.dat"; do
|
||||
install -m644 "${SRC_PATH}/${FILE}" "${DEST_PATH}"
|
||||
@@ -160,20 +188,15 @@ install_windows_launcher()
|
||||
MOD_ID="${4}"
|
||||
LAUNCHER_NAME="${5}"
|
||||
MOD_NAME="${6}"
|
||||
ICON_PATH="${7}"
|
||||
FAQ_URL="${8}"
|
||||
FAQ_URL="${7}"
|
||||
|
||||
msbuild -verbosity:m -nologo -t:Clean "${SRC_PATH}/OpenRA.WindowsLauncher/OpenRA.WindowsLauncher.csproj"
|
||||
rm -rf "${SRC_PATH:?}/bin"
|
||||
msbuild -t:Build "${SRC_PATH}/OpenRA.WindowsLauncher/OpenRA.WindowsLauncher.csproj" -restore -p:Configuration=Release -p:TargetPlatform="${TARGETPLATFORM}" -p:LauncherName="${LAUNCHER_NAME}" -p:LauncherIcon="${ICON_PATH}" -p:ModID="${MOD_ID}" -p:DisplayName="${MOD_NAME}" -p:FaqUrl="${FAQ_URL}"
|
||||
install -m755 "${SRC_PATH}/bin/${LAUNCHER_NAME}.exe" "${DEST_PATH}"
|
||||
install -m644 "${SRC_PATH}/bin/${LAUNCHER_NAME}.exe.config" "${DEST_PATH}"
|
||||
rm -rf "${SRC_PATH}/OpenRA.WindowsLauncher/obj"
|
||||
dotnet publish "${SRC_PATH}/OpenRA.WindowsLauncher/OpenRA.WindowsLauncher.csproj" -c Release -r "${TARGETPLATFORM}" -p:LauncherName="${LAUNCHER_NAME}" -p:TargetPlatform="${TARGETPLATFORM}" -p:ModID="${MOD_ID}" -p:DisplayName="${MOD_NAME}" -p:FaqUrl="${FAQ_URL}" -o "${DEST_PATH}"
|
||||
|
||||
# Enable the full 4GB address space for the 32 bit game executable
|
||||
# The server and utility do not use enough memory to need this
|
||||
if [ "${TARGETPLATFORM}" = "win-x86" ]; then
|
||||
python3 "${SRC_PATH}/packaging/windows/MakeLAA.py" "${DEST_PATH}/${LAUNCHER_NAME}.exe"
|
||||
fi
|
||||
# NET 5 is unable to customize the application host for windows when compiling from Linux,
|
||||
# so we must patch the properties we need in the PE header.
|
||||
# Setting the application icon requires an external tool, so is left to the calling code
|
||||
python3 "${SRC_PATH}/packaging/windows/fixlauncher.py" "${DEST_PATH}/${LAUNCHER_NAME}.exe"
|
||||
}
|
||||
|
||||
# Write a version string to the engine VERSION file
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
# OpenRA packaging script for Linux (AppImage)
|
||||
set -e
|
||||
|
||||
command -v make >/dev/null 2>&1 || { echo >&2 "Linux packaging requires make."; exit 1; }
|
||||
command -v tar >/dev/null 2>&1 || { echo >&2 "Linux packaging requires tar."; exit 1; }
|
||||
command -v curl >/dev/null 2>&1 || command -v wget > /dev/null 2>&1 || { echo >&2 "Linux packaging requires curl or wget."; exit 1; }
|
||||
|
||||
DEPENDENCIES_TAG="20200328"
|
||||
DEPENDENCIES_TAG="20201222"
|
||||
|
||||
if [ $# -eq "0" ]; then
|
||||
echo "Usage: $(basename "$0") version [outputdir]"
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
HERE="$(dirname "$(readlink -f "${0}")")"
|
||||
cd "${HERE}/../lib/openra" || exit 1
|
||||
|
||||
mono --debug OpenRA.Server.exe Game.Mod="{MODID}" "$@"
|
||||
mono --debug OpenRA.Server.dll Game.Mod="{MODID}" "$@"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
cd "{GAME_INSTALL_DIR}"
|
||||
|
||||
mono {DEBUG} OpenRA.Server.exe Game.Mod={MODID} "$@"
|
||||
mono {DEBUG} OpenRA.Server.dll Game.Mod={MODID} "$@"
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
# OpenRA.Utility relies on keeping the original working directory, so don't change directory
|
||||
HERE="$(dirname "$(readlink -f "${0}")")"
|
||||
mono --debug "${HERE}/../lib/openra/OpenRA.Utility.exe" {MODID} "$@"
|
||||
mono --debug "${HERE}/../lib/openra/OpenRA.Utility.dll" {MODID} "$@"
|
||||
|
||||
@@ -35,7 +35,7 @@ fi
|
||||
|
||||
# Run the game
|
||||
export SDL_VIDEO_X11_WMCLASS="openra-{MODID}-{TAG}"
|
||||
mono --debug OpenRA.exe Game.Mod={MODID} Engine.LaunchPath="${LAUNCHER}" Engine.LaunchWrapper="${HERE}/restore-environment.sh" "${JOIN_SERVER}" "$@"
|
||||
mono --debug OpenRA.dll Game.Mod={MODID} Engine.LaunchPath="${LAUNCHER}" Engine.LaunchWrapper="${HERE}/restore-environment.sh" "${JOIN_SERVER}" "$@"
|
||||
|
||||
# Show a crash dialog if something went wrong
|
||||
if [ $? != 0 ] && [ $? != 1 ]; then
|
||||
|
||||
@@ -9,7 +9,7 @@ if [ "${1#${PROTOCOL_PREFIX}}" != "${1}" ]; then
|
||||
fi
|
||||
|
||||
# Run the game
|
||||
mono {DEBUG} OpenRA.exe Game.Mod={MODID} Engine.LaunchPath="{BIN_DIR}/openra-{MODID}" "${JOIN_SERVER}" "$@"
|
||||
mono {DEBUG} OpenRA.dll Game.Mod={MODID} Engine.LaunchPath="{BIN_DIR}/openra-{MODID}" "${JOIN_SERVER}" "$@"
|
||||
|
||||
# Show a crash dialog if something went wrong
|
||||
if [ $? != 0 ] && [ $? != 1 ]; then
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>{MOD_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>OpenRA</string>
|
||||
<string>Launcher</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>{MOD_ID}.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
set -e
|
||||
|
||||
MONO_TAG="osx-launcher-20200830"
|
||||
MONO_TAG="osx-launcher-20201222"
|
||||
|
||||
if [ $# -ne "2" ]; then
|
||||
echo "Usage: $(basename "$0") tag outputdir"
|
||||
@@ -55,13 +55,15 @@ modify_plist() {
|
||||
|
||||
# Copies the game files and sets metadata
|
||||
build_app() {
|
||||
TEMPLATE_DIR="${1}"
|
||||
LAUNCHER_DIR="${2}"
|
||||
MOD_ID="${3}"
|
||||
MOD_NAME="${4}"
|
||||
DISCORD_APPID="${5}"
|
||||
PLATFORM="${1}"
|
||||
TEMPLATE_DIR="${2}"
|
||||
LAUNCHER_DIR="${3}"
|
||||
MOD_ID="${4}"
|
||||
MOD_NAME="${5}"
|
||||
DISCORD_APPID="${6}"
|
||||
|
||||
LAUNCHER_CONTENTS_DIR="${LAUNCHER_DIR}/Contents"
|
||||
LAUNCHER_ASSEMBLY_DIR="${LAUNCHER_CONTENTS_DIR}/MacOS"
|
||||
LAUNCHER_RESOURCES_DIR="${LAUNCHER_CONTENTS_DIR}/Resources"
|
||||
|
||||
cp -r "${TEMPLATE_DIR}" "${LAUNCHER_DIR}"
|
||||
@@ -72,7 +74,12 @@ build_app() {
|
||||
fi
|
||||
|
||||
# Install engine and mod files
|
||||
install_assemblies_mono "${SRCDIR}" "${LAUNCHER_RESOURCES_DIR}" "osx-x64" "True" "True" "${IS_D2K}"
|
||||
if [ "${PLATFORM}" = "compat" ]; then
|
||||
install_assemblies_mono "${SRCDIR}" "${LAUNCHER_ASSEMBLY_DIR}" "osx-x64" "True" "True" "${IS_D2K}"
|
||||
else
|
||||
install_assemblies "${SRCDIR}" "${LAUNCHER_ASSEMBLY_DIR}" "osx-x64" "True" "True" "${IS_D2K}"
|
||||
fi
|
||||
|
||||
install_data "${SRCDIR}" "${LAUNCHER_RESOURCES_DIR}" "${MOD_ID}"
|
||||
set_engine_version "${TAG}" "${LAUNCHER_RESOURCES_DIR}"
|
||||
set_mod_version "${TAG}" "${LAUNCHER_RESOURCES_DIR}/mods/${MOD_ID}/mod.yaml" "${LAUNCHER_RESOURCES_DIR}/mods/modcontent/mod.yaml"
|
||||
@@ -99,7 +106,6 @@ build_app() {
|
||||
|
||||
# Sign binaries with developer certificate
|
||||
if [ -n "${MACOS_DEVELOPER_IDENTITY}" ]; then
|
||||
codesign -s "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements entitlements.plist "${LAUNCHER_RESOURCES_DIR}/"*.dylib
|
||||
codesign -s "${MACOS_DEVELOPER_IDENTITY}" --timestamp --options runtime -f --entitlements entitlements.plist --deep "${LAUNCHER_DIR}"
|
||||
fi
|
||||
}
|
||||
@@ -120,23 +126,15 @@ build_platform() {
|
||||
|
||||
if [ "${PLATFORM}" = "compat" ]; then
|
||||
modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.9" "${TEMPLATE_DIR}/Contents/Info.plist"
|
||||
clang -m64 launcher-mono.m -o "${TEMPLATE_DIR}/Contents/MacOS/OpenRA" -framework AppKit -mmacosx-version-min=10.9
|
||||
clang -m64 launcher-mono.m -o "${TEMPLATE_DIR}/Contents/MacOS/Launcher" -framework AppKit -mmacosx-version-min=10.9
|
||||
else
|
||||
modify_plist "{MINIMUM_SYSTEM_VERSION}" "10.13" "${TEMPLATE_DIR}/Contents/Info.plist"
|
||||
clang -m64 launcher.m -o "${TEMPLATE_DIR}/Contents/MacOS/OpenRA" -framework AppKit -mmacosx-version-min=10.13
|
||||
|
||||
curl -s -L -O https://github.com/OpenRA/OpenRALauncherOSX/releases/download/${MONO_TAG}/mono.zip || exit 3
|
||||
unzip -qq -d "${BUILTDIR}/mono" mono.zip
|
||||
mv "${BUILTDIR}/mono/mono" "${TEMPLATE_DIR}/Contents/MacOS/"
|
||||
mv "${BUILTDIR}/mono/etc" "${TEMPLATE_DIR}/Contents/Resources"
|
||||
mv "${BUILTDIR}/mono/lib" "${TEMPLATE_DIR}/Contents/Resources"
|
||||
rm mono.zip
|
||||
rmdir "${BUILTDIR}/mono"
|
||||
clang -m64 launcher.m -o "${TEMPLATE_DIR}/Contents/MacOS/Launcher" -framework AppKit -mmacosx-version-min=10.13
|
||||
fi
|
||||
|
||||
build_app "${TEMPLATE_DIR}" "${BUILTDIR}/OpenRA - Red Alert.app" "ra" "Red Alert" "699222659766026240"
|
||||
build_app "${TEMPLATE_DIR}" "${BUILTDIR}/OpenRA - Tiberian Dawn.app" "cnc" "Tiberian Dawn" "699223250181292033"
|
||||
build_app "${TEMPLATE_DIR}" "${BUILTDIR}/OpenRA - Dune 2000.app" "d2k" "Dune 2000" "712711732770111550"
|
||||
build_app "${PLATFORM}" "${TEMPLATE_DIR}" "${BUILTDIR}/OpenRA - Red Alert.app" "ra" "Red Alert" "699222659766026240"
|
||||
build_app "${PLATFORM}" "${TEMPLATE_DIR}" "${BUILTDIR}/OpenRA - Tiberian Dawn.app" "cnc" "Tiberian Dawn" "699223250181292033"
|
||||
build_app "${PLATFORM}" "${TEMPLATE_DIR}" "${BUILTDIR}/OpenRA - Dune 2000.app" "d2k" "Dune 2000" "712711732770111550"
|
||||
|
||||
rm -rf "${TEMPLATE_DIR}"
|
||||
|
||||
@@ -183,6 +181,25 @@ build_platform() {
|
||||
SetFile -c icnC "/Volumes/OpenRA/.VolumeIcon.icns"
|
||||
SetFile -a C "/Volumes/OpenRA"
|
||||
|
||||
# Replace duplicate .NET runtime files with hard links to improve compression
|
||||
if [ "${PLATFORM}" != "compat" ]; then
|
||||
OIFS="$IFS"
|
||||
IFS=$'\n'
|
||||
for MOD in "Red Alert" "Tiberian Dawn"; do
|
||||
for f in $(find /Volumes/OpenRA/OpenRA\ -\ ${MOD}.app/Contents/MacOS/*); do
|
||||
g="/Volumes/OpenRA/OpenRA - Dune 2000.app/Contents/MacOS/"$(basename "${f}")
|
||||
hashf=$(shasum "${f}" | awk '{ print $1 }')
|
||||
hashg=$(shasum "${g}" | awk '{ print $1 }')
|
||||
if [ "${hashf}" = "${hashg}" ]; then
|
||||
echo "Deduplicating ${f}"
|
||||
rm "${f}"
|
||||
ln "${g}" "${f}"
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS="$OIFS"
|
||||
fi
|
||||
|
||||
chmod -Rf go-w /Volumes/OpenRA
|
||||
sync
|
||||
sync
|
||||
@@ -200,7 +217,7 @@ notarize_package() {
|
||||
sudo xcode-select -r
|
||||
|
||||
# Create a temporary read-only dmg for submission (notarization service rejects read/write images)
|
||||
hdiutil convert "${DMG_PATH}" -format UDZO -imagekey zlib-level=9 -ov -o "${NOTARIZE_DMG_PATH}"
|
||||
hdiutil convert "${DMG_PATH}" -format ULFO -ov -o "${NOTARIZE_DMG_PATH}"
|
||||
|
||||
NOTARIZATION_UUID=$(xcrun altool --notarize-app --primary-bundle-id "net.openra.packaging" -u "${MACOS_DEVELOPER_USERNAME}" -p "${MACOS_DEVELOPER_PASSWORD}" --file "${NOTARIZE_DMG_PATH}" 2>&1 | awk -F' = ' '/RequestUUID/ { print $2; exit }')
|
||||
if [ -z "${NOTARIZATION_UUID}" ]; then
|
||||
@@ -242,10 +259,17 @@ notarize_package() {
|
||||
}
|
||||
|
||||
finalize_package() {
|
||||
INPUT_PATH="${1}"
|
||||
OUTPUT_PATH="${2}"
|
||||
PLATFORM="${1}"
|
||||
INPUT_PATH="${2}"
|
||||
OUTPUT_PATH="${3}"
|
||||
|
||||
if [ "${PLATFORM}" = "compat" ]; then
|
||||
hdiutil convert "${INPUT_PATH}" -format UDZO -imagekey zlib-level=9 -ov -o "${OUTPUT_PATH}"
|
||||
else
|
||||
# ULFO offers better compression and faster decompression speeds, but is only supported by 10.11+
|
||||
hdiutil convert "${INPUT_PATH}" -format ULFO -ov -o "${OUTPUT_PATH}"
|
||||
fi
|
||||
|
||||
hdiutil convert "${INPUT_PATH}" -format UDZO -imagekey zlib-level=9 -ov -o "${OUTPUT_PATH}"
|
||||
rm "${INPUT_PATH}"
|
||||
}
|
||||
|
||||
@@ -258,8 +282,8 @@ fi
|
||||
|
||||
if [ -n "${MACOS_DEVELOPER_USERNAME}" ] && [ -n "${MACOS_DEVELOPER_PASSWORD}" ]; then
|
||||
# Parallelize processing
|
||||
(notarize_package "build.dmg") &
|
||||
(notarize_package "build-compat.dmg") &
|
||||
(notarize_package "standard" "build.dmg") &
|
||||
(notarize_package "compat" "build-compat.dmg") &
|
||||
wait
|
||||
fi
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ static int check_mono_version(const char *version, const char *req_version)
|
||||
[self exitWithMonoPrompt];
|
||||
|
||||
// Default values - can be overriden by setting certain keys Info.plist
|
||||
NSString *gameName = @"OpenRA.exe";
|
||||
NSString *gameName = @"OpenRA.dll";
|
||||
NSString *modId = nil;
|
||||
|
||||
NSDictionary *plist = [[NSBundle mainBundle] infoDictionary];
|
||||
@@ -262,8 +262,9 @@ static int check_mono_version(const char *version, const char *req_version)
|
||||
|
||||
NSMutableArray *launchArgs = [NSMutableArray arrayWithCapacity: [gameArgs count] + 2];
|
||||
[launchArgs addObject: @"--debug"];
|
||||
[launchArgs addObject: [gamePath stringByAppendingPathComponent: gameName]];
|
||||
[launchArgs addObject: [exePath stringByAppendingPathComponent: gameName]];
|
||||
[launchArgs addObject: [NSString stringWithFormat:@"Engine.LaunchPath=\"%@\"", engineLaunchPath]];
|
||||
[launchArgs addObject: [NSString stringWithFormat:@"Engine.EngineDir=../Resources"]];
|
||||
|
||||
if (modId)
|
||||
[launchArgs addObject: [NSString stringWithFormat:@"Game.Mod=%@", modId]];
|
||||
|
||||
@@ -131,16 +131,11 @@ NSTask *gameTask;
|
||||
launched = YES;
|
||||
|
||||
// Default values - can be overriden by setting certain keys Info.plist
|
||||
NSString *gameName = @"OpenRA.exe";
|
||||
NSString *modId = nil;
|
||||
|
||||
NSDictionary *plist = [[NSBundle mainBundle] infoDictionary];
|
||||
if (plist)
|
||||
{
|
||||
NSString *exeValue = [plist objectForKey:@"MonoGameExe"];
|
||||
if (exeValue && [exeValue length] > 0)
|
||||
gameName = exeValue;
|
||||
|
||||
NSString *modIdValue = [plist objectForKey:@"ModId"];
|
||||
if (modIdValue && [modIdValue length] > 0)
|
||||
modId = modIdValue;
|
||||
@@ -149,21 +144,20 @@ NSTask *gameTask;
|
||||
NSString *exePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"Contents/MacOS/"];
|
||||
NSString *gamePath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: @"Contents/Resources/"];
|
||||
|
||||
NSString *launchPath = [exePath stringByAppendingPathComponent: @"mono"];
|
||||
NSString *appPath = [exePath stringByAppendingPathComponent: @"OpenRA"];
|
||||
NSString *launchPath = [exePath stringByAppendingPathComponent: @"OpenRA"];
|
||||
NSString *appPath = [exePath stringByAppendingPathComponent: @"Launcher"];
|
||||
NSString *engineLaunchPath = [self resolveTranslocatedPath: appPath];
|
||||
|
||||
NSMutableArray *launchArgs = [NSMutableArray arrayWithCapacity: [gameArgs count] + 2];
|
||||
[launchArgs addObject: @"--debug"];
|
||||
[launchArgs addObject: [gamePath stringByAppendingPathComponent: gameName]];
|
||||
[launchArgs addObject: [NSString stringWithFormat:@"Engine.LaunchPath=\"%@\"", engineLaunchPath]];
|
||||
[launchArgs addObject: [NSString stringWithFormat:@"Engine.EngineDir=../Resources"]];
|
||||
|
||||
if (modId)
|
||||
[launchArgs addObject: [NSString stringWithFormat:@"Game.Mod=%@", modId]];
|
||||
|
||||
[launchArgs addObjectsFromArray: gameArgs];
|
||||
|
||||
NSLog(@"Running mono with arguments:");
|
||||
NSLog(@"Running OpenRA with arguments:");
|
||||
for (size_t i = 0; i < [launchArgs count]; i++)
|
||||
NSLog(@"%@", [launchArgs objectAtIndex: i]);
|
||||
|
||||
@@ -172,12 +166,6 @@ NSTask *gameTask;
|
||||
[gameTask setLaunchPath: launchPath];
|
||||
[gameTask setArguments: launchArgs];
|
||||
|
||||
NSMutableDictionary *environment = [NSMutableDictionary dictionaryWithDictionary: [[NSProcessInfo processInfo] environment]];
|
||||
[environment setObject: [gamePath stringByAppendingPathComponent: @"lib/mono/4.5"] forKey: @"MONO_PATH"];
|
||||
[environment setObject: [gamePath stringByAppendingPathComponent: @"etc"] forKey: @"MONO_CFG_DIR"];
|
||||
[environment setObject: [gamePath stringByAppendingPathComponent: @"etc/mono/config"] forKey: @"MONO_CONFIG"];
|
||||
[gameTask setEnvironment: environment];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver: self
|
||||
selector: @selector(taskExited:)
|
||||
|
||||
@@ -129,14 +129,16 @@ Section "Game" GAME
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
File "${SRCDIR}\*.exe"
|
||||
File "${SRCDIR}\*.exe.config"
|
||||
File "${SRCDIR}\*.dll.config"
|
||||
File "${SRCDIR}\*.dll"
|
||||
File "${SRCDIR}\*.ico"
|
||||
File "${SRCDIR}\*.deps.json"
|
||||
File "${SRCDIR}\*.runtimeconfig.json"
|
||||
File "${SRCDIR}\global mix database.dat"
|
||||
File "${SRCDIR}\IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP"
|
||||
File "${SRCDIR}\VERSION"
|
||||
File "${SRCDIR}\AUTHORS"
|
||||
File "${SRCDIR}\COPYING"
|
||||
File "${SRCDIR}\global mix database.dat"
|
||||
File "${SRCDIR}\IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP"
|
||||
|
||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
||||
CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
|
||||
@@ -162,6 +164,7 @@ Section "Game" GAME
|
||||
|
||||
SetShellVarContext all
|
||||
CreateDirectory "$APPDATA\OpenRA\ModMetadata"
|
||||
SetOutPath "$INSTDIR"
|
||||
nsExec::ExecToLog '"$INSTDIR\OpenRA.Utility.exe" ra --register-mod "$INSTDIR\RedAlert.exe" system'
|
||||
nsExec::ExecToLog '"$INSTDIR\OpenRA.Utility.exe" ra --clear-invalid-mod-registrations system'
|
||||
nsExec::ExecToLog '"$INSTDIR\OpenRA.Utility.exe" cnc --register-mod "$INSTDIR\TiberianDawn.exe" system'
|
||||
@@ -182,21 +185,6 @@ Section "Desktop Shortcut" DESKTOPSHORTCUT
|
||||
"$INSTDIR\Dune2000.exe" "" "" "" ""
|
||||
SectionEnd
|
||||
|
||||
;***************************
|
||||
;Dependency Sections
|
||||
;***************************
|
||||
Section "-DotNet" DotNet
|
||||
ClearErrors
|
||||
; https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
|
||||
ReadRegDWORD $0 HKLM "SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" "Release"
|
||||
IfErrors error 0
|
||||
IntCmp $0 461808 done error done
|
||||
error:
|
||||
MessageBox MB_OK ".NET Framework v4.7.2 or later is required to run OpenRA."
|
||||
Abort
|
||||
done:
|
||||
SectionEnd
|
||||
|
||||
;***************************
|
||||
;Uninstaller Sections
|
||||
;***************************
|
||||
@@ -225,14 +213,17 @@ Function ${UN}Clean
|
||||
RMDir /r $INSTDIR\glsl
|
||||
RMDir /r $INSTDIR\lua
|
||||
Delete $INSTDIR\*.exe
|
||||
Delete $INSTDIR\*.exe.config
|
||||
Delete $INSTDIR\*.dll
|
||||
Delete $INSTDIR\*.ico
|
||||
Delete $INSTDIR\*.dll.config
|
||||
Delete $INSTDIR\*.deps.json
|
||||
Delete $INSTDIR\*.runtimeconfig.json
|
||||
Delete $INSTDIR\VERSION
|
||||
Delete $INSTDIR\AUTHORS
|
||||
Delete $INSTDIR\COPYING
|
||||
Delete "$INSTDIR\global mix database.dat"
|
||||
Delete $INSTDIR\IP2LOCATION-LITE-DB1.IPV6.BIN.ZIP
|
||||
|
||||
RMDir /r $INSTDIR\Support
|
||||
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenRA${SUFFIX}"
|
||||
|
||||
@@ -32,6 +32,12 @@ elif [[ ${TAG} == playtest* ]]; then
|
||||
SUFFIX=" (playtest)"
|
||||
fi
|
||||
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -s -L -O https://github.com/electron/rcedit/releases/download/v1.1.1/rcedit-x64.exe || exit 3
|
||||
else
|
||||
wget -cq https://github.com/electron/rcedit/releases/download/v1.1.1/rcedit-x64.exe || exit 3
|
||||
fi
|
||||
|
||||
function makelauncher()
|
||||
{
|
||||
LAUNCHER_NAME="${1}"
|
||||
@@ -40,7 +46,9 @@ function makelauncher()
|
||||
PLATFORM="${4}"
|
||||
|
||||
convert "${ARTWORK_DIR}/${MOD_ID}_16x16.png" "${ARTWORK_DIR}/${MOD_ID}_24x24.png" "${ARTWORK_DIR}/${MOD_ID}_32x32.png" "${ARTWORK_DIR}/${MOD_ID}_48x48.png" "${ARTWORK_DIR}/${MOD_ID}_256x256.png" "${BUILTDIR}/${MOD_ID}.ico"
|
||||
install_windows_launcher "${SRCDIR}" "${BUILTDIR}" "win-${PLATFORM}" "${MOD_ID}" "${LAUNCHER_NAME}" "${DISPLAY_NAME}" "${BUILTDIR}/${MOD_ID}.ico" "${FAQ_URL}"
|
||||
install_windows_launcher "${SRCDIR}" "${BUILTDIR}" "win-${PLATFORM}" "${MOD_ID}" "${LAUNCHER_NAME}" "${DISPLAY_NAME}" "${FAQ_URL}"
|
||||
|
||||
wine64 rcedit-x64.exe "${BUILTDIR}/${LAUNCHER_NAME}.exe" --set-icon "${BUILTDIR}/${MOD_ID}.ico"
|
||||
}
|
||||
|
||||
function build_platform()
|
||||
@@ -54,7 +62,7 @@ function build_platform()
|
||||
USE_PROGRAMFILES32=""
|
||||
fi
|
||||
|
||||
install_assemblies_mono "${SRCDIR}" "${BUILTDIR}" "win-${PLATFORM}" "False" "True" "True"
|
||||
install_assemblies "${SRCDIR}" "${BUILTDIR}" "win-${PLATFORM}" "False" "True" "True"
|
||||
install_data "${SRCDIR}" "${BUILTDIR}" "cnc" "d2k" "ra"
|
||||
set_engine_version "${TAG}" "${BUILTDIR}"
|
||||
set_mod_version "${TAG}" "${BUILTDIR}/mods/cnc/mod.yaml" "${BUILTDIR}/mods/d2k/mod.yaml" "${BUILTDIR}/mods/ra/mod.yaml" "${BUILTDIR}/mods/modcontent/mod.yaml"
|
||||
|
||||
@@ -9,11 +9,21 @@ import struct
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(sys.argv[1] + ': Enabling /LARGEADDRESSAWARE')
|
||||
print('Patching ' + sys.argv[1] + ':')
|
||||
with open(sys.argv[1], 'r+b') as assembly:
|
||||
assembly.seek(0x3c)
|
||||
peOffset = struct.unpack('i', assembly.read(4))[0]
|
||||
peOffset = struct.unpack('H', assembly.read(2))[0]
|
||||
|
||||
assembly.seek(peOffset)
|
||||
peSignature = struct.unpack('I', assembly.read(4))[0]
|
||||
if peSignature != 0x4550:
|
||||
print(" ERROR: Invalid PE signature")
|
||||
|
||||
print(' - Setting /LARGEADDRESSAWARE')
|
||||
assembly.seek(peOffset + 4 + 18)
|
||||
flags = struct.unpack('B', assembly.read(1))[0] | 0x20
|
||||
assembly.seek(peOffset + 4 + 18)
|
||||
assembly.write(struct.pack('B', flags))
|
||||
print(' - Setting /subsystem:windows')
|
||||
assembly.seek(peOffset + 0x5C)
|
||||
assembly.write(struct.pack("H", 0x02))
|
||||
@@ -1,2 +1,2 @@
|
||||
#!/bin/sh
|
||||
ENGINE_DIR=.. mono --debug bin/OpenRA.Utility.exe $@
|
||||
ENGINE_DIR=.. mono --debug bin/OpenRA.Utility.dll $@
|
||||
|
||||
Reference in New Issue
Block a user