public

Rpg Maker Developers Group

Simple enough for a child, powerful enough for a developer

2 Followers

LudoSubWindow Plugin Bug

BMM Archive · July 15, 2026

Preserved forum archive. This topic stores the original first post and locally mirrored RPG Maker Web attachments when available. It is posted by the BMMPlay archive account, not by the original creator.

Original Source

  • Original title: LudoSubWindow Plugin Bug
  • Original author: CactuarBoy
  • Original date: January 9, 2019
  • Source thread: https://forums.rpgmakerweb.com/threads/ludosubwindow-plugin-bug.104237/
  • Source forum path: Game Development Engines > RPG Maker Javascript Plugins > Javascript/Plugin Support

Summary

Hello Makers, I'm using THIS Plugin but i found a little bug that make it unusable. When i select a single target skill, then I should select a target but if I press Cancel to go back on the skill selection the game shows me this error: "TypeError: Cannot read property 'LastBattleSkill' of null." This, without any other plugin. If I set back all my plugins, than the Error looks like this:

Archived First Post

Hello Makers,
I'm using THIS Plugin but i found a little bug that make it unusable.
When i select a single target skill, then I should select a target but if I press Cancel to go back on the skill selection the game shows me this error: "TypeError: Cannot read property 'LastBattleSkill' of null."
This, without any other plugin. If I set back all my plugins, than the Error looks like this:

Protected download

So Window_ActorCommand -> Window_SubActorCommand -> Window_SubBattleSkill -> Window_BattleEnemy -> Cancel -> BUG

Here in spoiler, the full script I'm using:

//==
//LudoSubWindow.js
//==

//Manually change this for now
$subTypes = {
"Talenti" : ["MagiaN", "MagiaB", "Giullare", "SpadaMagica", "Support"],
"Limite" : ["Baro", "Lucidità"],
};

/*:
* @plugindesc Plugin that adds sub-options to the skills and magic battle commands to better separate larger amounts of options.
* @author Alessio De Santis
*
* @Help Use metatags in the form of <subType:Fire> where Fire is a string of your choice, then in LudoSubWindow.js (this plugin), change the subTypes object to include all Skill Types and their associated sub-Types, also make sure all skills have a subtype and associate skill type or they will not appear.
*
*/

//TODO
//
//Scene_Battle.prototype.onActorOk
//Scene_Battle.prototype.stop

//-----------------------------------------------------------------------------
// Window_SubActorCommand
//
// The window for selecting an actor's subactions on the battle screen.

function Window_SubActorCommand() {
this.initialize.apply(this, arguments);
}

Window_SubActorCommand.prototype = Object.create(Window_ActorCommand.prototype);
Window_SubActorCommand.prototype.constructor = Window_SubActorCommand;

Window_SubActorCommand.prototype.initialize = function() {
var y = Graphics.boxHeight - this.windowHeight();
Window_Command.prototype.initialize.call(this, 192, y);
this._stypeId = 0;
this.openness = 0;
this.deactivate();
this._actor = null;
};

Window_SubActorCommand.prototype.makeCommandList = function() {
if (this._actor) {
this.addElementsCommands();
}
};


Window_SubActorCommand.prototype.setStypeId = function(stypeId) {
if (this._stypeId !== stypeId) {
this._stypeId = stypeId;
this.refresh();
this.resetScroll();
}
};

Window_SubActorCommand.prototype.addElementsCommands = function() {
var subTypes = $subTypes[$dataSystem.skillTypes[this._stypeId]];
if(subTypes){
subTypes.sort(function(a, b) {
return a - b;
});
subTypes.forEach(function(element) {
if(this.checkSubSkill(element)){
var name = element;
this.addCommand(name, 'subskill', true, element);
}
}, this);
}
};

Window_SubActorCommand.prototype.checkSubSkill = function(element) {
for(i of this._actor._skills){
skill = $dataSkills.meta.subType;
if(skill == element){
return true;
}
}

return false
}

Window_SubActorCommand.prototype.setup = function(actor) {
this._actor = actor;
this.clearCommandList();
this.makeCommandList();
this.refresh();
this.selectLast();
this.activate();
this.open();
};

Window_ActorCommand.prototype.addSkillCommands = function() {
var skillTypes = this._actor.addedSkillTypes();
skillTypes.sort(function(a, b) {
return a - b;
});
skillTypes.forEach(function(stypeId) {
if(this.checkSubSkill(stypeId)){
var name = $dataSystem.skillTypes[stypeId];
this.addCommand(name, 'skill', true, stypeId);
}
}, this);
};

Window_ActorCommand.prototype.checkSubSkill = function(element) {
for(i of this._actor._skills){
skill = $dataSkills;
if(skill.stypeId == element && skill.meta.subType){
return true;
}

}
return false
}
//-----------------------------------------------------------------------------
// Window_SubBattleSkill
//
// The window for selecting a subskill to use on the battle screen.

function Window_SubBattleSkill() {
this.initialize.apply(this, arguments);
}

Window_SubBattleSkill.prototype = Object.create(Window_BattleSkill.prototype);
Window_SubBattleSkill.prototype.constructor = Window_SubBattleSkill;

Window_SubBattleSkill.prototype.initialize = function(x, y, width, height) {
Window_SkillList.prototype.initialize.call(this, x, y, width, height);
this._subType = "";
this.hide();
};

Window_SubBattleSkill.prototype.setSubType = function(subtype) {
if (this._subType !== subtype) {
this._subType = subtype;
this.refresh();
this.resetScroll();
}
};

Window_SubBattleSkill.prototype.includes = function(item) {
var subType = item.meta.subType;
return (item && item.stypeId === this._stypeId && subType && subType === this._subType);
};

//-----------------------------------------------------------------------------
// Scene_Battle Optimization to accomodate for the subTypes
//
//

Scene_Battle.prototype.createAllWindows = function() {
this.createLogWindow();
this.createStatusWindow();
this.createPartyCommandWindow();
this.createActorCommandWindow();

this.createSubActorCommandWindow();

this.createHelpWindow();
this.createSkillWindow();

this.createSubSkillWindow();

this.createItemWindow();
this.createActorWindow();
this.createEnemyWindow();
this.createMessageWindow();
this.createScrollTextWindow();
};


Scene_Battle.prototype.createSubActorCommandWindow = function() {
this._subactorCommandWindow = new Window_SubActorCommand();
this._subactorCommandWindow.setHandler('subskill', this.commandSubSkill.bind(this));
this._subactorCommandWindow.setHandler('cancel', this.onSubCancel.bind(this));
this.addWindow(this._subactorCommandWindow);
}

Scene_Battle.prototype.createSubSkillWindow = function() {
var wy = this._helpWindow.y + this._helpWindow.height;
var wh = this._statusWindow.y - wy;
this._subskillWindow = new Window_SubBattleSkill(0, wy, Graphics.boxWidth, wh);
this._subskillWindow.setHelpWindow(this._helpWindow);
this._subskillWindow.setHandler('ok', this.onSubSkillOk.bind(this));
this._subskillWindow.setHandler('cancel', this.onSubSkillCancel.bind(this));
this.addWindow(this._subskillWindow);
};

Scene_Battle.prototype.commandSubSkill = function() {
this._subskillWindow.setActor(BattleManager.actor());
this._subskillWindow.setStypeId(this._actorCommandWindow.currentExt());
this._subskillWindow.setSubType(this._subactorCommandWindow.currentExt());
this._subskillWindow.refresh();
this._subskillWindow.show();
this._subskillWindow.activate();
};

Scene_Battle.prototype.onSubSkillCancel = function() {
this._subskillWindow.hide();
this._subactorCommandWindow.activate();
};

Scene_Battle.prototype.endCommandSelection = function() {
this._partyCommandWindow.close();
this._actorCommandWindow.close();
this._subactorCommandWindow.close();
this._statusWindow.deselect();
};

Scene_Battle.prototype.onSubCancel = function() {
this._subactorCommandWindow.close();
this._skillWindow.deactivate();
this._actorCommandWindow.activate();
};

Scene_Battle.prototype.onSubSkillOk = function() {
var skill = this._subskillWindow.item();
var action = BattleManager.inputtingAction();
action.setSkill(skill.id);
BattleManager.actor().setLastBattleSkill(skill);
this._skillWindow.deactivate();
this.onSelectAction();
};

Scene_Battle.prototype.isAnyInputWindowActive = function() {
console.log(this._actorCommandWindow.active, this._subactorCommandWindow.active, this._skillWindow.active)
return (this._partyCommandWindow.active ||
this._actorCommandWindow.active ||
this._subactorCommandWindow.active ||
this._skillWindow.active ||
this._itemWindow.active ||
this._actorWindow.active ||
this._enemyWindow.active);
};

Scene_Battle.prototype.startPartyCommandSelection = function() {
this.refreshStatus();
this._statusWindow.deselect();
this._statusWindow.open();
this._actorCommandWindow.close();
this._subactorCommandWindow.close();
this._partyCommandWindow.setup();
};

Scene_Battle.prototype.startActorCommandSelection = function() {
this._statusWindow.select(BattleManager.actor().index());
this._partyCommandWindow.close();
this._subactorCommandWindow.close();
this._actorCommandWindow.setup(BattleManager.actor());
};

Scene_Battle.prototype.onSelectAction = function() {
var action = BattleManager.inputtingAction();
this._skillWindow.hide();
this._subskillWindow.hide();
this._itemWindow.hide();
if (!action.needsSelection()) {
this.selectNextCommand();
} else if (action.isForOpponent()) {
this.selectEnemySelection();
} else {
this.selectActorSelection();
}
};

Scene_Battle.prototype.stop = function() {
Scene_Base.prototype.stop.call(this);
if (this.needsSlowFadeOut()) {
this.startFadeOut(this.slowFadeSpeed(), false);
} else {
this.startFadeOut(this.fadeSpeed(), false);
}
this._statusWindow.close();
this._partyCommandWindow.close();
this._actorCommandWindow.close();
this._subactorCommandWindow.close();
};

Scene_Battle.prototype.endCommandSelection = function() {
this._partyCommandWindow.close();
this._actorCommandWindow.close();
this._subactorCommandWindow.close();
this._statusWindow.deselect();
};

Scene_Battle.prototype.commandSkill = function() {
this._subactorCommandWindow.setStypeId(this._actorCommandWindow.currentExt());
this._subactorCommandWindow.setup(BattleManager.actor());
this._skillWindow.activate();
};

Scene_Battle.prototype.createSkillWindow = function() {
var wy = this._helpWindow.y + this._helpWindow.height;
var wh = this._statusWindow.y - wy;
this._skillWindow = new Window_BattleSkill(0, wy, Graphics.boxWidth, wh);
this._skillWindow.setHelpWindow(this._helpWindow);
this.addWindow(this._skillWindow);
};

Scene_Battle.prototype.onEnemyOk = function() {
var action = BattleManager.inputtingAction();
action.setTarget(this._enemyWindow.enemyIndex());
this._enemyWindow.hide();
this._skillWindow.hide();
this._subskillWindow.hide();
this._itemWindow.hide();
this.selectNextCommand();
};

Scene_Battle.prototype.onActorOk = function() {
var action = BattleManager.inputtingAction();
action.setTarget(this._actorWindow.index());
this._actorWindow.hide();
this._skillWindow.hide();
this._subskillWindow.hide();
this._itemWindow.hide();
this.selectNextCommand();
};

Scene_Battle.prototype.onActorCancel = function() {
this._actorWindow.hide();
switch (this._actorCommandWindow.currentSymbol()) {
case 'skill':
this._skillWindow.show();
this._skillWindow.activate();
break;
case 'item':
this._itemWindow.show();
this._itemWindow.activate();
break;
}
};

Thanks in advance

EDIT:
Added console log for both BattleEnemy window and BattleActor window.
I also tried to disable YEP_CoreEngine but I still get the Error.

Protected download
Protected download

Downloads / Referenced Files

Log in to download

Log in, then follow the RPG Maker Developers Group to see these download links.

Log in to download

Referenced Images / Attachments

Cattura.PNG
Cattura.PNG
Console1.PNG
Console1.PNG
Console2.PNG
Console2.PNG
Creator Claims / Removal

If you are the original creator and want this listing reassigned, edited, or removed, join BMMPlay and contact the moderators with proof that matches the original RPG Maker Web profile, linked GitHub, itch.io page, or another public creator identity.

#039#rpg-maker-archive#js-support

Replies (0)

No replies yet.

0 replies 1 view

Log in to reply.

User Avatar