Skip to content

Instantly share code, notes, and snippets.

@aewhite
Created May 17, 2016 21:17
Show Gist options
  • Save aewhite/f8f229f71258e67fbab887f3b996c8f8 to your computer and use it in GitHub Desktop.
Save aewhite/f8f229f71258e67fbab887f3b996c8f8 to your computer and use it in GitHub Desktop.
Modified GALV_DiagonalMovement plugin to prefer diagonal movement for stairs via magical region ids
//-----------------------------------------------------------------------------
// Galv's Diagonal Movement
//-----------------------------------------------------------------------------
// For: RPGMAKER MV
// GALV_DiagonalMovement.js
//-----------------------------------------------------------------------------
// 2016-05-17 - Version 1.1(AWhite) - added ability to force diagonal moves
// 2016-02-04 - Version 1.1 - added option to slow diagonal move speed
// 2015-12-12 - Version 1.0 - release
//-----------------------------------------------------------------------------
// Terms can be found at:
// galvs-scripts.com
//-----------------------------------------------------------------------------
var Imported = Imported || {};
Imported.Galv_DiagonalMovement = true;
var Galv = Galv || {};
Galv.DM = Galv.DM || {};
//-----------------------------------------------------------------------------
/*:
* @plugindesc Just a basic diagonal movement plugin. Written for compatibility with other Galv plugins.
*
* @author Galv - galvs-scripts.com
*
* @param Diagonal Mouse
* @desc true or false for diagonal pathfinding movement on mouse click. true may conflict with pathfinding plugins.
* @default true
*
* @param Diagonal Charset
* @desc true or false if you want to use diagonal charactersets (see help for more)
* @default true
*
* @param Diagonal Speed
* @desc % of move speed characters move while travelling diagonally
* @default 90
*
* @param Prefer Diagonal Region Id
* @desc region id to use for preferring diagonal movement
* @default 255
*
* @help
* Galv's Diagonal Movement
* ----------------------------------------------------------------------------
* Plug and play. If this doesn't play nice with other plugins, try putting it
* at the top of the plugin list. It overwrites the default diagonal function.
*
* If this conflicts with other pathfinding plugins you might have, change
* 'Diagonal Mouse' setting to false.
*
* When 'Diagonal Charsets' is true, the plugin will change the sprite if the
* character is on a diagonal. The new sprite used will be in the position
* directly below the selected character graphic. This means that only sprites
* on the top of a character sheet will be able to have diagonal graphics.
*
* Sprites on the bottom will not have diagonal graphics.
* ----------------------------------------------------------------------------
*/
//-----------------------------------------------------------------------------
// CODE STUFFS
//-----------------------------------------------------------------------------
(function () {
Galv.DM.mouseMove = PluginManager.parameters('Galv_DiagonalMovement')["Diagonal Mouse"].toLowerCase() == 'true';
Galv.DM.diagGraphic = PluginManager.parameters('Galv_DiagonalMovement')["Diagonal Charset"].toLowerCase() == 'true';
Galv.DM.diagMod = Number(PluginManager.parameters('Galv_DiagonalMovement')["Diagonal Speed"]) * 0.01;
Galv.DM.diagRegionId = Number(PluginManager.parameters('Galv_DiagonalMovement')["Prefer Diagonal Region Id"]);
Game_CharacterBase.prototype._cframes = 3;
var Galv_Game_CharacterBase_initMembers = Game_CharacterBase.prototype.initMembers;
Game_CharacterBase.prototype.initMembers = function () {
Galv_Game_CharacterBase_initMembers.call(this);
this.setDiagMoveSpeed(this._moveSpeed);
};
var Galv_Game_CharacterBase_setMoveSpeed = Game_CharacterBase.prototype.setMoveSpeed;
Game_CharacterBase.prototype.setMoveSpeed = function (moveSpeed) {
Galv_Game_CharacterBase_setMoveSpeed.call(this, moveSpeed);
this.setDiagMoveSpeed(moveSpeed);
};
Game_CharacterBase.prototype.setDiagMoveSpeed = function (moveSpeed) {
this._defaultMoveSpeed = moveSpeed;
this._diagMoveSpeed = moveSpeed * Galv.DM.diagMod;
};
Galv.DM.getHorzVertDirs = function (direction) {
switch (direction) {
case 1:
return [4, 2];
case 3:
return [6, 2];
case 7:
return [4, 8];
case 9:
return [6, 8];
default:
return [0, 0];
}
};
Galv.DM.getDir = function (horz, vert) {
if (horz == 4 && vert == 2) return 1;
if (horz == 6 && vert == 2) return 3;
if (horz == 4 && vert == 8) return 7;
if (horz == 6 && vert == 8) return 9;
return 0;
};
Galv.DM.diagRow = {
3: 0,
1: 1,
9: 2,
7: 3
};
var Galv_Game_CharacterBase_moveStraight = Game_CharacterBase.prototype.moveStraight;
Game_CharacterBase.prototype.moveStraight = function (d) {
this._diagDir = false;
this._moveSpeed = this._defaultMoveSpeed;
Galv_Game_CharacterBase_moveStraight.call(this, d);
};
// OVERWRITE
Game_CharacterBase.prototype.moveDiagonally = function (horz, vert) {
var diag = this.canPassDiagonally(this._x, this._y, horz, vert);
var norm = this.canPass(this._x, this._y, horz) || this.canPass(this._x, this._y, vert);
if (diag) {
this._moveSpeed = this._diagMoveSpeed;
this._diagDir = Galv.DM.getDir(horz, vert);
this._x = $gameMap.roundXWithDirection(this._x, horz);
this._y = $gameMap.roundYWithDirection(this._y, vert);
this._realX = $gameMap.xWithDirection(this._x, this.reverseDir(horz));
this._realY = $gameMap.yWithDirection(this._y, this.reverseDir(vert));
this.increaseSteps();
} else if (norm) {
this._diagDir = false;
this._moveSpeed = this._defaultMoveSpeed;
this.moveStraight(this.getOtherdir(horz, vert));
}
if (this._direction === this.reverseDir(horz)) this.setDirection(horz);
if (this._direction === this.reverseDir(vert)) this.setDirection(vert);
};
Game_CharacterBase.prototype.getOtherdir = function (horz, vert) {
return this.canPass(this._x, this._y, horz) ? horz : vert;
};
// OVERWRITE
Game_Player.prototype.getInputDirection = function () {
return Input.dir8;
};
var Galv_Game_Game_CharacterBase_canPass = Game_CharacterBase.prototype.canPass;
Game_CharacterBase.prototype.canPass = function(x, y, d) {
if (Galv_Game_Game_CharacterBase_canPass.call(this, x, y, d) == true) { return true; }
if ($gameMap.regionId(x, y) == Galv.DM.diagRegionId) {
var x2 = $gameMap.roundXWithDirection(x, d);
var y2 = $gameMap.roundYWithDirection(y, d);
return $gameMap.regionId(x2, y2) == Galv.DM.diagRegionId
}
return false
}
Game_CharacterBase.prototype.preferredPassDiagonally = function(x, y, horz, vert) {
var x2 = $gameMap.roundXWithDirection(x, horz);
var y2 = $gameMap.roundYWithDirection(y, vert);
return $gameMap.regionId(x, y) == Galv.DM.diagRegionId && $gameMap.regionId(x2, y2) == Galv.DM.diagRegionId;
}
// OVERWRITE
Game_CharacterBase.prototype.canPassDiagonally = function(x, y, horz, vert) {
var x2 = $gameMap.roundXWithDirection(x, horz);
var y2 = $gameMap.roundYWithDirection(y, vert);
if ($gameMap.regionId(x, y) && $gameMap.regionId(x2, y2) == Galv.DM.diagRegionId) { return true; };
if (this.canPass(x, y, vert) && this.canPass(x, y2, horz)) {
return true;
}
if (this.canPass(x, y, horz) && this.canPass(x2, y, vert)) {
return true;
}
return false;
};
Game_Player.prototype.determineDirectionSmartly = function (requestedDirection) {
if (requestedDirection % 2 == 0) {
if ($gameMap.regionId(this._x, this._y) == Galv.DM.diagRegionId) {
switch (requestedDirection) {
case 6:
if (this.preferredPassDiagonally(this._x, this._y, 6, 8)) { return 9; }
if (this.preferredPassDiagonally(this._x, this._y, 6, 2)) { return 3; }
break;
case 4:
if (this.preferredPassDiagonally(this._x, this._y, 4, 2)) { return 1; }
if (this.preferredPassDiagonally(this._x, this._y, 4, 8)) { return 7; }
break;
}
}
}
return requestedDirection;
}
var Galv_Game_Player_executeMove = Game_Player.prototype.executeMove;
Game_Player.prototype.executeMove = function (direction) {
direction = this.determineDirectionSmartly(direction)
if (direction % 2 == 0) {
Galv_Game_Player_executeMove.call(this, direction);
return;
}
var dirArray = Galv.DM.getHorzVertDirs(direction);
this.moveDiagonally(dirArray[0], dirArray[1]);
};
// If using Diaonal Charset
if (Galv.DM.diagGraphic) {
var Galv_Sprite_Character_characterPatternY = Sprite_Character.prototype.characterPatternY;
Sprite_Character.prototype.characterPatternY = function () {
if (!this._isBigCharacter && this._character._diagDir && this._character.characterIndex() < 4) {
return Galv.DM.diagRow[this._character._diagDir];
} else {
return Galv_Sprite_Character_characterPatternY.call(this);
}
};
var Galv_Sprite_Character_characterBlockX = Sprite_Character.prototype.characterBlockX;
Sprite_Character.prototype.characterBlockX = function () {
if (!this._isBigCharacter && this._character._diagDir && this._character.characterIndex() < 4) {
var index = this._character.characterIndex() + 4;
return index % 4 * this._character._cframes;
} else {
return Galv_Sprite_Character_characterBlockX.call(this);
}
};
var Galv_Sprite_Character_characterBlockY = Sprite_Character.prototype.characterBlockY;
Sprite_Character.prototype.characterBlockY = function () {
if (!this._isBigCharacter && this._character._diagDir && this._character.characterIndex() < 4) {
var index = this._character.characterIndex() + 4;
return Math.floor(index / 4) * 4;
} else {
return Galv_Sprite_Character_characterBlockY.call(this);
}
}
}
// If using diagonal mouse movement:
if (Galv.DM.mouseMove) {
// OVERWRITE
Game_Character.prototype.findDirectionTo = function (goalX, goalY) {
var searchLimit = this.searchLimit();
var mapWidth = $gameMap.width();
var nodeList = [];
var openList = [];
var closedList = [];
var start = {};
var best = start;
if (this.x === goalX && this.y === goalY) {
return 0;
}
start.parent = null;
start.x = this.x;
start.y = this.y;
start.g = 0;
start.f = $gameMap.distance(start.x, start.y, goalX, goalY);
nodeList.push(start);
openList.push(start.y * mapWidth + start.x);
while (nodeList.length > 0) {
var bestIndex = 0;
for (var i = 0; i < nodeList.length; i++) {
if (nodeList[i].f < nodeList[bestIndex].f) {
bestIndex = i;
}
}
var current = nodeList[bestIndex];
var x1 = current.x;
var y1 = current.y;
var pos1 = y1 * mapWidth + x1;
var g1 = current.g;
nodeList.splice(bestIndex, 1);
openList.splice(openList.indexOf(pos1), 1);
closedList.push(pos1);
if (current.x === goalX && current.y === goalY) {
best = current;
goaled = true;
break;
}
if (g1 >= searchLimit) {
continue;
}
for (var j = 0; j < 9; j++) {
var direction = 1 + j;
if (direction === 5) continue;
var diag = Math.abs(direction % 2) == 1;
var dirs = Galv.DM.getHorzVertDirs(direction);
var horz = dirs[0];
var vert = dirs[1];
if (diag && this.canPassDiagonally(x1, y1, horz, vert) && (this.canPass(x1, y1, horz) || this.canPass(x1, y1, vert))) {
// If can go diagonally and a horizontal dir isn't blocking
var x2 = $gameMap.roundXWithDirection(x1, horz);
var y2 = $gameMap.roundYWithDirection(y1, vert);
} else if (this.canPass(x1, y1, direction)) {
var x2 = $gameMap.roundXWithDirection(x1, direction);
var y2 = $gameMap.roundYWithDirection(y1, direction);
} else {
continue;
}
;
var pos2 = y2 * mapWidth + x2;
if (closedList.contains(pos2)) {
continue;
}
var g2 = g1 + 1;
var index2 = openList.indexOf(pos2);
if (index2 < 0 || g2 < nodeList[index2].g) {
var neighbor;
if (index2 >= 0) {
neighbor = nodeList[index2];
} else {
neighbor = {};
nodeList.push(neighbor);
openList.push(pos2);
}
neighbor.parent = current;
neighbor.x = x2;
neighbor.y = y2;
neighbor.g = g2;
neighbor.f = g2 + $gameMap.distance(x2, y2, goalX, goalY);
if (!best || neighbor.f - neighbor.g < best.f - best.g) {
best = neighbor;
}
}
}
}
var node = best;
while (node.parent && node.parent !== start) {
node = node.parent;
}
var deltaX1 = $gameMap.deltaX(node.x, start.x);
var deltaY1 = $gameMap.deltaY(node.y, start.y);
if (deltaY1 > 0 && deltaX1 > 0) {
return 3;
} else if (deltaY1 > 0 && deltaX1 < 0) {
return 1;
} else if (deltaY1 < 0 && deltaX1 < 0) {
return 7;
} else if (deltaY1 < 0 && deltaX1 > 0) {
return 9;
}
;
if (deltaY1 > 0) {
return 2;
} else if (deltaX1 < 0) {
return 4;
} else if (deltaX1 > 0) {
return 6;
} else if (deltaY1 < 0) {
return 8;
}
var deltaX2 = this.deltaXFrom(goalX);
var deltaY2 = this.deltaYFrom(goalY);
if (Math.abs(deltaX2) > Math.abs(deltaY2)) {
return deltaX2 > 0 ? 4 : 6;
} else if (deltaY2 !== 0) {
return deltaY2 > 0 ? 8 : 2;
}
return 0;
};
}
;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment