Skip to content

Commit

Permalink
Implement mob reward loading, managers, and drops while kill monster (#…
Browse files Browse the repository at this point in the history
…88)

* Add mobreward interfaces

* Add mobreward template loading, implement mobrewardmanager

* Add mob reward handling
  • Loading branch information
Kaioru authored Dec 7, 2023
1 parent d4a105d commit 6b81702
Show file tree
Hide file tree
Showing 17 changed files with 305 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/app/Edelstein.Application.Server/ProgramHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Edelstein.Common.Gameplay.Game.Combat;
using Edelstein.Common.Gameplay.Game.Continents;
using Edelstein.Common.Gameplay.Game.Conversations;
using Edelstein.Common.Gameplay.Game.Objects.Mob.Rewards;
using Edelstein.Common.Gameplay.Game.Objects.NPC;
using Edelstein.Common.Gameplay.Game.Quests;
using Edelstein.Common.Gameplay.Handling;
Expand All @@ -29,6 +30,7 @@
using Edelstein.Protocol.Gameplay.Game.Contexts;
using Edelstein.Protocol.Gameplay.Game.Continents;
using Edelstein.Protocol.Gameplay.Game.Conversations;
using Edelstein.Protocol.Gameplay.Game.Objects.Mob.Rewards;
using Edelstein.Protocol.Gameplay.Game.Objects.NPC;
using Edelstein.Protocol.Gameplay.Game.Quests;
using Edelstein.Protocol.Gameplay.Login;
Expand Down Expand Up @@ -178,6 +180,7 @@ public async Task StartAsync(CancellationToken cancellationToken)
b.RegisterType<ContiMoveManager>().As<IContiMoveManager>().SingleInstance();
b.RegisterType<ScriptedConversationManager>().As<INamedConversationManager>().SingleInstance();
b.RegisterType<NPCShopManager>().As<INPCShopManager>().SingleInstance();
b.RegisterType<MobRewardPoolManager>().As<IMobRewardPoolManager>().SingleInstance();
b.RegisterType<SkillManager>().As<ISkillManager>().SingleInstance();
b.RegisterType<ModifiedQuestTimeManager>().As<IModifiedQuestTimeManager>().SingleInstance();
b.RegisterType<QuestManager>().As<IQuestManager>().SingleInstance();
Expand Down
30 changes: 27 additions & 3 deletions src/common/Edelstein.Common.Gameplay.Game/Objects/Mob/FieldMob.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System.Collections.Immutable;
using Edelstein.Common.Gameplay.Game.Objects.Drop;
using Edelstein.Common.Gameplay.Game.Objects.Mob.Stats;
using Edelstein.Common.Gameplay.Game.Objects.Mob.Stats.Modify;
using Edelstein.Common.Gameplay.Handling;
using Edelstein.Common.Gameplay.Models.Inventories.Items;
using Edelstein.Common.Utilities.Packets;
using Edelstein.Protocol.Gameplay.Game.Objects;
using Edelstein.Protocol.Gameplay.Game.Objects.Mob;
Expand All @@ -10,6 +12,7 @@
using Edelstein.Protocol.Gameplay.Game.Objects.Mob.Templates;
using Edelstein.Protocol.Gameplay.Game.Objects.User;
using Edelstein.Protocol.Gameplay.Game.Spatial;
using Edelstein.Protocol.Gameplay.Models.Inventories.Templates;
using Edelstein.Protocol.Utilities.Packets;
using Edelstein.Protocol.Utilities.Spatial;
using Edelstein.Protocol.Utilities.Tickers;
Expand Down Expand Up @@ -87,10 +90,31 @@ public async Task Damage(int damage, IFieldUser? attacker = null)

if (HP <= 0)
{
await Field.Leave(this, () => GetLeaveFieldPacket(FieldMobLeaveType.Etc));

if (attacker != null)
if (attacker != null)
{
var rewardPool = attacker.StageUser.Context.Managers.MobRewardPool;
var rewards = await rewardPool.CalculateRewards(attacker, this);

foreach (var reward in rewards)
{
if (reward.ItemID == null) continue;
var template = await attacker.StageUser.Context.Templates.Item.Retrieve(reward.ItemID.Value);
if (template == null) continue;

var position = Position;
var drop = new FieldDropItem(
position,
template.ToItemSlot(ItemVariationOption.Normal),
sourceID: ObjectID ?? 0
);

await Field.Enter(drop, () => drop.GetEnterFieldPacket(1, position));
}

_ = attacker.StageUser.Context.Managers.Quest.UpdateMobKill(attacker, Template.ID);
}

await Field.Leave(this, () => GetLeaveFieldPacket(FieldMobLeaveType.Etc));
}
}
finally
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Edelstein.Protocol.Gameplay.Game.Objects.Mob.Rewards;

namespace Edelstein.Common.Gameplay.Game.Objects.Mob.Rewards;

public record MobReward(
int ID
) : IMobReward
{
public int? ItemID { get; init; }

public int? Money { get; init; }

public int? NumberMin { get; init; }
public int? NumberMax { get; init; }

public int? ReqQuest { get; init; }

public int? ReqLevelMin { get; init; }
public int? ReqLevelMax { get; init; }

public int? ReqMobLevelMin { get; init; }
public int? ReqMobLevelMax { get; init; }

public DateTime? DateStart { get; init; }
public DateTime? DateEnd { get; init; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Collections.Immutable;
using Edelstein.Common.Utilities.Repositories;
using Edelstein.Protocol.Gameplay.Game.Objects.Mob;
using Edelstein.Protocol.Gameplay.Game.Objects.Mob.Rewards;
using Edelstein.Protocol.Gameplay.Game.Objects.User;
using Edelstein.Protocol.Gameplay.Game.Rewards;
using Edelstein.Protocol.Utilities.Repositories;

namespace Edelstein.Common.Gameplay.Game.Objects.Mob.Rewards;

public class MobRewardPoolManager :
Repository<int, IRewardPool<IMobReward>>,
IMobRewardPoolManager
{
public IRepository<int, IMobReward> Global { get; } = new Repository<int, IMobReward>();

public async Task<ICollection<IMobReward>> CalculateRewards(IFieldUser user, IFieldMob mob)
{
var pool = await Retrieve(mob.Template.ID);
var items = new List<IMobReward>();

if (pool != null)
items.AddRange(await pool.RetrieveAll());
items.AddRange(await Global.RetrieveAll());

return items.ToImmutableArray();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Edelstein.Common.Gameplay.Game.Objects.Mob.Templates;
using Edelstein.Common.Gameplay.Game.Rewards;
using Edelstein.Protocol.Gameplay.Contracts;
using Edelstein.Protocol.Gameplay.Game.Objects.Mob.Rewards;
using Edelstein.Protocol.Utilities.Pipelines;
using Edelstein.Protocol.Utilities.Templates;

namespace Edelstein.Common.Gameplay.Game.Objects.Mob.Rewards;

public class MobRewardPoolManagerInit : IPipelinePlug<StageStart>
{
private readonly ITemplateManager<MobRewardPoolTemplate> _templates;
private readonly IMobRewardPoolManager _manager;

public MobRewardPoolManagerInit(
ITemplateManager<MobRewardPoolTemplate> templates,
IMobRewardPoolManager manager
)
{
_templates = templates;
_manager = manager;
}

public async Task Handle(IPipelineContext ctx, StageStart message)
{
foreach (var rewards in await _templates.RetrieveAll())
{
var pool = new RewardPool<IMobReward>(rewards.ID);
foreach (var item in rewards.Items)
await pool.Insert(item);
await _manager.Insert(pool);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Collections.Immutable;
using Duey.Abstractions;
using Edelstein.Common.Gameplay.Game.Objects.NPC.Templates;
using Edelstein.Protocol.Gameplay.Game.Objects.NPC;
using Edelstein.Protocol.Utilities.Templates;

namespace Edelstein.Common.Gameplay.Game.Objects.Mob.Templates;

public class MobRewardPoolTemplate : ITemplate
{
public int ID { get; }
public ICollection<MobRewardTemplate> Items { get; }

public MobRewardPoolTemplate(int id, IDataNode property)
{
ID = id;
Items = property.Children
.Select(p => new MobRewardTemplate(Convert.ToInt32(p.Name), p.Cache()))
.ToImmutableArray();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Duey.Abstractions;
using Edelstein.Common.Gameplay.Game.Objects.NPC.Templates;
using Edelstein.Common.Utilities.Templates;
using Edelstein.Protocol.Utilities.Templates;

namespace Edelstein.Common.Gameplay.Game.Objects.Mob.Templates;

public class MobRewardPoolTemplateLoader : ITemplateLoader
{
private readonly IDataNamespace _data;
private readonly ITemplateManager<MobRewardPoolTemplate> _manager;

public MobRewardPoolTemplateLoader(IDataNamespace data, ITemplateManager<MobRewardPoolTemplate> manager)
{
_data = data;
_manager = manager;
}

public async Task<int> Load()
{
await Task.WhenAll(_data.ResolvePath("Server/Reward.img")?.Children
.Select(async n =>
{
var id = Convert.ToInt32(n.Name);
await _manager.Insert(new TemplateProviderEager<MobRewardPoolTemplate>(
id,
new MobRewardPoolTemplate(id, n.Cache())
));
}) ?? Array.Empty<Task>());

return _manager.Count;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Duey.Abstractions;
using Edelstein.Protocol.Gameplay.Game.Objects.Mob.Rewards;
using Edelstein.Protocol.Utilities.Templates;

namespace Edelstein.Common.Gameplay.Game.Objects.Mob.Templates;

public class MobRewardTemplate : ITemplate, IMobReward
{
public int ID { get; }

public int? ItemID { get; }

public int? Money { get; }

public int? NumberMin { get; }
public int? NumberMax { get; }

public int? ReqQuest { get; }

public int? ReqLevelMin { get; }
public int? ReqLevelMax { get; }

public int? ReqMobLevelMin { get; }
public int? ReqMobLevelMax { get; }

public DateTime? DateStart { get; }
public DateTime? DateEnd { get; }

public MobRewardTemplate(int id, IDataNode property)
{
ID = id;

ItemID = property.ResolveInt("item");

Money = property.ResolveInt("money");

NumberMin = property.ResolveInt("min");
NumberMax = property.ResolveInt("max");
}
}
14 changes: 14 additions & 0 deletions src/common/Edelstein.Common.Gameplay.Game/Rewards/RewardPool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Edelstein.Common.Utilities.Repositories;
using Edelstein.Protocol.Gameplay.Game.Rewards;

namespace Edelstein.Common.Gameplay.Game.Rewards;

public class RewardPool<TReward> :
Repository<int, TReward>,
IRewardPool<TReward>
where TReward : IReward
{
public int ID { get; }

public RewardPool(int id) => ID = id;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Edelstein.Common.Utilities.Repositories;
using Edelstein.Protocol.Gameplay.Game.Rewards;

namespace Edelstein.Common.Gameplay.Game.Rewards;

public class RewardPoolManager<TReward> :
Repository<int, IRewardPool<TReward>>,
IRewardPoolManager<TReward>
where TReward : IReward
{
}
4 changes: 4 additions & 0 deletions src/plugin/Edelstein.Plugin.Rue/Edelstein.Plugin.Rue.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,8 @@
<PackageReference Include="TrieNet" Version="1.0.3.26316" />
</ItemGroup>

<ItemGroup>
<Folder Include="Commands\v2\" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Edelstein.Protocol.Gameplay.Game.Combat;
using Edelstein.Protocol.Gameplay.Game.Continents;
using Edelstein.Protocol.Gameplay.Game.Conversations;
using Edelstein.Protocol.Gameplay.Game.Objects.Mob.Rewards;
using Edelstein.Protocol.Gameplay.Game.Objects.NPC;
using Edelstein.Protocol.Gameplay.Game.Quests;
using Edelstein.Protocol.Gameplay.Models.Inventories;
Expand All @@ -18,6 +19,7 @@ public record GameContextManagers(
IContiMoveManager ContiMove,
INamedConversationManager Conversation,
INPCShopManager NPCShop,
IMobRewardPoolManager MobRewardPool,
ISkillManager Skill,
IQuestManager Quest,
IModifiedQuestTimeManager QuestTime
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Edelstein.Protocol.Gameplay.Game.Rewards;

namespace Edelstein.Protocol.Gameplay.Game.Objects.Mob.Rewards;

public interface IMobReward : IReward
{
int? ItemID { get; }

int? Money { get; }

int? NumberMin { get; }
int? NumberMax { get; }

int? ReqQuest { get; }

int? ReqLevelMin { get; }
int? ReqLevelMax { get; }

int? ReqMobLevelMin { get; }
int? ReqMobLevelMax { get; }

DateTime? DateStart { get; }
DateTime? DateEnd { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Edelstein.Protocol.Gameplay.Game.Objects.User;
using Edelstein.Protocol.Gameplay.Game.Rewards;
using Edelstein.Protocol.Utilities.Repositories;

namespace Edelstein.Protocol.Gameplay.Game.Objects.Mob.Rewards;

public interface IMobRewardPoolManager : IRewardPoolManager<IMobReward>
{
IRepository<int, IMobReward> Global { get; }

Task<ICollection<IMobReward>> CalculateRewards(IFieldUser user, IFieldMob mob);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Edelstein.Protocol.Utilities.Repositories;

namespace Edelstein.Protocol.Gameplay.Game.Rewards;

public interface IReward : IIdentifiable<int>
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Edelstein.Protocol.Utilities.Repositories;

namespace Edelstein.Protocol.Gameplay.Game.Rewards;

public interface IRewardPool<TReward> :
IIdentifiable<int>,
IRepository<int, TReward>
where TReward : IReward
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Edelstein.Protocol.Utilities.Repositories;

namespace Edelstein.Protocol.Gameplay.Game.Rewards;

public interface IRewardPoolManager<TReward> :
IRepository<int, IRewardPool<TReward>>
where TReward : IReward
{
}

0 comments on commit 6b81702

Please sign in to comment.