using System; using System.Collections.Generic; using ACE.Database; using ACE.Entity; using ACE.Entity.Enum; using ACE.Entity.Enum.Properties; using ACE.Entity.Models; using ACE.Server.Entity; using ACE.Server.Managers; using ACE.Server.Network.GameEvent.Events; using ACE.Server.Network.GameMessages.Messages; using ACE.Server.Network.Structure; namespace ACE.Server.WorldObjects { public class SlumLord : Container { /// /// The house this slumlord is linked to /// public House House { get => ParentLink as House; } /// /// A new biota be created taking all of its values from weenie. /// public SlumLord(Weenie weenie, ObjectGuid guid) : base(weenie, guid) { SetEphemeralValues(); } /// /// Restore a WorldObject from the database. /// public SlumLord(Biota biota) : base(biota) { SetEphemeralValues(); } private void SetEphemeralValues() { ItemCapacity = 120; } public bool HouseRequiresMonarch { get => GetProperty(PropertyBool.HouseRequiresMonarch) ?? false; set { if (!value) RemoveProperty(PropertyBool.HouseRequiresMonarch); else SetProperty(PropertyBool.HouseRequiresMonarch, value); } } public int? AllegianceMinLevel { get => GetProperty(PropertyInt.AllegianceMinLevel); set { if (!value.HasValue) RemoveProperty(PropertyInt.AllegianceMinLevel); else SetProperty(PropertyInt.AllegianceMinLevel, value.Value); } } public override void ActOnUse(WorldObject worldObject) { //Console.WriteLine($"SlumLord.ActOnUse({worldObject.Name})"); var player = worldObject as Player; if (player == null) return; // sent house profile var houseProfile = GetHouseProfile(); player.Session.Network.EnqueueSend(new GameEventHouseProfile(player.Session, Guid, houseProfile)); } public HouseProfile GetHouseProfile() { var houseProfile = new HouseProfile(); houseProfile.DwellingID = HouseId.Value; if (House != null) { houseProfile.Type = House.HouseType; if (House.HouseStatus == HouseStatus.Disabled) houseProfile.Bitmask &= ~HouseBitfield.Active; if (House.HouseStatus == HouseStatus.InActive) houseProfile.MaintenanceFree = true; } if (HouseRequiresMonarch) houseProfile.Bitmask |= HouseBitfield.RequiresMonarch; if (MinLevel != null) houseProfile.MinLevel = MinLevel.Value; if (AllegianceMinLevel != null) houseProfile.MinAllegRank = AllegianceMinLevel.Value; if (HouseOwner != null) { var ownerId = HouseOwner.Value; var owner = PlayerManager.FindByGuid(ownerId); houseProfile.OwnerID = new ObjectGuid(ownerId); houseProfile.OwnerName = owner?.Name; } houseProfile.SetBuyItems(GetBuyItems()); houseProfile.SetRentItems(GetRentItems()); houseProfile.SetPaidItems(this); return houseProfile; } /// /// Returns the list of items required to purchase this dwelling /// public List GetBuyItems() { var buyList = GetCreateListForSlumLord(DestinationType.HouseBuy); buyList.ForEach(item => item.Destroy(false)); return buyList; } /// /// Returns the list of items required to rent this dwelling /// public List GetRentItems() { var rentList = GetCreateListForSlumLord(DestinationType.HouseRent); rentList.ForEach(item => item.Destroy(false)); return rentList; } /// /// Returns TRUE if rent is already paid for current maintenance period /// public bool IsRentPaid() { if (House != null && House.HouseStatus == HouseStatus.InActive) return true; var houseProfile = GetHouseProfile(); foreach (var rentItem in houseProfile.Rent) { if (rentItem.Paid < rentItem.Num) return false; } return true; } /// /// Returns TRUE if this player has the minimum requirements to purchase / rent this house /// public bool HasRequirements(Player player) { if (!PropertyManager.GetBool("house_purchase_requirements").Item) return true; if (AllegianceMinLevel == null) return true; var allegianceMinLevel = PropertyManager.GetLong("mansion_min_rank", -1).Item; if (allegianceMinLevel == -1) allegianceMinLevel = AllegianceMinLevel.Value; if (allegianceMinLevel > 0 && (player.Allegiance == null || player.AllegianceNode.Rank < allegianceMinLevel)) { Console.WriteLine($"{Name}.HasRequirements({player.Name}) - allegiance rank {player.AllegianceNode?.Rank ?? 0} < {allegianceMinLevel}"); return false; } return true; } public int GetAllegianceMinLevel() { if (AllegianceMinLevel == null) return 0; var allegianceMinLevel = PropertyManager.GetLong("mansion_min_rank", -1).Item; if (allegianceMinLevel == -1) allegianceMinLevel = AllegianceMinLevel.Value; return (int)allegianceMinLevel; } protected override void OnInitialInventoryLoadCompleted() { HouseManager.OnInitialInventoryLoadCompleted(this); } public void On() { var on = new Motion(MotionStance.Invalid, MotionCommand.On); SetAndBroadcastMotion(on); } public void Off() { var off = new Motion(MotionStance.Invalid, MotionCommand.Off); if (CurrentLandblock != null) SetAndBroadcastMotion(off); } private void SetAndBroadcastMotion(Motion motion) { CurrentMotionState = motion; EnqueueBroadcastMotion(motion); } public void SetAndBroadcastName(string houseOwnerName = null) { if (string.IsNullOrWhiteSpace(houseOwnerName)) { var weenie = DatabaseManager.World.GetCachedWeenie(WeenieClassId); if (weenie != null) Name = weenie.GetProperty(PropertyString.Name); else Name = House.HouseType.ToString(); } else Name = $"{houseOwnerName}'s {Name}"; if (CurrentLandblock != null) EnqueueBroadcast(new GameMessagePublicUpdatePropertyString(this, PropertyString.Name, Name)); } /// /// This event is raised when HouseManager removes item for rent /// protected override void OnRemoveItem(WorldObject removedItem) { //Console.WriteLine("Slumlord.OnRemoveItem()"); // Here we explicitly remove the payment from the database to avoid storing unneeded objects and free guid. if (!removedItem.IsDestroyed) removedItem.Destroy(); } } }