Sphinx-Maplink
Comme tous mes plugins, ce script est publié sous licence CC BY 4.0.
//=============================================================================
// Sphinx-Maplink.js
//=============================================================================
/*:
* @plugindesc Système de jointure de cartes
* @author Sphinx
*
* @param Taille jointure horizontale
* @desc Nombre de colonnes des cartes jointes à gauche ou à droite affichées sur la carte courante (par défaut : 9)
* @default 9
*
* @param Taille jointure verticale
* @desc Nombre de lignes des cartes jointes au dessus ou en dessous affichées sur la carte courante (par défaut : 7)
* @default 7
*
* @help
* //==========================================================================
* // Plugin : Sphinx-Maplink
* // Date : 10 mars 2016
* // Auteur : Sphinx
* //==========================================================================
* Ce plugin permet de joindre les maps entre elles. Une map jointe est en
* partie affichée sur le côté de la map courante.
*
* Conditions pour être utilisable :
* - Les 2 maps jointes doivent utiliser des tilesets compatibles (chaque élément
* affiché dans la jointure devra donc être à la même place dans les 2 tilesets
* concernés si ceux-ci sont différents)
* - Les 2 maps jointes doivent avoir le côté en contact de la même dimension
*
* Pour activer le maplink sur une carte, ajoutez dans ses remarques les jointures
* nécessaires :
* - <linkLeft:ID_MAP> : pour que la carte ID_MAP soit affichée à gauche de la
* carte courante)
* - <linkRight:ID_MAP> : pour que la carte ID_MAP soit affichée à droite de la
* carte courante
* - <linkTop:ID_MAP> : pour que la carte ID_MAP soit affichée au dessus de la
* carte courante
* - <linkBottom:ID_MAP> : pour que la carte ID_MAP soit affichée en dessous de
* la carte courante
*
* Lorsqu'une map est jointe à une autre et que le joueur dépasse la jointure, il est
* automatiquement téléporté sur la map jointe.
*
* Les évènements présents sur les parties affichées des maps jointes seront
* eux aussi affichés. Cependant, aucun de ces évènements ajoutés ne sera
* exécutable : ils seront simplement affichés.
* L'apparence des évents des maps jointes tient compte des conditions des pages de
* ces évents. Les évents des maps jointes n'ayant aucune apparence sur aucune page
* ne seront pas importés dans la map courante.
*
* Dépendances :
* Aucune
*/
(function() {
Game_Map.prototype.resetMapLink = function() {
var parameters = PluginManager.parameters("Sphinx-Maplink");
this.offsetH = (parseInt(parameters["Taille jointure horizontale"], 10) || 9);
this.offsetV = (parseInt(parameters["Taille jointure verticale"], 10) || 7);
this._dataLikedMaps = {};
this._dataCornerLinks = {};
};
Scene_Map.prototype.aliasMaplinkCreate = Scene_Map.prototype.create;
Scene_Map.prototype.create = function() {
Scene_Map.prototype.aliasMaplinkCreate.call(this);
this._links = [];
this._corners = [];
this._waitingLinks = 0;
this._waitingCorners = 0;
$gameMap.resetMapLink();
};
Scene_Map.prototype.aliasMaplinkOnMapLoaded = Scene_Map.prototype.onMapLoaded;
Scene_Map.prototype.onMapLoaded = function() {
if($dataMap.meta.linkLeft) {
this._links.push("Left");
}
if($dataMap.meta.linkRight) {
this._links.push("Right");
}
if($dataMap.meta.linkTop) {
this._links.push("Top");
}
if($dataMap.meta.linkBottom) {
this._links.push("Bottom");
}
this._waitingLinks = this._links.length;
if(this._waitingLinks > 0) {
return this.loadLinkedMaps();
} else {
return Scene_Map.prototype.aliasMaplinkOnMapLoaded.call(this);
}
};
Scene_Map.prototype.aliasMaplinkIsReady = Scene_Map.prototype.isReady;
Scene_Map.prototype.isReady = function() {
return Scene_Map.prototype.aliasMaplinkIsReady.call(this) && this._waitingLinks === 0 && this._waitingCorners === 0;
};
Scene_Map.prototype.loadLinkedMaps = function() {
this._waitingLinks = this._links.length;
if(this._waitingLinks == 0) {
return this.onLinksLoaded();
} else {
return this.loadLink(this._links.pop());
}
};
Scene_Map.prototype.loadLink = function(dir) {
var mapId = 0;
switch(dir) {
case "Left":
mapId = parseInt($dataMap.meta.linkLeft, 10);
break;
case "Right":
mapId = parseInt($dataMap.meta.linkRight, 10);
break;
case "Top":
mapId = parseInt($dataMap.meta.linkTop, 10);
break;
case "Bottom":
mapId = parseInt($dataMap.meta.linkBottom, 10);
break;
}
if(mapId > 0 && !!$dataMapInfos[mapId]) {
var scene = this;
var xhr = new XMLHttpRequest();
var filename = "Map%1.json".format(mapId.padZero(3));
var url = "data/" + filename;
xhr.open("GET", url);
xhr.overrideMimeType("application/json");
xhr.onload = function() {
if(xhr.status < 400) {
try {
var dataMap = JSON.parse(xhr.responseText);
DataManager.extractMetadata(dataMap);
$gameMap._dataLikedMaps[dir] = dataMap;
} finally {
scene.loadLinkedMaps();
}
}
};
xhr.onerror = function() {
DataManager._errorUrl = DataManager._errorUrl || url;
};
xhr.send();
} else {
this.loadLinkedMaps();
}
};
Scene_Map.prototype.onLinksLoaded = function() {
if(!!$gameMap._dataLikedMaps.Left && !!$gameMap._dataLikedMaps.Top) {
this._corners.push("TopLeft");
}
if(!!$gameMap._dataLikedMaps.Left && !!$gameMap._dataLikedMaps.Bottom) {
this._corners.push("BottomLeft");
}
if(!!$gameMap._dataLikedMaps.Right && !!$gameMap._dataLikedMaps.Top) {
this._corners.push("TopRight");
}
if(!!$gameMap._dataLikedMaps.Right && !!$gameMap._dataLikedMaps.Bottom) {
this._corners.push("BottomRight");
}
this._waitingCorners = this._corners.length;
if(this._waitingCorners > 0) {
return this.loadCornerLinks();
} else {
return this.linkMaps();
}
}
Scene_Map.prototype.loadCornerLinks = function() {
this._waitingCorners = this._corners.length;
if(this._waitingCorners == 0) {
return this.onCornersLoaded();
} else {
return this.loadCorner(this._corners.pop());
}
};
Scene_Map.prototype.loadCorner = function(dir) {
var mapId = 0;
switch(dir) {
case "TopLeft":
if($gameMap._dataLikedMaps.Left.meta.linkTop === $gameMap._dataLikedMaps.Top.meta.linkLeft) {
mapId = parseInt($gameMap._dataLikedMaps.Left.meta.linkTop, 10);
}
break;
case "TopRight":
if($gameMap._dataLikedMaps.Right.meta.linkTop === $gameMap._dataLikedMaps.Top.meta.linkRight) {
mapId = parseInt($gameMap._dataLikedMaps.Right.meta.linkTop, 10);
}
break;
case "BottomLeft":
if($gameMap._dataLikedMaps.Left.meta.linkBottom === $gameMap._dataLikedMaps.Bottom.meta.linkLeft) {
mapId = parseInt($gameMap._dataLikedMaps.Left.meta.linkBottom, 10);
}
break;
case "BottomRight":
if($gameMap._dataLikedMaps.Right.meta.linkBottom === $gameMap._dataLikedMaps.Bottom.meta.linkRight) {
mapId = parseInt($gameMap._dataLikedMaps.Right.meta.linkBottom, 10);
}
break;
}
if(mapId > 0 && !!$dataMapInfos[mapId]) {
var scene = this;
var xhr = new XMLHttpRequest();
var filename = "Map%1.json".format(mapId.padZero(3));
var url = "data/" + filename;
xhr.open("GET", url);
xhr.overrideMimeType("application/json");
xhr.onload = function() {
if(xhr.status < 400) {
try {
var dataMap = JSON.parse(xhr.responseText);
DataManager.extractMetadata(dataMap);
$gameMap._dataCornerLinks[dir] = dataMap;
} finally {
scene.loadCornerLinks();
}
}
};
xhr.onerror = function() {
DataManager._errorUrl = DataManager._errorUrl || url;
};
xhr.send();
} else {
this.loadCornerLinks();
}
};
Scene_Map.prototype.onCornersLoaded = function() {
this.linkMaps();
};
Scene_Map.prototype.linkMaps = function() {
var newMap = {
data: [],
width: $dataMap.width,
height: $dataMap.height,
}
if(!!$gameMap._dataLikedMaps.Left) {
newMap.width += $gameMap.offsetH;
}
if(!!$gameMap._dataLikedMaps.Right) {
newMap.width += $gameMap.offsetH;
}
if(!!$gameMap._dataLikedMaps.Top) {
newMap.height += $gameMap.offsetV;
}
if(!!$gameMap._dataLikedMaps.Bottom) {
newMap.height += $gameMap.offsetV;
}
// Fusion des cartes
for(var z = 0; z < 6; ++z) {
for(var y = 0; y < newMap.height; ++y) {
for(var x = 0; x < newMap.width; ++x) {
var indexTileNewMap = (z * newMap.height * newMap.width) + (y * newMap.width) + x;
var indexTile = 0;
var valueTile = 0;
if(!!$gameMap._dataCornerLinks.TopLeft) { // Si coin haut gauche
if(x < $gameMap.offsetH && y < $gameMap.offsetV) { // Si on est dans la partie à joindre
indexTile = (z * $gameMap._dataCornerLinks.TopLeft.height * $gameMap._dataCornerLinks.TopLeft.width) + (($gameMap._dataCornerLinks.TopLeft.height - $gameMap.offsetV + y) * $gameMap._dataCornerLinks.TopLeft.width) + ($gameMap._dataCornerLinks.TopLeft.width - $gameMap.offsetH + x);
valueTile = $gameMap._dataCornerLinks.TopLeft.data[indexTile];
}
}
if(!!$gameMap._dataCornerLinks.TopRight) { // Si coin haut droit
if(x >= newMap.width - $gameMap.offsetH && y < $gameMap.offsetV) { // Si on est dans la partie à joindre
if(!$gameMap._dataLikedMaps.Left) { // S'il n'y a pas de jointure à gauche
indexTile = (z * $gameMap._dataCornerLinks.TopRight.height * $gameMap._dataCornerLinks.TopRight.width) + (($gameMap._dataCornerLinks.TopRight.height - $gameMap.offsetV + y) * $gameMap._dataCornerLinks.TopRight.width) + (x - $dataMap.width);
valueTile = $gameMap._dataCornerLinks.TopRight.data[indexTile];
} else { // S'il y a une jointure à gauche
indexTile = (z * $gameMap._dataCornerLinks.TopRight.height * $gameMap._dataCornerLinks.TopRight.width) + (($gameMap._dataCornerLinks.TopRight.height - $gameMap.offsetV + y) * $gameMap._dataCornerLinks.TopRight.width) + (x - $dataMap.width - $gameMap.offsetH);
valueTile = $gameMap._dataCornerLinks.TopRight.data[indexTile];
}
}
}
if(!!$gameMap._dataCornerLinks.BottomLeft) { // Si coin bas gauche
if(x < $gameMap.offsetH && y >= newMap.height - $gameMap.offsetV) { // Si on est dans la partie à joindre
if(!$gameMap._dataLikedMaps.Top) { // S'il n'y a pas de jointure au dessus
indexTile = (z * $gameMap._dataCornerLinks.BottomLeft.height * $gameMap._dataCornerLinks.BottomLeft.width) + ((y - $dataMap.height) * $gameMap._dataCornerLinks.BottomLeft.width) + ($gameMap._dataCornerLinks.BottomLeft.width - $gameMap.offsetH + x);
valueTile = $gameMap._dataCornerLinks.BottomLeft.data[indexTile];
} else { // S'il n'y a pas de jointure au dessus
indexTile = (z * $gameMap._dataCornerLinks.BottomLeft.height * $gameMap._dataCornerLinks.BottomLeft.width) + ((y - $dataMap.height - $gameMap.offsetV) * $gameMap._dataCornerLinks.BottomLeft.width) + ($gameMap._dataCornerLinks.BottomLeft.width - $gameMap.offsetH + x);
valueTile = $gameMap._dataLikedMaps.Bottom.data[indexTile];
}
}
}
if(!!$gameMap._dataCornerLinks.BottomRight) { // Si coin bas droite
if(x >= newMap.width - $gameMap.offsetH && y >= newMap.height - $gameMap.offsetV) { // Si on est dans la partie à joindre
if(!$gameMap._dataLikedMaps.Top) { // S'il n'y a pas de jointure au dessus
if(!$gameMap._dataLikedMaps.Left) { // S'il n'y a pas de jointure à gauche
indexTile = (z * $gameMap._dataCornerLinks.BottomRight.height * $gameMap._dataCornerLinks.BottomRight.width) + ((y - $dataMap.height) * $gameMap._dataCornerLinks.BottomRight.width) + (x - $dataMap.width);
valueTile = $gameMap._dataCornerLinks.BottomRight.data[indexTile];
} else { // S'il y a une jointure à gauche
indexTile = (z * $gameMap._dataCornerLinks.BottomRight.height * $gameMap._dataCornerLinks.BottomRight.width) + ((y - $dataMap.height) * $gameMap._dataCornerLinks.BottomRight.width) + (x - $dataMap.width - $gameMap.offsetH);
valueTile = $gameMap._dataCornerLinks.BottomRight.data[indexTile];
}
} else { // S'il n'y a pas de jointure au dessus
if(!$gameMap._dataLikedMaps.Left) { // S'il n'y a pas de jointure à gauche
indexTile = (z * $gameMap._dataCornerLinks.BottomRight.height * $gameMap._dataCornerLinks.BottomRight.width) + ((y - $dataMap.height - $gameMap.offsetV) * $gameMap._dataCornerLinks.BottomRight.width) + (x - $dataMap.width);
valueTile = $gameMap._dataCornerLinks.BottomRight.data[indexTile];
} else { // S'il y a une jointure à gauche
indexTile = (z * $gameMap._dataCornerLinks.BottomRight.height * $gameMap._dataCornerLinks.BottomRight.width) + ((y - $dataMap.height - $gameMap.offsetV) * $gameMap._dataCornerLinks.BottomRight.width) + (x - $dataMap.width - $gameMap.offsetH);
valueTile = $gameMap._dataCornerLinks.BottomRight.data[indexTile];
}
}
}
}
if(!!$gameMap._dataLikedMaps.Left) { // Si jointure à gauche
if(x < $gameMap.offsetH) { // Si on est dans la partie à joindre
if(!$gameMap._dataLikedMaps.Top) { // S'il n'y a pas de jointure au dessus
if(!$gameMap._dataLikedMaps.Bottom || y < newMap.height - $gameMap.offsetV) { // S'il n'y a pas de jointure en dessous ou qu'on se trouve au dessus
indexTile = (z * $gameMap._dataLikedMaps.Left.height * $gameMap._dataLikedMaps.Left.width) + (y * $gameMap._dataLikedMaps.Left.width) + ($gameMap._dataLikedMaps.Left.width - $gameMap.offsetH + x);
valueTile = $gameMap._dataLikedMaps.Left.data[indexTile];
}
} else if(y >= $gameMap.offsetV) { // Si on est en dessous de la jointure au dessus
if(!$gameMap._dataLikedMaps.Bottom || y < newMap.height - $gameMap.offsetV) { // S'il n'y a pas de jointure en dessous ou qu'on se trouve au dessus
indexTile = (z * $gameMap._dataLikedMaps.Left.height * $gameMap._dataLikedMaps.Left.width) + ((y - $gameMap.offsetV) * $gameMap._dataLikedMaps.Left.width) + ($gameMap._dataLikedMaps.Left.width - $gameMap.offsetH + x);
valueTile = $gameMap._dataLikedMaps.Left.data[indexTile];
}
}
}
}
if(!!$gameMap._dataLikedMaps.Right) { // Si jointure à droite
if(x >= newMap.width - $gameMap.offsetH) { // Si on est dans la partie à joindre
if(!$gameMap._dataLikedMaps.Top) { // S'il n'y a pas de jointure au dessus
if(!$gameMap._dataLikedMaps.Bottom || y < newMap.height - $gameMap.offsetV) { // S'il n'y a pas de jointure en dessous ou qu'on se trouve au dessus
if(!$gameMap._dataLikedMaps.Left) { // S'il n'y a pas de jointure à gauche
indexTile = (z * $gameMap._dataLikedMaps.Right.height * $gameMap._dataLikedMaps.Right.width) + (y * $gameMap._dataLikedMaps.Right.width) + (x - $dataMap.width);
valueTile = $gameMap._dataLikedMaps.Right.data[indexTile];
} else { // S'il y a une jointure à gauche
indexTile = (z * $gameMap._dataLikedMaps.Right.height * $gameMap._dataLikedMaps.Right.width) + (y * $gameMap._dataLikedMaps.Right.width) + (x - $dataMap.width - $gameMap.offsetH);
valueTile = $gameMap._dataLikedMaps.Right.data[indexTile];
}
}
} else if(y >= $gameMap.offsetV) { // Si on est en dessous de la jointure au dessus
if(!$gameMap._dataLikedMaps.Bottom || y < newMap.height - $gameMap.offsetV) { // S'il n'y a pas de jointure en dessous ou qu'on se trouve au dessus
if(!$gameMap._dataLikedMaps.Left) { // S'il n'y a pas de jointure à gauche
indexTile = (z * $gameMap._dataLikedMaps.Right.height * $gameMap._dataLikedMaps.Right.width) + ((y - $gameMap.offsetV) * $gameMap._dataLikedMaps.Right.width) + (x - $dataMap.width);
valueTile = $gameMap._dataLikedMaps.Right.data[indexTile];
} else { // S'il y a une jointure à gauche
indexTile = (z * $gameMap._dataLikedMaps.Right.height * $gameMap._dataLikedMaps.Right.width) + ((y - $gameMap.offsetV) * $gameMap._dataLikedMaps.Right.width) + (x - $dataMap.width - $gameMap.offsetH);
valueTile = $gameMap._dataLikedMaps.Right.data[indexTile];
}
}
}
}
}
if(!!$gameMap._dataLikedMaps.Top) { // Si jointure au dessus
if(y < $gameMap.offsetV) { // Si on est dans la partie à joindre
if(!$gameMap._dataLikedMaps.Left) { // S'il n'y a pas de jointure à gauche
if(!$gameMap._dataLikedMaps.Right || x < newMap.width - $gameMap.offsetH) { // S'il n'y a pas de jointure à droite ou qu'on se trouve avant
indexTile = (z * $gameMap._dataLikedMaps.Top.height * $gameMap._dataLikedMaps.Top.width) + (($gameMap._dataLikedMaps.Top.height - $gameMap.offsetV + y) * $gameMap._dataLikedMaps.Top.width) + x;
valueTile = $gameMap._dataLikedMaps.Top.data[indexTile];
}
} else if(x >= $gameMap.offsetH) { // Si on est après la jointure à gauche
if(!$gameMap._dataLikedMaps.Right || x < newMap.width - $gameMap.offsetH) { // S'il n'y a pas de jointure à droite ou qu'on se trouve avant
indexTile = (z * $gameMap._dataLikedMaps.Top.height * $gameMap._dataLikedMaps.Top.width) + (($gameMap._dataLikedMaps.Top.height - $gameMap.offsetV + y) * $gameMap._dataLikedMaps.Top.width) + (x - $gameMap.offsetH);
valueTile = $gameMap._dataLikedMaps.Top.data[indexTile];
}
}
}
}
if(!!$gameMap._dataLikedMaps.Bottom) { // Si jointure en dessous
if(y >= newMap.height - $gameMap.offsetV) { // Si on est dans la partie à joindre
if(!$gameMap._dataLikedMaps.Left) { // S'il n'y a pas de jointure à gauche
if(!$gameMap._dataLikedMaps.Top) { // S'il n'y a pas de jointure au dessus
if(!$gameMap._dataLikedMaps.Right || x < newMap.width - $gameMap.offsetH) { // S'il n'y a pas de jointure à droite ou qu'on se trouve avant
indexTile = (z * $gameMap._dataLikedMaps.Bottom.height * $gameMap._dataLikedMaps.Bottom.width) + ((y - $dataMap.height) * $gameMap._dataLikedMaps.Bottom.width) + x;
valueTile = $gameMap._dataLikedMaps.Bottom.data[indexTile];
}
} else { // S'il n'y a pas de jointure au dessus
if(!$gameMap._dataLikedMaps.Right || x < newMap.width - $gameMap.offsetH) { // S'il n'y a pas de jointure à droite ou qu'on se trouve avant
indexTile = (z * $gameMap._dataLikedMaps.Bottom.height * $gameMap._dataLikedMaps.Bottom.width) + ((y - $dataMap.height - $gameMap.offsetV) * $gameMap._dataLikedMaps.Bottom.width) + x;
valueTile = $gameMap._dataLikedMaps.Bottom.data[indexTile];
}
}
} else if(x >= $gameMap.offsetH) { // Si on est après la jointure à gauche
if(!$gameMap._dataLikedMaps.Top) { // S'il n'y a pas de jointure au dessus
if(!$gameMap._dataLikedMaps.Right || x < newMap.width - $gameMap.offsetH) { // S'il n'y a pas de jointure à droite ou qu'on se trouve avant
indexTile = (z * $gameMap._dataLikedMaps.Bottom.height * $gameMap._dataLikedMaps.Bottom.width) + ((y - $dataMap.height) * $gameMap._dataLikedMaps.Bottom.width) + (x - $gameMap.offsetH);
valueTile = $gameMap._dataLikedMaps.Bottom.data[indexTile];
}
} else { // S'il n'y a pas de jointure au dessus
if(!$gameMap._dataLikedMaps.Right || x < newMap.width - $gameMap.offsetH) { // S'il n'y a pas de jointure à droite ou qu'on se trouve avant
indexTile = (z * $gameMap._dataLikedMaps.Bottom.height * $gameMap._dataLikedMaps.Bottom.width) + ((y - $dataMap.height - $gameMap.offsetV) * $gameMap._dataLikedMaps.Bottom.width) + (x - $gameMap.offsetH);
valueTile = $gameMap._dataLikedMaps.Bottom.data[indexTile];
}
}
}
}
}
if(valueTile === 0) { // Si le tile n'a pas été défini avant
if(!$gameMap._dataLikedMaps.Top && !$gameMap._dataLikedMaps.Left) { // Si aucune jointure à gauche ou au dessus
if((!$gameMap._dataLikedMaps.Right || x < (newMap.width - $gameMap.offsetH)) && (!$gameMap._dataLikedMaps.Bottom || y < (newMap.height - $gameMap.offsetV))) { // Si on ne se trouve pas dans la jointure à droite ou en bas
indexTile = (z * $dataMap.height * $dataMap.width) + (y * $dataMap.width) + x;
valueTile = $dataMap.data[indexTile];
}
} else if(!$gameMap._dataLikedMaps.Top && !!$gameMap._dataLikedMaps.Left && x >= $gameMap.offsetH) { // Si jointure à gauche mais pas au dessus et si on est pas dans la zone à joindre
if((!$gameMap._dataLikedMaps.Right || x < (newMap.width - $gameMap.offsetH)) && (!$gameMap._dataLikedMaps.Bottom || y < (newMap.height - $gameMap.offsetV))) { // Si on ne se trouve pas dans la jointure à droite ou en bas
indexTile = (z * $dataMap.height * $dataMap.width) + (y * $dataMap.width) + (x - $gameMap.offsetH);
valueTile = $dataMap.data[indexTile];
}
} else if(!!$gameMap._dataLikedMaps.Top && !$gameMap._dataLikedMaps.Left && y >= $gameMap.offsetV) { // Si jointure au dessus mais pas à gauche et si on est pas dans la zone à joindre
if((!$gameMap._dataLikedMaps.Right || x < (newMap.width - $gameMap.offsetH)) && (!$gameMap._dataLikedMaps.Bottom || y < (newMap.height - $gameMap.offsetV))) { // Si on ne se trouve pas dans la jointure à droite ou en bas
indexTile = (z * $dataMap.height * $dataMap.width) + ((y - $gameMap.offsetV) * $dataMap.width) + x;
valueTile = $dataMap.data[indexTile];
}
} else if(!!$gameMap._dataLikedMaps.Top && !!$gameMap._dataLikedMaps.Left && y >= $gameMap.offsetV && x >= $gameMap.offsetH) { // Si jointures à gauche et au dessus et si on est pas dans la zone à joindre
if((!$gameMap._dataLikedMaps.Right || x < (newMap.width - $gameMap.offsetH)) && (!$gameMap._dataLikedMaps.Bottom || y < (newMap.height - $gameMap.offsetV))) { // Si on ne se trouve pas dans la jointure à droite ou en bas
indexTile = (z * $dataMap.height * $dataMap.width) + ((y - $gameMap.offsetV) * $dataMap.width) + (x - $gameMap.offsetH);
valueTile = $dataMap.data[indexTile];
}
}
}
newMap.data[indexTileNewMap] = valueTile;
}
}
}
// Si jointure en haut ou à gauche, coordonnées du joueur et des évènements décalées
if(!!$gameMap._dataLikedMaps.Top || !!$gameMap._dataLikedMaps.Left) {
// Actualisation des coordonnées du joueur
$gamePlayer._newX += (!!$gameMap._dataLikedMaps.Left ? $gameMap.offsetH : 0);
$gamePlayer._newY += (!!$gameMap._dataLikedMaps.Top ? $gameMap.offsetV : 0);
// Actualisation des coordonnées des évents
for(e = 1; e < $dataMap.events.length; ++e) {
if(!!$dataMap.events[e]) {
$dataMap.events[e].x += (!!$gameMap._dataLikedMaps.Left ? $gameMap.offsetH : 0);
$dataMap.events[e].y += (!!$gameMap._dataLikedMaps.Top ? $gameMap.offsetV : 0);
}
}
}
// Affichage des évents des maps jointes qui sont sur les parties affichées (ceux ci sont au préalable vidés de leurs commandes et ne s'exécuteront pas)
if(!!$gameMap._dataCornerLinks.TopLeft) {
for(e = 1; e < $gameMap._dataCornerLinks.TopLeft.events.length; ++e) {
var event = $gameMap._dataCornerLinks.TopLeft.events[e];
var ajouterEvent = false;
if(!!event && event.x >= $gameMap._dataCornerLinks.TopLeft.width - $gameMap.offsetH && event.y >= $gameMap._dataCornerLinks.TopLeft.height - $gameMap.offsetV) {
for(p = 0; p < event.pages.length; ++p) {
event.pages[p].list = [];
event.pages[p].trigger = 0;
ajouterEvent = ajouterEvent || !!event.pages[p].image.characterName || !!event.pages[p].image.tileId;
}
if(ajouterEvent) {
event.id = $dataMap.events.length;
event.x -= ($gameMap._dataCornerLinks.TopLeft.width - $gameMap.offsetH);
event.y -= ($gameMap._dataCornerLinks.TopLeft.height - $gameMap.offsetV);
$dataMap.events.push(event);
}
}
}
}
if(!!$gameMap._dataCornerLinks.TopRight) {
for(e = 1; e < $gameMap._dataCornerLinks.TopRight.events.length; ++e) {
var event = $gameMap._dataCornerLinks.TopRight.events[e];
var ajouterEvent = false;
if(!!event && event.x < $gameMap.offsetH && event.y >= $gameMap._dataCornerLinks.TopRight.height - $gameMap.offsetV) {
for(p = 0; p < event.pages.length; ++p) {
event.pages[p].list = [];
event.pages[p].trigger = 0;
ajouterEvent = ajouterEvent || !!event.pages[p].image.characterName || !!event.pages[p].image.tileId;
}
if(ajouterEvent) {
event.id = $dataMap.events.length;
event.x += (!!$gameMap._dataLikedMaps.Left ? $gameMap.offsetH : 0) + $dataMap.width;
event.y -= ($gameMap._dataCornerLinks.TopRight.height - $gameMap.offsetV);
$dataMap.events.push(event);
}
}
}
}
if(!!$gameMap._dataCornerLinks.BottomLeft) {
for(e = 1; e < $gameMap._dataCornerLinks.BottomLeft.events.length; ++e) {
var event = $gameMap._dataCornerLinks.BottomLeft.events[e];
var ajouterEvent = false;
if(!!event && event.x >= $gameMap._dataCornerLinks.BottomLeft.width - $gameMap.offsetH && event.y < $gameMap.offsetV) {
for(p = 0; p < event.pages.length; ++p) {
event.pages[p].list = [];
event.pages[p].trigger = 0;
ajouterEvent = ajouterEvent || !!event.pages[p].image.characterName || !!event.pages[p].image.tileId;
}
if(ajouterEvent) {
event.id = $dataMap.events.length;
event.x -= ($gameMap._dataCornerLinks.BottomLeft.width - $gameMap.offsetH);
event.y += (!!$gameMap._dataLikedMaps.Top ? $gameMap.offsetV : 0) + $dataMap.height;
$dataMap.events.push(event);
}
}
}
}
if(!!$gameMap._dataCornerLinks.BottomRight) {
for(e = 1; e < $gameMap._dataCornerLinks.BottomRight.events.length; ++e) {
var event = $gameMap._dataCornerLinks.BottomRight.events[e];
var ajouterEvent = false;
if(!!event && event.x < $gameMap.offsetH && event.y < $gameMap.offsetV) {
for(p = 0; p < event.pages.length; ++p) {
event.pages[p].list = [];
event.pages[p].trigger = 0;
ajouterEvent = ajouterEvent || !!event.pages[p].image.characterName || !!event.pages[p].image.tileId;
}
if(ajouterEvent) {
event.id = $dataMap.events.length;
event.x += (!!$gameMap._dataLikedMaps.Left ? $gameMap.offsetH : 0) + $dataMap.width;
event.y += (!!$gameMap._dataLikedMaps.Top ? $gameMap.offsetV : 0) + $dataMap.height;
$dataMap.events.push(event);
}
}
}
}
if(!!$gameMap._dataLikedMaps.Left) {
for(e = 1; e < $gameMap._dataLikedMaps.Left.events.length; ++e) {
var event = $gameMap._dataLikedMaps.Left.events[e];
var ajouterEvent = false;
if(!!event && event.x >= $gameMap._dataLikedMaps.Left.width - $gameMap.offsetH && event.y < $dataMap.height) {
for(p = 0; p < event.pages.length; ++p) {
event.pages[p].list = [];
event.pages[p].trigger = 0;
ajouterEvent = ajouterEvent || !!event.pages[p].image.characterName || !!event.pages[p].image.tileId;
}
if(ajouterEvent) {
event.id = $dataMap.events.length;
event.x -= ($gameMap._dataLikedMaps.Left.width - $gameMap.offsetH);
event.y += (!!$gameMap._dataLikedMaps.Top ? $gameMap.offsetV : 0);
$dataMap.events.push(event);
}
}
}
}
if(!!$gameMap._dataLikedMaps.Right) {
for(e = 1; e < $gameMap._dataLikedMaps.Right.events.length; ++e) {
var event = $gameMap._dataLikedMaps.Right.events[e];
var ajouterEvent = false;
if(!!event && event.x < $gameMap.offsetH && event.y < $dataMap.height) {
for(p = 0; p < event.pages.length; ++p) {
event.pages[p].list = [];
event.pages[p].trigger = 0;
ajouterEvent = ajouterEvent || !!event.pages[p].image.characterName || !!event.pages[p].image.tileId;
}
if(ajouterEvent) {
event.id = $dataMap.events.length;
event.x += (!!$gameMap._dataLikedMaps.Left ? $gameMap.offsetH : 0) + $dataMap.width;
event.y += (!!$gameMap._dataLikedMaps.Top ? $gameMap.offsetV : 0);
$dataMap.events.push(event);
}
}
}
}
if(!!$gameMap._dataLikedMaps.Top) {
for(e = 1; e < $gameMap._dataLikedMaps.Top.events.length; ++e) {
var event = $gameMap._dataLikedMaps.Top.events[e];
var ajouterEvent = false;
if(!!event && event.y >= $gameMap._dataLikedMaps.Top.height - $gameMap.offsetV && event.x < $dataMap.width) {
for(p = 0; p < event.pages.length; ++p) {
event.pages[p].list = [];
event.pages[p].trigger = 0;
ajouterEvent = ajouterEvent || !!event.pages[p].image.characterName || !!event.pages[p].image.tileId;
}
if(ajouterEvent) {
event.id = $dataMap.events.length;
event.x += (!!$gameMap._dataLikedMaps.Left ? $gameMap.offsetH : 0);
event.y -= ($gameMap._dataLikedMaps.Top.height - $gameMap.offsetV);
$dataMap.events.push(event);
}
}
}
}
if(!!$gameMap._dataLikedMaps.Bottom) {
for(e = 1; e < $gameMap._dataLikedMaps.Bottom.events.length; ++e) {
var event = $gameMap._dataLikedMaps.Bottom.events[e];
var ajouterEvent = false;
if(!!event && event.y < $gameMap.offsetV && event.x < $dataMap.width) {
for(p = 0; p < event.pages.length; ++p) {
event.pages[p].list = [];
event.pages[p].trigger = 0;
ajouterEvent = ajouterEvent || !!event.pages[p].image.characterName || !!event.pages[p].image.tileId;
}
if(ajouterEvent) {
event.id = $dataMap.events.length;
event.x += (!!$gameMap._dataLikedMaps.Left ? $gameMap.offsetH : 0);
event.y += (!!$gameMap._dataLikedMaps.Top ? $gameMap.offsetV : 0) + $dataMap.height;
$dataMap.events.push(event);
}
}
}
}
$dataMap.width = newMap.width;
$dataMap.height = newMap.height;
$dataMap.data = newMap.data;
return Scene_Map.prototype.aliasMaplinkOnMapLoaded.call(this);
};
Game_Player.prototype.aliasMaplinkUpdate = Game_Player.prototype.update;
Game_Player.prototype.update = function(sceneActive) {
Game_Player.prototype.aliasMaplinkUpdate.call(this, sceneActive);
if (!this.isMoving()) {
this.checkMapLink();
}
};
Game_Player.prototype.checkMapLink = function() {
var newMapId = 0;
if(!!$gameMap._dataLikedMaps.Left && this.direction() === 4 && this.x < $gameMap.offsetH) { // Jointure à gauche
this.reserveTransfer(parseInt($dataMap.meta.linkLeft, 10), $gameMap._dataLikedMaps.Left.width - 1, this.y - (!!$gameMap._dataLikedMaps.Top ? $gameMap.offsetV : 0), 4, 2);
if($gameTemp.isDestinationValid()) {
var x = $gameMap._dataLikedMaps.Left.width + $gameTemp.destinationX() - $gameMap.offsetH;
$gameTemp.setDestination(x, $gameTemp.destinationY());
}
} else if(!!$gameMap._dataLikedMaps.Right && this.direction() === 6 && this.x >= ($dataMap.width - $gameMap.offsetH)) { // Jointure à droite
this.reserveTransfer(parseInt($dataMap.meta.linkRight, 10), 0, this.y - (!!$gameMap._dataLikedMaps.Top ? $gameMap.offsetV : 0), 6, 2);
if($gameTemp.isDestinationValid()) {
var x = $gameTemp.destinationX() - $dataMap.width + $gameMap.offsetH
x += (!!$gameMap._dataLikedMaps.Right && !!$gameMap._dataLikedMaps.Right.meta && !!$gameMap._dataLikedMaps.Right.meta.linkLeft ? $gameMap.offsetH : 0);
$gameTemp.setDestination(x, $gameTemp.destinationY());
}
} else if(!!$gameMap._dataLikedMaps.Top && this.direction() === 8 && this.y < $gameMap.offsetV) { // Jointure au dessus
this.reserveTransfer(parseInt($dataMap.meta.linkTop, 10), this.x - (!!$gameMap._dataLikedMaps.Left ? $gameMap.offsetH : 0), $gameMap._dataLikedMaps.Top.height - 1, 8, 2);
if($gameTemp.isDestinationValid()) {
var y = $gameMap._dataLikedMaps.Top.height + $gameTemp.destinationY() - $gameMap.offsetV;
$gameTemp.setDestination($gameTemp.destinationX(), y);
}
} else if(!!$gameMap._dataLikedMaps.Bottom && this.direction() === 2 && this.y >= ($dataMap.height - $gameMap.offsetV)) { // Jointure en dessous
this.reserveTransfer(parseInt($dataMap.meta.linkBottom, 10), this.x - (!!$gameMap._dataLikedMaps.Left ? $gameMap.offsetH : 0), 0, 2, 2);
if($gameTemp.isDestinationValid()) {
var y = $gameTemp.destinationY() - $dataMap.height + $gameMap.offsetV
y += (!!$gameMap._dataLikedMaps.Bottom && !!$gameMap._dataLikedMaps.Bottom.meta && !!$gameMap._dataLikedMaps.Bottom.meta.linkTop ? $gameMap.offsetV : 0);
$gameTemp.setDestination($gameTemp.destinationX(), y);
}
}
};
Game_Temp.prototype.setDestination = function(x, y) {
console.log(x, y);
this._destinationX = x;
this._destinationY = y;
};
Sprite_Destination.prototype.update = function() {
Sprite.prototype.update.call(this);
if(!$gamePlayer.isTransferring() && $gameTemp.isDestinationValid()){
this.updatePosition();
this.updateAnimation();
this.visible = true;
} else {
this._frameCount = 0;
this.visible = false;
}
};
})();
L’utilisation est assez simple. Cependant, pour que le maplink fonctionne, il est nécessaire que les deux cartes à joindre utilisent le même tileset, ou au moins que tous les éléments de chaque carte affichée sur l’autre soient placés de facon identique sur les 2 tilesets.
Une fois jointes, les lignes (pour les maps au dessus et en dessous)/colonnes (pour les maps à gauche et à droite) à proximité de la jointure seront affichées sur la map courante.
Les remarques à insérer dans les propriétés des cartes sont les suivantes :
- <linkLeft:ID_CARTE> : Pour joindre la carte ID_CARTE à gauche
- <linkRight:ID_CARTE> : Pour joindre la carte ID_CARTE à droite
- <linkTop:ID_CARTE> : Pour joindre la carte ID_CARTE au dessus
- <linkBottom:ID_CARTE> : Pour joindre la carte ID_CARTE en dessous
Voilà un premier schéma expliquant comment joindre différentes cartes ensemble, la map courante étant celle sur laquelle se trouve le joueur.

Un maximum de 4 cartes peuvent être jointes : une au dessus (linkTop), une en dessous (linkBottom), une à gauche (linkLeft) et une à droite (linkRight).
Il n’est pas nécessaire que les cartes jointes fassent la même dimension, mais le côté en commun devrait être de même taille sur les deux cartes pour éviter l’apparition de tiles noirs au niveau de la jointure.

En outre, actuellement, les jointures sont alignées à partir de la gauche de chaque carte pour les jointures horizontales (linkLeft et linkRight) et à partir du haut pour les jointures verticales (linkTop et linkBottom).
Dans l’exemple ci-dessus, le coin en haut à gauche serait rempli de tiles vides. Une solution pourrait être alors d’empêcher le joueur d’approcher de ce coin. Cependant, le maplink peut également remplir ce vide automatiquement, si les cartes 2 et 3 sont elles même jointes à une même carte comme dans le schéma ci-dessous :

En outre, les évents présents dans les zones affichées des cartes jointes seront aussi affichés si ceux-ci ont une apparence sur au moins une page. Les évènements ainsi ajoutés ne seront pas exécutés (dans le cas où ceux-ci sont en démarrage automatique ou en processus parallèle) et leur apparence sur la carte sera conditionné aux mêmes règles que sur leur propre carte.
Ce plugin intègre 2 paramètres :
- Taille jointure horizontale : Nombre de colonnes de tiles affichées des cartes jointes à gauche ou à droite (par défaut : 9)
- Taille jointure verticale : Nombre de lignes de tiles affichées des cartes jointes au dessus ou en dessous (par défaut : 7)
Le choix des valeurs par défaut s’explique ainsi : dans le cas de la résolution par défaut des jeux RMMV (soit 17×13 tiles) c’est le nombre de lignes/colonnes qu’il faut ajouter à la carte courante pour que le joueur ait l’impression de se déplacer sur une seule et même carte plutôt que sur plusieurs morceaux de plus petite taille.
Pour un rendu optimal, il est évidemment recommandé de bien penser à faire les jointures sur les 2 cartes (sans quoi, au moment de la téléportation de la première carte à la seconde, le joueur se retrouve totalement au bord de la carte).
Ce plugin est actuellement destiné à être utilisé pour remplacer de grandes cartes (connues pour lagguer) comme de grandes villes ou de longues routes/grottes/… par de plus petites assemblées les unes aux autres.
Ce qui reste à intégrer/améliorer :
- Fluidifier la transition entre 2 cartes (actuellement, si le joueur se déplace avant la fin de sa téléportation – s’il maintient une touche de déplacement par exemple -, il y a comme un effet saccadé au moment de la transition)
- Intégrer la possibilité d’un décalage dans la jointure
- Joindre des maps utilisant des tilesets différents
- Mettre un tile par défaut pour remplacer les tiles vides
Voici une vidéo montrant ce qu’on peut obtenir avec ce système :
Remerciements
Je dois remercier Tonyryu pour ses notes (disponibles à cette adresse : https://www.rpgmakervx-fr.com/t19192-note-technique-les-tile-id-et-leur-decodage-pour-affichage) sur la gestion des tiles.