Add reload time filter

This commit is contained in:
kvan7
2025-06-06 18:28:27 -05:00
parent eea37254b5
commit 97750a1c26
24 changed files with 107 additions and 16 deletions
@@ -51,6 +51,7 @@
"crit": "暴擊率:{0}%",
"aps": "攻擊次數:{0}",
"spirit": "精魂:{0}",
"reload_time": "重新裝填時間: {0}",
"has_empty_modifier": "1 個空的或已製作的修改詞綴",
"has_empty_affix": "任何",
"has_empty_prefix": "前綴",
@@ -122,5 +122,6 @@ export default {
REQUIRES: '需要',
TIMELESS_SMALL_PASSIVES: '範圍內小型天賦也會賦予 {0}',
TIMELESS_NOTABLE_PASSIVES: '範圍內核心天賦也會賦予 {0}',
GRANTS_SKILL: '賦予技能'
GRANTS_SKILL: '賦予技能: ',
RELOAD_SPEED: '重新裝填時間: '
}
+1
View File
@@ -51,6 +51,7 @@
"crit": "Kritische Trefferchance: {0}%",
"aps": "Angriffe pro Sekunde: {0}",
"spirit": "Geist: {0}",
"reload_time": "Nachladezeit: {0}",
"has_empty_modifier": "1 Leerer oder hergestellter Modifikator",
"has_empty_affix": "Beliebig",
"has_empty_prefix": "Präfix",
+2 -1
View File
@@ -122,6 +122,7 @@ export default {
REQUIRES: 'Erfordert',
TIMELESS_SMALL_PASSIVES: 'Kleine Passive Fertigkeiten im Radius gewähren auch {0}',
TIMELESS_NOTABLE_PASSIVES: 'Bedeutende Passive Fertigkeiten im Radius gewähren auch {0}',
GRANTS_SKILL: 'Gewährt Fertigkeit'
GRANTS_SKILL: 'Gewährt Fertigkeit: ',
RELOAD_SPEED: 'Nachladezeit: '
}
+1
View File
@@ -51,6 +51,7 @@
"crit": "Critical Hit Chance: {0}%",
"aps": "Attacks per Second: {0}",
"spirit": "Spirit: {0}",
"reload_time": "Reload Time: {0}",
"has_empty_modifier": "1 Empty or Crafted Modifier",
"has_empty_affix": "Any",
"has_empty_prefix": "Prefix",
+3 -1
View File
@@ -221,5 +221,7 @@ export default {
// ModStatJewelAddToNotable
TIMELESS_NOTABLE_PASSIVES: 'Notable Passive Skills in Radius also grant {0}',
// ItemDisplayGrantsSkill
GRANTS_SKILL: 'Grants Skill'
GRANTS_SKILL: 'Grants Skill: ',
// SkillPopupReloadTime
RELOAD_SPEED: 'Reload Time: '
}
+1
View File
@@ -51,6 +51,7 @@
"crit": "Probabilidad de golpe crítico: {0}%",
"aps": "Ataques por segundo: {0}",
"spirit": "Espíritu: {0}",
"reload_time": "Tiempo de recarga: {0}",
"has_empty_modifier": "1 modificador vacío o fabricado",
"has_empty_affix": "Cualquiera",
"has_empty_prefix": "Prefijo",
+2 -1
View File
@@ -121,5 +121,6 @@ export default {
REQUIRES: 'Requiere',
TIMELESS_SMALL_PASSIVES: 'Las habilidades pasivas pequeñas dentro del radio también otorgan {0}',
TIMELESS_NOTABLE_PASSIVES: 'Las habilidades pasivas notables dentro del radio también otorgan {0}',
GRANTS_SKILL: 'Otorga la habilidad'
GRANTS_SKILL: 'Otorga la habilidad: ',
RELOAD_SPEED: 'Tiempo de recarga: '
}
+1
View File
@@ -51,6 +51,7 @@
"crit": "クリティカルヒット率: {0}%",
"aps": "秒間アタック回数: {0}",
"spirit": "スピリット: {0}",
"reload_time": "再装填時間: {0}",
"has_empty_modifier": "1つの空のまたはクラフトされたモッド",
"has_empty_affix": "任意",
"has_empty_prefix": "プレフィックス",
+2 -1
View File
@@ -122,5 +122,6 @@ export default {
REQUIRES: '要求',
TIMELESS_SMALL_PASSIVES: '範囲内の通常パッシブスキルは{0}も付与する',
TIMELESS_NOTABLE_PASSIVES: '範囲内の特殊パッシブスキルは{0}も付与する',
GRANTS_SKILL: 'スキルを付与'
GRANTS_SKILL: 'スキルを付与: ',
RELOAD_SPEED: '再装填時間: '
}
+2 -1
View File
@@ -47,11 +47,12 @@
"elemental_dps": "원소 DPS: {0}",
"crit": "치명타 확률: {0}%",
"aps": "초당 공격 횟수: {0}",
"reload_time": "재장전 시간: {0}",
"has_empty_modifier": "비었거나 작업대 모드 1",
"has_empty_affix": "빈 속성 부여",
"has_empty_prefix": "빈 접두어",
"has_empty_suffix": "빈 접미어",
"spirit": "Spirit: {0}",
"spirit": "정신력: {0}",
"item_level": "아이템 레벨: {0}",
"stock": "홈: {0}",
"map_tier": "지도 등급: {0}",
+2 -1
View File
@@ -122,5 +122,6 @@ export default {
REQUIRES: '요구 사항',
TIMELESS_SMALL_PASSIVES: '반경 내 소형 패시브 스킬이 {0}도 부여',
TIMELESS_NOTABLE_PASSIVES: '반경 내 주요 패시브 스킬이 {0}도 부여',
GRANTS_SKILL: '스킬 부여'
GRANTS_SKILL: '스킬 부여: ',
RELOAD_SPEED: '재장전 시간: '
}
+1
View File
@@ -50,6 +50,7 @@
"crit": "Chance de acerto crítico: {0}%",
"aps": "Ataques por segundo: {0}",
"spirit": "Espírito: {0}",
"reload_time": "Tempo de Recarregamento: {0}",
"has_empty_modifier": "1 modificador vazio ou fabricado",
"has_empty_affix": "Qualquer",
"has_empty_prefix": "Prefixo",
+2 -1
View File
@@ -221,5 +221,6 @@ export default {
// ModStatJewelAddToNotable
TIMELESS_NOTABLE_PASSIVES: 'Habilidades Passivas Notáveis no Raio também concedem {0}',
// ItemDisplayGrantsSkill
GRANTS_SKILL: 'Concede Habilidade'
GRANTS_SKILL: 'Concede Habilidade: ',
RELOAD_SPEED: 'Tempo de Recarregamento: '
}
+1
View File
@@ -72,6 +72,7 @@
"has_empty_suffix": "Суффикс",
"item_level": "Ур. предмета: {0}",
"spirit": "Дух: {0}",
"reload_time": "Время перезарядки: {0}",
"stock": "Запас: {0}",
"map_tier": "Ур. карты: {0}",
"area_level": "Ур. области: {0}",
+2 -1
View File
@@ -156,5 +156,6 @@ export default {
REQUIRES: 'Требуется',
TIMELESS_SMALL_PASSIVES: 'Малые пассивные умения в радиусе также дают: {0}',
TIMELESS_NOTABLE_PASSIVES: 'Значимые пассивные умения в радиусе также дают: {0}',
GRANTS_SKILL: 'Дарует умение'
GRANTS_SKILL: 'Дарует умение: ',
RELOAD_SPEED: 'Время перезарядки: '
}
+1
View File
@@ -230,6 +230,7 @@ export interface TranslationDict {
TIMELESS_SMALL_PASSIVES: string;
TIMELESS_NOTABLE_PASSIVES: string;
GRANTS_SKILL: string;
RELOAD_SPEED: string;
}
export interface Filter {
+1
View File
@@ -45,6 +45,7 @@ export interface ParsedItem {
weaponCOLD?: number;
weaponLIGHTNING?: number;
weaponChaos?: number;
weaponReload?: number;
mapBlighted?: "Blighted" | "Blight-ravaged";
mapTier?: number;
gemLevel?: number;
+6
View File
@@ -800,6 +800,11 @@ function parseWeapon(section: string[], item: ParsedItem) {
isParsed = "SECTION_PARSED";
continue;
}
if (line.startsWith(_$.RELOAD_SPEED)) {
item.weaponReload = parseFloat(line.slice(_$.RELOAD_SPEED.length));
isParsed = "SECTION_PARSED";
continue;
}
}
if (isParsed === "SECTION_PARSED") {
@@ -815,6 +820,7 @@ function parseWeapon(section: string[], item: ParsedItem) {
item.weaponLIGHTNING = undefined;
item.weaponFIRE = undefined;
item.weaponCRIT = undefined;
item.weaponReload = undefined;
}
return isParsed;
+23 -6
View File
@@ -66,14 +66,15 @@ export function calcPropBounds(
total: number,
statRefs: { flat: string[]; incr: string[] },
item: ParsedItem,
inverted: boolean = false,
): { roll: StatRoll; sources: StatSource[] } {
const { incr, flat, sources } = calcPropBase(statRefs, item);
const base = calcFlat(total, incr.value) - flat.value;
const base = calcFlat(total, incr.value, 0, inverted) - flat.value;
return {
roll: {
value: calcIncreased(base + flat.value, incr.value),
min: calcIncreased(base + flat.min, incr.min),
max: calcIncreased(base + flat.max, incr.max),
value: calcIncreased(base + flat.value, incr.value, 0, inverted),
min: calcIncreased(base + flat.min, incr.min, 0, inverted),
max: calcIncreased(base + flat.max, incr.max, 0, inverted),
},
sources:
statRefs.incr.length && statRefs.flat.length
@@ -131,10 +132,26 @@ export function calcPropBase(
return { incr, flat, sources };
}
export function calcFlat(total: number, incrPct: number, morePct = 0) {
export function calcFlat(
total: number,
incrPct: number,
morePct: number = 0,
inverted: boolean = false,
): number {
if (inverted) {
return calcIncreased(total, incrPct, morePct);
}
return total / (1 + morePct / 100) / (1 + incrPct / 100);
}
export function calcIncreased(flat: number, incrPct: number, morePct = 0) {
export function calcIncreased(
flat: number,
incrPct: number,
morePct: number = 0,
inverted: boolean = false,
): number {
if (inverted) {
return calcFlat(flat, incrPct, morePct);
}
return flat * (1 + incrPct / 100) * (1 + morePct / 100);
}
@@ -526,7 +526,15 @@ export function calculatedStatToFilter(
goodness,
};
filterFillMinMax(filter.roll, calc.stat.better);
let usedBetter = calc.stat.better;
if (
stat.trade.ids.pseudo?.length === 1 &&
stat.trade.ids.pseudo[0] === "item.reload_time"
) {
usedBetter = StatBetter.NegativeRoll;
}
filterFillMinMax(filter.roll, usedBetter);
if (translation.negate) {
filterAdjustmentForNegate(filter.roll);
@@ -162,6 +162,7 @@ export const INTERNAL_TRADE_IDS = [
"item.has_elemental_fire_affix",
"item.has_elemental_cold_affix",
"item.has_elemental_lightning_affix",
"item.reload_time",
] as const;
export type InternalTradeId = (typeof INTERNAL_TRADE_IDS)[number];
@@ -357,6 +357,32 @@ function weaponProps(ctx: FiltersCreationContext) {
);
}
if (item.weaponReload) {
const reloadTime = calcPropBounds(
item.weaponReload,
{
incr: ["#% increased Attack Speed"],
flat: [],
},
item,
// Inverted since lower is better for reload time
true,
);
ctx.filters.push(
propToFilter(
{
ref: "Reload Time: #",
tradeId: "item.reload_time",
roll: reloadTime.roll,
sources: reloadTime.sources,
dp: true,
disabled: true,
},
ctx,
),
);
}
if (
item.weaponAS ||
item.weaponCRIT ||
@@ -170,6 +170,8 @@ interface TradeRequest {
rune_sockets?: FilterRange;
// Spirit
spirit?: FilterRange;
// reload time
reload_time?: FilterRange;
};
};
req_filters?: {
@@ -742,6 +744,18 @@ export function createTradeRequest(
typeof input.max === "number" ? input.max : undefined,
);
break;
case "item.reload_time":
propSet(
query.filters,
"equipment_filters.filters.reload_time.min",
typeof input.min === "number" ? input.min : undefined,
);
propSet(
query.filters,
"equipment_filters.filters.reload_time.max",
typeof input.max === "number" ? input.max : undefined,
);
break;
}
}