@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
339 lines (294 loc) • 11.5 kB
JavaScript
import { BuffObjectTypes } from "../../../../../../generator/BuffObjectTypes.js";
import { UnlockableElementsManager } from "../../../../../../model/unlocks/UnlockableElementsManager.js";
import { MirMarkerTypes } from "../../../../../generator/MirMarkerTypes.js";
import { bitwiseAnd } from "../../../../src/core/binary/operations/bitwiseAnd.js";
import { CellFilterLiteralFloat } from "../../../../src/generation/filtering/numeric/CellFilterLiteralFloat.js";
import { GridTaskActionRuleSet } from "../../../../src/generation/grid/generation/discrete/GridTaskActionRuleSet.js";
import { GridActionRuleSet } from "../../../../src/generation/markers/GridActionRuleSet.js";
import { GridCellActionPlaceMarker } from "../../../../src/generation/markers/GridCellActionPlaceMarker.js";
import { GridCellActionPlaceMarkerGroup } from "../../../../src/generation/markers/GridCellActionPlaceMarkerGroup.js";
import { MarkerNodeMatcherAnd } from "../../../../src/generation/markers/matcher/MarkerNodeMatcherAnd.js";
import { MarkerNodeMatcherByType } from "../../../../src/generation/markers/matcher/MarkerNodeMatcherByType.js";
import {
MarkerNodeMatcherContainsTag
} from "../../../../src/generation/markers/matcher/MarkerNodeMatcherContainsTag.js";
import { RuleSelectionPolicyType } from "../../../../src/generation/markers/RuleSelectionPolicyType.js";
import { GridCellActionPlaceTags } from "../../../../src/generation/placement/action/GridCellActionPlaceTags.js";
import { GridCellActionSequence } from "../../../../src/generation/placement/action/util/GridCellActionSequence.js";
import { GridCellPlacementRule } from "../../../../src/generation/placement/GridCellPlacementRule.js";
import {
CellMatcherContainsMarkerWithinRadius
} from "../../../../src/generation/rules/cell/CellMatcherContainsMarkerWithinRadius.js";
import { CellMatcherGridPattern } from "../../../../src/generation/rules/cell/CellMatcherGridPattern.js";
import { GridPatternMatcherCell } from "../../../../src/generation/rules/cell/GridPatternMatcherCell.js";
import { CellMatcherAnd } from "../../../../src/generation/rules/logic/CellMatcherAnd.js";
import { CellMatcherNot } from "../../../../src/generation/rules/logic/CellMatcherNot.js";
import { CellMatcherOr } from "../../../../src/generation/rules/logic/CellMatcherOr.js";
import { GridTags } from "../../grid/GridTags.js";
import { MirGridLayers } from "../../grid/MirGridLayers.js";
import { matcher_tag_not_traversable } from "../../rules/matcher_tag_not_traversable.js";
import { matcher_tag_traversable_unoccupied } from "../../rules/matcher_tag_traversable_unoccupied.js";
const TAG_MAJOR = 'Major Buff';
const TAG_MINOR = 'Minor Buff';
const TAG_UTILITY = 'Utility Buff';
const pMatcherNextToWall = new CellMatcherGridPattern();
pMatcherNextToWall.addRule(0, 1, matcher_tag_not_traversable);
pMatcherNextToWall.addRule(0, 0, matcher_tag_traversable_unoccupied);
pMatcherNextToWall.addRule(0, -1, matcher_tag_traversable_unoccupied);
pMatcherNextToWall.addRule(0, -2, matcher_tag_traversable_unoccupied);
const mBuffObjectNearby = CellMatcherContainsMarkerWithinRadius.from(MarkerNodeMatcherContainsTag.from(MirMarkerTypes.BuffObject), 6);
const mNoBuffObjectsNearby = CellMatcherNot.from(
mBuffObjectNearby
);
const mNoMajorBuffObjectNearby = CellMatcherNot.from(
CellMatcherContainsMarkerWithinRadius.from(
MarkerNodeMatcherAnd.from(
MarkerNodeMatcherContainsTag.from(MirMarkerTypes.BuffObject),
MarkerNodeMatcherContainsTag.from(TAG_MAJOR)
), 21
)
);
const mNoMinorBuffObjectNearby = CellMatcherNot.from(
CellMatcherContainsMarkerWithinRadius.from(
MarkerNodeMatcherAnd.from(
MarkerNodeMatcherContainsTag.from(MirMarkerTypes.BuffObject),
MarkerNodeMatcherContainsTag.from(TAG_MINOR)
), 7
)
);
const mNoUtilityBuffObjectNearby = CellMatcherNot.from(
CellMatcherContainsMarkerWithinRadius.from(
MarkerNodeMatcherAnd.from(
MarkerNodeMatcherContainsTag.from(MirMarkerTypes.BuffObject),
MarkerNodeMatcherContainsTag.from(TAG_MINOR)
), 10
)
);
pMatcherNextToWall.addRule(0, 0, mNoBuffObjectsNearby);
const placeTags = new GridCellActionPlaceTags();
placeTags.layerId = MirGridLayers.Tags;
placeTags.resize(1, 1);
placeTags.fill(GridTags.Occupied);
const clearTags = new GridCellActionPlaceTags();
clearTags.layerId = MirGridLayers.Tags;
clearTags.resize(1, 1);
clearTags.fill(~GridTags.Traversable);
clearTags.operation = bitwiseAnd;
const placeRoadConnector0 = GridCellActionPlaceMarker.from({ type: 'Road Connector' });
placeRoadConnector0.offset.set(0, -1);
placeRoadConnector0.properties.connectivity = 0.1;
const placeRoadMarkers = GridCellActionPlaceMarkerGroup.from([placeRoadConnector0]);
/**
*
* @param {string} tag
* @return {GridCellPlacementRule}
*/
function makeMajorRule(tag) {
return GridCellPlacementRule.from({
matcher: CellMatcherAnd.from(
CellMatcherAnd.from(
mNoMajorBuffObjectNearby,
mNoBuffObjectsNearby
),
CellMatcherAnd.from(
pMatcherNextToWall,
CellMatcherNot.from(
CellMatcherContainsMarkerWithinRadius.from(MarkerNodeMatcherByType.from(tag), 42)
)
)
),
action: GridCellActionSequence.from([
placeTags,
clearTags,
GridCellActionPlaceMarker.from({
type: tag,
size: 0.52,
tags: [MirMarkerTypes.BuffObject, TAG_MAJOR]
}),
placeRoadMarkers
]),
probability: CellFilterLiteralFloat.from(0.1)
});
}
/**
*
* @param {string} tag
* @return {GridCellPlacementRule}
*/
function makeMinorRule(tag) {
return GridCellPlacementRule.from({
matcher: CellMatcherAnd.from(
CellMatcherGridPattern.from([
GridPatternMatcherCell.from(matcher_tag_not_traversable, 0, -1),
GridPatternMatcherCell.from(matcher_tag_not_traversable, 1, -1),
GridPatternMatcherCell.from(matcher_tag_traversable_unoccupied, 0, 0),
GridPatternMatcherCell.from(matcher_tag_not_traversable, 1, 0),
]),
CellMatcherAnd.from(
mNoMinorBuffObjectNearby,
CellMatcherNot.from(
CellMatcherOr.from(
mBuffObjectNearby,
CellMatcherContainsMarkerWithinRadius.from(MarkerNodeMatcherByType.from(tag), 21)
)
)
)
),
action: GridCellActionSequence.from([
placeTags,
clearTags,
GridCellActionPlaceMarker.from({
type: tag,
size: 0.52,
tags: [MirMarkerTypes.BuffObject, TAG_MINOR]
})
]),
probability: CellFilterLiteralFloat.from(0.1)
});
}
/**
*
* @param {string} tag
* @param {number} [frequency]
* @return {GridCellPlacementRule}
*/
function makeUtilityRule(tag, frequency = 17) {
return GridCellPlacementRule.from({
matcher: CellMatcherAnd.from(
matcher_tag_traversable_unoccupied,
CellMatcherAnd.from(
mNoUtilityBuffObjectNearby,
CellMatcherNot.from(
CellMatcherOr.from(
mBuffObjectNearby,
CellMatcherContainsMarkerWithinRadius.from(MarkerNodeMatcherByType.from(tag), frequency)
)
)
)
),
action: GridCellActionSequence.from([
placeTags,
clearTags,
GridCellActionPlaceMarker.from({
type: tag,
size: 0.52,
tags: [MirMarkerTypes.BuffObject, TAG_UTILITY]
})
]),
probability: CellFilterLiteralFloat.from(0.1)
});
}
/**
* @param {Engine} engine
* @returns {GridTaskActionRuleSet}
*/
export const mir_generator_place_buff_objects = (engine) => {
/**
*
* @type {GridCellPlacementRule[]}
*/
const rules = [];
/**
*
* @type {UnlockableElementsManager|undefined}
*/
const plugin = engine.plugins.getPlugin(UnlockableElementsManager);
/**
*
* @param {string} id
* @param {string} type
*/
function attemptMajorRule(id, type) {
plugin.runIfElementValue(
'object',
`buff/major/${id}`,
true,
false,
() => {
rules.push(makeMajorRule(type));
});
}
/**
*
* @param {string} id
* @param {string} type
*/
function attemptMinorRule(id, type) {
plugin.runIfElementValue(
'object',
`buff/minor/${id}`,
true,
false,
() => {
rules.push(makeMinorRule(type));
});
}
/**
*
* @param {string} id
* @param {string} type
* @param frequency
*/
function attemptUtilityRule(id, type, frequency) {
plugin.runIfElementValue(
'object',
`buff/utility/${id}`,
true,
false,
() => {
rules.push(makeUtilityRule(type, frequency));
});
}
if (plugin !== undefined) {
attemptMajorRule(
'increase_ability_power',
BuffObjectTypes.AttackPowerIncrease
);
attemptMajorRule(
'increase_defense',
BuffObjectTypes.DefenseIncrease
);
attemptMajorRule(
'increase_health',
BuffObjectTypes.HealthIncrease
);
attemptMajorRule(
'increase_ability_power_and_armor_piercing',
BuffObjectTypes.ABILITY_POWER_AND_ARMOR_PIERCING
);
attemptMajorRule(
'increase_experience_modifier',
BuffObjectTypes.EXPERIENCE_MODIFIER
);
attemptMajorRule(
'increase_movement_distance_and_initiative',
BuffObjectTypes.MOVEMENT_DISTANCE_AND_INITIATIVE
);
attemptMajorRule(
'increase_life_steal_and_healing_effectiveness',
BuffObjectTypes.LIFE_STEAL_AND_HEALING_EFFECTIVENESS
);
attemptMajorRule(
'increase_life_steal_and_healing_effectiveness',
BuffObjectTypes.LIFE_STEAL_AND_HEALING_EFFECTIVENESS
);
// Minor buffs
attemptMinorRule(
'well',
BuffObjectTypes.Well
);
attemptMinorRule(
'campfire',
BuffObjectTypes.Campfire
);
// utility
attemptUtilityRule('resurrect', BuffObjectTypes.RESURRECT_ALL, 30);
attemptUtilityRule('heal_small', BuffObjectTypes.HEAL_SMALL, 17);
}
return GridTaskActionRuleSet.from({
rules: GridActionRuleSet.from({
rules: rules,
policy: RuleSelectionPolicyType.Random
})
});
}