Skip to content

Commit

Permalink
[Loot] Fix bug in loot
Browse files Browse the repository at this point in the history
  • Loading branch information
BAndysc committed Aug 30, 2024
1 parent 69c7b41 commit 6046adb
Show file tree
Hide file tree
Showing 14 changed files with 331 additions and 19 deletions.
1 change: 1 addition & 0 deletions Modules/WDE.HttpDatabase/Models/MySqlLootEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace WDE.HttpDatabase.Models;
public class JsonLootEntry : ILootEntry
{
public LootSourceType SourceType { get; set; }
public LootType LootType { get; set; }
public uint Entry { get; set; }
public int ItemOrCurrencyId { get; set; }
public uint Reference { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<CompletionComboBox
IsEnabled="{CompiledBinding CanChangeLootType}"
SelectedItem="{CompiledBinding LootType, Mode=TwoWay}"
controls:Extensions.EnumType="{x:Type database:LootSourceType}" />
Items="{CompiledBinding SupportedLootTypes}" />

<Border Width="20" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ public LootSourceType LootType
}
}

public IReadOnlyList<LootSourceType> SupportedLootTypes { get; }

[Notify] private bool canChangeLootType = true;
[Notify] private bool canChangeEntry = true;
[Notify] private uint solutionEntry;
Expand Down Expand Up @@ -192,6 +194,7 @@ public StandaloneLootEditorViewModel(
ITextDocumentService textDocumentService,
IParameterFactory parameterFactory,
ICurrentCoreVersion currentCoreVersion,
ILootEditorFeatures lootEditorFeatures,
PerDatabaseTableLootSolutionItem? solutionItem = null
)
{
Expand All @@ -202,6 +205,7 @@ public StandaloneLootEditorViewModel(
this.parameterPickerService = parameterPickerService;
this.messageBoxService = messageBoxService;
this.currentCoreVersion = currentCoreVersion;
SupportedLootTypes = lootEditorFeatures.SupportedTypes;
legacyDifficulties[0] = DifficultyViewModel.Legacy(0, "default");
legacyDifficulties[1] = DifficultyViewModel.Legacy(1, "heroic dung/25 raid");
legacyDifficulties[2] = DifficultyViewModel.Legacy(2, "10 heroic raid");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1086,7 +1086,7 @@ private async Task UnloadLoot(LootSourceType type, LootEntry menu)

private IReadOnlyList<LootEntry> Roots =>
(LootEditingMode == LootEditingMode.PerDatabaseTable) ? PerDatabaseSolutionItems :
Loots.Where(x => x.LootSourceType != LootSourceType.Reference || (uint)x.LootEntry == perEntitySolutionItem!.Entry)
Loots.Where(x => x.LootSourceType != LootSourceType.Reference || perEntitySolutionItem!.Type == LootSourceType.Reference && (uint)x.LootEntry == perEntitySolutionItem!.Entry)
.Select(x => x.LootEntry)
.ToList();

Expand Down Expand Up @@ -1128,7 +1128,7 @@ private bool VerifyDuplicateKeys()
{
var loot = lootGroup.LootItems[lootIndex];
loot.IsDuplicate = false;
var item = loot.ItemOrCurrencyId.Value;
var item = loot.IsReference ? loot.ReferenceEntry : loot.ItemOrCurrencyId.Value;
var minPatch = loot.MinPatch.Value;
if (!keys.Add((item, minPatch)))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ public LootModel ToModel()
SourceType = Parent.LootSourceType,
Entry = (uint)Parent.LootEntry,
ItemOrCurrencyId = (int)ItemOrCurrencyId.Value,
LootType = IsReference ? LootType.Reference : LootType.Item,
Chance = Math.Abs(Chance.Value),
QuestRequired = Chance.Value < 0,
LootMode = (uint)LootMode.Value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public IQuery GenerateQuery(IReadOnlyList<LootGroupModel> models)
.BulkInsert(group.Items.Select(x => new
{
entry = x.Loot.Entry,
item = x.Loot.ItemOrCurrencyId,
item = x.Loot.IsReference() && x.Loot.ItemOrCurrencyId == 0 ? (long)x.Loot.Reference : x.Loot.ItemOrCurrencyId,
ChanceOrQuestChance = (x.Loot.QuestRequired ? -1 : 1) * x.Loot.Chance,
groupid = x.Loot.GroupId,
mincountOrRef = x.Loot.IsReference() ? -(int)x.Loot.Reference : x.Loot.MinCount,
Expand Down
33 changes: 30 additions & 3 deletions Modules/WDE.LootEditor/QueryGenerator/TrinityLootQueryGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public IQuery GenerateUpdateLootIds(LootSourceType sourceType, uint solutionEntr
}
}

[RequiresCore("TrinityMaster", "TrinityWrath", "Azeroth")]
[RequiresCore("TrinityWrath", "Azeroth")]
[AutoRegister]
[SingleInstance]
public class TrinityLootQueryGenerator : BaseTrinityLootQueryGenerator
Expand All @@ -143,7 +143,7 @@ protected override object CreateDatabaseObjectRow(LootModel x)
return new
{
Entry = x.Loot.Entry,
Item = x.Loot.ItemOrCurrencyId,
Item = x.Loot.IsReference() && x.Loot.ItemOrCurrencyId == 0 ? (long)x.Loot.Reference : x.Loot.ItemOrCurrencyId,
Reference = x.Loot.Reference,
Chance = x.Loot.Chance,
QuestRequired = x.Loot.QuestRequired,
Expand All @@ -156,6 +156,33 @@ protected override object CreateDatabaseObjectRow(LootModel x)
}
}

[RequiresCore("TrinityMaster")]
[AutoRegister]
[SingleInstance]
public class TrinityMasterLootQueryGenerator : BaseTrinityLootQueryGenerator
{
public TrinityMasterLootQueryGenerator(IConditionQueryGenerator conditionQueryGenerator, ICurrentCoreVersion currentCoreVersion, ILootEditorFeatures editorFeatures) : base(conditionQueryGenerator, currentCoreVersion, editorFeatures)
{
}

protected override object CreateDatabaseObjectRow(LootModel x)
{
return new
{
Entry = x.Loot.Entry,
Item = x.Loot.LootType == LootType.Reference ? x.Loot.Reference : (long)x.Loot.ItemOrCurrencyId,
ItemType = (int)x.Loot.LootType,
Chance = x.Loot.Chance,
QuestRequired = x.Loot.QuestRequired,
LootMode = x.Loot.LootMode,
GroupId = x.Loot.GroupId,
MinCount = x.Loot.MinCount,
MaxCount = x.Loot.MaxCount,
Comment = x.Loot.Comment
};
}
}

[RequiresCore("TrinityCata")]
[AutoRegister]
[SingleInstance]
Expand All @@ -170,7 +197,7 @@ protected override object CreateDatabaseObjectRow(LootModel x)
return new
{
Entry = x.Loot.Entry,
Item = Math.Abs(x.Loot.ItemOrCurrencyId),
Item = x.Loot.IsReference() && x.Loot.ItemOrCurrencyId == 0 ? (long)x.Loot.Reference : Math.Abs(x.Loot.ItemOrCurrencyId),
IsCurrency = x.Loot.ItemOrCurrencyId < 0,
Reference = x.Loot.Reference,
Chance = x.Loot.Chance,
Expand Down
4 changes: 3 additions & 1 deletion WoWDatabaseEditor.Common/WDE.CMMySqlDatabase/Models/Loot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ namespace WDE.CMMySqlDatabase.Models;
public abstract class BaseLootTemplate : ILootEntry
{
public abstract LootSourceType SourceType { get; }


public LootType LootType => Reference != 0 ? LootType.Reference : LootType.Item;

[PrimaryKey]
[Column(Name = "entry")]
public uint Entry { get; set; }
Expand Down
6 changes: 0 additions & 6 deletions WoWDatabaseEditor.Common/WDE.Common/Database/LootType.cs

This file was deleted.

21 changes: 18 additions & 3 deletions WoWDatabaseEditor.Common/WDE.Common/Utils/AsyncAutoCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Prism.Commands;
using WDE.Common.Annotations;
using WDE.Common.Exceptions;
using WDE.Common.Services;
using WDE.Common.Services.MessageBox;
using WDE.Common.Tasks;

Expand Down Expand Up @@ -46,7 +47,14 @@ public AsyncAutoCommand(Func<Task> execute,
{
LOG.LogError(e, "Error in {0} at {1}:{2}", caller, callerFile, callerLineNumber);
}
onException?.Invoke(e);
if (onException == null)
{
var service = DI.Resolve<IMessageBoxService>();
if (service != null)
GlobalApplication.MainThread.Dispatch(() => CommandExtensions.ShowError(service, e, null));
}
else
onException?.Invoke(e);
},
continueOnCapturedContext);
}
Expand Down Expand Up @@ -116,7 +124,14 @@ public AsyncAutoCommand([NotNull]
e =>
{
IsBusy = false;
onException?.Invoke(e);
if (onException == null)
{
var service = DI.Resolve<IMessageBoxService>();
if (service != null)
GlobalApplication.MainThread.Dispatch(() => CommandExtensions.ShowError(service, e, null));
}
else
onException?.Invoke(e);
},
continueOnCapturedContext);
}
Expand Down Expand Up @@ -290,7 +305,7 @@ public static IAsyncCommand<R> WrapMessageBox<T, R>(this IAsyncCommand<R> cmd, I
});
}

private static async Task ShowError(IMessageBoxService messageBoxService, Exception e, string? header,
internal static async Task ShowError(IMessageBoxService messageBoxService, Exception e, string? header,
[CallerMemberName] string? caller = null,
[CallerFilePath] string? callerFile = null,
[CallerLineNumber] int? callerLineNumber = null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,8 @@ public override async Task<IReadOnlyList<ICreatureTemplateAddon>> GetCreatureTem

public override async Task<ICreatureTemplateAddon?> GetCreatureTemplateAddon(uint entry)
{
await using var model = Database();
return await model.CreatureTemplateAddon.FirstOrDefaultAsync<ICreatureTemplateAddon>(x => x.Entry == entry);
using var model = Database();
return model.CreatureTemplateAddon.FirstOrDefault<ICreatureTemplateAddon>(x => x.Entry == entry);
}

public override async Task<IReadOnlyList<IPlayerChoice>?> GetPlayerChoicesAsync()
Expand Down Expand Up @@ -542,4 +542,132 @@ public override async Task<IReadOnlyList<IConversationActor>> GetConversationAct
await using var model = Database();
return await model.ConversationActor.OrderBy(x => x.ConversationId).ThenBy(x => x.Idx).ToListAsync<IConversationActor>();
}


public override async Task<IReadOnlyList<ILootEntry>> GetLoot(LootSourceType type)
{
await using var database = Database();
switch (type)
{
case LootSourceType.Item:
return await database.ItemMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
case LootSourceType.GameObject:
return await database.GameObjectMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
case LootSourceType.Fishing:
return await database.FishingMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
case LootSourceType.Pickpocketing:
return await database.PickpocketingMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
case LootSourceType.Skinning:
return await database.SkinningMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
case LootSourceType.Disenchant:
return await database.DisenchantMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
case LootSourceType.Prospecting:
return await database.ProspectingMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
case LootSourceType.Milling:
return await database.MillingMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
case LootSourceType.Reference:
return await database.ReferenceMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
case LootSourceType.Creature:
return await database.CreatureMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
case LootSourceType.Mail:
return await database.MailMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
case LootSourceType.Spell:
return await database.SpellMasterLootTemplate.OrderBy(x => x.Entry)
.ThenBy(x => x.GroupId)
.ThenBy(x => x.ItemOrCurrencyId)
.ToListAsync<ILootEntry>();
default:
throw new ArgumentOutOfRangeException(nameof(type), type, null);
}
}

public override async Task<IReadOnlyList<ILootEntry>> GetReferenceLootCrossReference(uint lootId)
{
if (lootId == 0)
return Array.Empty<ILootEntry>();
await using var database = Database();
var loot = new[]
{
await database.CreatureMasterLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
await database.GameObjectMasterLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
await database.ItemMasterLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
await database.FishingMasterLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
await database.PickpocketingMasterLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
await database.SkinningMasterLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
await database.DisenchantMasterLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
await database.ProspectingMasterLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
await database.MillingMasterLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
await database.MailMasterLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
await database.SpellMasterLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
await database.ReferenceLootTemplate.Where(x => x.Reference == lootId).ToListAsync<ILootEntry>(),
};
return loot.SelectMany(x => x).ToList();
}

public override async Task<IReadOnlyList<ILootEntry>> GetLoot(LootSourceType type, uint entry)
{
await using var database = Database();
switch (type)
{
case LootSourceType.Item:
return await database.ItemMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
case LootSourceType.GameObject:
return await database.GameObjectMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
case LootSourceType.Fishing:
return await database.FishingMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
case LootSourceType.Pickpocketing:
return await database.PickpocketingMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
case LootSourceType.Skinning:
return await database.SkinningMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
case LootSourceType.Disenchant:
return await database.DisenchantMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
case LootSourceType.Prospecting:
return await database.ProspectingMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
case LootSourceType.Milling:
return await database.MillingMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
case LootSourceType.Reference:
return await database.ReferenceMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
case LootSourceType.Creature:
return await database.CreatureMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
case LootSourceType.Mail:
return await database.MailMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
case LootSourceType.Spell:
return await database.SpellMasterLootTemplate.Where(x => x.Entry == entry).ToListAsync<ILootEntry>();
default:
throw new ArgumentOutOfRangeException(nameof(type), type, null);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,17 @@ public class TrinityMasterDatabase : BaseTrinityDatabase
public ITable<MasterWaypointData> WaypointData => this.GetTable<MasterWaypointData>();
public ITable<MySqlConditionLineMaster> ConditionsMaster => this.GetTable<MySqlConditionLineMaster>();
public ITable<MySqlConversationActor> ConversationActor => this.GetTable<MySqlConversationActor>();

public ITable<ItemMasterLootTemplate> ItemMasterLootTemplate => this.GetTable<ItemMasterLootTemplate>();
public ITable<PickpocketingMasterLootTemplate> PickpocketingMasterLootTemplate => this.GetTable<PickpocketingMasterLootTemplate>();
public ITable<CreatureMasterLootTemplate> CreatureMasterLootTemplate => this.GetTable<CreatureMasterLootTemplate>();
public ITable<DisenchantMasterLootTemplate> DisenchantMasterLootTemplate => this.GetTable<DisenchantMasterLootTemplate>();
public ITable<ProspectingMasterLootTemplate> ProspectingMasterLootTemplate => this.GetTable<ProspectingMasterLootTemplate>();
public ITable<MillingMasterLootTemplate> MillingMasterLootTemplate => this.GetTable<MillingMasterLootTemplate>();
public ITable<ReferenceMasterLootTemplate> ReferenceMasterLootTemplate => this.GetTable<ReferenceMasterLootTemplate>();
public ITable<SpellMasterLootTemplate> SpellMasterLootTemplate => this.GetTable<SpellMasterLootTemplate>();
public ITable<MailMasterLootTemplate> MailMasterLootTemplate => this.GetTable<MailMasterLootTemplate>();
public ITable<GameObjectMasterLootTemplate> GameObjectMasterLootTemplate => this.GetTable<GameObjectMasterLootTemplate>();
public ITable<FishingMasterLootTemplate> FishingMasterLootTemplate => this.GetTable<FishingMasterLootTemplate>();
public ITable<SkinningMasterLootTemplate> SkinningMasterLootTemplate => this.GetTable<SkinningMasterLootTemplate>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ public abstract class BaseMySqlLootEntry : ILootEntry
{
public abstract LootSourceType SourceType { get; }

public LootType LootType => Reference != 0 ? LootType.Reference : LootType.Item;

[PrimaryKey]
[Column(Name = "Entry")]
public uint Entry { get; set; }
Expand Down
Loading

0 comments on commit 6046adb

Please sign in to comment.