Skip to content

Commit

Permalink
Merge pull request #304 from Lacyway/item-events-healing
Browse files Browse the repository at this point in the history
Item events healing
  • Loading branch information
seionmoya authored Jan 9, 2025
2 parents d0f1347 + 47e4687 commit b5bff21
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 31 deletions.
38 changes: 31 additions & 7 deletions Fuyu.Backend.BSG/ItemTemplates/MedsItemProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,55 @@ namespace Fuyu.Backend.BSG.ItemTemplates;
public class MedsItemProperties : ItemProperties
{
[DataMember(Name = "medUseTime")]
public float UseTime;
public float UseTime { get; set; }

[DataMember(Name = "bodyPartTimeMults")]
public KeyValuePair<EBodyPart, float>[] BodyPartTimeMults;
public KeyValuePair<EBodyPart, float>[] BodyPartTimeMults { get; set; }

[DataMember(Name = "effects_health")]
public Union<Dictionary<string, HealthEffect>, object[]> HealthEffects;
public Union<Dictionary<string, HealthEffect>, object[]> HealthEffects { get; set; }

[DataMember(Name = "effects_damage")]
public Union<Dictionary<string, DamageEffect>, object[]> DamageEffects;
public Union<Dictionary<string, DamageEffect>, object[]> DamageEffects { get; set; }

[DataMember(Name = "StimulatorBuffs")]
public string StimulatorBuffs;
public string StimulatorBuffs { get; set; }

[DataMember(Name = "MaxHpResource")]
public int MaxHpResource;
public int MaxHpResource { get; set; }

[DataMember(Name = "hpResourceRate")]
public float HpResourceRate;
public float HpResourceRate { get; set; }
}

[DataContract]
public class HealthEffect
{
[DataMember(Name = "delay")]
public float Delay { get; set; }

[DataMember(Name = "duration")]
public float Duration { get; set; }
}

[DataContract]
public class DamageEffect
{
[DataMember(Name = "delay")]
public float Delay { get; set; }

[DataMember(Name = "duration")]
public float Duration { get; set; }

[DataMember(Name = "fadeOut")]
public float FadeOut { get; set; }

[DataMember(Name = "cost")]
public int Cost { get; set; }

[DataMember(Name = "healthPenaltyMin")]
public int HealthPenaltyMin { get; set; }

[DataMember(Name = "healthPenaltyMax")]
public int HealthPenaltyMax { get; set; }
}
13 changes: 0 additions & 13 deletions Fuyu.Backend.BSG/Models/Common/CurrentMaximum.cs

This file was deleted.

21 changes: 21 additions & 0 deletions Fuyu.Backend.BSG/Models/ItemEvents/HealItemEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Runtime.Serialization;
using Fuyu.Backend.BSG.ItemTemplates;
using Fuyu.Common.Hashing;

namespace Fuyu.Backend.BSG.Models.ItemEvents;

[DataContract]
public class HealItemEvent : BaseItemEvent
{
[DataMember(Name = "item")]
public MongoId Item { get; set; }

[DataMember(Name = "part")]
public EBodyPart BodyPart { get; set; }

[DataMember(Name = "count")]
public int Count { get; set; }

[DataMember(Name = "time")]
public int Time { get; set; }
}
7 changes: 5 additions & 2 deletions Fuyu.Backend.BSG/Models/Profiles/Health/BodyPart.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
using Fuyu.Backend.BSG.Models.Common;

namespace Fuyu.Backend.BSG.Models.Profiles.Health;

[DataContract]
public class BodyPart
{
[DataMember]
public CurrentMaximum<float> Health { get; set; }
public ClampedHealthStat<float> Health { get; set; }

[DataMember(EmitDefaultValue = false)]
public Dictionary<string, BodyPartEffect> Effects { get; set; }
}
10 changes: 10 additions & 0 deletions Fuyu.Backend.BSG/Models/Profiles/Health/BodyPartEffect.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Runtime.Serialization;

namespace Fuyu.Backend.BSG.Models.Profiles.Health;

[DataContract]
public class BodyPartEffect
{
[DataMember]
public float Time { get; set; } = -1f;
}
18 changes: 18 additions & 0 deletions Fuyu.Backend.BSG/Models/Profiles/Health/BodyPartsInfo.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace Fuyu.Backend.BSG.Models.Profiles.Health;
Expand Down Expand Up @@ -25,4 +27,20 @@ public class BodyPartInfo

[DataMember]
public BodyPart RightLeg { get; set; }

// TODO: Refactor class to support IEnumerator?
[IgnoreDataMember]
public IEnumerable<BodyPart> AllBodyParts
{
get
{
yield return Head;
yield return Chest;
yield return Stomach;
yield return LeftArm;
yield return RightArm;
yield return LeftLeg;
yield return RightLeg;
}
}
}
39 changes: 39 additions & 0 deletions Fuyu.Backend.BSG/Models/Profiles/Health/ClampedHealthStat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Numerics;
using System.Runtime.Serialization;

namespace Fuyu.Backend.BSG.Models.Profiles.Health;

/// <summary>
/// Class used to automatically clamp <see cref="Minimum"/> and <see cref="Maximum"/> values
/// </summary>
/// <typeparam name="T"></typeparam>
[DataContract]
public class ClampedHealthStat<T> where T : INumber<T>
{
[DataMember]
public T Current
{
get
{
return _current;
}
set
{
_current = T.Clamp(value, Minimum, Maximum);
}
}

private T _current;

[DataMember]
public T Minimum { get; set; }

[DataMember]
public T Maximum { get; set; }

[DataMember]
public T OverDamageReceivedMultiplier { get; set; }

[DataMember]
public T EnvironmentDamageMultiplier { get; set; }
}
41 changes: 37 additions & 4 deletions Fuyu.Backend.BSG/Models/Profiles/HealthInfo.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Linq;
using System.Runtime.Serialization;
using Fuyu.Backend.BSG.Models.Common;
using Fuyu.Backend.BSG.ItemTemplates;
using Fuyu.Backend.BSG.Models.Profiles.Health;

namespace Fuyu.Backend.BSG.Models.Profiles;
Expand All @@ -8,20 +10,51 @@ namespace Fuyu.Backend.BSG.Models.Profiles;
public class HealthInfo
{
[DataMember]
public CurrentMaximum<float> Hydration { get; set; }
public ClampedHealthStat<float> Hydration { get; set; }

[DataMember]
public CurrentMaximum<float> Energy { get; set; }
public ClampedHealthStat<float> Energy { get; set; }

[DataMember]
public CurrentMaximum<float> Temperature { get; set; }
public ClampedHealthStat<float> Temperature { get; set; }

[DataMember]
public ClampedHealthStat<float> Poison { get; set; }

[DataMember]
public BodyPartInfo BodyParts { get; set; }

[DataMember]
public int? UpdateTime { get; set; }

public BodyPart GetBodyPart(EBodyPart bodyPart)
{
return bodyPart switch
{
EBodyPart.Head => BodyParts.Head,
EBodyPart.Chest => BodyParts.Chest,
EBodyPart.Stomach => BodyParts.Stomach,
EBodyPart.LeftArm => BodyParts.LeftArm,
EBodyPart.RightArm => BodyParts.RightArm,
EBodyPart.LeftLeg => BodyParts.LeftLeg,
EBodyPart.RightLeg => BodyParts.RightLeg,
EBodyPart.Common => throw new NotImplementedException("Only used in client"),
_ => null,
};
}

/// <summary>
/// Returns whether any <see cref="BodyPart"/> contain a <see cref="BodyPartEffect"/>
/// </summary>
[IgnoreDataMember]
public bool HasEffects
{
get
{
return BodyParts.AllBodyParts.Any(x => x.Effects.Count > 0);
}
}

// SKIPPED: Immortal
// Reason: only used on BSG's internal server
}
10 changes: 5 additions & 5 deletions Fuyu.Backend.BSG/Models/Profiles/InventoryInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public ItemInstance GetStock(ItemInstance root)
return null;
}

var weaponItemProperties = rootItemTemplate.Props.ToObject<WeaponItemProperties>();
var weaponItemProperties = _itemFactoryService.GetItemProperties<WeaponItemProperties>(root.TemplateId);
var subItems = _itemService.GetItemAndChildren(Items, root).Skip(1);

return subItems.FirstOrDefault(i => i.SlotId == weaponItemProperties.FoldedSlot);
Expand All @@ -112,7 +112,7 @@ public ItemInstance GetStock(ItemInstance root)
public Vector2 GetItemSize(ItemInstance root)
{
var rootTemplate = _itemFactoryService.ItemTemplates[root.TemplateId];
var rootProperties = rootTemplate.Props.ToObject<ItemProperties>();
var rootProperties = _itemFactoryService.GetItemProperties<ItemProperties>(root.TemplateId);
var width = rootProperties.Width;
var height = rootProperties.Height;

Expand All @@ -129,7 +129,7 @@ public Vector2 GetItemSize(ItemInstance root)
foreach (var child in children)
{
var itemTemplate = _itemFactoryService.ItemTemplates[child.TemplateId];
var itemProperties = itemTemplate.Props.ToObject<ItemProperties>();
var itemProperties = _itemFactoryService.GetItemProperties<ItemProperties>(root.TemplateId);
if (itemProperties.ExtraSizeForceAdd)
{
forcedUp += itemProperties.ExtraSizeUp;
Expand Down Expand Up @@ -180,7 +180,7 @@ public LocationInGrid GetNextFreeSlot(int width, int height, out string gridName
}

var stashItemTemplate = _itemFactoryService.ItemTemplates[stashItem.TemplateId];
var stashItemProps = stashItemTemplate.Props.ToObject<CompoundItemItemProperties>();
var stashItemProps = _itemFactoryService.GetItemProperties<CompoundItemItemProperties>(stashItem.TemplateId);

foreach (var grid in stashItemProps.Grids)
{
Expand All @@ -198,7 +198,7 @@ public LocationInGrid GetNextFreeSlot(int width, int height, out string gridName
}

var itemTemplate = _itemFactoryService.ItemTemplates[itemInThisGrid.TemplateId];
var itemProps = itemTemplate.Props.ToObject<ItemProperties>();
var itemProps = _itemFactoryService.GetItemProperties<ItemProperties>(itemInThisGrid.TemplateId);
var itemLocation = itemInThisGrid.Location.Value1;
var itemSize = GetItemSize(itemInThisGrid);
var itemWidth = itemSize.X;
Expand Down
11 changes: 11 additions & 0 deletions Fuyu.Backend.BSG/Services/ItemFactoryService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ public void Load()
ItemTemplates = Json.Parse<ResponseBody<Dictionary<MongoId, ItemTemplate>>>(itemsText).data;
}

/// <summary>
/// Gets an <see cref="ItemProperties"/> from a <see cref="MongoId"/> TemplateId
/// </summary>
/// <typeparam name="T">The <see cref="ItemProperties"/> class to return</typeparam>
/// <param name="templateId">The <see cref="MongoId"/> TemplateId to get the <see cref="ItemProperties"/> from</param>
/// <returns>The <see cref="ItemProperties"/> class defined</returns>
public T GetItemProperties<T>(MongoId templateId) where T : ItemProperties
{
return ItemTemplates[templateId].Props.ToObject<T>();
}

public ItemInstance CreateItem(MongoId tpl, MongoId? id = null)
{
var template = ItemTemplates[tpl];
Expand Down
68 changes: 68 additions & 0 deletions Fuyu.Backend.EFT/Controllers/ItemEvents/HealItemEventController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using System.Threading.Tasks;
using Fuyu.Backend.BSG.ItemTemplates;
using Fuyu.Backend.BSG.Models.ItemEvents;
using Fuyu.Backend.BSG.Models.Items;
using Fuyu.Backend.BSG.Networking;
using Fuyu.Backend.BSG.Services;
using Fuyu.Common.IO;

namespace Fuyu.Backend.EFT.Controllers.ItemEvents;

public class HealItemEventController : AbstractItemEventController<HealItemEvent>
{
private readonly EftOrm _eftOrm;
private readonly ItemFactoryService _itemFactoryService;

public HealItemEventController() : base("Heal")
{
_eftOrm = EftOrm.Instance;
_itemFactoryService = ItemFactoryService.Instance;
}

public override Task RunAsync(ItemEventContext context, HealItemEvent request)
{
var profile = _eftOrm.GetActiveProfile(context.SessionId);
var item = profile.Pmc.Inventory.FindItem(request.Item);

if (item == null)
{
Terminal.WriteLine($"Failed to find item {request.Item}");
return Task.CompletedTask;
}

var medKit = item.GetOrCreateUpdatable<ItemMedKitComponent>();

var bodyPart = profile.Pmc.Health.GetBodyPart(request.BodyPart);
float toHeal = request.Count;

if (profile.Pmc.Health.HasEffects)
{
var itemProperties = _itemFactoryService.GetItemProperties<MedsItemProperties>(item.TemplateId);

if (itemProperties.DamageEffects.IsValue1)
{
foreach (var (effectName, effect) in itemProperties.DamageEffects.Value1)
{
if (bodyPart.Effects.ContainsKey(effectName))
{
toHeal -= effect.Cost;
bodyPart.Effects.Remove(effectName);
}
}
}
}

bodyPart.Health.Current += toHeal;
medKit.HpResource -= request.Count;

if (medKit.HpResource <= 0)
{
profile.Pmc.Inventory.RemoveItem(item);
}

// TODO:
// Check BackendConfig for 'HealExperience' and add to PMC profile

return Task.CompletedTask;
}
}

0 comments on commit b5bff21

Please sign in to comment.