From bb1758642bf7931a2e781198c8fd2935cfa53d6a Mon Sep 17 00:00:00 2001 From: Tobias Springer Date: Sun, 10 May 2020 17:45:48 +0200 Subject: [PATCH] Add originalRotation to static comp in order to fix bugs with the automatic placement --- src/css/ingame_hud/building_placer.scss | 16 ++++----- src/css/ingame_hud/buildings_toolbar.scss | 13 ++++--- src/css/variables.scss | 2 +- src/js/core/input_distributor.js | 8 +++++ src/js/core/input_receiver.js | 1 + src/js/game/buildings/belt_base.js | 15 +++++--- src/js/game/buildings/underground_belt.js | 4 +-- src/js/game/components/static_map_entity.js | 36 +++++++++---------- src/js/game/core.js | 10 +++--- src/js/game/hud/parts/building_placer.js | 11 ++++-- src/js/game/hud/parts/buildings_toolbar.js | 40 ++++++++++++++++----- src/js/game/hud/parts/keybinding_overlay.js | 12 ++++++- src/js/game/hud/parts/mass_selector.js | 3 ++ src/js/game/logic.js | 13 ++++--- src/js/game/meta_building.js | 14 ++++---- src/js/game/systems/belt.js | 4 +-- 16 files changed, 133 insertions(+), 69 deletions(-) create mode 100644 src/js/game/hud/parts/mass_selector.js diff --git a/src/css/ingame_hud/building_placer.scss b/src/css/ingame_hud/building_placer.scss index f90f155f..25584fc7 100644 --- a/src/css/ingame_hud/building_placer.scss +++ b/src/css/ingame_hud/building_placer.scss @@ -1,19 +1,17 @@ #ingame_HUD_building_placer { position: fixed; - @include S(bottom, 60px); - left: 50%; - transform: translateX(-50%); + @include S(top, 5q0px); + @include S(right, 10px); display: flex; flex-direction: column; @include S(padding, 6px); justify-content: center; - align-items: center; - background-color: $ingameHudBg; + align-items: flex-start; @include S(border-radius, 4px); - background: #333; - @include S(width, 300px); + background: rgba(#333, 0.5); + @include S(width, 200px); .buildingLabel { @include PlainText; @@ -24,8 +22,8 @@ .instructions, .description { - text-align: center; - color: mix($accentColorDark, $accentColorBright, 50%); + color: #fff; + opacity: 0.8; @include SuperSmallText; } diff --git a/src/css/ingame_hud/buildings_toolbar.scss b/src/css/ingame_hud/buildings_toolbar.scss index 779333ba..54adc41b 100644 --- a/src/css/ingame_hud/buildings_toolbar.scss +++ b/src/css/ingame_hud/buildings_toolbar.scss @@ -58,12 +58,17 @@ } } - // &:first-child .tooltip { - // display: flex; - // } + &.selected { + background: rgb(140, 229, 140) !important; + transform: scale(1.05); + .keybinding { + color: #111; + } + } pointer-events: all; - transition: background-color 0.1s ease-in-out; + transition: all 0.1s ease-in-out; + transition-property: background-color, transform; &.unlocked:hover { background: rgba($accentColorDark, 0.1); cursor: pointer; diff --git a/src/css/variables.scss b/src/css/variables.scss index 392393d6..680b40d6 100644 --- a/src/css/variables.scss +++ b/src/css/variables.scss @@ -32,7 +32,7 @@ $accentColorDark: #7d808a; $colorGreenBright: #66bb6a; $colorRedBright: #ef5072; $themeColor: #393747; -$ingameHudBg: rgba($accentColorBright, 0.9); +$ingameHudBg: rgba($accentColorBright, 0.1); $ingameHudBorder: #{D(1.5px)} solid $accentColorDark; $text3dColor: #f4ffff; diff --git a/src/js/core/input_distributor.js b/src/js/core/input_distributor.js index 668cdcec..ffd6cfcd 100644 --- a/src/js/core/input_distributor.js +++ b/src/js/core/input_distributor.js @@ -176,6 +176,7 @@ export class InputDistributor { */ handleBlur() { this.shiftIsDown = false; + this.altIsDown = false; this.forwardToReceiver("pageBlur", {}); this.forwardToReceiver("shiftUp", {}); } @@ -187,6 +188,9 @@ export class InputDistributor { if (event.keyCode === 16) { this.shiftIsDown = true; } + if (event.keyCode === 18) { + this.altIsDown = true; + } if ( // TAB @@ -225,6 +229,10 @@ export class InputDistributor { this.shiftIsDown = false; this.forwardToReceiver("shiftUp", {}); } + if (event.keyCode === 18) { + this.altIsDown = false; + this.forwardToReceiver("altUp", {}); + } this.forwardToReceiver("keyup", { keyCode: event.keyCode, diff --git a/src/js/core/input_receiver.js b/src/js/core/input_receiver.js index f2fdf32f..c4b6fbfe 100644 --- a/src/js/core/input_receiver.js +++ b/src/js/core/input_receiver.js @@ -10,6 +10,7 @@ export class InputReceiver { this.keyup = new Signal(); this.pageBlur = new Signal(); this.shiftUp = new Signal(); + this.altUp = new Signal(); // Dispatched on destroy this.destroyed = new Signal(); diff --git a/src/js/game/buildings/belt_base.js b/src/js/game/buildings/belt_base.js index 74244dcf..c14e953c 100644 --- a/src/js/game/buildings/belt_base.js +++ b/src/js/game/buildings/belt_base.js @@ -130,8 +130,8 @@ export class MetaBeltBaseBuilding extends MetaBuilding { const { ejectors, acceptors } = root.logic.getEjectorsAndAcceptorsAtTile(tile); let hasBottomEjector = false; - let hasLeftEjector = false; let hasRightEjector = false; + let hasLeftEjector = false; let hasTopAcceptor = false; let hasLeftAcceptor = false; @@ -144,9 +144,9 @@ export class MetaBeltBaseBuilding extends MetaBuilding { if (ejector.toDirection === topDirection) { hasBottomEjector = true; } else if (ejector.toDirection === leftDirection) { - hasLeftEjector = true; - } else if (ejector.toDirection === rightDirection) { hasRightEjector = true; + } else if (ejector.toDirection === rightDirection) { + hasLeftEjector = true; } } @@ -167,7 +167,9 @@ export class MetaBeltBaseBuilding extends MetaBuilding { if (!hasBottomEjector) { // When something ejects to us from the left and nothing from the right, // do a curve from the left to the top - if (hasLeftEjector && !hasRightEjector) { + + if (hasRightEjector && !hasLeftEjector) { + console.log("e - connect right"); return { rotation: (rotation + 270) % 360, rotationVariant: 2, @@ -176,7 +178,8 @@ export class MetaBeltBaseBuilding extends MetaBuilding { // When something ejects to us from the right and nothing from the left, // do a curve from the right to the top - if (hasRightEjector && !hasLeftEjector) { + if (hasLeftEjector && !hasRightEjector) { + console.log("e - connect left"); return { rotation: (rotation + 90) % 360, rotationVariant: 1, @@ -190,6 +193,7 @@ export class MetaBeltBaseBuilding extends MetaBuilding { // When there is an acceptor to the right but no acceptor to the left, // do a turn to the right if (hasRightAcceptor && !hasLeftAcceptor) { + console.log("a - connect right"); return { rotation, rotationVariant: 2, @@ -199,6 +203,7 @@ export class MetaBeltBaseBuilding extends MetaBuilding { // When there is an acceptor to the left but no acceptor to the right, // do a turn to the left if (hasLeftAcceptor && !hasRightAcceptor) { + console.log("a - connect left"); return { rotation, rotationVariant: 1, diff --git a/src/js/game/buildings/underground_belt.js b/src/js/game/buildings/underground_belt.js index c00a9469..7830e5d8 100644 --- a/src/js/game/buildings/underground_belt.js +++ b/src/js/game/buildings/underground_belt.js @@ -109,12 +109,12 @@ export class MetaUndergroundBeltBuilding extends MetaBuilding { const undergroundComp = contents.components.UndergroundBelt; if (undergroundComp) { const staticComp = contents.components.StaticMapEntity; - if (staticComp.rotationDegrees === targetRotation) { + if (staticComp.rotation === targetRotation) { if (undergroundComp.mode !== enumUndergroundBeltMode.sender) { // If we encounter an underground receiver on our way which is also faced in our direction, we don't accept that break; } - // console.log("GOT IT! rotation is", rotation, "and target is", staticComp.rotationDegrees); + // console.log("GOT IT! rotation is", rotation, "and target is", staticComp.rotation); return { rotation: targetRotation, diff --git a/src/js/game/components/static_map_entity.js b/src/js/game/components/static_map_entity.js index dc1cf0d5..9b5c3687 100644 --- a/src/js/game/components/static_map_entity.js +++ b/src/js/game/components/static_map_entity.js @@ -13,12 +13,7 @@ export class StaticMapEntityComponent extends Component { } static getSchema() { - return { - origin: types.tileVector, - tileSize: types.tileVector, - rotationDegrees: types.uint, - spriteKey: types.string, - }; + return {}; } /** @@ -26,27 +21,30 @@ export class StaticMapEntityComponent extends Component { * @param {object} param0 * @param {Vector=} param0.origin Origin (Top Left corner) of the entity * @param {Vector=} param0.tileSize Size of the entity in tiles - * @param {number=} param0.rotationDegrees Rotation in degrees. Must be multiple of 90 + * @param {number=} param0.rotation Rotation in degrees. Must be multiple of 90 + * @param {number=} param0.originalRotation Original Rotation in degrees. Must be multiple of 90 * @param {string=} param0.spriteKey Optional sprite * @param {string=} param0.silhouetteColor Optional silhouette color override */ constructor({ origin = new Vector(), tileSize = new Vector(1, 1), - rotationDegrees = 0, + rotation = 0, + originalRotation = 0, spriteKey = null, silhouetteColor = null, }) { super(); assert( - rotationDegrees % 90 === 0, - "Rotation of static map entity must be multiple of 90 (was " + rotationDegrees + ")" + rotation % 90 === 0, + "Rotation of static map entity must be multiple of 90 (was " + rotation + ")" ); this.origin = origin; this.tileSize = tileSize; this.spriteKey = spriteKey; - this.rotationDegrees = rotationDegrees; + this.rotation = rotation; + this.originalRotation = originalRotation; this.silhouetteColor = silhouetteColor; } @@ -55,7 +53,7 @@ export class StaticMapEntityComponent extends Component { * @returns {Rectangle} */ getTileSpaceBounds() { - switch (this.rotationDegrees) { + switch (this.rotation) { case 0: return new Rectangle(this.origin.x, this.origin.y, this.tileSize.x, this.tileSize.y); case 90: @@ -90,7 +88,7 @@ export class StaticMapEntityComponent extends Component { * @returns {Vector} */ applyRotationToVector(vector) { - return vector.rotateFastMultipleOf90(this.rotationDegrees); + return vector.rotateFastMultipleOf90(this.rotation); } /** @@ -99,7 +97,7 @@ export class StaticMapEntityComponent extends Component { * @returns {Vector} */ unapplyRotationToVector(vector) { - return vector.rotateFastMultipleOf90(360 - this.rotationDegrees); + return vector.rotateFastMultipleOf90(360 - this.rotation); } /** @@ -108,7 +106,7 @@ export class StaticMapEntityComponent extends Component { * @returns {enumDirection} */ localDirectionToWorld(direction) { - return Vector.transformDirectionFromMultipleOf90(direction, this.rotationDegrees); + return Vector.transformDirectionFromMultipleOf90(direction, this.rotation); } /** @@ -117,7 +115,7 @@ export class StaticMapEntityComponent extends Component { * @returns {enumDirection} */ worldDirectionToLocal(direction) { - return Vector.transformDirectionFromMultipleOf90(direction, 360 - this.rotationDegrees); + return Vector.transformDirectionFromMultipleOf90(direction, 360 - this.rotation); } /** @@ -151,7 +149,7 @@ export class StaticMapEntityComponent extends Component { const worldX = this.origin.x * globalConfig.tileSize; const worldY = this.origin.y * globalConfig.tileSize; - if (this.rotationDegrees === 0) { + if (this.rotation === 0) { // Early out, is faster sprite.drawCached( parameters, @@ -166,7 +164,7 @@ export class StaticMapEntityComponent extends Component { const rotationCenterY = worldY + globalConfig.halfTileSize; parameters.context.translate(rotationCenterX, rotationCenterY); - parameters.context.rotate(Math_radians(this.rotationDegrees)); + parameters.context.rotate(Math_radians(this.rotation)); sprite.drawCached( parameters, @@ -177,7 +175,7 @@ export class StaticMapEntityComponent extends Component { false ); - parameters.context.rotate(-Math_radians(this.rotationDegrees)); + parameters.context.rotate(-Math_radians(this.rotation)); parameters.context.translate(-rotationCenterX, -rotationCenterY); } } diff --git a/src/js/game/core.js b/src/js/game/core.js index 8a9c4857..a7eb8c8d 100644 --- a/src/js/game/core.js +++ b/src/js/game/core.js @@ -132,15 +132,17 @@ export class GameCore { /** * Initializes a new game, this means creating a new map and centering on the - * plaerbase + * playerbase * */ initNewGame() { logger.log("Initializing new game"); this.root.gameIsFresh = true; - gMetaBuildingRegistry - .findByClass(MetaHubBuilding) - .createAndPlaceEntity(this.root, new Vector(-2, -2), 0); + gMetaBuildingRegistry.findByClass(MetaHubBuilding).createAndPlaceEntity({ + root: this.root, + origin: new Vector(-2, -2), + rotation: 0, + }); } /** diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js index 2f44135e..14d3e19f 100644 --- a/src/js/game/hud/parts/building_placer.js +++ b/src/js/game/hud/parts/building_placer.js @@ -99,6 +99,11 @@ export class HUDBuildingPlacer extends BaseHUDPart { const angleDeg = Math_degrees(delta.angle()); this.currentBaseRotation = (Math.round(angleDeg / 90) * 90 + 360) % 360; + // Holding alt inverts the placement + if (this.root.app.inputMgr.altIsDown) { + this.currentBaseRotation = (180 + this.currentBaseRotation) % 360; + } + // - Using bresenhams algorithmus let x0 = oldPos.x; @@ -172,7 +177,7 @@ export class HUDBuildingPlacer extends BaseHUDPart { this.fakeEntity.addComponent( new StaticMapEntityComponent({ origin: new Vector(0, 0), - rotationDegrees: 0, + rotation: 0, tileSize: metaBuilding.getDimensions().copy(), }) ); @@ -190,7 +195,7 @@ export class HUDBuildingPlacer extends BaseHUDPart { if (selectedBuilding) { this.currentBaseRotation = (this.currentBaseRotation + 90) % 360; const staticComp = this.fakeEntity.components.StaticMapEntity; - staticComp.rotationDegrees = this.currentBaseRotation; + staticComp.rotation = this.currentBaseRotation; } } @@ -350,7 +355,7 @@ export class HUDBuildingPlacer extends BaseHUDPart { // Synchronize rotation and origin const staticComp = this.fakeEntity.components.StaticMapEntity; staticComp.origin = tile; - staticComp.rotationDegrees = rotation; + staticComp.rotation = rotation; metaBuilding.updateRotationVariant(this.fakeEntity, rotationVariant); // Check if we could place the buildnig diff --git a/src/js/game/hud/parts/buildings_toolbar.js b/src/js/game/hud/parts/buildings_toolbar.js index 4d621a2d..ef68886d 100644 --- a/src/js/game/hud/parts/buildings_toolbar.js +++ b/src/js/game/hud/parts/buildings_toolbar.js @@ -33,8 +33,8 @@ export class HUDBuildingsToolbar extends BaseHUDPart { constructor(root) { super(root); - /** @type {Object.} */ - this.buildingUnlockStates = {}; + /** @type {Object.} */ + this.buildingHandles = {}; this.sigBuildingSelected = new Signal(); @@ -92,29 +92,50 @@ export class HUDBuildingsToolbar extends BaseHUDPart { this.trackClicks(itemContainer, () => this.selectBuildingForPlacement(metaBuilding), {}); - this.buildingUnlockStates[metaBuilding.id] = { + this.buildingHandles[metaBuilding.id] = { metaBuilding, element: itemContainer, - status: false, + unlocked: false, + selected: false, }; } + + this.root.hud.signals.selectedPlacementBuildingChanged.add( + this.onSelectedPlacementBuildingChanged, + this + ); } update() { this.trackedIsVisisible.set(!this.root.camera.getIsMapOverlayActive()); - for (const buildingId in this.buildingUnlockStates) { - const handle = this.buildingUnlockStates[buildingId]; + for (const buildingId in this.buildingHandles) { + const handle = this.buildingHandles[buildingId]; const newStatus = handle.metaBuilding.getIsUnlocked(this.root); - if (handle.status !== newStatus) { - handle.status = newStatus; + if (handle.unlocked !== newStatus) { + handle.unlocked = newStatus; handle.element.classList.toggle("unlocked", newStatus); } } } /** - * + * @param {MetaBuilding} metaBuilding + */ + onSelectedPlacementBuildingChanged(metaBuilding) { + for (const buildingId in this.buildingHandles) { + const handle = this.buildingHandles[buildingId]; + const newStatus = handle.metaBuilding === metaBuilding; + if (handle.selected !== newStatus) { + handle.selected = newStatus; + handle.element.classList.toggle("selected", newStatus); + } + } + + this.element.classList.toggle("buildingSelected", !!metaBuilding); + } + + /** * @param {MetaBuilding} metaBuilding */ selectBuildingForPlacement(metaBuilding) { @@ -124,5 +145,6 @@ export class HUDBuildingsToolbar extends BaseHUDPart { } this.sigBuildingSelected.dispatch(metaBuilding); + this.onSelectedPlacementBuildingChanged(metaBuilding); } } diff --git a/src/js/game/hud/parts/keybinding_overlay.js b/src/js/game/hud/parts/keybinding_overlay.js index 96be31e3..a83ef1ce 100644 --- a/src/js/game/hud/parts/keybinding_overlay.js +++ b/src/js/game/hud/parts/keybinding_overlay.js @@ -6,6 +6,11 @@ import { TrackedState } from "../../../core/tracked_state"; export class HUDKeybindingOverlay extends BaseHUDPart { initialize() { this.shiftDownTracker = new TrackedState(this.onShiftStateChanged, this); + + this.root.hud.signals.selectedPlacementBuildingChanged.add( + this.onSelectedBuildingForPlacementChanged, + this + ); } onShiftStateChanged(shiftDown) { @@ -56,9 +61,14 @@ export class HUDKeybindingOverlay extends BaseHUDPart {
- SHIFT + ⇧ SHIFT
+ +
+ ALT + +
` ); } diff --git a/src/js/game/hud/parts/mass_selector.js b/src/js/game/hud/parts/mass_selector.js new file mode 100644 index 00000000..658eb8ee --- /dev/null +++ b/src/js/game/hud/parts/mass_selector.js @@ -0,0 +1,3 @@ +import { BaseHUDPart } from "../base_hud_part"; + +export class HUDMassSelector extends BaseHUDPart {} diff --git a/src/js/game/logic.js b/src/js/game/logic.js index 839549b7..f9c50f58 100644 --- a/src/js/game/logic.js +++ b/src/js/game/logic.js @@ -58,7 +58,7 @@ export class GameLogic { const checker = new StaticMapEntityComponent({ origin, tileSize: building.getDimensions(), - rotationDegrees: rotation, + rotation, }); const rect = checker.getTileSpaceBounds(); @@ -106,7 +106,7 @@ export class GameLogic { const beltComp = original.components.Belt; if (beltComp) { // Its a belt, check if it differs in either rotation or rotation variant - if (staticComp.rotationDegrees !== rotation) { + if (staticComp.rotation !== rotation) { return true; } if (beltComp.direction !== arrayBeltVariantToRotation[rotationVariant]) { @@ -150,7 +150,7 @@ export class GameLogic { const checker = new StaticMapEntityComponent({ origin, tileSize: building.getDimensions(), - rotationDegrees: rotation, + rotation, }); const rect = checker.getTileSpaceBounds(); @@ -167,7 +167,12 @@ export class GameLogic { } } - building.createAndPlaceEntity(this.root, origin, rotation, rotationVariant); + building.createAndPlaceEntity({ + root: this.root, + origin, + rotation, + rotationVariant, + }); return true; } return false; diff --git a/src/js/game/meta_building.js b/src/js/game/meta_building.js index a2201bed..7e101e4c 100644 --- a/src/js/game/meta_building.js +++ b/src/js/game/meta_building.js @@ -98,18 +98,20 @@ export class MetaBuilding { /** * Creates the entity at the given location - * @param {GameRoot} root - * @param {Vector} origin Origin tile - * @param {number=} rotation Rotation - * @param {number=} rotationVariant Rotation variant + * @param {object} param0 + * @param {GameRoot} param0.root + * @param {Vector} param0.origin Origin tile + * @param {number=} param0.rotation Rotation + * @param {number=} param0.rotationVariant Rotation variant */ - createAndPlaceEntity(root, origin, rotation = 0, rotationVariant = 0) { + createAndPlaceEntity({ root, origin, rotation = 0, rotationVariant = 0 }) { const entity = new Entity(root); entity.addComponent( new StaticMapEntityComponent({ spriteKey: "sprites/buildings/" + this.id + ".png", origin: new Vector(origin.x, origin.y), - rotationDegrees: rotation, + rotation, + originalRotation: rotation, tileSize: this.getDimensions().copy(), silhouetteColor: this.getSilhouetteColor(), }) diff --git a/src/js/game/systems/belt.js b/src/js/game/systems/belt.js index e71da85c..00fa4803 100644 --- a/src/js/game/systems/belt.js +++ b/src/js/game/systems/belt.js @@ -87,9 +87,9 @@ export class BeltSystem extends GameSystemWithFilter { } = metaBelt.computeOptimalDirectionAndRotationVariantAtTile( this.root, new Vector(x, y), - targetStaticComp.rotationDegrees + targetStaticComp.originalRotation ); - targetStaticComp.rotationDegrees = rotation; + targetStaticComp.rotation = rotation; metaBelt.updateRotationVariant(targetEntity, rotationVariant); } }