public bool FitsInsideRoom(RoomItem item, int x, int y, int rotation) { foreach (AffectedTile tile in ItemUtilies.AffectedTiles(item.BaseItem.Lenght, item.BaseItem.Width, x, y, rotation).Values) { if (!this.Room.RoomGamemapManager.CoordsInsideRoom(tile.X, tile.Y)) { return(false); } } return(true); }
public void OnCycle() { this.RollerTimer++; if (this.RollerTimer >= this.Room.RollerSpeed) { this.RollerTimer = 0; List <int> rollerUsers = new List <int>(); List <uint> rollerItems = new List <uint>(); foreach (RoomItem item in this.FloorItems.Get(typeof(RoomItemRoller)).OrderBy(i => i.Z)) { this.Room.ThrowIfRoomCycleCancalled("Cycle rollers", item); //Have room cycle cancalled? ThreeDCoord way = item.TDC; if (way.x >= this.Room.RoomGamemapManager.Model.MaxX || way.y >= this.Room.RoomGamemapManager.Model.MaxY || way.x < 0 || way.y < 0) //dont roll it out of room { continue; } else { RoomTile to = this.Room.RoomGamemapManager.GetTile(way.x, way.y); if (!to.IsHole && !to.IsDoor && !to.IsInUse) { RoomTile from = this.Room.RoomGamemapManager.GetTile(item.X, item.Y); List <RoomItem> itemsFrom = from.ItemsOnTile.Values.Where(i => i.Z >= item.ActiveHeight && !rollerItems.Contains(i.ID) && this.FitsInsideRoom(i, way.x, way.y, i.Rot)).ToList(); List <RoomItem> itemsTo = to.ItemsOnTile.Values.OrderByDescending(i => i.Z).ToList(); itemsTo.RemoveAll(t => itemsFrom.Contains(t)); RoomItem higestItem = null; foreach (RoomItem item_ in itemsTo) { if (higestItem == null) { higestItem = item_; } else { if (higestItem.Z == item_.Z) { if (item_.ActiveHeight > higestItem.ActiveHeight) { higestItem = item_; } } else //not even on same height { break; } } } if (!(higestItem is RoomItemRoller)) //the top item isint roller { if (itemsTo.Any(i => i is RoomItemRoller)) { continue; } } RoomUnit user = to.CanUserMoveToTile ? this.Room.RoomGamemapManager.GetTile(item.X, item.Y).UsersOnTile.Values.FirstOrDefault(u => u.Moving == false && !rollerUsers.Contains(u.VirtualID)) : null; if (itemsFrom.Count > 0 || user != null) //we have some work to do { double baseZ = 0; if (higestItem is RoomItemRoller) { baseZ = to.GetZ(true); } else { baseZ = to.ModelZ; } foreach (RoomItem item_ in itemsFrom) { rollerItems.Add(item_.ID); foreach (AffectedTile tile in new HashSet <AffectedTile>(item_.AffectedTiles) { new AffectedTile(item_.X, item_.Y, item_.Rot) }) { this.Room.RoomGamemapManager.GetTile(tile.X, tile.Y).RemoveItemFromTile(item_); } foreach (AffectedTile tile in new HashSet <AffectedTile>(ItemUtilies.AffectedTiles(item_.GetBaseItem().Lenght, item_.GetBaseItem().Width, to.X, to.Y, item_.Rot).Values) { new AffectedTile(to.X, to.Y, item_.Rot) }) { this.Room.RoomGamemapManager.GetTile(tile.X, tile.Y).AddItemToTile(item_); } double oldZ = item_.Z; item_.SetLocation(to.X, to.Y, baseZ + item_.Z - (item.Z + item.GetBaseItem().Height)); this.Room.RoomItemManager.MoveAnimation[item.ID] = new RoomItemRollerMovement(item_.ID, item.X, item.Y, oldZ, item.ID, to.X, to.Y, item_.Z); } if (user != null) { this.Room.UserWalkOff(user); if (user.X == item.X && user.Y == item.Y) //did walkoff prevent this? { rollerUsers.Add(user.VirtualID); double newZ = to.GetZ(true); this.Room.SendToAll(new MultiRevisionServerMessage(OutgoingPacketsEnum.RollerMovement, new ValueHolder("User", new RoomUserRollerMovement(user.VirtualID, item.X, item.Y, user.Z, item.ID, to.X, to.Y, newZ)))); user.SetLocation(to.X, to.Y, newZ, false); user.UpdateUserStateTimer = 2; //update user state somehow respecting the movement packet this.Room.UserWalkOn(user); } } } } } } } if (this.FloorItems.Count > 0) { foreach (RoomItem item in this.FloorItems.Values) { this.Room.ThrowIfRoomCycleCancalled("Cycle floor items", item); //Have room cycle cancalled? item.OnCycle(); } } if (this.WallItems.Count > 0) { foreach (RoomItem item in this.WallItems.Values) { this.Room.ThrowIfRoomCycleCancalled("Cycle wall items", item); //Have room cycle cancalled? item.OnCycle(); } } //AUTO SAVE if (this.Room.LastAutoSave.Elapsed.TotalMinutes >= 5) //Every 5min :) { this.Room.LastAutoSave.Restart(); this.SaveAll(); } }
public bool MoveFloorItemOnRoom(GameClient session, RoomItem item, int x, int y, int rotation, double height = -1.0, bool sendPacket = true, params RoomItem[] ignore) { int forceRotation = session != null?session.GetHabbo().GetRoomSession().GetRoomUser().ForceRotate : -1; if (forceRotation != -1) { rotation = forceRotation; } HashSet <AffectedTile> oldTiles = new HashSet <AffectedTile>(item.AffectedTiles) { new AffectedTile(item.X, item.Y, item.Rot) }; HashSet <AffectedTile> newTiles = new HashSet <AffectedTile>(ItemUtilies.AffectedTiles(item.BaseItem.Lenght, item.BaseItem.Width, x, y, rotation).Values) { new AffectedTile(x, y, rotation) }; if (height == -1.0) { foreach (AffectedTile tile in newTiles) { if (!this.CanPlaceItemAt(item, tile.X, tile.Y)) { return(false); } RoomTile tile_ = this.Room.RoomGamemapManager.GetTile(tile.X, tile.Y); if (ignore.Length <= 0) { if (tile_.HigestRoomItem?.ID != item.ID) { height = tile_.GetZ(true); } else { height = tile_.GetZ(false); } } else { RoomItem higestItem = tile_.GetHigestItem(ignore); if (higestItem != null) { if (higestItem.ID != item.ID) { height = higestItem.ActiveHeight; } else { height = higestItem.Z; } } else { height = tile_.ModelZ; } } } } this.AddedAndMovedRoomItems.AddOrUpdate(item.ID, item, (key, oldValue) => item); this.RoomItemStateUpdated.TryRemove(item.ID, out RoomItem item_); double forceHeight = session != null?session.GetHabbo().GetRoomSession().GetRoomUser().ForceHeight : -1.0; int forceState = session != null?session.GetHabbo().GetRoomSession().GetRoomUser().ForceState : -1; if (forceState != -1) { if (item.GetBaseItem().InteractionType == "default") { int mode = forceState; if (mode > item.GetBaseItem().InteractionModeCounts - 1) { mode = 0; } item.ExtraData = mode.ToString(); } } item.Rot = rotation; if (forceHeight != -1.0) { item.SetLocation(x, y, forceHeight); } else { item.SetLocation(x, y, height); } foreach (AffectedTile tile in oldTiles) { this.Room.RoomGamemapManager.GetTile(tile.X, tile.Y).RemoveItemFromTile(item); } foreach (AffectedTile tile in newTiles) { this.Room.RoomGamemapManager.GetTile(tile.X, tile.Y).AddItemToTile(item); } if (sendPacket) { item.TryChangeUpdateState(RoomItem.UpdateStatus.MOVE); this.RequireUpdateClientSide.TryAdd(item.ID, item); } foreach (RoomUnitUser user in this.Room.RoomUserManager.GetRealUsers()) { foreach (AffectedTile tile in oldTiles.Concat(newTiles)) { if (user.X == tile.X && user.Y == tile.Y) { user.UpdateState(); break; } } } item.OnMove(session); return(true); }
public bool AddFloorItemToRoom(GameClient session, RoomItem item, int x, int y, int rotation) { int forceRotation = session != null?session.GetHabbo().GetRoomSession().GetRoomUser().ForceRotate : -1; if (forceRotation != -1) { rotation = forceRotation; } HashSet <AffectedTile> tiles = new HashSet <AffectedTile>(); tiles.UnionWith(ItemUtilies.AffectedTiles(item.BaseItem.Lenght, item.BaseItem.Width, x, y, rotation).Values); tiles.Add(new AffectedTile(x, y, rotation)); double height = 0; foreach (AffectedTile tile in tiles) { if (!this.CanPlaceItemAt(item, tile.X, tile.Y)) { return(false); } RoomTile tile_ = this.Room.RoomGamemapManager.GetTile(tile.X, tile.Y); if (tile_.GetZ(true) > height) { height = tile_.GetZ(true); } } double forceHeight = session.GetHabbo().GetRoomSession().GetRoomUser().ForceHeight; int forceState = session.GetHabbo().GetRoomSession().GetRoomUser().ForceState; if (forceState != -1) { if (item.GetBaseItem().InteractionType == "default") { int mode = forceState; if (mode > item.GetBaseItem().InteractionModeCounts - 1) { mode = 0; } item.ExtraData = mode.ToString(); } } item.Rot = rotation; if (forceHeight != -1.0) { item.SetLocation(x, y, forceHeight); } else { item.SetLocation(x, y, height); } this.AddItem(session, item, true); foreach (AffectedTile tile in tiles) { this.Room.RoomGamemapManager.GetTile(tile.X, tile.Y).AddItemToTile(item); } this.Room.SendToAll(new MultiRevisionServerMessage(OutgoingPacketsEnum.AddFloorItemToRoom, new ValueHolder("Item", item))); foreach (RoomUnitUser user in this.Room.RoomUserManager.GetRealUsers()) { foreach (AffectedTile tile in tiles) { if (user.X == tile.X && user.Y == tile.Y) { user.UpdateState(); break; } } } return(true); }
public void CalcAffectedTiles() { this.AffectedTiles.Clear(); this.AffectedTiles.UnionWith(ItemUtilies.AffectedTiles(this.BaseItem.Lenght, this.BaseItem.Width, this.X, this.Y, this.Rot).Values); }