pywargame 0.3.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.
Files changed (150) hide show
  1. pywargame/__init__.py +2 -0
  2. pywargame/common/__init__.py +3 -0
  3. pywargame/common/collector.py +87 -0
  4. pywargame/common/dicedraw.py +363 -0
  5. pywargame/common/drawdice.py +40 -0
  6. pywargame/common/singleton.py +22 -0
  7. pywargame/common/test.py +25 -0
  8. pywargame/common/verbose.py +59 -0
  9. pywargame/common/verboseguard.py +53 -0
  10. pywargame/cyberboard/__init__.py +18 -0
  11. pywargame/cyberboard/archive.py +283 -0
  12. pywargame/cyberboard/base.py +63 -0
  13. pywargame/cyberboard/board.py +462 -0
  14. pywargame/cyberboard/cell.py +200 -0
  15. pywargame/cyberboard/collect.py +49 -0
  16. pywargame/cyberboard/collectgbx0pwd.py +30 -0
  17. pywargame/cyberboard/collectgbxext.py +30 -0
  18. pywargame/cyberboard/collectgsnexp.py +32 -0
  19. pywargame/cyberboard/collectgsnext.py +30 -0
  20. pywargame/cyberboard/draw.py +396 -0
  21. pywargame/cyberboard/exporter.py +1132 -0
  22. pywargame/cyberboard/extractor.py +240 -0
  23. pywargame/cyberboard/features.py +17 -0
  24. pywargame/cyberboard/gamebox.py +81 -0
  25. pywargame/cyberboard/gbxexp.py +76 -0
  26. pywargame/cyberboard/gbxext.py +64 -0
  27. pywargame/cyberboard/gsnexp.py +147 -0
  28. pywargame/cyberboard/gsnext.py +59 -0
  29. pywargame/cyberboard/head.py +111 -0
  30. pywargame/cyberboard/image.py +76 -0
  31. pywargame/cyberboard/main.py +47 -0
  32. pywargame/cyberboard/mark.py +102 -0
  33. pywargame/cyberboard/palette.py +36 -0
  34. pywargame/cyberboard/piece.py +169 -0
  35. pywargame/cyberboard/player.py +36 -0
  36. pywargame/cyberboard/scenario.py +115 -0
  37. pywargame/cyberboard/testgrid.py +156 -0
  38. pywargame/cyberboard/tile.py +121 -0
  39. pywargame/cyberboard/tray.py +68 -0
  40. pywargame/cyberboard/windows.py +41 -0
  41. pywargame/cyberboard/zeropwd.py +45 -0
  42. pywargame/cyberboard.py +2728 -0
  43. pywargame/gbx0pwd.py +2776 -0
  44. pywargame/gbxextract.py +2795 -0
  45. pywargame/gsnexport.py +16499 -0
  46. pywargame/gsnextract.py +2790 -0
  47. pywargame/latex/__init__.py +2 -0
  48. pywargame/latex/collect.py +34 -0
  49. pywargame/latex/latexexporter.py +4010 -0
  50. pywargame/latex/main.py +184 -0
  51. pywargame/vassal/__init__.py +66 -0
  52. pywargame/vassal/base.py +139 -0
  53. pywargame/vassal/board.py +243 -0
  54. pywargame/vassal/buildfile.py +60 -0
  55. pywargame/vassal/chart.py +79 -0
  56. pywargame/vassal/chessclock.py +197 -0
  57. pywargame/vassal/collect.py +98 -0
  58. pywargame/vassal/collectpatch.py +28 -0
  59. pywargame/vassal/command.py +21 -0
  60. pywargame/vassal/documentation.py +322 -0
  61. pywargame/vassal/dumpcollect.py +28 -0
  62. pywargame/vassal/dumpvsav.py +28 -0
  63. pywargame/vassal/element.py +439 -0
  64. pywargame/vassal/exporter.py +89 -0
  65. pywargame/vassal/extension.py +101 -0
  66. pywargame/vassal/folder.py +103 -0
  67. pywargame/vassal/game.py +940 -0
  68. pywargame/vassal/gameelements.py +1091 -0
  69. pywargame/vassal/globalkey.py +127 -0
  70. pywargame/vassal/globalproperty.py +433 -0
  71. pywargame/vassal/grid.py +573 -0
  72. pywargame/vassal/map.py +1061 -0
  73. pywargame/vassal/mapelements.py +1020 -0
  74. pywargame/vassal/merge.py +57 -0
  75. pywargame/vassal/merger.py +460 -0
  76. pywargame/vassal/moduledata.py +275 -0
  77. pywargame/vassal/mrgcollect.py +31 -0
  78. pywargame/vassal/patch.py +44 -0
  79. pywargame/vassal/patchcollect.py +28 -0
  80. pywargame/vassal/player.py +83 -0
  81. pywargame/vassal/save.py +495 -0
  82. pywargame/vassal/skel.py +380 -0
  83. pywargame/vassal/trait.py +224 -0
  84. pywargame/vassal/traits/__init__.py +36 -0
  85. pywargame/vassal/traits/area.py +50 -0
  86. pywargame/vassal/traits/basic.py +35 -0
  87. pywargame/vassal/traits/calculatedproperty.py +22 -0
  88. pywargame/vassal/traits/cargo.py +29 -0
  89. pywargame/vassal/traits/click.py +41 -0
  90. pywargame/vassal/traits/clone.py +28 -0
  91. pywargame/vassal/traits/delete.py +24 -0
  92. pywargame/vassal/traits/deselect.py +32 -0
  93. pywargame/vassal/traits/dynamicproperty.py +112 -0
  94. pywargame/vassal/traits/globalcommand.py +55 -0
  95. pywargame/vassal/traits/globalhotkey.py +26 -0
  96. pywargame/vassal/traits/globalproperty.py +54 -0
  97. pywargame/vassal/traits/hide.py +67 -0
  98. pywargame/vassal/traits/label.py +76 -0
  99. pywargame/vassal/traits/layer.py +105 -0
  100. pywargame/vassal/traits/mark.py +20 -0
  101. pywargame/vassal/traits/mask.py +85 -0
  102. pywargame/vassal/traits/mat.py +26 -0
  103. pywargame/vassal/traits/moved.py +35 -0
  104. pywargame/vassal/traits/movefixed.py +51 -0
  105. pywargame/vassal/traits/nonrect.py +95 -0
  106. pywargame/vassal/traits/nostack.py +55 -0
  107. pywargame/vassal/traits/place.py +104 -0
  108. pywargame/vassal/traits/prototype.py +20 -0
  109. pywargame/vassal/traits/report.py +34 -0
  110. pywargame/vassal/traits/restrictaccess.py +28 -0
  111. pywargame/vassal/traits/restrictcommand.py +32 -0
  112. pywargame/vassal/traits/return.py +40 -0
  113. pywargame/vassal/traits/rotate.py +62 -0
  114. pywargame/vassal/traits/sendto.py +59 -0
  115. pywargame/vassal/traits/sheet.py +129 -0
  116. pywargame/vassal/traits/skel.py +9 -0
  117. pywargame/vassal/traits/stack.py +28 -0
  118. pywargame/vassal/traits/submenu.py +27 -0
  119. pywargame/vassal/traits/trail.py +61 -0
  120. pywargame/vassal/traits/trigger.py +72 -0
  121. pywargame/vassal/turn.py +272 -0
  122. pywargame/vassal/upgrade.py +191 -0
  123. pywargame/vassal/vmod.py +323 -0
  124. pywargame/vassal/vsav.py +100 -0
  125. pywargame/vassal/widget.py +358 -0
  126. pywargame/vassal/withtraits.py +634 -0
  127. pywargame/vassal/xml.py +4 -0
  128. pywargame/vassal/zone.py +399 -0
  129. pywargame/vassal.py +12500 -0
  130. pywargame/vmodpatch.py +12548 -0
  131. pywargame/vsavdump.py +12533 -0
  132. pywargame/vslmerge.py +13015 -0
  133. pywargame/wgexport.py +16689 -0
  134. pywargame/ztexport.py +14351 -0
  135. pywargame/zuntzu/__init__.py +5 -0
  136. pywargame/zuntzu/base.py +82 -0
  137. pywargame/zuntzu/collect.py +38 -0
  138. pywargame/zuntzu/countersheet.py +250 -0
  139. pywargame/zuntzu/dicehand.py +48 -0
  140. pywargame/zuntzu/exporter.py +936 -0
  141. pywargame/zuntzu/gamebox.py +154 -0
  142. pywargame/zuntzu/map.py +36 -0
  143. pywargame/zuntzu/piece.py +37 -0
  144. pywargame/zuntzu/scenario.py +208 -0
  145. pywargame/zuntzu/ztexp.py +115 -0
  146. pywargame-0.3.1.dist-info/METADATA +353 -0
  147. pywargame-0.3.1.dist-info/RECORD +150 -0
  148. pywargame-0.3.1.dist-info/WHEEL +5 -0
  149. pywargame-0.3.1.dist-info/licenses/LICENSE +5 -0
  150. pywargame-0.3.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,634 @@
1
+ ## BEGIN_IMPORT
2
+ from common import VerboseGuard
3
+ from . base import *
4
+ from . element import Element
5
+ from . command import *
6
+ from . trait import Trait
7
+ from . traits import *
8
+ ## END_IMPORT
9
+
10
+ # --------------------------------------------------------------------
11
+ #
12
+ # Traits of this kind of object are
13
+ #
14
+ # - Evaluated from the start of the list to the end of the list,
15
+ # skipping over report and trigger traits
16
+ # - Then evaluated from the end of the list to the start, only
17
+ # evaluating report and trigger traits
18
+ # - The list _must_ end in a BasicTrait
19
+ #
20
+ # Traits are copied when making a copy of objects of this class, and
21
+ # are done so using a full decoding and encoding. This means that
22
+ # copying is a bit susceptible to expansions of the strings of the traits,
23
+ # in particular if they contain special characters such as ',' or '/'.
24
+ #
25
+ class WithTraits(Element):
26
+ UNIQUE = ['entryName']
27
+ def __init__(self,parent,tag,node=None,traits=[],**kwargs):
28
+ '''Base class for things that have traits
29
+
30
+ Parameters
31
+ ----------
32
+ parent : Element
33
+ Parent to add this to
34
+ node : xml.minidom.Element
35
+ If not None, XML element to read definition from.
36
+ Rest of the arguments are ignored if not None.
37
+ traits : list of Trait objects
38
+ The traits to set on this object
39
+ kwargs : dict
40
+ More attributes to set on element
41
+ '''
42
+ super(WithTraits,self).__init__(parent,tag,node=node,**kwargs)
43
+ if node is None: self.setTraits(*traits)
44
+
45
+ def addTrait(self,trait):
46
+ '''Add a `Trait` element to this. Note that this re-encodes
47
+ all traits.
48
+
49
+ Parameters
50
+ ----------
51
+ trait : Trait
52
+ The trait to add
53
+ '''
54
+ traits = self.getTraits()
55
+ traits.append(trait)
56
+ self.setTraits(*traits)
57
+
58
+
59
+ def getTraits(self):
60
+ '''Get all element traits as objects. This decodes the trait
61
+ definitions. This is useful if we have read the element from
62
+ the XML file, or similar.
63
+
64
+ Note that the list of traits returned are _not_ tied to the
65
+ XML nodes content. Therefore, if one makes changes to the list,
66
+ or to elements of the list, and these changes should be
67
+ reflected in this object, then we _must_ call
68
+
69
+ setTraits(traits)
70
+
71
+ with the changed list of traits.
72
+
73
+ Returns
74
+ -------
75
+ traits : list of Trait objects
76
+ The decoded traits
77
+
78
+ '''
79
+ code = self._node.childNodes[0].nodeValue
80
+ return self.decodeAdd(code)
81
+
82
+ def encodedStates(self):
83
+ from re import split
84
+
85
+ code = self._node.childNodes[0].nodeValue
86
+ cmd, iden, typ, sta = split(fr'(?<!\\)/',code) #code.split('/')
87
+
88
+ return sta
89
+
90
+ def decodeStates(self,code,verbose=False):
91
+ from re import split
92
+
93
+ newstates, oldstates = split(fr'(?<!\\)/',code)#code.split('/')
94
+
95
+ splitit = lambda l : \
96
+ [s.strip('\\').split(';') for s in l.split(r' ')]
97
+
98
+ newstates = splitit(newstates)
99
+ oldstates = splitit(oldstates)
100
+
101
+ traits = self.getTraits()
102
+
103
+ if len(traits) != len(newstates):
104
+ print(f'Piece has {len(traits)} traits but got '
105
+ f'{len(newstates)} states')
106
+
107
+ for trait, state in zip(traits,newstates):
108
+ trait._state = state;
109
+ # print(trait.ID)
110
+ # for n,s in zip(trait._snames,trait._state):
111
+ # print(f' {n:30s}: {s}')
112
+
113
+ self.setTraits(*traits)
114
+
115
+ def copyStates(self,other,verbose=False):
116
+ straits = other.getTraits()
117
+ dtraits = self.getTraits()
118
+
119
+ matches = 0
120
+ for strait in straits:
121
+ if len(strait._state) < 1:
122
+ continue
123
+
124
+ cand = []
125
+ ttrait = None
126
+ for dtrait in dtraits:
127
+ if dtrait.ID == strait.ID:
128
+ cand.append(dtrait)
129
+
130
+ if verbose and len(cand) < 1:
131
+ print(f'Could not find candidate for {strait.ID}')
132
+ continue
133
+
134
+ if len(cand) == 1:
135
+ ttrait = cand[0]
136
+
137
+ else:
138
+ # print(f'Got {len(cand)} candidiate targets {strait.ID}')
139
+
140
+ best = None
141
+ count = 0
142
+ types = strait._type
143
+ for c in cand:
144
+ cnt = sum([ct == t for ct,t in zip(c._type, types)])
145
+ if cnt > count:
146
+ best = c
147
+ count = cnt
148
+
149
+ if verbose and best is None:
150
+ print(f'No candidate for {strait.ID} {len(again)}')
151
+
152
+ if verbose and count+2 < len(types):
153
+ print(f'Ambigious candidate for {strait.ID} '
154
+ f'({count} match out of {len(types)})')
155
+ #print(best._type)
156
+ #print(types)
157
+
158
+ ttrait = best
159
+
160
+ if ttrait is None:
161
+ continue
162
+
163
+ ttrait._state = strait._state
164
+ matches += 1
165
+ # print(ttrait.ID)
166
+ # for n,s in zip(ttrait._snames,ttrait._state):
167
+ # print(f' {n:30s}: {s}')
168
+
169
+ if verbose:
170
+ print(f'Got {matches} matches out of {len(dtraits)}')
171
+
172
+ self.setTraits(*dtraits)
173
+
174
+
175
+ def decodeAdd(self,code,verbose=False):
176
+ '''Try to decode make a piece from a piece of state code'''
177
+ from re import split
178
+
179
+ cmd, iden, typ, sta = split(fr'(?<!\\)/',code) #code.split('/')
180
+ # print(cmd,iden,typ,sta)
181
+
182
+ types = typ.split(r' ')
183
+ states = sta.split(r' ')
184
+ types = [t.strip('\\').split(';') for t in types]
185
+ states = [s.strip('\\').split(';') for s in states]
186
+ traits = []
187
+
188
+ for t, s in zip(types,states):
189
+ tid = t[0]
190
+ trem = t[1:]
191
+ known = False
192
+
193
+ for c in Trait.known_traits:
194
+ t = c.take(tid,trem,s) # See if we have it
195
+ if t is not None:
196
+ traits.append(t) # Got it
197
+ known = True
198
+ break
199
+
200
+ if not known:
201
+ print(f'Warning: Unknown trait {tid}')
202
+
203
+ return traits
204
+
205
+ def encodeAdd(self,*traits,iden='null',verbose=False):
206
+ '''Encodes type and states'''
207
+ if len(traits) < 1: return ''
208
+
209
+ last = traits[-1]
210
+ # A little hackish to use the name of the class, but needed
211
+ # because of imports into patch scripts.
212
+ lastBasic = isinstance(last,BasicTrait) or \
213
+ last.__class__.__name__.endswith('BasicTrait')
214
+ lastStack = isinstance(last,StackTrait) or \
215
+ last.__class__.__name__.endswith('StackTrait')
216
+ if not lastBasic and not lastStack:
217
+ from sys import stderr
218
+ print(f'Warning - last trait NOT a Basic(Stack)Trait, '
219
+ f'but a {type(last)}',
220
+ file=stderr)
221
+
222
+ types = []
223
+ states = []
224
+ for trait in traits:
225
+ if trait is None:
226
+ print(f'Trait is None (traits: {traits})')
227
+ continue
228
+ tpe, state = trait.encode()
229
+ types.append(tpe)
230
+ states.append(state)
231
+
232
+ tpe = WithTraits.encodeParts(*types)
233
+ state = WithTraits.encodeParts(*states)
234
+ add = AddCommand(str(iden),tpe,state)
235
+ return add.cmd
236
+
237
+
238
+ def setTraits(self,*traits,iden='null'):
239
+ '''Set traits on this element. This encodes the traits into
240
+ this object.
241
+
242
+ Parameters
243
+ ----------
244
+ traits : tuple of Trait objects
245
+ The traits to set on this object.
246
+ iden : str
247
+ Identifier
248
+
249
+ '''
250
+ add = self.encodeAdd(*traits,iden=iden)
251
+ if self._node is None:
252
+ # from xml.dom.minidom import Element, Text
253
+ self._node = xmlns.Element(self.TAG)
254
+ self._node.appendChild(xmlns.Text())
255
+
256
+ if len(self._node.childNodes) < 1:
257
+ self.addText('')
258
+ self._node.childNodes[0].nodeValue = add
259
+
260
+ def removeTrait(self,ID,key=None,value=None,verbose=False):
261
+ '''Remove a trait from this object.
262
+
263
+ Parameters
264
+ ----------
265
+ ID : str
266
+ The type of trait to remove. Must be a valid
267
+ ID of a class derived from Trait.
268
+ key : str
269
+ Optional key to inspect to select trait that has
270
+ this key and the traits key value is the argument value,
271
+ value :
272
+ If specified, then only traits which key has this value
273
+ are removed
274
+ verbose : bool
275
+ Be verbose if True
276
+
277
+ Returns
278
+ -------
279
+ trait : Trait
280
+ The removed trait or None
281
+ '''
282
+ traits = self.getTraits()
283
+ trait = Trait.findTrait(traits,ID,key,value,verbose)
284
+ if trait is not None:
285
+ traits.remove(trait)
286
+ self.setTraits(traits)
287
+ return trait
288
+
289
+ def addTraits(self,*toadd):
290
+ '''Add traits to this. Note that this will
291
+ decode and reencode the traits. Only use this when
292
+ adding traits on-mass. Repeated use of this is inefficient.
293
+
294
+ This member function takes care to push any basic trait to
295
+ the end of the list.
296
+
297
+ The added traits will not override existing triats.
298
+
299
+ Paramters
300
+ ---------
301
+ toAdd : tuple of Trait objects
302
+ The traits to add
303
+
304
+ '''
305
+ traits = self.getTraits()
306
+ basic = Trait.findTrait(traits,BasicTrait.ID)
307
+ if basic:
308
+ traits.remove(basic)
309
+ traits.extend(toAdd)
310
+ if basic:
311
+ traits.append(basic)
312
+ self.setTraits(traits)
313
+
314
+
315
+ @classmethod
316
+ def encodeParts(cls,*parts):
317
+ '''Encode parts of a full piece definition
318
+
319
+ Each trait (VASSAL.counter.Decorator,
320
+ VASSAL.counter.BasicPiece) definition or state is separated by
321
+ a litteral TAB character. Beyond the first TAB separator,
322
+ additional escape characters (BACKSLAH) are added in front of
323
+ the separator. This is to that VASSAL.utils.SequenceDecoder
324
+ does not see consequitive TABs as a single TAB.
325
+ '''
326
+ ret = ''
327
+ sep = r' '
328
+ for i, p in enumerate(parts):
329
+ if i != 0:
330
+ ret += '\\'*(i-1) + sep
331
+ ret += str(p)
332
+
333
+ return ret
334
+
335
+
336
+ def cloneNode(self,parent):
337
+ '''This clones the underlying XML node.
338
+
339
+ Parameters
340
+ ----------
341
+ parent : Element
342
+ The element to clone this element into
343
+
344
+ Returns
345
+ -------
346
+ copy : xml.minidom.Element
347
+ The newly created clone of this object's node
348
+ '''
349
+ copy = self._node.cloneNode(deep=True)
350
+ if parent is not None:
351
+ parent._node.appendChild(copy)
352
+ else:
353
+ print('WARNING: No parent to add copy to')
354
+ return copy
355
+
356
+ def print(self,file=None,recursive=1024,indent=''):
357
+ if file is None:
358
+ from sys import stdout
359
+ file = stdout
360
+
361
+ from textwrap import indent as i
362
+
363
+ if recursive <= 1:
364
+ n = len(self.getTraits())
365
+ if n > 1:
366
+ print(i(f' {n} traits',indent),file=file)
367
+ return
368
+
369
+
370
+ from io import StringIO
371
+
372
+
373
+ stream = StringIO()
374
+ traits = self.getTraits()
375
+ for trait in traits:
376
+ trait.print(stream)
377
+
378
+ s = i(stream.getvalue().rstrip(), ' ')
379
+ print(i(s,indent), file=file)
380
+
381
+
382
+ # --------------------------------------------------------------------
383
+ class DummyWithTraits(WithTraits):
384
+ TAG = 'dummy'
385
+ def __init__(self,parent,node=None,traits=[]):
386
+ '''An empty element. Used when making searching'''
387
+ super(DummyWithTraits,self).__init__(tag = self.TAG,
388
+ parent = parent,
389
+ node = node,
390
+ traits = traits)
391
+ if parent is not None:
392
+ parent.remove(self)
393
+
394
+
395
+ registerElement(DummyWithTraits)
396
+
397
+ # --------------------------------------------------------------------
398
+ class WithTraitsSlot(WithTraits):
399
+ def __init__(self,
400
+ parent,
401
+ tag,
402
+ node = None,
403
+ entryName = '',
404
+ traits = [],
405
+ gpid = 0,
406
+ height = 72,
407
+ width = 72,
408
+ icon = ''):
409
+ '''A piece slot. Used all the time.
410
+
411
+ Parameters
412
+ ----------
413
+ parent : Element
414
+ Parent to add this to
415
+ node : xml.minidom.Element
416
+ If not None, XML element to read definition from.
417
+ Rest of the arguments are ignored if not None.
418
+ entryName : str
419
+ Name of this
420
+ traits : list of Trait objects
421
+ The traits to set on this object
422
+ gpid : int
423
+ Global Piece identifier. If 0, will be set by Game
424
+ height : int
425
+ Height size of the piece (in pixels)
426
+ width : int
427
+ Width size of the piece (in pixels)
428
+ icon : str
429
+ Piece image file name within 'image' sub-dir of archive
430
+ '''
431
+ super().\
432
+ __init__(parent,
433
+ tag,
434
+ node = node,
435
+ traits = traits,
436
+ entryName = entryName,
437
+ gpid = gpid,
438
+ height = height,
439
+ width = width,
440
+ icon = icon)
441
+
442
+
443
+ def _clone(self,cls,parent):
444
+ '''Adds copy of self to parent, possibly with new GPID'''
445
+ ## BEGIN_IMPORT
446
+ from . game import Game
447
+ ## END_IMPORT
448
+ game = self.getParentOfClass([Game])
449
+ gpid = game.nextPieceSlotId()
450
+ #opid = int(self.getAttribute('gpid'))
451
+ #print(f'Using GPID={gpid} for clone {opid}')
452
+
453
+ node = self.cloneNode(parent)
454
+ piece = cls(parent,node=node)
455
+ piece.setAttribute('gpid',gpid)
456
+
457
+ traits = piece.getTraits()
458
+ for trait in traits:
459
+ if isinstance(trait,BasicTrait):
460
+ trait['gpid'] = gpid
461
+
462
+ piece.setTraits(*traits)
463
+ return piece
464
+
465
+ def print(self,file=None,recursive=1024,indent=''):
466
+ if file is None:
467
+ from sys import stdout
468
+ file = stdout
469
+ from textwrap import indent as i
470
+
471
+ print(i(f'{type(self).__name__} {self["entryName"]}'+'\n'
472
+ f' gpid : {self["gpid"]}'+'\n'
473
+ f' height: {self["height"]}'+'\n'
474
+ f' width : {self["width"]}'+'\n'
475
+ f' icon : {self["icon"]}',indent),
476
+ file = file)
477
+
478
+ super().print(file=file,
479
+ recursive=recursive-1,
480
+ indent=indent)
481
+
482
+ # --------------------------------------------------------------------
483
+ class PieceSlot(WithTraitsSlot):
484
+ TAG = Element.WIDGET+'PieceSlot'
485
+ def __init__(self,
486
+ parent,
487
+ node = None,
488
+ entryName = '',
489
+ traits = [],
490
+ gpid = 0,
491
+ height = 72,
492
+ width = 72,
493
+ icon = ''):
494
+ '''A piece slot. Used all the time.
495
+
496
+ Parameters
497
+ ----------
498
+ parent : Element
499
+ Parent to add this to
500
+ node : xml.minidom.Element
501
+ If not None, XML element to read definition from.
502
+ Rest of the arguments are ignored if not None.
503
+ entryName : str
504
+ Name of this
505
+ traits : list of Trait objects
506
+ The traits to set on this object
507
+ gpid : int
508
+ Global Piece identifier. If 0, will be set by Game
509
+ height : int
510
+ Height size of the piece (in pixels)
511
+ width : int
512
+ Width size of the piece (in pixels)
513
+ icon : str
514
+ Piece image file name within 'image' sub-dir of archive
515
+ '''
516
+ super().\
517
+ __init__(parent,
518
+ self.TAG,
519
+ node = node,
520
+ traits = traits,
521
+ entryName = entryName,
522
+ gpid = gpid,
523
+ height = height,
524
+ width = width,
525
+ icon = icon)
526
+
527
+
528
+ def clone(self,parent):
529
+ return self._clone(PieceSlot,parent)
530
+
531
+
532
+ registerElement(PieceSlot)
533
+
534
+ # --------------------------------------------------------------------
535
+ class CardSlot(WithTraitsSlot):
536
+ TAG = Element.WIDGET+'CardSlot'
537
+ def __init__(self,
538
+ parent,
539
+ node = None,
540
+ entryName = '',
541
+ traits = [],
542
+ gpid = 0,
543
+ height = 72,
544
+ width = 72,
545
+ icon = ''):
546
+ '''A card slot. Used all the time. It is essentially the
547
+ same as a PieceSlot, though a `MaskTrait` is added (with
548
+ default settings), if no such trait is present (to-be-done)
549
+
550
+ Parameters
551
+ ----------
552
+ parent : Element
553
+ Parent to add this to
554
+ node : xml.minidom.Element
555
+ If not None, XML element to read definition from.
556
+ Rest of the arguments are ignored if not None.
557
+ entryName : str
558
+ Name of this
559
+ traits : list of Trait objects
560
+ The traits to set on this object
561
+ gpid : int
562
+ Global Piece identifier. If 0, will be set by Game
563
+ height : int
564
+ Height size of the card (in pixels)
565
+ width : int
566
+ Width size of the card (in pixels)
567
+ icon : str
568
+ Card image file name within 'image' sub-dir of archive
569
+
570
+ '''
571
+ super().\
572
+ __init__(parent,
573
+ self.TAG,
574
+ node = node,
575
+ traits = traits,
576
+ entryName = entryName,
577
+ gpid = gpid,
578
+ height = height,
579
+ width = width,
580
+ icon = icon)
581
+
582
+ def clone(self,parent):
583
+ return self._clone(CardSlot,parent)
584
+
585
+ registerElement(CardSlot)
586
+
587
+ # --------------------------------------------------------------------
588
+ class Prototype(WithTraits):
589
+ TAG = Element.MODULE+'PrototypeDefinition'
590
+ UNIQUE = ['name']
591
+ def __init__(self,cont,node=None,
592
+ name = '',
593
+ traits = [],
594
+ description = ''):
595
+ '''A prototype. Used all the time.
596
+
597
+ Parameters
598
+ ----------
599
+ cont : Element
600
+ Parent to add this to
601
+ node : xml.minidom.Element
602
+ If not None, XML element to read definition from.
603
+ Rest of the arguments are ignored if not None.
604
+ name : str
605
+ Name of this
606
+ traits : list of Trait objects
607
+ The traits to set on this object
608
+ description : str
609
+ A free-form description of this prototype
610
+ '''
611
+ super(Prototype,self).__init__(cont,self.TAG,node=node,
612
+ traits = traits,
613
+ name = name,
614
+ description = description)
615
+
616
+ def print(self,file=None,recursive=1024,indent=''):
617
+ if file is None:
618
+ from sys import stdout
619
+ file = stdout
620
+ from textwrap import indent as i
621
+
622
+ print(i(f'Prototype {self["name"]}'+'\n'
623
+ f' description: {self["description"]}',indent),
624
+ file = file)
625
+
626
+ super(Prototype,self).print(file=file,
627
+ indent=indent,
628
+ recursive=recursive-1)
629
+
630
+ registerElement(Prototype)
631
+
632
+ #
633
+ # EOF
634
+ #
@@ -0,0 +1,4 @@
1
+ # --------------------------------------------------------------------
2
+ # XML Dom parser namespace
3
+ import xml.dom.minidom as xmlns
4
+ #import xml.dom as xmlns