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); }
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); }
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; } } } }
public static ServerMessage Compose(Item Item, RoomInstance Instance) { // com.sulake.habbo.communication.messages.incoming.userdefinedroomevents.WiredFurniActionEvent; ServerMessage Message = new ServerMessage(OpcodesOut.WIRED_FURNI_ACTION); Message.AppendInt32(0); Message.AppendInt32(5); // Furni limit if (Item.WiredData.Data1.Contains("|")) { String[] Selected = Item.WiredData.Data1.Split('|'); Message.AppendInt32(Selected.Length - 1); // Selected Furni Count foreach (String selected in Selected) { if (selected == "") { continue; } int result; Int32.TryParse(selected, out result); Message.AppendInt32(result); } } else { Message.AppendUInt32(0); } Message.AppendUInt32(Item.Definition.SpriteId); Message.AppendUInt32(Item.Id); Message.AppendStringWithBreak(Item.WiredData.Data1); WiredEffectTypes Type = WiredTypesUtil.EffectFromInt(Item.Definition.BehaviorData); if (WiredEffectTypes.match_to_sshot == Type || WiredEffectTypes.move_rotate == Type) { Message.AppendUInt32(3); // Data Count } Message.AppendInt32(Item.WiredData.Data2); Message.AppendInt32(Item.WiredData.Data3); if (WiredEffectTypes.match_to_sshot == Type || WiredEffectTypes.move_rotate == Type) { Message.AppendInt32(Item.WiredData.Data4); Message.AppendUInt32(0); } Message.AppendInt32(Item.Definition.BehaviorData); Message.AppendInt32(Item.WiredData.Time); // TIME List <Item> Items = Instance.WiredManager.ActionRequiresActor(Item.Definition.BehaviorData, Item.RoomPosition.GetVector2()); Message.AppendInt32(Items.Count); foreach (Item Blocked in Items) { Message.AppendUInt32(Blocked.Definition.SpriteId); } return(Message); }
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); } }