public Floor Get(ulong id) { if (ById.ContainsKey((ushort)id)) { return(ById[(ushort)id]); } else { //get from iff if (!Entries.ContainsKey((ushort)id)) { return(null); } Files.Formats.IFF.IffFile iff = this.Floors.Get(Entries[(ushort)id].FileName); if (iff == null) { return(null); } var far = iff.Get <SPR2>(1); var medium = iff.Get <SPR2>(257); var near = iff.Get <SPR2>(513); ById[(ushort)id] = new Floor { ID = (ushort)id, Near = near, Medium = medium, Far = far }; return(ById[(ushort)id]); } }
public Wall Get(ulong id, bool ts1) { if (ById.ContainsKey((ushort)id)) { return(ById[(ushort)id]); } else { //get from iff Files.Formats.IFF.IffFile iff = this.Walls.Get(Entries[(ushort)id].FileName); if (iff == null) { return(null); } var far = iff.Get <SPR>(1); var medium = iff.Get <SPR>(1793); var near = iff.Get <SPR>(2049); ById[(ushort)id] = new Wall { ID = (ushort)id, Near = near, Medium = medium, Far = far }; return(ById[(ushort)id]); } }
public void SaveChange(Files.Formats.IFF.IffFile file) { lock (this) { if (file.RuntimeInfo.State == IffRuntimeState.Standalone) { //just save out iff var filename = file.RuntimeInfo.Path; Directory.CreateDirectory(Path.GetDirectoryName(filename)); using (var stream = new FileStream(filename, FileMode.Create)) file.Write(stream); foreach (var chunk in file.ListAll()) { chunk.RuntimeInfo = ChunkRuntimeState.Normal; } } else { string dest = Path.Combine(FSOEnvironment.ContentDir, ((file.RuntimeInfo.State == IffRuntimeState.PIFFClone) ? "Objects/" : "Patch/User/")); Directory.CreateDirectory(dest); if (file.RuntimeInfo.State == IffRuntimeState.ReadOnly) { file.RuntimeInfo.State = IffRuntimeState.PIFFPatch; } var stringResources = new HashSet <Type> { typeof(STR), typeof(CTSS), typeof(TTAs) }; var sprites = (file.RuntimeInfo.UseCase == IffUseCase.ObjectSprites); file.RuntimeInfo.Patches.Clear(); var piff = FSO.Files.Formats.PiffEncoder.GeneratePiff(file, null, stringResources); string name = file.Filename.Substring(0, file.Filename.Length - 4); //get without extension if (piff != null) { var filename = dest + name + (sprites ? ".spf" : "") + ".piff"; using (var stream = new FileStream(filename, FileMode.Create)) piff.Write(stream); file.RuntimeInfo.Patches.Add(piff); } if (!sprites) { piff = FSO.Files.Formats.PiffEncoder.GeneratePiff(file, stringResources, null); if (piff != null) { var filename = dest + name + ".str.piff"; using (var stream = new FileStream(filename, FileMode.Create)) piff.Write(stream); file.RuntimeInfo.Patches.Add(piff); } } } file.RuntimeInfo.Dirty = false; ChangedFiles.Remove(file); } }
public void DiscardChange(Files.Formats.IFF.IffFile file) { lock (this) { UnregisterObjects(file); file.Revert(); ChangedFiles.Remove(file); RegisterObjects(file); } }
public void RegisterObjects(Files.Formats.IFF.IffFile file) { var objRegistry = Content.Get().WorldObjects; var defs = file.List <OBJD>(); if (defs != null) { foreach (var def in defs) { objRegistry.AddObject(file, def); } } }
/// <summary> /// Gets a resource. /// </summary> /// <param name="filename">The filename of the resource to get.</param> /// <returns>A GameGlobal instance containing the resource.</returns> public GameGlobal Get(string filename) { string filepath; Files.Formats.IFF.IffFile iff = null; filename = filename.ToLowerInvariant(); lock (Cache) { if (Cache.ContainsKey(filename)) { return(Cache[filename]); } filepath = Path.Combine(Content.Get().BasePath, "objectdata/globals/" + filename + ".iff"); //if we can't load this let it throw an exception... //probably sanity check this when we add user objects. if (File.Exists(filepath)) { iff = new Files.Formats.IFF.IffFile(filepath); } if (GlobalIffs != null) { iff = this.GlobalIffs.Get(filename + ".iff"); } OTFFile otf = null; try { otf = new OTFFile(Path.Combine(Content.Get().BasePath, "objectdata/globals/" + filename + ".otf")); } catch (IOException) { //if we can't load an otf, it probably doesn't exist. } var resource = new GameGlobalResource(iff, otf); var item = new GameGlobal { Resource = resource }; Cache.Add(filename, item); return(item); } }
public UIHeadlineRenderer(VMRuntimeHeadline headline) : base(headline) { if (Sprites == null) { Sprites = new Files.Formats.IFF.IffFile(Content.Content.Get().GetPath("objectdata/globals/sprites.iff")); WhitePx = TextureGenerator.GetPxWhite(GameFacade.GraphicsDevice); } if (Headline.Operand.Group != VMSetBalloonHeadlineOperandGroup.Algorithmic) { Sprite = Sprites.Get <SPR>((ushort)(GroupOffsets[(int)Headline.Operand.Group] + Headline.Index)); } if (Headline.Operand.Type != 255 && Headline.Operand.Type != 3) { BGSprite = Sprites.Get <SPR>((ushort)(GroupOffsets[(int)VMSetBalloonHeadlineOperandGroup.Balloon] + Headline.Operand.Type)); } LastZoom = WorldZoom.Near; RecalculateTarget(); }
/// <summary> /// Intializes a specific neighbourhood. Also counts as a save discard, since it unloads the current neighbourhood. /// </summary> /// <param name="id"></param> public void InitSpecific(int id) { DirtyAvatars.Clear(); ZoningDictionary.Clear(); FamilyForHouse.Clear(); var udName = "UserData" + ((id == 0) ? "" : (id + 1).ToString()); //simitone shouldn't modify existing ts1 data, since our house saves are incompatible. //therefore we should copy to the simitone user data. var userPath = FSOEnvironment.ContentDir; UserPath = userPath; MainResource = new Files.Formats.IFF.IffFile(Path.Combine(UserPath, "Neighborhood.iff")); Neighbors = MainResource.List <NBRS>().FirstOrDefault(); Neighborhood = MainResource.List <NGBH>().FirstOrDefault(); //todo: manage avatar iffs here }
public GameGlobalResource(Files.Formats.IFF.IffFile iff, OTFFile tuning) { this.Iff = iff; this.Tuning = tuning; }
public void IffChanged(Files.Formats.IFF.IffFile file) { file.RuntimeInfo.Dirty = true; lock (this) ChangedFiles.Add(file); }
public GameObjectResource(Files.Formats.IFF.IffFile iff, Files.Formats.IFF.IffFile sprites, OTFFile tuning, string iname) { this.Iff = iff; this.Sprites = sprites; this.Tuning = tuning; this.Name = iname; if (iff == null) { return; } var GLOBChunks = iff.List <GLOB>(); if (GLOBChunks != null && GLOBChunks[0].Name != "") { var sg = FSO.Content.Content.Get().WorldObjectGlobals.Get(GLOBChunks[0].Name); if (sg != null) { SemiGlobal = sg.Resource; //used for tuning constant fetching. } } TreeByName = new Dictionary <string, VMTreeByNameTableEntry>(); var bhavs = List <BHAV>(); if (bhavs != null) { foreach (var bhav in bhavs) { string name = bhav.ChunkLabel; for (var i = 0; i < name.Length; i++) { if (name[i] == 0) { name = name.Substring(0, i); break; } } if (!TreeByName.ContainsKey(name)) { TreeByName.Add(name, new VMTreeByNameTableEntry(bhav)); } } } //also add semiglobals if (SemiGlobal != null) { bhavs = SemiGlobal.List <BHAV>(); if (bhavs != null) { foreach (var bhav in bhavs) { string name = bhav.ChunkLabel; for (var i = 0; i < name.Length; i++) { if (name[i] == 0) { name = name.Substring(0, i); break; } } if (!TreeByName.ContainsKey(name)) { TreeByName.Add(name, new VMTreeByNameTableEntry(bhav)); } } } } }
public GameObject Get(ulong id) { if (Cache.ContainsKey(id)) { return(Cache[id]); } lock (Cache) { if (!Cache.ContainsKey(id)) { GameObjectReference reference; GameObjectResource resource = null; lock (Entries) { Entries.TryGetValue(id, out reference); if (reference == null) { //Console.WriteLine("Failed to get Object ID: " + id.ToString() + " (no resource)"); return(null); } lock (ProcessedFiles) { //if a file is processed but an object in it is not in the cache, it may have changed. //check for it again! ProcessedFiles.TryGetValue(reference.FileName, out resource); } } if (resource == null) { /** Better set this up! **/ Files.Formats.IFF.IffFile sprites = null, iff = null; OTFFile tuning = null; if (reference.Source == GameObjectSource.Far) { iff = this.Iffs.Get(reference.FileName + ".iff"); iff.RuntimeInfo.Path = reference.FileName; if (WithSprites) { if (reference.EpObject) { sprites = this.Sprites.Get(reference.FileName + ".iff"); } else { sprites = this.Sprites.Get(reference.FileName + ".spf"); } } tuning = this.TuningTables.Get(reference.FileName + ".otf"); } else { iff = new Files.Formats.IFF.IffFile(reference.FileName); iff.RuntimeInfo.Path = reference.FileName; iff.RuntimeInfo.State = IffRuntimeState.Standalone; } if (iff.RuntimeInfo.State == IffRuntimeState.PIFFPatch) { //OBJDs may have changed due to patch. Remove all file references ResetFile(iff); } iff.RuntimeInfo.UseCase = IffUseCase.Object; if (sprites != null) { sprites.RuntimeInfo.UseCase = IffUseCase.ObjectSprites; } resource = new GameObjectResource(iff, sprites, tuning, reference.FileName); lock (ProcessedFiles) { ProcessedFiles.GetOrAdd(reference.FileName, resource); } var piffModified = PIFFRegistry.GetOBJDRewriteNames(); foreach (var name in piffModified) { ProcessedFiles.GetOrAdd(name, GenerateResource(new GameObjectReference(this) { FileName = name.Substring(0, name.Length - 4), Source = GameObjectSource.Far })); } } foreach (var objd in resource.MainIff.List <OBJD>()) { var item = new GameObject { GUID = objd.GUID, OBJ = objd, Resource = resource }; Cache.GetOrAdd(item.GUID, item); } //0x3BAA9787 if (!Cache.ContainsKey(id)) { // Console.WriteLine("Failed to get Object ID: " + id.ToString() + " from resource " + resource.Name); return(null); } return(Cache[id]); } return(Cache[id]); } }
/// <summary> /// Initiates loading of floors. /// </summary> public void Init() { this.Entries = new Dictionary <ushort, FloorReference>(); this.ById = new Dictionary <ushort, Floor>(); this.DynamicFloorFromID = new Dictionary <string, ushort>(); var floorGlobalsPath = ContentManager.GetPath("objectdata/globals/floors.iff"); var floorGlobals = new Files.Formats.IFF.IffFile(floorGlobalsPath); FloorGlobals = floorGlobals; var buildGlobalsPath = ContentManager.GetPath("objectdata/globals/build.iff"); var buildGlobals = new Files.Formats.IFF.IffFile(buildGlobalsPath); //todo: centralize? /** There is a small handful of floors in a global file for some reason **/ ushort floorID = 1; var floorStrs = buildGlobals.Get <STR>(0x83); for (ushort i = 1; i < (floorStrs.Length / 3); i++) { var far = floorGlobals.Get <SPR2>(i); var medium = floorGlobals.Get <SPR2>((ushort)(i + 256)); var near = floorGlobals.Get <SPR2>((ushort)(i + 512)); //2048 is water tile this.AddFloor(new Floor { ID = floorID, Far = far, Medium = medium, Near = near }); Entries.Add(floorID, new FloorReference(this) { ID = floorID, FileName = "global", Name = floorStrs.GetString((i - 1) * 3 + 1), Price = int.Parse(floorStrs.GetString((i - 1) * 3 + 0)), Description = floorStrs.GetString((i - 1) * 3 + 2) }); floorID++; } var waterStrs = buildGlobals.Get <STR>(0x85); //add pools for catalog logic Entries.Add(65535, new FloorReference(this) { ID = 65535, FileName = "global", Price = int.Parse(waterStrs.GetString(0)), Name = waterStrs.GetString(1), Description = waterStrs.GetString(2) }); floorID = 256; var archives = new string[] { "housedata/floors/floors.far", "housedata/floors2/floors2.far", "housedata/floors3/floors3.far", "housedata/floors4/floors4.far" }; for (var i = 0; i < archives.Length; i++) { var archivePath = ContentManager.GetPath(archives[i]); var archive = new FAR1Archive(archivePath, true); var entries = archive.GetAllEntries(); foreach (var entry in entries) { var iff = new Files.Formats.IFF.IffFile(); DynamicFloorFromID[new string(entry.Key.TakeWhile(x => x != '.').ToArray()).ToLowerInvariant()] = floorID; var bytes = archive.GetEntry(entry); using (var stream = new MemoryStream(bytes)) { iff.Read(stream); } var catStrings = iff.Get <STR>(0); Entries.Add(floorID, new FloorReference(this) { ID = floorID, FileName = entry.Key, Name = catStrings.GetString(0), Price = int.Parse(catStrings.GetString(1)), Description = catStrings.GetString(2) }); floorID++; } archive.Close(); } NumFloors = floorID; this.Floors = new FAR1Provider <Files.Formats.IFF.IffFile>(ContentManager, new IffCodec(), new Regex(".*/floors.*\\.far")); Floors.Init(); }
public Blueprint LoadFromIff(Files.Formats.IFF.IffFile iff) { var simi = iff.Get <SIMI>(1); var hous = iff.Get <HOUS>(0); short size = simi.GlobalData[23]; var type = simi.GlobalData[35]; //ts1 lots are 64x64... but we convert them into dynamic size. //if (VM.UseWorld) this.Blueprint = new Blueprint(size, size); //VM.Entities = new List<VMEntity>(); //VM.Context = new VMContext(VM.Context.World); //VM.Context.VM = VM; VM.Context.Blueprint = Blueprint; VM.Context.Architecture = new VMArchitecture(size, size, Blueprint, VM.Context); FlipRoad = (hous.CameraDir & 1) > 0; VM.GlobalState = simi.GlobalData; VM.GlobalState[20] = 255; //Game Edition. Basically, what "expansion packs" are running. Let's just say all of them. VM.GlobalState[25] = 4; //as seen in EA-Land edith's simulator globals, this needs to be set for people to do their idle interactions. VM.GlobalState[17] = 4; //Runtime Code Version, is this in EA-Land. VM.SetGlobalValue(10, 1); //set house number VM.SetGlobalValue(32, 0); //simless build mode VM.Context.Clock.Hours = VM.GlobalState[0]; VM.Context.Clock.DayOfMonth = VM.GlobalState[1]; VM.Context.Clock.Minutes = VM.GlobalState[5]; VM.Context.Clock.MinuteFractions = (VM.GlobalState[6] * VM.Context.Clock.TicksPerMinute); VM.Context.Clock.Month = VM.GlobalState[7]; VM.Context.Clock.Year = VM.GlobalState[8]; var floorM = iff.Get <FLRm>(1)?.Entries ?? iff.Get <FLRm>(0)?.Entries ?? new List <WALmEntry>(); var wallM = iff.Get <WALm>(1)?.Entries ?? iff.Get <WALm>(0)?.Entries ?? new List <WALmEntry>(); var floorDict = BuildFloorDict(floorM); var wallDict = BuildWallDict(wallM); var arch = VM.Context.Architecture; //altitude as 0 var advFloors = iff.Get <ARRY>(11); var flags = iff.Get <ARRY>(8).TransposeData; if (advFloors != null) { //advanced walls and floors from modern ts1. use 16 bit wall/floor data. arch.Floors[0] = RemapFloors(DecodeAdvFloors(advFloors.TransposeData), floorDict, flags); arch.Floors[1] = RemapFloors(DecodeAdvFloors(iff.Get <ARRY>(111).TransposeData), floorDict, flags); //objects as 3 arch.Walls[0] = RemapWalls(DecodeAdvWalls(iff.Get <ARRY>(12).TransposeData), wallDict, floorDict); arch.Walls[1] = RemapWalls(DecodeAdvWalls(iff.Get <ARRY>(112).TransposeData), wallDict, floorDict); } else { arch.Floors[0] = RemapFloors(DecodeFloors(iff.Get <ARRY>(1).TransposeData), floorDict, flags); arch.Floors[1] = RemapFloors(DecodeFloors(iff.Get <ARRY>(101).TransposeData), floorDict, flags); //objects as 3 arch.Walls[0] = RemapWalls(DecodeWalls(iff.Get <ARRY>(2).TransposeData), wallDict, floorDict); arch.Walls[1] = RemapWalls(DecodeWalls(iff.Get <ARRY>(102).TransposeData), wallDict, floorDict); } //objects as 103 //Blueprint.Terrain.GrassState = iff.Get<ARRY>(6).TransposeData.Select(x => (byte)(127 - x)).ToArray(); //Blueprint.Terrain.DarkType = Content.Model.TerrainType.SAND; //arch.Terrain.LightType = Content.Model.TerrainType.GRASS; arch.SignalRedraw(); //targetgrass is 7 //flags is 8/108 var pools = iff.Get <ARRY>(9).TransposeData; var water = iff.Get <ARRY>(10).TransposeData; for (int i = 0; i < pools.Length; i++) { //pools in freeso are slightly different if (pools[i] != 0xff && pools[i] != 0x0) { arch.Floors[0][i].Pattern = 65535; } if (water[i] != 0xff && water[i] != 0x0) { arch.Floors[0][i].Pattern = 65534; } } arch.Floors[0] = ResizeFloors(arch.Floors[0], size); arch.Floors[1] = ResizeFloors(arch.Floors[1], size); arch.Walls[0] = ResizeWalls(arch.Walls[0], size); arch.Walls[1] = ResizeWalls(arch.Walls[1], size); //arch.FineBuildableArea = ResizeFlags(flags, size); //arch.Terrain.GrassState = ResizeGrass(arch.Terrain.GrassState, size); //arch.Terrain.Heights = Array.ConvertAll(ResizeGrass(DecodeHeights(iff.Get<ARRY>(0).TransposeData), size), x => (short)(x * 10)); //arch.Terrain.RegenerateCenters(); arch.RoofStyle = (uint)Content.Content.Get().WorldRoofs.NameToID(hous.RoofName.ToLowerInvariant() + ".bmp"); if (VM.UseWorld) { World.State.WorldSize = size; Blueprint.Terrain = CreateTerrain(size); //Blueprint.Altitude = arch.Terrain.Heights; //Blueprint.FineArea = arch.FineBuildableArea; } arch.RegenWallsAt(); arch.RegenRoomMap(); VM.Context.RegeneratePortalInfo(); var objm = iff.Get <OBJM>(1); var objt = iff.Get <OBJT>(0); int j = 0; for (int i = 0; i < objm.IDToOBJT.Length; i += 2) { if (objm.IDToOBJT[i] == 0) { continue; } MappedObject target; if (!objm.ObjectData.TryGetValue(objm.IDToOBJT[i], out target)) { continue; } var entry = objt.Entries[objm.IDToOBJT[i + 1] - 1]; target.Name = entry.Name; target.GUID = entry.GUID; //Console.WriteLine((objm.IDToOBJT[i]) + ": " + objt.Entries[objm.IDToOBJT[i + 1] - 1].Name); } var objFlrs = new ushort[][] { DecodeObjID(iff.Get <ARRY>(3)?.TransposeData), DecodeObjID(iff.Get <ARRY>(103)?.TransposeData) }; for (int flr = 0; flr < 2; flr++) { var objs = objFlrs[flr]; if (objs == null) { continue; } for (int i = 0; i < objs.Length; i++) { var obj = objs[i]; if (obj != 0) { var x = i % 64; var y = i / 64; MappedObject targ; if (!objm.ObjectData.TryGetValue(obj, out targ)) { continue; } targ.ArryX = x; targ.ArryY = y; targ.ArryLevel = flr + 1; } } } var content = Content.Content.Get(); foreach (var controller in ControllerObjects) { VM.Context.CreateObjectInstance(controller, LotTilePos.OUT_OF_WORLD, Direction.NORTH, false); } var ents = new List <Tuple <VMEntity, OBJM.MappedObject> >(); foreach (var obj in objm.ObjectData.Values) { if (ControllerObjects.Contains(obj.GUID)) { continue; } var res = content.WorldObjects.Get(obj.GUID, false); if (res == null) { continue; //failed to load this object } var objd = res.OBJ; if (res.OBJ.MasterID != 0) { var allObjs = res.Resource.List <OBJD>().Where(x => x.MasterID == res.OBJ.MasterID); var hasLead = allObjs.Any(x => x.MyLeadObject != 0); if ((hasLead && res.OBJ.MyLeadObject != 0) || (!hasLead && res.OBJ.SubIndex == 0)) { //this is the object //look for its master //multitile object.. find master objd var master = allObjs.FirstOrDefault(x => x.SubIndex < 0); if (master == null) { continue; } objd = master; obj.GUID = master.GUID; } else { continue; } } //if (DeleteAvatars && objd.ObjectType == OBJDType.Person) continue; //objm parent positioning //objects without positions inherit position from the objects in their "parent id". MappedObject src = obj; while (src != null && src.ParentID != 0) { if (objm.ObjectData.TryGetValue(src.ParentID, out src)) { if (src.ParentID == 0) { obj.ArryX = src.ArryX; obj.ArryY = src.ArryY; obj.ArryLevel = src.ArryLevel; } } } LotTilePos pos = LotTilePos.OUT_OF_WORLD; var dir = (Direction)(1 << obj.Direction); var nobj = VM.Context.CreateObjectInstance(obj.GUID, pos, dir, true); if (nobj.Objects.Count == 0) { continue; } if (obj.ContainerID == 0 && obj.ArryX != 0 && obj.ArryY != 0) { nobj.BaseObject.SetPosition(LotTilePos.FromBigTile((short)(obj.ArryX), (short)(obj.ArryY), (sbyte)obj.ArryLevel), dir, VM.Context); } ents.Add(new Tuple <VMEntity, OBJM.MappedObject>(nobj.BaseObject, obj)); } //place objects in slots foreach (var ent in ents) { var obj = ent.Item2; if (ent.Item1.Position == LotTilePos.OUT_OF_WORLD && obj.ContainerID != 0 && obj.ArryX != 0 && obj.ArryY != 0) { var dir = (Direction)(1 << obj.Direction); ent.Item1.SetPosition(LotTilePos.FromBigTile((short)(obj.ArryX), (short)(obj.ArryY), (sbyte)obj.ArryLevel), dir, VM.Context); /* * var target = ents.First(x => x.Item2.ObjectID == obj.ContainerID); * target.Item1.PlaceInSlot(ent.Item1, obj.ContainerSlot, true, VM.Context); */ } } var entClone = new List <VMEntity>(VM.Entities); foreach (var nobj in entClone) { nobj.ExecuteEntryPoint(11, VM.Context, true); } arch.SignalRedraw(); VM.Context.World?.InitBlueprint(Blueprint); arch.Tick(); return(Blueprint); }
/// <summary> /// Initiates loading of walls. /// </summary> public void Init() { WallStyleToIndex = WallStyleIDs.ToDictionary(x => x, x => Array.IndexOf(WallStyleIDs, x)); this.Entries = new Dictionary <ushort, WallReference>(); this.ById = new Dictionary <ushort, Wall>(); this.DynamicWallFromID = new Dictionary <string, ushort>(); this.StyleById = new Dictionary <ushort, WallStyle>(); this.WallStyles = new List <WallStyle>(); var wallGlobalsPath = ContentManager.GetPath("objectdata/globals/walls.iff"); WallGlobals = new Files.Formats.IFF.IffFile(wallGlobalsPath); var buildGlobalsPath = ContentManager.GetPath("objectdata/globals/build.iff"); var buildGlobals = new Files.Formats.IFF.IffFile(buildGlobalsPath); //todo: centralize? /** Get wall styles from globals file **/ var styleStrs = buildGlobals.Get <STR>(0x81); ushort wallID = 1; for (ushort i = 2; i < 512; i += 2) { var far = WallGlobals.Get <SPR>((ushort)(i)); var medium = WallGlobals.Get <SPR>((ushort)(i + 512)); var near = WallGlobals.Get <SPR>((ushort)(i + 1024)); var fard = WallGlobals.Get <SPR>((ushort)(i + 1)); var mediumd = WallGlobals.Get <SPR>((ushort)(i + 513)); var neard = WallGlobals.Get <SPR>((ushort)(i + 1025)); if (fard == null) { //no walls down, just render exactly the same fard = far; mediumd = medium; neard = near; } string name = null, description = null; int price = -1; int buyIndex = -1; WallStyleToIndex.TryGetValue(wallID, out buyIndex); if (buyIndex != -1) { price = int.Parse(styleStrs.GetString(buyIndex * 3)); name = styleStrs.GetString(buyIndex * 3 + 1); description = styleStrs.GetString(buyIndex * 3 + 2); } this.AddWallStyle(new WallStyle { ID = wallID, WallsUpFar = far, WallsUpMedium = medium, WallsUpNear = near, WallsDownFar = fard, WallsDownMedium = mediumd, WallsDownNear = neard, Price = price, Name = name, Description = description }); wallID++; } DynamicStyleID = 256; //styles loaded from objects start at 256. The objd reference is dynamically altered to reference this new id, //so only refresh wall cache at same time as obj cache! (do this on lot unload) /** Get wall patterns from globals file **/ var wallStrs = buildGlobals.Get <STR>(0x83); wallID = 0; for (ushort i = 0; i < 256; i++) { var far = WallGlobals.Get <SPR>((ushort)(i + 1536)); var medium = WallGlobals.Get <SPR>((ushort)(i + 1536 + 256)); var near = WallGlobals.Get <SPR>((ushort)(i + 1536 + 512)); this.AddWall(new Wall { ID = wallID, Far = far, Medium = medium, Near = near, }); if (i > 0 && i < (wallStrs.Length / 3) + 1) { Entries.Add(wallID, new WallReference(this) { ID = wallID, FileName = "global", Name = wallStrs.GetString((i - 1) * 3 + 1), Price = int.Parse(wallStrs.GetString((i - 1) * 3 + 0)), Description = wallStrs.GetString((i - 1) * 3 + 2) }); } wallID++; } Junctions = new Wall { ID = wallID, Far = WallGlobals.Get <SPR>(4096), Medium = WallGlobals.Get <SPR>(4097), Near = WallGlobals.Get <SPR>(4098), }; wallID = 256; var archives = new string[] { "housedata/walls/walls.far", "housedata/walls2/walls2.far", "housedata/walls3/walls3.far", "housedata/walls4/walls4.far" }; for (var i = 0; i < archives.Length; i++) { var archivePath = ContentManager.GetPath(archives[i]); var archive = new FAR1Archive(archivePath, true); var entries = archive.GetAllEntries(); foreach (var entry in entries) { var iff = new Files.Formats.IFF.IffFile(); DynamicWallFromID[Path.GetFileNameWithoutExtension(entry.ToString().Replace('\\', '/')).ToLowerInvariant()] = wallID; var bytes = archive.GetEntry(entry); using (var stream = new MemoryStream(bytes)) { iff.Read(stream); } var catStrings = iff.Get <STR>(0); Entries.Add(wallID, new WallReference(this) { ID = wallID, FileName = entry.Key, Name = catStrings.GetString(0), Price = int.Parse(catStrings.GetString(1)), Description = catStrings.GetString(2) }); wallID++; } archive.Close(); } this.Walls = new FAR1Provider <Files.Formats.IFF.IffFile>(ContentManager, new IffCodec(), new Regex(".*/walls.*\\.far")); Walls.Init(); NumWalls = wallID; }
/// <summary> /// Gets a resource. /// </summary> /// <param name="filename">The filename of the resource to get.</param> /// <returns>A GameGlobal instance containing the resource.</returns> public GameGlobal Get(string filename, bool ts1) { string filepath; Files.Formats.IFF.IffFile iff = null; filename = filename.ToLowerInvariant(); lock (Cache) { if (Cache.ContainsKey(filename)) { return(Cache[filename]); } if (!ts1) { filepath = Path.Combine(Content.Get().BasePath, "objectdata/globals/" + filename + ".iff"); //if we can't load this let it throw an exception... //probably sanity check this when we add user objects. if (File.Exists(filepath)) { iff = new Files.Formats.IFF.IffFile(filepath); } } if (GlobalFar != null && iff == null) { var Giff = new IffFile(); var bytes = GlobalFar.GetEntry(GlobalFar.GetAllEntries().FirstOrDefault(x => x.Key.ToLowerInvariant() == (filename + ".iff").ToLowerInvariant())); using (var stream = new MemoryStream(bytes)) { Giff.Read(stream); } if (Giff != null) { iff = Giff; } } OTFFile otf = null; try { otf = new OTFFile(Path.Combine(Content.Get().BasePath, "objectdata/globals/" + filename + ".otf")); } catch (IOException) { //if we can't load an otf, it probably doesn't exist. } var resource = new GameGlobalResource(iff, otf); var item = new GameGlobal { Resource = resource }; Cache.Add(filename, item); return(item); } }