public override void LoadRules(IniFile.IniSection rules) { base.LoadRules(rules); WeaponType = rules.ReadEnum <WeaponType>("WeaponType", null); Action = rules.ReadEnum <Action>("Action", Action.MultiMissile); IsPowered = rules.ReadBool("IsPowered", true); DisableableFromShell = rules.ReadBool("DisableableFromShell"); SidebarFlashTabFrames = rules.ReadInt("SidebarFlashTabFrames", -1); AIDefendAgainst = rules.ReadBool("AIDefendAgainst"); PreClick = rules.ReadBool("PreClick"); PostClick = rules.ReadBool("PostClick"); ShowTimer = rules.ReadBool("ShowTimer"); SpecialSound = Get <Sound>(rules.ReadString("SpecialSound")); StartSound = Get <Sound>(rules.ReadString("StartSound")); Range = rules.ReadFloat("Range", 0); LineMultiplier = rules.ReadInt("LineMultiplier", 0); Type = rules.ReadEnum <AbstractType>("Type", null); PreDependent = rules.ReadEnum <WeaponType>("PreDependent", null); AuxBuilding = Get <BuildingType>(rules.ReadString("AuxBuilding")); UseChargeDrain = rules.ReadBool("UseChargeDrain"); ManualControl = rules.ReadBool("ManualControl"); RechargeTime = rules.ReadFloat("RechargeTime", 5.0f); SidebarImage = rules.ReadString("SidebarImage", ""); }
/* Finds out the correct name for an animation palette to use with fire animations. * Reason why this is so complicated is because with NPatch & Ares, the YR logic extensions that support custom animation palettes * use different name for the flag declaring the palette. (NPatch uses 'Palette' whilst Ares uses 'CustomPalette' to make it distinct * from the custom object palettes). */ private Palette GetFireAnimPalette(IniFile.IniSection animation) { Palette pal = null; if (animation.ReadString("Palette") != "") { pal = OwnerCollection.Palettes.GetCustomPalette(animation.ReadString("Palette")); if (pal == null) { pal = OwnerCollection.Palettes.AnimPalette; } } else if (animation.ReadString("CustomPalette") != "") { pal = OwnerCollection.Palettes.GetCustomPalette(animation.ReadString("CustomPalette")); if (pal == null) { pal = OwnerCollection.Palettes.AnimPalette; } } else if (animation.ReadString("AltPalette") != "") { pal = OwnerCollection.Palettes.UnitPalette; } else { pal = OwnerCollection.Palettes.AnimPalette; } return(pal); }
/* Finds out the correct name for an animation palette to use with fire animations. * Reason why this is so complicated is because NPatch & Ares, the YR logic extensions that support custom animation palettes * use different name for the flag declaring the palette. (NPatch uses 'Palette' whilst Ares uses 'CustomPalette' to make it distinct * from the custom object palettes). */ private Palette GetFireAnimPalette(IniFile.IniSection animation) { // Starkku: Altered as a part of a fix for crash that happened if custom palette was declared but file wasn't there. Palette pal = null; if (animation.ReadString("Palette") != "") { pal = OwnerCollection.Palettes.GetCustomPalette(animation.ReadString("Palette")); if (pal == null) { pal = OwnerCollection.Palettes.AnimPalette; } } else if (animation.ReadString("CustomPalette") != "") { pal = OwnerCollection.Palettes.GetCustomPalette(animation.ReadString("CustomPalette")); if (pal == null) { pal = OwnerCollection.Palettes.AnimPalette; } } else if (animation.ReadString("AltPalette") != "") { pal = OwnerCollection.Palettes.UnitPalette; } else { pal = OwnerCollection.Palettes.AnimPalette; } return(pal); }
public override void LoadRules(IniFile.IniSection rules) { base.LoadRules(rules); Normalized = rules.ReadBool("Normalized"); Translucent = rules.ReadBool("Translucent"); IsTiberium = rules.ReadBool("IsTiberium"); IsMeteor = rules.ReadBool("IsMeteor"); Elasticity = rules.ReadFloat("Elasticity", 0.8f); MinAngularVelocity = rules.ReadFloat("MinAngularVelocity"); MaxAngularVelocity = rules.ReadFloat("MaxAngularVelocity", 0.174528f); Duration = rules.ReadInt("Duration", 30); MinZVel = rules.ReadFloat("MinZVel", 3.5f); MaxZVel = rules.ReadFloat("MaxZVel", 5f); MaxXYVel = rules.ReadFloat("MaxXYVel", 15f); Spawns = Get <VoxelAnimation>(rules.ReadString("Spawns")); SpawnCount = rules.ReadInt("SpawnCount"); ShareBodyData = rules.ReadBool("ShareBodyData"); ShareTurretData = rules.ReadBool("ShareTurretData"); ShareBarrelData = rules.ReadBool("ShareBarrelData"); VoxelIndex = rules.ReadInt("VoxelIndex"); StartSound = Get <Sound>(rules.ReadString("StartSound")); StopSound = Get <Sound>(rules.ReadString("StopSound")); BounceAnim = Get <Animation>(rules.ReadString("BounceAnim")); ExpireAnim = Get <Animation>(rules.ReadString("ExpireAnim")); TrailerAnim = Get <Animation>(rules.ReadString("TrailerAnim")); Damage = rules.ReadInt("Damage"); DamageRadius = rules.ReadInt("DamageRadius"); Warhead = Get <WarheadType>(rules.ReadString("Warhead")); AttachedSystem = Get <ParticleSystem>(rules.ReadString("AttachedSystem")); ShareSource = Get <TechnoType>(rules.ReadString("ShareSource")); }
/* Finds out the correct name for an animation palette to use with fire animations. * Reason why this is so complicated is because NPatch & Ares, the YR logic extensions that support custom animation palettes * use different name for the flag declaring the palette. (NPatch uses 'Palette' whilst Ares uses 'CustomPalette' to make it distinct * from the custom object palettes). */ private Palette GetFireAnimPalette(IniFile.IniSection animation) { if (animation.ReadString("Palette") != "") { return(OwnerCollection.Palettes.GetCustomPalette(animation.ReadString("Palette"))); } else if (animation.ReadString("CustomPalette") != "") { return(OwnerCollection.Palettes.GetCustomPalette(animation.ReadString("CustomPalette"))); } else if (animation.ReadString("AltPalette") != "") { return(OwnerCollection.Palettes.UnitPalette); } else { return(OwnerCollection.Palettes.AnimPalette); } }
private static Button ReadIniButton(IniFile.IniSection sec, string workingDir) { if (sec == null) { return(null); } var ret = new Button { Offset = sec.ReadPoint("Position"), Size = sec.ReadSize("Size"), }; if (sec.HasKey("File_Free", false)) { ret.ImagePath = System.IO.Path.Combine(workingDir, sec.ReadString("File_Free", "", false)); } if (sec.HasKey("File_Push", false)) { ret.PressedImagePath = System.IO.Path.Combine(workingDir, sec.ReadString("File_Push", "", false)); } return(ret); }
private AnimDrawable LoadUpgrade(StructureObject structObj, int upgradeSlot, DrawProperties inheritProps) { string upgradeName = ""; if (upgradeSlot == 0) { upgradeName = structObj.Upgrade1; } else if (upgradeSlot == 1) { upgradeName = structObj.Upgrade2; } else if (upgradeSlot == 2) { upgradeName = structObj.Upgrade3; } IniFile.IniSection upgradeRules = OwnerCollection.Rules.GetOrCreateSection(upgradeName); if (upgradeRules != null && upgradeRules.HasKey("Image")) { upgradeName = upgradeRules.ReadString("Image"); } IniFile.IniSection upgradeArt = OwnerCollection.Art.GetOrCreateSection(upgradeName); if (upgradeArt != null && upgradeArt.HasKey("Image")) { upgradeName = upgradeArt.ReadString("Image"); } IniFile.IniSection upgRules = OwnerCollection.Rules.GetOrCreateSection(upgradeName); IniFile.IniSection upgArt = OwnerCollection.Art.GetOrCreateSection(upgradeName); AnimDrawable upgrade = new AnimDrawable(_config, _vfs, upgRules, upgArt); upgrade.OwnerCollection = OwnerCollection; upgrade.Props = inheritProps; upgrade.LoadFromRules(); upgrade.NewTheater = this.NewTheater; upgrade.IsBuildingPart = true; string shpfilename = NewTheater ? OwnerCollection.ApplyNewTheaterIfNeeded(upgradeName, upgradeName + ".shp") : upgradeName + ".shp"; upgrade.Shp = _vfs.Open <ShpFile>(shpfilename); Point powerupOffset = new Point(_powerupSlots[upgradeSlot].X, _powerupSlots[upgradeSlot].Y); upgrade.Props.Offset.Offset(powerupOffset); return(upgrade); }
private static Stick ReadIniStick(IniFile.IniSection sec, string workingDir) { if (sec == null) { return(null); } var ret = new Stick { Offset = sec.ReadPoint("Position"), Size = sec.ReadSize("Size"), }; var axes = sec.ReadPoint("Axes"); ret.HorizontalAxis = axes.X; ret.VerticalAxis = axes.Y; ret.OffsetScale = 0.15f; ret.ImagePath = System.IO.Path.Combine(workingDir, sec.ReadString("File_Stick", "", false)); return(ret); }
private static Trigger ReadIniTrigger(IniFile.IniSection sec, string workingDir) { if (sec == null) { return(null); } var ret = new Trigger { Offset = sec.ReadPoint("Position"), Size = sec.ReadSize("Size"), }; ret.Axis = sec.ReadInt("Axis"); ret.OffsetScale = 0.08f; if (sec.HasKey("File_Trigger", false)) { ret.ImagePath = System.IO.Path.Combine(workingDir, sec.ReadString("File_Trigger", "", false)); } ret.Z = -1; // default to behind controller return(ret); }
/// <summary>Loads the countries. </summary> private void LoadCountries() { Logger.Info("Loading countries"); var countriesSection = _rules.GetSection(Engine >= EngineType.RedAlert2 ? "Countries" : "Houses"); foreach (var entry in countriesSection.OrderedEntries) { IniFile.IniSection countrySection = _rules.GetSection(entry.Value); if (countrySection == null) { continue; } Color c; if (!_namedColors.TryGetValue(countrySection.ReadString("Color"), out c)) { c = _namedColors.Values.First(); } _countryColors[entry.Value] = c; } }
public virtual void LoadRules(IniFile.IniSection rules) { Name = rules.ReadString("Name", ID); UIName = rules.ReadString("Name"); }
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; } } }
private static Trigger ReadIniTrigger(IniFile.IniSection sec, FileInfo pi) { if (sec == null) { return(null); } var ret = new Trigger { Offset = sec.ReadPoint("Position"), Size = sec.ReadSize("Size"), }; ret.Axis = sec.ReadInt("Axis"); ret.OffsetScale = 0.08f; if (sec.HasKey("File_Trigger", false)) { ret.Bitmap = (Bitmap)Image.FromFile(System.IO.Path.Combine(pi.DirectoryName, sec.ReadString("File_Trigger", "", false))); ret.Texture = TextureHelper.CreateTexture(ret.Bitmap); } ret.Z = -1; // default to behind controller return(ret); }
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 Props.ZShapePointMove = Art.ReadPoint("ZShapePointMove"); _canBeOccupied = Rules.ReadBool("CanBeOccupied"); _techLevel = Rules.ReadInt("TechLevel"); _conditionYellowHealth = 128; _conditionRedHealth = 64; IniFile.IniSection audioVisual = OwnerCollection.Rules.GetOrCreateSection("AudioVisual"); if (audioVisual != null) { if (audioVisual.HasKey("ConditionYellow")) { int conditionYellow = audioVisual.ReadPercent("ConditionYellow"); _conditionYellowHealth = (int)(256 * (double)conditionYellow / 100); } if (audioVisual.HasKey("ConditionRed")) { int conditionRed = audioVisual.ReadPercent("ConditionRed"); _conditionRedHealth = (int)(256 * (double)conditionRed / 100); } } _baseShp = new ShpDrawable(_config, _vfs, 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); } } } // RA2 and later support adding fire animations to buildings, supports custom-paletted animations. if (_config.Engine >= EngineType.RedAlert2) { LoadFireAnimations(); } // Add turrets if (Rules.ReadBool("Turret") && Rules.HasKey("TurretAnim")) { string turretName = Rules.ReadString("TurretAnim"); IniFile.IniSection turretArt = OwnerCollection.Art.GetOrCreateSection(turretName); if (turretArt.HasKey("Image")) { turretName = turretArt.ReadString("Image"); } // NewTheater/generic image fallback support for turrets. string turretNameShp = NewTheater ? OwnerCollection.ApplyNewTheaterIfNeeded(turretName, turretName + ".shp") : turretName + ".shp"; Drawable turret = Rules.ReadBool("TurretAnimIsVoxel") ? (Drawable) new VoxelDrawable(_config, _vfs.Open <VxlFile>(turretName + ".vxl"), _vfs.Open <HvaFile>(turretName + ".hva")) : (Drawable) new ShpDrawable(new ShpRenderer(_config, _vfs), _vfs.Open <ShpFile>(turretNameShp)); 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"); turret.Props.Cloakable = Props.Cloakable; SubDrawables.Add(turret); if (turret is VoxelDrawable && turretName.ToUpper().Contains("TUR")) { string barrelName = turretName.Replace("TUR", "BARL"); if (_vfs.FileExists(barrelName + ".vxl")) { var barrel = new VoxelDrawable(_config, _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(new ShpRenderer(_config, _vfs), bibShp); bib.Props = this.Props.Clone(); bib.Flat = true; SubDrawables.Add(bib); } } // Powerup slots, at most 3 for (int i = 1; i <= 3; i++) { _powerupSlots.Add(new PowerupSlot { X = Art.ReadInt(String.Format("PowerUp{0}LocXX", i), 0), Y = Art.ReadInt(String.Format("PowerUp{0}LocYY", i), 0), Z = Art.ReadInt(String.Format("PowerUp{0}LocZZ", i), 0), YSort = Art.ReadInt(String.Format("PowerUp{0}LocYSort", i), 0), }); } if (IsWall && _baseShp.Shp != null) { _baseShp.Shp.Initialize(); if (_baseShp.Shp.NumImages >= 32) { IsActualWall = true; } } }
private static Stick ReadIniStick(IniFile.IniSection sec, FileInfo pi) { if (sec == null) { return(null); } var ret = new Stick { Offset = sec.ReadPoint("Position"), Size = sec.ReadSize("Size"), }; var axes = sec.ReadPoint("Axes"); ret.HorizontalAxis = axes.X; ret.VerticalAxis = axes.Y; ret.OffsetScale = 0.15f; ret.Bitmap = (Bitmap)Image.FromFile(System.IO.Path.Combine(pi.DirectoryName, sec.ReadString("File_Stick", "", false))); ret.Texture = TextureHelper.CreateTexture(ret.Bitmap); return(ret); }
/// <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); }
private static Button ReadIniButton(IniFile.IniSection sec, FileInfo pi) { if (sec == null) { return(null); } var ret = new Button { Offset = sec.ReadPoint("Position"), Size = sec.ReadSize("Size"), }; if (sec.HasKey("File_Free", false)) { ret.Bitmap = (Bitmap)Image.FromFile(System.IO.Path.Combine(pi.DirectoryName, sec.ReadString("File_Free", "", false))); ret.Texture = TextureHelper.CreateTexture(ret.Bitmap); } if (sec.HasKey("File_Push", false)) { ret.Pressed = (Bitmap)Image.FromFile(System.IO.Path.Combine(pi.DirectoryName, sec.ReadString("File_Push", "", false))); ret.PressedTexture = TextureHelper.CreateTexture(ret.Pressed); } return(ret); }