server-master/srcs/_plugins/WingsEmu.Plugins.BasicImplementation/Guri/HarvestGuriHandler.cs
2026-02-10 18:21:30 +01:00

210 lines
No EOL
7.7 KiB
C#

using System;
using System.Linq;
using System.Threading.Tasks;
using PhoenixLib.Events;
using PhoenixLib.Logging;
using WingsAPI.Data.Drops;
using WingsAPI.Game.Extensions.ItemExtension.Inventory;
using WingsAPI.Game.Extensions.ItemExtension.Item;
using WingsEmu.Game;
using WingsEmu.Game._enum;
using WingsEmu.Game._Guri;
using WingsEmu.Game._Guri.Event;
using WingsEmu.Game._i18n;
using WingsEmu.Game.Battle;
using WingsEmu.Game.Characters;
using WingsEmu.Game.Characters.Events;
using WingsEmu.Game.Entities;
using WingsEmu.Game.Entities.Extensions;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Helpers.Damages;
using WingsEmu.Game.Items;
using WingsEmu.Game.Managers;
using WingsEmu.Game.Managers.StaticData;
using WingsEmu.Game.Networking;
using WingsEmu.Game.Npcs.Event;
using WingsEmu.Game.Quests.Event;
using WingsEmu.Packets.Enums;
using WingsEmu.Packets.Enums.Chat;
namespace WingsEmu.Plugins.BasicImplementations.Guri;
public class HarverstGuriHandler : IGuriHandler
{
private readonly IAsyncEventPipeline _asyncEventPipeline;
private readonly IDelayManager _delayManager;
private readonly IGameItemInstanceFactory _gameItemInstanceFactory;
private readonly IGameLanguageService _gameLanguageService;
private readonly IItemsManager _itemsManager;
private readonly IRandomGenerator _randomGenerator;
private readonly IServerManager _serverManager;
public HarverstGuriHandler(IServerManager serverManager,
IGameLanguageService gameLanguageService, IRandomGenerator randomGenerator,
IItemsManager itemsManager, IGameItemInstanceFactory gameItemInstanceFactory, IDelayManager delayManager, IAsyncEventPipeline asyncEventPipeline)
{
_randomGenerator = randomGenerator;
_serverManager = serverManager;
_gameLanguageService = gameLanguageService;
_itemsManager = itemsManager;
_gameItemInstanceFactory = gameItemInstanceFactory;
_delayManager = delayManager;
_asyncEventPipeline = asyncEventPipeline;
}
public long GuriEffectId => 400;
public async Task ExecuteAsync(IClientSession session, GuriEvent guriPacket)
{
if (guriPacket == null)
{
return;
}
if (guriPacket.Data == 0)
{
return;
}
if (!session.HasCurrentMapInstance)
{
return;
}
INpcEntity npcEntity = session.CurrentMapInstance.GetNpcById(guriPacket.Data);
if (npcEntity == null)
{
Log.Debug($"Npc not found. GuriEffectId : {GuriEffectId}");
return;
}
if (!npcEntity.IsAlive())
{
await session.NotifyStrangeBehavior(StrangeBehaviorSeverity.ABUSING, "[ITEM_HARVEST] Tried to harvest a dead NPC.");
return;
}
if (!npcEntity.IsInRange(session.PlayerEntity.PositionX, session.PlayerEntity.PositionY, 5))
{
await session.NotifyStrangeBehavior(StrangeBehaviorSeverity.ABUSING, "[ITEM_HARVEST] Tried to harvest an NPC that is too far away.");
return;
}
if (!await _delayManager.CanPerformAction(session.PlayerEntity, DelayedActionType.Mining))
{
return;
}
await _delayManager.CompleteAction(session.PlayerEntity, DelayedActionType.Mining);
if (npcEntity.CurrentCollection <= 0)
{
int delayTime = (int)(npcEntity.LastCollection - DateTime.UtcNow).TotalSeconds;
session.SendMsg(_gameLanguageService.GetLanguageFormat(GameDialogKey.HARVEST_SHOUTMESSAGE_FAIL_TRY_AGAIN, session.UserLanguage, delayTime), MsgMessageType.Middle);
return;
}
if (npcEntity.VNumRequired != 0 && npcEntity.AmountRequired != 0)
{
if (!session.PlayerEntity.HasItem(npcEntity.VNumRequired, npcEntity.AmountRequired))
{
string itemName = _itemsManager.GetItem(npcEntity.VNumRequired).GetItemName(_gameLanguageService, session.UserLanguage);
session.SendMsg(_gameLanguageService.GetLanguageFormat(GameDialogKey.INVENTORY_SHOUTMESSAGE_NOT_ENOUGH_ITEMS, session.UserLanguage, npcEntity.AmountRequired, itemName),
MsgMessageType.Middle);
return;
}
}
double chance = _randomGenerator.RandomNumber(0, 100_000);
DropDTO drop;
if (npcEntity.Drops.Count <= 1)
{
drop = npcEntity.Drops.FirstOrDefault(s => s.MonsterVNum == npcEntity.NpcVNum);
if (drop != null && chance > drop.DropChance)
{
session.SendMsg(_gameLanguageService.GetLanguage(GameDialogKey.HARVEST_SHOUTMESSAGE_TRY_FAIL, session.UserLanguage), MsgMessageType.Middle);
return;
}
}
else
{
var randomBag = new RandomBag<DropDTO>(_randomGenerator);
foreach (DropDTO dropDto in npcEntity.Drops)
{
randomBag.AddEntry(dropDto, dropDto.DropChance);
}
drop = randomBag.GetRandom();
}
if (drop == null)
{
session.SendMsg(_gameLanguageService.GetLanguage(GameDialogKey.HARVEST_SHOUTMESSAGE_TRY_FAIL, session.UserLanguage), MsgMessageType.Middle);
return;
}
int vnum = drop.ItemVNum;
if (npcEntity.VNumRequired != 0 && npcEntity.AmountRequired != 0)
{
await session.RemoveItemFromInventory(npcEntity.VNumRequired, npcEntity.AmountRequired);
}
npcEntity.CurrentCollection--;
GameItemInstance newItem = _gameItemInstanceFactory.CreateItem(vnum, drop.Amount);
session.SendMsg(
_gameLanguageService.GetLanguageFormat(GameDialogKey.INVENTORY_CHATMESSAGE_X_ITEM_ACQUIRED, session.UserLanguage, newItem.Amount.ToString(),
_gameLanguageService.GetItemName(newItem.GameItem, session)), MsgMessageType.Middle);
switch ((MonsterVnum)npcEntity.NpcVNum)
{
case MonsterVnum.POISON_PLANT_OF_DAMNATION:
case MonsterVnum.ICE_FLOWER:
npcEntity.MapInstance.Broadcast(npcEntity.GenerateOut());
await _asyncEventPipeline.ProcessEventAsync(new MapNpcGenerateDeathEvent(npcEntity, null));
Position newPosition = npcEntity.MapInstance.GetRandomPosition();
npcEntity.FirstX = newPosition.X;
npcEntity.FirstY = newPosition.Y;
break;
case MonsterVnum.ROBBER_GANG_CHEST:
npcEntity.MapInstance.Broadcast(npcEntity.GenerateOut());
await _asyncEventPipeline.ProcessEventAsync(new MapNpcGenerateDeathEvent(npcEntity, null));
break;
}
// Quest logic
bool isHarvestObjective = session.PlayerEntity.GetCurrentQuestsByType(QuestType.COLLECT)
.Any(s => s.Quest.Objectives.Any(o =>
newItem.ItemVNum == o.Data1 && npcEntity.NpcVNum == o.Data0 && s.ObjectiveAmount[o.ObjectiveIndex].CurrentAmount <= s.ObjectiveAmount[o.ObjectiveIndex].RequiredAmount));
if (!isHarvestObjective)
{
await session.AddNewItemToInventory(newItem, true, sendGiftIsFull: true);
return;
}
if (session.PlayerEntity.IsInGroup())
{
foreach (IPlayerEntity member in session.PlayerEntity.GetGroup().Members)
{
await member.Session.EmitEventAsync(new QuestHarvestEvent
{
ItemVnum = newItem.ItemVNum,
NpcVnum = npcEntity.NpcVNum
});
}
}
else
{
await session.EmitEventAsync(new QuestHarvestEvent
{
ItemVnum = newItem.ItemVNum,
NpcVnum = npcEntity.NpcVNum
});
}
}
}