/*:
* @plugindesc Allows players to create their own custom characters.
* @author SumRndmDde
*
* @param Layers
* @desc This is the list in which layers are placed in the image. These are based off of the actual Folder names.
* @default Tail Part2, Wing Part2, Body, Eyes, Eyebrows, Nose, Mouth, Rear Hair Part1, Front Hair Part2, Rear Hair Part2, Clothing, Accessory A, Glasses, Front Hair Part1, Beast Ears, Accessory B, Tail Part1, Wing Part1
*
* @param Order
* @desc This is the order of the sections listed in the Section Command Window.
* @default Body, Eyes, Eyebrows, Nose, Mouth, Clothing, Front Hair, Rear Hair, Accessory A, Accessory B, Glasses, Beast Ears, Wing, Tail
*
* @param Mandatory
* @desc These are sections that MUST be filled before the Character Creation is closed.
* @default Body, Eyes, Eyebrows, Nose, Mouth
*
* @param Mandatory Color
* @desc This is the color of text for sections that are mandatory.
* @default #FFFF44
*
* @param Print to Console
* @desc If 'true', then whenever a character is created, code to replicate that character will be logged.
* @default false
*
* @param == Visual Options ==
* @default
*
* @param Use Fade Transition
* @desc If 'true', then there will be a fade transition when going from the map to the character creator.
* @default true
*
* @param Use Piece Background
* @desc If 'true', the pieces will be given backgrounds depending on their style!
* @default true
*
* @param Use Scene Background
* @desc If 'true', then the "Background" image will be used. Otherwise, the scene will simply overlap the map.
* @default true
*
* @param Background X Scroll
* @desc The X speed of the background's scrolling. Set to 0 in order to disable!
* @default 1
*
* @param Background Y Scroll
* @desc The Y speed of the background's scrolling. Set to 0 in order to disable!
* @default 0
*
* @param Small Piece Cols
* @desc The amount of columns when using small pieces.
* (More specifically, pieces less than 100px).
* @default 3
*
* @param Big Piece Cols
* @desc The amount of columns when using small pieces.
* (More specifically, pieces greater than 100px).
* @default 1
*
* @param == Dialogues ==
* @default
*
* @param Leave Dialogue
* @desc The dialogue that asks the player whether they're sure they wish to leave the character creator.
* @default Are you sure you want\n to save this character?
*
* @param Mandatory Dialogue
* @desc The dialogue that shows when the player tries to leave the character creator without completeing all the mandatories.
* @default You need to have all the mandatory sections \nfilled out before exiting.
*
* @param == Size Options ==
* @default
*
* @param Character Width
* @desc This is the width of each character frame created with the Character Creation.
* @default 48
*
* @param Character Height
* @desc This is the height of each character frame created with the Character Creation.
* @default 48
*
* @param SV Char Width
* @desc This is the width of each character frame created with the Character Creation (for side-view battlers).
* @default 64
*
* @param SV Char Height
* @desc This is the height of each character frame created with the Character Creation (for side-view battlers).
* @default 64
*
* @param Face Width
* @desc This is the width of each face image created with the Character Creation.
* @default 144
*
* @param Face Height
* @desc This is the height of each face image created with the Character Creation.
* @default 144
*
* @param == Localization ==
* @default
*
* @param Yes Text
* @desc The "Yes" text for the confirmation window.
* @default Yes!
*
* @param No Text
* @desc The "No" text for the confirmation window.
* @default Nope
*
* @param Color Mouse/Touch Input
* @desc If 'true', mouse and mobile controls will be enabled.
* @default true
*
* @help
*
* Character Creator EX
* Version 1.03
* SumRndmDde
*
*
* This is a plugin that allows players to create their own custom characters
* in game.
*
* A menu system in which the player can create a character can be called
* upon at any time and assigned to an Actor. Once an Actor has been assigned
* a custom character, that character will be used on the map and in side-
* view battles.
*
*
* In order to modify the properties of the sections and pieces, one must
* use the Super Tools Engine. Simply go to:
*
* Database EX > Custom Editors > Character Creator Editor
*
* With this, you'll be able to easily customize the various properties
* that exist within the sections!
*
*
* ==========================================================================
* Setting up Files
* ==========================================================================
*
* In order to set up the "generator" pieces, you need to create a new
* folder in the "img" folder called "character-creator".
*
* So the file location should be:
*
* /img/SumRndmDde/character-creator-ex/
*
* Within this folder, you need a folder for each section, for example:
*
* /img/SumRndmDde/character-creator-ex/Body/
* /img/SumRndmDde/character-creator-ex/Mouth/
* /img/SumRndmDde/character-creator-ex/Nose/
* /img/SumRndmDde/character-creator-ex/Glasses/
* etc...
*
* Within each of these folders, you'll also need 4 more folders:
*
* /walk/
* /dead/
* /face/
* /sv/
*
* As you can probably guess, each of those folders will contain the
* corresponding walking, dead, face, and side-view parts of the
* parent folder.
*
*
* For example, in order to store the "Face" parts of the "Body" section
* you would place them in:
*
* /img/character-creator-ex/Body/face/
*
*
* ==========================================================================
* Other Images
* ==========================================================================
*
* Finally, you're also going to need a couple required images placed in:
*
* /img/SumRndmDde/character-creator-ex/
*
* These images are:
*
* Background.png
* CustomCharacter.png
* CustomFace.png
* Walk-Background.png
* Dead-Background.png
* Face-Background.png
* SV-Background.png
*
*
* The "Background" image will be used as a background for the character
* creator if you choose to use it.
*
* The "CustomCharacter" and "CustomFace" will be used in scenarios where
* a custom character's Character or Face image cannot be loaded.
*
* The "____-Background" images are used as piece backgrounds in the
* editor itself.
*
*
* ==========================================================================
* Opening the Character Creator
* ==========================================================================
*
* In order to set up the Character Creator, use the Plugin Command:
*
* OpenCharacterCreator [actorId]
*
* Set "actorId" to the Actor ID of the Actor you wish to create images for.
*
*
* For example:
*
* OpenCharacterCreator 3
* OpenCharacterCreator 7
* OpenCharacterCreator 26
*
*
* ==========================================================================
* Showing Dead Custom Character
* ==========================================================================
*
* Use the following Plugin Command to make an Actor use their "dead"
* custom character image:
*
* SetDeadCustomCharacter [actorId] [true/false]
*
* This will set it so the Actor defind by "actorId" will have their
* dead image turned on or off.
*
*
* For example:
*
* SetDeadCustomCharacter 3 true
* SetDeadCustomCharacter 8 false
* SetDeadCustomCharacter 12 true
*
*
* ==========================================================================
* Setting Event to use Custom Character
* ==========================================================================
*
* If you wish for an event to use a custom character image, simply use
* the event notetag:
*
*
*
* This will set the event to use the custom image of the actor specified
* through the "actorId" input.
*
*
* You can also set an event to use a dead custom character using:
*
*
*
*
* Examples:
*
*
*
*
*
* ==========================================================================
* Showing Custom Face in Show Text
* ==========================================================================
*
* If you wish to have a character's custom face used in a "Show Text",
* here's what you need to do:
*
*
* 1) Make sure there is a face image selected for the "Show Text" event.
* It can be any face image, it just needs to be there.
*
*
* 2) Use the following notetag in the "Show Text" box:
*
*
*
* Set "id" to the ID of the Actor who has the Custom Face you wish to use.
*
*
* ==========================================================================
* Disabling the Custom Images
* ==========================================================================
*
* In order temporarily distable the custom images set up for an Actor, use
* the Plugin Command:
*
* DisableCharacterCreatorImages [actorId]
*
* Of course, simply set "actorId" to the Actor ID you wish to disable
* custom character images for.
*
*
* EnableCharacterCreatorImages [actorId]
*
* This would enable the character creator images again.
*
*
* For example:
*
* DisableCharacterCreatorImages 12
* EnableCharacterCreatorImages 8
*
*
* ==========================================================================
* Custom Colors
* ==========================================================================
*
* While most of the properties that can be manipulated in the
* "Character Creator Editor" in the Super Tools Engine are pretty
* self explanatory, the color-customization section... is a bit more
* difficult.
*
* The colors are set up using JSON arrays, meaning:
*
* [info for color 1],
* [info for color 2],
* ...
* [info for last color]
*
*
* As you can see, each "color" is separated into its own brackets.
* Every color is followed by a comma except for the last one.
*
*
* Now within these colors, you may customize the:
*
* - Name
* - Hue
* - Saturation
* - Brightness
* - Grayscale
*
* For example:
*
* ["Blue", 100, 0, 1, 0.5]
*
*
* This would set:
*
* - Name: Blue
* - Hue: 100
* - Saturation: 0
* - Brightness: 1
* - Grayscale: 0.5
*
*
* You are not forced to fill out all of the properties however. In fact,
* the less you fill out, the better. For a simple Hue shift, all one
* needs to do is:
*
* ["Green", 200]
*
* This will create a simple color called Green that shifts the hue by 200.
*
*
* The limits that may be defined through the properties are as follows:
*
* - Hue [0 ~ 360]
* - Saturation [-1 ~ 1]
* - Brightness [0 ~ 1]
* - Grayscale [0 ~ 1]
*
*
* ==========================================================================
* End of Help File
* ==========================================================================
*
* Welcome to the bottom of the Help file.
*
*
* Thanks for reading!
* If you have questions, or if you enjoyed this Plugin, please check
* out my YouTube channel!
*
* https://www.youtube.com/c/SumRndmDde
*
*
* Until next time,
* ~ SumRndmDde
*
*/
var SRD = SRD || {};
SRD.CharacterCreatorEX = SRD.CharacterCreatorEX || {};
var Imported = Imported || {};
Imported["SumRndmDde Character Creator EX"] = 1.03;
var $gameCharacterCreations = null;
function Scene_CharacterCreator() {
this.initialize.apply(this, arguments);
}
function Window_CharacterCreator_FileList() {
this.initialize.apply(this, arguments);
}
function Window_CharacterCreator_FolderList() {
this.initialize.apply(this, arguments);
}
function Window_CharacterCreator_Preview() {
this.initialize.apply(this, arguments);
}
function Game_CharacterCreations() {
this.initialize.apply(this, arguments);
}
function Sprite_DisplayCharacter() {
this.initialize.apply(this, arguments);
}
function Sprite_DisplayDeadCharacter() {
this.initialize.apply(this, arguments);
}
function Sprite_DisplayBlankCharacter() {
this.initialize.apply(this, arguments);
}
function Sprite_DisplaySvCharacter() {
this.initialize.apply(this, arguments);
}
function Window_HueSelector() {
this.initialize.apply(this, arguments);
}
function Window_CharacterCreatorConfirmation() {
this.initialize.apply(this, arguments);
}
(function(_) {
"use strict";
_.alertNeedSuperToolsEngine = function() {
alert("The 'SRD_SuperToolsEngine' plugin is required for using the 'SRD_CharacterCreatorEX' plugin.");
if(confirm("Do you want to open the download page to 'SRD_SuperToolsEngine'?")) {
window.open('http://sumrndm.site/super-tools-engine/');
}
};
if(!Imported["SumRndmDde Super Tools Engine"]) {
_.alertNeedSuperToolsEngine();
return;
}
_.alertGetRidOfCharacterCreator = function() {
alert("Please get rid of the 'SRD_CharacterCreator' plugin in order to use 'SRD_CharacterCreatorEX'!");
};
if(Imported["SumRndmDde Character Creator"]) {
_.alertGetRidOfCharacterCreator();
return;
}
//-----------------------------------------------------------------------------
// SRD.CharacterCreator
//-----------------------------------------------------------------------------
const params = PluginManager.parameters('SRD_CharacterCreatorEX');
_.isNodeJs = Utils.isNwjs();
_.fileInfoStuff = {};
_.path = 'img/SumRndmDde/character-creator-ex/';
_.priorities = String(params['Layers']).split(/\s*,\s*/);
_.order = String(params['Order']).split(/\s*,\s*/);
_.mandatory = String(params['Mandatory']).split(/\s*,\s*/);
_.mandatoryColor = String(params['Mandatory Color']);
_.console = String(params['Print to Console']).trim().toLowerCase() === 'true';
_.fade = String(params['Use Fade Transition']).trim().toLowerCase() === 'true';
_.pieceBackground = String(params['Use Piece Background']).trim().toLowerCase() === 'true';
_.background = String(params['Use Scene Background']).trim().toLowerCase() === 'true';
_.xScroll = parseInt(params['Background X Scroll']);
_.yScroll = parseInt(params['Background Y Scroll']);
_.smallCols = parseInt(params['Small Piece Cols']);
_.bigCols = parseInt(params['Big Piece Cols']);
_.leaveDialogue = String(params['Leave Dialogue']).replace(/\\n/g, '\n');
_.mandatoryDialogue = String(params['Mandatory Dialogue']).replace(/\\n/g, '\n');
_.width = parseInt(params['Character Width']);
_.height = parseInt(params['Character Height']);
_.fileWidth = _.width * 3;
_.fileHeight = _.height * 4;
_.svWidth = parseInt(params['SV Char Width']);
_.svHeight = parseInt(params['SV Char Height']);
_.svFileWidth = _.svWidth * 9;
_.svFileHeight = _.svHeight * 6;
_.faceFileWidth = parseInt(params['Face Width']);
_.faceFileHeight = parseInt(params['Face Height']);
_.yesText = String(params['Yes Text']);
_.noText = String(params['No Text']);
_.touchInput = String(params['Color Mouse/Touch Input']).trim().toLowerCase() === 'true';
_.xOffset = 40;
_.getRealFilePath = function(p) {
const path = require('path');
const base = path.dirname(process.mainModule.filename);
return path.join(base, p);
};
_.getFilePathData = function() {
var path = require('path');
var base = path.dirname(process.mainModule.filename);
return path.join(base, 'data/');
};
_.getFolderListNodeJs = function() {
const result = [];
const fs = require('fs');
const location = this.getRealFilePath(this.path);
const files = fs.readdirSync(location);
for(let i = 0; i < files.length; i++) {
const file = location + files[i];
const stat = fs.statSync(file);
if(stat && stat.isDirectory()) {
result.push(files[i]);
}
}
return result;
};
_.getFileListNodeJs = function(folder) {
const result = [];
const fs = require('fs');
const location = this.getRealFilePath(this.path) + folder + 'walk/';
const files = fs.readdirSync(location);
for(let i = 0; i < files.length; i++) {
const file = location + files[i];
const stat = fs.statSync(file);
if(!stat) continue;
if(!stat.isDirectory() && _.isImageFile(files[i])) {
const f = files[i].replace('.png', '');
result.push(f);
}
}
return result;
};
_.saveFileInfoStuff = function() {
const folds = this.getFolderListNodeJs();
this.fileInfoStuff.folders = folds;
for(let i = 0; i < folds.length; i++) {
const fold = folds[i] + '/';
this.fileInfoStuff[fold] = this.getFileListNodeJs(fold);
}
const data = LZString.compressToBase64(JSON.stringify(this.fileInfoStuff));
const fs = require('fs');
const dirPath = this.getFilePathData();
const filePath = dirPath + 'cc-info.sumrndmdde';
fs.writeFileSync(filePath, data);
};
_.loadSaveInfoFile = function() {
var xhr = new XMLHttpRequest();
var url = 'data/cc-info.sumrndmdde';
xhr.open('GET', url);
xhr.onload = function() {
if (xhr.status < 400) {
this.fileInfoStuff = JSON.parse(LZString.decompressFromBase64(xhr.responseText));
}
};
xhr.onerror = function() {};
xhr.send();
};
_.getFolderList = function() {
return this.fileInfoStuff.folders;
};
_.getFileList = function(folder) {
return this.fileInfoStuff[folder];
};
_.isImageFile = function(filename) {
return !!(filename.match(/\.png/i));
};
_.cache = new CacheMap(_);
_.loadImage = function(filename, hue) {
const key = filename;
let bitmap = this.cache.getItem(key);
if(!bitmap) {
bitmap = ImageManager.loadBitmap('img/SumRndmDde/character-creator-ex/', filename, hue, true);
this.cache.setItem(key, bitmap);
}
return bitmap;
};
_.loadImageWPath = function(path, filename, hue) {
const key = filename + path;
let bitmap = this.cache.getItem(key);
if(!bitmap) {
bitmap = ImageManager.loadBitmap(path, filename, hue, true);
this.cache.setItem(key, bitmap);
}
return bitmap;
};
_.preloadCharacterPieces = function() {
const folders = this.getFolderList();
_._ccex_loads = 0;
_._ccex_files = -1;
let tempFiles = 0;
const increaseLoads = function() {
_._ccex_loads++;
}
for(let i = 0; i < folders.length; i++) {
const files = this.getFileList(folders[i] + '/');
for(let j = 0; j < files.length; j++) {
this.loadImageWPath(this.path + folders[i] + '/walk/', files[j]).addLoadListener(increaseLoads.bind(this));
this.loadImageWPath(this.path + folders[i] + '/dead/', files[j]).addLoadListener(increaseLoads.bind(this));
this.loadImageWPath(this.path + folders[i] + '/face/', files[j]).addLoadListener(increaseLoads.bind(this));
this.loadImageWPath(this.path + folders[i] + '/sv/', files[j]).addLoadListener(increaseLoads.bind(this));
tempFiles += 4;
}
}
_._ccex_files = tempFiles;
this.loadImage('CustomCharacter');
this.loadImage('CustomFace');
this.loadImage('Background');
this.loadImage('Walk-Background');
this.loadImage('Dead-Background');
this.loadImage('SV-Background');
this.loadImage('Face-Background');
};
if(_.isNodeJs) {
_.saveFileInfoStuff();
} else {
_.loadSaveInfoFile();
}
_.checkFileExists = function() {
FileManager.checkDataExists("CharacterCreator.json", `{
"Body":{"label":"","direction":0,"source":"Face","color":false,"condition":"true","colors":[["White",0],["Tan",0,0.8,0],["Brown",24,-1,0.5],["Black",24,-1,0.3],["Gray",24,0,0,0.35],["Blue",0,0,0.5,0.5]]},
"Clothing":{"label":"","direction":0,"source":"Walk","color":false,"condition":"true","colors":[]},
"Rear Hair":{"label":"","direction":3,"source":"Walk","color":true,"condition":"true","colors":[["Blonde",0],["Brown",-27,-0.5,0.8],["Black",-27,-1,0.3],["White",0,0,1,0.5],["Gray",0,0,0.5,0.5],["Green",60],["Teal",120],["Blue",180],["Purple",240],["Red",300]]},
"Tail":{"label":"","direction":3,"source":"Walk","color":true,"condition":"true","colors":[]},
"Wing":{"label":"","direction":3,"source":"Walk","color":true,"condition":"true","colors":[]},
"Eyebrows":{"label":"","direction":1,"source":"Face","color":true,"condition":"true","colors":[["Blonde",0],["Brown",-27,-0.5,0.8],["Black",-27,-1,0.3],["White",0,0,1,0.5],["Gray",0,0,0.5,0.5],["Green",60],["Teal",120],["Blue",180],["Purple",240],["Red",300]]},
"Nose":{"label":"","direction":0,"source":"Face","color":false,"condition":"true","colors":[["White",0],["Tan",0,0.8,0],["Brown",24,-1,0.5],["Black",24,-1,0.3],["Gray",24,0,0,0.35],["Blue",0,0,0.5,0.5]]},
"Mouth":{"label":"","direction":0,"source":"Face","color":false,"condition":"true","colors":[["White",0],["Tan",0,0.8,0],["Brown",24,-1,0.5],["Black",24,-1,0.3],["Gray",24,0,0,0.35],["Blue",0,0,0.5,0.5]]},
"Eyes":{"label":"","direction":0,"source":"Face","color":true,"condition":"true","colors":[["Blue",0],["Purple",60],["Red",120],["Yellow",180],["Green",240],["Teal",300],["Orange",180,1,0.8],["Sky Blue",0,1,1,0.35]]},
"Front Hair":{"direction":0,"source":"Walk","color":true,"condition":"true","colors":[["Blonde",0],["Brown",-27,-0.5,0.8],["Black",-27,-1,0.3],["White",0,0,1,0.5],["Gray",0,0,0.5,0.5],["Green",60],["Teal",120],["Blue",180],["Purple",240],["Red",300]],"label":""},
"Accessory A":{"direction":0,"source":"SV","color":true,"condition":"true","colors":[],"label":""},
"Accessory B":{"direction":0,"source":"SV","color":true,"condition":"true","colors":[],"label":""},
"Glasses":{"direction":0,"source":"SV","color":true,"condition":"true","colors":[],"label":""},
"Beast Ears":{"direction":0,"source":"SV","color":true,"condition":"true","colors":[],"label":""}
}`);
};
_.checkFileExists();
//-----------------------------------------------------------------------------
// DataManager
//-----------------------------------------------------------------------------
DataManager._testExceptions.push("CharacterCreator.json");
DataManager._databaseFiles.push({name: '$dataCharacterCreator', src: "CharacterCreator.json"});
_.DataManager_createGameObjects = DataManager.createGameObjects;
DataManager.createGameObjects = function() {
_.DataManager_createGameObjects.call(this);
$gameCharacterCreations = new Game_CharacterCreations();
_.preloadCharacterPieces();
};
_.DataManager_makeSaveContents = DataManager.makeSaveContents;
DataManager.makeSaveContents = function() {
const contents = _.DataManager_makeSaveContents.apply(this, arguments);
contents.characterCreations = $gameCharacterCreations;
return contents;
};
_.DataManager_extractSaveContents = DataManager.extractSaveContents;
DataManager.extractSaveContents = function(contents) {
_.DataManager_extractSaveContents.apply(this, arguments);
$gameCharacterCreations = contents.characterCreations;
};
_.DataManager_makeSavefileInfo = DataManager.makeSavefileInfo;
DataManager.makeSavefileInfo = function() {
const info = _.DataManager_makeSavefileInfo.apply(this, arguments);
info.srd_cc_chars = $gameParty.charactersForSavefile2();
return info;
};
//-----------------------------------------------------------------------------
// DataManagerEX
//-----------------------------------------------------------------------------
DataManagerEX._characterCreatorSection = _.order[0];
_.DataManagerEX_getCustomInfo = DataManagerEX.getCustomInfo;
DataManagerEX.getCustomInfo = function() {
const result = _.DataManagerEX_getCustomInfo.apply(this, arguments);
result.push(['Character Creator Editor', 'DataManagerEX.getCharacterCreatorHtml']);
return result;
};
DataManagerEX.getCharacterCreatorHtml = function() {
const data = $dataCharacterCreator[_.order[0]];
let colorStuff = JSON.stringify(data.colors);
colorStuff = colorStuff.substring(1, colorStuff.length - 1);
colorStuff = colorStuff.replace(/\],\[/img, '],\n[');
return `