public List<VMEntity> GetObjectsAt(LotTilePos pos)
 {
     var off = GetOffest(pos);
     List<VMEntity> tile = null;
     TileToObjects.TryGetValue(off, out tile);
     return tile;
 }
Exemple #2
0
 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;
 }
Exemple #3
0
        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;
        }
Exemple #4
0
        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);
            }
        }
Exemple #6
0
        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;
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        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;
                }
            }
        }
Exemple #9
0
 public VMMultitileGroup CreateObjectInstance(UInt32 GUID, LotTilePos pos, Direction direction)
 {
     return CreateObjectInstance(GUID, pos, direction, 0, 0, false);
 }
Exemple #10
0
 public VMMultitileGroup CreateObjectInstance(UInt32 GUID, LotTilePos pos, Direction direction, bool ghostImage)
 {
     return CreateObjectInstance(GUID, pos, direction, 0, 0, ghostImage);
 }
Exemple #11
0
 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;
        }
Exemple #13
0
 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();
 }
Exemple #14
0
 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];
 }
Exemple #15
0
        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));
        }
Exemple #16
0
 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;
        }
Exemple #18
0
 private double GetDirectionTo(LotTilePos pos1, LotTilePos pos2)
 {
     return Math.Atan2(pos2.x - pos1.x, -(pos2.y - pos1.y));
 }
Exemple #19
0
 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);
 }
Exemple #20
0
 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;
 }
Exemple #21
0
        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);
        }
Exemple #22
0
        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);
        }
Exemple #23
0
        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
            });
        }
Exemple #24
0
 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();
 }
Exemple #26
0
        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;
        }
Exemple #27
0
 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;
 }
Exemple #28
0
        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);
        }
Exemple #29
0
        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);
        }
Exemple #30
0
        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);
        }
Exemple #31
0
 private static bool equals(LotTilePos c1, LotTilePos c2)
 {
     return(c1.x == c2.x && c1.y == c2.y && c1.Level == c2.Level);
 }
Exemple #32
0
 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?
 }
Exemple #33
0
 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;
 }
Exemple #34
0
 public LotTilePos(LotTilePos pos)
 {
     x     = pos.x;
     y     = pos.y;
     Level = pos.Level;
 }
Exemple #35
0
 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;
 }