- Joined
- Jun 6, 2020
- Messages
- 723
- Reaction score
- 314
- First Language
- English
- Primarily Uses
- RMMV
Miscellaneous Plugins
I've posted a few plugins in the Plugin Request forum already, so I thought it would be a good idea to gather them all in one place. This thread will only be for small and simple plugins - if I release something big or complex I'll create another thread. Some of my plugin depend on having SFG_Utils installed above them, so if a plugin doesn't work, try installing SFG_Utils before posting a bug report.
All these plugins are also available for download on MakerDevs.com. Unless otherwise noted, they are not compatible with MZ.
This is just a collection of utility functions that I use in several of my plugins. If you have any trouble getting one of my plugins to work, install this and make sure it's placed above any of my plugins.
Download Link
Download Link
This allows you to set additional states to be treated as a death state for purposes of targeting, game overs, or both. You can also set an auto-state for 0 MP.
Download Link
Download Link
This adds an option in the Options menu to set auto-battle for all actors. Turn it on and the game will do all your fights for you.
This plugin is also compatible with RPGMaker MZ.
Download Link
This plugin is also compatible with RPGMaker MZ.
Download Link
This lets you use balloon icons in battle. Attach them to side-view actors or to enemies.
Download Link
Download Link
This allows triggering an event while in an airship and also adds a way for events to have a "line of sight" that will trigger them when you step on a tile in the same row or column.
This plugin is also compatible with RPGMaker MZ, but the
Download Link
This plugin is also compatible with RPGMaker MZ, but the
<relativeTransfer>
not tag does not work in MZ.Download Link
This basically allows you to do with TP anything that's already possible with MP and HP, plus some extra things specific to TP like customizing what it's set to at the beginning and end of battle.
Get Code From Post
Get Code From Post
This is a mod of Zeriab_ExtraMaps. It works pretty much the same way; the only real difference is that when you switch map folders, it loads the MapInfos.json from the new folder, which is required for compatibility with some of my plugins such as SFG_Localization and SFG_MapHierarchy.
Download Link
Download Link
Makes maps inherit optional properties (currently BGM, BGS, and battle backs) from their parent map in the editor map hierarchy. Note: This could cause some lag when transferring between maps, especially if you have deep nesting and/or are deploying to the web. I didn't experience any lag in my testing, but your mileage may vary.
This plugin is also compatible with RPGMaker MZ.
Download Link
This plugin is also compatible with RPGMaker MZ.
Download Link
This lets you shake the screen or play weather effects in the middle of a battle animation. Should work even when calling the battle animation from the map.
Download Link
Download Link
Adds an option in the Options menu to disable all actor faces in message windows. You can override the setting for individual messages if you wish.
Download Link
Download Link
Allows you to control how items, weapons, armours, and skills are ordered in various windows. Useful if the lists in your database are not in any logical order.
Download Link
Download Link
This adds a new command for eventing that lets you check the value of a variable and run code depending on what the value is. Programmers may know this as a "switch statement". Here's a contrived example of its use:
And another example using strings:
Download Link
Code:
◆Control Variables:#0019 += 1
◆Plugin Command:switch @19
◆Show Choices:1, 2, 3, #4~8, 9, 10 (Window, Right, #1, #2)
:When 1
◆Text:None, Window, Bottom
:Text:First time!
◆
:When 2
◆Text:None, Window, Bottom
:Text:Second time!
◆
:When 3
◆Text:None, Window, Bottom
:Text:Third time!
◆
:When #4~8
◆Text:None, Window, Bottom
:Text:Maybe you should stop this...
◆
:When 9
◆Text:None, Window, Bottom
:Text:Calm down, that's already nine times!
◆
:When 10
◆Text:None, Window, Bottom
:Text:And now it's your tenth time!
◆
:End
◆Show Choices:#(value % 5 == 1), 20, >30 (Window, Right, #1, -)
:When #(value % 5 == 1)
◆Text:None, Window, Bottom
:Text:I'm really at a loss for words.
◆Plugin Command:switch @19
◆Show Choices:>100, >45 (Window, Right, #1, #2)
:When >100
◆Text:None, Window, Bottom
:Text:Are you serious!? You've exceeeded one hundred!!!
◆
:When >45
◆Text:None, Window, Bottom
:Text:No really, stop it!
◆
:End
◆
:When 20
◆Text:None, Window, Bottom
:Text:Twentieth time already!? Are you mad!?
◆
:When >30
◆Text:None, Window, Bottom
:Text:More than thirty times! Just... just stop!
◆
:When Cancel
◆Text:None, Window, Bottom
:Text:This is starting to get crazy...
◆
:End
And another example using strings:
Code:
◆Name Input Processing:Harold, 8 characters
◆Plugin Command:switch $gameActors.actor(1).name()
◆Show Choices:"Harold", #"x"~"zzzzzzz", ~"[aeiou]{3,}" (Window, Right, #1, -)
:When "Harold"
◆Text:None, Window, Bottom
:Text:The default, good choice!
◆
:When #"x"~"zzzzzzz"
◆Text:None, Window, Bottom
:Text:That's quite a rare name...
◆
:When ~"[aeiou]{3,}"
◆Text:None, Window, Bottom
:Text:So many vowels!
◆
:When Cancel
◆Text:None, Window, Bottom
:Text:Not a bad choice!
◆
:End
Download Link
Adds wait commands for various event commands that have an optional wait. The most useful of this is "waitForMovementRoute", which will wait for a given character's movement route to complete. This lets you set the movement route going, do other stuff while it executes, but later wait for it to complete. If you're having movement routes cut short due to fast-forward, this can fix it.
Download Link
Download Link
An add-on for TAA_BookMenu that will load your books from external text files, one file per book. Note: this does not work for web deployment at this time and may not work on mobile either - it requires NwJS in order to function.
To enable it, set DataSource Type to Book Files in the TAA_BookMenu configuration.
For some reason the forum wouldn't let me attach this file, so here's the full code - just paste it into a file called SFG_BookFiles.js.
To enable it, set DataSource Type to Book Files in the TAA_BookMenu configuration.
For some reason the forum wouldn't let me attach this file, so here's the full code - just paste it into a file called SFG_BookFiles.js.
JavaScript:
/*:
@plugindesc [v1.0] Load your books from dedicated book files instead of the Plugin Manager or JSON.
@author Solar Flare Games
@param directory
@text Books Directory
@desc The directory under data/ to load books from. All .txt files in this directory will be loaded as books.
@type text
@default books/
@param catDirs
@text Categories as Subdirectories
@desc Whether or not to use subdirectories as categories. If false, subdirectories are ignored.
@type boolean
@default true
@param catOrder
@text Category Order
@desc Specifies the sort order for the categories.
@type text[]
@default []
@param bkgnd
@text Backgrounds
@desc Specifies custom backgrounds for each of your books.
@type struct<BookBkgnd>[]
@param inline
@text Inline Images
@desc List images included with %img so that Exclude Unused Files knows about them.
@type file[]
@require 1
@dir img/pictures/
@default []
@help
This is an addon to TAA_BookMenu which allows you to load your books from
dedicated book files rather than a set of JSON files or directly from the
Plugin Manager.
For each book, create a simple .txt file with the book's contents. The filename
will be used as the book's key for ReadBook and other commands, with any spaces
stripped out. By default, it will also become the book's title.
Be warned: if you plan to deploy to the web or mobile, this plugin is not
guaranteed to work.
Also note: Even if you use subdirectories as categories, you need to make sure
that books in different directories do not have the same name!
A book file consists of two sections. The first section contains configuration
details about the book, while the second section consists of the book's
actual content. The two sections are separated by a line containing
three or more hyphens, like this:
---------
The configuration section consists of a series of "key: value" pairs, one
per line. The following keys can be used:
• title: Sets the book's title
• titleColor: Corresponds to Title Window Text Color
• category: Specifies the book's category
• id: Specifies the book's sorting key; if left out, books will be sorted
alphabetically by their key (filename).
You cannot set custom backgrounds in the file. This is done to suppoort the
Exclude Unused Files option in RMMV deployment. Instead, you set custom
backgrounds here in the Plugin Manager. The Backgrounds parameter is a list
of possible backgrounds, each of which also has a list of books which it should
be used for - use the book's filename without the .txt extension.
If you want the same background on two books but with a different mode, you
can add that background to the list multiple times without issue. However,
do note that if you specify the same book on more than one background entry,
only the first will take effect.
*//*~struct~BookBkgnd:
@param books
@text Books
@desc The books to apply this background to.
@type text[]
@default []
@param bkgnd
@text Custom Background
@desc Specifies the custom background to use for these books.
@type file
@require 1
@dir img/pictures/
@param mode
@text Custom Background Mode
@desc Define how the custom image should be used for these books.
@type select
@option Detached Text Window Only
@value 5
@option Detached Title + Text Window
@value 9
@option Menu Text Window Only
@value 6
@option Menu Title + Text Window
@value 10
@option All Text Window Only
@value 7
@option All Title + Text Window
@value 11
@default 11
*/
(function() {
var params = PluginManager.parameters('SFG_BookFiles');
var backgrounds = Utils.parseRecursive(params.bkgnd);
const readBooksFromDirectory = function(dir, mode) {
let fs_base = require('fs'), util = require('util');
// This works around Node being old and lacking the 'fs/promises' module.
let fs = {
exists: util.promisify(fs_base.exists),
stat: util.promisify(fs_base.stat),
readdir: util.promisify(fs_base.readdir),
readFile: util.promisify(fs_base.readFile),
};
fs.exists(dir).then(exists => {
if(!exists) return; // No books to load...
return fs.stat(dir);
}).then(stat => {
if(!stat.isDirectory()) return; // No books to load...
return fs.readdir(dir);
}).then(dirListing => {
if(dirListing.length == 0) return; // No books to load...
let stats = [];
for(let i = 0; i < dirListing.length; i++) {
let path = dir + dirListing[i];
stats.push(fs.stat(path).then(stat => {
return {
file: dirListing[i],
path: path,
isDir: stat.isDirectory(),
};
}));
}
return Promise.all(stats);
}).then(files => {
if(mode == '?categories') {
files = files.filter(f => f.isDir);
for(let i = 0; i < files.length; i++) {
let path = files[i].path;
if(!path.endsWith('/')) path += '/';
readBooksFromDirectory.call(this, path, files[i].file);
}
return [];
} else {
files = files.filter(f => !f.isDir).map(f => f.path);
let data = [];
for(let i = 0; i < files.length; i++) {
data.push(fs.readFile(files[i], 'utf8').then(data => {
return {
file: files[i].replace(/.*\//g, ''),
path: files[i],
data: data,
};
}))
}
return Promise.all(data);
}
}).then(files => {
if(files.length == 0) return; // No books to load...
for(let i = 0; i < files.length; i++) {
let file = files[i].file;
let data = files[i].data.split(/^-{3,}\r?\n/m);
if(data.length > 2) {
console.warn('More than one section separator in book file %1'.format(file))
}
let book = {
id: 0, customBg: '', titleColor: 0,
title: file.replace('.txt', ''),
category: mode === '?all' ? params.unknownCategory : mode,
};
let header = data[0], bookKey = file.replace(/\s+/g, '').replace('.txt', '');
// Backgrounds...
for(let j = 0; j < backgrounds.length; j++) {
if(backgrounds[j].includes(bookKey)) {
let bg = backgrounds[j];
book.customBg = bg.bkgnd;
book.customBgMode = bg.mode;
break;
}
}
book.text = data.slice(1).join('------').replace(/\r\n/g, '\n');
for(let line of header.split('\n')) {
let m = line.match(/^([a-z]+):(.*)$/im);
if(m) {
let key = m[1].trim().toLowerCase(), value = m[2].trim();
if(key === 'category' && mode !== '?all') continue;
book[key] = value;
}
}
this._books[bookKey] = book;
// Create category subobject
if(!this._bookKeyByCategory[book.category]) {
this._bookKeyByCategory[book.category] = [];
}
if(!this._booksRead[book.category]) {
this._booksRead[book.category] = [];
}
// Fill in books under categories ordered by IDs
if(this._bookKeyByCategory[book.category][book.id] === undefined) {
if(!this._bookKeyByCategory[book.category].contains(bookKey))
this._bookKeyByCategory[book.category][book.id] = bookKey;
} else {
if(!this._bookKeyByCategory[book.category].contans(bookKey))
this._bookKeyByCategory[book.category].push(bookKey);
}
if(!this._categoryByBookKey[bookKey])
this._categoryByBookKey[bookKey] = book.category;
}
this._doneLoading = true;
});
};
const old_loadBooks = LibraryData.prototype.loadBookData;
LibraryData.prototype.loadBookData = function() {
if(this._source === 'Book Files') {
if(!Utils.isNwjs()) {
throw Error("Node not available, can't load books!");
}
let dir = 'data/%1'.format(params.directory);
if(!dir.endsWith('/')) dir += '/';
this._bookKeyByCategory = {}
this._booksRead = {};
this._books = {};
this._categoryByBookKey = {};
this._doneLoading = false;
readBooksFromDirectory.call(this, dir, params.catDirs ? '?categories' : '?all');
this._categoryList = JSON.parse(params.catOrder);
this._bookTitleObject = "title";
this._bookMenuTitleColorObject = "titleColor";
this._bookTextObject = "text";
this._bookCategoryObject = "category";
this._bookIdObject = "id";
// TODO: Set custom backgrounds from params.bkgnd...
} else old_loadBooks.call(this);
};
})();
Terms of Use
- You don't need to credit me in the game credits or anything. However, don't remove me from the "author" field in the plugin file.
- You can use these plugins in commercial or non-commercial games, free of charge.
- Feel free to modify these plugins however you need for your game. Exception: Do not modify SFG_Utils for any reason. If you need something added to or altered in SFG_Utils, just create a new plugin.
- If a plugin that I created is not listed in this thread, these terms of use do not apply to it.
- You may port these plugins to MZ as long as you give change the filename to remove the SFG_ prefix (to avoid making it appear to be an official port; you may add your own prefix if you wish). You still need to leave me in the "author" field in the plugin file.
Attachments
-
SFG_OptionalFaces.js2 KB · Views: 32
-
SFG_ParamAdd.js2 KB · Views: 46
-
SFG_SortKeys.js5.2 KB · Views: 77
-
SFG_AutoBattle.js1.5 KB · Views: 126
-
SFG_EventTriggers.js3.1 KB · Views: 38
-
SFG_AltDeathState.js5.1 KB · Views: 48
-
SFG_MapHierarchy.js3 KB · Views: 15
-
SFG_SwitchCommand.js8.4 KB · Views: 43
-
SFG_BattleBalloons.js4.6 KB · Views: 28
-
SFG_NewAnimTimings.js3 KB · Views: 27
-
SFG_Wait.js9.1 KB · Views: 22
-
SFG_Utils.js8.5 KB · Views: 25
Last edited: