public ushort GetPreciseFloor(LotTilePos pos) { var wall = GetWall(pos.TileX, pos.TileY, pos.Level); if ((wall.Segments & WallSegments.VerticalDiag) > 0) { if ((pos.x % 16) - (pos.y % 16) > 0) { return(wall.TopLeftPattern); } else { return(wall.TopLeftStyle); } } else if ((wall.Segments & WallSegments.HorizontalDiag) > 0) { if ((pos.x % 16) + (pos.y % 16) > 15) { return(wall.TopLeftPattern); } else { return(wall.TopLeftStyle); } } return(GetFloor(pos.TileX, pos.TileY, pos.Level).Pattern); }
public bool SetFloor(short tileX, short tileY, sbyte level, FloorTile floor, bool force) { //returns false on failure var offset = GetOffset(tileX, tileY); if (!force) { //first check if we're supported if (floor.Pattern > 65533 && level > 1 && RoomData[(int)Rooms[level - 2].Map[offset] & 0xFFFF].IsOutside) { return(false); } if (level > 1 && !Supported[level - 2][offset]) { return(false); } //check if objects need/don't need floors if (!Context.CheckFloorValid(LotTilePos.FromBigTile((short)tileX, (short)tileY, level), floor)) { return(false); } } Floors[level - 1][offset] = floor; if (RealMode) { FloorsDirty = true; } Redraw = true; return(true); }
public List <VMEntity> GetObjectsAt(LotTilePos pos) { var off = GetOffest(pos); TileToObjects.TryGetValue(off, out var tile); return(tile); }
private bool SetPosition(VMEntity entity, LotTilePos pos, float radDir, bool shooAva, VMContext context) { var posChange = entity.SetPosition(pos, (Direction)(1 << (int)(Math.Round(DirectionUtils.PosMod(radDir, (float)Math.PI * 2) / (Math.PI / 4)) % 8)), context); if (posChange.Status != VMPlacementError.Success) { if (shooAva && posChange.Object != null && posChange.Object is VMAvatar) { if (!posChange.Object.Thread.Queue.Any(x => x.Callee != null && x.Callee.Object.GUID == GOTO_GUID && x.InteractionNumber == SHOO_INTERACTION)) { //push shoo if not already being shooed VMEntity callee = context.VM.Context.CreateObjectInstance(GOTO_GUID, new LotTilePos(posChange.Object.Position), Direction.NORTH).Objects[0]; callee.PushUserInteraction(SHOO_INTERACTION, posChange.Object, context.VM.Context, false); } } if (posChange.Status == VMPlacementError.LocationOutOfBounds) { entity.SetValue(VMStackObjectVariable.PrimitiveResult, 2); } entity.SetValue(VMStackObjectVariable.PrimitiveResultID, (posChange.Object == null) ? (short)0 : posChange.Object.ObjectID); return(false); } if (entity is VMAvatar) { entity.RadianDirection = radDir; } return(true); }
public static bool VerifyDrawWall(VMArchitecture target, Point pos, int length, int direction, sbyte level) { pos += WLStartOff[direction]; bool diagCheck = (direction % 2 == 1); for (int i = 0; i < length; i++) { if (target.OutsideClip((short)pos.X, (short)pos.Y, level)) { return(false); } var wall = target.GetWall((short)pos.X, (short)pos.Y, level); if ((wall.Segments & AnyDiag) == 0 && (!diagCheck || (wall.Segments == 0))) { wall.Segments |= WLMainSeg[direction]; if (!target.Context.CheckWallValid(LotTilePos.FromBigTile((short)pos.X, (short)pos.Y, level), wall)) { return(false); } if (!diagCheck) { var tPos = pos + WLSubOff[direction / 2]; //get the other side of the wall if (target.OutsideClip((short)tPos.X, (short)tPos.Y, level)) { return(false); //both sides of wall must be in bounds } wall = target.GetWall((short)tPos.X, (short)tPos.Y, level); if (!(level == 1 || target.Supported[level - 2][pos.Y * target.Width + pos.X] || target.Supported[level - 2][tPos.Y * target.Width + tPos.X])) { return(false); } if ((wall.Segments & AnyDiag) == 0) { wall.Segments |= WLSubSeg[direction / 2]; if (!target.Context.CheckWallValid(LotTilePos.FromBigTile((short)tPos.X, (short)tPos.Y, level), wall)) { return(false); } } else { return(false); } } else { if (!(level == 1 || target.Supported[level - 2][pos.Y * target.Width + pos.X])) { return(false); } } } else { return(false); } pos += WLStep[direction]; } return(true); }
public Tuple <LotTilePos, Vector2, Vector2> NextPointAndVel(int frame) { //if (Next == null) Next = InternalGetNext(frame); var current = InternalGetNext(frame); Vector2 velocity; if (frame >= TotalFrames) { if (Last != null) { velocity = Last.Value; } else { velocity = ((D - A).ToVector2() / (0x8000 * 16)) / TotalFrames; } } else { var next = InternalGetNext(frame + 1); velocity = (next - current) / 16; } Last = velocity; return(new Tuple <LotTilePos, Vector2, Vector2>(LotTilePos.FromVec2(current), current / 16, velocity)); }
public static bool VerifyEraseWall(VMArchitecture target, Point pos, int length, int direction, sbyte level) { pos += WLStartOff[direction]; bool diagCheck = (direction % 2 == 1); for (int i = 0; i < length; i++) { if (pos.X <= 0 || pos.X >= target.Width || pos.Y <= 0 || pos.Y >= target.Height) { return(false); } var wall = target.GetWall((short)pos.X, (short)pos.Y, level); wall.Segments &= ~WLMainSeg[direction]; if (!target.Context.CheckWallValid(LotTilePos.FromBigTile((short)pos.X, (short)pos.Y, level), wall)) { return(false); } if (!diagCheck) { var tPos = pos + WLSubOff[direction / 2]; wall = target.GetWall((short)tPos.X, (short)tPos.Y, level); wall.Segments &= ~WLSubSeg[direction / 2]; if (!target.Context.CheckWallValid(LotTilePos.FromBigTile((short)tPos.X, (short)tPos.Y, level), wall)) { return(false); } } pos += WLStep[direction]; } return(true); }
public VMEntity CreateObject(XmlHouseDataObject obj) { LotTilePos pos = LotTilePos.OUT_OF_WORLD; var nobj = VM.Context.CreateObjectInstance(obj.GUIDInt, pos, obj.Direction).Objects[0]; if (obj.Level != 0) { nobj.SetPosition(LotTilePos.FromBigTile((short)(obj.X + Offset.X), (short)(obj.Y + Offset.Y), (sbyte)obj.Level), obj.Direction, VM.Context, VMPlaceRequestFlags.AcceptSlots); } if (obj.Group != 0) { foreach (var sub in nobj.MultitileGroup.Objects) { sub.SetValue(VMStackObjectVariable.GroupID, (short)obj.Group); } } for (int i = 0; i < nobj.MultitileGroup.Objects.Count; i++) { nobj.MultitileGroup.Objects[i].ExecuteEntryPoint(11, VM.Context, true); } return(nobj); }
public bool IsUserOutOfBounds(LotTilePos pos) { var fine = Architecture.FineBuildableArea; if (fine != null) { if (pos.TileX < 0 || pos.TileX >= _Arch.Width) { return(false); } else if (pos.TileY < 0 || pos.TileY >= _Arch.Height) { return(false); } else if (pos.Level < 1 || pos.Level > _Arch.BuildableFloors) { return(false); } else { return(!fine[pos.TileX + pos.TileY * _Arch.Width]); } } else { var area = Architecture.BuildableArea; return(pos.TileX < area.X || pos.TileY < area.Y || pos.Level < 1 || pos.TileX >= area.Right || pos.TileY >= area.Bottom || pos.Level > _Arch.BuildableFloors); } }
public VMSolidResult SolidToAvatars(LotTilePos pos) { if (IsOutOfBounds(pos) || (pos.Level < 1) || (pos.Level != 1 && Architecture.GetFloor(pos.TileX, pos.TileY, pos.Level).Pattern == 0)) { return new VMSolidResult { Solid = true } } ; var objs = SetToNextCache.GetObjectsAt(pos); if (objs == null) { return(new VMSolidResult()); } foreach (var obj in objs) { if (obj == null) { continue; } var flags = (VMEntityFlags)obj.GetValue(VMStackObjectVariable.Flags); if (((flags & VMEntityFlags.DisallowPersonIntersection) > 0) || (flags & (VMEntityFlags.AllowPersonIntersection | VMEntityFlags.HasZeroExtent)) == 0) { return new VMSolidResult { Solid = true, Chair = (obj.EntryPoints[26].ActionFunction != 0)?obj:null } } ; //solid to people } return(new VMSolidResult()); }
public void Deserialize(BinaryReader reader) { MultiTile = reader.ReadBoolean(); Name = reader.ReadString(); Price = reader.ReadInt32(); if (Version > 12) { SalePrice = reader.ReadInt32(); } var objs = reader.ReadInt32(); Objects = new short[objs]; for (int i = 0; i < objs; i++) { Objects[i] = reader.ReadInt16(); } Offsets = new LotTilePos[objs]; for (int i = 0; i < objs; i++) { Offsets[i] = new LotTilePos(); Offsets[i].Deserialize(reader); } }
public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args) { var obj = context.Caller; if (context.Caller.TotalSlots() == 0) { return(VMPrimitiveExitCode.GOTO_FALSE); } var drop = context.Caller.GetSlot(0); if (drop == null) { return(VMPrimitiveExitCode.GOTO_FALSE); } int intDir = (int)Math.Round(Math.Log((double)obj.Direction, 2)); LotTilePos basePos = LotTilePos.FromBigTile(obj.Position.TileX, obj.Position.TileY, obj.Position.Level); for (int i = 0; i < Positions.Length; i++) { int j = (i % 2 == 1) ? ((Positions.Length - 1) - i / 2) : i / 2; var posChange = drop.MultitileGroup.ChangePosition(basePos + Positions[(j + intDir) % 8], obj.Direction, context.VM.Context); if (posChange.Status == VMPlacementError.Success) { return(VMPrimitiveExitCode.GOTO_TRUE); } } return(VMPrimitiveExitCode.GOTO_FALSE); }
public void CreateObject(XmlHouseDataObject obj) { LotTilePos pos = (obj.Level == 0) ? LotTilePos.OUT_OF_WORLD : LotTilePos.FromBigTile((short)obj.X, (short)obj.Y, (sbyte)obj.Level); var mojb = VM.Context.CreateObjectInstance(obj.GUIDInt, pos, obj.Direction, false); if (mojb == null) { return; } var nobj = mojb.Objects[0]; if (obj.Group != 0) { foreach (var sub in nobj.MultitileGroup.Objects) { sub.SetValue(VMStackObjectVariable.GroupID, (short)obj.Group); } } for (int i = 0; i < nobj.MultitileGroup.Objects.Count; i++) { nobj.MultitileGroup.Objects[i].ExecuteEntryPoint(11, VM.Context, true); } //return nobj; }
public static VMEntity AdjToLocal(VMStackFrame context, VMEntity pointer, int local) { VMEntity anchor = context.VM.GetObjectById((short)context.Locals[local]); int ptrDir = -1; if (pointer != null) { ptrDir = getAdjDir(anchor, pointer); if (ptrDir == 3) { return(null); //reached end } } //iterate through all following dirs til we find an object for (int i = ptrDir + 1; i < 4; i++) { var off = AdjStep[i]; var adj = context.VM.Context.ObjectQueries.GetObjectsAt(LotTilePos.FromBigTile( (short)(anchor.Position.TileX + off.X), (short)(anchor.Position.TileY + off.Y), anchor.Position.Level)); if (adj != null && adj.Count > 0) { return(adj[0]); } } return(null); }
public override VMEntityObstacle GetObstacle(LotTilePos pos, Direction dir, bool temp) { if (GetFlag(VMEntityFlags.HasZeroExtent) || Container != null) { return(null); } var idir = (DirectionToWallOff(dir) * 4); uint rotatedFPM = (uint)(Object.OBJ.FootprintMask << idir); rotatedFPM = (rotatedFPM >> 16) | (rotatedFPM & 0xFFFF); int tileWidth = Object.OBJ.TileWidth / 2; if (tileWidth == 0) { tileWidth = 8; } var footprint = Footprint; if (footprint == null || temp) { footprint = new VMEntityObstacle(); footprint.Parent = this; } footprint.x2 = (pos.x + tileWidth) - ((int)(rotatedFPM >> 4) & 0xF); footprint.y2 = (pos.y + tileWidth) - ((int)(rotatedFPM >> 8) & 0xF); footprint.x1 = (pos.x - tileWidth) + ((int)(rotatedFPM >> 12) & 0xF); footprint.y1 = (pos.y - tileWidth) + ((int)rotatedFPM & 0xF); return(footprint); }
public override VMObstacle GetObstacle(LotTilePos pos, Direction dir) { if (GetFlag(VMEntityFlags.HasZeroExtent)) { return(null); } var idir = (DirectionToWallOff(dir) * 4); uint rotatedFPM = (uint)(Object.OBJ.FootprintMask << idir); rotatedFPM = (rotatedFPM >> 16) | (rotatedFPM & 0xFFFF); int tileWidth = Object.OBJ.TileWidth / 2; if (tileWidth == 0) { tileWidth = 8; } return(new VMObstacle( (pos.x + tileWidth) - ((int)(rotatedFPM >> 4) & 0xF), (pos.y + tileWidth) - ((int)(rotatedFPM >> 8) & 0xF), (pos.x - tileWidth) + ((int)(rotatedFPM >> 12) & 0xF), (pos.y - tileWidth) + ((int)rotatedFPM & 0xF))); }
public void Deserialize(BinaryReader reader) { ObjectID = reader.ReadInt16(); GUID = reader.ReadUInt32(); MasterGUID = reader.ReadUInt32(); Position = new LotTilePos(); Position.Deserialize(reader); Direction = (Direction)reader.ReadByte(); Graphic = reader.ReadInt16(); DynamicSpriteFlags = reader.ReadUInt64(); DynamicSpriteFlags2 = reader.ReadUInt64(); var contC = reader.ReadInt32(); Contained = new short[contC]; for (int i = 0; i < contC; i++) { Contained[i] = reader.ReadInt16(); } Container = reader.ReadInt16(); ContainerSlot = reader.ReadInt16(); Flags = reader.ReadInt16(); Flags2 = reader.ReadInt16(); WallPlacementFlags = reader.ReadInt16(); PlacementFlags = reader.ReadInt16(); AllowedHeightFlags = reader.ReadInt16(); }
public void MoveSelected(Vector2 pos, sbyte level) { Holding.TilePos = pos; Holding.Level = level; //first, eject the object from any slots for (int i = 0; i < Holding.Group.Objects.Count; i++) { var obj = Holding.Group.Objects[i]; if (obj.Container != null) { obj.Container.ClearSlot(obj.ContainerSlot); } } //rotate through to try all configurations var dir = Holding.Dir; VMPlacementError status = VMPlacementError.Success; if (!Holding.IsBought && !vm.PlatformState.CanPlaceNewUserObject(vm)) { status = VMPlacementError.TooManyObjectsOnTheLot; } else { for (int i = 0; i < 4; i++) { status = Holding.Group.ChangePosition(LotTilePos.FromBigTile((short)pos.X, (short)pos.Y, World.State.Level), dir, vm.Context, VMPlaceRequestFlags.UserPlacement).Status; if (status != VMPlacementError.MustBeAgainstWall) { break; } dir = (Direction)((((int)dir << 6) & 255) | ((int)dir >> 2)); } if (Holding.Dir != dir) { Holding.Dir = dir; } } if (status != VMPlacementError.Success) { Holding.Group.ChangePosition(LotTilePos.OUT_OF_WORLD, Holding.Dir, vm.Context, VMPlaceRequestFlags.UserPlacement); Holding.Group.SetVisualPosition(new Vector3(pos, (((Holding.Group.Objects[0].GetValue(VMStackObjectVariable.AllowedHeightFlags) & 1) == 1) ? 0 : 4f / 5f) + (World.State.Level - 1) * 2.95f), //^ if we can't be placed on the floor, default to table height. Holding.Dir, vm.Context); } for (int i = 0; i < Holding.Group.Objects.Count; i++) { var target = Holding.Group.Objects[i]; var tpos = target.VisualPosition; tpos.Z = (World.State.Level - 1) * 2.95f; Holding.CursorTiles[i].MultitileGroup.SetVisualPosition(tpos, Holding.Dir, vm.Context); } Holding.CanPlace = status; }
private void RoofSpread(LotTilePos start, bool[] evaluated, int width, int height, sbyte level, List <RoofRect> result) { var rect = new RoofRect(start.x, start.y, start.x + 8, start.y + 8); var toCtr = new Point(4, 4); while (rect.ExpandDir != -1) { //still have to expand in a direction //order: 0, 2, 1, 3, (xpos,xneg,ypos,yneg) var dir = rect.ExpandDir; var startPt = StartLocation(rect, dir); var testPt = startPt; var inc = advanceByDir[(dir + 1) % 4]; var count = Math.Abs(rect.GetByDir((dir + 1) % 4) - rect.GetByDir((dir + 3) % 4)) / 8; bool canExpand = true; for (int i = 0; i < count; i++) { var tile = new LotTilePos((short)testPt.X, (short)testPt.Y, level); if (!IsRoofable(tile)) { canExpand = false; break; } testPt += inc; } if (!canExpand) { rect.ExpandDir = ExpandOrder[rect.ExpandDir]; } else { //mark as complete - new roof rects cannot START on these tiles.. testPt = startPt; for (int i = 0; i < count; i++) { evaluated[(testPt.X / 8) + (testPt.Y / 8) * width] = true; testPt += inc; } //SPEEDUP: if expansion is within an existing roof rectangle skip to the other end of it var midPt = startPt + new Point(inc.X * count / 2, inc.Y * count / 2) + toCtr; var expandInto = result.FirstOrDefault(x => x.Contains(midPt) && RangeCheck(rect, x, dir)); if (expandInto != null) { rect.SetByDir(dir, expandInto.GetByDir(dir)); } else { //on no detection, expand by 1 rect.SetByDir(dir, rect.GetByDir(dir) + ((dir > 1) ? -8 : 8)); } } } result.Add(rect); }
private int GetOffest(LotTilePos pos) { if (pos == LotTilePos.OUT_OF_WORLD) { return(-1); } return(pos.TileX + pos.TileY * Context.Architecture.Width + (pos.Level - 1) * Context.Architecture.Width * Context.Architecture.Height); }
public override VMObstacle GetObstacle(LotTilePos pos, Direction dir) { return(new VMObstacle( (pos.x - 3), (pos.y - 3), (pos.x + 3), (pos.y + 3))); }
public override VMObstacle GetObstacle(LotTilePos pos, Direction dir) { return((KillTimeout > -1 && !GetFlag(VMEntityFlags.HasZeroExtent)) ? null : new VMObstacle( (pos.x - 3), (pos.y - 3), (pos.x + 3), (pos.y + 3))); }
public void Load(VMFindLocationResultMarshal input, VMContext context) { RadianDirection = input.RadianDirection; Position = input.Position; Score = input.Score; FaceAnywhere = input.FaceAnywhere; Chair = context.VM.GetObjectById(input.Chair); RouteEntryFlags = input.RouteEntryFlags; }
public void Deserialize(BinaryReader reader) { RadianDirection = reader.ReadSingle(); Position = new LotTilePos(); Position.Deserialize(reader); Score = reader.ReadDouble(); FaceAnywhere = reader.ReadBoolean(); Chair = reader.ReadInt16(); RouteEntryFlags = (SLOTFlags)reader.ReadInt32(); }
public NetworkClient Client; //REPLACE WHEN MOVING OFF GONZONET!! public override bool Execute(VM vm) { Name = Name.Substring(0, Math.Min(Name.Length, 64)); var sim = vm.Context.CreateObjectInstance(VMAvatar.TEMPLATE_PERSON, LotTilePos.OUT_OF_WORLD, Direction.NORTH, false).Objects[0]; var mailbox = vm.Entities.FirstOrDefault(x => (x.Object.OBJ.GUID == 0xEF121974 || x.Object.OBJ.GUID == 0x1D95C9B0 || x.Object.OBJ.GUID == 0x865A6812)); LotTilePos pos = mailbox.Position; pos.x = (short)(mailbox.Position.x + 1); pos.y = (short)(mailbox.Position.y + 1); if (VM.UseWorld) { TSO.HIT.HITVM.Get().PlaySoundEvent("lot_enter"); } if (mailbox != null) { VMFindLocationFor.FindLocationFor(sim, mailbox, vm.Context); } ((VMAvatar)sim).Visitor = ActorUID == 0 ? true : false; sim.PersistID = ActorUID; VMAvatar avatar = (VMAvatar)sim; avatar.SkinTone = (Vitaboy.AppearanceType)SkinTone; avatar.SetPersonData(VMPersonDataVariable.Gender, (short)((Gender) ? 1 : 0)); avatar.DefaultSuits = new VMAvatarDefaultSuits(Gender); avatar.DefaultSuits.Daywear = BodyID; avatar.BodyOutfit = BodyID; avatar.HeadOutfit = HeadID; avatar.Name = Name; ((VMTSOAvatarState)avatar.TSOState).Budget.Value = 999999; ((VMTSOAvatarState)avatar.TSOState).Permissions = Permissions; avatar.SetPosition(pos, Direction.WEST, vm.Context); if (ActorUID == uint.MaxValue - 1) { avatar.SetValue(VMStackObjectVariable.Hidden, 1); avatar.SetPosition(LotTilePos.OUT_OF_WORLD, Direction.NORTH, vm.Context); avatar.SetFlag(VMEntityFlags.HasZeroExtent, true); avatar.SetPersonData(VMPersonDataVariable.IsGhost, 1); //oooooOOooooOo } if (RequesterID == vm.MyUID) { vm.MyUID = ActorUID; //we're this sim! try send commands as them. } vm.SignalChatEvent(new VMChatEvent(avatar.PersistID, VMChatEventType.Join, avatar.Name)); return(true); }
public void SubmitCommand(string msg) { var state = LastState; if (state == null) { return; } var spaceIndex = msg.IndexOf(' '); if (spaceIndex == -1) { spaceIndex = msg.Length; } var cmd = msg.Substring(1, spaceIndex - 1); var args = msg.Substring(Math.Min(msg.Length, spaceIndex + 1), Math.Max(0, msg.Length - (spaceIndex + 1))); string response = "(" + msg + ") "; try { switch (cmd.ToLowerInvariant()) { case "objat": //!objat (objects at mouse position) var tilePos = vm.Context.World.State.WorldSpace.GetTileAtPosWithScroll(new Vector2(state.MouseState.X, state.MouseState.Y) / FSOEnvironment.DPIScaleFactor); LotTilePos targetPos = LotTilePos.FromBigTile((short)tilePos.X, (short)tilePos.Y, vm.Context.World.State.Level); var objs = vm.Context.SetToNextCache.GetObjectsAt(targetPos); response += "Objects at (" + targetPos.TileX + ", " + targetPos.TileY + ", " + targetPos.Level + ")\r\n"; foreach (var obj in objs) { response += ObjectSummary(obj); response += "\r\n"; } break; case "del": //!del objectID vm.SendCommand(new VMNetDeleteObjectCmd() { ObjectID = short.Parse(args), CleanupAll = true }); response += "Sent deletion command."; break; default: response += "Unknown command."; break; } } catch (Exception e) { e = new Exception(); response += "Bad command."; } vm.SignalChatEvent(new VMChatEvent(0, VMChatEventType.Generic, response)); }
public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args) { var operand = (VMFindLocationForOperand)args; var refObj = (operand.UseLocalAsRef) ? context.VM.GetObjectById((short)context.Locals[operand.Local]) : context.Caller; var obj = context.StackObject; switch (operand.Mode) { case 0: //default if (FindLocationFor(obj, refObj, context.VM.Context)) { return(VMPrimitiveExitCode.GOTO_TRUE); } else { return(VMPrimitiveExitCode.GOTO_FALSE); } case 1: //out of world obj.SetPosition(LotTilePos.OUT_OF_WORLD, Direction.NORTH, context.VM.Context); return(VMPrimitiveExitCode.GOTO_TRUE); case 2: //"smoke cloud" - halfway between callee and caller (is "caller" actually reference object?) var smokePos = context.Callee.Position; smokePos += context.Caller.Position; smokePos /= 2; smokePos -= new LotTilePos(8, 8, 0); //smoke is 2x2... offset to center it. return((obj.SetPosition(smokePos, Direction.NORTH, context.VM.Context).Status == VMPlacementError.Success)? VMPrimitiveExitCode.GOTO_TRUE : VMPrimitiveExitCode.GOTO_FALSE); case 3: case 4: //along object vector var intDir = (int)Math.Round(Math.Log((double)refObj.Direction, 2)); if (operand.Mode == 4) { intDir = (intDir + 2) % 8; //lateral to object vector } if (FindLocationVector(obj, refObj, context.VM.Context, intDir)) { return(VMPrimitiveExitCode.GOTO_TRUE); } else { return(VMPrimitiveExitCode.GOTO_FALSE); } } return(VMPrimitiveExitCode.GOTO_FALSE); }
public void AddDynamicObject(VMEntity obj, LotTilePos offset) { Objects.Add(obj); Offsets.Add(offset); if (VM.UseWorld && obj is VMGameObject) { var component = (ObjectComponent)obj.WorldUI; WorldGroup.Objects.Add(component); component.MultitileGroup = WorldGroup; } }
public virtual void SetIndivPosition(LotTilePos pos,Direction direction,VMContext context,VMPlacementResult info) { Direction = direction; if (UseWorld && this is VMGameObject) { context.Blueprint.ChangeObjectLocation((ObjectComponent)WorldUI,pos); } Position = pos; if (info.Object != null) { info.Object.PlaceInSlot(this,0,false,context); } }
private void UpdateTalkingHeadSeek(VM vm, VMAvatar talker) { // Update head seek of everyone else to attempt to look at the person talking. var channel = vm.TSOState.ChatChannels.FirstOrDefault(x => x.ID == ChannelID); if (ChannelID == 7) { channel = VMTSOChatChannel.AdminChannel; } if (channel != null && channel.ViewPermMin != VMTSOAvatarPermissions.Visitor) { return; // Cannot use look towards on private channels. } bool isImportantChannel = channel != null && channel.SendPermMin > VMTSOAvatarPermissions.Visitor && channel.Flags.HasFlag(VMTSOChatChannelFlags.EnableTTS); int multiplier = isImportantChannel ? 2 : 1; int talkerRoom = vm.Context.GetObjectRoom(talker); foreach (VMAvatar avatar in vm.Context.ObjectQueries.Avatars) { if (avatar == talker) { continue; } if (!isImportantChannel) { // Check if the avatar is in the same room, and rather close by. int avatarRoom = vm.Context.GetObjectRoom(avatar); if (avatarRoom != talkerRoom || LotTilePos.Distance(avatar.Position, talker.Position) > 16 * 10) { continue; // Not close enough. } } var avatarHeadTarget = vm.GetObjectById(avatar.GetPersonData(VMPersonDataVariable.HeadSeekObject)); var avatarHeadFinish = avatar.GetPersonData(VMPersonDataVariable.HeadSeekFinishAction); var avatarHeadState = avatar.GetPersonData(VMPersonDataVariable.HeadSeekState); if (avatarHeadState == 8 || avatarHeadState == 0 || (avatarHeadTarget is VMAvatar && (avatarHeadFinish != -1 || isImportantChannel))) { // We can look towards the talker. (important talkers have priority) avatar.SetPersonData(VMPersonDataVariable.HeadSeekObject, talker.ObjectID); avatar.SetPersonData(VMPersonDataVariable.HeadSeekState, 1); //in progress flag only avatar.SetPersonData(VMPersonDataVariable.HeadSeekLimitAction, 1); //look back on limit? avatar.SetPersonData(VMPersonDataVariable.HeadSeekFinishAction, (short)(isImportantChannel ? -1 : 0)); //use to store if the person was an important talker avatar.SetPersonData(VMPersonDataVariable.HeadSeekTimeout, (short)(talker.MessageTimeout * multiplier)); //while the message is present } } }