//= ============================================================================
// EventWrapper.js
//= ============================================================================
/*:
* @plugindesc A simple wrapper for creating and handling events in your plugins. Press Help to see usage info.
* @author Alphaxaon
*
* @help // Create a new event
* var event = new MapEvent();
*
* // Copy actions from another event with the specified id
* event.copyActionsFromEvent(1);
*
* // Copy actions from another event that exists on the map with the specified id
* event.copyActionsFromEventOnMap(1, 4);
*
* // Copy actions from a Common Event with the specified id
* event.copyActionsFromCommonEvent(1);
*
* // Spawn the event at the specified coordinates
* event.spawn(11, 7);
*/
MATTIE.eventAPI = MATTIE.eventAPI || {};
/** @description an array storing all active map events */
MATTIE.eventAPI.dataEvents = MATTIE.eventAPI.dataEvents || {};
let val = 999;
class MapEvent {
/**
* The constructor for a new map event.
*/
constructor() {
const id = this.setId();
this.data = {
id,
name: `EV${id.padZero(3)}`,
note: '',
pages: [],
x: 0,
y: 0,
meta: {},
mapId: $gameMap.mapId(),
persist: false,
};
this.addPage();
}
/**
* Automatically set the id for the event.
*/
setId() {
val++;
if ($dataMap) {
if ($dataMap.events) {
let openIndex = $dataMap.events.length + Object.keys(MATTIE.eventAPI.dataEvents).length - 2;
do {
openIndex++;
} while ($gameMap.event(openIndex));
val = openIndex;
}
}
return val;
}
setPersist(bool) {
this.data.persist = bool;
}
/**
* Add a new page for the event's actions.
*/
addPage() {
this.data.pages.push(this.setDefaultPage());
}
/**
*
* @returns the default page objectt
*/
setDefaultPage() {
return {
conditions: this.setDefaultConditions(),
directionFix: true,
image: MapEvent.setDefaultImage(),
list: [],
moveFrequency: 3,
moveRoute: this.setDefaultMoveRoute(),
moveSpeed: 3,
moveType: 0,
priorityType: 0,
stepAnime: true, // this makes most things animate
through: false,
trigger: 0,
walkAnime: true,
};
}
/**
* @description add text command to page
* @param {*} pageId
* @param {*} text
*/
addText(pageId, text) {
this.addCommand(pageId, 101, ['', 0, 0, 2]);
this.addCommand(pageId, 401, [text]);
}
/**
* @description add text command to page with a speaker
* @param {*} pageId
* @param {*} text
*/
addSpokenText(pageId, text, speaker) {
this.addCommand(pageId, 101, ['', 0, 0, 2]);
this.addCommand(pageId, 401, [MATTIE.msgAPI.formatMsgAndTitle(speaker, text)]);
}
/**
* @description add the move route command to a page
* @param {*} pageId the id of the page to add the command to
* @param {*} route the id of the action
*/
addMoveRoute(pageId, moveCode, wait) {
this.addCommand(pageId, 205, [0, { list: [{ code: moveCode, indent: null }, { code: 0 }], wait }]);
}
/**
*
* @param {*} pageId the page Id to add the command to
* @param {*} tint the tint object
* @param {*} frames who many frames to tint for
*/
addTintScreen(pageId, tint, frames, wait) {
console.log([tint, frames, wait]);
this.addCommand(pageId, 223, [tint, frames, wait]);
}
/**
* Set the default event conditions for a page of actions.
*/
setDefaultConditions() {
return {
actorId: 1,
actorValid: false,
itemId: 1,
itemValid: false,
selfSwitchCh: 'A',
selfSwitchValid: false,
switch1Id: 1,
switch1Valid: false,
switch2Id: 1,
switch2Valid: false,
switch3Id: 1,
switch3Valid: false,
switch4Id: 1,
switch4Valid: false,
variableValue: 0,
};
}
/**
* @description add a wait command to a page
* @param {*} pageId the page id to add the command to
* @param {*} frames the number of frames to wait
*/
addWait(pageId, frames) {
this.addCommand(pageId, 230, [frames]);
}
/**
* Set the default event image for a page of actions.
*/
static setDefaultImage() {
return this.generateImage(0, '', 2, 0, 0);
}
/**
*
* @param {*} index the index of the char, 3 cols per index
* @param {*} name the name of the char sheet to use
* @param {*} dir the dir they are facing, 2,4,6,8
* @param {*} pattern
* @param {*} tile tile id not sure
* @returns obj
*/
static generateImage(index, name, dir, pattern, tile) {
return {
characterIndex: index,
characterName: name,
direction: dir,
pattern,
tileId: tile,
};
}
/**
* @description change the image of a page
* @param {*} pageId
* @param {*} imageObj
*/
setImage(pageId, imageObj) {
this.data.pages[pageId].image = imageObj;
}
/**
* @description change the charecter of a page
* @param {*} pageId
* @param {string} name string
*/
setChar(pageId, name) {
this.data.pages[pageId].image.characterName = name;
}
/**
*
* @param {*} pageId
* @param {*} command
* @param {*} parameters
*/
addCommand(pageId, command, parameters, indent = 0) {
this.data.pages[pageId].list.push(this.createCommand(command, parameters, indent));
}
/**
* @description create a command obj from these params
* @param {*} command the command code
* @param {*} parameters array of params
* @param {*} indent optional
* @returns {rm.types.Event}
*/
createCommand(command, parameters, indent = 0) {
const cmd = {};
cmd.code = command;
cmd.parameters = parameters;
cmd.indent = indent;
cmd.eventId = this.data.id;
return cmd;
}
/**
* Set the default move route for a page of actions.
*/
setDefaultMoveRoute() {
return {
list: [
{
code: 0,
parameters: [],
},
],
repeat: true,
skippable: false,
wait: false,
};
}
/**
* Set the name of the event.
*
* @param name (string)
*/
setName(name) {
this.data.name = name;
}
/**
* Set the note of the event.
*
* @param note (string)
*/
setNote(note) {
this.data.note = note;
}
/**
* Set the map coordinates of the event.
*
* @param x (int)
* @param y (int)
*/
setPosition(x, y) {
this.data.x = x;
this.data.y = y;
}
/**
* Get the last Event object stored in $dataMap.
*/
getLastEvent() {
return $dataMap.events[$dataMap.events.length - 1];
}
/**
* Create a new Game_Event object and store it in $gameMap.
*/
createGameEvent() {
$dataMap.events[this.data.id] = this.data;
$gameMap._events[this.data.id] = (new Game_Event($gameMap.mapId(), this.data.id));
return $gameMap.event(this.data.id);
}
/**
* Create a new Sprite_Character and store it in the current scene's Spriteset_Map.
*
* @param event (Game_Event)
* @returns the event or an empty event if something went wrong
*/
createCharacterSprite(event) {
console.log('rendering event as sprite:');
console.log(event);
try {
SceneManager._scene._spriteset._characterSprites.push(new Sprite_Character(event));
return SceneManager._scene._spriteset._characterSprites[SceneManager._scene._spriteset._characterSprites.length - 1];
} catch (error) {
console.error(`${error}An error occured in rendering a runtime sprite`);
return new Sprite_Character();
}
}
/**
* Add a sprite to the current scene's Tilemap.
*
* @param sprite (Sprite_Character)
*/
addSpriteToTilemap(sprite) {
if (this.oldSprite) {
SceneManager._scene._spriteset._tilemap.removeChild(sprite);
}
SceneManager._scene._spriteset._tilemap.addChild(sprite);
this.oldSprite = sprite;
}
removeSpriteFromTilemap() {
if (this.oldSprite) {
SceneManager._scene._spriteset._tilemap.removeChild(sprite);
}
}
/**
* Copy actions from another event on the same map with the specified id.
*
* @param id (int)
*/
copyActionsFromEvent(id) {
this.data.pages = $dataMap.events[id].pages;
}
/**
* Copy actions from another event on map with the specified id.
*
* @param id (int)
* @param mapId (int)
* @returns self for cmd chaining
*/
copyActionsFromEventOnMap(id, mapId) {
const url = 'data/Map%1.json'.format(mapId.padZero(3));
const xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.overrideMimeType('application/json');
xhr.onload = function () {
if (xhr.status < 400) {
const mapData = JSON.parse(xhr.responseText);
if (!(id in mapData.events)) {
console.error('Error getting event data. Check to make sure an event with that specific id exists on the map.');
} else {
this.data.pages = mapData.events[id].pages;
}
}
}.bind(this);
xhr.onerror = function () {
console.error('Error getting map data. Check to make sure a map with that specific id exists.');
};
xhr.send();
return this;
}
/**
* Copy actions from a Common Event with the specified id.
*
* @param id (int)
*/
copyActionsFromCommonEvent(id) {
this.data.pages = [];
this.addPage();
this.data.pages[0].list = $dataCommonEvents[id].list;
}
/**
* Place the event on the map at the specified coordinates.
*
* @param x (int)
* @param y (int)
*/
spawn(x, y) {
MATTIE.eventAPI.dataEvents[this.data.id] = this;
if (this.data.mapId === $gameMap.mapId()) {
this.setPosition(x, y);
this.refresh();
console.log('New event created!');
}
}
removeThisEvent() {
if (this.data.mapId === $gameMap.mapId()) {
$gameMap._events[this.data.id] = null;
$dataMap.events[this.data.id] = null;
}
MATTIE.eventAPI.dataEvents[this.data.id] = undefined;
delete MATTIE.eventAPI.dataEvents[this.data.id];
}
refresh() {
try {
const event = this.createGameEvent();
const sprite = this.createCharacterSprite(event);
this.addSpriteToTilemap(sprite);
console.log('sprite created:');
console.log(sprite);
} catch (error) {
console.error(error);
}
}
/**
* @description return an array of all command codes on page
* @param {*} page page index
*/
getListOfCommandCodesOnPage(page) {
return this.data.pages[page].list.map((cmd) => cmd.code);
}
/**
* @description returns the index of the first occurence of the command code on the page
* @param {*} commandCode command code
* @param {*} page page index
*/
indexOfCommandOnPage(page, commandCode) {
const list = this.getListOfCommandCodesOnPage(page);
return list.indexOf(commandCode);
}
/**
* @description add
* @param {*} index the index in the list of commands to add this command after
* @param {*} command the command obj to add
* @param {int} pageIndex the page index of the page to add the command to
*/
addCommandAfterIndex(pageIndex, index, command) {
const page = this.data.pages[pageIndex];
const secondHalf = page.list.slice(index + 1);
page.list = page.list.slice(0, index + 1);
page.list.push(command);
page.list = page.list.concat(secondHalf);
this.data.pages[pageIndex] = page;
}
/**
* @description check a self switch of this event
* @param {*} letter the letter of the self switch
* @returns {boolean} whether the switch is true or false
*/
checkSelfSwitch(letter) {
return $gameSelfSwitches.value($gameSelfSwitches.formatKey(this.data.mapId, this.data.id, letter));
}
}
(function () {
// override the function that triggers when the scene map is fully loaded
MATTIE.eventAPI.cleanup = function () {
if (!$dataMap) return;
// Get all existing event ids
const eventIds = [];
const persistingIds = [];
const eventsForDeletion = [];
const keys = Object.keys(MATTIE.eventAPI.dataEvents);
for (let index = 0; index < keys.length; index++) {
const key = keys[index];
const event = MATTIE.eventAPI.dataEvents[key];
console.log(event);
console.log(`map = ${$gameMap.mapId()}`);
if (event) {
if (event.data.mapId == $gameMap.mapId()) {
console.log('event on map');
if (!event.data.persist) {
eventIds.push(event.data.id);
eventsForDeletion.push(event);
}
}
if (event.data.persist) {
persistingIds.push(event.data.id);
}
}
}
console.log('persisding ids');
console.log(persistingIds);
$dataMap.events.forEach((object) => {
// if (object === null) { return; }
// eventIds.push(object.id);
});
// Clear self switches for non-existing events
for (const key in $gameSelfSwitches._data) {
if (key) {
const ids = key.split(',');
const mapId = Number(ids[0]);
const eventId = Number(ids[1]);
// this line is someone else's code IDK IDC enough to fix it /shrug
// eslint-disable-next-line no-continue
if (mapId != $gameMap._mapId) { continue; }
if (eventIds.contains(eventId) && !persistingIds.contains(eventId)) {
delete $gameSelfSwitches._data[key];
console.log(`cleaned up switch:${key} from event: ${eventId}`);
}
}
}
// remove all events qued for deletion
// eventsForDeletion.forEach((evd) => {
// evd.removeThisEvent();
// });
};
}());