Skip to content

Commit

Permalink
Enhancements to Housing (#3508)
Browse files Browse the repository at this point in the history
* Enhancements to Housing

* Update AdminCommands.cs

* Update Container.cs

* Add proper HAR support

/house guest list uses HAR

* Update AdminCommands.cs

* Update AdminCommands.cs

* Update HouseAccess.cs

* Update HouseAccess.cs

* house_30daylimit

* Update Player_Inventory.cs

Town Crier a deed, house gets abandoned

* Update HouseManager.cs

* Update Player_House.cs

* Update AdminCommands.cs

* Wire up House Hook limits

* Update Player_Inventory.cs

* Update AdminCommands.cs

* Add HookGroup support

* Update HookGroupType.cs

* Update PropertyInt.cs

* WriteableItems -> WritableItems

* Update Player_House.cs

* Update AdminCommands.cs

* Update Player_Tick.cs

* Update Player_House.cs

* Update Player_Tick.cs

* Update HookGroupType.cs

* dump_all

* Update AdminCommands.cs

* Update AdminCommands.cs

* Update AdminCommands.cs

* Update AdminCommands.cs

* Update AdminCommands.cs

* Update AdminCommands.cs

* Update AdminCommands.cs

* Update HouseManager.cs

* Update HouseManager.cs

* Update AdminCommands.cs

* house_15day_account

* Update appveyor.yml
  • Loading branch information
LtRipley36706 authored Apr 13, 2021
1 parent a50dbd6 commit 5a3191f
Show file tree
Hide file tree
Showing 21 changed files with 1,197 additions and 71 deletions.
13 changes: 13 additions & 0 deletions Source/ACE.Entity/Enum/HARBitfield.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;

namespace ACE.Entity.Enum
{
[Flags]
public enum HARBitfield
{
Undef = 0x0,
OpenHouse = 0x1,
AllegianceGuests = 0x2,
AllegianceStorage = 0x4
}
}
28 changes: 28 additions & 0 deletions Source/ACE.Entity/Enum/HookGroupType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using System.Linq;

namespace ACE.Entity.Enum
{
public enum HookGroupType
{
Undef = 0x0,
NoisemakingItems = 0x1,
TestItems = 0x2,
PortalItems = 0x4,
WritableItems = 0x8,
SpellCastingItems = 0x10,
SpellTeachingItems = 0x20
}

public static class HookGroupTypeExtensions
{
/// <summary>
/// Will add a space infront of capital letter words in a string
/// </summary>
/// <returns>string with spaces infront of capital letters</returns>
public static string ToSentence(this HookGroupType hookGroupType)
{
return new string(hookGroupType.ToString().ToCharArray().SelectMany((c, i) => i > 0 && char.IsUpper(c) ? new char[] { ' ', c } : new char[] { c }).ToArray());
}
}
}
3 changes: 3 additions & 0 deletions Source/ACE.Entity/Enum/Properties/PropertyInt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,9 @@ public enum PropertyInt : ushort
WieldRequirements = 158,
WieldSkillType = 159,
WieldDifficulty = 160,
[ServerOnly]
HouseMaxHooksUsable = 161,
[ServerOnly][Ephemeral]
HouseCurrentHooksUsable = 162,
AllegianceMinLevel = 163,
AllegianceMaxLevel = 164,
Expand Down Expand Up @@ -266,6 +268,7 @@ public enum PropertyInt : ushort
DeathTimestamp = 194,
PkTimestamp = 195,
VictimTimestamp = 196,
[ServerOnly]
HookGroup = 197,
AllegianceSwearTimestamp = 198,
[SendOnLogin]
Expand Down
620 changes: 618 additions & 2 deletions Source/ACE.Server/Command/Handlers/AdminCommands.cs

Large diffs are not rendered by default.

108 changes: 102 additions & 6 deletions Source/ACE.Server/Managers/HouseManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -360,11 +360,12 @@ private static void ProcessRent(PlayerHouse playerHouse)
{
playerHouse.House = house;

var isPaid = IsRentPaid(playerHouse) || playerHouse.House.HouseStatus <= HouseStatus.InActive;
var isInActiveOrDisabled = playerHouse.House.HouseStatus <= HouseStatus.InActive;
var isPaid = IsRentPaid(playerHouse);
var hasRequirements = HasRequirements(playerHouse);
//log.Info($"{playerHouse.PlayerName}.ProcessRent(): isPaid = {isPaid}");

if (isPaid && hasRequirements)
if (isInActiveOrDisabled || (isPaid && hasRequirements))
HandleRentPaid(playerHouse);
else
HandleEviction(playerHouse);
Expand Down Expand Up @@ -401,7 +402,7 @@ private static void HandleRentPaid(PlayerHouse playerHouse)

// clear out slumlord inventory
var slumlord = playerHouse.House.SlumLord;
slumlord.ClearInventory(true);
slumlord.ClearInventory();

slumlord.SaveBiotaToDatabase();

Expand Down Expand Up @@ -435,7 +436,7 @@ public static void HandleEviction(House house, uint playerGuid, bool multihouse
{
// clear out slumlord inventory
var slumlord = house.SlumLord;
slumlord.ClearInventory(true);
slumlord.ClearInventory();

var player = PlayerManager.FindByGuid(playerGuid, out bool isOnline);

Expand Down Expand Up @@ -524,7 +525,7 @@ public static void HandleEviction(House house, uint playerGuid, bool multihouse
onlinePlayer.House = null;

// send text message
onlinePlayer.Session.Network.EnqueueSend(new GameMessageSystemChat("You've been evicted from your house!", ChatMessageType.Broadcast));
onlinePlayer.Session.Network.EnqueueSend(new GameMessageSystemChat("Your house has reverted due to non-payment of the maintenance costs. All items stored in the house have been lost.", ChatMessageType.Broadcast));
onlinePlayer.RemoveDeed();

onlinePlayer.SaveBiotaToDatabase();
Expand All @@ -547,7 +548,7 @@ private static bool IsRentPaid(PlayerHouse playerHouse)
{
if (rentItem.Paid < rentItem.Num)
{
log.Debug($"[HOUSE] {playerHouse.PlayerName}.IsRentPaid() - required wcid {rentItem.WeenieID} amount {rentItem.Num:N0}, found {rentItem.Paid:N0}");
log.Debug($"[HOUSE] {playerHouse.PlayerName}.IsRentPaid() - required {rentItem.Num:N0}x {(rentItem.Num > 1 ? $"{rentItem.PluralName}" : $"{rentItem.Name}")} ({rentItem.WeenieID}), found {rentItem.Paid:N0}");
return false;
}
}
Expand Down Expand Up @@ -656,6 +657,14 @@ private static PlayerHouse FindPlayerHouse(uint playerGuid)
return RentQueue.FirstOrDefault(i => i.PlayerGuid == playerGuid);
}

/// <summary>
/// Returns all of the houses in the rent queue for a house id
/// </summary>
public static List<House> GetHouseById(uint houseId)
{
return RentQueue.Where(i => i.House.HouseId == houseId).Select(i => i.House).ToList();
}

/// <summary>
/// Returns all of the houses in the rent queue for an account
/// </summary>
Expand Down Expand Up @@ -812,5 +821,92 @@ public static void OnInitialInventoryLoadCompleted(SlumLord slumlord)
{ 0x9800, "Victory Residential Halls - Triumphal Gardens" },
{ 0x9900, "Victory Residential Halls - Wilamil Court" },
};

/// <summary>
/// Pay rent for a house
/// </summary>
private static void PayRent(PlayerHouse playerHouse)
{
// load the most up-to-date copy of the house data
GetHouse(playerHouse.House.Guid.Full, (house) =>
{
playerHouse.House = house;

var isPaid = IsRentPaid(playerHouse) || playerHouse.House.HouseStatus <= HouseStatus.InActive;

if (!isPaid)
{
var houseData = GetHouseData(playerHouse.House);

foreach (var rentItem in houseData.Rent)
{
if (rentItem.Paid < rentItem.Num)
{
var amountLeftToPay = rentItem.Num - rentItem.Paid;

while (amountLeftToPay > 0)
{
var payment = WorldObjectFactory.CreateNewWorldObject(rentItem.WeenieID);

if (payment == null)
{
log.Error($"[HOUSE] HouseManager.PayRent({house.Guid}): couldn't create payment for WCID {rentItem.WeenieID}");
return;
}

payment.SetStackSize(Math.Min(amountLeftToPay, payment.MaxStackSize ?? 1));

if (!house.SlumLord.TryAddToInventory(payment))
{
log.Error($"[HOUSE] HouseManager.PayRent({house.Guid}): couldn't place {payment.Name} (0x{payment.Guid}) in SlumLord's Inventory");
return;
}

amountLeftToPay -= (payment.StackSize ?? 1);
}
}
}

house.SlumLord.MergeAllStackables();

house.SlumLord.SaveBiotaToDatabase();

var onlinePlayer = PlayerManager.GetOnlinePlayer(playerHouse.PlayerGuid);
if (onlinePlayer != null)
{
var actionChain = new ActionChain();
actionChain.AddDelaySeconds(3.0f); // wait for slumlord inventory biotas above to save
actionChain.AddAction(onlinePlayer, onlinePlayer.HandleActionQueryHouse);
actionChain.EnqueueChain();
}
}
});
}

/// <summary>
/// Pay rent for a house
/// </summary>
public static bool PayRent(House house)
{
var foundHouse = RentQueue.FirstOrDefault(h => h.PlayerGuid == (house.HouseOwner ?? 0));

if (foundHouse == null)
return false;

PayRent(foundHouse);

return true;
}

/// <summary>
/// Pay rent for all owned housing
/// </summary>
public static void PayAllRent()
{
foreach (var house in RentQueue)
{
PayRent(house);
}
}
}
}
4 changes: 4 additions & 0 deletions Source/ACE.Server/Managers/PropertyManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,10 @@ public static void LoadDefaultProperties()
("fellow_kt_landblock", new Property<bool>(false, "if TRUE, fellowship kill tasks will share with landblock range (192 distance radius, or entire dungeon)")),
("fellow_quest_bonus", new Property<bool>(false, "if TRUE, applies EvenShare formula to fellowship quest reward XP (300% max bonus, defaults to false in retail)")),
("gateway_ties_summonable", new Property<bool>(true, "if disabled, players cannot summon ties from gateways. defaults to enabled, as in retail")),
("house_15day_account", new Property<bool>(true, "if disabled, houses can be purchased with accounts created less than 15 days old")),
("house_30day_cooldown", new Property<bool>(true, "if disabled, houses can be purchased without waiting 30 days between each purchase")),
("house_hook_limit", new Property<bool>(true, "if disabled, house hook limits are ignored")),
("house_hookgroup_limit", new Property<bool>(true, "if disabled, house hook group limits are ignored")),
("house_per_char", new Property<bool>(false, "if TRUE, allows 1 house per char instead of 1 house per account")),
("house_purchase_requirements", new Property<bool>(true, "if disabled, requirements to purchase/rent house are not checked")),
("house_rent_enabled", new Property<bool>(true, "If FALSE then rent is not required")),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using ACE.Server.Network.Structure;
using ACE.Server.WorldObjects;

namespace ACE.Server.Network.GameEvent.Events
{
Expand All @@ -8,12 +9,12 @@ namespace ACE.Server.Network.GameEvent.Events
/// </summary>
public class GameEventUpdateHAR : GameEventMessage
{
public GameEventUpdateHAR(Session session)
public GameEventUpdateHAR(Session session, House house)
: base(GameEventType.UpdateHAR, GameMessageGroup.UIQueue, session)
{
//Console.WriteLine("Sending 0x257 - Update House Access Records (HAR)");

var har = new HouseAccess();
var har = new HouseAccess(house);

Writer.Write(har);
}
Expand Down
10 changes: 10 additions & 0 deletions Source/ACE.Server/Network/Structure/GuestInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ public class GuestInfo
{
public bool ItemStoragePermission; // False = access to house, True = access to house+storage
public string GuestName; // Name of the guest

public GuestInfo()
{
}

public GuestInfo(bool itemStoragePermission, string name)
{
ItemStoragePermission = itemStoragePermission;
GuestName = name;
}
}

public static class GuestInfoExtensions
Expand Down
Loading

0 comments on commit 5a3191f

Please sign in to comment.