@nxg-org/mineflayer-ender 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,105 @@
1
+ <h2 align="center">mineflayer-ender</h2>
2
+ <h4 align="center">A Mineflayer plugin for ender-pearl planning and enderman-style movement helpers.</h4>
3
+
4
+ <p align="center">
5
+ <a href="https://github.com/nxg-org/mineflayer-ender">
6
+ <img src="https://img.shields.io/badge/github-181717?style=for-the-badge&logo=github" alt="GitHub">
7
+ </a>
8
+ <a href="https://www.npmjs.com/package/@nxg-org/mineflayer-ender">
9
+ <img src="https://img.shields.io/npm/v/%40nxg-org%2Fmineflayer-ender?style=for-the-badge&logo=npm" alt="NPM">
10
+ </a>
11
+ <img src="https://img.shields.io/badge/license-GPL--3.0-black?style=for-the-badge" alt="License">
12
+ </p>
13
+
14
+ > [!WARNING]
15
+ > This plugin is still under active iteration. The core pearling flow works, but the API is still fairly low-level and focused on block-targeted pearl shots.
16
+
17
+ <h3 align="center">Why use this plugin?</h3>
18
+
19
+ -----
20
+
21
+ `mineflayer-ender` gives Mineflayer bots a reusable ender-pearl planning layer instead of forcing every project to manually calculate yaw, pitch, travel ticks, and collision checks.
22
+
23
+ It is useful when you want a bot to:
24
+
25
+ - Pearl onto a specific block
26
+ - Plan whether a pearl shot is valid before throwing
27
+ - Reuse projectile simulation logic in your own combat or movement systems
28
+ - Build more "enderman-like" movement around a clean plugin surface
29
+
30
+ <h3 align="center">Features</h3>
31
+
32
+ -----
33
+
34
+ - [X] Attach `bot.ender` to Mineflayer bots
35
+ - [X] Check whether pearls are available in inventory
36
+ - [X] Auto-equip pearls before throwing
37
+ - [X] Plan a valid pearl shot to a target block
38
+ - [X] Expose low-level shot simulation via `EnderShotFactory`
39
+ - [ ] Higher-level chase / combat automation
40
+ - [ ] Broader polished docs and examples
41
+
42
+ <h3 align="center">Installation</h3>
43
+
44
+ -----
45
+
46
+ ```bash
47
+ npm install @nxg-org/mineflayer-ender
48
+ ```
49
+
50
+ The plugin depends on `@nxg-org/mineflayer-util-plugin` and loads it automatically if your bot does not already have `bot.util`.
51
+
52
+ <h3 align="center">Quick Start</h3>
53
+
54
+ -----
55
+
56
+ ```ts
57
+ import { createBot } from "mineflayer";
58
+ import enderPlugin from "@nxg-org/mineflayer-ender";
59
+
60
+ const bot = createBot({
61
+ host: "localhost",
62
+ port: 25565,
63
+ username: "ender-bot"
64
+ });
65
+
66
+ bot.loadPlugin(enderPlugin);
67
+
68
+ bot.once("spawn", async () => {
69
+ const block = bot.findBlock({
70
+ matching: (b) => b.name !== "air",
71
+ maxDistance: 16
72
+ });
73
+
74
+ if (block) {
75
+ const success = await bot.ender.pearl(block);
76
+ console.log("Pearl result:", success);
77
+ }
78
+ });
79
+ ```
80
+
81
+ There is also a chat-driven usage example in [`example/basic.ts`](./example/basic.ts).
82
+
83
+ <h3 align="center">Usage Notes</h3>
84
+
85
+ -----
86
+
87
+ - The plugin is centered around block-targeted pearl throws, not arbitrary teleport destinations.
88
+ - `bot.ender.pearl(block, face?)` returns `false` when no valid shot is found or no pearls are available.
89
+ - `shotToBlock()` can be used to inspect a candidate shot before actually throwing.
90
+ - Off-hand support exists on the `Enderman` instance through `useOffhand`.
91
+
92
+ <h3 align="center">API and Examples</h3>
93
+
94
+ -----
95
+
96
+ | Link | Description |
97
+ | --- | --- |
98
+ | [API](./docs/API.md) | Full API reference for the plugin, public classes, types, and method behavior. |
99
+ | [Example](./example/basic.ts) | A simple example showing pearl and follow commands. |
100
+
101
+ <h3 align="center">License</h3>
102
+
103
+ -----
104
+
105
+ This package is published as `GPL-3.0` in [`package.json`](./package.json).
package/docs/API.md ADDED
@@ -0,0 +1,278 @@
1
+ # API
2
+
3
+ This page documents the current public surface of `@nxg-org/mineflayer-ender`.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @nxg-org/mineflayer-ender
9
+ ```
10
+
11
+ ## Plugin Setup
12
+
13
+ ```ts
14
+ import { createBot } from "mineflayer";
15
+ import enderPlugin from "@nxg-org/mineflayer-ender";
16
+
17
+ const bot = createBot({
18
+ host: "localhost",
19
+ username: "ender-bot"
20
+ });
21
+
22
+ bot.loadPlugin(enderPlugin);
23
+ ```
24
+
25
+ When the plugin loads, it augments Mineflayer with:
26
+
27
+ ```ts
28
+ bot.ender: Enderman
29
+ ```
30
+
31
+ If `bot.util` is missing, the plugin automatically loads `@nxg-org/mineflayer-util-plugin`.
32
+
33
+ ## Exports
34
+
35
+ ### Default Export
36
+
37
+ ```ts
38
+ import enderPlugin from "@nxg-org/mineflayer-ender";
39
+ ```
40
+
41
+ Mineflayer plugin loader that attaches `bot.ender`.
42
+
43
+ ### Named Exports
44
+
45
+ ```ts
46
+ import { Enderman, EnderShotFactory } from "@nxg-org/mineflayer-ender";
47
+ ```
48
+
49
+ - `Enderman`: main runtime helper attached to the bot
50
+ - `EnderShotFactory`: lower-level shot simulator constructor for custom projectile work
51
+
52
+ ## Bot Augmentation
53
+
54
+ The plugin declares:
55
+
56
+ ```ts
57
+ declare module "mineflayer" {
58
+ interface Bot {
59
+ ender: Enderman;
60
+ }
61
+ }
62
+ ```
63
+
64
+ It also declares several bot events in the module augmentation, but the current plugin implementation shown in this repository does not emit those events itself.
65
+
66
+ ## `Enderman` Class
67
+
68
+ This is the primary class most users will interact with.
69
+
70
+ ## Properties
71
+
72
+ ### `enabled: boolean`
73
+
74
+ General runtime flag used by the class. Defaults to `false`.
75
+
76
+ ### `useOffhand: boolean`
77
+
78
+ Controls whether pearl equip/usage should target the off-hand. Defaults to `false`.
79
+
80
+ ## Methods
81
+
82
+ ### `shotToBlock(block: Block, face?: BlockFace): CheckedShot | null`
83
+
84
+ Calculates a candidate pearl shot to the target block using the internal planner.
85
+
86
+ ```ts
87
+ const shot = bot.ender.shotToBlock(block);
88
+ if (shot?.hit) {
89
+ console.log(shot.yaw, shot.pitch, shot.ticks);
90
+ }
91
+ ```
92
+
93
+ Returns:
94
+
95
+ - `CheckedShot` when planning succeeds
96
+ - `null` when no viable shot is found
97
+
98
+ ### `hasPearls(): boolean`
99
+
100
+ Checks whether the bot has any item whose name includes `"_pearl"` in inventory.
101
+
102
+ ```ts
103
+ if (!bot.ender.hasPearls()) {
104
+ console.log("Need more pearls");
105
+ }
106
+ ```
107
+
108
+ ### `equipPearls(): Promise<boolean>`
109
+
110
+ Ensures an ender pearl is equipped in the currently selected hand.
111
+
112
+ Behavior:
113
+
114
+ - returns `true` if pearls are already equipped
115
+ - returns `true` after equipping a pearl from inventory
116
+ - returns `false` if no pearls are found
117
+
118
+ ### `cancel(): void`
119
+
120
+ Stops the current ender action state and deactivates the held item.
121
+
122
+ If a shot is mid-charge and internal shot info exists, it also forces the bot to look back toward that stored shot direction before cancelling.
123
+
124
+ ### `pearl(block: Block, face?: number): Promise<boolean>`
125
+
126
+ Main high-level method for throwing a pearl at a target block.
127
+
128
+ ```ts
129
+ const success = await bot.ender.pearl(targetBlock, 1);
130
+ ```
131
+
132
+ Behavior:
133
+
134
+ - rejects concurrent pearl actions
135
+ - computes a valid shot using the planner
136
+ - equips pearls if needed
137
+ - force-looks to the computed yaw and pitch
138
+ - waits for an internal pearl cooldown gate
139
+ - swings and activates the held item to throw the pearl
140
+
141
+ Returns `false` when:
142
+
143
+ - a pearl throw is already in progress
144
+ - no pearls are available
145
+ - no valid shot is found
146
+ - shot validation fails
147
+
148
+ Returns `true` after the throw sequence is triggered.
149
+
150
+ ## `EnderShotFactory`
151
+
152
+ Static helper class for constructing `EnderShot` instances.
153
+
154
+ ### `EnderShotFactory.fromPlayer(shotEntity, bot, interceptCalcs?): EnderShot`
155
+
156
+ Builds an `EnderShot` from a player's position, yaw, pitch, and velocity.
157
+
158
+ ```ts
159
+ const shot = EnderShotFactory.fromPlayer(
160
+ {
161
+ position: bot.entity.position,
162
+ yaw: 0,
163
+ pitch: -Math.PI / 4,
164
+ velocity: bot.entity.velocity
165
+ },
166
+ bot
167
+ );
168
+ ```
169
+
170
+ Useful when you want to simulate a potential pearl shot before using `bot.ender.pearl()`.
171
+
172
+ ### `EnderShotFactory.fromEntity(projectileInfo, bot, interceptCalcs?): EnderShot`
173
+
174
+ Builds an `EnderShot` from an existing projectile-like position and velocity.
175
+
176
+ This is a lower-level helper for custom simulations.
177
+
178
+ ## `EnderShot`
179
+
180
+ `EnderShot` is not re-exported from `src/index.ts`, but it is part of the internal API surface used by the factory. It stores simulated trajectory points and can evaluate collisions against a target block.
181
+
182
+ ### Important Properties
183
+
184
+ - `initialPos: Vec3`
185
+ - `initialVel: Vec3`
186
+ - `initialYaw: number`
187
+ - `initialPitch: number`
188
+ - `gravity: number`
189
+ - `points: Vec3[]`
190
+ - `pointVelocities: Vec3[]`
191
+ - `blockHit: boolean`
192
+ - `blockCheck: boolean`
193
+
194
+ ### `calcToBlock(target: Block | Vec3, blockChecking = false): BasicShotInfo`
195
+
196
+ Simulates a projectile trajectory until it intersects the target block area or collides with another block.
197
+
198
+ The returned `BasicShotInfo` includes:
199
+
200
+ ```ts
201
+ type BasicShotInfo = {
202
+ XZLandingDistance: number;
203
+ YLandingDistance: number;
204
+ block: Block | null;
205
+ blockFace?: BlockFace;
206
+ closestPoint: Vec3 | null;
207
+ totalTicks: number;
208
+ };
209
+ ```
210
+
211
+ This method is useful when you want detailed trajectory information, not just a simple success/fail result.
212
+
213
+ ## Important Types
214
+
215
+ ## `CheckedShot`
216
+
217
+ ```ts
218
+ type CheckedShot = {
219
+ hit: boolean;
220
+ yaw: number;
221
+ pitch: number;
222
+ ticks: number;
223
+ shotInfo: BasicShotInfo | null;
224
+ };
225
+ ```
226
+
227
+ Returned by planner operations like `shotToBlock()`.
228
+
229
+ ## `BlockFace`
230
+
231
+ ```ts
232
+ enum BlockFace {
233
+ UNKNOWN = -999,
234
+ BOTTOM = 0,
235
+ TOP = 1,
236
+ NORTH = 2,
237
+ SOUTH = 3,
238
+ WEST = 4,
239
+ EAST = 5
240
+ }
241
+ ```
242
+
243
+ Useful when you want to constrain the desired face of the destination block.
244
+
245
+ ## `ShotEntity`
246
+
247
+ ```ts
248
+ type ShotEntity = {
249
+ position: Vec3;
250
+ velocity: Vec3;
251
+ yaw?: number;
252
+ pitch?: number;
253
+ heldItem?: Item | null;
254
+ };
255
+ ```
256
+
257
+ Used by `EnderShotFactory.fromPlayer()`.
258
+
259
+ ## Example Flow
260
+
261
+ ```ts
262
+ const target = bot.blockAt(player.position.offset(0, -1, 0));
263
+
264
+ if (target) {
265
+ const plan = bot.ender.shotToBlock(target);
266
+
267
+ if (plan?.hit) {
268
+ await bot.ender.pearl(target, plan.shotInfo?.blockFace);
269
+ }
270
+ }
271
+ ```
272
+
273
+ ## Caveats
274
+
275
+ - The plugin is focused on pearl-to-block planning, not a broad teleport behavior framework
276
+ - Several internal Mineflayer event declarations in `src/index.ts` are not emitted by the implementation shown here
277
+ - `EnderShot` itself is not re-exported from the package root
278
+ - The public API is still fairly low-level compared with more polished Mineflayer movement plugins
@@ -0,0 +1,82 @@
1
+ import { createBot } from "mineflayer";
2
+ import enderPearling from "../src/index";
3
+ import { Vec3 } from "vec3";
4
+ import utilPlugin from "@nxg-org/mineflayer-util-plugin"
5
+ import {pathfinder, goals} from "mineflayer-pathfinder"
6
+ import type { Entity } from "prismarine-entity";
7
+ import type { Block } from "prismarine-block";
8
+ import { promisify } from "util";
9
+
10
+ const sleep = promisify(setTimeout)
11
+
12
+ const bot = createBot({
13
+ username: "ender-testing",
14
+ host: process.argv[2] ?? "localhost",
15
+ port: Number(process.argv[3]) ?? 25565,
16
+ });
17
+
18
+ bot.loadPlugin(utilPlugin)
19
+ bot.loadPlugin(enderPearling);
20
+ bot.loadPlugin(pathfinder);
21
+ let pearlThrown: boolean = false
22
+
23
+ //lazy implementation. Will automate throwing later.
24
+ // bot.on("physicsTick", async () => {
25
+ // target = bot.nearestEntity((e) => e.type === "player" && e !== bot.entity);
26
+ // if (!target) return;
27
+ // if (target.position.distanceTo(bot.entity.position) > 10) {
28
+ // if (!pearlThrown) pearlThrown = await pearl(target.username);
29
+ // } else {
30
+ // come(target.username);
31
+ // pearlThrown = false;
32
+ // }
33
+ // });
34
+
35
+ bot._client.prependListener("entity_velocity", (packet: any) => {
36
+ if (packet.entityId === bot.entity.id) {
37
+ bot.entity.velocity.set(0, 0, 0)
38
+ }
39
+
40
+ })
41
+
42
+
43
+ bot.on("chat", async (username, message) => {
44
+ const split = message.split(" ");
45
+ switch (split[0]) {
46
+ case "pearl":
47
+ pearl(split[1] ?? username)
48
+ break;
49
+ case "come":
50
+ case "here":
51
+ come(split[1] ?? username)
52
+ break;
53
+ case "stop":
54
+ case "cease":
55
+ bot.pathfinder.setGoal(null);
56
+ break;
57
+ }
58
+ });
59
+
60
+ function pearl(name?: string) {
61
+ const pearlTarget = bot.nearestEntity((e) => (e.username ?? e.name) === name);
62
+ if (!pearlTarget) {
63
+ console.log("no entity");
64
+ return false;
65
+ }
66
+ const pearlBlock = bot.blockAt(pearlTarget.position.offset(0, -1, 0));
67
+ if (!pearlBlock) {
68
+ console.log("no block under entity");
69
+ return false;
70
+ }
71
+ return bot.ender.pearl(pearlBlock, 1);
72
+ }
73
+
74
+ function come(name?: string) {
75
+ const comeTarget = bot.nearestEntity((e) => (e.username ?? e.name) === name);
76
+ if (!comeTarget) {
77
+ console.log("no entity");
78
+ return;
79
+ }
80
+ bot.pathfinder.setGoal(new goals.GoalFollow(comeTarget, 3), true);
81
+ // bot.util.move.followEntityWithRespectRange(comeTarget, 3);
82
+ }
@@ -1,10 +1,10 @@
1
- import { AABB } from "@nxg-org/mineflayer-util-plugin";
2
- import type { Block } from "prismarine-block";
3
- import type { Vec3 } from "vec3";
4
- export declare function getEntityAABB(entity: {
5
- position: Vec3;
6
- height: number;
7
- width?: number;
8
- }): AABB;
9
- export declare function getBlockAABB(block: Block, height?: number): AABB;
10
- export declare function getBlockPosAABB(block: Vec3, height?: number): AABB;
1
+ import { AABB } from "@nxg-org/mineflayer-util-plugin";
2
+ import type { Block } from "prismarine-block";
3
+ import type { Vec3 } from "vec3";
4
+ export declare function getEntityAABB(entity: {
5
+ position: Vec3;
6
+ height: number;
7
+ width?: number;
8
+ }): AABB;
9
+ export declare function getBlockAABB(block: Block, height?: number): AABB;
10
+ export declare function getBlockPosAABB(block: Vec3, height?: number): AABB;
@@ -1,21 +1,21 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getBlockPosAABB = exports.getBlockAABB = exports.getEntityAABB = void 0;
4
- const mineflayer_util_plugin_1 = require("@nxg-org/mineflayer-util-plugin");
5
- function getEntityAABB(entity) {
6
- var _a;
7
- const w = (_a = entity.width) !== null && _a !== void 0 ? _a : (entity.height / 2);
8
- const { x, y, z } = entity.position;
9
- return new mineflayer_util_plugin_1.AABB(-w, 0, -w, w, entity.height, w).offset(x, y, z);
10
- }
11
- exports.getEntityAABB = getEntityAABB;
12
- function getBlockAABB(block, height = 1) {
13
- const { x, y, z } = block.position;
14
- return new mineflayer_util_plugin_1.AABB(x, y, z, x + 1, y + height, z + 1);
15
- }
16
- exports.getBlockAABB = getBlockAABB;
17
- function getBlockPosAABB(block, height = 1) {
18
- const { x, y, z } = block.floored();
19
- return new mineflayer_util_plugin_1.AABB(x, y, z, x + 1, y + height, z + 1);
20
- }
21
- exports.getBlockPosAABB = getBlockPosAABB;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getBlockPosAABB = exports.getBlockAABB = exports.getEntityAABB = void 0;
4
+ const mineflayer_util_plugin_1 = require("@nxg-org/mineflayer-util-plugin");
5
+ function getEntityAABB(entity) {
6
+ var _a;
7
+ const w = (_a = entity.width) !== null && _a !== void 0 ? _a : (entity.height / 2);
8
+ const { x, y, z } = entity.position;
9
+ return new mineflayer_util_plugin_1.AABB(-w, 0, -w, w, entity.height, w).translate(x, y, z);
10
+ }
11
+ exports.getEntityAABB = getEntityAABB;
12
+ function getBlockAABB(block, height = 1) {
13
+ const { x, y, z } = block.position;
14
+ return new mineflayer_util_plugin_1.AABB(x, y, z, x + 1, y + height, z + 1);
15
+ }
16
+ exports.getBlockAABB = getBlockAABB;
17
+ function getBlockPosAABB(block, height = 1) {
18
+ const { x, y, z } = block.floored();
19
+ return new mineflayer_util_plugin_1.AABB(x, y, z, x + 1, y + height, z + 1);
20
+ }
21
+ exports.getBlockPosAABB = getBlockPosAABB;
@@ -1,27 +1,27 @@
1
- declare type ProjectileInfo = {
2
- v0: number;
3
- g: number;
4
- ph: number;
5
- };
6
- declare type ProjectileInfos = {
7
- [name: string]: ProjectileInfo;
8
- };
9
- declare type ProjectileGravity = {
10
- [name: string]: number;
11
- };
12
- export declare const trajectoryInfo: ProjectileInfos;
13
- export declare const projectileGravity: ProjectileGravity;
14
- export declare const airResistance: {
15
- y: number;
16
- h: number;
17
- };
18
- export declare enum BlockFace {
19
- UNKNOWN = -999,
20
- BOTTOM = 0,
21
- TOP = 1,
22
- NORTH = 2,
23
- SOUTH = 3,
24
- WEST = 4,
25
- EAST = 5
26
- }
27
- export {};
1
+ type ProjectileInfo = {
2
+ v0: number;
3
+ g: number;
4
+ ph: number;
5
+ };
6
+ type ProjectileInfos = {
7
+ [name: string]: ProjectileInfo;
8
+ };
9
+ type ProjectileGravity = {
10
+ [name: string]: number;
11
+ };
12
+ export declare const trajectoryInfo: ProjectileInfos;
13
+ export declare const projectileGravity: ProjectileGravity;
14
+ export declare const airResistance: {
15
+ y: number;
16
+ h: number;
17
+ };
18
+ export declare enum BlockFace {
19
+ UNKNOWN = -999,
20
+ BOTTOM = 0,
21
+ TOP = 1,
22
+ NORTH = 2,
23
+ SOUTH = 3,
24
+ WEST = 4,
25
+ EAST = 5
26
+ }
27
+ export {};
@@ -1,36 +1,36 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BlockFace = exports.airResistance = exports.projectileGravity = exports.trajectoryInfo = void 0;
4
- exports.trajectoryInfo = {
5
- bow: { v0: 3, g: -0.05, ph: 1.62 },
6
- crossbow: { v0: 3.15, g: -0.05, ph: 1.62 },
7
- crossbow_firework: { v0: 1.6, g: 0.00, ph: 1.62 },
8
- trident: { v0: 2.5, g: -0.05, ph: 1.62 },
9
- snowball: { v0: 1.5, g: -0.04, ph: 1.52 },
10
- egg: { v0: 1.5, g: -0.04, ph: 1.52 },
11
- ender_pearl: { v0: 1.5, g: -0.03, ph: 1.52 },
12
- splash_potion: { v0: 0.4, g: -0.03, ph: 1.52 },
13
- };
14
- exports.projectileGravity = {
15
- arrow: 0.05,
16
- trident: 0.05,
17
- egg: 0.04,
18
- snowball: 0.04,
19
- ender_pearl: 0.03,
20
- splash_potion: 0.03,
21
- firework_rocket: 0.00,
22
- };
23
- exports.airResistance = {
24
- y: 0.01,
25
- h: 0.01
26
- };
27
- var BlockFace;
28
- (function (BlockFace) {
29
- BlockFace[BlockFace["UNKNOWN"] = -999] = "UNKNOWN";
30
- BlockFace[BlockFace["BOTTOM"] = 0] = "BOTTOM";
31
- BlockFace[BlockFace["TOP"] = 1] = "TOP";
32
- BlockFace[BlockFace["NORTH"] = 2] = "NORTH";
33
- BlockFace[BlockFace["SOUTH"] = 3] = "SOUTH";
34
- BlockFace[BlockFace["WEST"] = 4] = "WEST";
35
- BlockFace[BlockFace["EAST"] = 5] = "EAST";
36
- })(BlockFace = exports.BlockFace || (exports.BlockFace = {}));
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BlockFace = exports.airResistance = exports.projectileGravity = exports.trajectoryInfo = void 0;
4
+ exports.trajectoryInfo = {
5
+ bow: { v0: 3, g: -0.05, ph: 1.62 },
6
+ crossbow: { v0: 3.15, g: -0.05, ph: 1.62 },
7
+ crossbow_firework: { v0: 1.6, g: 0.00, ph: 1.62 },
8
+ trident: { v0: 2.5, g: -0.05, ph: 1.62 },
9
+ snowball: { v0: 1.5, g: -0.04, ph: 1.52 },
10
+ egg: { v0: 1.5, g: -0.04, ph: 1.52 },
11
+ ender_pearl: { v0: 1.5, g: -0.03, ph: 1.52 },
12
+ splash_potion: { v0: 0.4, g: -0.03, ph: 1.52 },
13
+ };
14
+ exports.projectileGravity = {
15
+ arrow: 0.05,
16
+ trident: 0.05,
17
+ egg: 0.04,
18
+ snowball: 0.04,
19
+ ender_pearl: 0.03,
20
+ splash_potion: 0.03,
21
+ firework_rocket: 0.00,
22
+ };
23
+ exports.airResistance = {
24
+ y: 0.01,
25
+ h: 0.01
26
+ };
27
+ var BlockFace;
28
+ (function (BlockFace) {
29
+ BlockFace[BlockFace["UNKNOWN"] = -999] = "UNKNOWN";
30
+ BlockFace[BlockFace["BOTTOM"] = 0] = "BOTTOM";
31
+ BlockFace[BlockFace["TOP"] = 1] = "TOP";
32
+ BlockFace[BlockFace["NORTH"] = 2] = "NORTH";
33
+ BlockFace[BlockFace["SOUTH"] = 3] = "SOUTH";
34
+ BlockFace[BlockFace["WEST"] = 4] = "WEST";
35
+ BlockFace[BlockFace["EAST"] = 5] = "EAST";
36
+ })(BlockFace = exports.BlockFace || (exports.BlockFace = {}));