-
Notifications
You must be signed in to change notification settings - Fork 10
improve loot table UI and item sorting #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,7 @@ import { | |
| UnitItemDrop | ||
| } from "./modules/unit-item-drops"; | ||
| import {ItemClass} from "./modules/item-groups"; | ||
| import {initItemsDB} from "./modules/items-db"; | ||
| import {initItemsDB, getItemById} from "./modules/items-db"; | ||
| import { | ||
| calcUnitHpBarPosition, | ||
| initIsReforgedUnitModelsEnabledLocal, | ||
|
|
@@ -113,13 +113,6 @@ function enablePreviewFeatureToggleChatCommand() { | |
| }) | ||
| } | ||
|
|
||
| function getSingleGroupDrop(itemDropSets: ItemDropSet[]): RandomItemGroupDrop | undefined { | ||
| if (itemDropSets.length === 1 && itemDropSets[0].itemDrops.length === 1 | ||
| && itemDropSets[0].itemDrops[0] instanceof RandomItemGroupDrop) { | ||
| return itemDropSets[0].itemDrops[0]; | ||
| } | ||
| } | ||
|
|
||
| function isTomeDrop(itemDrop: ItemDrop): boolean { | ||
| if (itemDrop instanceof RandomItemGroupDrop) { | ||
| const group = itemDrop.itemGroup; | ||
|
|
@@ -130,6 +123,22 @@ function isTomeDrop(itemDrop: ItemDrop): boolean { | |
| return false; | ||
| } | ||
|
|
||
| function areAllDropsTomes(itemDropSets: ItemDropSet[]): boolean { | ||
| for (const set of itemDropSets) { | ||
| for (const drop of set.itemDrops) { | ||
| if (drop instanceof RandomItemGroupDrop) { | ||
| if (!isTomeDrop(drop)) return false; | ||
| } else { | ||
| const item = getItemById(drop.getRawId()); | ||
| if (!item) return false; | ||
| if (item.classification !== ItemClass.Power_Up) return false; | ||
| if (item.level !== 1 && item.level !== 2) return false; | ||
| } | ||
|
Comment on lines
+129
to
+136
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move this to |
||
| } | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| function enableLootTablePreviewUI() { | ||
| LootTableUI.init(); | ||
|
|
||
|
|
@@ -170,14 +179,14 @@ class UnitLootIndicator { | |
| const itemDropSets = unitItemDrop.dropSets; | ||
| let e: Effect; | ||
|
|
||
| //In 99% of cases a unit has a single set (drops 1 item) with a single group item drop (can drop any item from that group) | ||
| const groupDrop = getSingleGroupDrop(itemDropSets); | ||
| if (groupDrop && isTomeDrop(groupDrop)) { | ||
| if (areAllDropsTomes(itemDropSets)) { | ||
| e = Effect.create("loot-indicator\\loot-indicator-tome.mdx", 0, 0)!; | ||
| } else { | ||
| e = Effect.create("loot-indicator\\loot-indicator-generic.mdx", 0, 0)!; | ||
| } | ||
|
|
||
| e.scale = 1.5; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check with @Kenshin on changes to indicator appearance. I think it looks better with this scale, but maybe too big? Like 1.3 - 1.4 maybe? |
||
|
|
||
| //For units with mana bar, we adjust the position of the effect model with animation | ||
| //We don't use Z offset for effect in the world, because that will affect "billboarding", | ||
| //and will lead to the effect slightly shifting relative to HP bar depending on the camera angle | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,30 @@ | ||
| import {Frame} from "w3ts"; | ||
| import {getItemById} from "./items-db"; | ||
| import {getAllItemIds, ItemDropSet, RandomItemGroupDrop} from "./unit-item-drops"; | ||
| import { ItemClass } from "./item-groups"; | ||
|
|
||
| const ITEM_CLASS_PRIORITY: Record<ItemClass, number> = { | ||
| [ItemClass.Permanent]: 0, | ||
| [ItemClass.Charged]: 1, | ||
| [ItemClass.Power_Up]: 2, | ||
| [ItemClass.Artifact]: 3, | ||
| [ItemClass.Purchasable]: 4, | ||
| [ItemClass.Campaign]: 5, | ||
| [ItemClass.Misc]: 6 | ||
| }; | ||
|
|
||
| function sortItems(itemIds: string[]): string[] { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do sorting ones in |
||
| return itemIds | ||
| .map(id => getItemById(id)!) | ||
| .sort((a, b) => { | ||
| if (a.level !== b.level) return b.level - a.level; | ||
| const aPriority = ITEM_CLASS_PRIORITY[a.classification] ?? 999; | ||
| const bPriority = ITEM_CLASS_PRIORITY[b.classification] ?? 999; | ||
| if (aPriority !== bPriority) return aPriority - bPriority; | ||
| return a.name < b.name ? -1 : a.name > b.name ? 1 : 0; | ||
| }) | ||
| .map(i => i.id); | ||
| } | ||
|
|
||
| export class LootTableUI { | ||
| static INSTANCE: LootTableUI; | ||
|
|
@@ -48,14 +72,31 @@ export class LootTableUI { | |
| show(dropSets: ItemDropSet[]) { | ||
| this.mainParent.setVisible(true) | ||
|
|
||
| this.allDropsBtn.setTooltip(`|cffffff00Full loot table (${dropSets.length} drops)|r`, buildDropsInfoMsg(dropSets)) | ||
| const dropWord = dropSets.length === 1 ? "drop" : "drops"; | ||
| this.allDropsBtn.setTooltip(`|cffffff00Loot Table (${dropSets.length} ${dropWord})|r`, buildDropsInfoMsg(dropSets)) | ||
|
|
||
| let itemIds = getAllItemIds(dropSets); | ||
| itemIds = Array.from(new Set(itemIds)); | ||
| itemIds = sortItems(itemIds); | ||
|
|
||
| // Can't fit more than 12 right now. | ||
| if (itemIds.length > LootTableUI.MAX_ITEMS) { | ||
| itemIds = itemIds.slice(0, LootTableUI.MAX_ITEMS) | ||
| } | ||
|
|
||
| if (itemIds.length < LootTableUI.MAX_ITEMS) { | ||
| this.allDropsBtn.btn.setSize(0.04, 0.04) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think 0.039 is more closer to the actual icon size |
||
| } else { | ||
| this.allDropsBtn.btn.setSize(0.02, 0.02) | ||
| } | ||
| this.allDropsBtn.btn.clearPoints() | ||
| this.allDropsBtn.btn.setPoint( | ||
| FRAMEPOINT_BOTTOMRIGHT, | ||
| Frame.fromOrigin(ORIGIN_FRAME_COMMAND_BUTTON, 11), | ||
| FRAMEPOINT_BOTTOMRIGHT, | ||
| 0, 0 | ||
| ) | ||
|
Comment on lines
+92
to
+98
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can remove this. The point is already set in constructor. |
||
|
|
||
| for (let i = 0; i < LootTableUI.MAX_ITEMS; i++) { | ||
| const itemBtn = this.itemBtnList[i]; | ||
| const itemId = itemIds[i]; | ||
|
|
@@ -156,26 +197,35 @@ function buildDropsInfoMsg(sets: ItemDropSet[]): string { | |
| return sets.map((set, i) => { | ||
| let m = `|cffffff00== Drop ${i + 1} `; | ||
|
|
||
| //Short most common form | ||
| // Short most common form | ||
| if (set.itemDrops.length === 1 && set.itemDrops[0] instanceof RandomItemGroupDrop) { | ||
| const drop = set.itemDrops[0] as RandomItemGroupDrop; | ||
| m += `|cff00ff00[${drop.itemGroup.itemClass}, Level ${drop.itemGroup.itemLevel}]|r\n` | ||
| m += set.itemDrops.flatMap(d => d.getDropItemIds()) | ||
| .map(id => ` ${getItemById(id)!.name}`) | ||
| .join("\n") | ||
| //A set that contains a list of specific items or multiple GroupDrops, or a mix of both | ||
|
|
||
| const ids = Array.from(new Set(set.itemDrops.flatMap(d => d.getDropItemIds()))); | ||
| const sortedIds = sortItems(ids); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do sorting ones in findMapInitialCreepsWithDrops(). No need to sort them every time we show them. |
||
|
|
||
| m += sortedIds.map(id => ` ${getItemById(id)!.name}`).join("\n"); | ||
| // A set that contains a list of specific items or multiple GroupDrops, or a mix of both | ||
| } else { | ||
| m += `|cff00ff00[Custom drop pool]|r\n` | ||
| m += set.itemDrops.map(d => { | ||
| if (d instanceof RandomItemGroupDrop) { | ||
| return ` |cff00ff00[${d.itemGroup.itemClass}, Level ${d.itemGroup.itemLevel}]|r\n` + | ||
| d.getDropItemIds() | ||
| .map(id => ` - ${getItemById(id).name}`) | ||
| .join("\n") | ||
| } else { | ||
| return ` ${getItemById(d.getRawId()).name}` | ||
| } | ||
| }).join("\n") | ||
| m += `|cff00ff00[Custom]|r\n` | ||
|
|
||
| const allIds = Array.from( | ||
| new Set( | ||
| set.itemDrops.flatMap(d => | ||
| d instanceof RandomItemGroupDrop | ||
| ? d.getDropItemIds() | ||
| : [d.getRawId()] | ||
| ) | ||
| ) | ||
| ); | ||
|
|
||
| const sortedIds = sortItems(allIds); | ||
|
|
||
| m += sortedIds.map(id => { | ||
| const item = getItemById(id)!; | ||
| return ` ${item.name} |cff00ff00[${item.classification}, Level ${item.level}]|r`; | ||
| }).join("\n"); | ||
|
Comment on lines
210
to
+228
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
|
|
||
| return m; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -178,7 +178,6 @@ export function findMapInitialCreepsWithDrops(): UnitItemDrop[] { | |
| } else if (getItemById(itemOrGroupId) !== undefined) { | ||
| return [new SpecificItemDrop(itemOrGroupId)] | ||
| } else { | ||
| print(`Unknown item drop id "${itemOrGroupId}" for unit "${unit.name}" at (${unit.x}, ${unit.y}).`); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment instead. This might be useful in the future.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can for example have a creep with
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All current maps do not print this msg. If new map is added. Would it be better to have this msg, temporarily disable the feature/or msg, fix the bug in the feature or a map, then enable it back. Or its better to hide all the bugs?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's a non-blocking issue, no? I would just print some warning messages when you run the script
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure what you mean by
But, if you think it's an issue - you can comment it out instead of disabling. Ideally i would like for |
||
| return [] as ItemDrop[]; | ||
| } | ||
| }); | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't do those checks for items from drop sets - they are guaranteed to not be null anyway and it keeps it consistent with other code