Sigony

Sigony's Map Additions - Copy and Delete Maps In-Game - RPG Maker MV Plugin - RMMV

Aug 20th, 2020
555
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*:
  2.  * @plugindesc Allows you to copy a map file from within the game.
  3.  * @author Sigony
  4. */
  5.  
  6.  
  7. /*
  8. Overview​
  9.  
  10. This RMMV plugin allows you to use a plugin command to copy and delete maps using plugin commands, meaning this can happen in-game. This has some powerful possibilities for those with imagination.
  11.  
  12.  
  13.  
  14. [QUOTE]With great power comes great responsibility.[/QUOTE]
  15.  
  16.  
  17.  
  18. Important
  19.  
  20. This plugin manipulates your project's files. Before using this plugin, you should backup your data. I am not responsible for any loss that you incur from using this plugin. Use this plugin with caution.
  21.  
  22.  
  23.  
  24. Potential Use Cases
  25.  
  26. ​Map instances
  27. Powerful when used with Shaz's Tile Changer.
  28. Plugin creators who would like to generate new maps in-game may find that this plugin saves them lots of work.
  29. Features
  30.  
  31. Copy a map using a plugin command.
  32. Delete a map using a plugin command (mainly if you want to clean up instances)
  33. ​INSTRUCTIONS
  34.  
  35.  
  36. To copy a map you can use the following plugin command format:
  37.  
  38. [QUOTE]CopyMap mapId "mapName" variableForNewMapId parentId [/QUOTE]
  39.  
  40. mapId - this is the ID of the map that you wish to copy. A new map, with a different ID will be created.
  41. mapName - this is the name that appears in the editor, and is also the display name.
  42. variableForNewMapId - this is the $gameVariable that will store the newly copied map's ID.
  43. Once you copy the map, you might like to go to it, and so you can do this using events.
  44. Event > Transfer Player > Designation with variables. (You will need to set some temporary values for x and y coord)
  45. You do not need an endless list of variables to hold the mapIDs of every new map that you create in-game. You can be clever and juggle them a bit. To get you started look at: Event > Control Variables > GameData > MapID. The fact that the current map's ID is accessible allows you to store the ID of a map after you leave it.
  46. Make sure to keep track of if a mapID actually exists and know where it leads at any moment. When a map is deleted, and another created, the mapID will be re-used, and this might create some headaches for you if you aren't careful.
  47. parentId - this allows you to make the generated map a child of the map with this parent ID, making it indented and able to be hidden with a spoiler in the editor, the purpose of which is to help reduce clutter in the editor and for you to organize the potentially large amount of maps you'll be dealing with. If you do not desire the copied map to be foldable, set the parentId to 0.
  48. Example:
  49.  
  50. [QUOTE]CopyMap 1 "Copied Map" 5 1[/QUOTE]
  51.  
  52.  
  53. ​​Note: If you copy a map in-game and it does not appear in your editor, it is because the editor hasn't updated its list. If you want to see your copied map in the editor, then feel free to close and re-open the editor.
  54.  
  55.  
  56. To delete a map you can use the following plugin command format:
  57.  
  58. [QUOTE]DeleteMap mapId[/QUOTE]
  59.  
  60. mapId - The mapID of the map you wish to delete.
  61. Example, accessing the value stored in variable 5:
  62.  
  63. [QUOTE]DeleteMap $gameVariables.value(5)[/QUOTE]
  64.  
  65.  
  66. Note: Deletion is permanent. Deleting maps should be done with extreme caution. Again, make sure you backup any maps that are important to you. Make sure you know what you are deleting. Make sure you do any necessary cleanup of your variables. Make sure you do not try to transfer the player to a map that no longer exists.
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73. ​Troubleshooting / Feedback
  74.  
  75. Please report any bugs that you have, and how to recreate the issue. Press F8 to open console.
  76.  
  77. Feedback is welcome.
  78.  
  79.  
  80.  
  81. Credit
  82.  
  83. Sigony
  84.  
  85.  
  86.  
  87. License
  88.  
  89. Credit me where applicable in your derivative works.
  90.  
  91. Redistribute by linking to the original post by Sigony.
  92.  
  93. Commercial use requires payment.
  94.  */
  95.  
  96. (async function() {
  97.     var parameters = PluginManager.parameters('SigonysMapAdditions');
  98.  
  99.     function SigonyMapAdditions(){
  100.         return new Error("This is a static class");
  101.     }
  102.  
  103.     SigonyMapAdditions.copyMapCommand = async function(args){
  104.         const mapId = eval(args.shift());
  105.         const mapName = eval(args.shift());
  106.         const variable = eval(args.shift());
  107.         const parentId = eval(args.shift());
  108.         const destFolder = eval(args.shift());
  109.  
  110.         const newMapId = await this.copyMapFile(mapId,mapName,parentId,destFolder);
  111.         $gameVariables.setValue(variable,newMapId)
  112.  
  113.     }
  114.  
  115.     SigonyMapAdditions.deleteMapCommand = async function(args){
  116.         const mapId = eval(args.shift());
  117.         const srcFolder = eval(args.shift());
  118.         await this.deleteMapFile(mapId,srcFolder)
  119.     }
  120.  
  121.     SigonyMapAdditions.deleteMapFile = async function(mapId,srcFolder=null){
  122.         const mapInfos = await this.scrapeMapInfos();
  123.         const filename = 'Map%1.json'.format(mapId.padZero(3));
  124.         const src = srcFolder? srcFolder+filename : "data/"+filename;
  125.  
  126.         const fs = require('fs');
  127.         fs.unlinkSync(src);
  128.        
  129.         this.removeMapInfo(mapId);
  130.        
  131.         console.log(`${src} SUCCESSFULLY DELETED`)
  132.     }
  133.  
  134.     SigonyMapAdditions.copyMapFile = async function(mapId=$gameMap.mapId(),mapName=null,parentId=0,destFolder=null){
  135.         let mapInfos = await this.scrapeMapInfos();
  136.         //Copy the file
  137.         const filename = 'Map%1.json'.format(mapId.padZero(3));
  138.         const newMapId = await this.findAvailableMapId(mapInfos);
  139.         const newFileName = 'Map%1.json'.format(newMapId.padZero(3));
  140.         const src = 'data/'+filename;
  141.         const dest = destFolder ? destFolder+newFileName : 'data/'+newFileName
  142.  
  143.         const fs = require('fs');
  144.         const { COPYFILE_EXCL } = fs.constants;
  145.         fs.copyFile(src,dest,COPYFILE_EXCL,()=>{console.log(`${filename} COPIED SUCCESSFULLY to ${dest}`)});
  146.  
  147.         //Add the reference to MapInfos.json
  148.         await SigonyMapAdditions.addMapInfo(mapInfos,newMapId,mapName,parentId);
  149.  
  150.         //Polish copied map, change display name
  151.         const map = await SigonyMapAdditions.scrapeMap(newMapId);
  152.         map.displayName = mapName;
  153.         fs.writeFileSync(dest,JSON.stringify(map));
  154.  
  155.  
  156.         return newMapId;
  157.     }
  158.  
  159.     SigonyMapAdditions.removeMapInfo = async function(mapId){
  160.         let mapInfos = await this.scrapeMapInfos()
  161.         mapInfos = mapInfos.filter(mapInfo => {
  162.             if(mapInfo==null){return true;}
  163.             return mapInfo.id != mapId
  164.         });
  165.         const mapInfoData = JSON.stringify(mapInfos);
  166.         const fs = require('fs');
  167.         fs.writeFileSync('data/MapInfos.json',mapInfoData);
  168.     }
  169.  
  170.     SigonyMapAdditions.addMapInfo = async function(mapInfos,mapId,mapName=null,parentId=0){
  171.         let mapInfo = {"id":mapId,"expanded":true,"name":mapName? mapName : "GeneratedMap"+mapId,"order":mapId,"parentId":parentId?parentId:0,"scrollX":1081.3333333333333,"scrollY":680}
  172.         mapInfos.push(mapInfo);
  173.         console.log(JSON.parse(JSON.stringify(mapInfos)));
  174.         mapInfos=this.fixMapInfos(mapInfos);
  175.         console.log(mapInfos);
  176.         const mapInfoData = JSON.stringify(mapInfos);
  177.  
  178.         const fs = require('fs');
  179.         fs.writeFileSync('data/MapInfos.json',mapInfoData);
  180.        
  181.     }
  182.  
  183.     /*SigonyMapAdditions.addMapInfo = async function(mapId){
  184.         const mapInfos = await this.scrapeMapInfos();
  185.         this.addMapInfo(mapInfos,mapId)
  186.     }*/
  187.  
  188.     SigonyMapAdditions.fixMapInfos = function(mapInfos){
  189.         //Sort first
  190.         mapInfos.sort((a,b)=>{
  191.             if(a == null){
  192.                 return -1;
  193.             }
  194.             if(b==null){
  195.                 return 1;
  196.             }
  197.             return a.id-b.id
  198.         });
  199.         console.log(mapInfos);
  200.        
  201.         //Now ensure just one null at beginning
  202.        
  203.         mapInfos = mapInfos.filter(info=>info);
  204.         mapInfos.unshift(null);
  205.         return mapInfos;
  206.        
  207.     }
  208.  
  209.     SigonyMapAdditions.findAvailableMapId = async function(mapInfos){
  210.         let occupied = []
  211.         for(info of mapInfos){
  212.             if(info==null){
  213.                 continue
  214.             }else{
  215.                 occupied.push(info.id)
  216.             }
  217.         }
  218.         occupied.sort((a,b)=>a-b);
  219.         console.log(occupied);
  220.  
  221.         let prev = occupied[0];
  222.         for(i=1;i<occupied.length;i++){
  223.             const o = occupied[i];
  224.             console.log(prev+" "+o)
  225.             if(o==prev+1){
  226.                 prev = o;
  227.                 continue;
  228.             }else{
  229.                 return prev+1
  230.             }
  231.         }
  232.         return prev+1;
  233.     }
  234.  
  235.     SigonyMapAdditions.scrapeMapInfos = async function(){
  236.         var url = 'data/MapInfos.json';
  237.         const data = await fetch(url,{
  238.             headers:{
  239.                 'Content-Type':'application/json'
  240.             }
  241.         });
  242.         return data.json();
  243.     }
  244.  
  245.     SigonyMapAdditions.scrapeMap = async function(mapId,folder="data/"){
  246.         const filename = 'Map%1.json'.format(mapId.padZero(3));
  247.         const data = await fetch(folder+filename,{headers:{
  248.             'Content-Type':'application/json'
  249.         }}).catch(err=>{console.log(err)});
  250.         return data.json()
  251.  
  252.     }
  253.  
  254.     SigonyMapAdditions.createBlankMap = async function(parentId=0, folder="data/"){
  255.         const mapInfos = await SigonyMapAdditions.scrapeMapInfos();
  256.         const mapId = await SigonyMapAdditions.findAvailableMapId(mapInfos);
  257.         const filename = 'Map%1.json'.format(mapId.padZero(3));
  258.         const fs = require('fs');
  259.         fs.writeFileSync(folder+filename,JSON.stringify(
  260.             {
  261.                 "autoplayBgm":false,"autoplayBgs":false,"battleback1Name":"","battleback2Name":"","bgm":{"name":"","pan":0,"pitch":100,"volume":90},"bgs":{"name":"","pan":0,"pitch":100,"volume":90},"disableDashing":false,"displayName":"","encounterList":[],"encounterStep":30,"height":13,"note":"","parallaxLoopX":false,"parallaxLoopY":false,"parallaxName":"","parallaxShow":true,"parallaxSx":0,"parallaxSy":0,"scrollType":0,"specifyBattleback":false,"tilesetId":1,"width":17,
  262.                 "data":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
  263.                 "events":[
  264.                 ]
  265.                 }
  266.  
  267.         ));
  268.         mapInfos.push(
  269.             {"id":mapId,"expanded":false,"name":"GeneratedMap"+mapId,"order":mapId,"parentId":parentId,"scrollX":1092,"scrollY":604}
  270.             );
  271.         fs.writeFileSync('data/MapInfos.json',JSON.stringify(mapInfos));
  272.         return mapId;
  273.     }
  274.  
  275.     var Sigony_MapAdditions_Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
  276.     Game_Interpreter.prototype.pluginCommand = function(command, args) {
  277.         switch(command.toUpperCase()) {
  278.             case 'COPYMAP': // PluginCommand: CopyMap mapId mapName variableForNewMapId parentId  destFolder
  279.                 SigonyMapAdditions.copyMapCommand(args);
  280.                 break;
  281.             case 'DELETEMAP':
  282.                 SigonyMapAdditions.deleteMapCommand(args)
  283.                 break;
  284.             default:
  285.                 Sigony_MapAdditions_Game_Interpreter_pluginCommand.call(this, command, args);
  286.         }
  287.     };
  288.  
  289. })();
Add Comment
Please, Sign In to add comment