Mi2dRPGamEng/engine/item.py

55 lines
3.3 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
@dataclass(frozen=True)
class ItemDef:
id: str
name: str
width: int
height: int
texture: str | None = None
color: tuple[int, int, int] = (255, 0, 255)
stackable: bool = False
max_stack: int = 1
clothing_slot: str | None = None # set if this item can be worn (e.g. "torso", "back")
grants_inventory_size: tuple[int, int] | None = None # e.g. a backpack, when worn
armor_reduction: float = 0.0 # flat damage reduction while worn (clothing)
arm_slots_required: int = 0 # sleeved garments only (e.g. a jacket): 0 = no arm-count
# constraint (hats, backpacks, pants, ...); a garment with more sleeves than the wearer
# has arms still fits (extras go unused), fewer does not - see Character.wear_item
compatible_body_types: tuple[str, ...] = () # e.g. ("biped",), ("quadruped",) - which
# SpeciesDef.body_type values this item can be worn by at all; empty = fits any body type
weapon_skill: str | None = None # bio skill this weapon's attacks are checked against
weapon_damage: float = 0.0 # flat bonus added on a successful skill check
weapon_range: int = 1 # tiles; 1 = melee (adjacent), >1 = ranged (used by shooting)
projectile_type: str | None = None # e.g. "bullet", "arrow" - what a shield needs to block it
hands_required: int = 1 # 1 or 2; two-handed items occupy a hand pair when wielded
shield_block_bonus: float = 0.0 # bonus added to the defender's blocking skill check
blockable_projectile_types: tuple[str, ...] = () # projectile_types this shield stops
tool_kind: str | None = None # e.g. "deconstructor", "constructor"
builds_tile_layer: str | None = None # which layer this material can construct (used with a constructor tool)
builds_tile_layer_def_id: str | None = None # which def gets placed there
ammo_type: str | None = None # set on ammo items: "small_caliber", "heavy_caliber", "shotgun_shell", ...
ranged_knockback: float = 0.0 # ammo items: tiles of knockback dealt on impact
ammo_damage_bonus: float = 0.0 # ammo items: extra flat damage added to the weapon's own bonus
compatible_ammo_types: tuple[str, ...] = () # ammo-based weapons: which ammo_types they accept
magazine_size: int = 0 # ammo-based weapons: base capacity (0 = not ammo-fed, e.g. bow/pistol_basic)
aim_cone_degrees: float = 0.0 # ranged weapons: base spread; 0 = perfectly accurate
pellet_count: int = 1 # shotgun-style weapons: independent projectiles fired per shot
blast_radius: int = 0 # rocket-style weapons: AoE radius in tiles (0 = no AoE)
attachment_kind: str | None = None # e.g. "scope", "stock", "magazine"
aimcone_reduction_degrees: float = 0.0 # attachment effect
magazine_capacity_bonus: int = 0 # attachment effect (e.g. an extended mag)
melee_knockback: float = 0.0 # melee weapons: base knockback tiles, scaled by attacker strength
grants_ability: str | None = None # e.g. "time_warp_sphere" - triggered on activation, see resources/logic/abilities.py
is_implant: bool = False # slotless: installed directly on the character, not held/worn
class ItemInstance:
def __init__(self, item_id: str, def_id: str, quantity: int = 1):
self.item_id = item_id
self.def_id = def_id
self.quantity = quantity