diff --git a/src/events/001-base/baseEvent.js b/src/events/001-base/baseEvent.js new file mode 100644 index 0000000000000000000000000000000000000000..8fe3d9f7c03eba76c013c2cfee78153af989845f --- /dev/null +++ b/src/events/001-base/baseEvent.js @@ -0,0 +1,110 @@ +/** base class for class-based events */ +App.Events.BaseEvent = class BaseEvent { + /** build a new event + * parameters are necessary for serialization (so that saving with the event active will work correctly) and should not normally be used directly + * child classes should forward to this implementation */ + constructor(actors, params) { + /** @member {Array<number>} actors - a list of IDs for the actors participating in this event. */ + this.actors = actors || []; + /** @member {object} params - a set of parameters to pass to the event. */ + this.params = params || {}; + } + + /** generate an array of zero or more predicates which must all be true in order for the event to be valid. + * lambda predicates may add properties to {@link App.Events.BaseEvent#params the params member} in order to pass information on to the event. + * child classes should implement this. + * @returns {Array<Function>} + */ + eventPrerequisites() { + return []; + } + + /** generate an array of zero or more arrays, each corresponding to an actor in the event, which contain zero or more predicates which must be satisfied by the actor. + * child classes should implement this. + * @returns {Array<Array<Function>>} + */ + actorPrerequisites() { + return []; + } + + /** get the choice weight for the event. Weights should be integral; higher weight means higher probability of selection. + * @returns {number} + */ + get weight() { + return 1; + } + + /** run the event and attach DOM output to the event passage. + * child classes must implement this. + * @param {DocumentFragment} node - Document fragment which event output should be attached to + */ + execute(node) { + } + + /** clone the event (needed for serialization). + * default implementation should suffice for child classes */ + clone() { + let c = {}; + Reflect.setPrototypeOf(c, Reflect.getPrototypeOf(this)); + deepAssign(c, this); + return c; + } + + /** serialize the event instance so it persists through saves. + * default implementation should suffice for child classes assigned to App.Events */ + toJSON() { + return JSON.reviveWrapper(`new App.Events.${this.constructor.name}(${JSON.stringify(this.actors)},${JSON.stringify(this.params)})`); + } + + /** build the actual list of actors that will be involved in this event. + * default implementation should suffice for child classes with a fixed number of actors; may be overridden for events with variable actor count. + * @param {App.Entity.SlaveState} firstActor - if non-null, the first actor should be this slave (fail if she is not qualified) + * @returns {boolean} - return false if sufficient qualified actors could not be found (cancel the event) + */ + castActors(firstActor) { + const prereqs = this.actorPrerequisites(); + + let i = 0; + if (firstActor && prereqs.length > 0) { + if (prereqs[0].every(p => p(firstActor))) { + this.actors.push(firstActor.ID); + } else { + return false; // preselected first actor was not qualified + } + i = 1; // first actor is cast + } + + for (; i < prereqs.length; ++i) { + const qualified = V.slaves.filter(s => !this.actors.includes(s.ID) && prereqs[i].every(p => p(s))); + if (qualified.empty) { + return false; // a required actor was not found + } + this.actors.push(qualified.pluck().ID); + } + + return true; // all actors cast + } +}; + +/** This is a trivial event for use as an example. */ +App.Events.TestEvent = class TestEvent extends App.Events.BaseEvent { + constructor(actors, params) { + super(actors, params); + } + + eventPrerequisites() { + return []; + } + + actorPrerequisites() { + return [ + [] // one actor, no requirements + ]; + } + + execute(node) { + let [eventSlave] = this.actors.map(a => getSlave(a)); // mapped deconstruction of actors into local slave variables + App.Events.drawEventArt(node, eventSlave); + node.appendChild(document.createTextNode(`This test event for ${eventSlave.slaveName} was successful.`)); + } +}; diff --git a/src/events/randomEvent.js b/src/events/randomEvent.js index 4c77029de340a0d29e4f0e7079ec6dca13c8f7f7..84ad32ee14c58289a30d74c1a09dadb81befbbfe 100644 --- a/src/events/randomEvent.js +++ b/src/events/randomEvent.js @@ -1,114 +1,3 @@ -/** base class for class-based events */ -App.Events.BaseEvent = class BaseEvent { - /** build a new event - * parameters are necessary for serialization (so that saving with the event active will work correctly) and should not normally be used directly - * child classes should forward to this implementation */ - constructor(actors, params) { - /** @member {Array<number>} actors - a list of IDs for the actors participating in this event. */ - this.actors = actors || []; - /** @member {object} params - a set of parameters to pass to the event. */ - this.params = params || {}; - } - - /** generate an array of zero or more predicates which must all be true in order for the event to be valid. - * lambda predicates may add properties to {@link App.Events.BaseEvent#params the params member} in order to pass information on to the event. - * child classes should implement this. - * @returns {Array<Function>} - */ - eventPrerequisites() { - return []; - } - - /** generate an array of zero or more arrays, each corresponding to an actor in the event, which contain zero or more predicates which must be satisfied by the actor. - * child classes should implement this. - * @returns {Array<Array<Function>>} - */ - actorPrerequisites() { - return []; - } - - /** get the choice weight for the event. Weights should be integral; higher weight means higher probability of selection. - * @returns {number} - */ - get weight() { - return 1; - } - - /** run the event and attach DOM output to the event passage. - * child classes must implement this. - * @param {DocumentFragment} node - Document fragment which event output should be attached to - */ - execute(node) { - } - - /** clone the event (needed for serialization). - * default implementation should suffice for child classes */ - clone() { - let c = {}; - Reflect.setPrototypeOf(c, Reflect.getPrototypeOf(this)); - deepAssign(c, this); - return c; - } - - /** serialize the event instance so it persists through saves. - * default implementation should suffice for child classes assigned to App.Events */ - toJSON() { - return JSON.reviveWrapper(`new App.Events.${this.constructor.name}(${JSON.stringify(this.actors)},${JSON.stringify(this.params)})`); - } - - /** build the actual list of actors that will be involved in this event. - * default implementation should suffice for child classes with a fixed number of actors; may be overridden for events with variable actor count. - * @param {App.Entity.SlaveState} firstActor - if non-null, the first actor should be this slave (fail if she is not qualified) - * @returns {boolean} - return false if sufficient qualified actors could not be found (cancel the event) - */ - castActors(firstActor) { - const prereqs = this.actorPrerequisites(); - - let i = 0; - if (firstActor && prereqs.length > 0) { - if (prereqs[0].every(p => p(firstActor))) { - this.actors.push(firstActor.ID); - } else { - return false; // preselected first actor was not qualified - } - i = 1; // first actor is cast - } - - for (; i < prereqs.length; ++i) { - const qualified = V.slaves.filter(s => !this.actors.includes(s.ID) && prereqs[i].every(p => p(s))); - if (qualified.empty) { - return false; // a required actor was not found - } - this.actors.push(qualified.pluck().ID); - } - - return true; // all actors cast - } -}; - -/** This is a trivial event for use as an example. */ -App.Events.TestEvent = class TestEvent extends App.Events.BaseEvent { - constructor(actors, params) { - super(actors, params); - } - - eventPrerequisites() { - return []; - } - - actorPrerequisites() { - return [ - [] // one actor, no requirements - ]; - } - - execute(node) { - let [eventSlave] = this.actors.map(a => getSlave(a)); // mapped deconstruction of actors into local slave variables - App.Events.drawEventArt(node, eventSlave); - node.appendChild(document.createTextNode(`This test event for ${eventSlave.slaveName} was successful.`)); - } -}; - /* Note that we use a much more strict delineation between individual and nonindividual events here than in the old event system. * Individual events always trigger for the chosen event slave, and the first actor is always the event slave. * Nonindividual events are not provided any event slave and should cast one themselves.