Merge pull request #8799 from Mailaender/differentiate-ts-mixes

Added support to specify the package/folder in the virtual file system for Tiberian Sun Cabal/EVA voices and Nod/GDI icons
This commit is contained in:
Pavel Penev
2015-08-02 18:39:30 +03:00
12 changed files with 339 additions and 44 deletions

View File

@@ -185,10 +185,23 @@ namespace OpenRA.FileSystem
return s;
}
public static bool TryOpen(string filename, out Stream s)
public static bool TryOpen(string name, out Stream s)
{
// Check the cache for a quick lookup
if (filename.IndexOfAny(new char[] { '/', '\\' }) == -1)
var filename = name;
var foldername = string.Empty;
// Used for faction specific packages; rule out false positive on Windows C:\ drive notation
var explicitFolder = name.Contains(':') && !Directory.Exists(Path.GetDirectoryName(name));
if (explicitFolder)
{
var divide = name.Split(':');
foldername = divide.First();
filename = divide.Last();
}
// Check the cache for a quick lookup if the folder name is unknown
// TODO: This disables caching for explicit folder requests
if (filename.IndexOfAny(new char[] { '/', '\\' }) == -1 && !explicitFolder)
{
s = GetFromCache(PackageHashType.Classic, filename);
if (s != null)
@@ -200,9 +213,11 @@ namespace OpenRA.FileSystem
}
// Ask each package individually
var folder = MountedFolders
.Where(x => x.Exists(filename))
.MaxByOrDefault(x => x.Priority);
IFolder folder;
if (explicitFolder && !string.IsNullOrEmpty(foldername))
folder = MountedFolders.Where(x => x.Name == foldername).MaxByOrDefault(x => x.Priority);
else
folder = MountedFolders.Where(x => x.Exists(filename)).MaxByOrDefault(x => x.Priority);
if (folder != null)
{
@@ -214,7 +229,19 @@ namespace OpenRA.FileSystem
return false;
}
public static bool Exists(string filename) { return MountedFolders.Any(f => f.Exists(filename)); }
public static bool Exists(string name)
{
var explicitFolder = name.Contains(':') && !Directory.Exists(Path.GetDirectoryName(name));
if (explicitFolder)
{
var divide = name.Split(':');
var foldername = divide.First();
var filename = divide.Last();
return MountedFolders.Where(n => n.Name == foldername).Any(f => f.Exists(filename));
}
else
return MountedFolders.Any(f => f.Exists(name));
}
static Dictionary<string, Assembly> assemblyCache = new Dictionary<string, Assembly>();

View File

@@ -156,7 +156,7 @@ namespace OpenRA
if (index >= actors.Count || actors[index].ActorID != actor)
return default(T);
else if (index + 1 < actors.Count && actors[index + 1].ActorID == actor)
throw new InvalidOperationException("Actor has multiple traits of type `{0}`".F(typeof(T)));
throw new InvalidOperationException("Actor {0} has multiple traits of type `{1}`".F(actors[index].Info.Name, typeof(T)));
else return traits[index];
}

View File

@@ -1,4 +1,7 @@
Speech:
Prefixes:
gdi: speech01.mix:
nod: speech02.mix:
Notifications:
AirUnitLost: 00-i074
AirstrikeReady: 00-n160

View File

@@ -45,9 +45,8 @@ Packages:
sno.mix:CRC32
snow.mix:CRC32
sounds.mix:CRC32
# TODO: differentiate between:
speech01.mix:CRC32 # EVA
# speech02.mix:CRC32 # Cabal
speech02.mix:CRC32 # Cabal
tem.mix:CRC32
temperat.mix:CRC32
# Firestorm

View File

@@ -28,6 +28,11 @@ E1:
AttackSequence: shoot
ProducibleWithLevel:
Prerequisites: barracks.upgraded
RenderSprites:
Image: e1.gdi
RaceImages:
gdi: e1.gdi
nod: e1.nod
ENGINEER:
Inherits: ^Soldier
@@ -54,4 +59,9 @@ ENGINEER:
CaptureTypes: building
-AutoTarget:
-GainsExperience:
RenderSprites:
Image: engineer.gdi
RaceImages:
gdi: engineer.gdi
nod: engineer.nod

View File

@@ -97,6 +97,11 @@ PROC:
ProvidesPrerequisite@buildingname:
SelectionDecorations:
VisualBounds: 134, 122, 0, -18
RenderBuilding:
Image: proc.gdi
RaceImages:
gdi: proc.gdi
nod: proc.nod
GASILO:
Inherits: ^Building
@@ -123,6 +128,10 @@ GASILO:
Range: 4c0
-RenderBuilding:
RenderBuildingSilo:
Image: gasilo.gdi
RaceImages:
gdi: gasilo.gdi
nod: gasilo.nod
WithIdleOverlay@UNDERLAY:
Sequence: idle-underlay
WithIdleOverlay@LIGHTS:

View File

@@ -79,4 +79,9 @@ NAPULS:
Amount: -150
SelectionDecorations:
VisualBounds: 78, 54, 0, -12
RenderBuilding:
Image: napuls.gdi
RaceImages:
gdi: napuls.gdi
nod: napuls.nod

View File

@@ -32,6 +32,11 @@ MCV:
Voice: Move
SelectionDecorations:
VisualBounds: 42,42
RenderSprites:
Image: mcv.gdi
RaceImages:
gdi: mcv.gdi
nod: mcv.nod
HARV:
Inherits: ^VoxelTank
@@ -87,6 +92,11 @@ HARV:
Palette: effect
SelectionDecorations:
VisualBounds: 36,36
RenderSprites:
Image: harv.gdi
RaceImages:
gdi: harv.gdi
nod: harv.nod
LPST:
Inherits: ^VoxelVehicle
@@ -114,6 +124,11 @@ LPST:
TransformSounds:
NoTransformSounds:
Voice: Move
RenderSprites:
Image: lpst.gdi
RaceImages:
gdi: lpst.gdi
nod: lpst.nod
GGHUNT:
Inherits: ^Vehicle

View File

@@ -1,5 +1,5 @@
e1:
Defaults:
e1.gdi:
Defaults: e1
Tick: 80
stand:
Facings: 8
@@ -66,7 +66,77 @@ e1:
ShadowStart: 190
die6: electro
Length: *
icon: e1icon
icon: sidec01.mix:e1icon
e1.nod:
Defaults: e1
Tick: 80
stand:
Facings: 8
ShadowStart: 292
run:
Start: 8
Length: 6
Facings: 8
ShadowStart: 300
idle1:
Start: 56
Length: 15
ShadowStart: 348
idle2:
Start: 71
Length: 15
ShadowStart: 363
prone-run:
Start: 86
Length: 6
Facings: 8
ShadowStart: 378
prone-stand:
Start: 86
Facings: 8
Stride: 6
ShadowStart: 378
die1:
Start: 134
Length: 15
ShadowStart: 426
die2:
Start: 149
Length: 15
ShadowStart: 441
die3: infdie
Length: *
die4: s_bang34
Length: *
die-crushed:
Start: 159
Length: 5
ShadowStart: 451
Tick: 800
ZOffset: -511
shoot:
Start: 164
Length: 6
Facings: 8
ShadowStart: 456
prone-shoot:
Start: 212
Length: 6
Facings: 8
ShadowStart: 504
standup-0:
Start: 260
Length: 2
Facings: 8
ShadowStart: 552
die5: flameguy # TODO: walking animation unused
Start: 42
Length: 104
ShadowStart: 190
die6: electro
Length: *
icon: sidec02.mix:e1icon
e2:
Defaults:
@@ -347,8 +417,8 @@ medic:
Length: *
icon: mediicon
engineer:
Defaults:
engineer.gdi:
Defaults: engineer
Tick: 80
stand:
Facings: 8
@@ -407,7 +477,69 @@ engineer:
ShadowStart: 190
die6: electro
Length: *
icon: engnicon
icon: sidec01.mix:engnicon
engineer.nod:
Defaults: engineer
Tick: 80
stand:
Facings: 8
ShadowStart: 292
run:
Start: 8
Length: 6
Facings: 8
ShadowStart: 300
idle1:
Start: 56
Length: 15
ShadowStart: 348
idle2:
Start: 71
Length: 15
ShadowStart: 363
prone-run:
Start: 86
Length: 6
Facings: 8
ShadowStart: 378
prone-stand:
Start: 86
Facings: 8
Stride: 6
ShadowStart: 378
die1:
Start: 134
Length: 15
ShadowStart: 426
die2:
Start: 149
Length: 15
ShadowStart: 441
die3: # TODO: copy-paste of die2
Start: 149
Length: 15
ShadowStart: 441
die4: s_bang34
Length: *
die-crushed:
Start: 159
Length: 5
ShadowStart: 451
Tick: 800
ZOffset: -511
standup-0:
Start: 260
Length: 2
Facings: 8
ShadowStart: 552
die5: flameguy # TODO: walking animation unused
Start: 42
Length: 104
ShadowStart: 190
die6: electro
Length: *
icon: sidec02.mix:engnicon
umagon:
Defaults:

View File

@@ -443,10 +443,6 @@ dbris9sm:
idle:
Length:*
dbris10sm:
idle:
Length:*
dbris1lg:
idle:
Length:*
@@ -482,7 +478,3 @@ dbris8lg:
dbris9lg:
idle:
Length:*
dbris10lg:
idle:
Length:*

View File

@@ -665,8 +665,8 @@ nasam:
Offset: 0, 0
UseTilesetCode: false
napuls:
Defaults:
napuls.gdi:
Defaults: ntpuls
Offset: 0, -24
UseTilesetCode: true
idle:
@@ -678,12 +678,34 @@ napuls:
Start: 2
ShadowStart: 5
Tick: 400
turret: ntpuls_a
turret:_a
Facings: 32
make: ntpulsmk
make:mk
Length: 20
ShadowStart: 20
icon: empicon
icon: sidec01.mix:empicon
Offset: 0, 0
UseTilesetCode: false
napuls.nod:
Defaults: ntpuls
Offset: 0, -24
UseTilesetCode: true
idle:
ShadowStart: 3
damaged-idle:
Start: 1
ShadowStart: 4
dead:
Start: 2
ShadowStart: 5
Tick: 400
turret:_a
Facings: 32
make:mk
Length: 20
ShadowStart: 20
icon: sidec02.mix:empicon
Offset: 0, 0
UseTilesetCode: false
@@ -871,16 +893,17 @@ nahpad:
Offset: 0, 0
UseTilesetCode: false
proc: # TODO: unused narefn_a
Defaults:
# TODO: unused narefn_a
proc.gdi:
Defaults: ntrefn
Offset: -12, -42
UseTilesetCode: true
idle: ntrefn
idle:
ShadowStart: 3
damaged-idle: ntrefn
damaged-idle:
Start: 1
ShadowStart: 4
dead: ntrefn
dead:
Start: 2
ShadowStart: 5
Tick: 400
@@ -900,12 +923,46 @@ proc: # TODO: unused narefn_a
damaged-bib: ntrefnbb
Start: 1
ZOffset: -1024
icon: reficon
icon: sidec01.mix:reficon
Offset: 0, 0
UseTilesetCode: false
gasilo:
Defaults:
# TODO: unused narefn_a
proc.nod:
Defaults: ntrefn
Offset: -12, -42
UseTilesetCode: true
idle:
ShadowStart: 3
damaged-idle:
Start: 1
ShadowStart: 4
dead:
Start: 2
ShadowStart: 5
Tick: 400
make: ntrefnmk
Length: 20
ShadowStart: 20
flame: ntrefn_b
Length: *
idle-redlights: ntrefn_c
Length: 16
Tick: 120
damaged-idle-redlights: ntrefn_c
Length: 16
Tick: 120
bib: ntrefnbb
ZOffset: -1024
damaged-bib: ntrefnbb
Start: 1
ZOffset: -1024
icon: sidec02.mix:reficon
Offset: 0, 0
UseTilesetCode: false
gasilo.gdi:
Defaults: gtsilo
Offset: 0, -24
UseTilesetCode: true
idle: gtsilo_a
@@ -935,7 +992,42 @@ gasilo:
make: gtsilomk
Length: 18
ShadowStart: 20
icon: siloicon
icon: sidec01.mix:siloicon
Offset: 0, 0
UseTilesetCode: false
gasilo.nod:
Defaults: gtsilo
Offset: 0, -24
UseTilesetCode: true
idle: gtsilo_a
Length: 4
damaged-idle: gtsilo_a
Start: 4
Length: 4
idle-underlay:
ShadowStart: 3
ZOffset: -512
damaged-idle-underlay:
Start: 1
ShadowStart: 4
ZOffset: -512
dead:
Start: 2
ShadowStart: 5
ZOffset: -512
Tick: 400
idle-lights: gtsilo_b
Length: 16
Tick: 120
damaged-idle-lights: gtsilo_b
Start: 16
Length: 16
Tick: 120
make: gtsilomk
Length: 18
ShadowStart: 20
icon: sidec02.mix:siloicon
Offset: 0, 0
UseTilesetCode: false

View File

@@ -1,13 +1,21 @@
mcv:
icon: mcvicon
mcv.gdi:
icon: sidec01.mix:mcvicon
mcv.nod:
icon: sidec02.mix:mcvicon
apc:
icon: apcicon
harv:
icon: harvicon
harv.gdi:
harvest: harvestr
Length: *
icon: sidec01.mix:harvicon
harv.nod:
harvest: harvestr
Length: *
icon: sidec02.mix:harvicon
hvr:
icon: hovricon
@@ -16,8 +24,11 @@ hvr:
muzzle: gunfire
Length: *
lpst:
icon: lpsticon
lpst.gdi:
icon: sidec01.mix:lpsticon
lpst.nod:
icon: sidec02.mix:lpsticon
repair:
icon: rboticon