Skip to content

Commit

Permalink
went crazy with type defs lol
Browse files Browse the repository at this point in the history
  • Loading branch information
GenerelSchwerz committed Feb 20, 2024
1 parent 42cba2b commit 5575ff9
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 31 deletions.
3 changes: 2 additions & 1 deletion examples/example.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use strict";
const { createBot } = require("mineflayer");
const { createPlugin, goals } = require("../dist");
const { GoalBlock, GoalLookAt, GoalPlaceBlock } = goals;
const { GoalBlock, GoalLookAt, GoalPlaceBlock, GoalInvert } = goals;
const { Vec3 } = require("vec3");
const rl = require('readline')
const { default: loader, EntityState, EPhysicsCtx, EntityPhysics } = require("@nxg-org/mineflayer-physics-util");
Expand Down Expand Up @@ -136,6 +136,7 @@ async function cmdHandler(username, msg) {
if (!author) return bot.whisper(username, "failed to find player");
const dist = parseInt(args[0]) || 1;
const goal = GoalFollowEntity.fromEntity(author, dist, {neverfinish: true});
const goal1 = GoalInvert.fromDyn(goal);
await bot.pathfinder.goto(goal);
break;
}
Expand Down
14 changes: 7 additions & 7 deletions src/ThePathfinder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,19 +387,20 @@ export class ThePathfinder {
const ret = bounded(...args)
if (ret) {
void this.reset('goalUpdated')
this.bot.off(goal.eventKey, list1)
for (const key of goal._eventKeys) this.bot.off(key, list1)
}
}

this.bot.on(goal.eventKey, list1)
for (const key of goal._eventKeys) this.bot.on(key, list1)

goal.cleanup = () => {
this.bot.off(goal.eventKey, list1)
for (const key of goal._eventKeys) this.bot.off(key, list1)
delete goal.cleanup
}

cleanup = () => {
old()
this.bot.off(goal.eventKey, list1)
for (const key of goal._eventKeys) this.bot.off(key, list1)
}
}

Expand Down Expand Up @@ -516,13 +517,12 @@ export class ThePathfinder {
const bounded = refGoal.hasChanged.bind(refGoal)
const listener = (...args: any[]): void => {
if (this.userAborted || bounded(...args)) {
console.log('hi', bounded(...args), this.bot.listenerCount(refGoal.eventKey))
refGoal.update()
this.bot.off(refGoal.eventKey, listener)
for (const key of refGoal._eventKeys) this.bot.off(key, listener)
resolve()
}
}
this.bot.on(refGoal.eventKey, listener)
for (const key of refGoal._eventKeys) this.bot.on(key, listener)
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/abstract/algorithms/astar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class AStar<Data extends PathData = PathData> implements Algorithm<Data>
movements: MovementProvider<Data>,
goal: Goal<Data>,
timeout: number,
tickTimeout = 45,
tickTimeout = 40,
searchRadius = -1,
differential = 0
) {
Expand Down
89 changes: 82 additions & 7 deletions src/mineflayer-specific/goals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,84 @@ export abstract class Goal implements AGoal<Move> {
async onFinish (node: MovementExecutor): Promise<void> {}
}

export abstract class GoalDynamic<Key extends keyof BotEvents> extends Goal {
type EasyKeys = keyof BotEvents | Array<keyof BotEvents>
export abstract class GoalDynamic<
Change extends EasyKeys = Array<keyof BotEvents>,
Valid extends EasyKeys = Array<keyof BotEvents>,
ChKey extends Change extends keyof BotEvents ? [Change] : Change = Change extends keyof BotEvents ? [Change] : Change,
VlKey extends Valid extends keyof BotEvents ? [Valid] : Valid = Valid extends keyof BotEvents ? [Valid] : Valid
> extends Goal {
dynamic = true
neverfinish = false
readonly abstract eventKey: Key
abstract hasChanged (...args: Parameters<BotEvents[Key]>): boolean
abstract readonly eventKeys: Readonly<Change>
abstract readonly validKeys: Readonly<Valid>
abstract hasChanged (...args: Parameters<BotEvents[ChKey[number]]>): boolean
abstract isValid (...args: Parameters<BotEvents[VlKey[number]]>): boolean
abstract update (): void
cleanup?: () => void // will be assigned later.

get _eventKeys (): ChKey {
if (this.eventKeys instanceof Array) return this.eventKeys as ChKey
return [this.eventKeys] as ChKey
}

get _validKeys (): VlKey {
if (this.validKeys instanceof Array) return this.validKeys as VlKey
return [this.validKeys] as VlKey
}
}

export class GoalInvert<Et extends EasyKeys = [], Val extends EasyKeys = []> extends GoalDynamic<Et, Val> {
eventKeys = [] as unknown as Et
validKeys = [] as unknown as Val // to be set later.

isDynamic = false

private constructor (private readonly goal: Goal) {
super()

if (goal instanceof GoalDynamic) {
this.eventKeys = goal._eventKeys
this.validKeys = goal._validKeys
this.isDynamic = true
}
}

static from (goal: Goal): GoalInvert {
return new GoalInvert(goal)
}

static fromDyn<
G extends GoalDynamic,
K0 extends EasyKeys = G extends GoalDynamic<infer K extends EasyKeys> ? K : never,
K1 extends EasyKeys = G extends GoalDynamic<any, infer V extends EasyKeys> ? V : never
>(goal: GoalDynamic<K0, K1>): GoalInvert<K0, K1> {
return new GoalInvert(goal)
}

isEnd (node: Move): boolean {
return !this.goal.isEnd(node)
}

heuristic (node: Move): number {
return -this.goal.heuristic(node)
}

hasChanged (...args: Parameters<BotEvents[keyof BotEvents]>): boolean {
if (!this.isDynamic) return false
return (this.goal as GoalDynamic).hasChanged(...args)
}

isValid (...args: Parameters<BotEvents[keyof BotEvents]>): boolean {
if (!this.isDynamic) return false
return (this.goal as GoalDynamic).isValid(...args)
}

update (): void {
if (this.goal instanceof GoalDynamic) this.goal.update()
}
}

/**
* A goal to be directly at a specific coordinate.
*/
Expand Down Expand Up @@ -265,10 +335,11 @@ export class GoalPlaceBlock extends GoalLookAt {
interface GoalFollowEntityOpts {
neverfinish?: boolean
dynamic?: boolean

}
export class GoalFollowEntity extends GoalDynamic<'entityMoved'> {
readonly eventKey = 'entityMoved' as const

export class GoalFollowEntity extends GoalDynamic<'entityMoved', 'entityGone'> {
readonly eventKeys = 'entityMoved' as const
readonly validKeys = 'entityGone' as const

public x: number
public y: number
Expand Down Expand Up @@ -306,7 +377,7 @@ export class GoalFollowEntity extends GoalDynamic<'entityMoved'> {
}

hasChanged (e: Entity): boolean {
// if (e.position !== this.refVec) return false;
if (e.position !== this.refVec) return false
const dx = this.x - this.refVec.x
const dy = this.y - this.refVec.y
const dz = this.z - this.refVec.z
Expand All @@ -319,6 +390,10 @@ export class GoalFollowEntity extends GoalDynamic<'entityMoved'> {
return ret
}

isValid (entity: Entity): boolean {
return entity.position === this.refVec
}

update (): void {
this.x = this.refVec.x
this.y = this.refVec.y
Expand Down
31 changes: 16 additions & 15 deletions src/mineflayer-specific/movements/movementProviders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,15 +430,29 @@ export class ParkourForward extends MovementProvider {

// if (blockC.safe) cost += this.getNumEntitiesAt(blockC.position, 0, 0, 0) * this.entityCost

if (ceilingClear && blockB.safe && blockC.safe && blockD.physical) {
if ((ceilingClear || d === 2) && blockB.safe && blockC.safe && blockD.safe && floorCleared) {
const off = blockD.position
if (closed.has(`${off.x},${off.y},${off.z}`)) continue

// Down
const blockE = this.getBlockInfo(node, dx, -2, dz)
if (blockE.physical) {
// cost += this.exclusionStep(blockD)
// cost += this.getNumEntitiesAt(blockD.position, 0, 0, 0) * this.entityCost
neighbors.push(Move.fromPrevious(cost, blockD.position.offset(0.5, 0, 0.5), node, this))
// neighbors.push(new Move(blockD.position.x, blockD.position.y, blockD.position.z, node.remainingBlocks, cost, [], [], true))
}
floorCleared = floorCleared && !blockE.physical
} else if (ceilingClear && blockB.safe && blockC.safe && blockD.physical) {
if (d === 5) continue
const cost1 = cost + 3 // potential slowdown (will fix later.)
// cost += this.exclusionStep(blockB)
// Forward

const off = blockC.position
if (closed.has(`${off.x},${off.y},${off.z}`)) continue

neighbors.push(Move.fromPrevious(cost, blockC.position.offset(0.5, 0, 0.5), node, this))
neighbors.push(Move.fromPrevious(cost1, blockC.position.offset(0.5, 0, 0.5), node, this))
// neighbors.push(new Move(blockC.position.x, blockC.position.y, blockC.position.z, node.remainingBlocks, cost, [], [], true))
break
} else if (ceilingClear && blockA.safe && blockB.safe && blockC.physical) {
Expand All @@ -456,19 +470,6 @@ export class ParkourForward extends MovementProvider {
// neighbors.push(new Move(blockB.position.x, blockB.position.y, blockB.position.z, node.remainingBlocks, cost, [], [], true))
break
// }
} else if ((ceilingClear || d === 2) && blockB.safe && blockC.safe && blockD.safe && floorCleared) {
const off = blockD.position
if (closed.has(`${off.x},${off.y},${off.z}`)) continue

// Down
const blockE = this.getBlockInfo(node, dx, -2, dz)
if (blockE.physical) {
// cost += this.exclusionStep(blockD)
// cost += this.getNumEntitiesAt(blockD.position, 0, 0, 0) * this.entityCost
neighbors.push(Move.fromPrevious(cost, blockD.position.offset(0.5, 0, 0.5), node, this))
// neighbors.push(new Move(blockD.position.x, blockD.position.y, blockD.position.z, node.remainingBlocks, cost, [], [], true))
}
floorCleared = floorCleared && !blockE.physical
} else if (!blockB.safe || !blockC.safe) {
break
}
Expand Down

0 comments on commit 5575ff9

Please sign in to comment.