Skip to content

Commit

Permalink
Added #shadow mask
Browse files Browse the repository at this point in the history
  • Loading branch information
SIsilicon committed Nov 5, 2024
1 parent 783558c commit cd77f1c
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 23 deletions.
22 changes: 17 additions & 5 deletions src/library/utils/vector.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import { Vector3 } from "@minecraft/server";
import { Direction, Vector3 } from "@minecraft/server";
import { Matrix } from "./matrix";

type anyVec = Vector3 | [number, number, number];
type anyVec = Vector3 | [number, number, number] | Direction;

export type axis = "x" | "y" | "z";

const DIRECTION_VECTORS: Record<Direction, [number, number, number]> = {
[Direction.Up]: [0, 1, 0],
[Direction.Down]: [0, -1, 0],
[Direction.North]: [0, 0, -1],
[Direction.South]: [0, 0, 1],
[Direction.East]: [1, 0, 0],
[Direction.West]: [-1, 0, 0],
};

export class Vector {
private vals: [number, number, number] = [0, 0, 0];

Expand All @@ -28,9 +37,8 @@ export class Vector {
}

static from(loc: anyVec) {
if (Array.isArray(loc)) {
return new Vector(...loc);
}
if (Array.isArray(loc)) return new Vector(...loc);
else if (typeof loc === "string") return new Vector(...DIRECTION_VECTORS[loc]);
return new Vector(loc.x, loc.y, loc.z);
}

Expand All @@ -50,6 +58,10 @@ export class Vector {
return Vector.from(a).max(b);
}

static equals(a: anyVec, b: anyVec) {
return Vector.from(a).equals(b);
}

constructor(x: number, y: number, z: number) {
this.vals = [x, y, z];
}
Expand Down
65 changes: 47 additions & 18 deletions src/server/modules/mask.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Vector3, BlockPermutation, BlockFilter } from "@minecraft/server";
import { Vector3, BlockPermutation, BlockFilter, Direction } from "@minecraft/server";
import { CustomArgType, commandSyntaxError, Vector } from "@notbeer-api";
import { Token } from "./extern/tokenizr.js";
import {
Expand Down Expand Up @@ -38,7 +38,7 @@ export class Mask implements CustomArgType {

withContext(session: PlayerSession) {
const mask = this.clone();
mask.context.placePosition = session.getPlacementPosition();
mask.context.placePosition = Vector.from(session.getPlayer().getHeadLocation()); //session.getPlacementPosition().add(0.5);
return mask;
}

Expand All @@ -48,10 +48,8 @@ export class Mask implements CustomArgType {
* @returns True if the block matches; false otherwise
*/
matchesBlock(block: BlockUnit) {
if (this.empty()) {
return true;
}
return this.condition.matchesBlock(block);
if (this.empty()) return true;
return this.condition.matchesBlock(block, this.context);
}

clear() {
Expand Down Expand Up @@ -184,9 +182,7 @@ export class Mask implements CustomArgType {

static parseArgs(args: Array<string>, index = 0) {
const input = args[index];
if (!input) {
return { result: new Mask(), argIndex: index + 1 };
}
if (!input) return { result: new Mask(), argIndex: index + 1 };

const tokens = tokenize(input);
let token: Token;
Expand Down Expand Up @@ -233,6 +229,8 @@ export class Mask implements CustomArgType {
out.push(new ExistingMask(nodeToken()));
} else if (t.value == "surface" || t.value == "exposed") {
out.push(new SurfaceMask(nodeToken()));
} else if (t.value == "shadow") {
out.push(new ShadowMask(nodeToken()));
} else if (t.value == "#") {
const id = tokens.next();
if (id.type != "id") {
Expand Down Expand Up @@ -321,7 +319,7 @@ abstract class MaskNode implements AstNode {

constructor(public readonly token: Token) {}

abstract matchesBlock(block: BlockUnit): boolean;
abstract matchesBlock(block: BlockUnit, context: maskContext): boolean;

// eslint-disable-next-line @typescript-eslint/no-empty-function
postProcess() {}
Expand Down Expand Up @@ -403,6 +401,36 @@ class ExistingMask extends MaskNode {
}
}

class ShadowMask extends MaskNode {
readonly prec = -1;
readonly opCount = 0;

static readonly testFaces = [
Vector.from(Direction.Up).mul(0.5),
Vector.from(Direction.Down).mul(0.5),
Vector.from(Direction.North).mul(0.5),
Vector.from(Direction.South).mul(0.5),
Vector.from(Direction.East).mul(0.5),
Vector.from(Direction.West).mul(0.5),
];

matchesBlock(block: BlockUnit, context: maskContext) {
const start = context.placePosition;
const toBlock = Vector.sub(Vector.add(block.location, [0.5, 0.5, 0.5]), start);
for (const face of ShadowMask.testFaces) {
if (face.dot(toBlock) > 0) continue;
const target = Vector.add(block.location, face).add(0.5);
const ray = Vector.sub(target, start);
const hit = block.dimension.getBlockFromRay(start, ray, { includePassableBlocks: false, includeLiquidBlocks: false });
if (!hit) return false;

const hitLocation = Vector.add(hit.block, hit.faceLocation);
if (Vector.sub(hitLocation, start).length > ray.length + 0.01 || Vector.equals(hit.block, block.location)) return false;
}
return true;
}
}

class TagMask extends MaskNode {
readonly prec = -1;
readonly opCount = 0;
Expand Down Expand Up @@ -439,9 +467,9 @@ class ChainMask extends MaskNode {
readonly prec = 3;
readonly opCount = 2;

matchesBlock(block: BlockUnit) {
matchesBlock(block: BlockUnit, context: maskContext) {
for (const mask of this.nodes) {
if (mask.matchesBlock(block)) return true;
if (mask.matchesBlock(block, context)) return true;
}
return false;
}
Expand Down Expand Up @@ -470,9 +498,9 @@ class IntersectMask extends MaskNode {
readonly prec = 1;
readonly opCount = 2;

matchesBlock(block: BlockUnit) {
matchesBlock(block: BlockUnit, context: maskContext) {
for (const mask of this.nodes) {
if (!mask.matchesBlock(block)) return false;
if (!mask.matchesBlock(block, context)) return false;
}
return true;
}
Expand Down Expand Up @@ -501,8 +529,8 @@ class NegateMask extends MaskNode {
readonly prec = 2;
readonly opCount = 1;

matchesBlock(block: BlockUnit) {
return !this.nodes[0].matchesBlock(block);
matchesBlock(block: BlockUnit, context: maskContext) {
return !this.nodes[0].matchesBlock(block, context);
}
}

Expand All @@ -520,14 +548,15 @@ class OffsetMask extends MaskNode {
super(token);
}

matchesBlock(block: BlockUnit) {
matchesBlock(block: BlockUnit, context: maskContext) {
const loc = block.location;
return this.nodes[0].matchesBlock(
block.dimension.getBlock({
x: loc.x + this.x,
y: loc.y + this.y,
z: loc.z + this.z,
})
}),
context
);
}

Expand Down

0 comments on commit cd77f1c

Please sign in to comment.