mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-12-14 02:31:51 +00:00
Direction lock now indicates when there is a building inbetween
This commit is contained in:
parent
f3a939b071
commit
4a76135d57
@ -65,10 +65,10 @@ class Mod extends shapez.Mod {
|
|||||||
// Only allow placing an entity when there is enough currency
|
// Only allow placing an entity when there is enough currency
|
||||||
this.modInterface.replaceMethod(shapez.GameLogic, "checkCanPlaceEntity", function (
|
this.modInterface.replaceMethod(shapez.GameLogic, "checkCanPlaceEntity", function (
|
||||||
$original,
|
$original,
|
||||||
[entity, offset]
|
[entity, options]
|
||||||
) {
|
) {
|
||||||
const storedCurrency = this.root.hubGoals.storedShapes[CURRENCY] || 0;
|
const storedCurrency = this.root.hubGoals.storedShapes[CURRENCY] || 0;
|
||||||
return storedCurrency > 0 && $original(entity, offset);
|
return storedCurrency > 0 && $original(entity, options);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Take shapes when placing a building
|
// Take shapes when placing a building
|
||||||
|
|||||||
@ -40,6 +40,10 @@ const RESOURCES = {
|
|||||||
color: "rgb(74, 237, 134)",
|
color: "rgb(74, 237, 134)",
|
||||||
background: "rgba(74, 237, 134, 0.2)",
|
background: "rgba(74, 237, 134, 0.2)",
|
||||||
},
|
},
|
||||||
|
error: {
|
||||||
|
color: "rgb(255, 137, 137)",
|
||||||
|
background: "rgba(255, 137, 137, 0.2)",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
colorBlindPickerTile: "rgba(50, 50, 50, 0.4)",
|
colorBlindPickerTile: "rgba(50, 50, 50, 0.4)",
|
||||||
|
|||||||
@ -82,7 +82,7 @@ export class Blueprint {
|
|||||||
const rect = staticComp.getTileSpaceBounds();
|
const rect = staticComp.getTileSpaceBounds();
|
||||||
rect.moveBy(tile.x, tile.y);
|
rect.moveBy(tile.x, tile.y);
|
||||||
|
|
||||||
if (!parameters.root.logic.checkCanPlaceEntity(entity, tile)) {
|
if (!parameters.root.logic.checkCanPlaceEntity(entity, { offset: tile })) {
|
||||||
parameters.context.globalAlpha = 0.3;
|
parameters.context.globalAlpha = 0.3;
|
||||||
} else {
|
} else {
|
||||||
parameters.context.globalAlpha = 1;
|
parameters.context.globalAlpha = 1;
|
||||||
@ -131,7 +131,7 @@ export class Blueprint {
|
|||||||
|
|
||||||
for (let i = 0; i < this.entities.length; ++i) {
|
for (let i = 0; i < this.entities.length; ++i) {
|
||||||
const entity = this.entities[i];
|
const entity = this.entities[i];
|
||||||
if (root.logic.checkCanPlaceEntity(entity, tile)) {
|
if (root.logic.checkCanPlaceEntity(entity, { offset: tile })) {
|
||||||
anyPlaceable = true;
|
anyPlaceable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ export class Blueprint {
|
|||||||
let count = 0;
|
let count = 0;
|
||||||
for (let i = 0; i < this.entities.length; ++i) {
|
for (let i = 0; i < this.entities.length; ++i) {
|
||||||
const entity = this.entities[i];
|
const entity = this.entities[i];
|
||||||
if (!root.logic.checkCanPlaceEntity(entity, tile)) {
|
if (!root.logic.checkCanPlaceEntity(entity, { offset: tile })) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,7 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
this.currentInterpolatedCornerTile = new Vector();
|
this.currentInterpolatedCornerTile = new Vector();
|
||||||
|
|
||||||
this.lockIndicatorSprites = {};
|
this.lockIndicatorSprites = {};
|
||||||
layers.forEach(layer => {
|
[...layers, "error"].forEach(layer => {
|
||||||
this.lockIndicatorSprites[layer] = this.makeLockIndicatorSprite(layer);
|
this.lockIndicatorSprites[layer] = this.makeLockIndicatorSprite(layer);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes the lock indicator sprite for the given layer
|
* Makes the lock indicator sprite for the given layer
|
||||||
* @param {Layer} layer
|
* @param {string} layer
|
||||||
*/
|
*/
|
||||||
makeLockIndicatorSprite(layer) {
|
makeLockIndicatorSprite(layer) {
|
||||||
const dims = 48;
|
const dims = 48;
|
||||||
@ -358,7 +358,7 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
rotationVariant
|
rotationVariant
|
||||||
);
|
);
|
||||||
|
|
||||||
const canBuild = this.root.logic.checkCanPlaceEntity(this.fakeEntity);
|
const canBuild = this.root.logic.checkCanPlaceEntity(this.fakeEntity, {});
|
||||||
|
|
||||||
// Fade in / out
|
// Fade in / out
|
||||||
parameters.context.lineWidth = 1;
|
parameters.context.lineWidth = 1;
|
||||||
@ -397,6 +397,42 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if there are any entities in the way, returns true if there are
|
||||||
|
* @param {Vector} from
|
||||||
|
* @param {Vector} to
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
checkForObstales(from, to) {
|
||||||
|
assert(from.x === to.x || from.y === to.y, "Must be a straight line");
|
||||||
|
|
||||||
|
const prop = from.x === to.x ? "y" : "x";
|
||||||
|
const current = from.copy();
|
||||||
|
|
||||||
|
const metaBuilding = this.currentMetaBuilding.get();
|
||||||
|
this.fakeEntity.layer = metaBuilding.getLayer();
|
||||||
|
const staticComp = this.fakeEntity.components.StaticMapEntity;
|
||||||
|
staticComp.origin = current;
|
||||||
|
staticComp.rotation = 0;
|
||||||
|
metaBuilding.updateVariants(this.fakeEntity, 0, this.currentVariant.get());
|
||||||
|
staticComp.code = getCodeFromBuildingData(
|
||||||
|
this.currentMetaBuilding.get(),
|
||||||
|
this.currentVariant.get(),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
const start = Math.min(from[prop], to[prop]);
|
||||||
|
const end = Math.max(from[prop], to[prop]);
|
||||||
|
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
|
current[prop] = i;
|
||||||
|
if (!this.root.logic.checkCanPlaceEntity(this.fakeEntity, { allowReplaceBuildings: false })) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {DrawParameters} parameters
|
* @param {DrawParameters} parameters
|
||||||
*/
|
*/
|
||||||
@ -407,55 +443,73 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const applyStyles = look => {
|
||||||
|
parameters.context.fillStyle = THEME.map.directionLock[look].color;
|
||||||
|
parameters.context.strokeStyle = THEME.map.directionLock[look].background;
|
||||||
|
parameters.context.lineWidth = 10;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!this.lastDragTile) {
|
||||||
|
// Not dragging yet
|
||||||
|
applyStyles(this.root.currentLayer);
|
||||||
|
const mouseWorld = this.root.camera.screenToWorld(mousePosition);
|
||||||
|
parameters.context.beginCircle(mouseWorld.x, mouseWorld.y, 4);
|
||||||
|
parameters.context.fill();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const mouseWorld = this.root.camera.screenToWorld(mousePosition);
|
const mouseWorld = this.root.camera.screenToWorld(mousePosition);
|
||||||
const mouseTile = mouseWorld.toTileSpace();
|
const mouseTile = mouseWorld.toTileSpace();
|
||||||
parameters.context.fillStyle = THEME.map.directionLock[this.root.currentLayer].color;
|
const startLine = this.lastDragTile.toWorldSpaceCenterOfTile();
|
||||||
parameters.context.strokeStyle = THEME.map.directionLock[this.root.currentLayer].background;
|
const endLine = mouseTile.toWorldSpaceCenterOfTile();
|
||||||
parameters.context.lineWidth = 10;
|
const midLine = this.currentDirectionLockCorner.toWorldSpaceCenterOfTile();
|
||||||
|
const anyObstacle =
|
||||||
|
this.checkForObstales(this.lastDragTile, this.currentDirectionLockCorner) ||
|
||||||
|
this.checkForObstales(this.currentDirectionLockCorner, mouseTile);
|
||||||
|
|
||||||
|
if (anyObstacle) {
|
||||||
|
applyStyles("error");
|
||||||
|
} else {
|
||||||
|
applyStyles(this.root.currentLayer);
|
||||||
|
}
|
||||||
|
|
||||||
parameters.context.beginCircle(mouseWorld.x, mouseWorld.y, 4);
|
parameters.context.beginCircle(mouseWorld.x, mouseWorld.y, 4);
|
||||||
parameters.context.fill();
|
parameters.context.fill();
|
||||||
|
|
||||||
if (this.lastDragTile) {
|
parameters.context.beginCircle(startLine.x, startLine.y, 8);
|
||||||
const startLine = this.lastDragTile.toWorldSpaceCenterOfTile();
|
parameters.context.fill();
|
||||||
const endLine = mouseTile.toWorldSpaceCenterOfTile();
|
|
||||||
const midLine = this.currentDirectionLockCorner.toWorldSpaceCenterOfTile();
|
|
||||||
|
|
||||||
parameters.context.beginCircle(startLine.x, startLine.y, 8);
|
parameters.context.beginPath();
|
||||||
parameters.context.fill();
|
parameters.context.moveTo(startLine.x, startLine.y);
|
||||||
|
parameters.context.lineTo(midLine.x, midLine.y);
|
||||||
|
parameters.context.lineTo(endLine.x, endLine.y);
|
||||||
|
parameters.context.stroke();
|
||||||
|
|
||||||
parameters.context.beginPath();
|
parameters.context.beginCircle(endLine.x, endLine.y, 5);
|
||||||
parameters.context.moveTo(startLine.x, startLine.y);
|
parameters.context.fill();
|
||||||
parameters.context.lineTo(midLine.x, midLine.y);
|
|
||||||
parameters.context.lineTo(endLine.x, endLine.y);
|
|
||||||
parameters.context.stroke();
|
|
||||||
|
|
||||||
parameters.context.beginCircle(endLine.x, endLine.y, 5);
|
// Draw arrow
|
||||||
parameters.context.fill();
|
const arrowSprite = this.lockIndicatorSprites[anyObstacle ? "error" : this.root.currentLayer];
|
||||||
|
const path = this.computeDirectionLockPath();
|
||||||
|
for (let i = 0; i < path.length - 1; i += 1) {
|
||||||
|
const { rotation, tile } = path[i];
|
||||||
|
const worldPos = tile.toWorldSpaceCenterOfTile();
|
||||||
|
const angle = Math.radians(rotation);
|
||||||
|
|
||||||
// Draw arrow
|
parameters.context.translate(worldPos.x, worldPos.y);
|
||||||
const arrowSprite = this.lockIndicatorSprites[this.root.currentLayer];
|
parameters.context.rotate(angle);
|
||||||
const path = this.computeDirectionLockPath();
|
parameters.context.drawImage(
|
||||||
for (let i = 0; i < path.length - 1; i += 1) {
|
arrowSprite,
|
||||||
const { rotation, tile } = path[i];
|
-6,
|
||||||
const worldPos = tile.toWorldSpaceCenterOfTile();
|
-globalConfig.halfTileSize -
|
||||||
const angle = Math.radians(rotation);
|
clamp((this.root.time.realtimeNow() * 1.5) % 1.0, 0, 1) * 1 * globalConfig.tileSize +
|
||||||
|
globalConfig.halfTileSize -
|
||||||
parameters.context.translate(worldPos.x, worldPos.y);
|
6,
|
||||||
parameters.context.rotate(angle);
|
12,
|
||||||
parameters.context.drawImage(
|
12
|
||||||
arrowSprite,
|
);
|
||||||
-6,
|
parameters.context.rotate(-angle);
|
||||||
-globalConfig.halfTileSize -
|
parameters.context.translate(-worldPos.x, -worldPos.y);
|
||||||
clamp((this.root.time.realtimeNow() * 1.5) % 1.0, 0, 1) * 1 * globalConfig.tileSize +
|
|
||||||
globalConfig.halfTileSize -
|
|
||||||
6,
|
|
||||||
12,
|
|
||||||
12
|
|
||||||
);
|
|
||||||
parameters.context.rotate(-angle);
|
|
||||||
parameters.context.translate(-worldPos.x, -worldPos.y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -53,10 +53,12 @@ export class GameLogic {
|
|||||||
/**
|
/**
|
||||||
* Checks if the given entity can be placed
|
* Checks if the given entity can be placed
|
||||||
* @param {Entity} entity
|
* @param {Entity} entity
|
||||||
* @param {Vector=} offset Optional, move the entity by the given offset first
|
* @param {Object} param0
|
||||||
|
* @param {boolean=} param0.allowReplaceBuildings
|
||||||
|
* @param {Vector=} param0.offset Optional, move the entity by the given offset first
|
||||||
* @returns {boolean} true if the entity could be placed there
|
* @returns {boolean} true if the entity could be placed there
|
||||||
*/
|
*/
|
||||||
checkCanPlaceEntity(entity, offset = null) {
|
checkCanPlaceEntity(entity, { allowReplaceBuildings = false, offset = null }) {
|
||||||
// Compute area of the building
|
// Compute area of the building
|
||||||
const rect = entity.components.StaticMapEntity.getTileSpaceBounds();
|
const rect = entity.components.StaticMapEntity.getTileSpaceBounds();
|
||||||
if (offset) {
|
if (offset) {
|
||||||
@ -71,7 +73,7 @@ export class GameLogic {
|
|||||||
const otherEntity = this.root.map.getLayerContentXY(x, y, entity.layer);
|
const otherEntity = this.root.map.getLayerContentXY(x, y, entity.layer);
|
||||||
if (otherEntity) {
|
if (otherEntity) {
|
||||||
const metaClass = otherEntity.components.StaticMapEntity.getMetaBuilding();
|
const metaClass = otherEntity.components.StaticMapEntity.getMetaBuilding();
|
||||||
if (!metaClass.getIsReplaceable()) {
|
if (!allowReplaceBuildings || !metaClass.getIsReplaceable()) {
|
||||||
// This one is a direct blocker
|
// This one is a direct blocker
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -116,7 +118,7 @@ export class GameLogic {
|
|||||||
rotationVariant,
|
rotationVariant,
|
||||||
variant,
|
variant,
|
||||||
});
|
});
|
||||||
if (this.checkCanPlaceEntity(entity)) {
|
if (this.checkCanPlaceEntity(entity, {})) {
|
||||||
this.freeEntityAreaBeforeBuild(entity);
|
this.freeEntityAreaBeforeBuild(entity);
|
||||||
this.root.map.placeStaticEntity(entity);
|
this.root.map.placeStaticEntity(entity);
|
||||||
this.root.entityMgr.registerEntity(entity);
|
this.root.entityMgr.registerEntity(entity);
|
||||||
|
|||||||
@ -18,6 +18,10 @@
|
|||||||
"wires": {
|
"wires": {
|
||||||
"color": "rgb(74, 237, 134)",
|
"color": "rgb(74, 237, 134)",
|
||||||
"background": "rgba(74, 237, 134, 0.2)"
|
"background": "rgba(74, 237, 134, 0.2)"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"color": "rgb(255, 137, 137)",
|
||||||
|
"background": "rgba(255, 137, 137, 0.2)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,10 @@
|
|||||||
"wires": {
|
"wires": {
|
||||||
"color": "rgb(74, 237, 134)",
|
"color": "rgb(74, 237, 134)",
|
||||||
"background": "rgba(74, 237, 134, 0.2)"
|
"background": "rgba(74, 237, 134, 0.2)"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"color": "rgb(255, 137, 137)",
|
||||||
|
"background": "rgba(255, 137, 137, 0.2)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user