From bc3f785d1bc9d34d3c55ed626c56b301755e2be7 Mon Sep 17 00:00:00 2001 From: Dimava Date: Thu, 18 Jun 2020 22:45:48 +0300 Subject: [PATCH] rewrite pipette to determine type using unplaced clones --- src/js/game/hud/parts/buildings_toolbar.js | 96 ++++++++++++++++++++++ src/js/game/key_action_mapper.js | 1 + src/js/game/meta_building.js | 44 ++++++++++ translations/base-en.yaml | 1 + 4 files changed, 142 insertions(+) diff --git a/src/js/game/hud/parts/buildings_toolbar.js b/src/js/game/hud/parts/buildings_toolbar.js index 305d3eee..ac3ea05c 100644 --- a/src/js/game/hud/parts/buildings_toolbar.js +++ b/src/js/game/hud/parts/buildings_toolbar.js @@ -93,6 +93,7 @@ export class HUDBuildingsToolbar extends BaseHUDPart { this.lastSelectedIndex = 0; actionMapper.getBinding(KEYMAPPINGS.placement.cycleBuildings).add(this.cycleBuildings, this); + actionMapper.getBinding(KEYMAPPINGS.placement.pipette).add(this.usePipette, this); } update() { @@ -123,6 +124,101 @@ export class HUDBuildingsToolbar extends BaseHUDPart { this.selectBuildingForPlacement(metaBuilding); } + detectPippeted(entity) { + const alike = []; + for (let i = 0; i < toolbarBuildings.length; ++i) { + const metaBuilding = gMetaBuildingRegistry.findByClass(toolbarBuildings[i]); + const handle = this.buildingHandles[metaBuilding.id]; + if (!handle.unlocked) { + continue; + } + + const availableVariants = metaBuilding.getAvailableVariants(this.root); + checkVariant: for (let variant of availableVariants) { + let unplaced = metaBuilding.createUnplacedEntity({ root: this.root, variant }); + // compare props + for (let c in entity.components) { + if ( + (entity.components[c] && !unplaced.components[c]) || + (!entity.components[c] && unplaced.components[c]) + ) { + continue checkVariant; + } + } + + if ( + entity.components.ItemProcessor && + entity.components.ItemProcessor.type != unplaced.components.ItemProcessor.type + ) { + continue checkVariant; + } + if ( + entity.components.UndergroundBelt && + entity.components.UndergroundBelt.tier != unplaced.components.UndergroundBelt.tier + ) { + continue checkVariant; + } + // tecnically this one is enough without all others BUT ubelts + if ( + entity.components.StaticMapEntity.spriteKey != + unplaced.components.StaticMapEntity.spriteKey && + !entity.components.UndergroundBelt + ) { + console.log("ignored %o cuz other sprite", unplaced); + continue checkVariant; + } + console.log("%O is probably %O (%s/%s)", entity, unplaced, metaBuilding.id, variant); + alike.push({ metaBuilding, variant, unplaced }); + } + } + + if (alike.length == 1) { + let staticEntity = entity.components.StaticMapEntity; + let key = staticEntity.spriteKey || staticEntity.blueprintSpriteKey; + assertAlways( + key && + key.includes(alike[0].metaBuilding.id) && + (alike[0].variant == "default" || key.includes(alike[0].variant)) + ); + return alike[0]; + } + if (alike.length > 1) { + console.warn("multiple alike buildings:", alike); + } + console.log("entity is unknown", entity); + return null; + } + + usePipette() { + if (this.root.hud.parts.buildingPlacer.currentMetaBuilding.get()) { + return; + } + if (this.root.camera.getIsMapOverlayActive()) { + return; + } + + const mousePos = this.root.app.mousePosition; + if (!mousePos) { + return; + } + const worldPos = this.root.camera.screenToWorld(mousePos); + const worldTile = worldPos.toTileSpace(); + + const entity = this.root.map.getTileContent(worldTile); + if (!entity) { + return; + } + + let detected = this.detectPippeted(entity); + + if (detected) { + this.selectBuildingForPlacement(detected.metaBuilding); + this.root.hud.parts.buildingPlacer.currentVariant.set(detected.variant); + this.root.hud.parts.buildingPlacer.currentBaseRotation = + (Math.round(entity.components.StaticMapEntity.originalRotation / 90) * 90 + 360) % 360; + } + } + /** * @param {MetaBuilding} metaBuilding */ diff --git a/src/js/game/key_action_mapper.js b/src/js/game/key_action_mapper.js index 6a1e265c..11820343 100644 --- a/src/js/game/key_action_mapper.js +++ b/src/js/game/key_action_mapper.js @@ -62,6 +62,7 @@ export const KEYMAPPINGS = { cycleBuildingVariants: { keyCode: key("T") }, cycleBuildings: { keyCode: 9 }, // TAB switchDirectionLockSide: { keyCode: key("R") }, + pipette: { keyCode: key("Q") }, }, massSelect: { diff --git a/src/js/game/meta_building.js b/src/js/game/meta_building.js index 723e854b..cf7974f8 100644 --- a/src/js/game/meta_building.js +++ b/src/js/game/meta_building.js @@ -136,6 +136,50 @@ export class MetaBuilding { return null; } + /** + * Creates the entity but does not adds it to world + * @param {object} param0 + * @param {GameRoot} param0.root + * @param {Vector} [param0.origin] Origin tile + * @param {number=} [param0.rotation] Rotation + * @param {number} [param0.originalRotation] Original Rotation + * @param {number} [param0.rotationVariant] Rotation variant + * @param {string} param0.variant + */ + createUnplacedEntity({ + root, + origin = new Vector(9999, 9999), + rotation = 0, + originalRotation = 0, + rotationVariant = 0, + variant, + }) { + const entity = new Entity(root); + + const blueprintSprite = this.getBlueprintSprite(rotationVariant, variant); + + entity.addComponent( + new StaticMapEntityComponent({ + spriteKey: + "sprites/buildings/" + + this.id + + (variant === defaultBuildingVariant ? "" : "-" + variant) + + ".png", + origin: new Vector(origin.x, origin.y), + rotation, + originalRotation, + tileSize: this.getDimensions(variant).copy(), + silhouetteColor: this.getSilhouetteColor(), + blueprintSpriteKey: blueprintSprite ? blueprintSprite.spriteName : "", + }) + ); + + this.setupEntityComponents(entity, root); + this.updateVariants(entity, rotationVariant, variant); + + return entity; + } + /** * Creates the entity at the given location * @param {object} param0 diff --git a/translations/base-en.yaml b/translations/base-en.yaml index 8321e20b..0dbf6269 100644 --- a/translations/base-en.yaml +++ b/translations/base-en.yaml @@ -746,6 +746,7 @@ keybindings: lockBeltDirection: Enable belt planner switchDirectionLockSide: >- Planner: Switch side + pipette: Pipette (select hovered) massSelectStart: Hold and drag to start massSelectSelectMultiple: Select multiple areas