import { createCharacter } from "../create_character.js";
import Model from "./model.js";
/**
* Template for creating location instances. Defines the blueprint for creating location
* instances, including their properties, sub-divisions, material contents, and behavior patterns.
*
* @extends Model
*/
export class LocationTemplate extends Model {
/**
* Creates a new LocationTemplate instance.
*
* @constructor
* @param {Object} [params={}] - Configuration parameters
* @param {String} [params.type] - Unambiguous and unique, human-readable label for the location type. Either `type` or `room` must be provided and they are mutually exclusive.
* @param {String} [params.room] - If present, supplies the type of the location, and also indicates that is a room, which will not be not included in the list of locations from which you can start to build a top-down representation of a location. Either `type` or `room` must be provided and they are mutually exclusive.
* @param {String} [params.name=params.type] - The display name of a location. Can contain alternatives in the string form "{A|B}"
* @param {String[]} [params.tags] - Array of tags to categorize this location template
* @param {Boolean} [params.abstract=false] - Whether this is an abstract template that cannot be instantiated directly
* @param {Object} [params.contents] - Contents configuration to create content of this location in the format defined by the `selectElements` function.
* @param {Object} [params.inventory] - An array of configurations for the inventory of this location, each in the format defined by the `bagSpecParser` function.
* @param {Array|Object} [params.ch] - The child nodes of this location template, either as an array of types, or as an object in the format defined by the `selectElements` function.
* @param {String} [params.descr] - Description of the location
* @param {String} [params.policy] - A free-text description of the sales policies of a store
* @param {String} [params.owner] - The profession to use when generating an owner of a store
*/
constructor({
type,
name,
tags = [],
abstract = false,
room = false,
contents = {},
inventory = {},
ch = [],
descr,
policy,
owner,
} = {}) {
super({ tags });
this.type = type ?? room;
this.name = name ?? type ?? room;
this.room = room;
this.abstract = abstract;
this.description = descr;
this.contents = Object.freeze(contents);
this.inventory = Object.freeze(inventory);
this.ch = Object.freeze(ch);
this.policy = policy;
this.owner = owner;
}
}
/**
* Represents an actual location instance created from a LocationTemplate.
* Contains the runtime state and hierarchical relationships between locations.
*
* @extends Model
*/
export class Location extends Model {
/**
* Creates a new Location instance from a template.
*
* @constructor
* @param {LocationTemplate} template - The template to create this location from
* @param {Location} [parent] - The parent location in the hierarchy
*/
constructor(template, parent) {
super({ tags: template.tags });
this.name = template.name;
this.seqValue = "";
this.type = template.type;
this.description = template.description;
this.contents = [];
this.inventory = [];
this.children = [];
this.parent = parent;
}
/**
* Adds a child location to this location's hierarchy.
*
* @param {Location} child - The child location to add
* @throws {Error} If the child is not a Location instance
*/
addChild(child) {
if (!(child instanceof Location)) {
throw new Error("Cannot add a template to a location: " + child);
}
child.parent = this;
this.children.push(child);
}
}
/**
* Represents a store location with ownership, policies, and commercial properties.
* Extends Location with store-specific features like owners and business policies.
*
* @extends Location
*/
export class Store extends Location {
/**
* Creates a new Store instance from a template.
*
* @constructor
* @param {LocationTemplate} template - The template to create this store from
* @param {Location} [parent] - The parent location in the hierarchy
*/
constructor(template, parent) {
super(template, parent);
this.policy = template.policy;
this.owner = createCharacter({ profession: template.owner });
}
}