Beispiel #1
0
        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)
            {
                if (DonateMode && !vm.TSOState.CanPlaceNewDonatedObject(vm))
                {
                    status = VMPlacementError.TooManyObjectsOnTheLot;
                }
                else if (!DonateMode && !vm.TSOState.CanPlaceNewUserObject(vm))
                {
                    status = VMPlacementError.TooManyObjectsOnTheLot;
                }
            }

            if (status == VMPlacementError.Success)
            {
                for (int i = 0; i < 4; i++)
                {
                    status = Holding.Group.ChangePosition(LotTilePos.FromBigTile((short)pos.X, (short)pos.Y, 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) + (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 = (level - 1) * 2.95f;
                Holding.CursorTiles[i].MultitileGroup.SetVisualPosition(tpos, Holding.Dir, vm.Context);
            }
            Holding.CanPlace = status;
        }
Beispiel #2
0
        private void OnMouse(UIMouseEventType type, UpdateState state)
        {
            if (!vm.Ready)
            {
                return;
            }

            if (type == UIMouseEventType.MouseOver)
            {
                if (QueryPanel.Mode == 1)
                {
                    QueryPanel.Active = false;
                }
                MouseIsOn = true;
            }
            else if (type == UIMouseEventType.MouseOut)
            {
                MouseIsOn = false;
                Tooltip   = null;
            }
            else if (type == UIMouseEventType.MouseDown)
            {
                if (!LiveMode)
                {
                    if (CustomControl != null)
                    {
                        CustomControl.MouseDown(state);
                    }
                    else
                    {
                        ObjectHolder.MouseDown(state);
                    }
                    return;
                }
                if (PieMenu == null && ActiveEntity != null)
                {
                    VMEntity obj;
                    //get new pie menu, make new pie menu panel for it
                    var tilePos = World.State.WorldSpace.GetTileAtPosWithScroll(new Vector2(state.MouseState.X, state.MouseState.Y) / FSOEnvironment.DPIScaleFactor);

                    LotTilePos targetPos = LotTilePos.FromBigTile((short)tilePos.X, (short)tilePos.Y, World.State.Level);
                    if (vm.Context.SolidToAvatars(targetPos).Solid)
                    {
                        targetPos = LotTilePos.OUT_OF_WORLD;
                    }

                    GotoObject.SetPosition(targetPos, Direction.NORTH, vm.Context);

                    bool objSelected = ObjectHover > 0 && InteractionsAvailable;
                    if (objSelected || (GotoObject.Position != LotTilePos.OUT_OF_WORLD && ObjectHover <= 0))
                    {
                        HITVM.Get().PlaySoundEvent(UISounds.PieMenuAppear);
                        if (objSelected)
                        {
                            obj = vm.GetObjectById(ObjectHover);
                        }
                        else
                        {
                            obj = GotoObject;
                        }
                        obj = obj.MultitileGroup.GetInteractionGroupLeader(obj);

                        var menu = obj.GetPieMenu(vm, ActiveEntity, false);
                        if (menu.Count != 0)
                        {
                            PieMenu = new UIPieMenu(menu, obj, ActiveEntity, this);
                            this.Add(PieMenu);
                            PieMenu.X = state.MouseState.X / FSOEnvironment.DPIScaleFactor;
                            PieMenu.Y = state.MouseState.Y / FSOEnvironment.DPIScaleFactor;
                            PieMenu.UpdateHeadPosition(state.MouseState.X, state.MouseState.Y);
                        }
                    }
                    else
                    {
                        HITVM.Get().PlaySoundEvent(UISounds.Error);
                        state.UIState.TooltipProperties.Show     = true;
                        state.UIState.TooltipProperties.Color    = Color.Black;
                        state.UIState.TooltipProperties.Opacity  = 1;
                        state.UIState.TooltipProperties.Position = new Vector2(state.MouseState.X,
                                                                               state.MouseState.Y);
                        state.UIState.Tooltip = GameFacade.Strings.GetString("159", "0");
                        state.UIState.TooltipProperties.UpdateDead = false;
                        ShowTooltip = true;
                        TipIsError  = true;
                    }
                }
                else
                {
                    if (PieMenu != null)
                    {
                        PieMenu.RemoveSimScene();
                    }
                    this.Remove(PieMenu);
                    PieMenu = null;
                }
            }
            else if (type == UIMouseEventType.MouseUp)
            {
                if (!LiveMode)
                {
                    if (CustomControl != null)
                    {
                        CustomControl.MouseUp(state);
                    }
                    else
                    {
                        ObjectHolder.MouseUp(state);
                    }
                    return;
                }
                state.UIState.TooltipProperties.Show    = false;
                state.UIState.TooltipProperties.Opacity = 0;
                ShowTooltip = false;
                TipIsError  = false;
            }
        }
Beispiel #3
0
        public override void Update(UpdateState state)
        {
            base.Update(state);
            Cheats.Update(state);

            if (!vm.Ready)
            {
                return;
            }

            if (ActiveEntity == null || ActiveEntity.Dead || ActiveEntity.PersistID != SelectedSimID)
            {
                ActiveEntity = vm.Entities.FirstOrDefault(x => x is VMAvatar && x.PersistID == SelectedSimID); //try and hook onto a sim if we have none selected.
                if (ActiveEntity == null)
                {
                    ActiveEntity = vm.Entities.FirstOrDefault(x => x is VMAvatar);
                }

                if (!FoundMe && ActiveEntity != null)
                {
                    vm.Context.World.State.CenterTile   = new Vector2(ActiveEntity.VisualPosition.X, ActiveEntity.VisualPosition.Y);
                    vm.Context.World.State.ScrollAnchor = null;
                    FoundMe = true;
                }
                Queue.QueueOwner = ActiveEntity;
            }

            if (GotoObject == null)
            {
                GotoObject = vm.Context.CreateObjectInstance(GOTO_GUID, LotTilePos.OUT_OF_WORLD, Direction.NORTH, true).Objects[0];
            }

            if (ActiveEntity != null && BlockingDialog != null)
            {
                //are we still waiting on a blocking dialog? if not, cancel.
                if (ActiveEntity.Thread != null && (ActiveEntity.Thread.BlockingState == null || !(ActiveEntity.Thread.BlockingState is VMDialogResult)))
                {
                    UIScreen.RemoveDialog(BlockingDialog);
                    LastDialogID   = 0;
                    BlockingDialog = null;
                }
            }

            if (Visible)
            {
                if (ShowTooltip)
                {
                    state.UIState.TooltipProperties.UpdateDead = false;
                }

                bool scrolled = false;
                if (RMBScroll)
                {
                    World.State.ScrollAnchor = null;
                    Vector2 scrollBy = new Vector2();
                    if (state.TouchMode)
                    {
                        scrollBy   = new Vector2(RMBScrollX - state.MouseState.X, RMBScrollY - state.MouseState.Y);
                        RMBScrollX = state.MouseState.X;
                        RMBScrollY = state.MouseState.Y;
                        scrollBy  /= 128f;
                        scrollBy  /= FSOEnvironment.DPIScaleFactor;
                    }
                    else
                    {
                        scrollBy  = new Vector2(state.MouseState.X - RMBScrollX, state.MouseState.Y - RMBScrollY);
                        scrollBy *= 0.0005f;
                    }
                    World.Scroll(scrollBy);
                    scrolled = true;
                }
                if (MouseIsOn)
                {
                    if (state.MouseState.RightButton == ButtonState.Pressed)
                    {
                        if (RMBScroll == false)
                        {
                            RMBScroll  = true;
                            RMBScrollX = state.MouseState.X;
                            RMBScrollY = state.MouseState.Y;
                        }
                    }
                    else
                    {
                        RMBScroll = false;
                        if (!scrolled && GlobalSettings.Default.EdgeScroll && !state.TouchMode)
                        {
                            scrolled = World.TestScroll(state);
                        }
                    }
                }

                if (LiveMode)
                {
                    LiveModeUpdate(state, scrolled);
                }
                else if (CustomControl != null)
                {
                    CustomControl.Update(state, scrolled);
                }
                else
                {
                    ObjectHolder.Update(state, scrolled);
                }

                //set cutaway around mouse

                if (vm.Context.Blueprint != null)
                {
                    World.State.DynamicCutaway = (WallsMode == 1);
                    //first we need to cycle the rooms that are being cutaway. Keep this up even if we're in all-cut mode.
                    var mouseTilePos = World.State.WorldSpace.GetTileAtPosWithScroll(new Vector2(state.MouseState.X, state.MouseState.Y) / FSOEnvironment.DPIScaleFactor);
                    var roomHover    = vm.Context.GetRoomAt(LotTilePos.FromBigTile((short)(mouseTilePos.X), (short)(mouseTilePos.Y), World.State.Level));
                    var outside      = (vm.Context.RoomInfo[roomHover].Room.IsOutside);
                    if (!outside && !CutRooms.Contains(roomHover))
                    {
                        CutRooms.Add(roomHover); //outside hover should not persist like with other rooms.
                    }
                    while (CutRooms.Count > 3)
                    {
                        CutRooms.Remove(CutRooms.ElementAt(0));
                    }

                    if (LastWallMode != WallsMode)
                    {
                        if (WallsMode == 0) //walls down
                        {
                            LastCuts = new bool[vm.Context.Architecture.Width * vm.Context.Architecture.Height];
                            vm.Context.Blueprint.Cutaway = LastCuts;
                            vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED));
                            for (int i = 0; i < LastCuts.Length; i++)
                            {
                                LastCuts[i] = true;
                            }
                        }
                        else if (WallsMode == 1)
                        {
                            MouseCutRect = new Rectangle();
                            LastCutRooms = new HashSet <uint>()
                            {
                                uint.MaxValue
                            };                                                    //must regenerate cuts
                        }
                        else //walls up or roof
                        {
                            LastCuts = new bool[vm.Context.Architecture.Width * vm.Context.Architecture.Height];
                            vm.Context.Blueprint.Cutaway = LastCuts;
                            vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED));
                        }
                        LastWallMode = WallsMode;
                    }

                    if (WallsMode == 1)
                    {
                        int recut      = 0;
                        var finalRooms = new HashSet <uint>(CutRooms);

                        var newCut = new Rectangle((int)(mouseTilePos.X - 2.5), (int)(mouseTilePos.Y - 2.5), 5, 5);
                        newCut.X -= VMArchitectureTools.CutCheckDir[(int)World.State.Rotation][0] * 2;
                        newCut.Y -= VMArchitectureTools.CutCheckDir[(int)World.State.Rotation][1] * 2;
                        if (newCut != MouseCutRect)
                        {
                            MouseCutRect = newCut;
                            recut        = 1;
                        }

                        if (LastFloor != World.State.Level || LastRotation != World.State.Rotation || !finalRooms.SetEquals(LastCutRooms))
                        {
                            LastCuts     = VMArchitectureTools.GenerateRoomCut(vm.Context.Architecture, World.State.Level, World.State.Rotation, finalRooms);
                            recut        = 2;
                            LastFloor    = World.State.Level;
                            LastRotation = World.State.Rotation;
                        }
                        LastCutRooms = finalRooms;

                        if (recut > 0)
                        {
                            var finalCut = new bool[LastCuts.Length];
                            Array.Copy(LastCuts, finalCut, LastCuts.Length);
                            var notableChange = VMArchitectureTools.ApplyCutRectangle(vm.Context.Architecture, World.State.Level, finalCut, MouseCutRect);
                            if (recut > 1 || notableChange || LastRectCutNotable)
                            {
                                vm.Context.Blueprint.Cutaway = finalCut;
                                vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED));
                            }
                            LastRectCutNotable = notableChange;
                        }
                    }
                }
            }
        }
Beispiel #4
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args)
        {
            var operand     = (VMSetToNextOperand)args;
            var targetValue = VMMemory.GetVariable(context, operand.TargetOwner, operand.TargetData);
            var entities    = context.VM.Entities;

            VMEntity Pointer = context.VM.GetObjectById(targetValue);

            //re-evaluation of what this actually does:
            //tries to find the next object id (from the previous) that meets a specific condition.
            //the previous object id is supplied via the target variable
            //
            //we should take the first result with object id > targetValue.

            if (operand.SearchType == VMSetToNextSearchType.PartOfAMultipartTile)
            {
                var target = context.VM.GetObjectById(targetValue);
                if (target == null || (!target.MultitileGroup.MultiTile))
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);                                                      //single part
                }
                else
                {
                    var   group      = target.MultitileGroup.Objects;
                    bool  found      = false;
                    short bestID     = 0;
                    short smallestID = 0;
                    for (int i = 0; i < group.Count; i++)
                    {
                        var temp = group[i];
                        if (temp.ObjectID < smallestID || smallestID == 0)
                        {
                            smallestID = temp.ObjectID;
                        }
                        if (temp.ObjectID > targetValue)
                        {
                            if ((!found) || (temp.ObjectID < bestID))
                            {
                                found  = true;
                                bestID = temp.ObjectID;
                            }
                        }
                    }
                    if (found)
                    {
                        VMMemory.SetVariable(context, operand.TargetOwner, operand.TargetData, bestID);
                        return(VMPrimitiveExitCode.GOTO_TRUE);
                    }
                    else
                    {
                        VMMemory.SetVariable(context, operand.TargetOwner, operand.TargetData, smallestID);
                        return(VMPrimitiveExitCode.GOTO_TRUE);
                    }
                }
            }
            else if (operand.SearchType == VMSetToNextSearchType.ObjectAdjacentToObjectInLocal)
            {
                VMEntity anchor = context.VM.GetObjectById((short)context.Locals[operand.Local]);
                int      ptrDir = -1;

                targetValue = 0;
                if (Pointer != null)
                {
                    ptrDir = getAdjDir(anchor, Pointer);
                    if (ptrDir == 3)
                    {
                        return(VMPrimitiveExitCode.GOTO_FALSE);             //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.SetToNextCache.GetObjectsAt(LotTilePos.FromBigTile(
                                                                                 (short)(anchor.Position.TileX + off.X),
                                                                                 (short)(anchor.Position.TileY + off.Y),
                                                                                 anchor.Position.Level));

                    if (adj != null && adj.Count > 0)
                    {
                        //lists are ordered by object id. first is the smallest.
                        VMMemory.SetVariable(context, operand.TargetOwner, operand.TargetData, adj[0].ObjectID);
                        return(VMPrimitiveExitCode.GOTO_TRUE);
                    }
                }
                return(VMPrimitiveExitCode.GOTO_FALSE);
            }
            else
            {
                //if we've cached the search type, use that instead of all objects
                switch (operand.SearchType)
                {
                case VMSetToNextSearchType.ObjectOnSameTile:
                    entities = context.VM.Context.SetToNextCache.GetObjectsAt(Pointer.Position); break;

                case VMSetToNextSearchType.Person:
                    entities = context.VM.Context.SetToNextCache.Avatars; break;

                case VMSetToNextSearchType.ObjectOfType:
                    entities = context.VM.Context.SetToNextCache.GetObjectsByGUID(operand.GUID); break;
                }
                if (entities == null)
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }

                bool     loop  = (operand.SearchType == VMSetToNextSearchType.ObjectOnSameTile);
                VMEntity first = null;

                for (int i = 0; i < entities.Count; i++) //generic search through all objects
                {
                    var  temp  = entities[i];
                    bool found = false;
                    if (temp.ObjectID > targetValue || loop)
                    {
                        switch (operand.SearchType)
                        { //manual search types
                        case VMSetToNextSearchType.NonPerson:
                            found = (temp.GetType() == typeof(VMGameObject));
                            break;

                        case VMSetToNextSearchType.NeighborId:
                            throw new VMSimanticsException("Not implemented!", context);

                        case VMSetToNextSearchType.ObjectWithCategoryEqualToSP0:
                            found = (temp.Object.OBJ.FunctionFlags == context.Args[0]);     //I'm assuming that means "Stack parameter 0", that category means function and that it needs to be exactly the same (no subsets)
                            break;

                        case VMSetToNextSearchType.NeighborOfType:
                            throw new VMSimanticsException("Not implemented!", context);

                        case VMSetToNextSearchType.Career:
                            throw new VMSimanticsException("Not implemented!", context);

                        case VMSetToNextSearchType.ClosestHouse:
                            throw new VMSimanticsException("Not implemented!", context);

                        default:
                            //set to next object, or cached search.
                            found = true; break;
                        }
                        if (temp.ObjectID <= targetValue && found)
                        {
                            //remember the first element in case we need to loop back to it (set to next tile on same location)
                            if (first == null)
                            {
                                first = temp;
                            }
                            found = false;
                        }
                    }
                    if (found)
                    {
                        VMMemory.SetVariable(context, operand.TargetOwner, operand.TargetData, temp.ObjectID);
                        return(VMPrimitiveExitCode.GOTO_TRUE);
                    }
                }

                if (loop)
                {
                    if (first == null)
                    {
                        return(VMPrimitiveExitCode.GOTO_FALSE);               //no elements of this kind at all.
                    }
                    else
                    {
                        VMMemory.SetVariable(context, operand.TargetOwner, operand.TargetData, first.ObjectID); //set to loop, so go back to lowest obj id.
                        return(VMPrimitiveExitCode.GOTO_TRUE);
                    }
                    //loop around
                }
            }
            return(VMPrimitiveExitCode.GOTO_FALSE); //ran out of objects to test
        }
Beispiel #5
0
        public static uint FIRE_GUID = 0x24C95F99; //probably different for ts1

        public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args)
        {
            var operand = (VMBurnOperand)args;

            if (!context.VM.TS1 && context.VM.Tuning.GetTuning("special", 0, 0) != 1f)
            {
                return(VMPrimitiveExitCode.GOTO_FALSE); //fire disabled for now
            }
            if ((int)context.VM.Context.NextRandom(10000) >= context.VM.Context.Clock.FirePercent)
            {
                return(VMPrimitiveExitCode.GOTO_FALSE);
            }

            //as fires burn, the chance they can spread lowers dramatically.
            context.VM.Context.Clock.FirePercent -= 500; // lower by 5% every spread. 40 spreads reaches 0.
            if (context.VM.Context.Clock.FirePercent < 0)
            {
                context.VM.Context.Clock.FirePercent = 0;
            }

            //begin the burn setup.
            var arch  = context.VM.Context.Architecture;
            var query = context.VM.Context.ObjectQueries;

            bool[] fires  = new bool[arch.Width * arch.Height];
            var    spread = new Queue <LotTilePos>();

            LotTilePos pos;

            switch (operand.Type)
            {
            case VMBurnType.FrontOfStackObject:
                pos = new LotTilePos(context.StackObject.Position);
                switch (context.StackObject.Direction)
                {
                case Direction.SOUTH:
                    pos.y += 16;
                    break;

                case Direction.WEST:
                    pos.x -= 16;
                    break;

                case Direction.EAST:
                    pos.x += 16;
                    break;

                case Direction.NORTH:
                    pos.y -= 16;
                    break;
                }
                break;

            case VMBurnType.StackObject:
            default:
                pos = context.StackObject.Position;
                break;
            }

            bool first     = true;
            bool madeAFire = false;

            spread.Enqueue(pos);

            while (spread.Count > 0)
            {
                var item = spread.Dequeue();

                var objat = query.GetObjectsAt(item) ?? new List <VMEntity>();

                if (first && !(objat?.Any(x => x.Object.OBJ.GUID == FIRE_GUID) ?? false))
                {
                    madeAFire = true;
                    context.VM.Context.CreateObjectInstance(FIRE_GUID, LotTilePos.FromBigTile(pos.TileX, pos.TileY, pos.Level), Direction.NORTH);
                }
                first = false;

                foreach (var obj in objat)
                {
                    var inUse = obj.IsInUse(context.VM.Context, true) || (obj is VMAvatar && ((VMAvatar)obj).GetPersonData(Model.VMPersonDataVariable.IsGhost) > 0);
                    if (inUse)
                    {
                        continue;
                    }
                    foreach (var sobj in obj.MultitileGroup.Objects)
                    {
                        //attempt to add fire for this element.
                        //for each tile add a spread.

                        //is this object burnable? if so, set it as burning
                        if (sobj.Position.Level != pos.Level)
                        {
                            continue;
                        }

                        if ((((VMEntityFlags2)sobj.GetValue(Model.VMStackObjectVariable.FlagField2) & VMEntityFlags2.Burns) > 0) && !sobj.GetFlag(VMEntityFlags.FireProof))
                        {
                            sobj.SetFlag(VMEntityFlags.Burning, true);
                            var fpos  = sobj.Position;
                            var index = fpos.TileX + fpos.TileY * arch.Width;

                            if (fires[index] || (query.GetObjectsAt(fpos)?.Any(x => x.Object.OBJ.GUID == FIRE_GUID) ?? false))
                            {
                                fires[index] = true;
                                continue;
                            }
                            spread.Enqueue(fpos);

                            madeAFire = true;
                            context.VM.Context.CreateObjectInstance(FIRE_GUID, LotTilePos.FromBigTile(fpos.TileX, fpos.TileY, fpos.Level), Direction.NORTH);
                            fires[index] = true;
                        }
                    }
                }
            }

            return(madeAFire?VMPrimitiveExitCode.GOTO_TRUE:VMPrimitiveExitCode.GOTO_FALSE);
        }
Beispiel #6
0
        public List <VMObstacle> GenerateRoomObs(ushort room, sbyte level, Rectangle bounds, VMContext context)
        {
            var result = new List <VMObstacle>();

            if (room == 0)
            {
                bounds = new Rectangle(1, 1, Width - 2, Height - 2);
            }
            var x1 = Math.Max(0, bounds.X - 1);
            var x2 = Math.Min(Width, bounds.Right + 1);
            var y1 = Math.Max(0, bounds.Y - 1);
            var y2 = Math.Min(Height, bounds.Bottom + 1);

            for (int y = y1; y < y2; y++)
            {
                VMObstacle next = null;
                for (int x = x1; x < x2; x++)
                {
                    uint tRoom = Map[x + y * Width];
                    if ((ushort)tRoom != room && ((tRoom >> 16) & 0x7FFF) != room)
                    {
                        //is there a door on this tile?
                        var door = (context.ObjectQueries.GetObjectsAt(LotTilePos.FromBigTile((short)x, (short)y, level))?.FirstOrDefault(
                                        o => ((VMEntityFlags2)(o.GetValue(VMStackObjectVariable.FlagField2)) & VMEntityFlags2.ArchitectualDoor) > 0)
                                    );
                        if (door != null)
                        {
                            //ok... is is a portal to this room? block all sides that are not a portal to this room
                            var otherSide = door.MultitileGroup.Objects.FirstOrDefault(o => context.GetObjectRoom(o) == room && o.EntryPoints[15].ActionFunction != 0);
                            if (otherSide != null)
                            {
                                //make a hole for this door
                                if (next != null)
                                {
                                    next = null;
                                }
                                // note: the sims 1 stops here. this creates issues where sims can walk through doors in some circumstance
                                // eg. two doors back to back into the same room. The sim will not perform a room route to the middle room, they will just walk through the door.
                                // like, through it. This also works for pools but some additional rules prevent you from doing anything too silly.
                                // we want to create 1 unit thick walls blocking each non-portal side.

                                // todo: fix for this
                                continue;
                            }
                        }

                        if (next != null)
                        {
                            next.x2 += 16;
                        }
                        else
                        {
                            next = new VMObstacle((x << 4) - 3, (y << 4) - 3, (x << 4) + 19, (y << 4) + 19);
                            result.Add(next);
                        }
                    }
                    else
                    {
                        if (next != null)
                        {
                            next = null;
                        }
                    }
                }
            }
            OptimizeObstacles(result);
            return(result);
        }
Beispiel #7
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args)
        {
            var operand = (VMFindLocationForOperand)args;
            var refObj  = (operand.UseLocalAsRef) ? context.VM.GetObjectById(context.Locals[operand.Local]) : context.Caller;

            var obj   = context.StackObject;
            var flags = VMPlaceRequestFlags.AcceptSlots;

            if (operand.UserEditableTilesOnly)
            {
                flags |= VMPlaceRequestFlags.UserBuildableLimit;
            }
            if (operand.AllowIntersection && operand.Mode != 4 && operand.Mode != 3)
            {
                flags |= VMPlaceRequestFlags.AllowIntersection;
            }

            switch (operand.Mode)
            {
            case 0:
                //default
                if (FindLocationFor(obj, refObj, context.VM.Context, flags))
                {
                    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, flags);
                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, flags))
                {
                    return(VMPrimitiveExitCode.GOTO_TRUE);
                }
                else
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }

            case 5:
                //random
                var ctx = context.VM.Context;
                for (int i = 0; i < 100; i++)
                {
                    var loc = LotTilePos.FromBigTile((short)(ctx.NextRandom((ulong)ctx.Architecture.Width - 2) + 1), (short)(ctx.NextRandom((ulong)ctx.Architecture.Height - 2) + 1), refObj.Position.Level);
                    if (obj.SetPosition(loc, Direction.NORTH, ctx, flags).Status == VMPlacementError.Success)
                    {
                        return(VMPrimitiveExitCode.GOTO_TRUE);
                    }
                }
                return(VMPrimitiveExitCode.GOTO_FALSE);
            }

            return(VMPrimitiveExitCode.GOTO_FALSE);
        }
        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 + ") ";
            var    tilePos  = vm.Context.World.EstTileAtPosWithScroll(Control.GetScaledPoint(state.MouseState.Position).ToVector2() / FSOEnvironment.DPIScaleFactor);

            try {
                switch (cmd.ToLowerInvariant())
                {
                case "roomat":
                    //!roomat
                    LotTilePos targetrPos = new LotTilePos((short)(tilePos.X * 16), (short)(tilePos.Y * 16), vm.Context.World.State.Level);
                    var        room       = vm.Context.GetRoomAt(targetrPos);
                    response += "Room at (" + targetrPos.TileX + ", " + targetrPos.TileY + ", " + targetrPos.Level + ") is " + room + "\r\n";
                    var roomInfo = vm.Context.RoomInfo[room];
                    foreach (var obj in roomInfo.Room.AdjRooms)
                    {
                        var info = vm.Context.RoomInfo[obj];
                        response += "adjacent room: " + obj;
                        response += "\r\n";
                    }
                    break;

                case "objat":
                    //!objat (objects at mouse position)
                    LotTilePos targetPos = LotTilePos.FromBigTile((short)tilePos.X, (short)tilePos.Y, vm.Context.World.State.Level);
                    if (args == "oow")
                    {
                        targetPos = LotTilePos.OUT_OF_WORLD;
                    }
                    var objs = vm.Context.ObjectQueries.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)
            {
                response += "Bad command.";
            }
            vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, response));
        }
Beispiel #9
0
        public void ShowPieMenu(Point pt, UpdateState state)
        {
            if (!LiveMode)
            {
                /*
                 * if (CustomControl != null) CustomControl.MouseDown(state);
                 * else ObjectHolder.MouseDown(state);
                 */
                if (FSOEnvironment.SoftwareKeyboard && ObjectHolder.Holding == null)
                {
                    ObjectHolder.MouseDown(state);
                }
                return;
            }
            if (PieMenu == null && ActiveEntity != null)
            {
                VMEntity obj;
                //get new pie menu, make new pie menu panel for it
                var tilePos = World.EstTileAtPosWithScroll(new Vector2(pt.X, pt.Y) / FSOEnvironment.DPIScaleFactor);

                LotTilePos targetPos = LotTilePos.FromBigTile((short)tilePos.X, (short)tilePos.Y, World.State.Level);
                if (vm.Context.SolidToAvatars(targetPos).Solid)
                {
                    targetPos = LotTilePos.OUT_OF_WORLD;
                }

                GotoObject.SetPosition(targetPos, Direction.NORTH, vm.Context);

                var newHover = World.GetObjectIDAtScreenPos(pt.X,
                                                            pt.Y,
                                                            GameFacade.GraphicsDevice);

                ObjectHover = newHover;

                bool objSelected = ObjectHover > 0;
                if (objSelected || (GotoObject.Position != LotTilePos.OUT_OF_WORLD && ObjectHover <= 0))
                {
                    if (objSelected)
                    {
                        obj = vm.GetObjectById(ObjectHover);
                    }
                    else
                    {
                        obj = GotoObject;
                    }
                    if (obj != null)
                    {
                        obj = obj.MultitileGroup.GetInteractionGroupLeader(obj);
                        if (obj is VMGameObject && ((VMGameObject)obj).Disabled > 0)
                        {
                            var flags = ((VMGameObject)obj).Disabled;

                            if ((flags & VMGameObjectDisableFlags.ForSale) > 0)
                            {
                                //for sale
                                var retailPrice = obj.MultitileGroup.Price; //wrong... should get this from catalog
                                var salePrice   = obj.MultitileGroup.SalePrice;
                                ShowErrorTooltip(state, 22, true, "$" + retailPrice.ToString("##,#0"), "$" + salePrice.ToString("##,#0"));
                            }
                            else if ((flags & VMGameObjectDisableFlags.LotCategoryWrong) > 0)
                            {
                                ShowErrorTooltip(state, 21, true); //category wrong
                            }
                            else if ((flags & VMGameObjectDisableFlags.TransactionIncomplete) > 0)
                            {
                                ShowErrorTooltip(state, 27, true); //transaction not yet complete
                            }
                            else if ((flags & VMGameObjectDisableFlags.ObjectLimitExceeded) > 0)
                            {
                                ShowErrorTooltip(state, 24, true); //object is temporarily disabled... todo: something more helpful
                            }
                            else if ((flags & VMGameObjectDisableFlags.PendingRoommateDeletion) > 0)
                            {
                                ShowErrorTooltip(state, 16, true); //pending roommate deletion
                            }
                        }
                        else
                        {
                            var menu = obj.GetPieMenu(vm, ActiveEntity, false, true);
                            if (menu.Count != 0)
                            {
                                HITVM.Get().PlaySoundEvent(UISounds.PieMenuAppear);
                                PieMenu = new UIPieMenu(menu, obj, ActiveEntity, this);
                                this.Add(PieMenu);
                                PieMenu.X = state.MouseState.X / FSOEnvironment.DPIScaleFactor;
                                PieMenu.Y = state.MouseState.Y / FSOEnvironment.DPIScaleFactor;
                                PieMenu.UpdateHeadPosition(state.MouseState.X, state.MouseState.Y);
                            }
                        }
                    }
                }
                else
                {
                    ShowErrorTooltip(state, 0, true);
                }
            }
            else
            {
                if (PieMenu != null)
                {
                    PieMenu.RemoveSimScene();
                }
                this.Remove(PieMenu);
                PieMenu = null;
            }
        }
Beispiel #10
0
        private void UpdateCutaway(UpdateState state)
        {
            if (vm.Context.Blueprint != null)
            {
                World.State.DynamicCutaway = (WallsMode == 1);
                //first we need to cycle the rooms that are being cutaway. Keep this up even if we're in all-cut mode.
                var mouseTilePos = World.EstTileAtPosWithScroll(new Vector2(state.MouseState.X, state.MouseState.Y) / FSOEnvironment.DPIScaleFactor);
                var roomHover    = vm.Context.GetRoomAt(LotTilePos.FromBigTile((short)(mouseTilePos.X), (short)(mouseTilePos.Y), World.State.Level));
                var outside      = (vm.Context.RoomInfo[roomHover].Room.IsOutside);
                if (!outside && !CutRooms.Contains(roomHover))
                {
                    CutRooms.Add(roomHover); //outside hover should not persist like with other rooms.
                }
                while (CutRooms.Count > 3)
                {
                    CutRooms.Remove(CutRooms.ElementAt(0));
                }

                if (LastWallMode != WallsMode)
                {
                    if (WallsMode == 0) //walls down
                    {
                        LastCuts = new bool[vm.Context.Architecture.Width * vm.Context.Architecture.Height];
                        vm.Context.Blueprint.Cutaway = LastCuts;
                        vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED));
                        for (int i = 0; i < LastCuts.Length; i++)
                        {
                            LastCuts[i] = true;
                        }
                    }
                    else if (WallsMode == 1)
                    {
                        MouseCutRect = new Rectangle();
                        LastCutRooms = new HashSet <uint>()
                        {
                            uint.MaxValue
                        };                                                    //must regenerate cuts
                    }
                    else //walls up or roof
                    {
                        LastCuts = new bool[vm.Context.Architecture.Width * vm.Context.Architecture.Height];
                        vm.Context.Blueprint.Cutaway = LastCuts;
                        vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED));
                    }
                    LastWallMode = WallsMode;
                }

                if (WallsMode == 1)
                {
                    HashSet <uint> finalRooms;
                    int            recut = 0;
                    if (FSOEnvironment.SoftwareKeyboard)
                    {
                        finalRooms = new HashSet <uint>();
                        foreach (var room in vm.Context.RoomInfo)
                        {
                            if (!room.Room.IsOutside && room.Room.Floor == World.State.Level - 1)
                            {
                                finalRooms.Add(room.Room.RoomID);
                            }
                        }
                    }
                    else
                    {
                        if (RMBScroll || !MouseIsOn)
                        {
                            return;
                        }
                        finalRooms = new HashSet <uint>(CutRooms);
                        var newCut = new Rectangle((int)(mouseTilePos.X - 2.5), (int)(mouseTilePos.Y - 2.5), 5, 5);
                        newCut.X -= VMArchitectureTools.CutCheckDir[(int)World.State.CutRotation][0] * 2;
                        newCut.Y -= VMArchitectureTools.CutCheckDir[(int)World.State.CutRotation][1] * 2;
                        if (newCut != MouseCutRect)
                        {
                            MouseCutRect = newCut;
                            recut        = 1;
                        }
                    }

                    if (LastFloor != World.State.Level || LastRotation != World.State.CutRotation || !finalRooms.SetEquals(LastCutRooms))
                    {
                        LastCuts     = VMArchitectureTools.GenerateRoomCut(vm.Context.Architecture, World.State.Level, World.State.CutRotation, finalRooms);
                        recut        = 2;
                        LastFloor    = World.State.Level;
                        LastRotation = World.State.CutRotation;
                    }
                    LastCutRooms = finalRooms;

                    if (recut > 0)
                    {
                        var finalCut = new bool[LastCuts.Length];
                        Array.Copy(LastCuts, finalCut, LastCuts.Length);
                        var notableChange = VMArchitectureTools.ApplyCutRectangle(vm.Context.Architecture, World.State.Level, finalCut, MouseCutRect);
                        if (recut > 1 || notableChange || LastRectCutNotable)
                        {
                            vm.Context.Blueprint.Cutaway = finalCut;
                            vm.Context.Blueprint.Damage.Add(new FSO.LotView.Model.BlueprintDamage(FSO.LotView.Model.BlueprintDamageType.WALL_CUT_CHANGED));
                        }
                        LastRectCutNotable = notableChange;
                    }
                }
            }
        }
Beispiel #11
0
        public void SetFamilyMember(int index)
        {
            if (RepresentFamily.Count <= index)
            {
                var member = (VMAvatar)vm.Context.CreateObjectInstance(0x7FD96B54, LotTilePos.OUT_OF_WORLD

                                                                       , Direction.EAST, false).BaseObject;

                RepresentFamily.Add(member);
            }

            var fam = RepresentFamily[index];

            fam.SetPosition(LotTilePos.FromBigTile(34, 31, 1) +
                            new LotTilePos((short)((((index + 1) / 2) % 2) * 8), (short)(((index % 2) * 2 - 1) * ((index + 1) / 2) * 10), 0), Direction.EAST, vm.Context, VMPlaceRequestFlags.AllowIntersection);
            var data = WIPFamily[index];

            //set this person's body and head

            fam.Name                = data.Name;
            fam.Avatar.Skeleton     = Content.Get().AvatarSkeletons.Get((data.Gender > 1) ? "child.skel" : "adult.skel").Clone();
            fam.Avatar.BaseSkeleton = fam.Avatar.Skeleton.Clone();
            fam.Avatar.ReloadSkeleton();

            fam.SetPersonData(VMPersonDataVariable.PersonsAge, (short)((data.Gender > 1) ? 12 : 21));
            fam.InitBodyData(vm.Context);

            var oft = new Outfit()
            {
                TS1AppearanceID = data.Body + ".apr", TS1TextureID = data.BodyTex
            };
            var code = (data.Gender > 1) ? "u" : ((data.Gender == 0) ? "m" : "f");
            var hg   = data.HandgroupTex;

            oft.LiteralHandgroup = new HandGroup()
            {
                TS1HandSet = true,
                LightSkin  = new HandSet()
                {
                    LeftHand = new Hand()
                    {
                        Idle = new Gesture()
                        {
                            Name = "h" + code + "lo.apr", TexName = "huao" + hg
                        },
                        Pointing = new Gesture()
                        {
                            Name = "h" + code + "lp.apr", TexName = "huap" + hg
                        },
                        Fist = new Gesture()
                        {
                            Name = "h" + code + "lc.apr", TexName = "huac" + hg
                        }
                    },
                    RightHand = new Hand()
                    {
                        Idle = new Gesture()
                        {
                            Name = "h" + code + "ro.apr", TexName = "huao" + hg
                        },
                        Pointing = new Gesture()
                        {
                            Name = "h" + code + "rp.apr", TexName = "huap" + hg
                        },
                        Fist = new Gesture()
                        {
                            Name = "h" + code + "rc.apr", TexName = "huac" + hg
                        }
                    }
                }
            };

            fam.BodyOutfit = new FSO.SimAntics.Model.VMOutfitReference(oft);
            fam.HeadOutfit = new FSO.SimAntics.Model.VMOutfitReference(new Outfit()
            {
                TS1AppearanceID = data.Head + ".apr", TS1TextureID = data.HeadTex
            });
        }
Beispiel #12
0
        private void UpdateCarousel(UpdateState state)
        {
            var frac     = 60f / FSOEnvironment.RefreshRate;
            var minSpeed = (Math.PI / 240f) * frac;
            var mult     = (float)Math.Pow(0.95, frac);

            var moving = 0;

            if (state.MouseStates.Count > 0)
            {
                if (XLast == -1)
                {
                    if (state.MouseState.Y > 282)
                    {
                        XLast = state.MouseState.X;
                    }
                }
                else
                {
                    if (state.MouseState.Y / (float)UIScreen.Current.ScreenHeight > 0.625f)
                    {
                        BodySpeed = ((XLast - state.MouseState.X) / 200f) * frac;
                        moving    = 1;
                    }
                    else
                    {
                        HeadSpeed = ((XLast - state.MouseState.X) / 200f) * frac;
                        moving    = 2;
                    }
                    XLast = state.MouseState.X;
                }
            }
            else
            {
                XLast = -1;
            }

            BodySpeed = BodySpeed * mult;
            if (Math.Abs(BodySpeed) < minSpeed && moving != 1)
            {
                var targInt = (int)Math.Round(BodyPosition);
                BodySpeed = (float)Math.Max(-minSpeed, Math.Min(minSpeed, targInt - BodyPosition));
            }

            HeadSpeed = HeadSpeed * mult;
            if (Math.Abs(HeadSpeed) < minSpeed && moving != 2)
            {
                var targInt = (int)Math.Round(HeadPosition);
                HeadSpeed = (float)Math.Max(-minSpeed, Math.Min(minSpeed, targInt - HeadPosition));
            }

            HeadPosition += HeadSpeed;
            BodyPosition += BodySpeed;

            var room = vm.Context.GetRoomAt(LotTilePos.FromBigTile(28, 21, 1));

            foreach (var body in BodyAvatars)
            {
                body.SetRoom(room);
            }
            foreach (var head in HeadAvatars)
            {
                head.SetRoom(65534);
            }

            var curbody = (int)BodyPosition;

            if (curbody != BodyPositionLast)
            {
                FSO.HIT.HITVM.Get().PlaySoundEvent(FSO.Client.UI.Model.UISounds.Click);
                int replacePos = (int)DirectionUtils.PosMod((-BodyPositionLast), 18);
                int increment  = 1;
                if (curbody < BodyPositionLast) //start adding after last position's compliment position
                {
                    increment  = -1;
                    replacePos = (int)DirectionUtils.PosMod((-BodyPositionLast), 18);
                }
                var total = Math.Abs(curbody - BodyPositionLast);
                for (int i = 0; i < total; i++)
                {
                    if (increment == -1)
                    {
                        SetBody(BodyAvatars[replacePos], BodyPositionLast - 1);
                    }
                    else
                    {
                        SetBody(BodyAvatars[replacePos], BodyPositionLast + 17);
                    }
                    BodyPositionLast += increment;
                    replacePos        = ((replacePos - increment) + 18) % 18;
                }
                BodyPositionLast = curbody;
            }

            var curhead = (int)HeadPosition;

            if (curhead != HeadPositionLast)
            {
                FSO.HIT.HITVM.Get().PlaySoundEvent(FSO.Client.UI.Model.UISounds.Click);
                int replacePos = (int)DirectionUtils.PosMod(-HeadPositionLast, 18);
                int increment  = 1;
                if (curhead < HeadPositionLast) //start adding after last position's compliment position
                {
                    increment  = -1;
                    replacePos = (int)DirectionUtils.PosMod((-HeadPositionLast), 18);
                }
                var total = Math.Abs(curhead - HeadPositionLast);
                for (int i = 0; i < total; i++)
                {
                    if (increment == -1)
                    {
                        SetHead(HeadAvatars[replacePos], HeadPositionLast - 1);
                    }
                    else
                    {
                        SetHead(HeadAvatars[replacePos], HeadPositionLast + 17);
                    }
                    HeadPositionLast += increment;
                    replacePos        = ((replacePos - increment) + 18) % 18;
                }
                HeadPositionLast = curhead;
            }
        }