//-----------------------------------------------------------------------------
// Group
//
// Group represents a group of assets that is dynamically generated by the
// include_tag and exclude_tag attributes.
//-----------------------------------------------------------------------------
/**
* @class RezGroup
* @extends RezBasicObject
* @category Elements
* @description Represents a dynamically generated group of assets in the Rez game engine.
* Groups filter assets based on type, include_tags, and exclude_tags attributes.
* Provides methods for getting random assets from the filtered collection.
*/
class RezGroup extends RezBasicObject {
/**
* @function constructor
* @memberof RezGroup
* @param {string} id - unique identifier for this group
* @param {object} attributes - group attributes including type, include_tags, exclude_tags
* @description Creates a new asset group instance
*/
constructor(id, attributes) {
super("group", id, attributes);
}
/**
* @function elementInitializer
* @memberof RezGroup
* @description Initializes the group by filtering assets during game startup
*/
elementInitializer() {
this.filterAssets();
}
/**
* @function filterAssets
* @memberof RezGroup
* @description Filters all game assets based on type, include_tags, and exclude_tags
* to build the group's asset collection. The filtered assets are shuffled and stored.
*/
filterAssets() {
// Start with all assets
let assets = this.game.getAll("asset");
// Does the asset have the right type
const selectedType = this.getAttributeValue("type");
assets = assets.filter((asset) => asset.type === selectedType);
// Assets without tags can't be in a group
assets = assets.filter((asset) => asset.hasAttribute("tags") && asset.getAttributeValue("tags").size > 0);
// If there is an include filter, filter those without the relevant tags
const includeTags = this.getAttributeValue("include_tags", new Set());
if(includeTags.size > 0) {
assets = assets.filter((asset) => {
const tags = asset.getAttributeValue("tags");
return tags.hasSubset(includeTags);
});
}
// If there is an exclude filter, filter those with the relevant tags
const excludeTags = this.getAttributeValue("exclude_tags", new Set());
if(excludeTags.size > 0) {
assets = assets.filter((asset) => {
const tags = asset.getAttributeValue("tags");
return tags.intersection(excludeTags).size === 0;
});
}
if(assets.size === 0) {
console.log("Attempt to create group that matches 0 assets!");
}
assets = assets.map((asset) => asset.id).fyShuffle();
this.setAttribute("assets", assets);
}
/**
* @function randomAssetId
* @memberof RezGroup
* @returns {string} ID of a random asset from this group
* @description Gets a random asset ID from this group, consuming it from the collection.
* If the group is empty, it will re-filter assets first.
* @throws {Error} if no matching assets are found
*/
randomAssetId() {
if(this.assets.size === 0) {
this.filterAssets();
}
const assetId = this.assets.shift();
if(typeof(assetId) === "undefined") {
throw new Error(`Attempt to get random asset from Group |${this.id}| with no matching assets!`);
}
return assetId;
}
}
// this.properties_to_archive = ["assets"];
window.Rez.RezGroup = RezGroup;
Source