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.
- pywargame/__init__.py +2 -0
- pywargame/common/__init__.py +3 -0
- pywargame/common/collector.py +87 -0
- pywargame/common/dicedraw.py +363 -0
- pywargame/common/drawdice.py +40 -0
- pywargame/common/singleton.py +22 -0
- pywargame/common/test.py +25 -0
- pywargame/common/verbose.py +59 -0
- pywargame/common/verboseguard.py +53 -0
- pywargame/cyberboard/__init__.py +18 -0
- pywargame/cyberboard/archive.py +283 -0
- pywargame/cyberboard/base.py +63 -0
- pywargame/cyberboard/board.py +462 -0
- pywargame/cyberboard/cell.py +200 -0
- pywargame/cyberboard/collect.py +49 -0
- pywargame/cyberboard/collectgbx0pwd.py +30 -0
- pywargame/cyberboard/collectgbxext.py +30 -0
- pywargame/cyberboard/collectgsnexp.py +32 -0
- pywargame/cyberboard/collectgsnext.py +30 -0
- pywargame/cyberboard/draw.py +396 -0
- pywargame/cyberboard/exporter.py +1132 -0
- pywargame/cyberboard/extractor.py +240 -0
- pywargame/cyberboard/features.py +17 -0
- pywargame/cyberboard/gamebox.py +81 -0
- pywargame/cyberboard/gbxexp.py +76 -0
- pywargame/cyberboard/gbxext.py +64 -0
- pywargame/cyberboard/gsnexp.py +147 -0
- pywargame/cyberboard/gsnext.py +59 -0
- pywargame/cyberboard/head.py +111 -0
- pywargame/cyberboard/image.py +76 -0
- pywargame/cyberboard/main.py +47 -0
- pywargame/cyberboard/mark.py +102 -0
- pywargame/cyberboard/palette.py +36 -0
- pywargame/cyberboard/piece.py +169 -0
- pywargame/cyberboard/player.py +36 -0
- pywargame/cyberboard/scenario.py +115 -0
- pywargame/cyberboard/testgrid.py +156 -0
- pywargame/cyberboard/tile.py +121 -0
- pywargame/cyberboard/tray.py +68 -0
- pywargame/cyberboard/windows.py +41 -0
- pywargame/cyberboard/zeropwd.py +45 -0
- pywargame/cyberboard.py +2728 -0
- pywargame/gbx0pwd.py +2776 -0
- pywargame/gbxextract.py +2795 -0
- pywargame/gsnexport.py +16499 -0
- pywargame/gsnextract.py +2790 -0
- pywargame/latex/__init__.py +2 -0
- pywargame/latex/collect.py +34 -0
- pywargame/latex/latexexporter.py +4010 -0
- pywargame/latex/main.py +184 -0
- pywargame/vassal/__init__.py +66 -0
- pywargame/vassal/base.py +139 -0
- pywargame/vassal/board.py +243 -0
- pywargame/vassal/buildfile.py +60 -0
- pywargame/vassal/chart.py +79 -0
- pywargame/vassal/chessclock.py +197 -0
- pywargame/vassal/collect.py +98 -0
- pywargame/vassal/collectpatch.py +28 -0
- pywargame/vassal/command.py +21 -0
- pywargame/vassal/documentation.py +322 -0
- pywargame/vassal/dumpcollect.py +28 -0
- pywargame/vassal/dumpvsav.py +28 -0
- pywargame/vassal/element.py +439 -0
- pywargame/vassal/exporter.py +89 -0
- pywargame/vassal/extension.py +101 -0
- pywargame/vassal/folder.py +103 -0
- pywargame/vassal/game.py +940 -0
- pywargame/vassal/gameelements.py +1091 -0
- pywargame/vassal/globalkey.py +127 -0
- pywargame/vassal/globalproperty.py +433 -0
- pywargame/vassal/grid.py +573 -0
- pywargame/vassal/map.py +1061 -0
- pywargame/vassal/mapelements.py +1020 -0
- pywargame/vassal/merge.py +57 -0
- pywargame/vassal/merger.py +460 -0
- pywargame/vassal/moduledata.py +275 -0
- pywargame/vassal/mrgcollect.py +31 -0
- pywargame/vassal/patch.py +44 -0
- pywargame/vassal/patchcollect.py +28 -0
- pywargame/vassal/player.py +83 -0
- pywargame/vassal/save.py +495 -0
- pywargame/vassal/skel.py +380 -0
- pywargame/vassal/trait.py +224 -0
- pywargame/vassal/traits/__init__.py +36 -0
- pywargame/vassal/traits/area.py +50 -0
- pywargame/vassal/traits/basic.py +35 -0
- pywargame/vassal/traits/calculatedproperty.py +22 -0
- pywargame/vassal/traits/cargo.py +29 -0
- pywargame/vassal/traits/click.py +41 -0
- pywargame/vassal/traits/clone.py +28 -0
- pywargame/vassal/traits/delete.py +24 -0
- pywargame/vassal/traits/deselect.py +32 -0
- pywargame/vassal/traits/dynamicproperty.py +112 -0
- pywargame/vassal/traits/globalcommand.py +55 -0
- pywargame/vassal/traits/globalhotkey.py +26 -0
- pywargame/vassal/traits/globalproperty.py +54 -0
- pywargame/vassal/traits/hide.py +67 -0
- pywargame/vassal/traits/label.py +76 -0
- pywargame/vassal/traits/layer.py +105 -0
- pywargame/vassal/traits/mark.py +20 -0
- pywargame/vassal/traits/mask.py +85 -0
- pywargame/vassal/traits/mat.py +26 -0
- pywargame/vassal/traits/moved.py +35 -0
- pywargame/vassal/traits/movefixed.py +51 -0
- pywargame/vassal/traits/nonrect.py +95 -0
- pywargame/vassal/traits/nostack.py +55 -0
- pywargame/vassal/traits/place.py +104 -0
- pywargame/vassal/traits/prototype.py +20 -0
- pywargame/vassal/traits/report.py +34 -0
- pywargame/vassal/traits/restrictaccess.py +28 -0
- pywargame/vassal/traits/restrictcommand.py +32 -0
- pywargame/vassal/traits/return.py +40 -0
- pywargame/vassal/traits/rotate.py +62 -0
- pywargame/vassal/traits/sendto.py +59 -0
- pywargame/vassal/traits/sheet.py +129 -0
- pywargame/vassal/traits/skel.py +9 -0
- pywargame/vassal/traits/stack.py +28 -0
- pywargame/vassal/traits/submenu.py +27 -0
- pywargame/vassal/traits/trail.py +61 -0
- pywargame/vassal/traits/trigger.py +72 -0
- pywargame/vassal/turn.py +272 -0
- pywargame/vassal/upgrade.py +191 -0
- pywargame/vassal/vmod.py +323 -0
- pywargame/vassal/vsav.py +100 -0
- pywargame/vassal/widget.py +358 -0
- pywargame/vassal/withtraits.py +634 -0
- pywargame/vassal/xml.py +4 -0
- pywargame/vassal/zone.py +399 -0
- pywargame/vassal.py +12500 -0
- pywargame/vmodpatch.py +12548 -0
- pywargame/vsavdump.py +12533 -0
- pywargame/vslmerge.py +13015 -0
- pywargame/wgexport.py +16689 -0
- pywargame/ztexport.py +14351 -0
- pywargame/zuntzu/__init__.py +5 -0
- pywargame/zuntzu/base.py +82 -0
- pywargame/zuntzu/collect.py +38 -0
- pywargame/zuntzu/countersheet.py +250 -0
- pywargame/zuntzu/dicehand.py +48 -0
- pywargame/zuntzu/exporter.py +936 -0
- pywargame/zuntzu/gamebox.py +154 -0
- pywargame/zuntzu/map.py +36 -0
- pywargame/zuntzu/piece.py +37 -0
- pywargame/zuntzu/scenario.py +208 -0
- pywargame/zuntzu/ztexp.py +115 -0
- pywargame-0.3.1.dist-info/METADATA +353 -0
- pywargame-0.3.1.dist-info/RECORD +150 -0
- pywargame-0.3.1.dist-info/WHEEL +5 -0
- pywargame-0.3.1.dist-info/licenses/LICENSE +5 -0
- pywargame-0.3.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
from .. base import *
|
5
|
+
## END_IMPORT
|
6
|
+
|
7
|
+
# --------------------------------------------------------------------
|
8
|
+
class LayerTrait(Trait):
|
9
|
+
ID = 'emb2'
|
10
|
+
def __init__(self,
|
11
|
+
images = [''],
|
12
|
+
newNames = None,
|
13
|
+
activateName = 'Activate',
|
14
|
+
activateMask = CTRL,
|
15
|
+
activateChar = 'A',
|
16
|
+
increaseName = 'Increase',
|
17
|
+
increaseMask = CTRL,
|
18
|
+
increaseChar = '[',
|
19
|
+
decreaseName = '',
|
20
|
+
decreaseMask = CTRL,
|
21
|
+
decreaseChar = ']',
|
22
|
+
resetName = '',
|
23
|
+
resetKey = '',
|
24
|
+
resetLevel = 1,
|
25
|
+
under = False,
|
26
|
+
underXoff = 0,
|
27
|
+
underYoff = 0,
|
28
|
+
loop = True,
|
29
|
+
name = '',
|
30
|
+
description = '',
|
31
|
+
randomKey = '',
|
32
|
+
randomName = '',
|
33
|
+
follow = False,
|
34
|
+
expression = '',
|
35
|
+
first = 1,
|
36
|
+
version = 1, # 1:new, 0:old
|
37
|
+
always = True,
|
38
|
+
activateKey = key('A'),
|
39
|
+
increaseKey = key('['),
|
40
|
+
decreaseKey = key(']'),
|
41
|
+
scale = 1.):
|
42
|
+
'''Create a layer trait (VASSAL.counter.Embellishment)'''
|
43
|
+
super(LayerTrait,self).__init__()
|
44
|
+
if newNames is None and images is not None:
|
45
|
+
newNames = ['']*len(images)
|
46
|
+
self.setType(
|
47
|
+
activateName = activateName,
|
48
|
+
activateMask = activateMask,
|
49
|
+
activateChar = activateChar,
|
50
|
+
increaseName = increaseName,
|
51
|
+
increaseMask = increaseMask,
|
52
|
+
increaseChar = increaseChar,
|
53
|
+
decreaseName = decreaseName,
|
54
|
+
decreaseMask = decreaseMask,
|
55
|
+
decreaseChar = decreaseChar,
|
56
|
+
resetName = resetName,
|
57
|
+
resetKey = resetKey,
|
58
|
+
resetLevel = resetLevel,
|
59
|
+
under = under,
|
60
|
+
underXoff = underXoff,
|
61
|
+
underYoff = underYoff,
|
62
|
+
images = ','.join(images),
|
63
|
+
newNames = ','.join(newNames),
|
64
|
+
loop = loop,
|
65
|
+
name = name,
|
66
|
+
randomKey = randomKey,
|
67
|
+
randomName = randomName,
|
68
|
+
follow = follow,
|
69
|
+
expression = expression,
|
70
|
+
first = first,
|
71
|
+
version = version,
|
72
|
+
always = always,
|
73
|
+
activateKey = activateKey,
|
74
|
+
increaseKey = increaseKey,
|
75
|
+
decreaseKey = decreaseKey,
|
76
|
+
description = description,
|
77
|
+
scale = scale)
|
78
|
+
self.setState(level=1)
|
79
|
+
|
80
|
+
def getImages(self):
|
81
|
+
return self['images'].split(',')
|
82
|
+
|
83
|
+
def setImages(self,*images):
|
84
|
+
self['images'] = ','.join(images)
|
85
|
+
|
86
|
+
def getNames(self):
|
87
|
+
return self['newNames'].split(',')
|
88
|
+
|
89
|
+
def setNames(self,*names):
|
90
|
+
images = self.getImages()
|
91
|
+
newNames = ','.join(names+['']*(len(images)-len(names)))
|
92
|
+
self['newNames'] = newNames
|
93
|
+
|
94
|
+
def getLevel(self):
|
95
|
+
return self['level']
|
96
|
+
|
97
|
+
def setLevel(self,level):
|
98
|
+
self['level'] = level
|
99
|
+
|
100
|
+
|
101
|
+
Trait.known_traits.append(LayerTrait)
|
102
|
+
|
103
|
+
#
|
104
|
+
# EOF
|
105
|
+
#
|
@@ -0,0 +1,20 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
## END_IMPORT
|
5
|
+
|
6
|
+
# --------------------------------------------------------------------
|
7
|
+
class MarkTrait(Trait):
|
8
|
+
ID = 'mark'
|
9
|
+
def __init__(self,name='',value=''):
|
10
|
+
'''Create a mark trait (static property)'''
|
11
|
+
super(MarkTrait,self).__init__()
|
12
|
+
self.setType(name = name)
|
13
|
+
self.setState(value = value)
|
14
|
+
|
15
|
+
|
16
|
+
Trait.known_traits.append(MarkTrait)
|
17
|
+
|
18
|
+
#
|
19
|
+
# EOF
|
20
|
+
#
|
@@ -0,0 +1,85 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
## END_IMPORT
|
5
|
+
|
6
|
+
# --------------------------------------------------------------------
|
7
|
+
# Inset
|
8
|
+
# obs;88,130;ag_hide_1.png;Reveal;I;?;sides:Argentine;Peek;;true;;
|
9
|
+
# obs;88,130;ag_hide_1.png;Reveal;I;?;side:Argentine;;;true;;
|
10
|
+
#
|
11
|
+
# Peek
|
12
|
+
# obs;88,130;ag_hide_1.png;Reveal;P89,130;?;sides:Argentine;Peek;;true;;
|
13
|
+
#
|
14
|
+
# Image
|
15
|
+
#
|
16
|
+
class MaskTrait(Trait):
|
17
|
+
ID = 'obs'
|
18
|
+
INSET = 'I'
|
19
|
+
BACKGROUND = 'B'
|
20
|
+
PEEK = 'P'
|
21
|
+
IMAGE = 'G'
|
22
|
+
INSET2 = '2'
|
23
|
+
PLAYER = 'player:'
|
24
|
+
SIDE = 'side:'
|
25
|
+
SIDES = 'sides:'
|
26
|
+
def __init__(self,
|
27
|
+
keyCommand = '',
|
28
|
+
imageName = '',
|
29
|
+
hideCommand = '',
|
30
|
+
displayStyle = '',
|
31
|
+
peekKey = '',
|
32
|
+
ownerImage = '',
|
33
|
+
maskedName = '?',
|
34
|
+
access = '',#?
|
35
|
+
peekCommand = '',
|
36
|
+
description = '',
|
37
|
+
autoPeek = True,
|
38
|
+
dealKey = '',
|
39
|
+
dealExpr = ''):
|
40
|
+
'''Create a masking trait'''
|
41
|
+
super(MaskTrait,self).__init__()
|
42
|
+
disp = displayStyle
|
43
|
+
if displayStyle == self.PEEK:
|
44
|
+
disp += peekKey
|
45
|
+
elif displayStyle == self.IMAGE:
|
46
|
+
disp += ownerImage
|
47
|
+
|
48
|
+
acc = self.PLAYER
|
49
|
+
if isinstance(access,list):
|
50
|
+
acc = self.SIDES + ':'.join(access)
|
51
|
+
elif access.startswith('player'):
|
52
|
+
acc = self.PLAYER
|
53
|
+
elif access.startswith('side'):
|
54
|
+
acc = self.SIDE
|
55
|
+
|
56
|
+
self.setType(keyCommand = keyCommand,
|
57
|
+
imageImage = imageName,
|
58
|
+
hideCommand = hideCommand,
|
59
|
+
displayStyle = disp,
|
60
|
+
maskedName = maskedName,
|
61
|
+
access = acc, # ?
|
62
|
+
peekCommand = peekCommand,
|
63
|
+
description = description,
|
64
|
+
autoPeek = autoPeek,
|
65
|
+
dealKey = dealKey,
|
66
|
+
dealExpr = dealExpr)
|
67
|
+
self.setState(value='null')
|
68
|
+
|
69
|
+
@classmethod
|
70
|
+
def peekDisplay(cls,key):#Encoded key
|
71
|
+
return cls.PEEK + key
|
72
|
+
|
73
|
+
@classmethod
|
74
|
+
def peekImage(cls,ownerImage):
|
75
|
+
return cls.IMAGE + ownerImage
|
76
|
+
|
77
|
+
@classmethod
|
78
|
+
def sides(cls,*names):
|
79
|
+
return cls.SIDES+':'.join(names)
|
80
|
+
|
81
|
+
Trait.known_traits.append(MaskTrait)
|
82
|
+
|
83
|
+
#
|
84
|
+
# EOF
|
85
|
+
#
|
@@ -0,0 +1,26 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
## END_IMPORT
|
5
|
+
|
6
|
+
|
7
|
+
class MatTrait(Trait):
|
8
|
+
ID = 'mat'
|
9
|
+
|
10
|
+
def __init__(self,
|
11
|
+
name = 'Mat',
|
12
|
+
description = ''):
|
13
|
+
self.setType(name = name,
|
14
|
+
description = description)
|
15
|
+
self.setState(content='0')
|
16
|
+
|
17
|
+
def setContent(self,*args):
|
18
|
+
# Not sure this is correct
|
19
|
+
self.setState(content=str(len(args))+';'+';'.joint(args))
|
20
|
+
|
21
|
+
|
22
|
+
Trait.known_traits.append(MatTrait)
|
23
|
+
|
24
|
+
#
|
25
|
+
# EOF
|
26
|
+
#
|
@@ -0,0 +1,35 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
from .. base import *
|
5
|
+
## END_IMPORT
|
6
|
+
|
7
|
+
# --------------------------------------------------------------------
|
8
|
+
class MovedTrait(Trait):
|
9
|
+
ID = 'markmoved'
|
10
|
+
def __init__(self,
|
11
|
+
image = 'moved.gif',
|
12
|
+
xoff = 36,
|
13
|
+
yoff = -38,
|
14
|
+
name = 'Mark moved',
|
15
|
+
key = key('M'),
|
16
|
+
dummy = '' # Description
|
17
|
+
# ignoreSame = True
|
18
|
+
):
|
19
|
+
'''Create a moved trait (VASSAL.counters.MovementMarkable)'''
|
20
|
+
super(MovedTrait,self).__init__()
|
21
|
+
self.setType(image = image,
|
22
|
+
xoff = xoff,
|
23
|
+
yoff = yoff,
|
24
|
+
name = name,
|
25
|
+
key = key,
|
26
|
+
dummy = dummy, # Description
|
27
|
+
# ignoreSame = ignoreSame
|
28
|
+
)
|
29
|
+
self.setState(moved = False)
|
30
|
+
|
31
|
+
Trait.known_traits.append(MovedTrait)
|
32
|
+
|
33
|
+
#
|
34
|
+
# EOF
|
35
|
+
#
|
@@ -0,0 +1,51 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
## END_IMPORT
|
5
|
+
|
6
|
+
|
7
|
+
class MoveFixedTrait(Trait):
|
8
|
+
ID = 'translate'
|
9
|
+
|
10
|
+
def __init__(self,
|
11
|
+
command = '', # menu command,
|
12
|
+
key = '', # Hotkey or command
|
13
|
+
dx = 0, # X distance (int or expr))
|
14
|
+
dy = 0, # Y distance (int or expr))
|
15
|
+
stack = False,# Move entire stack
|
16
|
+
xStepFactor = 0, # Factor on X offset (int or expr)
|
17
|
+
yStepFactor = 0, # Factor on Y offset (int or expr)
|
18
|
+
xStep = 0, # X offset (int or expr)
|
19
|
+
yStep = 0, # Y offset (int or expr)
|
20
|
+
description = '', # str
|
21
|
+
):
|
22
|
+
'''Move a fixed distance.
|
23
|
+
|
24
|
+
x' = dx + xStepFactor * xStep
|
25
|
+
y' = dy + yStepFactor * yStep
|
26
|
+
|
27
|
+
If piece can rotate, and this is trait is given _after_ (more
|
28
|
+
recent in the traits list), then the piece will move according
|
29
|
+
to the direction faced. If given _before_ (later in the traits list),
|
30
|
+
then the move is relative to the current map.
|
31
|
+
|
32
|
+
(VASSAL.counters.Translate)
|
33
|
+
|
34
|
+
'''
|
35
|
+
self.setType(command = command,
|
36
|
+
key = key,
|
37
|
+
dx = dx,
|
38
|
+
dy = dy,
|
39
|
+
stack = stack,
|
40
|
+
xStepFactor = xStepFactor,
|
41
|
+
yStepFactor = yStepFactor,
|
42
|
+
xStep = xStep,
|
43
|
+
yStep = yStep,
|
44
|
+
description = description)
|
45
|
+
self.setState()
|
46
|
+
|
47
|
+
|
48
|
+
Trait.known_traits.append(MoveFixedTrait)
|
49
|
+
#
|
50
|
+
# EOF
|
51
|
+
#
|
@@ -0,0 +1,95 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
## END_IMPORT
|
5
|
+
|
6
|
+
# --------------------------------------------------------------------
|
7
|
+
class NonRectangleTrait(Trait):
|
8
|
+
ID = 'nonRect2'
|
9
|
+
CLOSE = 'c'
|
10
|
+
MOVETO = 'm'
|
11
|
+
LINETO = 'l'
|
12
|
+
CUBICTO = 'l'
|
13
|
+
QUADTO = 'l'
|
14
|
+
def __init__(self,
|
15
|
+
scale = 1.,
|
16
|
+
filename = '',
|
17
|
+
path = [],
|
18
|
+
image = None):
|
19
|
+
'''Create a NonRectangle trait (static property)'''
|
20
|
+
super(NonRectangleTrait,self).__init__()
|
21
|
+
l = []
|
22
|
+
if len(filename) > 0:
|
23
|
+
l.append(f'n{filename}')
|
24
|
+
|
25
|
+
if len(path) <= 0:
|
26
|
+
path = self.getShape(image)
|
27
|
+
|
28
|
+
if len(path) > 0:
|
29
|
+
# print(path)
|
30
|
+
l += [f'{p[0]},{int(p[1])},{int(p[2])}' if len(p) > 2 else p
|
31
|
+
for p in path]
|
32
|
+
|
33
|
+
self.setType(scale = scale,
|
34
|
+
code = ','.join(l))
|
35
|
+
self.setState()
|
36
|
+
|
37
|
+
@classmethod
|
38
|
+
def getShape(cls,buffer):
|
39
|
+
if buffer is None:
|
40
|
+
return []
|
41
|
+
|
42
|
+
from io import BytesIO
|
43
|
+
|
44
|
+
image = buffer
|
45
|
+
if image[:5] == b'<?xml':
|
46
|
+
from cairosvg import svg2png
|
47
|
+
image = svg2png(image)
|
48
|
+
|
49
|
+
from PIL import Image
|
50
|
+
|
51
|
+
code = []
|
52
|
+
with Image.open(BytesIO(image)) as img:
|
53
|
+
alp = img.getchannel('A') # Alpha channel
|
54
|
+
# Find least and largest non-transparent pixel in each row
|
55
|
+
rows = []
|
56
|
+
w = alp.width
|
57
|
+
h = alp.height
|
58
|
+
bb = alp.getbbox()
|
59
|
+
for r in range(bb[1],bb[3]):
|
60
|
+
ll, rr = bb[2], bb[0]
|
61
|
+
for c in range(bb[0],bb[2]):
|
62
|
+
if alp.getpixel((c,r)) != 0:
|
63
|
+
ll = min(c,ll)
|
64
|
+
rr = max(c,rr)
|
65
|
+
rows += [[r-h//2,ll-w//2,rr-w//2]]
|
66
|
+
|
67
|
+
# Now produce the code - we start with the top line
|
68
|
+
code = [(cls.MOVETO,rows[0][1],rows[0][0]-1),
|
69
|
+
(cls.LINETO,rows[0][2],rows[0][0]-1)]
|
70
|
+
|
71
|
+
# Now loop down right side of image
|
72
|
+
for c in rows:
|
73
|
+
last = code[-1]
|
74
|
+
if last[1] != c[2]:
|
75
|
+
code += [(cls.LINETO, c[2], last[2])]
|
76
|
+
code += [(cls.LINETO, c[2], c[0])]
|
77
|
+
|
78
|
+
# Now loop up left side of image
|
79
|
+
for c in rows[::-1]:
|
80
|
+
last = code[-1]
|
81
|
+
if last[1] != c[1]:
|
82
|
+
code += [(cls.LINETO,c[1],last[2])]
|
83
|
+
code += [(cls.LINETO,c[1],c[0])]
|
84
|
+
|
85
|
+
# Terminate with close
|
86
|
+
code += [(cls.CLOSE)]
|
87
|
+
|
88
|
+
return code
|
89
|
+
|
90
|
+
|
91
|
+
Trait.known_traits.append(NonRectangleTrait)
|
92
|
+
|
93
|
+
#
|
94
|
+
# EOF
|
95
|
+
#
|
@@ -0,0 +1,55 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
## END_IMPORT
|
5
|
+
|
6
|
+
# --------------------------------------------------------------------
|
7
|
+
class NoStackTrait(Trait):
|
8
|
+
ID = 'immob'
|
9
|
+
NORMAL_SELECT = ''
|
10
|
+
SHIFT_SELECT = 'i'
|
11
|
+
CTRL_SELECT = 't'
|
12
|
+
ALT_SELECT = 'c'
|
13
|
+
NEVER_SELECT = 'n'
|
14
|
+
NORMAL_BAND_SELECT = ''
|
15
|
+
ALT_BAND_SELECT = 'A'
|
16
|
+
ALT_SHIFT_BAND_SELECT = 'B'
|
17
|
+
NEVER_BAND_SELECT = 'Z'
|
18
|
+
NORMAL_MOVE = 'N'
|
19
|
+
SELECT_MOVE = 'I'
|
20
|
+
NEVER_MOVE = 'V'
|
21
|
+
NORMAL_STACK = 'L'
|
22
|
+
NEVER_STACK = 'R'
|
23
|
+
IGNORE_GRID = 'g'
|
24
|
+
def __init__(self,
|
25
|
+
select = NORMAL_SELECT,
|
26
|
+
bandSelect = NORMAL_BAND_SELECT,
|
27
|
+
move = NORMAL_MOVE,
|
28
|
+
canStack = False,
|
29
|
+
ignoreGrid = False,
|
30
|
+
description = ''):
|
31
|
+
'''No stacking trait
|
32
|
+
|
33
|
+
(VASSAL.counter.Immobilized)
|
34
|
+
'''
|
35
|
+
selectionOptions = (select +
|
36
|
+
(self.IGNORE_GRID if ignoreGrid else '') +
|
37
|
+
bandSelect)
|
38
|
+
movementOptions = move
|
39
|
+
stackingOptions = self.NORMAL_STACK if canStack else self.NEVER_STACK
|
40
|
+
|
41
|
+
'''Create a mark trait (static property)'''
|
42
|
+
super(NoStackTrait,self).__init__()
|
43
|
+
|
44
|
+
self.setType(selectionOptions = selectionOptions,
|
45
|
+
movementOptions = movementOptions,
|
46
|
+
stackingOptions = stackingOptions,
|
47
|
+
description = description)
|
48
|
+
self.setState()
|
49
|
+
|
50
|
+
|
51
|
+
Trait.known_traits.append(NoStackTrait)
|
52
|
+
|
53
|
+
#
|
54
|
+
# EOF
|
55
|
+
#
|
@@ -0,0 +1,104 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
from .. base import *
|
5
|
+
# from .. widget import *
|
6
|
+
# from .. withtraits import PieceSlot
|
7
|
+
## END_IMPORT
|
8
|
+
|
9
|
+
# --------------------------------------------------------------------
|
10
|
+
class PlaceTrait(Trait):
|
11
|
+
ID = 'placemark'
|
12
|
+
STACK_TOP = 0
|
13
|
+
STACK_BOTTOM = 1
|
14
|
+
ABOVE = 2
|
15
|
+
BELOW = 3
|
16
|
+
|
17
|
+
# How the LaTeX exporter organises the units. Format with
|
18
|
+
# 0: the group
|
19
|
+
# 1: the piece name
|
20
|
+
# SKEL_PATH = (PieceWindow.TAG +r':Counters\/' +
|
21
|
+
# TabWidget.TAG +r':Counters\/' +
|
22
|
+
# PanelWidget.TAG +':{0}' +r'\/'+
|
23
|
+
# ListWidget.TAG +':{0} counters'+r'\/'+
|
24
|
+
# PieceSlot.TAG +':{1}')
|
25
|
+
@classmethod
|
26
|
+
# @property
|
27
|
+
def SKEL_PATH(cls):
|
28
|
+
## BEGIN_IMPORT
|
29
|
+
from .. widget import PieceWindow, TabWidget, PanelWidget, ListWidget
|
30
|
+
from .. withtraits import PieceSlot
|
31
|
+
## END_IMPORT
|
32
|
+
|
33
|
+
return (PieceWindow.TAG +r':Counters\/' +
|
34
|
+
TabWidget.TAG +r':Counters\/' +
|
35
|
+
PanelWidget.TAG +':{0}' +r'\/'+
|
36
|
+
ListWidget.TAG +':{0} counters'+r'\/'+
|
37
|
+
PieceSlot.TAG +':{1}')
|
38
|
+
|
39
|
+
def __init__(self,
|
40
|
+
command = '', # Context menu name
|
41
|
+
key = '', # Context menu key
|
42
|
+
markerSpec = '', # Full path in module
|
43
|
+
markerText = 'null', # Hard coded message
|
44
|
+
xOffset = 0,
|
45
|
+
yOffset = 0,
|
46
|
+
matchRotation = True,
|
47
|
+
afterKey = '',
|
48
|
+
description = '',
|
49
|
+
gpid = '', # Set in JAVA, but with warning
|
50
|
+
placement = ABOVE,
|
51
|
+
above = False):
|
52
|
+
'''Create a place marker trait (VASSAL.counter.PlaceMarker)'''
|
53
|
+
super(PlaceTrait,self).__init__()
|
54
|
+
self.setType(command = command, # Context menu name
|
55
|
+
key = key, # Context menu key
|
56
|
+
markerSpec = markerSpec,
|
57
|
+
markerText = markerText,
|
58
|
+
xOffset = xOffset,
|
59
|
+
yOffset = yOffset,
|
60
|
+
matchRotation = matchRotation,
|
61
|
+
afterKey = afterKey,
|
62
|
+
description = description,
|
63
|
+
gpid = gpid,
|
64
|
+
placement = placement,
|
65
|
+
above = above)
|
66
|
+
self.setState()
|
67
|
+
|
68
|
+
Trait.known_traits.append(PlaceTrait)
|
69
|
+
|
70
|
+
# --------------------------------------------------------------------
|
71
|
+
class ReplaceTrait(PlaceTrait):
|
72
|
+
ID = 'replace'
|
73
|
+
def __init__(self,
|
74
|
+
command = '', # Context menu name
|
75
|
+
key = '', # Context menu key
|
76
|
+
markerSpec = '', # Full path in module
|
77
|
+
markerText = 'null', # Hard message
|
78
|
+
xOffset = 0,
|
79
|
+
yOffset = 0,
|
80
|
+
matchRotation = True,
|
81
|
+
afterKey = '',
|
82
|
+
description = '',
|
83
|
+
gpid = '', # Set in JAVA
|
84
|
+
placement = PlaceTrait.ABOVE,
|
85
|
+
above = False):
|
86
|
+
super(ReplaceTrait,self).__init__(command = command,
|
87
|
+
key = key,
|
88
|
+
markerSpec = markerSpec,
|
89
|
+
markerText = markerText,
|
90
|
+
xOffset = xOffset,
|
91
|
+
yOffset = yOffset,
|
92
|
+
matchRotation = matchRotation,
|
93
|
+
afterKey = afterKey,
|
94
|
+
description = description,
|
95
|
+
gpid = gpid,
|
96
|
+
placement = placement,
|
97
|
+
above = above)
|
98
|
+
|
99
|
+
|
100
|
+
Trait.known_traits.append(ReplaceTrait)
|
101
|
+
|
102
|
+
#
|
103
|
+
# EOF
|
104
|
+
#
|
@@ -0,0 +1,20 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
## END_IMPORT
|
5
|
+
|
6
|
+
# --------------------------------------------------------------------
|
7
|
+
class PrototypeTrait(Trait):
|
8
|
+
ID = 'prototype'
|
9
|
+
def __init__(self,name=''):
|
10
|
+
'''Create a prototype trait (VASSAL.counter.UsePrototype)'''
|
11
|
+
super(PrototypeTrait,self).__init__()
|
12
|
+
self.setType(name = name)
|
13
|
+
self.setState(ignored = '')
|
14
|
+
|
15
|
+
|
16
|
+
Trait.known_traits.append(PrototypeTrait)
|
17
|
+
|
18
|
+
#
|
19
|
+
# EOF
|
20
|
+
#
|
@@ -0,0 +1,34 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
## END_IMPORT
|
5
|
+
|
6
|
+
# --------------------------------------------------------------------
|
7
|
+
class ReportTrait (Trait):
|
8
|
+
ID = 'report'
|
9
|
+
def __init__(self,
|
10
|
+
*keys,
|
11
|
+
nosuppress = True,
|
12
|
+
description = '',
|
13
|
+
report = '$location$: $newPieceName$ $menuCommand$ *',
|
14
|
+
cyclekeys = '',
|
15
|
+
cyclereps = ''):
|
16
|
+
'''Create a report trait (VASSAL.counters.ReportActon)'''
|
17
|
+
super(ReportTrait,self).__init__()
|
18
|
+
esckeys = ','.join([k.replace(',',r'\,') for k in keys])
|
19
|
+
esccycl = ','.join([k.replace(',',r'\,') for k in cyclekeys])
|
20
|
+
escreps = ','.join([k.replace(',',r'\,') for k in cyclereps])
|
21
|
+
|
22
|
+
self.setType(keys = esckeys,
|
23
|
+
report = report,
|
24
|
+
cycleKeys = esccycl,
|
25
|
+
cycleReports = escreps,
|
26
|
+
description = description,
|
27
|
+
nosuppress = nosuppress)
|
28
|
+
self.setState(cycle = -1)
|
29
|
+
|
30
|
+
Trait.known_traits.append(ReportTrait)
|
31
|
+
|
32
|
+
#
|
33
|
+
# EOF
|
34
|
+
#
|
@@ -0,0 +1,28 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from .. trait import Trait
|
4
|
+
## END_IMPORT
|
5
|
+
|
6
|
+
# --------------------------------------------------------------------
|
7
|
+
class RestrictAccessTrait(Trait):
|
8
|
+
ID = 'restrict'
|
9
|
+
def __init__(self,
|
10
|
+
sides = [],
|
11
|
+
byPlayer = False,
|
12
|
+
noMovement = True,
|
13
|
+
description = '',
|
14
|
+
owner = '',):
|
15
|
+
'''Create a layer trait (VASSAL.counter.Restricted)'''
|
16
|
+
super(RestrictAccessTrait,self).__init__()
|
17
|
+
encSides = ','.join(sides)
|
18
|
+
self.setType(sides = encSides,
|
19
|
+
byPlayer = byPlayer,
|
20
|
+
noMovement = noMovement,
|
21
|
+
description = description)
|
22
|
+
self.setState(owner=owner)
|
23
|
+
|
24
|
+
Trait.known_traits.append(RestrictAccessTrait)
|
25
|
+
|
26
|
+
#
|
27
|
+
# EOF
|
28
|
+
#
|