Custom Map System Not Working...

Status
Not open for further replies.

Nekohime1989

Nekohime
Veteran
Joined
May 31, 2014
Messages
498
Reaction score
227
First Language
English
Primarily Uses
RMMZ
Code:
YEP_CoreEngine.js:1094 TypeError: Cannot read property 'trim' of undefined
    at Game_Interpreter.pluginCommand (Tsukitsune_animatedOverlayAddon.js:288)
    at Game_Interpreter.pluginCommand (Olivia_HorrorEffects.js:1385)
    at Game_Interpreter.pluginCommand (MM_MapSystem.js:107)
    at Game_Interpreter.command356 (rpg_objects.js:10508)
    at Game_Interpreter.executeCommand (rpg_objects.js:8930)
    at Game_Interpreter.update (rpg_objects.js:8838)
    at Game_Map.updateInterpreter (rpg_objects.js:6115)
    at Game_Map.update (rpg_objects.js:6022)
    at Scene_Map.updateMain (rpg_scenes.js:608)
    at Scene_Map.updateMainMultiply (rpg_scenes.js:600)
SceneManager.catchException @ YEP_CoreEngine.js:1094
I the aforementioned error when I call the following Common Event.
Code:
◆Comment:These are constant values, no other picture can use them.
:       :Picture 51 is the Background
:       :Picture 52 is the Foreground
◆Play SE:Book2 (90, 100, 0)
◆Show Picture:#51, mapbase, Upper Left (0,0), (100%,100%), 255, Normal
◆Plugin Command:GET CURRENT FLOOR
◆Label:maploop
◆If:Script:$gameVariables.value(20) === $dataMap.mapOverlay
  ◆Plugin Command:DISPLAY MAP ICON
  ◆
:End
◆If:Button [Cancel] is pressed down
  ◆Play SE:Book2 (90, 100, 0)
  ◆Erase Picture:#51
  ◆Erase Picture:#52
  ◆Exit Event Processing
  ◆
:End
◆If:Button [Left] is pressed down
  ◆Plugin Command:PREVIOUS MAP
  ◆
:End
◆If:Button [Right] is pressed down
  ◆Plugin Command:NEXT MAP
  ◆
:End
◆Jump to Label:MapLoop
Here is the plugin where the plugin commands are stored.

The thing is i'm not calling str.trim. So I don't understand what I'm doing wrong. Am I missing something.
Goal: Common event display 2 picture, background never changes, but the foreground image does depending on the current maps notetags. You can also loop through all the foreground images by pressing left and right. An icon will show the players current position on the current map, but not be displayed if they are viewing another map.

edit: Okay so appears to have something to do with Tsukitsune's Animated Overlay plugin.
 
Last edited:

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,108
Reaction score
13,713
First Language
English
Primarily Uses
RMMV
According to your error log, it's the Tsukitsune_animatedOverlayAddon.js plugin that's throwing the error.

The plugin commands above are not very nice. GET, DISPLAY, PREVIOUS, NEXT - they're all so ambiguous and could be detected by a number of plugins as their own, so plugins could be trying to execute commands that don't belong to them.

Please provide a link to Tsukitsune's plugin. At a guess, I'd say it also has a GET or DISPLAY command.
 

Saelorable

Villager
Member
Joined
Feb 22, 2019
Messages
9
Reaction score
16
First Language
English
Primarily Uses
RMMV
From the look of things, Tsukitsune's Animated Overlay plugin has a misplaced closing bracket, and something is modifying the args array when it shouldn't be. given that i can't see Olivia Horror Effects' code, i'd hazard that they're doing something funky, and you should check their `Game_Interpreter.prototype.pluginCommand` hook to see what they're doing to the args object.
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,108
Reaction score
13,713
First Language
English
Primarily Uses
RMMV
I think it's more that that's the order of the plugins, and they're all calling each other, which is what they're meant to do. So it's called the map system plugin command, which called Olivia's plugin command, which called Tsukitsune's plugin command, which is what's having the problem.
 

Nekohime1989

Nekohime
Veteran
Joined
May 31, 2014
Messages
498
Reaction score
227
First Language
English
Primarily Uses
RMMZ
they
According to your error log, it's the Tsukitsune_animatedOverlayAddon.js plugin that's throwing the error.

The plugin commands above are not very nice. GET, DISPLAY, PREVIOUS, NEXT - they're all so ambiguous and could be detected by a number of plugins as their own, so plugins could be trying to execute commands that don't belong to them.

Please provide a link to Tsukitsune's plugin. At a guess, I'd say it also has a GET or DISPLAY command.
Wait what? Theirs words after that too. The entire phrase is a plugin command.
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,108
Reaction score
13,713
First Language
English
Primarily Uses
RMMV
The entire phrase is a plugin command
Actually, it's not. The plugin command is only the first word. The remainder are the arguments.

For this reason, your command is GET, and the arguments are CURRENT and FLOOR. Because you don't have those in quotes, it's looking for variables called CURRENT and FLOOR, and they're not defined.

Tsukitsune's plugin goes ahead and does processing on the arguments, without even checking if the command is one that that plugin is looking for. It's trying to do CURRENT.trim() and CURRENT isn't a valid variable name.

I also expect your plugin won't work properly either, because you're looking for a command called "GET CURRENT FLOOR" but the command is only GET.

If you want the entire thing to be the plugin command, then you need to make it one word. GETCURRENTFLOOR or GET_CURRENT_FLOOR or GetCurrentFloor or anything without spaces.
 
Last edited:

Nekohime1989

Nekohime
Veteran
Joined
May 31, 2014
Messages
498
Reaction score
227
First Language
English
Primarily Uses
RMMZ
Oh crap i think your right. Okay I'll just add underscores instead of spaces then.

As for the Efficiency you say... :)
Tell me more. I love making my code more efficient, So back move the alias to the bottom then like this?

Code:
Game_Interpreter.prototype.pluginCommand = function(command, args) {
  var overlays = [
    Rachnera.Param.MapOverlay1,
    Rachnera.Param.MapOverlay2,
    Rachnera.Param.MapOverlay3,
    Rachnera.Param.MapOverlay4
  ];
  if (command === 'GET_CURRENT_FLOOR') {
    var index = $dataMap.mapOverlay;
    $gameScreen.showPicture(Rachnera.Param.MapPicture, overlays[index], 0 , 0, 0, 100, 100, 255, 0);
    $gameVariables.setValue(20,index);
  }
  else if (command === 'NEXT_MAP') {
    var currentMap = $gameVariables.value(20);
    currentmap = (currentmap + 1)%4;
    $gameScreen.showPicture(Rachnera.Param.MapPicture, overlays[currentmap], 0 , 0, 0, 100, 100, 255, 0);
    $gameVariables.setValue(20,currentmap);
  }
  else if (command === 'PREVIOUS_MAP') {
    var currentMap = $gameVariables.value(20);
    currentmap -= 1;
    if (currentmap < 0) currentmap = 3;
    $gameScreen.showPicture(Rachnera.Param.MapPicture, overlays[currentmap], 0 , 0, 0, 100, 100, 255, 0);
    $gameVariables.setValue(20,currentmap);
  }
  else if (command === 'DISPLAY_MAP_ICON') {
    //notetags determine the x and y coordinates of the map
    this.drawIcon(Rachnera.Param.MapIcon,$dataMap.mapIconX-16,$dataMap.mapIconY-16);
  }
  Rachnera.MapSystem.Game_Interpreter_pluginCommand.call(this, command, args);
};
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,108
Reaction score
13,713
First Language
English
Primarily Uses
RMMV
lol - I completely edited my post there, hoping you wouldn't read it until afterwards. Please go back and look at it, as I was looking at a few things that turned out to be irrelevant and I think my new version will be more understandable.

You're close with the efficiency thing - just put it inside one more else statement:

Code:
if (command === 'GET_CURRENT_FLOOR') {
  // do some stuff
}
else if (command === 'NEXT_MAP') {
  // do some stuff
}
else if (command === 'PREVIOUS_MAP') {
  // do some stuff
}
else if (command === 'DISPLAY_MAP_ICON') {
  // do some stuff
}
else {
  // the command isn't handled by this plugin, so pass it back for someone else to look at
  Rachnera.MapSystem.Game_Interpreter_pluginCommand.call(this, command, args);
};
What you're saying here is "if MY plugin handles this command, handle it and stop processing - don't pass the command and arguments along to the next plugin to check".


Now, there's an order that the plugin commands get executed, and that depends on how they're arranged in your plugin manager. I think it starts at the bottom and works its way up. So it would be nice if you have a plugin that's called a LOT, to put it near the bottom of the list, and if you have a plugin that's called very rarely, to put it near the top of the list. That means the commands that get called most frequently will "find" their plugin faster, and the ones that have to go through more aliased functions to find their plugin aren't called very often.

However, there's also the issue where several plugins might alias the same function, or even overwrite it. In those cases, it's important to make sure they're getting executed in the right order (plugins that overwrite functions should be higher in the list, otherwise other plugins that alias it will be ignored completely).

It's all a bit of a juggling act :)


For Tsukitsune's plugin, you could potentially add a check after line 273 (command = command.toLowerCase(); ) to return if the command is not one that that plugin is looking for. That'll stop it trying to do trim() or other processing on commands that it's not even meant to handle.
 
Last edited:

Nekohime1989

Nekohime
Veteran
Joined
May 31, 2014
Messages
498
Reaction score
227
First Language
English
Primarily Uses
RMMZ
Yeah the problem is line 288,
Code:
layer = args[0].trim().toLowerCase();
That's a serious lack of efficiency. I think this will work. Let me try something.
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,108
Reaction score
13,713
First Language
English
Primarily Uses
RMMV
It's only because args[0] was an undefined variable, due to your error with the name of the command (spaces). But yeah, I'd put in a check to stop it trying to process commands that belong to other plugins.
 

Nekohime1989

Nekohime
Veteran
Joined
May 31, 2014
Messages
498
Reaction score
227
First Language
English
Primarily Uses
RMMZ
Derp... I had the wrong common events assigned.
Okay moving on. It sort of works... However when I press cancel it opens up the menu.
I don't want the menu accessible when the map system is open. Is their a way to lock the player out of the menu?

edit: $gameSystem.disableMenu() does the trick. Now I just need to figure out how to make only this common event update when it is reserved.
 
Last edited:

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,108
Reaction score
13,713
First Language
English
Primarily Uses
RMMV
there is an event command to toggle menu access
 

Saelorable

Villager
Member
Joined
Feb 22, 2019
Messages
9
Reaction score
16
First Language
English
Primarily Uses
RMMV
As for the Efficiency you say... :)
Tell me more. I love making my code more efficient, So back move the alias to the bottom then like this?

Code:
Game_Interpreter.prototype.pluginCommand = function(command, args) {
  var overlays = [
    Rachnera.Param.MapOverlay1,
    Rachnera.Param.MapOverlay2,
    Rachnera.Param.MapOverlay3,
    Rachnera.Param.MapOverlay4
  ];
  if (command === 'GET_CURRENT_FLOOR') {
    var index = $dataMap.mapOverlay;
    $gameScreen.showPicture(Rachnera.Param.MapPicture, overlays[index], 0 , 0, 0, 100, 100, 255, 0);
    $gameVariables.setValue(20,index);
  }
  else if (command === 'NEXT_MAP') {
    var currentMap = $gameVariables.value(20);
    currentmap = (currentmap + 1)%4;
    $gameScreen.showPicture(Rachnera.Param.MapPicture, overlays[currentmap], 0 , 0, 0, 100, 100, 255, 0);
    $gameVariables.setValue(20,currentmap);
  }
  else if (command === 'PREVIOUS_MAP') {
    var currentMap = $gameVariables.value(20);
    currentmap -= 1;
    if (currentmap < 0) currentmap = 3;
    $gameScreen.showPicture(Rachnera.Param.MapPicture, overlays[currentmap], 0 , 0, 0, 100, 100, 255, 0);
    $gameVariables.setValue(20,currentmap);
  }
  else if (command === 'DISPLAY_MAP_ICON') {
    //notetags determine the x and y coordinates of the map
    this.drawIcon(Rachnera.Param.MapIcon,$dataMap.mapIconX-16,$dataMap.mapIconY-16);
  }
  Rachnera.MapSystem.Game_Interpreter_pluginCommand.call(this, command, args);
};
You're close with the efficiency thing - just put it inside one more else statement:

Code:
if (command === 'GET_CURRENT_FLOOR') {
  // do some stuff
}
else if (command === 'NEXT_MAP') {
  // do some stuff
}
else if (command === 'PREVIOUS_MAP') {
  // do some stuff
}
else if (command === 'DISPLAY_MAP_ICON') {
  // do some stuff
}
else {
  // the command isn't handled by this plugin, so pass it back for someone else to look at
  Rachnera.MapSystem.Game_Interpreter_pluginCommand.call(this, command, args);
};
What you're saying here is "if MY plugin handles this command, handle it and stop processing - don't pass the command and arguments along to the next plugin to check".
Actually, as far as performance goes, a switch .. case function is most efficient. (and easier to write IMO) so the most efficient code would be:

Code:
switch(command){
    case 'GET_CURRENT_FLOOR':
        // do some stuff

    break;
    case 'NEXT_MAP':
        // do some stuff

    break;
    case 'PREVIOUS_MAP':
        // do some stuff

    break;
    case 'DISPLAY_MAP_ICON':
        // do some stuff

    break;
    default:
        // the command isn't handled by this plugin, so pass it back for someone else to look at
        Rachnera.MapSystem.Game_Interpreter_pluginCommand.call(this, command, args);
}
also, useful bonus:
with a switch you can also easily alias commands, so say if you wanted both 'DISPLAY_MAP_ICON' and 'SHOW_MAP_ICON' (say you keep getting mixed up and forgetting which one to use) you can do:

Code:
switch(command){
    case 'GET_CURRENT_FLOOR':
        // do some stuff

    break;
    case 'NEXT_MAP':
        // do some stuff

    break;
    case 'PREVIOUS_MAP':
        // do some stuff

    break;
    case 'DISPLAY_MAP_ICON':
    case 'SHOW_MAP_ICON':
        // do some stuff

    break;
    default:
        // the command isn't handled by this plugin, so pass it back for someone else to look at
        Rachnera.MapSystem.Game_Interpreter_pluginCommand.call(this, command, args);
}
}
 

Nekohime1989

Nekohime
Veteran
Joined
May 31, 2014
Messages
498
Reaction score
227
First Language
English
Primarily Uses
RMMZ
This entire implementation is inefficient. Im switching to a custom scene. (insert disgonbgud meme here)
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,108
Reaction score
13,713
First Language
English
Primarily Uses
RMMV
It's not always about being efficient though. Your code would have worked just fine. If you start over every time you find a new/better way of doing something, you'll never finish your game - sometimes "it works" is good enough :)
 

Nekohime1989

Nekohime
Veteran
Joined
May 31, 2014
Messages
498
Reaction score
227
First Language
English
Primarily Uses
RMMZ
Actually no it doesn't work, at least not as intended. Do to how common events work.
It needs to be a separate scene. Which I've mostly figured out. Just got to figure out how to get the pictures and icon to display.
 
Last edited:

mlogan

Global Moderators
Global Mod
Joined
Mar 18, 2012
Messages
15,374
Reaction score
8,536
First Language
English
Primarily Uses
RMMV

This thread is being closed, due to being solved. If for some reason you would like this thread re-opened, please report this post and leave a message why. Thank you.

 

Nekohime1989

Nekohime
Veteran
Joined
May 31, 2014
Messages
498
Reaction score
227
First Language
English
Primarily Uses
RMMZ
So let me post the code in it's current state.
Code:
//=============================================================================
// Manor Mouse Map System
// MM_MapSystem.js
//=============================================================================

var Imported = Imported || {};
Imported.MM_MapSystem = true;

var Rachnera = Rachnera || {};
Rachnera.MapSystem = Rachnera.MapSystem || {};

//=============================================================================
/*:
* @plugindesc Handles the map system.
* @author Rachnera
*
* @param Floor 1 Overlay
* @type file
* @dir img/pictures/
* @require 1
* @desc This is the filename of your map base. Do not include an extension.
* @default floor1overlay
*
* @param Floor 2 Overlay
* @type file
* @dir img/pictures/
* @require 1
* @desc This is the filename of your map base. Do not include an extension.
* @default floor2overlay
*
* @param Floor 3 Overlay
* @type file
* @dir img/pictures/
* @require 1
* @desc This is the filename of your map base. Do not include an extension.
* @default floor3overlay
*
* @param Outside Overlay
* @type file
* @dir img/pictures/
* @require 1
* @desc This is the filename of your map base. Do not include an extension.
* @default outsideoverlay
*
* @param MapOverlay Picture Number
* @min 1
* @max 100
* @desc This is picture number that is used for displaying the map overlays.
* @default 100
*
* @param Map Icon
* @desc This is the icon to display the players position on the map.
* @default 15
*
* @param Map Variable
* @desc This is the game variable that stores the map being displayed.
* @default 5
*
*/
//=============================================================================

//=============================================================================
//Parameters
//=============================================================================

Rachnera.Parameters = PluginManager.parameters('MM_MapSystem');
Rachnera.Param = Rachnera.Param || {};

Rachnera.Param.MapOverlay1 = String(Rachnera.Parameters['Floor 1 Overlay']);
Rachnera.Param.MapOverlay2 = String(Rachnera.Parameters['Floor 2 Overlay']);
Rachnera.Param.MapOverlay3 = String(Rachnera.Parameters['Floor 3 Overlay']);
Rachnera.Param.MapOverlay4 = String(Rachnera.Parameters['Outside Overlay']);
Rachnera.Param.MapPicture = Number(Rachnera.Parameters['MapOverlay Picture Number']);
Rachnera.Param.MapIcon = Number(Rachnera.Parameters['Map Icon']);
Rachnera.Param.MapVariable = Number(Rachnera.Parameters['Map Variable']);

//=============================================================================
//Data Manager
//=============================================================================

Rachnera.MapSystem.DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
DataManager.isDatabaseLoaded = function() {
    if (!Rachnera.MapSystem.DataManager_isDatabaseLoaded.call(this)) return false;
    return true;
};

DataManager.processMapSystemNotetags = function() {
    if (!$dataMap) return;

    $dataMap.mapOverlay = 0;
    $dataMap.mapIconX = 0;
    $dataMap.mapIconY = 0;

    if (!$dataMap.note) return;
    var notedata = $dataMap.note.split(/[\r\n]+/);
    for (var i = 0; i < notedata.length; i++) {
        var line = notedata[i];
        if (line.match(/<(?:MAP):[ ](\d+)[ ](\d+)[ ](\d+)>/i)) {
            $dataMap.mapOverlay = parseInt(RegExp.$1).clamp(0,3);
            $dataMap.mapIconX = parseInt(RegExp.$2);
            $dataMap.mapIconY = parseInt(RegExp.$3);
        }
    }
};

//=============================================================================
// Game_Map
//=============================================================================

Rachnera.MapSystem.Game_Map_setup = Game_Map.prototype.setup;
Game_Map.prototype.setup = function(mapId) {
    if ($dataMap) DataManager.processMapSystemNotetags();
    Rachnera.MapSystem.Game_Map_setup.call(this, mapId);
};

//=============================================================================
// Game_Interpreter
//=============================================================================

Rachnera.MapSystem.Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;

Game_Interpreter.prototype.pluginCommand = function(command, args) {
    var overlays = [
        Rachnera.Param.MapOverlay1,
        Rachnera.Param.MapOverlay2,
        Rachnera.Param.MapOverlay3,
        Rachnera.Param.MapOverlay4
    ];
    if (command === 'MapGUI_GetCurrentFloor') {
        var index = $dataMap.mapOverlay;
        $gameScreen.showPicture(Rachnera.Param.MapPicture, overlays[index], 0 , 0, 0, 100, 100, 255, 0);
        $gameVariables.setValue(Rachnera.Param.MapVariable,index);
    }
    else if (command === 'MapGUI_NextMap') {
        var currentMap = $gameVariables.value(Rachnera.Param.MapVariable);
        currentMap = (currentMap + 1)%4;
        $gameScreen.showPicture(Rachnera.Param.MapPicture, overlays[currentMap], 0 , 0, 0, 100, 100, 255, 0);
        $gameVariables.setValue(Rachnera.Param.MapVariable,currentMap);
    }
    else if (command === 'MapGUI_PreviousMap') {
        var currentMap = $gameVariables.value(Rachnera.Param.MapVariable);
        currentMap -= 1;
        if (currentMap < 0) currentMap = 3;
        $gameScreen.showPicture(Rachnera.Param.MapPicture, overlays[currentMap], 0 , 0, 0, 100, 100, 255, 0);
        $gameVariables.setValue(Rachnera.Param.MapVariable,currentMap);
    }
    else if (command === 'MapGUI_DisplayMapIcon') {
        //notetags determine the x and y coordinates of the map
        this.drawIcon(Rachnera.Param.MapIcon,$dataMap.mapIconX-16,$dataMap.mapIconY-16);
    }
    else Rachnera.MapSystem.Game_Interpreter_pluginCommand.call(this,command,args);
};

So everything works as expected but theirs a serious problem going on in the background. It generates serious lag occur and player and event movement happens. I think I know why, I tried solving it myself by adding a kill switch that when active would prevent Player, Timer, and Map Events from updating but it resulted in the screen freezing when the script was called from the main menu.

This function runs every frame and is how the map scene is updated. I left a note tag where Common Event updates occur.
Code:
Scene_Map.prototype.updateMain = function() {
    var active = this.isActive();
    $gameMap.update(active); //common events up here.
    $gamePlayer.update(active);
    $gameTimer.update(active);
    $gameScreen.update();
};[/code
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
40,108
Reaction score
13,713
First Language
English
Primarily Uses
RMMV
There is nothing at all in there that would cause the game to lag.

What is the purpose of your aliasing DataManager.isDatabaseLoaded? You are basically returning what the original function would have returned. I would put the reading of the note tags into DataManager, where it loads the map, rather than into Game_Map.

You don't happen to have your plugin command in an event set to parallel process that never kills itself, do you? That would cause lag, because you are showing a picture on every frame when the picture could already be showing. If this is a "map setup" thing, do it once on a parallel event, then erase the event. If it's not a "map setup" thing, but you need it to run continually on the map, put in a Wait 15 so it's not doing it 60 times a second.

Edit - going back to your first post, it looks like that's exactly what you've done. You have a loop, and you're calling the plugin command on every loop. Put a WAIT somewhere in the loop so it will get executed on every iteration - either at the start of the loop or at the end (as long as there are no commands in there that will skip the wait command and go back to the start of the loop again)
 
Status
Not open for further replies.

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

Our latest feature is an interview with... me?!

People4_2 (Capelet off and on) added!

Just beat the last of us 2 last night and starting jedi: fallen order right now, both use unreal engine & when I say i knew 80% of jedi's buttons right away because they were the same buttons as TLOU2 its ridiculous, even the same narrow hallway crawl and barely-made-it jump they do. Unreal Engine is just big budget RPG Maker the way they make games nearly identical at its core lol.
Can someone recommend some fun story-heavy RPGs to me? Coming up with good gameplay is a nightmare! I was thinking of making some gameplay platforming-based, but that doesn't work well in RPG form*. I also was thinking of removing battles, but that would be too much like OneShot. I don't even know how to make good puzzles!
one bad plugin combo later and one of my followers is moonwalking off the screen on his own... I didn't even more yet on the new map lol.

Forum statistics

Threads
106,035
Messages
1,018,454
Members
137,821
Latest member
Capterson
Top