// Drainable.js
(function () {
/*global adventurejs A*/
"use strict";
/**
* @ajspath adventurejs.Atom.Asset.Matter.Tangible.Thing.Container.LiquidContainer.Drainable
* @augments adventurejs.LiquidContainer
* @class adventurejs.Drainable
* @ajsconstruct MyGame.createAsset({ "class":"Drainable", "name":"foo", [...] })
* @ajsconstructedby adventurejs.Game#createAsset
* @ajsnavheading MiscAssetClasses
* @param {String} game_name The name of the top level game object.
* @param {String} name A name for the object, to be serialized and used as ID.
* @ajsparts Faucet, GraduatedController, Drain, Plug
* @summary Ancestor class for Sinks and Bathtubs.
* @ajssubstancecontainer in
* @ajstangiblecontainer in
* @ajstangiblecontainer attached
* @classdesc
* <p>
* <strong>Drainable</strong> is a subsclass of
* {@link adventurejs.Container|Container} /
* {@link adventurejs.LiquidContainer|LiquidContainer},
* and the ancestor class for
* {@link adventurejs.Sink|Sink} and
* {@link adventurejs.Bathtub|Bathtub} and other basins.
* You wouldn't construct a Drainable directly, but you can
* subclass it to create new types of Drainables.
* </p>
* <p>
* Drainables can be easily linked with
* {@link adventurejs.Faucet|Faucets},
* {@link adventurejs.Handle|Handles},
* {@link adventurejs.Drain|Drains} and
* {@link adventurejs.Plug|Plugs}
* through the use of the
* <code class="property">{@link adventurejs.Tangible#parts|parts}</code>
* property,
* a special convenience property that can be used to link some
* {@link adventurejs.Asset|Asset} classes to other Asset classes.
* To learn more about which classes can be linked with
* <code class="property">parts</code>, see <a href="/doc/Tangibles_LinkedAssets.html">Linked Assets</a>.
* </p>
**/
class Drainable extends adventurejs.LiquidContainer {
constructor(name, game_name) {
super(name, game_name);
this.class = "Drainable";
this.noun = "drainable";
this.plural = "drainables";
this.singlePluralPairs = [["drainable", "drainables"]];
this.is = new adventurejs.Drainable_Is("is", this.game_name, this.id).set(
{
parent_id: this.id,
}
);
this.unsetDOVs(["take", "give", "put"]);
this.setDOVs(["fill", "empty", "turn", "drink", "pour"]);
this.default_aspect = "in";
this.aspects.attached = new adventurejs.Aspect(
"attached",
this.game_name
).set({
parent_id: this.id,
list_in_examine: false,
list_in_room: false,
player_can_add_assets_to_contents: false,
player_can_remove_assets_from_contents: false,
});
this.registerableClasses = {
Faucet: function (object) {
this.registered_parts.Faucet = object.id;
// this faucet = faucet
// faucet sink = this
// what else does a sink need to know about a faucet?
// faucet is attached to sink
object.setPlace("attached", this.id);
object.aspects.in.vessel.target_id = this.id;
},
GraduatedController: function (object) {
// this faucets push faucet
// can have multiple handles
// faucet sink = this
// where do we ask about multiple inputs mixing?
// is each handle worth a fraction of max_volume_of_flow_per_turn?
if (
"undefined" === typeof this.registered_parts.GraduatedControllers
) {
this.registered_parts.GraduatedControllers = [];
}
this.registered_parts.GraduatedControllers.push(object.id);
// handles are attached to sink... but don't need to be? shower handles/
object.control_target_id = this.id;
object.setPlace("attached", this.id);
},
Drain: function (object) {
this.registered_parts.Drain = object.id;
// this drain = drain
// drain sink = this
// what else does a sink need to know about a drain?
// drain is attached to sink
object.setPlace("attached", this.id);
},
Plug: function (object) {
// this plugs push plug // can have multiple plugs
if ("undefined" === typeof this.registered_parts.Plugs) {
this.registered_parts.Plugs = [];
}
this.registered_parts.Plugs.push(object.id);
},
};
this.linkRegisteredParts = function Drainable_linkRegisteredParts() {
var drain;
// link handles to faucet
if (
"undefined" !== typeof this.registered_parts.Faucet &&
"undefined" !== typeof this.registered_parts.GraduatedControllers
) {
var faucet = this.game.getAsset(this.registered_parts.Faucet);
if (
"undefined" === typeof faucet.registered_parts.GraduatedControllers
) {
faucet.registered_parts.GraduatedControllers = [];
}
this.registered_parts.GraduatedControllers.forEach(function (id) {
this.game.getAsset(id).control_target_id =
this.registered_parts.Faucet;
faucet.registered_parts.GraduatedControllers.push(id);
}, this);
}
// link drain to sink
if ("undefined" !== typeof this.registered_parts.Drain) {
drain = this.game.getAsset(this.registered_parts.Drain);
this.aspects.in.vessel.drain_id = drain.id;
} else {
drain = this;
}
// link plugs to drain
if ("undefined" !== typeof this.registered_parts.Plugs) {
//console.warn('drain',drain);
this.registered_parts.Plugs.forEach(function (id) {
var plug = this.game.getAsset(id);
//console.warn('Drainable linkRegisteredParts plug',plug);
// plug sink with plug
// need to add verb connections
drain.DOVsetWithAsset("plug", plug);
// drain is direct object, should have plug as indirect connection
// plug is indirect object, should have drain as direct connection
plug.IOVsetWithAsset("plug", drain);
// @TODO PLUGCHECK
}, this);
}
}; // linkRegisteredParts
this.dov.turn.doAfterTry = function (params) {
var input = this.game.getInput();
var direct_object = input.getAsset(1);
var direct_preposition = input.getPreposition(1);
// sentence structure: verb preposition noun
if (input.hasStructure("verb preposition noun")) {
if (direct_preposition === "on") return this.turnOn_doAfterTry();
if (direct_preposition === "off") return this.turnOff_doAfterTry();
} // verb preposition noun
};
this.turnOn_doAfterTry = function (params) {
var input = this.game.getInput();
var direct_object = input.getAsset(1);
var msg = "";
// nothing with which to turn the faucet on
if (
"undefined" ===
typeof direct_object.registered_parts.GraduatedControllers ||
0 === direct_object.registered_parts.GraduatedControllers.length
) {
this.game.debug(
`F1847 | Drainable.js | ${direct_object.id} has no GraduatedControllers `
);
msg += `$(We) can't turn on ${direct_object.articlename}. `;
this.game.dictionary.verbs[params.verb].handleFailure(msg);
return null;
}
// else if( 1 === direct_object.registered_parts.GraduatedControllers.length )
else {
var controllers = direct_object.registered_parts.GraduatedControllers;
var controller_count = controllers.length;
var rand = Math.floor(Math.random() * controller_count);
var controller = this.game.getAsset(controllers[rand]);
input.setAsset(1, controller);
input.allow_circular_verb = true;
this.game.dictionary.doVerb("turn");
return null;
}
};
this.turnOff_doAfterTry = function (params) {
var input = this.game.getInput();
var direct_object = input.getAsset(1);
// nothing with which to turn the faucet off
if (
"undefined" ===
typeof direct_object.registered_parts.GraduatedControllers
) {
this.game.debug(
`F1846 | Drainable.js | ${direct_object.id} has no GraduatedControllers `
);
msg += `$(We) can't turn off ${direct_object.articlename}. `;
this.game.dictionary.verbs[params.verb].handleFailure(msg);
return null;
}
var controllers = direct_object.registered_parts.GraduatedControllers;
var controller_count = controllers.length;
var controllers_to_turn_off_count = 0;
for (var c = 0; c < controller_count; c++) {
var controller = this.game.getAsset(controllers[c]);
if (0 < controller.current_position) {
controllers_to_turn_off_count++;
input.setAsset(1, controller);
input.allow_circular_verb = true;
this.game.dictionary.doVerb("turn");
}
}
if (0 === controllers_to_turn_off_count) {
var msg = direct_object.Articlename + " isn't on. ";
this.game.dictionary.verbs[params.verb].handleFailure(msg);
}
return null;
};
}
}
adventurejs.Drainable = Drainable;
})();