Add OR gate and different colors of wire based on the value

pull/567/head
tobspr 4 years ago
parent 49da768b73
commit 984bea1921

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 70 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

After

Width:  |  Height:  |  Size: 217 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 516 KiB

After

Width:  |  Height:  |  Size: 532 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1011 KiB

After

Width:  |  Height:  |  Size: 997 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

@ -8,12 +8,16 @@ import { enumLogicGateType, LogicGateComponent } from "../components/logic_gate"
/** @enum {string} */ /** @enum {string} */
export const enumLogicGateVariants = { export const enumLogicGateVariants = {
not: "not", not: "not",
xor: "xor",
or: "or",
}; };
/** @enum {string} */ /** @enum {string} */
export const enumVariantToGate = { export const enumVariantToGate = {
[defaultBuildingVariant]: enumLogicGateType.and, [defaultBuildingVariant]: enumLogicGateType.and,
[enumLogicGateVariants.not]: enumLogicGateType.not, [enumLogicGateVariants.not]: enumLogicGateType.not,
[enumLogicGateVariants.xor]: enumLogicGateType.xor,
[enumLogicGateVariants.or]: enumLogicGateType.or,
}; };
export class MetaLogicGateBuilding extends MetaBuilding { export class MetaLogicGateBuilding extends MetaBuilding {
@ -42,7 +46,12 @@ export class MetaLogicGateBuilding extends MetaBuilding {
} }
getAvailableVariants() { getAvailableVariants() {
return [defaultBuildingVariant, enumLogicGateVariants.not]; return [
defaultBuildingVariant,
enumLogicGateVariants.not,
enumLogicGateVariants.xor,
enumLogicGateVariants.or,
];
} }
/** /**
@ -57,7 +66,9 @@ export class MetaLogicGateBuilding extends MetaBuilding {
const pinComp = entity.components.WiredPins; const pinComp = entity.components.WiredPins;
switch (gateType) { switch (gateType) {
case enumLogicGateType.and: { case enumLogicGateType.and:
case enumLogicGateType.xor:
case enumLogicGateType.or: {
pinComp.setSlots([ pinComp.setSlots([
{ {
pos: new Vector(0, 0), pos: new Vector(0, 0),

@ -4,6 +4,8 @@ import { Component } from "../component";
export const enumLogicGateType = { export const enumLogicGateType = {
and: "and", and: "and",
not: "not", not: "not",
xor: "xor",
or: "or",
}; };
export class LogicGateComponent extends Component { export class LogicGateComponent extends Component {

@ -289,7 +289,7 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
const mousePosition = this.root.app.mousePosition; const mousePosition = this.root.app.mousePosition;
if (!mousePosition) { if (!mousePosition) {
// Not on screen // Not on screen
return; return false;
} }
const worldPos = this.root.camera.screenToWorld(mousePosition); const worldPos = this.root.camera.screenToWorld(mousePosition);
@ -298,8 +298,10 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
if (contents) { if (contents) {
if (this.root.logic.tryDeleteBuilding(contents)) { if (this.root.logic.tryDeleteBuilding(contents)) {
this.root.soundProxy.playUi(SOUNDS.destroyBuilding); this.root.soundProxy.playUi(SOUNDS.destroyBuilding);
return true;
} }
} }
return false;
} }
/** /**
@ -637,9 +639,10 @@ export class HUDBuildingPlacerLogic extends BaseHUDPart {
this.currentlyDragging = true; this.currentlyDragging = true;
this.currentlyDeleting = true; this.currentlyDeleting = true;
this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace(); this.lastDragTile = this.root.camera.screenToWorld(pos).toTileSpace();
this.deleteBelowCursor(); if (this.deleteBelowCursor()) {
return STOP_PROPAGATION; return STOP_PROPAGATION;
} }
}
// Cancel placement // Cancel placement
if (button === enumMouseButton.right && metaBuilding) { if (button === enumMouseButton.right && metaBuilding) {

@ -14,15 +14,17 @@ export class HUDLeverToggle extends BaseHUDPart {
* @param {enumMouseButton} button * @param {enumMouseButton} button
*/ */
downPreHandler(pos, button) { downPreHandler(pos, button) {
if (button === enumMouseButton.left) {
const tile = this.root.camera.screenToWorld(pos).toTileSpace(); const tile = this.root.camera.screenToWorld(pos).toTileSpace();
const contents = this.root.map.getLayerContentXY(tile.x, tile.y, enumLayer.regular); const contents = this.root.map.getLayerContentXY(tile.x, tile.y, enumLayer.regular);
if (contents) { if (contents) {
const leverComp = contents.components.Lever; const leverComp = contents.components.Lever;
if (leverComp) { if (leverComp) {
if (button === enumMouseButton.left) {
leverComp.toggled = !leverComp.toggled; leverComp.toggled = !leverComp.toggled;
return STOP_PROPAGATION; return STOP_PROPAGATION;
} else if (button === enumMouseButton.right) {
this.root.logic.tryDeleteBuilding(contents);
return STOP_PROPAGATION;
} }
} }
} }

@ -3,8 +3,14 @@ import { HUDBaseToolbar } from "./base_toolbar";
import { MetaWireBuilding } from "../../buildings/wire"; import { MetaWireBuilding } from "../../buildings/wire";
import { MetaConstantSignalBuilding } from "../../buildings/constant_signal"; import { MetaConstantSignalBuilding } from "../../buildings/constant_signal";
import { MetaLogicGateBuilding } from "../../buildings/logic_gate"; import { MetaLogicGateBuilding } from "../../buildings/logic_gate";
import { MetaLeverBuilding } from "../../buildings/lever";
const supportedBuildings = [MetaWireBuilding, MetaConstantSignalBuilding, MetaLogicGateBuilding]; const supportedBuildings = [
MetaWireBuilding,
MetaConstantSignalBuilding,
MetaLogicGateBuilding,
MetaLeverBuilding,
];
export class HUDWiresToolbar extends HUDBaseToolbar { export class HUDWiresToolbar extends HUDBaseToolbar {
constructor(root) { constructor(root) {

@ -98,6 +98,8 @@ export function initMetaBuildingRegistry() {
// Logic gate // Logic gate
registerBuildingVariant(32, MetaLogicGateBuilding); registerBuildingVariant(32, MetaLogicGateBuilding);
registerBuildingVariant(34, MetaLogicGateBuilding, enumLogicGateVariants.not); registerBuildingVariant(34, MetaLogicGateBuilding, enumLogicGateVariants.not);
registerBuildingVariant(35, MetaLogicGateBuilding, enumLogicGateVariants.xor);
registerBuildingVariant(36, MetaLogicGateBuilding, enumLogicGateVariants.or);
// Lever // Lever
registerBuildingVariant(33, MetaLeverBuilding); registerBuildingVariant(33, MetaLeverBuilding);

@ -39,8 +39,14 @@ export class LeverSystem extends GameSystemWithFilter {
if (entity && entity.components.Lever) { if (entity && entity.components.Lever) {
const sprite = entity.components.Lever.toggled ? this.spriteOn : this.spriteOff; const sprite = entity.components.Lever.toggled ? this.spriteOn : this.spriteOff;
const staticComp = entity.components.StaticMapEntity; const origin = entity.components.StaticMapEntity.origin;
staticComp.drawSpriteOnFullEntityBounds(parameters, sprite, 0); sprite.drawCached(
parameters,
origin.x * globalConfig.tileSize,
origin.y * globalConfig.tileSize,
globalConfig.tileSize,
globalConfig.tileSize
);
} }
} }
} }

@ -11,6 +11,8 @@ export class LogicGateSystem extends GameSystemWithFilter {
this.boundOperations = { this.boundOperations = {
[enumLogicGateType.and]: this.compute_AND.bind(this), [enumLogicGateType.and]: this.compute_AND.bind(this),
[enumLogicGateType.not]: this.compute_NOT.bind(this), [enumLogicGateType.not]: this.compute_NOT.bind(this),
[enumLogicGateType.xor]: this.compute_XOR.bind(this),
[enumLogicGateType.or]: this.compute_OR.bind(this),
}; };
} }
@ -95,4 +97,64 @@ export class LogicGateSystem extends GameSystemWithFilter {
const value = /** @type {BooleanItem} */ (item).value; const value = /** @type {BooleanItem} */ (item).value;
return value ? BOOL_FALSE_SINGLETON : BOOL_TRUE_SINGLETON; return value ? BOOL_FALSE_SINGLETON : BOOL_TRUE_SINGLETON;
} }
/**
* @param {Array<BaseItem|null>} parameters
* @returns {BaseItem}
*/
compute_XOR(parameters) {
assert(parameters.length === 2, "bad parameter count for XOR");
const param1 = parameters[0];
const param2 = parameters[1];
if (!param1 || !param2) {
// Not enough params
return null;
}
const itemType = param1.getItemType();
if (itemType !== param2.getItemType()) {
// Differing type
return BOOL_FALSE_SINGLETON;
}
if (itemType === enumItemType.boolean) {
return /** @type {BooleanItem} */ (param1).value ^ /** @type {BooleanItem} */ (param2).value
? BOOL_TRUE_SINGLETON
: BOOL_FALSE_SINGLETON;
}
return BOOL_FALSE_SINGLETON;
}
/**
* @param {Array<BaseItem|null>} parameters
* @returns {BaseItem}
*/
compute_OR(parameters) {
assert(parameters.length === 2, "bad parameter count for OR");
const param1 = parameters[0];
const param2 = parameters[1];
if (!param1 || !param2) {
// Not enough params
return null;
}
const itemType = param1.getItemType();
if (itemType !== param2.getItemType()) {
// Differing type
return BOOL_FALSE_SINGLETON;
}
if (itemType === enumItemType.boolean) {
return /** @type {BooleanItem} */ (param1).value || /** @type {BooleanItem} */ (param2).value
? BOOL_TRUE_SINGLETON
: BOOL_FALSE_SINGLETON;
}
return BOOL_FALSE_SINGLETON;
}
} }

@ -18,6 +18,7 @@ import { createLogger } from "../../core/logging";
import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins"; import { WiredPinsComponent, enumPinSlotType } from "../components/wired_pins";
import { getCodeFromBuildingData } from "../building_codes"; import { getCodeFromBuildingData } from "../building_codes";
import { BaseItem, enumItemType } from "../base_item"; import { BaseItem, enumItemType } from "../base_item";
import { BooleanItem } from "../items/boolean_item";
const logger = createLogger("wires"); const logger = createLogger("wires");
@ -75,10 +76,30 @@ export class WireSystem extends GameSystemWithFilter {
super(root, [WireComponent]); super(root, [WireComponent]);
this.wireSprites = { this.wireSprites = {
regular: {
[enumWireType.regular]: Loader.getSprite("sprites/buildings/wire.png"), [enumWireType.regular]: Loader.getSprite("sprites/buildings/wire.png"),
[enumWireType.turn]: Loader.getSprite("sprites/buildings/wire-turn.png"), [enumWireType.turn]: Loader.getSprite("sprites/buildings/wire-turn.png"),
[enumWireType.split]: Loader.getSprite("sprites/buildings/wire-split.png"), [enumWireType.split]: Loader.getSprite("sprites/buildings/wire-split.png"),
[enumWireType.cross]: Loader.getSprite("sprites/buildings/wire-cross.png"), [enumWireType.cross]: Loader.getSprite("sprites/buildings/wire-cross.png"),
},
conflict: {
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/conflict.png"),
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/conflict-turn.png"),
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/conflict-split.png"),
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/conflict-cross.png"),
},
shape: {
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/shape.png"),
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/shape-turn.png"),
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/shape-split.png"),
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/shape-cross.png"),
},
color: {
[enumWireType.regular]: Loader.getSprite("sprites/wires/sets/color.png"),
[enumWireType.turn]: Loader.getSprite("sprites/wires/sets/color-turn.png"),
[enumWireType.split]: Loader.getSprite("sprites/wires/sets/color-split.png"),
[enumWireType.cross]: Loader.getSprite("sprites/wires/sets/color-cross.png"),
},
}; };
this.root.signals.entityDestroyed.add(this.updateSurroundingWirePlacement, this); this.root.signals.entityDestroyed.add(this.updateSurroundingWirePlacement, this);
@ -406,6 +427,64 @@ export class WireSystem extends GameSystemWithFilter {
} }
} }
/**
* Returns the given tileset and opacity
* @param {WireComponent} wireComp
* @returns {{ spriteSet: Object<enumWireType, import("../../core/draw_utils").AtlasSprite>, opacity: number}}
*/
getSpriteSetAndOpacityForWire(wireComp) {
if (!wireComp.linkedNetwork) {
// There is no network, it's empty
return {
spriteSet: this.wireSprites.regular,
opacity: 0.3,
};
}
const network = wireComp.linkedNetwork;
if (network.valueConflict) {
// There is a conflict
return {
spriteSet: this.wireSprites.conflict,
opacity: 1,
};
}
const value = network.currentValue;
if (!value) {
// There is no value stored
return {
spriteSet: this.wireSprites.regular,
opacity: 0.3,
};
}
const valueType = value.getItemType();
if (valueType === enumItemType.shape) {
return {
spriteSet: this.wireSprites.shape,
opacity: 1,
};
} else if (valueType === enumItemType.color) {
return {
spriteSet: this.wireSprites.color,
opacity: 1,
};
} else if (valueType === enumItemType.boolean) {
return {
spriteSet: this.wireSprites.regular,
opacity: /** @type {BooleanItem} */ (value).value ? 1 : 0.5,
};
} else {
assertAlways(false, "Unknown item type: " + valueType);
}
return {
spriteSet: this.wireSprites.regular,
opacity: 1,
};
}
/** /**
* Draws a given chunk * Draws a given chunk
* @param {import("../../core/draw_utils").DrawParameters} parameters * @param {import("../../core/draw_utils").DrawParameters} parameters
@ -421,31 +500,30 @@ export class WireSystem extends GameSystemWithFilter {
const wireType = wireComp.type; const wireType = wireComp.type;
const network = wireComp.linkedNetwork; const network = wireComp.linkedNetwork;
let opacity = 1; const { opacity, spriteSet } = this.getSpriteSetAndOpacityForWire(wireComp);
let spriteSet = this.wireSprites;
// if (!network) {
if (!network) { // opacity = 0.3;
opacity = 0.3; // } else {
} else { // if (network.valueConflict) {
if (network.valueConflict) { // opacity = 1;
opacity = 1; // // TODO
// TODO // } else {
} else { // if (network.currentValue) {
if (network.currentValue) { // if (
if ( // network.currentValue.getItemType() === enumItemType.boolean &&
network.currentValue.getItemType() === enumItemType.boolean && // // @ts-ignore
// @ts-ignore // network.currentValue.value === 0
network.currentValue.value === 0 // ) {
) { // opacity = 0.5;
opacity = 0.5; // } else {
} else { // opacity = 1;
opacity = 1; // }
} // } else {
} else { // opacity = 0.5;
opacity = 0.5; // }
} // }
} // }
}
const sprite = spriteSet[wireType]; const sprite = spriteSet[wireType];

@ -563,10 +563,16 @@ buildings:
logic_gate: logic_gate:
default: default:
name: &logic_gate AND Gate name: &logic_gate AND Gate
description: Emits a boolean signal if both inputs are truthy. description: Emits a truthy boolean signal if both inputs are truthy.
not: not:
name: NOT name: NOT
description: Inverts the given signal description: Inverts the given signal.
xor:
name: XOR
description: Emits a truthy signal if one of the inputs is truthy, but not both.
or:
name: OR
description: Emits a truthy signal if one of the inputs is truthy.
storyRewards: storyRewards:
# Those are the rewards gained from completing the store # Those are the rewards gained from completing the store

Loading…
Cancel
Save