/// <summary> /// Opens a file /// </summary> /// <param name="path">The path</param> /// <param name="flags">The flags</param> /// <returns>The file descriptor ID</returns> public static int Open(string path, int flags) { if (path.Length == 0) { return(-(int)ErrorCode.EINVAL); } Node node = null; // Check if O_CREATE if ((flags & 0x0200) > 0) { node = VFS.GetOffsetNodeByPath(path, 1); node = VFS.Create(node, "test"); if (node == null) { return(-(int)ErrorCode.ENOENT); } } else { node = VFS.GetByPath(path); if (node == null) { return(-(int)ErrorCode.ENOENT); } VFS.Open(node, flags); } FileDescriptors descriptors = Tasking.CurrentTask.FileDescriptors; return(descriptors.AddNode(node)); }
/// <summary> /// Starts a new process based on the given path and arguments /// </summary> /// <param name="path">The path</param> /// <param name="argv">The arguments</param> /// <param name="flags">Spawn flags</param> /// <returns>Errorcode or PID</returns> public static int StartProcess(string path, string[] argv, Task.SpawnFlags flags) { if (argv == null) { Panic.DoPanic("argv == null"); } Node node = VFS.GetByAbsolutePath(path); if (node == null) { return(-(int)ErrorCode.ENOENT); } // Open and create buffer VFS.Open(node, (int)FileMode.O_RDONLY); byte[] buffer = new byte[node.Size]; if (buffer == null) { Heap.Free(node); VFS.Close(node); return(-(int)ErrorCode.ENOMEM); } // Fill buffer contents VFS.Read(node, 0, node.Size, buffer); VFS.Close(node); // Pass execution to ELF loader int status = ELFLoader.Execute(buffer, node.Size, argv, flags); Heap.Free(buffer); Heap.Free(node); return(status); }
/// <summary> /// Gets a custom palette from collection. If custom palette is not found, creates one, adds it to the collection and returns it. /// Search is done by comparing names of the palettes. /// </summary> /// <param name="paletteName">Name of the palette to find, without theater or .pal extension.</param> /// <returns>The correct custom palette.</returns> public Palette GetCustomPalette(string paletteName) { string fileName; // Starkku: Necessary to distinguish between object and theater/animation palettes when recalculating values. bool objectPalette = false; if (paletteName.ToLower().EndsWith(".pal")) // full name already given { fileName = paletteName; } else { // filename = <paletteName><theaterExtension>.pal (e.g. lib<tem/sno/urb>.pal) fileName = paletteName + ModConfig.ActiveTheater.Extension.Substring(1) + ".pal"; objectPalette = true; } var pal = CustomPalettes.FirstOrDefault(p => p.Name == paletteName); if (pal == null) { // palette hasn't been loaded yet // Starkku: If the original does not exist, it means the file it should use does not exist. It now returns a null in this case, which is // handled appropriately wherever this method is called to fall back to the default palette for that type of object. PalFile orig = VFS.Open <PalFile>(fileName); if (orig == null) { return(null); } pal = new Palette(VFS.Open <PalFile>(fileName), paletteName, objectPalette); CustomPalettes.Add(pal); } return(pal); }
public bool LoadInis() { if (Engine == EngineType.YurisRevenge) { _rules = VFS.Open <IniFile>("rulesmd.ini"); _art = VFS.Open <IniFile>("artmd.ini"); } else if (Engine == EngineType.Firestorm) { _rules = VFS.Open <IniFile>("rules.ini"); _art = VFS.Open <IniFile>("art.ini"); Logger.Info("Merging Firestorm rules with TS rules"); _rules.MergeWith(VFS.Open <IniFile>("firestrm.ini")); _art.MergeWith(VFS.Open <IniFile>("artfs.ini")); } else { _rules = VFS.Open <IniFile>("rules.ini"); _art = VFS.Open <IniFile>("art.ini"); } if (_rules == null || _art == null) { Logger.Fatal("Rules or art config file could not be loaded! You cannot render a YR/FS map" + " without the expansion installed"); return(false); } return(true); }
public void InitTilesets() { int sectionIdx = 0; int setNum = 0; while (true) { string sectionName = "TileSet" + sectionIdx.ToString("0000"); var sect = _theaterIni.GetSection(sectionName); if (sect == null) { break; } sectionIdx++; Logger.Trace("Loading tileset {0}", sectionName); var ts = new TileSet(sect.ReadString("FileName"), sect.ReadString("SetName"), sect.ReadInt("TilesInSet")); _setNumToFirstTile.Add((short)_drawables.Count); _tileSets.Add(ts); for (int j = 1; j <= ts.TilesInSet; j++) { _tileNumToSet.Add((short)setNum); var rs = new TileSetEntry(ts, j - 1); // add as many tiles (with randomized name) as can be found for (var r = (char)('a' - 1); r <= 'z'; r++) { if ((r >= 'a') && ts.SetName == "Bridges") { continue; } // filename = set filename + dd + .tmp/.urb/.des etc string filename = ts.FileName + j.ToString("00"); if (r >= 'a') { filename += r; } filename += _theaterSettings.Extension; var tmpFile = VFS.Open <TmpFile>(filename); if (tmpFile != null) { rs.AddTile(tmpFile); } else { break; } } ts.Entries.Add(rs); _drawables.Add(new TileDrawable(null, null, rs)); } setNum++; } _animsSectionsStartIdx = sectionIdx + 1; }
private Drawable InitAnimDrawable(IniFile.IniSection rules, IniFile.IniSection art) { var anim = new AnimDrawable(rules, art); InitDrawableDefaults(anim, art); anim.LoadFromRules(); anim.Shp = VFS.Open <ShpFile>(anim.Image + ".shp"); return(anim); }
public bool Initialize() { Logger.Info("Initializing theater of type {0}", _theaterType); if (!ModConfig.SetActiveTheater(_theaterType)) { return(false); } Active = this; // load palettes and additional mix files for this theater _palettes = new PaletteCollection(); _palettes.IsoPalette = new Palette(VFS.Open <PalFile>(ModConfig.ActiveTheater.IsoPaletteName)); _palettes.OvlPalette = new Palette(VFS.Open <PalFile>(ModConfig.ActiveTheater.OverlayPaletteName)); _palettes.UnitPalette = new Palette(VFS.Open <PalFile>(ModConfig.ActiveTheater.UnitPaletteName), ModConfig.ActiveTheater.UnitPaletteName, true); foreach (string mix in ModConfig.ActiveTheater.Mixes) { VFS.Add(mix, CacheMethod.Cache); // we wish for these to be cached as they're gonna be hit often } _palettes.AnimPalette = new Palette(VFS.Open <PalFile>("anim.pal")); _animations = new ObjectCollection(CollectionType.Animation, _theaterType, _engine, _rules, _art, _rules.GetSection("Animations"), _palettes); _tileTypes = new TileCollection(CollectionType.Tiles, _theaterType, _engine, _rules, _art, ModConfig.ActiveTheater); _buildingTypes = new ObjectCollection(CollectionType.Building, _theaterType, _engine, _rules, _art, _rules.GetSection("BuildingTypes"), _palettes); _aircraftTypes = new ObjectCollection(CollectionType.Aircraft, _theaterType, _engine, _rules, _art, _rules.GetSection("AircraftTypes"), _palettes); _infantryTypes = new ObjectCollection(CollectionType.Infantry, _theaterType, _engine, _rules, _art, _rules.GetSection("InfantryTypes"), _palettes); _overlayTypes = new ObjectCollection(CollectionType.Overlay, _theaterType, _engine, _rules, _art, _rules.GetSection("OverlayTypes"), _palettes); _terrainTypes = new ObjectCollection(CollectionType.Terrain, _theaterType, _engine, _rules, _art, _rules.GetSection("TerrainTypes"), _palettes); _smudgeTypes = new ObjectCollection(CollectionType.Smudge, _theaterType, _engine, _rules, _art, _rules.GetSection("SmudgeTypes"), _palettes); _vehicleTypes = new ObjectCollection(CollectionType.Vehicle, _theaterType, _engine, _rules, _art, _rules.GetSection("VehicleTypes"), _palettes); _tileTypes.InitTilesets(); _tileTypes.InitAnimations(_animations); return(true); }
public DllFile(string path) { if (path == null) { throw new ArgumentNullException("path"); } Name = Path.GetFileName(path); using (var file = VFS.Open(path)) { provider = new ManagedDllProvider(file); } }
private static short GetBuildingZ(int x, int y, ShpFile shp, ShpFile.ShpImage img, GameObject obj) { if (_noBuildingZAvailable) { return(0); } else if (BuildingZ == null) { if (ModConfig.ActiveConfig.Engine < EngineType.YurisRevenge) { BuildingZ = VFS.Open <ShpFile>("buildngz.shp"); } else // Yuri's Revenge uses .sha as a file extension for this { BuildingZ = VFS.Open <ShpFile>("buildngz.sha"); } if (BuildingZ != null) { BuildingZ.Initialize(); } else { _noBuildingZAvailable = true; } } var zImg = BuildingZ.GetImage(0); byte[] zData = zImg.GetImageData(); // center x x += zImg.Width / 2 - shp.Width / 2 + img.X; // correct for foundation x -= (obj.Drawable.Foundation.Width - obj.Drawable.Foundation.Height) * 30; // add zshapepointmove x += obj.Drawable.Props.ZShapePointMove.X; // align y on bottom y += zImg.Height - shp.Height; // add zshapepointmove y -= obj.Drawable.Props.ZShapePointMove.Y; x = Math.Min(zImg.Width - 1, Math.Max(0, x)); y = Math.Min(zImg.Height - 1, Math.Max(0, y)); return((short)(-64 + zData[y * zImg.Width + x])); }
public override void LoadFromRules() { base.LoadFromArtEssential(); if (IsVoxel) { var vxl = new VoxelDrawable(Rules, Art); vxl.OwnerCollection = OwnerCollection; vxl.Props = Props; vxl.LoadFromRules(); vxl.Vxl = VFS.Open <VxlFile>(vxl.Image + ".vxl"); vxl.Hva = VFS.Open <HvaFile>(vxl.Image + ".hva"); SubDrawables.Add(vxl); } else { var shp = new ShpDrawable(Rules, Art); shp.Props = Props; shp.OwnerCollection = OwnerCollection; shp.LoadFromRules(); shp.Shp = VFS.Open <ShpFile>(shp.GetFilename()); shp.Props.FrameDecider = FrameDeciders.SHPVehicleFrameDecider(shp.StartStandFrame, shp.StandingFrames, shp.Facings); if (Ready_Start != -1 && Ready_Count != -1 && Ready_CountNext != -1) { shp.Props.FrameDecider = FrameDeciders.InfantryFrameDecider(Ready_Start, Ready_Count, Ready_CountNext); } SubDrawables.Add(shp); } if (Rules.ReadBool("Turret") && IsVoxel) { var turretVxl = VFS.Open <VxlFile>(Image + "TUR.vxl"); var turretHva = VFS.Open <HvaFile>(Image + "TUR.hva"); var turret = new VoxelDrawable(turretVxl, turretHva); turret.Props.Offset = Props.Offset; turret.Props.Offset += new Size(Rules.ReadInt("TurretAnimX"), Rules.ReadInt("TurretAnimY")); turret.Props.TurretVoxelOffset = Art.ReadFloat("TurretOffset"); SubDrawables.Add(turret); var barrelVxl = VFS.Open <VxlFile>(Image + "BARL.vxl"); var barrelHva = VFS.Open <HvaFile>(Image + "BARL.hva"); if (barrelVxl != null && barrelHva != null) { var barrel = new VoxelDrawable(barrelVxl, barrelHva); barrel.Props = turret.Props; SubDrawables.Add(barrel); } } }
void Parse() { logger.Info("Parsing {0}", Path.GetFileName(FileName)); while (CanRead) { ProcessLine(ReadLine()); } // support for Ares tag var includes = GetOrCreateSection("#include"); foreach (var entry in includes.OrderedEntries) { MergeWith(VFS.Open <IniFile>(entry.Value)); } }
public override void LoadFromRules() { base.LoadFromArtEssential(); if (IsVoxel) { var vxl = new VoxelDrawable(Rules, Art); vxl.OwnerCollection = OwnerCollection; vxl.Props = Props; vxl.LoadFromRules(); vxl.Vxl = VFS.Open <VxlFile>(vxl.Image + ".vxl"); vxl.Hva = VFS.Open <HvaFile>(vxl.Image + ".hva"); SubDrawables.Add(vxl); } else { var shp = new ShpDrawable(Rules, Art); shp.Props = Props; shp.OwnerCollection = OwnerCollection; shp.LoadFromRules(); shp.Shp = VFS.Open <ShpFile>(shp.GetFilename()); SubDrawables.Add(shp); } if (Rules.ReadBool("Turret") && IsVoxel) { var turretVxl = VFS.Open <VxlFile>(Image + "TUR.vxl"); var turretHva = VFS.Open <HvaFile>(Image + "TUR.hva"); var turret = new VoxelDrawable(turretVxl, turretHva); turret.Props.Offset = Props.Offset; turret.Props.Offset += new Size(Rules.ReadInt("TurretAnimX"), Rules.ReadInt("TurretAnimY")); turret.Props.TurretVoxelOffset = Art.ReadFloat("TurretOffset"); SubDrawables.Add(turret); var barrelVxl = VFS.Open <VxlFile>(Image + "BARL.vxl"); var barrelHva = VFS.Open <HvaFile>(Image + "BARL.hva"); if (barrelVxl != null && barrelHva != null) { var barrel = new VoxelDrawable(barrelVxl, barrelHva); barrel.Props = turret.Props; SubDrawables.Add(barrel); } } }
private void LoadSimpleDrawable(ShpDrawable drawable) { InitDrawableDefaults(drawable); drawable.LoadFromRules(); string shpFile = drawable.GetFilename(); drawable.Shp = VFS.Open <ShpFile>(shpFile); if (Type == CollectionType.Smudge) { drawable.Foundation = new Size(drawable.Rules.ReadInt("Width", 1), drawable.Rules.ReadInt("Height", 1)); } if (Type == CollectionType.Overlay) { LoadOverlayDrawable(drawable); } }
public override void Draw(GameObject obj, DrawingSurface ds, bool shadows = true) { terrainShp = new ShpDrawable(Rules, Art); terrainShp.OwnerCollection = OwnerCollection; terrainShp.LoadFromArtEssential(); terrainShp.Props = Props; terrainShp.Shp = VFS.Open <ShpFile>(terrainShp.GetFilename()); foreach (var sub in SubDrawables.OfType <AlphaDrawable>()) { sub.Draw(obj, ds, false); } if (shadows) { terrainShp.DrawShadow(obj, ds); } terrainShp.Draw(obj, ds, false); }
private AnimDrawable LoadExtraImage(string extraImage, DrawProperties inheritProps) { string animSection = Art.ReadString(extraImage); if (animSection == "") { return(null); } IniFile.IniSection extraRules = OwnerCollection.Rules.GetOrCreateSection(animSection); IniFile.IniSection extraArt = OwnerCollection.Art.GetOrCreateSection(animSection); var anim = new AnimDrawable(extraRules, extraArt); anim.OwnerCollection = OwnerCollection; anim.LoadFromRules(); anim.NewTheater = this.NewTheater; if (extraArt.HasKey("YSortAdjust") || Art.HasKey(extraImage + "YSort") || extraArt.HasKey("ZAdjust") || Art.HasKey(extraImage + "ZAdjust")) { anim.Props.SortIndex = extraArt.ReadInt("YSortAdjust", Art.ReadInt(extraImage + "YSort")) - extraArt.ReadInt("ZAdjust", Art.ReadInt(extraImage + "ZAdjust")); } else { anim.Props.SortIndex = inheritProps.SortIndex; } if (Art.HasKey(extraImage + "X") || Art.HasKey(extraImage + "Y")) { anim.Props.Offset = this.Props.Offset + new Size(Art.ReadInt(extraImage + "X"), Art.ReadInt(extraImage + "Y")); } else { anim.Props.Offset = inheritProps.Offset; } anim.Props.ZAdjust = Art.ReadInt(extraImage + "ZAdjust"); anim.IsBuildingPart = true; anim.Shp = VFS.Open <ShpFile>(anim.GetFilename()); return(anim); }
protected IEnumerable <Section> ParseFile(string path, bool allowmaps = false) { if (path == null) { throw new ArgumentNullException("path"); } if (!path.ToLowerInvariant().EndsWith(".ini")) { path = path + ".ini"; } using (var stream = new MemoryStream()) { //Don't wait on I/O for yield return using (Stream file = VFS.Open(path)) { file.CopyTo(stream); } foreach (var s in ParseFile(path, stream, allowmaps)) { yield return(s); } } }
private static byte GetBuildingZ(int x, int y, ShpFile shp, ShpFile.ShpImage img, GameObject obj, DrawProperties props) { if (BuildingZ == null) { BuildingZ = VFS.Open <ShpFile>("buildngz.shp"); BuildingZ.Initialize(); } var zImg = BuildingZ.GetImage(0); byte[] zData = zImg.GetImageData(); // center x x += zImg.Width / 2; x += obj.Drawable.Foundation.Width * Drawable.TileHeight / 2; // align y y += zImg.Height - shp.Height; // y += props.ZAdjust; return(zData[y * zImg.Width + x]); }
private Drawable InitSimpleDrawable(IniFile.IniSection rulesSection, IniFile.IniSection artSection) { var drawable = new ShpDrawable(rulesSection, artSection); InitDrawableDefaults(drawable, artSection); drawable.LoadFromRules(); string shpFile = drawable.GetFilename(); drawable.Shp = VFS.Open <ShpFile>(shpFile); if (Type == CollectionType.Smudge) { drawable.Foundation = new Size(rulesSection.ReadInt("Width", 1), rulesSection.ReadInt("Height", 1)); } if (Type == CollectionType.Overlay) { LoadOverlayDrawable(drawable); } return(drawable); }
/// <summary> /// Gets a custom palette from collection. If custom palette is not found, creates one, adds it to the collection and returns it. /// Search is done by comparing names of the palettes. /// </summary> /// <param name="paletteName">Name of the palette to find, without theater or .pal extension.</param> /// <returns>The correct custom palette.</returns> public Palette GetCustomPalette(string paletteName) { string fileName; if (paletteName.ToLower().EndsWith(".pal")) // full name already given { fileName = paletteName; } else // filename = <paletteName><theaterExtension>.pal (e.g. lib<tem/sno/urb>.pal) { fileName = paletteName + ModConfig.ActiveTheater.Extension.Substring(1) + ".pal"; } var pal = CustomPalettes.FirstOrDefault(p => p.Name == paletteName); if (pal == null) { // palette hasn't been loaded yet pal = new Palette(VFS.Open <PalFile>(fileName), paletteName); CustomPalettes.Add(pal); } return(pal); }
public Theater(TheaterType theaterType, EngineType engine) { _theaterType = theaterType; _engine = engine; if (engine == EngineType.RedAlert2 || engine == EngineType.TiberianSun) { _rules = VFS.Open <IniFile>("rules.ini"); _art = VFS.Open <IniFile>("art.ini"); } else if (engine == EngineType.YurisRevenge) { _rules = VFS.Open <IniFile>("rulesmd.ini"); _art = VFS.Open <IniFile>("artmd.ini"); } else if (engine == EngineType.Firestorm) { _rules = VFS.Open <IniFile>("rules.ini"); var fsRules = VFS.Open <IniFile>("firestrm.ini"); Logger.Info("Merging Firestorm rules with TS rules"); _rules.MergeWith(fsRules); _art = VFS.Open <IniFile>("artmd.ini"); } }
// Adds fire animations to a building. Supports custom-paletted animations. private void LoadFireAnimations() { // http://modenc.renegadeprojects.com/DamageFireTypes int f = 0; while (true) // enumerate as many fires as are existing { string dfo = Art.ReadString("DamageFireOffset" + f++); if (dfo == "") { break; } string[] coords = dfo.Split(new[] { ',', '.' }, StringSplitOptions.RemoveEmptyEntries); string fireAnim = OwnerCollection.FireNames[R.Next(OwnerCollection.FireNames.Length)]; IniFile.IniSection fireArt = OwnerCollection.Art.GetOrCreateSection(fireAnim); var fire = new AnimDrawable(Rules, Art, VFS.Open <ShpFile>(fireAnim + ".shp")); fire.Props.PaletteOverride = GetFireAnimPalette(fireArt); fire.Props.Offset = new Point(Int32.Parse(coords[0]), Int32.Parse(coords[1])); fire.Props.FrameDecider = FrameDeciders.RandomFrameDecider; _fires.Add(fire); } }
public override void LoadFromRules() { base.LoadFromRules(); IsBuildingPart = true; InvisibleInGame = Rules.ReadBool("InvisibleInGame") || LampNames.Contains(Name.ToUpper()); string foundation = Art.ReadString("Foundation", "1x1"); if (!foundation.Equals("custom", StringComparison.InvariantCultureIgnoreCase)) { int fx = foundation[0] - '0'; int fy = foundation[2] - '0'; Foundation = new Size(fx, fy); } else { int fx = Art.ReadInt("Foundation.X", 1); int fy = Art.ReadInt("Foundation.Y", 1); Foundation = new Size(fx, fy); } Props.SortIndex = Art.ReadInt("NormalYSort") - Art.ReadInt("NormalZAdjust"); // "main" building image before anims _baseShp = new ShpDrawable(Rules, Art); _baseShp.OwnerCollection = OwnerCollection; _baseShp.LoadFromArtEssential(); _baseShp.Props = Props; _baseShp.Shp = VFS.Open <ShpFile>(_baseShp.GetFilename()); var extraProps = Props.Clone(); extraProps.SortIndex = 0; foreach (string extraImage in AnimImages) { var extra = LoadExtraImage(extraImage, extraProps); if (extra != null && extra.Shp != null) { _anims.Add(extra); var extraDmg = LoadExtraImage(extraImage + "Damaged", extra.Props); if (extraDmg != null && extraDmg.Shp != null) { _animsDamaged.Add(extraDmg); } else // no damaged anim --> use normal anim also in damaged state { _animsDamaged.Add(extra); } } } // Starkku: New code for adding fire animations to buildings, supports custom-paletted animations. if (OwnerCollection.Engine >= EngineType.RedAlert2) { LoadFireAnimations(); } // Add turrets if (Rules.ReadBool("Turret") && Rules.HasKey("TurretAnim")) { string turretName = Rules.ReadString("TurretAnim"); Drawable turret = Rules.ReadBool("TurretAnimIsVoxel") ? (Drawable) new VoxelDrawable(VFS.Open <VxlFile>(turretName + ".vxl"), VFS.Open <HvaFile>(turretName + ".hva")) : new ShpDrawable(VFS.Open <ShpFile>(turretName + ".shp")); turret.Props.Offset = Props.Offset + new Size(Rules.ReadInt("TurretAnimX"), Rules.ReadInt("TurretAnimY")); turret.Props.HasShadow = Rules.ReadBool("UseTurretShadow"); turret.Props.FrameDecider = FrameDeciders.TurretFrameDecider; turret.Props.ZAdjust = Rules.ReadInt("TurretAnimZAdjust"); SubDrawables.Add(turret); if (turret is VoxelDrawable && turretName.ToUpper().Contains("TUR")) { string barrelName = turretName.Replace("TUR", "BARL"); if (VFS.Exists(barrelName + ".vxl")) { var barrel = new VoxelDrawable(VFS.Open <VxlFile>(barrelName + ".vxl"), VFS.Open <HvaFile>(barrelName + ".hva")); SubDrawables.Add(barrel); barrel.Props = turret.Props; } } } // Bib if (Art.HasKey("BibShape")) { var bibImg = Art.ReadString("BibShape") + ".shp"; if (NewTheater) { bibImg = OwnerCollection.ApplyNewTheaterIfNeeded(bibImg, bibImg); } var bibShp = VFS.Open <ShpFile>(bibImg); if (bibShp != null) { var bib = new ShpDrawable(bibShp); bib.Props = this.Props.Clone(); bib.Flat = true; SubDrawables.Add(bib); } } // Powerup slots, at most 3 for (int i = 1; i <= 3; i++) { if (!Art.HasKey(String.Format("PowerUp{0}LocXX", i))) { break; } _powerupSlots.Add(new PowerupSlot { X = Art.ReadInt(String.Format("PowerUp{0}LocXX", i)), Y = Art.ReadInt(String.Format("PowerUp{0}LocYY", i)), Z = Art.ReadInt(String.Format("PowerUp{0}LocZZ", i)), YSort = Art.ReadInt(String.Format("PowerUp{0}LocYSort", i)), }); } }
private void LoadAnimDrawable(AnimDrawable anim) { InitDrawableDefaults(anim); anim.LoadFromRules(); anim.Shp = VFS.Open <ShpFile>(anim.Image + ".shp"); }
/// <summary>Gets the determine map name. </summary> /// <returns>The filename to save the map as</returns> public static string DetermineMapName(MapFile map, EngineType engine) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(map.FileName); IniFile.IniSection basic = map.GetSection("Basic"); if (basic.ReadBool("Official") == false) { return(StripPlayersFromName(basic.ReadString("Name", fileNameWithoutExtension))); } string mapExt = Path.GetExtension(Settings.InputFile); string missionName = ""; string mapName = ""; PktFile.PktMapEntry pktMapEntry = null; MissionsFile.MissionEntry missionEntry = null; // campaign mission if (!basic.ReadBool("MultiplayerOnly") && basic.ReadBool("Official")) { string missionsFile; switch (engine) { case EngineType.TiberianSun: case EngineType.RedAlert2: missionsFile = "mission.ini"; break; case EngineType.Firestorm: missionsFile = "mission1.ini"; break; case EngineType.YurisRevenge: missionsFile = "missionmd.ini"; break; default: throw new ArgumentOutOfRangeException("engine"); } var mf = VFS.Open <MissionsFile>(missionsFile); missionEntry = mf.GetMissionEntry(Path.GetFileName(map.FileName)); if (missionEntry != null) { missionName = (engine >= EngineType.RedAlert2) ? missionEntry.UIName : missionEntry.Name; } } else { // multiplayer map string pktEntryName = fileNameWithoutExtension; PktFile pkt = null; if (FormatHelper.MixArchiveExtensions.Contains(mapExt)) { // this is an 'official' map 'archive' containing a PKT file with its name try { var mix = new MixFile(File.Open(Settings.InputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)); pkt = mix.OpenFile(fileNameWithoutExtension + ".pkt", FileFormat.Pkt) as PktFile; // pkt file is cached by default, so we can close the handle to the file mix.Close(); if (pkt != null && pkt.MapEntries.Count > 0) { pktEntryName = pkt.MapEntries.First().Key; } } catch (ArgumentException) { } } else { // determine pkt file based on engine switch (engine) { case EngineType.TiberianSun: case EngineType.RedAlert2: pkt = VFS.Open <PktFile>("missions.pkt"); break; case EngineType.Firestorm: pkt = VFS.Open <PktFile>("multi01.pkt"); break; case EngineType.YurisRevenge: pkt = VFS.Open <PktFile>("missionsmd.pkt"); break; default: throw new ArgumentOutOfRangeException("engine"); } } // fallback for multiplayer maps with, .map extension, // no YR objects so assumed to be ra2, but actually meant to be used on yr if (mapExt == ".map" && pkt != null && !pkt.MapEntries.ContainsKey(pktEntryName) && engine >= EngineType.RedAlert2) { var vfs = new VFS(); vfs.AddFile(Settings.InputFile); pkt = vfs.OpenFile <PktFile>("missionsmd.pkt"); } if (pkt != null && !string.IsNullOrEmpty(pktEntryName)) { pktMapEntry = pkt.GetMapEntry(pktEntryName); } } // now, if we have a map entry from a PKT file, // for TS we are done, but for RA2 we need to look in the CSV file for the translated mapname if (engine <= EngineType.Firestorm) { if (pktMapEntry != null) { mapName = pktMapEntry.Description; } else if (missionEntry != null) { if (engine == EngineType.TiberianSun) { string campaignSide; string missionNumber; if (missionEntry.Briefing.Length >= 3) { campaignSide = missionEntry.Briefing.Substring(0, 3); missionNumber = missionEntry.Briefing.Length > 3 ? missionEntry.Briefing.Substring(3) : ""; missionName = ""; mapName = string.Format("{0} {1} - {2}", campaignSide, missionNumber.TrimEnd('A').PadLeft(2, '0'), missionName); } else if (missionEntry.Name.Length >= 10) { mapName = missionEntry.Name; } } else { // FS map names are constructed a bit easier mapName = missionName.Replace(":", " - "); } } else if (!string.IsNullOrEmpty(basic.ReadString("Name"))) { mapName = basic.ReadString("Name", fileNameWithoutExtension); } } // if this is a RA2/YR mission (csfEntry set) or official map with valid pktMapEntry else if (missionEntry != null || pktMapEntry != null) { string csfEntryName = missionEntry != null ? missionName : pktMapEntry.Description; string csfFile = engine == EngineType.YurisRevenge ? "ra2md.csf" : "ra2.csf"; Logger.Info("Loading csf file {0}", csfFile); var csf = VFS.Open <CsfFile>(csfFile); mapName = csf.GetValue(csfEntryName.ToLower()); if (missionEntry != null) { if (mapName.Contains("Operation: ")) { string missionMapName = Path.GetFileName(map.FileName); if (char.IsDigit(missionMapName[3]) && char.IsDigit(missionMapName[4])) { string missionNr = Path.GetFileName(map.FileName).Substring(3, 2); mapName = mapName.Substring(0, mapName.IndexOf(":")) + " " + missionNr + " -" + mapName.Substring(mapName.IndexOf(":") + 1); } } } else { // not standard map if ((pktMapEntry.GameModes & PktFile.GameMode.Standard) == 0) { if ((pktMapEntry.GameModes & PktFile.GameMode.Megawealth) == PktFile.GameMode.Megawealth) { mapName += " (Megawealth)"; } if ((pktMapEntry.GameModes & PktFile.GameMode.Duel) == PktFile.GameMode.Duel) { mapName += " (Land Rush)"; } if ((pktMapEntry.GameModes & PktFile.GameMode.NavalWar) == PktFile.GameMode.NavalWar) { mapName += " (Naval War)"; } } } } // not really used, likely empty, but if this is filled in it's probably better than guessing if (mapName == "" && basic.SortedEntries.ContainsKey("Name")) { mapName = basic.ReadString("Name"); } if (mapName == "") { Logger.Warn("No valid mapname given or found, reverting to default filename {0}", fileNameWithoutExtension); mapName = fileNameWithoutExtension; } else { Logger.Info("Mapname found: {0}", mapName); } mapName = StripPlayersFromName(MakeValidFileName(mapName)).Replace(" ", " "); return(mapName); }
public void InitTilesets() { int sectionIdx = 0; int setNum = 0; while (true) { string sectionName = "TileSet" + sectionIdx.ToString("0000"); var sect = _theaterIni.GetSection(sectionName); if (sect == null) { break; } Logger.Trace("Loading tileset {0}", sectionName); var ts = new TileSet(sect.ReadString("FileName"), sect.ReadString("SetName"), sect.ReadInt("TilesInSet"), (short)sectionIdx); _setNumToFirstTile.Add((short)_drawables.Count); _tileSets.Add(ts); sectionIdx++; for (int j = 1; j <= ts.TilesInSet; j++) { _tileNumToSet.Add((short)setNum); var rs = new TileSetEntry(ts, j - 1); // add as many tiles (with randomized name) as can be found for (var r = (char)('a' - 1); r <= 'z'; r++) { if ((r >= 'a') && (ts.TileSetNum == BridgeSet || ts.TileSetNum == TrainBridgeSet || ts.TileSetNum == WoodBridgeSet)) { continue; } // filename = set filename + dd + .tmp/.urb/.des etc string filename = ts.FileName + j.ToString("00"); if (r >= 'a') { filename += r; } filename += _theaterSettings.Extension; var tmpFile = VFS.Open <TmpFile>(filename); if (tmpFile == null && _theaterSettings.Type == TheaterType.NewUrban) { tmpFile = VFS.Open <TmpFile>(filename.Replace(".ubn", ".tem")); } if (tmpFile != null) { rs.AddTile(tmpFile); } else { break; } } ts.Entries.Add(rs); _drawableIndexNameMap[_drawables.Count] = ts.SetName; var td = AddObject(sectionName) as TileDrawable; td.TsEntry = rs; } setNum++; } _animsSectionsStartIdx = sectionIdx + 1; }
protected List <Section> ParseFile(string path, bool allowmaps = false) { if (path == null) { throw new ArgumentNullException("path"); } List <Section> sections = new List <Section>(); if (!path.ToLowerInvariant().EndsWith(".ini")) { path = path + ".ini"; } using (Stream stream = VFS.Open(path)) { byte[] buffer = new byte[4]; stream.Read(buffer, 0, 4); string fileType = Encoding.ASCII.GetString(buffer); if (fileType == FileType) // Binary Ini { BinaryReader reader = new BinaryReader(stream); int formatVersion = reader.ReadInt32(); if (formatVersion != FileVersion) { throw new FileVersionException(path, fileType, formatVersion, FileVersion); } int stringBlockOffset = reader.ReadInt32(); if (stringBlockOffset > reader.BaseStream.Length) { throw new FileContentException(path, fileType, "The string block offset was out of range: " + stringBlockOffset); } long sectionBlockOffset = reader.BaseStream.Position; reader.BaseStream.Seek(stringBlockOffset, SeekOrigin.Begin); Array.Resize <byte>(ref buffer, (int)(reader.BaseStream.Length - stringBlockOffset)); reader.Read(buffer, 0, buffer.Length); string stringBlock = Encoding.ASCII.GetString(buffer); reader.BaseStream.Seek(sectionBlockOffset, SeekOrigin.Begin); while (reader.BaseStream.Position < stringBlockOffset) { sections.Add(new Section(reader, stringBlock)); } } else // Text Ini { stream.Seek(0, SeekOrigin.Begin); StreamReader reader = new StreamReader(stream); int currentSection = -2; int currentLine = 0; bool inSection = false; while (!reader.EndOfStream) { string line = reader.ReadLine().Trim(); if (string.IsNullOrWhiteSpace(line) || line.StartsWith(";", StringComparison.OrdinalIgnoreCase) || line.StartsWith("@", StringComparison.OrdinalIgnoreCase)) { continue; } if (line.StartsWith("[", StringComparison.OrdinalIgnoreCase)) { if (line.Substring(1).Trim()[0] == ';') { inSection = false; currentSection = -1; continue; } if (!line.Contains("]")) { throw new FileContentException(path, IniFileType, "Invalid section header: " + line); } string name = line.Substring(1); sections.Add(new Section(name.Remove(name.IndexOf(']')).Trim())); currentSection = sections.Count - 1; inSection = true; continue; } else { if (!inSection) { continue; } if (line.Contains(";")) { line = line.Remove(line.IndexOf(";", StringComparison.OrdinalIgnoreCase)).TrimEnd(); } if (!char.IsLetterOrDigit(line [0]) && line [0] != '_') { FLLog.Warning("Ini", "Invalid line in file: " + path + " at line " + currentLine + '"' + line + '"'); } else if (line.Contains("=")) { string[] parts = line.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 2) { string val = parts [1].TrimStart(); string[] valParts; if (val.Contains(",")) { valParts = val.Split(new char[] { ',' }); } else { valParts = new string[] { val } }; List <IValue> values = new List <IValue> (); foreach (string part in valParts) { string s = part.Trim(); bool tempBool; int tempInt; float tempFloat; if (bool.TryParse(s, out tempBool)) { values.Add(new BooleanValue(tempBool)); } else if (int.TryParse(s, out tempInt)) { values.Add(new Int32Value(tempInt)); } else if (float.TryParse(s, out tempFloat)) { long templong; bool a = long.TryParse(s, out templong); values.Add(new SingleValue(tempFloat, a ? (long?)templong : null)); } else { values.Add(new StringValue(s)); } } sections [currentSection].Add(new Entry(parts [0].TrimEnd(), values)); } else if (parts.Length == 3 && allowmaps) { string k = parts [1].Trim(); string v = parts [2].Trim(); sections[currentSection].Add(new Entry(parts[0].Trim(), new IValue[] { new StringKeyValue(k, v) })); } else if (parts.Length == 1) { sections [currentSection].Add(new Entry(parts [0].Trim(), new List <IValue> ())); } else { FLLog.Error("INI", "Invalid entry line: " + line + " in " + path); } } else { sections[currentSection].Add(new Entry(line, new List <IValue>(0))); } } currentLine++; } } } return(sections); }
public virtual void LoadFromRulesFull() { if (Art.ReadString("Remapable") != string.Empty) { // does NOT work in RA2 if (OwnerCollection.Engine <= EngineType.Firestorm) { IsRemapable = Art.ReadBool("Remapable"); } } // Used palet can be overriden bool noUseTileLandType = Rules.ReadString("NoUseTileLandType") != ""; if (noUseTileLandType) { Props.PaletteType = PaletteType.Iso; Props.LightingType = LightingType.Full; } if (Art.ReadBool("TerrainPalette")) { Props.PaletteType = PaletteType.Iso; IsRemapable = false; } else if (Art.ReadBool("AnimPalette")) { Props.PaletteType = PaletteType.Anim; Props.LightingType = LightingType.None; IsRemapable = false; } else if (Art.ReadString("Palette") != string.Empty) { Props.PaletteType = PaletteType.Custom; Props.CustomPaletteName = Art.ReadString("Palette"); } if (Rules.ReadString("AlphaImage") != "") { string alphaImageFile = Rules.ReadString("AlphaImage") + ".shp"; if (VFS.Exists(alphaImageFile)) { var ad = new AlphaDrawable(VFS.Open <ShpFile>(alphaImageFile)); ad.OwnerCollection = OwnerCollection; SubDrawables.Add(ad); } } Props.HasShadow = Art.ReadBool("Shadow", Defaults.GetShadowAssumption(OwnerCollection.Type)); Props.HasShadow = !Rules.ReadBool("NoShadow"); Props.Cloakable = Rules.ReadBool("Cloakable"); Flat = Rules.ReadBool("DrawFlat", Defaults.GetFlatnessAssumption(OwnerCollection.Type)) || Rules.ReadBool("Flat"); if (Rules.ReadBool("Gate")) { IsGate = true; Flat = false; IsBuildingPart = true; Props.PaletteType = PaletteType.Unit; Props.FrameDecider = FrameDeciders.NullFrameDecider; } if (Rules.ReadBool("Wall")) { IsWall = true; Flat = false; IsBuildingPart = true; // RA2 walls appear a bit higher if (OwnerCollection.Engine >= EngineType.RedAlert2) { Props.Offset.Offset(0, 3); // seems walls are located 3 pixels lower } Props.PaletteType = PaletteType.Unit; Props.LightingType = LightingType.Ambient; Props.FrameDecider = FrameDeciders.OverlayValueFrameDecider; } // Starkku: Overlays with IsRubble are not drawn. if (Rules.ReadBool("IsRubble")) { InvisibleInGame = true; } if (Rules.ReadBool("IsVeins")) { Props.LightingType = LightingType.None; Props.PaletteType = PaletteType.Unit; IsVeins = true; Flat = true; Props.Offset.Y = -1; // why is this needed??? } if (Rules.ReadBool("IsVeinholeMonster")) { Props.Offset.Y = -49; // why is this needed??? Props.LightingType = LightingType.None; Props.PaletteType = PaletteType.Unit; IsVeinHoleMonster = true; } if (Rules.ReadString("Land") == "Rock") { Props.Offset.Y += TileHeight / 2; //mainProps.ZBufferAdjust += Drawable.TileHeight / 2; } else if (Rules.ReadString("Land") == "Road") { Props.Offset.Y += TileHeight / 2; // Starkku: Some silly crap with low bridges not rendering. if (Name.ToUpper().Contains("LOBRDG") || Name.ToUpper().Contains("LOBRDB")) { Props.ZAdjust += TileHeight; } // drawable.Foundation = new Size(3, 1); // ensures bridges are drawn a bit lower than where they're stored } else if (Rules.ReadString("Land") == "Railroad") { if (OwnerCollection.Engine <= EngineType.Firestorm) { Props.Offset.Y = 11; } else { Props.Offset.Y = 14; } Props.LightingType = LightingType.Full; Props.PaletteType = PaletteType.Iso; // Foundation = new Size(2, 2); // hack to get these later in the drawing order } if (Rules.ReadBool("SpawnsTiberium")) { // For example on TIBTRE / Ore Poles Props.Offset.Y = -1; Props.LightingType = LightingType.None; // todo: verify it's not NONE Props.PaletteType = PaletteType.Unit; } // Starkku: Jumpjet units placed on maps actually start at same height as ground units so adjusting this for the renderer makes no sense. /* * if (Rules.HasKey("JumpjetHeight")) { * Props.Offset.Offset(0, (int)(-Rules.ReadInt("JumpjetHeight") / 256.0 * TileHeight)); * } */ // Starkku: Better support for SHP vehicles. Facings = Art.ReadInt("Facings", 8); StartStandFrame = Art.ReadInt("StartStandFrame", 0); StandingFrames = Art.ReadInt("StandingFrames", 0); StartWalkFrame = Art.ReadInt("StartWalkFrame", 0); WalkFrames = Art.ReadInt("WalkFrames", 0); Props.Offset.Offset(Art.ReadInt("XDrawOffset"), Art.ReadInt("YDrawOffset")); string sequence = Art.ReadString("Sequence"); if (sequence != string.Empty) { IniFile.IniSection seqSection = OwnerCollection.Art.GetOrCreateSection(sequence); string seqReady = seqSection.ReadString("Ready"); string[] readyParts = seqReady.Split(','); int start, frames, facingcount; if (readyParts.Length == 3 && int.TryParse(readyParts[0], out start) && int.TryParse(readyParts[1], out frames) && int.TryParse(readyParts[2], out facingcount)) { Ready_Start = start; Ready_Count = frames; Ready_CountNext = facingcount; } } }
public TileCollection(CollectionType type, TheaterType theater, EngineType engine, IniFile rules, IniFile art, TheaterSettings theaterSettings, IniFile theaterIni = null) : base(type, theater, engine, rules, art) { _theaterSettings = theaterSettings; if (theaterIni == null) { _theaterIni = VFS.Open <IniFile>(theaterSettings.TheaterIni); if (_theaterIni == null) { Logger.Warn("Unavailable theater loaded, theater.ini not found"); return; } } else { _theaterIni = theaterIni; } #region Set numbers IniFile.IniSection General = _theaterIni.GetSection("General"); ACliffMMPieces = General.ReadShort("ACliffMMPieces", -1); ACliffPieces = General.ReadShort("ACliffPieces", -1); BlackTile = General.ReadShort("BlackTile", -1); BridgeBottomLeft1 = General.ReadShort("BridgeBottomLeft1", -1); BridgeBottomLeft2 = General.ReadShort("BridgeBottomLeft2", -1); BridgeBottomRight1 = General.ReadShort("BridgeBottomRight1", -1); BridgeBottomRight2 = General.ReadShort("BridgeBottomRight2", -1); BridgeMiddle1 = General.ReadShort("BridgeMiddle1", -1); BridgeMiddle2 = General.ReadShort("BridgeMiddle2", -1); BridgeSet = General.ReadShort("BridgeSet", -1); BridgeTopLeft1 = General.ReadShort("BridgeTopLeft1", -1); BridgeTopLeft2 = General.ReadShort("BridgeTopLeft2", -1); BridgeTopRight1 = General.ReadShort("BridgeTopRight1", -1); BridgeTopRight2 = General.ReadShort("BridgeTopRight2", -1); ClearTile = General.ReadShort("ClearTile", -1); ClearToGreenLat = General.ReadShort("ClearToGreenLat", -1); ClearToPaveLat = General.ReadShort("ClearToPaveLat", -1); ClearToRoughLat = General.ReadShort("ClearToRoughLat", -1); ClearToSandLat = General.ReadShort("ClearToSandLat", -1); CliffRamps = General.ReadShort("CliffRamps", -1); CliffSet = General.ReadShort("CliffSet", -1); DestroyableCliffs = General.ReadShort("DestroyableCliffs", -1); DirtRoadCurve = General.ReadShort("DirtRoadCurve", -1); DirtRoadJunction = General.ReadShort("DirtRoadJunction", -1); DirtRoadSlopes = General.ReadShort("DirtRoadSlopes", -1); DirtRoadStraight = General.ReadShort("DirtRoadStraight", -1); DirtTrackTunnels = General.ReadShort("DirtTrackTunnels", -1); DirtTunnels = General.ReadShort("DirtTunnels", -1); GreenTile = General.ReadShort("GreenTile", -1); HeightBase = General.ReadShort("HeightBase", -1); Ice1Set = General.ReadShort("Ice1Set", -1); Ice2Set = General.ReadShort("Ice2Set", -1); Ice3Set = General.ReadShort("Ice3Set", -1); IceShoreSet = General.ReadShort("IceShoreSet", -1); MMRampBase = General.ReadShort("MMRampBase", -1); MMWaterCliffAPieces = General.ReadShort("MMWaterCliffAPieces", -1); Medians = General.ReadShort("Medians", -1); MiscPaveTile = General.ReadShort("MiscPaveTile", -1); MonorailSlopes = General.ReadShort("MonorailSlopes", -1); PaveTile = General.ReadShort("PaveTile", -1); PavedRoadEnds = General.ReadShort("PavedRoadEnds", -1); PavedRoadSlopes = General.ReadShort("PavedRoadSlopes", -1); PavedRoads = General.ReadShort("PavedRoads", -1); RampBase = General.ReadShort("RampBase", -1); RampSmooth = General.ReadShort("RampSmooth", -1); Rocks = General.ReadShort("Rocks", -1); RoughGround = General.ReadShort("RoughGround", -1); RoughTile = General.ReadShort("RoughTile", -1); SandTile = General.ReadShort("SandTile", -1); ShorePieces = General.ReadShort("ShorePieces", -1); SlopeSetPieces = General.ReadShort("SlopeSetPieces", -1); SlopeSetPieces2 = General.ReadShort("SlopeSetPieces2", -1); TrackTunnels = General.ReadShort("TrackTunnels", -1); TrainBridgeSet = General.ReadShort("TrainBridgeSet", -1); Tunnels = General.ReadShort("Tunnels", -1); WaterBridge = General.ReadShort("WaterBridge", -1); WaterCaves = General.ReadShort("WaterCaves", -1); WaterCliffAPieces = General.ReadShort("WaterCliffAPieces", -1); WaterCliffs = General.ReadShort("WaterCliffs", -1); WaterSet = General.ReadShort("WaterSet", -1); WaterfallEast = General.ReadShort("WaterfallEast", -1); WaterfallNorth = General.ReadShort("WaterfallNorth", -1); WaterfallSouth = General.ReadShort("WaterfallSouth", -1); WaterfallWest = General.ReadShort("WaterfallWest", -1); WoodBridgeSet = General.ReadShort("WoodBridgeSet", -1); #endregion }
public override void LoadFromRules() { base.LoadFromArtEssential(); ShpDrawable shp = null; VoxelDrawable vxl = null; if (IsVoxel) { vxl = new VoxelDrawable(Rules, Art); vxl.OwnerCollection = OwnerCollection; vxl.Props = Props; vxl.LoadFromRules(); vxl.Vxl = VFS.Open <VxlFile>(vxl.Image + ".vxl"); vxl.Hva = VFS.Open <HvaFile>(vxl.Image + ".hva"); SubDrawables.Add(vxl); } else { shp = new ShpDrawable(Rules, Art); shp.Props = Props; shp.OwnerCollection = OwnerCollection; shp.LoadFromRules(); shp.Shp = VFS.Open <ShpFile>(shp.GetFilename()); shp.Props.FrameDecider = FrameDeciders.SHPVehicleFrameDecider(shp.StartStandFrame, shp.StandingFrames, shp.StartWalkFrame, shp.WalkFrames, shp.Facings); SubDrawables.Add(shp); } if (shp != null || vxl != null) { if (Rules.ReadBool("Turret")) { VoxelDrawable vxlturret = null; ShpDrawable shpturret = null; var turretVxl = VFS.Open <VxlFile>(Image + "TUR.vxl"); var turretHva = VFS.Open <HvaFile>(Image + "TUR.hva"); if (turretVxl != null && turretHva != null) { vxlturret = new VoxelDrawable(turretVxl, turretHva); vxlturret.Props.Offset = Props.Offset; vxlturret.Props.Offset += new Size(Rules.ReadInt("TurretAnimX"), Rules.ReadInt("TurretAnimY")); vxlturret.Props.TurretVoxelOffset = Art.ReadFloat("TurretOffset"); vxlturret.Props.Cloakable = Props.Cloakable; SubDrawables.Add(vxlturret); } if (vxlturret == null && shp != null) { shpturret = new ShpDrawable(Rules, Art); shpturret.Props = (DrawProperties)shp.Props.Clone(); shpturret.OwnerCollection = OwnerCollection; shpturret.LoadFromRules(); shpturret.Shp = VFS.Open <ShpFile>(shpturret.GetFilename()); shpturret.Props.FrameDecider = FrameDeciders.SHPVehicleSHPTurretFrameDecider(shpturret.StartWalkFrame, shpturret.WalkFrames, shpturret.Facings); shpturret.Props.Cloakable = Props.Cloakable; SubDrawables.Add(shpturret); } var barrelVxl = VFS.Open <VxlFile>(Image + "BARL.vxl"); var barrelHva = VFS.Open <HvaFile>(Image + "BARL.hva"); if (barrelVxl != null && barrelHva != null) { var barrel = new VoxelDrawable(barrelVxl, barrelHva); if (vxlturret != null) { barrel.Props = vxlturret.Props; } else if (shp != null) { barrel.Props.Offset = Props.Offset; barrel.Props.Offset += new Size(Rules.ReadInt("TurretAnimX"), Rules.ReadInt("TurretAnimY")); barrel.Props.TurretVoxelOffset = Art.ReadFloat("TurretOffset"); } barrel.Props.Cloakable = Props.Cloakable; SubDrawables.Add(barrel); } } } }
public virtual void LoadFromRulesFull() { if (Art.ReadString("Remapable") != string.Empty) { // does NOT work in RA2 if (OwnerCollection.Engine <= EngineType.Firestorm) { IsRemapable = Art.ReadBool("Remapable"); } } // Used palet can be overriden bool noUseTileLandType = Rules.ReadString("NoUseTileLandType") != ""; if (noUseTileLandType) { Props.PaletteType = PaletteType.Iso; Props.LightingType = LightingType.Full; } if (Art.ReadBool("TerrainPalette")) { Props.PaletteType = PaletteType.Iso; IsRemapable = false; } else if (Art.ReadBool("AnimPalette")) { Props.PaletteType = PaletteType.Anim; Props.LightingType = LightingType.None; IsRemapable = false; } else if (Art.ReadString("Palette") != string.Empty) { Props.PaletteType = PaletteType.Custom; Props.CustomPaletteName = Art.ReadString("Palette"); } if (Rules.ReadString("AlphaImage") != "") { string alphaImageFile = Rules.ReadString("AlphaImage") + ".shp"; if (VFS.Exists(alphaImageFile)) { var ad = new AlphaDrawable(VFS.Open <ShpFile>(alphaImageFile)); ad.OwnerCollection = OwnerCollection; SubDrawables.Add(ad); } } Props.HasShadow = Art.ReadBool("Shadow", Defaults.GetShadowAssumption(OwnerCollection.Type)); Flat = Rules.ReadBool("DrawFlat", Defaults.GetFlatnessAssumption(OwnerCollection.Type)) || Rules.ReadBool("Flat"); if (Rules.ReadBool("Wall")) { IsWall = true; Flat = false; IsBuildingPart = true; // RA2 walls appear a bit higher if (OwnerCollection.Engine >= EngineType.RedAlert2) { Props.Offset.Offset(0, 3); // seems walls are located 3 pixels lower } Props.PaletteType = PaletteType.Unit; Props.LightingType = LightingType.Ambient; Props.FrameDecider = FrameDeciders.OverlayValueFrameDecider; } if (Rules.ReadBool("Gate")) { IsGate = true; Flat = false; IsBuildingPart = true; Props.PaletteType = PaletteType.Unit; Props.FrameDecider = FrameDeciders.NullFrameDecider; } if (Rules.ReadBool("IsVeins")) { Props.LightingType = LightingType.None; Props.PaletteType = PaletteType.Unit; IsVeins = true; Flat = true; Props.Offset.Y = -1; // why is this needed??? } if (Rules.ReadBool("IsVeinholeMonster")) { Props.Offset.Y = -49; // why is this needed??? Props.LightingType = LightingType.None; Props.PaletteType = PaletteType.Unit; IsVeinHoleMonster = true; } if (Rules.ReadString("Land") == "Rock") { Props.Offset.Y += TileHeight / 2; //mainProps.ZBufferAdjust += Drawable.TileHeight / 2; } else if (Rules.ReadString("Land") == "Road") { Props.Offset.Y += TileHeight / 2; // drawable.Foundation = new Size(3, 1); // ensures bridges are drawn a bit lower than where they're stored } else if (Rules.ReadString("Land") == "Railroad") { if (OwnerCollection.Engine <= EngineType.Firestorm) { Props.Offset.Y = 11; } else { Props.Offset.Y = 14; } Props.LightingType = LightingType.Full; Props.PaletteType = PaletteType.Iso; // Foundation = new Size(2, 2); // hack to get these later in the drawing order } if (Rules.ReadBool("SpawnsTiberium")) { // For example on TIBTRE / Ore Poles Props.Offset.Y = -1; Props.LightingType = LightingType.None; // todo: verify it's not NONE Props.PaletteType = PaletteType.Unit; } if (Rules.HasKey("JumpjetHeight")) { Props.Offset.Offset(0, (int)(-Rules.ReadInt("JumpjetHeight") / 256.0 * TileHeight)); } StartWalkFrame = Rules.ReadInt("StartWalkFrame"); StartStandFrame = Rules.ReadInt("StartStandFrame", StartWalkFrame); Props.Offset.Offset(Art.ReadInt("XDrawOffset"), Art.ReadInt("YDrawOffset")); }