/Spells

Documentation - Sorts

Vue d'ensemble

Le système de sorts gère tous les pouvoirs magiques utilisables en combat. Chaque sort possède des propriétés de base et des statistiques dépendantes du niveau.

Architecture

Hiérarchie des Classes

Spell (Sort principal)
├── SortStats (Statistiques par niveau)
│   └── SpellEffect (Effets du sort)
└── EffectTarget (Cibles affectées)

Spell - Sort Principal

Définition

La classe Spell représente un sort avec ses propriétés de base et ses effets.

Localisation: src/main/java/fight/spells/Spell.java

Propriétés

private String nombre;                              // Nom du sort
private int spellID;                                // ID unique
private int spriteID;                               // ID du sprite graphique
private String spriteInfos;                         // Infos du sprite
private Map<Integer, SortStats> sortStats;          // Stats par niveau
private ArrayList<ArrayList<Integer>> effectTargets; // Cibles normales
private ArrayList<ArrayList<Integer>> CCeffectTargets; // Cibles critique
private int type;                                   // Type de sort
private int duration;                               // Durée du sort

Types de Sorts

Type Description Exemple
0 Attaque directe Coup d'épée
1 Sort de dégâts Boule de feu
2 Sort de soin Guérison
3 Sort de buff Augmentation de force
4 Sort de debuff Ralentissement
5 Sort de contrôle Téléportation
6 Sort de zone Explosion

Chargement depuis la Base de Données

Table: sorts

SELECT * FROM sorts WHERE id = ?

Colonnes:

  • id: INT - ID unique
  • nom: VARCHAR - Nom du sort
  • sprite: INT - ID du sprite
  • spriteInfos: VARCHAR - Infos du sprite
  • effectTarget: VARCHAR - Cibles des effets (format: "1;2;3:4;5;6")
  • type: INT - Type de sort
  • duration: INT - Durée en tours
  • lvl1 à lvl6: VARCHAR - Stats par niveau

Constructeur

public Spell(int aspellID, String aNombre, int aspriteID, String aspriteInfos, 
             String ET, int type, int duration)

Paramètres:

  • aspellID: ID unique du sort
  • aNombre: Nom du sort
  • aspriteID: ID du sprite
  • aspriteInfos: Infos du sprite
  • ET: Cibles des effets (format: "1;2;3" ou "1;2;3:4;5;6" pour critique)
  • type: Type de sort
  • duration: Durée en tours

Exemple de Sort

// Créer un sort: Boule de feu
Spell fireball = new Spell(
    1,                          // ID
    "Boule de Feu",             // Nom
    100,                        // Sprite ID
    "100x100",                  // Infos sprite
    "1;2;3",                    // Cibles: 1, 2, 3
    1,                          // Type: Dégâts
    0                           // Durée: 0 (instantané)
);

SortStats - Statistiques par Niveau

Définition

La classe SortStats (imbriquée dans Spell) contient les statistiques d'un sort pour un niveau spécifique.

Propriétés

private int level;                  // Niveau du sort (1-6)
private int PA;                     // Coût en PA
private int range;                  // Portée
private int areaSize;               // Taille de la zone d'effet
private int minDamage;              // Dégâts minimum
private int maxDamage;              // Dégâts maximum
private int criticalChance;         // Chance de critique
private int criticalMultiplier;     // Multiplicateur de critique
private ArrayList<SpellEffect> effects; // Effets du sort

Format des Données

Les statistiques sont stockées sous forme de chaîne avec le format:

PA:range:areaSize:minDamage:maxDamage:criticalChance:criticalMultiplier:effects

Exemple

3:8:0:10:20:10:150:1|100;2|50

Signifie:

  • PA: 3
  • Portée: 8
  • Zone: 0 (pas de zone)
  • Dégâts: 10-20
  • Critique: 10% de chance, 150% de multiplicateur
  • Effets: Effet 1 (100), Effet 2 (50)

Parsing des Statistiques

public static SortStats parseSortStats(int spellId, int level, String data) {
    String[] parts = data.split(":");
    
    int PA = Integer.parseInt(parts[0]);
    int range = Integer.parseInt(parts[1]);
    int areaSize = Integer.parseInt(parts[2]);
    int minDamage = Integer.parseInt(parts[3]);
    int maxDamage = Integer.parseInt(parts[4]);
    int criticalChance = Integer.parseInt(parts[5]);
    int criticalMultiplier = Integer.parseInt(parts[6]);
    
    // Créer les effets
    ArrayList<SpellEffect> effects = new ArrayList<>();
    if (parts.length > 7) {
        String[] effectData = parts[7].split(";");
        for (String effect : effectData) {
            String[] effectParts = effect.split("\\|");
            int effectId = Integer.parseInt(effectParts[0]);
            int effectValue = Integer.parseInt(effectParts[1]);
            effects.add(new SpellEffect(effectId, effectValue));
        }
    }
    
    return new SortStats(level, PA, range, areaSize, minDamage, maxDamage, 
                         criticalChance, criticalMultiplier, effects);
}

SpellEffect - Effets du Sort

Définition

La classe SpellEffect représente un effet appliqué par un sort.

Localisation: src/main/java/fight/spells/SpellEffect.java

Propriétés

private int id;                     // ID de l'effet
private int duration;               // Durée en tours
private int value;                  // Valeur de l'effet
private int type;                   // Type d'effet
private ArrayList<Integer> targets; // Cibles affectées

Types d'Effets

Type Description Valeur
0 Dégâts directs Montant de dégâts
1 Soin Montant de soin
2 Augmentation de stat Montant du bonus
3 Diminution de stat Montant de la pénalité
4 Poison Dégâts par tour
5 Paralysie Durée en tours
6 Invulnérabilité Durée en tours
7 Téléportation Cellule cible
8 Invocation ID du monstre

Exemple d'Effet

// Effet: Dégâts de 50
SpellEffect damage = new SpellEffect(
    1,                          // ID
    0,                          // Durée: 0 (instantané)
    50,                         // Valeur: 50 dégâts
    0,                          // Type: Dégâts directs
    targets                     // Cibles
);

// Effet: Poison (10 dégâts par tour pendant 3 tours)
SpellEffect poison = new SpellEffect(
    2,                          // ID
    3,                          // Durée: 3 tours
    10,                         // Valeur: 10 dégâts/tour
    4,                          // Type: Poison
    targets                     // Cibles
);

Cibles des Effets

Format

Les cibles sont définies par des cellules relatives à la cible du sort.

1;2;3:4;5;6

Signifie:

  • Cibles normales: cellules 1, 2, 3
  • Cibles critiques: cellules 4, 5, 6

Système de Cellules

    0  1  2
    3  4  5
    6  7  8

La cellule 4 est la cible du sort. Les autres cellules sont relatives.

Exemple

4:4;7;8

Signifie:

  • Cible normale: cellule 4 (la cible)
  • Cible critique: cellules 4, 7, 8 (la cible et les deux cellules en dessous)

Utilisation d'un Sort en Combat

Étape 1: Vérifier les Conditions

// Vérifier le PA disponible
if (fighter.getPA() < spell.getSortStats(level).getPA()) {
    throw new Exception("PA insuffisant");
}

// Vérifier la portée
int distance = PathFinding.getDistance(fighter.getCell(), targetCell);
if (distance > spell.getSortStats(level).getRange()) {
    throw new Exception("Portée insuffisante");
}

// Vérifier les obstacles
if (!PathFinding.canReach(fighter.getCell(), targetCell)) {
    throw new Exception("Chemin bloqué");
}

Étape 2: Appliquer les Effets

// Récupérer les stats du sort
SortStats stats = spell.getSortStats(level);

// Calculer les dégâts
int baseDamage = Formulas.calculateDamage(
    fighter.getStats(),
    stats.getMinDamage(),
    stats.getMaxDamage()
);

// Vérifier le critique
boolean isCritical = Math.random() * 100 < stats.getCriticalChance();
if (isCritical) {
    baseDamage = (int)(baseDamage * stats.getCriticalMultiplier() / 100.0);
}

// Appliquer les dégâts
target.takeDamage(baseDamage);

// Appliquer les effets
for (SpellEffect effect : stats.getEffects()) {
    effect.apply(target, spell.getDuration());
}

Étape 3: Consommer les Ressources

// Consommer le PA
fighter.setPA(fighter.getPA() - stats.getPA());

// Ajouter le sort au cooldown si nécessaire
if (spell.getDuration() > 0) {
    fighter.addSpellCooldown(spell.getId(), spell.getDuration());
}

Exemple Complet - Créer un Sort

1. Créer le Sort en Base de Données

-- Créer le sort
INSERT INTO sorts (id, nom, sprite, spriteInfos, effectTarget, type, duration)
VALUES (
    1,                          -- ID
    "Boule de Feu",             -- Nom
    100,                        -- Sprite ID
    "100x100",                  -- Infos sprite
    "4:4;7;8",                  -- Cibles: 4 normal, 4;7;8 critique
    1,                          -- Type: Dégâts
    0                           -- Durée: 0
);

-- Créer les statistiques par niveau
INSERT INTO sort_stats (sort_id, level, PA, range, areaSize, minDamage, maxDamage, criticalChance, criticalMultiplier, effects)
VALUES 
(1, 1, 3, 8, 0, 10, 20, 10, 150, "1|50"),
(1, 2, 3, 8, 0, 15, 30, 10, 150, "1|75"),
(1, 3, 3, 8, 0, 20, 40, 10, 150, "1|100"),
(1, 4, 3, 8, 0, 25, 50, 10, 150, "1|125"),
(1, 5, 3, 8, 0, 30, 60, 10, 150, "1|150"),
(1, 6, 3, 8, 0, 35, 70, 10, 150, "1|175");

2. Charger le Sort

// Charger le sort
Spell fireball = Main.world.getSort(1);

// Afficher les infos
System.out.println("Sort: " + fireball.getNombre());
System.out.println("Type: " + fireball.getType());

// Afficher les stats par niveau
for (int level = 1; level <= 6; level++) {
    SortStats stats = fireball.getSortStats(level);
    System.out.println("Niveau " + level + ": PA=" + stats.getPA() + 
                       ", Portée=" + stats.getRange() + 
                       ", Dégâts=" + stats.getMinDamage() + "-" + stats.getMaxDamage());
}

3. Utiliser le Sort en Combat

// Le combattant utilise le sort
Fighter fighter = fight.getFighter(playerId);
Fighter target = fight.getFighter(targetId);

// Vérifier les conditions
Spell spell = Main.world.getSort(1);
SortStats stats = spell.getSortStats(1);

if (fighter.getPA() >= stats.getPA()) {
    // Calculer les dégâts
    int damage = Formulas.calculateDamage(
        fighter.getStats(),
        stats.getMinDamage(),
        stats.getMaxDamage()
    );
    
    // Appliquer les dégâts
    target.takeDamage(damage);
    
    // Consommer le PA
    fighter.setPA(fighter.getPA() - stats.getPA());
    
    System.out.println(fighter.getName() + " utilise " + spell.getNombre() + 
                       " et inflige " + damage + " dégâts!");
}

Formules de Calcul

Calcul des Dégâts

public static int calculateDamage(Stats stats, int minDamage, int maxDamage) {
    // Dégâts de base
    int baseDamage = minDamage + (int)(Math.random() * (maxDamage - minDamage + 1));
    
    // Bonus de force
    int forceBonus = (stats.getForce() - 100) / 10;
    
    // Bonus de dommages
    int damageBonus = stats.getDamage();
    
    // Calcul final
    int finalDamage = baseDamage + forceBonus + damageBonus;
    
    return Math.max(1, finalDamage);  // Minimum 1 dégât
}

Calcul de la Résistance

public static int calculateResistance(Stats stats, int elementType) {
    int resistance = 0;
    
    switch (elementType) {
        case 0: // Neutre
            resistance = stats.getResistanceNeutre();
            break;
        case 1: // Terre
            resistance = stats.getResistanceTerre();
            break;
        case 2: // Feu
            resistance = stats.getResistanceFeu();
            break;
        case 3: // Eau
            resistance = stats.getResistanceEau();
            break;
        case 4: // Air
            resistance = stats.getResistanceAir();
            break;
    }
    
    return resistance;
}

Gestion des Erreurs

Validations Courantes

// Vérifier le PA
if (fighter.getPA() < stats.getPA()) {
    throw new Exception("PA insuffisant");
}

// Vérifier la portée
if (distance > stats.getRange()) {
    throw new Exception("Portée insuffisante");
}

// Vérifier le cooldown
if (fighter.isSpellOnCooldown(spell.getId())) {
    throw new Exception("Sort en cooldown");
}

// Vérifier les obstacles
if (!PathFinding.canReach(fighter.getCell(), targetCell)) {
    throw new Exception("Chemin bloqué");
}

Conclusion

Le système de sorts offre une grande flexibilité pour créer des pouvoirs magiques variés avec des effets complexes. Les statistiques dépendantes du niveau permettent une progression naturelle du personnage.

Powered by hosted.md