diff options
Diffstat (limited to 'dropcalc/mxl_types')
-rw-r--r-- | dropcalc/mxl_types/__init__.py | 15 | ||||
-rw-r--r-- | dropcalc/mxl_types/base.py | 34 | ||||
-rw-r--r-- | dropcalc/mxl_types/dao.py | 13 | ||||
-rw-r--r-- | dropcalc/mxl_types/item_ratio.py | 39 | ||||
-rw-r--r-- | dropcalc/mxl_types/item_type.py | 32 | ||||
-rw-r--r-- | dropcalc/mxl_types/set.py | 15 | ||||
-rw-r--r-- | dropcalc/mxl_types/treasure_class.py | 46 | ||||
-rw-r--r-- | dropcalc/mxl_types/unique.py | 18 |
8 files changed, 212 insertions, 0 deletions
diff --git a/dropcalc/mxl_types/__init__.py b/dropcalc/mxl_types/__init__.py new file mode 100644 index 0000000..09b00bc --- /dev/null +++ b/dropcalc/mxl_types/__init__.py @@ -0,0 +1,15 @@ +__all__ = ["ItemRatio", "ItemType", "BaseItem", "Weapon", "Armor", "Misc", "UniqueItem", "SetItem", "TreasureClass"] + +from .dao import BaseDAO + +from .item_ratio import ItemRatio +from .item_type import ItemType +from .base import BaseItem, Weapon, Armor, Misc +from .unique import UniqueItem +from .set import SetItem +from .treasure_class import TreasureClass + +# TODO +# MonStats grab Id, hcIdx, enabled, TreasureClass1(H), maybe remaining TC2/3/4(H) +# SuperUniques Superunique, TC(H) +# Levels MonLvl3 and nmon1-nmon20 diff --git a/dropcalc/mxl_types/base.py b/dropcalc/mxl_types/base.py new file mode 100644 index 0000000..cd7e8be --- /dev/null +++ b/dropcalc/mxl_types/base.py @@ -0,0 +1,34 @@ +from sqlalchemy import ForeignKey, String +from sqlalchemy.orm import Mapped, mapped_column + +from .dao import BaseDAO + + +class BaseItem(BaseDAO): + __tablename__ = "base" + + code: Mapped[str] = mapped_column(String(4), primary_key=True) + name: Mapped[str] # internal name only, game actually looks up `code` in strings + type = mapped_column(ForeignKey("item_type.Code")) # can have two item_type... and all their parents + type2 = mapped_column(ForeignKey("item_type.Code")) # should really figure out a better way to store them + rarity: Mapped[int] + level: Mapped[int] # variously referred to as ilvl or qlvl + spawnable: Mapped[int] # items with spawnable=0 *can* be dropped directly from TCs, but shouldn't randomly drop + category: Mapped[str] + + __mapper_args__ = {'polymorphic_on': 'category'} + + +class Weapon(BaseItem): + filename = "Weapons.txt" + __mapper_args__ = {'polymorphic_identity': 'weap'} + + +class Armor(BaseItem): + filename = "Armor.txt" + __mapper_args__ = {'polymorphic_identity': 'armo'} + + +class Misc(BaseItem): + filename = "Misc.txt" + __mapper_args__ = {'polymorphic_identity': 'misc'} diff --git a/dropcalc/mxl_types/dao.py b/dropcalc/mxl_types/dao.py new file mode 100644 index 0000000..db459e7 --- /dev/null +++ b/dropcalc/mxl_types/dao.py @@ -0,0 +1,13 @@ +from sqlalchemy.orm import DeclarativeBase + + +class BaseDAO(DeclarativeBase): + __csv_to_db__ = dict() + + def is_valid(self): + return True + + def __init__(self, iterable=(), **kwargs): + self.__dict__.update(iterable, **kwargs) + for this, that in self.__csv_to_db__.items(): + self.__dict__[this] = self.__dict__[that] diff --git a/dropcalc/mxl_types/item_ratio.py b/dropcalc/mxl_types/item_ratio.py new file mode 100644 index 0000000..7a783c3 --- /dev/null +++ b/dropcalc/mxl_types/item_ratio.py @@ -0,0 +1,39 @@ +from sqlalchemy.orm import Mapped, mapped_column + +from .dao import BaseDAO + + +class ItemRatio(BaseDAO): + filename = "ItemRatio_mp.txt" + __csv_to_db__ = {"Class_Specific": "Class Specific"} + __tablename__ = "item_ratio" + + id: Mapped[int] = mapped_column(primary_key=True) + + # D2Fileguide goes into more detail about how these are used + # the gist is 1 in (Quality - (mlvl-ilvl) / Divisor) * 128 of rolling each of these + # in the order unique, set, rare, magic, hiq, normal (and falling back on loq) + # further modified by MF after diminishing returns value (250 uni, 500 set, 600 rar) - which I believe is hardcoded + # and then the TC values + Unique: Mapped[int] + UniqueDivisor: Mapped[int] + UniqueMin: Mapped[int] + Rare: Mapped[int] + RareDivisor: Mapped[int] + RareMin: Mapped[int] + Set: Mapped[int] + SetDivisor: Mapped[int] + SetMin: Mapped[int] + Magic: Mapped[int] + MagicDivisor: Mapped[int] + MagicMin: Mapped[int] + HiQuality: Mapped[int] + HiQualityDivisor: Mapped[int] + Normal: Mapped[int] + NormalDivisor: Mapped[int] + + Uber: Mapped[int] # exceptional/elite as decided by normcode, ubercode, ultracode in Weapons.txt / Armor.txt + Class_Specific: Mapped[int] # class specifics as decided by Class in Itemtypes.txt + + def is_valid(self): + return self.Version == "1" diff --git a/dropcalc/mxl_types/item_type.py b/dropcalc/mxl_types/item_type.py new file mode 100644 index 0000000..8dd9b37 --- /dev/null +++ b/dropcalc/mxl_types/item_type.py @@ -0,0 +1,32 @@ +from typing import Optional + +from sqlalchemy import ForeignKey, String +from sqlalchemy.orm import Mapped, mapped_column + +from .dao import BaseDAO + + +class ItemType(BaseDAO): + filename = "ItemTypes.txt" + __tablename__ = "item_type" + + Id: Mapped[int] = mapped_column(primary_key=True) + Code: Mapped[str] = mapped_column(String(4)) # referred to by other tables + ItemType: Mapped[Optional[str]] # internal human readable name + + Equiv1 = mapped_column(ForeignKey("item_type.Code")) + Equiv2 = mapped_column(ForeignKey("item_type.Code")) + + # what does Rarity do here? fileguide description is unclear + + def is_valid(self): + return is_int(self.Id) and self.Code not in (None, '') + + +def is_int(obj): + try: + int(obj) + except ValueError: + return False + else: + return True diff --git a/dropcalc/mxl_types/set.py b/dropcalc/mxl_types/set.py new file mode 100644 index 0000000..498cdcf --- /dev/null +++ b/dropcalc/mxl_types/set.py @@ -0,0 +1,15 @@ +from sqlalchemy import ForeignKey +from sqlalchemy.orm import Mapped, mapped_column + +from . import BaseDAO + + +class SetItem(BaseDAO): + filename = "SetItems.txt" + __tablename__ = "set_item" + + id: Mapped[int] = mapped_column(primary_key=True) + index: Mapped[str] # string reference, often also human-readable + item = mapped_column(ForeignKey("base.code")) # note inconsistency with everything else... + rarity: Mapped[int] # drop frequency, relative to other sets on this base + lvl: Mapped[int] # minimum drop level diff --git a/dropcalc/mxl_types/treasure_class.py b/dropcalc/mxl_types/treasure_class.py new file mode 100644 index 0000000..d00da6f --- /dev/null +++ b/dropcalc/mxl_types/treasure_class.py @@ -0,0 +1,46 @@ +from typing import Optional + +from sqlalchemy.orm import Mapped, mapped_column + +from . import BaseDAO + + +class TreasureClass(BaseDAO): + filename = "TreasureClassEx.txt" + __csv_to_db__ = {"name": "Treasure Class"} + __tablename__ = "treasure_class" + + name: Mapped[str] = mapped_column(primary_key=True) + + group: Mapped[Optional[int]] + level: Mapped[Optional[int]] + + Picks: Mapped[int] + + Unique: Mapped[Optional[str]] + Set: Mapped[Optional[int]] + Rare: Mapped[Optional[int]] + Magic: Mapped[Optional[int]] + + NoDrop: Mapped[Optional[int]] + + Item1: Mapped[str] + Prob1: Mapped[int] + Item2: Mapped[Optional[str]] + Prob2: Mapped[Optional[int]] + Item3: Mapped[Optional[str]] + Prob3: Mapped[Optional[int]] + Item4: Mapped[Optional[str]] + Prob4: Mapped[Optional[int]] + Item5: Mapped[Optional[str]] + Prob5: Mapped[Optional[int]] + Item6: Mapped[Optional[str]] + Prob6: Mapped[Optional[int]] + Item7: Mapped[Optional[str]] + Prob7: Mapped[Optional[int]] + Item8: Mapped[Optional[str]] + Prob8: Mapped[Optional[int]] + Item9: Mapped[Optional[str]] + Prob9: Mapped[Optional[int]] + Item10: Mapped[Optional[str]] + Prob10: Mapped[Optional[int]] diff --git a/dropcalc/mxl_types/unique.py b/dropcalc/mxl_types/unique.py new file mode 100644 index 0000000..49c4e39 --- /dev/null +++ b/dropcalc/mxl_types/unique.py @@ -0,0 +1,18 @@ +from sqlalchemy import ForeignKey +from sqlalchemy.orm import Mapped, mapped_column + +from . import BaseDAO + + +class UniqueItem(BaseDAO): + filename = "UniqueItems.txt" + __tablename__ = "unique_item" + + id: Mapped[int] = mapped_column(primary_key=True) + index: Mapped[str] # string reference, often also human-readable + code = mapped_column(ForeignKey("base.code")) + rarity: Mapped[int] # drop frequency, relative to other uniques on this base + lvl: Mapped[int] # minimum drop level + + def is_valid(self): + return self.enabled == "1" # TODO: can we create fixed drop but not randomly available uniques by setting this to 0? |