// doVerbAction.js
(function () {
/* global adventurejs A */
var p = adventurejs.Asset.prototype;
/**
* Check if this asset has a general verb action or reaction
* for the specified event, or if the asset has an action for
* the specific asset. If either form is found, pass it to
* getStringOrArrayOrFunction and return the results. If the
* result returns false or null it will terminate the calling
* verb's default behavior.
* <br><br>
* We look for actions in two forms:<br>
* <li>Function properties such as <code>asset.doThisToThat()</code>
* are called. If a function returns null or false, that effectively
* ends the turn.</li>
* <li>String properties such as <code>asset.do_this_to_that</code>
* override the turn's default output.</li>
* @memberOf adventurejs.Asset
* @method adventurejs.Asset#doVerbAction
* @param {string} action
* @param {string} asset2 We use asset.name here instead of asset.id
* in support of authors, because we're never asking them to deal in IDs,
* only names. Hooks will only be defined by authors, so we let them use
* asset.name as their identifier. We do however make an effort to see if
* an id has been passed instead of a name, because Ivan.
* @param {string} asset3
* @param {object} params Arbitrary parameter object.
* @return {Boolean}
*/
p.doVerbAction = function Asset_doVerbAction({
action,
asset2,
asset3,
params = {},
type = "Hook",
} = {}) {
// if we didn't receive an action, exit
if (!action) return;
if (asset3) {
this.game.log(
"L1459",
"log",
"high",
`[doVerbAction.js] ${this.id}.${action}(${asset2.id ? asset2.id : asset2}, ${asset3.id ? asset3.id : asset3})`,
type
);
this.game.debug(
`D1442 | ${type} | <span class="ajs-tryfound">TRY</span> <span class="ajs-actor">${this.id}</span>.<span class="ajs-action">${action}(</span><span class="ajs-target">"${asset2.name ? asset2.name : asset2}", "${asset3.name ? asset3.name : asset3}"</span><span class="ajs-action">)</span>`
);
} else if (asset2) {
this.game.log(
"L1456",
"log",
"high",
`[doVerbAction.js] ${this.id}.${action}(${asset2.id ? asset2.id : asset2})`,
type
);
this.game.debug(
`D1420 | ${type} | <span class="ajs-tryfound">TRY</span> <span class="ajs-actor">${this.id}</span>.<span class="ajs-action">${action}(</span><span class="ajs-target">"${asset2.name ? asset2.name : asset2}"</span><span class="ajs-action">)</span>`
);
} else {
this.game.log(
"L1476",
"log",
"high",
`[doVerbAction.js] ${this.id}.${action}()`,
type
);
this.game.debug(
`D1415 | ${type} | <span class="ajs-tryfound">TRY</span> <span class="ajs-actor">${this.id}</span>.<span class="ajs-action">${action}(</span><span class="ajs-target">${""}</span><span class="ajs-action">)</span>`
);
}
// in addition to checking for camel cased method properties,
// we also look for alternative snake cased string properties
const _action_ = A.camelToSnake(action);
// if this hasn't got function or string, exit
if (!this[action] && !this[_action_]) return;
const input = this.game.getInput();
if (asset2) {
// if an asset was passed, disregard assets retrieved from input
asset2 = asset2.class ? asset2 : this.game.getAsset(asset2);
if (asset3) {
asset3 = asset3.class ? asset3 : this.game.getAsset(asset3);
}
} else {
asset2 = input.getAsset(2);
asset3 = input.getAsset(3);
if (!asset2) asset2 = this.game.getPlayer();
}
let _a = this[action] ? action : _action_;
let _o = this[action] ? "(" : "[";
let _c = this[action] ? ")" : "]";
this.game.log(
"L1038",
"log",
"high",
`[doVerbAction.js] Asset.doVerbAction() FOUND ${this.id}.${_a}${_o}${asset2 ? asset2.id : ""}${asset2 && asset3 ? ", " : ""}${asset3 ? asset3.id : ""}${_c}`,
"VerbAction"
);
//→ ↳
this.game.debug(
`D1383 | ${type} | <span class="ajs-tryfound">↳ FOUND</span> <span class="ajs-actor">${this.id}</span>.<span class="ajs-action">${_a}${_o}</span><span class="ajs-target">${asset2 ? '"' + asset2.name + '"' : ""}${asset2 && asset3 ? ", " : ""}${asset3 ? '"' + asset3.name + '"' : ""}</span><span class="ajs-action">${_c}</span>`
);
// is there a method at this[action]?
if ("function" === typeof this[action]) {
return this[action].call(this, { asset2, asset3, params });
}
// if no method was found at this[action]
// is there an alt string at this[_action_]?
if (this[_action_]) {
// did author specify an output method?
if (
this[_action_].append ||
this[_action_].prepend ||
this[_action_].override
) {
let method = this[_action_].append
? "append"
: this[_action_].prepend
? "prepend"
: "override";
// console.warn(`this[_action_][method]`, this[_action_][method]);
input[`${method}Output`](
A.getSAF.call(this.game, this[_action_][method])
);
} else if (
"string" === typeof this[_action_] ||
Array.isArray(this[_action_]) ||
"function" === typeof this[_action_]
) {
input.overrideOutput(A.getSAF.call(this.game, this[_action_]));
}
} // this[_action_]
// is there a method at this[action][asset2]?
if (this[action] && "function" === typeof this[action][asset2.name]) {
return this[action][asset2.name].call(this, { asset2, asset3, params });
}
// if no method was found at this[action][asset2]
// is there an alt string at this[_action_][asset2]?
if (this[_action_] && asset2 && this[_action_][asset2.name]) {
if (
this[_action_][asset2.name].append ||
this[_action_][asset2.name].prepend ||
this[_action_][asset2.name].override
) {
let method = this[_action_][asset2.name].append
? "append"
: this[_action_][asset2.name].prepend
? "prepend"
: "override";
// console.warn(
// `this[_action_][asset2.name][method]`,
// this[_action_][asset2.name][method]
// );
input[`${method}Output`](
A.getSAF.call(this.game, this[_action_][asset2.name][method])
);
} else if (
"string" === typeof this[_action_][asset2.name] ||
Array.isArray(this[_action_][asset2.name]) ||
"function" === typeof this[_action_][asset2.name]
) {
input.overrideOutput(
A.getSAF.call(this.game, this[_action_][asset2.name])
);
return;
}
}
// is there a method at this[action][asset2][asset3]?
if (
this[action] &&
asset2 &&
this[action][asset2.name] &&
asset3 &&
"function" === typeof this[action][asset2.name][asset3.name]
) {
return this[action][asset2.name][asset3.name].call(this, {
asset2,
asset3,
params,
});
}
// if no method was found at this[action][asset2][asset3]
// is there an alt string at this[_action_][asset2][asset3]?
if (
this[_action_] &&
asset2 &&
this[_action_][asset2.name] &&
asset3 &&
this[_action_][asset2.name][asset3.name]
) {
if (
this[_action_][asset2.name][asset3.name].append ||
this[_action_][asset2.name][asset3.name].prepend ||
this[_action_][asset2.name][asset3.name].override
) {
let method = this[_action_][asset2.name][asset3.name].append
? "append"
: this[_action_][asset2.name][asset3.name].prepend
? "prepend"
: "override";
// console.warn(
// `this[_action_][asset2.name][asset3.name][method]`,
// this[_action_][asset2.name][asset3.name][method]
// );
input[`${method}Output`](
A.getSAF.call(
this.game,
this[_action_][asset2.name][asset3.name][method]
)
);
} else if (
"string" === typeof this[_action_][asset2.name][asset3.name] ||
Array.isArray(this[_action_][asset2.name][asset3.name]) ||
"function" === typeof this[_action_][asset2.name][asset3.name]
) {
input.overrideOutput(
A.getSAF.call(this.game, this[_action_][asset2.name][asset3.name])
);
return;
}
}
return;
};
})();