Download index.js from Programming-Clem/Crocobras: direct link, hf CLI and curl.
- Browser
- Download file 107 kB
-
https://huggingface.co/Programming-Clem/Crocobras/resolve/main/index.js
- Command line
-
hf download hf://Programming-Clem/Crocobras/index.js
-
curl -L -o index.js https://huggingface.co/Programming-Clem/Crocobras/resolve/main/index.js
107 kB
| // 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; | |