设为首页收藏本站同能贴吧 切换语言 繁体中文
开启辅助访问 切换到窄版
扫描二维码关注官方公众号
返回列表
+ 发新帖
查看: 76|回复: 0

[转载发布] Multi Party Plugin for MZ

[复制链接]
累计送礼:
0 个
累计收礼:
1 个
  • TA的每日心情
    开心
    2026-7-12 04:10
  • 签到天数: 209 天

    连续签到: 2 天

    [LV.7]常住居民III

    9015

    主题

    864

    回帖

    6万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    7
    卡币
    58751
    OK点
    16
    推广点
    0
    同能卷
    50
    积分
    68660

    灌水之王

    发表于 2026-7-23 11:43:06 | 显示全部楼层 |阅读模式
    I've been creating a multi party for MZ for some time now, and it's finally on a stable version.

    This plugin just adds the option to add, manage and swap to other parties, with it's own actors and items.




    For now it just works using Plugin Commands on events, but I plan to add a Swap Menu (I'm actually working on that, but I'm getting some problems with parties on different maps).

    Just put the
    1. TomazellaGames_MultiGroupManager.js
    复制代码
    file on the js/plugins folder of your project.

    The plugin description has instructions on how to use it.

    If you want to help me you can give me a tip on itch.io: https://jeftomazella.itch.io/mz-multi-parties

    Download the file or get the code here:
                    JavaScript:       
    1. /*:
    2. * @target MZ
    3. * @plugindesc Manages multiple parties, allowing switching and visibility (items per group).
    4. * @author Tomazella Games
    5. * @help
    6. * This plugin enables managing multiple groups in RPG Maker MZ.
    7. * Groups can exchange items and actors, and are visible on the map.
    8. *
    9. * This plugin is licensed under GPL-3 license:
    10. * - License link: https://www.gnu.org/licenses/gpl-3.0.en.html
    11. * - The plugin is Open Source, and you can change, update, edit,
    12. *  use for commercial or personal projects, but it always has to use
    13. *  the same license, and always be open source.
    14. *
    15. * Website: https://tomazellagames.com/
    16. *
    17. * # How to Use:
    18. *
    19. * 1. Open Tools -> Plugin Manager... ⚙️
    20. * 2. Double click on the TomazellaGames_MultiGroupManager.js.️️
    21. * 3. On Parameters, double click Extra Groups.️️
    22. * 4. Double click an empty row to create, or an existing row to edit
    23. *  (Always Double Click to edit or add an item on the plugins window). ➕/✏️
    24. * 5. Open Initial Actors and choose what actors start on that group. ➡️
    25. * 6. Set the Initial Map ID for the group. ️
    26. * 7. Select the X and Y starting positions.
    27. * 8. You can leave the other options as they are, unless you want
    28. *  to interact with the group since the game start.
    29. *
    30. * ## How to find values
    31. * - To find the correct `X` and `Y` positions and Map ID:
    32. *   - Go to the map you want to start the party. ️
    33. *   - Change to Mode -> Event (or hit F6) ️
    34. *   - Click the map cell you want to use. ️
    35. *   - On the bottom right of the program you'll see some informations. ℹ️
    36. *     - The rightmost information is the `X, Y` position.
    37. *     - The next one (to the left) is current Zoom (Usually 100%)
    38. *     - Then you have info in the format `MAP_ID:NAME_NAME (WIdth, Height)`,
    39. *       just get the Map ID.
    40. *
    41. * ## Plugin Commands
    42. * You can use the following plugin commands for this plugin:
    43. *
    44. * ### Switch Group
    45. * Params:
    46. * - Group Index (default group is 0)
    47. * Effect: Change the control to the chosen group. ➡️
    48. *
    49. * ### Set Group Discovered ️
    50. * Params:
    51. * - Group ID: The group that will be affected by this command
    52. * - Discovered: `True` or `False` ✅/❌
    53. * Effect: Set the discovered state (shown on the Switch Group window) ️
    54. *
    55. * ### Set Group Can Swap
    56. * Params:
    57. * - Group ID: The group that will be affected by this command
    58. * - Can Swap: `True` or `False` ✅/❌
    59. * Effect: Set if this group can be swapped to
    60. *         (can be selected on the Switch Group window)
    61. *
    62. * ### Modify Group Actor
    63. * Params:
    64. * - Group ID: The group that will be affected by this command
    65. * - Actor ID: The actor that will be affected by this command
    66. * - Action: `add` or `remove` ➕/➖
    67. * Effect: Adds or Removes the selected actor from the selected group ➡️
    68. *
    69. * ### Modify Group Item
    70. * Params:
    71. * - Group ID: The group that will be affected by this command
    72. * - Item Type: `Item`, `Weapon` or `Armor`,
    73. *               the RPG Maker MZ default item types ️/⚔️/
    74. * - Item ID: The index of the item on the selected item type
    75. * - Amount: `Integer` value, the desired quantity of items of that
    76. *           type and ID the party will have.
    77. * Effect: Sets the exact amount of items of that ID and type
    78. *         to that party. ➡️
    79. *
    80. * ### Transport Group
    81. * Params:
    82. * - Group ID: The group that will be affected by this command
    83. * - Map ID: The map the group will be transported to ️
    84. * - X Position: x position on the selected map the group will transfer
    85. * - Y Position: y position on the selected map the group will transfer
    86. * Effect: Sets the selected group position to the desired map coordinate
    87. *
    88. * @command SwitchGroup
    89. * @text Switch Group
    90. * @desc Switches to the specified group.
    91. *
    92. * @arg groupIndex
    93. * @text Group Index
    94. * @type number
    95. * @min 0
    96. * @default 0
    97. * @desc Index of the group to switch to (0 = main group, 1 = extra group 1, etc.).
    98. *
    99. * @command SetGroupDiscovered
    100. * @text Set Group Discovered
    101. * @desc Changes the "discovered" status of a group.
    102. *
    103. * @arg groupId
    104. * @text Group ID
    105. * @type number
    106. * @min 0
    107. * @default 1
    108. * @desc The ID of the group to modify.
    109. *
    110. * @arg discovered
    111. * @text Discovered
    112. * @type boolean
    113. * @on Yes
    114. * @off No
    115. * @default true
    116. * @desc Whether the group is discovered.
    117. *
    118. * @command SetGroupCanSwap
    119. * @text Set Group Can Swap
    120. * @desc Changes the "canSwap" status of a group.
    121. *
    122. * @arg groupId
    123. * @text Group ID
    124. * @type number
    125. * @min 0
    126. * @default 1
    127. * @desc The ID of the group to modify.
    128. *
    129. * @arg canSwap
    130. * @text Can Swap
    131. * @type boolean
    132. * @on Yes
    133. * @off No
    134. * @default true
    135. * @desc Whether the group can be swapped.
    136. *
    137. * @command ModifyGroupActor
    138. * @text Modify Group Actor
    139. * @desc Adds or removes an actor from a group.
    140. *
    141. * @arg groupId
    142. * @text Group ID
    143. * @type number
    144. * @min 0
    145. * @default 0
    146. * @desc The ID of the group to modify.
    147. *
    148. * @arg actorId
    149. * @text Actor ID
    150. * @type actor
    151. * @desc The actor to add or remove.
    152. *
    153. * @arg action
    154. * @text Action
    155. * @type select
    156. * @option Add
    157. * @value add
    158. * @option Remove
    159. * @value remove
    160. * @default add
    161. * @desc Whether to add or remove the actor.
    162. *
    163. * @command ModifyGroupItem
    164. * @text Modify Group Item
    165. * @desc Adds or removes an item, weapon, or armor from a group.
    166. *
    167. * @arg groupId
    168. * @text Group ID
    169. * @type number
    170. * @min 0
    171. * @default 0
    172. * @desc The ID of the group to modify.
    173. *
    174. * @arg itemType
    175. * @text Item Type
    176. * @type select
    177. * @option Item
    178. * @value item
    179. * @option Weapon
    180. * @value weapon
    181. * @option Armor
    182. * @value armor
    183. * @default item
    184. * @desc The type of item to modify.
    185. *
    186. * @arg itemId
    187. * @text Item ID
    188. * @type number
    189. * @default 1
    190. * @desc The ID of the item, weapon, or armor to modify.
    191. *
    192. * @arg amount
    193. * @text Amount
    194. * @type number
    195. * @default 1
    196. * @desc The quantity to add or remove (use negative values to remove).
    197. *
    198. * @command TransportGroup
    199. * @text Transport Group
    200. * @desc Transports a group to a position on any map.
    201. *
    202. * @arg groupId
    203. * @text Group ID
    204. * @type number
    205. * @min 0
    206. * @default 0
    207. * @desc The ID of the group to transport.
    208. *
    209. * @arg mapId
    210. * @text Map ID
    211. * @type number
    212. * @min 1
    213. * @default 1
    214. * @desc The ID of the map to transport to.
    215. *
    216. * @arg x
    217. * @text X Position
    218. * @type number
    219. * @default 0
    220. * @desc The X position to transport to.
    221. *
    222. * @arg y
    223. * @text Y Position
    224. * @type number
    225. * @default 0
    226. * @desc The Y position to transport to.
    227. *
    228. * @param extraGroups
    229. * @text Extra Groups
    230. * @type struct<Group>[]
    231. * @desc Define extra groups and their starting positions.
    232. * @default []
    233. *
    234. * @param textGroupSwitchPrompt
    235. * @text Group Switch Prompt
    236. * @type text
    237. * @desc Text shown when asking the player to switch groups.
    238. * @default Switch to this group?
    239. *
    240. * @param textGroupSwitchPrompt
    241. * @text Group Switch Prompt
    242. * @type text
    243. * @desc Text shown when asking the player to switch groups.
    244. * @default Switch to this group?
    245. *
    246. * @param enableGroupSwitch
    247. * @text Enable Group Switching
    248. * @type boolean
    249. * @on Yes
    250. * @off No
    251. * @desc Enable or disable group switching directly by the player.
    252. * @default true
    253. *
    254. * @param enableGroupCollision
    255. * @text Enable Group Collision
    256. * @type boolean
    257. * @on Yes
    258. * @off No
    259. * @desc Enable or disable collision between groups.
    260. * @default true
    261. */
    262. /*~struct~Group:
    263. * @param actors
    264. * @text Initial Actors
    265. * @type actor[]
    266. * @desc Initial actors of this group.
    267. *
    268. * @param startMapId
    269. * @text Initial Map ID
    270. * @type number
    271. * @min 1
    272. * @desc Map ID where the group starts.
    273. * @default 1
    274. *
    275. * @param startX
    276. * @text Initial X Position
    277. * @type number
    278. * @desc X-coordinate where the group starts.
    279. * @default 0
    280. *
    281. * @param startY
    282. * @text Initial Y Position
    283. * @type number
    284. * @desc Y-coordinate where the group starts.
    285. * @default 0
    286. *
    287. * @param discovered
    288. * @text Is discovered at start
    289. * @type boolean
    290. * @on Yes
    291. * @off No
    292. * @desc Whether the group can be seen in the swap group menu from the start of the game.
    293. * @default false
    294. *
    295. * @param canSwap
    296. * @text Can Swap at Start
    297. * @type boolean
    298. * @on Yes
    299. * @off No
    300. * @desc Whether the group can be swapped at the start of the game.
    301. * @default false
    302. */
    303. (() => {
    304.     const pluginName = "TomazellaGames_MultiGroupManager";
    305.     const parameters = PluginManager.parameters(pluginName);
    306.     // Plugin parameters
    307.     const extraGroups = JSON.parse(parameters["extraGroups"] || "[]").map(group => JSON.parse(group));
    308.     const enableGroupSwitch = JSON.parse(parameters["enableGroupSwitch"] || "true");
    309.     const enableGroupCollision = JSON.parse(parameters["enableGroupCollision"] || "true");
    310.     const textGroupSwitchPrompt = parameters["textGroupSwitchPrompt"] || "Switch to this group?";
    311.    
    312.     // Namespace for all TomazellaGames plugins
    313.     window.TomazellaGames = window.TomazellaGames || {};
    314.     // Groups and related properties
    315.     window.groups = [];
    316.     window.currentGroupIndex = 0;
    317.     window.wantToChangeToGroupIndex = -1;
    318.     window.wantToChangeGroupFromAnotherMap = false;
    319.     const groupEventExtraId = 90;
    320.     // const targetSelfSwitch = "D";
    321.     window.savedDataMapEvents = null;
    322.     window.savedGameMapEvents = null;
    323.     window.savedGroupPositions = {};
    324.     window.savedEventsMapId = -1;
    325.    
    326.     TomazellaGames.MultiGroupManager = {
    327.         resetSavedEvents() {
    328.             window.savedDataMapEvents = null;
    329.             window.savedGameMapEvents = null;
    330.             window.savedGroupPositions = {};
    331.             window.savedEventsMapId = -1;
    332.             console.log("Reseting saved events for map", $gameMap.mapId());
    333.         },
    334.     };
    335.     /**
    336.      * Initializes groups with parameters and starting values.
    337.      */
    338.     function initializeGroups() {
    339.         groups = [{
    340.             id: 0,
    341.             actors: $dataSystem.partyMembers,
    342.             mapId: $dataSystem.startMapId,
    343.             x: $dataSystem.startX,
    344.             y: $dataSystem.startY,
    345.             inventory: { items: {}, weapons: {}, armors: {}, gold: $dataSystem.startGold || 0 },
    346.             discovered: true,
    347.             canSwap: true
    348.         }];
    349.         extraGroups.forEach((group, index) => {
    350.             try {
    351.                 const parsedActors = JSON.parse(group.actors);
    352.                 if (Array.isArray(parsedActors)) {
    353.                     const discovered = !!(group.discovered === "true");
    354.                     const canSwap = !!(group.canSwap === "true");
    355.                     groups.push({
    356.                         id: index + 1,
    357.                         actors: parsedActors.map(Number),
    358.                         mapId: Number(group.startMapId),
    359.                         x: Number(group.startX),
    360.                         y: Number(group.startY),
    361.                         inventory: { items: {}, weapons: {}, armors: {}, gold: 0 },
    362.                         discovered: discovered,
    363.                         canSwap: canSwap && discovered
    364.                     });
    365.                 } else {
    366.                     console.error(`Error initializing group ${index + 1}: actors is not an array`, group.actors);
    367.                 }
    368.             } catch (e) {
    369.                 console.error("Error analysing group.actors:", e);
    370.             }
    371.         });
    372.     }
    373.     /**
    374.      * Make sure map contents are up to changes
    375.      */
    376.     function refreshEvents() {
    377.         $gameMap.refresh();
    378.     }
    379.     // TODO make this work on different maps
    380.     /**
    381.      * Switches to the specified group, saving and restoring relevant data.
    382.      * @param {number} forceGroupId - The group ID to switch to. If not specified, cycles to the next group.
    383.      */
    384.     window.switchGroup = function (forceGroupId = -1) {
    385.         let targetGroupIndex = forceGroupId % groups.length;
    386.         if (forceGroupId < 0) targetGroupIndex = (currentGroupIndex + 1) % groups.length;
    387.         if (targetGroupIndex === currentGroupIndex) return;
    388.         
    389.         const lastGroup = groups[currentGroupIndex];
    390.         lastGroup.x = $gamePlayer.x;
    391.         lastGroup.y = $gamePlayer.y;
    392.         lastGroup.mapId = $gameMap.mapId();
    393.         
    394.         const targetGroup = groups[targetGroupIndex];
    395.         
    396.         if (!targetGroup.canSwap || !targetGroup.discovered || !lastGroup.canSwap) {
    397.             SoundManager.playBuzzer();
    398.             return;
    399.         }
    400.         
    401.         // if (lastGroup.mapId !== targetGroup.mapId) {
    402.             // $gamePlayer.reserveTransfer(targetGroup.mapId, targetGroup.x, targetGroup.y, $gamePlayer.direction(), 0);
    403.             // $gamePlayer.performTransfer();
    404.         // }
    405.         
    406.         // Determine the next group to switch to
    407.         currentGroupIndex = targetGroupIndex;
    408.         
    409.         // Save current group's inventory
    410.         saveInventory(lastGroup.inventory);
    411.          // Restore the inventory of the new active group
    412.         loadInventory(targetGroup.inventory);
    413.         
    414.         // Remove all actors from the current group
    415.         $gameParty.members().forEach(actor => {
    416.             $gameParty.removeActor(actor.actorId());
    417.         });
    418.         // Add actors from the new active group
    419.         targetGroup.actors.forEach(actorId => {
    420.             $gameParty.addActor(actorId);
    421.         });
    422.         
    423.         // refresh event positions
    424.         toggleEventForGroup(lastGroup);
    425.         toggleEventForGroup(targetGroup);
    426.         refreshEvents();
    427.         
    428.         // Transfer the player to the new group's position
    429.         $gamePlayer.reserveTransfer(targetGroup.mapId, targetGroup.x, targetGroup.y, $gamePlayer.direction(), 0);
    430.         
    431.         if (lastGroup.mapId !== targetGroup.mapId) {
    432.             setTimeout(() => {
    433.                 $gamePlayer.performTransfer();
    434.                
    435.                 targetGroup.x = $gamePlayer.x;
    436.                 targetGroup.y = $gamePlayer.y;
    437.                 targetGroup.mapId = $gameMap.mapId();
    438.                
    439.                 groups.forEach((group, index) => {
    440.                     createEventForGroup(group);
    441.                     toggleEventForGroup(group);
    442.                 });
    443.                 refreshEvents();
    444.                
    445.                 if (SceneManager._scene._spriteset) {
    446.                     SceneManager._scene._spriteset.refreshCharacterSprites();
    447.                 }
    448.             }, 0);
    449.         } else {
    450.             $gamePlayer.performTransfer();
    451.                
    452.             targetGroup.x = $gamePlayer.x;
    453.             targetGroup.y = $gamePlayer.y;
    454.             targetGroup.mapId = $gameMap.mapId();
    455.             
    456.             // groups.forEach((group, index) => {
    457.                 // createEventForGroup(group);
    458.                 // toggleEventForGroup(group);
    459.             // });
    460.             // refreshEvents();
    461.             
    462.             if (SceneManager._scene._spriteset) {
    463.                 SceneManager._scene._spriteset.refreshCharacterSprites();
    464.             }
    465.         }
    466.         
    467.         
    468.         
    469.         // if (SceneManager._scene._spriteset) {
    470.             // SceneManager._scene._spriteset.refreshCharacterSprites();
    471.         // }
    472.         
    473.         // Refresh character sprites to avoid visual glitches
    474.         // if (lastGroup.mapId === targetGroup.mapId) {
    475.             // refreshEvents();
    476.             // SceneManager._scene._spriteset.refreshCharacterSprites();
    477.         // } else {
    478.             // // TomazellaGames.MultiGroupManager.resetSavedEvents();
    479.             // // groups.forEach((group, index) => {
    480.                 // // createEventForGroup(group);
    481.                 // // toggleEventForGroup(group);
    482.             // // });
    483.             // // refreshEvents();
    484.         // }
    485.         
    486.         // Play switch sound
    487.         SoundManager.playRecovery();
    488.         console.log("Changed to %s, from %s | Map: %s", currentGroupIndex, lastGroup.id, $gameMap.mapId());
    489.     }
    490.    
    491.     /**
    492.      * Saves the inventory of the current group.
    493.      * @param {Object} inventory - The inventory to save.
    494.      */
    495.     function saveInventory(inventory) {
    496.         inventory.items = JSON.parse(JSON.stringify($gameParty._items));
    497.         inventory.weapons = JSON.parse(JSON.stringify($gameParty._weapons));
    498.         inventory.armors = JSON.parse(JSON.stringify($gameParty._armors));
    499.         inventory.gold = $gameParty.gold();
    500.     }
    501.    
    502.     /**
    503.      * Loads the inventory of the active group.
    504.      * @param {Object} inventory - The inventory to load.
    505.      */
    506.     function loadInventory(inventory) {
    507.         $gameParty._items = JSON.parse(JSON.stringify(inventory.items));
    508.         $gameParty._weapons = JSON.parse(JSON.stringify(inventory.weapons));
    509.         $gameParty._armors = JSON.parse(JSON.stringify(inventory.armors));
    510.         $gameParty._gold = inventory.gold;
    511.     }
    512.    
    513.     /**
    514.      * Creates an event for a specific group with appropriate properties.
    515.      * @param {Object} group - The group for which the event is created.
    516.      */
    517.     function createEventForGroup(group) {
    518.         const mainActorId = group.actors[0];
    519.         const mainActorData = $dataActors[mainActorId];
    520.         let characterName = mainActorData ? mainActorData.characterName : "";
    521.         let characterIndex = mainActorData ? mainActorData.characterIndex : 0;
    522.         if (!characterName) {
    523.             console.warn(`Main actor for group ${group.id} doesn't have a sprite. Using default image.`);
    524.             characterName = "Actor1";
    525.         }
    526.         createEvent(group.x, group.y, group.id, characterName, characterIndex);
    527.     };
    528.    
    529.     /**
    530.      * Toggles visibility of a group event.
    531.      * @param {Object} group - The group whose event should be toggled.
    532.      * @param {boolean} show - Whether to show or hide the event.
    533.      */
    534.     function toggleEventForGroup(group) {
    535.         let id = group.id + groupEventExtraId;
    536.         const event = $gameMap.event(id);
    537.         if (event) {
    538.             event.locate(group.x, group.y);
    539.         } else {
    540.             createEventForGroup(group);
    541.         }
    542.         refreshEvents();
    543.     }
    544.    
    545.     /**
    546.      * Creates a new event dynamically with specified properties.
    547.      * @param {number} x - X-coordinate of the event.
    548.      * @param {number} y - Y-coordinate of the event.
    549.      * @param {number} id - Unique ID for the event.
    550.      * @param {string} characterName - Character graphic filename.
    551.      * @param {number} characterIndex - Character graphic index.
    552.      * @param {Array} commands - Event commands.
    553.      * @param {string} eventName - Name of the event.
    554.      */
    555.     function createEvent(x, y, groupId, characterName = "", characterIndex = 0) {
    556.         const event_name = `Group[${groupId}]`;
    557.         const id = groupId + groupEventExtraId;
    558.         if ($dataMap.events[id]) {
    559.             const existingEvent = $dataMap.events[id];
    560.             if (
    561.                 existingEvent.name === event_name &&
    562.                 existingEvent.x === x &&
    563.                 existingEvent.y === y &&
    564.                 existingEvent.pages?.length > 0
    565.             ) {
    566.                 return;
    567.             } else {
    568.                 console.warn(`Evento ${id} está corrompido ou incompleto. Recriando...`);
    569.             }
    570.         }
    571.         
    572.         const sameMap = `groups[${groupId}]?.mapId === $gameMap.mapId()`;
    573.         const otherGroup = `${groupId} !== window.currentGroupIndex`;
    574.         const discovered = `groups[${groupId}]?.discovered === true`;
    575.         const condition = discovered + " && " + otherGroup + " && " + sameMap;
    576.         
    577.         const canSwapCondition = condition + ` && groups[${groupId}]?.canSwap === true`;
    578.         
    579.         const eventData = {
    580.             id: id,
    581.             name: event_name,
    582.             x: x,
    583.             y: y,
    584.             pages: [
    585.                 {
    586.                     conditions: { switch1Valid: false, switch2Valid: false, variableValid: false, selfSwitchValid: false },
    587.                     image: { tileId: 0, characterName: "", characterIndex: 0, direction: 2, pattern: 0 },
    588.                     moveType: 0,
    589.                     trigger: 0,
    590.                     list: [],
    591.                     directionFix: false,
    592.                     priorityType: 0,
    593.                     walkAnime: false,
    594.                     stepAnime: false,
    595.                     moveSpeed: 0,
    596.                     moveFrequency: 0
    597.                 },
    598.                 {
    599.                     conditions: {
    600.                         switch1Valid: false, switch2Valid: false,
    601.                         variableValid: false,
    602.                         customCondition: condition
    603.                     },
    604.                     image: { tileId: 0, characterName: characterName || "", characterIndex: characterIndex, direction: 2, pattern: 0 },
    605.                     moveType: 0,
    606.                     trigger: enableGroupCollision ? 0 : 1,
    607.                     list: [
    608.                         { code: 102, indent: 0, parameters: [["Can't switch to this group now"], 2] },
    609.                         { code: 402, indent: 0, parameters: [0] },
    610.                         { code: 0, indent: 0 }
    611.                     ],
    612.                     directionFix: false,
    613.                     priorityType: enableGroupCollision ? 1 : 0,
    614.                     walkAnime: true,
    615.                     stepAnime: true,
    616.                     moveSpeed: 3,
    617.                     moveFrequency: 3
    618.                 },
    619.                 {
    620.                     conditions: {
    621.                         switch1Valid: false, switch2Valid: false,
    622.                         variableValid: false,
    623.                         customCondition: canSwapCondition
    624.                     },
    625.                     image: { tileId: 0, characterName: characterName || "", characterIndex: characterIndex, direction: 2, pattern: 0 },
    626.                     moveType: 0,
    627.                     trigger: enableGroupCollision ? 0 : 1,
    628.                     list: [
    629.                         { code: 102, indent: 0, parameters: [[textGroupSwitchPrompt], 2] },
    630.                         { code: 402, indent: 0, parameters: [0] },
    631.                         { code: 355, indent: 1, parameters: [`switchGroup(${groupId});`] },
    632.                         { code: 0, indent: 0 }
    633.                     ],
    634.                     directionFix: false,
    635.                     priorityType: enableGroupCollision ? 1 : 0,
    636.                     walkAnime: true,
    637.                     stepAnime: true,
    638.                     moveSpeed: 3,
    639.                     moveFrequency: 3
    640.                 }
    641.             ]
    642.         };
    643.         if (!$dataMap.events[id]) {
    644.             $dataMap.events[id] = eventData;
    645.         } else {
    646.             Object.assign($dataMap.events[id], eventData);
    647.         }
    648.         $gameMap.setupEvents();
    649.         refreshEvents();
    650.     }
    651.    
    652.     /**
    653.      * Call the plugin command from events
    654.      */
    655.     const _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
    656.     Game_Interpreter.prototype.pluginCommand = function(command, args) {
    657.         _Game_Interpreter_pluginCommand.call(this, command, args);
    658.     };
    659.    
    660.     /**
    661.      * Updates current group inventory as soon as we change items
    662.      */
    663.     const _Game_Party_gainItem = Game_Party.prototype.gainItem;
    664.     Game_Party.prototype.gainItem = function(item, amount, includeEquip) {
    665.         _Game_Party_gainItem.call(this, item, amount, includeEquip);
    666.         
    667.         if (groups) {
    668.             const currentGroup = groups[currentGroupIndex];
    669.             if (currentGroup) {
    670.                 currentGroup.inventory.items = JSON.parse(JSON.stringify(this._items));
    671.                 currentGroup.inventory.weapons = JSON.parse(JSON.stringify(this._weapons));
    672.                 currentGroup.inventory.armors = JSON.parse(JSON.stringify(this._armors));
    673.                 currentGroup.inventory.gold = this.gold();
    674.             }
    675.         }
    676.     };
    677.     /**
    678.      * Adds the groups events to the current map
    679.      */
    680.     const _Game_Map_setup = Game_Map.prototype.setup;
    681.     Game_Map.prototype.setup = function(mapId) {
    682.         _Game_Map_setup.call(this, mapId);
    683.         if (SceneManager._scene instanceof Scene_Map) {
    684.             groups.forEach((group, index) => {
    685.                 createEventForGroup(group);
    686.                 toggleEventForGroup(group);
    687.             });
    688.             refreshEvents();
    689.             console.log("Criou grupos para o mapa", $gameMap.mapId());
    690.         }
    691.         
    692.     };
    693.    
    694.     /**
    695.      * Release current sprites and update the correct ones
    696.      */
    697.     Spriteset_Map.prototype.refreshCharacterSprites = function() {
    698.         // Remove current sprites
    699.         if (this._characterSprites) {
    700.             this._characterSprites.forEach(sprite => {
    701.                 if (sprite.parent) {
    702.                     sprite.parent.removeChild(sprite);
    703.                 }
    704.             });
    705.         }
    706.         // Restore characters sprites
    707.         this.createCharacters();
    708.     };
    709.    
    710.     /**
    711.      * Save current map events so groups sprites and events are not lost when opening menu
    712.      */
    713.     const _Scene_Menu_create = Scene_Menu.prototype.create;
    714.     Scene_Menu.prototype.create = function() {
    715.         window.savedEventsMapId = $gameMap.mapId();
    716.         savedDataMapEvents = JSON.parse(JSON.stringify($dataMap.events));
    717.         savedGameMapEventIds = $gameMap._events.map(event => event ? event.eventId() : null);
    718.         savedGroupPositions = groups.map(group => ({
    719.             mapId: group.mapId,
    720.             x: group.x,
    721.             y: group.y
    722.         }));
    723.         _Scene_Menu_create.call(this);
    724.     };
    725.     /**
    726.      * Overriding Scene_Map.start to handle restoring events
    727.      */
    728.     const _Scene_Map_start = Scene_Map.prototype.start;
    729.     Scene_Map.prototype.start = function() {
    730.         console.warn("Scene_Map.prototype.start START", $gameMap.mapId());
    731.         console.log("window.savedEventsMapId %s | $gameMap.mapId() %s", window.savedEventsMapId, $gameMap.mapId());
    732.         if (window.savedEventsMapId == $gameMap.mapId() && !window.wantToChangeGroupFromAnotherMap) {
    733.             if (savedDataMapEvents && savedGameMapEventIds) {
    734.                 // Restore events in $dataMap
    735.                 $dataMap.events = JSON.parse(JSON.stringify(savedDataMapEvents));
    736.                 // Restore events in $gameMap as instances of Game_Event
    737.                 $gameMap._events = savedGameMapEventIds.map(eventId => {
    738.                     if (eventId !== null && $dataMap.events[eventId]) {
    739.                         const eventData = $dataMap.events[eventId];
    740.                         if (eventData && typeof eventData.x === "number" && typeof eventData.y === "number") {
    741.                             try {
    742.                                 return new Game_Event($gameMap.mapId(), eventId);
    743.                             } catch (error) {
    744.                                 console.error(`Error creating the event ${eventId}:`, error);
    745.                                 return null;
    746.                             }
    747.                         } else {
    748.                             console.warn(`Event ${eventId} doesn't have valid coordinates.`);
    749.                             return null;
    750.                         }
    751.                     }
    752.                     console.warn(`Event ${eventId} not found or invalid.`);
    753.                     return null;
    754.                 });
    755.                 $gameMap.refresh();
    756.                 this._spriteset.refreshCharacterSprites(); // Clear and recreate the sprites
    757.             }
    758.             if (savedGroupPositions && savedGroupPositions.length > 0) {
    759.                 groups.forEach((group, index) => {
    760.                     const position = savedGroupPositions[index];
    761.                     if (position) {
    762.                         group.mapId = position.mapId;
    763.                         group.x = position.x;
    764.                         group.y = position.y;
    765.                     }
    766.                 });
    767.                 groups.forEach(group => {
    768.                     // createEventForGroup(group);
    769.                     toggleEventForGroup(group);
    770.                 });
    771.                 refreshEvents();
    772.             }
    773.         } else {
    774.             TomazellaGames.MultiGroupManager.resetSavedEvents();
    775.             window.wantToChangeGroupFromAnotherMap = false;
    776.             // groups.forEach((group, index) => {
    777.                 // createEventForGroup(group);
    778.                 // toggleEventForGroup(group);
    779.             // });
    780.             // refreshEvents();
    781.             // console.log("Criou grupos para o mapa", $gameMap.mapId());
    782.         }
    783.         
    784.         // if (wantToChangeToGroupIndex >= 0 && wantToChangeToGroupIndex != currentGroupIndex) {
    785.             // console.log("Is going to change to %s, from %s", wantToChangeToGroupIndex, currentGroupIndex);
    786.             // switchGroup(wantToChangeToGroupIndex);
    787.         // }
    788.         // wantToChangeToGroupIndex = -1;
    789.         
    790.         _Scene_Map_start.call(this);
    791.         
    792.         if (wantToChangeToGroupIndex >= 0 && wantToChangeToGroupIndex != currentGroupIndex) {
    793.             console.log("Is going to change to %s, from %s", wantToChangeToGroupIndex, currentGroupIndex);
    794.             switchGroup(wantToChangeToGroupIndex);
    795.         }
    796.         wantToChangeToGroupIndex = -1;
    797.         console.warn("Scene_Map.prototype.start END", $gameMap.mapId());
    798.     };
    799.    
    800.     /**
    801.      * Add the option to switch groups
    802.      */
    803.     const _Scene_Map_update = Scene_Map.prototype.update;
    804.     Scene_Map.prototype.update = function() {
    805.         _Scene_Map_update.call(this);
    806.         if (enableGroupSwitch && Input.isTriggered('pageup')) {
    807.             switchGroup(currentGroupIndex - 1);
    808.         }
    809.         if (enableGroupSwitch && Input.isTriggered('pagedown')) {
    810.             switchGroup();
    811.         }
    812.         
    813.         // if (wantToChangeToGroupIndex >= 0 && wantToChangeToGroupIndex != currentGroupIndex) {
    814.             // console.log("Is going to change to %s, from %s", wantToChangeToGroupIndex, currentGroupIndex);
    815.             // switchGroup(wantToChangeToGroupIndex);
    816.             // wantToChangeToGroupIndex = -1;
    817.         // }
    818.     };
    819.     /**
    820.      * Initialize the groups when a new game is created.
    821.      */
    822.     const _Scene_Title_commandNewGame = Scene_Title.prototype.commandNewGame;
    823.     Scene_Title.prototype.commandNewGame = function() {
    824.         _Scene_Title_commandNewGame.call(this);
    825.         initializeGroups();
    826.     };
    827.    
    828.     /**
    829.      * Adds the ability to check custom conditions in events. Only accessible by code.
    830.      */
    831.     const _Game_Event_meetsConditions = Game_Event.prototype.meetsConditions;
    832.     Game_Event.prototype.meetsConditions = function(page) {
    833.         if (!_Game_Event_meetsConditions.call(this, page)) {
    834.             return false;
    835.         }
    836.         if (page.conditions.customCondition) {
    837.             try {
    838.                 const result = eval(page.conditions.customCondition); // Avalia a condição
    839.                 return !!result; // Garante que o resultado seja um valor booleano
    840.             } catch (error) {
    841.                 console.error("Erro ao avaliar a condição personalizada:", page.conditions.customCondition, error);
    842.                 return false; // Retorna `false` para evitar travar o jogo
    843.             }
    844.         }
    845.         // Todas as condições foram atendidas
    846.         return true;
    847.     };
    848.    
    849.     /**
    850.      * Save groups data to persist through game sessions
    851.      */
    852.     const _DataManager_makeSaveContents = DataManager.makeSaveContents;
    853.     DataManager.makeSaveContents = function() {
    854.         const contents = _DataManager_makeSaveContents.call(this);
    855.         contents.groups = window.groups; // Salvar os grupos
    856.         contents.currentGroupIndex = window.currentGroupIndex; // Salvar o índice do grupo atual
    857.         return contents;
    858.     };
    859.    
    860.     /**
    861.      * Overload load data to get groups data
    862.      */
    863.     const _DataManager_extractSaveContents = DataManager.extractSaveContents;
    864.     DataManager.extractSaveContents = function(contents) {
    865.         _DataManager_extractSaveContents.call(this);
    866.         window.groups = contents.groups || groups;
    867.         window.wantToChangeToGroupIndex = contents.currentGroupIndex || -1;
    868.     };
    869.    
    870.     // Plugin commands ----------------------------------------
    871.    
    872.     /**
    873.      * Plugin command to switch groups
    874.      */
    875.     PluginManager.registerCommand(pluginName, "SwitchGroup", args => {
    876.         const groupIndex = Number(args.groupIndex) - 1;
    877.         if (!isNaN(groupIndex) && groups[groupIndex]) {
    878.             switchGroup(groupIndex);
    879.         } else {
    880.             console.error(`Grupo inválido: ${groupIndex}`);
    881.         }
    882.     });
    883.    
    884.     PluginManager.registerCommand(pluginName, "SetGroupDiscovered", args => {
    885.         const groupId = Number(args.groupId);
    886.         const discovered = args.discovered === "true";
    887.         const group = groups[groupId];
    888.         if (group) {
    889.             group.discovered = discovered;
    890.             group.canSwap = discovered && group.canSwap; // Ensure "canSwap" is only true if "discovered" is true.
    891.             if (discovered) {
    892.                 createEventForGroup(group);
    893.             }
    894.             console.log(`Group ${groupId} discovered status set to: ${discovered}`);
    895.         } else {
    896.             console.error(`Group ${groupId} not found.`);
    897.         }
    898.     });
    899.     PluginManager.registerCommand(pluginName, "SetGroupCanSwap", args => {
    900.         const groupId = Number(args.groupId);
    901.         const canSwap = args.canSwap === "true";
    902.         const group = groups[groupId];
    903.         if (group) {
    904.             group.canSwap = canSwap;
    905.             createEventForGroup(group);
    906.             console.log(`Group ${groupId} canSwap status set to: ${canSwap}`);
    907.         } else {
    908.             console.error(`Group ${groupId} not found.`);
    909.         }
    910.     });
    911.     PluginManager.registerCommand(pluginName, "ModifyGroupActor", args => {
    912.         const groupId = Number(args.groupId);
    913.         const actorId = Number(args.actorId);
    914.         const action = args.action;
    915.         const group = groups[groupId];
    916.         if (group) {
    917.             if (action === "add" && !group.actors.includes(actorId)) {
    918.                 group.actors.push(actorId);
    919.                 console.log(`Actor ${actorId} added to group ${groupId}.`);
    920.                 createEventForGroup(group);
    921.             } else if (action === "remove" && group.actors.includes(actorId)) {
    922.                 group.actors = group.actors.filter(id => id !== actorId);
    923.                 console.log(`Actor ${actorId} removed from group ${groupId}.`);
    924.                 createEventForGroup(group);
    925.             } else {
    926.                 console.warn(`Action "${action}" on actor ${actorId} for group ${groupId} could not be completed.`);
    927.             }
    928.         } else {
    929.             console.error(`Group ${groupId} not found.`);
    930.         }
    931.     });
    932.    
    933.     PluginManager.registerCommand(pluginName, "ModifyGroupItem", args => {
    934.         const groupId = Number(args.groupId);
    935.         const itemType = args.itemType;
    936.         const itemId = Number(args.itemId);
    937.         const amount = Number(args.amount);
    938.         const group = groups[groupId];
    939.         if (group) {
    940.             let inventory;
    941.             if (itemType === "item") {
    942.                 inventory = group.inventory.items;
    943.             } else if (itemType === "weapon") {
    944.                 inventory = group.inventory.weapons;
    945.             } else if (itemType === "armor") {
    946.                 inventory = group.inventory.armors;
    947.             } else {
    948.                 console.error(`Invalid item type: ${itemType}`);
    949.                 return;
    950.             }
    951.             inventory[itemId] = (inventory[itemId] || 0) + amount;
    952.             if (inventory[itemId] <= 0) delete inventory[itemId]; // Remove item if quantity is zero or less.
    953.             console.log(`${itemType.charAt(0).toUpperCase() + itemType.slice(1)} ${itemId} quantity changed by ${amount} for group ${groupId}.`);
    954.         } else {
    955.             console.error(`Group ${groupId} not found.`);
    956.         }
    957.     });
    958.     PluginManager.registerCommand(pluginName, "TransportGroup", args => {
    959.         const groupId = Number(args.groupId);
    960.         const mapId = Number(args.mapId);
    961.         const x = Number(args.x);
    962.         const y = Number(args.y);
    963.         const group = groups[groupId];
    964.         if (group) {
    965.             group.mapId = mapId;
    966.             group.x = x;
    967.             group.y = y;
    968.             console.log(`Group ${groupId} transported to Map ${mapId}, X: ${x}, Y: ${y}.`);
    969.             createEventForGroup(group);
    970.         } else {
    971.             console.error(`Group ${groupId} not found.`);
    972.         }
    973.     });
    974.     PluginManager.registerCommand(pluginName, "InitializeGroups", initializeGroups);
    975. })();
    复制代码




    本贴来自国际rpgmaker官方论坛作者:JefersonTomazella处,因国际论坛即将永久关站,为了存档多年珍贵资料,署名转载到本论坛存档,由于官方帖子为英文原帖,需要中文翻译请点击论坛顶部切换语言为中文就可以将帖子翻译成中文浏览,方便大家随时查看,原文地址:https://forums.rpgmakerweb.com/threads/multi-party-plugin-for-mz.176124/

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    天天去同能,天天有童年!
    回复 送礼论坛版权

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    高级模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    简体中文
    繁體中文
    English(英语)
    日本語(日语)
    Deutsch(德语)
    Русский язык(俄语)
    بالعربية(阿拉伯语)
    Türkçe(土耳其语)
    Português(葡萄牙语)
    ภาษาไทย(泰国语)
    한어(朝鲜语/韩语)
    Français(法语)
    关闭

    幸运抽奖

    社区每日抽奖来袭,快来试试你是欧皇还是非酋~

    立即查看

    聊天机器人
    Loading...

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2026-8-4 19:30 , Processed in 0.067901 second(s), 55 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表