rpgtkoolmv / corescript

http://www.rpgmakerweb.com/products/programs/rpg-maker-mv
MIT License
311 stars 75 forks source link

New Plugin Command Proposal #119

Open inc0der opened 7 years ago

inc0der commented 7 years ago

New Plugin Command Proposal

I'm going to make this proposal over at the forums on rmweb but I figured I would also create a feature issue here and see what developers think about it. Maybe you have other ideas for a way to handle everything, either way, we can brainstorm together. Maybe it's just not possible on the editor side of things but it's worth the proposal either way.

The Plugin Command Parameter Tags

New Plugin Command Selection Window

@command Layers

@action add
@text Add Layer
@parent Layers
@type struct<LayerAdd>
@desc Add layer to the map.

@action refresh
@text Refresh Layer
@parent Layers
@desc Remove and re-add all layers

@param Quest

@action start
@text Start
@parent Quest
@type number
@desc Start a quest and add to journal.
@default 0

@action complete
@text Complete Quest
@parent Quest
@type number
@desc Complete a quest
@default 0

PluginManager Handling

All pseudo code, was kind of rushed but general idea is here. We will need a few extra methods in the PluginManager to register, retrieve and check existence

PluginManager.registerCommand(command, actions) {
  this._commands[command] = actions
}
PluginManager.isCommand(command) {
  return typeof this._commands[command] !== 'undefined'
}
PluginManager.retrieveCommand(command) {
  if  (this.isCommand(command)) {
    return this._command[command]
  }
}

All commands are registered by the plugin developer, and it's simply an object with functions. They're always a function which has the arguments passed into them.

  PluginManager.registerCommands('layer', {
    add: function (data) { /* Do Stuff */ },
    refresh: function (data) { /* Do Stuff */ },
    remove: function (data) { /* Do Stuff */ }
  })

Game Interpreter Handling

When calling a plugin command from an event, clicking okay will simply add the plugin command to the event list just like a plugin parameter.

layers add {"type":"static","mapId":"1","x":"0","y":"0","z":"1","opacity":"255","blend":"1"}

Rather than the developer alias Game_Interpreter.prototype.pluginCommand method, RMMV would simply handle the command. But, for backward compatibility aliasing is still possible.

For further backward compatibility, we still use the pluginCommand() args argument to determine which action should be applied.

Game_Interpreter.prototype.pluginCommand = function(command, args) {
    var actions = PluginManager.retrieveCommand(command)
    if (actions) {
      var action = actions[args[0]]
    if (typeof action === 'function') {
    //Upon apply of function, we can add important information from the event for use with all plugin commands.
      command.apply(null, {
        // We can pass all args or just the 3rd element args[3]
        args: args[3]
        mapId: this._mapId,
        eventId: this._eventId,
        list: this._list
      })
    } else {
      throw new Error('Plugin command action must be a function')
    }
  }
};

For a plugin developer to use the information passed in you'd simply tap into the data object passed in from Game_Interpreter which also contains an args property. This args property is in JSON format just like plugin parameters and can be parsed using JSON.parse(data.args)

  PluginManager.registerCommands('layer', {
    add: function (data) {
      const args = JSON.parse(data.args)
      Layers.createConfig(data.mapId, args.id, {
        x: args.x,
        y: args.y,
        z: args.z
      })
     },
    refresh: function (data) { /* Do Stuff */ },
    remove: function (data) { /* Do Stuff */ }
  })