Advanced Event Activation
Comme tous mes plugins, ce script est publié sous licence CC BY 4.0.
C’est un script tout bête dont l’idée m’est venue quand j’ai voulu faire un garde qui réagirait en voyant le joueur passer devant lui. Bien sur, c’est assez facile de le faire en event, mais j’ai cherché une méthode plus rapide. Aussi j’ai créé ce plugin :
//=============================================================================
// Sphinx-Advanced-Event-Activation.js
//=============================================================================
/*:
* @plugindesc Condition d'activation d'event avancées
* @author Sphinx
*
* @help
* //==========================================================================
* // Plugin : Sphinx-Advanced-Event-Activation
* // Date : 29 mars 2020
* // Auteur : Sphinx
* //==========================================================================
* Ce script est destiné à ajouter des conditions d'activation de pages
* d'events
* Pour utiliser ce script, créez un commentaire au tout début d'une page d'un
* event. Le commentaire d'activation doit contenir une condition par ligne.
* Si toutes les conditions sont remplies, alors la page de l'event sera
* activée.
*
* Les conditions peuvent faire référence au joueur, grâce au mot clé @player,
* et/ou à l'évent en cours, grâce au mot clé @event.
*
* Les conditions sont obligatoirement des comparaisons de nombres tels que les
* coordonnées du joueur ou de l'évent, leur direction, ...
* L'important étant de comparer, avec l'un des 6 opérateurs disponibles :
* - > : Supérieur strict
* - >= : Supérieur ou égal
* - == : Egal
* - <= : Inférieur ou égal
* - < : Inférieur stric
* - != : Différent
*
* Dans les conditions, vous pouvez utiliser les opérateurs mathématiques
* simples disponibles :
* - + : Addition
* - - : Soustraction
* - * : Multiplication
* - / : Division
* - % : Modulo
*
* Dans les conditions vous pouvez aussi utiliser une des constantes définies
* suivantes :
* BOTTOM : 2
* LEFT : 4
* RIGHT : 6
* TOP : 8
* Ce sont les 4 valeurs correspondant aux 4 directions utilisées par le jeu
*
* Voici quelques exemples de conditions valides
* - L'event s'active si le joueur regarde vers le bas :
* ¤ @player.direction == BOTTOM
* - L'event s'active si le joueur et l'event sont sur la même colonne :
* ¤ @player.x == @event.x
* - L'event s'active si le joueur se trouve sur la ligne en dessous de
* l'event :
* ¤ @player.y == @event.y + 1
* - L'event s'active si le joueur se trouve dans une zone rectangulaire
* comprise entre (10;10) et (20;20) inclus :
* ¤ @player.x >= 10
* ¤ @player.x <= 20
* ¤ @player.y >= 10
* ¤ @player.y <= 20
*
* Ce dernier exemple contient les 4 conditions écrites. Dans ce cas, comme dit
* précédemment, toutes les conditions doivent être remplies pour que la page
* de l'event s'active
*
* Dépendances :
* Aucune
*/
(function() {
// Constantes utilisables dans les formules
SphinxAEAConstants = {
BOTTOM: 2,
LEFT: 4,
RIGHT: 6,
TOP: 8
};
// Fonction de rafraichissement des events (la méthode refresh classique actualise l'ensemble de la map causant un certain lag)
Game_Map.prototype.refreshEvents = function() {
this.events().forEach(event => {
event.refresh();
});
};
// Rafraichissement des events à chaque changement de direction d'un event ou du joueur
Game_CharacterBase.prototype.sphinxAEASetDirection = Game_CharacterBase.prototype.setDirection;
Game_CharacterBase.prototype.setDirection = function(d) {
hasTurned = d != this._direction;
Game_CharacterBase.prototype.sphinxAEASetDirection.call(this, d);
if(hasTurned && $gameMap != null) {
$gameMap.refreshEvents();
}
};
// Rafraichissement des events à chaque pas d'un event ou du joueur
Game_CharacterBase.prototype.sphinxAEAUpdateMove = Game_CharacterBase.prototype.updateMove;
Game_CharacterBase.prototype.updateMove = function() {
Game_CharacterBase.prototype.sphinxAEAUpdateMove.call(this);
if(!this.isMoving()) {
$gameMap.refreshEvents();
}
};
// Rafraichissement des events à l'arrivée du joueur sur la map
Game_Player.prototype.sphinxAEAPerformTransfer = Game_Player.prototype.performTransfer;
Game_Player.prototype.performTransfer = function() {
Game_Player.prototype.sphinxAEAPerformTransfer.call(this);
$gameMap.refreshEvents();
}
// Conditions d'activation de la page de l'évent
Game_Event.prototype.sphinxAEAMeetsConditions = Game_Event.prototype.meetsConditions;
Game_Event.prototype.meetsConditions = function(page) {
// Si les conditions normales d'activation ne sont pas remplies, alors on active pas l'event
if(!Game_Event.prototype.sphinxAEAMeetsConditions.call(this, page)) return false;
// Les conditions normales d'activation de la page de l'évent sont remplies
// Si la première commande de la page n'est pas un commentaire, alors on active normalement l'event
if(page.list[0].code != 108) return true;
// Récupération de toutes les conditions avancées
page.advancedConditions = [];
var index = 0;
do {
regexpValidCondition = /^\s*(\s*([\+\-\*\/]|[A-Z]+|\d+|\@[a-z\.]+)\s*)+(\s*(<|<=|={2}|>=|>|!=)\s*)(\s*([\+\-\*\/]|[A-Z]+|\d+|\@[a-z\.]+)\s*)+\s*$/;
if(page.list[index].parameters[0].match(regexpValidCondition)) page.advancedConditions.push(page.list[index].parameters[0]);
++index;
} while(page.list[index].code == 108 || page.list[index].code == 408);
// Initialisation du booléen qui sera retourné à la fin de la fonction
// La page de l'event sera activée si aucune condition n'est pas remplie (autrement dit si toutes les conditions sont remplies)
isActivated = true;
// Analyse des conditions avancées d'activation
page.advancedConditions.forEach(advancedCondition => {
// Regexp de découpage de la condition
operatorRegexp = /\s*<|<=|\={2}|>=|>|!=\s*/;
// Si la condition est une condition valide (si elle contient bien un opérateur);
if(advancedCondition.match(operatorRegexp)) {
// Découpage des opérandes et extraction de l'opérateur
operands = advancedCondition.split(operatorRegexp).slice(0, 2);//.map(operand => operand.trim());
comparisonOperator = advancedCondition.match(operatorRegexp)[0].trim();
// Pour chaque opérande
operands = operands.map(operand => {
// Extraction des valeurs et des opérateurs
extractRegexp = /([\+\-\*\/]|[A-Z]+|\d+|\@[a-z\.]+)/g;
extracted = operand.match(extractRegexp);
// Analyse et calcul de l'opérande
result = 0;
operandOperation = "+";
extracted.forEach(value => {
switch(true) {
// Opérateur
case /[\+\-\*\/]/.test(value):
operandOperation = value;
value = null;
break;
// Constantes
case /[A-Z]+/.test(value):
value = SphinxAEAConstants[value];
break;
// Nombre
case /\d+/.test(value):
value = parseInt(value, 10);
break;
// Variable (@player ou @event)
case /\@[a-z\.]+/.test(value):
// Découpage des appels de fonctions
value = value.split(".");
// Pour chaque fonction
var analyzedValue = null;
value.forEach(v => {
// Si c'est le premier appel, alors interprétation du nom de la variable
if(analyzedValue == null) {
switch(v) {
// Joueur
case "@player":
analyzedValue = $gamePlayer;
break;
// Event courant
case "@event":
analyzedValue = this;
break;
// Tout autre valeur sera ignorée
default:
analyzedValue = 0;
break;
}
}
// Si la valeur actuellement enregistrée est un objet qui contient une clé égale à v
else if(typeof analyzedValue == "object" && analyzedValue[v] != null) {
// Si clé v de la valeur actuellement enregistrée est une fonction, appel de cette fonction et enregistrement de son résultat
if(typeof analyzedValue[v] == "function") analyzedValue = analyzedValue[v].call(analyzedValue);
// Sinon, enregistrement de la valeur de la clé v de la valeur actuellement enregistrée
else analyzedValue = analyzedValue[v];
}
});
// Récupération du résultat de l'interprétation de la variable
value = analyzedValue;
break;
}
// Selon l'opérateur mathématique :
switch(operandOperation) {
// Addition
case "+":
result += value;
break;
// Soustraction
case "-":
result -= value;
break;
// Multiplication
case "*":
result *= value;
break;
// Division
case "/":
result /= value;
break;
// Modulo
case "%":
result %= value;
break;
}
});
// Résultat retourné à la fonction map
return result;
});
// Selon l'opérateur de comparaison utilisée
switch(comparisonOperator) {
// Supérieur strict
case ">":
if(operands[0] <= operands[1]) isActivated = false;
break;
// Supérieur ou égal
case ">=":
if(operands[0] < operands[1]) isActivated = false;
break;
// Egal
case "==":
if(operands[0] != operands[1]) isActivated = false;
break;
// Inférieur ou égal
case "<=":
if(operands[0] > operands[1]) isActivated = false;
break;
// Inférieur strict
case "<":
if(operands[0] >= operands[1]) isActivated = false;
break;
// Différent
case "!=":
if(operands[0] == operands[1]) isActivated = false;
break;
}
}
});
// Retourne le booléen indiquant si la page remplit toutes ses conditions ou non
return isActivated;
};
})();
Utilisation
Pour utiliser ce script, créez un commentaire au tout début d’une page d’un event. Le commentaire d’activation doit contenir une condition par ligne. Si toutes les conditions sont remplies, alors la page de l’event sera activée.
Les conditions peuvent faire référence au joueur, grâce au mot clé @player, et/ou à l’évent en cours, grâce au mot clé @event.
Les conditions sont obligatoirement des comparaisons de nombres tels que les coordonnées du joueur ou de l’évent, leur direction, … L’important étant de comparer, avec l’un des 6 opérateurs disponibles :
- > : Supérieur strict
- >= : Supérieur ou égal
- == : Egal
- <= : Inférieur ou égal
- < : Inférieur stric
- != : Différent
Dans les conditions, vous pouvez utiliser les opérateurs mathématiques
simples disponibles :
- + : Addition
- – : Soustraction
- * : Multiplication
- / : Division
- % : Modulo
Dans les conditions vous pouvez aussi utiliser une des constantes définies
suivantes :
- BOTTOM : 2
- LEFT : 4
- RIGHT : 6
- TOP : 8
Ce sont les 4 valeurs correspondant aux 4 directions utilisées par le jeu
Voici quelques exemples de conditions valides :
- L’event s’active si le joueur regarde vers le bas :
- @player.direction == BOTTOM
- L’event s’active si le joueur et l’event sont sur la même colonne :
- @player.x == @event.x
- L’event s’active si le joueur se trouve sur la ligne en dessous de l’event :
- @player.y == @event.y + 1
- L’event s’active si le joueur se trouve dans une zone rectangulaire comprise entre (10;10) et (20;20) inclus :
- @player.x >= 10
- @player.x <= 20
- @player.y >= 10
- @player.y <= 20
Ce dernier exemple contient les 4 conditions écrites. Dans ce cas, comme dit
précédemment, toutes les conditions doivent être remplies pour que la page
de l’event s’active.