dfpyre 0.4.6__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,41 +1,53 @@
1
1
  """
2
- Contains class definitions for code items.
2
+ Class definitions for code items.
3
3
  """
4
4
 
5
5
  from enum import Enum
6
- from typing import Literal, Dict
7
- from dfpyre.style import isAmpersandCoded, ampersandToMinimessage
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
8
11
 
9
12
 
10
- def _add_slot(d: Dict, slot: int|None):
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):
11
31
  if slot is not None:
12
32
  d['slot'] = slot
13
33
 
14
34
 
15
- class item:
35
+ class Item(NbtItem):
16
36
  """
17
37
  Represents a Minecraft item.
18
38
  """
19
39
  type = 'item'
20
40
 
21
- def __init__(self, itemID: str, count: int=1):
22
- self.id = itemID
23
- self.count = count
24
-
25
41
  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
42
+ formatted_dict = {"item": {"id": self.type, "data": {"item": self.get_nbt()}}}
43
+ _add_slot(formatted_dict, slot)
44
+ return formatted_dict
36
45
 
46
+ def __repr__(self) -> str:
47
+ return f'{self.__class__.__name__}({self.get_id()}, {self.get_count()})'
37
48
 
38
- class string:
49
+
50
+ class String:
39
51
  """
40
52
  Represents a DiamondFire string object. (`txt`)
41
53
  """
@@ -45,65 +57,57 @@ class string:
45
57
  self.value = value
46
58
 
47
59
  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
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
58
68
 
59
69
 
60
- class text:
70
+ class Text:
61
71
  """
62
72
  Represents a DiamondFire styled text object (`comp`)
63
73
  """
64
74
  type = 'comp'
65
75
 
66
76
  def __init__(self, value: str):
67
- if isAmpersandCoded(value):
68
- value = ampersandToMinimessage(value)
77
+ if is_ampersand_coded(value):
78
+ value = ampersand_to_minimessage(value)
69
79
  self.value = value
70
-
80
+
71
81
  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
+ formatted_dict = {"item": {"id": self.type, "data": {"name": self.value}}}
83
+ _add_slot(formatted_dict, slot)
84
+ return formatted_dict
82
85
 
86
+ def __repr__(self) -> str:
87
+ return f'{self.__class__.__name__}("{self.value}")'
83
88
 
84
- class num:
89
+
90
+ class Number:
85
91
  """
86
92
  Represents a DiamondFire number object.
87
93
  """
88
94
  type = 'num'
89
95
 
90
- def __init__(self, num: int|float):
96
+ def __init__(self, num: int|float|str):
91
97
  self.value = num
92
98
 
93
99
  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
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
104
108
 
105
109
 
106
- class loc:
110
+ class Location:
107
111
  """
108
112
  Represents a DiamondFire location object.
109
113
  """
@@ -117,50 +121,53 @@ class loc:
117
121
  self.yaw = float(yaw)
118
122
 
119
123
  def format(self, slot: int|None):
120
- formattedDict = {
121
- "item": {
122
- "id": self.type,
123
- "data": {
124
+ formatted_dict = {"item": {
125
+ "id": self.type,
126
+ "data": {
124
127
  "isBlock": False,
125
128
  "loc": {
126
- "x": self.x,
127
- "y": self.y,
128
- "z": self.z,
129
- "pitch": self.pitch,
130
- "yaw": self.yaw
129
+ "x": self.x,
130
+ "y": self.y,
131
+ "z": self.z,
132
+ "pitch": self.pitch,
133
+ "yaw": self.yaw
131
134
  }
132
- }
133
135
  }
134
- }
135
- _add_slot(formattedDict, slot)
136
- return formattedDict
136
+ }}
137
+ _add_slot(formatted_dict, slot)
138
+ return formatted_dict
137
139
 
140
+ def __repr__(self) -> str:
141
+ return f'{self.__class__.__name__}({self.x}, {self.y}, {self.z}, {self.pitch}, {self.yaw})'
138
142
 
139
- class var:
143
+ Loc = Location # Location alias
144
+
145
+
146
+ class Variable:
140
147
  """
141
148
  Represents a DiamondFire variable object.
142
149
  """
143
150
  type = 'var'
144
151
 
145
- def __init__(self, name: str, scope: Literal['unsaved', 'saved', 'local', 'line']='unsaved'):
152
+ def __init__(self, name: str, scope: Literal['unsaved', 'game', 'saved', 'local', 'line']='unsaved'):
146
153
  self.name = name
154
+
155
+ if scope == 'game':
156
+ scope = 'unsaved'
147
157
  self.scope = scope
148
158
 
149
159
  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
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
161
168
 
162
169
 
163
- class sound:
170
+ class Sound:
164
171
  """
165
172
  Represents a DiamondFire sound object.
166
173
  """
@@ -172,61 +179,34 @@ class sound:
172
179
  self.vol = vol
173
180
 
174
181
  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
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
187
190
 
188
191
 
189
- class particle:
192
+ class Particle:
190
193
  """
191
194
  Represents a DiamondFire particle object.
192
195
  """
193
196
  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
197
+ def __init__(self, particle_data: dict):
198
+ self.particle_data = particle_data
204
199
 
205
200
  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
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})'
227
207
 
228
208
 
229
- class potion:
209
+ class Potion:
230
210
  """
231
211
  Represents a DiamondFire potion object.
232
212
  """
@@ -238,21 +218,17 @@ class potion:
238
218
  self.amp = amp
239
219
 
240
220
  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
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})'
253
227
 
228
+ Pot = Potion # Potion alias
254
229
 
255
- class gamevalue:
230
+
231
+ class GameValue:
256
232
  """
257
233
  Represents a DiamondFire game value object.
258
234
  """
@@ -263,20 +239,15 @@ class gamevalue:
263
239
  self.target = target
264
240
 
265
241
  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
242
+ formatted_dict = {"item": {"id": self.type, "data": {"type": self.name, "target": self.target}}}
243
+ _add_slot(formatted_dict, slot)
244
+ return formatted_dict
277
245
 
246
+ def __repr__(self) -> str:
247
+ return f'{self.__class__.__name__}({self.name}, target: {self.target})'
278
248
 
279
- class vector:
249
+
250
+ class Vector:
280
251
  """
281
252
  Represents a DiamondFire vector object.
282
253
  """
@@ -288,18 +259,14 @@ class vector:
288
259
  self.z = float(z)
289
260
 
290
261
  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
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
303
270
 
304
271
 
305
272
  PARAMETER_TYPE_LOOKUP = ['txt', 'comp', 'num', 'loc', 'vec', 'snd', 'part', 'pot', 'item', 'any', 'var', 'list', 'dict']
@@ -322,40 +289,108 @@ class ParameterType(Enum):
322
289
  def get_string_value(self) -> str:
323
290
  return PARAMETER_TYPE_LOOKUP[self.value]
324
291
 
325
- class parameter:
292
+ class Parameter:
326
293
  """
327
294
  Represents a DiamondFire parameter object.
328
295
  """
329
296
  type = 'pn_el'
330
297
 
331
- def __init__(self, name: str, paramType: ParameterType, plural: bool=False, optional: bool=False, description: str="", note: str="", defaultValue=None):
298
+ def __init__(self, name: str, param_type: ParameterType, plural: bool=False, optional: bool=False, description: str="", note: str="", default_value=None):
332
299
  self.name = name
333
- self.paramType = paramType
300
+ self.param_type = param_type
334
301
  self.plural = plural
335
302
  self.optional = optional
336
303
  self.description = description
337
304
  self.note = note
338
- self.defaultValue = defaultValue
305
+ self.default_value = convert_argument(default_value)
339
306
 
340
307
 
341
308
  def format(self, slot: int):
342
- formattedDict = {
343
- "item": {
344
- "id": self.type,
345
- "data": {
309
+ formatted_dict = {"item": {
310
+ "id": self.type,
311
+ "data": {
346
312
  "name": self.name,
347
- "type": self.paramType.get_string_value(),
313
+ "type": self.param_type.get_string_value(),
348
314
  "plural": self.plural,
349
315
  "optional": self.optional,
350
- }
351
- },
316
+ }},
352
317
  "slot": slot
353
- }
318
+ }
354
319
  if self.description:
355
- formattedDict['item']['data']['description'] = self.description
320
+ formatted_dict['item']['data']['description'] = self.description
356
321
  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']
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']
360
330
 
361
- return formattedDict
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}`')