Browse Source

purge framework of sandboxes and package it

Bastien Sevajol 6 years ago
parent
commit
25ec43a46b
78 changed files with 77 additions and 1559 deletions
  1. 0 3
      DATA_100
  2. 0 3
      DATA_2000
  3. 25 1
      README.md
  4. 0 1
      cocos
  5. 0 152
      perf.py
  6. 4 11
      requirements.txt
  7. 0 0
      sandbox/__init__.py
  8. 0 0
      sandbox/perf/__init__.py
  9. 0 53
      sandbox/perf/run.py
  10. 0 65
      sandbox/perf/simulation.py
  11. 0 28
      sandbox/print_terminal.py
  12. 0 1
      sandbox/tile/__init__.py
  13. 0 16
      sandbox/tile/config.yaml
  14. 0 14
      sandbox/tile/const.py
  15. 0 1
      sandbox/tile/gui/__init__.py
  16. 0 42
      sandbox/tile/gui/actor.py
  17. 0 239
      sandbox/tile/gui/base.py
  18. 0 89
      sandbox/tile/gui/fire.py
  19. 0 48
      sandbox/tile/gui/move.py
  20. 0 140
      sandbox/tile/maps/003/003.tmx
  21. BIN
      sandbox/tile/maps/003/actors/man.png
  22. BIN
      sandbox/tile/maps/003/actors/man_c1.png
  23. BIN
      sandbox/tile/maps/003/actors/man_c2.png
  24. BIN
      sandbox/tile/maps/003/actors/man_c3.png
  25. BIN
      sandbox/tile/maps/003/actors/man_c4.png
  26. BIN
      sandbox/tile/maps/003/actors/man_d1.png
  27. BIN
      sandbox/tile/maps/003/actors/man_w1.png
  28. BIN
      sandbox/tile/maps/003/actors/man_w10.png
  29. BIN
      sandbox/tile/maps/003/actors/man_w2.png
  30. BIN
      sandbox/tile/maps/003/actors/man_w3.png
  31. BIN
      sandbox/tile/maps/003/actors/man_w4.png
  32. BIN
      sandbox/tile/maps/003/actors/man_w5.png
  33. BIN
      sandbox/tile/maps/003/actors/man_w6.png
  34. BIN
      sandbox/tile/maps/003/actors/man_w7.png
  35. BIN
      sandbox/tile/maps/003/actors/man_w8.png
  36. BIN
      sandbox/tile/maps/003/actors/man_w9.png
  37. BIN
      sandbox/tile/maps/003/background.png
  38. BIN
      sandbox/tile/maps/003/terrain.png
  39. 0 22
      sandbox/tile/maps/003/terrain.tsx
  40. BIN
      sandbox/tile/maps/003/trees_64x64.png
  41. 0 4
      sandbox/tile/maps/003/trees_64x64.tsx
  42. 0 23
      sandbox/tile/maps/004/004.tmx
  43. BIN
      sandbox/tile/maps/004/actors/man.png
  44. BIN
      sandbox/tile/maps/004/actors/man_c1.png
  45. BIN
      sandbox/tile/maps/004/actors/man_c2.png
  46. BIN
      sandbox/tile/maps/004/actors/man_c3.png
  47. BIN
      sandbox/tile/maps/004/actors/man_c4.png
  48. BIN
      sandbox/tile/maps/004/actors/man_w1.png
  49. BIN
      sandbox/tile/maps/004/actors/man_w10.png
  50. BIN
      sandbox/tile/maps/004/actors/man_w2.png
  51. BIN
      sandbox/tile/maps/004/actors/man_w3.png
  52. BIN
      sandbox/tile/maps/004/actors/man_w4.png
  53. BIN
      sandbox/tile/maps/004/actors/man_w5.png
  54. BIN
      sandbox/tile/maps/004/actors/man_w6.png
  55. BIN
      sandbox/tile/maps/004/actors/man_w7.png
  56. BIN
      sandbox/tile/maps/004/actors/man_w8.png
  57. BIN
      sandbox/tile/maps/004/actors/man_w9.png
  58. BIN
      sandbox/tile/maps/004/background.png
  59. BIN
      sandbox/tile/maps/004/terrain.png
  60. 0 18
      sandbox/tile/maps/004/terrain.tsx
  61. BIN
      sandbox/tile/maps/004/trees_64x64.png
  62. 0 4
      sandbox/tile/maps/004/trees_64x64.tsx
  63. 0 100
      sandbox/tile/run.py
  64. 0 1
      sandbox/tile/simulation/__init__.py
  65. 0 42
      sandbox/tile/simulation/base.py
  66. 0 154
      sandbox/tile/simulation/behaviour.py
  67. 0 47
      sandbox/tile/simulation/event.py
  68. 0 39
      sandbox/tile/simulation/fire.py
  69. 0 16
      sandbox/tile/simulation/mechanism.py
  70. 0 80
      sandbox/tile/simulation/physics.py
  71. 0 22
      sandbox/tile/simulation/subject.py
  72. 0 16
      sandbox/tile/simulation/tmx.py
  73. BIN
      sandbox/tile/sounds/204010__duckduckpony__homemade-gunshot-2.ogg
  74. 0 1
      sandbox/tile/terminal/__init__.py
  75. 0 53
      sandbox/tile/terminal/base.py
  76. 0 9
      sandbox/tile/user_action.py
  77. 47 0
      setup.py
  78. 1 1
      synergine2_cocos2d/util.py

+ 0 - 3
DATA_100 View File

@@ -1,3 +0,0 @@
1
-# (COMPLEXITY 100) SUBJECTS CORES_1 CORES_2
2
-500 0.24411559104919434 0.9702152252197266
3
-100 0.04988713264465332 0.1922530174255371

+ 0 - 3
DATA_2000 View File

@@ -1,3 +0,0 @@
1
-# (COMPLEXITY 2000) SUBJECTS CORES_1 CORES_2
2
-500 0.9194584846496582 1.1027130842208863
3
-100 0.1884233236312866 0.21506776809692382

+ 25 - 1
README.md View File

@@ -2,4 +2,28 @@
2 2
 
3 3
 [![Build Status](https://travis-ci.org/buxx/synergine2.svg?branch=master)](https://travis-ci.org/buxx/synergine2) [![Coverage Status](https://coveralls.io/repos/github/buxx/synergine2/badge.svg?branch=master)](https://coveralls.io/github/buxx/synergine2?branch=master)
4 4
 
5
-Rethinked synergine framework
5
+A framework to build simulation with subject focused.
6
+
7
+# Install
8
+
9
+Synergine is in Alpha development status. To install the lib:
10
+
11
+    python setup.py develop
12
+
13
+To install xyz tools packages:
14
+
15
+    pip install -e ".[xyz]"
16
+
17
+To install cocos2d tools packages:
18
+
19
+    pip install -e ".[cocos2d]"
20
+
21
+# Automated testing
22
+
23
+To install tests packages:
24
+
25
+    pip install -e ".[tests]"
26
+
27
+And run tests:
28
+
29
+    pytest tests

+ 0 - 1
cocos View File

@@ -1 +0,0 @@
1
-../cocos/cocos

+ 0 - 152
perf.py View File

@@ -1,152 +0,0 @@
1
-
2
-
3
-"""
4
-Produce performance measurement
5
-"""
6
-import argparse
7
-import multiprocessing
8
-import os
9
-
10
-import time
11
-from collections import OrderedDict
12
-from random import randint
13
-
14
-from sandbox.perf.simulation import ComputeSubject, ComputeBehaviour, ComputeMechanism
15
-from synergine2.config import Config
16
-from synergine2.cycle import CycleManager
17
-from synergine2.log import SynergineLogger
18
-from synergine2.simulation import Simulation, Subjects
19
-
20
-
21
-def simulate(complexity, subject_count, cycle_count, cores):
22
-    config = Config(dict(complexity=complexity, core=dict(use_x_cores=cores)))
23
-    simulation = Simulation(config)
24
-    subjects = Subjects(simulation=simulation)
25
-
26
-    for i in range(subject_count):
27
-        subject = ComputeSubject(
28
-            config=config,
29
-            simulation=simulation,
30
-        )
31
-        subject.data = [randint(0, 1000) for i in range(1000)]
32
-        subjects.append(subject)
33
-
34
-    simulation.subjects = subjects
35
-
36
-    cycle_manager = CycleManager(
37
-        config,
38
-        SynergineLogger('perf'),
39
-        simulation=simulation,
40
-    )
41
-
42
-    for j in range(cycle_count):
43
-        cycle_manager.next()
44
-
45
-
46
-def main():
47
-    parser = argparse.ArgumentParser(description='Perf measures')
48
-    parser.add_argument(
49
-        '--max_cores',
50
-        type=int,
51
-        default=0,
52
-        help='number of used cores',
53
-    )
54
-
55
-    args = parser.parse_args()
56
-
57
-    host_cores = multiprocessing.cpu_count()
58
-    retry = 1
59
-    cycles = 10
60
-    subject_counts = [500]
61
-    complexities = [200]
62
-    max_cores = args.max_cores or host_cores
63
-
64
-    results = []
65
-    datas = OrderedDict()
66
-
67
-    for core_i in range(max_cores):
68
-        # if core_i == 0:
69
-        #     continue
70
-        core_count = core_i + 1
71
-        for subject_count in subject_counts:
72
-            for complexity in complexities:
73
-                print('COMPLEXITY: {}, SUBJECTS: {}, CORES: {}'.format(
74
-                    complexity,
75
-                    subject_count,
76
-                    core_count,
77
-                ), end='')
78
-
79
-                durations = []
80
-                for try_i in range(retry):
81
-                    start_time = time.time()
82
-                    simulate(complexity, subject_count, cycles, core_count)
83
-                    durations.append(time.time() - start_time)
84
-                duration = min(durations)
85
-
86
-                result = {
87
-                    'cores': core_count,
88
-                    'complexity': complexity,
89
-                    'subject_count': subject_count,
90
-                    'cycles': cycles,
91
-                    'duration': duration,
92
-                    'duration_cycle': duration / cycles,
93
-                    'duration_subj_complex': (duration / cycles) / (subject_count * complexity),
94
-                }
95
-                results.append(result)
96
-
97
-                print(': {}s, {}s/c, {}s/C'.format(
98
-                    result['duration'],
99
-                    result['duration_cycle'],
100
-                    result['duration_subj_complex'],
101
-                ))
102
-                datas.setdefault(complexity, {}).setdefault(subject_count, {})[core_count] = result['duration_cycle']
103
-
104
-    for d_complexity, c_values in sorted(datas.items(), key=lambda e: int(e[0])):
105
-        data_file_name = 'DATA_{}'.format(str(d_complexity))
106
-        try:
107
-            os.unlink(data_file_name)
108
-        except FileNotFoundError:
109
-            pass
110
-        with open(data_file_name, 'w+') as file:
111
-            file.writelines(['# (COMPLEXITY {}) SUBJECTS CORES_{}\n'.format(
112
-                str(d_complexity),
113
-                ' CORES_'.join(map(str, range(1, max_cores+1))),
114
-            )])
115
-            for d_subject_count, d_cores in c_values.items():
116
-                line = '{} {}\n'.format(
117
-                    str(d_subject_count),
118
-                    ' '.join(map(str, d_cores.values())),
119
-                )
120
-                file.writelines([line])
121
-
122
-        """
123
-        subj_core = []
124
-            for subj, core_v in c_values.items():
125
-                for core_nb in core_v.keys():
126
-                    subj_core.append((subj, core_nb))
127
-            file.writelines(['# (COMPLEXITY {}) SUBJECTS CORES_{}\n'.format(
128
-                str(d_complexity),
129
-                ' '.join([
130
-                    'SUBJ_{}_COR_{}'.format(
131
-                        subj, core_nb,
132
-                    ) for subj, core_nb in subj_core
133
-                ])
134
-            )])
135
-        """
136
-
137
-    for d_complexity, c_values in datas.items():
138
-        print('')
139
-        print('gnuplot -p -e "set title \\"COMPLEXITY_{}\\"; plot {}"'.format(
140
-            str(d_complexity),
141
-            ','.join([
142
-                ' \'DATA_{}\' using 1:{} title \'CORE_{}\' with lines'.format(
143
-                    d_complexity,
144
-                    d_core+1,
145
-                    d_core,
146
-                ) for d_core in range(1, max_cores+1)
147
-            ])
148
-        ))
149
-
150
-
151
-if __name__ == '__main__':
152
-    main()

+ 4 - 11
requirements.txt View File

@@ -1,23 +1,16 @@
1
-apipkg==1.4
2
-appdirs==1.4.3
1
+attrs==17.3.0
3 2
 cocos2d==0.6.5
4
-coverage==4.4.2
5 3
 Dijkstar==2.3.0
6
-execnet==1.5.0
7 4
 freezegun==0.3.9
8
-packaging==16.8
5
+future==0.16.0
9 6
 numpy==1.13.3
7
+pluggy==0.6.0
10 8
 psutil==5.4.1
11 9
 py==1.5.2
12 10
 pyglet==1.3.0
13
-pyparsing==2.2.0
14
-pytest==3.2.5
15
-pytest-cov==2.5.1
16
-pytest-timeout==1.2.0
17
-pytest-xdist==1.20.1
11
+pytest==3.3.0
18 12
 python-dateutil==2.6.1
19 13
 PyYAML==3.12
20 14
 redis==2.10.6
21 15
 six==1.11.0
22 16
 tmx==1.9.1
23
-typing==3.6.2

+ 0 - 0
sandbox/__init__.py View File


+ 0 - 0
sandbox/perf/__init__.py View File


+ 0 - 53
sandbox/perf/run.py View File

@@ -1,53 +0,0 @@
1
-from random import seed
2
-import logging
3
-import os
4
-import sys
5
-
6
-synergine2_ath = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../'))
7
-sys.path.append(synergine2_ath)
8
-
9
-
10
-from sandbox.perf.simulation import ComputeSubject
11
-from synergine2.config import Config
12
-from synergine2.core import Core
13
-from synergine2.cycle import CycleManager
14
-from synergine2.log import get_default_logger
15
-from synergine2.simulation import Simulation, Subjects
16
-from synergine2.terminals import TerminalManager
17
-
18
-
19
-def main():
20
-    seed(42)
21
-
22
-    config = Config(dict(complexity=10000))
23
-    logger = get_default_logger(level=logging.ERROR)
24
-
25
-    simulation = Simulation(config)
26
-    subjects = Subjects(simulation=simulation)
27
-    subjects.extend([ComputeSubject(
28
-        config=config,
29
-        simulation=simulation,
30
-    ) for i in range(500)])
31
-    simulation.subjects = subjects
32
-
33
-    core = Core(
34
-        config=config,
35
-        logger=logger,
36
-        simulation=simulation,
37
-        cycle_manager=CycleManager(
38
-            config=config,
39
-            logger=logger,
40
-            simulation=simulation,
41
-        ),
42
-        terminal_manager=TerminalManager(
43
-            config=config,
44
-            logger=logger,
45
-            terminals=[]
46
-        ),
47
-        cycles_per_seconds=1000000,
48
-    )
49
-    core.run()
50
-
51
-
52
-if __name__ == '__main__':
53
-    main()

+ 0 - 65
sandbox/perf/simulation.py View File

@@ -1,65 +0,0 @@
1
-import random
2
-
3
-from synergine2.config import Config
4
-from synergine2.share import shared
5
-from synergine2.simulation import SubjectMechanism, SubjectBehaviour, Event, Subject
6
-
7
-
8
-def compute(complexity: int):
9
-    random_floats = []
10
-    result = 0.0
11
-
12
-    for i in range(complexity):
13
-        random_floats.append(random.uniform(0, 100))
14
-
15
-    for j, random_float in enumerate(random_floats):
16
-        if not j % 2:
17
-            result += random_float
18
-        else:
19
-            result -= random_float
20
-
21
-    return result
22
-
23
-
24
-class ComputeMechanism(SubjectMechanism):
25
-    def run(self):
26
-        complexity = self.config.get('complexity')
27
-        value = compute(complexity)
28
-
29
-        return {
30
-            'mechanism_value': value,
31
-            'complexity': complexity,
32
-        }
33
-
34
-
35
-class ComplexityEvent(Event):
36
-    def __init__(self, complexity, *args, **kwargs):
37
-        self.complexity = complexity
38
-
39
-
40
-class ComputeBehaviour(SubjectBehaviour):
41
-    use = [ComputeMechanism]
42
-
43
-    def run(self, data):
44
-        return not data.get('ComputeMechanism').get('mechanism_value') % 2
45
-
46
-    def action(self, data):
47
-        mechanism_value = data.get('ComputeMechanism').get('mechanism_value')
48
-        complexity = data.get('ComputeMechanism').get('complexity')
49
-
50
-        if not int(str(mechanism_value)[-1]) % 2:
51
-            compute(complexity)
52
-
53
-        return [Event(complexity)]
54
-
55
-
56
-class ComputeSubject(Subject):
57
-    behaviours_classes = [ComputeBehaviour]
58
-    data = shared.create_self('data', lambda: [])
59
-
60
-    def __init__(
61
-        self,
62
-        config: Config,
63
-        simulation: 'Simulation',
64
-    ):
65
-        super().__init__(config, simulation)

+ 0 - 28
sandbox/print_terminal.py View File

@@ -1,28 +0,0 @@
1
-# coding: utf-8
2
-import time
3
-import sys
4
-
5
-sys.path.append('../')
6
-
7
-from synergine2.terminals import Terminal, TerminalPackage, TerminalManager
8
-
9
-
10
-class PrintTerminal(Terminal):
11
-    def receive(self, package: TerminalPackage):
12
-        print(package.value)
13
-        sys.stdout.flush()
14
-
15
-    def run(self):
16
-        while self.read():
17
-            print('Hello world')
18
-            sys.stdout.flush()
19
-            time.sleep(1)
20
-
21
-
22
-terminals_manager = TerminalManager(terminals=[PrintTerminal()])
23
-terminals_manager.start()
24
-for i in range(3):
25
-    time.sleep(2)
26
-    terminals_manager.send(TerminalPackage('Just print me'))
27
-
28
-terminals_manager.stop()

+ 0 - 1
sandbox/tile/__init__.py View File

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

+ 0 - 16
sandbox/tile/config.yaml View File

@@ -1,16 +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
-global:
16
-    debug: true

+ 0 - 14
sandbox/tile/const.py View File

@@ -1,14 +0,0 @@
1
-# coding: utf-8
2
-
3
-COLLECTION_ALIVE = 'ALIVE'
4
-
5
-FLAG = 'FLAG'
6
-FLAG_DE = 'DE'
7
-FLAG_URSS = 'URSS'
8
-
9
-SIDE = 'SIDE'
10
-COMBAT_MODE = 'COMBAT_MODE'
11
-COMBAT_MODE_DEFENSE = 'COMBAT_MODE_DEFENSE'
12
-
13
-DE_COLOR = (0, 81, 211)
14
-URSS_COLOR = (204, 0, 0)

+ 0 - 1
sandbox/tile/gui/__init__.py View File

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

+ 0 - 42
sandbox/tile/gui/actor.py View File

@@ -1,42 +0,0 @@
1
-# coding: utf-8
2
-import pyglet
3
-
4
-from synergine2.simulation import Subject
5
-from synergine2_cocos2d.actor import Actor
6
-from synergine2_cocos2d.animation import ANIMATION_WALK
7
-from synergine2_cocos2d.animation import ANIMATION_CRAWL
8
-
9
-
10
-FLAG_DE = 'DE'
11
-FLAG_URSS = 'URSS'
12
-
13
-FLAG_COLORS = {
14
-    FLAG_DE
15
-}
16
-
17
-
18
-class Man(Actor):
19
-    animation_image_paths = {
20
-        ANIMATION_WALK: [
21
-            'actors/man.png',
22
-            'actors/man_w1.png',
23
-            'actors/man_w2.png',
24
-            'actors/man_w3.png',
25
-            'actors/man_w4.png',
26
-            'actors/man_w5.png',
27
-            'actors/man_w6.png',
28
-            'actors/man_w7.png',
29
-        ],
30
-        ANIMATION_CRAWL: [
31
-            'actors/man_c1.png',
32
-            'actors/man_c2.png',
33
-            'actors/man_c3.png',
34
-            'actors/man_c4.png',
35
-        ]
36
-    }
37
-
38
-    def __init__(
39
-        self,
40
-        subject: Subject,
41
-    ) -> None:
42
-        super().__init__(pyglet.resource.image('actors/man.png'), subject=subject)

+ 0 - 239
sandbox/tile/gui/base.py View File

@@ -1,239 +0,0 @@
1
-# coding: utf-8
2
-import os
3
-import random
4
-import typing
5
-
6
-import pyglet
7
-from pyglet.window import key
8
-
9
-from cocos.actions import MoveTo as BaseMoveTo
10
-from cocos.audio.pygame.mixer import Sound
11
-from sandbox.tile.user_action import UserAction
12
-from synergine2.config import Config
13
-from synergine2.log import SynergineLogger
14
-from synergine2.terminals import Terminal
15
-from synergine2_cocos2d.actions import MoveTo
16
-from synergine2_cocos2d.animation import ANIMATION_CRAWL
17
-from synergine2_cocos2d.animation import ANIMATION_WALK
18
-from synergine2_cocos2d.animation import Animate
19
-from synergine2_cocos2d.gl import draw_line
20
-from synergine2_cocos2d.gui import EditLayer as BaseEditLayer
21
-from synergine2_cocos2d.gui import TMXGui
22
-from synergine2_cocos2d.layer import LayerManager
23
-from synergine2_xyz.move.simulation import FinishMoveEvent
24
-from synergine2_xyz.move.simulation import StartMoveEvent
25
-from synergine2_xyz.physics import Physics
26
-from synergine2_xyz.utils import get_angle
27
-from sandbox.tile.simulation.event import NewVisibleOpponent
28
-from sandbox.tile.simulation.event import NoLongerVisibleOpponent
29
-from sandbox.tile.simulation.event import FireEvent
30
-from sandbox.tile.simulation.event import DieEvent
31
-
32
-
33
-class EditLayer(BaseEditLayer):
34
-    def __init__(self, *args, **kwargs) -> None:
35
-        super().__init__(*args, **kwargs)
36
-
37
-    def _on_key_press(self, k, m):
38
-        if self.selection:
39
-            if k == key.M:
40
-                self.user_action_pending = UserAction.ORDER_MOVE
41
-            if k == key.R:
42
-                self.user_action_pending = UserAction.ORDER_MOVE_FAST
43
-            if k == key.C:
44
-                self.user_action_pending = UserAction.ORDER_MOVE_CRAWL
45
-            if k == key.F:
46
-                self.user_action_pending = UserAction.ORDER_FIRE
47
-
48
-
49
-class TileLayerManager(LayerManager):
50
-    edit_layer_class = EditLayer
51
-
52
-
53
-# TODO: Move into synergine2cocos2d
54
-class AudioLibrary(object):
55
-    sound_file_paths = {
56
-        'gunshot_default': '204010__duckduckpony__homemade-gunshot-2.ogg',
57
-    }
58
-
59
-    def __init__(self, sound_dir_path: str) -> None:
60
-        self._sound_dir_path = sound_dir_path
61
-        self._sounds = {}
62
-
63
-    def get_sound(self, name: str) -> Sound:
64
-        if name not in self._sounds:
65
-            sound_file_name = self.sound_file_paths[name]
66
-            self._sounds[name] = Sound(os.path.join(self._sound_dir_path, sound_file_name))
67
-        return self._sounds[name]
68
-
69
-
70
-class Game(TMXGui):
71
-    layer_manager_class = TileLayerManager
72
-
73
-    def __init__(
74
-        self,
75
-        config: Config,
76
-        logger: SynergineLogger,
77
-        terminal: Terminal,
78
-        physics: Physics,
79
-        read_queue_interval: float = 1 / 60.0,
80
-        map_dir_path: str=None,
81
-    ):
82
-        super().__init__(
83
-            config,
84
-            logger,
85
-            terminal,
86
-            physics=physics,
87
-            read_queue_interval=read_queue_interval,
88
-            map_dir_path=map_dir_path,
89
-        )
90
-        self.sound_lib = AudioLibrary('sandbox/tile/sounds/')
91
-
92
-        self.terminal.register_event_handler(
93
-            FinishMoveEvent,
94
-            self.set_subject_position,
95
-        )
96
-
97
-        self.terminal.register_event_handler(
98
-            StartMoveEvent,
99
-            self.start_move_subject,
100
-        )
101
-
102
-        self.terminal.register_event_handler(
103
-            NewVisibleOpponent,
104
-            self.new_visible_opponent,
105
-        )
106
-
107
-        self.terminal.register_event_handler(
108
-            NoLongerVisibleOpponent,
109
-            self.no_longer_visible_opponent,
110
-        )
111
-
112
-        self.terminal.register_event_handler(
113
-            FireEvent,
114
-            self.fire_happen,
115
-        )
116
-
117
-        self.terminal.register_event_handler(
118
-            DieEvent,
119
-            self.subject_die,
120
-        )
121
-
122
-        # configs
123
-        self.move_duration_ref = float(self.config.resolve('game.move.walk_ref_time'))
124
-        self.move_fast_duration_ref = float(self.config.resolve('game.move.run_ref_time'))
125
-        self.move_crawl_duration_ref = float(self.config.resolve('game.move.crawl_ref_time'))
126
-
127
-    def before_run(self) -> None:
128
-        from sandbox.tile.gui.move import MoveActorInteraction
129
-        from sandbox.tile.gui.move import MoveFastActorInteraction
130
-        from sandbox.tile.gui.move import MoveCrawlActorInteraction
131
-        from sandbox.tile.gui.fire import FireActorInteraction
132
-
133
-        self.layer_manager.interaction_manager.register(MoveActorInteraction, self.layer_manager)
134
-        self.layer_manager.interaction_manager.register(MoveFastActorInteraction, self.layer_manager)
135
-        self.layer_manager.interaction_manager.register(MoveCrawlActorInteraction, self.layer_manager)
136
-        self.layer_manager.interaction_manager.register(FireActorInteraction, self.layer_manager)
137
-
138
-    def set_subject_position(self, event: FinishMoveEvent):
139
-        actor = self.layer_manager.subject_layer.subjects_index[event.subject_id]
140
-        new_world_position = self.layer_manager.grid_manager.get_world_position_of_grid_position(event.to_position)
141
-
142
-        actor.stop_actions((BaseMoveTo,))
143
-        actor.set_position(*new_world_position)
144
-
145
-    def start_move_subject(self, event: StartMoveEvent):
146
-        actor = self.layer_manager.subject_layer.subjects_index[event.subject_id]
147
-        new_world_position = self.layer_manager.grid_manager.get_world_position_of_grid_position(event.to_position)
148
-
149
-        if event.gui_action == UserAction.ORDER_MOVE:
150
-            animation = ANIMATION_WALK
151
-            cycle_duration = 2
152
-            move_duration = self.move_duration_ref
153
-        elif event.gui_action == UserAction.ORDER_MOVE_FAST:
154
-            animation = ANIMATION_WALK
155
-            cycle_duration = 0.5
156
-            move_duration = self.move_fast_duration_ref
157
-        elif event.gui_action == UserAction.ORDER_MOVE_CRAWL:
158
-            animation = ANIMATION_CRAWL
159
-            cycle_duration = 2
160
-            move_duration = self.move_crawl_duration_ref
161
-        else:
162
-            raise NotImplementedError()
163
-
164
-        move_action = MoveTo(new_world_position, move_duration)
165
-        actor.do(move_action)
166
-        actor.do(Animate(animation, duration=move_duration, cycle_duration=cycle_duration))
167
-        actor.rotation = get_angle(event.from_position, event.to_position)
168
-
169
-    def new_visible_opponent(self, event: NewVisibleOpponent):
170
-        self.visible_or_no_longer_visible_opponent(event, (153, 0, 153))
171
-
172
-    def no_longer_visible_opponent(self, event: NoLongerVisibleOpponent):
173
-        self.visible_or_no_longer_visible_opponent(event, (255, 102, 0))
174
-
175
-    def visible_or_no_longer_visible_opponent(
176
-        self,
177
-        event: typing.Union[NoLongerVisibleOpponent, NewVisibleOpponent],
178
-        line_color,
179
-    ) -> None:
180
-        if self.layer_manager.debug:
181
-            observer_actor = self.layer_manager.subject_layer.subjects_index[event.observer_subject_id]
182
-            observed_actor = self.layer_manager.subject_layer.subjects_index[event.observed_subject_id]
183
-
184
-            observer_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
185
-                *self.layer_manager.grid_manager.get_world_position_of_grid_position(
186
-                    observer_actor.subject.position,
187
-                )
188
-            )
189
-            observed_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
190
-                *self.layer_manager.grid_manager.get_world_position_of_grid_position(
191
-                    observed_actor.subject.position,
192
-                )
193
-            )
194
-
195
-            def draw_visible_opponent():
196
-                draw_line(
197
-                    observer_pixel_position,
198
-                    observed_pixel_position,
199
-                    line_color,
200
-                )
201
-
202
-            # TODO: Not in edit layer !
203
-            self.layer_manager.edit_layer.append_callback(draw_visible_opponent, 1.0)
204
-
205
-    def fire_happen(self, event: FireEvent) -> None:
206
-        # TODO: Not in edit layer !
207
-        shooter_actor = self.layer_manager.subject_layer.subjects_index[event.shooter_subject_id]
208
-        shooter_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
209
-            *self.layer_manager.grid_manager.get_world_position_of_grid_position(
210
-                shooter_actor.subject.position,
211
-            )
212
-        )
213
-        fire_to_pixel_position = self.layer_manager.scrolling_manager.world_to_screen(
214
-            *self.layer_manager.grid_manager.get_world_position_of_grid_position(
215
-                event.target_position,
216
-            )
217
-        )
218
-
219
-        def gunshot_trace():
220
-            draw_line(
221
-                shooter_pixel_position,
222
-                fire_to_pixel_position,
223
-                color=(255, 0, 0),
224
-            )
225
-
226
-        def gunshot_sound():
227
-            self.sound_lib.get_sound('gunshot_default').play()
228
-
229
-        # To avoid all in same time
230
-        delay = random.uniform(0.0, 0.6)
231
-
232
-        self.layer_manager.edit_layer.append_callback(gunshot_trace, duration=0.1, delay=delay)
233
-        self.layer_manager.edit_layer.append_callback(gunshot_sound, duration=0.0, delay=delay)
234
-
235
-    def subject_die(self, event: DieEvent) -> None:
236
-        killed_actor = self.layer_manager.subject_layer.subjects_index[event.shoot_subject_id]
237
-        dead_image = pyglet.resource.image('maps/003/actors/man_d1.png')
238
-        killed_actor.update_image(dead_image)
239
-        killed_actor.freeze()

+ 0 - 89
sandbox/tile/gui/fire.py View File

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

+ 0 - 48
sandbox/tile/gui/move.py View File

@@ -1,48 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from synergine2_cocos2d.interaction import BaseActorInteraction
5
-from sandbox.tile.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.grid_manager.get_grid_position(actor.position)
20
-            pixel_position = self.layer_manager.grid_manager.get_world_position_of_grid_position(grid_position)
21
-
22
-            draw_line(
23
-                self.layer_manager.scrolling_manager.world_to_screen(*pixel_position),
24
-                self.layer_manager.edit_layer.screen_mouse,
25
-                self.color,
26
-            )
27
-
28
-    def get_behaviour(self, actor: Actor, mouse_grid_position) -> typing.Tuple[typing.Type[SimulationBehaviour], dict]:
29
-        return self.request_move_behaviour_class, {
30
-            'subject_id': actor.subject.id,
31
-            'move_to': mouse_grid_position,
32
-            'gui_action': self.gui_action,
33
-        }
34
-
35
-
36
-class MoveActorInteraction(BaseMoveActorInteraction):
37
-    gui_action = UserAction.ORDER_MOVE
38
-    color = (0, 0, 255)
39
-
40
-
41
-class MoveFastActorInteraction(BaseMoveActorInteraction):
42
-    gui_action = UserAction.ORDER_MOVE_FAST
43
-    color = (72, 244, 66)
44
-
45
-
46
-class MoveCrawlActorInteraction(BaseMoveActorInteraction):
47
-    gui_action = UserAction.ORDER_MOVE_CRAWL
48
-    color = (235, 244, 66)

+ 0 - 140
sandbox/tile/maps/003/003.tmx View File

@@ -1,140 +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
- <imagelayer name="background">
6
-  <image source="background.png" width="560" height="320"/>
7
- </imagelayer>
8
- <layer name="terrain" width="70" height="40" opacity="0.3">
9
-  <data encoding="csv">
10
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,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
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,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
-10,10,10,10,10,10,10,10,10,10,10,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,
13
-10,10,10,10,10,10,10,10,10,10,10,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,
14
-10,10,10,10,10,10,10,10,10,10,10,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,
15
-10,10,10,10,10,10,10,10,10,10,10,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,
16
-10,10,10,10,10,10,10,10,10,10,10,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,
17
-10,10,10,10,10,10,10,10,10,10,10,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,
18
-10,10,10,10,10,10,10,10,10,10,10,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,
19
-10,10,10,10,10,10,10,10,10,10,10,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,
20
-10,10,10,10,10,10,10,10,10,10,10,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,
21
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
22
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
23
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
24
-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,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
25
-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,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
26
-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,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
27
-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,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
28
-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,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
29
-10,10,10,10,11,0,0,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,10,10,10,10,10,10,10,10,10,
30
-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,10,10,10,10,10,10,10,10,10,10,10,10,
31
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
32
-10,10,10,10,10,10,10,10,10,10,10,10,10,10,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,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,
33
-10,10,10,10,10,10,10,10,10,10,10,10,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,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,
34
-10,10,10,10,10,10,10,10,10,10,10,10,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,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,
35
-10,10,10,10,10,10,10,10,10,10,10,10,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,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,
36
-10,10,10,10,10,10,10,10,10,10,10,10,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,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,
37
-10,10,10,10,10,10,10,10,10,10,10,10,10,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,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,
38
-10,10,10,10,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,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,
39
-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,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,
40
-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,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,
41
-10,10,10,10,10,10,10,10,10,10,10,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,
42
-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,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,
43
-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,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,
44
-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,
45
-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,
46
-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,
47
-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,
48
-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,
49
-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
50
-</data>
51
- </layer>
52
- <layer name="ground" width="70" height="40">
53
-  <data encoding="csv">
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,
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,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,0,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,
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,
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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
78
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
79
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
80
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
81
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
82
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
83
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
84
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
85
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
86
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
87
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
88
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
89
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
90
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
91
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
92
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
93
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
94
-</data>
95
- </layer>
96
- <layer name="top" width="70" height="40">
97
-  <data encoding="csv">
98
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
99
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
100
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
101
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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,1,0,0,0,0,0,0,0,0,0,0,0,
106
-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,
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,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,
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,1,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,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,
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
-</data>
139
- </layer>
140
-</map>

BIN
sandbox/tile/maps/003/actors/man.png View File


BIN
sandbox/tile/maps/003/actors/man_c1.png View File


BIN
sandbox/tile/maps/003/actors/man_c2.png View File


BIN
sandbox/tile/maps/003/actors/man_c3.png View File


BIN
sandbox/tile/maps/003/actors/man_c4.png View File


BIN
sandbox/tile/maps/003/actors/man_d1.png View File


BIN
sandbox/tile/maps/003/actors/man_w1.png View File


BIN
sandbox/tile/maps/003/actors/man_w10.png View File


BIN
sandbox/tile/maps/003/actors/man_w2.png View File


BIN
sandbox/tile/maps/003/actors/man_w3.png View File


BIN
sandbox/tile/maps/003/actors/man_w4.png View File


BIN
sandbox/tile/maps/003/actors/man_w5.png View File


BIN
sandbox/tile/maps/003/actors/man_w6.png View File


BIN
sandbox/tile/maps/003/actors/man_w7.png View File


BIN
sandbox/tile/maps/003/actors/man_w8.png View File


BIN
sandbox/tile/maps/003/actors/man_w9.png View File


BIN
sandbox/tile/maps/003/background.png View File


BIN
sandbox/tile/maps/003/terrain.png View File


+ 0 - 22
sandbox/tile/maps/003/terrain.tsx View File

@@ -1,22 +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
-</tileset>

BIN
sandbox/tile/maps/003/trees_64x64.png View File


+ 0 - 4
sandbox/tile/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>

+ 0 - 23
sandbox/tile/maps/004/004.tmx View File

@@ -1,23 +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="15" height="5" tilewidth="8" tileheight="8" nextobjectid="4">
3
- <tileset firstgid="1" source="trees_64x64.tsx"/>
4
- <tileset firstgid="10" source="terrain.tsx"/>
5
- <imagelayer name="background" visible="0">
6
-  <image source="background.png" width="24" height="40"/>
7
- </imagelayer>
8
- <layer name="terrain" width="15" height="5" opacity="0.5">
9
-  <data encoding="base64">
10
-   CgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAoAAAALAAAACwAAAAsAAAAKAAAACgAAAAsAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAsAAAAKAAAACgAAAAsAAAALAAAACwAAAAoAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAA
11
-  </data>
12
- </layer>
13
- <layer name="ground" width="15" height="5">
14
-  <data encoding="base64">
15
-   CgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAoAAAALAAAACwAAAAsAAAAKAAAACgAAAAsAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAsAAAAKAAAACgAAAAsAAAALAAAACwAAAAoAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAA
16
-  </data>
17
- </layer>
18
- <layer name="top" width="15" height="5">
19
-  <data encoding="base64">
20
-   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
21
-  </data>
22
- </layer>
23
-</map>

BIN
sandbox/tile/maps/004/actors/man.png View File


BIN
sandbox/tile/maps/004/actors/man_c1.png View File


BIN
sandbox/tile/maps/004/actors/man_c2.png View File


BIN
sandbox/tile/maps/004/actors/man_c3.png View File


BIN
sandbox/tile/maps/004/actors/man_c4.png View File


BIN
sandbox/tile/maps/004/actors/man_w1.png View File


BIN
sandbox/tile/maps/004/actors/man_w10.png View File


BIN
sandbox/tile/maps/004/actors/man_w2.png View File


BIN
sandbox/tile/maps/004/actors/man_w3.png View File


BIN
sandbox/tile/maps/004/actors/man_w4.png View File


BIN
sandbox/tile/maps/004/actors/man_w5.png View File


BIN
sandbox/tile/maps/004/actors/man_w6.png View File


BIN
sandbox/tile/maps/004/actors/man_w7.png View File


BIN
sandbox/tile/maps/004/actors/man_w8.png View File


BIN
sandbox/tile/maps/004/actors/man_w9.png View File


BIN
sandbox/tile/maps/004/background.png View File


BIN
sandbox/tile/maps/004/terrain.png View File


+ 0 - 18
sandbox/tile/maps/004/terrain.tsx View File

@@ -1,18 +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
-  </properties>
10
- </tile>
11
- <tile id="1">
12
-  <properties>
13
-   <property name="name" type="str" value="Wood wall"/>
14
-   <property name="traversable_by_man" type="bool" value="false"/>
15
-   <property name="traversable_by_vehicle" type="bool" value="false"/>
16
-  </properties>
17
- </tile>
18
-</tileset>

BIN
sandbox/tile/maps/004/trees_64x64.png View File


+ 0 - 4
sandbox/tile/maps/004/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>

+ 0 - 100
sandbox/tile/run.py View File

@@ -1,100 +0,0 @@
1
-# coding: utf-8
2
-import argparse
3
-import os
4
-import sys
5
-import logging
6
-from random import seed
7
-
8
-synergine2_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../'))
9
-sys.path.append(synergine2_path)
10
-
11
-from sandbox.tile.const import FLAG, SIDE
12
-from sandbox.tile.const import FLAG_DE
13
-from sandbox.tile.const import DE_COLOR
14
-from sandbox.tile.const import URSS_COLOR
15
-from sandbox.tile.const import FLAG_URSS
16
-from synergine2_cocos2d.const import SELECTION_COLOR_RGB
17
-from synergine2_cocos2d.util import get_map_file_path_from_dir
18
-from sandbox.tile.simulation.subject import TileSubject
19
-from sandbox.tile.simulation.base import TileStrategySimulation
20
-from sandbox.tile.simulation.base import TileStrategySubjects
21
-from synergine2.log import get_default_logger
22
-from synergine2.config import Config
23
-from sandbox.tile.terminal.base import CocosTerminal
24
-from synergine2.core import Core
25
-from synergine2.cycle import CycleManager
26
-from synergine2.terminals import TerminalManager
27
-
28
-
29
-def main(map_dir_path: str, seed_value: int=None):
30
-    if seed_value is not None:
31
-        seed(seed_value)
32
-
33
-    config = Config()
34
-    config.load_yaml('sandbox/tile/config.yaml')
35
-    logger = get_default_logger(level=logging.ERROR)
36
-
37
-    map_file_path = get_map_file_path_from_dir(map_dir_path)
38
-
39
-    simulation = TileStrategySimulation(config, map_file_path=map_file_path)
40
-    subjects = TileStrategySubjects(simulation=simulation)
41
-
42
-    for position in ((10, 2), (11, 3), (11, 4), (12, 5),):
43
-        man = TileSubject(
44
-            config=config,
45
-            simulation=simulation,
46
-            position=position,
47
-            properties={
48
-                SELECTION_COLOR_RGB: DE_COLOR,
49
-                FLAG: FLAG_DE,
50
-                SIDE: 'AXIS',
51
-            }
52
-        )
53
-        subjects.append(man)
54
-
55
-    for position in ((30, 15), (31, 16), (32, 17), (33, 18),):
56
-        man = TileSubject(
57
-            config=config,
58
-            simulation=simulation,
59
-            position=position,
60
-            properties={
61
-                SELECTION_COLOR_RGB: URSS_COLOR,
62
-                FLAG: FLAG_URSS,
63
-                SIDE: 'ALLIES',
64
-            }
65
-        )
66
-        subjects.append(man)
67
-
68
-    simulation.subjects = subjects
69
-
70
-    core = Core(
71
-        config=config,
72
-        logger=logger,
73
-        simulation=simulation,
74
-        cycle_manager=CycleManager(
75
-            config=config,
76
-            logger=logger,
77
-            simulation=simulation,
78
-        ),
79
-        terminal_manager=TerminalManager(
80
-            config=config,
81
-            logger=logger,
82
-            terminals=[CocosTerminal(
83
-                config,
84
-                logger,
85
-                asynchronous=False,
86
-                map_dir_path=map_dir_path,
87
-            )]
88
-        ),
89
-        cycles_per_seconds=1 / config.resolve('core.cycle_duration'),
90
-    )
91
-    core.run()
92
-
93
-if __name__ == '__main__':
94
-    parser = argparse.ArgumentParser(description='Run TileStrategy')
95
-    parser.add_argument('map_dir_path', help='map directory path')
96
-    parser.add_argument('--seed', dest='seed', default=None)
97
-
98
-    args = parser.parse_args()
99
-
100
-    main(args.map_dir_path, seed_value=args.seed)

+ 0 - 1
sandbox/tile/simulation/__init__.py View File

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

+ 0 - 42
sandbox/tile/simulation/base.py View File

@@ -1,42 +0,0 @@
1
-# coding: utf-8
2
-from sandbox.tile.const import COLLECTION_ALIVE
3
-from sandbox.tile.simulation.physics import TilePhysics
4
-from synergine2.config import Config
5
-from synergine2.simulation import SubjectBehaviour
6
-from synergine2_xyz.physics import Physics
7
-from synergine2_xyz.simulation import XYZSimulation
8
-from synergine2_xyz.subjects import XYZSubject
9
-from synergine2_xyz.subjects import XYZSubjects
10
-
11
-
12
-class TileStrategySimulation(XYZSimulation):
13
-    behaviours_classes = [
14
-
15
-    ]
16
-
17
-    def __init__(
18
-        self,
19
-        config: Config,
20
-        map_file_path: str,
21
-    ) -> None:
22
-        self.map_file_path = map_file_path
23
-        super().__init__(config)
24
-
25
-    def create_physics(self) -> Physics:
26
-        return TilePhysics(
27
-            config=self.config,
28
-            map_file_path=self.map_file_path,
29
-        )
30
-
31
-
32
-class TileStrategySubjects(XYZSubjects):
33
-    pass
34
-
35
-
36
-class BaseSubject(XYZSubject):
37
-    pass
38
-
39
-
40
-class AliveSubjectBehaviour(SubjectBehaviour):
41
-    def is_terminated(self) -> bool:
42
-        return COLLECTION_ALIVE not in self.subject.collections

+ 0 - 154
sandbox/tile/simulation/behaviour.py View File

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

+ 0 - 47
sandbox/tile/simulation/event.py View File

@@ -1,47 +0,0 @@
1
-# coding: utf-8
2
-
3
-
4
-# TODO: Reprendre les events Move, pour les lister tous ici
5
-import typing
6
-
7
-from synergine2.simulation import Event
8
-
9
-
10
-class NewVisibleOpponent(Event):
11
-    def __init__(
12
-        self,
13
-        observer_subject_id: int,
14
-        observed_subject_id: int,
15
-    ) -> None:
16
-        self.observer_subject_id = observer_subject_id
17
-        self.observed_subject_id = observed_subject_id
18
-
19
-
20
-class NoLongerVisibleOpponent(Event):
21
-    def __init__(
22
-        self,
23
-        observer_subject_id: int,
24
-        observed_subject_id: int,
25
-    ) -> None:
26
-        self.observer_subject_id = observer_subject_id
27
-        self.observed_subject_id = observed_subject_id
28
-
29
-
30
-class FireEvent(Event):
31
-    def __init__(
32
-        self,
33
-        shooter_subject_id: int,
34
-        target_position: typing.Tuple[int, int],
35
-    ) -> None:
36
-        self.shooter_subject_id = shooter_subject_id
37
-        self.target_position = target_position
38
-
39
-
40
-class DieEvent(Event):
41
-    def __init__(
42
-        self,
43
-        shooter_subject_id: int,
44
-        shoot_subject_id: int,
45
-    ) -> None:
46
-        self.shooter_subject_id = shooter_subject_id
47
-        self.shoot_subject_id = shoot_subject_id

+ 0 - 39
sandbox/tile/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 - 16
sandbox/tile/simulation/mechanism.py View File

@@ -1,16 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from sandbox.tile.const import SIDE, COLLECTION_ALIVE
5
-from synergine2_xyz.subjects import XYZSubject
6
-from synergine2_xyz.visible.simulation import VisibleMechanism
7
-
8
-
9
-class OpponentVisibleMechanism(VisibleMechanism):
10
-    from_collection = COLLECTION_ALIVE
11
-
12
-    def reduce_subjects(self, subjects: typing.List[XYZSubject]) -> typing.Iterator[XYZSubject]:
13
-        def filter_subject(subject: XYZSubject) -> bool:
14
-            return self.subject.properties[SIDE] != subject.properties[SIDE]
15
-
16
-        return filter(filter_subject, subjects)

+ 0 - 80
sandbox/tile/simulation/physics.py View File

@@ -1,80 +0,0 @@
1
-# coding: utf-8
2
-import typing
3
-
4
-from sandbox.tile.simulation.tmx import TileMap
5
-from sandbox.tile.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 sandbox.tile.simulation.base import BaseSubject
12
-    from sandbox.tile.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: Objets/IT qui compute les couts de déplacement
25
-
26
-        if not tile.property('traversable_by_man'):
27
-            # TODO: revoir la lib disjkstar because les mecs traverses quand meme ...
28
-            return 100
29
-
30
-        return 1.0
31
-
32
-
33
-class TilePhysics(TMXPhysics):
34
-    tmx_map_class = TileMap
35
-    move_cost_computer_class = TileMoveCostComputer
36
-    matrixes_configuration = {
37
-        'visibility': [
38
-            'height',
39
-            'opacity',
40
-        ]
41
-    }
42
-
43
-    def get_visibility_obstacle(
44
-        self,
45
-        subject: XYZSubject,
46
-        to_position: typing.Tuple[int, int],
47
-        matrix_name: str,
48
-        opacity_property_name: str='opacity',
49
-    ) -> typing.Union[None, typing.Tuple[int, int]]:
50
-        """
51
-        Return grid position obstacle if any between given subject and given to_position
52
-        :param subject: Subject observer
53
-        :param to_position: position to observe
54
-        :param matrix_name: matrix name to use
55
-        :param opacity_property_name: name of property containing opacity property
56
-        :return: obstacle grid position or None if not
57
-        """
58
-        from_x, from_y = subject.position
59
-        path_positions = self.matrixes.get_path_positions(from_=(from_x, from_y), to=to_position)
60
-        path_opacities = self.matrixes.get_values_for_path(
61
-            matrix_name,
62
-            path_positions=path_positions,
63
-            value_name=opacity_property_name,
64
-        )
65
-
66
-        # FIXME: This algo is not ok, it is for test
67
-        actual_opacity = 0
68
-        for i, path_opacity in enumerate(path_opacities):
69
-            actual_opacity += path_opacity
70
-            if actual_opacity >= 100:
71
-                return path_positions[i]
72
-
73
-        return None
74
-
75
-    def subject_see_subject(self, observer: 'TileSubject', observed: 'TileSubject') -> bool:
76
-        return not bool(self.get_visibility_obstacle(
77
-            observer,
78
-            observed.position,
79
-            matrix_name='visibility',
80
-        ))

+ 0 - 22
sandbox/tile/simulation/subject.py View File

@@ -1,22 +0,0 @@
1
-# coding: utf-8
2
-from sandbox.tile.const import COLLECTION_ALIVE, COMBAT_MODE_DEFENSE
3
-from sandbox.tile.simulation.base import BaseSubject
4
-from sandbox.tile.simulation.behaviour import MoveToBehaviour
5
-from sandbox.tile.simulation.behaviour import EngageOpponent
6
-from sandbox.tile.simulation.behaviour import LookAroundBehaviour
7
-from synergine2.share import shared
8
-
9
-
10
-class TileSubject(BaseSubject):
11
-    start_collections = [
12
-        COLLECTION_ALIVE,
13
-    ]
14
-    behaviours_classes = [
15
-        MoveToBehaviour,
16
-        LookAroundBehaviour,
17
-        EngageOpponent,
18
-    ]
19
-    visible_opponent_ids = shared.create_self('visible_opponent_ids', lambda: [])
20
-    combat_mode = shared.create_self('combat_mode', COMBAT_MODE_DEFENSE)
21
-    # TODO: implement (copied from engulf)
22
-    # behaviour_selector_class = CellBehaviourSelector

+ 0 - 16
sandbox/tile/simulation/tmx.py View File

@@ -1,16 +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
-
15
-    def get_default_tileset(self) -> tmx.Tileset:
16
-        return self.tmx_tilesets['terrain']

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


+ 0 - 1
sandbox/tile/terminal/__init__.py View File

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

+ 0 - 53
sandbox/tile/terminal/base.py View File

@@ -1,53 +0,0 @@
1
-# coding: utf-8
2
-from sandbox.tile.simulation.event import NewVisibleOpponent
3
-from sandbox.tile.simulation.event import FireEvent
4
-from sandbox.tile.simulation.event import DieEvent
5
-from sandbox.tile.simulation.event import NoLongerVisibleOpponent
6
-from sandbox.tile.simulation.physics import TilePhysics
7
-from sandbox.tile.simulation.subject import TileSubject as ManSubject
8
-from sandbox.tile.gui.actor import Man as ManActor
9
-from synergine2_cocos2d.terminal import GameTerminal
10
-from synergine2_cocos2d.util import get_map_file_path_from_dir
11
-from synergine2_xyz.move.simulation import FinishMoveEvent
12
-from synergine2_xyz.move.simulation import StartMoveEvent
13
-
14
-
15
-class CocosTerminal(GameTerminal):
16
-    subscribed_events = [
17
-        FinishMoveEvent,
18
-        StartMoveEvent,
19
-        NewVisibleOpponent,
20
-        NoLongerVisibleOpponent,
21
-        FireEvent,
22
-        DieEvent,
23
-    ]
24
-
25
-    def __init__(self, *args, asynchronous: bool, map_dir_path: str, **kwargs):
26
-        super().__init__(*args, **kwargs)
27
-        self.asynchronous = asynchronous
28
-        map_file_path = get_map_file_path_from_dir(map_dir_path)
29
-        self.physics = TilePhysics(
30
-            self.config,
31
-            map_file_path=map_file_path,
32
-        )
33
-        self.map_dir_path = map_dir_path
34
-
35
-    def run(self):
36
-        from sandbox.tile.gui.base import Game
37
-        from synergine2_cocos2d.gui import SubjectMapper
38
-
39
-        self.gui = Game(
40
-            self.config,
41
-            self.logger,
42
-            self,
43
-            physics=self.physics,
44
-            map_dir_path=self.map_dir_path,
45
-        )
46
-
47
-        # TODO: Defind on some other place ?
48
-        self.gui.subject_mapper_factory.register_mapper(
49
-            ManSubject,
50
-            SubjectMapper(ManActor),
51
-        )
52
-
53
-        self.gui.run()

+ 0 - 9
sandbox/tile/user_action.py View File

@@ -1,9 +0,0 @@
1
-# coding: utf-8
2
-from synergine2_cocos2d.user_action import UserAction as BaseUserAction
3
-
4
-
5
-class UserAction(BaseUserAction):
6
-    ORDER_MOVE = 'ORDER_MOVE'
7
-    ORDER_MOVE_FAST = 'ORDER_MOVE_FAST'
8
-    ORDER_MOVE_CRAWL = 'ORDER_MOVE_CRAWL'
9
-    ORDER_FIRE = 'ORDER_FIRE'

+ 47 - 0
setup.py View File

@@ -0,0 +1,47 @@
1
+# coding: utf-8
2
+from setuptools import setup
3
+from setuptools import find_packages
4
+
5
+install_requires = [
6
+    'PyYAML',
7
+    'redis',
8
+    'psutil',
9
+]
10
+xyz_require = [
11
+    'dijkstar',
12
+    'tmx',
13
+    'numpy',
14
+]
15
+cocos2d_require = [
16
+    'cocos2d',
17
+] + xyz_require
18
+tests_require = [
19
+    'pytest',
20
+    'freezegun',
21
+] + cocos2d_require
22
+
23
+
24
+setup(
25
+    name='synergine2',
26
+    version='1.0',
27
+    description='Subject focus simulation framework',
28
+    author='Bastien Sevajol',
29
+    author_email='sevajol.bastien@gmail.com',
30
+    url='https://github.com/buxx/synergine2',
31
+    packages=find_packages(exclude=[
32
+        'contrib',
33
+        'docs',
34
+        'tests',
35
+    ]),
36
+    classifiers=[
37
+        "Programming Language :: Python",
38
+        "Development Status :: 4 - Beta",
39
+        "Programming Language :: Python :: 3.5",
40
+    ],
41
+    install_requires=install_requires,
42
+    extras_require={
43
+        'tests': tests_require,
44
+        'cocos2d': tests_require,
45
+        'xyz': tests_require,
46
+    },
47
+)

+ 1 - 1
synergine2_cocos2d/util.py View File

@@ -4,4 +4,4 @@ import os
4 4
 
5 5
 def get_map_file_path_from_dir(map_dir_path: str) -> str:
6 6
     # TODO: path is temp here
7
-    return 'sandbox/tile/{}.tmx'.format(os.path.join(map_dir_path, os.path.basename(map_dir_path)))
7
+    return '{}.tmx'.format(os.path.join(map_dir_path, os.path.basename(map_dir_path)))