public VMArchitecture(int width, int height, Blueprint blueprint, VMContext context) { this.Context = context; this.Width = width; this.Height = height; var numTiles = width * height; this.WallsAt = new List<int>[Stories]; this.Walls = new WallTile[Stories][]; this.VisWalls = new WallTile[Stories][]; this.Floors = new FloorTile[Stories][]; this.VisFloors = new FloorTile[Stories][]; this.ObjectSupport = new bool[Stories][]; //true if there's an object support in the specified position this.Supported = new bool[Stories-1][]; //no supported array for bottom floor. true if this tile is supported. blueprint.Supported = Supported; this.Rooms = new RoomMap[Stories]; for (int i = 0; i < Stories; i++) { this.WallsAt[i] = new List<int>(); this.Walls[i] = new WallTile[numTiles]; this.VisWalls[i] = new WallTile[numTiles]; this.Floors[i] = new FloorTile[numTiles]; this.VisFloors[i] = new FloorTile[numTiles]; this.ObjectSupport[i] = new bool[numTiles]; if (i<Stories-1) this.Supported[i] = new bool[numTiles]; this.Rooms[i] = new RoomMap(); } this.RoomData = new List<BlueprintRoom>(); this.WorldUI = blueprint; this.Commands = new List<VMArchitectureCommand>(); this.Commands = new List<VMArchitectureCommand>(); WallsDirty = true; FloorsDirty = true; RealMode = true; Redraw = true; }
public virtual void SetIndivPosition(LotTilePos pos, Direction direction, VMContext context, VMPlacementResult info) { Direction = direction; //TODO: clean the f**k up out of OUT_OF_WORLD if (this is VMGameObject) context.Blueprint.ChangeObjectLocation((ObjectComponent)WorldUI, (pos==LotTilePos.OUT_OF_WORLD)?LotTilePos.FromBigTile(-1,-1,1):pos); Position = pos; if (info.Container != null) info.Container.PlaceInSlot(this, 0); }
public virtual VMPlacementError SetPosition(LotTilePos pos, Direction direction, VMContext context) { return MultitileGroup.ChangePosition(pos, direction, context); }
public virtual void PrePositionChange(VMContext context) { if (Container != null) { Container.ClearSlot(ContainerSlot); return; } if (Position == LotTilePos.OUT_OF_WORLD) return; var arch = context.Architecture; if (((VMEntityFlags2)ObjectData[(int)VMStackObjectVariable.FlagField2] & (VMEntityFlags2.ArchitectualWindow | VMEntityFlags2.ArchitectualDoor)) > 0) { //if wall or door, attempt to place style on wall var placeFlags = (WallPlacementFlags)ObjectData[(int)VMStackObjectVariable.WallPlacementFlags]; var dir = DirectionToWallOff(Direction); if ((placeFlags & WallPlacementFlags.WallRequiredInFront) > 0) SetWallStyle((dir) % 4, arch, 0); if ((placeFlags & WallPlacementFlags.WallRequiredOnRight) > 0) SetWallStyle((dir+1) % 4, arch, 0); if ((placeFlags & WallPlacementFlags.WallRequiredBehind) > 0) SetWallStyle((dir+2) % 4, arch, 0); if ((placeFlags & WallPlacementFlags.WallRequiredOnLeft) > 0) SetWallStyle((dir+3) % 4, arch, 0); } SetWallUse(arch, false); if (GetValue(VMStackObjectVariable.Category) == 8) context.Architecture.SetObjectSupported(Position.TileX, Position.TileY, Position.Level, false); if (EntryPoints[15].ActionFunction != 0) { //portal context.RemoveRoomPortal(this); } context.UnregisterObjectPos(this); }
public void PushUserInteraction(int interaction, VMEntity caller, VMContext context) { var Action = TreeTable.InteractionByIndex[(uint)interaction]; ushort ActionID = Action.ActionFunction; var function = GetBHAVWithOwner(ActionID, context); VMEntity carriedObj = caller.GetSlot(0); var routine = context.VM.Assemble(function.bhav); caller.Thread.EnqueueAction( new TSO.Simantics.engine.VMQueuedAction { Callee = this, CodeOwner = function.owner, Routine = routine, Name = TreeTableStrings.GetString((int)Action.TTAIndex), StackObject = this, Args = ((Action.MaskFlags & InteractionMaskFlags.AvailableWhenCarrying) > 0) ? new short[] { (carriedObj == null)?(short)0:carriedObj.ObjectID, 0, 0, 0 }:null, InteractionNumber = interaction, Priority = VMQueuePriority.UserDriven } ); }
public override void Init(VMContext context) { ((AvatarComponent)WorldUI).ObjectID = (ushort)ObjectID; base.Init(context); SetAvatarBodyStrings(Object.Resource.Get<STR>(Object.OBJ.BodyStringID), context); //init walking strings var GlobWalk = context.Globals.Resource.Get<STR>(150); for (int i = 0; i < GlobWalk.Length; i++) { WalkAnimations[i] = GlobWalk.GetString(i); } var SpecialWalk = Object.Resource.Get<STR>(150); if (SpecialWalk != null) { for (int i = 0; i < SpecialWalk.Length; i++) { var str = SpecialWalk.GetString(i); if (str != "") WalkAnimations[i] = str; } } SetMotiveData(VMMotive.Comfort, 100); SetPersonData(VMPersonDataVariable.NeatPersonality, 1000); //for testing wash hands after toilet SetPersonData(VMPersonDataVariable.OnlineJobID, 1); //for testing wash hands after toilet SetPersonData(VMPersonDataVariable.IsHousemate, 2); SetPersonData(VMPersonDataVariable.CreativitySkill, 15); }
public virtual void PositionChange(VMContext context) { var blueprint = context.Blueprint; if (((VMEntityFlags2)ObjectData[(int)VMStackObjectVariable.FlagField2] & (VMEntityFlags2.ArchitectualWindow | VMEntityFlags2.ArchitectualDoor)) > 0) { //if wall or door, attempt to place style on wall if (Object.OBJ.WallStyle > 21 && Object.OBJ.WallStyle < 256) { //first thing's first, is the style between 22-255 inclusive? If it is, then the style is stored in the object. Need to load its sprites and change the id for the objd. var id = Object.OBJ.WallStyleSpriteID; var style = new WallStyle() { WallsUpFar = Object.Resource.Get<SPR>(id), WallsUpMedium = Object.Resource.Get<SPR>((ushort)(id + 1)), WallsUpNear = Object.Resource.Get<SPR>((ushort)(id + 2)), WallsDownFar = Object.Resource.Get<SPR>((ushort)(id + 3)), WallsDownMedium = Object.Resource.Get<SPR>((ushort)(id + 4)), WallsDownNear = Object.Resource.Get<SPR>((ushort)(id + 5)) }; Object.OBJ.WallStyle = TSO.Content.Content.Get().WorldWalls.AddDynamicWallStyle(style); } var placeFlags = (WallPlacementFlags)ObjectData[(int)VMStackObjectVariable.WallPlacementFlags]; var dir = DirectionToWallOff(Direction); if ((placeFlags & WallPlacementFlags.WallRequiredInFront) > 0) SetWallStyle((dir) % 4, blueprint, Object.OBJ.WallStyle); if ((placeFlags & WallPlacementFlags.WallRequiredOnRight) > 0) SetWallStyle((dir+1) % 4, blueprint, Object.OBJ.WallStyle); if ((placeFlags & WallPlacementFlags.WallRequiredBehind) > 0) SetWallStyle((dir+2) % 4, blueprint, Object.OBJ.WallStyle); if ((placeFlags & WallPlacementFlags.WallRequiredOnLeft) > 0) SetWallStyle((dir+3) % 4, blueprint, Object.OBJ.WallStyle); } if (EntryPoints[15].ActionFunction != 0) { //portal context.AddRoomPortal(this); } context.RegisterObjectPos(this); }
public VMBHAVOwnerPair GetBHAVWithOwner(ushort ActionID, VMContext context) { BHAV bhav; GameIffResource CodeOwner; if (ActionID < 4096) { //global bhav = context.Globals.Resource.Get<BHAV>(ActionID); //CodeOwner = context.Globals.Resource; } else if (ActionID < 8192) { //local bhav = Object.Resource.Get<BHAV>(ActionID); } else { //semi-global bhav = SemiGlobal.Resource.Get<BHAV>(ActionID); //CodeOwner = SemiGlobal.Resource; } CodeOwner = Object.Resource; if (bhav == null) throw new Exception("Invalid BHAV call!"); return new VMBHAVOwnerPair(bhav, CodeOwner); }
public virtual void Init(VMContext context) { GenerateTreeByName(context); this.Thread = new VMThread(context, this, this.Object.OBJ.StackSize); ExecuteEntryPoint(0, context, true); //Init ExecuteEntryPoint(1, context, false); //Main }
public void ExecuteEntryPoint(int entry, VMContext context, bool runImmediately) { if (entry == 11) { //user placement, hack to do auto floor removal/placement for stairs if (Object.OBJ.LevelOffset > 0 && Position != LotTilePos.OUT_OF_WORLD) { var floor = context.Architecture.GetFloor(Position.TileX, Position.TileY, Position.Level); var placeFlags = (VMPlacementFlags)ObjectData[(int)VMStackObjectVariable.PlacementFlags]; if ((placeFlags & VMPlacementFlags.InAir) > 0) context.Architecture.SetFloor(Position.TileX, Position.TileY, Position.Level, new FloorTile(), true); if ((placeFlags & VMPlacementFlags.OnFloor) > 0 && (floor.Pattern == 0)) context.Architecture.SetFloor(Position.TileX, Position.TileY, Position.Level, new FloorTile { Pattern = 1 } , true); } } if (EntryPoints[entry].ActionFunction > 255) { BHAV bhav; GameIffResource CodeOwner; ushort ActionID = EntryPoints[entry].ActionFunction; if (ActionID < 4096) { //global bhav = context.Globals.Resource.Get<BHAV>(ActionID); } else if (ActionID < 8192) { //local bhav = Object.Resource.Get<BHAV>(ActionID); } else { //semi-global bhav = SemiGlobal.Resource.Get<BHAV>(ActionID); } CodeOwner = Object.Resource; var routine = context.VM.Assemble(bhav); if (bhav == null) return; //throw new Exception("Invalid BHAV call!"); short[] Args = null; VMEntity StackOBJ = null; if (entry == 1) { if (MainParam != 0) { Args = new short[4]; Args[0] = MainParam; MainParam = 0; } if (MainStackOBJ != 0) { StackOBJ = context.VM.GetObjectById(MainStackOBJ); MainStackOBJ = 0; } } var action = new TSO.Simantics.engine.VMQueuedAction { Callee = this, CodeOwner = CodeOwner, /** Main function **/ StackObject = StackOBJ, Routine = routine, Args = Args }; if (runImmediately) VMThread.EvaluateCheck(context, this, action); else this.Thread.EnqueueAction(action); } }
public void GenerateTreeByName(VMContext context) { TreeByName = new Dictionary<string, VMTreeByNameTableEntry>(); var bhavs = Object.Resource.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; } } TreeByName.Add(name, new VMTreeByNameTableEntry(bhav, Object.Resource)); } } //also add semiglobals if (SemiGlobal != null) { bhavs = SemiGlobal.Resource.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, Object.Resource)); } } } }
public void Delete(bool cleanupAll, VMContext context) { if (cleanupAll) MultitileGroup.Delete(context); else { PrePositionChange(context); context.RemoveObjectInstance(this); MultitileGroup.Objects.Remove(this); //we're no longer part of the multitile group } }
public virtual void SetPosition(short x, short y, sbyte level, Direction direction, VMContext context) { if (MultitileGroup != null) MultitileGroup.ChangePosition(x, y, level, direction, context); else { Direction = direction; if (this is VMGameObject) context.Blueprint.ChangeObjectLocation((ObjectComponent)WorldUI, (short)x, (short)y, (sbyte)level); else Position = new Vector3(x+0.5f, y+0.5f, level * 3); PositionChange(context); } }
public void PushUserInteraction(int interaction, VMEntity caller, VMContext context) { var Action = TreeTable.InteractionByIndex[(uint)interaction]; ushort ActionID = Action.ActionFunction; var function = GetBHAVWithOwner(ActionID, context); var routine = context.VM.Assemble(function.bhav); caller.Thread.EnqueueAction( new TSO.Simantics.engine.VMQueuedAction { Callee = this, CodeOwner = function.owner, Routine = routine, Name = TreeTableStrings.GetString((int)Action.TTAIndex), StackObject = this, InteractionNumber = interaction, Priority = VMQueuePriority.UserDriven } ); }
/// <summary> /// Constructs a new Virtual Machine instance. /// </summary> /// <param name="context">The VMContext instance to use.</param> public VM(VMContext context) { context.VM = this; ThreadLock = this; this.Context = context; }
public virtual void PositionChange(VMContext context) { if (Container != null) return; if (Position == LotTilePos.OUT_OF_WORLD) return; var arch = context.Architecture; if (((VMEntityFlags2)ObjectData[(int)VMStackObjectVariable.FlagField2] & (VMEntityFlags2.ArchitectualWindow | VMEntityFlags2.ArchitectualDoor)) > 0) { //if wall or door, attempt to place style on wall if (Object.OBJ.WallStyle > 21 && Object.OBJ.WallStyle < 256) { //first thing's first, is the style between 22-255 inclusive? If it is, then the style is stored in the object. Need to load its sprites and change the id for the objd. var id = Object.OBJ.WallStyleSpriteID; var style = new WallStyle() { WallsUpFar = Object.Resource.Get<SPR>(id), WallsUpMedium = Object.Resource.Get<SPR>((ushort)(id + 1)), WallsUpNear = Object.Resource.Get<SPR>((ushort)(id + 2)), WallsDownFar = Object.Resource.Get<SPR>((ushort)(id + 3)), WallsDownMedium = Object.Resource.Get<SPR>((ushort)(id + 4)), WallsDownNear = Object.Resource.Get<SPR>((ushort)(id + 5)) }; Object.OBJ.WallStyle = TSO.Content.Content.Get().WorldWalls.AddDynamicWallStyle(style); } var placeFlags = (WallPlacementFlags)ObjectData[(int)VMStackObjectVariable.WallPlacementFlags]; var dir = DirectionToWallOff(Direction); if ((placeFlags & WallPlacementFlags.WallRequiredInFront) > 0) SetWallStyle((dir) % 4, arch, Object.OBJ.WallStyle); if ((placeFlags & WallPlacementFlags.WallRequiredOnRight) > 0) SetWallStyle((dir+1) % 4, arch, Object.OBJ.WallStyle); if ((placeFlags & WallPlacementFlags.WallRequiredBehind) > 0) SetWallStyle((dir+2) % 4, arch, Object.OBJ.WallStyle); if ((placeFlags & WallPlacementFlags.WallRequiredOnLeft) > 0) SetWallStyle((dir+3) % 4, arch, Object.OBJ.WallStyle); } SetWallUse(arch, true); if (GetValue(VMStackObjectVariable.Category) == 8) context.Architecture.SetObjectSupported(Position.TileX, Position.TileY, Position.Level, true); if (EntryPoints[15].ActionFunction != 0) { //portal context.AddRoomPortal(this); } context.RegisterObjectPos(this); ExecuteEntryPoint(9, context, true); //Placement }
public override void Init(VMContext context) { base.Init(context); SetAvatarBodyStrings(Object.Resource.Get<STR>(Object.OBJ.BodyStringID), context); //init walking strings var GlobWalk = context.Globals.Resource.Get<STR>(150); for (int i = 0; i < GlobWalk.Length; i++) { WalkAnimations[i] = GlobWalk.GetString(i); } var SpecialWalk = Object.Resource.Get<STR>(150); if (SpecialWalk != null) { for (int i = 0; i < SpecialWalk.Length; i++) { var str = SpecialWalk.GetString(i); if (str != "") WalkAnimations[i] = str; } } SetMotiveData(VMMotive.Comfort, 100); SetPersonData(VMPersonDataVariable.NeatPersonality, 1000); //for testing wash hands after toilet }
public VMPlacementResult PositionValid(LotTilePos pos, Direction direction, VMContext context) { if (pos == LotTilePos.OUT_OF_WORLD) return new VMPlacementResult(); else if (context.IsOutOfBounds(pos)) return new VMPlacementResult { Status = VMPlacementError.LocationOutOfBounds }; //TODO: speedup with exit early checks //TODO: corner checks (wtf uses this) var arch = context.Architecture; var wall = arch.GetWall(pos.TileX, pos.TileY, pos.Level); //todo: preprocess to check which walls are real solid walls. VMPlacementError wallValid = WallChangeValid(wall, direction, true); if (wallValid != VMPlacementError.Success) return new VMPlacementResult { Status = wallValid }; var floor = arch.GetFloor(pos.TileX, pos.TileY, pos.Level); //todo: preprocess to check which walls are real solid walls. VMPlacementError floorValid = FloorChangeValid(floor, pos.Level); if (floorValid != VMPlacementError.Success) return new VMPlacementResult { Status = floorValid }; //we've passed the wall test, now check if we intersect any objects. var valid = context.GetObjPlace(this, pos); return valid; }
public void SetAvatarBodyStrings(STR data, VMContext context) { if (data == null) return; try { var body = data.GetString(1); var randBody = data.GetString(9); if (randBody != "") { var bodySpl = randBody.Split(';'); BodyOutfit = Convert.ToUInt64(bodySpl[context.NextRandom((ulong)bodySpl.Length)], 16); } else if (body != "") { BodyOutfit = Convert.ToUInt64(body, 16); } var head = data.GetString(2); var randHead = data.GetString(10); if (randHead != "") { var headSpl = randHead.Split(';'); HeadOutfit = Convert.ToUInt64(headSpl[context.NextRandom((ulong)headSpl.Length)], 16); } else if (head != "") { HeadOutfit = Convert.ToUInt64(head, 16); } } catch { //head or body invalid, resort to default. } var gender = data.GetString(12); var genVar = (int)VMPersonDataVariable.Gender; if (gender.Equals("male", StringComparison.InvariantCultureIgnoreCase)) PersonData[genVar] = 0; else if (gender.Equals("female", StringComparison.InvariantCultureIgnoreCase)) PersonData[genVar] = 1; else if (gender.Equals("dogmale", StringComparison.InvariantCultureIgnoreCase)) PersonData[genVar] = 8; else if (gender.Equals("dogfemale", StringComparison.InvariantCultureIgnoreCase)) PersonData[genVar] = 9; else if (gender.Equals("catmale", StringComparison.InvariantCultureIgnoreCase)) PersonData[genVar] = 16; else if (gender.Equals("catfemale", StringComparison.InvariantCultureIgnoreCase)) PersonData[genVar] = 17; var names = data.GetString(11); if (names != "") { var nameSpl = names.Split(';'); Name = nameSpl[context.NextRandom((ulong)nameSpl.Length)]; } PersonData[(int)VMPersonDataVariable.PersonsAge] = Convert.ToInt16(data.GetString(13)); var skinTone = data.GetString(14); if (skinTone.Equals("lgt", StringComparison.InvariantCultureIgnoreCase)) SkinTone = AppearanceType.Light; else if (skinTone.Equals("med", StringComparison.InvariantCultureIgnoreCase)) SkinTone = AppearanceType.Medium; else if (skinTone.Equals("drk", StringComparison.InvariantCultureIgnoreCase)) SkinTone = AppearanceType.Dark; }
public void ExecuteEntryPoint(int entry, VMContext context, bool runImmediately) { if (EntryPoints[entry].ActionFunction > 255) { BHAV bhav; GameIffResource CodeOwner; ushort ActionID = EntryPoints[entry].ActionFunction; if (ActionID < 4096) { //global bhav = context.Globals.Resource.Get<BHAV>(ActionID); CodeOwner = context.Globals.Resource; } else if (ActionID < 8192) { //local bhav = Object.Resource.Get<BHAV>(ActionID); CodeOwner = Object.Resource; } else { //semi-global bhav = SemiGlobal.Resource.Get<BHAV>(ActionID); CodeOwner = SemiGlobal.Resource; } var routine = context.VM.Assemble(bhav); if (bhav == null) return; //throw new Exception("Invalid BHAV call!"); short[] Args = null; VMEntity StackOBJ = null; if (entry == 1) { if (MainParam != 0) { Args = new short[4]; Args[0] = MainParam; MainParam = 0; } if (MainStackOBJ != 0) { StackOBJ = context.VM.GetObjectById(MainStackOBJ); MainStackOBJ = 0; } } var action = new TSO.Simantics.engine.VMQueuedAction { Callee = this, CodeOwner = CodeOwner, /** Main function **/ StackObject = StackOBJ, Routine = routine, Args = Args }; if (runImmediately) VMThread.EvaluateCheck(context, this, action); else this.Thread.EnqueueAction(action); } }