1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-03-02 03:39:21 +00:00

Further blueprint improvements

This commit is contained in:
tobspr
2020-05-27 15:03:36 +02:00
parent 19c770201f
commit dfe1e64b27
17 changed files with 159 additions and 152 deletions

View File

@@ -1,10 +1,9 @@
import { GameRoot } from "../../root";
import { DrawParameters } from "../../../core/draw_parameters";
import { Loader } from "../../../core/loader";
import { createLogger } from "../../../core/logging";
import { Vector } from "../../../core/vector";
import { Entity } from "../../entity";
import { DrawParameters } from "../../../core/draw_parameters";
import { StaticMapEntityComponent } from "../../components/static_map_entity";
import { createLogger } from "../../../core/logging";
import { Loader } from "../../../core/loader";
import { GameRoot } from "../../root";
const logger = createLogger("blueprint");
@@ -17,6 +16,7 @@ export class Blueprint {
}
/**
* Creates a new blueprint from the given entity uids
* @param {GameRoot} root
* @param {Array<number>} uids
*/
@@ -48,7 +48,7 @@ export class Blueprint {
}
/**
*
* Draws the blueprint at the given origin
* @param {DrawParameters} parameters
*/
draw(parameters, tile) {
@@ -93,6 +93,31 @@ export class Blueprint {
}
/**
* Rotates the blueprint clockwise
*/
rotateCw() {
for (let i = 0; i < this.entities.length; ++i) {
const entity = this.entities[i];
const staticComp = entity.components.StaticMapEntity;
staticComp.rotation = (staticComp.rotation + 90) % 360;
staticComp.originalRotation = (staticComp.originalRotation + 90) % 360;
staticComp.origin = staticComp.origin.rotateFastMultipleOf90(90);
}
}
/**
* Rotates the blueprint counter clock wise
*/
rotateCcw() {
// Well ...
for (let i = 0; i < 3; ++i) {
this.rotateCw();
}
}
/**
* Checks if the blueprint can be placed at the given tile
* @param {GameRoot} root
* @param {Vector} tile
*/
@@ -123,54 +148,57 @@ export class Blueprint {
}
/**
* Attempts to place the blueprint at the given tile
* @param {GameRoot} root
* @param {Vector} tile
*/
tryPlace(root, tile) {
let anyPlaced = false;
for (let i = 0; i < this.entities.length; ++i) {
let placeable = true;
const entity = this.entities[i];
const staticComp = entity.components.StaticMapEntity;
const rect = staticComp.getTileSpaceBounds();
rect.moveBy(tile.x, tile.y);
placementCheck: for (let x = rect.x; x < rect.right(); ++x) {
for (let y = rect.y; y < rect.bottom(); ++y) {
const contents = root.map.getTileContentXY(x, y);
if (contents && !contents.components.ReplaceableMapEntity) {
placeable = false;
break placementCheck;
}
}
}
if (placeable) {
for (let x = rect.x; x < rect.right(); ++x) {
return root.logic.performBulkOperation(() => {
let anyPlaced = false;
for (let i = 0; i < this.entities.length; ++i) {
let placeable = true;
const entity = this.entities[i];
const staticComp = entity.components.StaticMapEntity;
const rect = staticComp.getTileSpaceBounds();
rect.moveBy(tile.x, tile.y);
placementCheck: for (let x = rect.x; x < rect.right(); ++x) {
for (let y = rect.y; y < rect.bottom(); ++y) {
const contents = root.map.getTileContentXY(x, y);
if (contents) {
assert(
contents.components.ReplaceableMapEntity,
"Can not delete entity for blueprint"
);
if (!root.logic.tryDeleteBuilding(contents)) {
logger.error(
"Building has replaceable component but is also unremovable in blueprint"
);
return false;
}
if (contents && !contents.components.ReplaceableMapEntity) {
placeable = false;
break placementCheck;
}
}
}
const clone = entity.duplicateWithoutContents();
clone.components.StaticMapEntity.origin.addInplace(tile);
if (placeable) {
for (let x = rect.x; x < rect.right(); ++x) {
for (let y = rect.y; y < rect.bottom(); ++y) {
const contents = root.map.getTileContentXY(x, y);
if (contents) {
assert(
contents.components.ReplaceableMapEntity,
"Can not delete entity for blueprint"
);
if (!root.logic.tryDeleteBuilding(contents)) {
logger.error(
"Building has replaceable component but is also unremovable in blueprint"
);
return false;
}
}
}
}
root.map.placeStaticEntity(clone);
root.entityMgr.registerEntity(clone);
anyPlaced = true;
const clone = entity.duplicateWithoutContents();
clone.components.StaticMapEntity.origin.addInplace(tile);
root.map.placeStaticEntity(clone);
root.entityMgr.registerEntity(clone);
anyPlaced = true;
}
}
}
return anyPlaced;
return anyPlaced;
});
}
}

View File

@@ -21,6 +21,7 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
keyActionMapper
.getBinding(KEYMAPPINGS.placement.abortBuildingPlacement)
.add(this.abortPlacement, this);
keyActionMapper.getBinding(KEYMAPPINGS.placement.rotateWhilePlacing).add(this.rotateBlueprint, this);
this.root.camera.downPreHandler.add(this.onMouseDown, this);
this.root.camera.movePreHandler.add(this.onMouseMove, this);
@@ -54,13 +55,13 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
return;
}
console.log("down");
const worldPos = this.root.camera.screenToWorld(pos);
const tile = worldPos.toTileSpace();
if (blueprint.tryPlace(this.root, tile)) {
if (!this.root.app.inputMgr.shiftIsDown) {
this.currentBlueprint.set(null);
}
// This actually feels weird
// if (!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeMultiple).currentlyDown) {
// this.currentBlueprint.set(null);
// }
}
}
@@ -81,6 +82,16 @@ export class HUDBlueprintPlacer extends BaseHUDPart {
this.currentBlueprint.set(Blueprint.fromUids(this.root, uids));
}
rotateBlueprint() {
if (this.currentBlueprint.get()) {
if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateInverseModifier).currentlyDown) {
this.currentBlueprint.get().rotateCcw();
} else {
this.currentBlueprint.get().rotateCw();
}
}
}
/**
*
* @param {DrawParameters} parameters

View File

@@ -161,14 +161,19 @@ export class HUDBuildingPlacer extends BaseHUDPart {
if (
metaBuilding &&
metaBuilding.getRotateAutomaticallyWhilePlacing(this.currentVariant.get()) &&
!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation).currentlyDown
!this.root.keyMapper.getBinding(
KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation
).currentlyDown
) {
const delta = newPos.sub(oldPos);
const angleDeg = Math_degrees(delta.angle());
this.currentBaseRotation = (Math.round(angleDeg / 90) * 90 + 360) % 360;
// Holding alt inverts the placement
if (this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeInverse).currentlyDown) {
if (
this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placeInverse)
.currentlyDown
) {
this.currentBaseRotation = (180 + this.currentBaseRotation) % 360;
}
}
@@ -389,7 +394,12 @@ export class HUDBuildingPlacer extends BaseHUDPart {
tryRotate() {
const selectedBuilding = this.currentMetaBuilding.get();
if (selectedBuilding) {
this.currentBaseRotation = (this.currentBaseRotation + 90) % 360;
if (this.root.keyMapper.getBinding(KEYMAPPINGS.placement.rotateInverseModifier).currentlyDown) {
this.currentBaseRotation = (this.currentBaseRotation + 270) % 360;
} else {
this.currentBaseRotation = (this.currentBaseRotation + 90) % 360;
}
const staticComp = this.fakeEntity.components.StaticMapEntity;
staticComp.rotation = this.currentBaseRotation;
}
@@ -468,8 +478,10 @@ export class HUDBuildingPlacer extends BaseHUDPart {
// Succesfully placed
if (
metaBuilding.getFlipOrientationAfterPlacement() &&
!this.root.keyMapper.getBinding(KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation).currentlyDown
metaBuilding.getFlipOrientationAfterPlacement() &&
!this.root.keyMapper.getBinding(
KEYMAPPINGS.placementModifiers.placementDisableAutoOrientation
).currentlyDown
) {
this.currentBaseRotation = (180 + this.currentBaseRotation) % 360;
}

View File

@@ -1,24 +1,16 @@
import { BaseHUDPart } from "../base_hud_part";
import { makeDiv } from "../../../core/utils";
import { getStringForKeyCode, KEYMAPPINGS } from "../../key_action_mapper";
import { TrackedState } from "../../../core/tracked_state";
import { queryParamOptions } from "../../../core/query_parameters";
import { T } from "../../../translations";
import { getStringForKeyCode, KEYMAPPINGS } from "../../key_action_mapper";
import { BaseHUDPart } from "../base_hud_part";
export class HUDKeybindingOverlay extends BaseHUDPart {
initialize() {
this.shiftDownTracker = new TrackedState(this.onShiftStateChanged, this);
this.root.hud.signals.selectedPlacementBuildingChanged.add(
this.onSelectedBuildingForPlacementChanged,
this
);
}
onShiftStateChanged(shiftDown) {
this.element.classList.toggle("shiftDown", shiftDown);
}
createElements(parent) {
const mapper = this.root.keyMapper;
@@ -70,7 +62,9 @@ export class HUDKeybindingOverlay extends BaseHUDPart {
</div>
<div class="binding placementOnly">
<code class="keybinding builtinKey shift">⇧ ${T.global.keys.shift}</code>
<code class="keybinding builtinKey shift">⇧ ${getKeycode(
KEYMAPPINGS.placementModifiers.placeMultiple
)}</code>
<label>${T.ingame.keybindingsOverlay.placeMultiple}</label>
</div>
`
@@ -81,7 +75,5 @@ export class HUDKeybindingOverlay extends BaseHUDPart {
this.element.classList.toggle("placementActive", !!selectedMetaBuilding);
}
update() {
this.shiftDownTracker.set(this.root.app.inputMgr.shiftIsDown);
}
update() {}
}