#!/usr/bin/env python3 """SAMPLE / PREVIEW ONLY — does NOT write to any SQL file. Shows a proposed Fire Giant (npc 344) reward rework: - FREEZE tier (exclusives) weights untouched -> rates stay identical - boost a mix of rune / skilling / consumable drops to target 1/N - carve the added weight out of the dead 'nothing'/'60 coins' pool so the NPC total weight stays constant -> every frozen exclusive keeps its exact rate """ import re txt = open('pk_itemdef.sql').read() NAME = {} for m in re.finditer(r"\((\d+),\s*-?\d+,\s*-?\d+,\s*'((?:[^'\\]|\\.)*)',.*?,\s*(\d+)\),?\n", txt): NAME[int(m.group(1))] = (m.group(2), int(m.group(3))) rows = [] for line in open('pk_npcdrops_live.sql'): m = re.match(r"\((\d+),\s*'(-?\d+)',\s*(-?\d+),\s*(\d+),\s*(\d+)\),?\s*$", line.strip()) if m and int(m.group(1)) == 344: rows.append([int(m.group(3)), m.group(2), int(m.group(4)), int(m.group(5))]) # id, amt, weight, idx T = sum(r[2] for r in rows if r[2] > 0) cur_w = {(r[0], r[1]): r[2] for r in rows} FREEZE = {1092: 'Rune Spear', 1276: 'Half Dragon Sq (R)', 1277: 'Half Dragon Sq (L)', 795: 'Dragon med helm', 593: 'Dragon sword', 594: 'Dragon axe', 523: 'Dragonstone'} def w_for(N): return round(T / N) # (item_id, amount, target_1/N, category) -- amount as string to match existing rows PLAN = [ # --- RUNE ITEMS (boost existing; rune scimitar 398 left as-is at 1/121) --- (81, '1', 650, 'rune'), # rune 2h sword (was 1/5161) (404, '1', 750, 'rune'), # rune kite (was 1/15482) (93, '1', 700, 'rune'), # rune battle axe(was 1/7741) (403, '1', 700, 'rune'), # rune square (was 1/7741) (405, '1', 900, 'rune'), # rune axe (was 1/5161) (75, '1', 750, 'rune'), # rune long sword(NEW) # --- SKILLING ITEMS --- (408, '1', 900, 'skill'), # runite bar (was 1/7741) (155, '100', 60, 'skill'), # coal x100 (NEW) (154, '1', 250, 'skill'), # adamantite ore (NEW) # --- CONSUMABLES --- (38, '30', 120, 'consum'), # death rune x30 (was 1/7741) (40, '45', 150, 'consum'), # nature rune x45(was 1/7741) (545, '2', 90, 'consum'), # raw shark x2 (NEW) ] print(f"FIRE GIANT (344) total_weight = {T:,} (held CONSTANT)\n") print("FROZEN exclusives (weights untouched -> rate identical before & after):") for iid, lbl in FREEZE.items(): for r in rows: if r[0] == iid: print(f" {lbl:20} weight {r[2]:>12,} -> 1/{round(T/r[2])}") print() print(f"{'item':26} {'amt':>5} {'cat':>7} {'cur rate':>10} {'NEW rate':>9} {'cur w':>13} {'NEW w':>13} {'delta':>13}") total_delta = 0 for iid, amt, N, cat in PLAN: nm = NAME.get(iid, ('?', 0))[0] old = cur_w.get((iid, amt), 0) new = w_for(N) delta = new - old total_delta += delta cur_rate = f"1/{round(T/old)}" if old > 0 else "—(new)" print(f"{nm[:26]:26} {amt:>5} {cat:>7} {cur_rate:>10} {'1/'+str(N):>9} {old:>13,} {new:>13,} {delta:>+13,}") print(f"\nTotal NEW weight to add = {total_delta:,}") # carve from the dead pool: 60 coins (id 10 amt 60) and 'nothing' (-1) coins60 = cur_w.get((10, '60'), 0) nothing = cur_w.get((-1, '-1'), 0) print(f"Dead pool today: 60 coins = {coins60:,} (1/{round(T/coins60)}, {coins60/T*100:.1f}% of kills)") print(f" nothing = {nothing:,} (1/{round(T/nothing)}, {nothing/T*100:.1f}% of kills)") new_coins60 = coins60 - total_delta print(f"\nCarve all {total_delta:,} from 60-coins drop:") print(f" 60 coins: {coins60:,} -> {new_coins60:,} (1/{round(T/coins60)} -> 1/{round(T/new_coins60)}, {new_coins60/T*100:.1f}% of kills)") print(f" => total stays {T:,}; every frozen exclusive rate UNCHANGED")