Example #1
0
        private static bool HandleSwitch(Session Session, Item Item, RoomInstance Instance, ItemEventType Event, int RequestData, uint Opcode)
        {
            if (Event != ItemEventType.Interact)
            {
                return(true);
            }
            RoomActor actor = Instance.GetActor(Session.CharacterId);

            if (actor == null)
            {
                return(true);
            }

            foreach (Item item in Instance.GetFloorItems())
            {
                if (item.Definition.Behavior != ItemBehavior.WiredTrigger || WiredTypesUtil.TriggerFromInt(item.Definition.BehaviorData) != WiredTriggerTypes.state_changed)
                {
                    continue;
                }

                String[] Selected = item.WiredData.Data1.Split('|');

                if (Selected.Contains(Item.Id.ToString()))
                {
                    Instance.WiredManager.ExecuteActions(item, actor);
                }
            }
            return(true);
        }
Example #2
0
        private static bool HandleWired(Session Session, Item Item, RoomInstance Instance, ItemEventType Event, int RequestData, uint Opcode)
        {
            switch (Event)
            {
            case ItemEventType.Interact:
                switch (Item.Definition.Behavior)
                {
                case ItemBehavior.WiredTrigger:
                    Session.SendData(WiredFurniTriggerComposer.Compose(Item, Instance));
                    break;

                case ItemBehavior.WiredEffect:
                    Session.SendData(WiredFurniActionComposer.Compose(Item, Instance));
                    break;
                }
                break;

            case ItemEventType.Placed:
                Item.WiredData = Instance.WiredManager.LoadWired(Item.Id, Item.Definition.BehaviorData);
                break;

            case ItemEventType.Removing:
                using (SqlDatabaseClient MySqlClient = SqlDatabaseManager.GetClient()) {
                    Instance.WiredManager.RemoveWired(Item.Id, MySqlClient);
                }

                Instance.WiredManager.DeRegisterWalkItem(Item.Id);
                break;

            case ItemEventType.UpdateTick:
                if (Item.Definition.Behavior == ItemBehavior.WiredTrigger)
                {
                    switch (WiredTypesUtil.TriggerFromInt(Item.Definition.BehaviorData))
                    {
                    case WiredTriggerTypes.periodically:
                        Instance.WiredManager.ExecuteActions(Item, null);
                        Item.RequestUpdate(Item.WiredData.Data2);
                        break;

                    case WiredTriggerTypes.at_given_time:
                        Instance.WiredManager.ExecuteActions(Item, null);
                        break;
                    }
                    return(true);
                }
                Item.BroadcastStateUpdate(Instance);
                break;
            }
            return(true);
        }
Example #3
0
        public Item(uint Id, uint DefinitionId, uint UserId, uint RoomId, Vector3 RoomPos, string RoomWallPos, int Rotation,
                    string Flags, string DisplayFlags, bool Untradable, uint SoundManagerId, int SoundManagerOrder, double ExpireTimestamp, WiredManager WiredManager)
        {
            mId                  = Id;
            mDefinitionId        = DefinitionId;
            mUserId              = UserId;
            mRoomId              = RoomId;
            mRoomPos             = RoomPos;
            mRoomWallPos         = RoomWallPos;
            mRoomRot             = Rotation;
            mFlags               = Flags;
            mDisplayFlags        = DisplayFlags;
            mInitialFlags        = Flags;
            mUntradable          = Untradable;
            mCachedDefinition    = ItemDefinitionManager.GetDefinition(mDefinitionId);
            mTmpInteractingUsers = new Dictionary <int, uint> ();
            mSoundManagerId      = SoundManagerId;
            mSoundManagerOrder   = SoundManagerOrder;
            mExpireTimestamp     = ExpireTimestamp;


            if (WiredManager != null && (mCachedDefinition.Behavior == ItemBehavior.WiredCondition || mCachedDefinition.Behavior == ItemBehavior.WiredTrigger || mCachedDefinition.Behavior == ItemBehavior.WiredEffect))
            {
                mWiredData = WiredManager.LoadWired(Id, mCachedDefinition.BehaviorData);
                if (mCachedDefinition.Behavior == ItemBehavior.WiredTrigger)
                {
                    switch (WiredTypesUtil.TriggerFromInt(mCachedDefinition.BehaviorData))
                    {
                    case WiredTriggerTypes.periodically:
                        RequestUpdate(mWiredData.Data2);
                        break;

                    case WiredTriggerTypes.walks_on_furni:
                    case WiredTriggerTypes.walks_off_furni:
                        WiredManager.RegisterWalkItems(mId);
                        break;
                    }
                }
            }
        }
Example #4
0
        public void PerformUpdate(object state)
        {
            //Console.WriteLine(Thread.CurrentThread.ManagedThreadId); // use this only to debug threadpooling...

            List <RoomActor> ActorsToUpdate = new List <RoomActor> ();
            List <RoomActor> ActorsToRemove = new List <RoomActor> ();

            // Copy collection
            Dictionary <uint, RoomActor> ActorsCopy = new Dictionary <uint, RoomActor> ();

            List <RoomActor>[,] NewUserGrid = new List <RoomActor> [mCachedModel.Heightmap.SizeX, mCachedModel.Heightmap.SizeY];

            lock (mActorSyncRoot) {
                foreach (KeyValuePair <uint, RoomActor> CopyItem in mActors)
                {
                    ActorsCopy.Add(CopyItem.Key, CopyItem.Value);
                }
            }

            foreach (RoomActor Actor in ActorsCopy.Values)
            {
                // If the room is unloaded, allow no actors
                if (mUnloaded)
                {
                    ActorsToRemove.Add(Actor);
                    continue;
                }

                // The idle time is increased in every step.
                if (Actor.Type == RoomActorType.UserCharacter)
                {
                    Actor.IncreaseIdleTime(Actor.ReferenceId == Info.OwnerId);
                }

                // If this is a bot, allow the brain to process this update tick.
                if (Actor.Type == RoomActorType.AiBot)
                {
                    ((Bot)Actor.ReferenceObject).Brain.PerformUpdate(this);
                }

                // Remove any walking statusses (they will be re-applied below if neccessary)
                if (Actor.UserStatusses.ContainsKey("mv"))
                {
                    Actor.RemoveStatus("mv");
                    Actor.UpdateNeeded = true;
                }

                // Update actor position if neccessary
                if (Actor.PositionToSet != null)
                {
                    // Check if the new position is in the door
                    if (Actor.Type == RoomActorType.UserCharacter && Actor.PositionToSet.X == mCachedModel.DoorPosition.X && Actor.PositionToSet.Y == mCachedModel.DoorPosition.Y)
                    {
                        ActorsToRemove.Add(Actor);
                        continue;
                    }

                    // Update the actual position
                    Actor.Position      = new Vector3(Actor.PositionToSet.X, Actor.PositionToSet.Y, (Math.Round(GetUserStepHeight(Actor.PositionToSet), 1)));
                    Actor.PositionToSet = null;

                    // Handle any "MoveToAndInteract" events if this was the last step
                    if (!Actor.IsMoving && Actor.MoveToAndInteract > 0 && Actor.Type == RoomActorType.UserCharacter)
                    {
                        Item Item = GetItem(Actor.MoveToAndInteract);

                        if (Item != null)
                        {
                            ItemEventDispatcher.InvokeItemEventHandler(SessionManager.GetSessionByCharacterId(
                                                                           Actor.ReferenceId), Item, this, ItemEventType.Interact, Actor.MoveToAndInteractData);
                        }

                        Actor.MoveToAndInteract = 0;
                    }
                }

                // If there are more steps to be made, handle it.
                if (Actor.IsMoving)
                {
                    // Check if moving to door
                    if (!Actor.IsLeavingRoom && Actor.Pathfinder.Target.X == mCachedModel.DoorPosition.X &&
                        Actor.Pathfinder.Target.Y == mCachedModel.DoorPosition.Y)
                    {
                        Actor.IsLeavingRoom = true;
                    }

                    // Get the next step from the pathfinder
                    Vector2 NextStep = Actor.GetNextStep();

                    // If the user is leaving and has exceeded 11 steps, help him out by instantly
                    // removing them.
                    if (Actor.LeaveStepsTaken >= 11)
                    {
                        ActorsToRemove.Add(Actor);
                        continue;
                    }

                    // If the pathfinder reports no more steps to be made, this is the last step.
                    bool LastStep = !Actor.IsMoving;

                    // Check that the next step is valid and allowed
                    if (NextStep != null && ((!Actor.ClippingEnabled && IsValidPosition(NextStep)) ||
                                             IsValidStep(Actor.Position.GetVector2(), NextStep, LastStep, NewUserGrid)))
                    {
                        // Update "mv" status
                        Actor.SetStatus("mv", NextStep.X + "," + NextStep.Y + "," + (Math.Round(GetUserStepHeight(NextStep), 1)).ToString().Replace(',', '.'));
                        Actor.PositionToSet = NextStep;

                        // Update new/temporary grid with our new move to position
                        if (NewUserGrid [NextStep.X, NextStep.Y] == null)
                        {
                            NewUserGrid [NextStep.X, NextStep.Y] = new List <RoomActor> ();
                        }

                        NewUserGrid [NextStep.X, NextStep.Y].Add(Actor);

                        // Remove any "sit" statusses
                        if (Actor.UserStatusses.ContainsKey("sit"))
                        {
                            Actor.RemoveStatus("sit");
                        }

                        // Remove any "lay" statusses
                        if (Actor.UserStatusses.ContainsKey("lay"))
                        {
                            Actor.RemoveStatus("lay");
                        }

                        // Update rotation
                        if (Actor.WalkingBackwards)
                        {
                            Actor.BodyRotation = Rotation.CalculateBackwards(Actor.Position.GetVector2(), NextStep);
                        }
                        else
                        {
                            Actor.BodyRotation = Rotation.Calculate(Actor.Position.GetVector2(), NextStep);
                        }
                        Actor.HeadRotation = Actor.BodyRotation;

                        RoomTileEffect Effect = mTileEffects [NextStep.X, NextStep.Y];


                        uint WiredId = mWiredManager.GetRegisteredWalkItem(mFurniMap[NextStep.X, NextStep.Y]);
                        Item Wired   = GetItem(WiredId);
                        if (Wired != null && Wired.Definition.Behavior == ItemBehavior.WiredTrigger)
                        {
                            if (WiredTypesUtil.TriggerFromInt(Wired.Definition.BehaviorData) == WiredTriggerTypes.walks_on_furni && Actor.FurniOnId != mFurniMap[NextStep.X, NextStep.Y])
                            {
                                mWiredManager.ExecuteActions(Wired, Actor);
                            }
                        }

                        WiredId = mWiredManager.GetRegisteredWalkItem(mFurniMap[Actor.Position.X, Actor.Position.Y]);
                        Wired   = GetItem(WiredId);
                        if (Wired != null && Wired.Definition.Behavior == ItemBehavior.WiredTrigger)
                        {
                            if (WiredTypesUtil.TriggerFromInt(Wired.Definition.BehaviorData) == WiredTriggerTypes.walks_off_furni && Actor.FurniOnId != mFurniMap[NextStep.X, NextStep.Y])
                            {
                                mWiredManager.ExecuteActions(Wired, Actor);
                            }
                        }

                        Actor.FurniOnId = mFurniMap[NextStep.X, NextStep.Y];

                        // Request update for next @B cycle
                        Actor.UpdateNeeded = true;
                    }
                    else
                    {
                        // Invalid step: tell pathfinder to stop and mark current position on temporary grid
                        Vector2 target = Actor.Pathfinder.Target;

                        Actor.StopMoving();
                        if (NewUserGrid [NextStep.X, NextStep.Y] == null)
                        {
                            NewUserGrid [NextStep.X, NextStep.Y] = new List <RoomActor> ();
                        }

                        NewUserGrid [NextStep.X, NextStep.Y].Add(Actor);
                        if (ConfigManager.GetValue("pathfinder.mode").ToString().ToLower() == "simple_redirect")
                        {
                            Actor.MoveTo(new Vector2(NextStep.X - 1, NextStep.Y));                               // Redirect???
                            while (Actor.IsMoving)
                            {
                            }
                            Actor.MoveTo(target);
                        }
                    }
                }
                else
                {
                    if (NewUserGrid [Actor.Position.X, Actor.Position.Y] == null)
                    {
                        NewUserGrid [Actor.Position.X, Actor.Position.Y] = new List <RoomActor> ();
                    }

                    NewUserGrid [Actor.Position.X, Actor.Position.Y].Add(Actor);
                }

                // If the actor is leaving and has stopped walking, help them out by removing them.
                if (!Actor.IsMoving && Actor.IsLeavingRoom && Actor.Type == RoomActorType.UserCharacter)
                {
                    ActorsToRemove.Add(Actor);
                    continue;
                }

                // Update status (apply any sit/lay/effect)
                UpdateActorStatus(Actor);

                // Add this actor to the update list if this has been requested
                if (Actor.UpdateNeeded)
                {
                    ActorsToUpdate.Add(Actor);
                    Actor.UpdateNeeded = false;
                }
            }

            // Remove all actors that need to be removed
            foreach (RoomActor Actor in ActorsToRemove)
            {
                lock (mActorSyncRoot) {
                    if (ActorsToUpdate.Contains(Actor))
                    {
                        ActorsToUpdate.Remove(Actor);
                    }
                }

                switch (Actor.Type)
                {
                default:

                    RemoveActorFromRoom(Actor.Id);
                    break;

                case RoomActorType.UserCharacter:

                    HardKickUser(Actor.ReferenceId);
                    break;
                }
            }

            // Send update list (if there are any updates) to room
            if (ActorsToUpdate.Count > 0)
            {
                BroadcastMessage(RoomUserStatusListComposer.Compose(ActorsToUpdate));
            }

            // Update tick on all items --
            List <Item> ItemCopy = null;

            lock (mItemSyncRoot) {
                ItemCopy = mItems.Values.ToList();
            }

            foreach (Item Item in ItemCopy)
            {
                Item.Update(this);
            }

            // Invalidate door position
            NewUserGrid [mCachedModel.DoorPosition.X, mCachedModel.DoorPosition.Y] = null;

            // Update user grid to our new version
            lock (mActorSyncRoot) {
                mUserGrid = NewUserGrid;
            }

            if (mMusicController != null && mMusicController.IsPlaying)
            {
                mMusicController.Update(this);
            }
        }