public Wall Get(ulong id) { if (ById.ContainsKey((ushort)id)) { return(ById[(ushort)id]); } else { //get from 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 Texture2D GetFloorThumb(ushort id, GraphicsDevice device) { if (id < 256) { return(TextureUtils.Copy(device, ById[id].Near.Frames[0].GetTexture(device))); } else if (id == 65535) { return(TextureUtils.Copy(device, FloorGlobals.Get <SPR2>(0x420).Frames[0].GetTexture(device))); } else if (id == 65534) { var spr = FloorGlobals.Get <SPR2>(0x800); if (!spr.SpritePreprocessed) { spr.ZAsAlpha = true; spr.FloorCopy = 2; spr.SpritePreprocessed = true; } return(TextureUtils.Copy(device, spr.Frames[0].GetTexture(device))); } else { return(this.Floors.ThrowawayGet(Entries[(ushort)id].FileName).Get <SPR2>(513).Frames[0].GetTexture(device)); } }
public Wall Get(ulong id) { if (ById.ContainsKey((ushort)id)) { return(ById[(ushort)id]); } else { //get from iff WallReference entry = null; if (!Entries.TryGetValue((ushort)id, out entry)) { entry = Entries.Values.First(x => x.ID > 255); } IffFile iff = this.Walls.Get(entry.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 Floor Get(ulong id) { if (ById.ContainsKey((ushort)id)) { return(ById[(ushort)id]); } else { //get from iff if (!Entries.ContainsKey((ushort)id)) { return(null); } 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 Texture2D GetFloorThumb(ushort id, GraphicsDevice device) { if (id < 256) { return(TextureUtils.Copy(device, ById[id].Near.Frames[0].GetTexture(device))); } else if (id == 65535) { return(TextureUtils.Copy(device, FloorGlobals.Get <SPR2>(0x420).Frames[0].GetTexture(device))); } else { return(this.Floors.ThrowawayGet(Entries[(ushort)id].FileName).Get <SPR2>(513).Frames[0].GetTexture(device)); } }
/// <summary> /// Initiates loading of walls. /// </summary> public void Init() { var wallGlobalsPath = ContentManager.GetPath("objectdata/globals/walls.iff"); WallGlobals = new IffFile(wallGlobalsPath); var buildGlobalsPath = ContentManager.GetPath("objectdata/globals/build.iff"); BuildGlobals = new IffFile(buildGlobalsPath); //todo: centralize? InitGlobals(); ushort 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 IffFile(); DynamicWallFromID[new string(entry.Key.TakeWhile(x => x != '.').ToArray()).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(); } var far1 = new FAR1Provider <IffFile>(ContentManager, new IffCodec(), new Regex(".*/walls.*\\.far")); far1.Init(); Walls = far1; NumWalls = wallID; }
public Tuple <string, string> GetHouseNameDesc(int houseID) { STR res; if (houseID < 80) { res = NeighbourhoodDesc.Get <STR>((ushort)(houseID + 2000)); } else if (houseID < 90) { res = STDesc.Get <STR>((ushort)(houseID + 2000)); } else { res = MTDesc.Get <STR>((ushort)(houseID + 2000)); } if (res == null) { return(new Tuple <string, string>("", "")); } else { return(new Tuple <string, string>(res.GetString(0), res.GetString(1))); } }
public TS1NeighborhoodProvider(Content contentManager) { ContentManager = contentManager; MainResource = new IffFile(Path.Combine(contentManager.TS1BasePath, "UserData/Neighborhood.iff")); LotLocations = new IffFile(Path.Combine(contentManager.TS1BasePath, "UserData/LotLocations.iff")); var lotZoning = new IffFile(Path.Combine(contentManager.TS1BasePath, "UserData/LotZoning.iff")); var zones = lotZoning.Get <STR>(1); for (int i = 0; i < zones.Length; i++) { var split = zones.GetString(i).Split(','); ZoningDictionary[short.Parse(split[0])] = (short)((split[1] == " community") ? 1 : 0); } Neighbors = MainResource.List <NBRS>().FirstOrDefault(); Neighborhood = MainResource.List <NGBH>().FirstOrDefault(); FamilyForHouse = new Dictionary <short, FAMI>(); var families = MainResource.List <FAMI>(); foreach (var fam in families) { FamilyForHouse[(short)fam.HouseNumber] = fam; } }
public UIHeadlineRenderer(VMRuntimeHeadline headline) : base(headline) { if (Sprites == null) { Sprites = new FSO.Files.Formats.IFF.IffFile(FSO.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(); }
private void button6_Click(object sender, EventArgs e) { string current = listBox3.SelectedItem.ToString(); string userdata = comboBox1.SelectedItem.ToString(); var iff = new IffFile(userdata + "/Houses" + current + ".iff"); var simi = iff.Get <SIMI>(326); // int value = simi.ArchitectureValue(); //int rooms = simi.Rooms(); }
public UIHeadlineRenderer(VMRuntimeHeadline headline) : base(headline) { if (Sprites == null) { var content = FSO.Content.Content.Get(); Sprites = new FSO.Files.Formats.IFF.IffFile( content.TS1? Path.Combine(content.TS1BasePath, "GameData/Sprites.iff") : content.GetPath("objectdata/globals/sprites.iff") ); } 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; }
private void InitGlobals() { /** There is a small handful of floors in a global file for some reason **/ ushort floorID = 1; var floorStrs = BuildGlobals.Get <STR>(0x82); 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 far.FloorCopy = 1; medium.FloorCopy = 1; near.FloorCopy = 1; 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) }); Entries.Add(65534, new FloorReference(this) { ID = 65534, FileName = "global", Price = int.Parse(waterStrs.GetString(3)), Name = waterStrs.GetString(4), Description = waterStrs.GetString(5) }); floorID = 256; }
/// <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.StyleById = new Dictionary <ushort, WallStyle>(); this.WallStyles = new List <WallStyle>(); var wallGlobalsPath = ContentManager.GetPath("objectdata/globals/walls.iff"); WallGlobals = new IffFile(wallGlobalsPath); var buildGlobalsPath = ContentManager.GetPath("objectdata/globals/build.iff"); var buildGlobals = new 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" }; DynamicWallFromID = new Dictionary <string, ushort>(); 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 IffFile(); DynamicWallFromID[new string(entry.Key.TakeWhile(x => x != '.').ToArray()).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 <IffFile>(ContentManager, new IffCodec(), new Regex(".*/walls.*\\.far")); Walls.Init(); NumWalls = wallID; }
public FAMI GetFamily(ushort ID) { return(MainResource.Get <FAMI>(ID)); }
public BMP GetWallStyleIcon(ushort id) { return(WallGlobals.Get <BMP>(id)); }
public string GetVarScopeName(VMVariableScope scope) { return(Behaviour.Get <STR>(132).GetString((int)scope)); }
/// <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 = Path.Combine(FSOEnvironment.UserDir, udName + "/"); if (!Directory.Exists(userPath)) { var source = Path.Combine(ContentManager.TS1BasePath, udName + "/"); var destination = userPath; //quick and dirty copy. foreach (string dirPath in Directory.GetDirectories(source, "*", SearchOption.AllDirectories)) { Directory.CreateDirectory(dirPath.Replace('\\', '/').Replace(source, destination)); } foreach (string newPath in Directory.GetFiles(source, "*.*", SearchOption.AllDirectories)) { File.Copy(newPath, newPath.Replace('\\', '/').Replace(source, destination), true); } } UserPath = userPath; MainResource = new IffFile(Path.Combine(UserPath, "Neighborhood.iff")); LotLocations = new IffFile(Path.Combine(UserPath, "LotLocations.iff")); var lotZoning = new IffFile(Path.Combine(UserPath, "LotZoning.iff")); StreetNames = new IffFile(Path.Combine(UserPath, "StreetNames.iff")); NeighbourhoodDesc = new IffFile(Path.Combine(UserPath, "Houses/NeighborhoodDesc.iff")); STDesc = new IffFile(Path.Combine(UserPath, "Houses/STDesc.iff")); MTDesc = new IffFile(Path.Combine(UserPath, "Houses/MTDesc.iff")); var zones = lotZoning.Get <STR>(1); for (int i = 0; i < zones.Length; i++) { var split = zones.GetString(i).Split(','); ZoningDictionary[short.Parse(split[0])] = (short)((split[1] == " community") ? 1 : 0); } Neighbors = MainResource.List <NBRS>().FirstOrDefault(); Neighborhood = MainResource.List <NGBH>().FirstOrDefault(); TypeAttributes = MainResource.List <TATT>().FirstOrDefault(); FamilyForHouse = new Dictionary <short, FAMI>(); var families = MainResource.List <FAMI>(); foreach (var fam in families) { FamilyForHouse[(short)fam.HouseNumber] = fam; } LoadCharacters(true); //todo: manage avatar iffs here }
public override string GetBody(EditorScope scope) { var op = (VMSetBalloonHeadlineOperand)Operand; var result = new StringBuilder(); var content = Content.Content.Get(); if (Sprites == null) { Sprites = new IffFile(content.TS1 ? Path.Combine(content.TS1BasePath, "GameData/Sprites.iff") : content.GetPath("objectdata/globals/sprites.iff")); } result.AppendLine((op.OfStackOBJ) ? "Set Headline of Stack Object" : "Set my Headline"); if (op.Duration == 0) { result.Append("Clear Headline"); } else { var balloon = Sprites.Get <SPR>((ushort)(GroupOffsets[(int)VMSetBalloonHeadlineOperandGroup.Balloon] + op.Type)); string iconName; if (op.Group == VMSetBalloonHeadlineOperandGroup.Algorithmic) { if (op.Algorithmic < 2) { iconName = "Stack Object Icon"; } else { iconName = "Object in Local[" + op.Algorithmic + "] Icon"; } } else { var icon = Sprites.Get <SPR>((ushort)(GroupOffsets[(int)op.Group] + op.Index)); iconName = icon?.ChunkLabel ?? op.Index.ToString(); } if (op.Indexed) { iconName += " + temp[0]"; } result.AppendLine("Category " + op.Group.ToString() + ", Type " + iconName); result.AppendLine("Balloon Type " + balloon?.ChunkLabel ?? "none"); result.Append("Duration " + op.Duration + ((op.DurationInLoops) ? " loops" : " ticks")); var flagStr = new StringBuilder(); string prepend = ""; if (op.Crossed) { flagStr.Append("Crossed"); prepend = ", "; } if (op.Backwards) { flagStr.Append(prepend + "Backwards"); prepend = ", "; } if (op.Inactive) { flagStr.Append(prepend + "Inactive"); prepend = ", "; } if (flagStr.Length != 0) { result.Append("\r\n("); result.Append(flagStr); result.Append(")"); } } return(result.ToString()); }
public override Texture2D DrawFrame(World world) { if (!Inited) { 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(); Inited = true; } if (LastZoom != world.State.Zoom || Texture == null) { Invalidated = true; LastZoom = world.State.Zoom; RecalculateTarget(); if (Texture == null) { return(null); } } var GD = GameFacade.GraphicsDevice; var batch = GameFacade.Screens.SpriteBatch; if (DrawSkill) { ProcessSkill(); } else if (Headline.Anim % 15 == 0 && Sprite != null && Sprite.Frames.Count > 3) { Invalidated = true; } if (Invalidated) //todo: logic for drawing skills less often { GD.SetRenderTarget(Texture); GD.Clear(Color.Transparent); batch.Begin(); if (BGSprite != null) { batch.Draw(BGSprite.Frames[ZoomFrame].GetTexture(GD), new Vector2(), Color.White); } Texture2D main = null; Vector2 offset = new Vector2(); if (Sprite != null) { var animFrame = (Headline.Anim / 15) % (Sprite.Frames.Count / 3); main = Sprite.Frames[ZoomFrame + animFrame * 3].GetTexture(GD); offset = new Vector2(0, 4); } else if (AlgTex != null) { main = AlgTex; offset = new Vector2(0, -6); } offset /= ZoomToDiv[(int)LastZoom]; if (main != null && Texture != null) { batch.Draw(main, new Vector2(Texture.Width / 2 - main.Width / 2, Texture.Height / 2 - main.Height / 2) + offset, Color.White); } if (Headline.Operand.Crossed) { Texture2D Cross = Sprites.Get <SPR>(0x67).Frames[ZoomFrame].GetTexture(GD); batch.Draw(Cross, new Vector2(Texture.Width / 2 - Cross.Width / 2, Texture.Height / 2 - Cross.Height / 4), Color.White); } if (DrawSkill) { batch.Draw(WhitePx, new Rectangle(88, 4, 71, 41), new Color(92, 92, 92)); var font = GameFacade.MainFont.GetNearest(14).Font; Vector2 fontOrigin = font.MeasureString(SkillString) / 2; batch.DrawString(font, SkillString, new Vector2(88 + 35, 15) - fontOrigin * 0.60f, new Color(255, 249, 157), 0, new Vector2(), 0.60f, SpriteEffects.None, 0); fontOrigin = font.MeasureString(SpeedString) / 2; batch.DrawString(font, SpeedString, new Vector2(88 + 35, 34) - fontOrigin * 0.60f, new Color(255, 249, 157), 0, new Vector2(), 0.60f, SpriteEffects.None, 0); } batch.End(); GD.SetRenderTarget(null); Invalidated = false; } return(Texture); }
public Blueprint LoadFromIff(IffFile iff) { var size = 64; //ts1 lots are fixed size if (VM.UseWorld) { this.Blueprint = new Blueprint(size, size); } VM.Entities = new List <VMEntity>(); VM.Scheduler = new Engine.VMScheduler(VM); 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); 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); if (advFloors != null) { //advanced walls and floors from modern ts1. use 16 bit wall/floor data. arch.Floors[0] = RemapFloors(DecodeAdvFloors(advFloors.TransposeData), floorDict); arch.Floors[1] = RemapFloors(DecodeAdvFloors(iff.Get <ARRY>(111).TransposeData), floorDict); //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); arch.Floors[1] = RemapFloors(DecodeFloors(iff.Get <ARRY>(101).TransposeData), floorDict); //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 arch.Terrain.GrassState = iff.Get <ARRY>(6).TransposeData.Select(x => (byte)(127 - x)).ToArray(); //arch.Terrain.DarkType = Content.Model.TerrainType.SAND; //arch.Terrain.LightType = Content.Model.TerrainType.GRASS; arch.SignalTerrainRedraw(); //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; } } if (VM.UseWorld) { World.State.WorldSize = size; Blueprint.Terrain = CreateTerrain(size); } arch.RebuildWallsAt(); 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); } 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); if (res == null) { continue; //failed to load this object } 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; } obj.GUID = master.GUID; } else { 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).BaseObject; if (nobj == null) { continue; } if (obj.ContainerID == 0 && obj.ArryX != 0 && obj.ArryY != 0) { nobj.SetPosition(LotTilePos.FromBigTile((short)(obj.ArryX), (short)(obj.ArryY), (sbyte)obj.ArryLevel), dir, VM.Context, VMPlaceRequestFlags.AcceptSlots); } for (int i = 0; i < nobj.MultitileGroup.Objects.Count; i++) { nobj.MultitileGroup.Objects[i].ExecuteEntryPoint(11, VM.Context, true); } ents.Add(new Tuple <VMEntity, OBJM.MappedObject>(nobj, 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, VMPlaceRequestFlags.AcceptSlots); /* * var target = ents.First(x => x.Item2.ObjectID == obj.ContainerID); * target.Item1.PlaceInSlot(ent.Item1, obj.ContainerSlot, true, VM.Context); */ } } arch.SignalTerrainRedraw(); VM.Context.World?.InitBlueprint(Blueprint); arch.Tick(); return(this.Blueprint); }
/// <summary> /// Initiates loading of floors. /// </summary> public void Init() { this.Entries = new Dictionary <ushort, FloorReference>(); this.ById = new Dictionary <ushort, Floor>(); var floorGlobalsPath = ContentManager.GetPath("objectdata/globals/floors.iff"); var floorGlobals = new IffFile(floorGlobalsPath); FloorGlobals = floorGlobals; var buildGlobalsPath = ContentManager.GetPath("objectdata/globals/build.iff"); var buildGlobals = new 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 IffFile(); 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 <IffFile>(ContentManager, new IffCodec(), new Regex(".*/floors.*\\.far")); Floors.Init(); }
private void InitGlobals() { /** 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 (far != null) { near.WallStyle = true; medium.WallStyle = true; far.WallStyle = true; } if (fard == null) { //no walls down, just render exactly the same fard = far; mediumd = medium; neard = near; } else { neard.WallStyle = true; mediumd.WallStyle = true; fard.WallStyle = true; } 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; }
public short GetJobData(ushort jobID, int jobLevel, int data) { return((short)(JobResource.Get <CARR>(jobID)?.GetJobData(jobLevel, data) ?? 0)); }
public Blueprint LoadFromIff(IffFile iff) { var simi = iff.Get <SIMI>(1); var hous = iff.Get <HOUS>(0); Size = simi.GlobalData[23]; var type = simi.GlobalData[35]; var size = Size; //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.Scheduler = new Engine.VMScheduler(VM); VM.TS1State.SimulationInfo = simi; 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, HouseNumber); //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]; TerrainType ttype = TerrainType.GRASS; if (!HouseNumToType.TryGetValue(HouseNumber, out ttype)) { ttype = TerrainType.GRASS; } VM.Context.Architecture.Terrain.LightType = (ttype == TerrainType.SAND) ? TerrainType.GRASS : ttype; VM.Context.Architecture.Terrain.DarkType = ttype; 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 arch.Terrain.GrassState = iff.Get <ARRY>(6).TransposeData.Select(x => (byte)(127 - x)).ToArray(); //arch.Terrain.DarkType = Content.Model.TerrainType.SAND; //arch.Terrain.LightType = Content.Model.TerrainType.GRASS; arch.SignalTerrainRedraw(); //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.GameContent.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.RebuildWallsAt(); 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; } if (!objm.ObjectData.TryGetValue(objm.IDToOBJT[i], out var 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; if (!objm.ObjectData.TryGetValue(obj, out var targ)) { continue; } targ.ArryX = x; targ.ArryY = y; targ.ArryLevel = flr + 1; } } } var content = Content.GameContent.Get; foreach (var controller in ControllerObjects) { VM.Context.CreateObjectInstance(controller, LotTilePos.OUT_OF_WORLD, Direction.NORTH); } 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); 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).BaseObject; if (nobj == null) { continue; } if (obj.ContainerID == 0 && obj.ArryX != 0 && obj.ArryY != 0) { nobj.SetPosition(LotTilePos.FromBigTile((short)(obj.ArryX), (short)(obj.ArryY), (sbyte)obj.ArryLevel), dir, VM.Context, VMPlaceRequestFlags.AcceptSlots); } ents.Add(new Tuple <VMEntity, OBJM.MappedObject>(nobj, 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, VMPlaceRequestFlags.AcceptSlots); /* * 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.SignalTerrainRedraw(); VM.Context.World?.InitBlueprint(Blueprint); arch.Tick(); return(this.Blueprint); }