Advertisement
Guest User

CharacterShowShadow.js

a guest
Apr 11th, 2025
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 16.49 KB | Source Code | 0 0
  1. "use strict";
  2. /*:
  3. @target MZ
  4. @plugindesc character shadow display v1.0.3
  5. @author unagi ootoro
  6. @url https://raw.githubusercontent.com/unagiootoro/RPGMZ/master/CharacterShowShadow.js
  7. @help
  8. This plugin introduces a simple shadow display function.
  9.  
  10. 【How to use】
  11. Add the characters you want to display shadows to the plug-in parameter "Shadow display character list"
  12. Once registered, the character will be able to display shadows.
  13. In the shadow display character list, "character file name" and
  14. You have to specify the "character index",
  15. Specify the following for each:
  16.  
  17. [character file name]
  18. Specify the image file name of the character for shadow display.
  19.  
  20. [Character Index]
  21. When using an image with 4*2 characters registered, which position image
  22. Specify whether to use it with a number from 0 to 7. 0 to 3 are the first row,
  23. 4 to 7 are the second row.
  24. If -1 is specified, all indexes will be shadowed.
  25. In the case of a single character image (those with $ at the beginning of the file name),
  26. This setting is not used.
  27.  
  28.  
  29. Also, in the notes section of the event or the first comment on the first page of the event
  30. <showShadow>
  31. Regardless of the setting of "Shadow display character list"
  32. Show shadows. Conversely, to hide shadows
  33. <hideShadow>
  34. will be described.
  35.  
  36. It is also possible to switch the shadow display / non-display from the script.
  37. In the travel route script
  38. this.showShadow();
  39. You can display shadows by writing If you want to hide
  40. this.hideShadow();
  41. Please write
  42.  
  43. 【License】
  44. This plugin is available under the terms of the MIT license.
  45.  
  46. @param ShowShadowCharacterList
  47. @text shadow display character list
  48. @type struct<ShowShadowCharacter>[]
  49. @default[]
  50. @desc
  51. Register a list of characters for shadow display.
  52.  
  53. @param ShadowImageFileName
  54. @text shadow image file name
  55. @type file
  56. @dir img
  57. @default system/Shadow1
  58. @desc
  59. Specifies the file name of the shadow image.
  60.  
  61. @param ShadowYOffset
  62. @text shadow Y coordinate offset
  63. @type number
  64. @default 6
  65. @desc
  66. Specifies the Y coordinate offset of the shadow image.
  67. */
  68. /*~struct~ShowShadowCharacter:
  69. @param CharacterFileName
  70. @text character file name
  71. @type file
  72. @dir img/characters
  73. @desc
  74. Specifies the file name of the character.
  75.  
  76. @param CharacterIndex
  77. @text character index
  78. @type number
  79. @default -1
  80. @min-1
  81. @desc
  82. Specifies the character index. Specify -1 to target all indexes.
  83. */
  84. /*:ja
  85. @target MZ
  86. @plugindesc キャラクター影表示 v1.0.3
  87. @author うなぎおおとろ
  88. @url https://raw.githubusercontent.com/unagiootoro/RPGMZ/master/CharacterShowShadow.js
  89. @help
  90. シンプルな影表示機能を導入するプラグインです。
  91.  
  92. 【使用方法】
  93. 影を表示させたいキャラクターをプラグインパラメータ「影表示キャラクターリスト」に
  94. 登録すると、そのキャラクターは影が表示されるようになります。
  95. 影表示キャラクターリストには「キャラクターファイル名」と
  96. 「キャラクターインデックス」を指定する必要があり、
  97. それぞれ次の内容を指定します。
  98.  
  99. [キャラクターファイル名]
  100. 影表示対象のキャラクターの画像ファイル名を指定します。
  101.  
  102. [キャラクターインデックス]
  103. 4*2のキャラクターが登録された画像を使用する場合、どの位置の画像を
  104. 使用するかを0~7までの数値で指定します。0~3までが1列目となり、
  105. 4~7までが2列目となります。
  106. -1を指定した場合、全てのインデックスを影表示の対象とします。
  107. 単体のキャラクター画像(ファイル名の先頭に$がつくもの)の場合、
  108. この設定値は使用されません。
  109.  
  110.  
  111. また、イベントのメモ欄またはイベント1ページ目の最初の注釈に
  112. <showShadow>
  113. と記載すると「影表示キャラクターリスト」の設定にかかわらず
  114. 影表示を行います。逆に影を非表示にするには
  115. <hideShadow>
  116. と記載します。
  117.  
  118. スクリプトから影表示/非表示を切り替えることも可能です。
  119. 移動ルートのスクリプトで
  120. this.showShadow();
  121. と記載することで影表示を行うことができます。非表示にする場合は
  122. this.hideShadow();
  123. と記載してください。
  124.  
  125. 【ライセンス】
  126. このプラグインは、MITライセンスの条件の下で利用可能です。
  127.  
  128. @param ShowShadowCharacterList
  129. @text 影表示キャラクターリスト
  130. @type struct<ShowShadowCharacter>[]
  131. @default []
  132. @desc
  133. 影表示を行うキャラクターの一覧を登録します。
  134.  
  135. @param ShadowImageFileName
  136. @text 影画像ファイル名
  137. @type file
  138. @dir img
  139. @default system/Shadow1
  140. @desc
  141. 影画像のファイル名を指定します。
  142.  
  143. @param ShadowYOffset
  144. @text 影Y座標オフセット
  145. @type number
  146. @default 6
  147. @desc
  148. 影画像のY座標オフセットを指定します。
  149. */
  150. /*~struct~ShowShadowCharacter:ja
  151. @param CharacterFileName
  152. @text キャラクターファイル名
  153. @type file
  154. @dir img/characters
  155. @desc
  156. キャラクターのファイル名を指定します。
  157.  
  158. @param CharacterIndex
  159. @text キャラクターインデックス
  160. @type number
  161. @default -1
  162. @min -1
  163. @desc
  164. キャラクターのインデックスを指定します。-1を指定すると全インデックスを対象にします。
  165. */
  166. const SimpleShadowPluginName = document.currentScript ? decodeURIComponent(document.currentScript.src.match(/^.*\/(.+)\.js$/)[1]) : "SimpleShadow";
  167. var SimpleShadow;
  168. (function (SimpleShadow) {
  169.     class PluginParamsParser {
  170.         constructor(predictEnable = true) {
  171.             this._predictEnable = predictEnable;
  172.         }
  173.         static parse(params, typeData, predictEnable = true) {
  174.             return new PluginParamsParser(predictEnable).parse(params, typeData);
  175.         }
  176.         parse(params, typeData, loopCount = 0) {
  177.             if (++loopCount > 255)
  178.                 throw new Error("endless loop error");
  179.             const result = {};
  180.             for (const name in typeData) {
  181.                 if (params[name] === "" || params[name] === undefined) {
  182.                     result[name] = null;
  183.                 }
  184.                 else {
  185.                     result[name] = this.convertParam(params[name], typeData[name], loopCount);
  186.                 }
  187.             }
  188.             if (!this._predictEnable)
  189.                 return result;
  190.             if (typeof params === "object" && !(params instanceof Array)) {
  191.                 for (const name in params) {
  192.                     if (result[name])
  193.                         continue;
  194.                     const param = params[name];
  195.                     const type = this.predict(param);
  196.                     result[name] = this.convertParam(param, type, loopCount);
  197.                 }
  198.             }
  199.             return result;
  200.         }
  201.         convertParam(param, type, loopCount) {
  202.             if (typeof type === "string") {
  203.                 return this.cast(param, type);
  204.             }
  205.             else if (typeof type === "object" && type instanceof Array) {
  206.                 const aryParam = JSON.parse(param);
  207.                 if (type[0] === "string") {
  208.                     return aryParam.map((strParam) => this.cast(strParam, type[0]));
  209.                 }
  210.                 else {
  211.                     return aryParam.map((strParam) => this.parse(JSON.parse(strParam), type[0]), loopCount);
  212.                 }
  213.             }
  214.             else if (typeof type === "object") {
  215.                 return this.parse(JSON.parse(param), type, loopCount);
  216.             }
  217.             else {
  218.                 throw new Error(`${type} is not string or object`);
  219.             }
  220.         }
  221.         cast(param, type) {
  222.             switch (type) {
  223.                 case "any":
  224.                     if (!this._predictEnable)
  225.                         throw new Error("Predict mode is disable");
  226.                     return this.cast(param, this.predict(param));
  227.                 case "string":
  228.                     return param;
  229.                 case "number":
  230.                     if (param.match(/^\-?\d+\.\d+$/))
  231.                         return parseFloat(param);
  232.                     return parseInt(param);
  233.                 case "boolean":
  234.                     return param === "true";
  235.                 default:
  236.                     throw new Error(`Unknow type: ${type}`);
  237.             }
  238.         }
  239.         predict(param) {
  240.             if (param.match(/^\-?\d+$/) || param.match(/^\-?\d+\.\d+$/)) {
  241.                 return "number";
  242.             }
  243.             else if (param === "true" || param === "false") {
  244.                 return "boolean";
  245.             }
  246.             else {
  247.                 return "string";
  248.             }
  249.         }
  250.     }
  251.     const typeDefine = {
  252.         ShowShadowCharacterList: [{}]
  253.     };
  254.     const PP = PluginParamsParser.parse(PluginManager.parameters(SimpleShadowPluginName), typeDefine);
  255.     function mixin(dest, src) {
  256.         for (const name of Object.getOwnPropertyNames(src.prototype)) {
  257.             if (name === "constructor")
  258.                 continue;
  259.             const value = Object.getOwnPropertyDescriptor(src.prototype, name) || Object.create(null);
  260.             Object.defineProperty(dest.prototype, name, value);
  261.         }
  262.     }
  263.     class Game_CharacterBase_Mixin extends Game_CharacterBase {
  264.         initMembers() {
  265.             Game_CharacterBase_Mixin._initMembers.call(this);
  266.             this._needShadowByShowShadowList = false;
  267.         }
  268.         setImage(characterName, characterIndex) {
  269.             Game_CharacterBase_Mixin._setImage.call(this, characterName, characterIndex);
  270.             this._needShadowByShowShadowList = this.checkIncludedShowShadowCharacterList();
  271.         }
  272.         isNeedShadow() {
  273.             if (this._needShadowByApi != null)
  274.                 return this._needShadowByApi;
  275.             return this._needShadowByShowShadowList;
  276.         }
  277.         showShadow() {
  278.             this._needShadowByApi = true;
  279.         }
  280.         hideShadow() {
  281.             this._needShadowByApi = false;
  282.         }
  283.         shadowScreenX() {
  284.             return this.screenX();
  285.         }
  286.         shadowScreenY() {
  287.             const th = $gameMap.tileHeight();
  288.             return Math.floor(this.scrolledY() * th + th - this.shiftY() + PP.ShadowYOffset);
  289.         }
  290.         shadowScreenZ() {
  291.             return this.screenZ() - 1;
  292.         }
  293.         checkIncludedShowShadowCharacterList() {
  294.             for (const showShadowCharacter of PP.ShowShadowCharacterList) {
  295.                 if (showShadowCharacter.CharacterFileName === this._characterName &&
  296.                     (showShadowCharacter.CharacterIndex < 0 || ImageManager.isBigCharacter(this._characterName) || showShadowCharacter.CharacterIndex === this._characterIndex)) {
  297.                     return true;
  298.                 }
  299.             }
  300.             return false;
  301.         }
  302.     }
  303.     Game_CharacterBase_Mixin._initMembers = Game_CharacterBase.prototype.initMembers;
  304.     Game_CharacterBase_Mixin._setImage = Game_CharacterBase.prototype.setImage;
  305.     mixin(Game_CharacterBase, Game_CharacterBase_Mixin);
  306.     class Game_Event_Mixin extends Game_Event {
  307.         refresh() {
  308.             Game_Event_Mixin._refresh.call(this);
  309.             const values = this.getAnnotationValues(0);
  310.             if (this.event().meta.showShadow || values.showShadow) {
  311.                 this._needShadowByMeta = true;
  312.             }
  313.             else if (this.event().meta.hideShadow || values.hideShadow) {
  314.                 this._needShadowByMeta = false;
  315.             }
  316.         }
  317.         isNeedShadow() {
  318.             if (this._needShadowByApi != null)
  319.                 return this._needShadowByApi;
  320.             if (this._needShadowByMeta != null)
  321.                 return this._needShadowByMeta;
  322.             return this._needShadowByShowShadowList;
  323.         }
  324.         getAnnotationValues(page) {
  325.             const note = this.getAnnotation(page);
  326.             const data = { note };
  327.             DataManager.extractMetadata(data);
  328.             return data.meta;
  329.         }
  330.         getAnnotation(page) {
  331.             const eventData = this.event();
  332.             if (eventData) {
  333.                 const noteLines = [];
  334.                 const pageList = eventData.pages[page].list;
  335.                 for (let i = 0; i < pageList.length; i++) {
  336.                     if (pageList[i].code === 108 || pageList[i].code === 408) {
  337.                         noteLines.push(pageList[i].parameters[0]);
  338.                     }
  339.                     else {
  340.                         break;
  341.                     }
  342.                 }
  343.                 return noteLines.join("\n");
  344.             }
  345.             return "";
  346.         }
  347.     }
  348.     Game_Event_Mixin._refresh = Game_Event.prototype.refresh;
  349.     mixin(Game_Event, Game_Event_Mixin);
  350.     class Sprite_Shadow extends Sprite {
  351.         constructor(...args) {
  352.             super(...args);
  353.         }
  354.         initialize(character) {
  355.             super.initialize();
  356.             this.hide();
  357.             this.bitmap = ImageManager.loadBitmap("img/", PP.ShadowImageFileName);
  358.             this.anchor.x = 0.5;
  359.             this.anchor.y = 1;
  360.             this._character = character;
  361.             this.updatePosition();
  362.         }
  363.         update() {
  364.             super.update();
  365.             this.updatePosition();
  366.             this.updateVisible();
  367.         }
  368.         character() {
  369.             return this._character;
  370.         }
  371.         updatePosition() {
  372.             this.x = this._character.shadowScreenX();
  373.             this.y = this._character.shadowScreenY();
  374.             this.z = this._character.shadowScreenZ();
  375.         }
  376.         updateVisible() {
  377.             this.visible = this._character.isNeedShadow();
  378.             const spriteset = SceneManager._scene._spriteset;
  379.             const characterSprite = spriteset.findTargetSprite(this._character);
  380.             if (characterSprite && characterSprite.visible) {
  381.                 if (this._character.isNeedShadow()) {
  382.                     this.visible = true;
  383.                 }
  384.                 else {
  385.                     this.visible = false;
  386.                 }
  387.             }
  388.             else {
  389.                 this.visible = false;
  390.             }
  391.         }
  392.     }
  393.     SimpleShadow.Sprite_Shadow = Sprite_Shadow;
  394.     class Sprite_Character_Mixin extends Sprite_Character {
  395.         character() {
  396.             return this._character;
  397.         }
  398.     }
  399.     mixin(Sprite_Character, Sprite_Character_Mixin);
  400.     class Spriteset_Map_Mixin extends Spriteset_Map {
  401.         initialize() {
  402.             // NOTE: createLowerLayerがsuper.initializeのコンテキストでコールされるため先に初期化する。
  403.             this._characterShadowSprites = [];
  404.             Spriteset_Map_Mixin._initialize.call(this);
  405.         }
  406.         update() {
  407.             Spriteset_Map_Mixin._update.call(this);
  408.             this.updateCharacterShadows();
  409.         }
  410.         createLowerLayer() {
  411.             Spriteset_Map_Mixin._createLowerLayer.call(this);
  412.             this.updateCharacterShadows();
  413.         }
  414.         updateCharacterShadows() {
  415.             const spriteCharacters = this._characterSprites.map(sprite => sprite.character());
  416.             const shadowSpriteCharacter = this._characterShadowSprites.map(sprite => sprite.character());
  417.             for (const characterSprite of this._characterSprites) {
  418.                 const character = characterSprite.character();
  419.                 if (!shadowSpriteCharacter.includes(character)) {
  420.                     this.createShadowSprite(character);
  421.                 }
  422.             }
  423.             for (const shadowSprite of this._characterShadowSprites.concat()) {
  424.                 const character = shadowSprite.character();
  425.                 if (!spriteCharacters.includes(character)) {
  426.                     this.removeShadowSprite(shadowSprite);
  427.                 }
  428.             }
  429.         }
  430.         createShadowSprite(character) {
  431.             const shadowSprite = new Sprite_Shadow(character);
  432.             this._tilemap.addChild(shadowSprite);
  433.             this._characterShadowSprites.push(shadowSprite);
  434.         }
  435.         removeShadowSprite(shadowSprite) {
  436.             this._tilemap.removeChild(shadowSprite);
  437.             this._characterShadowSprites = this._characterShadowSprites.filter(sprite => sprite !== shadowSprite);
  438.         }
  439.     }
  440.     Spriteset_Map_Mixin._createLowerLayer = Spriteset_Map.prototype.createLowerLayer;
  441.     Spriteset_Map_Mixin._initialize = Spriteset_Map.prototype.initialize;
  442.     Spriteset_Map_Mixin._update = Spriteset_Map.prototype.update;
  443.     mixin(Spriteset_Map, Spriteset_Map_Mixin);
  444. })(SimpleShadow || (SimpleShadow = {}));
Tags: RPG maker
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement