7 Commits

11 changed files with 351 additions and 130 deletions

View File

@@ -1,21 +1,36 @@
import csv import csv
import json import json
import os import argparse
import sys from pathlib import Path
path = sys.argv[1] if len(sys.argv) >= 2 else "." parser = argparse.ArgumentParser(
description="Process unique and set items from game data"
)
parser.add_argument(
"DATA_DIR", help="Path to d2 data dir containing local/ and global/"
)
parser.add_argument("OUTPUT_DIR", help="Path to destination directory")
args = parser.parse_args()
excelpath = Path(args.DATA_DIR) / "global/excel"
outputpath = Path(args.OUTPUT_DIR)
namespath = Path(args.DATA_DIR) / "local/lng/strings/item-names.json"
with namespath.open(encoding="utf-8-sig") as f:
names = json.load(f)
names = {name["Key"]: name["enUS"] for name in names}
category = "Base" category = "Base"
setitems = {} setitems = {}
with open(os.path.join(path, "setitems.txt")) as f: with (excelpath / "setitems.txt").open() as f:
dr = csv.DictReader(f, delimiter="\t") dr = csv.DictReader(f, delimiter="\t")
for row in dr: for row in dr:
if row["index"] == "Expansion": if row["index"] == "Expansion":
category = row["index"] category = row["index"]
continue continue
setitems[row["*ID"]] = { setitems[row["*ID"]] = {
"name": row["index"], "name": names[row["index"]],
"set": row["set"], "set": names[row["set"]],
"itembase": row["item"], "itembase": row["item"],
"req_lvl": int(row["lvl req"]), "req_lvl": int(row["lvl req"]),
"ilvl": int(row["lvl"]), "ilvl": int(row["lvl"]),
@@ -25,7 +40,7 @@ with open(os.path.join(path, "setitems.txt")) as f:
category = "Base" category = "Base"
uniqueitems = {} uniqueitems = {}
with open(os.path.join(path, "uniqueitems.txt")) as f: with (excelpath / "uniqueitems.txt").open() as f:
dr = csv.DictReader(f, delimiter="\t") dr = csv.DictReader(f, delimiter="\t")
for row in dr: for row in dr:
if row["index"] in [ if row["index"] in [
@@ -42,7 +57,7 @@ with open(os.path.join(path, "uniqueitems.txt")) as f:
if len(row["lvl req"]) == 0: if len(row["lvl req"]) == 0:
continue # deleted uniques continue # deleted uniques
uniqueitems[row["*ID"]] = { uniqueitems[row["*ID"]] = {
"name": row["index"], "name": names[row["index"]],
"itembase": row["code"], "itembase": row["code"],
"req_lvl": int(row["lvl req"]), "req_lvl": int(row["lvl req"]),
"ilvl": int(row["lvl"]), "ilvl": int(row["lvl"]),
@@ -50,10 +65,10 @@ with open(os.path.join(path, "uniqueitems.txt")) as f:
"category": category, "category": category,
} }
with open("uniques.json", "w", newline="\n") as f: with (outputpath / "uniques.json").open("w", newline="\n") as f:
json.dump(uniqueitems, f, indent=4) json.dump(uniqueitems, f, indent=4)
f.write("\n") f.write("\n")
with open("sets.json", "w", newline="\n") as f: with (outputpath / "sets.json").open("w", newline="\n") as f:
json.dump(setitems, f, indent=4) json.dump(setitems, f, indent=4)
f.write("\n") f.write("\n")

View File

@@ -3,6 +3,7 @@ from flask import Flask, redirect, abort, render_template, request
from pathlib import Path from pathlib import Path
import shutil import shutil
from datetime import datetime from datetime import datetime
import json
import psutil import psutil
from d2warehouse.item import Item, Quality, lookup_basetype from d2warehouse.item import Item, Quality, lookup_basetype
@@ -14,6 +15,7 @@ import re
from d2warehouse.stash import StashFullError from d2warehouse.stash import StashFullError
STASH_FILES = { STASH_FILES = {
"softcore": "SharedStashSoftCoreV2.d2i", "softcore": "SharedStashSoftCoreV2.d2i",
"hardcore": "SharedStashHardCoreV2.d2i", "hardcore": "SharedStashHardCoreV2.d2i",
@@ -92,22 +94,26 @@ def storage_count(item: Item, stash: str) -> int | str:
db = get_stash_db(stash) db = get_stash_db(stash)
if item.is_simple: if item.is_simple:
return db.execute( return db.execute(
"SELECT COUNT(id) FROM item WHERE code = ? AND deleted IS NULL", "SELECT COUNT(id) FROM item "
"WHERE code = ? AND deleted IS NULL AND socketed_into IS NULL",
(item.code,), (item.code,),
).fetchone()[0] ).fetchone()[0]
elif item.quality == Quality.UNIQUE: elif item.quality == Quality.UNIQUE:
return db.execute( return db.execute(
"SELECT COUNT(id) FROM item INNER JOIN item_extra ON id = item_id WHERE code = ? AND unique_id = ? AND deleted IS NULL", "SELECT COUNT(id) FROM item INNER JOIN item_extra ON id = item_id "
"WHERE code = ? AND unique_id = ? AND deleted IS NULL AND socketed_into IS NULL",
(item.code, item.unique_id), (item.code, item.unique_id),
).fetchone()[0] ).fetchone()[0]
elif item.quality == Quality.SET: elif item.quality == Quality.SET:
return db.execute( return db.execute(
"SELECT COUNT(id) FROM item INNER JOIN item_extra ON id = item_id WHERE code = ? AND set_id = ? AND deleted IS NULL", "SELECT COUNT(id) FROM item INNER JOIN item_extra ON id = item_id "
"WHERE code = ? AND set_id = ? AND deleted IS NULL AND socketed_into IS NULL",
(item.code, item.set_id), (item.code, item.set_id),
).fetchone()[0] ).fetchone()[0]
elif item.is_runeword: elif item.is_runeword:
return db.execute( return db.execute(
"SELECT COUNT(id) FROM item INNER JOIN item_extra ON id = item_id WHERE code = ? AND runeword_id = ? AND deleted IS NULL", "SELECT COUNT(id) FROM item INNER JOIN item_extra ON id = item_id "
"WHERE code = ? AND runeword_id = ? AND deleted IS NULL and socketed_into IS NULL",
(item.code, item.runeword_id), (item.code, item.runeword_id),
).fetchone()[0] ).fetchone()[0]
else: else:
@@ -217,7 +223,9 @@ def list_storage(stash_name: str):
db = get_stash_db(stash_name) db = get_stash_db(stash_name)
items = {} items = {}
rows = db.execute("SELECT id FROM item WHERE deleted IS NULL").fetchall() rows = db.execute(
"SELECT id FROM item WHERE deleted IS NULL and socketed_into IS NULL"
).fetchall()
for row in rows: for row in rows:
items[row["id"]] = Item.load_from_db(row["id"], db=db) items[row["id"]] = Item.load_from_db(row["id"], db=db)
@@ -238,16 +246,21 @@ def list_storage_category(stash_name: str, category: str):
if category == "uniques": if category == "uniques":
q = db.execute( q = db.execute(
"SELECT id FROM item INNER JOIN item_extra ON id = item_id WHERE deleted IS NULL AND quality = ?", "SELECT id FROM item INNER JOIN item_extra ON id = item_id "
"WHERE deleted IS NULL AND socketed_into IS NULL AND quality = ?",
(int(Quality.UNIQUE),), (int(Quality.UNIQUE),),
) )
elif category == "sets": elif category == "sets":
q = db.execute( q = db.execute(
"SELECT id FROM item INNER JOIN item_extra ON id = item_id WHERE deleted IS NULL AND quality = ?", "SELECT id FROM item INNER JOIN item_extra ON id = item_id "
"WHERE deleted IS NULL AND socketed_into IS NULL AND quality = ?",
(int(Quality.SET),), (int(Quality.SET),),
) )
elif category == "misc": elif category == "misc":
q = db.execute("SELECT id FROM item WHERE deleted IS NULL AND is_simple = TRUE") q = db.execute(
"SELECT id FROM item "
"WHERE deleted IS NULL AND socketed_into IS NULL AND is_simple = TRUE"
)
else: else:
return "Unexpected category", 400 return "Unexpected category", 400
@@ -260,6 +273,7 @@ def list_storage_category(stash_name: str, category: str):
"list_storage.html", "list_storage.html",
stash_name=stash_name, stash_name=stash_name,
storage_items=items, storage_items=items,
category=category,
storage_count=lambda x: storage_count(x, stash_name), storage_count=lambda x: storage_count(x, stash_name),
) )
@@ -325,14 +339,16 @@ def storage_currency_counts(item_codes: list[str], stash_name: str) -> dict:
for code in item_codes: for code in item_codes:
currencies[code] = { currencies[code] = {
"count": db.execute( "count": db.execute(
"SELECT COUNT(id) FROM item WHERE code = ?", (code,) "SELECT COUNT(id) FROM item "
"WHERE code = ? AND deleted IS NULL AND socketed_into IS NULL",
(code,),
).fetchone()[0], ).fetchone()[0],
"name": lookup_basetype(code)["name"], "name": lookup_basetype(code)["name"],
} }
return currencies return currencies
@app.route("/storage/<stash_name>/currency") @app.route("/currency/<stash_name>")
def storage_currency(stash_name: str): def storage_currency(stash_name: str):
if stash_name not in DB_FILES: if stash_name not in DB_FILES:
abort(404) abort(404)
@@ -343,3 +359,86 @@ def storage_currency(stash_name: str):
return render_template( return render_template(
"currency.html", runes=runes, gems=gems, keys=keys, essences=essences "currency.html", runes=runes, gems=gems, keys=keys, essences=essences
) )
def load_uniques_data():
"""Return a sorted dictionary of unique item ids indexed by names."""
uniques_path = Path(__file__).resolve().parent.parent / "data/uniques.json"
with uniques_path.open() as f:
data = json.load(f)
name_to_id = {v["name"]: int(k) for k, v in data.items()}
del name_to_id["Amulet of the Viper"]
del name_to_id["Staff of Kings"]
del name_to_id["Horadric Staff"]
del name_to_id["Khalim's Flail"]
del name_to_id["Khalim's Will"]
del name_to_id["Hell Forge Hammer"]
return {name: name_to_id[name] for name in sorted(name_to_id.keys())}
def load_sets_data():
"""Return a sorted dictionary of unique item ids indexed by names."""
uniques_path = Path(__file__).resolve().parent.parent / "data/sets.json"
with uniques_path.open() as f:
data = json.load(f)
name_to_id = {v["name"]: int(k) for k, v in data.items()}
return {name: name_to_id[name] for name in sorted(name_to_id.keys())}
all_uniques = load_uniques_data()
all_sets = load_sets_data()
def get_found_uniques(db):
rows = db.execute(
"SELECT DISTINCT unique_id "
"FROM item INNER JOIN item_extra ON id = item_id "
"WHERE quality = 7 AND deleted IS NULL AND socketed_into IS NULL",
).fetchall()
return {row["unique_id"]: True for row in rows}
def get_found_sets(db):
rows = db.execute(
"SELECT DISTINCT set_id "
"FROM item INNER JOIN item_extra ON id = item_id "
"WHERE quality = 5 AND deleted IS NULL AND socketed_into IS NULL",
).fetchall()
return {row["set_id"]: True for row in rows}
@app.route("/grail/<stash_name>")
def storage_grail(stash_name: str):
if stash_name not in DB_FILES:
abort(404)
db = get_stash_db(stash_name)
# Unique progress
found = get_found_uniques(db)
items = {name: found.get(id, False) for name, id in all_uniques.items()}
count = len(found)
total = len(all_uniques)
uniques = {
"list": items,
"count": count,
"total": total,
"progress": count / total * 100,
}
# Set progress
found = get_found_sets(db)
items = {name: found.get(id, False) for name, id in all_sets.items()}
count = len(found)
total = len(all_sets)
sets = {
"list": items,
"count": count,
"total": total,
"progress": count / total * 100,
}
return render_template(
"grail.html",
uniques=uniques,
sets=sets,
)

View File

@@ -11,3 +11,10 @@ function toggleSelectAll(tabIndex) {
cb.checked = !allSelected; cb.checked = !allSelected;
}); });
} }
function toggleCollected() {
const collected = document.querySelectorAll('.collected');
collected.forEach(item => {
item.classList.toggle('hidden');
});
}

View File

@@ -5,6 +5,25 @@ body {
color: rgb(240, 240, 240); color: rgb(240, 240, 240);
} }
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
background-color: #444;
}
nav a {
display: block;
padding: 1rem 1.5rem;
text-decoration: none;
color: rgb(240, 240, 240);
}
nav a:hover {
background-color: #333;
}
.stash-tab { .stash-tab {
display: grid; display: grid;
grid-template-columns: repeat(5, 1fr); grid-template-columns: repeat(5, 1fr);
@@ -104,3 +123,28 @@ input[type="checkbox"]:checked + label {
background-color: #444; background-color: #444;
color: rgb(240, 240, 240); color: rgb(240, 240, 240);
} }
ul.grail {
list-style: none;
display: flex;
flex-wrap: wrap;
gap: 0.5rem 2rem;
}
ul.grail li {
flex: 0 0 15rem;
padding: 0.5rem;
width: 15rem;
display: flex;
}
.hidden {
display: none !important;
}
.collected {
background-color: #343;
}
.uncollected {
background-color: #433;
}

View File

@@ -2,10 +2,19 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Shared Stash</title> <title>Currency</title>
<link rel="stylesheet" href="/static/style.css" /> <link rel="stylesheet" href="/static/style.css" />
<head> <head>
<body> <body>
{% include "menu.html" %}
<nav>
<ul>
<li><a href="/storage/{{stash_name or 'softcore'}}">All</a></li>
<li><a href="/storage/{{stash_name or 'softcore'}}/uniques">Uniques</a></li>
<li><a href="/storage/{{stash_name or 'softcore'}}/sets">Sets</a></li>
<li><a href="/storage/{{stash_name or 'softcore'}}/currency">Currency</a></li>
</ul>
</nav>
<div class="currencies"> <div class="currencies">
<div> <div>
<table> <table>

View File

@@ -0,0 +1,28 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Grail</title>
<link rel="stylesheet" href="/static/style.css" />
<script src="/static/helpers.js"></script>
<head>
<body>
{% include "menu.html" %}
<button type="button" onclick="toggleCollected()">Toggle collected</button>
<h1>Unique Items</h1>
Progress: {{uniques.count}}/{{uniques.total}} ({{uniques.progress | round(1)}}%)
<ul class="grail">
{% for name,collected in uniques.list.items() %}
<li class="{{ 'collected' if collected else 'uncollected' }}">{{name}}</li>
{% endfor %}
</ul>
<h1>Set Items</h1>
Progress: {{sets.count}}/{{sets.total}} ({{sets.progress | round(1)}}%)
<ul class="grail">
{% for name,collected in sets.list.items() %}
<li class="{{ 'collected' if collected else 'uncollected' }}">{{name}}</li>
{% endfor %}
</ul>
</body>
</html>

View File

@@ -7,6 +7,7 @@
<script src="/static/helpers.js"></script> <script src="/static/helpers.js"></script>
<head> <head>
<body> <body>
{% include "menu.html" %}
<form action="/stash/{{stash_name}}/store" method="POST"> <form action="/stash/{{stash_name}}/store" method="POST">
{% for tab in stash.tabs %} {% for tab in stash.tabs %}
{% set tabloop = loop %} {% set tabloop = loop %}

View File

@@ -2,13 +2,23 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Storage</title> <title>Storage - {{category or 'all'}}</title>
<link rel="stylesheet" href="/static/style.css" /> <link rel="stylesheet" href="/static/style.css" />
<head> <head>
<body> <body>
{% include "menu.html" %}
<nav>
<ul>
<li><a href="/storage/{{stash_name or 'softcore'}}">All</a></li>
<li><a href="/storage/{{stash_name or 'softcore'}}/uniques">Uniques</a></li>
<li><a href="/storage/{{stash_name or 'softcore'}}/sets">Sets</a></li>
<li><a href="/storage/{{stash_name or 'softcore'}}/misc">Misc</a></li>
</ul>
</nav>
<form action="/storage/{{stash_name}}/take" method="POST"> <form action="/storage/{{stash_name}}/take" method="POST">
<div> <div>
<!-- TODO: Include item.html --> <!-- TODO: Include item.html -->
There are {{ storage_items | length }} items.
{% for db_id, item in storage_items.items() %} {% for db_id, item in storage_items.items() %}
<div class="storage-item-entry"> <div class="storage-item-entry">
<input type="checkbox" name="item_{{db_id}}" id="item_{{db_id}}" value="take" /> <input type="checkbox" name="item_{{db_id}}" id="item_{{db_id}}" value="take" />

View File

@@ -0,0 +1,8 @@
<nav>
<ul>
<li><a href="/stash/{{stash_name or 'softcore'}}">Stash</a></li>
<li><a href="/storage/{{stash_name or 'softcore'}}">Storage</a></li>
<li><a href="/grail/{{stash_name or 'softcore'}}">Grail</a></li>
<li><a href="/currency/{{stash_name or 'softcore'}}">Currency</a></li>
</ul>
</nav>

View File

@@ -397,7 +397,7 @@
}, },
"44": { "44": {
"name": "Berserker's Headgear", "name": "Berserker's Headgear",
"set": "Berserker's Garb", "set": "Berserker's Arsenal",
"itembase": "hlm", "itembase": "hlm",
"req_lvl": 3, "req_lvl": 3,
"ilvl": 5, "ilvl": 5,
@@ -406,7 +406,7 @@
}, },
"45": { "45": {
"name": "Berserker's Hauberk", "name": "Berserker's Hauberk",
"set": "Berserker's Garb", "set": "Berserker's Arsenal",
"itembase": "spl", "itembase": "spl",
"req_lvl": 3, "req_lvl": 3,
"ilvl": 5, "ilvl": 5,
@@ -415,7 +415,7 @@
}, },
"46": { "46": {
"name": "Berserker's Hatchet", "name": "Berserker's Hatchet",
"set": "Berserker's Garb", "set": "Berserker's Arsenal",
"itembase": "2ax", "itembase": "2ax",
"req_lvl": 3, "req_lvl": 3,
"ilvl": 5, "ilvl": 5,
@@ -451,7 +451,7 @@
}, },
"50": { "50": {
"name": "Angelic Sickle", "name": "Angelic Sickle",
"set": "Angelical Raiment", "set": "Angelic Raiment",
"itembase": "sbr", "itembase": "sbr",
"req_lvl": 12, "req_lvl": 12,
"ilvl": 17, "ilvl": 17,
@@ -460,7 +460,7 @@
}, },
"51": { "51": {
"name": "Angelic Mantle", "name": "Angelic Mantle",
"set": "Angelical Raiment", "set": "Angelic Raiment",
"itembase": "rng", "itembase": "rng",
"req_lvl": 12, "req_lvl": 12,
"ilvl": 17, "ilvl": 17,
@@ -469,7 +469,7 @@
}, },
"52": { "52": {
"name": "Angelic Halo", "name": "Angelic Halo",
"set": "Angelical Raiment", "set": "Angelic Raiment",
"itembase": "rin", "itembase": "rin",
"req_lvl": 12, "req_lvl": 12,
"ilvl": 17, "ilvl": 17,
@@ -478,7 +478,7 @@
}, },
"53": { "53": {
"name": "Angelic Wings", "name": "Angelic Wings",
"set": "Angelical Raiment", "set": "Angelic Raiment",
"itembase": "amu", "itembase": "amu",
"req_lvl": 12, "req_lvl": 12,
"ilvl": 17, "ilvl": 17,
@@ -612,7 +612,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"68": { "68": {
"name": "Aldur's Gauntlet", "name": "Aldur's Rhythm",
"set": "Aldur's Watchtower", "set": "Aldur's Watchtower",
"itembase": "9mt", "itembase": "9mt",
"req_lvl": 42, "req_lvl": 42,
@@ -684,7 +684,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"76": { "76": {
"name": "Tal Rasha's Fire-Spun Cloth", "name": "Tal Rasha's Fine-Spun Cloth",
"set": "Tal Rasha's Wrappings", "set": "Tal Rasha's Wrappings",
"itembase": "zmb", "itembase": "zmb",
"req_lvl": 53, "req_lvl": 53,
@@ -711,7 +711,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"79": { "79": {
"name": "Tal Rasha's Howling Wind", "name": "Tal Rasha's Guardianship",
"set": "Tal Rasha's Wrappings", "set": "Tal Rasha's Wrappings",
"itembase": "uth", "itembase": "uth",
"req_lvl": 71, "req_lvl": 71,
@@ -747,7 +747,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"83": { "83": {
"name": "Griswolds's Redemption", "name": "Griswold's Redemption",
"set": "Griswold's Legacy", "set": "Griswold's Legacy",
"itembase": "7ws", "itembase": "7ws",
"req_lvl": 53, "req_lvl": 53,
@@ -882,7 +882,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"98": { "98": {
"name": "Spiritual Custodian", "name": "Dark Adherent",
"set": "The Disciple", "set": "The Disciple",
"itembase": "uui", "itembase": "uui",
"req_lvl": 43, "req_lvl": 43,
@@ -909,7 +909,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"101": { "101": {
"name": "Heaven's Taebaek", "name": "Taebaek's Glory",
"set": "Heaven's Brethren", "set": "Heaven's Brethren",
"itembase": "uts", "itembase": "uts",
"req_lvl": 81, "req_lvl": 81,
@@ -918,7 +918,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"102": { "102": {
"name": "Haemosu's Adament", "name": "Haemosu's Adamant",
"set": "Heaven's Brethren", "set": "Heaven's Brethren",
"itembase": "xrs", "itembase": "xrs",
"req_lvl": 44, "req_lvl": 44,
@@ -963,7 +963,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"107": { "107": {
"name": "Wihtstan's Guard", "name": "Whitstan's Guard",
"set": "Orphan's Call", "set": "Orphan's Call",
"itembase": "xml", "itembase": "xml",
"req_lvl": 29, "req_lvl": 29,
@@ -990,7 +990,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"110": { "110": {
"name": "Hwanin's Seal", "name": "Hwanin's Blessing",
"set": "Hwanin's Majesty", "set": "Hwanin's Majesty",
"itembase": "mbl", "itembase": "mbl",
"req_lvl": 35, "req_lvl": 35,
@@ -1071,7 +1071,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"119": { "119": {
"name": "Cow King's Hoofs", "name": "Cow King's Hooves",
"set": "Cow King's Leathers", "set": "Cow King's Leathers",
"itembase": "vbt", "itembase": "vbt",
"req_lvl": 13, "req_lvl": 13,
@@ -1081,7 +1081,7 @@
}, },
"120": { "120": {
"name": "Naj's Puzzler", "name": "Naj's Puzzler",
"set": "Naj's Ancient Set", "set": "Naj's Ancient Vestige",
"itembase": "6cs", "itembase": "6cs",
"req_lvl": 78, "req_lvl": 78,
"ilvl": 43, "ilvl": 43,
@@ -1090,7 +1090,7 @@
}, },
"121": { "121": {
"name": "Naj's Light Plate", "name": "Naj's Light Plate",
"set": "Naj's Ancient Set", "set": "Naj's Ancient Vestige",
"itembase": "ult", "itembase": "ult",
"req_lvl": 71, "req_lvl": 71,
"ilvl": 43, "ilvl": 43,
@@ -1099,7 +1099,7 @@
}, },
"122": { "122": {
"name": "Naj's Circlet", "name": "Naj's Circlet",
"set": "Naj's Ancient Set", "set": "Naj's Ancient Vestige",
"itembase": "ci0", "itembase": "ci0",
"req_lvl": 28, "req_lvl": 28,
"ilvl": 43, "ilvl": 43,
@@ -1107,8 +1107,8 @@
"category": "Expansion" "category": "Expansion"
}, },
"123": { "123": {
"name": "McAuley's Paragon", "name": "Sander's Paragon",
"set": "McAuley's Folly", "set": "Sander's Folly",
"itembase": "cap", "itembase": "cap",
"req_lvl": 25, "req_lvl": 25,
"ilvl": 20, "ilvl": 20,
@@ -1116,8 +1116,8 @@
"category": "Expansion" "category": "Expansion"
}, },
"124": { "124": {
"name": "McAuley's Riprap", "name": "Sander's Riprap",
"set": "McAuley's Folly", "set": "Sander's Folly",
"itembase": "vbt", "itembase": "vbt",
"req_lvl": 20, "req_lvl": 20,
"ilvl": 20, "ilvl": 20,
@@ -1125,8 +1125,8 @@
"category": "Expansion" "category": "Expansion"
}, },
"125": { "125": {
"name": "McAuley's Taboo", "name": "Sander's Taboo",
"set": "McAuley's Folly", "set": "Sander's Folly",
"itembase": "vgl", "itembase": "vgl",
"req_lvl": 28, "req_lvl": 28,
"ilvl": 20, "ilvl": 20,
@@ -1134,8 +1134,8 @@
"category": "Expansion" "category": "Expansion"
}, },
"126": { "126": {
"name": "McAuley's Superstition", "name": "Sander's Superstition",
"set": "McAuley's Folly", "set": "Sander's Folly",
"itembase": "bwn", "itembase": "bwn",
"req_lvl": 25, "req_lvl": 25,
"ilvl": 20, "ilvl": 20,

View File

@@ -24,7 +24,7 @@
"category": "Base" "category": "Base"
}, },
"3": { "3": {
"name": "Mindrend", "name": "Skull Splitter",
"itembase": "mpi", "itembase": "mpi",
"req_lvl": 21, "req_lvl": 21,
"ilvl": 28, "ilvl": 28,
@@ -40,7 +40,7 @@
"category": "Base" "category": "Base"
}, },
"5": { "5": {
"name": "Fechmars Axe", "name": "Axe of Fechmar",
"itembase": "lax", "itembase": "lax",
"req_lvl": 8, "req_lvl": 8,
"ilvl": 11, "ilvl": 11,
@@ -56,7 +56,7 @@
"category": "Base" "category": "Base"
}, },
"7": { "7": {
"name": "The Chieftan", "name": "The Chieftain",
"itembase": "btx", "itembase": "btx",
"req_lvl": 19, "req_lvl": 19,
"ilvl": 26, "ilvl": 26,
@@ -72,7 +72,7 @@
"category": "Base" "category": "Base"
}, },
"9": { "9": {
"name": "The Humongous", "name": "Humongous",
"itembase": "gix", "itembase": "gix",
"req_lvl": 29, "req_lvl": 29,
"ilvl": 39, "ilvl": 39,
@@ -80,7 +80,7 @@
"category": "Base" "category": "Base"
}, },
"10": { "10": {
"name": "Iros Torch", "name": "Torch of Iro",
"itembase": "wnd", "itembase": "wnd",
"req_lvl": 5, "req_lvl": 5,
"ilvl": 7, "ilvl": 7,
@@ -88,7 +88,7 @@
"category": "Base" "category": "Base"
}, },
"11": { "11": {
"name": "Maelstromwrath", "name": "Maelstrom",
"itembase": "ywn", "itembase": "ywn",
"req_lvl": 14, "req_lvl": 14,
"ilvl": 19, "ilvl": 19,
@@ -104,7 +104,7 @@
"category": "Base" "category": "Base"
}, },
"13": { "13": {
"name": "Umes Lament", "name": "Ume's Lament",
"itembase": "gwn", "itembase": "gwn",
"req_lvl": 28, "req_lvl": 28,
"ilvl": 38, "ilvl": 38,
@@ -168,7 +168,7 @@
"category": "Base" "category": "Base"
}, },
"21": { "21": {
"name": "The Generals Tan Do Li Ga", "name": "The General's Tan Do Li Ga",
"itembase": "fla", "itembase": "fla",
"req_lvl": 21, "req_lvl": 21,
"ilvl": 28, "ilvl": 28,
@@ -184,7 +184,7 @@
"category": "Base" "category": "Base"
}, },
"23": { "23": {
"name": "Bonesob", "name": "Bonesnap",
"itembase": "mau", "itembase": "mau",
"req_lvl": 24, "req_lvl": 24,
"ilvl": 32, "ilvl": 32,
@@ -200,7 +200,7 @@
"category": "Base" "category": "Base"
}, },
"25": { "25": {
"name": "Rixots Keen", "name": "Rixot's Keen",
"itembase": "ssd", "itembase": "ssd",
"req_lvl": 2, "req_lvl": 2,
"ilvl": 3, "ilvl": 3,
@@ -216,7 +216,7 @@
"category": "Base" "category": "Base"
}, },
"27": { "27": {
"name": "Krintizs Skewer", "name": "Skewer of Krintiz",
"itembase": "sbr", "itembase": "sbr",
"req_lvl": 10, "req_lvl": 10,
"ilvl": 14, "ilvl": 14,
@@ -240,7 +240,7 @@
"category": "Base" "category": "Base"
}, },
"30": { "30": {
"name": "Griswolds Edge", "name": "Griswold's Edge",
"itembase": "bsd", "itembase": "bsd",
"req_lvl": 17, "req_lvl": 17,
"ilvl": 23, "ilvl": 23,
@@ -256,7 +256,7 @@
"category": "Base" "category": "Base"
}, },
"32": { "32": {
"name": "Culwens Point", "name": "Culwen's Point",
"itembase": "wsd", "itembase": "wsd",
"req_lvl": 29, "req_lvl": 29,
"ilvl": 39, "ilvl": 39,
@@ -280,7 +280,7 @@
"category": "Base" "category": "Base"
}, },
"35": { "35": {
"name": "Kinemils Awl", "name": "Kinemil's Awl",
"itembase": "gis", "itembase": "gis",
"req_lvl": 23, "req_lvl": 23,
"ilvl": 31, "ilvl": 31,
@@ -336,7 +336,7 @@
"category": "Base" "category": "Base"
}, },
"42": { "42": {
"name": "Irices Shard", "name": "Spectral Shard",
"itembase": "bld", "itembase": "bld",
"req_lvl": 25, "req_lvl": 25,
"ilvl": 34, "ilvl": 34,
@@ -384,7 +384,7 @@
"category": "Base" "category": "Base"
}, },
"48": { "48": {
"name": "Dimoaks Hew", "name": "Dimoak's Hew",
"itembase": "bar", "itembase": "bar",
"req_lvl": 8, "req_lvl": 8,
"ilvl": 11, "ilvl": 11,
@@ -448,7 +448,7 @@
"category": "Base" "category": "Base"
}, },
"56": { "56": {
"name": "Lazarus Spire", "name": "Spire of Lazarus",
"itembase": "cst", "itembase": "cst",
"req_lvl": 18, "req_lvl": 18,
"ilvl": 24, "ilvl": 24,
@@ -488,7 +488,7 @@
"category": "Base" "category": "Base"
}, },
"61": { "61": {
"name": "Rimeraven", "name": "Raven Claw",
"itembase": "lbw", "itembase": "lbw",
"req_lvl": 15, "req_lvl": 15,
"ilvl": 20, "ilvl": 20,
@@ -496,7 +496,7 @@
"category": "Base" "category": "Base"
}, },
"62": { "62": {
"name": "Piercerib", "name": "Rogue's Bow",
"itembase": "cbw", "itembase": "cbw",
"req_lvl": 20, "req_lvl": 20,
"ilvl": 27, "ilvl": 27,
@@ -504,7 +504,7 @@
"category": "Base" "category": "Base"
}, },
"63": { "63": {
"name": "Pullspite", "name": "Stormstrike",
"itembase": "sbb", "itembase": "sbb",
"req_lvl": 25, "req_lvl": 25,
"ilvl": 34, "ilvl": 34,
@@ -560,7 +560,7 @@
"category": "Base" "category": "Base"
}, },
"70": { "70": {
"name": "Doomspittle", "name": "Doomslinger",
"itembase": "rxb", "itembase": "rxb",
"req_lvl": 28, "req_lvl": 28,
"ilvl": 38, "ilvl": 38,
@@ -568,7 +568,7 @@
"category": "Base" "category": "Base"
}, },
"71": { "71": {
"name": "War Bonnet", "name": "Biggin's Bonnet",
"itembase": "cap", "itembase": "cap",
"req_lvl": 3, "req_lvl": 3,
"ilvl": 4, "ilvl": 4,
@@ -640,7 +640,7 @@
"category": "Base" "category": "Base"
}, },
"80": { "80": {
"name": "Blinkbats Form", "name": "Blinkbat's Form",
"itembase": "lea", "itembase": "lea",
"req_lvl": 12, "req_lvl": 12,
"ilvl": 16, "ilvl": 16,
@@ -688,7 +688,7 @@
"category": "Base" "category": "Base"
}, },
"86": { "86": {
"name": "Venomsward", "name": "Venom Ward",
"itembase": "brs", "itembase": "brs",
"req_lvl": 20, "req_lvl": 20,
"ilvl": 27, "ilvl": 27,
@@ -736,7 +736,7 @@
"category": "Base" "category": "Base"
}, },
"92": { "92": {
"name": "Victors Silk", "name": "Silks of the Victor",
"itembase": "aar", "itembase": "aar",
"req_lvl": 28, "req_lvl": 28,
"ilvl": 38, "ilvl": 38,
@@ -896,7 +896,7 @@
"category": "Base" "category": "Base"
}, },
"112": { "112": {
"name": "Lenyms Cord", "name": "Lenymo",
"itembase": "lbl", "itembase": "lbl",
"req_lvl": 7, "req_lvl": 7,
"ilvl": 10, "ilvl": 10,
@@ -1016,7 +1016,7 @@
"category": "Base" "category": "Base"
}, },
"127": { "127": {
"name": "KhalimFlail", "name": "Khalim's Flail",
"itembase": "qf1", "itembase": "qf1",
"req_lvl": 0, "req_lvl": 0,
"ilvl": 0, "ilvl": 0,
@@ -1024,7 +1024,7 @@
"category": "Base" "category": "Base"
}, },
"128": { "128": {
"name": "SuperKhalimFlail", "name": "Khalim's Will",
"itembase": "qf2", "itembase": "qf2",
"req_lvl": 0, "req_lvl": 0,
"ilvl": 0, "ilvl": 0,
@@ -1056,7 +1056,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"132": { "132": {
"name": "Pompe's Wrath", "name": "Pompeii's Wrath",
"itembase": "9mp", "itembase": "9mp",
"req_lvl": 45, "req_lvl": 45,
"ilvl": 53, "ilvl": 53,
@@ -1104,7 +1104,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"138": { "138": {
"name": "The Minataur", "name": "The Minotaur",
"itembase": "9gi", "itembase": "9gi",
"req_lvl": 45, "req_lvl": 45,
"ilvl": 53, "ilvl": 53,
@@ -1288,7 +1288,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"161": { "161": {
"name": "The Atlantian", "name": "The Atlantean",
"itembase": "9wd", "itembase": "9wd",
"req_lvl": 42, "req_lvl": 42,
"ilvl": 50, "ilvl": 50,
@@ -1496,7 +1496,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"187": { "187": {
"name": "Skullcollector", "name": "Skull Collector",
"itembase": "8ws", "itembase": "8ws",
"req_lvl": 41, "req_lvl": 41,
"ilvl": 49, "ilvl": 49,
@@ -1536,7 +1536,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"192": { "192": {
"name": "Whichwild String", "name": "Witchwild String",
"itembase": "8s8", "itembase": "8s8",
"req_lvl": 39, "req_lvl": 39,
"ilvl": 47, "ilvl": 47,
@@ -1560,7 +1560,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"195": { "195": {
"name": "Godstrike Arch", "name": "Goldstrike Arch",
"itembase": "8lw", "itembase": "8lw",
"req_lvl": 46, "req_lvl": 46,
"ilvl": 54, "ilvl": 54,
@@ -1576,7 +1576,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"197": { "197": {
"name": "Pus Spiter", "name": "Pus Spitter",
"itembase": "8mx", "itembase": "8mx",
"req_lvl": 36, "req_lvl": 36,
"ilvl": 44, "ilvl": 44,
@@ -1600,7 +1600,7 @@
"category": "Expansion" "category": "Expansion"
}, },
"201": { "201": {
"name": "Peasent Crown", "name": "Peasant Crown",
"itembase": "xap", "itembase": "xap",
"req_lvl": 28, "req_lvl": 28,
"ilvl": 36, "ilvl": 36,
@@ -1632,7 +1632,7 @@
"category": "Armor" "category": "Armor"
}, },
"205": { "205": {
"name": "Valkiry Wing", "name": "Valkyrie Wing",
"itembase": "xhm", "itembase": "xhm",
"req_lvl": 44, "req_lvl": 44,
"ilvl": 52, "ilvl": 52,
@@ -1656,7 +1656,7 @@
"category": "Armor" "category": "Armor"
}, },
"208": { "208": {
"name": "Vampiregaze", "name": "Vampire Gaze",
"itembase": "xh9", "itembase": "xh9",
"req_lvl": 41, "req_lvl": 41,
"ilvl": 49, "ilvl": 49,
@@ -1680,7 +1680,7 @@
"category": "Armor" "category": "Armor"
}, },
"211": { "211": {
"name": "Skin of the Flayerd One", "name": "Skin of the Flayed One",
"itembase": "xla", "itembase": "xla",
"req_lvl": 31, "req_lvl": 31,
"ilvl": 39, "ilvl": 39,
@@ -1688,7 +1688,7 @@
"category": "Armor" "category": "Armor"
}, },
"212": { "212": {
"name": "Ironpelt", "name": "Iron Pelt",
"itembase": "xtu", "itembase": "xtu",
"req_lvl": 33, "req_lvl": 33,
"ilvl": 41, "ilvl": 41,
@@ -1696,7 +1696,7 @@
"category": "Armor" "category": "Armor"
}, },
"213": { "213": {
"name": "Spiritforge", "name": "Spirit Forge",
"itembase": "xng", "itembase": "xng",
"req_lvl": 35, "req_lvl": 35,
"ilvl": 43, "ilvl": 43,
@@ -1776,7 +1776,7 @@
"category": "Armor" "category": "Armor"
}, },
"223": { "223": {
"name": "Que-Hegan's Wisdon", "name": "Que-Hegan's Wisdom",
"itembase": "xtp", "itembase": "xtp",
"req_lvl": 51, "req_lvl": 51,
"ilvl": 59, "ilvl": 59,
@@ -1792,7 +1792,7 @@
"category": "Armor" "category": "Armor"
}, },
"225": { "225": {
"name": "Mosers Blessed Circle", "name": "Moser's Blessed Circle",
"itembase": "xml", "itembase": "xml",
"req_lvl": 31, "req_lvl": 31,
"ilvl": 39, "ilvl": 39,
@@ -1816,7 +1816,7 @@
"category": "Armor" "category": "Armor"
}, },
"228": { "228": {
"name": "Kerke's Sanctuary", "name": "Gerke's Sanctuary",
"itembase": "xow", "itembase": "xow",
"req_lvl": 44, "req_lvl": 44,
"ilvl": 52, "ilvl": 52,
@@ -1824,7 +1824,7 @@
"category": "Armor" "category": "Armor"
}, },
"229": { "229": {
"name": "Radimant's Sphere", "name": "Radament's Sphere",
"itembase": "xts", "itembase": "xts",
"req_lvl": 50, "req_lvl": 50,
"ilvl": 58, "ilvl": 58,
@@ -1872,7 +1872,7 @@
"category": "Armor" "category": "Armor"
}, },
"235": { "235": {
"name": "Lavagout", "name": "Lava Gout",
"itembase": "xtg", "itembase": "xtg",
"req_lvl": 42, "req_lvl": 42,
"ilvl": 50, "ilvl": 50,
@@ -1912,7 +1912,7 @@
"category": "Armor" "category": "Armor"
}, },
"240": { "240": {
"name": "Wartraveler", "name": "War Traveler",
"itembase": "xtb", "itembase": "xtb",
"req_lvl": 42, "req_lvl": 42,
"ilvl": 50, "ilvl": 50,
@@ -1920,7 +1920,7 @@
"category": "Armor" "category": "Armor"
}, },
"241": { "241": {
"name": "Gorerider", "name": "Gore Rider",
"itembase": "xhb", "itembase": "xhb",
"req_lvl": 47, "req_lvl": 47,
"ilvl": 55, "ilvl": 55,
@@ -1944,7 +1944,7 @@
"category": "Armor" "category": "Armor"
}, },
"244": { "244": {
"name": "Gloomstrap", "name": "Gloom's Trap",
"itembase": "zmb", "itembase": "zmb",
"req_lvl": 36, "req_lvl": 36,
"ilvl": 45, "ilvl": 45,
@@ -1960,7 +1960,7 @@
"category": "Armor" "category": "Armor"
}, },
"246": { "246": {
"name": "Thudergod's Vigor", "name": "Thundergod's Vigor",
"itembase": "zhb", "itembase": "zhb",
"req_lvl": 47, "req_lvl": 47,
"ilvl": 55, "ilvl": 55,
@@ -2120,7 +2120,7 @@
"category": "Elite Uniques" "category": "Elite Uniques"
}, },
"268": { "268": {
"name": "Bul Katho's Wedding Band", "name": "Bul-Kathos' Wedding Band",
"itembase": "rin", "itembase": "rin",
"req_lvl": 58, "req_lvl": 58,
"ilvl": 66, "ilvl": 66,
@@ -2256,7 +2256,7 @@
"category": "Class Specific" "category": "Class Specific"
}, },
"286": { "286": {
"name": "Cutthroat1", "name": "Bartuc's Cut-Throat",
"itembase": "9tw", "itembase": "9tw",
"req_lvl": 42, "req_lvl": 42,
"ilvl": 50, "ilvl": 50,
@@ -2288,7 +2288,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"290": { "290": {
"name": "Djinnslayer", "name": "Djinn Slayer",
"itembase": "7sm", "itembase": "7sm",
"req_lvl": 65, "req_lvl": 65,
"ilvl": 73, "ilvl": 73,
@@ -2312,7 +2312,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"293": { "293": {
"name": "Gutsiphon", "name": "Gut Siphon",
"itembase": "6rx", "itembase": "6rx",
"req_lvl": 71, "req_lvl": 71,
"ilvl": 79, "ilvl": 79,
@@ -2320,7 +2320,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"294": { "294": {
"name": "Razoredge", "name": "Razor's Edge",
"itembase": "7ha", "itembase": "7ha",
"req_lvl": 67, "req_lvl": 67,
"ilvl": 75, "ilvl": 75,
@@ -2328,7 +2328,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"296": { "296": {
"name": "Demonlimb", "name": "Demon Limb",
"itembase": "7sp", "itembase": "7sp",
"req_lvl": 63, "req_lvl": 63,
"ilvl": 71, "ilvl": 71,
@@ -2336,7 +2336,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"297": { "297": {
"name": "Steelshade", "name": "Steel Shade",
"itembase": "ulm", "itembase": "ulm",
"req_lvl": 62, "req_lvl": 62,
"ilvl": 70, "ilvl": 70,
@@ -2352,7 +2352,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"299": { "299": {
"name": "Deaths's Web", "name": "Death's Web",
"itembase": "7gw", "itembase": "7gw",
"req_lvl": 66, "req_lvl": 66,
"ilvl": 74, "ilvl": 74,
@@ -2408,7 +2408,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"308": { "308": {
"name": "Jadetalon", "name": "Jade Talon",
"itembase": "7wb", "itembase": "7wb",
"req_lvl": 66, "req_lvl": 66,
"ilvl": 74, "ilvl": 74,
@@ -2416,7 +2416,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"309": { "309": {
"name": "Shadowdancer", "name": "Shadow Dancer",
"itembase": "uhb", "itembase": "uhb",
"req_lvl": 71, "req_lvl": 71,
"ilvl": 79, "ilvl": 79,
@@ -2424,7 +2424,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"310": { "310": {
"name": "Cerebus", "name": "Cerebus' Bite",
"itembase": "drb", "itembase": "drb",
"req_lvl": 63, "req_lvl": 63,
"ilvl": 71, "ilvl": 71,
@@ -2440,7 +2440,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"312": { "312": {
"name": "Souldrain", "name": "Soul Drainer",
"itembase": "umg", "itembase": "umg",
"req_lvl": 74, "req_lvl": 74,
"ilvl": 82, "ilvl": 82,
@@ -2448,7 +2448,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"313": { "313": {
"name": "Runemaster", "name": "Rune Master",
"itembase": "72a", "itembase": "72a",
"req_lvl": 72, "req_lvl": 72,
"ilvl": 80, "ilvl": 80,
@@ -2456,7 +2456,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"314": { "314": {
"name": "Deathcleaver", "name": "Death Cleaver",
"itembase": "7wa", "itembase": "7wa",
"req_lvl": 70, "req_lvl": 70,
"ilvl": 78, "ilvl": 78,
@@ -2488,7 +2488,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"319": { "319": {
"name": "Wisp", "name": "Wisp Projector",
"itembase": "rin", "itembase": "rin",
"req_lvl": 76, "req_lvl": 76,
"ilvl": 84, "ilvl": 84,
@@ -2552,7 +2552,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"327": { "327": {
"name": "Spiritkeeper", "name": "Spirit Keeper",
"itembase": "drd", "itembase": "drd",
"req_lvl": 67, "req_lvl": 67,
"ilvl": 75, "ilvl": 75,
@@ -2576,7 +2576,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"330": { "330": {
"name": "Darkforge Spawn", "name": "Darkforce Spawn",
"itembase": "nef", "itembase": "nef",
"req_lvl": 64, "req_lvl": 64,
"ilvl": 72, "ilvl": 72,
@@ -2592,7 +2592,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"332": { "332": {
"name": "Bloodraven's Charge", "name": "Blood Raven's Charge",
"itembase": "amb", "itembase": "amb",
"req_lvl": 71, "req_lvl": 71,
"ilvl": 79, "ilvl": 79,
@@ -2608,7 +2608,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"334": { "334": {
"name": "Shadowkiller", "name": "Shadow Killer",
"itembase": "7cs", "itembase": "7cs",
"req_lvl": 78, "req_lvl": 78,
"ilvl": 85, "ilvl": 85,
@@ -2664,7 +2664,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"342": { "342": {
"name": "Steelpillar", "name": "Steel Pillar",
"itembase": "7p7", "itembase": "7p7",
"req_lvl": 69, "req_lvl": 69,
"ilvl": 77, "ilvl": 77,
@@ -2704,7 +2704,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"348": { "348": {
"name": "Steel Carapice", "name": "Steel Carapace",
"itembase": "uul", "itembase": "uul",
"req_lvl": 66, "req_lvl": 66,
"ilvl": 74, "ilvl": 74,
@@ -2744,7 +2744,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"354": { "354": {
"name": "Fathom", "name": "Death's Fathom",
"itembase": "obf", "itembase": "obf",
"req_lvl": 73, "req_lvl": 73,
"ilvl": 81, "ilvl": 81,
@@ -2840,7 +2840,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"367": { "367": {
"name": "Eschuta's temper", "name": "Eschuta's Temper",
"itembase": "obc", "itembase": "obc",
"req_lvl": 72, "req_lvl": 72,
"ilvl": 80, "ilvl": 80,
@@ -2904,7 +2904,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"376": { "376": {
"name": "Verdugo's Hearty Cord", "name": "Verdungo's Hearty Cord",
"itembase": "umc", "itembase": "umc",
"req_lvl": 63, "req_lvl": 63,
"ilvl": 71, "ilvl": 71,
@@ -2920,7 +2920,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"379": { "379": {
"name": "Giantskull", "name": "Giant Skull",
"itembase": "uh9", "itembase": "uh9",
"req_lvl": 65, "req_lvl": 65,
"ilvl": 73, "ilvl": 73,
@@ -2928,7 +2928,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"380": { "380": {
"name": "Ironward", "name": "Astreon's Iron Ward",
"itembase": "7ws", "itembase": "7ws",
"req_lvl": 60, "req_lvl": 60,
"ilvl": 68, "ilvl": 68,
@@ -2968,7 +2968,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"385": { "385": {
"name": "Earthshifter", "name": "Earth Shifter",
"itembase": "7gm", "itembase": "7gm",
"req_lvl": 69, "req_lvl": 69,
"ilvl": 77, "ilvl": 77,
@@ -2976,7 +2976,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"386": { "386": {
"name": "Wraithflight", "name": "Wraith Flight",
"itembase": "7gl", "itembase": "7gl",
"req_lvl": 76, "req_lvl": 76,
"ilvl": 84, "ilvl": 84,
@@ -3000,7 +3000,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"389": { "389": {
"name": "The Reedeemer", "name": "The Redeemer",
"itembase": "7sc", "itembase": "7sc",
"req_lvl": 72, "req_lvl": 72,
"ilvl": 80, "ilvl": 80,
@@ -3008,7 +3008,7 @@
"category": "Patch 1.10+" "category": "Patch 1.10+"
}, },
"390": { "390": {
"name": "Headhunter's Glory", "name": "Head Hunter's Glory",
"itembase": "ush", "itembase": "ush",
"req_lvl": 75, "req_lvl": 75,
"ilvl": 83, "ilvl": 83,