I really appreciate it. You don't know how many years I've waited for a fully functional plugin with no incompatibilities with other plugins. Now everything works perfectly, I just had to put KC_Mirrors below all the Q plugins.
That was what was not making the main character's reflection. Now everything is perfect. Thank you very much.
[MZ/MV] KC_Mirrors - Add reflections to your map characters
● ARCHIVED · READ-ONLY
-
-
I suspect it was the QSprite pluginI really appreciate it. You don't know how many years I've waited for a fully functional plugin with no incompatibilities with other plugins. Now everything works perfectly, I just had to put KC_Mirrors below all the Q plugins.
That was what was not making the main character's reflection. Now everything is perfect. Thank you very much. -
I just had to put KC_Mirrors below QSprite and all the other Quxios plugins and now everything is working perfectly.I suspect it was the QSprite plugin
-
Did a bit of my own investigation, and I believe the incompatibility lays within QMovement.
My plugin aliases and modifies theGame_Player.prototype.updatefunction like so:
Code:KCDev.Mirrors.Game_Player_update = Game_Player.prototype.update; Game_Player.prototype.update = function () { KCDev.Mirrors.Game_Player_update.apply(this, arguments); if ($gameParty.size() > 0) { const actor = $gameParty.leader(); KCDev.Mirrors.updateActorCharacterReflect(actor, this); } };
QMovement does the following:
Code:Game_Player.prototype.update = function(sceneActive) { var lastScrolledX = this.scrolledX(); var lastScrolledY = this.scrolledY(); var wasMoving = this.isMoving(); this.updateDashing(); if (sceneActive) { this.moveByInput(); } Game_Character.prototype.update.call(this); this.updateScroll(lastScrolledX, lastScrolledY); this.updateVehicle(); if (!this.startedMoving()) this.updateNonmoving(wasMoving); this._followers.update(); };
As can be seen, QMovement overwrites the update function inGame_Playerand does not call the original update function, just the update function forGame_Character. So, my code responsible for setting up the reflection on theGame_Playercharacter never actually runs.
I'll document this in the thread OP and the help section of the plugin. Thank you again for reporting these issues.
EDIT: Whoops, didn't mean to ping user "Help"! -
Amazing plugin, thank you! I have been trying to make a wall mirror reflection plugin with no success.
All the one i have found so far were unperfect. This one is just great, well done! I am using the event reflection mode.
just a comment to say I am on MV and i am using Galv's plugins and the fix in the MV version of KC Mirror is made for MZ, not translated for MV. This makes it incompatible with Galv character frames for MV, but at least i managed to edit in the MV version of KC Mirror, the part that patches for Galv character frames and successfully converted it for MV. Now all is great. -
Can you be more specific on the issue? I aimed to fix compatibility issues with Galv_CharacterFrames MV v1.3 when creating 1.4.1, and I don't believe 1.4.2 introduced any regressions on CF compatibility.Amazing plugin, thank you! I have been trying to make a wall mirror reflection plugin with no success.
All the one i have found so far were unperfect. This one is just great, well done! I am using the event reflection mode.
just a comment to say I am on MV and i am using Galv's plugins and the fix in the MV version of KC Mirror is made for MZ, not translated for MV. This makes it incompatible with Galv character frames for MV, but at least i managed to edit in the MV version of KC Mirror, the part that patches for Galv character frames and successfully converted it for MV. Now all is great.
In fact, I just tested it, and it seems to be working as expected on the CF MV demo (Galv_CharacterFrames v1.3, KC_Mirrors v1.4.2).
Spoiler
If you can describe and give me an easy way to reproduce the unexpected behavior, I would be more than happy to look into it. -
Sure, I can be specific!
So, with KC Mirror 1.4.2 for MV and Galv CharacterFrames for MV:
When KC Mirror was above it was not creating reflections. (I know this is expected)
When KC Mirror was below Galv character frame, the game crashed at startup returning:
RangeError: Maximum call stack size exceeded at Function.keys (<anonymous>)
Turning KC mirror or Galv Character Frames OFF was resolving the crash issue.
In the header, I have noticed the MZ mention, eventhough this was in the MV plugin:
@Author K. Chavez * @url https://github.com/kchavezdev/RPGMP_Mirrors
* @target MV * @orderAfter PluginCommonBase
* @orderAfter GALV_DiagonalMovementMZ
* @orderAfter GALV_CharacterFramesMZ
* @orderAfter GALV_EventSpawnerMZ *
* @plugindesc [v1.4.2]Add reflections to events and actors.
(as in GALV_CharacterFramesMZ)
I guess Galv plugins must be a little different in both versions. I have never touched MZ so I am not sure.
Basically I have replaced:
OriginalJavaScript:if (Imported.Galv_CharacterFrames) { KCDev.Mirrors.Sprite_Reflect_initMembers_GalvCF = KCDev.Mirrors.Sprite_Reflect.prototype.initMembers; KCDev.Mirrors.Sprite_Reflect.prototype.initMembers = function () { KCDev.Mirrors.Sprite_Reflect_initMembers_GalvCF.apply(this, arguments); this._cframes = 3; }; KCDev.Mirrors.Sprite_Reflect_refreshGraphic_GalvCF = KCDev.Mirrors.Sprite_Reflect.prototype.refreshGraphic; KCDev.Mirrors.Sprite_Reflect.prototype.refreshGraphic = function () { KCDev.Mirrors.Sprite_Reflect_refreshGraphic_GalvCF.apply(this, arguments); const cf = this._characterName.match(Galv.CF.regex || /%\((\d+)\)/); if (cf) { this._cframes = Number(cf[1]); } else { this._cframes = 3; } }; KCDev.Mirrors.setReflectFrame_GalvCF = KCDev.Mirrors.setReflectFrame; /** * @param {KCDev.Mirrors.Sprite_Reflect} r */ KCDev.Mirrors.setReflectFrame = function (r) { // store character values const tmpCFrames = r._character._cframes; // write reflection values r._character._cframes = r._cframes; KCDev.Mirrors.setReflectFrame_GalvCF.apply(this, arguments); // restore original character values r._character._cframes = tmpCFrames; }; // hacky speedup // basically, hitting "load game" to a map with many reflections chugs otherwise on MZ // this seems to be related to property access times? // not entirely sure, but this fixes the slow down and shouldn't conflict with other plugins? if (!JsonEx._cleanMetaData) { // ported from MV JsonEx._cleanMetadata = function (object) { if (!object) return; delete object['@']; if (typeof object === 'object') { Object.keys(object).forEach(function (key) { var value = object[key]; if (typeof value === 'object') { JsonEx._cleanMetadata(value); } }); } }; KCDev.Mirrors.JsonEx_parse = JsonEx.parse; JsonEx.parse = function (s) { const obj = KCDev.Mirrors.JsonEx_parse.apply(this, arguments); JsonEx._cleanMetadata(obj) return obj; }; } } if (Imported.Galv_DiagonalMovement && Galv.DM.diagGraphic) { KCDev.Mirrors.setReflectFrame_GalvDM = KCDev.Mirrors.setReflectFrame; /** * @param {KCDev.Mirrors.Sprite_Reflect} r */ KCDev.Mirrors.setReflectFrame = function (r) { const tmpDiagDir = r._character._diagDir; if (r._isReflectionWall && tmpDiagDir) r._character._diagDir = r._character.reverseDir(tmpDiagDir); KCDev.Mirrors.setReflectFrame_GalvDM.apply(this, arguments); r._character._diagDir = tmpDiagDir; }; } if (Imported.Galv_EventSpawner) { KCDev.Mirrors.Spriteset_Map_unspawnEvent = Spriteset_Map.prototype.unspawnEvent; Spriteset_Map.prototype.unspawnEvent = function (eventId) { for (let i = 0; i < this._characterSprites.length; i++) { const sprite = this._characterSprites[i]; if (sprite._reflectionFloor) { const char = sprite._character; if (char.isSpawnEvent && char._eventId === eventId) { this._tilemap.removeChild(sprite._reflectionFloor); this._tilemap.removeChild(sprite._reflectionWall); } } } KCDev.Mirrors.Spriteset_Map_unspawnEvent.apply(this, arguments); }; KCDev.Mirrors.Spriteset_Map_clearSpawnedEvents = Spriteset_Map.prototype.clearSpawnedEvents; Spriteset_Map.prototype.clearSpawnedEvents = function (clearSaved) { for (let i = 0; i < this._characterSprites.length; i++) { const sprite = this._characterSprites[i]; if (sprite._reflectionFloor) { const char = sprite._character; if (char.isSpawnEvent && (clearSaved || !char.isSavedEvent)) { this._tilemap.removeChild(sprite._reflectionFloor); this._tilemap.removeChild(sprite._reflectionWall); } } } KCDev.Mirrors.Spriteset_Map_clearSpawnedEvents.apply(this, arguments); };
With:
EDITEDJavaScript:if (Imported.Galv_CharacterFrames) { // Initialize members for Sprite_Reflect KCDev.Mirrors.Sprite_Reflect_initMembers_GalvCF = KCDev.Mirrors.Sprite_Reflect.prototype.initMembers; KCDev.Mirrors.Sprite_Reflect.prototype.initMembers = function () { KCDev.Mirrors.Sprite_Reflect_initMembers_GalvCF.apply(this, arguments); this._cframes = 3; }; // Refresh graphic for Sprite_Reflect KCDev.Mirrors.Sprite_Reflect_refreshGraphic_GalvCF = KCDev.Mirrors.Sprite_Reflect.prototype.refreshGraphic; KCDev.Mirrors.Sprite_Reflect.prototype.refreshGraphic = function () { KCDev.Mirrors.Sprite_Reflect_refreshGraphic_GalvCF.apply(this, arguments); const cf = this._characterName.match(/\%\((\d+)\)/); if (cf) { this._cframes = Number(cf[1]); } else { this._cframes = 3; } }; // Set reflect frame for Sprite_Reflect KCDev.Mirrors.setReflectFrame_GalvCF = KCDev.Mirrors.setReflectFrame; KCDev.Mirrors.setReflectFrame = function (r) { // Store character values const tmpCFrames = r._character._cframes; // Write reflection values r._character._cframes = r._cframes; KCDev.Mirrors.setReflectFrame_GalvCF.apply(this, arguments); // Restore original character values r._character._cframes = tmpCFrames; }; // Override patternWidth for Sprite_Reflect KCDev.Mirrors.Sprite_Reflect_patternWidth_GalvCF = KCDev.Mirrors.Sprite_Reflect.prototype.patternWidth; KCDev.Mirrors.Sprite_Reflect.prototype.patternWidth = function () { if (this._tileId > 0) { return $gameMap.tileWidth(); } else if (this._isBigCharacter) { return this.bitmap.width / this._cframes; } else { return this.bitmap.width / (this._cframes * 4); } }; // Override updatePattern for Sprite_Reflect KCDev.Mirrors.Sprite_Reflect_updatePattern_GalvCF = KCDev.Mirrors.Sprite_Reflect.prototype.updatePattern; KCDev.Mirrors.Sprite_Reflect.prototype.updatePattern = function () { if (!this.hasStepAnime() && this._stopCount > 0) { this.resetPattern(); } else { this._pattern = (this._pattern + 1) % (this._cframes + this._spattern); } }; } if (Imported.Galv_DiagonalMovement && Galv.DM.diagGraphic) { KCDev.Mirrors.setReflectFrame_GalvDM = KCDev.Mirrors.setReflectFrame; /** * @param {KCDev.Mirrors.Sprite_Reflect} r */ KCDev.Mirrors.setReflectFrame = function (r) { const tmpDiagDir = r._character._diagDir; if (r._isReflectionWall && tmpDiagDir) r._character._diagDir = r._character.reverseDir(tmpDiagDir); KCDev.Mirrors.setReflectFrame_GalvDM.apply(this, arguments); r._character._diagDir = tmpDiagDir; }; } if (Imported.Galv_EventSpawner) { KCDev.Mirrors.Spriteset_Map_unspawnEvent = Spriteset_Map.prototype.unspawnEvent; Spriteset_Map.prototype.unspawnEvent = function (eventId) { for (let i = 0; i < this._characterSprites.length; i++) { const sprite = this._characterSprites[i]; if (sprite._reflectionFloor) { const char = sprite._character; if (char.isSpawnEvent && char._eventId === eventId) { this._tilemap.removeChild(sprite._reflectionFloor); this._tilemap.removeChild(sprite._reflectionWall); } } } KCDev.Mirrors.Spriteset_Map_unspawnEvent.apply(this, arguments); }; KCDev.Mirrors.Spriteset_Map_clearSpawnedEvents = Spriteset_Map.prototype.clearSpawnedEvents; Spriteset_Map.prototype.clearSpawnedEvents = function (clearSaved) { for (let i = 0; i < this._characterSprites.length; i++) { const sprite = this._characterSprites[i]; if (sprite._reflectionFloor) { const char = sprite._character; if (char.isSpawnEvent && (clearSaved || !char.isSavedEvent)) { this._tilemap.removeChild(sprite._reflectionFloor); this._tilemap.removeChild(sprite._reflectionWall); } } } KCDev.Mirrors.Spriteset_Map_clearSpawnedEvents.apply(this, arguments); };
That has worked for me. -
Thank you for posting that error message. I still can't reproduce the bug on my end, but it gives me an idea. I want to keep engine-specific code to a minimum, so would you be able to try this slightly-edited version of KC_Mirrors to see if the crash still occurs? I would love to test myself, but I can't reproduce this bug on a fresh MV project with KC_Mirrors and Galv_CharacterFrames loaded.-snip-
-
It seems to be working! Thank you, i will use this last version instead.
-
Thank you for confirming and for reporting this incompatibility. I can't test every project configuration, so every bug report helps!It seems to be working! Thank you, i will use this last version instead.
New GitHub release pushed (v1.4.3) -
I'm finding this plugin very useful and easy to use, although I've been wondering if there's a way to get the boat/ship to reflect on water?
-
Not currently supported as I honestly forgot vehicles exist since I don't play many games that use them. Putting it on the todo list for version 1.5!I'm finding this plugin very useful and easy to use, although I've been wondering if there's a way to get the boat/ship to reflect on water?
-
Vehicle support is officially in!I'm finding this plugin very useful and easy to use, although I've been wondering if there's a way to get the boat/ship to reflect on water?
Also added a feature I originally planned to put in version 2.0—rotations. 2.0 is on indefinite hold, so I decided to re-implement it in the 1.x code since adding vehicle support had me poking around anyway.
I had to make a fair amount of changes under the hood for 1.5, so please inform me of any bugs that you all find, and I'll do my best to patch them.
Happy playing!
:ptea: -
I downloaded the demo for MV. How did you get the water reflection to only render on the water tiles? This is not explained. Thanks.
-
Hi, this is answered here in the OP:I downloaded the demo for MV. How did you get the water reflection to only render on the water tiles? This is not explained. Thanks.
So, if you were to look at the A1 tileset in the demo, you would find these water tiles that were used in the demo room:Features
--snip--
This is a plugin that allows the developer to add reflections to actors and events. This is done by drawing sprites below the map but above the parallax layer. So, to get full usage out of this plugin, you must be using tilesets that actually show the parallax layer (i.e. tilesets with transparency). The demo uses a tileset with reduced opacity on the water tiles to achieve the water reflection effect, for example.
--snip--
The top left tile in each frame of animation is only used in the editor, so it was left untouched. The rest of the water areas have an opacity of somewhere between 100 and 200 (I don't remember the exact value I used). -
Hey there, I'm trying to use this plugin in an MV project and it seems to work well except for some reason I cannot disable floor tile reflections. When I do a map note-tag for just Walls it disables every reflection instead of just floor reflections.
EDIT: IGNORE THIS, I didn't realize I would have to make a new save file for these changes to update I'm a dumb dumb. -
Hello, there is a rather strange bug/incompatibility relating to QSprite, both in the function of changing reflection opacities and the character's facing being wrong when it comes to the walls' reflections. These were tested in the KC_Mirrors demo to see what was the problem once I got to see it in my own project, pictures of the latter shown here.
The demo also has the ability to change reflection opacities, but only the floor reflections were affected - the wall reflections just weren't.
Though, the floor reflections seem to be working fine with no problem involved.
For reference, the setup I used in the demo:
EDIT: I forgot to mention, I am utilizing the MV version, so I have no idea if this bug shows up in the MZ version. -
Thank you so much for taking the time to narrow down which plugin was causing the incompatibility before reporting this error—it made narrowing down the bug to fix it a lot easier. I tested the plugin against the QMV master demo, and it seems to be resolved.--snip--
Also thank you for pointing out that bug in MV commands with walls; that's fixed too. -
Thank you very much for the quick response and fix - I've tried it now and it works very well, though it can have a very small bug when some idle animations do not have the same amount of frames as others (mainly that the animation disappears), but that can be easily fixed on my end so it's all right.Thank you so much for taking the time to narrow down which plugin was causing the incompatibility before reporting this error—it made narrowing down the bug to fix it a lot easier. I tested the plugin against the QMV master demo, and it seems to be resolved.
Also thank you for pointing out that bug in MV commands with walls; that's fixed too. -
Detected a bug, unsure what is the exact cause but apparently there are events maintaining there graphics on the parallax,
May be a cause from Galv's spawn events MZ plugin.