diff --git a/mpf/config_spec.yaml b/mpf/config_spec.yaml index d952db5f7..164905841 100644 --- a/mpf/config_spec.yaml +++ b/mpf/config_spec.yaml @@ -304,6 +304,16 @@ digital_outputs: platform_settings: single|dict|None type: single|enum(light,driver)| light_subtype: single|str|None +digital_score_reels: + __valid_in__: machine + __type__: device + reel_count: single|num|0 + start_value: single|str|0 + frames: list|subconfig(digital_score_reel_frame)|None + include_player_number: single|bool|False +digital_score_reel_frame: + character: single|str|None + frame: single|int|None dual_wound_coils: __valid_in__: machine __type__: device @@ -678,11 +688,21 @@ info_lights: image_pools: __valid_in__: machine, mode # todo add to validator __type__: config_dict +image_templates: + __valid_in__: machine + __type: config images: __valid_in__: machine, mode __type__: config_dict file: single|str|None + frame_skips: list|subconfig(images_frame_skips)|None + image_template: single|subconfig(images,device)| load: single|str|None +images_frame_skips: + __valid_in__: machine, mode + __type__: config_dict + from: single|int|None + to: single|int|None keyboard: __valid_in__: machine # todo add to validator __type__: config_dict diff --git a/mpf/devices/digital_score_reel.py b/mpf/devices/digital_score_reel.py new file mode 100644 index 000000000..c9d9f3b1f --- /dev/null +++ b/mpf/devices/digital_score_reel.py @@ -0,0 +1,35 @@ +"""Contains the base class for digital (image-based) score reels.""" + +from mpf.core.system_wide_device import SystemWideDevice + + +class DigitalScoreReel(SystemWideDevice): + config_section = 'digital_score_reels' + collection = 'digital_score_reels' + class_label = 'digital_score_reel' + + def __init__(self, machine, name): + super().__init__(machine, name) + self._frames = {} + self._reel_count = 0 + self._include_player_number = False + + async def _initialize(self): + await super()._initialize() + + self._reel_count = self.config["reel_count"] + self._include_player_number = self.config["include_player_number"] + for frame in self.config["frames"]: + self._frames[str(frame["character"])] = str(frame["frame"]) + + self.machine.events.add_handler(self.name, self._post_reel_values) + + def _post_reel_values(self, **kwargs): + # Pad the string up to the necessary number of characters in the reel + score = str(kwargs["value"]).rjust(self._reel_count, self.config["start_value"]) + # Create a dict of reel name keys to target frame values + result = { str(i + 1): self._frames[score[i]] for i in range(self._reel_count)} + # Post the event + event_name = "score_reel_{}_player{}".format(self.name, self.machine.game.player.number) if \ + self._include_player_number else "score_reel_{}".format(self.name) + self.machine.events.post(event_name, **result) diff --git a/mpf/mpfconfig.yaml b/mpf/mpfconfig.yaml index 25fea9423..b47105bae 100644 --- a/mpf/mpfconfig.yaml +++ b/mpf/mpfconfig.yaml @@ -64,6 +64,7 @@ mpf: - mpf.devices.servo.Servo - mpf.devices.achievement.Achievement - mpf.devices.achievement_group.AchievementGroup + - mpf.devices.digital_score_reel.DigitalScoreReel - mpf.devices.dmd.Dmd - mpf.devices.rgb_dmd.RgbDmd - mpf.devices.light_group.LightStrip diff --git a/mpf/tests/machine_files/digital_score_reels/config/test_digital_score_reels.yaml b/mpf/tests/machine_files/digital_score_reels/config/test_digital_score_reels.yaml new file mode 100644 index 000000000..3ec9f6d7a --- /dev/null +++ b/mpf/tests/machine_files/digital_score_reels/config/test_digital_score_reels.yaml @@ -0,0 +1,43 @@ +#config_version=5 + +digital_score_reels: + player_score: + reel_count: 4 + include_player_number: true + frames: + - character: 1 + frame: 2 + - character: 2 + frame: 4 + - character: 3 + frame: 6 + - character: 4 + frame: 8 + - character: 5 + frame: 10 + - character: 6 + frame: 12 + - character: 7 + frame: 14 + - character: 8 + frame: 16 + - character: 9 + frame: 18 + - character: 0 + frame: 20 + arbitrary_event: + reel_count: 3 + start_value: X + frames: + - character: A + frame: 1 + - character: B + frame: 2 + - character: C + frame: 3 + - character: D + frame: 4 + - character: E + frame: 5 + - character: X + frame: 6 diff --git a/mpf/tests/test_DigitalScoreReels.py b/mpf/tests/test_DigitalScoreReels.py new file mode 100644 index 000000000..55724d5d7 --- /dev/null +++ b/mpf/tests/test_DigitalScoreReels.py @@ -0,0 +1,44 @@ +"""Test digital score reels.""" + +from mpf.tests.MpfFakeGameTestCase import MpfFakeGameTestCase + +class TestDigitalScoreReels(MpfFakeGameTestCase): + + def get_config_file(self): + return 'test_digital_score_reels.yaml' + + def get_machine_path(self): + return 'tests/machine_files/digital_score_reels' + + def test_player_score(self): + self.mock_event('score_reel_player_score_player1') + self.mock_event('score_reel_player_score_player2') + self.start_two_player_game() + self.assertGameIsRunning() + + self.assertPlayerNumber(1) + self.advance_time_and_run() + self.machine.game.player.score = 123 + self.advance_time_and_run() + self.assertEqual({"1": "20", "2": "2", "3": "4", "4": "6"}, self._last_event_kwargs['score_reel_player_score_player1']) + self.assertEventNotCalled('score_reel_player_score_player2') + + self.drain_all_balls() + self.assertPlayerNumber(2) + self.machine.game.player.score = 9876 + self.advance_time_and_run() + self.assertEqual({"1": "18", "2": "16", "3": "14", "4": "12"}, self._last_event_kwargs['score_reel_player_score_player2']) + + def test_arbitrary_event(self): + self.mock_event('score_reel_arbitrary_event') + self.post_event_with_params('arbitrary_event', value='AB') + self.advance_time_and_run() + self.assertEqual({"1": "6", "2": "1", "3": "2"}, self._last_event_kwargs['score_reel_arbitrary_event']) + + self.post_event_with_params('arbitrary_event', value='DXB') + self.advance_time_and_run() + self.assertEqual({"1": "4", "2":"6", "3": "2"}, self._last_event_kwargs['score_reel_arbitrary_event']) + + self.post_event_with_params('arbitrary_event', value='EC') + self.advance_time_and_run() + self.assertEqual({"1": "6", "2":"5", "3": "3"}, self._last_event_kwargs['score_reel_arbitrary_event']) \ No newline at end of file