@startuml mining_model skinparam roundcorner 8 skinparam shadowing false skinparam classAttributeIconSize 0 title Système de Minage Personnalisé (GamingCore) - Modèle & Architecture package "Database Schema (SQLite / MySQL)" <> { class "ores" as OresTable << (T,#5DADE2) >> { + id : VARCHAR(64) [PK] -- + block_material : VARCHAR(64) + hardness : DOUBLE + rarity : VARCHAR(32) + stock : INTEGER + respawnable : BOOLEAN + respawn_time : INTEGER + temp_block : VARCHAR(64) + created_at : TIMESTAMP } class "ore_drops" as OreDropsTable << (T,#5DADE2) >> { + id : INTEGER [PK AUTO] -- + ore_id : VARCHAR(64) [FK] + item_material : VARCHAR(64) + default_amount : INTEGER + default_chance : DOUBLE + fortunable : BOOLEAN + fortune_multiplier : DOUBLE + smeltable : BOOLEAN + smelted_material : VARCHAR(64) } class "placed_ores" as PlacedOresTable << (T,#5DADE2) >> { + id : INTEGER [PK AUTO] -- + ore_id : VARCHAR(64) [FK] + world : VARCHAR(64) + x : INTEGER + y : INTEGER + z : INTEGER + current_stock : INTEGER + is_depleted : BOOLEAN + next_respawn_at : BIGINT } OresTable "1" *-- "0..*" OreDropsTable : "drops configurés" OresTable "1" *-- "0..*" PlacedOresTable : "blocs actifs" } 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" *-- "0..*" OreDrop CustomOre "1" -- "0..*" PlacedOreBlock CustomOre --> OreRarity OreManager o-- CustomOre OreManager o-- PlacedOreBlock OreManager --> DatabaseManager OreManager --> RespawnScheduler BlockBreakListener --> OreManager BlockPlaceListener --> OreManager @enduml