Skip to content

Commit

Permalink
multiball lock without virtual ball keeping
Browse files Browse the repository at this point in the history
  • Loading branch information
jabdoa2 committed Apr 19, 2017
1 parent 3cf9219 commit 96cfeee
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 11 deletions.
1 change: 1 addition & 0 deletions mpf/core/config_spec.py
Expand Up @@ -652,6 +652,7 @@
source_playfield: single|machine(ball_devices)|playfield
enable_events: dict|str:ms|None
disable_events: dict|str:ms|None
keep_virtual_ball_count_per_player: single|bool|True
reset_all_counts_events: dict|str:ms|None
reset_count_for_current_player_events: dict|str:ms|None
opp:
Expand Down
28 changes: 17 additions & 11 deletions mpf/devices/multiball_lock.py
Expand Up @@ -32,9 +32,6 @@ def __init__(self, machine, name):

self.machine.events.add_handler("player_turn_starting", self._player_turn_starting)

def _add_balls_in_play(self, number):
self.machine.game.balls_in_play += number

def device_removed_from_mode(self, mode):
"""Disable ball lock when mode ends."""
del mode
Expand Down Expand Up @@ -121,24 +118,32 @@ def disable(self, **kwargs):
def reset_all_counts(self, **kwargs):
"""Reset the locked balls for all players."""
del kwargs
if not self.config['keep_virtual_ball_count_per_player']:
raise AssertionError("Cannot reset physical counts")
for player in self.machine.game.player_list:
player['{}_locked_balls'.format(self.name)] = 0

@event_handler(2)
def reset_count_for_current_player(self, **kwargs):
"""Reset the locked balls for the current player."""
del kwargs
if not self.config['keep_virtual_ball_count_per_player']:
raise AssertionError("Cannot reset physical counts")
self.machine.game.player['{}_locked_balls'.format(self.name)] = 0

@property
def locked_balls(self):
"""Return the number of locked balls for the current player."""
return self.machine.game.player['{}_locked_balls'.format(self.name)]
if self.config['keep_virtual_ball_count_per_player']:
return self.machine.game.player['{}_locked_balls'.format(self.name)]
else:
return self._physically_locked_balls

@locked_balls.setter
def locked_balls(self, value):
"""Set the number of locked balls for the current player."""
self.machine.game.player['{}_locked_balls'.format(self.name)] = value
if self.config['keep_virtual_ball_count_per_player']:
self.machine.game.player['{}_locked_balls'.format(self.name)] = value

def _register_handlers(self):
# register on ball_enter of lock_devices
Expand Down Expand Up @@ -229,13 +234,14 @@ def _lock_ball(self, unclaimed_balls: int, device: "BallDevice", **kwargs):
has locked.
'''

# only keep ball if any player could use it
if self._max_balls_locked_by_any_player <= self._physically_locked_balls:
balls_to_lock_physically = 0
if self.config['keep_virtual_ball_count_per_player']:
# only keep ball if any player could use it
if self._max_balls_locked_by_any_player <= self._physically_locked_balls:
balls_to_lock_physically = 0

# do not lock if the lock would be physically full but not virtually
if not self.is_virtually_full and self._physically_remaining_space <= 1:
balls_to_lock_physically = 0
# do not lock if the lock would be physically full but not virtually
if not self.is_virtually_full and self._physically_remaining_space <= 1:
balls_to_lock_physically = 0

# check if we are full now and post event if yes
if self.is_virtually_full:
Expand Down
1 change: 1 addition & 0 deletions mpf/tests/machine_files/multiball/config/config.yaml
Expand Up @@ -57,6 +57,7 @@ modes:
- mode2
- mode3
- mode4
- mode5

multiballs:
mb1:
Expand Down
11 changes: 11 additions & 0 deletions mpf/tests/machine_files/multiball/modes/mode5/config/mode5.yaml
@@ -0,0 +1,11 @@
#config_version=4
mode:
start_events: start_mode5
stop_events: stop_mode5


multiball_locks:
lock_mb7:
lock_devices: bd_lock
balls_to_lock: 2
keep_virtual_ball_count_per_player: False
61 changes: 61 additions & 0 deletions mpf/tests/test_MultiBall.py
Expand Up @@ -425,6 +425,67 @@ def testMultiballInMode(self):
self.advance_time_and_run(1)
self.assertEqual(None, self.machine.game)

def testMultiballLockNoStateKeepingInMode(self):
# prepare game
self.fill_troughs()

# start game
self.start_two_player_game()

# takes roughly 4s to get ball confirmed
self.advance_time_and_run(4)
self.assertNotEqual(None, self.machine.game)
self.assertEqual(1, self.machine.playfield.balls)

self.advance_time_and_run(4)
self.assertEqual(1, self.machine.playfield.available_balls)

# start mode
self.post_event("start_mode5")

self.advance_time_and_run(4)

# lock one ball and another one should go to pf
self.hit_switch_and_run("s_lock1", 10)
self.assertEqual(1, self.machine.ball_devices.bd_lock.balls)
self.assertEqual(1, self.machine.playfield.balls)

# player change
self.drain_ball()
self.advance_time_and_run(10)

# start mode
self.post_event("start_mode5")

self.assertPlayerNumber(2)
self.assertEqual(1, self.machine.ball_devices.bd_lock.balls)
self.assertEqual(1, self.machine.playfield.balls)

self.hit_switch_and_run("s_lock2", 10)
self.assertEqual(2, self.machine.ball_devices.bd_lock.balls)
self.assertEqual(1, self.machine.playfield.balls)

# player change
self.drain_ball()
self.advance_time_and_run(10)
self.assertGameIsNotRunning()

self.assertEqual(0, self.machine.ball_devices.bd_lock.balls)
self.assertEqual(2, self.machine.playfield.balls)

# game should not start yet
self.assertGameIsNotRunning()
self.hit_and_release_switch("s_start")
self.advance_time_and_run()
self.assertGameIsNotRunning()

self.drain_ball()
self.drain_ball()
self.advance_time_and_run()

# game should start again
self.start_game()

def testMultiballInModeSimple(self):
self.mock_event("multiball_mb5_ended")

Expand Down

0 comments on commit 96cfeee

Please sign in to comment.