phaser4-rex-plugins
Version:
412 lines (338 loc) • 11.2 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.rexgashaponplugin = factory());
})(this, (function () { 'use strict';
var Clear = function (obj) {
if ((typeof (obj) !== 'object') || (obj === null)) {
return obj;
}
if (Array.isArray(obj)) {
obj.length = 0;
} else {
for (var key in obj) {
delete obj[key];
}
}
return obj;
};
/**
* Shallow Object Clone. Will not out nested objects.
* @param {object} obj JSON object
* @param {object} ret JSON object to return, set null to return a new object
* @returns {object} this object
*/
var Clone = function (obj, out) {
var objIsArray = Array.isArray(obj);
if (out === undefined) {
out = (objIsArray) ? [] : {};
} else {
Clear(out);
}
if (objIsArray) {
out.length = obj.length;
for (var i = 0, cnt = obj.length; i < cnt; i++) {
out[i] = obj[i];
}
} else {
for (var key in obj) {
out[key] = obj[key];
}
}
return out;
};
var IsEmpty = function (source) {
for (var k in source) {
return false;
}
return true;
};
const GetValue = Phaser.Utils.Objects.GetValue;
class Gashapon {
constructor(config) {
this.resetFromJSON(config);
}
destroy() {
this.items = undefined;
this.remainder = undefined;
this._list = undefined;
}
resetFromJSON(o) {
if (this.items == undefined) {
this.items = {};
}
if (this.remainder == undefined) {
this.remainder = {};
}
if (this._list == undefined) {
this._list = [];
}
this.setMode(GetValue(o, 'mode', 0));
this.setReload(GetValue(o, 'reload', true));
this.setRND(GetValue(o, 'rnd', undefined));
// data
this.items = Clone(GetValue(o, 'items', {}), this.items);
this._list.length = 0;
// result
this.result = GetValue(o, 'result', null);
// flags
this._restartFlag = true; // force restart to rebuild this._list
// initialize
if (this._restartFlag) {
this.startGen();
}
var remainder = GetValue(o, 'remainder', undefined);
if (remainder) {
this.remainder = Clone(remainder, this.remainder);
}
return this;
}
toJSON() {
return {
// configuration
mode: this.mode,
reload: this.reload,
rnd: this.rnd,
// data
items: Clone(this.items),
remainder: Clone(this.remainder),
// result
result: this.result,
// flags
restart: true // force restart to rebuild this._list
};
};
startGen() {
var name;
// clear remainder items
for (name in this.remainder) {
if (!this.items.hasOwnProperty(name)) {
delete this.remainder[name];
}
}
// init remainder items
for (name in this.items) {
var count = this.items[name];
if (count > 0) {
this.remainder[name] = count;
}
}
if (this.mode === 1) { // random mode
this.resetItemList(this.remainder);
}
this._restartFlag = false;
return this;
}
setMode(m) {
if (typeof (m) === 'string') {
m = MODE[m];
}
this._restartFlag = (this.mode !== m);
this.mode = m;
return this;
}
setReload(isReload) {
this.reload = !!isReload;
return this;
}
setRND(rnd) {
this.rnd = rnd;
return this;
}
setItem(name, count) {
this._restartFlag = (this.items[name] !== count);
this.items[name] = count;
return this;
}
removeItem(name) {
if (this.items.hasOwnProperty(name)) {
delete this.items[name];
this._restartFlag = true;
}
return this;
}
removeAllItems() {
for (var name in this.items) {
delete this.items[name];
}
this._restartFlag = true;
return this;
}
getItems() {
return Clone(this.items);
}
getRemain() {
return Clone(this.remainder);
}
getItemCount(name) {
return this.items[name] || 0;
}
getRemainCount(name) {
return this.remainder[name] || 0;
}
forEachItem(callback, scope) {
var args = [null, undefined];
for (var i = 2, len = arguments.length; i < len; i++) {
args.push(arguments[i]);
}
for (var name in this.items) {
args[0] = name;
args[1] = this.items[name];
if (scope) {
callback.apply(scope, args);
} else {
callback(args);
}
}
return this;
}
forEachRemain(callback, scope) {
var args = [null, undefined];
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
for (var name in this.remainder) {
args[1] = name;
args[2] = this.remainder[name];
if (scope) {
callback.apply(scope, args);
} else {
callback(args);
}
}
return this;
}
addItem(name, count) {
if (!this.items.hasOwnProperty(name)) {
this.items[name] = 0;
}
this.items[name] += count;
if (this._restartFlag)
return;
if (this.mode === 0) { // shuffle mode
this.addRemainItem(name, count);
} else { // random mode
this.resetItemList(this.remainder);
}
return this;
}
putItemBack(name, count) {
if (this.mode === 1) // random mode
return;
if (!this.items.hasOwnProperty(name)) {
return;
}
if ((this.mode === 2) && this.restartGenFlg) {
return;
}
// generator had started
if (!this.remainder.hasOwnProperty(name)) {
this.remainder[name] = 0;
}
this.addShadowPattern(name, count, this.items[name]);
return this;
};
next(name) {
var result = null;
if (this._restartFlag) {
this.startGen();
}
if (name == null) {
if (this.mode === 0) { // shuffle mode
this.resetItemList(this.remainder);
result = this.getRndItem(this._list);
this.addRemainItem(result, -1);
} else { // random mode
result = this.getRndItem(this._list);
}
} else { // force pick
if (!this.remainder.hasOwnProperty(name)) {
result = null; // can not pick that result
} else {
if (this.mode === 0) {
this.addRemainItem(name, -1);
}
result = name;
}
}
this.result = result;
return result;
}
/** @private */
resetItemList(items) {
// clear list
this._list.length = 0;
var name, count, totalCount = 0;
// get total count
for (name in items) {
count = items[name];
if (count > 0)
totalCount += count;
}
// set percentage
for (name in items) {
count = items[name];
if (count > 0) {
this._list.push([
name,
count / totalCount
]);
}
}
return this;
}
/** @private */
addRemainItem(name, inc, maxCount) {
if ((name == null) || (inc === 0)) {
return this;
}
if (!this.remainder.hasOwnProperty(name)) {
this.remainder[name] = 0;
}
this.remainder[name] += inc;
if ((maxCount != null) && (this.remainder[name] > maxCount)) {
this.remainder[name] = maxCount;
}
if (this.remainder[name] <= 0) {
delete this.remainder[name];
}
if ((this.mode === 0) && this.reload && IsEmpty(this.remainder)) {
this._restartFlag = true;
}
return this;
}
/** @private */
getRndItem(list) {
var value = (this.rnd) ? this.rnd.frac() : Math.random();
var result = null,
i, cnt = list.length,
item;
for (i = 0; i < cnt; i++) {
item = list[i];
value -= item[1];
if (value < 0) {
result = item[0];
break;
}
}
return result;
}
}
const MODE = {
shuffle: 0,
random: 1
};
class GashaponPlugin extends Phaser.Plugins.BasePlugin {
constructor(pluginManager) {
super(pluginManager);
}
start() {
var eventEmitter = this.game.events;
eventEmitter.on('destroy', this.destroy, this);
}
add(config) {
return new Gashapon(config);
}
}
return GashaponPlugin;
}));