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

Add support for different building variants

This commit is contained in:
tobspr
2020-05-16 22:45:40 +02:00
parent 436f700606
commit 5e3c28c150
66 changed files with 1196 additions and 466 deletions

View File

@@ -1,5 +1,5 @@
import { BaseHUDPart } from "../base_hud_part";
import { MetaBuilding } from "../../meta_building";
import { MetaBuilding, defaultBuildingVariant } from "../../meta_building";
import { DrawParameters } from "../../../core/draw_parameters";
import { globalConfig } from "../../../core/config";
import { StaticMapEntityComponent } from "../../components/static_map_entity";
@@ -10,7 +10,7 @@ import {
enumInvertedDirections,
enumDirectionToVector,
} from "../../../core/vector";
import { pulseAnimation, makeDiv } from "../../../core/utils";
import { pulseAnimation, makeDiv, removeAllChildren } from "../../../core/utils";
import { DynamicDomAttach } from "../dynamic_dom_attach";
import { TrackedState } from "../../../core/tracked_state";
import { Math_abs, Math_radians, Math_degrees } from "../../../core/builtins";
@@ -32,6 +32,7 @@ export class HUDBuildingPlacer extends BaseHUDPart {
keyActionMapper.getBinding("back").add(this.abortPlacement, this);
keyActionMapper.getBinding("rotate_while_placing").add(this.tryRotate, this);
keyActionMapper.getBinding("cycle_variants").add(this.cycleVariants, this);
this.domAttach = new DynamicDomAttach(this.root, this.element, {});
@@ -40,6 +41,15 @@ export class HUDBuildingPlacer extends BaseHUDPart {
this.root.camera.upPostHandler.add(this.abortDragging, this);
this.currentlyDragging = false;
this.currentVariant = new TrackedState(this.rerenderVariants, this);
this.variantsAttach = new DynamicDomAttach(this.root, this.variantsElement, {});
/**
* Stores which variants for each building we prefer, this is based on what
* the user last selected
*/
this.preferredVariants = {};
/**
* The tile we last dragged onto
@@ -55,7 +65,7 @@ export class HUDBuildingPlacer extends BaseHUDPart {
}
createElements(parent) {
this.element = makeDiv(parent, "ingame_HUD_building_placer", [], ``);
this.element = makeDiv(parent, "ingame_HUD_PlacementHints", [], ``);
this.buildingInfoElements = {};
this.buildingInfoElements.label = makeDiv(this.element, null, ["buildingLabel"], "Extract");
@@ -63,6 +73,8 @@ export class HUDBuildingPlacer extends BaseHUDPart {
this.buildingInfoElements.descText = makeDiv(this.buildingInfoElements.desc, null, ["text"], "");
this.buildingInfoElements.hotkey = makeDiv(this.buildingInfoElements.desc, null, ["hotkey"], "");
this.buildingInfoElements.tutorialImage = makeDiv(this.element, null, ["buildingImage"]);
this.variantsElement = makeDiv(parent, "ingame_HUD_PlacerVariants");
}
abortPlacement() {
@@ -106,8 +118,17 @@ export class HUDBuildingPlacer extends BaseHUDPart {
const oldPos = this.lastDragTile;
const newPos = this.root.camera.screenToWorld(pos).toTileSpace();
if (this.root.camera.desiredCenter) {
// Camera is moving
this.lastDragTile = newPos;
return;
}
if (!oldPos.equals(newPos)) {
if (metaBuilding.getRotateAutomaticallyWhilePlacing()) {
if (
metaBuilding.getRotateAutomaticallyWhilePlacing(this.currentVariant.get()) &&
!this.root.app.inputMgr.ctrlIsDown
) {
const delta = newPos.sub(oldPos);
const angleDeg = Math_degrees(delta.angle());
this.currentBaseRotation = (Math.round(angleDeg / 90) * 90 + 360) % 360;
@@ -177,7 +198,6 @@ export class HUDBuildingPlacer extends BaseHUDPart {
}
/**
*
* @param {MetaBuilding} metaBuilding
*/
onSelectedMetaBuildingChanged(metaBuilding) {
@@ -189,16 +209,18 @@ export class HUDBuildingPlacer extends BaseHUDPart {
const binding = this.root.gameState.keyActionMapper.getBinding(
"building_" + metaBuilding.getId()
);
this.buildingInfoElements.hotkey.innerHTML = "Hotkey: " + binding.getKeyCodeString();
const variant = this.preferredVariants[metaBuilding.getId()] || defaultBuildingVariant;
this.currentVariant.set(variant);
this.fakeEntity = new Entity(null);
metaBuilding.setupEntityComponents(this.fakeEntity, null);
metaBuilding.setupEntityComponents(this.fakeEntity, null, variant);
this.fakeEntity.addComponent(
new StaticMapEntityComponent({
origin: new Vector(0, 0),
rotation: 0,
tileSize: metaBuilding.getDimensions().copy(),
tileSize: metaBuilding.getDimensions(this.currentVariant.get()).copy(),
})
);
@@ -210,6 +232,74 @@ export class HUDBuildingPlacer extends BaseHUDPart {
this.currentlyDragging = false;
this.fakeEntity = null;
}
// Since it depends on both, rerender twice
this.rerenderVariants();
}
rerenderVariants() {
removeAllChildren(this.variantsElement);
const metaBuilding = this.currentMetaBuilding.get();
if (!metaBuilding) {
return;
}
const availableVariants = metaBuilding.getAvailableVariants(this.root);
if (availableVariants.length === 1) {
return;
}
makeDiv(
this.variantsElement,
null,
["explanation"],
`
Press <code class='keybinding'>${this.root.gameState.keyActionMapper
.getBinding("cycle_variants")
.getKeyCodeString()}</code> to cycle variants.
`
);
for (let i = 0; i < availableVariants.length; ++i) {
const variant = availableVariants[i];
const element = makeDiv(this.variantsElement, null, ["variant"]);
element.classList.toggle("active", variant === this.currentVariant.get());
makeDiv(element, null, ["label"], variant);
const iconSize = 64;
const dimensions = metaBuilding.getDimensions(variant);
const sprite = metaBuilding.getPreviewSprite(0, variant);
const spriteWrapper = makeDiv(element, null, ["iconWrap"]);
spriteWrapper.setAttribute("data-tile-w", dimensions.x);
spriteWrapper.setAttribute("data-tile-h", dimensions.y);
spriteWrapper.innerHTML = sprite.getAsHTML(iconSize * dimensions.x, iconSize * dimensions.y);
}
}
/**
* Cycles through the variants
*/
cycleVariants() {
const metaBuilding = this.currentMetaBuilding.get();
if (!metaBuilding) {
this.currentVariant.set(defaultBuildingVariant);
} else {
const availableVariants = metaBuilding.getAvailableVariants(this.root);
const index = availableVariants.indexOf(this.currentVariant.get());
assert(
index >= 0,
"Current variant was invalid: " + this.currentVariant.get() + " out of " + availableVariants
);
const newIndex = (index + 1) % availableVariants.length;
const newVariant = availableVariants[newIndex];
this.currentVariant.set(newVariant);
this.preferredVariants[metaBuilding.getId()] = newVariant;
}
}
/**
@@ -290,6 +380,7 @@ export class HUDBuildingPlacer extends BaseHUDPart {
rotationVariant,
originalRotation: this.currentBaseRotation,
building: this.currentMetaBuilding.get(),
variant: this.currentVariant.get(),
})
) {
// Succesfully placed
@@ -317,10 +408,12 @@ export class HUDBuildingPlacer extends BaseHUDPart {
if (this.root.camera.zoomLevel < globalConfig.mapChunkOverviewMinZoom) {
// Dont allow placing in overview mode
this.domAttach.update(false);
this.variantsAttach.update(false);
return;
}
this.domAttach.update(this.currentMetaBuilding.get());
this.variantsAttach.update(this.currentMetaBuilding.get());
const metaBuilding = this.currentMetaBuilding.get();
if (!metaBuilding) {
@@ -382,7 +475,9 @@ export class HUDBuildingPlacer extends BaseHUDPart {
const staticComp = this.fakeEntity.components.StaticMapEntity;
staticComp.origin = tile;
staticComp.rotation = rotation;
staticComp.tileSize = metaBuilding.getDimensions(this.currentVariant.get());
metaBuilding.updateRotationVariant(this.fakeEntity, rotationVariant);
metaBuilding.updateVariant(this.fakeEntity, this.currentVariant.get());
// Check if we could place the buildnig
const canBuild = this.root.logic.checkCanPlaceBuilding({
@@ -390,6 +485,7 @@ export class HUDBuildingPlacer extends BaseHUDPart {
rotation,
rotationVariant,
building: metaBuilding,
variant: this.currentVariant.get(),
});
// Fade in / out
@@ -419,7 +515,7 @@ export class HUDBuildingPlacer extends BaseHUDPart {
parameters.context.globalAlpha = 1;
// HACK to draw the entity sprite
const previewSprite = metaBuilding.getBlueprintSprite(rotationVariant);
const previewSprite = metaBuilding.getBlueprintSprite(rotationVariant, this.currentVariant.get());
staticComp.origin = worldPos.divideScalar(globalConfig.tileSize).subScalars(0.5, 0.5);
staticComp.drawSpriteOnFullEntityBounds(parameters, previewSprite);
staticComp.origin = tile;

View File

@@ -57,24 +57,14 @@ export class HUDBuildingsToolbar extends BaseHUDPart {
const actionMapper = this.root.gameState.keyActionMapper;
const items = makeDiv(this.element, null, ["buildings"]);
const iconSize = 32;
for (let i = 0; i < toolbarBuildings.length; ++i) {
const metaBuilding = gMetaBuildingRegistry.findByClass(toolbarBuildings[i]);
const binding = actionMapper.getBinding("building_" + metaBuilding.getId());
const dimensions = metaBuilding.getDimensions();
const itemContainer = makeDiv(items, null, ["building"]);
itemContainer.setAttribute("data-tilewidth", dimensions.x);
itemContainer.setAttribute("data-tileheight", dimensions.y);
itemContainer.setAttribute("data-icon", "building_icons/" + metaBuilding.getId() + ".png");
const label = makeDiv(itemContainer, null, ["label"]);
label.innerText = metaBuilding.getName();
const sprite = metaBuilding.getPreviewSprite(0);
const spriteWrapper = makeDiv(itemContainer, null, ["iconWrap"]);
spriteWrapper.innerHTML = sprite.getAsHTML(iconSize * dimensions.x, iconSize * dimensions.y);
binding.add(() => this.selectBuildingForPlacement(metaBuilding));
this.trackClicks(itemContainer, () => this.selectBuildingForPlacement(metaBuilding), {

View File

@@ -72,6 +72,11 @@ export class HUDKeybindingOverlay extends BaseHUDPart {
<code class="keybinding shift">ALT</code>
<label>Reverse orientation</label>
</div>
<div class="binding placementOnly">
<code class="keybinding shift">CTRL</code>
<label>Disable auto orientation</label>
</div>
` +
(queryParamOptions.betaMode
? `

View File

@@ -5,12 +5,7 @@ import { Application } from "../../../application";
import { SOUNDS } from "../../../platform/sound";
import { DynamicDomAttach } from "../dynamic_dom_attach";
import { BaseHUDPart } from "../base_hud_part";
import {
Dialog,
DialogLoading,
DialogVideoTutorial,
DialogOptionChooser,
} from "../../../core/modal_dialog_elements";
import { Dialog, DialogLoading, DialogOptionChooser } from "../../../core/modal_dialog_elements";
import { makeDiv } from "../../../core/utils";
export class HUDModalDialogs extends BaseHUDPart {

View File

@@ -94,7 +94,7 @@ export class HUDShapeStatisticsHandle {
if (displayMode === enumDisplayMode.detailed) {
const graphDpi = globalConfig.statisticsGraphDpi;
const w = 300;
const w = 270;
const h = 40;
if (!this.graphCanvas) {