예제 #1
0
        /// <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));
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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;
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
 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);
     }
 }
예제 #9
0
        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]));
        }
예제 #10
0
        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);
                }
            }
        }
예제 #11
0
        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));
            }
        }
예제 #12
0
        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);
                }
            }
        }
예제 #13
0
        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);
            }
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
 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);
         }
     }
 }
예제 #17
0
        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]);
        }
예제 #18
0
        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);
        }
예제 #19
0
        /// <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);
        }
예제 #20
0
 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");
     }
 }
예제 #21
0
        // 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);
            }
        }
예제 #22
0
        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)),
                });
            }
        }
예제 #23
0
 private void LoadAnimDrawable(AnimDrawable anim)
 {
     InitDrawableDefaults(anim);
     anim.LoadFromRules();
     anim.Shp = VFS.Open <ShpFile>(anim.Image + ".shp");
 }
예제 #24
0
        /// <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);
        }
예제 #25
0
        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;
        }
예제 #26
0
        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);
        }
예제 #27
0
        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;
                }
            }
        }
예제 #28
0
        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
        }
예제 #29
0
        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);
                    }
                }
            }
        }
예제 #30
0
        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"));
        }