pumpkin-api-py 0.1.0__py3-none-any.whl
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.
- componentize_py_async_support/__init__.py +570 -0
- componentize_py_async_support/futures.py +149 -0
- componentize_py_async_support/streams.py +345 -0
- componentize_py_runtime.pyi +40 -0
- componentize_py_types.py +32 -0
- poll_loop.py +440 -0
- pumpkin_api/__init__.py +41 -0
- pumpkin_api/build.py +68 -0
- pumpkin_api/impl.py +355 -0
- pumpkin_api/wit/advancement.wit +41 -0
- pumpkin_api/wit/attributes.wit +56 -0
- pumpkin_api/wit/bedrock-packets.wit +1709 -0
- pumpkin_api/wit/biomes.wit +72 -0
- pumpkin_api/wit/block-entity.wit +423 -0
- pumpkin_api/wit/boss-bar.wit +83 -0
- pumpkin_api/wit/command.wit +244 -0
- pumpkin_api/wit/common.wit +261 -0
- pumpkin_api/wit/context.wit +61 -0
- pumpkin_api/wit/damage-types.wit +57 -0
- pumpkin_api/wit/data-components.wit +117 -0
- pumpkin_api/wit/datapack.wit +54 -0
- pumpkin_api/wit/display.wit +171 -0
- pumpkin_api/wit/enchantments.wit +102 -0
- pumpkin_api/wit/entity-statuses.wit +68 -0
- pumpkin_api/wit/entity-types.wit +164 -0
- pumpkin_api/wit/entity.wit +1 -0
- pumpkin_api/wit/event.wit +2435 -0
- pumpkin_api/wit/forms.wit +51 -0
- pumpkin_api/wit/game-events.wit +67 -0
- pumpkin_api/wit/game-rules.wit +69 -0
- pumpkin_api/wit/gui.wit +39 -0
- pumpkin_api/wit/i18n.wit +21 -0
- pumpkin_api/wit/inventory.wit +78 -0
- pumpkin_api/wit/ipc.wit +7 -0
- pumpkin_api/wit/item-stack.wit +104 -0
- pumpkin_api/wit/java-dialogs.wit +155 -0
- pumpkin_api/wit/java-packets.wit +1838 -0
- pumpkin_api/wit/log.wit +14 -0
- pumpkin_api/wit/metadata.wit +19 -0
- pumpkin_api/wit/particles.wit +131 -0
- pumpkin_api/wit/permission.wit +46 -0
- pumpkin_api/wit/player.wit +1432 -0
- pumpkin_api/wit/plugin.wit +121 -0
- pumpkin_api/wit/potions.wit +52 -0
- pumpkin_api/wit/recipe.wit +88 -0
- pumpkin_api/wit/scheduler.wit +24 -0
- pumpkin_api/wit/scoreboard.wit +111 -0
- pumpkin_api/wit/screens.wit +31 -0
- pumpkin_api/wit/server.wit +286 -0
- pumpkin_api/wit/sounds.wit +1987 -0
- pumpkin_api/wit/statistics.wit +94 -0
- pumpkin_api/wit/status-effect.wit +54 -0
- pumpkin_api/wit/text.wit +68 -0
- pumpkin_api/wit/uuid.wit +16 -0
- pumpkin_api/wit/world.wit +1050 -0
- pumpkin_api_py-0.1.0.dist-info/METADATA +53 -0
- pumpkin_api_py-0.1.0.dist-info/RECORD +108 -0
- pumpkin_api_py-0.1.0.dist-info/WHEEL +4 -0
- pumpkin_api_py-0.1.0.dist-info/entry_points.txt +2 -0
- pumpkin_api_py-0.1.0.dist-info/licenses/LICENSE-APACHE +176 -0
- pumpkin_api_py-0.1.0.dist-info/licenses/LICENSE-MIT +21 -0
- wit_world/__init__.py +114 -0
- wit_world/exports/__init__.py +19 -0
- wit_world/exports/metadata.py +24 -0
- wit_world/imports/__init__.py +0 -0
- wit_world/imports/advancement.py +56 -0
- wit_world/imports/attributes.py +66 -0
- wit_world/imports/bedrock_packets.py +2413 -0
- wit_world/imports/biomes.py +81 -0
- wit_world/imports/block_entity.py +1353 -0
- wit_world/imports/boss_bar.py +137 -0
- wit_world/imports/command.py +705 -0
- wit_world/imports/common.py +335 -0
- wit_world/imports/context.py +91 -0
- wit_world/imports/damage_types.py +66 -0
- wit_world/imports/data_components.py +126 -0
- wit_world/imports/datapack.py +124 -0
- wit_world/imports/display.py +295 -0
- wit_world/imports/enchantments.py +129 -0
- wit_world/imports/entity_statuses.py +77 -0
- wit_world/imports/entity_types.py +173 -0
- wit_world/imports/event.py +3558 -0
- wit_world/imports/forms.py +98 -0
- wit_world/imports/game_events.py +76 -0
- wit_world/imports/game_rules.py +88 -0
- wit_world/imports/gui.py +81 -0
- wit_world/imports/i18n.py +35 -0
- wit_world/imports/inventory.py +159 -0
- wit_world/imports/ipc.py +20 -0
- wit_world/imports/item_stack.py +206 -0
- wit_world/imports/java_dialogs.py +208 -0
- wit_world/imports/java_packets.py +3560 -0
- wit_world/imports/logging.py +30 -0
- wit_world/imports/particles.py +140 -0
- wit_world/imports/permission.py +71 -0
- wit_world/imports/player.py +1753 -0
- wit_world/imports/potions.py +61 -0
- wit_world/imports/recipe.py +120 -0
- wit_world/imports/scheduler.py +44 -0
- wit_world/imports/scoreboard.py +167 -0
- wit_world/imports/screens.py +40 -0
- wit_world/imports/server.py +493 -0
- wit_world/imports/sounds.py +1996 -0
- wit_world/imports/statistics.py +103 -0
- wit_world/imports/status_effect.py +63 -0
- wit_world/imports/text.py +156 -0
- wit_world/imports/uuid.py +36 -0
- wit_world/imports/world.py +1640 -0
pumpkin_api/impl.py
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# pumpkin-api-py: Pumpkin plugin API for Python
|
|
2
|
+
# Copyright (C) 2024 alex
|
|
3
|
+
#
|
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
|
|
17
|
+
import traceback
|
|
18
|
+
from typing import Any, Callable, Dict, Optional, Type, TypedDict
|
|
19
|
+
|
|
20
|
+
import wit_world
|
|
21
|
+
import wit_world.exports
|
|
22
|
+
from componentize_py_types import Err
|
|
23
|
+
from wit_world.exports import metadata
|
|
24
|
+
from wit_world.imports import command, context, event, scheduler, server, text, world
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class AiGoal(TypedDict):
|
|
28
|
+
can_start: Callable[[server.Server, world.Entity], bool]
|
|
29
|
+
should_continue: Callable[[server.Server, world.Entity], bool]
|
|
30
|
+
start: Callable[[server.Server, world.Entity], None]
|
|
31
|
+
tick: Callable[[server.Server, world.Entity], None]
|
|
32
|
+
stop: Callable[[server.Server, world.Entity], None]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
_PLUGIN_INSTANCE: Optional["Plugin"] = None
|
|
36
|
+
_EVENT_HANDLERS: Dict[int, Callable[[server.Server, Any], Any]] = {}
|
|
37
|
+
_COMMAND_HANDLERS: Dict[
|
|
38
|
+
int, Callable[[command.CommandSender, server.Server, command.ConsumedArgs], int]
|
|
39
|
+
] = {}
|
|
40
|
+
_COMMAND_SUGGESTION_HANDLERS: Dict[
|
|
41
|
+
int,
|
|
42
|
+
Callable[
|
|
43
|
+
[command.CommandSender, server.Server, command.SuggestionRequest],
|
|
44
|
+
command.CommandSuggestions,
|
|
45
|
+
],
|
|
46
|
+
] = {}
|
|
47
|
+
_TASK_HANDLERS: Dict[int, Callable[[server.Server], None]] = {}
|
|
48
|
+
_AI_GOALS: Dict[int, AiGoal] = {}
|
|
49
|
+
_GENERATORS: Dict[int, Callable[[world.GenerationPhase, world.ChunkBuffer], None]] = {}
|
|
50
|
+
|
|
51
|
+
_NEXT_HANDLER_ID: int = 0
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _exception_message(exc: Exception) -> str:
|
|
55
|
+
if hasattr(exc, "value"):
|
|
56
|
+
value = getattr(exc, "value")
|
|
57
|
+
if value is not None:
|
|
58
|
+
return str(value)
|
|
59
|
+
message = str(exc)
|
|
60
|
+
if message:
|
|
61
|
+
return message
|
|
62
|
+
return "".join(traceback.format_exception_only(type(exc), exc)).strip()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _format_exception(exc: Exception) -> str:
|
|
66
|
+
details = "".join(
|
|
67
|
+
traceback.format_exception(type(exc), exc, exc.__traceback__)
|
|
68
|
+
).strip()
|
|
69
|
+
if details:
|
|
70
|
+
return details
|
|
71
|
+
return _exception_message(exc)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _get_next_handler_id() -> int:
|
|
75
|
+
global _NEXT_HANDLER_ID
|
|
76
|
+
handler_id = _NEXT_HANDLER_ID
|
|
77
|
+
_NEXT_HANDLER_ID += 1
|
|
78
|
+
return handler_id
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class Plugin:
|
|
82
|
+
def __init__(self):
|
|
83
|
+
self._pending_events = []
|
|
84
|
+
|
|
85
|
+
def metadata(self) -> metadata.PluginMetadata:
|
|
86
|
+
raise NotImplementedError
|
|
87
|
+
|
|
88
|
+
def on_load(self, ctx: context.Context) -> None:
|
|
89
|
+
for event_type, handler, priority, blocking in self._pending_events:
|
|
90
|
+
self.register_event(ctx, event_type, handler, priority, blocking)
|
|
91
|
+
|
|
92
|
+
def on_unload(self, ctx: context.Context) -> None:
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
def register_event(
|
|
96
|
+
self,
|
|
97
|
+
ctx: context.Context,
|
|
98
|
+
event_type: event.EventType,
|
|
99
|
+
handler: Callable[[server.Server, Any], Any],
|
|
100
|
+
priority=event.EventPriority.NORMAL,
|
|
101
|
+
blocking=True,
|
|
102
|
+
):
|
|
103
|
+
handler_id = _get_next_handler_id()
|
|
104
|
+
_EVENT_HANDLERS[handler_id] = handler
|
|
105
|
+
ctx.register_event(handler_id, event_type, priority, blocking)
|
|
106
|
+
|
|
107
|
+
def register_command_handler(
|
|
108
|
+
self,
|
|
109
|
+
handler: Callable[
|
|
110
|
+
[command.CommandSender, server.Server, command.ConsumedArgs], int
|
|
111
|
+
],
|
|
112
|
+
) -> int:
|
|
113
|
+
handler_id = _get_next_handler_id()
|
|
114
|
+
_COMMAND_HANDLERS[handler_id] = handler
|
|
115
|
+
return handler_id
|
|
116
|
+
|
|
117
|
+
def register_command_suggestion_handler(
|
|
118
|
+
self,
|
|
119
|
+
handler: Callable[
|
|
120
|
+
[command.CommandSender, server.Server, command.SuggestionRequest],
|
|
121
|
+
command.CommandSuggestions,
|
|
122
|
+
],
|
|
123
|
+
) -> int:
|
|
124
|
+
handler_id = _get_next_handler_id()
|
|
125
|
+
_COMMAND_SUGGESTION_HANDLERS[handler_id] = handler
|
|
126
|
+
return handler_id
|
|
127
|
+
|
|
128
|
+
def register_command(
|
|
129
|
+
self,
|
|
130
|
+
ctx: context.Context,
|
|
131
|
+
cmd: command.Command,
|
|
132
|
+
handler: Callable[
|
|
133
|
+
[command.CommandSender, server.Server, command.ConsumedArgs], int
|
|
134
|
+
],
|
|
135
|
+
suggestion_handler: Callable[
|
|
136
|
+
[command.CommandSender, server.Server, command.SuggestionRequest],
|
|
137
|
+
command.CommandSuggestions,
|
|
138
|
+
]
|
|
139
|
+
| None = None,
|
|
140
|
+
permission: str = "",
|
|
141
|
+
extra_nodes: list[command.CommandNode] | None = None,
|
|
142
|
+
):
|
|
143
|
+
suggestion_id = None
|
|
144
|
+
if suggestion_handler:
|
|
145
|
+
suggestion_id = self.register_command_suggestion_handler(suggestion_handler)
|
|
146
|
+
handler_id = self.register_command_handler(handler)
|
|
147
|
+
cmd.execute_with_handler_id(handler_id)
|
|
148
|
+
if extra_nodes:
|
|
149
|
+
for node in extra_nodes:
|
|
150
|
+
node.execute_with_handler_id(handler_id)
|
|
151
|
+
if suggestion_id:
|
|
152
|
+
node.suggest_with_handler_id(suggestion_id)
|
|
153
|
+
ctx.register_command(cmd, permission)
|
|
154
|
+
|
|
155
|
+
def register_ai_goal(self, goal: AiGoal) -> int:
|
|
156
|
+
goal_id = _get_next_handler_id()
|
|
157
|
+
_AI_GOALS[goal_id] = goal
|
|
158
|
+
return goal_id
|
|
159
|
+
|
|
160
|
+
def register_chunk_generator(
|
|
161
|
+
self, generator: Callable[[world.GenerationPhase, world.ChunkBuffer], None]
|
|
162
|
+
) -> int:
|
|
163
|
+
generator_id = _get_next_handler_id()
|
|
164
|
+
_GENERATORS[generator_id] = generator
|
|
165
|
+
return generator_id
|
|
166
|
+
|
|
167
|
+
def schedule_delayed_task(
|
|
168
|
+
self, delay_ticks: int, handler: Callable[[server.Server], None]
|
|
169
|
+
) -> int:
|
|
170
|
+
handler_id = _get_next_handler_id()
|
|
171
|
+
_TASK_HANDLERS[handler_id] = handler
|
|
172
|
+
return scheduler.schedule_delayed_task(handler_id, delay_ticks)
|
|
173
|
+
|
|
174
|
+
def schedule_repeating_task(
|
|
175
|
+
self,
|
|
176
|
+
delay_ticks: int,
|
|
177
|
+
period_ticks: int,
|
|
178
|
+
handler: Callable[[server.Server], None],
|
|
179
|
+
) -> int:
|
|
180
|
+
handler_id = _get_next_handler_id()
|
|
181
|
+
_TASK_HANDLERS[handler_id] = handler
|
|
182
|
+
return scheduler.schedule_repeating_task(handler_id, delay_ticks, period_ticks)
|
|
183
|
+
|
|
184
|
+
def event_handler(
|
|
185
|
+
self,
|
|
186
|
+
event_type: event.EventType,
|
|
187
|
+
priority=event.EventPriority.NORMAL,
|
|
188
|
+
blocking=True,
|
|
189
|
+
):
|
|
190
|
+
def decorator(func):
|
|
191
|
+
self._pending_events.append((event_type, func, priority, blocking))
|
|
192
|
+
return func
|
|
193
|
+
|
|
194
|
+
return decorator
|
|
195
|
+
|
|
196
|
+
def handle_ipc_message(self, sender: str, message: bytes) -> bytes:
|
|
197
|
+
raise NotImplementedError
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def register_plugin(plugin_class: Type[Plugin]):
|
|
201
|
+
global _PLUGIN_INSTANCE
|
|
202
|
+
_PLUGIN_INSTANCE = plugin_class()
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class WitWorldImpl(wit_world.WitWorld):
|
|
206
|
+
def init_plugin(self) -> None:
|
|
207
|
+
pass
|
|
208
|
+
|
|
209
|
+
def on_load(self, context: context.Context) -> None:
|
|
210
|
+
if _PLUGIN_INSTANCE:
|
|
211
|
+
try:
|
|
212
|
+
# In WIT, on-load returns result<_, string>
|
|
213
|
+
# componentize-py handles this by expecting None or raising Err
|
|
214
|
+
_PLUGIN_INSTANCE.on_load(context)
|
|
215
|
+
except Err as e:
|
|
216
|
+
raise Err(_exception_message(e))
|
|
217
|
+
except Exception as e:
|
|
218
|
+
raise Err(_format_exception(e))
|
|
219
|
+
|
|
220
|
+
def on_unload(self, context: context.Context) -> None:
|
|
221
|
+
if _PLUGIN_INSTANCE:
|
|
222
|
+
try:
|
|
223
|
+
_PLUGIN_INSTANCE.on_unload(context)
|
|
224
|
+
except Err as e:
|
|
225
|
+
raise Err(_exception_message(e))
|
|
226
|
+
except Exception as e:
|
|
227
|
+
raise Err(_format_exception(e))
|
|
228
|
+
|
|
229
|
+
def handle_event(
|
|
230
|
+
self, event_id: int, server: server.Server, event: event.Event
|
|
231
|
+
) -> event.Event:
|
|
232
|
+
if event_id in _EVENT_HANDLERS:
|
|
233
|
+
# Pass the inner event data to the handler
|
|
234
|
+
result = _EVENT_HANDLERS[event_id](server, event.value)
|
|
235
|
+
# If the handler returns something, assume it's the updated event data
|
|
236
|
+
if result is not None:
|
|
237
|
+
event.value = result
|
|
238
|
+
return event
|
|
239
|
+
|
|
240
|
+
def handle_command(
|
|
241
|
+
self,
|
|
242
|
+
command_id: int,
|
|
243
|
+
sender: command.CommandSender,
|
|
244
|
+
server: server.Server,
|
|
245
|
+
args: command.ConsumedArgs,
|
|
246
|
+
) -> int:
|
|
247
|
+
if command_id in _COMMAND_HANDLERS:
|
|
248
|
+
try:
|
|
249
|
+
return _COMMAND_HANDLERS[command_id](sender, server, args)
|
|
250
|
+
except Exception as e:
|
|
251
|
+
if hasattr(e, "value") and isinstance(
|
|
252
|
+
e.value,
|
|
253
|
+
(
|
|
254
|
+
command.CommandError_InvalidConsumption,
|
|
255
|
+
command.CommandError_InvalidRequirement,
|
|
256
|
+
command.CommandError_PermissionDenied,
|
|
257
|
+
command.CommandError_CommandFailed,
|
|
258
|
+
),
|
|
259
|
+
):
|
|
260
|
+
raise e
|
|
261
|
+
raise Err(
|
|
262
|
+
command.CommandError_CommandFailed(
|
|
263
|
+
text.TextComponent.text(_format_exception(e))
|
|
264
|
+
)
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
raise Err(
|
|
268
|
+
command.CommandError_CommandFailed(
|
|
269
|
+
text.TextComponent.text(
|
|
270
|
+
f"no handler registered for command id {command_id}"
|
|
271
|
+
)
|
|
272
|
+
)
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
def handle_command_suggestion(
|
|
276
|
+
self,
|
|
277
|
+
handler_id: int,
|
|
278
|
+
sender: command.CommandSender,
|
|
279
|
+
server: server.Server,
|
|
280
|
+
request: command.SuggestionRequest,
|
|
281
|
+
) -> command.CommandSuggestions:
|
|
282
|
+
if handler_id in _COMMAND_SUGGESTION_HANDLERS:
|
|
283
|
+
return _COMMAND_SUGGESTION_HANDLERS[handler_id](sender, server, request)
|
|
284
|
+
|
|
285
|
+
raise Exception(f"No suggestion handler registered for ID {handler_id}")
|
|
286
|
+
|
|
287
|
+
def handle_task(self, handler_id: int, server: server.Server) -> None:
|
|
288
|
+
if handler_id in _TASK_HANDLERS:
|
|
289
|
+
_TASK_HANDLERS[handler_id](server)
|
|
290
|
+
|
|
291
|
+
def handle_ipc_message(self, sender: str, message: bytes) -> bytes:
|
|
292
|
+
if _PLUGIN_INSTANCE:
|
|
293
|
+
try:
|
|
294
|
+
return _PLUGIN_INSTANCE.handle_ipc_message(sender, message)
|
|
295
|
+
except Err as e:
|
|
296
|
+
raise Err(_exception_message(e))
|
|
297
|
+
except Exception as e:
|
|
298
|
+
raise Err(_format_exception(e))
|
|
299
|
+
|
|
300
|
+
raise Err("Internal error: No plugin instance available?")
|
|
301
|
+
|
|
302
|
+
def handle_ai_goal_can_start(
|
|
303
|
+
self, goal_id: int, server: server.Server, entity: world.Entity
|
|
304
|
+
) -> bool:
|
|
305
|
+
if goal_id in _AI_GOALS:
|
|
306
|
+
return _AI_GOALS[goal_id]["can_start"](server, entity)
|
|
307
|
+
|
|
308
|
+
raise Exception(f"No AI goal registered for ID {goal_id}")
|
|
309
|
+
|
|
310
|
+
def handle_ai_goal_should_continue(
|
|
311
|
+
self, goal_id: int, server: server.Server, entity: world.Entity
|
|
312
|
+
) -> bool:
|
|
313
|
+
if goal_id in _AI_GOALS:
|
|
314
|
+
return _AI_GOALS[goal_id]["should_continue"](server, entity)
|
|
315
|
+
|
|
316
|
+
raise Exception(f"No AI goal registered for ID {goal_id}")
|
|
317
|
+
|
|
318
|
+
def handle_ai_goal_start(
|
|
319
|
+
self, goal_id: int, server: server.Server, entity: world.Entity
|
|
320
|
+
) -> None:
|
|
321
|
+
if goal_id in _AI_GOALS:
|
|
322
|
+
_AI_GOALS[goal_id]["start"](server, entity)
|
|
323
|
+
return
|
|
324
|
+
raise Exception(f"No AI goal registered for ID {goal_id}")
|
|
325
|
+
|
|
326
|
+
def handle_ai_goal_tick(
|
|
327
|
+
self, goal_id: int, server: server.Server, entity: world.Entity
|
|
328
|
+
) -> None:
|
|
329
|
+
if goal_id in _AI_GOALS:
|
|
330
|
+
_AI_GOALS[goal_id]["tick"](server, entity)
|
|
331
|
+
return
|
|
332
|
+
raise Exception(f"No AI goal registered for ID {goal_id}")
|
|
333
|
+
|
|
334
|
+
def handle_ai_goal_stop(
|
|
335
|
+
self, goal_id: int, server: server.Server, entity: world.Entity
|
|
336
|
+
) -> None:
|
|
337
|
+
if goal_id in _AI_GOALS:
|
|
338
|
+
_AI_GOALS[goal_id]["stop"](server, entity)
|
|
339
|
+
return
|
|
340
|
+
raise Exception(f"No AI goal registered for ID {goal_id}")
|
|
341
|
+
|
|
342
|
+
def handle_generate_phase(
|
|
343
|
+
self, generator_id: int, phase: world.GenerationPhase, chunk: world.ChunkBuffer
|
|
344
|
+
) -> None:
|
|
345
|
+
if generator_id in _AI_GOALS:
|
|
346
|
+
_GENERATORS[generator_id](phase, chunk)
|
|
347
|
+
return
|
|
348
|
+
raise Exception(f"No generator registered for ID {generator_id}")
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
class MetadataImpl:
|
|
352
|
+
def get_metadata(self) -> metadata.PluginMetadata:
|
|
353
|
+
if _PLUGIN_INSTANCE:
|
|
354
|
+
return _PLUGIN_INSTANCE.metadata()
|
|
355
|
+
return metadata.PluginMetadata("unknown", "0.0.0", [], "No metadata", [], [])
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
package pumpkin:plugin@0.1.0;
|
|
2
|
+
|
|
3
|
+
interface advancement {
|
|
4
|
+
use text.{text-component};
|
|
5
|
+
|
|
6
|
+
/// Frame type for an advancement.
|
|
7
|
+
enum frame-type {
|
|
8
|
+
task,
|
|
9
|
+
challenge,
|
|
10
|
+
goal,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/// Display information for an advancement.
|
|
14
|
+
record advancement-display {
|
|
15
|
+
title: text-component,
|
|
16
|
+
description: text-component,
|
|
17
|
+
frame: frame-type,
|
|
18
|
+
show-toast: bool,
|
|
19
|
+
hidden: bool,
|
|
20
|
+
announce-to-chat: bool,
|
|
21
|
+
background: option<string>,
|
|
22
|
+
x: f32,
|
|
23
|
+
y: f32,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Detailed information about an advancement.
|
|
27
|
+
record advancement-info {
|
|
28
|
+
id: string,
|
|
29
|
+
parent-id: option<string>,
|
|
30
|
+
criteria: list<string>,
|
|
31
|
+
display: option<advancement-display>,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/// Represents progress of an advancement for a player.
|
|
35
|
+
record advancement-progress {
|
|
36
|
+
advancement-id: string,
|
|
37
|
+
done: bool,
|
|
38
|
+
awarded-criteria: list<string>,
|
|
39
|
+
remaining-criteria: list<string>,
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
package pumpkin:plugin@0.1.0;
|
|
2
|
+
|
|
3
|
+
interface attributes {
|
|
4
|
+
enum attribute {
|
|
5
|
+
air-drag-modifier,
|
|
6
|
+
armor,
|
|
7
|
+
armor-toughness,
|
|
8
|
+
attack-damage,
|
|
9
|
+
attack-knockback,
|
|
10
|
+
attack-speed,
|
|
11
|
+
below-name-distance,
|
|
12
|
+
block-break-speed,
|
|
13
|
+
block-interaction-range,
|
|
14
|
+
bounciness,
|
|
15
|
+
burning-time,
|
|
16
|
+
camera-distance,
|
|
17
|
+
explosion-knockback-resistance,
|
|
18
|
+
entity-interaction-range,
|
|
19
|
+
fall-damage-multiplier,
|
|
20
|
+
flying-speed,
|
|
21
|
+
follow-range,
|
|
22
|
+
friction-modifier,
|
|
23
|
+
gravity,
|
|
24
|
+
jump-strength,
|
|
25
|
+
knockback-resistance,
|
|
26
|
+
luck,
|
|
27
|
+
max-absorption,
|
|
28
|
+
max-health,
|
|
29
|
+
mining-efficiency,
|
|
30
|
+
movement-efficiency,
|
|
31
|
+
movement-speed,
|
|
32
|
+
name-tag-distance,
|
|
33
|
+
oxygen-bonus,
|
|
34
|
+
safe-fall-distance,
|
|
35
|
+
scale,
|
|
36
|
+
sneaking-speed,
|
|
37
|
+
spawn-reinforcements,
|
|
38
|
+
step-height,
|
|
39
|
+
submerged-mining-speed,
|
|
40
|
+
sweeping-damage-ratio,
|
|
41
|
+
tempt-range,
|
|
42
|
+
water-movement-efficiency,
|
|
43
|
+
waypoint-transmit-range,
|
|
44
|
+
waypoint-receive-range,
|
|
45
|
+
}
|
|
46
|
+
enum modifier-operation {
|
|
47
|
+
add,
|
|
48
|
+
multiply-base,
|
|
49
|
+
multiply-total,
|
|
50
|
+
}
|
|
51
|
+
record attribute-modifier {
|
|
52
|
+
id: string,
|
|
53
|
+
amount: f64,
|
|
54
|
+
operation: modifier-operation,
|
|
55
|
+
}
|
|
56
|
+
}
|