Skip to content

Commit

Permalink
Fix max speed reduction from encumbrance sometimes not clearing properly
Browse files Browse the repository at this point in the history
* Fix incorrect max speed reduction when the player's base speed is different than the default base speed (probably only affected GMs using /speed).
* Optimize encumbrance calculation to reduce amount of inventory iterations.
  • Loading branch information
bm01 committed Nov 12, 2024
1 parent c7f075d commit 207e2dc
Show file tree
Hide file tree
Showing 40 changed files with 251 additions and 317 deletions.
4 changes: 2 additions & 2 deletions CoreServer/ConsolePacketLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public void SendGroupWindowUpdate() { }
public void SendGroupMemberUpdate(bool updateIcons, bool updateMap, GameLiving living) { }
public void SendGroupMembersUpdate(bool updateIcons, bool updateMap) { }
public void SendInventoryItemsUpdate(ICollection<DbInventoryItem> itemsToUpdate) { }
public void SendInventorySlotsUpdate(ICollection<int> slots) { }
public void SendInventorySlotsUpdate(ICollection<eInventorySlot> slots) { }
public void SendInventoryItemsUpdate(eInventoryWindowType windowType, ICollection<DbInventoryItem> itemsToUpdate) { }
public void SendInventoryItemsUpdate(IDictionary<int, DbInventoryItem> updateItems, eInventoryWindowType windowType) { }
public void SendInventoryItemsPartialUpdate(IDictionary<int, DbInventoryItem> items, eInventoryWindowType windowType) { }
Expand All @@ -123,7 +123,7 @@ public void SendUpdatePlayer() { }
public void SendUpdatePlayerSkills(bool updateInternalCache) { }
public void SendUpdateWeaponAndArmorStats() { }
public void SendCustomTextWindow(string caption, IList<string> text) { }
public void SendEncumberance() { }
public void SendEncumbrance() { }
public void SendAddFriends(string[] friendNames) { }
public void SendRemoveFriends(string[] friendNames) { }
public void SendTimerWindow(string title, int seconds) { }
Expand Down
2 changes: 1 addition & 1 deletion GameServer/ECS-Components/EffectListComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ public void SendPlayerUpdates()
playerOwner.Out.SendUpdateWeaponAndArmorStats();

if ((RequestedPlayerUpdates & EffectService.PlayerUpdate.ENCUMBERANCE) != 0)
playerOwner.Out.SendEncumberance();
playerOwner.Out.SendEncumbrance();

if ((RequestedPlayerUpdates & EffectService.PlayerUpdate.CONCENTRATION) != 0)
playerOwner.Out.SendConcentrationList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public override bool Check(DOLEvent e, object sender, EventArgs args)
bool result = true;
GamePlayer player = BehaviourUtils.GuessGamePlayerFromNotify(e, sender, args);

result = compare(player.MaxEncumberance, N, Comparator);
result = compare(player.MaxCarryingCapacity, N, Comparator);

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public override bool Check(DOLEvent e, object sender, EventArgs args)
bool result = true;
GamePlayer player = BehaviourUtils.GuessGamePlayerFromNotify(e, sender, args);

result = compare(player.Encumberance, N, Comparator);
result = compare(player.Inventory.InventoryWeight, N, Comparator);

return result;
}
Expand Down
2 changes: 1 addition & 1 deletion GameServer/commands/gmcommands/item.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public void OnCommand(GameClient client, string[] args)
}

client.Out.SendInventoryItemsUpdate(new DbInventoryItem[] { item });
client.Player.UpdateEncumberance();
client.Player.UpdateEncumbrance();
break;
}
#endregion Count
Expand Down
2 changes: 1 addition & 1 deletion GameServer/craft/Repair.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ protected static int Proceed(ECSGameTimer timer)
item.Durability -= toRecoverCond;
}

player.Out.SendInventorySlotsUpdate(new int[] { item.SlotPosition });
player.Out.SendInventorySlotsUpdate([(eInventorySlot) item.SlotPosition]);

player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Repair.Proceed.FullyRepaired1", item.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow);
if (tradePartner != null) tradePartner.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Repair.Proceed.FullyRepaired2", player.Name, item.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow);
Expand Down
4 changes: 2 additions & 2 deletions GameServer/gameobjects/GameInventoryItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ public virtual void OnStrikeTarget(GameLiving owner, GameObject target)
player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "GamePlayer.Attack.NeedRepairDire", Name), eChatType.CT_System, eChatLoc.CL_SystemWindow);

player.Out.SendUpdateWeaponAndArmorStats();
player.Out.SendInventorySlotsUpdate(new int[] { SlotPosition });
player.Out.SendInventorySlotsUpdate([(eInventorySlot) SlotPosition]);
}
}
}
Expand Down Expand Up @@ -329,7 +329,7 @@ public virtual void OnStruckByEnemy(GameLiving owner, GameLiving enemy)
player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "GamePlayer.Attack.NeedRepairDire", Name), eChatType.CT_System, eChatLoc.CL_SystemWindow);

player.Out.SendUpdateWeaponAndArmorStats();
player.Out.SendInventorySlotsUpdate(new int[] { SlotPosition });
player.Out.SendInventorySlotsUpdate([(eInventorySlot) SlotPosition]);
}
}
}
Expand Down
110 changes: 52 additions & 58 deletions GameServer/gameobjects/GamePlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5809,7 +5809,7 @@ public virtual void SwitchQuiver(eActiveQuiverSlot slot, bool forced)
Out.SendMessage(LanguageMgr.GetTranslation(Client.Account.Language, "GamePlayer.SwitchQuiver.NoMoreAmmo"), eChatType.CT_System, eChatLoc.CL_SystemWindow);
}

Out.SendInventorySlotsUpdate(new int[] { (int)updatedSlot });
Out.SendInventorySlotsUpdate([updatedSlot]);
}
else
{
Expand Down Expand Up @@ -8615,6 +8615,7 @@ public override bool AddToWorld()
}

UpdateEquipmentAppearance();
UpdateEncumbrance(true);

// display message
if (SpecPointsOk == false)
Expand Down Expand Up @@ -9694,84 +9695,77 @@ public void UpdatePlayerStatus()

#region Equipment/Encumberance

/// <summary>
/// Gets the total possible Encumberance
/// </summary>
public virtual int MaxEncumberance
public int MaxCarryingCapacity
{
get
{
double enc = (double)Strength;
RAPropertyEnhancer ab = GetAbility<AtlasOF_LifterAbility>();
if (ab != null)
enc *= 1 + ((double)ab.Amount / 100);
double result = Strength;
RAPropertyEnhancer lifter = GetAbility<AtlasOF_LifterAbility>();

if (lifter != null)
result *= 1 + lifter.Amount * 0.01;

return (int)enc;
return (int) result;
}
}

/// <summary>
/// Gets the current Encumberance
/// </summary>
public virtual int Encumberance
{
get { return Inventory.InventoryWeight; }
}
private int _previousInventoryWeight;
private int _previousMaxCarryingCapacity;

/// <summary>
/// The Encumberance state of this player
/// </summary>
protected bool m_overencumbered = true;
public bool IsEncumbered { get; private set;}
public double MaxSpeedModifierFromEncumbrance { get; private set; }

/// <summary>
/// Gets/Set the players Encumberance state
/// </summary>
public bool IsOverencumbered
public void UpdateEncumbrance(bool forced = false)
{
get { return m_overencumbered; }
set { m_overencumbered = value; }
}
int inventoryWeight = Inventory.InventoryWeight;
int maxCarryingCapacity = MaxCarryingCapacity;

/// <summary>
/// Updates the appearance of the equipment this player is using
/// </summary>
public virtual void UpdateEquipmentAppearance()
{
foreach (GamePlayer player in GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE))
if (!forced && _previousInventoryWeight == inventoryWeight && _previousMaxCarryingCapacity == maxCarryingCapacity)
return;

double maxCarryingCapacityRatio = maxCarryingCapacity * 0.35;
double newMaxSpeedModifier = 1 - inventoryWeight / maxCarryingCapacityRatio + maxCarryingCapacity / maxCarryingCapacityRatio;

if (forced || MaxSpeedModifierFromEncumbrance != newMaxSpeedModifier)
{
if (player == null) continue;
if (player != this)
player.Out.SendLivingEquipmentUpdate(this);
if (inventoryWeight > maxCarryingCapacity)
{
IsEncumbered = true;
string message;

if (MaxSpeed == 0)
message = "PropertyCalc.MaxSpeed.YouAreEncumbered";
else
message = "GamePlayer.UpdateEncumbrance.EncumberedMoveSlowly";

Out.SendMessage(LanguageMgr.GetTranslation(Client.Account.Language, message), eChatType.CT_System, eChatLoc.CL_SystemWindow);
}
else
IsEncumbered = false;

MaxSpeedModifierFromEncumbrance = newMaxSpeedModifier;
Out.SendUpdateMaxSpeed(); // Should automatically end up updating max speed using `MaxSpeedModifierFromEncumbrance` if `IsEncumbered` is set to true.
}

_previousInventoryWeight = inventoryWeight;
_previousMaxCarryingCapacity = maxCarryingCapacity;
Out.SendEncumbrance();
}

/// <summary>
/// Updates Encumberance and its effects
/// </summary>
public void UpdateEncumberance()
public void UpdateEquipmentAppearance()
{
if (Inventory.InventoryWeight > MaxEncumberance)
{
IsOverencumbered = true;
Out.SendUpdateMaxSpeed();
if (MaxSpeed == 0)
Out.SendMessage(LanguageMgr.GetTranslation(Client.Account.Language, "PropertyCalc.MaxSpeed.YouAreEncumbered"), eChatType.CT_System, eChatLoc.CL_SystemWindow);
else
Out.SendMessage(LanguageMgr.GetTranslation(Client.Account.Language, "GamePlayer.UpdateEncumberance.EncumberedMoveSlowly"), eChatType.CT_System, eChatLoc.CL_SystemWindow);
}
else if (IsOverencumbered)
foreach (GamePlayer player in GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE))
{
IsOverencumbered = false;
Out.SendUpdateMaxSpeed();
if (player != this)
player.Out.SendLivingEquipmentUpdate(this);
}
Out.SendEncumberance();
}

public override void UpdateHealthManaEndu()
{
Out.SendCharStatsUpdate();
Out.SendUpdateWeaponAndArmorStats();
UpdateEncumberance();
UpdateEncumbrance();
UpdatePlayerStatus();
base.UpdateHealthManaEndu();
}
Expand Down Expand Up @@ -10144,7 +10138,7 @@ public virtual void OnItemUnequipped(DbInventoryItem item, eInventorySlot slot)
private int OnStatsSendCompletionAfterEquipmentChange()
{
_statsSenderOnEquipmentChange = null;
return 0; // Must return 0 to stop the timer. This is just to make `OnTick` cleaner.
return 0;
}

public class StatsSenderOnEquipmentChange : ECSGameTimerWrapperBase
Expand All @@ -10168,8 +10162,8 @@ protected override int OnTick(ECSGameTimer timer)
Owner.Out.SendCharResistsUpdate();
Owner.Out.SendUpdateWeaponAndArmorStats();
Owner.Out.SendUpdateMaxSpeed();
Owner.Out.SendEncumberance();
Owner.Out.SendUpdatePlayerSkills(false);
Owner.UpdateEncumbrance();
Owner.UpdatePlayerStatus();

if (!IsAlive)
Expand Down Expand Up @@ -10335,7 +10329,7 @@ protected virtual void OnItemBonusChanged(int bonusType, int bonusAmount)
Out.SendCharResistsUpdate();
Out.SendUpdateWeaponAndArmorStats();
Out.SendUpdateMaxSpeed();
Out.SendEncumberance();
Out.SendEncumbrance();
// Out.SendUpdatePlayerSkills();
UpdatePlayerStatus();

Expand Down
39 changes: 9 additions & 30 deletions GameServer/gameutils/GameLivingInventory.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using DOL.Database;

namespace DOL.GS
{
public abstract class GameLivingInventory : IGameInventory
public abstract class GameLivingInventory : IGameInventory
{
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

Expand Down Expand Up @@ -56,6 +55,8 @@ public abstract class GameLivingInventory : IGameInventory
eInventorySlot.ArmsArmor
};

public object LockObject { get; } = new();

#region Constructor/Declaration/LoadDatabase/SaveDatabase

/// <summary>
Expand Down Expand Up @@ -747,7 +748,7 @@ public virtual bool MoveItem(eInventorySlot fromSlot, eInventorySlot toSlot, int
m_items.TryGetValue(toSlot, out toItem);

if (!CombineItems(fromItem, toItem) && !StackItems(fromSlot, toSlot, itemCount))
ExchangeItems(fromSlot, toSlot);
SwapItems(fromSlot, toSlot);

if (!m_changedSlots.Contains(fromSlot))
m_changedSlots.Add(fromSlot);
Expand Down Expand Up @@ -1152,7 +1153,7 @@ protected virtual bool StackItems(eInventorySlot fromSlot, eInventorySlot toSlot
/// <param name="fromSlot">First SlotPosition</param>
/// <param name="toSlot">Second SlotPosition</param>
/// <returns>true if items exchanged successfully</returns>
protected virtual bool ExchangeItems(eInventorySlot fromSlot, eInventorySlot toSlot)
protected virtual bool SwapItems(eInventorySlot fromSlot, eInventorySlot toSlot)
{
DbInventoryItem newFromItem;
DbInventoryItem newToItem;
Expand Down Expand Up @@ -1194,36 +1195,14 @@ protected virtual bool ExchangeItems(eInventorySlot fromSlot, eInventorySlot toS
#endregion Combine/Exchange/Stack Items

#region Encumberance
/// <summary>
/// Gets the inventory weight
/// </summary>
public virtual int InventoryWeight
{
get
{
var weight = 0;
IList<DbInventoryItem> items;

lock (LockObject)
{
items = new List<DbInventoryItem>(m_items.Values);
}

foreach (var item in items)
{
if (!EQUIP_SLOTS.Contains((eInventorySlot)item.SlotPosition))
continue;
if ((eInventorySlot) item.SlotPosition is eInventorySlot.FirstQuiver or eInventorySlot.SecondQuiver or eInventorySlot.ThirdQuiver or eInventorySlot.FourthQuiver)
continue;
weight += item.Weight;
}
public virtual int InventoryWeight => 0;

return weight/10;
}
public virtual bool UpdateInventoryWeight()
{
return false;
}

public object LockObject { get; } = new();

#endregion

#region BeginChanges/CommitChanges/UpdateSlots
Expand Down
2 changes: 1 addition & 1 deletion GameServer/gameutils/GameNpcInventoryTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ protected override bool StackItems(eInventorySlot fromSlot, eInventorySlot toSlo
/// <param name="fromSlot">First SlotPosition</param>
/// <param name="toSlot">Second SlotPosition</param>
/// <returns>false</returns>
protected override bool ExchangeItems(eInventorySlot fromSlot, eInventorySlot toSlot)
protected override bool SwapItems(eInventorySlot fromSlot, eInventorySlot toSlot)
{
return false;
}
Expand Down
Loading

0 comments on commit 207e2dc

Please sign in to comment.