Settlers of EMF
Allow menu screens to avoid redrawing the logo, for quicker response times when navigating menus.master
parent
846bab0ab1
commit
fcd537cdfd
|
@ -80,19 +80,28 @@ class State:
|
||||||
|
|
||||||
class Menu(State):
|
class Menu(State):
|
||||||
|
|
||||||
def __init__(self, question, choices):
|
MENU_ITEM_OFFSET = 120
|
||||||
|
|
||||||
|
def __init__(self, question, choices, clear_title=True):
|
||||||
self.question = question
|
self.question = question
|
||||||
self.choices = choices
|
self.choices = choices
|
||||||
|
self.clear_title = clear_title
|
||||||
|
|
||||||
def is_choice_enabled(self, num):
|
def is_choice_enabled(self, num):
|
||||||
c = self.choices[num]
|
c = self.choices[num]
|
||||||
return 'disabled' not in c or not c['disabled']
|
return 'disabled' not in c or not c['disabled']
|
||||||
|
|
||||||
|
def get_selected_choice(self):
|
||||||
|
return self.choices[self.selection].copy()
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
# Draw the menu on screen
|
# Draw the menu on screen
|
||||||
ugfx.clear(ugfx.BLACK)
|
if self.clear_title:
|
||||||
ugfx.display_image(0, 0, 'settlers_of_emf/title.png')
|
ugfx.clear(ugfx.BLACK)
|
||||||
ugfx.text(5, 100, self.question, ugfx.WHITE)
|
ugfx.display_image(0, 0, 'settlers_of_emf/title.png')
|
||||||
|
else:
|
||||||
|
ugfx.area(0, 95, 240, 225, ugfx.BLACK)
|
||||||
|
ugfx.text(5, 95, self.question, ugfx.WHITE)
|
||||||
offset = 0
|
offset = 0
|
||||||
for i in range(len(self.choices)):
|
for i in range(len(self.choices)):
|
||||||
c = self.choices[i]
|
c = self.choices[i]
|
||||||
|
@ -105,13 +114,13 @@ class Menu(State):
|
||||||
text = "{} ".format(c['name'])
|
text = "{} ".format(c['name'])
|
||||||
else:
|
else:
|
||||||
text = "{} - {} ".format(i + 1, c['name'])
|
text = "{} - {} ".format(i + 1, c['name'])
|
||||||
ugfx.text(18, offset + 125, text, col)
|
ugfx.text(18, offset + Menu.MENU_ITEM_OFFSET, text, col)
|
||||||
offset = offset + 20
|
offset = offset + 20
|
||||||
if 'cost' in c:
|
if 'cost' in c:
|
||||||
for j in range(len(c['cost'])):
|
for j in range(len(c['cost'])):
|
||||||
cost = c['cost'][j]
|
cost = c['cost'][j]
|
||||||
ugfx.area((42 * j) + 46, offset + 125, 18, 18, cost['resource']['col'])
|
ugfx.area((42 * j) + 46, offset + Menu.MENU_ITEM_OFFSET, 18, 18, cost['resource']['col'])
|
||||||
ugfx.text((42 * j) + 64, offset + 125, "x{} ".format(cost['amount']), col)
|
ugfx.text((42 * j) + 64, offset + Menu.MENU_ITEM_OFFSET, "x{} ".format(cost['amount']), col)
|
||||||
offset = offset + 20
|
offset = offset + 20
|
||||||
|
|
||||||
# Set the initial selection
|
# Set the initial selection
|
||||||
|
@ -185,10 +194,10 @@ class Menu(State):
|
||||||
def _set_selection(self, new_selection):
|
def _set_selection(self, new_selection):
|
||||||
# Redraws the selection box
|
# Redraws the selection box
|
||||||
size = 2 if 'cost' in self.choices[self.selection] else 1
|
size = 2 if 'cost' in self.choices[self.selection] else 1
|
||||||
ugfx.box(0, self._get_offset_for_selection(self.selection) + 125, 240, 20 * size, ugfx.BLACK)
|
ugfx.box(0, self._get_offset_for_selection(self.selection) + Menu.MENU_ITEM_OFFSET, 240, 20 * size, ugfx.BLACK)
|
||||||
self.selection = new_selection
|
self.selection = new_selection
|
||||||
size = 2 if 'cost' in self.choices[self.selection] else 1
|
size = 2 if 'cost' in self.choices[self.selection] else 1
|
||||||
ugfx.box(0, self._get_offset_for_selection(self.selection) + 125, 240, 20 * size, ugfx.WHITE)
|
ugfx.box(0, self._get_offset_for_selection(self.selection) + Menu.MENU_ITEM_OFFSET, 240, 20 * size, ugfx.WHITE)
|
||||||
|
|
||||||
def _get_offset_for_selection(self, sel):
|
def _get_offset_for_selection(self, sel):
|
||||||
# Menu items are double height if they need to show a cost, so iterate
|
# Menu items are double height if they need to show a cost, so iterate
|
||||||
|
@ -203,9 +212,6 @@ class Menu(State):
|
||||||
|
|
||||||
|
|
||||||
class MainMenu(Menu):
|
class MainMenu(Menu):
|
||||||
NEW_GAME = 0
|
|
||||||
CONTINUE_GAME = 1
|
|
||||||
EXIT = 2
|
|
||||||
|
|
||||||
options = [
|
options = [
|
||||||
{'name': "Start New Game"},
|
{'name': "Start New Game"},
|
||||||
|
@ -213,9 +219,13 @@ class MainMenu(Menu):
|
||||||
{'name': "Exit"},
|
{'name': "Exit"},
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, disable_continue_option=True):
|
NEW_GAME = 0
|
||||||
|
CONTINUE_GAME = 1
|
||||||
|
EXIT = 2
|
||||||
|
|
||||||
|
def __init__(self, disable_continue_option=True, clear_title=True):
|
||||||
MainMenu.options[MainMenu.CONTINUE_GAME]['disabled'] = disable_continue_option
|
MainMenu.options[MainMenu.CONTINUE_GAME]['disabled'] = disable_continue_option
|
||||||
super().__init__('Welcome!', MainMenu.options)
|
super().__init__('Welcome!', MainMenu.options, clear_title)
|
||||||
|
|
||||||
|
|
||||||
class TeamMenu(Menu):
|
class TeamMenu(Menu):
|
||||||
|
@ -248,14 +258,31 @@ class TeamMenu(Menu):
|
||||||
continue
|
continue
|
||||||
option['disabled'] = option['name'] in [team['name'] for team in teams]
|
option['disabled'] = option['name'] in [team['name'] for team in teams]
|
||||||
TeamMenu.options[TeamMenu.START_GAME]['disabled'] = len(teams) == 0
|
TeamMenu.options[TeamMenu.START_GAME]['disabled'] = len(teams) == 0
|
||||||
super().__init__('Player {}, choose a team:'.format(len(teams) + 1), TeamMenu.options)
|
super().__init__('Player {}, choose a team:'.format(len(teams) + 1), TeamMenu.options, False)
|
||||||
|
|
||||||
def get_selected_team(self):
|
|
||||||
return TeamMenu.options[self.selection].copy()
|
|
||||||
|
|
||||||
|
|
||||||
class ActionMenu(Menu):
|
class ActionMenu(Menu):
|
||||||
|
|
||||||
|
options = [
|
||||||
|
{'name': "Build"},
|
||||||
|
{'name': "Trade"},
|
||||||
|
{'name': "End Turn"},
|
||||||
|
{'name': "Back"},
|
||||||
|
]
|
||||||
|
|
||||||
|
BUILD = 0
|
||||||
|
TRADE = 1
|
||||||
|
END_TURN = 2
|
||||||
|
BACK = 3
|
||||||
|
|
||||||
|
def __init__(self, dice_roll, clear_title=True):
|
||||||
|
# Rolling the dice is mandatory, so don't let the turn end unless it happened
|
||||||
|
ActionMenu.options[ActionMenu.END_TURN]['disabled'] = dice_roll == 0
|
||||||
|
super().__init__('Do a thing:', ActionMenu.options, clear_title)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildMenu(Menu):
|
||||||
|
|
||||||
options = [
|
options = [
|
||||||
{'name': "Build Road (0 points)",
|
{'name': "Build Road (0 points)",
|
||||||
'cost': [{'resource': BRICK, 'amount': 1},
|
'cost': [{'resource': BRICK, 'amount': 1},
|
||||||
|
@ -268,19 +295,14 @@ class ActionMenu(Menu):
|
||||||
{'name': "Upgrade to City (2 points)",
|
{'name': "Upgrade to City (2 points)",
|
||||||
'cost': [{'resource': WHEAT, 'amount': 2},
|
'cost': [{'resource': WHEAT, 'amount': 2},
|
||||||
{'resource': ORE, 'amount': 3}]},
|
{'resource': ORE, 'amount': 3}]},
|
||||||
# TODO Implement trading
|
|
||||||
{'name': "Trade", 'disabled': True},
|
|
||||||
{'name': "End Turn"},
|
|
||||||
{'name': "Back"},
|
{'name': "Back"},
|
||||||
]
|
]
|
||||||
|
|
||||||
TRADE = len(options) - 3
|
|
||||||
END_TURN = len(options) - 2
|
|
||||||
BACK = len(options) - 1
|
BACK = len(options) - 1
|
||||||
|
|
||||||
def __init__(self, resources, dice_roll):
|
def __init__(self, resources):
|
||||||
# Disable build options based on whether the player can afford them
|
# Disable build options based on whether the player can afford them
|
||||||
for option in ActionMenu.options:
|
for option in BuildMenu.options:
|
||||||
if 'cost' not in option:
|
if 'cost' not in option:
|
||||||
continue
|
continue
|
||||||
option['disabled'] = False
|
option['disabled'] = False
|
||||||
|
@ -289,12 +311,39 @@ class ActionMenu(Menu):
|
||||||
if resource.resource == cost['resource']:
|
if resource.resource == cost['resource']:
|
||||||
if resource.quantity < cost['amount']:
|
if resource.quantity < cost['amount']:
|
||||||
option['disabled'] = True
|
option['disabled'] = True
|
||||||
# Rolling the dice is mandatory, so don't let the turn end unless it happened
|
super().__init__('Build:', BuildMenu.options, False)
|
||||||
ActionMenu.options[ActionMenu.END_TURN]['disabled'] = dice_roll == 0
|
|
||||||
super().__init__('Do a thing:', ActionMenu.options)
|
|
||||||
|
|
||||||
def get_selected_build(self):
|
|
||||||
return ActionMenu.options[self.selection].copy()
|
class TradeMenu(Menu):
|
||||||
|
|
||||||
|
options = [
|
||||||
|
{'name': "Buy a Resource",
|
||||||
|
'cost': [{'resource': BRICK, 'amount': 4}]},
|
||||||
|
{'name': "Buy a Resource",
|
||||||
|
'cost': [{'resource': WOOD, 'amount': 4}]},
|
||||||
|
{'name': "Buy a Resource",
|
||||||
|
'cost': [{'resource': SHEEP, 'amount': 4}]},
|
||||||
|
{'name': "Buy a Resource",
|
||||||
|
'cost': [{'resource': WHEAT, 'amount': 4}]},
|
||||||
|
{'name': "Buy a Resource",
|
||||||
|
'cost': [{'resource': ORE, 'amount': 4}]},
|
||||||
|
{'name': "Back"},
|
||||||
|
]
|
||||||
|
|
||||||
|
BACK = len(options) - 1
|
||||||
|
|
||||||
|
def __init__(self, resources):
|
||||||
|
# Disable trade options based on whether the player can afford them
|
||||||
|
for option in TradeMenu.options:
|
||||||
|
if 'cost' not in option:
|
||||||
|
continue
|
||||||
|
option['disabled'] = False
|
||||||
|
for cost in option['cost']:
|
||||||
|
for resource in resources:
|
||||||
|
if resource.resource == cost['resource']:
|
||||||
|
if resource.quantity < cost['amount']:
|
||||||
|
option['disabled'] = True
|
||||||
|
super().__init__('Trade:', TradeMenu.options, False)
|
||||||
|
|
||||||
|
|
||||||
class NextPlayer(Menu):
|
class NextPlayer(Menu):
|
||||||
|
@ -302,7 +351,7 @@ class NextPlayer(Menu):
|
||||||
START_TURN = 0
|
START_TURN = 0
|
||||||
|
|
||||||
def __init__(self, team):
|
def __init__(self, team):
|
||||||
super().__init__('Pass the badge to next team:', [team])
|
super().__init__('Pass the badge to next team:', [team], False)
|
||||||
|
|
||||||
|
|
||||||
class Hex:
|
class Hex:
|
||||||
|
@ -937,62 +986,86 @@ class Settlers:
|
||||||
TEAM_MENU = 2
|
TEAM_MENU = 2
|
||||||
GAME = 3
|
GAME = 3
|
||||||
ACTION_MENU = 4
|
ACTION_MENU = 4
|
||||||
END_TURN = 5
|
ACTION_TRADE_MENU = 5
|
||||||
|
ACTION_BUILD_MENU = 6
|
||||||
|
ACTION_END_TURN = 7
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.old_state = None
|
||||||
self.state = Settlers.MAIN_MENU
|
self.state = Settlers.MAIN_MENU
|
||||||
self.game = None
|
self.game = None
|
||||||
self.teams = []
|
self.teams = []
|
||||||
|
|
||||||
|
def enter_state(self, state):
|
||||||
|
self.old_state = self.state
|
||||||
|
self.state = state
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while self.state != Settlers.EXIT:
|
while self.state != Settlers.EXIT:
|
||||||
|
|
||||||
if self.state == Settlers.MAIN_MENU:
|
if self.state == Settlers.MAIN_MENU:
|
||||||
menu = MainMenu(self.game is None)
|
menu = MainMenu(self.game is None, self.old_state != Settlers.TEAM_MENU)
|
||||||
x = menu.run()
|
x = menu.run()
|
||||||
if x == MainMenu.NEW_GAME:
|
if x == MainMenu.NEW_GAME:
|
||||||
self.teams = []
|
self.teams = []
|
||||||
self.state = Settlers.TEAM_MENU
|
self.enter_state(Settlers.TEAM_MENU)
|
||||||
if x == MainMenu.CONTINUE_GAME:
|
if x == MainMenu.CONTINUE_GAME:
|
||||||
self.state = Settlers.GAME
|
self.enter_state(Settlers.GAME)
|
||||||
if x == MainMenu.EXIT:
|
if x == MainMenu.EXIT:
|
||||||
self.state = Settlers.EXIT
|
self.enter_state(Settlers.EXIT)
|
||||||
|
|
||||||
if self.state == Settlers.TEAM_MENU:
|
elif self.state == Settlers.TEAM_MENU:
|
||||||
menu = TeamMenu(self.teams)
|
menu = TeamMenu(self.teams)
|
||||||
x = menu.run()
|
x = menu.run()
|
||||||
if x <= TeamMenu.TEAM_MAX:
|
if x <= TeamMenu.TEAM_MAX:
|
||||||
self.teams.append(menu.get_selected_team())
|
self.teams.append(menu.get_selected_choice())
|
||||||
if len(self.teams) >= 4:
|
if len(self.teams) >= 4:
|
||||||
x = TeamMenu.START_GAME
|
x = TeamMenu.START_GAME
|
||||||
if x == TeamMenu.BACK:
|
if x == TeamMenu.BACK:
|
||||||
self.state = Settlers.MAIN_MENU
|
self.enter_state(Settlers.MAIN_MENU)
|
||||||
if x == TeamMenu.START_GAME:
|
if x == TeamMenu.START_GAME:
|
||||||
self.game = GameBoard(self.teams)
|
self.game = GameBoard(self.teams)
|
||||||
self.game.next_player()
|
self.game.next_player()
|
||||||
self.state = Settlers.GAME
|
self.enter_state(Settlers.GAME)
|
||||||
|
|
||||||
if self.state == Settlers.GAME:
|
elif self.state == Settlers.GAME:
|
||||||
x = self.game.run()
|
x = self.game.run()
|
||||||
if x == GameBoard.MAIN_MENU:
|
if x == GameBoard.MAIN_MENU:
|
||||||
self.state = Settlers.MAIN_MENU
|
self.enter_state(Settlers.MAIN_MENU)
|
||||||
if x == GameBoard.ACTION_MENU:
|
if x == GameBoard.ACTION_MENU:
|
||||||
self.state = Settlers.ACTION_MENU
|
self.enter_state(Settlers.ACTION_MENU)
|
||||||
|
|
||||||
if self.state == Settlers.ACTION_MENU:
|
elif self.state == Settlers.ACTION_MENU:
|
||||||
menu = ActionMenu(self.game.player.resources, self.game.dice.total())
|
menu = ActionMenu(self.game.dice.total(), self.old_state != Settlers.ACTION_BUILD_MENU and self.old_state != Settlers.ACTION_TRADE_MENU)
|
||||||
x = menu.run()
|
x = menu.run()
|
||||||
if x == ActionMenu.BACK:
|
if x == ActionMenu.BUILD:
|
||||||
self.state = Settlers.GAME
|
self.enter_state(Settlers.ACTION_BUILD_MENU)
|
||||||
|
if x == ActionMenu.TRADE:
|
||||||
|
self.enter_state(Settlers.ACTION_TRADE_MENU)
|
||||||
if x == ActionMenu.END_TURN:
|
if x == ActionMenu.END_TURN:
|
||||||
self.state = Settlers.END_TURN
|
self.enter_state(Settlers.ACTION_END_TURN)
|
||||||
|
if x == ActionMenu.BACK:
|
||||||
|
self.enter_state(Settlers.GAME)
|
||||||
|
|
||||||
|
elif self.state == Settlers.ACTION_BUILD_MENU:
|
||||||
|
menu = BuildMenu(self.game.player.resources)
|
||||||
|
x = menu.run()
|
||||||
|
if x == BuildMenu.BACK:
|
||||||
|
self.enter_state(Settlers.ACTION_MENU)
|
||||||
# TODO initiate building a thing
|
# TODO initiate building a thing
|
||||||
|
|
||||||
if self.state == Settlers.END_TURN:
|
elif self.state == Settlers.ACTION_TRADE_MENU:
|
||||||
|
menu = TradeMenu(self.game.player.resources)
|
||||||
|
x = menu.run()
|
||||||
|
if x == TradeMenu.BACK:
|
||||||
|
self.enter_state(Settlers.ACTION_MENU)
|
||||||
|
# TODO initiate trading a thing
|
||||||
|
|
||||||
|
elif self.state == Settlers.ACTION_END_TURN:
|
||||||
self.game.next_player()
|
self.game.next_player()
|
||||||
menu = NextPlayer(self.game.player.team)
|
menu = NextPlayer(self.game.player.team)
|
||||||
x = menu.run()
|
x = menu.run()
|
||||||
self.state = Settlers.GAME
|
self.enter_state(Settlers.GAME)
|
||||||
|
|
||||||
# User chose exit, a machine reset is the easiest way :-)
|
# User chose exit, a machine reset is the easiest way :-)
|
||||||
restart_to_default()
|
restart_to_default()
|
||||||
|
|
Loading…
Reference in New Issue