public List<VMEntity> GetObjectsAt(LotTilePos pos) { var off = GetOffest(pos); List<VMEntity> tile = null; TileToObjects.TryGetValue(off, out tile); return tile; }
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 ChangeObjectLocation(ObjectComponent component, LotTilePos pos) { short tileX = (pos.x < 0) ? (short)0 : pos.TileX; short tileY = (pos.y < 0) ? (short)0 : pos.TileY; sbyte level = pos.Level; Changes.RegisterObjectChange(component); component.blueprint = this; component.TileX = tileX; component.TileY = tileY; component.Level = level; }
public void ChangeObjectLocation(ObjectComponent component, LotTilePos pos) { short tileX = (pos.x < 0) ? (short)0 : pos.TileX; short tileY = (pos.y < 0) ? (short)0 : pos.TileY; sbyte level = pos.Level; Damage.Add(new BlueprintDamage(BlueprintDamageType.OBJECT_MOVE, tileX, tileY, level) { Component = component }); component.blueprint = this; component.TileX = tileX; component.TileY = tileY; component.Level = level; }
public void Deserialize(BinaryReader reader) { MultiTile = reader.ReadBoolean(); Name = reader.ReadString(); Price = 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 operand = (VMLookTowardsOperand)args; //TODO: primitive fails if object calls it VMAvatar sim = (VMAvatar)context.Caller; var result = new VMFindLocationResult(); result.Position = new LotTilePos(sim.Position); LotTilePos pos = new LotTilePos(); switch (operand.Mode) { case VMLookTowardsMode.HeadTowardsObject: return VMPrimitiveExitCode.GOTO_TRUE; //TODO: turning head towards things, with head seek timeout case VMLookTowardsMode.BodyTowardsCamera: return VMPrimitiveExitCode.GOTO_TRUE; //does not work in TSO case VMLookTowardsMode.BodyTowardsStackObj: result.RadianDirection = (float)GetDirectionTo(sim.Position, context.StackObject.Position); break; case VMLookTowardsMode.BodyAwayFromStackObj: result.RadianDirection = (float)GetDirectionTo(sim.Position, context.StackObject.Position); result.RadianDirection = (float)((result.RadianDirection + Math.PI) % (Math.PI*2)); break; case VMLookTowardsMode.BodyTowardsAverageStackObj: foreach (var obj in context.StackObject.MultitileGroup.Objects) pos += obj.Position; pos /= context.StackObject.MultitileGroup.Objects.Count; result.RadianDirection = (float)GetDirectionTo(sim.Position, pos); break; case VMLookTowardsMode.BodyAwayFromAverageStackObj: foreach (var obj in context.StackObject.MultitileGroup.Objects) pos += obj.Position; pos /= context.StackObject.MultitileGroup.Objects.Count; result.RadianDirection = (float)GetDirectionTo(sim.Position, pos); result.RadianDirection = (float)((result.RadianDirection + Math.PI) % (Math.PI * 2)); break; } if (context.Thread.IsCheck) return VMPrimitiveExitCode.GOTO_FALSE; var pathFinder = context.Thread.PushNewRoutingFrame(context, false); //use the path finder to do the turn animation. pathFinder.InitRoutes(new List<VMFindLocationResult>() { result }); return VMPrimitiveExitCode.CONTINUE; }
public virtual void Deserialize(BinaryReader reader) { ObjectID = reader.ReadInt16(); PersistID = reader.ReadUInt32(); var datas = reader.ReadInt32(); ObjectData = new short[datas]; for (int i = 0; i < datas; i++) ObjectData[i] = reader.ReadInt16(); var listLen = reader.ReadInt32(); MyList = new short[listLen]; for (int i = 0; i < listLen; i++) MyList[i] = reader.ReadInt16(); GUID = reader.ReadUInt32(); MasterGUID = reader.ReadUInt32(); MainParam = reader.ReadInt16(); MainStackOBJ = reader.ReadInt16(); var contN = reader.ReadInt32(); Contained = new short[contN]; for (int i = 0; i < contN; i++) Contained[i] = reader.ReadInt16(); Container = reader.ReadInt16(); ContainerSlot = reader.ReadInt16(); var attrN = reader.ReadInt32(); Attributes = new short[attrN]; for (int i = 0; i < attrN; i++) Attributes[i] = reader.ReadInt16(); var relN = reader.ReadInt32(); MeToObject = new VMEntityRelationshipMarshal[relN]; for (int i = 0; i < relN; i++) { MeToObject[i] = new VMEntityRelationshipMarshal(); MeToObject[i].Deserialize(reader); } DynamicSpriteFlags = reader.ReadUInt32(); Position = new LotTilePos(); Position.Deserialize(reader); }
public VMMultitileGroup CreateObjectInstance(UInt32 GUID, LotTilePos pos, Direction direction, short MainStackOBJ, short MainParam, bool ghostImage) { VMMultitileGroup group = new VMMultitileGroup(); var objDefinition = FSO.Content.Content.Get().WorldObjects.Get(GUID); if (objDefinition == null) { return null; } var master = objDefinition.OBJ.MasterID; if (master != 0) { group.MultiTile = true; var objd = objDefinition.Resource.List<OBJD>(); for (int i = 0; i < objd.Count; i++) { if (objd[i].MasterID == master && objd[i].SubIndex != -1) //if sub-part of this object, make it! { var subObjDefinition = FSO.Content.Content.Get().WorldObjects.Get(objd[i].GUID); if (subObjDefinition != null) { var worldObject = new ObjectComponent(subObjDefinition); var vmObject = new VMGameObject(subObjDefinition, worldObject); vmObject.GhostImage = ghostImage; vmObject.MasterDefinition = objDefinition.OBJ; vmObject.UseTreeTableOf(objDefinition); vmObject.MainParam = MainParam; vmObject.MainStackOBJ = MainStackOBJ; group.Objects.Add(vmObject); vmObject.MultitileGroup = group; if (!ghostImage) VM.AddEntity(vmObject); } } } group.Init(this); VMPlacementError couldPlace = group.ChangePosition(pos, direction, this).Status; return group; } else { if (objDefinition.OBJ.ObjectType == OBJDType.Person) //person { var vmObject = new VMAvatar(objDefinition); vmObject.MultitileGroup = group; group.Objects.Add(vmObject); vmObject.GhostImage = ghostImage; if (!ghostImage) VM.AddEntity(vmObject); if (UseWorld) Blueprint.AddAvatar((AvatarComponent)vmObject.WorldUI); vmObject.MainParam = MainParam; vmObject.MainStackOBJ = MainStackOBJ; group.Init(this); vmObject.SetPosition(pos, direction, this); return group; } else { var worldObject = new ObjectComponent(objDefinition); var vmObject = new VMGameObject(objDefinition, worldObject); vmObject.MultitileGroup = group; group.Objects.Add(vmObject); vmObject.GhostImage = ghostImage; if (!ghostImage) VM.AddEntity(vmObject); vmObject.MainParam = MainParam; vmObject.MainStackOBJ = MainStackOBJ; group.Init(this); vmObject.SetPosition(pos, direction, this); return group; } } }
public VMMultitileGroup CreateObjectInstance(UInt32 GUID, LotTilePos pos, Direction direction) { return CreateObjectInstance(GUID, pos, direction, 0, 0, false); }
public VMMultitileGroup CreateObjectInstance(UInt32 GUID, LotTilePos pos, Direction direction, bool ghostImage) { return CreateObjectInstance(GUID, pos, direction, 0, 0, ghostImage); }
public bool CheckFloorValid(LotTilePos pos, FloorTile floor) { var objs = SetToNextCache.GetObjectsAt(pos); if (objs == null) return true; foreach (var obj in objs) { if (obj.FloorChangeValid(floor, pos.Level) != VMPlacementError.Success) return false; } return true; }
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 VMSolidResult SolidToAvatars(LotTilePos pos) { if (IsOutOfBounds(pos) || (pos.Level < 1 || pos.Level > ObjectsAt.Count) || (pos.Level != 1 && Architecture.GetFloor(pos.TileX, pos.TileY, pos.Level).Pattern == 0)) return new VMSolidResult { Solid = true }; if (!ObjectsAt[pos.Level - 1].ContainsKey(pos.TileID)) return new VMSolidResult(); var objs = ObjectsAt[pos.Level - 1][pos.TileID]; foreach (var id in objs) { var obj = VM.GetObjectById(id); 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 ushort GetRoomAt(LotTilePos pos) { if (pos.TileX < 0 || pos.TileX >= _Arch.Width) return 0; else if (pos.TileY < 0 || pos.TileY >= _Arch.Height) return 0; else if (pos.Level < 1 || pos.Level > _Arch.Stories) return 0; else return Architecture.Rooms[pos.Level-1].Map[pos.TileX + pos.TileY * _Arch.Width]; }
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 override VMObstacle GetObstacle(LotTilePos pos, Direction dir) { return new VMObstacle( (pos.x - 3), (pos.y - 3), (pos.x + 3), (pos.y + 3)); }
public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args) { var operand = (VMCreateObjectInstanceOperand)args; LotTilePos tpos = new LotTilePos(LotTilePos.OUT_OF_WORLD); Direction dir; switch (operand.Position) { case VMCreateObjectPosition.UnderneathMe: case VMCreateObjectPosition.OnTopOfMe: tpos = new LotTilePos(context.Caller.Position); dir = Direction.NORTH; break; case VMCreateObjectPosition.BelowObjectInLocal: tpos = new LotTilePos(context.VM.GetObjectById((short)context.Locals[operand.LocalToUse]).Position); dir = Direction.NORTH; break; case VMCreateObjectPosition.BelowObjectInStackParam0: tpos = new LotTilePos(context.VM.GetObjectById((short)context.Args[0]).Position); dir = Direction.NORTH; break; case VMCreateObjectPosition.OutOfWorld: dir = Direction.NORTH; break; case VMCreateObjectPosition.InSlot0OfStackObject: case VMCreateObjectPosition.InMyHand: dir = Direction.NORTH; //this object should start in slot 0 of the stack object! //we have to create it first tho so hold your horses break; case VMCreateObjectPosition.InFrontOfStackObject: case VMCreateObjectPosition.InFrontOfMe: var objp = (operand.Position == VMCreateObjectPosition.InFrontOfStackObject)?context.StackObject:context.Caller; tpos = new LotTilePos(objp.Position); switch (objp.Direction) { case FSO.LotView.Model.Direction.SOUTH: tpos.y += 16; break; case FSO.LotView.Model.Direction.WEST: tpos.x -= 16; break; case FSO.LotView.Model.Direction.EAST: tpos.x += 16; break; case FSO.LotView.Model.Direction.NORTH: tpos.y -= 16; break; } dir = objp.Direction; break; case VMCreateObjectPosition.NextToMeInDirectionOfLocal: tpos = new LotTilePos(context.Caller.Position); dir = (Direction)context.Locals[operand.LocalToUse]; switch (dir) { case FSO.LotView.Model.Direction.SOUTH: tpos.y += 16; break; case FSO.LotView.Model.Direction.WEST: tpos.x -= 16; break; case FSO.LotView.Model.Direction.EAST: tpos.x += 16; break; case FSO.LotView.Model.Direction.NORTH: tpos.y -= 16; break; } break; default: throw new VMSimanticsException("Where do I put this??", context); } var obj = context.VM.Context.CreateObjectInstance(operand.GUID, tpos, dir, (operand.PassObjectIds && context.StackObject != null) ? (context.StackObject.ObjectID) : (short)0, (operand.PassTemp0) ? (context.Thread.TempRegisters[0]) : (operand.PassObjectIds ? context.Caller.ObjectID : (short)0) , false).Objects[0]; if (operand.Position == VMCreateObjectPosition.InSlot0OfStackObject) context.StackObject.PlaceInSlot(obj, 0, true, context.VM.Context); else if (operand.Position == VMCreateObjectPosition.InMyHand) context.Caller.PlaceInSlot(obj, 0, true, context.VM.Context); if ((operand.Flags & (1 << 6)) > 0) { var interaction = operand.InteractionCallback; if (interaction == 254) { var temp = context.Caller.Thread.Queue[0].InteractionNumber; if (temp == -1) throw new VMSimanticsException("Set callback as 'this interaction' when queue item has no interaction number!", context); interaction = (byte)temp; } var callback = new VMActionCallback(context.VM, interaction, context.Callee, context.StackObject, context.Caller, true); callback.Run(obj); } else context.StackObject = obj; return VMPrimitiveExitCode.GOTO_TRUE; }
private double GetDirectionTo(LotTilePos pos1, LotTilePos pos2) { return Math.Atan2(pos2.x - pos1.x, -(pos2.y - pos1.y)); }
public bool IsOutOfBounds(LotTilePos pos) { return (pos.x < 0 || pos.y < 0 || pos.Level < 1 || pos.TileX >= _Arch.Width || pos.TileY >= _Arch.Height || pos.Level > _Arch.Stories); }
public bool CheckWallValid(LotTilePos pos, WallTile wall) { var objs = SetToNextCache.GetObjectsAt(pos); if (objs == null) return true; foreach (var obj in objs) { if (obj.WallChangeValid(wall, obj.Direction, false) != VMPlacementError.Success) return false; } return true; }
public VMPlacementResult GetAvatarPlace(VMEntity target, LotTilePos pos, Direction dir) { //avatars cannot be placed in slots under any circumstances, so we skip a few steps. VMObstacle footprint = target.GetObstacle(pos, dir); ushort room = GetRoomAt(pos); VMPlacementError status = VMPlacementError.Success; VMEntity statusObj = null; if (footprint == null || pos.Level < 1) { return new VMPlacementResult(status); } var objs = RoomInfo[room].Entities; foreach (var obj in objs) { if (obj.MultitileGroup == target.MultitileGroup) continue; var oFoot = obj.Footprint; if (oFoot != null && oFoot.Intersects(footprint)) //also ignore allow intersection trees? { var flags = (VMEntityFlags)obj.GetValue(VMStackObjectVariable.Flags); bool allowAvatars = ((flags & VMEntityFlags.DisallowPersonIntersection) == 0) && ((flags & VMEntityFlags.AllowPersonIntersection) > 0); if (!allowAvatars) { status = VMPlacementError.CantIntersectOtherObjects; statusObj = obj; if (obj.EntryPoints[26].ActionFunction != 0) break; //select chairs immediately. } } } return new VMPlacementResult(status, statusObj); }
public VMPlacementResult GetObjPlace(VMEntity target, LotTilePos pos, Direction dir) { //ok, this might be confusing... short allowedHeights = target.GetValue(VMStackObjectVariable.AllowedHeightFlags); short weight = target.GetValue(VMStackObjectVariable.Weight); bool noFloor = (allowedHeights&1)==0; var flags = (VMEntityFlags)target.GetValue(VMStackObjectVariable.Flags); bool allowAvatars = ((flags & VMEntityFlags.DisallowPersonIntersection) == 0) && ((flags & VMEntityFlags.AllowPersonIntersection) > 0); VMObstacle footprint = target.GetObstacle(pos, dir); ushort room = GetRoomAt(pos); VMPlacementError status = (noFloor)?VMPlacementError.HeightNotAllowed:VMPlacementError.Success; VMEntity statusObj = null; if (footprint == null || pos.Level < 1) { return new VMPlacementResult { Status = status }; } var objs = RoomInfo[room].Entities; foreach (var obj in objs) { if (obj.MultitileGroup == target.MultitileGroup || (obj is VMAvatar && allowAvatars)) continue; var oFoot = obj.Footprint; if (oFoot != null && oFoot.Intersects(footprint) && (!(target.ExecuteEntryPoint(5, this, true, obj, new short[] { obj.ObjectID, 0, 0, 0 }) || obj.ExecuteEntryPoint(5, this, true, target, new short[] { target.ObjectID, 0, 0, 0 }))) ) { statusObj = obj; status = VMPlacementError.CantIntersectOtherObjects; //this object is technically solid. Check if we can place on top of it if (allowedHeights>1 && obj.TotalSlots() > 0 && (obj.GetSlot(0) == null || obj.GetSlot(0) == target)) { //first check if we have a slot 0, which is what we place onto. then check if it's empty, //then check if the object can support this one's weight. //we also need to make sure that the height of this specific slot is allowed. if (((1 << (obj.GetSlotHeight(0) - 1)) & allowedHeights) > 0) { if (weight < obj.GetValue(VMStackObjectVariable.SupportStrength)) { return new VMPlacementResult(VMPlacementError.Success, obj); } else { status = VMPlacementError.CantSupportWeight; } } else { if (noFloor) { if ((allowedHeights & (1 << 3)) > 0) status = VMPlacementError.CounterHeight; else status = (obj.GetSlotHeight(0) == 8) ? VMPlacementError.CannotPlaceComputerOnEndTable : VMPlacementError.HeightNotAllowed; } } } } } return new VMPlacementResult(status, statusObj); }
private void VerifyAndAddLocation(VMEntity obj, Vector2 pos, Vector2 center, SLOTFlags entryFlags, double score, VMContext context, VMEntity caller, float facingDir) { //note: verification is not performed if snap target slot is enabled. var tpos = new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level); if (context.IsOutOfBounds(tpos)) return; score -= LotTilePos.Distance(tpos, caller.Position)/3.0; if (Slot.SnapTargetSlot < 0 && context.Architecture.RaycastWall(new Point((int)pos.X, (int)pos.Y), new Point(obj.Position.TileX, obj.Position.TileY), obj.Position.Level)) { SetFail(VMRouteFailCode.WallInWay, null); return; } bool faceAnywhere = false; if (float.IsNaN(facingDir)) { var obj3P = obj.Position.ToVector3(); var objP = new Vector2(obj3P.X, obj3P.Y); switch (Slot.Facing) { case SLOTFacing.FaceTowardsObject: facingDir = (float)GetDirectionTo(pos, objP); break; case SLOTFacing.FaceAwayFromObject: facingDir = (float)GetDirectionTo(objP, pos); break; case SLOTFacing.FaceAnywhere: faceAnywhere = true; facingDir = 0.0f; break; default: int intDir = (int)Math.Round(Math.Log((double)obj.Direction, 2)); var rotatedF = ((int)Slot.Facing + intDir) % 8; facingDir = (float)(((int)rotatedF > 4) ? ((double)rotatedF * Math.PI / 4.0) : (((double)rotatedF - 8.0) * Math.PI / 4.0)); break; } } VMEntity chair = null; if (Slot.SnapTargetSlot < 0) { var solid = caller.PositionValid(tpos, Direction.NORTH, context); if (solid.Status != Model.VMPlacementError.Success) { if (solid.Object != null && solid.Object is VMGameObject) { if (Slot.Sitting > 0 && solid.Object.EntryPoints[26].ActionFunction != 0) { chair = solid.Object; } else { SetFail(VMRouteFailCode.DestTileOccupied, solid.Object); return; } } } if (chair != null && (Math.Abs(DirectionUtils.Difference(chair.RadianDirection, facingDir)) > Math.PI / 4)) return; //not a valid goal. if (chair == null && OnlySit) return; } Results.Add(new VMFindLocationResult { Position = new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level), Score = score * ((chair != null) ? Slot.Sitting : Slot.Standing), //todo: prefer closer? RadianDirection = facingDir, Chair = chair, FaceAnywhere = faceAnywhere, RouteEntryFlags = entryFlags }); }
public bool IsOutOfBounds(LotTilePos pos) { return (pos.x < 0 || pos.y < 0 || pos.TileX >= _Arch.Width || pos.TileY >= _Arch.Height); }
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(); }
private double GetDist(LotTilePos pos1, LotTilePos pos2) { return Math.Sqrt(Math.Pow(pos1.x - pos2.x, 2) + Math.Pow(pos1.y - pos2.y, 2))/16.0 + Math.Abs(pos1.Level-pos2.Level)*10; }
public VMPlacementResult ChangePosition(LotTilePos pos, Direction direction, VMContext context) { if (pos.Level > context.Architecture.Stories) return new VMPlacementResult(VMPlacementError.NotAllowedOnFloor); VMEntity[] OldContainers = new VMEntity[Objects.Count]; short[] OldSlotNum = new short[Objects.Count]; for (int i = 0; i < Objects.Count(); i++) { OldContainers[i] = Objects[i].Container; OldSlotNum[i] = Objects[i].ContainerSlot; Objects[i].PrePositionChange(context); } int Dir = 0; switch (direction) { case Direction.NORTH: Dir = 0; break; case Direction.EAST: Dir = 2; break; case Direction.SOUTH: Dir = 4; break; case Direction.WEST: Dir = 6; break; } Matrix rotMat = Matrix.CreateRotationZ((float)(Dir * Math.PI / 4.0)); VMPlacementResult[] places = new VMPlacementResult[Objects.Count]; var bObj = BaseObject; var leadOff = new Vector3(((sbyte)(((ushort)bObj.Object.OBJ.SubIndex) >> 8) * 16), ((sbyte)(((ushort)bObj.Object.OBJ.SubIndex) & 0xFF) * 16), 0); //TODO: optimize so we don't have to recalculate all of this if (pos != LotTilePos.OUT_OF_WORLD) { for (int i = 0; i < Objects.Count(); i++) { var sub = Objects[i]; var off = new Vector3((sbyte)(((ushort)sub.Object.OBJ.SubIndex) >> 8) * 16, (sbyte)(((ushort)sub.Object.OBJ.SubIndex) & 0xFF) * 16, 0); off = Vector3.Transform(off-leadOff, rotMat); var offPos = new LotTilePos((short)Math.Round(pos.x + off.X), (short)Math.Round(pos.y + off.Y), (sbyte)(pos.Level + sub.Object.OBJ.LevelOffset)); places[i] = sub.PositionValid(offPos, direction, context); if (places[i].Status != VMPlacementError.Success) { //go back to where we started: we're no longer out of world. for (int j = 0; j < Objects.Count(); j++) { //need to restore slot we were in if (OldContainers[j] != null) { OldContainers[j].PlaceInSlot(Objects[j], OldSlotNum[j], false, context); } Objects[j].PositionChange(context, false); } return places[i]; } } } //verification success for (int i = 0; i < Objects.Count(); i++) { var sub = Objects[i]; var off = new Vector3((sbyte)(((ushort)sub.Object.OBJ.SubIndex) >> 8) * 16, (sbyte)(((ushort)sub.Object.OBJ.SubIndex) & 0xFF)*16, 0); off = Vector3.Transform(off-leadOff, rotMat); var offPos = (pos==LotTilePos.OUT_OF_WORLD)? LotTilePos.OUT_OF_WORLD : new LotTilePos((short)Math.Round(pos.x + off.X), (short)Math.Round(pos.y + off.Y), (sbyte)(pos.Level+sub.Object.OBJ.LevelOffset)); sub.SetIndivPosition(offPos, direction, context, places[i]); } for (int i = 0; i < Objects.Count(); i++) Objects[i].PositionChange(context, false); return new VMPlacementResult(VMPlacementError.Success); }
public virtual void Deserialize(BinaryReader reader) { ObjectID = reader.ReadInt16(); PersistID = reader.ReadUInt32(); if (this is VMGameObjectMarshal) PlatformState = new VMTSOObjectState(); else PlatformState = new VMTSOAvatarState(); PlatformState.Deserialize(reader); var datas = reader.ReadInt32(); ObjectData = new short[datas]; for (int i = 0; i < datas; i++) ObjectData[i] = reader.ReadInt16(); var listLen = reader.ReadInt32(); MyList = new short[listLen]; for (int i = 0; i < listLen; i++) MyList[i] = reader.ReadInt16(); if (reader.ReadBoolean()) { Headline = new VMRuntimeHeadlineMarshal(); Headline.Deserialize(reader); } GUID = reader.ReadUInt32(); MasterGUID = reader.ReadUInt32(); MainParam = reader.ReadInt16(); MainStackOBJ = reader.ReadInt16(); var contN = reader.ReadInt32(); Contained = new short[contN]; for (int i = 0; i < contN; i++) Contained[i] = reader.ReadInt16(); Container = reader.ReadInt16(); ContainerSlot = reader.ReadInt16(); var attrN = reader.ReadInt32(); Attributes = new short[attrN]; for (int i = 0; i < attrN; i++) Attributes[i] = reader.ReadInt16(); var relN = reader.ReadInt32(); MeToObject = new VMEntityRelationshipMarshal[relN]; for (int i = 0; i < relN; i++) { MeToObject[i] = new VMEntityRelationshipMarshal(); MeToObject[i].Deserialize(reader); } DynamicSpriteFlags = reader.ReadUInt64(); if (Version > 2) DynamicSpriteFlags2 = reader.ReadUInt64(); Position = new LotTilePos(); Position.Deserialize(reader); }
public void ChangeObjectLocation(ObjectComponent component, LotTilePos pos) { short tileX = (pos.x < 0) ? (short)0 : pos.TileX; short tileY = (pos.y < 0) ? (short)0 : pos.TileY; sbyte level = pos.Level; /** It has never been placed before if tileX == -2 **/ if (component.TileX != -2){ var currentOffset = GetOffset(component.TileX, component.TileY); var currentList = Objects[currentOffset]; if (currentList != null){ currentList.RemoveObject(component); } } if (tileX != -2) { var newOffset = GetOffset(tileX, tileY); var newList = Objects[newOffset]; if (newList == null) { newList = Objects[newOffset] = new BlueprintObjectList(); } newList.AddObject(component); if (!All.Contains(component)) { All.Add(component); } } else if (All.Contains(component)) { All.Remove(component); } Damage.Add(new BlueprintDamage(BlueprintDamageType.OBJECT_MOVE, tileX, tileY, level) { Component = component }); OccupiedTilesDirty = true; component.blueprint = this; component.TileX = tileX; component.TileY = tileY; component.Level = level; component.Position = new Microsoft.Xna.Framework.Vector3(pos.x / 16.0f, pos.y / 16.0f, (level - 1) * 3.0f); }
private static bool equals(LotTilePos c1, LotTilePos c2) { return(c1.x == c2.x && c1.y == c2.y && c1.Level == c2.Level); }
public static int Distance(LotTilePos a, LotTilePos b) { return((int)Math.Sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y))); //TODO: consider level? does anything need this? }
public bool CheckFloorValid(LotTilePos pos, FloorTile floor) { if (pos.Level < 1 || pos.Level > ObjectsAt.Count || !ObjectsAt[pos.Level - 1].ContainsKey(pos.TileID)) return true; var objs = ObjectsAt[pos.Level - 1][pos.TileID]; foreach (var id in objs) { var obj = VM.GetObjectById(id); if (obj.FloorChangeValid(floor, pos.Level) != VMPlacementError.Success) return false; } return true; }
public LotTilePos(LotTilePos pos) { x = pos.x; y = pos.y; Level = pos.Level; }
public bool CheckWallValid(LotTilePos pos, WallTile wall) { if (pos.Level < 1 || pos.Level > ObjectsAt.Count || !ObjectsAt[pos.Level - 1].ContainsKey(pos.TileID)) return true; var objs = ObjectsAt[pos.Level - 1][pos.TileID]; foreach (var id in objs) { var obj = VM.GetObjectById(id); if (obj.WallChangeValid(wall, obj.Direction, false) != VMPlacementError.Success) return false; } return true; }