@startuml mining_model !theme plain skinparam roundcorner 10 skinparam shadowing false skinparam classAttributeIconSize 0 skinparam linetype ortho title Système de Minage Personnalisé (GamingCore) - Modèle de Données & Architecture package "Database Schema (SQLite / MySQL)" <> { entity "ores" as OresTable { * id : VARCHAR(64) <> -- * block_material : VARCHAR(64) * hardness : DOUBLE * rarity : VARCHAR(32) * stock : INTEGER * respawnable : BOOLEAN * respawn_time : INTEGER * temp_block : VARCHAR(64) created_at : TIMESTAMP } entity "ore_drops" as OreDropsTable { * id : INTEGER <> -- * ore_id : VARCHAR(64) <> * item_material : VARCHAR(64) * default_amount : INTEGER * default_chance : DOUBLE * fortunable : BOOLEAN * fortune_multiplier : DOUBLE * smeltable : BOOLEAN smelted_material : VARCHAR(64) } entity "placed_ores" as PlacedOresTable { * id : INTEGER <> -- * ore_id : VARCHAR(64) <> * world : VARCHAR(64) * x : INTEGER * y : INTEGER * z : INTEGER * current_stock : INTEGER * is_depleted : BOOLEAN * next_respawn_at : BIGINT } OresTable ||..o{ OreDropsTable : "1:N (Drops configurés)" OresTable ||..o{ PlacedOresTable : "1:N (Blocs actifs dans le monde)" } package "fr.luc.gamingcore.mining.model" { class CustomOre { - id: String - blockMaterial: XMaterial - hardness: double - rarity: OreRarity - stock: int - respawnable: boolean - respawnTimeSeconds: int - tempBlockMaterial: XMaterial - drops: List + isDepleted(currentStock: int): boolean } class OreDrop { - id: int - itemMaterial: XMaterial - defaultAmount: int - defaultChance: double - fortunable: boolean - fortuneMultiplier: double - smeltable: boolean - smeltedMaterial: XMaterial + calculateDrop(fortuneLevel: int, hasSmeltEnchant: boolean): ItemStack } class PlacedOreBlock { - id: int - oreType: CustomOre - worldName: String - x: int - y: int - z: int - currentStock: int - depleted: boolean - nextRespawnTimestamp: long + mine(player: Player): List + triggerRespawn(): void } enum OreRarity { COMMON UNCOMMON RARE EPIC LEGENDARY MYTHIC } } package "fr.luc.gamingcore.mining.manager" { class OreManager { - ores: Map - placedBlocks: Map + registerOre(ore: CustomOre): void + getOre(id: String): CustomOre + getPlacedBlock(location: Location): PlacedOreBlock + placeOreBlock(oreId: String, location: Location): PlacedOreBlock + removeOreBlock(location: Location): void } class RespawnScheduler { + startTask(): void + checkRespawnQueue(): void } class DatabaseManager { - connectionSource: Connection + initTables(): void + loadAllOres(): List + loadPlacedBlocks(): List + savePlacedBlock(block: PlacedOreBlock): void + updatePlacedBlockState(block: PlacedOreBlock): void + deletePlacedBlock(id: int): void } } package "fr.luc.gamingcore.mining.listener" { class BlockBreakListener { + onBlockBreak(event: BlockBreakEvent): void } class BlockPlaceListener { + onBlockPlace(event: BlockPlaceEvent): void } } CustomOre "1" *-- "many" OreDrop CustomOre "1" -- "many" PlacedOreBlock CustomOre --> OreRarity OreManager o-- CustomOre OreManager o-- PlacedOreBlock OreManager --> DatabaseManager OreManager --> RespawnScheduler BlockBreakListener --> OreManager BlockPlaceListener --> OreManager @enduml