513 lines
No EOL
15 KiB
JavaScript
513 lines
No EOL
15 KiB
JavaScript
/*:
|
|
-------------------------------------------------------------------------------
|
|
@title Equip Slots Core
|
|
@author Hime --> HimeWorks (http://himeworks.com)
|
|
@date Apr 15, 2016
|
|
@version 1.5
|
|
@filename HIME_EquipSlotsCore.js
|
|
@url http://himeworks.com/2015/11/equip-slots-core/
|
|
|
|
If you have any questions or concerns, you can contact me at any of
|
|
the following sites:
|
|
|
|
Main Website: http://himeworks.com
|
|
Facebook: https://www.facebook.com/himeworkscom/
|
|
Twitter: https://twitter.com/HimeWorks
|
|
Youtube: https://www.youtube.com/c/HimeWorks
|
|
Tumblr: http://himeworks.tumblr.com/
|
|
-------------------------------------------------------------------------------
|
|
@plugindesc v1.5 - Provides you with tools to set up custom equip slots
|
|
for each actor individually.
|
|
@help
|
|
-------------------------------------------------------------------------------
|
|
== Description ==
|
|
|
|
Video: https://www.youtube.com/watch?v=fXcA0IdPsPg
|
|
|
|
By default, RPG Maker gives you 5 equip types to work with:
|
|
|
|
Weapon
|
|
Shield
|
|
Head
|
|
Body
|
|
Accessory
|
|
|
|
You also have the ability to add and modify equip slots directly in
|
|
the database.
|
|
|
|
However, one problem you might notice is that every actor will have
|
|
those equip slots, even if they can't use any of the equips that you've
|
|
designed for those slots.
|
|
|
|
Another problem is you can't add multiple copies of the same slot to
|
|
an actor: they can only have one of each. Want to wear two accessories?
|
|
Can't be done.
|
|
|
|
This plugin solves that problem. It provides ways for you to customize
|
|
your actors' equip slots, allowing you to choose exactly which slots
|
|
they will have in the game.
|
|
|
|
== Terms of Use ==
|
|
|
|
- Free for use in non-commercial projects with credits
|
|
- Contact me for commercial use
|
|
|
|
== Change Log ==
|
|
|
|
1.5 - Apr 15, 2016
|
|
* added support for multiple equip types for equips.
|
|
* standardized the way to check whether an equip slot can hold an item
|
|
1.4 - Apr 11, 2016
|
|
* Change the way etype ID is checked
|
|
* Fixed "Change Equipment" command
|
|
1.3 - Mar 14, 2016
|
|
* Added support for adding and removing equip slots using script calls
|
|
1.2 - Nov 20, 2015
|
|
* updated to support enemy equips
|
|
1.1 - Nov 18, 2015
|
|
* updated to support Yanfly's EquipCore
|
|
1.0 - Nov 12, 2015
|
|
* initial release
|
|
|
|
== Usage ==
|
|
|
|
-- Adding equip slots --
|
|
|
|
First, if you are using this plugin, the default "Initial equipment" box
|
|
will no longer be used. Instead, you will manage all actor equip slots
|
|
using note-tags.
|
|
|
|
To add an equip slot, use the following note tag:
|
|
|
|
<equip slot: ETYPE>
|
|
|
|
The ETYPE, which is short for "equip type", is one of the equip types
|
|
that you have set up for your project. You can see this in the Types tab.
|
|
|
|
You can either write the ID of the etype, or you can write the exact name
|
|
of the etype. For example, Weapon is equip type 1, so you can write either
|
|
|
|
<equip slot: 1>
|
|
<equip slot: Weapon>
|
|
|
|
Depending on your preferences. I would recommend writing out the full
|
|
name so that it is clearer, but if you ever change your equip types names
|
|
you will need to remember to update these note-tags.
|
|
|
|
If you would like to add more equip slots, just add more note-tags.
|
|
Want 3 weapons and 2 rings, assuming they are in the database?
|
|
|
|
<equip slot: Weapon>
|
|
<equip slot: Weapon>
|
|
<equip slot: Weapon>
|
|
<equip slot: Ring>
|
|
<equip slot: Ring>
|
|
|
|
-- Specifying Initial Equip --
|
|
|
|
Because the Initial Equipment box is no longer used, you will need to
|
|
find another way to specify them.
|
|
|
|
The equip slot note-tag supports initial equip, using something called an
|
|
"Item Code", and is written like this:
|
|
|
|
<equip slot: ETYPE ITEMCODE>
|
|
|
|
An Item code is a quick way to reference a particular weapon, armor, or
|
|
item. They look like this:
|
|
|
|
a1 - armor 1
|
|
w3 - weapon 3
|
|
i5 - item 5
|
|
|
|
So for example, if you want your actor to have a weapon slot with
|
|
weapon 4 from the database as its initial equip, use the note-tag
|
|
|
|
<equip slot: Weapon w4>
|
|
|
|
-- Adding and Removing Equip Slots Dynamically --
|
|
|
|
You may want to add or remove equip slots during the game.
|
|
To add an equip slot, use the script call
|
|
|
|
ACTOR.addEquipSlot(ETYPE)
|
|
|
|
Where the ACTOR is a reference to a Game_Actor object, and the ETYPE is
|
|
the name or ID of the equip slot you want to add.
|
|
|
|
For example, you can write
|
|
|
|
$gameActors.actor(2).addEquipSlot(4)
|
|
$gameActors.actor(2).addEquipSlot("Accessory")
|
|
|
|
To give actor 2 an extra equip slot of type 4 and "Accessory"
|
|
|
|
Removing slots is done using a similar script call
|
|
|
|
ACTOR.removeEquipSlot(ETYPE)
|
|
|
|
For example, if you want to remove the equip slot you added before, you can
|
|
write
|
|
|
|
$gameActors.actor(2).removeEquipSlot(4)
|
|
$gameActors.actor(2).removeEquipSlot("Accessory")
|
|
|
|
A random equip slot of that type will be removed. If the equip slot contains
|
|
an item, the item will be un-equipped and returned to the inventory.
|
|
|
|
If no such equip slot exists, nothing will happen.
|
|
|
|
-- Multiple Equip Types --
|
|
|
|
By default, all equips have one equip type.
|
|
You can assign additional equip types using note-tags.
|
|
|
|
With multiple equip types, you can put on the same equip in multiple slots
|
|
of your choice.
|
|
|
|
To assign additional equip types, note-tag armors or weapons with
|
|
|
|
<equip type: TYPE />
|
|
|
|
You can assign as many equip types as you want.
|
|
|
|
-- Custom Scenes --
|
|
|
|
This plugin provides bare-bones equip slot functionality. The purpose
|
|
is to be able to use it with *any* equip scene, whether it is the
|
|
default scene or a custom scene.
|
|
|
|
-------------------------------------------------------------------------------
|
|
*/
|
|
var Imported = Imported || {} ;
|
|
var TH = TH || {};
|
|
Imported.EquipSlotsCore = 1;
|
|
TH.EquipSlotsCore = TH.EquipSlotsCore || {};
|
|
|
|
function Game_EquipSlot() {
|
|
this.initialize.apply(this, arguments);
|
|
};
|
|
|
|
(function ($) {
|
|
|
|
$.Regex = /<equip[-_ ]slot:\s+(\w+)(?:\s+(\w)(\d+))?>/img
|
|
$.EtypeRegex = /<equip[-_ ]type:\s*(.+?)\s*\/>/img
|
|
|
|
$.etypeIds = function(obj) {
|
|
if (obj.etypeIds === undefined) {
|
|
obj.etypeIds = [obj.etypeId];
|
|
var res;
|
|
while (res = $.EtypeRegex.exec(obj.note)) {
|
|
|
|
obj.etypeIds.push($.getEtypeId(res[1]));
|
|
}
|
|
}
|
|
return obj.etypeIds;
|
|
}
|
|
|
|
$.etypeNameToId = function(etypeName) {
|
|
if (!$.etypeMap) {
|
|
$.etypeMap = {}
|
|
for (var i = 1; i < $dataSystem.equipTypes.length; i++) {
|
|
var name = $dataSystem.equipTypes[i].toUpperCase();
|
|
$.etypeMap[name] = i;
|
|
}
|
|
}
|
|
return $.etypeMap[etypeName.toUpperCase()];
|
|
}
|
|
|
|
$.getEtypeId = function(etypeId) {
|
|
if (isNaN(etypeId)) {
|
|
etypeId = $.etypeNameToId(etypeId);
|
|
}
|
|
else {
|
|
etypeId = Math.floor(etypeId)
|
|
}
|
|
return etypeId;
|
|
};
|
|
|
|
Game_EquipSlot.prototype.initialize = function() {
|
|
this._etypeId = 1;
|
|
this._item = new Game_Item();
|
|
};
|
|
|
|
Game_EquipSlot.prototype.setEtypeId = function(etypeID) {
|
|
this._etypeId = etypeID;
|
|
};
|
|
|
|
Game_EquipSlot.prototype.etypeId = function() {
|
|
return this._etypeId;
|
|
};
|
|
|
|
Game_EquipSlot.prototype.setObject = function(item) {
|
|
this._item.setObject(item);
|
|
};
|
|
|
|
Game_EquipSlot.prototype.object = function() {
|
|
return this._item.object();
|
|
};
|
|
|
|
Game_EquipSlot.prototype.setEquip = function(isWeapon, item) {
|
|
this._item.setEquip(isWeapon, item);
|
|
};
|
|
|
|
/* Support for multiple equip types */
|
|
Game_EquipSlot.prototype.canEquip = function(item) {
|
|
ids = $.etypeIds(item);
|
|
return ids.contains(this._etypeId);
|
|
}
|
|
|
|
Game_EquipSlot.prototype.isEtypeId = function(id) {
|
|
return this._etypeId === id;
|
|
};
|
|
|
|
/***************************************************************************/
|
|
|
|
var TH_EquipSlotsCore_GameBattler_initMembers = Game_Battler.prototype.initMembers;
|
|
Game_Battler.prototype.initMembers = function() {
|
|
this._equips = [];
|
|
TH_EquipSlotsCore_GameBattler_initMembers.call(this);
|
|
};
|
|
|
|
/* Returns equip slot objects */
|
|
Game_Battler.prototype.equipSlotList = function() {
|
|
return this._equips;
|
|
};
|
|
|
|
/* Returns all of the equip slot types for the battler
|
|
* Purely for backwards compatibility
|
|
*/
|
|
Game_Battler.prototype.equipSlots = function() {
|
|
var slots = this._equips;
|
|
var ids = [];
|
|
for (var i = 0; i < slots.length; i++) {
|
|
ids.push(slots[i].etypeId());
|
|
}
|
|
return ids;
|
|
};
|
|
|
|
Game_Battler.prototype.equips = function() {
|
|
return this._equips.map(function(item) {
|
|
return item.object();
|
|
});
|
|
};
|
|
|
|
Game_Battler.prototype.initEquips = function(equips) {
|
|
var baseSlots = this.baseSlots();
|
|
if (baseSlots.length > 0) {
|
|
var maxSlots = baseSlots.length;
|
|
this._equips = [];
|
|
for (var i = 0; i < maxSlots; i++) {
|
|
this._equips[i] = JsonEx.makeDeepCopy(baseSlots[i]);
|
|
}
|
|
this.releaseUnequippableItems(true);
|
|
this.refresh();
|
|
}
|
|
};
|
|
|
|
/* Base equip slots for the battler */
|
|
Game_Battler.prototype.baseSlots = function() {
|
|
return [];
|
|
}
|
|
|
|
Game_Battler.prototype.getBaseSlots = function(battler) {
|
|
if (!battler.baseEquipSlots) {
|
|
battler.baseEquipSlots = [];
|
|
var res;
|
|
while (res = $.Regex.exec(battler.note)) {
|
|
var equipSlot = new Game_EquipSlot();
|
|
var etypeId = res[1];
|
|
var itemType = res[2];
|
|
var itemID = res[3];
|
|
|
|
// /* Not a number. Assume it's the name of an equip type */
|
|
etypeId = $.getEtypeId(etypeId);
|
|
|
|
equipSlot.setEtypeId(etypeId);
|
|
if (itemType) {
|
|
equipSlot.setEquip(itemType.toLowerCase() === "w", Math.floor(itemID));
|
|
}
|
|
|
|
battler.baseEquipSlots.push(equipSlot);
|
|
}
|
|
}
|
|
return battler.baseEquipSlots;
|
|
};
|
|
|
|
Game_Battler.prototype.weapons = function() {
|
|
return this.equips().filter(function(item) {
|
|
return item && DataManager.isWeapon(item);
|
|
});
|
|
};
|
|
|
|
Game_Battler.prototype.armors = function() {
|
|
return this.equips().filter(function(item) {
|
|
return item && DataManager.isArmor(item);
|
|
});
|
|
};
|
|
|
|
/* Finds the first equip slot with the given equip type */
|
|
Game_Battler.prototype.getSlotByEtypeId = function(etypeId) {
|
|
var slots = this._equips;
|
|
for (var i = 0; i < slots.length; i++) {
|
|
if (slots[i].isEtypeId(etypeId)) {
|
|
return i;
|
|
}
|
|
}
|
|
};
|
|
|
|
/* Overwrite. */
|
|
Game_Battler.prototype.changeEquip = function(slotId, item) {
|
|
if (this.tradeItemWithParty(item, this.equips()[slotId]) &&
|
|
(!item || this.equipSlotList()[slotId].canEquip(item))) {
|
|
this._equips[slotId].setObject(item);
|
|
this.refresh();
|
|
}
|
|
};
|
|
|
|
/* Ovewrite. We need to find a slot. Assumes 1 is the weapon type */
|
|
Game_Battler.prototype.changeEquipById = function(etypeId, itemId) {
|
|
var slotId = this.getSlotByEtypeId(etypeId);
|
|
if (this.equipSlots()[slotId] === 1) {
|
|
this.changeEquip(slotId, $dataWeapons[itemId]);
|
|
} else {
|
|
this.changeEquip(slotId, $dataArmors[itemId]);
|
|
}
|
|
};
|
|
|
|
/* Adds a new equip slot to the actor */
|
|
Game_Battler.prototype.addEquipSlot = function(etypeId) {
|
|
var equipSlot = new Game_EquipSlot();
|
|
etypeId = $.getEtypeId(etypeId);
|
|
equipSlot.setEtypeId(etypeId);
|
|
this._equips.push(equipSlot);
|
|
};
|
|
|
|
/* Removes one instance of the specified equip slot. If an object
|
|
* exists in that slot, the object is un-equipped.
|
|
*/
|
|
Game_Battler.prototype.removeEquipSlot = function(etypeId) {
|
|
etypeId = $.getEtypeId(etypeId);
|
|
var slots = this._equips;
|
|
for (var i = 0; i < slots.length; i++) {
|
|
if (slots[i].isEtypeId(etypeId)) {
|
|
this.tradeItemWithParty(null, slots[i].object());
|
|
slots.splice(i, 1);
|
|
break;
|
|
}
|
|
};
|
|
};
|
|
|
|
/* Overwrite */
|
|
Game_Battler.prototype.releaseUnequippableItems = function(forcing) {
|
|
for (;;) {
|
|
var slots = this.equipSlotList();
|
|
var slotTypes = this.equipSlots();
|
|
var equips = this.equips();
|
|
var changed = false;
|
|
for (var i = 0; i < equips.length; i++) {
|
|
var item = equips[i];
|
|
if (item && (!this.canEquip(item) || !slots[i].canEquip(item))) {
|
|
if (!forcing) {
|
|
this.tradeItemWithParty(null, item);
|
|
}
|
|
this._equips[i].setObject(null);
|
|
changed = true;
|
|
}
|
|
}
|
|
if (!changed) {
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
/* Overwrite */
|
|
Game_Battler.prototype.bestEquipItem = function(slotId) {
|
|
var slot = this.equipSlotList()[slotId];
|
|
var etypeId = this.equipSlots()[slotId];
|
|
var items = $gameParty.equipItems().filter(function(item) {
|
|
return slot.canEquip(item) && this.canEquip(item);
|
|
}, this);
|
|
var bestItem = null;
|
|
var bestPerformance = -1000;
|
|
for (var i = 0; i < items.length; i++) {
|
|
var performance = this.calcEquipItemPerformance(items[i]);
|
|
if (performance > bestPerformance) {
|
|
bestPerformance = performance;
|
|
bestItem = items[i];
|
|
}
|
|
}
|
|
return bestItem;
|
|
};
|
|
|
|
/***************************************************************************/
|
|
|
|
/* Pulled up */
|
|
var TH_GameActor_equipSlots = Game_Actor.prototype.equipSlots;
|
|
Game_Actor.prototype.equipSlots = function() {
|
|
return Game_Battler.prototype.equipSlots.call(this);
|
|
};
|
|
|
|
/* Pulled up */
|
|
Game_Actor.prototype.equips = function() {
|
|
return Game_Battler.prototype.equips.call(this);
|
|
};
|
|
|
|
/* Pulled up */
|
|
Game_Actor.prototype.weapons = function() {
|
|
return Game_Battler.prototype.weapons.call(this);
|
|
};
|
|
|
|
/* Pulled up */
|
|
Game_Actor.prototype.armors = function() {
|
|
return Game_Battler.prototype.armors.call(this);
|
|
};
|
|
|
|
/* Pulled up */
|
|
var TH_GameActor_initEquips = Game_Actor.prototype.initEquips;
|
|
Game_Actor.prototype.initEquips = function(equips) {
|
|
Game_Battler.prototype.initEquips.call(this, equips);
|
|
};
|
|
|
|
/* Pulled up */
|
|
Game_Actor.prototype.changeEquipById = function(etypeId, itemId) {
|
|
Game_Battler.prototype.changeEquipById.call(this, etypeId, itemId);
|
|
};
|
|
|
|
/* Pulled up */
|
|
Game_Actor.prototype.changeEquip = function(slotId, item) {
|
|
Game_Battler.prototype.changeEquip.call(this, slotId, item);
|
|
};
|
|
|
|
/* Pulled up */
|
|
Game_Actor.prototype.releaseUnequippableItems = function(forcing) {
|
|
Game_Battler.prototype.releaseUnequippableItems.call(this, forcing);
|
|
};
|
|
|
|
/* Pulled up */
|
|
Game_Actor.prototype.bestEquipItem = function(slotId) {
|
|
return Game_Battler.prototype.bestEquipItem.call(this, slotId);
|
|
};
|
|
|
|
/* By default, we check the actor for any equip slots */
|
|
Game_Actor.prototype.baseSlots = function() {
|
|
var slots = Game_Battler.prototype.baseSlots.call(this);
|
|
return slots.concat(this.getBaseSlots(this.actor()))
|
|
};
|
|
|
|
/***************************************************************************/
|
|
|
|
/* Overwrite. Ask if the equip slot can hold the item */
|
|
Window_EquipItem.prototype.includes = function(item) {
|
|
if (item === null) {
|
|
return true;
|
|
}
|
|
if (this._slotId < 0 || !this._actor.equipSlotList()[this._slotId].canEquip(item)) {
|
|
return false;
|
|
}
|
|
return this._actor.canEquip(item);
|
|
};
|
|
|
|
/***************************************************************************/
|
|
|
|
})(TH.EquipSlotsCore); |