private void ApplyNewTheater(ref string imageFileName) { var sb = new StringBuilder(imageFileName); sb[1] = ModConfig.ActiveTheater.NewTheaterChar; if (!VFS.Exists(sb.ToString())) { sb[1] = 'G'; // generic if (!VFS.Exists(sb.ToString())) { sb[1] = imageFileName[1]; // fallback to original } } imageFileName = sb.ToString(); }
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)), }); } }
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 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")); }