Crocobras / index.js
Clemylia's picture
Rename index-3.js to index.js
07dce12 verified
// crocobras/index.js
const EventEmitter = require('events');
const nekomaths = require('nekomaths'); // Pour les nombres aléatoires
// --- Configuration du jeu (peut être personnalisé par le développeur utilisateur) ---
const DEFAULT_GAME_SETTINGS = {
initialArmHealth: 100, // Exemple de vie du bras
crocoDamage: 25, // Dégâts d'un croco qui mange le bras
initialCrocodiles: 1, // Nombre de crocos au niveau 1
crocoPerLevel: 1, // Crocos supplémentaires par niveau
crocoSpeedMultiplier: 1.1, // Crocos plus rapides à chaque niveau
levelUpThreshold: 5 // Crocos à tuer pour passer au niveau suivant (modifiable via croconumber)
};
class CrocobrasGame extends EventEmitter {
constructor(settings = {}) {
super();
this.settings = { ...DEFAULT_GAME_SETTINGS, ...settings };
this.armHealth = this.settings.initialArmHealth;
this.currentLevel = 1;
this.crocodilesRemaining = 0; // Nombre de crocos à tuer pour le niveau actuel
this.crocodilesSpawnedThisLevel = 0; // Crocos déjà apparus ce niveau
this.killedCrocodilesThisLevel = 0; // Crocos tués dans le niveau actuel
this.isGameOver = false;
this.isGameRunning = false;
// Stocke les crocos actifs pour la logique de collision
// En vrai jeu, ce serait un tableau d'objets avec position, vitesse, etc.
// Ici, on gère juste le nombre.
this.activeCrocodiles = [];
this.initializeLevel();
}
/**
* Initialise le niveau actuel : détermine le nombre de crocodiles à tuer.
* Peut être appelé manuellement par crocolevel.
* @param {number} [level] - Niveau spécifique à initialiser. Si non fourni, utilise currentLevel.
*/
initializeLevel(level = this.currentLevel) {
this.currentLevel = level;
this.killedCrocodilesThisLevel = 0;
this.crocodilesSpawnedThisLevel = 0;
// Calcul du nombre total de crocos pour ce niveau
// Tu as dit "un crocodile de plus que le niveau suivant arrive en même temps"
// Interprétation: Niveau 1 -> 1 croco, Niveau 2 -> 2 crocos, etc.
this.crocodilesToSpawnTotal = this.settings.initialCrocodiles + (this.currentLevel - 1) * this.settings.crocoPerLevel;
this.crocodilesRemaining = this.crocodilesToSpawnTotal; // Pour l'UI du développeur utilisateur
this.emit('levelInitialized', {
level: this.currentLevel,
crocodilesToKill: this.crocodilesToSpawnTotal,
armHealth: this.armHealth
});
console.log(`[Crocobras] Niveau ${this.currentLevel} initialisé. Crocodiles à tuer : ${this.crocodilesToSpawnTotal}`);
}
/**
* Démarre la partie.
* @returns {boolean} True si le jeu a démarré, false s'il était déjà en cours.
*/
startGame() {
if (this.isGameRunning) {
this.emit('gameAlreadyRunning');
return false;
}
this.isGameRunning = true;
this.isGameOver = false;
this.armHealth = this.settings.initialArmHealth;
this.currentLevel = 1;
this.initializeLevel(1);
this.emit('gameStarted', { level: this.currentLevel, armHealth: this.armHealth });
console.log("[Crocobras] Partie démarrée !");
return true;
}
/**
* Gère la fin de partie.
* @fires CrocobrasGame#gameOver
* @returns {boolean} True si le jeu est terminé, false sinon (si déjà game over).
*/
crocover() {
if (this.isGameOver) return false;
this.isGameOver = true;
this.isGameRunning = false;
this.emit('gameOver', { finalLevel: this.currentLevel, reason: 'Arm eaten' });
console.log("[Crocobras] GAME OVER ! Le bras a été mangé.");
return true;
}
/**
* Redémarre le jeu au niveau 1.
* @fires CrocobrasGame#gameReset
*/
crocoreset() {
this.armHealth = this.settings.initialArmHealth;
this.currentLevel = 1;
this.correctGuesses = 0; // Si jamais tu as une logique de devinette cachée
this.isGameOver = false;
this.isGameRunning = false; // Ne pas démarrer automatiquement, l'utilisateur appellera startGame()
this.killedCrocodilesThisLevel = 0;
this.crocodilesSpawnedThisLevel = 0;
this.activeCrocodiles = []; // Vide les crocos actifs
this.initializeLevel(1); // Réinitialise le premier niveau
this.emit('gameReset', { level: this.currentLevel, armHealth: this.armHealth });
console.log("[Crocobras] Jeu réinitialisé au niveau 1.");
}
/**
* Simule un crocodile mangeant le bras.
* Déclenche la perte de points de vie ou le game over.
* @fires CrocobrasGame#armEaten
* @fires CrocobrasGame#gameOver
*/
crocobouffe() {
if (!this.isGameRunning || this.isGameOver) {
console.log("[Crocobras] Ignoré: le jeu n'est pas en cours ou est terminé.");
return;
}
this.armHealth = nekomaths.neksub(this.armHealth, this.settings.crocoDamage);
this.emit('armEaten', {
currentHealth: this.armHealth,
damageTaken: this.settings.crocoDamage
});
console.log(`[Crocobras] Un crocodile a mangé le bras ! Vie restante : ${this.armHealth}`);
if (this.armHealth <= 0) {
this.crocover();
}
}
/**
* Simule un coup de feu tiré. Ne gère pas si la cible est touchée.
* Les développeurs utilisent `crocofuls` pour la logique de détection.
* @fires CrocobrasGame#shotFired
*/
crocotire() {
if (!this.isGameRunning || this.isGameOver) {
this.emit('gameNotRunning');
return;
}
this.emit('shotFired');
console.log("[Crocobras] Coup de feu tiré !");
}
/**
* Simule la mort d'un crocodile.
* @fires CrocobrasGame#crocoKilled
* @fires CrocobrasGame#levelUp
* @returns {boolean} True si un crocodile a été tué, false si aucun n'est à tuer.
*/
crocokill() {
if (!this.isGameRunning || this.isGameOver) {
this.emit('gameNotRunning');
return false;
}
if (this.killedCrocodilesThisLevel < this.crocodilesToSpawnTotal) {
this.killedCrocodilesThisLevel = nekomaths.nekadd(this.killedCrocodilesThisLevel, 1);
this.crocodilesRemaining = nekomaths.neksub(this.crocodilesToSpawnTotal, this.killedCrocodilesThisLevel);
this.emit('crocoKilled', {
killedCount: this.killedCrocodilesThisLevel,
remainingCount: this.crocodilesRemaining,
level: this.currentLevel
});
console.log(`[Crocobras] Crocodile tué ! Restant : ${this.crocodilesRemaining}/${this.crocodilesToSpawnTotal}`);
if (this.killedCrocodilesThisLevel >= this.crocodilesToSpawnTotal) {
this.levelUp(); // Passe au niveau suivant
}
return true;
} else {
this.emit('noMoreCrocosToKill');
console.log("[Crocobras] Tous les crocodiles du niveau actuel sont déjà tués.");
return false;
}
}
/**
* Permet aux développeurs de définir le nombre de crocos à tuer pour un niveau donné.
* OU de définir le seuil pour le passage de niveau.
* @param {number} [targetCrocosPerLevel] - Nombre de crocodiles requis pour passer le niveau actuel.
* @param {number} [levelToApply] - Le niveau auquel appliquer ce seuil. Si non fourni, applique à levelUpThreshold.
*/
croconumber(targetCrocosPerLevel = DEFAULT_GAME_SETTINGS.levelUpThreshold) {
// Cette fonction peut être interprétée de deux façons:
// 1. Définir le nombre de crocos à tuer pour le level up (ce que tu as dit "double pour le niveau suivant")
// 2. Définir le nombre de crocos qui apparaissent
// Je vais opter pour la 1ère (seuil de level up) comme le plus utile pour la personnalisation.
// La quantité de crocos qui apparaissent est déjà gérée par initializeLevel.
this.settings.levelUpThreshold = targetCrocosPerLevel;
this.emit('levelUpThresholdUpdated', targetCrocosPerLevel);
console.log(`[Crocobras] Seuil de crocos à tuer pour passer le niveau mis à jour : ${targetCrocosPerLevel}`);
}
/**
* Fait monter le jeu de niveau.
* @fires CrocobrasGame#levelUp
*/
levelUp() {
if (this.isGameOver) {
this.emit('gameNotRunning');
return;
}
this.currentLevel = nekomaths.nekadd(this.currentLevel, 1);
this.emit('levelUp', { newLevel: this.currentLevel });
console.log(`[Crocobras] BRAVO ! Vous passez au niveau ${this.currentLevel} !`);
this.initializeLevel(this.currentLevel); // Réinitialise les compteurs pour le nouveau niveau
}
// --- Fonctions d'accès aux états (pour l'UI) ---
getGameState() {
return {
armHealth: this.armHealth,
currentLevel: this.currentLevel,
crocodilesRemaining: this.crocodilesRemaining,
crocodilesToSpawnTotal: this.crocodilesToSpawnTotal,
killedCrocodilesThisLevel: this.killedCrocodilesThisLevel,
isGameOver: this.isGameOver,
isGameRunning: this.isGameRunning
};
}
/**
* crocofuls: Permet de définir une logique de détection de tir personnalisée.
* Cette fonction ne fait rien directement, elle est là comme un hook ou un concept.
* C'est au développeur d'appeler `crocokill()` si sa logique de `crocofuls` détecte un coup réussi.
* @param {Function} customGunLogic - Une fonction de callback que le développeur fournira.
*/
crocofuls(customGunLogic) {
if (typeof customGunLogic === 'function') {
this.emit('customGunLogicDefined', customGunLogic);
console.log("[Crocobras] Logique de tir personnalisée définie. Le développeur doit l'appeler !");
} else {
throw new Error("crocofuls: L'argument doit être une fonction.");
}
}
/**
* crocoanm: Ce package ne gère PAS les sons/musiques directement.
* Cette fonction est un simple émetteur d'événements pour indiquer au développeur
* qu'il est temps de jouer un son ou une musique.
* @param {string} soundType - Le type de son ('shot', 'crocoGrowl', 'musicLoop', 'gameOverSound').
*/
crocoanm(soundType) {
this.emit('playAnimationSound', soundType);
console.log(`[Crocobras] Événement de son émis : ${soundType}.`);
}
/**
* crocustom: Permet aux développeurs d'étendre la logique du jeu avec leurs propres fonctions.
* C'est une fonction "fourre-tout" pour la personnalisation avancée.
* Le développeur peut passer un objet de nouvelles fonctions ou un callback pour modifier le jeu.
* @param {Function|object} customization - Une fonction ou un objet contenant des personnalisations.
*/
crocustom(customization) {
if (typeof customization === 'function') {
customization(this); // Passe l'instance du jeu au développeur pour qu'il puisse interagir.
this.emit('gameCustomized', 'function');
} else if (typeof customization === 'object' && customization !== null) {
Object.assign(this, customization); // Fusionne les propriétés dans l'instance du jeu
this.emit('gameCustomized', 'object');
} else {
throw new Error("crocustom: L'argument doit être une fonction ou un objet.");
}
console.log("[Crocobras] Personnalisation avancée appliquée via crocustom.");
}
/**
* crocopow: Permet au développeur de créer ses propres power-ups avec sa logique JavaScript.
* @param {string} powerUpType - Type/nom du power-up personnalisé
* @param {Function} powerUpLogic - Fonction qui définit l'effet du power-up
* @param {Object} [options] - Options supplémentaires (durée, valeur, etc.)
*/
crocopow(powerUpType, powerUpLogic, options = {}) {
if (typeof powerUpLogic !== 'function') {
throw new Error("crocopow: powerUpLogic doit être une fonction.");
}
if (!this.customPowerUps) {
this.customPowerUps = {};
}
this.customPowerUps[powerUpType] = {
logic: powerUpLogic,
options: { duration: 5000, value: 1, ...options }
};
this.emit('customPowerUpRegistered', { type: powerUpType, options });
console.log(`[Crocobras] Power-up personnalisé '${powerUpType}' enregistré.`);
}
/**
* Déclenche un power-up personnalisé
* @param {string} powerUpType - Type du power-up à activer
*/
activatePowerUp(powerUpType) {
if (!this.customPowerUps || !this.customPowerUps[powerUpType]) {
console.warn(`[Crocobras] Power-up '${powerUpType}' non trouvé.`);
return false;
}
const powerUp = this.customPowerUps[powerUpType];
powerUp.logic.call(this, powerUp.options);
this.emit('powerUpActivated', { type: powerUpType, options: powerUp.options });
console.log(`[Crocobras] Power-up '${powerUpType}' activé !`);
return true;
}
/**
* crocoboost: Permet au développeur de créer des systèmes de boost temporaires ou de cadeaux.
* @param {string} boostType - Type de boost (ex: 'speedBoost', 'damageBoost', 'healthBoost')
* @param {number} value - Valeur du boost
* @param {number} duration - Durée en millisecondes
* @param {Function} [onExpire] - Callback appelé quand le boost expire
*/
crocoboost(boostType, value, duration, onExpire = null) {
if (!this.activeBoosts) {
this.activeBoosts = {};
}
// Appliquer le boost
this.activeBoosts[boostType] = {
value: value,
startTime: Date.now(),
duration: duration,
onExpire: onExpire
};
this.emit('boostActivated', { type: boostType, value, duration });
console.log(`[Crocobras] Boost '${boostType}' activé pour ${duration}ms avec valeur ${value}.`);
// Programmer l'expiration du boost
setTimeout(() => {
if (this.activeBoosts && this.activeBoosts[boostType]) {
delete this.activeBoosts[boostType];
if (onExpire) onExpire();
this.emit('boostExpired', { type: boostType });
console.log(`[Crocobras] Boost '${boostType}' expiré.`);
}
}, duration);
}
/**
* Vérifie si un boost est actif
* @param {string} boostType - Type de boost à vérifier
* @returns {boolean|Object} False si inactif, sinon retourne les données du boost
*/
getActiveBoost(boostType) {
return this.activeBoosts && this.activeBoosts[boostType] ? this.activeBoosts[boostType] : false;
}
/**
* crocolife: Permet au développeur de définir un système de points de vie pour les crocodiles.
* @param {number} crocoId - ID unique du crocodile
* @param {number} health - Points de vie du crocodile
* @param {Object} [options] - Options supplémentaires (maxHealth, regeneration, etc.)
*/
crocolife(crocoId, health, options = {}) {
if (!this.crocodileHealths) {
this.crocodileHealths = {};
}
this.crocodileHealths[crocoId] = {
currentHealth: health,
maxHealth: options.maxHealth || health,
regeneration: options.regeneration || 0,
lastRegenTime: Date.now(),
...options
};
this.emit('crocodileHealthSet', { crocoId, health, options });
console.log(`[Crocobras] Crocodile ${crocoId} a maintenant ${health} points de vie.`);
}
/**
* Inflige des dégâts à un crocodile spécifique
* @param {number} crocoId - ID du crocodile
* @param {number} damage - Dégâts à infliger
* @returns {boolean} True si le crocodile est mort, false sinon
*/
damageCrocodile(crocoId, damage) {
if (!this.crocodileHealths || !this.crocodileHealths[crocoId]) {
// Si pas de système de vie défini, comportement par défaut (mort en 1 coup)
return this.crocokill();
}
const croco = this.crocodileHealths[crocoId];
croco.currentHealth = nekomaths.neksub(croco.currentHealth, damage);
this.emit('crocodileDamaged', { crocoId, damage, remainingHealth: croco.currentHealth });
console.log(`[Crocobras] Crocodile ${crocoId} reçoit ${damage} dégâts. Vie restante: ${croco.currentHealth}`);
if (croco.currentHealth <= 0) {
delete this.crocodileHealths[crocoId];
this.emit('crocodileKilledByDamage', { crocoId });
return this.crocokill();
}
return false;
}
/**
* crocoarmure: Permet au développeur de personnaliser la force des crocodiles.
* @param {number} crocoId - ID du crocodile
* @param {number} strength - Force/armure du crocodile
* @param {Function} [strengthLogic] - Logique personnalisée pour calculer la force
*/
crocoarmure(crocoId, strength, strengthLogic = null) {
if (!this.crocodileStrengths) {
this.crocodileStrengths = {};
}
this.crocodileStrengths[crocoId] = {
baseStrength: strength,
currentStrength: strength,
strengthLogic: strengthLogic,
lastUpdate: Date.now()
};
this.emit('crocodileStrengthSet', { crocoId, strength });
console.log(`[Crocobras] Crocodile ${crocoId} a maintenant une force de ${strength}.`);
}
/**
* Met à jour la force d'un crocodile selon sa logique personnalisée
* @param {number} crocoId - ID du crocodile
* @param {Object} [context] - Contexte pour la logique (niveau, temps, etc.)
*/
updateCrocodileStrength(crocoId, context = {}) {
if (!this.crocodileStrengths || !this.crocodileStrengths[crocoId]) return;
const croco = this.crocodileStrengths[crocoId];
if (croco.strengthLogic) {
const newStrength = croco.strengthLogic.call(this, croco.currentStrength, context);
croco.currentStrength = newStrength;
croco.lastUpdate = Date.now();
this.emit('crocodileStrengthUpdated', { crocoId, newStrength, context });
console.log(`[Crocobras] Force du crocodile ${crocoId} mise à jour: ${newStrength}`);
}
}
/**
* crocorap: Permet aux développeurs de personnaliser la vitesse des crocodiles.
* @param {number} crocoId - ID du crocodile
* @param {number} speed - Vitesse du crocodile
* @param {Function} [speedModifier] - Fonction pour modifier la vitesse dynamiquement
*/
crocorap(crocoId, speed, speedModifier = null) {
if (!this.crocodileSpeeds) {
this.crocodileSpeeds = {};
}
this.crocodileSpeeds[crocoId] = {
baseSpeed: speed,
currentSpeed: speed,
speedModifier: speedModifier,
lastUpdate: Date.now()
};
this.emit('crocodileSpeedSet', { crocoId, speed });
console.log(`[Crocobras] Crocodile ${crocoId} a maintenant une vitesse de ${speed}.`);
}
/**
* Met à jour la vitesse d'un crocodile
* @param {number} crocoId - ID du crocodile
* @param {Object} [factors] - Facteurs influençant la vitesse (niveau, boosts, etc.)
*/
updateCrocodileSpeed(crocoId, factors = {}) {
if (!this.crocodileSpeeds || !this.crocodileSpeeds[crocoId]) return;
const croco = this.crocodileSpeeds[crocoId];
if (croco.speedModifier) {
const newSpeed = croco.speedModifier.call(this, croco.baseSpeed, factors);
croco.currentSpeed = newSpeed;
croco.lastUpdate = Date.now();
this.emit('crocodileSpeedUpdated', { crocoId, newSpeed, factors });
console.log(`[Crocobras] Vitesse du crocodile ${crocoId} mise à jour: ${newSpeed}`);
}
}
/**
* crocopop: Permet au développeur de créer des systèmes de danse/esquive sur les crocodiles.
* @param {number} crocoId - ID du crocodile
* @param {string} danceType - Type de danse/mouvement ('dodge', 'spin', 'jump', etc.)
* @param {Function} danceLogic - Logique de la danse/esquive
* @param {Object} [options] - Options (durée, probabilité d'esquive, etc.)
*/
crocopop(crocoId, danceType, danceLogic, options = {}) {
if (typeof danceLogic !== 'function') {
throw new Error("crocopop: danceLogic doit être une fonction.");
}
if (!this.crocodileDances) {
this.crocodileDances = {};
}
if (!this.crocodileDances[crocoId]) {
this.crocodileDances[crocoId] = {};
}
this.crocodileDances[crocoId][danceType] = {
logic: danceLogic,
options: { duration: 1000, dodgeChance: 0.3, ...options },
isActive: false
};
this.emit('crocodileDanceRegistered', { crocoId, danceType, options });
console.log(`[Crocobras] Danse '${danceType}' enregistrée pour le crocodile ${crocoId}.`);
}
/**
* Déclenche une danse/esquive pour un crocodile
* @param {number} crocoId - ID du crocodile
* @param {string} danceType - Type de danse à exécuter
* @returns {boolean} True si la danse a été déclenchée, false sinon
*/
triggerCrocodileDance(crocoId, danceType) {
if (!this.crocodileDances || !this.crocodileDances[crocoId] || !this.crocodileDances[crocoId][danceType]) {
return false;
}
const dance = this.crocodileDances[crocoId][danceType];
if (dance.isActive) return false; // Déjà en cours
dance.isActive = true;
const result = dance.logic.call(this, crocoId, dance.options);
this.emit('crocodileDanceTriggered', { crocoId, danceType, result });
console.log(`[Crocobras] Crocodile ${crocoId} exécute la danse '${danceType}'.`);
// Fin automatique de la danse après la durée
setTimeout(() => {
if (this.crocodileDances && this.crocodileDances[crocoId] && this.crocodileDances[crocoId][danceType]) {
this.crocodileDances[crocoId][danceType].isActive = false;
this.emit('crocodileDanceEnded', { crocoId, danceType });
}
}, dance.options.duration);
return true;
}
/**
* crocoexplose: Fait exploser un crocodile à sa mort, infligeant des dégâts de zone.
* @param {number} crocoId - ID du crocodile qui explose
* @param {number} explosionDamage - Dégâts de l'explosion
* @param {number} explosionRadius - Rayon de l'explosion
* @param {Function} [explosionLogic] - Logique personnalisée d'explosion
*/
crocoexplose(crocoId, explosionDamage, explosionRadius, explosionLogic = null) {
const explosion = {
damage: explosionDamage,
radius: explosionRadius,
logic: explosionLogic,
source: crocoId
};
// Si logique personnalisée fournie, l'utiliser
if (explosionLogic && typeof explosionLogic === 'function') {
explosionLogic.call(this, explosion);
} else {
// Logique par défaut : dégâts au bras si dans le rayon
this.handleDefaultExplosion(explosion);
}
this.emit('crocodileExploded', {
crocoId,
damage: explosionDamage,
radius: explosionRadius
});
console.log(`[Crocobras] Crocodile ${crocoId} explose ! Dégâts: ${explosionDamage}, Rayon: ${explosionRadius}`);
}
/**
* Gère l'explosion par défaut (dégâts au bras)
* @private
*/
handleDefaultExplosion(explosion) {
// Dans un vrai jeu, on vérifierait la distance entre l'explosion et les cibles
// Ici, on simule des dégâts au bras
const armDamage = Math.floor(explosion.damage * 0.5); // 50% des dégâts à l'explosion
this.armHealth = nekomaths.neksub(this.armHealth, armDamage);
this.emit('explosionDamageToArm', {
damage: armDamage,
source: explosion.source,
currentArmHealth: this.armHealth
});
console.log(`[Crocobras] L'explosion inflige ${armDamage} dégâts au bras. Vie restante: ${this.armHealth}`);
if (this.armHealth <= 0) {
this.crocover();
}
}
/**
* Version améliorée de crocokill qui prend en compte les nouvelles mécaniques
* @param {number} [crocoId] - ID spécifique du crocodile tué (optionnel)
* @returns {boolean} True si un crocodile a été tué, false sinon
*/
crocokillAdvanced(crocoId = null) {
const killed = this.crocokill(); // Appel de la fonction originale
if (killed && crocoId) {
// Nettoyer les données du crocodile mort
if (this.crocodileHealths && this.crocodileHealths[crocoId]) {
delete this.crocodileHealths[crocoId];
}
if (this.crocodileStrengths && this.crocodileStrengths[crocoId]) {
delete this.crocodileStrengths[crocoId];
}
if (this.crocodileSpeeds && this.crocodileSpeeds[crocoId]) {
delete this.crocodileSpeeds[crocoId];
}
if (this.crocodileDances && this.crocodileDances[crocoId]) {
delete this.crocodileDances[crocoId];
}
this.emit('crocodileDataCleared', { crocoId });
}
return killed;
}
/**
* crocom: Permet d'écrire des systèmes de combo qui augmentent le score ou déclenchent des effets spéciaux.
* @param {string} comboType - Type de combo (ex: 'killStreak', 'perfectAim', 'rapidKills')
* @param {Function} comboLogic - Logique du combo qui gère le déclenchement et les effets
* @param {Object} [options] - Options du combo (seuil, multiplicateur, durée, etc.)
*/
crocom(comboType, comboLogic, options = {}) {
if (typeof comboLogic !== 'function') {
throw new Error("crocom: comboLogic doit être une fonction.");
}
if (!this.combos) {
this.combos = {};
this.comboCounters = {};
}
this.combos[comboType] = {
logic: comboLogic,
options: {
threshold: 3,
multiplier: 1.5,
resetTime: 5000,
maxLevel: 10,
...options
},
isActive: false,
level: 0
};
this.comboCounters[comboType] = 0;
this.emit('comboRegistered', { type: comboType, options });
console.log(`[Crocobras] Combo '${comboType}' enregistré.`);
}
/**
* Déclenche la vérification d'un combo
* @param {string} comboType - Type de combo à vérifier
* @param {Object} [context] - Contexte pour la logique du combo
*/
triggerCombo(comboType, context = {}) {
if (!this.combos || !this.combos[comboType]) return false;
const combo = this.combos[comboType];
this.comboCounters[comboType]++;
const result = combo.logic.call(this, this.comboCounters[comboType], combo.options, context);
if (result && this.comboCounters[comboType] >= combo.options.threshold) {
combo.isActive = true;
combo.level = Math.min(combo.level + 1, combo.options.maxLevel);
this.emit('comboTriggered', {
type: comboType,
level: combo.level,
counter: this.comboCounters[comboType],
result: result
});
console.log(`[Crocobras] Combo '${comboType}' niveau ${combo.level} déclenché !`);
// Reset automatique après un délai
setTimeout(() => {
this.resetCombo(comboType);
}, combo.options.resetTime);
}
return result;
}
/**
* Remet à zéro un combo
* @param {string} comboType - Type de combo à reset
*/
resetCombo(comboType) {
if (this.combos && this.combos[comboType]) {
this.combos[comboType].isActive = false;
this.combos[comboType].level = 0;
this.comboCounters[comboType] = 0;
this.emit('comboReset', { type: comboType });
console.log(`[Crocobras] Combo '${comboType}' remis à zéro.`);
}
}
/**
* crocomode: Permet aux développeurs de créer leurs propres modes de défis.
* @param {string} modeName - Nom du mode de défi
* @param {Function} modeLogic - Logique personnalisée du mode
* @param {Object} [settings] - Paramètres spécifiques au mode
*/
crocomode(modeName, modeLogic, settings = {}) {
if (typeof modeLogic !== 'function') {
throw new Error("crocomode: modeLogic doit être une fonction.");
}
if (!this.gameModes) {
this.gameModes = {};
}
this.gameModes[modeName] = {
logic: modeLogic,
settings: {
timeLimit: null,
objectives: [],
rewards: {},
difficulty: 'normal',
...settings
},
isActive: false,
progress: {}
};
this.emit('gameModeRegistered', { name: modeName, settings });
console.log(`[Crocobras] Mode de jeu '${modeName}' enregistré.`);
}
/**
* Active un mode de jeu spécifique
* @param {string} modeName - Nom du mode à activer
* @param {Object} [parameters] - Paramètres d'activation
*/
activateGameMode(modeName, parameters = {}) {
if (!this.gameModes || !this.gameModes[modeName]) {
console.warn(`[Crocobras] Mode '${modeName}' non trouvé.`);
return false;
}
const mode = this.gameModes[modeName];
mode.isActive = true;
mode.progress = { startTime: Date.now(), ...parameters };
mode.logic.call(this, mode.settings, mode.progress);
this.emit('gameModeActivated', { name: modeName, settings: mode.settings, progress: mode.progress });
console.log(`[Crocobras] Mode '${modeName}' activé !`);
return true;
}
/**
* crocorpes: Permet aux développeurs de créer des armures avec des propriétés spéciales.
* @param {string} armorType - Type d'armure
* @param {Object} properties - Propriétés de l'armure
* @param {Function} [armorLogic] - Logique personnalisée de l'armure
*/
crocorpes(armorType, properties, armorLogic = null) {
if (!this.armors) {
this.armors = {};
this.equippedArmor = null;
}
this.armors[armorType] = {
properties: {
defense: 0,
resistance: {},
effects: [],
durability: 100,
...properties
},
logic: armorLogic,
isEquipped: false
};
this.emit('armorCreated', { type: armorType, properties });
console.log(`[Crocobras] Armure '${armorType}' créée.`);
}
/**
* Équipe une armure
* @param {string} armorType - Type d'armure à équiper
*/
equipArmor(armorType) {
if (!this.armors || !this.armors[armorType]) return false;
// Déséquiper l'armure actuelle
if (this.equippedArmor) {
this.armors[this.equippedArmor].isEquipped = false;
}
// Équiper la nouvelle armure
this.armors[armorType].isEquipped = true;
this.equippedArmor = armorType;
// Appliquer la logique de l'armure si elle existe
if (this.armors[armorType].logic) {
this.armors[armorType].logic.call(this, this.armors[armorType].properties);
}
this.emit('armorEquipped', { type: armorType, properties: this.armors[armorType].properties });
console.log(`[Crocobras] Armure '${armorType}' équipée.`);
return true;
}
/**
* crocodial: Permet aux développeurs de créer leurs propres dialogues personnalisés.
* @param {string} dialogueId - Identifiant unique du dialogue
* @param {Object} dialogueData - Données du dialogue (textes, choix, conditions)
* @param {Function} [dialogueLogic] - Logique personnalisée du dialogue
*/
crocodial(dialogueId, dialogueData, dialogueLogic = null) {
if (!this.dialogues) {
this.dialogues = {};
this.currentDialogue = null;
}
this.dialogues[dialogueId] = {
data: {
texts: [],
choices: [],
conditions: {},
speaker: 'narrator',
...dialogueData
},
logic: dialogueLogic,
isActive: false,
currentStep: 0
};
this.emit('dialogueCreated', { id: dialogueId, data: dialogueData });
console.log(`[Crocobras] Dialogue '${dialogueId}' créé.`);
}
/**
* Lance un dialogue
* @param {string} dialogueId - ID du dialogue à lancer
* @param {Object} [context] - Contexte pour le dialogue
*/
startDialogue(dialogueId, context = {}) {
if (!this.dialogues || !this.dialogues[dialogueId]) return false;
const dialogue = this.dialogues[dialogueId];
dialogue.isActive = true;
dialogue.currentStep = 0;
this.currentDialogue = dialogueId;
if (dialogue.logic) {
dialogue.logic.call(this, dialogue.data, context);
}
this.emit('dialogueStarted', {
id: dialogueId,
data: dialogue.data,
context: context
});
console.log(`[Crocobras] Dialogue '${dialogueId}' démarré.`);
return true;
}
/**
* crocomise: Permet aux développeurs d'écrire des logiques de missions ou quêtes.
* @param {string} missionId - ID unique de la mission
* @param {Object} missionData - Données de la mission (objectifs, récompenses, etc.)
* @param {Function} missionLogic - Logique personnalisée de la mission
*/
crocomise(missionId, missionData, missionLogic) {
if (typeof missionLogic !== 'function') {
throw new Error("crocomise: missionLogic doit être une fonction.");
}
if (!this.missions) {
this.missions = {};
this.activeMissions = [];
this.completedMissions = [];
}
this.missions[missionId] = {
data: {
title: 'Mission sans titre',
description: '',
objectives: [],
rewards: {},
difficulty: 'normal',
timeLimit: null,
...missionData
},
logic: missionLogic,
status: 'available', // available, active, completed, failed
progress: {},
startTime: null
};
this.emit('missionCreated', { id: missionId, data: missionData });
console.log(`[Crocobras] Mission '${missionId}' créée.`);
}
/**
* Démarre une mission
* @param {string} missionId - ID de la mission à démarrer
*/
startMission(missionId) {
if (!this.missions || !this.missions[missionId]) return false;
const mission = this.missions[missionId];
if (mission.status !== 'available') return false;
mission.status = 'active';
mission.startTime = Date.now();
mission.progress = {};
this.activeMissions.push(missionId);
mission.logic.call(this, mission.data, mission.progress);
this.emit('missionStarted', {
id: missionId,
data: mission.data,
progress: mission.progress
});
console.log(`[Crocobras] Mission '${missionId}' démarrée.`);
return true;
}
/**
* Complète une mission
* @param {string} missionId - ID de la mission à compléter
* @param {Object} [results] - Résultats de la mission
*/
completeMission(missionId, results = {}) {
if (!this.missions || !this.missions[missionId]) return false;
const mission = this.missions[missionId];
if (mission.status !== 'active') return false;
mission.status = 'completed';
this.activeMissions = this.activeMissions.filter(id => id !== missionId);
this.completedMissions.push(missionId);
this.emit('missionCompleted', {
id: missionId,
data: mission.data,
results: results,
rewards: mission.data.rewards
});
console.log(`[Crocobras] Mission '${missionId}' terminée !`);
return true;
}
/**
* crocomons: Permet aux développeurs de créer leurs propres systèmes de monnaie et boutique.
* @param {string} currencyName - Nom de la monnaie
* @param {Object} shopData - Données de la boutique (articles, prix, etc.)
* @param {Function} purchaseLogic - Logique d'achat personnalisée
*/
crocomons(currencyName, shopData, purchaseLogic) {
if (typeof purchaseLogic !== 'function') {
throw new Error("crocomons: purchaseLogic doit être une fonction.");
}
if (!this.economy) {
this.economy = {
currencies: {},
shop: {},
inventory: {},
transactions: []
};
}
this.economy.currencies[currencyName] = {
amount: shopData.startingAmount || 0,
properties: shopData.currencyProperties || {}
};
this.economy.shop[currencyName] = {
items: shopData.items || [],
logic: purchaseLogic,
settings: shopData.settings || {}
};
this.emit('economySystemCreated', { currency: currencyName, shopData });
console.log(`[Crocobras] Système économique '${currencyName}' créé.`);
}
/**
* Effectue un achat dans la boutique
* @param {string} currencyName - Nom de la monnaie utilisée
* @param {string} itemId - ID de l'article à acheter
* @param {number} [quantity] - Quantité à acheter
*/
purchase(currencyName, itemId, quantity = 1) {
if (!this.economy || !this.economy.shop[currencyName]) return false;
const shop = this.economy.shop[currencyName];
const currency = this.economy.currencies[currencyName];
const result = shop.logic.call(this, {
itemId: itemId,
quantity: quantity,
currency: currency,
inventory: this.economy.inventory,
shop: shop
});
if (result.success) {
this.economy.transactions.push({
timestamp: Date.now(),
type: 'purchase',
currencyName: currencyName,
itemId: itemId,
quantity: quantity,
cost: result.cost
});
this.emit('purchaseCompleted', {
currencyName,
itemId,
quantity,
result
});
console.log(`[Crocobras] Achat réussi: ${quantity}x ${itemId}`);
}
return result;
}
/**
* crocodym: Permet aux développeurs de coder des logiques de changements environnementaux.
* @param {string} environmentId - ID de l'environnement
* @param {Object} environmentData - Données de l'environnement
* @param {Function} environmentLogic - Logique des changements environnementaux
*/
crocodym(environmentId, environmentData, environmentLogic) {
if (typeof environmentLogic !== 'function') {
throw new Error("crocodym: environmentLogic doit être une fonction.");
}
if (!this.environments) {
this.environments = {};
this.currentEnvironment = null;
}
this.environments[environmentId] = {
data: {
obstacles: [],
effects: [],
climate: 'normal',
visibility: 1.0,
...environmentData
},
logic: environmentLogic,
isActive: false,
lastUpdate: Date.now()
};
this.emit('environmentCreated', { id: environmentId, data: environmentData });
console.log(`[Crocobras] Environnement '${environmentId}' créé.`);
}
/**
* Active un environnement
* @param {string} environmentId - ID de l'environnement à activer
* @param {Object} [parameters] - Paramètres d'activation
*/
activateEnvironment(environmentId, parameters = {}) {
if (!this.environments || !this.environments[environmentId]) return false;
// Désactiver l'environnement actuel
if (this.currentEnvironment) {
this.environments[this.currentEnvironment].isActive = false;
}
const environment = this.environments[environmentId];
environment.isActive = true;
environment.lastUpdate = Date.now();
this.currentEnvironment = environmentId;
environment.logic.call(this, environment.data, parameters);
this.emit('environmentActivated', {
id: environmentId,
data: environment.data,
parameters
});
console.log(`[Crocobras] Environnement '${environmentId}' activé.`);
return true;
}
/**
* crocopay: Permet aux développeurs de scripter des logiques pour des changements d'assets personnalisés.
* @param {string} assetType - Type d'asset (background, crocodile, arm, etc.)
* @param {Object} assetData - Données de l'asset
* @param {Function} customizationLogic - Logique de personnalisation
*/
crocopay(assetType, assetData, customizationLogic) {
if (typeof customizationLogic !== 'function') {
throw new Error("crocopay: customizationLogic doit être une fonction.");
}
if (!this.assetCustomization) {
this.assetCustomization = {};
this.equippedAssets = {};
}
if (!this.assetCustomization[assetType]) {
this.assetCustomization[assetType] = {};
}
const assetId = assetData.id || `${assetType}_${Date.now()}`;
this.assetCustomization[assetType][assetId] = {
data: {
name: assetData.name || 'Asset sans nom',
rarity: assetData.rarity || 'common',
unlocked: assetData.unlocked || false,
price: assetData.price || 0,
...assetData
},
logic: customizationLogic,
isEquipped: false
};
this.emit('assetCreated', { type: assetType, id: assetId, data: assetData });
console.log(`[Crocobras] Asset '${assetId}' de type '${assetType}' créé.`);
}
/**
* Équipe un asset personnalisé
* @param {string} assetType - Type d'asset
* @param {string} assetId - ID de l'asset à équiper
*/
equipAsset(assetType, assetId) {
if (!this.assetCustomization || !this.assetCustomization[assetType] || !this.assetCustomization[assetType][assetId]) {
return false;
}
const asset = this.assetCustomization[assetType][assetId];
if (!asset.data.unlocked) return false;
// Déséquiper l'asset actuel du même type
if (this.equippedAssets[assetType]) {
const currentAsset = this.assetCustomization[assetType][this.equippedAssets[assetType]];
if (currentAsset) currentAsset.isEquipped = false;
}
// Équiper le nouvel asset
asset.isEquipped = true;
this.equippedAssets[assetType] = assetId;
asset.logic.call(this, asset.data);
this.emit('assetEquipped', { type: assetType, id: assetId, data: asset.data });
console.log(`[Crocobras] Asset '${assetId}' équipé pour '${assetType}'.`);
return true;
}
/**
* crocia: Permet aux développeurs de coder des comportements IA personnalisés pour les crocodiles.
* @param {number} crocoId - ID du crocodile
* @param {string} aiType - Type d'IA (aggressive, defensive, smart, random, etc.)
* @param {Function} aiLogic - Logique de l'IA personnalisée
* @param {Object} [aiSettings] - Paramètres de l'IA
*/
crocia(crocoId, aiType, aiLogic, aiSettings = {}) {
if (typeof aiLogic !== 'function') {
throw new Error("crocia: aiLogic doit être une fonction.");
}
if (!this.crocodileAI) {
this.crocodileAI = {};
}
this.crocodileAI[crocoId] = {
type: aiType,
logic: aiLogic,
settings: {
aggressiveness: 0.5,
intelligence: 0.5,
adaptability: 0.3,
memory: [],
...aiSettings
},
state: 'idle',
lastDecision: Date.now(),
decisions: []
};
this.emit('crocodileAISet', { crocoId, aiType, settings: aiSettings });
console.log(`[Crocobras] IA '${aiType}' configurée pour le crocodile ${crocoId}.`);
}
/**
* Met à jour l'IA d'un crocodile
* @param {number} crocoId - ID du crocodile
* @param {Object} [context] - Contexte pour la prise de décision
*/
updateCrocodileAI(crocoId, context = {}) {
if (!this.crocodileAI || !this.crocodileAI[crocoId]) return;
const ai = this.crocodileAI[crocoId];
const gameState = this.getGameState();
const decision = ai.logic.call(this, {
crocoId: crocoId,
gameState: gameState,
aiState: ai.state,
settings: ai.settings,
memory: ai.settings.memory,
context: context
});
if (decision) {
ai.state = decision.newState || ai.state;
ai.lastDecision = Date.now();
ai.decisions.push({
timestamp: Date.now(),
decision: decision,
context: context
});
// Garder seulement les 10 dernières décisions en mémoire
if (ai.decisions.length > 10) {
ai.decisions.shift();
}
this.emit('crocodileAIDecision', {
crocoId,
decision,
aiType: ai.type,
context
});
}
}
/**
* crocohab: Permet aux développeurs de scripter des logiques d'accessoires à collecter ou de succès.
* @param {string} collectibleType - Type de collectible (achievement, item, trophy, etc.)
* @param {Object} collectibleData - Données du collectible
* @param {Function} collectibleLogic - Logique de collecte personnalisée
*/
crocohab(collectibleType, collectibleData, collectibleLogic) {
if (typeof collectibleLogic !== 'function') {
throw new Error("crocohab: collectibleLogic doit être une fonction.");
}
if (!this.collectibles) {
this.collectibles = {};
this.unlockedCollectibles = [];
}
if (!this.collectibles[collectibleType]) {
this.collectibles[collectibleType] = {};
}
const collectibleId = collectibleData.id || `${collectibleType}_${Date.now()}`;
this.collectibles[collectibleType][collectibleId] = {
data: {
name: collectibleData.name || 'Collectible sans nom',
description: collectibleData.description || '',
rarity: collectibleData.rarity || 'common',
rewards: collectibleData.rewards || {},
requirements: collectibleData.requirements || {},
...collectibleData
},
logic: collectibleLogic,
isUnlocked: false,
unlockedAt: null,
progress: {}
};
this.emit('collectibleCreated', { type: collectibleType, id: collectibleId, data: collectibleData });
console.log(`[Crocobras] Collectible '${collectibleId}' de type '${collectibleType}' créé.`);
}
/**
* Vérifie et débloque des collectibles
* @param {string} collectibleType - Type de collectible à vérifier
* @param {Object} [context] - Contexte pour la vérification
*/
checkCollectibles(collectibleType, context = {}) {
if (!this.collectibles || !this.collectibles[collectibleType]) return;
Object.entries(this.collectibles[collectibleType]).forEach(([id, collectible]) => {
if (!collectible.isUnlocked) {
const result = collectible.logic.call(this, {
collectibleData: collectible.data,
gameState: this.getGameState(),
context: context,
progress: collectible.progress
});
if (result && result.unlocked) {
collectible.isUnlocked = true;
collectible.unlockedAt = Date.now();
collectible.progress = result.progress || {};
this.unlockedCollectibles.push(`${collectibleType}:${id}`);
this.emit('collectibleUnlocked', {
type: collectibleType,
id: id,
data: collectible.data,
rewards: collectible.data.rewards
});
console.log(`[Crocobras] Collectible '${id}' débloqué !`);
}
}
});
}
/**
* crocotive: Fonction créative pour des messages aléatoires envoyés par différents personnages.
* @param {string} messageType - Type de message (crocodile, arm, narrator, etc.)
* @param {Object} messageData - Données des messages
* @param {Function} messageLogic - Logique de sélection des messages
*/
crocotive(messageType, messageData, messageLogic) {
if (typeof messageLogic !== 'function') {
throw new Error("crocotive: messageLogic doit être une fonction.");
}
if (!this.creativeMessages) {
this.creativeMessages = {};
}
this.creativeMessages[messageType] = {
data: {
messages: messageData.messages || [],
frequency: messageData.frequency || 'random',
conditions: messageData.conditions || {},
speakers: messageData.speakers || [messageType],
...messageData
},
logic: messageLogic,
lastMessage: null,
messageHistory: []
};
this.emit('creativeMessagesRegistered', { type: messageType, data: messageData });
console.log(`[Crocobras] Messages créatifs '${messageType}' enregistrés.`);
}
/**
* Déclenche un message créatif
* @param {string} messageType - Type de message à déclencher
* @param {Object} [context] - Contexte pour la sélection du message
*/
triggerCreativeMessage(messageType, context = {}) {
if (!this.creativeMessages || !this.creativeMessages[messageType]) return null;
const messageSystem = this.creativeMessages[messageType];
const gameState = this.getGameState();
const result = messageSystem.logic.call(this, {
messageData: messageSystem.data,
gameState: gameState,
context: context,
history: messageSystem.messageHistory
});
if (result && result.message) {
messageSystem.lastMessage = {
timestamp: Date.now(),
message: result.message,
speaker: result.speaker || messageType,
context: context
};
messageSystem.messageHistory.push(messageSystem.lastMessage);
// Garder seulement les 20 derniers messages
if (messageSystem.messageHistory.length > 20) {
messageSystem.messageHistory.shift();
}
this.emit('creativeMessageTriggered', {
type: messageType,
message: result.message,
speaker: result.speaker,
context: context
});
console.log(`[Crocobras] Message créatif (${result.speaker}): ${result.message}`);
return result;
}
return null;
}
/**
* croconage: Permet aux développeurs de créer leurs propres personnages personnalisés.
* @param {string} characterId - ID unique du personnage
* @param {Object} characterData - Données du personnage
* @param {Function} characterLogic - Logique de comportement du personnage
*/
croconage(characterId, characterData, characterLogic) {
if (typeof characterLogic !== 'function') {
throw new Error("croconage: characterLogic doit être une fonction.");
}
if (!this.customCharacters) {
this.customCharacters = {};
this.activeCharacters = [];
}
this.customCharacters[characterId] = {
data: {
name: characterData.name || 'Personnage sans nom',
type: characterData.type || 'neutral',
health: characterData.health || 100,
abilities: characterData.abilities || [],
appearance: characterData.appearance || {},
personality: characterData.personality || {},
...characterData
},
logic: characterLogic,
isActive: false,
state: 'idle',
interactions: [],
lastUpdate: Date.now()
};
this.emit('customCharacterCreated', { id: characterId, data: characterData });
console.log(`[Crocobras] Personnage personnalisé '${characterId}' créé.`);
}
/**
* Active un personnage personnalisé
* @param {string} characterId - ID du personnage à activer
* @param {Object} [spawnData] - Données d'apparition
*/
spawnCharacter(characterId, spawnData = {}) {
if (!this.customCharacters || !this.customCharacters[characterId]) return false;
const character = this.customCharacters[characterId];
if (character.isActive) return false;
character.isActive = true;
character.state = spawnData.initialState || 'idle';
character.lastUpdate = Date.now();
if (!this.activeCharacters.includes(characterId)) {
this.activeCharacters.push(characterId);
}
character.logic.call(this, {
characterData: character.data,
gameState: this.getGameState(),
spawnData: spawnData,
action: 'spawn'
});
this.emit('characterSpawned', {
id: characterId,
data: character.data,
spawnData: spawnData
});
console.log(`[Crocobras] Personnage '${characterId}' apparu dans le jeu.`);
return true;
}
/**
* Met à jour un personnage personnalisé
* @param {string} characterId - ID du personnage à mettre à jour
* @param {Object} [updateData] - Données de mise à jour
*/
updateCharacter(characterId, updateData = {}) {
if (!this.customCharacters || !this.customCharacters[characterId] || !this.customCharacters[characterId].isActive) {
return;
}
const character = this.customCharacters[characterId];
character.lastUpdate = Date.now();
const result = character.logic.call(this, {
characterData: character.data,
gameState: this.getGameState(),
updateData: updateData,
currentState: character.state,
action: 'update'
});
if (result) {
character.state = result.newState || character.state;
if (result.interaction) {
character.interactions.push({
timestamp: Date.now(),
interaction: result.interaction,
context: updateData
});
}
this.emit('characterUpdated', {
id: characterId,
state: character.state,
result: result
});
}
}
// ================= NOUVELLES FONCTIONNALITÉS v1.3.0 =================
/**
* crocojom: Permet aux développeurs de créer des quêtes et missions dynamiques qui s'adaptent aux choix des joueurs.
* @param {string} questId - ID unique de la quête
* @param {Object} questData - Données de la quête (objectifs, branches, récompenses)
* @param {Function} questLogic - Logique personnalisée de la quête dynamique
*/
crocojom(questId, questData, questLogic) {
if (typeof questLogic !== 'function') {
throw new Error("crocojom: questLogic doit être une fonction.");
}
if (!this.dynamicQuests) {
this.dynamicQuests = {};
this.activeQuests = [];
}
this.dynamicQuests[questId] = {
data: {
title: questData.title || 'Quête dynamique',
description: questData.description || '',
branches: questData.branches || {},
currentBranch: questData.startBranch || 'start',
playerChoices: [],
rewards: questData.rewards || {},
conditions: questData.conditions || {},
...questData
},
logic: questLogic,
isActive: false,
progress: {}
};
this.emit('dynamicQuestCreated', { questId, data: questData });
console.log(`[Crocobras] Quête dynamique '${questId}' créée.`);
}
/**
* Démarre une quête dynamique
* @param {string} questId - ID de la quête à démarrer
* @param {Object} [initialChoices] - Choix initiaux du joueur
*/
startDynamicQuest(questId, initialChoices = {}) {
if (!this.dynamicQuests || !this.dynamicQuests[questId]) return false;
const quest = this.dynamicQuests[questId];
quest.isActive = true;
quest.data.playerChoices = [initialChoices];
quest.progress = { startTime: Date.now() };
this.activeQuests.push(questId);
quest.logic.call(this, quest.data, quest.progress, 'start');
this.emit('dynamicQuestStarted', { questId, choices: initialChoices });
console.log(`[Crocobras] Quête dynamique '${questId}' démarrée.`);
return true;
}
/**
* Effectue un choix dans une quête dynamique
* @param {string} questId - ID de la quête
* @param {Object} choice - Choix du joueur
*/
makeDynamicQuestChoice(questId, choice) {
if (!this.dynamicQuests || !this.dynamicQuests[questId] || !this.dynamicQuests[questId].isActive) {
return false;
}
const quest = this.dynamicQuests[questId];
quest.data.playerChoices.push(choice);
const result = quest.logic.call(this, quest.data, quest.progress, 'choice', choice);
if (result && result.newBranch) {
quest.data.currentBranch = result.newBranch;
}
this.emit('dynamicQuestChoice', { questId, choice, result });
console.log(`[Crocobras] Choix effectué dans la quête '${questId}': ${JSON.stringify(choice)}`);
return result;
}
/**
* crocera: Permet aux développeurs de créer leur propre système de climat qui interagit avec le comportement des crocodiles ou du bras.
* @param {string} weatherId - ID unique du climat
* @param {Object} weatherData - Données météorologiques
* @param {Function} weatherLogic - Logique personnalisée du climat
*/
crocera(weatherId, weatherData, weatherLogic) {
if (typeof weatherLogic !== 'function') {
throw new Error("crocera: weatherLogic doit être une fonction.");
}
if (!this.weatherSystems) {
this.weatherSystems = {};
this.currentWeather = null;
}
this.weatherSystems[weatherId] = {
data: {
name: weatherData.name || 'Climat personnalisé',
effects: weatherData.effects || {},
intensity: weatherData.intensity || 1.0,
duration: weatherData.duration || 30000,
crocodileEffects: weatherData.crocodileEffects || {},
armEffects: weatherData.armEffects || {},
visualEffects: weatherData.visualEffects || {},
...weatherData
},
logic: weatherLogic,
isActive: false,
startTime: null
};
this.emit('weatherSystemCreated', { weatherId, data: weatherData });
console.log(`[Crocobras] Système climatique '${weatherId}' créé.`);
}
/**
* Active un système climatique
* @param {string} weatherId - ID du climat à activer
*/
activateWeather(weatherId) {
if (!this.weatherSystems || !this.weatherSystems[weatherId]) return false;
// Désactiver le climat actuel
if (this.currentWeather) {
this.weatherSystems[this.currentWeather].isActive = false;
}
const weather = this.weatherSystems[weatherId];
weather.isActive = true;
weather.startTime = Date.now();
this.currentWeather = weatherId;
weather.logic.call(this, weather.data, this.getGameState());
this.emit('weatherActivated', { weatherId, data: weather.data });
console.log(`[Crocobras] Climat '${weatherId}' activé.`);
// Désactiver automatiquement après la durée
if (weather.data.duration > 0) {
setTimeout(() => {
this.deactivateWeather(weatherId);
}, weather.data.duration);
}
return true;
}
/**
* Désactive un système climatique
* @param {string} weatherId - ID du climat à désactiver
*/
deactivateWeather(weatherId) {
if (!this.weatherSystems || !this.weatherSystems[weatherId]) return false;
this.weatherSystems[weatherId].isActive = false;
if (this.currentWeather === weatherId) {
this.currentWeather = null;
}
this.emit('weatherDeactivated', { weatherId });
console.log(`[Crocobras] Climat '${weatherId}' désactivé.`);
return true;
}
/**
* crocogiw: Permet aux développeurs de créer des crocodiles ou des événements spéciaux qui n'apparaissent qu'à certains moments clés.
* @param {string} specialId - ID de l'élément spécial
* @param {Object} specialData - Données de l'élément spécial
* @param {Function} specialLogic - Logique de déclenchement personnalisée
*/
crocogiw(specialId, specialData, specialLogic) {
if (typeof specialLogic !== 'function') {
throw new Error("crocogiw: specialLogic doit être une fonction.");
}
if (!this.specialElements) {
this.specialElements = {};
}
this.specialElements[specialId] = {
data: {
type: specialData.type || 'crocodile',
triggerConditions: specialData.triggerConditions || {},
behavior: specialData.behavior || {},
rewards: specialData.rewards || {},
rarity: specialData.rarity || 'rare',
cooldown: specialData.cooldown || 0,
...specialData
},
logic: specialLogic,
isActive: false,
lastTriggered: null,
triggerCount: 0
};
this.emit('specialElementCreated', { specialId, data: specialData });
console.log(`[Crocobras] Élément spécial '${specialId}' créé.`);
}
/**
* Vérifie et déclenche les éléments spéciaux selon les conditions
* @param {Object} [gameContext] - Contexte du jeu pour les vérifications
*/
checkSpecialElements(gameContext = {}) {
if (!this.specialElements) return;
Object.entries(this.specialElements).forEach(([specialId, element]) => {
if (element.isActive) return;
const now = Date.now();
const cooldownPassed = !element.lastTriggered ||
(now - element.lastTriggered) >= element.data.cooldown;
if (cooldownPassed) {
const shouldTrigger = element.logic.call(this, element.data, {
...this.getGameState(),
...gameContext
});
if (shouldTrigger) {
this.triggerSpecialElement(specialId);
}
}
});
}
/**
* Déclenche un élément spécial
* @param {string} specialId - ID de l'élément spécial à déclencher
*/
triggerSpecialElement(specialId) {
if (!this.specialElements || !this.specialElements[specialId]) return false;
const element = this.specialElements[specialId];
element.isActive = true;
element.lastTriggered = Date.now();
element.triggerCount++;
this.emit('specialElementTriggered', {
specialId,
data: element.data,
triggerCount: element.triggerCount
});
console.log(`[Crocobras] Élément spécial '${specialId}' déclenché !`);
return true;
}
/**
* crocorin: Permet de définir des comportements IA avancés avec prise de décisions personnalisées pour les crocodiles.
* @param {number} crocoId - ID du crocodile
* @param {Object} aiConfig - Configuration de l'IA avancée
* @param {Function} decisionLogic - Logique de prise de décision personnalisée
*/
crocorin(crocoId, aiConfig, decisionLogic) {
if (typeof decisionLogic !== 'function') {
throw new Error("crocorin: decisionLogic doit être une fonction.");
}
if (!this.advancedCrocodileAI) {
this.advancedCrocodileAI = {};
}
this.advancedCrocodileAI[crocoId] = {
config: {
learningRate: aiConfig.learningRate || 0.1,
memorySize: aiConfig.memorySize || 50,
decisionFrequency: aiConfig.decisionFrequency || 1000,
personalityTraits: aiConfig.personalityTraits || {},
adaptiveRules: aiConfig.adaptiveRules || [],
...aiConfig
},
decisionLogic: decisionLogic,
memory: [],
currentDecision: null,
decisionHistory: [],
learningData: {}
};
this.emit('advancedAICreated', { crocoId, config: aiConfig });
console.log(`[Crocobras] IA avancée configurée pour le crocodile ${crocoId}.`);
}
/**
* Exécute la prise de décision IA avancée pour un crocodile
* @param {number} crocoId - ID du crocodile
* @param {Object} [situation] - Situation actuelle pour la prise de décision
*/
executeAdvancedAIDecision(crocoId, situation = {}) {
if (!this.advancedCrocodileAI || !this.advancedCrocodileAI[crocoId]) return null;
const ai = this.advancedCrocodileAI[crocoId];
const gameState = this.getGameState();
const decision = ai.decisionLogic.call(this, {
crocoId: crocoId,
config: ai.config,
memory: ai.memory,
gameState: gameState,
situation: situation,
learningData: ai.learningData
});
if (decision) {
ai.currentDecision = decision;
ai.decisionHistory.push({
timestamp: Date.now(),
decision: decision,
situation: situation,
gameState: { ...gameState }
});
// Ajouter à la mémoire
ai.memory.push({
timestamp: Date.now(),
type: 'decision',
data: decision,
context: situation
});
// Limiter la taille de la mémoire
if (ai.memory.length > ai.config.memorySize) {
ai.memory.shift();
}
this.emit('advancedAIDecision', { crocoId, decision, situation });
console.log(`[Crocobras] Décision IA avancée pour crocodile ${crocoId}: ${JSON.stringify(decision)}`);
}
return decision;
}
/**
* crocomp: Permet d'analyser les données du jeu selon la personnalisation JavaScript du développeur.
* @param {string} analysisId - ID de l'analyse
* @param {Object} analysisConfig - Configuration de l'analyse
* @param {Function} analysisLogic - Logique d'analyse personnalisée
*/
crocomp(analysisId, analysisConfig, analysisLogic) {
if (typeof analysisLogic !== 'function') {
throw new Error("crocomp: analysisLogic doit être une fonction.");
}
if (!this.gameAnalytics) {
this.gameAnalytics = {};
this.analyticsData = {};
}
this.gameAnalytics[analysisId] = {
config: {
dataPoints: analysisConfig.dataPoints || [],
updateInterval: analysisConfig.updateInterval || 5000,
reportFormat: analysisConfig.reportFormat || 'simple',
triggers: analysisConfig.triggers || [],
...analysisConfig
},
logic: analysisLogic,
lastUpdate: Date.now(),
reports: []
};
this.analyticsData[analysisId] = {};
this.emit('gameAnalyticsCreated', { analysisId, config: analysisConfig });
console.log(`[Crocobras] Système d'analyse '${analysisId}' créé.`);
}
/**
* Exécute une analyse des données de jeu
* @param {string} analysisId - ID de l'analyse à exécuter
* @param {Object} [customData] - Données personnalisées pour l'analyse
*/
runGameAnalysis(analysisId, customData = {}) {
if (!this.gameAnalytics || !this.gameAnalytics[analysisId]) return null;
const analytics = this.gameAnalytics[analysisId];
const gameState = this.getGameState();
const report = analytics.logic.call(this, {
config: analytics.config,
gameState: gameState,
analyticsData: this.analyticsData[analysisId],
customData: customData,
previousReports: analytics.reports
});
if (report) {
analytics.reports.push({
timestamp: Date.now(),
report: report
});
analytics.lastUpdate = Date.now();
this.emit('gameAnalysisCompleted', { analysisId, report });
console.log(`[Crocobras] Analyse '${analysisId}' terminée.`);
}
return report;
}
/**
* crocotina: Permet aux développeurs d'écrire leurs propres fonctions personnalisées en JavaScript pour leur code et leur jeu.
* @param {string} functionName - Nom de la fonction personnalisée
* @param {Function} customFunction - Fonction personnalisée du développeur
* @param {Object} [options] - Options de la fonction
*/
crocotina(functionName, customFunction, options = {}) {
if (typeof customFunction !== 'function') {
throw new Error("crocotina: customFunction doit être une fonction.");
}
if (!this.customFunctions) {
this.customFunctions = {};
}
this.customFunctions[functionName] = {
function: customFunction,
options: {
async: options.async || false,
parameters: options.parameters || [],
description: options.description || '',
category: options.category || 'general',
...options
},
callCount: 0,
lastCalled: null
};
this.emit('customFunctionRegistered', { functionName, options });
console.log(`[Crocobras] Fonction personnalisée '${functionName}' enregistrée.`);
}
/**
* Exécute une fonction personnalisée
* @param {string} functionName - Nom de la fonction à exécuter
* @param {...any} args - Arguments à passer à la fonction
*/
executeCustomFunction(functionName, ...args) {
if (!this.customFunctions || !this.customFunctions[functionName]) {
console.warn(`[Crocobras] Fonction personnalisée '${functionName}' non trouvée.`);
return null;
}
const customFunc = this.customFunctions[functionName];
customFunc.callCount++;
customFunc.lastCalled = Date.now();
try {
const result = customFunc.function.call(this, ...args);
this.emit('customFunctionExecuted', {
functionName,
args,
result,
callCount: customFunc.callCount
});
console.log(`[Crocobras] Fonction personnalisée '${functionName}' exécutée.`);
return result;
} catch (error) {
this.emit('customFunctionError', { functionName, error: error.message });
console.error(`[Crocobras] Erreur dans la fonction '${functionName}': ${error.message}`);
return null;
}
}
/**
* crocofaf: Permet aux développeurs de créer des mini-jeux personnalisés de quiz pour tuer plus de crocodiles ou obtenir des points/monnaie.
* @param {string} quizId - ID du quiz
* @param {Object} quizData - Données du quiz
* @param {Function} quizLogic - Logique personnalisée du quiz
*/
crocofaf(quizId, quizData, quizLogic) {
if (typeof quizLogic !== 'function') {
throw new Error("crocofaf: quizLogic doit être une fonction.");
}
if (!this.miniGames) {
this.miniGames = {};
}
this.miniGames[quizId] = {
data: {
title: quizData.title || 'Quiz Crocobras',
questions: quizData.questions || [],
rewards: quizData.rewards || {},
timeLimit: quizData.timeLimit || 30000,
difficulty: quizData.difficulty || 'normal',
categories: quizData.categories || ['general'],
...quizData
},
logic: quizLogic,
isActive: false,
currentQuestion: 0,
score: 0,
startTime: null
};
this.emit('miniGameCreated', { quizId, data: quizData });
console.log(`[Crocobras] Mini-jeu quiz '${quizId}' créé.`);
}
/**
* Démarre un mini-jeu quiz
* @param {string} quizId - ID du quiz à démarrer
*/
startMiniGame(quizId) {
if (!this.miniGames || !this.miniGames[quizId]) return false;
const quiz = this.miniGames[quizId];
quiz.isActive = true;
quiz.currentQuestion = 0;
quiz.score = 0;
quiz.startTime = Date.now();
quiz.logic.call(this, quiz.data, 'start');
this.emit('miniGameStarted', { quizId, data: quiz.data });
console.log(`[Crocobras] Mini-jeu '${quizId}' démarré.`);
return true;
}
/**
* Répond à une question du quiz
* @param {string} quizId - ID du quiz
* @param {any} answer - Réponse du joueur
*/
answerQuizQuestion(quizId, answer) {
if (!this.miniGames || !this.miniGames[quizId] || !this.miniGames[quizId].isActive) {
return false;
}
const quiz = this.miniGames[quizId];
const result = quiz.logic.call(this, quiz.data, 'answer', {
answer: answer,
currentQuestion: quiz.currentQuestion,
score: quiz.score
});
if (result && result.correct) {
quiz.score += result.points || 1;
}
quiz.currentQuestion++;
this.emit('quizAnswered', {
quizId,
answer,
result,
score: quiz.score,
question: quiz.currentQuestion
});
return result;
}
/**
* crocojup: Permet aux développeurs de créer et d'afficher des messages temporaires personnalisés.
* @param {string} messageId - ID du message
* @param {Object} messageData - Données du message
* @param {Function} messageLogic - Logique personnalisée du message
*/
crocojup(messageId, messageData, messageLogic) {
if (typeof messageLogic !== 'function') {
throw new Error("crocojup: messageLogic doit être une fonction.");
}
if (!this.temporaryMessages) {
this.temporaryMessages = {};
this.activeMessages = [];
}
this.temporaryMessages[messageId] = {
data: {
text: messageData.text || '',
duration: messageData.duration || 3000,
style: messageData.style || {},
position: messageData.position || 'center',
animation: messageData.animation || 'fade',
triggers: messageData.triggers || [],
...messageData
},
logic: messageLogic,
isActive: false,
displayCount: 0
};
this.emit('temporaryMessageCreated', { messageId, data: messageData });
console.log(`[Crocobras] Message temporaire '${messageId}' créé.`);
}
/**
* Affiche un message temporaire
* @param {string} messageId - ID du message à afficher
* @param {Object} [context] - Contexte pour le message
*/
showTemporaryMessage(messageId, context = {}) {
if (!this.temporaryMessages || !this.temporaryMessages[messageId]) return false;
const message = this.temporaryMessages[messageId];
message.isActive = true;
message.displayCount++;
this.activeMessages.push(messageId);
const result = message.logic.call(this, message.data, context);
this.emit('temporaryMessageShown', {
messageId,
data: message.data,
context,
result,
displayCount: message.displayCount
});
console.log(`[Crocobras] Message temporaire '${messageId}' affiché.`);
// Masquer automatiquement après la durée
setTimeout(() => {
this.hideTemporaryMessage(messageId);
}, message.data.duration);
return true;
}
/**
* Masque un message temporaire
* @param {string} messageId - ID du message à masquer
*/
hideTemporaryMessage(messageId) {
if (!this.temporaryMessages || !this.temporaryMessages[messageId]) return false;
this.temporaryMessages[messageId].isActive = false;
this.activeMessages = this.activeMessages.filter(id => id !== messageId);
this.emit('temporaryMessageHidden', { messageId });
console.log(`[Crocobras] Message temporaire '${messageId}' masqué.`);
return true;
}
/**
* crocodae: Permet aux développeurs de créer des power-ups temporaires personnalisés selon leur logique JavaScript.
* @param {string} powerUpId - ID du power-up
* @param {Object} powerUpData - Données du power-up
* @param {Function} powerUpLogic - Logique personnalisée du power-up
*/
crocodae(powerUpId, powerUpData, powerUpLogic) {
if (typeof powerUpLogic !== 'function') {
throw new Error("crocodae: powerUpLogic doit être une fonction.");
}
if (!this.temporaryPowerUps) {
this.temporaryPowerUps = {};
this.activePowerUps = [];
}
this.temporaryPowerUps[powerUpId] = {
data: {
name: powerUpData.name || 'Power-up temporaire',
duration: powerUpData.duration || 10000,
effects: powerUpData.effects || {},
stackable: powerUpData.stackable || false,
cooldown: powerUpData.cooldown || 5000,
rarity: powerUpData.rarity || 'common',
...powerUpData
},
logic: powerUpLogic,
isActive: false,
activationTime: null,
usageCount: 0
};
this.emit('temporaryPowerUpCreated', { powerUpId, data: powerUpData });
console.log(`[Crocobras] Power-up temporaire '${powerUpId}' créé.`);
}
/**
* Active un power-up temporaire
* @param {string} powerUpId - ID du power-up à activer
* @param {Object} [context] - Contexte d'activation
*/
activateTemporaryPowerUp(powerUpId, context = {}) {
if (!this.temporaryPowerUps || !this.temporaryPowerUps[powerUpId]) return false;
const powerUp = this.temporaryPowerUps[powerUpId];
// Vérifier si déjà actif et non stackable
if (powerUp.isActive && !powerUp.data.stackable) return false;
powerUp.isActive = true;
powerUp.activationTime = Date.now();
powerUp.usageCount++;
if (!powerUp.data.stackable || !this.activePowerUps.includes(powerUpId)) {
this.activePowerUps.push(powerUpId);
}
powerUp.logic.call(this, powerUp.data, context, 'activate');
this.emit('temporaryPowerUpActivated', {
powerUpId,
data: powerUp.data,
context,
usageCount: powerUp.usageCount
});
console.log(`[Crocobras] Power-up temporaire '${powerUpId}' activé.`);
// Désactiver automatiquement après la durée
setTimeout(() => {
this.deactivateTemporaryPowerUp(powerUpId);
}, powerUp.data.duration);
return true;
}
/**
* Désactive un power-up temporaire
* @param {string} powerUpId - ID du power-up à désactiver
*/
deactivateTemporaryPowerUp(powerUpId) {
if (!this.temporaryPowerUps || !this.temporaryPowerUps[powerUpId]) return false;
const powerUp = this.temporaryPowerUps[powerUpId];
powerUp.isActive = false;
this.activePowerUps = this.activePowerUps.filter(id => id !== powerUpId);
powerUp.logic.call(this, powerUp.data, {}, 'deactivate');
this.emit('temporaryPowerUpDeactivated', { powerUpId });
console.log(`[Crocobras] Power-up temporaire '${powerUpId}' désactivé.`);
return true;
}
/**
* crocolog: Permet aux développeurs de créer leurs propres logs personnalisés pour le jeu.
* @param {string} logId - ID du système de log
* @param {Object} logConfig - Configuration des logs
* @param {Function} logLogic - Logique personnalisée des logs
*/
crocolog(logId, logConfig, logLogic) {
if (typeof logLogic !== 'function') {
throw new Error("crocolog: logLogic doit être une fonction.");
}
if (!this.customLogs) {
this.customLogs = {};
}
this.customLogs[logId] = {
config: {
prefix: logConfig.prefix || '[LOG]',
colors: logConfig.colors || {},
format: logConfig.format || 'simple',
output: logConfig.output || 'console',
shapes: logConfig.shapes || {},
filters: logConfig.filters || [],
...logConfig
},
logic: logLogic,
entries: [],
lastLog: null
};
this.emit('customLogCreated', { logId, config: logConfig });
console.log(`[Crocobras] Système de log personnalisé '${logId}' créé.`);
}
/**
* Écrit un log personnalisé
* @param {string} logId - ID du système de log
* @param {string} message - Message à logger
* @param {Object} [data] - Données supplémentaires
*/
writeCustomLog(logId, message, data = {}) {
if (!this.customLogs || !this.customLogs[logId]) return false;
const logger = this.customLogs[logId];
const logEntry = {
timestamp: Date.now(),
message: message,
data: data,
level: data.level || 'info'
};
logger.entries.push(logEntry);
logger.lastLog = logEntry;
const formattedLog = logger.logic.call(this, logger.config, logEntry);
this.emit('customLogWritten', { logId, entry: logEntry, formatted: formattedLog });
// Affichage selon la configuration
if (logger.config.output === 'console') {
console.log(formattedLog);
}
return true;
}
/**
* crocojust: Permet aux développeurs de créer des logiques de clonage ou d'invocation pour les crocodiles.
* @param {string} cloneId - ID du système de clonage
* @param {Object} cloneData - Données de clonage
* @param {Function} cloneLogic - Logique personnalisée de clonage
*/
crocojust(cloneId, cloneData, cloneLogic) {
if (typeof cloneLogic !== 'function') {
throw new Error("crocojust: cloneLogic doit être une fonction.");
}
if (!this.crocodileCloning) {
this.crocodileCloning = {};
}
this.crocodileCloning[cloneId] = {
data: {
maxClones: cloneData.maxClones || 3,
cloneCooldown: cloneData.cloneCooldown || 5000,
cloneConditions: cloneData.cloneConditions || {},
cloneProperties: cloneData.cloneProperties || {},
invocationRules: cloneData.invocationRules || {},
...cloneData
},
logic: cloneLogic,
activeClones: [],
lastCloneTime: null
};
this.emit('crocodileCloningCreated', { cloneId, data: cloneData });
console.log(`[Crocobras] Système de clonage '${cloneId}' créé.`);
}
/**
* Clone ou invoque des crocodiles
* @param {string} cloneId - ID du système de clonage
* @param {number} sourceCrocoId - ID du crocodile source
* @param {Object} [context] - Contexte du clonage
*/
cloneCrocodile(cloneId, sourceCrocoId, context = {}) {
if (!this.crocodileCloning || !this.crocodileCloning[cloneId]) return false;
const cloneSystem = this.crocodileCloning[cloneId];
const now = Date.now();
// Vérifier les limites et cooldowns
if (cloneSystem.activeClones.length >= cloneSystem.data.maxClones) return false;
if (cloneSystem.lastCloneTime && (now - cloneSystem.lastCloneTime) < cloneSystem.data.cloneCooldown) {
return false;
}
const cloneResult = cloneSystem.logic.call(this, cloneSystem.data, {
sourceCrocoId: sourceCrocoId,
gameState: this.getGameState(),
context: context
});
if (cloneResult && cloneResult.success) {
const newCloneId = cloneResult.cloneId || Date.now();
cloneSystem.activeClones.push({
id: newCloneId,
sourceId: sourceCrocoId,
createdAt: now,
properties: cloneResult.properties || {}
});
cloneSystem.lastCloneTime = now;
this.emit('crocodileCloned', {
cloneId,
sourceId: sourceCrocoId,
newCloneId: newCloneId,
result: cloneResult
});
console.log(`[Crocobras] Crocodile ${sourceCrocoId} cloné avec l'ID ${newCloneId}.`);
return newCloneId;
}
return false;
}
/**
* crocorare: Permet aux développeurs de créer des crocodiles spéciaux rares avec des comportements spéciaux.
* @param {string} rareId - ID du crocodile rare
* @param {Object} rareData - Données du crocodile rare
* @param {Function} rareLogic - Logique personnalisée du crocodile rare
*/
crocorare(rareId, rareData, rareLogic) {
if (typeof rareLogic !== 'function') {
throw new Error("crocorare: rareLogic doit être une fonction.");
}
if (!this.rareCrocodiles) {
this.rareCrocodiles = {};
}
this.rareCrocodiles[rareId] = {
data: {
name: rareData.name || 'Crocodile Rare',
rarity: rareData.rarity || 'legendary',
spawnChance: rareData.spawnChance || 0.01,
specialAbilities: rareData.specialAbilities || [],
rewards: rareData.rewards || {},
appearance: rareData.appearance || {},
behavior: rareData.behavior || {},
...rareData
},
logic: rareLogic,
spawnCount: 0,
lastSpawn: null,
isActive: false
};
this.emit('rareCrocodileCreated', { rareId, data: rareData });
console.log(`[Crocobras] Crocodile rare '${rareId}' créé.`);
}
/**
* Vérifie et fait apparaître des crocodiles rares
* @param {Object} [spawnContext] - Contexte d'apparition
*/
checkRareCrocodileSpawn(spawnContext = {}) {
if (!this.rareCrocodiles) return;
Object.entries(this.rareCrocodiles).forEach(([rareId, rareCroco]) => {
if (rareCroco.isActive) return;
const shouldSpawn = Math.random() < rareCroco.data.spawnChance;
if (shouldSpawn) {
const spawnResult = rareCroco.logic.call(this, rareCroco.data, {
...this.getGameState(),
...spawnContext
});
if (spawnResult && spawnResult.spawn) {
rareCroco.isActive = true;
rareCroco.spawnCount++;
rareCroco.lastSpawn = Date.now();
this.emit('rareCrocodileSpawned', {
rareId,
data: rareCroco.data,
spawnCount: rareCroco.spawnCount,
result: spawnResult
});
console.log(`[Crocobras] Crocodile rare '${rareId}' est apparu !`);
}
}
});
}
/**
* crocomd: Permet aux développeurs de créer des mini-tutoriels de démarrage sous forme de dialogues.
* @param {string} tutorialId - ID du tutoriel
* @param {Object} tutorialData - Données du tutoriel
* @param {Function} tutorialLogic - Logique personnalisée du tutoriel
*/
crocomd(tutorialId, tutorialData, tutorialLogic) {
if (typeof tutorialLogic !== 'function') {
throw new Error("crocomd: tutorialLogic doit être une fonction.");
}
if (!this.tutorials) {
this.tutorials = {};
}
this.tutorials[tutorialId] = {
data: {
title: tutorialData.title || 'Tutoriel',
steps: tutorialData.steps || [],
targetLevels: tutorialData.targetLevels || [1],
dialogues: tutorialData.dialogues || [],
rewards: tutorialData.rewards || {},
optional: tutorialData.optional || false,
...tutorialData
},
logic: tutorialLogic,
isActive: false,
currentStep: 0,
completed: false
};
this.emit('tutorialCreated', { tutorialId, data: tutorialData });
console.log(`[Crocobras] Tutoriel '${tutorialId}' créé.`);
}
/**
* Démarre un tutoriel
* @param {string} tutorialId - ID du tutoriel à démarrer
*/
startTutorial(tutorialId) {
if (!this.tutorials || !this.tutorials[tutorialId]) return false;
const tutorial = this.tutorials[tutorialId];
tutorial.isActive = true;
tutorial.currentStep = 0;
tutorial.logic.call(this, tutorial.data, 'start');
this.emit('tutorialStarted', { tutorialId, data: tutorial.data });
console.log(`[Crocobras] Tutoriel '${tutorialId}' démarré.`);
return true;
}
/**
* Avance à l'étape suivante du tutoriel
* @param {string} tutorialId - ID du tutoriel
*/
nextTutorialStep(tutorialId) {
if (!this.tutorials || !this.tutorials[tutorialId] || !this.tutorials[tutorialId].isActive) {
return false;
}
const tutorial = this.tutorials[tutorialId];
tutorial.currentStep++;
if (tutorial.currentStep >= tutorial.data.steps.length) {
tutorial.completed = true;
tutorial.isActive = false;
this.emit('tutorialCompleted', { tutorialId, rewards: tutorial.data.rewards });
console.log(`[Crocobras] Tutoriel '${tutorialId}' terminé !`);
} else {
tutorial.logic.call(this, tutorial.data, 'step', tutorial.currentStep);
this.emit('tutorialStepChanged', {
tutorialId,
step: tutorial.currentStep,
stepData: tutorial.data.steps[tutorial.currentStep]
});
}
return true;
}
/**
* crocoglop: Permet aux développeurs de créer des événements facultatifs de personnalisation pour leurs crocodiles.
* @param {number} crocoId - ID du crocodile
* @param {Object} customData - Données de personnalisation
* @param {Function} customLogic - Logique personnalisée
*/
crocoglop(crocoId, customData, customLogic) {
if (typeof customLogic !== 'function') {
throw new Error("crocoglop: customLogic doit être une fonction.");
}
if (!this.crocodileCustomization) {
this.crocodileCustomization = {};
}
this.crocodileCustomization[crocoId] = {
data: {
messages: customData.messages || [],
messageInterval: customData.messageInterval || 2000,
specialBehaviors: customData.specialBehaviors || {},
visualEffects: customData.visualEffects || {},
sounds: customData.sounds || {},
...customData
},
logic: customLogic,
isActive: false,
intervals: [],
lastAction: Date.now()
};
this.emit('crocodileCustomizationCreated', { crocoId, data: customData });
console.log(`[Crocobras] Personnalisation créée pour le crocodile ${crocoId}.`);
}
/**
* Active la personnalisation d'un crocodile
* @param {number} crocoId - ID du crocodile
*/
activateCrocodileCustomization(crocoId) {
if (!this.crocodileCustomization || !this.crocodileCustomization[crocoId]) return false;
const customization = this.crocodileCustomization[crocoId];
customization.isActive = true;
// Démarrer les messages récurrents si configurés
if (customization.data.messages.length > 0 && customization.data.messageInterval > 0) {
const messageInterval = setInterval(() => {
if (customization.isActive) {
const randomMessage = customization.data.messages[
Math.floor(Math.random() * customization.data.messages.length)
];
this.emit('crocodileCustomMessage', {
crocoId,
message: randomMessage
});
console.log(`[Crocobras] Crocodile ${crocoId}: ${randomMessage}`);
} else {
clearInterval(messageInterval);
}
}, customization.data.messageInterval);
customization.intervals.push(messageInterval);
}
customization.logic.call(this, customization.data, 'activate');
this.emit('crocodileCustomizationActivated', { crocoId });
console.log(`[Crocobras] Personnalisation activée pour le crocodile ${crocoId}.`);
return true;
}
/**
* crocofarm: Permet aux développeurs de créer des bébés crocodiles avec leurs logiques de naissance/apparition et comportements.
* @param {string} babyId - ID du système de bébés crocodiles
* @param {Object} babyData - Données des bébés crocodiles
* @param {Function} babyLogic - Logique personnalisée des bébés
*/
crocofarm(babyId, babyData, babyLogic) {
if (typeof babyLogic !== 'function') {
throw new Error("crocofarm: babyLogic doit être une fonction.");
}
if (!this.babyCrocodiles) {
this.babyCrocodiles = {};
}
this.babyCrocodiles[babyId] = {
data: {
maxBabies: babyData.maxBabies || 5,
spawnConditions: babyData.spawnConditions || {},
growthTime: babyData.growthTime || 15000,
babyBehavior: babyData.babyBehavior || {},
parentInfluence: babyData.parentInfluence || {},
appearance: babyData.appearance || {},
...babyData
},
logic: babyLogic,
activeBabies: [],
totalSpawned: 0
};
this.emit('babyCrocodileSystemCreated', { babyId, data: babyData });
console.log(`[Crocobras] Système de bébés crocodiles '${babyId}' créé.`);
}
/**
* Fait naître un bébé crocodile
* @param {string} babyId - ID du système de bébés
* @param {number} [parentId] - ID du parent (optionnel)
* @param {Object} [birthContext] - Contexte de naissance
*/
spawnBabyCrocodile(babyId, parentId = null, birthContext = {}) {
if (!this.babyCrocodiles || !this.babyCrocodiles[babyId]) return false;
const babySystem = this.babyCrocodiles[babyId];
if (babySystem.activeBabies.length >= babySystem.data.maxBabies) return false;
const babyResult = babySystem.logic.call(this, babySystem.data, {
action: 'spawn',
parentId: parentId,
gameState: this.getGameState(),
context: birthContext
});
if (babyResult && babyResult.success) {
const newBabyId = babyResult.babyId || Date.now();
const baby = {
id: newBabyId,
parentId: parentId,
birthTime: Date.now(),
isGrown: false,
properties: babyResult.properties || {}
};
babySystem.activeBabies.push(baby);
babySystem.totalSpawned++;
this.emit('babyCrocodileSpawned', {
babyId,
baby: baby,
parentId: parentId,
result: babyResult
});
console.log(`[Crocobras] Bébé crocodile ${newBabyId} né !`);
// Programmer la croissance
setTimeout(() => {
this.growBabyCrocodile(babyId, newBabyId);
}, babySystem.data.growthTime);
return newBabyId;
}
return false;
}
/**
* Fait grandir un bébé crocodile
* @param {string} babyId - ID du système de bébés
* @param {number} babyInstanceId - ID de l'instance du bébé
*/
growBabyCrocodile(babyId, babyInstanceId) {
if (!this.babyCrocodiles || !this.babyCrocodiles[babyId]) return false;
const babySystem = this.babyCrocodiles[babyId];
const baby = babySystem.activeBabies.find(b => b.id === babyInstanceId);
if (!baby || baby.isGrown) return false;
baby.isGrown = true;
const growthResult = babySystem.logic.call(this, babySystem.data, {
action: 'grow',
baby: baby,
gameState: this.getGameState()
});
this.emit('babyCrocodileGrown', {
babyId,
baby: baby,
result: growthResult
});
console.log(`[Crocobras] Bébé crocodile ${babyInstanceId} a grandi !`);
return true;
}
/**
* crocenvie: Permet aux développeurs de créer des systèmes d'envies pour les crocodiles.
* @param {string} desireId - ID du système d'envies
* @param {Object} desireData - Données des envies
* @param {Function} desireLogic - Logique personnalisée des envies
*/
crocenvie(desireId, desireData, desireLogic) {
if (typeof desireLogic !== 'function') {
throw new Error("crocenvie: desireLogic doit être une fonction.");
}
if (!this.crocodileDesires) {
this.crocodileDesires = {};
}
this.crocodileDesires[desireId] = {
data: {
desires: desireData.desires || ['eat', 'hunt', 'play', 'rest'],
desireWeights: desireData.desireWeights || {},
satisfactionLevels: desireData.satisfactionLevels || {},
desireDecay: desireData.desireDecay || 0.1,
influences: desireData.influences || {},
...desireData
},
logic: desireLogic,
crocodileDesires: {},
lastUpdate: Date.now()
};
this.emit('crocodileDesireSystemCreated', { desireId, data: desireData });
console.log(`[Crocobras] Système d'envies '${desireId}' créé.`);
}
/**
* Met à jour les envies d'un crocodile
* @param {string} desireId - ID du système d'envies
* @param {number} crocoId - ID du crocodile
* @param {Object} [context] - Contexte pour les envies
*/
updateCrocodileDesires(desireId, crocoId, context = {}) {
if (!this.crocodileDesires || !this.crocodileDesires[desireId]) return;
const desireSystem = this.crocodileDesires[desireId];
if (!desireSystem.crocodileDesires[crocoId]) {
desireSystem.crocodileDesires[crocoId] = {};
desireSystem.data.desires.forEach(desire => {
desireSystem.crocodileDesires[crocoId][desire] = Math.random();
});
}
const currentDesires = desireSystem.crocodileDesires[crocoId];
const result = desireSystem.logic.call(this, desireSystem.data, {
crocoId: crocoId,
currentDesires: currentDesires,
gameState: this.getGameState(),
context: context
});
if (result) {
// Mettre à jour les envies selon le résultat
Object.keys(currentDesires).forEach(desire => {
if (result[desire] !== undefined) {
currentDesires[desire] = Math.max(0, Math.min(1, result[desire]));
}
});
desireSystem.lastUpdate = Date.now();
this.emit('crocodileDesireUpdated', {
desireId,
crocoId,
desires: currentDesires,
result: result
});
}
}
/**
* Obtient les envies actuelles d'un crocodile
* @param {string} desireId - ID du système d'envies
* @param {number} crocoId - ID du crocodile
* @returns {Object|null} Envies actuelles du crocodile
*/
getCrocodileDesires(desireId, crocoId) {
if (!this.crocodileDesires || !this.crocodileDesires[desireId]) return null;
const desireSystem = this.crocodileDesires[desireId];
return desireSystem.crocodileDesires[crocoId] || null;
}
}
// Exporte la classe du jeu
module.exports = CrocobrasGame;