Skip to content

Commit

Permalink
WIP Quest Progression Sharing
Browse files Browse the repository at this point in the history
- Now shares looted QuestItems
  • Loading branch information
Lacyway committed Jun 14, 2024
1 parent ef8b979 commit f48d9d0
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 15 deletions.
1 change: 1 addition & 0 deletions Fika.Core/Coop/BotClasses/CoopBotInventoryController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using Comfort.Common;
using EFT;
using EFT.InventoryLogic;
using Fika.Core.Coop.Players;
using Fika.Core.Networking;
using JetBrains.Annotations;
Expand Down
16 changes: 15 additions & 1 deletion Fika.Core/Coop/ClientClasses/CoopClientInventoryController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Fika.Core.Coop.Matchmaker;
using Fika.Core.Coop.Players;
using Fika.Core.Networking;
using Fika.Core.Networking.Packets;
using JetBrains.Annotations;
using System.IO;
using UnityEngine;
Expand All @@ -15,6 +16,7 @@ namespace Fika.Core.Coop.ClientClasses
public sealed class CoopClientInventoryController(Player player, Profile profile, bool examined) : Player.PlayerOwnerInventoryController(player, profile, examined)
{
public override bool HasDiscardLimits => false;


ManualLogSource BepInLogger { get; set; } = BepInEx.Logging.Logger.CreateLogSource(nameof(CoopClientInventoryController));

Expand All @@ -39,8 +41,20 @@ public override void Execute(GClass2854 operation, [CanBeNull] Callback callback
// Do not replicate picking up quest items, throws an error on the other clients
if (operation is GClass2856 pickupOperation)
{
if (pickupOperation.Item.Template.QuestItem)
Item lootedItem = pickupOperation.Item;
if (lootedItem.Template.QuestItem)
{
if (CoopPlayer.GClass3227_0 is CoopSharedQuestController sharedQuestController)
{
if (!sharedQuestController.CheckForTemplateId(lootedItem.TemplateId))
{
sharedQuestController.AddLootedTemplateId(lootedItem.TemplateId);

// We use templateId because each client gets a unique itemId
QuestItemPacket packet = new(CoopPlayer.Profile.Info.MainProfileNickname, lootedItem.TemplateId);
CoopPlayer.PacketSender.SendQuestItemPacket(ref packet);
}
}
base.Execute(operation, callback);
return;
}
Expand Down
51 changes: 46 additions & 5 deletions Fika.Core/Coop/ClientClasses/CoopSharedQuestController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using EFT;
using EFT.InventoryLogic;
using EFT.Quests;
using Fika.Core.Coop.Players;
using Fika.Core.Networking.Packets;
Expand All @@ -12,6 +13,7 @@ public sealed class CoopSharedQuestController(Profile profile, InventoryControll
private readonly CoopPlayer player = player;
private readonly List<string> lastFromNetwork = [];
private readonly List<string> acceptedTypes = ["Kill", "Hit", "InZone", "Location"];
private readonly HashSet<string> lootedTemplateIds = [];

public override void OnConditionValueChanged(IConditionCounter conditional, EQuestStatus status, Condition condition, bool notify = true)
{
Expand All @@ -21,7 +23,7 @@ public override void OnConditionValueChanged(IConditionCounter conditional, EQue
lastFromNetwork.Remove(condition.id);
return;
}
SendQuestPacket(conditional, condition.id);
SendQuestPacket(conditional, condition);
}

public void AddNetworkId(string id)
Expand All @@ -32,14 +34,30 @@ public void AddNetworkId(string id)
}
}

private void SendQuestPacket(IConditionCounter conditional, string conditionId)
public void AddLootedTemplateId(string templateId)
{
if (!lootedTemplateIds.Contains(templateId))
{
lootedTemplateIds.Add(templateId);
}
}

public bool CheckForTemplateId(string templateId)
{
return lootedTemplateIds.Contains(templateId);
}

private void SendQuestPacket(IConditionCounter conditional, Condition condition)
{
if (conditional is GClass1258 quest)
{
GClass3242 counter = quest.ConditionCountersManager.GetCounter(conditionId);
GClass3242 counter = quest.ConditionCountersManager.GetCounter(condition.id);
if (counter != null)
{
QuestConditionPacket packet = new(player.Profile.Info.MainProfileNickname, counter.Id, counter.SourceId);
#if DEBUG
FikaPlugin.Instance.FikaLogger.LogInfo("SendQuestPacket: Sending quest progress");
#endif
player.PacketSender.SendQuestPacket(ref packet);
}
}
Expand All @@ -55,10 +73,10 @@ internal void ReceiveQuestPacket(ref QuestConditionPacket packet)
GClass3242 counter = quest.ConditionCountersManager.GetCounter(packet.Id);
if (counter != null)
{
if (!acceptedTypes.Contains(counter.Type))
/*if (!acceptedTypes.Contains(counter.Type))
{
return;
}
}*/

counter.Value++;
NotificationManagerClass.DisplayMessageNotification($"Received shared quest progression from {packet.Nickname}",
Expand All @@ -67,5 +85,28 @@ internal void ReceiveQuestPacket(ref QuestConditionPacket packet)
}
}
}

internal void ReceiveQuestItemPacket(ref QuestItemPacket packet)
{
if (!string.IsNullOrEmpty(packet.ItemId))
{
Item item = player.FindItem(packet.ItemId, true);
if (item != null)
{
InventoryControllerClass playerInventory = player.GClass2777_0;
GStruct414<GInterface339> pickupResult = InteractionsHandlerClass.QuickFindAppropriatePlace(item, playerInventory,
playerInventory.Inventory.Equipment.ToEnumerable(),
InteractionsHandlerClass.EMoveItemOrder.PickUp, true);

if (pickupResult.Succeeded && playerInventory.CanExecute(pickupResult.Value))
{
AddLootedTemplateId(item.TemplateId);
playerInventory.RunNetworkTransaction(pickupResult.Value);
NotificationManagerClass.DisplayMessageNotification($"{packet.Nickname} picked up {item.Name.Localized()}",
iconType: EFT.Communications.ENotificationIconType.Quest);
}
}
}
}
}
}
5 changes: 5 additions & 0 deletions Fika.Core/Coop/PacketHandlers/BotPacketSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ public void SendQuestPacket(ref QuestConditionPacket packet)

}

public void SendQuestItemPacket(ref QuestItemPacket packet)
{

}

protected void FixedUpdate()
{
if (!Enabled)
Expand Down
6 changes: 6 additions & 0 deletions Fika.Core/Coop/PacketHandlers/ClientPacketSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ public void SendQuestPacket(ref QuestConditionPacket packet)
Client.SendData(Writer, ref packet, DeliveryMethod.ReliableUnordered);
}

public void SendQuestItemPacket(ref QuestItemPacket packet)
{
Writer.Reset();
Client.SendData(Writer, ref packet, DeliveryMethod.ReliableUnordered);
}

protected void FixedUpdate()
{
if (player == null || Writer == null)
Expand Down
1 change: 1 addition & 0 deletions Fika.Core/Coop/PacketHandlers/IPacketSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public interface IPacketSender

public void Init();
public void SendQuestPacket(ref QuestConditionPacket packet);
public void SendQuestItemPacket(ref QuestItemPacket packet);
public void DestroyThis();
}
}
5 changes: 5 additions & 0 deletions Fika.Core/Coop/PacketHandlers/ObservedPacketSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ public void SendQuestPacket(ref QuestConditionPacket packet)

}

public void SendQuestItemPacket(ref QuestItemPacket packet)
{

}

protected void Update()
{
if (player == null || Writer == null)
Expand Down
6 changes: 6 additions & 0 deletions Fika.Core/Coop/PacketHandlers/ServerPacketSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ public void SendQuestPacket(ref QuestConditionPacket packet)
Server.SendDataToAll(Writer, ref packet, DeliveryMethod.ReliableUnordered);
}

public void SendQuestItemPacket(ref QuestItemPacket packet)
{
Writer.Reset();
Server.SendDataToAll(Writer, ref packet, DeliveryMethod.ReliableUnordered);
}

protected void FixedUpdate()
{
if (player == null || Writer == null || Server == null)
Expand Down
21 changes: 19 additions & 2 deletions Fika.Core/Coop/Players/CoopPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class CoopPlayer : LocalPlayer
public Transform RaycastCameraTransform;
public int NetId;
public bool IsObservedAI = false;
public Dictionary<uint, Callback<EOperationStatus>> OperationCallbacks = [];
public Dictionary<uint, Callback<EOperationStatus>> OperationCallbacks = [];
#endregion

public static async Task<LocalPlayer> Create(int playerId, Vector3 position, Quaternion rotation,
Expand Down Expand Up @@ -1398,8 +1398,25 @@ public override void OnVaulting()
});
}

public Item FindItem(string itemId)
public Item FindItem(string itemId, bool questItem = false)
{
if (questItem)
{
//List<LootItemPositionClass> itemPositions = Traverse.Create(Singleton<GameWorld>.Instance).Field<List<LootItemPositionClass>>("list_1").Value;
foreach (GInterface12 lootItem in Singleton<GameWorld>.Instance.LootList)
{
if (lootItem is LootItem observedLootItem)
{
if (observedLootItem.Item.TemplateId == itemId)
{
return observedLootItem.Item;
}
}
}
FikaPlugin.Instance.FikaLogger.LogError($"CoopPlayer::FindItem: Could not find questItem with id '{itemId}' in the world at all.");
return null;
}

Item item = Inventory.Equipment.FindItem(itemId);
if (item != null)
{
Expand Down
19 changes: 17 additions & 2 deletions Fika.Core/Networking/FikaClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public void Init()
packetProcessor.SubscribeNetSerializable<OperationCallbackPacket>(OnOperationCallbackPacketReceived);
packetProcessor.SubscribeNetSerializable<TextMessagePacket>(OnTextMessagePacketReceived);
packetProcessor.SubscribeNetSerializable<QuestConditionPacket>(OnQuestConditionPacketReceived);
packetProcessor.SubscribeNetSerializable<QuestItemPacket>(OnQuestItemPacketReceived);

_netClient = new NetManager(this)
{
Expand Down Expand Up @@ -122,11 +123,25 @@ public void Init()
FikaEventDispatcher.DispatchEvent(new FikaClientCreatedEvent(this));
}

private void OnQuestItemPacketReceived(QuestItemPacket packet)
{
if (MyPlayer.HealthController.IsAlive)
{
if (MyPlayer.GClass3227_0 is CoopSharedQuestController sharedQuestController)
{
sharedQuestController.ReceiveQuestItemPacket(ref packet);
}
}
}

private void OnQuestConditionPacketReceived(QuestConditionPacket packet)
{
if (MyPlayer.GClass3227_0 is CoopSharedQuestController sharedQuestController)
if (MyPlayer.HealthController.IsAlive)
{
sharedQuestController.ReceiveQuestPacket(ref packet);
if (MyPlayer.GClass3227_0 is CoopSharedQuestController sharedQuestController)
{
sharedQuestController.ReceiveQuestPacket(ref packet);
}
}
}

Expand Down
22 changes: 20 additions & 2 deletions Fika.Core/Networking/FikaServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public async Task Init()
packetProcessor.SubscribeNetSerializable<SendCharacterPacket, NetPeer>(OnSendCharacterPacketReceived);
packetProcessor.SubscribeNetSerializable<TextMessagePacket, NetPeer>(OnTextMessagePacketReceived);
packetProcessor.SubscribeNetSerializable<QuestConditionPacket, NetPeer>(OnQuestConditionPacketReceived);
packetProcessor.SubscribeNetSerializable<QuestItemPacket, NetPeer>(OnQuestItemPacketReceived);

_netServer = new NetManager(this)
{
Expand Down Expand Up @@ -190,14 +191,31 @@ public async Task Init()
FikaEventDispatcher.DispatchEvent(new FikaServerCreatedEvent(this));
}

private void OnQuestItemPacketReceived(QuestItemPacket packet, NetPeer peer)
{
_dataWriter.Reset();
SendDataToAll(_dataWriter, ref packet, DeliveryMethod.ReliableUnordered, peer);

if (MyPlayer.HealthController.IsAlive)
{
if (MyPlayer.GClass3227_0 is CoopSharedQuestController sharedQuestController)
{
sharedQuestController.ReceiveQuestItemPacket(ref packet);
}
}
}

private void OnQuestConditionPacketReceived(QuestConditionPacket packet, NetPeer peer)
{
_dataWriter.Reset();
SendDataToAll(_dataWriter, ref packet, DeliveryMethod.ReliableUnordered, peer);

if (MyPlayer.GClass3227_0 is CoopSharedQuestController sharedQuestController)
if (MyPlayer.HealthController.IsAlive)
{
sharedQuestController.ReceiveQuestPacket(ref packet);
if (MyPlayer.GClass3227_0 is CoopSharedQuestController sharedQuestController)
{
sharedQuestController.ReceiveQuestPacket(ref packet);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,19 @@ public struct QuestConditionPacket(string nickname, string id, string sourceId)
public string Nickname = nickname;
public string Id = id;
public string SourceId = sourceId;
public string ItemId;

public void Deserialize(NetDataReader reader)
{
Nickname = reader.GetString();
Id = reader.GetString();
SourceId = reader.GetString();
ItemId = reader.GetString();
}

public void Serialize(NetDataWriter writer)
{
writer.Put(Nickname);
writer.Put(Id);
writer.Put(SourceId);
writer.Put(ItemId);
}
}
}
22 changes: 22 additions & 0 deletions Fika.Core/Networking/Packets/Communication/QuestItemPacket.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using LiteNetLib.Utils;

namespace Fika.Core.Networking.Packets
{
public struct QuestItemPacket(string nickname, string itemId) : INetSerializable
{
public string Nickname = nickname;
public string ItemId = itemId;

public void Deserialize(NetDataReader reader)
{
Nickname = reader.GetString();
ItemId = reader.GetString();
}

public void Serialize(NetDataWriter writer)
{
writer.Put(Nickname);
writer.Put(ItemId);
}
}
}

0 comments on commit f48d9d0

Please sign in to comment.