// Substance.js
(function () {
/*global adventurejs A*/
"use strict";
/**
* @ajspath adventurejs.Atom.Asset.Matter.Substance
* @augments adventurejs.Matter
* @class adventurejs.Substance
* @ajsconstruct MyGame.createAsset({ "class":"Substance", "name":"foo", [...] })
* @ajsconstructedby adventurejs.Game#createAsset
* @ajsnavheading BaseClasses
* @param {String} game_name Name of top level game instance that is scoped to window.
* @param {String} name Instance name.
* @summary Solids, Liquids, Slurries, and Gasses, baby.
* @tutorial Substances_AboutSubstances
* @todo How is gas volume measured? Is it something other than ml?
* @todo State conversion
* @todo Slurries
* @todo is_edible / is_potable
* @classdesc
* <p>
* <strong>Substance</strong> is a low-level subclass of
* {@link adventurejs.Asset|Asset}, and the base class for
* all
* {@link adventurejs.Solid|Solids},
* {@link adventurejs.Liquid|Liquids},
* {@link adventurejs.Slurry|Slurries}, and
* {@link adventurejs.Gas|Gasses}.
* Substance is one of the pillars of the
* {@link adventurejs.Game|Game} world,
* along with
* {@link adventurejs.Tangible|Tangibles} and
* {@link adventurejs.Intangible|Intangibles}.
* Substances fall somewhere between Tangibles and
* Intangibles. Instances of Substances are quasi-global;
* as with Intangibles,
* player can refer to Substances regardless of their
* physical availability, and be understood by the parser.
* Yet, as with Tangibles, Substances exist in the physical
* world. Substances have no physical aspect of their own,
* but are defined by the Vessels that contain them.
* A <strong>glass</strong> of water. A <strong>pile</strong>
* of dirt. A <strong>cylinder</strong> of gas.
* Technically, Substances are infinite. For example,
* an instance of Water represents all Water,
* everywhere in the Game, whether it's in a glass or a lake.
* Substances can be added and divided;
* Vessels can be emptied and filled.
* </p>
* <h3 class="examples">Example:</h3>
* <p>
* Rather than subclassing Substance directly, authors should
* use Solid, Liquid, Gas, or Slurry.
* </p>
* <pre class="display"><code class="language-javascript">MyGame.createAsset({
* class: "Slurry",
* name: "frogurt",
* description: "The frogurt is full of vitamins and minerals.
* That's good. The frogurt is also cursed. That's bad. ",
* });
* </code></pre>
**/
class Substance extends adventurejs.Matter {
constructor(name, game_name) {
super(name, game_name);
this.class = "Substance";
this.is = new adventurejs.Substance_Is("is", this.game_name, this.id).set(
{
parent_id: this.id,
}
);
this.setIOV({ throw: { with_nothing: true } });
this.setIOV({ flick: { with_nothing: true } });
this.setDOV({ throw: { with_nothing: true } });
this.setDOV({ flick: { with_anything: true } });
this.can = this.can || {};
this.can.be_poured_into = false;
this.mixwith = {};
this.melting_temperature = 0; // water // TODO lookup table
this.boiling_temperature = 100; // water // TODO lookup table
// Specific heat capacity is a measure of the amount of heat necessary
// to raise the temperature of one gram of a pure substance by one degree K.
this.specific_heat = 4.2; // water = 4186, commonly(?) rounded to 4.2Kj or 4200j
// TODO lookup table
// specific heats of common liquids and substances:
// https://www.engineeringtoolbox.com/specific-heat-fluids-d_151.html
// https://www.engineeringtoolbox.com/specific-heat-capacity-d_391.html
// Heat Capacity is the amount of heat required to increase the temperature
// of a mass of substance by one degree K.
this.heat_capacity = 4.2;
// TODO this should calculate specific_heat * mass
// ( which is volume * grams-per-ml - water is roughly 1 gram per ml )
this.state = this.game.settings.states.LIQUID; // liquid is default
// but when we do state transitions we're just going to swap substances
// 2023.05.18 I guess I toyed with changing states and then abandoned it
// but leaving this in as it seems like it might be worth future exploration
this.states_ids = {};
// In reality density of liquids changes with temperature
// but we're keeping it simple.
this.density = 1; // water = 1(ish)
} // function Substance(id)
initialize(game) {
super.initialize(game);
/*
mixwiths are object ids but as with most object id
references we allow authors to enter them as
non-serialized strings. In this case, both the key
and the value are ids, so we need to serialize both.
*/
var keys = Object.keys(this.mixwith);
for (var i = keys.length - 1; i > -1; i--) {
var key = keys[i];
var serialized_key = A.serialize(key);
var serialized_with = A.serialize(this.mixwith[key]);
this.mixwith[serialized_key] = serialized_with;
}
return true;
} // p.initialize
}
adventurejs.Substance = Substance;
})();
/*
is global - sort of
- can always refer to it though it might not be present
is not a thing
all water is water
what if you color it?
then it becomes a different substance?
pour one substance into another
either they become a third substance
or one substance dissipates into the other
probably depending on viscosity?
water and oil don't mix
water and dirt becomes mud
sponges?
simulate leakage or evaporation - damp_level decrements over time
if you take a handful of a substance does the handful temporarily become an object?
fullness is a property of the object rather than an object in itself?
disambiguation from bodies of water
*/