Skip to content

Commit

Permalink
Cursed broken score matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
MulverineX committed Nov 22, 2023
1 parent ea270fe commit 7a6b430
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 44 deletions.
2 changes: 2 additions & 0 deletions src/commands/implementations/entity/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ export class ExecuteIfUnlessCommand<MACRO extends boolean> extends ExecuteComman
/** Checks whether the data point exists or the targeted block, entity or storage has any data for a given tag. */
data(dataPoint: DataPointClass): void

data(): ExecuteDataArgsCommand<MACRO>

data(dataPoint?: DataPointClass) {
if (dataPoint) {
return this.nestedExecute(dataPoint._toMinecraftCondition().getCondition() as [''])
Expand Down
2 changes: 1 addition & 1 deletion src/commands/implementations/server/return.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export class ReturnCommand<MACRO extends boolean> extends CommandArguments {
protected NodeType = ReturnCommandNode

get return() {
const run = new ReturnArgumentsCommand(this.sandstonePack)
const run = new ReturnArgumentsCommand<MACRO>(this.sandstonePack)

return makeCallable(run, (value: Macroable<number, MACRO>) => this.finalCommand([value]), true)
}
Expand Down
1 change: 1 addition & 0 deletions src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './commands.js'
export * from './helpers.js'
export * from './implementations/index.js'
15 changes: 14 additions & 1 deletion src/pack/visitors/containerCommandsToMCFunction.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
/* eslint-disable dot-notation */

import { ContainerCommandNode } from 'sandstone/core'

import { GenericSandstoneVisitor } from './visitor.js'

import type { ContainerCommandNode, MCFunctionNode } from 'sandstone/core'
import type { MCFunctionNode } from 'sandstone/core'

// let bippity = 0

// let boppity = 0

/**
* Transforms an execute with several nodes into an execute calling a new function.
Expand All @@ -11,17 +17,24 @@ export class ContainerCommandsToMCFunctionVisitor extends GenericSandstoneVisito
currentMCFunction: MCFunctionNode | null = null

visitContainerCommandNode = (node_: ContainerCommandNode) => {
// console.log('bippity', bippity++)
const { node, mcFunction } = node_.createMCFunction(this.currentMCFunction)

if (mcFunction) {
const visitedMCFunction = this.visitMCFunctionNode(mcFunction)
this.core.resourceNodes.add(visitedMCFunction)
} else if (node instanceof ContainerCommandNode && node.body) {
for (const [i, child] of node.body.entries()) {
const visit = this.visit(child)
node.body.splice(i, 1, ...(Array.isArray(visit) ? visit : [visit]))
}
}

return Array.isArray(node) ? node.flatMap((n) => this.visit(n)) : node
}

visitMCFunctionNode = (node: MCFunctionNode) => {
// console.log('boppity', boppity++)
const prev = this.currentMCFunction

this.currentMCFunction = node
Expand Down
7 changes: 5 additions & 2 deletions src/pack/visitors/ifElseTransformationVisitor.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-spaced-func */
/* eslint-disable func-call-spacing */
import { ExecuteCommandNode, ReturnCommandNode } from 'sandstone/commands'
import { ExecuteCommandNode, ReturnCommandNode, ReturnRunCommandNode } from 'sandstone/commands'
import { IfNode } from 'sandstone/flow'

import { GenericSandstoneVisitor } from './visitor.js'
Expand Down Expand Up @@ -62,7 +62,10 @@ export class IfElseTransformationVisitor extends GenericSandstoneVisitor {
return new ExecuteCommandNode(this.pack, [[node.condition.getValue()]], {
isSingleExecute: false,
givenCallbackName: `${i}_${callbackName}`,
body: body.map((_node) => this.genericVisit(_node)),
body: [new ReturnRunCommandNode(this.pack, ['run'], {
isSingleExecute: false,
body: body.map((_node) => this.genericVisit(_node)),
})],
})
}
// Else node, just add the body
Expand Down
4 changes: 2 additions & 2 deletions src/pack/visitors/unifyChainedExecutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export class UnifyChainedExecutesVisitor extends GenericSandstoneVisitor {
}

const chainedCommand = node.body[0]
if (chainedCommand instanceof ExecuteCommandNode) {
if (chainedCommand && chainedCommand instanceof ExecuteCommandNode) {
// The chained command is an execute.
node.body = [chainedCommand.body[0]]
node.body = chainedCommand.body

node.args.push(...chainedCommand.args)
}
Expand Down
95 changes: 57 additions & 38 deletions src/variables/Score.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { rangeParser } from './parsers.js'
import type {
COMPARISON_OPERATORS, FormattingTags, JSONTextComponent, MultipleEntitiesArgument, ObjectiveArgument, OPERATORS, Range,
} from 'sandstone/arguments'
import type { FinalCommandOutput, SandstoneCommands } from 'sandstone/commands'
import type { NotNode } from 'sandstone/flow'
import type { ConditionClass } from 'sandstone/variables'
import type { SandstoneCommands } from '../commands/index.js'
import type { SandstonePack } from '../pack/index.js'
import type { ComponentClass } from './abstractClasses.js'
import type { DATA_TYPES, DataPointClass } from './Data.js'
Expand Down Expand Up @@ -613,51 +613,70 @@ export class Score extends MacroArgument implements ConditionClass, ComponentCla
_toMinecraftCondition: () => new this.sandstonePack.conditions.Score(this.sandstonePack.core, [`${this.target}`, `${this.objective}`, 'matches', rangeParser(range)]),
})

match = (minimum: number, maximum: number, callback: (num: number) => void) => {
const { _ } = this.sandstonePack
match = (minimum: number, maximum: number, callback: (returnCmd: (SandstoneCommands<false> & ((_callback: () => any) => FinalCommandOutput)), num: number) => void) => {
const { _, commands: { execute }, MCFunction } = this.sandstonePack
// First, specify we didn't find a match yet
const foundMatch = this.sandstoneCore.pack.Variable(0)

const callCallback = (num: number) => {
_.if(_.and(this['=='](num), foundMatch['=='](0)), () => {
_.return.run(() => {
// If we found the correct score, call the callback & specify we found a match
callback(num)
foundMatch.set(1)
})
})
// If we found the correct score, call the callback & specify we found a match
callback(execute.if.score(this, 'matches', num).run.returnCmd.run, num)
}

// Recursively match the score
const recursiveMatch = (min: number, max: number) => {
const diff = max - min
// I actually have no idea why this is needed, but it is
const total = maximum - minimum - 1

if (diff < 0) {
return
}
const score = this

if (diff === 3) {
callCallback(min)
callCallback(min + 1)
callCallback(min + 2)
return
}
if (diff === 2) {
callCallback(min)
callCallback(min + 1)
return
}
if (diff === 1) {
callCallback(min)
return
}
// This is my personal hell

const mean = Math.floor((min + max) / 2)
let executeCount = 0

_.if(this['<'](mean), () => _.return.run(() => recursiveMatch(min, mean)))
_.if(this['>='](mean), () => _.return.run(() => recursiveMatch(mean, max)))
}
function split(currentTotal: number, current: number) {
if (currentTotal > 10) {
const chunks = Math.floor(currentTotal / 10)

if (chunks > 10) {
const _chunks = Math.floor(chunks / 10)

const chunkSize = Math.floor(currentTotal / _chunks)

for (let i = 0; i < _chunks; i += 1) {
const last = i === _chunks - 1

executeCount += 1

recursiveMatch(minimum, maximum)
const localCurrent = current + chunkSize * i

execute.if.score(score, 'matches', `${localCurrent}..${localCurrent + chunkSize - (last ? 0 : 1)}`).run.returnCmd.run(() => split(chunkSize, localCurrent))
}

executeCount += 1

execute.if.score(score, 'matches', `${(chunkSize * _chunks) + current}..`).run.returnCmd.run(() => split((currentTotal % chunkSize) + 1, (chunkSize * _chunks) + current))
} else {
const chunkSize = Math.floor(currentTotal / chunks)

if (chunkSize > 10) {
executeCount += 2
execute.if.score(score, 'matches', `${current}..${current + 9}`).run.returnCmd.run(() => split(10, current))

execute.if.score(score, 'matches', `${10 + current}..`).run.returnCmd.run(() => split(currentTotal - 10, 10 + current))
} else {
for (let i = 0; i < chunks; i += 1) {
const localCurrent = (chunkSize * i) + current

executeCount += 1

execute.if.score(score, 'matches', `${localCurrent}..${localCurrent + chunkSize - 1}`).run.returnCmd.run(() => split(chunkSize, localCurrent))
}
}
}
}
if (currentTotal !== 0 && currentTotal <= 10) {
for (let i = 0; i < currentTotal; i += 1) {
callback(execute.if.score(score, 'matches', current + i).run.returnCmd.run, current + i)
}
}
}
split(total, minimum)
}
}

0 comments on commit 7a6b430

Please sign in to comment.