Since there is an OnStructureUpgrade method, when we try to repair a structure, we can get different errors: RecentlyDamagedError, NotDamagedError, OnRepairFailedResources
However, this method does not take this into account, and each error received for a structure triggers a method to update the UI, resulting in false updates, although this makes no sense, since we still get an error in the Toast, rather than in the statuses above HP/Food/Water
This is my solution, but it can be implemented differently (cleaner, better):
private bool IsFailedRepair(BuildingBlock entity, BasePlayer basePlayer)
{
if (entity.SecondsSinceAttacked <= entity.GetDamageRepairCooldown()) return true; // RecentlyDamagedError
float missingHealth = entity.MaxHealth() - entity.Health();
float healthMissingFraction = missingHealth / entity.MaxHealth();
if (missingHealth <= 0f || healthMissingFraction <= 0f) return true; // NotDamagedError
List<ItemAmount> repairCost = entity.RepairCost(healthMissingFraction);
if (repairCost == null || repairCost.Count == 0) return false;
float resourceRatio = repairCost.Min(x =>
Mathf.Clamp01((float)basePlayer.inventory.GetAmount(x.itemid) / x.amount)
);
if (float.IsNaN(resourceRatio))
resourceRatio = 0f;
float repairAmount = Mathf.Min(resourceRatio, 50f / missingHealth);
if (repairAmount <= 0f) return true; // OnRepairFailedResources
return false;
}
private void OnStructureRepair(BuildingBlock entity, BasePlayer basePlayer)
{
NextTick(() =>
{
if (IsFailedRepair(entity, basePlayer)) return;
if (entity != null && basePlayer != null)
{
Behaviours.GetValueOrDefault(basePlayer.UserIDString)?.itemStatuses.Inc($"removed {entity.grade}");
}
});
}