/*: * @plugindesc v1.0 * @author DreamX * @help * This plugin will allow you to randomly add traits and other attributes to * enemies by combining enemies together. * ============================================================================ * How combination works * ============================================================================ * By default, a base enemy will be combined with a suffix/prefix enemy like * this: * * -A prefix enemy will add their name to the beginning of the new enemy name. * -A suffix enemy will add their name to the end of the new enemy name. * -The suffix/prefix enemy's action patterns will be added to the base enemy's * patterns. * -The suffix/prefix enemy's drops will be added to the base enemy's drops. * -The suffix/prefix enemy's params will be added to the base enemy's params. * -The suffix/prefix enemy's exp will be added to the base enemy's exp. * -The suffix/prefix enemy's gold will be added to the base enemy's gold. * -The suffix/prefix enemy's traits will be added to the base enemy's traits. * -The suffix/prefix enemy's notes will be added to the base enemy's notes. * -The suffix/prefix enemy's meta will be added to the base enemy's meta. * * However, there are notetags you can use to change how some of this works. * Check the next help sections. * * ============================================================================ * Base Enemy Notetag * ============================================================================ * You can have unlimited amounts of prefix and suffix combinations. * Each set of choices should begin on its own line. * You can enter ranges to select randomly for a set of numbers. * After a number or set of numbers, you will enter the chance. * If the chances do not add up to 100%, there is a chance none will be chosen. * It's up to you use percentages that add up to less than or equal to 100%. * * Here's an example with suffixes. * * 5-8 50% 10 50% * 7 100% * * In this example, one id from 5-8 has a 50% chance of being chosen, and id 10 has a * 50% of being chosen. * Then, 7 has a 100% chance of being chosen. * * Here's another example with prefixes this time. * * 12-15 25% * * In this example, one id from 12-15 has a 25% of being chosen. So, there is a * 75% of none being chosen. * * Prefix enemies will add their name to the beginning of the new randomized * enemy's name. Suffix enemies will add their name to the end instead. * * will mean that this enemy's image will be overlayed. * Not compatible with Animatd SV Enemies from YEP Animated SV Enemies yet. * will decides the order of overlaying for images. The * highest value gets put on top, lowest on bottom, etc. * ============================================================================ * Prefix/Suffix Enemy Notetags * ============================================================================ * will cause the new enemy's red tone to be x. * will add x to the new enemy's red tone. * will cause the new enemy's green tone to be x. * will add x to the new enemy's green tone. * will cause the new enemy's blue tone to be x. * will add x to the new enemy's blue tone. * * will use x instead of the database name when combining * names for the new enemy. * * will mean that this new enemy's hue will be replaced by * enemy's hue. * will mean that the new enemy's hue will be the average of the * prefix/suffix enemy hue and the base enemy hue. * * will mean that the new enemy's actions patterns will * be replaced by the this enemy's action patterns. * * will mean the new enemy's drops will be replaced by this * enemy's drops. * * will mean the new enemy's exp will be replaced by this * enemy's exp. * * will mean the new enemy's traits will be replaced by this * enemy's traits. * * will mean the new enemy's params will be replaced by this * enemy's params. * * will mean the new enemy's image will be replaced by this * enemy's image. * * will mean that this enemy's image will be overlayed. * Not compatible with Animatd SV Enemies from YEP Animated SV Enemies yet. * will decides the order of overlaying for images. The * highest value gets put on top, lowest on bottom, etc. * ============================================================================ * Tips * ============================================================================ * To further reduce time making enemy variations, I suggest using * YEP Enemy Levels and Himeworks Enemy Classes MV. This way, you have * both variation from this plugin and also have enemies level up with you. * Making differently strengthened enemies will become less necessary. * ============================================================================ * Terms Of Use * ============================================================================ * Free to use and modify for commercial and noncommercial games, with credit. * ============================================================================ * Credits * ============================================================================ * DreamX * Thank you to Yanfly for reference/code from their plugins. */ var Imported = Imported || {}; Imported.DreamX_RandomEnemyTraits = true; var DreamX = DreamX || {}; DreamX.RandomEnemyTraits = DreamX.RandomEnemyTraits || {}; (function () { var parameters = PluginManager.parameters('DreamX_RandomEnemyTraits'); DreamX.RandomEnemyTraits.evaluateChoices = function (enemy) { var evalMode = 'none'; var notedata = enemy.note.split(/[\r\n]+/); enemy.affixChoicesNotes = []; enemy.affixChoices = []; for (var i = 0; i < notedata.length; i++) { var line = notedata[i]; if (line.match(/<(?:Suffixes)>/i)) { evalMode = 'suffix'; } else if (line.match(/<\/(?:Suffixes)>/i)) { evalMode = 'none'; } else if (line.match(/<(?:Prefixes)>/i)) { evalMode = 'prefix'; } else if (line.match(/<\/(?:Prefixes)>/i)) { evalMode = 'none'; } else if (evalMode === 'suffix' || evalMode === 'prefix') { enemy.affixChoicesNotes.push({affixType: evalMode, line: line}); } } for (var i = 0; i < enemy.affixChoicesNotes.length; i++) { var lineObj = enemy.affixChoicesNotes[i]; var id = DreamX.RandomEnemyTraits.choose(lineObj.line); if (id && id !== -1) { enemy.affixChoices.push({affixType: lineObj.affixType, id: id}); } } }; DreamX.RandomEnemyTraits.choose = function (line) { var diceRoll = Math.floor(Math.random() * 100) + 1; var split = line.split(" "); var chosenId = -1; var choices = []; for (var i = 0; i < split.length; i++) { var numbers = split[i]; i++; var chance = split[i]; if (!chance) { continue; } chance = parseInt(chance.toString().replace("%", "")); choices.push({chance: chance, numbers: numbers}); } choices.sort(function (a, b) { if (a.chance === b.chance) { // randomly select between the two if they have the same chance return Math.randomInt(2) === 0; } else { return a.chance - b.chance; } }); for (var i = 0; i < choices.length; i++) { var chance = choices[i].chance; var numbers = choices[i].numbers; if (diceRoll <= chance) { chosenId = DreamX.parseNumberRanges(numbers); break; } else { diceRoll -= chance; } } chosenId = DreamX.randomArrayElement(chosenId); return chosenId; }; DreamX.randomArrayElement = function (array) { var diceRoll = Math.floor(Math.random() * array.length); var selected = array[diceRoll]; return selected; }; DreamX.parseNumberRanges = function (string) { var nums = []; var stringSplit = string.trim().replace(/,/g, " ").split(new RegExp("\\s{1,}")); for (var i = 0; i < stringSplit.length; i++) { var split = stringSplit[i].split("-"); var min = parseInt(split[0]); var max = split[1] ? parseInt(split[1]) : min; if (!min || min > max) { continue; } for (var j = min; j <= max; j++) { nums.push(j); } } return nums; }; DreamX.RandomEnemyTraits.combineHue = function (hue1, hue2) { return Math.floor((hue1 + hue2) / 2); }; DreamX.RandomEnemyTraits.combineWithBaseEnemy = function (affixEnemy, newEnemy, affixType) { var affixName = affixEnemy.meta.prefixSuffixName ? affixEnemy.meta.prefixSuffixName : affixEnemy.name; newEnemy.tones = {}; if (affixEnemy.meta.ReplaceRed) { newEnemy.tones.red = parseInt(affixEnemy.meta.ReplaceRed); newEnemy.changedTones = true; } else if (affixEnemy.meta.AddRed) { newEnemy.tones.red = parseInt(newEnemy.tones.red) || 0; newEnemy.tones.red += parseInt(affixEnemy.meta.AddRed); newEnemy.changedTones = true; } if (affixEnemy.meta.ReplaceBlue) { newEnemy.tones.blue = parseInt(affixEnemy.meta.ReplaceBlue); newEnemy.changedTones = true; } else if (affixEnemy.meta.AddBlue) { newEnemy.tones.blue = parseInt(newEnemy.tones.blue) || 0; newEnemy.tones.blue += parseInt(affixEnemy.meta.AddBlue); newEnemy.changedTones = true; } if (affixEnemy.meta.ReplaceGreen) { newEnemy.tones.green = parseInt(affixEnemy.meta.ReplaceGreen); } else if (affixEnemy.meta.AddGreen) { newEnemy.tones.green = parseInt(newEnemy.tones.green) || 0; newEnemy.tones.green += parseInt(affixEnemy.meta.AddGreen); newEnemy.changedTones = true; } if (affixType === "prefix") { newEnemy.name = affixName + " " + newEnemy.name; } else if (affixType === "suffix") { newEnemy.name = newEnemy.name + " " + affixName; } if (!affixEnemy.meta.OverlayImage) { if (affixEnemy.meta.ReplaceHue) { newEnemy.battlerHue = affixEnemy.battlerHue; } else if (affixEnemy.meta.CombineHue) { newEnemy.battlerHue = DreamX.RandomEnemyTraits.combineHue(newEnemy.battlerHue, affixEnemy.battlerHue); } } if (affixEnemy.meta.ReplaceActionPatterns) { newEnemy.actions = affixEnemy.actions; } else { newEnemy.actions = newEnemy.actions.concat(affixEnemy.actions); } if (affixEnemy.meta.ReplaceDrops) { newEnemy.dropItems = affixEnemy.dropItems; } else { newEnemy.dropItems = newEnemy.dropItems.concat(affixEnemy.dropItems); } if (affixEnemy.meta.ReplaceEXP) { newEnemy.exp = affixEnemy.exp; } else { newEnemy.exp += affixEnemy.exp; } if (affixEnemy.meta.ReplaceTraits) { newEnemy.traits = affixEnemy.traits; } else { newEnemy.traits = newEnemy.traits.concat(affixEnemy.traits); } if (affixEnemy.meta.ReplaceParams) { newEnemy.params = affixEnemy.params; } else { for (var i = 0; i < newEnemy.params.length; i++) { newEnemy.params[i] += affixEnemy.params[i]; } } if (affixEnemy.meta.ReplaceGold) { newEnemy.gold = affixEnemy.gold; } else { newEnemy.gold += affixEnemy.gold; } if (affixEnemy.meta.ReplaceImage) { if (Imported.YEP_X_AnimatedSVEnemies && affixEnemy.sideviewBattler.length > 0) { newEnemy.sideviewBattler = affixEnemy.sideviewBattler; } else { newEnemy.battlerName = affixEnemy.battlerName; } } else if (affixEnemy.meta.OverlayImage) { if (!newEnemy.overlayImages) { newEnemy.overlayImages = []; } var overlayPriority = affixEnemy.meta.OverlayImageOrder || 0; var overlayHue = affixEnemy.meta.CombineHue ? DreamX.RandomEnemyTraits.combineHue(newEnemy.battlerHue, affixEnemy.battlerHue) : affixEnemy.battlerHue; overlayPriority = parseInt(overlayPriority); newEnemy.overlayImages.push({name: affixEnemy.battlerName, order: overlayPriority, hue: overlayHue}); } for (var key in affixEnemy.meta) { switch (key) { case "OverlayImageOrder": break; default: newEnemy.meta[key] = affixEnemy.meta[key]; } } var newNote = ""; var oldNoteSplit = newEnemy.note.split(/[\r\n]+/); for (var i = 0; i < oldNoteSplit.length; i++) { var line = oldNoteSplit[i]; if (line.indexOf("