Browse Source

remove poc source code

Bastien Sevajol 3 years ago
parent
commit
8fcf4371f9
100 changed files with 1 additions and 4539 deletions
  1. 1 78
      .gitignore
  2. 0 674
      LICENSE
  3. 0 67
      README.md
  4. 0 46
      config.yaml
  5. 0 284
      maps/001/001.tmx
  6. BIN
      maps/001/background.png
  7. BIN
      maps/001/background_interiors.png
  8. BIN
      maps/001/map001.xcf
  9. 0 128
      maps/001/state1.xml
  10. 0 188
      maps/003/003.tmx
  11. BIN
      maps/003/background.png
  12. BIN
      maps/003/background_interiors.png
  13. BIN
      maps/003/background_interiors.xcf
  14. BIN
      maps/003/interiors.png
  15. 0 22
      maps/003/interiors.tsx
  16. BIN
      maps/003/terrain.png
  17. 0 31
      maps/003/terrain.tsx
  18. BIN
      maps/003/trees_64x64.png
  19. 0 4
      maps/003/trees_64x64.tsx
  20. BIN
      maps/shared/tilesets/interiors.png
  21. 0 22
      maps/shared/tilesets/interiors.tsx
  22. BIN
      maps/shared/tilesets/terrain.png
  23. 0 31
      maps/shared/tilesets/terrain.tsx
  24. BIN
      maps/shared/tilesets/trees.png
  25. 0 5
      maps/shared/tilesets/trees.tsx
  26. BIN
      maps/shared/tilesets/trees.xcf
  27. BIN
      medias/images/actors/man.png
  28. BIN
      medias/images/actors/man_c1.png
  29. BIN
      medias/images/actors/man_c1_weap0.png
  30. BIN
      medias/images/actors/man_c1_weap1.png
  31. BIN
      medias/images/actors/man_c1_weap1_firing1.png
  32. BIN
      medias/images/actors/man_c1_weap1_firing2.png
  33. BIN
      medias/images/actors/man_c1_weap1_firing3.png
  34. BIN
      medias/images/actors/man_c2.png
  35. BIN
      medias/images/actors/man_c2_weap1.png
  36. BIN
      medias/images/actors/man_c3.png
  37. BIN
      medias/images/actors/man_c3_weap1.png
  38. BIN
      medias/images/actors/man_c4.png
  39. BIN
      medias/images/actors/man_c4_weap1.png
  40. BIN
      medias/images/actors/man_d1.png
  41. BIN
      medias/images/actors/man_w1.png
  42. BIN
      medias/images/actors/man_w10.png
  43. BIN
      medias/images/actors/man_w2.png
  44. BIN
      medias/images/actors/man_w3.png
  45. BIN
      medias/images/actors/man_w4.png
  46. BIN
      medias/images/actors/man_w5.png
  47. BIN
      medias/images/actors/man_w6.png
  48. BIN
      medias/images/actors/man_w7.png
  49. BIN
      medias/images/actors/man_w8.png
  50. BIN
      medias/images/actors/man_w9.png
  51. BIN
      medias/images/actors/man_weap1.png
  52. BIN
      medias/images/actors/man_weap1_firing1.png
  53. BIN
      medias/images/actors/man_weap1_firing2.png
  54. BIN
      medias/images/actors/man_weap1_firing3.png
  55. BIN
      medias/images/actors/src/man_c1_riffle1.xcf
  56. BIN
      medias/images/actors/src/man_c1_weap1.xcf
  57. BIN
      medias/images/actors/src/man_c1_weap1_firing.xcf
  58. BIN
      medias/images/actors/src/man_weap1_firing.xcf
  59. BIN
      medias/images/actors/src/tank1.xcf
  60. BIN
      medias/images/actors/tank1.png
  61. BIN
      medias/images/empty.png
  62. BIN
      medias/images/unknown.png
  63. BIN
      medias/sounds/204010__duckduckpony__homemade-gunshot-2.ogg
  64. 0 1
      opencombat/__init__.py
  65. 0 1
      opencombat/ai/__init__.py
  66. 0 39
      opencombat/ai/placement.py
  67. 0 24
      opencombat/const.py
  68. 0 29
      opencombat/exception.py
  69. 0 1
      opencombat/game/__init__.py
  70. 0 303
      opencombat/game/actor.py
  71. 0 4
      opencombat/game/animation.py
  72. 0 482
      opencombat/game/base.py
  73. 0 9
      opencombat/game/const.py
  74. 0 115
      opencombat/game/fire.py
  75. 0 109
      opencombat/game/image.py
  76. 0 56
      opencombat/game/move.py
  77. 0 26
      opencombat/game/placement.py
  78. 0 18
      opencombat/game/state.py
  79. 0 97
      opencombat/game/weapon.py
  80. 0 17
      opencombat/gui.py
  81. 0 1
      opencombat/simulation/__init__.py
  82. 0 70
      opencombat/simulation/base.py
  83. 0 133
      opencombat/simulation/behaviour.py
  84. 0 58
      opencombat/simulation/event.py
  85. 0 39
      opencombat/simulation/fire.py
  86. 0 148
      opencombat/simulation/interior.py
  87. 0 24
      opencombat/simulation/mechanism.py
  88. 0 475
      opencombat/simulation/move.py
  89. 0 79
      opencombat/simulation/physics.py
  90. 0 21
      opencombat/simulation/placement.py
  91. 0 41
      opencombat/simulation/state.py
  92. 0 125
      opencombat/simulation/subject.py
  93. 0 20
      opencombat/simulation/tmx.py
  94. 0 267
      opencombat/state.py
  95. 0 73
      opencombat/state.xsd
  96. 0 7
      opencombat/state_template.xml
  97. 0 1
      opencombat/strategy/__init__.py
  98. 0 45
      opencombat/strategy/manager.py
  99. 0 1
      opencombat/strategy/selection/__init__.py
  100. 0 0
      opencombat/strategy/selection/gui.py

+ 1 - 78
.gitignore View File

@@ -1,80 +1,3 @@
1
-# Byte-compiled / optimized / DLL files
2
-__pycache__/
3
-*.py[cod]
4
-*$py.class
5
-
6
-# C extensions
7
-*.so
8
-
9
-# Distribution / packaging
10
-.Python
11
-venv/
12
-build/
13
-develop-eggs/
14
-dist/
15
-downloads/
16
-eggs/
17
-.eggs/
18
-lib/
19
-lib64/
20
-parts/
21
-sdist/
22
-var/
23
-wheels/
24
-*.egg-info/
25
-.installed.cfg
26
-*.egg
27
-
28
-# PyInstaller
29
-#  Usually these files are written by a python script from a template
30
-#  before PyInstaller builds the exe, so as to inject date/other infos into it.
31
-*.manifest
32
-*.spec
33
-
34
-# Installer logs
35
-pip-log.txt
36
-pip-delete-this-directory.txt
37
-
38
-# Unit test / coverage reports
39
-htmlcov/
40
-.tox/
41
-.coverage
42
-.coverage.*
43
-.cache
44
-nosetests.xml
45
-coverage.xml
46
-*.cover
47
-.hypothesis/
48
-
49
-# Translations
50
-*.mo
51
-*.pot
52
-
53
-# Sphinx documentation
54
-docs/_build/
55
-
56
-# Pycharm
1
+/target
57 2
 .idea
58
-
59
-# PyBuilder
60
-target/
61
-
62
-# pyenv
63
-.python-version
64
-
65
-# dotenv
66
-.env
67
-
68
-# virtualenv
69
-.venv
70
-/venv*/
71
-ENV/
72
-
73
-# mypy
74
-.mypy_cache/
75
-
76
-# other
77 3
 *~
78
-
79
-# OpenCombat
80
-/cache

+ 0 - 674
LICENSE View File

@@ -1,674 +0,0 @@
1
-                    GNU GENERAL PUBLIC LICENSE
2
-                       Version 3, 29 June 2007
3
-
4
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
- Everyone is permitted to copy and distribute verbatim copies
6
- of this license document, but changing it is not allowed.
7
-
8
-                            Preamble
9
-
10
-  The GNU General Public License is a free, copyleft license for
11
-software and other kinds of works.
12
-
13
-  The licenses for most software and other practical works are designed
14
-to take away your freedom to share and change the works.  By contrast,
15
-the GNU General Public License is intended to guarantee your freedom to
16
-share and change all versions of a program--to make sure it remains free
17
-software for all its users.  We, the Free Software Foundation, use the
18
-GNU General Public License for most of our software; it applies also to
19
-any other work released this way by its authors.  You can apply it to
20
-your programs, too.
21
-
22
-  When we speak of free software, we are referring to freedom, not
23
-price.  Our General Public Licenses are designed to make sure that you
24
-have the freedom to distribute copies of free software (and charge for
25
-them if you wish), that you receive source code or can get it if you
26
-want it, that you can change the software or use pieces of it in new
27
-free programs, and that you know you can do these things.
28
-
29
-  To protect your rights, we need to prevent others from denying you
30
-these rights or asking you to surrender the rights.  Therefore, you have
31
-certain responsibilities if you distribute copies of the software, or if
32
-you modify it: responsibilities to respect the freedom of others.
33
-
34
-  For example, if you distribute copies of such a program, whether
35
-gratis or for a fee, you must pass on to the recipients the same
36
-freedoms that you received.  You must make sure that they, too, receive
37
-or can get the source code.  And you must show them these terms so they
38
-know their rights.
39
-
40
-  Developers that use the GNU GPL protect your rights with two steps:
41
-(1) assert copyright on the software, and (2) offer you this License
42
-giving you legal permission to copy, distribute and/or modify it.
43
-
44
-  For the developers' and authors' protection, the GPL clearly explains
45
-that there is no warranty for this free software.  For both users' and
46
-authors' sake, the GPL requires that modified versions be marked as
47
-changed, so that their problems will not be attributed erroneously to
48
-authors of previous versions.
49
-
50
-  Some devices are designed to deny users access to install or run
51
-modified versions of the software inside them, although the manufacturer
52
-can do so.  This is fundamentally incompatible with the aim of
53
-protecting users' freedom to change the software.  The systematic
54
-pattern of such abuse occurs in the area of products for individuals to
55
-use, which is precisely where it is most unacceptable.  Therefore, we
56
-have designed this version of the GPL to prohibit the practice for those
57
-products.  If such problems arise substantially in other domains, we
58
-stand ready to extend this provision to those domains in future versions
59
-of the GPL, as needed to protect the freedom of users.
60
-
61
-  Finally, every program is threatened constantly by software patents.
62
-States should not allow patents to restrict development and use of
63
-software on general-purpose computers, but in those that do, we wish to
64
-avoid the special danger that patents applied to a free program could
65
-make it effectively proprietary.  To prevent this, the GPL assures that
66
-patents cannot be used to render the program non-free.
67
-
68
-  The precise terms and conditions for copying, distribution and
69
-modification follow.
70
-
71
-                       TERMS AND CONDITIONS
72
-
73
-  0. Definitions.
74
-
75
-  "This License" refers to version 3 of the GNU General Public License.
76
-
77
-  "Copyright" also means copyright-like laws that apply to other kinds of
78
-works, such as semiconductor masks.
79
-
80
-  "The Program" refers to any copyrightable work licensed under this
81
-License.  Each licensee is addressed as "you".  "Licensees" and
82
-"recipients" may be individuals or organizations.
83
-
84
-  To "modify" a work means to copy from or adapt all or part of the work
85
-in a fashion requiring copyright permission, other than the making of an
86
-exact copy.  The resulting work is called a "modified version" of the
87
-earlier work or a work "based on" the earlier work.
88
-
89
-  A "covered work" means either the unmodified Program or a work based
90
-on the Program.
91
-
92
-  To "propagate" a work means to do anything with it that, without
93
-permission, would make you directly or secondarily liable for
94
-infringement under applicable copyright law, except executing it on a
95
-computer or modifying a private copy.  Propagation includes copying,
96
-distribution (with or without modification), making available to the
97
-public, and in some countries other activities as well.
98
-
99
-  To "convey" a work means any kind of propagation that enables other
100
-parties to make or receive copies.  Mere interaction with a user through
101
-a computer network, with no transfer of a copy, is not conveying.
102
-
103
-  An interactive user interface displays "Appropriate Legal Notices"
104
-to the extent that it includes a convenient and prominently visible
105
-feature that (1) displays an appropriate copyright notice, and (2)
106
-tells the user that there is no warranty for the work (except to the
107
-extent that warranties are provided), that licensees may convey the
108
-work under this License, and how to view a copy of this License.  If
109
-the interface presents a list of user commands or options, such as a
110
-menu, a prominent item in the list meets this criterion.
111
-
112
-  1. Source Code.
113
-
114
-  The "source code" for a work means the preferred form of the work
115
-for making modifications to it.  "Object code" means any non-source
116
-form of a work.
117
-
118
-  A "Standard Interface" means an interface that either is an official
119
-standard defined by a recognized standards body, or, in the case of
120
-interfaces specified for a particular programming language, one that
121
-is widely used among developers working in that language.
122
-
123
-  The "System Libraries" of an executable work include anything, other
124
-than the work as a whole, that (a) is included in the normal form of
125
-packaging a Major Component, but which is not part of that Major
126
-Component, and (b) serves only to enable use of the work with that
127
-Major Component, or to implement a Standard Interface for which an
128
-implementation is available to the public in source code form.  A
129
-"Major Component", in this context, means a major essential component
130
-(kernel, window system, and so on) of the specific operating system
131
-(if any) on which the executable work runs, or a compiler used to
132
-produce the work, or an object code interpreter used to run it.
133
-
134
-  The "Corresponding Source" for a work in object code form means all
135
-the source code needed to generate, install, and (for an executable
136
-work) run the object code and to modify the work, including scripts to
137
-control those activities.  However, it does not include the work's
138
-System Libraries, or general-purpose tools or generally available free
139
-programs which are used unmodified in performing those activities but
140
-which are not part of the work.  For example, Corresponding Source
141
-includes interface definition files associated with source files for
142
-the work, and the source code for shared libraries and dynamically
143
-linked subprograms that the work is specifically designed to require,
144
-such as by intimate data communication or control flow between those
145
-subprograms and other parts of the work.
146
-
147
-  The Corresponding Source need not include anything that users
148
-can regenerate automatically from other parts of the Corresponding
149
-Source.
150
-
151
-  The Corresponding Source for a work in source code form is that
152
-same work.
153
-
154
-  2. Basic Permissions.
155
-
156
-  All rights granted under this License are granted for the term of
157
-copyright on the Program, and are irrevocable provided the stated
158
-conditions are met.  This License explicitly affirms your unlimited
159
-permission to run the unmodified Program.  The output from running a
160
-covered work is covered by this License only if the output, given its
161
-content, constitutes a covered work.  This License acknowledges your
162
-rights of fair use or other equivalent, as provided by copyright law.
163
-
164
-  You may make, run and propagate covered works that you do not
165
-convey, without conditions so long as your license otherwise remains
166
-in force.  You may convey covered works to others for the sole purpose
167
-of having them make modifications exclusively for you, or provide you
168
-with facilities for running those works, provided that you comply with
169
-the terms of this License in conveying all material for which you do
170
-not control copyright.  Those thus making or running the covered works
171
-for you must do so exclusively on your behalf, under your direction
172
-and control, on terms that prohibit them from making any copies of
173
-your copyrighted material outside their relationship with you.
174
-
175
-  Conveying under any other circumstances is permitted solely under
176
-the conditions stated below.  Sublicensing is not allowed; section 10
177
-makes it unnecessary.
178
-
179
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180
-
181
-  No covered work shall be deemed part of an effective technological
182
-measure under any applicable law fulfilling obligations under article
183
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
184
-similar laws prohibiting or restricting circumvention of such
185
-measures.
186
-
187
-  When you convey a covered work, you waive any legal power to forbid
188
-circumvention of technological measures to the extent such circumvention
189
-is effected by exercising rights under this License with respect to
190
-the covered work, and you disclaim any intention to limit operation or
191
-modification of the work as a means of enforcing, against the work's
192
-users, your or third parties' legal rights to forbid circumvention of
193
-technological measures.
194
-
195
-  4. Conveying Verbatim Copies.
196
-
197
-  You may convey verbatim copies of the Program's source code as you
198
-receive it, in any medium, provided that you conspicuously and
199
-appropriately publish on each copy an appropriate copyright notice;
200
-keep intact all notices stating that this License and any
201
-non-permissive terms added in accord with section 7 apply to the code;
202
-keep intact all notices of the absence of any warranty; and give all
203
-recipients a copy of this License along with the Program.
204
-
205
-  You may charge any price or no price for each copy that you convey,
206
-and you may offer support or warranty protection for a fee.
207
-
208
-  5. Conveying Modified Source Versions.
209
-
210
-  You may convey a work based on the Program, or the modifications to
211
-produce it from the Program, in the form of source code under the
212
-terms of section 4, provided that you also meet all of these conditions:
213
-
214
-    a) The work must carry prominent notices stating that you modified
215
-    it, and giving a relevant date.
216
-
217
-    b) The work must carry prominent notices stating that it is
218
-    released under this License and any conditions added under section
219
-    7.  This requirement modifies the requirement in section 4 to
220
-    "keep intact all notices".
221
-
222
-    c) You must license the entire work, as a whole, under this
223
-    License to anyone who comes into possession of a copy.  This
224
-    License will therefore apply, along with any applicable section 7
225
-    additional terms, to the whole of the work, and all its parts,
226
-    regardless of how they are packaged.  This License gives no
227
-    permission to license the work in any other way, but it does not
228
-    invalidate such permission if you have separately received it.
229
-
230
-    d) If the work has interactive user interfaces, each must display
231
-    Appropriate Legal Notices; however, if the Program has interactive
232
-    interfaces that do not display Appropriate Legal Notices, your
233
-    work need not make them do so.
234
-
235
-  A compilation of a covered work with other separate and independent
236
-works, which are not by their nature extensions of the covered work,
237
-and which are not combined with it such as to form a larger program,
238
-in or on a volume of a storage or distribution medium, is called an
239
-"aggregate" if the compilation and its resulting copyright are not
240
-used to limit the access or legal rights of the compilation's users
241
-beyond what the individual works permit.  Inclusion of a covered work
242
-in an aggregate does not cause this License to apply to the other
243
-parts of the aggregate.
244
-
245
-  6. Conveying Non-Source Forms.
246
-
247
-  You may convey a covered work in object code form under the terms
248
-of sections 4 and 5, provided that you also convey the
249
-machine-readable Corresponding Source under the terms of this License,
250
-in one of these ways:
251
-
252
-    a) Convey the object code in, or embodied in, a physical product
253
-    (including a physical distribution medium), accompanied by the
254
-    Corresponding Source fixed on a durable physical medium
255
-    customarily used for software interchange.
256
-
257
-    b) Convey the object code in, or embodied in, a physical product
258
-    (including a physical distribution medium), accompanied by a
259
-    written offer, valid for at least three years and valid for as
260
-    long as you offer spare parts or customer support for that product
261
-    model, to give anyone who possesses the object code either (1) a
262
-    copy of the Corresponding Source for all the software in the
263
-    product that is covered by this License, on a durable physical
264
-    medium customarily used for software interchange, for a price no
265
-    more than your reasonable cost of physically performing this
266
-    conveying of source, or (2) access to copy the
267
-    Corresponding Source from a network server at no charge.
268
-
269
-    c) Convey individual copies of the object code with a copy of the
270
-    written offer to provide the Corresponding Source.  This
271
-    alternative is allowed only occasionally and noncommercially, and
272
-    only if you received the object code with such an offer, in accord
273
-    with subsection 6b.
274
-
275
-    d) Convey the object code by offering access from a designated
276
-    place (gratis or for a charge), and offer equivalent access to the
277
-    Corresponding Source in the same way through the same place at no
278
-    further charge.  You need not require recipients to copy the
279
-    Corresponding Source along with the object code.  If the place to
280
-    copy the object code is a network server, the Corresponding Source
281
-    may be on a different server (operated by you or a third party)
282
-    that supports equivalent copying facilities, provided you maintain
283
-    clear directions next to the object code saying where to find the
284
-    Corresponding Source.  Regardless of what server hosts the
285
-    Corresponding Source, you remain obligated to ensure that it is
286
-    available for as long as needed to satisfy these requirements.
287
-
288
-    e) Convey the object code using peer-to-peer transmission, provided
289
-    you inform other peers where the object code and Corresponding
290
-    Source of the work are being offered to the general public at no
291
-    charge under subsection 6d.
292
-
293
-  A separable portion of the object code, whose source code is excluded
294
-from the Corresponding Source as a System Library, need not be
295
-included in conveying the object code work.
296
-
297
-  A "User Product" is either (1) a "consumer product", which means any
298
-tangible personal property which is normally used for personal, family,
299
-or household purposes, or (2) anything designed or sold for incorporation
300
-into a dwelling.  In determining whether a product is a consumer product,
301
-doubtful cases shall be resolved in favor of coverage.  For a particular
302
-product received by a particular user, "normally used" refers to a
303
-typical or common use of that class of product, regardless of the status
304
-of the particular user or of the way in which the particular user
305
-actually uses, or expects or is expected to use, the product.  A product
306
-is a consumer product regardless of whether the product has substantial
307
-commercial, industrial or non-consumer uses, unless such uses represent
308
-the only significant mode of use of the product.
309
-
310
-  "Installation Information" for a User Product means any methods,
311
-procedures, authorization keys, or other information required to install
312
-and execute modified versions of a covered work in that User Product from
313
-a modified version of its Corresponding Source.  The information must
314
-suffice to ensure that the continued functioning of the modified object
315
-code is in no case prevented or interfered with solely because
316
-modification has been made.
317
-
318
-  If you convey an object code work under this section in, or with, or
319
-specifically for use in, a User Product, and the conveying occurs as
320
-part of a transaction in which the right of possession and use of the
321
-User Product is transferred to the recipient in perpetuity or for a
322
-fixed term (regardless of how the transaction is characterized), the
323
-Corresponding Source conveyed under this section must be accompanied
324
-by the Installation Information.  But this requirement does not apply
325
-if neither you nor any third party retains the ability to install
326
-modified object code on the User Product (for example, the work has
327
-been installed in ROM).
328
-
329
-  The requirement to provide Installation Information does not include a
330
-requirement to continue to provide support service, warranty, or updates
331
-for a work that has been modified or installed by the recipient, or for
332
-the User Product in which it has been modified or installed.  Access to a
333
-network may be denied when the modification itself materially and
334
-adversely affects the operation of the network or violates the rules and
335
-protocols for communication across the network.
336
-
337
-  Corresponding Source conveyed, and Installation Information provided,
338
-in accord with this section must be in a format that is publicly
339
-documented (and with an implementation available to the public in
340
-source code form), and must require no special password or key for
341
-unpacking, reading or copying.
342
-
343
-  7. Additional Terms.
344
-
345
-  "Additional permissions" are terms that supplement the terms of this
346
-License by making exceptions from one or more of its conditions.
347
-Additional permissions that are applicable to the entire Program shall
348
-be treated as though they were included in this License, to the extent
349
-that they are valid under applicable law.  If additional permissions
350
-apply only to part of the Program, that part may be used separately
351
-under those permissions, but the entire Program remains governed by
352
-this License without regard to the additional permissions.
353
-
354
-  When you convey a copy of a covered work, you may at your option
355
-remove any additional permissions from that copy, or from any part of
356
-it.  (Additional permissions may be written to require their own
357
-removal in certain cases when you modify the work.)  You may place
358
-additional permissions on material, added by you to a covered work,
359
-for which you have or can give appropriate copyright permission.
360
-
361
-  Notwithstanding any other provision of this License, for material you
362
-add to a covered work, you may (if authorized by the copyright holders of
363
-that material) supplement the terms of this License with terms:
364
-
365
-    a) Disclaiming warranty or limiting liability differently from the
366
-    terms of sections 15 and 16 of this License; or
367
-
368
-    b) Requiring preservation of specified reasonable legal notices or
369
-    author attributions in that material or in the Appropriate Legal
370
-    Notices displayed by works containing it; or
371
-
372
-    c) Prohibiting misrepresentation of the origin of that material, or
373
-    requiring that modified versions of such material be marked in
374
-    reasonable ways as different from the original version; or
375
-
376
-    d) Limiting the use for publicity purposes of names of licensors or
377
-    authors of the material; or
378
-
379
-    e) Declining to grant rights under trademark law for use of some
380
-    trade names, trademarks, or service marks; or
381
-
382
-    f) Requiring indemnification of licensors and authors of that
383
-    material by anyone who conveys the material (or modified versions of
384
-    it) with contractual assumptions of liability to the recipient, for
385
-    any liability that these contractual assumptions directly impose on
386
-    those licensors and authors.
387
-
388
-  All other non-permissive additional terms are considered "further
389
-restrictions" within the meaning of section 10.  If the Program as you
390
-received it, or any part of it, contains a notice stating that it is
391
-governed by this License along with a term that is a further
392
-restriction, you may remove that term.  If a license document contains
393
-a further restriction but permits relicensing or conveying under this
394
-License, you may add to a covered work material governed by the terms
395
-of that license document, provided that the further restriction does
396
-not survive such relicensing or conveying.
397
-
398
-  If you add terms to a covered work in accord with this section, you
399
-must place, in the relevant source files, a statement of the
400
-additional terms that apply to those files, or a notice indicating
401
-where to find the applicable terms.
402
-
403
-  Additional terms, permissive or non-permissive, may be stated in the
404
-form of a separately written license, or stated as exceptions;
405
-the above requirements apply either way.
406
-
407
-  8. Termination.
408
-
409
-  You may not propagate or modify a covered work except as expressly
410
-provided under this License.  Any attempt otherwise to propagate or
411
-modify it is void, and will automatically terminate your rights under
412
-this License (including any patent licenses granted under the third
413
-paragraph of section 11).
414
-
415
-  However, if you cease all violation of this License, then your
416
-license from a particular copyright holder is reinstated (a)
417
-provisionally, unless and until the copyright holder explicitly and
418
-finally terminates your license, and (b) permanently, if the copyright
419
-holder fails to notify you of the violation by some reasonable means
420
-prior to 60 days after the cessation.
421
-
422
-  Moreover, your license from a particular copyright holder is
423
-reinstated permanently if the copyright holder notifies you of the
424
-violation by some reasonable means, this is the first time you have
425
-received notice of violation of this License (for any work) from that
426
-copyright holder, and you cure the violation prior to 30 days after
427
-your receipt of the notice.
428
-
429
-  Termination of your rights under this section does not terminate the
430
-licenses of parties who have received copies or rights from you under
431
-this License.  If your rights have been terminated and not permanently
432
-reinstated, you do not qualify to receive new licenses for the same
433
-material under section 10.
434
-
435
-  9. Acceptance Not Required for Having Copies.
436
-
437
-  You are not required to accept this License in order to receive or
438
-run a copy of the Program.  Ancillary propagation of a covered work
439
-occurring solely as a consequence of using peer-to-peer transmission
440
-to receive a copy likewise does not require acceptance.  However,
441
-nothing other than this License grants you permission to propagate or
442
-modify any covered work.  These actions infringe copyright if you do
443
-not accept this License.  Therefore, by modifying or propagating a
444
-covered work, you indicate your acceptance of this License to do so.
445
-
446
-  10. Automatic Licensing of Downstream Recipients.
447
-
448
-  Each time you convey a covered work, the recipient automatically
449
-receives a license from the original licensors, to run, modify and
450
-propagate that work, subject to this License.  You are not responsible
451
-for enforcing compliance by third parties with this License.
452
-
453
-  An "entity transaction" is a transaction transferring control of an
454
-organization, or substantially all assets of one, or subdividing an
455
-organization, or merging organizations.  If propagation of a covered
456
-work results from an entity transaction, each party to that
457
-transaction who receives a copy of the work also receives whatever
458
-licenses to the work the party's predecessor in interest had or could
459
-give under the previous paragraph, plus a right to possession of the
460
-Corresponding Source of the work from the predecessor in interest, if
461
-the predecessor has it or can get it with reasonable efforts.
462
-
463
-  You may not impose any further restrictions on the exercise of the
464
-rights granted or affirmed under this License.  For example, you may
465
-not impose a license fee, royalty, or other charge for exercise of
466
-rights granted under this License, and you may not initiate litigation
467
-(including a cross-claim or counterclaim in a lawsuit) alleging that
468
-any patent claim is infringed by making, using, selling, offering for
469
-sale, or importing the Program or any portion of it.
470
-
471
-  11. Patents.
472
-
473
-  A "contributor" is a copyright holder who authorizes use under this
474
-License of the Program or a work on which the Program is based.  The
475
-work thus licensed is called the contributor's "contributor version".
476
-
477
-  A contributor's "essential patent claims" are all patent claims
478
-owned or controlled by the contributor, whether already acquired or
479
-hereafter acquired, that would be infringed by some manner, permitted
480
-by this License, of making, using, or selling its contributor version,
481
-but do not include claims that would be infringed only as a
482
-consequence of further modification of the contributor version.  For
483
-purposes of this definition, "control" includes the right to grant
484
-patent sublicenses in a manner consistent with the requirements of
485
-this License.
486
-
487
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
488
-patent license under the contributor's essential patent claims, to
489
-make, use, sell, offer for sale, import and otherwise run, modify and
490
-propagate the contents of its contributor version.
491
-
492
-  In the following three paragraphs, a "patent license" is any express
493
-agreement or commitment, however denominated, not to enforce a patent
494
-(such as an express permission to practice a patent or covenant not to
495
-sue for patent infringement).  To "grant" such a patent license to a
496
-party means to make such an agreement or commitment not to enforce a
497
-patent against the party.
498
-
499
-  If you convey a covered work, knowingly relying on a patent license,
500
-and the Corresponding Source of the work is not available for anyone
501
-to copy, free of charge and under the terms of this License, through a
502
-publicly available network server or other readily accessible means,
503
-then you must either (1) cause the Corresponding Source to be so
504
-available, or (2) arrange to deprive yourself of the benefit of the
505
-patent license for this particular work, or (3) arrange, in a manner
506
-consistent with the requirements of this License, to extend the patent
507
-license to downstream recipients.  "Knowingly relying" means you have
508
-actual knowledge that, but for the patent license, your conveying the
509
-covered work in a country, or your recipient's use of the covered work
510
-in a country, would infringe one or more identifiable patents in that
511
-country that you have reason to believe are valid.
512
-
513
-  If, pursuant to or in connection with a single transaction or
514
-arrangement, you convey, or propagate by procuring conveyance of, a
515
-covered work, and grant a patent license to some of the parties
516
-receiving the covered work authorizing them to use, propagate, modify
517
-or convey a specific copy of the covered work, then the patent license
518
-you grant is automatically extended to all recipients of the covered
519
-work and works based on it.
520
-
521
-  A patent license is "discriminatory" if it does not include within
522
-the scope of its coverage, prohibits the exercise of, or is
523
-conditioned on the non-exercise of one or more of the rights that are
524
-specifically granted under this License.  You may not convey a covered
525
-work if you are a party to an arrangement with a third party that is
526
-in the business of distributing software, under which you make payment
527
-to the third party based on the extent of your activity of conveying
528
-the work, and under which the third party grants, to any of the
529
-parties who would receive the covered work from you, a discriminatory
530
-patent license (a) in connection with copies of the covered work
531
-conveyed by you (or copies made from those copies), or (b) primarily
532
-for and in connection with specific products or compilations that
533
-contain the covered work, unless you entered into that arrangement,
534
-or that patent license was granted, prior to 28 March 2007.
535
-
536
-  Nothing in this License shall be construed as excluding or limiting
537
-any implied license or other defenses to infringement that may
538
-otherwise be available to you under applicable patent law.
539
-
540
-  12. No Surrender of Others' Freedom.
541
-
542
-  If conditions are imposed on you (whether by court order, agreement or
543
-otherwise) that contradict the conditions of this License, they do not
544
-excuse you from the conditions of this License.  If you cannot convey a
545
-covered work so as to satisfy simultaneously your obligations under this
546
-License and any other pertinent obligations, then as a consequence you may
547
-not convey it at all.  For example, if you agree to terms that obligate you
548
-to collect a royalty for further conveying from those to whom you convey
549
-the Program, the only way you could satisfy both those terms and this
550
-License would be to refrain entirely from conveying the Program.
551
-
552
-  13. Use with the GNU Affero General Public License.
553
-
554
-  Notwithstanding any other provision of this License, you have
555
-permission to link or combine any covered work with a work licensed
556
-under version 3 of the GNU Affero General Public License into a single
557
-combined work, and to convey the resulting work.  The terms of this
558
-License will continue to apply to the part which is the covered work,
559
-but the special requirements of the GNU Affero General Public License,
560
-section 13, concerning interaction through a network will apply to the
561
-combination as such.
562
-
563
-  14. Revised Versions of this License.
564
-
565
-  The Free Software Foundation may publish revised and/or new versions of
566
-the GNU General Public License from time to time.  Such new versions will
567
-be similar in spirit to the present version, but may differ in detail to
568
-address new problems or concerns.
569
-
570
-  Each version is given a distinguishing version number.  If the
571
-Program specifies that a certain numbered version of the GNU General
572
-Public License "or any later version" applies to it, you have the
573
-option of following the terms and conditions either of that numbered
574
-version or of any later version published by the Free Software
575
-Foundation.  If the Program does not specify a version number of the
576
-GNU General Public License, you may choose any version ever published
577
-by the Free Software Foundation.
578
-
579
-  If the Program specifies that a proxy can decide which future
580
-versions of the GNU General Public License can be used, that proxy's
581
-public statement of acceptance of a version permanently authorizes you
582
-to choose that version for the Program.
583
-
584
-  Later license versions may give you additional or different
585
-permissions.  However, no additional obligations are imposed on any
586
-author or copyright holder as a result of your choosing to follow a
587
-later version.
588
-
589
-  15. Disclaimer of Warranty.
590
-
591
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599
-
600
-  16. Limitation of Liability.
601
-
602
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610
-SUCH DAMAGES.
611
-
612
-  17. Interpretation of Sections 15 and 16.
613
-
614
-  If the disclaimer of warranty and limitation of liability provided
615
-above cannot be given local legal effect according to their terms,
616
-reviewing courts shall apply local law that most closely approximates
617
-an absolute waiver of all civil liability in connection with the
618
-Program, unless a warranty or assumption of liability accompanies a
619
-copy of the Program in return for a fee.
620
-
621
-                     END OF TERMS AND CONDITIONS
622
-
623
-            How to Apply These Terms to Your New Programs
624
-
625
-  If you develop a new program, and you want it to be of the greatest
626
-possible use to the public, the best way to achieve this is to make it
627
-free software which everyone can redistribute and change under these terms.
628
-
629
-  To do so, attach the following notices to the program.  It is safest
630
-to attach them to the start of each source file to most effectively
631
-state the exclusion of warranty; and each file should have at least
632
-the "copyright" line and a pointer to where the full notice is found.
633
-
634
-    <one line to give the program's name and a brief idea of what it does.>
635
-    Copyright (C) <year>  <name of author>
636
-
637
-    This program is free software: you can redistribute it and/or modify
638
-    it under the terms of the GNU General Public License as published by
639
-    the Free Software Foundation, either version 3 of the License, or
640
-    (at your option) any later version.
641
-
642
-    This program is distributed in the hope that it will be useful,
643
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
644
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
645
-    GNU General Public License for more details.
646
-
647
-    You should have received a copy of the GNU General Public License
648
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
649
-
650
-Also add information on how to contact you by electronic and paper mail.
651
-
652
-  If the program does terminal interaction, make it output a short
653
-notice like this when it starts in an interactive mode:
654
-
655
-    <program>  Copyright (C) <year>  <name of author>
656
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657
-    This is free software, and you are welcome to redistribute it
658
-    under certain conditions; type `show c' for details.
659
-
660
-The hypothetical commands `show w' and `show c' should show the appropriate
661
-parts of the General Public License.  Of course, your program's commands
662
-might be different; for a GUI interface, you would use an "about box".
663
-
664
-  You should also get your employer (if you work as a programmer) or school,
665
-if any, to sign a "copyright disclaimer" for the program, if necessary.
666
-For more information on this, and how to apply and follow the GNU GPL, see
667
-<http://www.gnu.org/licenses/>.
668
-
669
-  The GNU General Public License does not permit incorporating your program
670
-into proprietary programs.  If your program is a subroutine library, you
671
-may consider it more useful to permit linking proprietary applications with
672
-the library.  If this is what you want to do, use the GNU Lesser General
673
-Public License instead of this License.  But first, please read
674
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.

+ 0 - 67
README.md View File

@@ -3,70 +3,3 @@
3 3
 [![Build Status](https://travis-ci.org/buxx/OpenCombat.svg?branch=master)](https://travis-ci.org/buxx/OpenCombat) [![Coverage Status](https://coveralls.io/repos/github/buxx/OpenCombat/badge.svg?branch=master)](https://coveralls.io/github/buxx/OpenCombat?branch=master) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/917ff3fc2e184dd5a001c4571d5c583f)](https://www.codacy.com/app/sevajol.bastien/OpenCombat?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=buxx/OpenCombat&amp;utm_campaign=Badge_Grade) [![Known Vulnerabilities](https://snyk.io/test/github/buxx/opencombat/badge.svg?targetFile=requirements.txt)](https://snyk.io/test/github/buxx/opencombat?targetFile=requirements.txt)
4 4
 
5 5
 Open source close combat inspired game. Presentation here: http://www.closecombatseries.net/CCS/modules.php?name=Forums&file=viewtopic&t=11696
6
-
7
-**Important note**: OpenCombat is in development and is developed under linux. Windows support is planned but not actually tested.
8
-
9
-# Install
10
-
11
-Tested only under linux, debian/Ubuntu. Before install project, install OS packages:
12
-
13
-    build-essential python3-tk libsdl1.2debian libsdl-image1.2 libsdl-image1.2-dev libsdl-ttf2.0-0 libsdl-ttf2.0-dev libsdl-mixer1.2 libsdl-mixer1.2-dev redis-server
14
-
15
-Python version: 3.5+
16
-
17
-Considering in your virtual environment, install synergine2:
18
-
19
-    git clone https://github.com/buxx/synergine2.git
20
-    cd synergine2
21
-    python setup.py develop
22
-    pip install -e ".[cocos2d]"
23
-
24
-Then install additional or specific version of development environment:
25
-
26
-    pip install -r requirements.txt
27
-
28
-You also need a running redis server (used db number is `0`, soon configurable). 
29
-
30
-# Run
31
-
32
-## Troops selection
33
-
34
-Start troops selection GUI with:
35
-
36
-    python select_troops.py --country USSR --country DE
37
-
38
-Select troops for every countries then generate a troops file.
39
-
40
-## Troops Placement phase
41
-
42
-You must: specify a map and a state and `--placement` option:
43
-
44
-    python run.py maps/001 --troops troops.xml --placement
45
-
46
-`troops.xml` must be previously (at `Troops selection` phase) generated troops file.
47
-
48
-Map will be loaded with state file troops and you will be able
49
-to move (drag and drop with your mouse) troops.
50
-
51
-Press `s` key will generate a state file in current dir.
52
-
53
-## Combat phase
54
-
55
-You must: specify a map and a state:
56
-
57
-    python run.py maps/001 --state maps/001/state1.xml
58
-
59
-Map will be loaded with state file troops and you will be able to order them.
60
-
61
-# Actual keys / Give orders
62
-
63
-When unit selected (click with mouse on soldier):
64
-
65
-* `r`: run
66
-* `c`: crouch
67
-* `m`: move
68
-* `f`: fire (not implemented)
69
-
70
-And you can:
71
-
72
-* `s`: Save current state into OpenCombat dir (or dir specified with `--state-save-dir`)

+ 0 - 46
config.yaml View File

@@ -1,46 +0,0 @@
1
-core:
2
-    cycle_duration: 0.25
3
-    use_x_cores: 2
4
-terminals:
5
-    sync: True
6
-game:
7
-    look_around:
8
-        frequency: 1
9
-    engage:
10
-        frequency: 1
11
-    move:
12
-        walk_ref_time: 3
13
-        run_ref_time: 1
14
-        crawl_ref_time: 10
15
-        rotate_ref_time: 0  # seconds per degrees
16
-        subject:
17
-          tank1:
18
-            global_move_coeff: 3
19
-            rotate_ref_time: 0.1111  # seconds per degrees
20
-    building:
21
-      draw_interior_gap: 2
22
-
23
-global:
24
-    state_loader: "opencombat.state.StateLoader"
25
-    state_dumper: "opencombat.state.StateDumper"
26
-    state_schema: "opencombat/state.xsd"
27
-    state_template: "opencombat/state_template.xml"
28
-    unit_stash: "opencombat.strategy.unit.stash.UnitStash"
29
-    team_stash: "opencombat.strategy.team.stash.TeamStash"
30
-    teams_schema: "opencombat/strategy/teams.xsd"
31
-    units_schema: "opencombat/strategy/units.xsd"
32
-    troop_dumper: "opencombat.strategy.troops.TroopDumper"
33
-    troop_schema: "opencombat/strategy/troops.xsd"
34
-    units: "opencombat/strategy/units.xml"
35
-    teams: "opencombat/strategy/teams.xml"
36
-    cache_dir_path: 'cache'
37
-    include_path:
38
-      maps:
39
-        - "maps"
40
-      graphics:
41
-        - "medias/images"
42
-      sounds:
43
-        - "medias/sounds"
44
-    logging_level: ERROR
45
-    debug: false
46
-    debug_gui: false

+ 0 - 284
maps/001/001.tmx View File

@@ -1,284 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<map version="1.0" tiledversion="2017.07.26" orientation="orthogonal" renderorder="left-up" width="128" height="64" tilewidth="8" tileheight="8" nextobjectid="1">
3
- <tileset firstgid="1" source="../shared/tilesets/trees.tsx"/>
4
- <tileset firstgid="82" source="../shared/tilesets/terrain.tsx"/>
5
- <tileset firstgid="131" source="../shared/tilesets/interiors.tsx"/>
6
- <imagelayer name="interior">
7
-  <image source="background_interior.png" width="1024" height="512"/>
8
- </imagelayer>
9
- <imagelayer name="background" visible="0">
10
-  <image source="background.png" width="1024" height="512"/>
11
- </imagelayer>
12
- <layer name="top" width="128" height="64">
13
-  <data encoding="csv">
14
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,9,0,0,0,8,0,0,0,0,0,0,1,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
15
-0,1,0,0,0,0,0,0,4,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,7,0,0,0,0,4,0,0,0,0,7,0,0,0,0,5,0,0,0,0,0,7,0,0,0,0,
16
-0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,6,0,0,0,0,0,8,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
17
-0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,
18
-0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,4,0,0,8,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,6,0,0,6,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
19
-2,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
20
-0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
21
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
22
-0,6,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,
23
-0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
24
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,2,0,0,0,1,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,
25
-1,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26
-0,0,0,3,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
27
-0,0,0,0,0,0,0,0,0,0,1,0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
28
-0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
29
-0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
30
-1,0,0,0,0,0,0,0,6,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,
31
-0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
32
-0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
33
-0,0,0,0,0,0,0,0,6,0,0,6,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,5,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
34
-4,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
35
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
36
-0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
37
-8,0,0,0,0,0,0,2,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
38
-0,0,1,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
39
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,
40
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,
41
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,6,0,0,0,0,0,0,0,1,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,
42
-8,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
43
-0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
44
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,7,0,0,7,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
45
-0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
46
-0,1,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,3,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,
47
-0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,6,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
48
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
49
-0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,7,0,0,0,3,0,2,0,0,0,2,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
50
-6,0,0,7,0,0,0,0,0,0,6,0,0,0,3,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,
51
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,9,0,5,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,
52
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,
53
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,9,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
54
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
55
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,9,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
56
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,10,0,0,10,0,0,10,0,0,0,10,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
57
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,
58
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,
59
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,12,0,0,12,0,0,12,0,0,12,0,0,0,0,12,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,
60
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
61
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
63
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,
64
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,
65
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
66
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,
67
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,
68
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,
69
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
70
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,13,0,0,13,0,0,0,0,0,4,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,
71
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
72
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,
73
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
74
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,0,0,0,13,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
75
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,8,0,
76
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,11,0,0,14,0,0,0,14,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,8,0,0,0,0,0,0,0,0,0,
77
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
78
-</data>
79
- </layer>
80
- <layer name="terrain" width="128" height="64" visible="0" opacity="0.55">
81
-  <data encoding="csv">
82
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
83
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
84
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83,83,83,83,83,83,83,83,83,83,83,83,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
85
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
86
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
87
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
88
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
89
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
90
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
91
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
92
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,83,83,83,83,83,83,83,83,83,83,83,83,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
93
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
94
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
95
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
96
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
97
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
98
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
99
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
100
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
101
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
102
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
103
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
104
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
105
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
106
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
107
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
108
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
109
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
110
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
111
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
112
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
113
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
114
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
115
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
116
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
117
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
118
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
119
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
120
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
121
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
122
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
123
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
124
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
125
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
126
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
127
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
128
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
129
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
130
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
131
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
132
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,83,83,83,83,83,83,83,83,83,83,83,83,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
133
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
134
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
135
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
136
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
137
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
138
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
139
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,83,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
140
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,83,83,83,83,83,83,83,83,83,83,83,83,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
141
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
142
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
143
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
144
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
145
-82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,84,84,84,84,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82
146
-</data>
147
- </layer>
148
- <layer name="interiors" width="128" height="64" visible="0" opacity="0.4">
149
-  <data encoding="csv">
150
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
151
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
152
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,133,133,133,133,133,133,133,133,133,133,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
153
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
154
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
155
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
156
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
157
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
158
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
159
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
160
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,133,133,133,133,133,133,133,133,133,133,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
161
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
162
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
163
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
164
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
165
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
166
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
167
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
168
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
169
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
170
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
171
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
172
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
173
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
174
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
175
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
176
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
177
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
178
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
179
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
180
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
181
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
182
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
183
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
184
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
185
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
186
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
187
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
188
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
189
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
190
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
191
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
192
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
193
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
194
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
195
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
196
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
197
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
198
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
199
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
200
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,133,133,133,133,133,133,133,133,133,133,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
201
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
202
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
203
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
204
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
205
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
206
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
207
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,132,132,132,132,133,132,132,132,132,132,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
208
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,133,133,133,133,133,133,133,133,133,133,133,133,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
209
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
210
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
211
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
212
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
213
-131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131
214
-</data>
215
- </layer>
216
- <layer name="ground" width="128" height="64">
217
-  <data encoding="csv">
218
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
219
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
220
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
221
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
222
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
223
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
224
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
225
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
226
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
227
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
228
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
229
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
230
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
231
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
232
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
233
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
234
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
235
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
236
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
237
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
238
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
239
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
240
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
241
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
242
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
243
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
244
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
245
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
246
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
247
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
248
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
249
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
250
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
251
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
252
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
253
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
254
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
255
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
256
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
257
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
258
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
259
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
260
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
261
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
262
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
263
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
264
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
265
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
266
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
267
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
268
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
269
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
270
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
271
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
272
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
273
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
274
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
275
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
276
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
277
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
278
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
279
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
280
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
281
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
282
-</data>
283
- </layer>
284
-</map>

BIN
maps/001/background.png View File


BIN
maps/001/background_interiors.png View File


BIN
maps/001/map001.xcf View File


+ 0 - 128
maps/001/state1.xml View File

@@ -1,128 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<state type="before_battle">
3
-    <map>
4
-        <name>001</name>
5
-    </map>
6
-    <subjects>
7
-        <subject>
8
-            <type>opencombat.simulation.subject.ManSubject</type>
9
-            <position>72,7</position>
10
-            <direction>90</direction>
11
-            <combat_mode>COMBAT_MODE_DEFEND</combat_mode>
12
-            <properties>
13
-                <item>
14
-                    <key>SELECTION_COLOR_RGB</key>
15
-                    <value>204,0,0</value>
16
-                </item>
17
-                <item>
18
-                    <key>FLAG</key>
19
-                    <value>FLAG_USSR</value>
20
-                </item>
21
-                <item>
22
-                    <key>SIDE</key>
23
-                    <value>ALLIES</value>
24
-                </item>
25
-            </properties>
26
-        </subject>
27
-        <subject>
28
-            <type>opencombat.simulation.subject.ManSubject</type>
29
-            <position>72,9</position>
30
-            <direction>90</direction>
31
-            <combat_mode>COMBAT_MODE_DEFEND</combat_mode>
32
-            <properties>
33
-                <item>
34
-                    <key>SELECTION_COLOR_RGB</key>
35
-                    <value>204,0,0</value>
36
-                </item>
37
-                <item>
38
-                    <key>FLAG</key>
39
-                    <value>FLAG_USSR</value>
40
-                </item>
41
-                <item>
42
-                    <key>SIDE</key>
43
-                    <value>ALLIES</value>
44
-                </item>
45
-            </properties>
46
-        </subject>
47
-        <subject>
48
-            <type>opencombat.simulation.subject.ManSubject</type>
49
-            <position>72,11</position>
50
-            <direction>90</direction>
51
-            <combat_mode>COMBAT_MODE_DEFEND</combat_mode>
52
-            <properties>
53
-                <item>
54
-                    <key>SELECTION_COLOR_RGB</key>
55
-                    <value>204,0,0</value>
56
-                </item>
57
-                <item>
58
-                    <key>FLAG</key>
59
-                    <value>FLAG_USSR</value>
60
-                </item>
61
-                <item>
62
-                    <key>SIDE</key>
63
-                    <value>ALLIES</value>
64
-                </item>
65
-            </properties>
66
-        </subject>
67
-        <subject>
68
-            <type>opencombat.simulation.subject.ManSubject</type>
69
-            <position>58,54</position>
70
-            <direction>270</direction>
71
-            <combat_mode>COMBAT_MODE_DEFEND</combat_mode>
72
-            <properties>
73
-                <item>
74
-                    <key>SELECTION_COLOR_RGB</key>
75
-                    <value>0,81,211</value>
76
-                </item>
77
-                <item>
78
-                    <key>FLAG</key>
79
-                    <value>FLAG_DE</value>
80
-                </item>
81
-                <item>
82
-                    <key>SIDE</key>
83
-                    <value>AXIS</value>
84
-                </item>
85
-            </properties>
86
-        </subject>
87
-        <subject>
88
-            <type>opencombat.simulation.subject.ManSubject</type>
89
-            <position>58,56</position>
90
-            <direction>270</direction>
91
-            <combat_mode>COMBAT_MODE_DEFEND</combat_mode>
92
-            <properties>
93
-                <item>
94
-                    <key>SELECTION_COLOR_RGB</key>
95
-                    <value>0,81,211</value>
96
-                </item>
97
-                <item>
98
-                    <key>FLAG</key>
99
-                    <value>FLAG_DE</value>
100
-                </item>
101
-                <item>
102
-                    <key>SIDE</key>
103
-                    <value>AXIS</value>
104
-                </item>
105
-            </properties>
106
-        </subject>
107
-        <subject>
108
-            <type>opencombat.simulation.subject.ManSubject</type>
109
-            <position>58,58</position>
110
-            <direction>270</direction>
111
-            <combat_mode>COMBAT_MODE_DEFEND</combat_mode>
112
-            <properties>
113
-                <item>
114
-                    <key>SELECTION_COLOR_RGB</key>
115
-                    <value>0,81,211</value>
116
-                </item>
117
-                <item>
118
-                    <key>FLAG</key>
119
-                    <value>FLAG_DE</value>
120
-                </item>
121
-                <item>
122
-                    <key>SIDE</key>
123
-                    <value>AXIS</value>
124
-                </item>
125
-            </properties>
126
-        </subject>
127
-    </subjects>
128
-</state>

+ 0 - 188
maps/003/003.tmx View File

@@ -1,188 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<map version="1.0" tiledversion="2017.07.26" orientation="orthogonal" renderorder="left-up" width="70" height="40" tilewidth="8" tileheight="8" nextobjectid="4">
3
- <tileset firstgid="1" source="trees_64x64.tsx"/>
4
- <tileset firstgid="10" source="terrain.tsx"/>
5
- <tileset firstgid="59" source="interiors.tsx"/>
6
- <imagelayer name="interiors">
7
-  <image source="background_interiors.png" width="560" height="320"/>
8
- </imagelayer>
9
- <imagelayer name="background">
10
-  <image source="background.png" width="560" height="320"/>
11
- </imagelayer>
12
- <layer name="interiors" width="70" height="40" opacity="0.53">
13
-  <data encoding="csv">
14
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
15
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,
17
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,
18
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,
19
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,
20
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,
21
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,
22
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,
23
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,
24
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,
25
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
26
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
27
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
28
-0,0,0,0,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
29
-0,0,0,0,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
30
-0,0,0,0,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
31
-0,0,0,0,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
32
-0,0,0,0,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
33
-0,0,0,0,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
34
-0,0,0,0,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
35
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
36
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,0,0,60,60,60,60,60,60,60,60,0,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,
37
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,0,0,60,60,60,60,60,60,60,60,0,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,
38
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,0,0,60,60,60,60,60,60,60,60,0,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,
39
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,0,0,60,60,60,60,60,60,60,60,0,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,
40
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,0,0,60,60,60,60,60,60,60,60,0,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,
41
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,60,0,60,60,60,60,60,60,60,60,0,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,
42
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,61,0,0,60,60,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,
43
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,
44
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,61,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,
45
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,
46
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
47
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
48
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,61,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
49
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
50
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,60,61,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
51
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,60,61,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
52
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,60,60,61,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
53
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,60,60,60,60,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
54
-</data>
55
- </layer>
56
- <layer name="terrain" width="70" height="40" opacity="0.46">
57
-  <data encoding="csv">
58
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
59
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
60
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,
61
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
62
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
63
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
64
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
65
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
66
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
67
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,
68
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,
69
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
70
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
71
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
72
-10,10,10,10,11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
73
-10,10,10,10,11,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
74
-10,10,10,10,11,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
75
-10,10,10,10,11,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
76
-10,10,10,10,11,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
77
-10,10,10,10,11,0,0,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
78
-10,10,10,10,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
79
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
80
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,10,10,10,11,11,11,11,11,10,10,10,11,11,11,11,11,11,11,11,10,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,
81
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,10,10,10,11,11,11,0,0,0,11,10,10,10,11,0,0,0,0,0,0,11,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
82
-10,10,10,10,10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,10,10,10,10,10,10,11,0,0,0,0,0,11,10,10,10,11,0,0,0,0,0,0,11,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
83
-10,10,10,10,10,10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,11,11,10,10,11,0,0,0,0,0,0,11,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
84
-10,10,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,10,10,10,10,10,10,10,10,10,10,10,10,11,11,0,0,0,0,0,11,10,10,11,0,0,0,0,0,0,11,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
85
-12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,11,10,10,11,11,11,11,11,11,11,11,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
86
-12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,10,10,10,10,10,10,10,10,10,11,11,11,11,11,10,10,11,11,11,0,0,0,0,0,11,11,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
87
-12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,10,10,10,10,10,10,10,11,11,11,11,11,0,0,0,11,11,11,11,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
88
-12,12,12,12,12,12,12,12,12,12,12,12,12,12,10,10,10,10,10,10,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,11,10,10,10,10,10,10,10,
89
-12,12,12,12,12,12,12,12,12,12,12,10,10,10,10,11,11,11,11,11,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,10,10,10,10,10,10,10,
90
-12,12,12,12,12,12,12,12,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
91
-12,12,12,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
92
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
93
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
94
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
95
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,0,0,0,0,0,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
96
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,0,0,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
97
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10
98
-</data>
99
- </layer>
100
- <layer name="ground" width="70" height="40">
101
-  <data encoding="csv">
102
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
103
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
104
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
105
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
106
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
107
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
108
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
109
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
110
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
111
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
112
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
113
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
114
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
115
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
116
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
117
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
118
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
119
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
120
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
121
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
122
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
123
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
124
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
125
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
126
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
127
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
128
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
129
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
130
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
131
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
132
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
133
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
134
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
135
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
136
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
137
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
138
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
139
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
140
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
141
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
142
-</data>
143
- </layer>
144
- <layer name="top" width="70" height="40">
145
-  <data encoding="csv">
146
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
147
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
148
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
149
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
150
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
151
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
152
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
153
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
154
-0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
155
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
156
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
157
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
158
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
159
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
160
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
161
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
162
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
163
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
164
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
165
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
166
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
167
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
168
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
169
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
170
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
171
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
172
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
173
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
174
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
175
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
176
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
177
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
178
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
179
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
180
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
181
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
182
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
183
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
184
-0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
185
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
186
-</data>
187
- </layer>
188
-</map>

BIN
maps/003/background.png View File


BIN
maps/003/background_interiors.png View File


BIN
maps/003/background_interiors.xcf View File


BIN
maps/003/interiors.png View File


+ 0 - 22
maps/003/interiors.tsx View File

@@ -1,22 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<tileset name="interiors" tilewidth="8" tileheight="8" spacing="1" tilecount="49" columns="7">
3
- <image source="interiors.png" width="64" height="64"/>
4
- <tile id="0">
5
-  <properties>
6
-   <property name="name" type="str" value="Exterior"/>
7
-   <property name="id" type="str" value="ext"/>
8
-  </properties>
9
- </tile>
10
- <tile id="1">
11
-  <properties>
12
-   <property name="name" type="str" value="interior"/>
13
-   <property name="id" type="str" value="int"/>
14
-  </properties>
15
- </tile>
16
- <tile id="2">
17
-  <properties>
18
-   <property name="name" type="str" value="separator"/>
19
-   <property name="id" type="str" value="sep"/>
20
-  </properties>
21
- </tile>
22
-</tileset>

BIN
maps/003/terrain.png View File


+ 0 - 31
maps/003/terrain.tsx View File

@@ -1,31 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<tileset name="terrain" tilewidth="8" tileheight="8" spacing="1" tilecount="49" columns="7">
3
- <image source="terrain.png" width="64" height="64"/>
4
- <tile id="0">
5
-  <properties>
6
-   <property name="name" type="str" value="Grass"/>
7
-   <property name="traversable_by_man" type="bool" value="true"/>
8
-   <property name="traversable_by_vehicle" type="bool" value="true"/>
9
-   <property name="opacity" type="float" value="0.0"/>
10
-   <property name="height" type="float" value="0.0"/>
11
-  </properties>
12
- </tile>
13
- <tile id="1">
14
-  <properties>
15
-   <property name="name" type="str" value="Wood wall"/>
16
-   <property name="traversable_by_man" type="bool" value="false"/>
17
-   <property name="traversable_by_vehicle" type="bool" value="false"/>
18
-   <property name="opacity" type="float" value="100.0"/>
19
-   <property name="height" type="float" value="2.0"/>
20
-  </properties>
21
- </tile>
22
- <tile id="2">
23
-  <properties>
24
-   <property name="name" type="str" value="Bitume"/>
25
-   <property name="traversable_by_man" type="bool" value="true"/>
26
-   <property name="traversable_by_vehicle" type="bool" value="true"/>
27
-   <property name="opacity" type="float" value="0.0"/>
28
-   <property name="height" type="float" value="0.0"/>
29
-  </properties>
30
- </tile>
31
-</tileset>

BIN
maps/003/trees_64x64.png View File


+ 0 - 4
maps/003/trees_64x64.tsx View File

@@ -1,4 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<tileset name="trees_64x64" tilewidth="64" tileheight="64" tilecount="9" columns="3">
3
- <image source="trees_64x64.png" width="192" height="192"/>
4
-</tileset>

BIN
maps/shared/tilesets/interiors.png View File


+ 0 - 22
maps/shared/tilesets/interiors.tsx View File

@@ -1,22 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<tileset name="interiors" tilewidth="8" tileheight="8" spacing="1" tilecount="49" columns="7">
3
- <image source="interiors.png" width="64" height="64"/>
4
- <tile id="0">
5
-  <properties>
6
-   <property name="name" type="str" value="Exterior"/>
7
-   <property name="id" type="str" value="ext"/>
8
-  </properties>
9
- </tile>
10
- <tile id="1">
11
-  <properties>
12
-   <property name="name" type="str" value="interior"/>
13
-   <property name="id" type="str" value="int"/>
14
-  </properties>
15
- </tile>
16
- <tile id="2">
17
-  <properties>
18
-   <property name="name" type="str" value="separator"/>
19
-   <property name="id" type="str" value="sep"/>
20
-  </properties>
21
- </tile>
22
-</tileset>

BIN
maps/shared/tilesets/terrain.png View File


+ 0 - 31
maps/shared/tilesets/terrain.tsx View File

@@ -1,31 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<tileset name="terrain" tilewidth="8" tileheight="8" spacing="1" tilecount="49" columns="7">
3
- <image source="terrain.png" width="64" height="64"/>
4
- <tile id="0">
5
-  <properties>
6
-   <property name="name" type="str" value="Grass"/>
7
-   <property name="traversable_by_man" type="bool" value="true"/>
8
-   <property name="traversable_by_vehicle" type="bool" value="true"/>
9
-   <property name="opacity" type="float" value="0.0"/>
10
-   <property name="height" type="float" value="0.0"/>
11
-  </properties>
12
- </tile>
13
- <tile id="1">
14
-  <properties>
15
-   <property name="name" type="str" value="Wood wall"/>
16
-   <property name="traversable_by_man" type="bool" value="false"/>
17
-   <property name="traversable_by_vehicle" type="bool" value="false"/>
18
-   <property name="opacity" type="float" value="100.0"/>
19
-   <property name="height" type="float" value="2.0"/>
20
-  </properties>
21
- </tile>
22
- <tile id="2">
23
-  <properties>
24
-   <property name="name" type="str" value="Bitume"/>
25
-   <property name="traversable_by_man" type="bool" value="true"/>
26
-   <property name="traversable_by_vehicle" type="bool" value="true"/>
27
-   <property name="opacity" type="float" value="0.0"/>
28
-   <property name="height" type="float" value="0.0"/>
29
-  </properties>
30
- </tile>
31
-</tileset>

BIN
maps/shared/tilesets/trees.png View File


+ 0 - 5
maps/shared/tilesets/trees.tsx View File

@@ -1,5 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<tileset name="trees" tilewidth="64" tileheight="64" spacing="0" margin="0" tilecount="81" columns="9">
3
- <tileoffset x="-28" y="28"/>
4
- <image source="trees.png" width="640" height="640"/>
5
-</tileset>

BIN
maps/shared/tilesets/trees.xcf View File


BIN
medias/images/actors/man.png View File


BIN
medias/images/actors/man_c1.png View File


BIN
medias/images/actors/man_c1_weap0.png View File


BIN
medias/images/actors/man_c1_weap1.png View File


BIN
medias/images/actors/man_c1_weap1_firing1.png View File


BIN
medias/images/actors/man_c1_weap1_firing2.png View File


BIN
medias/images/actors/man_c1_weap1_firing3.png View File


BIN
medias/images/actors/man_c2.png View File


BIN
medias/images/actors/man_c2_weap1.png View File


BIN
medias/images/actors/man_c3.png View File


BIN
medias/images/actors/man_c3_weap1.png View File


BIN
medias/images/actors/man_c4.png View File


BIN
medias/images/actors/man_c4_weap1.png View File


BIN
medias/images/actors/man_d1.png View File


BIN
medias/images/actors/man_w1.png View File


BIN
medias/images/actors/man_w10.png View File


BIN
medias/images/actors/man_w2.png View File


BIN
medias/images/actors/man_w3.png View File


BIN
medias/images/actors/man_w4.png View File


BIN
medias/images/actors/man_w5.png View File


BIN
medias/images/actors/man_w6.png View File


BIN
medias/images/actors/man_w7.png View File


BIN
medias/images/actors/man_w8.png View File


BIN
medias/images/actors/man_w9.png View File


BIN
medias/images/actors/man_weap1.png View File


BIN
medias/images/actors/man_weap1_firing1.png View File


BIN
medias/images/actors/man_weap1_firing2.png View File


BIN
medias/images/actors/man_weap1_firing3.png View File


BIN
medias/images/actors/src/man_c1_riffle1.xcf View File


BIN
medias/images/actors/src/man_c1_weap1.xcf View File


BIN
medias/images/actors/src/man_c1_weap1_firing.xcf View File


BIN
medias/images/actors/src/man_weap1_firing.xcf View File


BIN
medias/images/actors/src/tank1.xcf View File


BIN
medias/images/actors/tank1.png View File


BIN
medias/images/empty.png View File


BIN
medias/images/unknown.png View File


BIN
medias/sounds/204010__duckduckpony__homemade-gunshot-2.ogg View File


+ 0 - 1
opencombat/__init__.py View File

@@ -1 +0,0 @@
1
-# coding: utf-8

+ 0 - 1
opencombat/ai/__init__.py View File

@@ -1 +0,0 @@
1
-# coding: utf-8

+ 0 - 39
opencombat/ai/placement.py View File

@@ -1,39 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from synergine2.config import Config
5
-
6
-from opencombat.const import SIDE
7
-from opencombat.simulation.base import TileStrategySimulation
8
-
9
-if typing.TYPE_CHECKING:
10
-    from opencombat.simulation.subject import TileSubject
11
-
12
-
13
-class Placement(object):
14
-    """
15
-    Place troops on a map
16
-    """
17
-    def __init__(
18
-        self,
19
-        config: Config,
20
-        simulation: TileStrategySimulation,
21
-    ) -> None:
22
-        self._config = config
23
-        self._simulation = simulation
24
-
25
-    def place(self) -> None:
26
-        # For now it is an extremely simple way to do it
27
-        subject_by_sides = {}  # type: typing.Dict[str, typing.List[TileSubject]]  # nopep8
28
-        for subject in self._simulation.subjects:
29
-            subject_by_sides.setdefault(subject.properties[SIDE], []).append(
30
-                subject,
31
-            )
32
-
33
-        x, y = 0, 0
34
-        for side, subjects in subject_by_sides.items():
35
-            y += 2
36
-            for subject in subjects:
37
-                x += 2
38
-
39
-                subject.position = (x, y)

+ 0 - 24
opencombat/const.py View File

@@ -1,24 +0,0 @@
1
-# coding: utf-8
2
-
3
-COLLECTION_ALIVE = 'ALIVE'
4
-
5
-SELECTION_COLOR_RGB = 'SELECTION_COLOR_RGB'
6
-
7
-FLAG = 'FLAG'
8
-FLAG_DE = 'FLAG_DE'
9
-FLAG_USSR = 'FLAG_USSR'
10
-
11
-SIDE = 'SIDE'
12
-SIDE_ALLIES = 'SIDE_ALLIES'
13
-SIDE_AXIS = 'SIDE_AXIS'
14
-
15
-COUNTRY = 'COUNTRY'
16
-COUNTRY_USSR = 'USSR'
17
-COUNTRY_DE = 'DE'
18
-
19
-COMBAT_MODE = 'COMBAT_MODE'
20
-COMBAT_MODE_DEFEND = 'COMBAT_MODE_DEFEND'
21
-COMBAT_MODE_HIDE = 'COMBAT_MODE_HIDE'
22
-
23
-DE_COLOR = (0, 81, 211)
24
-USSR_COLOR = (204, 0, 0)

+ 0 - 29
opencombat/exception.py View File

@@ -1,29 +0,0 @@
1
-# coding: utf-8
2
-
3
-
4
-class OpenCombatException(Exception):
5
-    pass
6
-
7
-
8
-class UnknownWeapon(OpenCombatException):
9
-    pass
10
-
11
-
12
-class UnknownFiringAnimation(OpenCombatException):
13
-    pass
14
-
15
-
16
-class WrongMode(OpenCombatException):
17
-    pass
18
-
19
-
20
-class StateLoadError(OpenCombatException):
21
-    pass
22
-
23
-
24
-class NotFoundError(OpenCombatException):
25
-    pass
26
-
27
-
28
-class NotFoundException(OpenCombatException):
29
-    pass

+ 0 - 1
opencombat/game/__init__.py View File

@@ -1 +0,0 @@
1
-# coding: utf-8

+ 0 - 303
opencombat/game/actor.py View File

@@ -1,303 +0,0 @@
1
-# coding: utf-8
2
-import os
3
-import typing
4
-
5
-import time
6
-
7
-import pyglet
8
-from PIL import Image
9
-from synergine2.config import Config
10
-from synergine2.simulation import Subject
11
-from synergine2_cocos2d.actor import Actor
12
-from synergine2_xyz.exception import UnknownAnimationIndex
13
-
14
-from opencombat.exception import UnknownWeapon
15
-from opencombat.exception import WrongMode
16
-from opencombat.exception import UnknownFiringAnimation
17
-from opencombat.game.animation import ANIMATION_CRAWL
18
-from opencombat.game.animation import ANIMATION_WALK
19
-from opencombat.game.const import MODE_MAN_STAND_UP
20
-from opencombat.game.const import MODE_MAN_CRAWLING
21
-from opencombat.game.image import TileImageCacheManager
22
-from opencombat.game.weapon import RIFFLE
23
-from opencombat.game.weapon import WeaponImageApplier
24
-from opencombat.user_action import UserAction
25
-
26
-if typing.TYPE_CHECKING:
27
-    from opencombat.game.fire import GuiFiringEvent
28
-
29
-
30
-MODE_DEFAULT = 'MODE_DEFAULT'
31
-
32
-
33
-class BaseActor(Actor):
34
-    position_matching = {
35
-        ANIMATION_WALK: MODE_MAN_STAND_UP,
36
-        ANIMATION_CRAWL: MODE_MAN_CRAWLING,
37
-    }
38
-    mode_image_paths = {
39
-        MODE_DEFAULT: 'unknown.png',
40
-    }
41
-    modes = [
42
-        MODE_DEFAULT,
43
-    ]
44
-    weapons_firing_image_scheme = {}
45
-    weapon_image_scheme = {}
46
-    move_for_gui_actions = {}
47
-
48
-    def __init__(
49
-        self,
50
-        image_path: str,
51
-        config: Config,
52
-        subject: Subject,
53
-    ) -> None:
54
-        self._mode = MODE_MAN_STAND_UP
55
-        self.weapon_image_applier = WeaponImageApplier(config, self)
56
-        self.firing_texture_cache = {}  # type: typing.Dict[str, typing.Dict[str, typing.List[pyglet.image.AbstractImage]]  # nopep8
57
-        super().__init__(image_path, subject=subject, config=config)
58
-
59
-        # Firing
60
-        self.last_firing_time = 0
61
-        self.firing_change_image_gap = 0.05  # seconds
62
-
63
-    def get_image_cache_manager(self) -> TileImageCacheManager:
64
-        return TileImageCacheManager(self, self.config)
65
-
66
-    def get_default_mode(self) -> str:
67
-        return MODE_DEFAULT
68
-
69
-    def get_mode_image_path(self, mode: str) -> str:
70
-        return self.mode_image_paths[mode]
71
-
72
-    def get_modes(self) -> typing.List[str]:
73
-        return self.modes
74
-
75
-    @property
76
-    def mode(self) -> str:
77
-        return self._mode
78
-
79
-    @mode.setter
80
-    def mode(self, value) -> None:
81
-        if value not in self.get_modes():
82
-            raise WrongMode('Actor "{}" has no mode "{}" ({})'.format(
83
-                self.__class__.__name__,
84
-                value,
85
-                ', '.join(self.get_modes()),
86
-            ))
87
-
88
-        self._mode = value
89
-
90
-    def get_mode_for_gui_action(self, gui_action: str) -> str:
91
-        try:
92
-            return self.move_for_gui_actions[gui_action]
93
-        except KeyError:
94
-            return self.get_default_mode()
95
-
96
-    @property
97
-    def weapons(self) -> typing.List[str]:
98
-        return []
99
-
100
-    def build_textures_cache(self) -> None:
101
-        super().build_textures_cache()
102
-        self.build_firing_texture_cache()
103
-
104
-    def get_default_appliable_images(self) -> typing.List[Image.Image]:
105
-        if not self.weapons:
106
-            return []
107
-
108
-        return [
109
-            self.weapon_image_applier.get_image_for_weapon(
110
-                self.mode,
111
-                # TODO BS 2018-02-08: Change this when weapon management enhanced
112
-                self.weapons[0],
113
-            )
114
-        ]
115
-
116
-    def can_rotate_instant(self) -> bool:
117
-        return True
118
-
119
-    def get_animation_appliable_images(
120
-        self,
121
-        animation_name: str,
122
-        animation_position: int,
123
-    ) -> typing.List[Image.Image]:
124
-        if not self.weapons:
125
-            return []
126
-
127
-        position = self.position_matching[animation_name]
128
-
129
-        try:
130
-            return [
131
-                self.weapon_image_applier.get_animation_image_for_weapon(
132
-                    position,
133
-                    self.weapons[0],
134
-                    animation_position,
135
-                )
136
-            ]
137
-        except UnknownWeapon:
138
-            return []
139
-
140
-    def build_firing_texture_cache(self) -> None:
141
-        cache_dir = self.config.resolve('global.cache_dir_path')
142
-        for mode in self.get_modes():
143
-            for weapon in self.weapons:
144
-                firing_images = self.image_cache_manager.firing_cache.get_list(
145
-                    mode,
146
-                    weapon,
147
-                )
148
-                for i, firing_image in enumerate(firing_images):
149
-                    image_name = '{}_firing_{}_{}_{}.png'.format(
150
-                        str(self.subject.id),
151
-                        mode,
152
-                        weapon,
153
-                        i,
154
-                    )
155
-                    cache_image_path = os.path.join(cache_dir, image_name)
156
-                    firing_image.save(cache_image_path)
157
-
158
-                    self.firing_texture_cache\
159
-                        .setdefault(mode, {})\
160
-                        .setdefault(weapon, [])\
161
-                        .append(pyglet.image.load(cache_image_path))
162
-
163
-    def firing(self, firing: 'GuiFiringEvent') -> None:
164
-        # FIXME: move some code ?
165
-        now = time.time()
166
-        if now - self.last_firing_time >= self.firing_change_image_gap:
167
-            self.last_firing_time = now
168
-            firing.increment_animation_index()
169
-
170
-            try:
171
-                texture = self.firing_texture_cache\
172
-                    [self.mode]\
173
-                    [firing.weapon]\
174
-                    [firing.animation_index]
175
-            except KeyError:
176
-                self.logger.error(
177
-                    'No firing animation for actor {}({}) for mode "{}"'
178
-                    ' and weapon "{}"'.format(
179
-                        self.__class__.__name__,
180
-                        str(self.subject.id),
181
-                        self.mode,
182
-                        firing.weapon,
183
-                    )
184
-                )
185
-                return  # There is no firing animation defined
186
-            except IndexError:
187
-                texture = self.firing_texture_cache\
188
-                    [self.mode]\
189
-                    [firing.weapon]\
190
-                    [0]
191
-                firing.reset_animation_index()
192
-
193
-            self.update_image(texture)
194
-
195
-
196
-class Man(BaseActor):
197
-    animation_image_paths = {
198
-        ANIMATION_WALK: [
199
-            'actors/man.png',
200
-            'actors/man_w1.png',
201
-            'actors/man_w2.png',
202
-            'actors/man_w3.png',
203
-            'actors/man_w4.png',
204
-            'actors/man_w5.png',
205
-            'actors/man_w6.png',
206
-            'actors/man_w7.png',
207
-        ],
208
-        ANIMATION_CRAWL: [
209
-            'actors/man_c1.png',
210
-            'actors/man_c2.png',
211
-            'actors/man_c3.png',
212
-            'actors/man_c4.png',
213
-        ]
214
-    }
215
-    modes = [
216
-        MODE_MAN_STAND_UP,
217
-        MODE_MAN_CRAWLING,
218
-    ]
219
-    mode_image_paths = {
220
-        MODE_MAN_STAND_UP: 'actors/man.png',
221
-        MODE_MAN_CRAWLING: 'actors/man_c1.png',
222
-    }
223
-    weapon_image_scheme = {
224
-        MODE_MAN_STAND_UP: {
225
-            RIFFLE: [
226
-                'actors/man_weap1.png'
227
-            ],
228
-        },
229
-        MODE_MAN_CRAWLING: {
230
-            RIFFLE: [
231
-                'actors/man_c1_weap1.png',
232
-                'actors/man_c2_weap1.png',
233
-                'actors/man_c3_weap1.png',
234
-                'actors/man_c4_weap1.png',
235
-            ],
236
-
237
-        }
238
-    }
239
-    weapons_firing_image_scheme = {
240
-        MODE_MAN_STAND_UP: {
241
-            RIFFLE: [
242
-                'actors/man_weap1_firing1.png',
243
-                'actors/man_weap1_firing2.png',
244
-                'actors/man_weap1_firing3.png',
245
-            ],
246
-        },
247
-        MODE_MAN_CRAWLING: {
248
-            RIFFLE: [
249
-                'actors/man_weap1_firing1.png',
250
-                'actors/man_weap1_firing2.png',
251
-                'actors/man_weap1_firing3.png',
252
-            ]
253
-        }
254
-    }
255
-    move_for_gui_actions = {
256
-        UserAction.ORDER_MOVE: MODE_MAN_STAND_UP,
257
-        UserAction.ORDER_MOVE_FAST: MODE_MAN_STAND_UP,
258
-        UserAction.ORDER_MOVE_CRAWL: MODE_MAN_CRAWLING,
259
-    }
260
-
261
-    def __init__(
262
-        self,
263
-        config: Config,
264
-        subject: Subject,
265
-    ) -> None:
266
-        super().__init__('actors/man.png', subject=subject, config=config)
267
-
268
-    @property
269
-    def weapons(self) -> typing.List[str]:
270
-        # TODO BS 2018-01-26: Will be managed by complex part of code
271
-        return [RIFFLE]
272
-
273
-    def get_default_mode(self) -> str:
274
-        return MODE_MAN_STAND_UP
275
-
276
-
277
-class HeavyVehicle(BaseActor):
278
-    animation_image_paths = {
279
-        ANIMATION_WALK: [
280
-            'actors/tank1.png',
281
-        ],
282
-        ANIMATION_CRAWL: [
283
-            'actors/tank1.png',
284
-        ]
285
-    }
286
-    mode_image_paths = {
287
-        MODE_DEFAULT: 'actors/tank1.png',
288
-    }
289
-
290
-    def __init__(
291
-        self,
292
-        config: Config,
293
-        subject: Subject,
294
-    ) -> None:
295
-        super().__init__('actors/tank1.png', subject=subject, config=config)
296
-
297
-    @property
298
-    def weapons(self) -> typing.List[str]:
299
-        # TODO BS 2018-01-26: Will be managed by complex part of code
300
-        return [RIFFLE]
301
-
302
-    def can_rotate_instant(self) -> bool:
303
-        return False

+ 0 - 4
opencombat/game/animation.py View File

@@ -1,4 +0,0 @@
1
-# coding: utf-8
2
-
3
-ANIMATION_WALK = 'WALK'
4
-ANIMATION_CRAWL = 'CRAWL'

+ 0 - 482
opencombat/game/base.py View File

@@ -1,482 +0,0 @@
1
-# coding: utf-8
2
-import io
3
-import os
4
-import random
5
-import typing
6
-
7
-import cocos
8
-import pyglet
9
-import time
10
-
11
-from PIL import Image
12
-from pyglet.window import key
13
-
14
-from cocos.actions import MoveTo as BaseMoveTo
15
-from cocos.actions import RotateTo
16
-from synergine2_cocos2d.audio import AudioLibrary as BaseAudioLibrary
17
-from synergine2_cocos2d.interaction import InteractionManager
18
-from synergine2_cocos2d.middleware import MapMiddleware
19
-from synergine2_cocos2d.util import PathManager
20
-
21
-from opencombat.game.animation import ANIMATION_WALK
22
-from opencombat.game.animation import ANIMATION_CRAWL
23
-from opencombat.game.fire import GuiFiringEvent
24
-from opencombat.game.placement import SetSubjectPositionsInteraction
25
-from opencombat.game.state import SaveStateInteraction
26
-from opencombat.simulation.interior import InteriorManager
27
-from opencombat.simulation.tmx import TileMap
28
-from opencombat.user_action import UserAction
29
-from synergine2.config import Config
30
-from synergine2.terminals import Terminal
31
-from synergine2_cocos2d.actions import MoveTo
32
-from synergine2_cocos2d.animation import Animate
33
-from synergine2_cocos2d.gl import draw_line
34
-from synergine2_cocos2d.gui import EditLayer as BaseEditLayer
35
-from synergine2_cocos2d.gui import SubjectMapper
36
-from synergine2_cocos2d.gui import Gui
37
-from synergine2_cocos2d.gui import TMXGui
38
-from synergine2_cocos2d.layer import LayerManager
39
-from opencombat.simulation import move
40
-from synergine2_xyz.physics import Physics
41
-from synergine2_xyz.utils import get_angle
42
-from opencombat.simulation.event import NewVisibleOpponent
43
-from opencombat.simulation.event import NoLongerVisibleOpponent
44
-from opencombat.simulation.event import FireEvent
45
-from opencombat.simulation.event import DieEvent
46
-from opencombat.simulation.subject import ManSubject
47
-from opencombat.simulation.subject import TankSubject
48
-from opencombat.game.actor import Man as ManActor
49
-from opencombat.game.actor import HeavyVehicle as HeavyVehicleActor
50
-
51
-
52
-class EditLayer(BaseEditLayer):
53
-    def _on_key_press(self, k, m):
54
-        if self.selection:
55
-            if k == key.M:
56
-                self.user_action_pending = UserAction.ORDER_MOVE
57
-            if k == key.R:
58
-                self.user_action_pending = UserAction.ORDER_MOVE_FAST
59
-            if k == key.C:
60
-                self.user_action_pending = UserAction.ORDER_MOVE_CRAWL
61
-            if k == key.F:
62
-                self.user_action_pending = UserAction.ORDER_FIRE
63
-
64
-        if k == key.S:
65
-            self.run_save_state()
66
-
67
-    def draw(self) -> None:
68
-        super().draw()
69
-
70
-    def run_save_state(self) -> None:
71
-        interaction = self.layer_manager\
72
-            .interaction_manager\
73
-            .get_for_user_action(
74
-                UserAction.SAVE_STATE,
75
-            )
76
-        interaction.execute()
77
-
78
-    def can_move(self, selected) -> bool:
79
-        return self.config.resolve('_runtime.placement_mode', False)
80
-
81
-    def end_drag_move(self, wx, wy):
82
-        # set position
83
-        super().end_drag_move(wx, wy)
84
-
85
-        interaction = self.layer_manager \
86
-            .interaction_manager \
87
-            .get_for_user_action(
88
-                UserAction.SET_SUBJECTS_POSITION,
89
-            )
90
-        interaction.execute()
91
-
92
-
93
-class BackgroundLayer(cocos.layer.Layer):
94
-    def __init__(
95
-        self,
96
-        config: Config,
97
-        layer_manager: LayerManager,
98
-        background_sprite: cocos.sprite.Sprite,
99
-    ) -> None:
100
-        super().__init__()
101
-        self.config = config
102
-        self.layer_manager = layer_manager
103
-        self.background_sprite = background_sprite
104
-        self.last_interior_draw_timestamp = 0
105
-        self.draw_interiors_gap = self.config.resolve(
106
-            'game.building.draw_interior_gap',
107
-            2,
108
-        )
109
-        self.background_image = Image.open(os.path.join(
110
-            self.layer_manager.middleware.map_dir_path,
111
-            'background.png',
112
-        ))
113
-        self.interior_manager = InteriorManager(
114
-            TileMap(layer_manager.middleware.get_map_file_path()),
115
-            original_image=self.background_image,
116
-        )
117
-        self.map_tile_width = self.layer_manager.middleware.get_cell_width()
118
-        self.map_tile_height = self.layer_manager.middleware.get_cell_height()
119
-
120
-    def draw(self, *args, **kwargs):
121
-        super().draw(*args, **kwargs)
122
-        self.draw_interiors()
123
-
124
-    def draw_interiors(self):
125
-        now = time.time()
126
-        if now - self.last_interior_draw_timestamp > self.draw_interiors_gap:
127
-            self.last_interior_draw_timestamp = now
128
-            subject_grid_positions = [
129
-                a.subject.position for a
130
-                in self.layer_manager.subject_layer.subjects_index.values()
131
-            ]
132
-            interiors = self.interior_manager.get_interiors(
133
-                where_positions=subject_grid_positions)
134
-
135
-            # FIXME BS 2018-01-25: if not, put original background image
136
-            if interiors:
137
-                image_fake_file = io.BytesIO()
138
-                new_background_image = self.interior_manager.update_image_for_interiors(
139
-                    interiors,
140
-                    self.map_tile_width,
141
-                    self.map_tile_height,
142
-                )
143
-                new_background_image.save(image_fake_file, format='PNG')
144
-                self.background_sprite.image = pyglet.image.load(
145
-                    'new_background.png',
146
-                    file=image_fake_file,
147
-                )
148
-
149
-
150
-class TileLayerManager(LayerManager):
151
-    edit_layer_class = EditLayer
152
-
153
-    def __init__(
154
-        self,
155
-        config: Config,
156
-        middleware: MapMiddleware,
157
-        interaction_manager: 'InteractionManager',
158
-        gui: 'Gui',
159
-    ) -> None:
160
-        super().__init__(
161
-            config,
162
-            middleware,
163
-            interaction_manager,
164
-            gui,
165
-        )
166
-        self.background_layer = None  # type: BackgroundLayer
167
-        self.interior_sprite = None  # type: cocos.sprite.Sprite
168
-        self.ground_layer = None  # type: cocos.tiles.RectMapLayer
169
-        self.top_layer = None  # type: cocos.tiles.RectMapLayer
170
-
171
-    def init(self) -> None:
172
-        super().init()
173
-        self.interior_sprite = self.middleware.get_interior_sprite()
174
-        background_sprite = self.middleware.get_background_sprite()
175
-        self.background_layer = BackgroundLayer(self.config, self, background_sprite)
176
-        self.background_layer.add(background_sprite)
177
-        self.ground_layer = self.middleware.get_ground_layer()
178
-        self.top_layer = self.middleware.get_top_layer()
179
-
180
-    def connect_layers(self) -> None:
181
-        self.main_layer.add(self.interior_sprite)
182
-        self.main_layer.add(self.background_layer)
183
-        self.main_layer.add(self.ground_layer)
184
-        super().connect_layers()
185
-        self.main_layer.add(self.top_layer)
186
-
187
-    def center(self) -> None:
188
-        super().center()
189
-        self.interior_sprite.position = \
190
-            0 + (self.interior_sprite.width / 2), 0 + (self.interior_sprite.height / 2)
191
-        self.background_layer.background_sprite.position = \
192
-            0 + (self.background_layer.background_sprite.width / 2), 0 +\
193
-            (self.background_layer.background_sprite.height/2)
194
-        self.ground_layer.set_view(
195
-            0, 0, self.ground_layer.px_width, self.ground_layer.px_height,
196
-        )
197
-        # TODO BS 2018-06-14: We have to move this layer to be correct.
198
-        # but some trees disapears ... wtf ?
199
-        self.top_layer.set_view(
200
-            28, 28, self.top_layer.px_width, self.top_layer.px_height,
201
-        )
202
-
203
-
204
-class AudioLibrary(BaseAudioLibrary):
205
-    sound_file_paths = {
206
-        'gunshot_default': '204010__duckduckpony__homemade-gunshot-2.ogg',
207
-    }
208
-
209
-
210
-class Game(TMXGui):
211
-    layer_manager_class = TileLayerManager
212
-
213
-    def __init__(
214
-        self,
215
-        config: Config,
216
-        terminal: Terminal,
217
-        physics: Physics,
218
-        read_queue_interval: float = 1 / 60.0,
219
-        map_dir_path: str=None,
220
-    ):
221
-        super().__init__(
222
-            config,
223
-            terminal,
224
-            physics=physics,
225
-            read_queue_interval=read_queue_interval,
226
-            map_dir_path=map_dir_path,
227
-        )
228
-        self.sound_lib = AudioLibrary(config.resolve('global.include_path.sounds'))
229
-        self.graphic_path_manager = PathManager(self.config.resolve(
230
-            'global.include_path.graphics',
231
-        ))
232
-        self.debug_gui = self.config.resolve('global.debug_gui', False)
233
-
234
-        self.terminal.register_event_handler(
235
-            move.SubjectFinishTileMoveEvent,
236
-            self.set_subject_position,
237
-        )
238
-        self.terminal.register_event_handler(
239
-            move.SubjectFinishMoveEvent,
240
-            self.set_subject_position,
241
-        )
242
-
243
-        self.terminal.register_event_handler(
244
-            move.SubjectStartTileMoveEvent,
245
-            self.start_move_subject,
246
-        )
247
-
248
-        self.terminal.register_event_handler(
249
-            move.SubjectStartRotationEvent,
250
-            self.start_rotate_subject,
251
-        )
252
-
253
-        self.terminal.register_event_handler(
254
-            move.SubjectFinishRotationEvent,
255
-            self.rotate_subject,
256
-        )
257
-
258
-        self.terminal.register_event_handler(
259
-            NewVisibleOpponent,
260
-            self.new_visible_opponent,
261
-        )
262
-
263
-        self.terminal.register_event_handler(
264
-            NoLongerVisibleOpponent,
265
-            self.no_longer_visible_opponent,
266
-        )
267
-
268
-        self.terminal.register_event_handler(
269
-            FireEvent,
270
-            self.fire_happen,
271
-        )
272
-
273
-        self.terminal.register_event_handler(
274
-            DieEvent,
275
-            self.subject_die,
276
-        )
277
-
278
-        self.dead_soldier_image = pyglet.resource.image(self.graphic_path_manager.path(
279
-            'actors/man_d1.png',
280
-        ))
281
-
282
-        # subject/actor mapping
283
-        self.subject_mapper_factory.register_mapper(
284
-            ManSubject,
285
-            SubjectMapper(self.config, ManActor),
286
-        )
287
-        self.subject_mapper_factory.register_mapper(
288
-            TankSubject,
289
-            SubjectMapper(self.config, HeavyVehicleActor),
290
-        )
291
-
292
-    def before_run(self) -> None:
293
-        from opencombat.game.move import MoveActorInteraction
294
-        from opencombat.game.move import MoveFastActorInteraction
295
-        from opencombat.game.move import MoveCrawlActorInteraction
296
-        from opencombat.game.fire import FireActorInteraction
297
-
298
-        self.layer_manager.interaction_manager.register(
299
-            MoveActorInteraction,
300
-            self.layer_manager,
301
-        )
302
-        self.layer_manager.interaction_manager.register(
303
-            MoveFastActorInteraction,
304
-            self.layer_manager,
305
-        )
306
-        self.layer_manager.interaction_manager.register(
307
-            MoveCrawlActorInteraction,
308
-            self.layer_manager,
309
-        )
310
-        self.layer_manager.interaction_manager.register(
311
-            FireActorInteraction,
312
-            self.layer_manager,
313
-        )
314
-        self.layer_manager.interaction_manager.register(
315
-            SaveStateInteraction,
316
-            self.layer_manager,
317
-        )
318
-        self.layer_manager.interaction_manager.register(
319
-            SetSubjectPositionsInteraction,
320
-            self.layer_manager,
321
-        )
322
-
323
-    def set_subject_position(
324
-        self,
325
-        event: typing.Union[move.SubjectFinishMoveEvent, move.SubjectFinishTileMoveEvent]
326
-    ):
327
-        actor = self.layer_manager.subject_layer.subjects_index[event.subject_id]
328
-        new_world_position = self.layer_manager\
329
-            .grid_manager\
330
-            .get_world_position_of_grid_position(event.move_to)
331
-
332
-        actor.stop_actions((BaseMoveTo,))
333
-        actor.set_position(*new_world_position)
334
-
335
-    def start_move_subject(
336
-        self,
337
-        event: typing.Union[move.SubjectFinishTileMoveEvent, move.SubjectContinueTileMoveEvent, move.SubjectFinishMoveEvent],  # nopep8
338
-    ):
339
-        actor = self.layer_manager.subject_layer.subjects_index[event.subject_id]
340
-        new_world_position = self.layer_manager\
341
-            .grid_manager\
342
-            .get_world_position_of_grid_position(event.move_to)
343
-
344
-        # FIXME BS 20180319: compute/config for cycle duration? ?
345
-        if event.gui_action == UserAction.ORDER_MOVE:
346
-            animation = ANIMATION_WALK
347
-            cycle_duration = 2
348
-        elif event.gui_action == UserAction.ORDER_MOVE_FAST:
349
-            animation = ANIMATION_WALK
350
-            cycle_duration = 0.5
351
-        elif event.gui_action == UserAction.ORDER_MOVE_CRAWL:
352
-            animation = ANIMATION_CRAWL
353
-            cycle_duration = 2
354
-        else:
355
-            raise NotImplementedError(
356
-                'Gui action {} unknown'.format(event.gui_action)
357
-            )
358
-
359
-        move_duration = event.duration
360
-        move_action = MoveTo(new_world_position, move_duration)
361
-        actor.do(move_action)
362
-        actor.do(Animate(
363
-            animation,
364
-            duration=move_duration,
365
-            cycle_duration=cycle_duration,
366
-        ))
367
-        if actor.can_rotate_instant():
368
-            actor.rotation = get_angle(actor.subject.position, event.move_to)
369
-        actor.mode = actor.get_mode_for_gui_action(animation)
370
-
371
-    def start_rotate_subject(self, event: move.SubjectStartRotationEvent):
372
-        actor = self.layer_manager.subject_layer.subjects_index[event.subject_id]
373
-        rotate_action = RotateTo(event.rotate_absolute, event.duration)
374
-        actor.stop_actions((RotateTo,))
375
-        actor.do(rotate_action)
376
-
377
-    def rotate_subject(self, event: move.SubjectFinishRotationEvent):
378
-        actor = self.layer_manager.subject_layer.subjects_index[event.subject_id]
379
-        actor.rotation = event.rotation_absolute
380
-
381
-    def new_visible_opponent(self, event: NewVisibleOpponent):
382
-        self.visible_or_no_longer_visible_opponent(event, (153, 0, 153))
383
-
384
-    def no_longer_visible_opponent(self, event: NoLongerVisibleOpponent):
385
-        self.visible_or_no_longer_visible_opponent(event, (255, 102, 0))
386
-
387
-    def visible_or_no_longer_visible_opponent(
388
-        self,
389
-        event: typing.Union[NoLongerVisibleOpponent, NewVisibleOpponent],
390
-        line_color,
391
-    ) -> None:
392
-        if not self.layer_manager.debug:
393
-            return
394
-
395
-        observer_actor = self.layer_manager.subject_layer.subjects_index[event.observer_subject_id]
396
-        observed_actor = self.layer_manager.subject_layer.subjects_index[event.observed_subject_id]
397
-
398
-        observer_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
399
-            *self.layer_manager.grid_manager.get_world_position_of_grid_position(
400
-                observer_actor.subject.position,
401
-            )
402
-        )
403
-        observed_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
404
-            *self.layer_manager.grid_manager.get_world_position_of_grid_position(
405
-                observed_actor.subject.position,
406
-            )
407
-        )
408
-
409
-        def draw_visible_opponent():
410
-            draw_line(
411
-                observer_pixel_position,
412
-                observed_pixel_position,
413
-                line_color,
414
-            )
415
-
416
-        self.layer_manager.edit_layer.append_callback(draw_visible_opponent, 1.0)
417
-
418
-    def fire_happen(self, event: FireEvent) -> None:
419
-        shooter_actor = self.layer_manager.subject_layer.subjects_index[event.shooter_subject_id]
420
-        shooter_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
421
-            *self.layer_manager.grid_manager.get_world_position_of_grid_position(
422
-                shooter_actor.subject.position,
423
-            )
424
-        )
425
-        fire_to_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
426
-            *self.layer_manager.grid_manager.get_world_position_of_grid_position(
427
-                event.target_position,
428
-            )
429
-        )
430
-
431
-        def gunshot_trace():
432
-            draw_line(
433
-                shooter_pixel_position,
434
-                fire_to_pixel_position,
435
-                color=(255, 0, 0),
436
-            )
437
-
438
-        def gunshot_sound():
439
-            self.sound_lib.get_sound('gunshot_default').play()
440
-
441
-        firing_event = GuiFiringEvent(shooter_actor, event.weapon_type)
442
-
443
-        def actor_rotate():
444
-            shooter_actor.rotation = get_angle(
445
-                shooter_actor.subject.position,
446
-                event.target_position,
447
-            )
448
-
449
-        def actor_firing():
450
-            shooter_actor.firing(firing_event)
451
-
452
-        def actor_end_firing():
453
-            shooter_actor.reset_default_texture()
454
-
455
-        # To avoid all in same time
456
-        # TODO BS 2018-01-24: This should be unecessary when core events sending will be
457
-        # base on time base instead cycle base. Remove it to ensure.
458
-        delay = random.uniform(0.0, 0.6)
459
-
460
-        if self.debug_gui:
461
-            self.layer_manager.edit_layer.append_callback(
462
-                gunshot_trace,
463
-                duration=0.1,
464
-                delay=delay,
465
-            )
466
-        self.layer_manager.edit_layer.append_callback(
467
-            gunshot_sound,
468
-            duration=0.0,
469
-            delay=delay,
470
-        )
471
-        self.layer_manager.edit_layer.append_callback(
472
-            actor_firing,
473
-            duration=0.5,  # TODO BS 2018-01-25: Wil depend of weapon type
474
-            delay=delay,
475
-            end_callback=actor_end_firing,
476
-            start_callback=actor_rotate,
477
-        )
478
-
479
-    def subject_die(self, event: DieEvent) -> None:
480
-        killed_actor = self.layer_manager.subject_layer.subjects_index[event.shoot_subject_id]
481
-        killed_actor.update_image(self.dead_soldier_image)
482
-        killed_actor.freeze()

+ 0 - 9
opencombat/game/const.py View File

@@ -1,9 +0,0 @@
1
-# coding: utf-8
2
-
3
-MODE_MAN_STAND_UP = 'MODE_MAN_STAND_UP'
4
-MODE_MAN_CRAWLING = 'MODE_MAN_CRAWLING'
5
-FLAG_DE = 'DE'
6
-FLAG_COLORS = {
7
-    FLAG_DE
8
-}
9
-FLAG_USSR = 'USSR'

+ 0 - 115
opencombat/game/fire.py View File

@@ -1,115 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from opencombat.game.actor import BaseActor
5
-from opencombat.simulation.event import DEFAULT_WEAPON_TYPE
6
-from opencombat.simulation.fire import RequestFireBehaviour
7
-from synergine2_cocos2d.interaction import BaseActorInteraction
8
-from opencombat.user_action import UserAction
9
-from synergine2.simulation import SimulationBehaviour
10
-from synergine2_cocos2d.actor import Actor
11
-from synergine2_cocos2d.gl import draw_line
12
-
13
-
14
-class BaseFireActorInteraction(BaseActorInteraction):
15
-    gui_action = None
16
-    color = None
17
-    not_visible_color = (0, 0, 0)
18
-    request_move_behaviour_class = RequestFireBehaviour
19
-
20
-    def draw_pending(self) -> None:
21
-        for actor in self.layer_manager.edit_layer.selection:
22
-            actor_grid_position = self.layer_manager.grid_manager.get_grid_position(actor.position)
23
-            actor_pixel_position = self.layer_manager.grid_manager.get_world_position_of_grid_position(
24
-                actor_grid_position,
25
-            )
26
-            mouse_grid_position = self.layer_manager.grid_manager.get_grid_position(
27
-                self.layer_manager.scrolling_manager.screen_to_world(
28
-                    *self.layer_manager.edit_layer.screen_mouse,
29
-                )
30
-            )
31
-            draw_to_pixel = self.layer_manager.edit_layer.screen_mouse
32
-
33
-            obstacle_grid_position = self.layer_manager.gui.physics.get_visibility_obstacle(
34
-                subject=actor.subject,
35
-                to_position=mouse_grid_position,
36
-                matrix_name='visibility',
37
-                opacity_property_name='opacity',
38
-            )
39
-
40
-            # DEBUG
41
-            if self.layer_manager.debug:
42
-                grid_paths = self.layer_manager.gui.physics.matrixes.get_path_positions(
43
-                    from_=actor_grid_position,
44
-                    to=mouse_grid_position,
45
-                )
46
-                previous_grid_path = None
47
-                for grid_path in grid_paths:
48
-                    if previous_grid_path:
49
-                        previous_grid_path_pixel = self.layer_manager.grid_manager.get_world_position_of_grid_position(
50
-                            previous_grid_path,
51
-                        )
52
-                        current_grid_pixel = self.layer_manager.grid_manager.get_world_position_of_grid_position(
53
-                            grid_path,
54
-                        )
55
-                        draw_line(
56
-                            self.layer_manager.scrolling_manager.world_to_screen(*previous_grid_path_pixel),
57
-                            self.layer_manager.scrolling_manager.world_to_screen(*current_grid_pixel),
58
-                            (25, 125, 25),
59
-                        )
60
-                    previous_grid_path = grid_path
61
-
62
-            if obstacle_grid_position:
63
-                obstacle_pixel = self.layer_manager.grid_manager.get_world_position_of_grid_position(
64
-                    obstacle_grid_position,
65
-                )
66
-                draw_to_pixel = self.layer_manager.scrolling_manager.world_to_screen(*obstacle_pixel)
67
-
68
-                draw_line(
69
-                    self.layer_manager.scrolling_manager.world_to_screen(*obstacle_pixel),
70
-                    self.layer_manager.edit_layer.screen_mouse,
71
-                    self.not_visible_color,
72
-                )
73
-
74
-            draw_line(
75
-                self.layer_manager.scrolling_manager.world_to_screen(*actor_pixel_position),
76
-                draw_to_pixel,
77
-                self.color,
78
-            )
79
-
80
-    def get_behaviour(self, actor: Actor, mouse_grid_position) -> typing.Tuple[typing.Type[SimulationBehaviour], dict]:
81
-        raise NotImplementedError()
82
-        return self.request_move_behaviour_class, {
83
-            'subject_id': actor.subject.id,
84
-            'move_to': mouse_grid_position,
85
-            'gui_action': self.gui_action,
86
-        }
87
-
88
-
89
-class FireActorInteraction(BaseFireActorInteraction):
90
-    gui_action = UserAction.ORDER_FIRE
91
-    color = (255, 0, 0)
92
-
93
-
94
-class GuiFiringEvent(object):
95
-    def __init__(
96
-        self,
97
-        actor: BaseActor,
98
-        weapon: str,
99
-    ) -> None:
100
-        self.actor = actor
101
-        self.weapon = weapon
102
-        self._animation_index = -1
103
-
104
-        if weapon == DEFAULT_WEAPON_TYPE:
105
-            self.weapon = self.actor.weapons[0]
106
-
107
-    @property
108
-    def animation_index(self) -> int:
109
-        return self._animation_index
110
-
111
-    def increment_animation_index(self) -> None:
112
-        self._animation_index += 1
113
-
114
-    def reset_animation_index(self) -> None:
115
-        self._animation_index = -1

+ 0 - 109
opencombat/game/image.py View File

@@ -1,109 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from PIL import Image
5
-from synergine2.config import Config
6
-from synergine2_cocos2d.util import PathManager
7
-from synergine2_xyz.image import ImageCache
8
-from synergine2_xyz.image import ImageCacheManager
9
-from synergine2_xyz.exception import UnknownAnimationIndex
10
-
11
-from opencombat.exception import UnknownWeapon
12
-from opencombat.exception import UnknownFiringAnimation
13
-
14
-if typing.TYPE_CHECKING:
15
-    from opencombat.game.actor import BaseActor
16
-
17
-
18
-class FiringImageCache(ImageCache):
19
-    def add(
20
-        self,
21
-        mode: str,
22
-        weapon: str,
23
-        image: Image.Image,
24
-    ) -> None:
25
-        self.cache.setdefault(mode, {}).setdefault(weapon, []).append(image)
26
-
27
-    def get(
28
-        self,
29
-        mode: str,
30
-        weapon: str,
31
-        position: int,
32
-    ) -> Image.Image:
33
-        try:
34
-            return self.cache[mode][weapon][position]
35
-        except KeyError:
36
-            raise UnknownFiringAnimation(
37
-                'Unknown firing animation for mode "{}" and weapon "{}"'.format(
38
-                    mode,
39
-                    weapon,
40
-                )
41
-            )
42
-        except IndexError:
43
-            raise UnknownAnimationIndex(
44
-                'Unknown animation index "{}" for mode "{}" and weapon "{}"'.format(
45
-                    position,
46
-                    mode,
47
-                    weapon,
48
-                ),
49
-            )
50
-
51
-    def get_list(
52
-        self,
53
-        mode: str,
54
-        weapon: str,
55
-    ) -> typing.List[Image.Image]:
56
-        try:
57
-            return self.cache[mode][weapon]
58
-        except KeyError:
59
-            raise UnknownFiringAnimation(
60
-                'Unknown firing animation for mode "{}" and weapon "{}"'.format(
61
-                    mode,
62
-                    weapon,
63
-                )
64
-            )
65
-
66
-
67
-class TileImageCacheManager(ImageCacheManager):
68
-    def __init__(
69
-        self,
70
-        actor: 'BaseActor',
71
-        config: Config,
72
-    ) -> None:
73
-        super().__init__(actor, config)
74
-        self.firing_cache = FiringImageCache()
75
-        from opencombat.game.actor import BaseActor
76
-        self.actor = typing.cast(BaseActor, self.actor)
77
-        self.path_manager = PathManager(
78
-            self.config.resolve('global.include_path.graphics'),
79
-        )
80
-
81
-    def build(self) -> None:
82
-        super().build()
83
-        self.build_firing()
84
-
85
-    def build_firing(self) -> None:
86
-        for mode in self.actor.get_modes():
87
-            mode_image_path = self.actor.get_mode_image_path(mode)
88
-            mode_image = Image.open(self.path_manager.path(mode_image_path))
89
-
90
-            for weapon in self.actor.weapons:
91
-                try:
92
-                    images = self.actor.weapon_image_applier.get_firing_image(
93
-                        mode=mode,
94
-                        weapon_type=weapon,
95
-                    )
96
-                except UnknownWeapon:
97
-                    images = [Image.open(self.path_manager.path('empty.png'))]
98
-
99
-                for position in range(len(images)):
100
-                    position_image = images[position]
101
-
102
-                    final_image = mode_image.copy()
103
-                    final_image.paste(
104
-                        position_image,
105
-                        (0, 0),
106
-                        position_image,
107
-                    )
108
-
109
-                    self.firing_cache.add(mode, weapon, final_image)

+ 0 - 56
opencombat/game/move.py View File

@@ -1,56 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from synergine2_cocos2d.interaction import BaseActorInteraction
5
-from opencombat.user_action import UserAction
6
-from synergine2.simulation import SimulationBehaviour
7
-from synergine2_cocos2d.actor import Actor
8
-from synergine2_cocos2d.gl import draw_line
9
-from synergine2_xyz.move.simulation import RequestMoveBehaviour
10
-
11
-
12
-class BaseMoveActorInteraction(BaseActorInteraction):
13
-    gui_action = None
14
-    color = None
15
-    request_move_behaviour_class = RequestMoveBehaviour
16
-
17
-    def draw_pending(self) -> None:
18
-        for actor in self.layer_manager.edit_layer.selection:
19
-            grid_position = self.layer_manager\
20
-                .grid_manager\
21
-                .get_grid_position(actor.position)
22
-            pixel_position = self.layer_manager\
23
-                .grid_manager\
24
-                .get_world_position_of_grid_position(grid_position)
25
-
26
-            draw_line(
27
-                self.layer_manager.scrolling_manager.world_to_screen(*pixel_position),
28
-                self.layer_manager.edit_layer.screen_mouse,
29
-                self.color,
30
-            )
31
-
32
-    def get_behaviour(
33
-        self,
34
-        actor: Actor,
35
-        mouse_grid_position,
36
-    ) -> typing.Tuple[typing.Type[SimulationBehaviour], dict]:
37
-        return self.request_move_behaviour_class, {
38
-            'subject_id': actor.subject.id,
39
-            'move_to': mouse_grid_position,
40
-            'gui_action': self.gui_action,
41
-        }
42
-
43
-
44
-class MoveActorInteraction(BaseMoveActorInteraction):
45
-    gui_action = UserAction.ORDER_MOVE
46
-    color = (0, 0, 255)
47
-
48
-
49
-class MoveFastActorInteraction(BaseMoveActorInteraction):
50
-    gui_action = UserAction.ORDER_MOVE_FAST
51
-    color = (72, 244, 66)
52
-
53
-
54
-class MoveCrawlActorInteraction(BaseMoveActorInteraction):
55
-    gui_action = UserAction.ORDER_MOVE_CRAWL
56
-    color = (235, 244, 66)

+ 0 - 26
opencombat/game/placement.py View File

@@ -1,26 +0,0 @@
1
-# coding: utf-8
2
-from synergine2.terminals import TerminalPackage
3
-from synergine2_cocos2d.interaction import Interaction
4
-
5
-from opencombat.simulation.placement import SetSubjectPositionsSimulationBehaviour  # nopep8
6
-from opencombat.user_action import UserAction
7
-
8
-
9
-class SetSubjectPositionsInteraction(Interaction):
10
-    gui_action = UserAction.SET_SUBJECTS_POSITION
11
-
12
-    def get_package_for_terminal(self) -> TerminalPackage:
13
-        data = []  # type: typing.List[typing.Tuple[int, typing.Tuple[int, int]]]  # nopep8
14
-        for moved_subject in self.layer_manager.edit_layer.selection.keys():
15
-            grid_position = self.layer_manager.grid_manager.get_grid_position(
16
-                moved_subject.position,
17
-            )
18
-            data.append(
19
-                (moved_subject.subject.id, grid_position),
20
-            )
21
-
22
-        return TerminalPackage(
23
-            simulation_actions=[
24
-                (SetSubjectPositionsSimulationBehaviour, data),
25
-            ]
26
-        )

+ 0 - 18
opencombat/game/state.py View File

@@ -1,18 +0,0 @@
1
-# coding: utf-8
2
-
3
-from synergine2.terminals import TerminalPackage
4
-from synergine2_cocos2d.interaction import Interaction
5
-
6
-from opencombat.simulation.state import SaveStateSimulationAction
7
-from opencombat.user_action import UserAction
8
-
9
-
10
-class SaveStateInteraction(Interaction):
11
-    gui_action = UserAction.SAVE_STATE
12
-
13
-    def get_package_for_terminal(self) -> TerminalPackage:
14
-        return TerminalPackage(
15
-            simulation_actions=[
16
-                (SaveStateSimulationAction, {}),
17
-            ]
18
-        )

+ 0 - 97
opencombat/game/weapon.py View File

@@ -1,97 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-import pyglet
5
-from PIL import Image
6
-from pyglet.image import ImageData
7
-from synergine2.config import Config
8
-from synergine2_cocos2d.util import PathManager
9
-
10
-from opencombat.exception import UnknownWeapon
11
-from opencombat.game.const import MODE_MAN_STAND_UP
12
-from opencombat.game.const import MODE_MAN_CRAWLING
13
-
14
-if typing.TYPE_CHECKING:
15
-    from opencombat.game.actor import BaseActor
16
-
17
-RIFFLE = 'RIFFLE'
18
-
19
-
20
-class WeaponImageApplier(object):
21
-    def __init__(
22
-        self,
23
-        config: Config,
24
-        actor: 'BaseActor',
25
-    ) -> None:
26
-        self.actor = actor
27
-        self._images_scheme = self.get_rest_images_scheme()
28
-        self._firing_images_scheme = self.get_firing_images_scheme()
29
-        self.path_manager = PathManager(config.resolve('global.include_path.graphics'))
30
-        self._cache = {}  # type: typing.Dict[str, Image.Image]
31
-        self._firing_cache = {}  # type: typing.Dict[str, Image.Image]
32
-
33
-    def get_rest_images_scheme(self) -> typing.Dict[str, typing.Dict[str, typing.List[str]]]:
34
-        return self.actor.weapon_image_scheme
35
-
36
-    def get_firing_images_scheme(self) -> typing.Dict[str, typing.Dict[str, typing.List[str]]]:
37
-        return self.actor.weapons_firing_image_scheme
38
-
39
-    def get_image_for_weapon(self, mode: str, weapon_type: str) -> Image.Image:
40
-        try:
41
-            image_file_path = self.path_manager.path(
42
-                self._images_scheme[mode][weapon_type][0],
43
-            )
44
-            try:
45
-                return self._cache[image_file_path]
46
-            except KeyError:
47
-                self._cache[image_file_path] = Image.open(image_file_path)
48
-                return self._cache[image_file_path]
49
-        except KeyError:
50
-            raise UnknownWeapon(
51
-                'Unknown weapon "{}" for mode "{}"'.format(weapon_type, mode),
52
-            )
53
-
54
-    def get_firing_image(
55
-        self, mode: str,
56
-        weapon_type: str,
57
-    ) -> typing.List[Image.Image]:
58
-        images = []
59
-        try:
60
-            image_file_paths = self._firing_images_scheme[mode][weapon_type]
61
-            for image_file_path in image_file_paths:
62
-                final_path = self.path_manager.path(image_file_path)
63
-                try:
64
-                    images.append(self._firing_cache[final_path])
65
-                except KeyError:
66
-                    self._firing_cache[image_file_path] = Image.open(final_path)
67
-                    images.append(self._firing_cache[image_file_path])
68
-            return images
69
-        except KeyError:
70
-            raise UnknownWeapon(
71
-                'Unknown weapon "{}" for mode "{}"'.format(weapon_type, mode),
72
-            )
73
-
74
-    def get_animation_image_for_weapon(
75
-        self,
76
-        mode: str,
77
-        weapon_type: str,
78
-        animation_position: int,
79
-    ) -> Image.Image:
80
-        try:
81
-            image_file_path = self.path_manager.path(
82
-                self._images_scheme[mode][weapon_type][animation_position],
83
-            )
84
-            try:
85
-                return self._cache[image_file_path]
86
-            except KeyError:
87
-                self._cache[image_file_path] = Image.open(image_file_path)
88
-                return self._cache[image_file_path]
89
-        except KeyError:
90
-            raise UnknownWeapon(
91
-                'Unknown weapon "{}" for mode "{}"'.format(weapon_type, mode),
92
-            )
93
-        except IndexError:
94
-            raise UnknownWeapon(
95
-                'Unknown weapon "{}" for mode "{}"'.format(weapon_type, mode),
96
-            )
97
-

+ 0 - 17
opencombat/gui.py View File

@@ -1,17 +0,0 @@
1
-# coding: utf-8
2
-from logging import Logger
3
-from tkinter import Tk
4
-
5
-from synergine2.config import Config
6
-from synergine2.log import get_logger
7
-
8
-
9
-class Gui(object):
10
-    def __init__(
11
-        self,
12
-        config: Config,
13
-        master: Tk,
14
-    ) -> None:
15
-        self._config = config
16
-        self._logger = get_logger(self.__class__.__name__, config)
17
-        self._master = master

+ 0 - 1
opencombat/simulation/__init__.py View File

@@ -1 +0,0 @@
1
-# coding: utf-8

+ 0 - 70
opencombat/simulation/base.py View File

@@ -1,70 +0,0 @@
1
-# coding: utf-8
2
-from opencombat.const import COLLECTION_ALIVE
3
-from opencombat.const import COUNTRY_USSR
4
-from opencombat.const import FLAG_USSR
5
-from opencombat.const import FLAG_DE
6
-from opencombat.const import SIDE_ALLIES
7
-from opencombat.const import SIDE_AXIS
8
-from opencombat.const import COUNTRY_DE
9
-from opencombat.const import USSR_COLOR
10
-from opencombat.const import DE_COLOR
11
-from opencombat.const import SIDE
12
-from opencombat.const import FLAG
13
-from opencombat.const import SELECTION_COLOR_RGB
14
-from opencombat.simulation.physics import TilePhysics
15
-from synergine2.config import Config
16
-from synergine2.simulation import SubjectBehaviour
17
-from synergine2_xyz.physics import Physics
18
-from synergine2_xyz.simulation import XYZSimulation
19
-from synergine2_xyz.subjects import XYZSubject
20
-from synergine2_xyz.subjects import XYZSubjects
21
-
22
-
23
-class TileStrategySimulation(XYZSimulation):
24
-    behaviours_classes = [
25
-
26
-    ]
27
-
28
-    @classmethod
29
-    def get_default_properties_for_country(cls, country: str) -> dict:
30
-        if country == COUNTRY_USSR:
31
-            return {
32
-                SELECTION_COLOR_RGB: USSR_COLOR,
33
-                FLAG: FLAG_USSR,
34
-                SIDE: SIDE_ALLIES,
35
-            }
36
-        elif country == COUNTRY_DE:
37
-            return {
38
-                SELECTION_COLOR_RGB: DE_COLOR,
39
-                FLAG: FLAG_DE,
40
-                SIDE: SIDE_AXIS,
41
-            }
42
-
43
-        raise NotImplementedError('Unknown country "{}"'.format(country))
44
-
45
-    def __init__(
46
-        self,
47
-        config: Config,
48
-        map_file_path: str,
49
-    ) -> None:
50
-        self.map_file_path = map_file_path
51
-        super().__init__(config)
52
-
53
-    def create_physics(self) -> Physics:
54
-        return TilePhysics(
55
-            config=self.config,
56
-            map_file_path=self.map_file_path,
57
-        )
58
-
59
-
60
-class TileStrategySubjects(XYZSubjects):
61
-    pass
62
-
63
-
64
-class BaseSubject(XYZSubject):
65
-    pass
66
-
67
-
68
-class AliveSubjectBehaviour(SubjectBehaviour):
69
-    def is_terminated(self) -> bool:
70
-        return COLLECTION_ALIVE not in self.subject.collections

+ 0 - 133
opencombat/simulation/behaviour.py View File

@@ -1,133 +0,0 @@
1
-# coding: utf-8
2
-import random
3
-import time
4
-import typing
5
-
6
-from synergine2.simulation import Event
7
-from synergine2.simulation import disable_when
8
-from synergine2.simulation import config_value
9
-
10
-from opencombat.const import COLLECTION_ALIVE
11
-from opencombat.simulation.base import AliveSubjectBehaviour
12
-from opencombat.simulation.event import NoLongerVisibleOpponent
13
-from opencombat.simulation.event import FireEvent
14
-from opencombat.simulation.event import DieEvent
15
-from opencombat.simulation.event import NewVisibleOpponent
16
-from opencombat.simulation.mechanism import OpponentVisibleMechanism
17
-
18
-
19
-class LookAroundBehaviour(AliveSubjectBehaviour):
20
-    """
21
-    Behaviour who permit to reference visible things like enemies
22
-    """
23
-    visible_mechanism = OpponentVisibleMechanism
24
-    use = [visible_mechanism]
25
-
26
-    def __init__(self, *args, **kwargs) -> None:
27
-        super().__init__(*args, **kwargs)
28
-        self._seconds_frequency = float(self.config.resolve('game.look_around.frequency'))
29
-
30
-    @property
31
-    def seconds_frequency(self) -> typing.Optional[float]:
32
-        return self._seconds_frequency
33
-
34
-    def action(self, data) -> [Event]:
35
-        new_visible_subject_events = []
36
-        no_longer_visible_subject_events = []
37
-
38
-        for no_longer_visible_subject_id in data['no_longer_visible_subject_ids']:
39
-            no_longer_visible_subject_events.append(NoLongerVisibleOpponent(
40
-                observer_subject_id=self.subject.id,
41
-                observed_subject_id=no_longer_visible_subject_id,
42
-            ))
43
-            self.subject.visible_opponent_ids.remove(no_longer_visible_subject_id)
44
-
45
-        for new_visible_subject_id in data['new_visible_subject_ids']:
46
-            new_visible_subject_events.append(NewVisibleOpponent(
47
-                observer_subject_id=self.subject.id,
48
-                observed_subject_id=new_visible_subject_id,
49
-            ))
50
-            self.subject.visible_opponent_ids.append(new_visible_subject_id)
51
-
52
-        return new_visible_subject_events + no_longer_visible_subject_events
53
-
54
-    @disable_when(config_value('_runtime.placement_mode'))
55
-    def run(self, data):
56
-        visible_subjects = data[self.visible_mechanism]['visible_subjects']
57
-        visible_subject_ids = [s.id for s in visible_subjects]
58
-        new_visible_subject_ids = []
59
-        no_longer_visible_subject_ids = []
60
-
61
-        for subject_id in self.subject.visible_opponent_ids:
62
-            if subject_id not in visible_subject_ids:
63
-                no_longer_visible_subject_ids.append(subject_id)
64
-
65
-        for subject in visible_subjects:
66
-            if subject.id not in self.subject.visible_opponent_ids:
67
-                new_visible_subject_ids.append(subject.id)
68
-
69
-        return {
70
-            'new_visible_subject_ids': new_visible_subject_ids,
71
-            'no_longer_visible_subject_ids': no_longer_visible_subject_ids,
72
-        }
73
-
74
-
75
-class EngageOpponent(AliveSubjectBehaviour):
76
-    visible_mechanism = OpponentVisibleMechanism
77
-    use = [visible_mechanism]
78
-
79
-    def __init__(self, *args, **kwargs) -> None:
80
-        super().__init__(*args, **kwargs)
81
-        self._seconds_frequency = float(self.config.resolve('game.engage.frequency'))
82
-
83
-    @property
84
-    def seconds_frequency(self) -> typing.Optional[float]:
85
-        return self._seconds_frequency
86
-
87
-    def action(self, data) -> [Event]:
88
-        kill = data['kill']
89
-        target_subject_id = data['target_subject_id']
90
-        target_subject = self.simulation.subjects.index[target_subject_id]
91
-        target_position = data['target_position']
92
-
93
-        events = list()
94
-        events.append(FireEvent(
95
-            shooter_subject_id=self.subject.id,
96
-            target_position=target_position,
97
-        ))
98
-
99
-        # Must be check if target is not already dead (killed same cycle)
100
-        if kill and COLLECTION_ALIVE in target_subject.collections:
101
-            DieEvent.apply_subject_death(target_subject)
102
-            events.append(DieEvent(
103
-                shooter_subject_id=self.subject.id,
104
-                shoot_subject_id=target_subject_id,
105
-            ))
106
-
107
-        return events
108
-
109
-    @disable_when(config_value('_runtime.placement_mode'))
110
-    def run(self, data):
111
-        visible_subjects = data[self.visible_mechanism]['visible_subjects']
112
-        if not visible_subjects:
113
-            return
114
-        # Manage selected target (can change, better visibility, etc ...)
115
-        # Manage weapon munition to be able to fire
116
-        # Manage fear/under fire ...
117
-        # Manage weapon reload time
118
-
119
-        # For dev fun, don't fire at random
120
-        if random.randint(1, 3) == -1:
121
-            # Executed but decided to fail
122
-            self.last_execution_time = time.time()
123
-            return False
124
-
125
-        target_subject = random.choice(visible_subjects)
126
-        kill = random.randint(0, 100) >= 75
127
-
128
-        # Manage fire miss or touch (visibility, fear, opponent hiding, etc ...)
129
-        return {
130
-            'kill': kill,
131
-            'target_subject_id': target_subject.id,
132
-            'target_position': target_subject.position,
133
-        }

+ 0 - 58
opencombat/simulation/event.py View File

@@ -1,58 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from synergine2.simulation import Event
5
-
6
-from opencombat.const import COLLECTION_ALIVE
7
-
8
-if typing.TYPE_CHECKING:
9
-    from opencombat.simulation.subject import TileSubject
10
-
11
-DEFAULT_WEAPON_TYPE = 'DEFAULT_WEAPON_TYPE'
12
-
13
-
14
-class NewVisibleOpponent(Event):
15
-    def __init__(
16
-        self,
17
-        observer_subject_id: int,
18
-        observed_subject_id: int,
19
-    ) -> None:
20
-        self.observer_subject_id = observer_subject_id
21
-        self.observed_subject_id = observed_subject_id
22
-
23
-
24
-class NoLongerVisibleOpponent(Event):
25
-    def __init__(
26
-        self,
27
-        observer_subject_id: int,
28
-        observed_subject_id: int,
29
-    ) -> None:
30
-        self.observer_subject_id = observer_subject_id
31
-        self.observed_subject_id = observed_subject_id
32
-
33
-
34
-class FireEvent(Event):
35
-    def __init__(
36
-        self,
37
-        shooter_subject_id: int,
38
-        target_position: typing.Tuple[int, int],
39
-        weapon_type: str=DEFAULT_WEAPON_TYPE,
40
-    ) -> None:
41
-        self.shooter_subject_id = shooter_subject_id
42
-        self.target_position = target_position
43
-        self.weapon_type = weapon_type
44
-
45
-
46
-class DieEvent(Event):
47
-    @classmethod
48
-    def apply_subject_death(cls, subject: 'TileSubject') -> None:
49
-        subject.remove_collection(COLLECTION_ALIVE)
50
-        subject.intentions.remove_all()
51
-
52
-    def __init__(
53
-        self,
54
-        shooter_subject_id: int,
55
-        shoot_subject_id: int,
56
-    ) -> None:
57
-        self.shooter_subject_id = shooter_subject_id
58
-        self.shoot_subject_id = shoot_subject_id

+ 0 - 39
opencombat/simulation/fire.py View File

@@ -1,39 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from synergine2.config import Config
5
-from synergine2.simulation import SimulationBehaviour
6
-from synergine2.simulation import Simulation
7
-from synergine2.simulation import Event
8
-from synergine2.simulation import Intention
9
-from synergine2_xyz.simulation import XYZSimulation
10
-
11
-
12
-class FireIntention(Intention):
13
-    def __init__(
14
-        self,
15
-        to_position: typing.Tuple[int, int],
16
-        to_subject_id: int,
17
-        gui_action: typing.Any,
18
-    ) -> None:
19
-        self.to_position = to_position
20
-        self.to_subject_id = to_subject_id
21
-        self.gui_action = gui_action
22
-
23
-
24
-class RequestFireBehaviour(SimulationBehaviour):
25
-    move_intention_class = FireIntention
26
-
27
-    def __init__(
28
-        self,
29
-        config: Config,
30
-        simulation: Simulation,
31
-    ):
32
-        super().__init__(config, simulation)
33
-        self.simulation = typing.cast(XYZSimulation, self.simulation)
34
-
35
-    def action(self, data) -> typing.List[Event]:
36
-        to_position = data['to_position']
37
-        to_subject_id = data['to_subject_id']
38
-
39
-        return []

+ 0 - 148
opencombat/simulation/interior.py View File

@@ -1,148 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from PIL.PngImagePlugin import PngImageFile
5
-from synergine2_xyz.map import TMXMap
6
-from synergine2_xyz.utils import get_direct_around_positions_of_position
7
-
8
-
9
-class InteriorMapConfiguration(object):
10
-    def __init__(
11
-        self,
12
-        layer_name: str='interiors',
13
-        exterior_id: str='ext',
14
-        interior_id: str='int',
15
-        separator_id: str='sep',
16
-    ) -> None:
17
-        self.layer_name = layer_name
18
-        self.exterior_id = exterior_id
19
-        self.interior_id = interior_id
20
-        self.separator_id = separator_id
21
-
22
-
23
-class InteriorManager(object):
24
-    def __init__(
25
-        self,
26
-        map_: TMXMap,
27
-        original_image: PngImageFile,
28
-        configuration: InteriorMapConfiguration=None,
29
-    ) -> None:
30
-        self.interiors = []
31
-        self.map = map_
32
-        self.original_image = original_image
33
-        self.configuration = configuration or InteriorMapConfiguration()
34
-        self.interiors = self._compute_interiors()
35
-        self._cache = {}  # type: typing.Dict[str, PngImageFile]
36
-
37
-    def _compute_interiors(self) -> typing.List[typing.List[typing.Tuple[int, int]]]:
38
-        interiors = []
39
-        layer_tiles = self.map.layer_tiles(self.configuration.layer_name)
40
-        for tile_xy, tile in layer_tiles.items():
41
-
42
-            if tile.property('id') == self.configuration.interior_id:
43
-                x, y = map(int, tile_xy.split('.'))
44
-                if not any([(x, y) in i for i in interiors]):
45
-                    new_interior = [(x, y)]
46
-                    positions_to_parse = []
47
-                    possible_positions_xyz = get_direct_around_positions_of_position((x, y, 0))
48
-                    possible_positions_xy = [(p[0], p[1]) for p in possible_positions_xyz]
49
-                    positions_to_parse.extend(possible_positions_xy)
50
-
51
-                    for possible_position_xyz in positions_to_parse:
52
-                        test_tile = None
53
-                        new_tile_x = possible_position_xyz[0]
54
-                        new_tile_y = possible_position_xyz[1]
55
-                        possible_position_key = '{}.{}'.format(new_tile_x, new_tile_y)
56
-
57
-                        if (new_tile_x, new_tile_y) in new_interior:
58
-                            continue
59
-
60
-                        try:
61
-                            test_tile = layer_tiles[possible_position_key]
62
-                        except KeyError:
63
-                            continue
64
-
65
-                        if test_tile.property('id') not in [
66
-                            self.configuration.interior_id,
67
-                            self.configuration.separator_id,
68
-                        ]:
69
-                            continue
70
-
71
-                        new_interior.append((new_tile_x, new_tile_y))
72
-
73
-                        if not test_tile.property('id') == self.configuration.separator_id:
74
-                            new_position_neighbour = get_direct_around_positions_of_position((new_tile_x, new_tile_y, 0))
75
-                            positions_to_parse.extend(new_position_neighbour)
76
-
77
-                    interiors.append(new_interior)
78
-
79
-        return interiors
80
-
81
-    def get_interiors(
82
-        self,
83
-        where_positions: typing.Iterable[typing.Tuple[int, int]]=None,
84
-    ) -> typing.List[typing.List[typing.Tuple[int, int]]]:
85
-        if where_positions is None:
86
-            return self.interiors
87
-        interiors = []
88
-
89
-        for interior in self.interiors:
90
-            for where_position in where_positions:
91
-                if where_position in interior and interior not in interiors:
92
-                    interiors.append(interior)
93
-        return interiors
94
-
95
-    def _get_interior_unique_key(
96
-        self,
97
-        interiors: typing.List[typing.List[typing.Tuple[int, int]]],
98
-    ) -> str:
99
-        """
100
-        Compute a key for given interior list. WARNING: For performance reasons,
101
-        actual unique key is interior list ID concatenation:
102
-        So, if same interior list is given, but in different python object, key will be
103
-        different !
104
-        :param interiors: Interior list to build unique key
105
-        :return: String or Int who id unique key of given interiors
106
-        """
107
-        return '.'.join([str(id(i)) for i in interiors])
108
-
109
-    def update_image_for_interiors(
110
-        self,
111
-        interiors: typing.List[typing.List[typing.Tuple[int, int]]],
112
-        tile_width: int,
113
-        tile_height: int,
114
-        invert_y: bool=True,
115
-    ) -> PngImageFile:
116
-        """
117
-
118
-        :param interiors: List of list of interior tile positions
119
-        :param tile_width: Width of a tile
120
-        :param tile_height: Height of a tile
121
-        :param invert_y: If y reference is top left instead bottom left
122
-        :return: Image givan at __init__ with all tile pixels replaces by transparent
123
-        pixel
124
-        """
125
-        try:
126
-            return self._cache[self._get_interior_unique_key(interiors)]
127
-        except KeyError:
128
-            pass  # compute it
129
-
130
-        image = self.original_image.copy()
131
-        image_height = image.height
132
-        pixels = image.load()
133
-
134
-        for interior in interiors:
135
-            for tile_x, tile_y in interior:
136
-                start_x = tile_x * tile_width
137
-                start_y = tile_y * tile_height
138
-                for x in range(start_x, start_x+tile_width):
139
-                    for y in range(start_y, start_y+tile_height):
140
-
141
-                        real_y = y
142
-                        if invert_y:
143
-                            real_y = image_height - 1 - y
144
-
145
-                        pixels[x, real_y] = (0, 0, 0, 0)
146
-
147
-        self._cache[self._get_interior_unique_key(interiors)] = image
148
-        return image

+ 0 - 24
opencombat/simulation/mechanism.py View File

@@ -1,24 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from synergine2_xyz.subjects import XYZSubject
5
-from synergine2_xyz.visible.simulation import VisibleMechanism
6
-from synergine2.simulation import disable_when
7
-from synergine2.simulation import config_value
8
-
9
-from opencombat.const import SIDE
10
-from opencombat.const import COLLECTION_ALIVE
11
-
12
-
13
-class OpponentVisibleMechanism(VisibleMechanism):
14
-    from_collection = COLLECTION_ALIVE
15
-
16
-    @disable_when(config_value('_runtime.placement_mode'))
17
-    def run(self) -> dict:
18
-        return super().run()
19
-
20
-    def reduce_subjects(self, subjects: typing.List[XYZSubject]) -> typing.Iterator[XYZSubject]:
21
-        def filter_subject(subject: XYZSubject) -> bool:
22
-            return self.subject.properties[SIDE] != subject.properties[SIDE]
23
-
24
-        return filter(filter_subject, subjects)

+ 0 - 475
opencombat/simulation/move.py View File

@@ -1,475 +0,0 @@
1
-# coding: utf-8
2
-import time
3
-import typing
4
-
5
-from synergine2.simulation import SubjectBehaviour
6
-from synergine2.simulation import SubjectMechanism
7
-from synergine2.simulation import Event
8
-from synergine2_xyz.move.intention import MoveToIntention
9
-from synergine2_xyz.simulation import XYZSimulation
10
-from synergine2_xyz.utils import get_angle
11
-from synergine2.simulation import disable_when
12
-from synergine2.simulation import config_value
13
-
14
-from opencombat.const import COLLECTION_ALIVE
15
-from opencombat.user_action import UserAction
16
-
17
-
18
-class SubjectStartRotationEvent(Event):
19
-    def __init__(
20
-        self,
21
-        subject_id: int,
22
-        rotate_relative: float,
23
-        rotate_absolute: float,
24
-        duration: float,
25
-        gui_action: UserAction,
26
-    ) -> None:
27
-        self.subject_id = subject_id
28
-        self.rotate_relative = rotate_relative
29
-        self.rotate_absolute = rotate_absolute
30
-        self.duration = duration
31
-        self.gui_action = gui_action
32
-
33
-
34
-class SubjectContinueRotationEvent(Event):
35
-    def __init__(
36
-        self,
37
-        subject_id: int,
38
-        rotate_relative: float,
39
-        duration: float,
40
-        gui_action: UserAction,
41
-    ) -> None:
42
-        self.subject_id = subject_id
43
-        self.rotate_relative = rotate_relative
44
-        self.duration = duration
45
-        self.gui_action = gui_action
46
-
47
-
48
-class SubjectFinishRotationEvent(Event):
49
-    def __init__(
50
-        self,
51
-        subject_id: int,
52
-        rotation_absolute: float,
53
-        gui_action: UserAction,
54
-    ) -> None:
55
-        self.subject_id = subject_id
56
-        self.rotation_absolute = rotation_absolute
57
-        self.gui_action = gui_action
58
-
59
-
60
-class SubjectStartTileMoveEvent(Event):
61
-    def __init__(
62
-        self,
63
-        subject_id: int,
64
-        move_to: typing.Tuple[int, int],
65
-        duration: float,
66
-        gui_action: UserAction,
67
-    ) -> None:
68
-        self.subject_id = subject_id
69
-        self.move_to = move_to
70
-        self.duration = duration
71
-        self.gui_action = gui_action
72
-
73
-
74
-class SubjectContinueTileMoveEvent(Event):
75
-    def __init__(
76
-        self,
77
-        subject_id: int,
78
-        move_to: typing.Tuple[int, int],
79
-        duration: float,
80
-        gui_action: UserAction,
81
-    ) -> None:
82
-        self.subject_id = subject_id
83
-        self.move_to = move_to
84
-        self.duration = duration
85
-        self.gui_action = gui_action
86
-
87
-
88
-class SubjectFinishTileMoveEvent(Event):
89
-    def __init__(
90
-        self,
91
-        subject_id: int,
92
-        move_to: typing.Tuple[int, int],
93
-        gui_action: UserAction,
94
-    ) -> None:
95
-        self.subject_id = subject_id
96
-        self.move_to = move_to
97
-        self.gui_action = gui_action
98
-
99
-
100
-class SubjectFinishMoveEvent(Event):
101
-    def __init__(
102
-        self,
103
-        subject_id: int,
104
-        move_to: typing.Tuple[int, int],
105
-        gui_action: UserAction,
106
-    ) -> None:
107
-        self.subject_id = subject_id
108
-        self.move_to = move_to
109
-        self.gui_action = gui_action
110
-
111
-
112
-class MoveToMechanism(SubjectMechanism):
113
-    @disable_when(config_value('_runtime.placement_mode'))
114
-    def run(self) -> dict:
115
-        try:
116
-            # TODO: MoveToIntention doit être configurable
117
-            move = self.subject.intentions.get(MoveToIntention)  # type: MoveToIntention
118
-        except KeyError:
119
-            return {}
120
-
121
-        if COLLECTION_ALIVE not in self.subject.collections:
122
-            return {}
123
-
124
-        return move.get_data()
125
-
126
-
127
-class MoveWithRotationBehaviour(SubjectBehaviour):
128
-    use = [MoveToMechanism]
129
-
130
-    def __init__(self, *args, **kwargs):
131
-        super().__init__(*args, **kwargs)
132
-        self.simulation = typing.cast(XYZSimulation, self.simulation)
133
-
134
-    @disable_when(config_value('_runtime.placement_mode'))
135
-    def run(self, data) -> object:
136
-        """
137
-        Compute data relative to move
138
-        """
139
-        data = data[MoveToMechanism]
140
-        if not data:
141
-            return False
142
-
143
-        # Prepare data
144
-        to = data['to']  # type: typing.Tuple(int, int)
145
-        return_data = {}
146
-        now = time.time()
147
-
148
-        # Test if it's first time
149
-        if not data.get('path'):
150
-            return_data['path'] = self.simulation.physics.found_path(
151
-                start=self.subject.position,
152
-                end=to,
153
-                subject=self.subject,
154
-            )
155
-            # find path algorithm can skip start position, add it if not in
156
-            if return_data['path'][0] != self.subject.position:
157
-                return_data['path'] = [self.subject.position] + return_data['path']
158
-            data['path'] = return_data['path']
159
-
160
-        # Prepare data
161
-        path = data['path']  # type: typing.List[typing.Tuple(int, int)]
162
-        path_index = path.index(self.subject.position)
163
-        next_position = path[path_index + 1]
164
-        next_position_direction = get_angle(self.subject.position, next_position)
165
-        rotate_relative = next_position_direction - self.subject.direction
166
-
167
-        # Test if finish move
168
-        if path_index == len(path) - 1:
169
-            return {
170
-                'move_to_finished': to,
171
-                'gui_action': data['gui_action'],
172
-            }
173
-
174
-        # Check if moving
175
-        if self.subject.moving_to == next_position:
176
-            if self.subject.start_move + self.subject.move_duration > now:
177
-                # Let moving
178
-                return {
179
-                    'tile_move_to': next_position,
180
-                    'gui_action': data['gui_action'],
181
-                }
182
-            return_data['tile_move_to_finished'] = self.subject.moving_to
183
-            # Must consider new position of subject
184
-            path_index = path.index(return_data['tile_move_to_finished'])
185
-            if path_index == len(path) - 1:
186
-                return {
187
-                    'move_to_finished': to,
188
-                    'gui_action': data['gui_action'],
189
-                }
190
-            next_position = path[path_index + 1]
191
-            next_position_direction = get_angle(
192
-                return_data['tile_move_to_finished'],
193
-                next_position,
194
-            )
195
-            rotate_relative = next_position_direction - self.subject.direction
196
-
197
-        # Check if rotating
198
-        if self.subject.rotate_to != -1:
199
-            # If it is not finished
200
-            if self.subject.start_rotation + self.subject.rotate_duration > now:
201
-                # Let rotation do it's job
202
-                return {
203
-                    'rotate_relative': rotate_relative,
204
-                    'rotate_absolute': next_position_direction,
205
-                    'gui_action': data['gui_action'],
206
-                }
207
-            # rotation finish
208
-            return_data['rotate_to_finished'] = self.subject.rotate_to
209
-
210
-        # Check if need to rotate
211
-        if not return_data.get('rotate_to_finished') \
212
-                and self.subject.direction != next_position_direction:
213
-            return_data.update({
214
-                'rotate_relative': rotate_relative,
215
-                'rotate_absolute': next_position_direction,
216
-                'gui_action': data['gui_action'],
217
-            })
218
-            return return_data
219
-
220
-        # Need to move to next tile
221
-        return_data['tile_move_to'] = next_position
222
-        return_data['gui_action'] = data['gui_action']
223
-        return return_data
224
-
225
-    def action(self, data) -> [Event]:
226
-        events = []
227
-        now = time.time()
228
-
229
-        if data.get('path'):
230
-            move = self.subject.intentions.get(MoveToIntention)
231
-            move.path = data['path']
232
-            self.subject.intentions.set(move)
233
-
234
-        if data.get('tile_move_to_finished'):
235
-            self.subject.position = data['tile_move_to_finished']
236
-            self.subject.moving_to = (-1, -1)
237
-            self.subject.start_move = -1
238
-            self.subject.move_duration = -1
239
-            events.append(SubjectFinishTileMoveEvent(
240
-                subject_id=self.subject.id,
241
-                move_to=data['tile_move_to_finished'],
242
-                gui_action=data['gui_action'],
243
-            ))
244
-
245
-        if data.get('move_to_finished'):
246
-            self.subject.position = data['move_to_finished']
247
-            self.subject.moving_to = (-1, -1)
248
-            self.subject.start_move = -1
249
-            self.subject.move_duration = -1
250
-            self.subject.intentions.remove(MoveToIntention)
251
-            events.append(SubjectFinishMoveEvent(
252
-                subject_id=self.subject.id,
253
-                move_to=data['move_to_finished'],
254
-                gui_action=data['gui_action'],
255
-            ))
256
-
257
-        if data.get('rotate_to_finished'):
258
-            self.subject.rotate_to = -1
259
-            self.subject.rotate_duration = -1
260
-            self.subject.start_rotation = -1
261
-            self.subject.direction = data['rotate_to_finished']
262
-
263
-            events.append(SubjectFinishRotationEvent(
264
-                subject_id=self.subject.id,
265
-                rotation_absolute=data['rotate_to_finished'],
266
-                gui_action=data['gui_action'],
267
-            ))
268
-
269
-        if data.get('rotate_relative'):
270
-            # Test if rotation is already started
271
-            if self.subject.rotate_to == data['rotate_absolute']:
272
-                # look at progression
273
-                rotate_since = now - self.subject.start_rotation
274
-                rotate_progress = rotate_since / self.subject.rotate_duration
275
-                rotation_to_do = self.subject.rotate_to - self.subject.direction  # nopep8
276
-                rotation_done = rotation_to_do * rotate_progress
277
-                self.subject.direction = self.subject.direction + rotation_done
278
-                rotation_left = self.subject.rotate_to - self.subject.direction
279
-                duration = abs(self.subject.get_rotate_duration(
280
-                    angle=rotation_left,
281
-                ))
282
-                self.subject.rotate_duration = duration
283
-                self.subject.start_rotation = now
284
-
285
-                return [SubjectContinueRotationEvent(
286
-                    subject_id=self.subject.id,
287
-                    rotate_relative=rotation_left,
288
-                    duration=duration,
289
-                    gui_action=data['gui_action'],
290
-                )]
291
-            else:
292
-                duration = abs(self.subject.get_rotate_duration(
293
-                    angle=data['rotate_relative'],
294
-                ))
295
-                self.subject.rotate_to = data['rotate_absolute']
296
-                self.subject.rotate_duration = duration
297
-                self.subject.start_rotation = time.time()
298
-
299
-                events.append(SubjectStartRotationEvent(
300
-                    subject_id=self.subject.id,
301
-                    rotate_relative=data['rotate_relative'],
302
-                    rotate_absolute=data['rotate_absolute'],
303
-                    duration=duration,
304
-                    gui_action=data['gui_action'],
305
-                ))
306
-
307
-        if data.get('tile_move_to'):
308
-            # It is already moving ?
309
-            if self.subject.moving_to == data.get('tile_move_to'):
310
-                # look at progression
311
-                move_since = now - self.subject.start_move
312
-                move_progress = move_since / self.subject.move_duration
313
-                move_done = self.subject.move_duration * move_progress
314
-                duration = self.subject.move_duration - move_done
315
-                self.subject.move_duration = duration
316
-
317
-                return [SubjectContinueTileMoveEvent(
318
-                    subject_id=self.subject.id,
319
-                    move_to=data['tile_move_to'],
320
-                    duration=duration,
321
-                    gui_action=data['gui_action'],
322
-                )]
323
-            else:
324
-                move = self.subject.intentions.get(MoveToIntention)
325
-                move_type_duration = self.subject.get_move_duration(move)
326
-                # FIXME: duration depend next tile type, etc
327
-                # see opencombat.gui.base.Game#start_move_subject
328
-                duration = move_type_duration * 1
329
-                self.subject.moving_to = data['tile_move_to']
330
-                self.subject.move_duration = duration
331
-                self.subject.start_move = time.time()
332
-                events.append(SubjectStartTileMoveEvent(
333
-                    subject_id=self.subject.id,
334
-                    move_to=data['tile_move_to'],
335
-                    duration=duration,
336
-                    gui_action=data['gui_action'],
337
-                ))
338
-
339
-        return events
340
-
341
-
342
-class MoveBehaviour(SubjectBehaviour):
343
-    use = [MoveToMechanism]
344
-
345
-    def __init__(self, *args, **kwargs):
346
-        super().__init__(*args, **kwargs)
347
-        self.simulation = typing.cast(XYZSimulation, self.simulation)
348
-
349
-    @disable_when(config_value('_runtime.placement_mode'))
350
-    def run(self, data) -> object:
351
-        """
352
-        Compute data relative to move
353
-        """
354
-        data = data[MoveToMechanism]
355
-        if not data:
356
-            return False
357
-
358
-        # Prepare data
359
-        to = data['to']  # type: typing.Tuple(int, int)
360
-        return_data = {}
361
-        now = time.time()
362
-
363
-        # Test if it's first time
364
-        if not data.get('path'):
365
-            return_data['path'] = self.simulation.physics.found_path(
366
-                start=self.subject.position,
367
-                end=to,
368
-                subject=self.subject,
369
-            )
370
-            # find path algorithm can skip start position, add it if not in
371
-            if return_data['path'][0] != self.subject.position:
372
-                return_data['path'] = [self.subject.position] + return_data['path']
373
-            data['path'] = return_data['path']
374
-
375
-        # Prepare data
376
-        path = data['path']  # type: typing.List[typing.Tuple(int, int)]
377
-        path_index = path.index(self.subject.position)
378
-        next_position = path[path_index + 1]
379
-
380
-        # Test if finish move
381
-        if path_index == len(path) - 1:
382
-            return {
383
-                'move_to_finished': to,
384
-                'gui_action': data['gui_action'],
385
-            }
386
-
387
-        # Check if moving
388
-        if self.subject.moving_to == next_position:
389
-            if self.subject.start_move + self.subject.move_duration > now:
390
-                # Let moving
391
-                return {
392
-                    'tile_move_to': next_position,
393
-                    'gui_action': data['gui_action'],
394
-                }
395
-            return_data['tile_move_to_finished'] = self.subject.moving_to
396
-            # Must consider new position of subject
397
-            path_index = path.index(return_data['tile_move_to_finished'])
398
-            if path_index == len(path) - 1:
399
-                return {
400
-                    'move_to_finished': to,
401
-                    'gui_action': data['gui_action'],
402
-                }
403
-            next_position = path[path_index + 1]
404
-
405
-        # Need to move to next tile
406
-        return_data['tile_move_to'] = next_position
407
-        return_data['gui_action'] = data['gui_action']
408
-        return return_data
409
-
410
-    def action(self, data) -> [Event]:
411
-        events = []
412
-        now = time.time()
413
-
414
-        if data.get('path'):
415
-            move = self.subject.intentions.get(MoveToIntention)
416
-            move.path = data['path']
417
-            self.subject.intentions.set(move)
418
-
419
-        if data.get('tile_move_to_finished'):
420
-            self.subject.position = data['tile_move_to_finished']
421
-            self.subject.moving_to = (-1, -1)
422
-            self.subject.start_move = -1
423
-            self.subject.move_duration = -1
424
-            events.append(SubjectFinishTileMoveEvent(
425
-                subject_id=self.subject.id,
426
-                move_to=data['tile_move_to_finished'],
427
-                gui_action=data['gui_action'],
428
-            ))
429
-
430
-        if data.get('move_to_finished'):
431
-            self.subject.position = data['move_to_finished']
432
-            self.subject.moving_to = (-1, -1)
433
-            self.subject.start_move = -1
434
-            self.subject.move_duration = -1
435
-            self.subject.intentions.remove(MoveToIntention)
436
-            events.append(SubjectFinishMoveEvent(
437
-                subject_id=self.subject.id,
438
-                move_to=data['move_to_finished'],
439
-                gui_action=data['gui_action'],
440
-            ))
441
-
442
-        if data.get('tile_move_to'):
443
-            # It is already moving ?
444
-            if self.subject.moving_to == data.get('tile_move_to'):
445
-                # look at progression
446
-                move_since = now - self.subject.start_move
447
-                move_progress = move_since / self.subject.move_duration
448
-                move_done = self.subject.move_duration * move_progress
449
-                duration = self.subject.move_duration - move_done
450
-                self.subject.move_duration = duration
451
-                self.subject.start_move = time.time()
452
-
453
-                return [SubjectContinueTileMoveEvent(
454
-                    subject_id=self.subject.id,
455
-                    move_to=data['tile_move_to'],
456
-                    duration=duration,
457
-                    gui_action=data['gui_action'],
458
-                )]
459
-            else:
460
-                move = self.subject.intentions.get(MoveToIntention)
461
-                move_type_duration = self.subject.get_move_duration(move)
462
-                # FIXME: duration depend next tile type, etc
463
-                # see opencombat.gui.base.Game#start_move_subject
464
-                duration = move_type_duration * 1
465
-                self.subject.moving_to = data['tile_move_to']
466
-                self.subject.move_duration = duration
467
-                self.subject.start_move = time.time()
468
-                events.append(SubjectStartTileMoveEvent(
469
-                    subject_id=self.subject.id,
470
-                    move_to=data['tile_move_to'],
471
-                    duration=duration,
472
-                    gui_action=data['gui_action'],
473
-                ))
474
-
475
-        return events

+ 0 - 79
opencombat/simulation/physics.py View File

@@ -1,79 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from opencombat.simulation.tmx import TileMap
5
-from opencombat.simulation.tmx import TerrainTile
6
-from synergine2_xyz.physics import MoveCostComputer
7
-from synergine2_xyz.physics import TMXPhysics
8
-from synergine2_xyz.subjects import XYZSubject
9
-
10
-if typing.TYPE_CHECKING:
11
-    from opencombat.simulation.base import BaseSubject
12
-    from opencombat.simulation.subject import TileSubject
13
-
14
-
15
-class TileMoveCostComputer(MoveCostComputer):
16
-    def compute_move_cost(
17
-        self,
18
-        subject: 'BaseSubject',
19
-        tile: TerrainTile,
20
-        previous_node: str,
21
-        next_node: str,
22
-        unknown,
23
-    ) -> float:
24
-        # TODO #MoveCost: Write move cost system
25
-
26
-        if not tile.property('traversable_by_man'):
27
-            return 100
28
-
29
-        return 1.0
30
-
31
-
32
-class TilePhysics(TMXPhysics):
33
-    tmx_map_class = TileMap
34
-    move_cost_computer_class = TileMoveCostComputer
35
-    matrixes_configuration = {
36
-        'visibility': [
37
-            'height',
38
-            'opacity',
39
-        ]
40
-    }
41
-
42
-    def get_visibility_obstacle(
43
-        self,
44
-        subject: XYZSubject,
45
-        to_position: typing.Tuple[int, int],
46
-        matrix_name: str,
47
-        opacity_property_name: str='opacity',
48
-    ) -> typing.Union[None, typing.Tuple[int, int]]:
49
-        """
50
-        Return grid position obstacle if any between given subject and given to_position
51
-        :param subject: Subject observer
52
-        :param to_position: position to observe
53
-        :param matrix_name: matrix name to use
54
-        :param opacity_property_name: name of property containing opacity property
55
-        :return: obstacle grid position or None if not
56
-        """
57
-        from_x, from_y = subject.position
58
-        path_positions = self.matrixes.get_path_positions(from_=(from_x, from_y), to=to_position)
59
-        path_opacities = self.matrixes.get_values_for_path(
60
-            matrix_name,
61
-            path_positions=path_positions,
62
-            value_name=opacity_property_name,
63
-        )
64
-
65
-        # TODO #Visibility: Write visibility system
66
-        actual_opacity = 0
67
-        for i, path_opacity in enumerate(path_opacities):
68
-            actual_opacity += path_opacity
69
-            if actual_opacity >= 100:
70
-                return path_positions[i]
71
-
72
-        return None
73
-
74
-    def subject_see_subject(self, observer: 'TileSubject', observed: 'TileSubject') -> bool:
75
-        return not bool(self.get_visibility_obstacle(
76
-            observer,
77
-            observed.position,
78
-            matrix_name='visibility',
79
-        ))

+ 0 - 21
opencombat/simulation/placement.py View File

@@ -1,21 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from synergine2.simulation import SimulationBehaviour
5
-from synergine2.simulation import Event
6
-
7
-
8
-class SetSubjectPositionsSimulationBehaviour(SimulationBehaviour):
9
-    def action(self, data) -> typing.List[Event]:
10
-        for subject_id, new_position in data:
11
-            subject = self.simulation.subjects.index[subject_id]
12
-            subject.position = new_position
13
-
14
-        return []
15
-
16
-    @classmethod
17
-    def merge_data(cls, new_data, start_data=None):
18
-        pass
19
-
20
-    def run(self, data):
21
-        pass

+ 0 - 41
opencombat/simulation/state.py View File

@@ -1,41 +0,0 @@
1
-import os
2
-import time
3
-import typing
4
-
5
-from synergine2.config import Config
6
-from synergine2.simulation import SimulationBehaviour
7
-from synergine2.simulation import Event
8
-from synergine2.simulation import Simulation
9
-
10
-from opencombat.state import StateConstructorBuilder
11
-
12
-
13
-class SaveStateSimulationAction(SimulationBehaviour):
14
-    def __init__(
15
-        self,
16
-        config: Config,
17
-        simulation: Simulation,
18
-    ):
19
-        super().__init__(config, simulation)
20
-        self.state_dumper = StateConstructorBuilder(
21
-            config,
22
-            simulation,
23
-        ).get_state_dumper()
24
-        self.state_save_dir = self.config.resolve('_runtime.state_save_dir')
25
-
26
-    def run(self, data):
27
-        pass
28
-
29
-    def action(self, data) -> typing.List[Event]:
30
-        state_file_path = os.path.join(
31
-            self.state_save_dir,
32
-            'state_{}.xml'.format(time.time())
33
-        )
34
-        with open(state_file_path, 'w+') as file:
35
-            file.write(self.state_dumper.get_state_dump())
36
-
37
-        return []
38
-
39
-    @classmethod
40
-    def merge_data(cls, new_data, start_data=None):
41
-        pass

+ 0 - 125
opencombat/simulation/subject.py View File

@@ -1,125 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from synergine2.simulation import SubjectBehaviourSelector
5
-from synergine2.simulation import SubjectBehaviour
6
-from opencombat.user_action import UserAction
7
-from synergine2_xyz.move.intention import MoveToIntention
8
-
9
-from opencombat.const import COLLECTION_ALIVE
10
-from opencombat.const import COMBAT_MODE_DEFEND
11
-from opencombat.simulation.base import BaseSubject
12
-from opencombat.simulation.move import MoveBehaviour
13
-from opencombat.simulation.move import MoveWithRotationBehaviour
14
-from opencombat.simulation.behaviour import EngageOpponent
15
-from opencombat.simulation.behaviour import LookAroundBehaviour
16
-from synergine2.share import shared
17
-
18
-
19
-class TileBehaviourSelector(SubjectBehaviourSelector):
20
-    def reduce_behaviours(
21
-        self,
22
-        behaviours: typing.Dict[typing.Type[SubjectBehaviour], object],
23
-    ) -> typing.Dict[typing.Type[SubjectBehaviour], object]:
24
-        return behaviours
25
-
26
-
27
-class TileSubject(BaseSubject):
28
-    start_collections = [
29
-        COLLECTION_ALIVE,
30
-    ]
31
-    visible_opponent_ids = shared.create_self('visible_opponent_ids', lambda: [])
32
-    combat_mode = shared.create_self('combat_mode', COMBAT_MODE_DEFEND)
33
-    behaviour_selector_class = TileBehaviourSelector
34
-
35
-    direction = shared.create_self('direction', 0)
36
-    moving_to = shared.create_self('moving_to', (-1, -1))
37
-    move_duration = shared.create_self('move_duration', -1)
38
-    start_move = shared.create_self('start_move', -1)
39
-
40
-    rotate_to = shared.create_self('rotate_to', -1)
41
-    rotate_duration = shared.create_self('rotate_duration', -1)
42
-    start_rotation = shared.create_self('start_rotation', -1)
43
-
44
-    def __init__(self, *args, **kwargs):
45
-        super().__init__(*args, **kwargs)
46
-        self._walk_ref_time = float(self.config.resolve('game.move.walk_ref_time'))
47
-        self._run_ref_time = float(self.config.resolve('game.move.run_ref_time'))
48
-        self._crawl_ref_time = float(self.config.resolve('game.move.crawl_ref_time'))
49
-        self._rotate_ref_time = float(self.config.resolve('game.move.rotate_ref_time'))
50
-        self.direction = kwargs.get('direction', 0)
51
-
52
-    @property
53
-    def global_move_coeff(self) -> float:
54
-        return 1
55
-
56
-    @property
57
-    def run_duration(self) -> float:
58
-        """
59
-        :return: move to tile time (s) when running
60
-        """
61
-        return self._run_ref_time * self.global_move_coeff
62
-
63
-    @property
64
-    def walk_duration(self) -> float:
65
-        """
66
-        :return: move to tile time (s) when walking
67
-        """
68
-        return self._walk_ref_time * self.global_move_coeff
69
-
70
-    @property
71
-    def crawl_duration(self) -> float:
72
-        """
73
-        :return: move to tile time (s) when crawling
74
-        """
75
-        return self._crawl_ref_time * self.global_move_coeff
76
-
77
-    def get_rotate_duration(self, angle: float) -> float:
78
-        return angle * self._rotate_ref_time
79
-
80
-    def get_move_duration(self, move: MoveToIntention) -> float:
81
-        gui_action = move.gui_action
82
-
83
-        if gui_action == UserAction.ORDER_MOVE:
84
-            return self.walk_duration
85
-        if gui_action == UserAction.ORDER_MOVE_FAST:
86
-            return self.run_duration
87
-        if gui_action == UserAction.ORDER_MOVE_CRAWL:
88
-            return self.crawl_duration
89
-
90
-        raise NotImplementedError(
91
-            'Gui action {} unknown'.format(move.gui_action)
92
-        )
93
-
94
-
95
-class ManSubject(TileSubject):
96
-    behaviours_classes = [
97
-        MoveBehaviour,
98
-        LookAroundBehaviour,
99
-        EngageOpponent,
100
-    ]  # type: typing.List[SubjectBehaviour]
101
-
102
-
103
-class TankSubject(TileSubject):
104
-    behaviours_classes = [
105
-        MoveWithRotationBehaviour,
106
-        LookAroundBehaviour,
107
-        EngageOpponent,
108
-    ]  # type: typing.List[SubjectBehaviour]
109
-
110
-    def __init__(self, *args, **kwargs) -> None:
111
-        super().__init__(*args, **kwargs)
112
-        # TODO BS 2018-01-26: This coeff will be dependent of real
113
-        # unit type (tiger 2, etc)
114
-        self._global_move_coeff = self.config.resolve(
115
-            'game.move.subject.tank1.global_move_coeff',
116
-            3,
117
-        )
118
-        self._rotate_ref_time = float(self.config.resolve(
119
-            'game.move.subject.tank1.rotate_ref_time',
120
-            0.1111,
121
-        ))
122
-
123
-    @property
124
-    def global_move_coeff(self) -> float:
125
-        return self._global_move_coeff

+ 0 - 20
opencombat/simulation/tmx.py View File

@@ -1,20 +0,0 @@
1
-# coding: utf-8
2
-import tmx
3
-
4
-from synergine2_xyz.map import TMXMap
5
-from synergine2_xyz.map import XYZTile
6
-
7
-
8
-class TerrainTile(XYZTile):
9
-    pass
10
-
11
-
12
-class TileMap(TMXMap):
13
-    xyz_tile_class = TerrainTile
14
-    default_layer_tilesets = {
15
-        'interiors': 'interiors',
16
-        'terrain': 'terrain',
17
-    }
18
-
19
-    def get_default_tileset(self) -> tmx.Tileset:
20
-        return self.tmx_tilesets['terrain']

+ 0 - 267
opencombat/state.py View File

@@ -1,267 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from _elementtree import Element
5
-from lxml import etree
6
-
7
-from synergine2.config import Config
8
-from synergine2.log import get_logger
9
-
10
-from opencombat.exception import NotFoundError
11
-from opencombat.simulation.base import TileStrategySimulation
12
-from opencombat.simulation.subject import TileSubject
13
-from opencombat.util import get_class_from_string_path
14
-from opencombat.util import pretty_xml
15
-from opencombat.util import get_text_xml_element
16
-from opencombat.xml import XmlValidator
17
-from opencombat.const import SIDE
18
-from opencombat.const import FLAG
19
-from opencombat.const import SELECTION_COLOR_RGB
20
-
21
-
22
-class State(object):
23
-    def __init__(
24
-        self,
25
-        config: Config,
26
-        state_root: Element,
27
-        simulation: TileStrategySimulation,
28
-    ) -> None:
29
-        self._config = config
30
-        self._state_root = state_root
31
-        self._subjects = None  # type: typing.List[TileSubject]
32
-        self._simulation = simulation
33
-
34
-    @property
35
-    def subjects(self) -> typing.List[TileSubject]:
36
-        if self._subjects is None:
37
-            self._subjects = self._get_subjects()
38
-
39
-        return self._subjects
40
-
41
-    def _get_subjects(self) -> typing.List[TileSubject]:
42
-        subjects = []
43
-        subject_elements = self._state_root.find('subjects').findall('subject')
44
-
45
-        for subject_element in subject_elements:
46
-            subject_class_path = subject_element.find('type').text
47
-            subject_class = get_class_from_string_path(
48
-                self._config,
49
-                subject_class_path,
50
-            )
51
-            subject = subject_class(self._config, self._simulation)
52
-            self._fill_subject(subject, subject_element)
53
-            subjects.append(subject)
54
-
55
-        return subjects
56
-
57
-    def _fill_subject(
58
-        self,
59
-        subject: TileSubject,
60
-        subject_element: Element,
61
-    ) -> None:
62
-        subject_properties = {}
63
-
64
-        subject.position = tuple(
65
-            map(
66
-                int,
67
-                get_text_xml_element(subject_element, 'position').split(','),
68
-            ),
69
-        )
70
-        subject.direction = float(
71
-            get_text_xml_element(subject_element, 'direction'),
72
-        )
73
-        # TODO BS 2018-06-20: Maybe need apply this mode no ?
74
-        subject.combat_mode = \
75
-            get_text_xml_element(subject_element, 'combat_mode')
76
-
77
-        properties_element = subject_element.find('properties')
78
-        decode_properties_map = self._get_decode_properties_map()
79
-
80
-        for item_element in properties_element.findall('item'):
81
-            key_text = item_element.find('key').text
82
-            value_text = item_element.find('value').text
83
-
84
-            try:
85
-                decoded_value = decode_properties_map[key_text](value_text)
86
-            except KeyError:
87
-                raise NotFoundError(
88
-                    'You try to load property "{}" but it is unknown'.format(
89
-                        key_text,
90
-                    )
91
-                )
92
-
93
-            subject_properties[key_text] = decoded_value
94
-
95
-        subject.properties = subject_properties
96
-
97
-    def _get_decode_properties_map(self) -> typing.Dict[str, typing.Callable[[str], typing.Any]]:  # nopep8
98
-        return {
99
-            SELECTION_COLOR_RGB: lambda v: tuple(map(int, v.split(','))),
100
-            FLAG: str,
101
-            SIDE: str,
102
-        }
103
-
104
-
105
-class StateDumper(object):
106
-    def __init__(
107
-        self,
108
-        config: Config,
109
-        simulation: TileStrategySimulation,
110
-    ) -> None:
111
-        self._logger = get_logger('StateDumper', config)
112
-        self._config = config
113
-        self._simulation = simulation
114
-
115
-        state_template = self._config.resolve(
116
-           'global.state_template',
117
-           'opencombat/state_template.xml',
118
-        )
119
-        with open(state_template, 'r') as xml_file:
120
-            template_str = xml_file.read()
121
-
122
-        parser = etree.XMLParser(remove_blank_text=True)
123
-        self._state_root = etree.fromstring(
124
-            template_str.encode('utf-8'),
125
-            parser,
126
-        )
127
-        self._state_root_filled = False
128
-
129
-    def get_state_dump(self) -> str:
130
-        if not self._state_root_filled:
131
-            self._fill_state_root()
132
-
133
-        return pretty_xml(
134
-            etree.tostring(
135
-                self._state_root,
136
-            ).decode('utf-8'),
137
-        )
138
-
139
-    def _fill_state_root(self) -> None:
140
-        subjects_element = self._state_root.find('subjects')
141
-        map_element = self._state_root.find('map')
142
-
143
-        map_name_element = etree.SubElement(map_element, 'name')
144
-        map_name_element.text = self._config.resolve('_runtime.map_dir_path')
145
-
146
-        for subject in self._simulation.subjects:
147
-            subject_element = etree.SubElement(subjects_element, 'subject')
148
-
149
-            position_element = etree.SubElement(subject_element, 'type')
150
-            position_element.text = '.'.join([
151
-                subject.__module__,
152
-                subject.__class__.__name__,
153
-            ])
154
-
155
-            position_element = etree.SubElement(subject_element, 'position')
156
-            position_element.text = ','.join(map(str, subject.position))
157
-
158
-            direction_element = etree.SubElement(subject_element, 'direction')
159
-            direction_element.text = str(subject.direction)
160
-
161
-            combat_mode_element = etree.SubElement(
162
-                subject_element,
163
-                'combat_mode',
164
-            )
165
-            combat_mode_element.text = str(subject.combat_mode)
166
-
167
-            properties_element = etree.SubElement(
168
-                subject_element,
169
-                'properties',
170
-            )
171
-            encode_properties_map = self._get_encode_properties_map()
172
-
173
-            for key, value in subject.properties.items():
174
-                item_element = etree.SubElement(properties_element, 'item')
175
-                key_element = etree.SubElement(item_element, 'key')
176
-                value_element = etree.SubElement(item_element, 'value')
177
-
178
-                key_element.text = str(key)
179
-                value_element.text = encode_properties_map[key](value)
180
-
181
-        self._state_root_filled = True
182
-
183
-    def _get_encode_properties_map(self) -> typing.Dict[str, typing.Callable[[typing.Any], str]]:  # nopep8:
184
-        return {
185
-            SELECTION_COLOR_RGB: lambda v: ','.join(map(str, v)),
186
-            FLAG: str,
187
-            SIDE: str,
188
-        }
189
-
190
-
191
-class StateLoader(object):
192
-    def __init__(
193
-        self,
194
-        config: Config,
195
-        simulation: TileStrategySimulation,
196
-    ) -> None:
197
-        self._logger = get_logger('StateLoader', config)
198
-        self._config = config
199
-        self._simulation = simulation
200
-
201
-        schema_file_path = self._config.get(
202
-            'global.state_schema',
203
-            'opencombat/state.xsd',
204
-        )
205
-        self._xml_validator = XmlValidator(
206
-            config,
207
-            schema_file_path,
208
-        )
209
-
210
-    def get_state(
211
-        self,
212
-        state_file_path: str,
213
-    ) -> State:
214
-        return State(
215
-            self._config,
216
-            self._validate_and_return_state_element(state_file_path),
217
-            self._simulation,
218
-        )
219
-
220
-    def _validate_and_return_state_element(
221
-        self,
222
-        state_file_path: str,
223
-    ) -> Element:
224
-        return self._xml_validator.validate_and_return(state_file_path)
225
-
226
-
227
-class StateConstructorBuilder(object):
228
-    def __init__(
229
-        self,
230
-        config: Config,
231
-        simulation: TileStrategySimulation,
232
-    ) -> None:
233
-        self._logger = get_logger('StateConstructorBuilder', config)
234
-        self._config = config
235
-        self._simulation = simulation
236
-
237
-    def get_state_loader(
238
-        self,
239
-    ) -> StateLoader:
240
-        class_address = self._config.resolve(
241
-            'global.state_loader',
242
-            'opencombat.state.StateLoader',
243
-        )
244
-        state_loader_class = get_class_from_string_path(
245
-            self._config,
246
-            class_address,
247
-        )
248
-        return state_loader_class(
249
-            self._config,
250
-            self._simulation,
251
-        )
252
-
253
-    def get_state_dumper(
254
-        self,
255
-    ) -> StateDumper:
256
-        class_address = self._config.resolve(
257
-            'global.state_dumper',
258
-            'opencombat.state.StateDumper',
259
-        )
260
-        state_loader_class = get_class_from_string_path(
261
-            self._config,
262
-            class_address,
263
-        )
264
-        return state_loader_class(
265
-            self._config,
266
-            self._simulation,
267
-        )

+ 0 - 73
opencombat/state.xsd View File

@@ -1,73 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8" ?>
2
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3
-
4
-    <xs:element name="state" type="statetype"/>
5
-
6
-    <xs:simpleType name="statetypetype" final="restriction">
7
-        <xs:restriction base="xs:string">
8
-            <xs:enumeration value="before_battle"/>
9
-            <xs:enumeration value="during_battle"/>
10
-        </xs:restriction>
11
-    </xs:simpleType>
12
-
13
-    <xs:complexType name="propertiestype">
14
-        <xs:sequence>
15
-            <xs:element maxOccurs="unbounded" name="item">
16
-                <xs:complexType>
17
-                    <xs:sequence>
18
-                        <xs:element name="key" type="xs:string"  />
19
-                        <xs:element name="value" type="xs:string" />
20
-                    </xs:sequence>
21
-                </xs:complexType>
22
-            </xs:element>
23
-        </xs:sequence>
24
-    </xs:complexType>
25
-
26
-    <xs:simpleType name="combatmodetype" final="restriction">
27
-        <xs:restriction base="xs:string">
28
-            <xs:enumeration value="COMBAT_MODE_DEFEND"/>
29
-            <xs:enumeration value="COMBAT_MODE_HIDE"/>
30
-        </xs:restriction>
31
-    </xs:simpleType>
32
-
33
-    <xs:simpleType name="positiontype">
34
-        <xs:restriction base="xs:string">
35
-            <xs:pattern value="[0-9]+,[0-9]+"/>
36
-        </xs:restriction>
37
-    </xs:simpleType>
38
-
39
-    <xs:simpleType name="directiontype">
40
-        <xs:restriction base="xs:float"/>
41
-    </xs:simpleType>
42
-
43
-    <xs:complexType name="statetype">
44
-        <xs:sequence>
45
-            <xs:element name="map" type="maptype" maxOccurs="1"/>
46
-            <xs:element name="subjects" type="subjectstype"/>
47
-        </xs:sequence>
48
-        <xs:attribute name="type" type="statetypetype" use="required"/>
49
-    </xs:complexType>
50
-
51
-    <xs:complexType name="subjectstype">
52
-        <xs:sequence>
53
-            <xs:element name="subject" type="subjecttype" maxOccurs="unbounded"/>
54
-        </xs:sequence>
55
-    </xs:complexType>
56
-
57
-    <xs:complexType name="subjecttype">
58
-        <xs:sequence>
59
-            <xs:element name="type" type="xs:string" minOccurs="1" />
60
-            <xs:element name="position" type="positiontype" minOccurs="1"/>
61
-            <xs:element name="direction" type="directiontype" minOccurs="1"/>
62
-            <xs:element name="combat_mode" type="combatmodetype" minOccurs="1"/>
63
-            <xs:element name="properties" type="propertiestype" minOccurs="1"/>
64
-        </xs:sequence>
65
-    </xs:complexType>
66
-
67
-    <xs:complexType name="maptype">
68
-        <xs:sequence>
69
-            <xs:element name="name" type="xs:string"/>
70
-        </xs:sequence>
71
-    </xs:complexType>
72
-
73
-</xs:schema>

+ 0 - 7
opencombat/state_template.xml View File

@@ -1,7 +0,0 @@
1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<state type="before_battle">
3
-    <map>
4
-    </map>
5
-    <subjects>
6
-    </subjects>
7
-</state>

+ 0 - 1
opencombat/strategy/__init__.py View File

@@ -1 +0,0 @@
1
-# coding: utf-8

+ 0 - 45
opencombat/strategy/manager.py View File

@@ -1,45 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from synergine2.config import Config
5
-from synergine2.log import get_logger
6
-
7
-from opencombat.strategy.team.model import TeamModel
8
-from opencombat.strategy.team.stash import TeamStash
9
-from opencombat.strategy.troops import TroopClassBuilder
10
-from opencombat.strategy.unit.stash import UnitStash
11
-
12
-
13
-class TroopManager(object):
14
-    def __init__(
15
-        self,
16
-        config: Config,
17
-        units_file_path: str,
18
-        teams_file_path: str,
19
-    ) -> None:
20
-        self._config = config
21
-        self._logger = get_logger('TroopManager', config)
22
-
23
-        self._builder = TroopClassBuilder(config)
24
-        self._unit_stash = self._builder.get_unit_stash(
25
-            units_file_path,
26
-        )
27
-        self._team_stash = self._builder.get_team_stash(
28
-            units_file_path,
29
-            teams_file_path,
30
-        )
31
-
32
-    @property
33
-    def team_stash(self) -> TeamStash:
34
-        return self._team_stash
35
-
36
-    @property
37
-    def unit_stash(self) -> UnitStash:
38
-        return self._unit_stash
39
-
40
-    def get_troop_dump(
41
-        self,
42
-        countries_troops: typing.Dict[str, typing.List[TeamModel]],
43
-    ):
44
-        dumper = self._builder.get_troop_dumper()
45
-        return dumper.get_troop_dump(countries_troops)

+ 0 - 1
opencombat/strategy/selection/__init__.py View File

@@ -1 +0,0 @@
1
-# coding: utf-8

+ 0 - 0
opencombat/strategy/selection/gui.py View File


Some files were not shown because too many files changed in this diff