You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
autohero/backend/migrations/000012_gear_balance_overlay...

104 lines
5.1 KiB
SQL

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

-- Gear balance overlay for every row in public.gear (no per-name balance runs).
-- Anchors from the previous overlay: weapon families daggers/sword/axe bases 3/7/12; chest light/medium/heavy 2/4/10;
-- extended slots use canonical base per gear.form.* (catalog §0a; same idea as equipment_items MIN-per-form).
-- primary_stat = round(base_primary * L(ilvl) * M(rarity) * tol(id)) with
-- L(ilvl) = 1.1^max(0, ilvl-1) (§6.4 / runtime_config ilvlPerLevelMultiplier)
-- M(rarity) from runtime_config §6.4.2
-- tol(id) in [0.92, 1.15] — deterministic spread (+15% / 8% band) via mod(id, 24).
-- main_hand: class-uniform speed/crit (000010).
WITH canon AS (
SELECT
g.id,
COALESCE(
CASE
WHEN g.slot = 'main_hand' AND g.subtype = 'daggers' THEN 3
WHEN g.slot = 'main_hand' AND g.subtype = 'sword' THEN 7
WHEN g.slot = 'main_hand' AND g.subtype = 'axe' THEN 12
WHEN g.slot = 'chest' AND g.subtype = 'light' THEN 2
WHEN g.slot = 'chest' AND g.subtype = 'medium' THEN 4
WHEN g.slot = 'chest' AND g.subtype = 'heavy' THEN 10
WHEN g.form_id = 'gear.form.chest.plate' THEN 10
WHEN g.form_id = 'gear.form.chest.mail' THEN 4
WHEN g.form_id = 'gear.form.chest.leather' THEN 2
WHEN g.form_id = 'gear.form.chest.robe' THEN 2
WHEN g.form_id = 'gear.form.chest.brigandine' THEN 4
WHEN g.form_id = 'gear.form.head.cap' THEN 2
WHEN g.form_id = 'gear.form.head.crown' THEN 3
WHEN g.form_id = 'gear.form.head.helmet' THEN 4
WHEN g.form_id = 'gear.form.head.hood' THEN 2
WHEN g.form_id = 'gear.form.head.hat' THEN 2
WHEN g.form_id = 'gear.form.head.circlet' THEN 3
WHEN g.form_id = 'gear.form.head.mask' THEN 2
WHEN g.form_id = 'gear.form.head.coif' THEN 3
WHEN g.form_id = 'gear.form.neck.amulet' THEN 4
WHEN g.form_id = 'gear.form.neck.necklace' THEN 3
WHEN g.form_id = 'gear.form.neck.pendant' THEN 2
WHEN g.form_id = 'gear.form.neck.medallion' THEN 3
WHEN g.form_id = 'gear.form.neck.talisman' THEN 3
WHEN g.form_id = 'gear.form.finger.ring' THEN 2
WHEN g.form_id = 'gear.form.finger.signet' THEN 3
WHEN g.form_id = 'gear.form.finger.band' THEN 2
WHEN g.form_id = 'gear.form.feet.boots' THEN 3
WHEN g.form_id = 'gear.form.feet.shoes' THEN 3
WHEN g.form_id = 'gear.form.feet.sabatons' THEN 4
WHEN g.form_id = 'gear.form.feet.greaves' THEN 5
WHEN g.form_id = 'gear.form.feet.sandals' THEN 1
WHEN g.form_id = 'gear.form.legs.greaves' THEN 5
WHEN g.form_id = 'gear.form.legs.chausses' THEN 4
WHEN g.form_id = 'gear.form.legs.pants' THEN 3
WHEN g.form_id = 'gear.form.legs.tassets' THEN 4
WHEN g.form_id = 'gear.form.cloak.cloak' THEN 2
WHEN g.form_id = 'gear.form.cloak.cape' THEN 2
WHEN g.form_id = 'gear.form.cloak.mantle' THEN 3
WHEN g.form_id = 'gear.form.wrist.bracers' THEN 3
WHEN g.form_id = 'gear.form.wrist.bracelet' THEN 2
WHEN g.form_id = 'gear.form.wrist.vambraces' THEN 4
END,
GREATEST(1, g.base_primary)
) AS canon_base
FROM public.gear AS g
)
UPDATE public.gear AS g
SET
base_primary = c.canon_base,
primary_stat = GREATEST(
1,
ROUND(
c.canon_base::numeric
* POWER(1.1, GREATEST(0, g.ilvl - 1))
* (CASE g.rarity::text
WHEN 'common' THEN 1.0
WHEN 'uncommon' THEN 1.0877573
WHEN 'rare' THEN 1.1832160
WHEN 'epic' THEN 1.2870518
WHEN 'legendary' THEN 1.40
ELSE 1.0
END)
* (0.92::numeric + (mod(g.id, 24)::numeric / 23.0) * 0.23)
)::integer
),
speed_modifier = CASE
WHEN g.slot = 'main_hand' AND g.subtype = 'daggers' THEN 1.3
WHEN g.slot = 'main_hand' AND g.subtype = 'sword' THEN 1.0
WHEN g.slot = 'main_hand' AND g.subtype = 'axe' THEN 0.7
ELSE g.speed_modifier
END,
crit_chance = CASE
WHEN g.slot = 'main_hand' AND g.subtype = 'daggers' THEN 0.05
WHEN g.slot = 'main_hand' AND g.subtype = 'sword' THEN 0.03
WHEN g.slot = 'main_hand' AND g.subtype = 'axe' THEN 0.02
ELSE g.crit_chance
END
FROM canon AS c
WHERE g.id = c.id;
-- Heavy chest armor: strong attack-cadence penalty (chest multiplies EffectiveSpeedAt after weapon).
-- Spec heavy ≈ 30% speed (0.7); here 0.55 for a clearly heavier feel. Extra agility on the piece
-- further lowers effective attack speed via agility_coef (world MoveSpeed is still buff/debuff-only).
UPDATE public.gear
SET
speed_modifier = 0.55,
agility_bonus = agility_bonus - 3
WHERE slot = 'chest' AND subtype = 'heavy';