dfpyre 0.4.5__py3-none-any.whl → 0.8.1__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.

Potentially problematic release.


This version of dfpyre might be problematic. Click here for more details.

dfpyre/items.py CHANGED
@@ -1,361 +1,396 @@
1
- """
2
- Contains class definitions for code items.
3
- """
4
-
5
- from enum import Enum
6
- from typing import Literal, Dict
7
- from dfpyre.style import isAmpersandCoded, ampersandToMinimessage
8
-
9
-
10
- def _add_slot(d: Dict, slot: int|None):
11
- if slot is not None:
12
- d['slot'] = slot
13
-
14
-
15
- class item:
16
- """
17
- Represents a Minecraft item.
18
- """
19
- type = 'item'
20
-
21
- def __init__(self, itemID: str, count: int=1):
22
- self.id = itemID
23
- self.count = count
24
-
25
- def format(self, slot: int|None):
26
- formattedDict = {
27
- "item": {
28
- "id": self.type,
29
- "data": {
30
- "item": f"{{DF_NBT:2586,id:\"{self.id}\",Count:{self.count}b}}"
31
- }
32
- }
33
- }
34
- _add_slot(formattedDict, slot)
35
- return formattedDict
36
-
37
-
38
- class string:
39
- """
40
- Represents a DiamondFire string object. (`txt`)
41
- """
42
- type = 'txt'
43
-
44
- def __init__(self, value: str):
45
- self.value = value
46
-
47
- def format(self, slot: int|None):
48
- formattedDict = {
49
- "item": {
50
- "id": self.type,
51
- "data": {
52
- "name": self.value
53
- }
54
- }
55
- }
56
- _add_slot(formattedDict, slot)
57
- return formattedDict
58
-
59
-
60
- class text:
61
- """
62
- Represents a DiamondFire styled text object (`comp`)
63
- """
64
- type = 'comp'
65
-
66
- def __init__(self, value: str):
67
- if isAmpersandCoded(value):
68
- value = ampersandToMinimessage(value)
69
- self.value = value
70
-
71
- def format(self, slot: int|None):
72
- formattedDict = {
73
- "item": {
74
- "id": self.type,
75
- "data": {
76
- "name": self.value
77
- }
78
- }
79
- }
80
- _add_slot(formattedDict, slot)
81
- return formattedDict
82
-
83
-
84
- class num:
85
- """
86
- Represents a DiamondFire number object.
87
- """
88
- type = 'num'
89
-
90
- def __init__(self, num: int|float):
91
- self.value = num
92
-
93
- def format(self, slot: int|None):
94
- formattedDict = {
95
- "item": {
96
- "id": self.type,
97
- "data": {
98
- "name": str(self.value)
99
- }
100
- }
101
- }
102
- _add_slot(formattedDict, slot)
103
- return formattedDict
104
-
105
-
106
- class loc:
107
- """
108
- Represents a DiamondFire location object.
109
- """
110
- type = 'loc'
111
-
112
- def __init__(self, x: float=0, y: float=0, z: float=0, pitch: float=0, yaw: float=0):
113
- self.x = float(x)
114
- self.y = float(y)
115
- self.z = float(z)
116
- self.pitch = float(pitch)
117
- self.yaw = float(yaw)
118
-
119
- def format(self, slot: int|None):
120
- formattedDict = {
121
- "item": {
122
- "id": self.type,
123
- "data": {
124
- "isBlock": False,
125
- "loc": {
126
- "x": self.x,
127
- "y": self.y,
128
- "z": self.z,
129
- "pitch": self.pitch,
130
- "yaw": self.yaw
131
- }
132
- }
133
- }
134
- }
135
- _add_slot(formattedDict, slot)
136
- return formattedDict
137
-
138
-
139
- class var:
140
- """
141
- Represents a DiamondFire variable object.
142
- """
143
- type = 'var'
144
-
145
- def __init__(self, name: str, scope: Literal['unsaved', 'saved', 'local', 'line']='unsaved'):
146
- self.name = name
147
- self.scope = scope
148
-
149
- def format(self, slot: int|None):
150
- formattedDict = {
151
- "item": {
152
- "id": self.type,
153
- "data": {
154
- "name": self.name,
155
- "scope": self.scope
156
- }
157
- }
158
- }
159
- _add_slot(formattedDict, slot)
160
- return formattedDict
161
-
162
-
163
- class sound:
164
- """
165
- Represents a DiamondFire sound object.
166
- """
167
- type = 'snd'
168
-
169
- def __init__(self, name: str, pitch: float=1.0, vol: float=2.0):
170
- self.name = name
171
- self.pitch = pitch
172
- self.vol = vol
173
-
174
- def format(self, slot: int|None):
175
- formattedDict = {
176
- "item": {
177
- "id": self.type,
178
- "data": {
179
- "sound": self.name,
180
- "pitch": self.pitch,
181
- "vol": self.vol
182
- }
183
- }
184
- }
185
- _add_slot(formattedDict, slot)
186
- return formattedDict
187
-
188
-
189
- class particle:
190
- """
191
- Represents a DiamondFire particle object.
192
- """
193
- type = 'part'
194
- def __init__(self, name: str='Cloud', amount: int=1, horizontal: float=0.0, vertical: float=0.0,
195
- x: float=1.0, y: float=0.0, z: float=0.0, motionVariation: float=100):
196
- self.name = name
197
- self.amount = amount
198
- self.horizontal = horizontal
199
- self.vertical = vertical
200
- self.x = x
201
- self.y = y
202
- self.z = z
203
- self.motionVariation = motionVariation
204
-
205
- def format(self, slot: int|None):
206
- formattedDict = {
207
- "item": {
208
- "id": self.type,
209
- "data": {
210
- "particle": self.name,
211
- "cluster": {
212
- "amount": self.amount,
213
- "horizontal": self.horizontal,
214
- "vertical": self.vertical
215
- },
216
- "data": {
217
- "x": self.x,
218
- "y": self.y,
219
- "z": self.z,
220
- "motionVariation": self.motionVariation
221
- }
222
- }
223
- }
224
- }
225
- _add_slot(formattedDict, slot)
226
- return formattedDict
227
-
228
-
229
- class potion:
230
- """
231
- Represents a DiamondFire potion object.
232
- """
233
- type = 'pot'
234
-
235
- def __init__(self, name: str, dur: int=1000000, amp: int=0):
236
- self.name = name
237
- self.dur = dur
238
- self.amp = amp
239
-
240
- def format(self, slot: int|None):
241
- formattedDict = {
242
- "item": {
243
- "id": self.type,
244
- "data": {
245
- "pot": self.name,
246
- "dur": self.dur,
247
- "amp": self.amp
248
- }
249
- }
250
- }
251
- _add_slot(formattedDict, slot)
252
- return formattedDict
253
-
254
-
255
- class gamevalue:
256
- """
257
- Represents a DiamondFire game value object.
258
- """
259
- type = 'g_val'
260
-
261
- def __init__(self, name: str, target: str='Default'):
262
- self.name = name
263
- self.target = target
264
-
265
- def format(self, slot: int|None):
266
- formattedDict = {
267
- "item": {
268
- "id": self.type,
269
- "data": {
270
- "type": self.name,
271
- "target": self.target
272
- }
273
- }
274
- }
275
- _add_slot(formattedDict, slot)
276
- return formattedDict
277
-
278
-
279
- class vector:
280
- """
281
- Represents a DiamondFire vector object.
282
- """
283
- type = 'vec'
284
-
285
- def __init__(self, x: float=0.0, y: float=0.0, z: float=0.0):
286
- self.x = float(x)
287
- self.y = float(y)
288
- self.z = float(z)
289
-
290
- def format(self, slot: int|None):
291
- formattedDict = {
292
- "item": {
293
- "id": self.type,
294
- "data": {
295
- "x": self.x,
296
- "y": self.y,
297
- "z": self.z
298
- }
299
- }
300
- }
301
- _add_slot(formattedDict, slot)
302
- return formattedDict
303
-
304
-
305
- PARAMETER_TYPE_LOOKUP = ['txt', 'comp', 'num', 'loc', 'vec', 'snd', 'part', 'pot', 'item', 'any', 'var', 'list', 'dict']
306
-
307
- class ParameterType(Enum):
308
- STRING = 0
309
- TEXT = 1
310
- NUMBER = 2
311
- LOCATION = 3
312
- VECTOR = 4
313
- SOUND = 5
314
- PARTICLE = 6
315
- POTION_EFFECT = 7
316
- ITEM = 8
317
- ANY = 9
318
- VAR = 10
319
- LIST = 11
320
- DICT = 12
321
-
322
- def get_string_value(self) -> str:
323
- return PARAMETER_TYPE_LOOKUP[self.value]
324
-
325
- class parameter:
326
- """
327
- Represents a DiamondFire parameter object.
328
- """
329
- type = 'pn_el'
330
-
331
- def __init__(self, name: str, paramType: ParameterType, plural: bool=False, optional: bool=False, description: str="", note: str="", defaultValue=None):
332
- self.name = name
333
- self.paramType = paramType
334
- self.plural = plural
335
- self.optional = optional
336
- self.description = description
337
- self.note = note
338
- self.defaultValue = defaultValue
339
-
340
-
341
- def format(self, slot: int):
342
- formattedDict = {
343
- "item": {
344
- "id": self.type,
345
- "data": {
346
- "name": self.name,
347
- "type": self.paramType.get_string_value(),
348
- "plural": self.plural,
349
- "optional": self.optional,
350
- }
351
- },
352
- "slot": slot
353
- }
354
- if self.description:
355
- formattedDict['item']['data']['description'] = self.description
356
- if self.note:
357
- formattedDict['item']['data']['note'] = self.note
358
- if self.defaultValue is not None and not self.plural and self.optional:
359
- formattedDict['item']['data']['default_value'] = self.defaultValue.format(None)['item']
360
-
361
- return formattedDict
1
+ """
2
+ Class definitions for code items.
3
+ """
4
+
5
+ from enum import Enum
6
+ import re
7
+ from typing import Literal, Any
8
+ from dfpyre.style import is_ampersand_coded, ampersand_to_minimessage
9
+ from dfpyre.util import PyreException, warn
10
+ from mcitemlib.itemlib import Item as NbtItem
11
+
12
+
13
+ NUMBER_REGEX = r'^-?\d*\.?\d+$'
14
+ VAR_SHORTHAND_REGEX = r'^\$([gsli]) (.+)$'
15
+ VAR_SCOPES = {'g': 'unsaved', 's': 'saved', 'l': 'local', 'i': 'line'}
16
+
17
+
18
+ def convert_argument(arg: Any):
19
+ if type(arg) in {int, float}:
20
+ return Number(arg)
21
+ elif isinstance(arg, str):
22
+ shorthand_match: re.Match = re.match(VAR_SHORTHAND_REGEX, arg)
23
+ if shorthand_match:
24
+ scope = VAR_SCOPES[shorthand_match.group(1)]
25
+ return Variable(shorthand_match.group(2), scope)
26
+ return Text(arg)
27
+ return arg
28
+
29
+
30
+ def _add_slot(d: dict, slot: int|None):
31
+ if slot is not None:
32
+ d['slot'] = slot
33
+
34
+
35
+ class Item(NbtItem):
36
+ """
37
+ Represents a Minecraft item.
38
+ """
39
+ type = 'item'
40
+
41
+ def format(self, slot: int|None):
42
+ formatted_dict = {"item": {"id": self.type, "data": {"item": self.get_nbt()}}}
43
+ _add_slot(formatted_dict, slot)
44
+ return formatted_dict
45
+
46
+ def __repr__(self) -> str:
47
+ return f'{self.__class__.__name__}({self.get_id()}, {self.get_count()})'
48
+
49
+
50
+ class String:
51
+ """
52
+ Represents a DiamondFire string object. (`txt`)
53
+ """
54
+ type = 'txt'
55
+
56
+ def __init__(self, value: str):
57
+ self.value = value
58
+
59
+ def format(self, slot: int|None):
60
+ formatted_dict = {"item": {"id": self.type, "data": {"name": self.value}}}
61
+ _add_slot(formatted_dict, slot)
62
+ return formatted_dict
63
+
64
+ def __repr__(self) -> str:
65
+ return f'{self.__class__.__name__}("{self.value}")'
66
+
67
+ Str = String # String alias
68
+
69
+
70
+ class Text:
71
+ """
72
+ Represents a DiamondFire styled text object (`comp`)
73
+ """
74
+ type = 'comp'
75
+
76
+ def __init__(self, value: str):
77
+ if is_ampersand_coded(value):
78
+ value = ampersand_to_minimessage(value)
79
+ self.value = value
80
+
81
+ def format(self, slot: int|None):
82
+ formatted_dict = {"item": {"id": self.type, "data": {"name": self.value}}}
83
+ _add_slot(formatted_dict, slot)
84
+ return formatted_dict
85
+
86
+ def __repr__(self) -> str:
87
+ return f'{self.__class__.__name__}("{self.value}")'
88
+
89
+
90
+ class Number:
91
+ """
92
+ Represents a DiamondFire number object.
93
+ """
94
+ type = 'num'
95
+
96
+ def __init__(self, num: int|float|str):
97
+ self.value = num
98
+
99
+ def format(self, slot: int|None):
100
+ formatted_dict = {"item": {"id": self.type, "data": {"name": str(self.value)}}}
101
+ _add_slot(formatted_dict, slot)
102
+ return formatted_dict
103
+
104
+ def __repr__(self) -> str:
105
+ return f'{self.__class__.__name__}({self.value})'
106
+
107
+ Num = Number # Number alias
108
+
109
+
110
+ class Location:
111
+ """
112
+ Represents a DiamondFire location object.
113
+ """
114
+ type = 'loc'
115
+
116
+ def __init__(self, x: float=0, y: float=0, z: float=0, pitch: float=0, yaw: float=0):
117
+ self.x = float(x)
118
+ self.y = float(y)
119
+ self.z = float(z)
120
+ self.pitch = float(pitch)
121
+ self.yaw = float(yaw)
122
+
123
+ def format(self, slot: int|None):
124
+ formatted_dict = {"item": {
125
+ "id": self.type,
126
+ "data": {
127
+ "isBlock": False,
128
+ "loc": {
129
+ "x": self.x,
130
+ "y": self.y,
131
+ "z": self.z,
132
+ "pitch": self.pitch,
133
+ "yaw": self.yaw
134
+ }
135
+ }
136
+ }}
137
+ _add_slot(formatted_dict, slot)
138
+ return formatted_dict
139
+
140
+ def __repr__(self) -> str:
141
+ return f'{self.__class__.__name__}({self.x}, {self.y}, {self.z}, {self.pitch}, {self.yaw})'
142
+
143
+ Loc = Location # Location alias
144
+
145
+
146
+ class Variable:
147
+ """
148
+ Represents a DiamondFire variable object.
149
+ """
150
+ type = 'var'
151
+
152
+ def __init__(self, name: str, scope: Literal['unsaved', 'game', 'saved', 'local', 'line']='unsaved'):
153
+ self.name = name
154
+
155
+ if scope == 'game':
156
+ scope = 'unsaved'
157
+ self.scope = scope
158
+
159
+ def format(self, slot: int|None):
160
+ formatted_dict = {"item": {"id": self.type,"data": {"name": self.name, "scope": self.scope}}}
161
+ _add_slot(formatted_dict, slot)
162
+ return formatted_dict
163
+
164
+ def __repr__(self) -> str:
165
+ return f'{self.__class__.__name__}({self.scope}, "{self.name}")'
166
+
167
+ Var = Variable # Variable alias
168
+
169
+
170
+ class Sound:
171
+ """
172
+ Represents a DiamondFire sound object.
173
+ """
174
+ type = 'snd'
175
+
176
+ def __init__(self, name: str, pitch: float=1.0, vol: float=2.0):
177
+ self.name = name
178
+ self.pitch = pitch
179
+ self.vol = vol
180
+
181
+ def format(self, slot: int|None):
182
+ formatted_dict = {"item": {"id": self.type,"data": {"sound": self.name, "pitch": self.pitch, "vol": self.vol}}}
183
+ _add_slot(formatted_dict, slot)
184
+ return formatted_dict
185
+
186
+ def __repr__(self) -> str:
187
+ return f'{self.__class__.__name__}(pitch: {self.pitch}, volume: {self.vol})'
188
+
189
+ Snd = Sound # Sound alias
190
+
191
+
192
+ class Particle:
193
+ """
194
+ Represents a DiamondFire particle object.
195
+ """
196
+ type = 'part'
197
+ def __init__(self, particle_data: dict):
198
+ self.particle_data = particle_data
199
+
200
+ def format(self, slot: int|None):
201
+ formatted_dict = {"item": {"id": self.type, "data": self.particle_data}}
202
+ _add_slot(formatted_dict, slot)
203
+ return formatted_dict
204
+
205
+ def __repr__(self) -> str:
206
+ return f'{self.__class__.__name__}({self.particle_data})'
207
+
208
+
209
+ class Potion:
210
+ """
211
+ Represents a DiamondFire potion object.
212
+ """
213
+ type = 'pot'
214
+
215
+ def __init__(self, name: str, dur: int=1000000, amp: int=0):
216
+ self.name = name
217
+ self.dur = dur
218
+ self.amp = amp
219
+
220
+ def format(self, slot: int|None):
221
+ formatted_dict = {"item": {"id": self.type,"data": {"pot": self.name, "dur": self.dur, "amp": self.amp}}}
222
+ _add_slot(formatted_dict, slot)
223
+ return formatted_dict
224
+
225
+ def __repr__(self) -> str:
226
+ return f'{self.__class__.__name__}(effect: {self.name}, duration: {self.dur}, amplifier: {self.amp})'
227
+
228
+ Pot = Potion # Potion alias
229
+
230
+
231
+ class GameValue:
232
+ """
233
+ Represents a DiamondFire game value object.
234
+ """
235
+ type = 'g_val'
236
+
237
+ def __init__(self, name: str, target: str='Default'):
238
+ self.name = name
239
+ self.target = target
240
+
241
+ def format(self, slot: int|None):
242
+ formatted_dict = {"item": {"id": self.type, "data": {"type": self.name, "target": self.target}}}
243
+ _add_slot(formatted_dict, slot)
244
+ return formatted_dict
245
+
246
+ def __repr__(self) -> str:
247
+ return f'{self.__class__.__name__}({self.name}, target: {self.target})'
248
+
249
+
250
+ class Vector:
251
+ """
252
+ Represents a DiamondFire vector object.
253
+ """
254
+ type = 'vec'
255
+
256
+ def __init__(self, x: float=0.0, y: float=0.0, z: float=0.0):
257
+ self.x = float(x)
258
+ self.y = float(y)
259
+ self.z = float(z)
260
+
261
+ def format(self, slot: int|None):
262
+ formatted_dict = {"item": {"id": self.type, "data": {"x": self.x, "y": self.y, "z": self.z}}}
263
+ _add_slot(formatted_dict, slot)
264
+ return formatted_dict
265
+
266
+ def __repr__(self) -> str:
267
+ return f'{self.__class__.__name__}({self.x}, {self.y}, {self.z})'
268
+
269
+ Vec = Vector # Vector alias
270
+
271
+
272
+ PARAMETER_TYPE_LOOKUP = ['txt', 'comp', 'num', 'loc', 'vec', 'snd', 'part', 'pot', 'item', 'any', 'var', 'list', 'dict']
273
+
274
+ class ParameterType(Enum):
275
+ STRING = 0
276
+ TEXT = 1
277
+ NUMBER = 2
278
+ LOCATION = 3
279
+ VECTOR = 4
280
+ SOUND = 5
281
+ PARTICLE = 6
282
+ POTION_EFFECT = 7
283
+ ITEM = 8
284
+ ANY = 9
285
+ VAR = 10
286
+ LIST = 11
287
+ DICT = 12
288
+
289
+ def get_string_value(self) -> str:
290
+ return PARAMETER_TYPE_LOOKUP[self.value]
291
+
292
+ class Parameter:
293
+ """
294
+ Represents a DiamondFire parameter object.
295
+ """
296
+ type = 'pn_el'
297
+
298
+ def __init__(self, name: str, param_type: ParameterType, plural: bool=False, optional: bool=False, description: str="", note: str="", default_value=None):
299
+ self.name = name
300
+ self.param_type = param_type
301
+ self.plural = plural
302
+ self.optional = optional
303
+ self.description = description
304
+ self.note = note
305
+ self.default_value = convert_argument(default_value)
306
+
307
+
308
+ def format(self, slot: int):
309
+ formatted_dict = {"item": {
310
+ "id": self.type,
311
+ "data": {
312
+ "name": self.name,
313
+ "type": self.param_type.get_string_value(),
314
+ "plural": self.plural,
315
+ "optional": self.optional,
316
+ }},
317
+ "slot": slot
318
+ }
319
+ if self.description:
320
+ formatted_dict['item']['data']['description'] = self.description
321
+ if self.note:
322
+ formatted_dict['item']['data']['note'] = self.note
323
+ if self.default_value is not None:
324
+ if not self.optional:
325
+ warn(f'For parameter "{self.name}": Default value cannot be set if optional is False.')
326
+ elif self.plural:
327
+ warn(f'For parameter "{self.name}": Default value cannot be set while plural is True.')
328
+ else:
329
+ formatted_dict['item']['data']['default_value'] = self.default_value.format(None)['item']
330
+
331
+ return formatted_dict
332
+
333
+ def __repr__(self) -> str:
334
+ raw_type = str(self.param_type).partition('.')[2]
335
+ return f'{self.__class__.__name__}({self.name}, type: {raw_type})'
336
+
337
+
338
+ def item_from_dict(item_dict: dict) -> object:
339
+ item_id = item_dict['id']
340
+ item_data = item_dict['data']
341
+
342
+ if item_id == 'item':
343
+ return Item.from_nbt(item_data['item'])
344
+
345
+ elif item_id == 'txt':
346
+ return String(item_data['name'])
347
+
348
+ elif item_id == 'comp':
349
+ return Text(item_data['name'])
350
+
351
+ elif item_id == 'num':
352
+ num_value = item_data['name']
353
+ if re.match(NUMBER_REGEX, num_value):
354
+ num_value = float(item_data['name'])
355
+ if num_value % 1 == 0:
356
+ num_value = int(num_value)
357
+ return Number(num_value)
358
+ return Number(num_value)
359
+
360
+ elif item_id == 'loc':
361
+ item_loc = item_data['loc']
362
+ return Location(item_loc['x'], item_loc['y'], item_loc['z'], item_loc['pitch'], item_loc['yaw'])
363
+
364
+ elif item_id == 'var':
365
+ return Variable(item_data['name'], item_data['scope'])
366
+
367
+ elif item_id == 'snd':
368
+ return Sound(item_data['sound'], item_data['pitch'], item_data['vol'])
369
+
370
+ elif item_id == 'part':
371
+ return Particle(item_data)
372
+
373
+ elif item_id == 'pot':
374
+ return Potion(item_data['pot'], item_data['dur'], item_data['amp'])
375
+
376
+ elif item_id == 'g_val':
377
+ return GameValue(item_data['type'], item_data['target'])
378
+
379
+ elif item_id == 'vec':
380
+ return Vector(item_data['x'], item_data['y'], item_data['z'])
381
+
382
+ elif item_id == 'pn_el':
383
+ description = item_data.get('description') or ''
384
+ note = item_data.get('note') or ''
385
+ param_type = ParameterType(PARAMETER_TYPE_LOOKUP.index(item_data['type']))
386
+ if item_data['optional']:
387
+ if 'default_value' in item_data:
388
+ return Parameter(item_data['name'], param_type, item_data['plural'], True, description, note, item_from_dict(item_data['default_value']))
389
+ return Parameter(item_data['name'], param_type, item_data['plural'], True, description, note)
390
+ return Parameter(item_data['name'], param_type, item_data['plural'], False, description, note)
391
+
392
+ elif item_id in {'bl_tag', 'hint'}: # Ignore tags and hints
393
+ return
394
+
395
+ else:
396
+ raise PyreException(f'Unrecognized item id `{item_id}`')