/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 uniquenom: VARCHAR - Nom du sortsprite: INT - ID du spritespriteInfos: VARCHAR - Infos du spriteeffectTarget: VARCHAR - Cibles des effets (format: "1;2;3:4;5;6")type: INT - Type de sortduration: INT - Durée en tourslvl1à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 sortaNombre: Nom du sortaspriteID: ID du spriteaspriteInfos: Infos du spriteET: Cibles des effets (format: "1;2;3" ou "1;2;3:4;5;6" pour critique)type: Type de sortduration: 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.