UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

339 lines (294 loc) • 11.5 kB
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 }) }); }