/*:
* @target MZ
* @plugindesc Make characters rotate.
* @author Caethyril
* @help Free to use and/or modify for any project.
*
* Rotate a Game_CharacterBase using this script call:
* CHAR.rotate(RATE, REVS);
* e.g. $gamePlayer.rotate(2, 1);
* e.g. $gameMap.event(1).rotate(6);
* Replace:
* - CHAR with a Game_CharacterBase reference;
* - RATE with the clockwise rotation per frame, in degrees;
* - REVS with the total number of revolutions to make.
* REVS is optional: if omitted (or 0) then rotation will be indefinite.
* Use RATE = 0 to stop rotation.
*/
(alias => {
Sprite_Character.prototype.updatePosition = function() {
alias.apply(this, arguments);
this.y += this.pivot.y; // external anchor offset
};
})(Sprite_Character.prototype.updatePosition);
(alias => {
Sprite_Character.prototype.updateOther = function() {
alias.apply(this, arguments);
this.updateRotation(); // see below
};
})(Sprite_Character.prototype.updateOther);
(() => {
/**
* @param {Number} [rate] Degrees of rotation per frame (default: 0).
* @param {Number} [revs] Number of complete revolutions to make (default: 0).
* @returns {{rate:Number,revs:Number,turn:Number}} Character rotation data.
*/
const mkRotationData = function(rate = 0, revs = 0) {
const fRate = (Number(rate) || 0) % 360;
const iRevs = parseInt(revs, 10) || 0;
return fRate ? { rate: fRate, revs: iRevs, turn: 0 } : null;
};
/**
* Sets y-pivot to the midpoint of the sprite's current frame.
* @param {Sprite_CharacterBase} sprite Sprite_CharacterBase reference to update.
*/
const updatePivot = function(sprite) {
sprite.pivot.y = -sprite.patternHeight() / 2;
sprite.updatePosition(); // to stop 1-frame positional glitch
};
// New: apply character rotation. See mkRotationData, above.
Game_CharacterBase.prototype.rotate = function(rate, revs) {
this._rotationData = mkRotationData(rate, revs);
};
// New: update character rotation. See Sprite_Character#updateOther, above.
Sprite_Character.prototype.updateRotation = function() {
const DATA = this._character?._rotationData;
if (DATA) {
const REV = 360;
updatePivot(this);
this.angle += DATA.rate;
if (Math.abs(DATA.turn += DATA.rate) >= REV) {
DATA.turn -= REV;
if (--DATA.revs === 0) { // allow indefinite
this._character.rotate(0);
}
}
}
};
})();