protected override void LoadDrawable(Drawable drawable) {
			switch (Type) {
				case CollectionType.Aircraft:
				case CollectionType.Vehicle:
					LoadUnitDrawable((UnitDrawable)drawable);
					break;
				case CollectionType.Building:
					LoadBuildingDrawable((BuildingDrawable)drawable);
					break;
				case CollectionType.Infantry:
				case CollectionType.Overlay:
				case CollectionType.Smudge:
				case CollectionType.Terrain:
					LoadSimpleDrawable((ShpDrawable)drawable);
					break;
				case CollectionType.Animation:
					LoadAnimDrawable((AnimDrawable)drawable);
					break;
				default:
					throw new InvalidEnumArgumentException();
			}

			// overrides from the modconfig
			var cfgOverrides = ModConfig.ActiveConfig.ObjectOverrides.Where(ovr =>
				// matches collection
				(ovr.CollectionTypes & Type) == Type &&
				// matches collection
				(ovr.TheaterTypes & Theater) == Theater &&
				// matches object regex
				Regex.IsMatch(drawable.Name, ovr.ObjRegex, RegexOptions.IgnoreCase))
				.OrderByDescending(o => o.Priority);

			foreach (var cfgOverride in cfgOverrides) {
				Logger.Debug("Object {0} receives overrides from regex {1}", drawable.Name, cfgOverride.ObjRegex);

				if (cfgOverride.Lighting != LightingType.Default)
					drawable.Props.LightingType = cfgOverride.Lighting;

				if (cfgOverride.Palette != PaletteType.Default) {
					drawable.Props.PaletteType = cfgOverride.Palette;
					drawable.Props.CustomPaletteName = cfgOverride.CustomPaletteFile;
				}
				if (!string.IsNullOrWhiteSpace(cfgOverride.FrameDeciderCode) && !_cannotCompile) {
					try {
						var fdc = FrameDeciders.GetOverrideFrameDecider(cfgOverride);
						if (fdc != null)
							drawable.Props.FrameDecider = fdc;
					}
					catch (TypeLoadException exc) {
						_cannotCompile = true;
						Logger.Error("Custom framedecider could not be compiled. You need .NET 4.5 for this."
							+ " Functionality will be unavailable.\r\n{0}", exc);
					}
				}
			}
		}
Beispiel #2
0
		internal Palette GetPalette(Drawable drawable) {
            // 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 (drawable.Props.PaletteType == PaletteType.Custom)
            {
                pal = _palettes.GetCustomPalette(drawable.Props.CustomPaletteName);
                if (pal == null)
                {
                    if (drawable is BuildingDrawable || drawable is UnitDrawable) return _palettes.UnitPalette;
                    else if (drawable is AnimDrawable) return _palettes.AnimPalette;
                    else return _palettes.IsoPalette;
                }
            }
            else
            {
                pal = _palettes.GetPalette(drawable.Props.PaletteType);
            }
            return pal;
		}
Beispiel #3
0
 public AnimationObject(string name, Drawable drawable)
 {
     Name = name;
     Drawable = drawable;
 }
Beispiel #4
0
			public void AddAnimation(int subtile, Drawable drawable) {
				AnimationSubtile = subtile;
				AnimationDrawable = drawable;
			}
Beispiel #5
0
		protected virtual void LoadDrawable(Drawable d) { 	}
Beispiel #6
0
		unsafe public static void Draw(ShpFile shp, GameObject obj, Drawable dr, DrawProperties props, DrawingSurface ds, int transLucency = 0) {
			shp.Initialize();

			int frameIndex = props.FrameDecider(obj);
			Palette p = props.PaletteOverride ?? obj.Palette;

			frameIndex = DecideFrameIndex(frameIndex, shp.NumImages);
			if (frameIndex >= shp.Images.Count)
				return;

			var img = shp.GetImage(frameIndex);
			var imgData = img.GetImageData();
			if (imgData == null || img.Width * img.Height != imgData.Length)
				return;

			Point offset = props.GetOffset(obj);
			offset.X += obj.Tile.Dx * Drawable.TileWidth / 2 - shp.Width / 2 + img.X;
			offset.Y += (obj.Tile.Dy - obj.Tile.Z) * Drawable.TileHeight / 2 - shp.Height / 2 + img.Y;
			Logger.Trace("Drawing SHP file {0} (Frame {1}) at ({2},{3})", shp.FileName, frameIndex, offset.X, offset.Y);

			int stride = ds.BitmapData.Stride;
			var heightBuffer = ds.GetHeightBuffer();
			var zBuffer = ds.GetZBuffer();

			var w_low = (byte*)ds.BitmapData.Scan0;
			byte* w_high = (byte*)ds.BitmapData.Scan0 + stride * ds.BitmapData.Height;
			byte* w = (byte*)ds.BitmapData.Scan0 + offset.X * 3 + stride * offset.Y;

			// clip to 25-50-75-100
			transLucency = (transLucency / 25) * 25;
			float a = transLucency / 100f;
			float b = 1 - a;

			int rIdx = 0; // image pixel index
			int zIdx = offset.X + offset.Y * ds.Width; // z-buffer pixel index
			short hBufVal = (short)(obj.Tile.Z * Drawable.TileHeight / 2);
			short zOffset = (short)((obj.BottomTile.Rx + obj.BottomTile.Ry) * Drawable.TileHeight / 2);

			if (!dr.Flat)
				hBufVal += shp.Height;

			for (int y = 0; y < img.Height; y++) {
				if (offset.Y + y < 0) {
					w += stride;
					rIdx += img.Width;
					zIdx += ds.Width;
					continue; // out of bounds
				}

				for (int x = 0; x < img.Width; x++) {
					byte paletteValue = imgData[rIdx];

					short zshapeOffset = obj is StructureObject ? (GetBuildingZ(x, y, shp, img, obj)) : (short)0;
					
					if (paletteValue != 0) {
						short zBufVal = zOffset;
						if (dr.Flat)
							zBufVal += (short)(y - img.Height);
						else if (dr.IsBuildingPart) {
							// nonflat building
							zBufVal += zshapeOffset;
						}
						else
							zBufVal += img.Height;

						if (w_low <= w && w < w_high  /*&& zBufVal >= zBuffer[zIdx]*/) {
							if (transLucency != 0) {
								*(w + 0) = (byte)(a * *(w + 0) + b * p.Colors[paletteValue].B);
								*(w + 1) = (byte)(a * *(w + 1) + b * p.Colors[paletteValue].G);
								*(w + 2) = (byte)(a * *(w + 2) + b * p.Colors[paletteValue].R);
							}
							else {
								*(w + 0) = p.Colors[paletteValue].B;
								*(w + 1) = p.Colors[paletteValue].G;
								*(w + 2) = p.Colors[paletteValue].R;

								//var pal = Theater.Active.GetPalettes().UnitPalette.Colors;
								//*(w + 0) = pal[zshapeOffset].R;
								//*(w + 1) = pal[zshapeOffset].G;
								//*(w + 2) = pal[zshapeOffset].B;
							}
							zBuffer[zIdx] = zBufVal;
							heightBuffer[zIdx] = hBufVal;
						}
					}
					//else {
					//	*(w + 0) = 0;
					//	*(w + 1) = 0;
					//	*(w + 2) = 255;
					//}

					// Up to the next pixel
					rIdx++;
					zIdx++;
					w += 3;
				}
				w += stride - 3 * img.Width;
				zIdx += ds.Width - img.Width;
			}
		}
		private void InitDrawableDefaults(Drawable drawable) {
			drawable.OwnerCollection = this;
			drawable.Props.PaletteType = Defaults.GetDefaultPalette(Type, Engine);
			drawable.Props.LightingType = Defaults.GetDefaultLighting(Type);
			drawable.IsRemapable = Defaults.GetDefaultRemappability(Type, Engine);
			drawable.Props.FrameDecider = Defaults.GetDefaultFrameDecider(Type);

			// apply collection-specific offsets
			switch (Type) {
				case CollectionType.Building:
				case CollectionType.Overlay:
				case CollectionType.Smudge:
					drawable.Props.Offset.Offset(Drawable.TileWidth / 2, 0);
					break;
				case CollectionType.Terrain:
				case CollectionType.Vehicle:
				case CollectionType.Infantry:
				case CollectionType.Aircraft:
				case CollectionType.Animation:
					drawable.Props.Offset.Offset(Drawable.TileWidth / 2, Drawable.TileHeight / 2);
					break;
			}
		}
        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;
                }
            }
        }
		public void DrawPowerup(GameObject obj, Drawable powerup, int slot, DrawingSurface ds) {
			if (slot >= _powerupSlots.Count)
				throw new InvalidOperationException("Building does not have requested slot ");

			var powerupOffset = new Point(_powerupSlots[slot].X, _powerupSlots[slot].Y);
			powerup.Props.Offset.Offset(powerupOffset);
			powerup.Draw(obj, ds);
			// undo offset
			powerup.Props.Offset.Offset(-powerupOffset.X, -powerupOffset.Y);
		}