Settlers of EMF
Refactor menu drawing to allow menus to customise how choices are drawn. Make the trade menu more sensible to use, showing better the trade costs. Implement simple 4 for 1 trading with the bankmaster
parent
25f35c0518
commit
bdbaa2f62e
|
@ -40,6 +40,7 @@ WOOD = {'kind':2, 'col': ugfx.html_color(0x993300)}
|
||||||
BRICK = {'kind':3, 'col': ugfx.html_color(0xff0000)}
|
BRICK = {'kind':3, 'col': ugfx.html_color(0xff0000)}
|
||||||
ORE = {'kind':4, 'col': ugfx.html_color(0x757575)}
|
ORE = {'kind':4, 'col': ugfx.html_color(0x757575)}
|
||||||
DESERT = {'kind':5, 'col': ugfx.html_color(0xffee55)} # Not really a resource
|
DESERT = {'kind':5, 'col': ugfx.html_color(0xffee55)} # Not really a resource
|
||||||
|
RESOURCE_KINDS = [ SHEEP, WHEAT, WOOD, BRICK, ORE ]
|
||||||
|
|
||||||
|
|
||||||
class State:
|
class State:
|
||||||
|
@ -107,6 +108,18 @@ class Menu(State):
|
||||||
ugfx.text(5, 95, self.question, ugfx.WHITE)
|
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)):
|
||||||
|
self._draw_choice(i, offset)
|
||||||
|
offset = offset + 20
|
||||||
|
if 'cost' in self.choices[i]:
|
||||||
|
offset = offset + 20
|
||||||
|
|
||||||
|
# Set the initial selection
|
||||||
|
if self.is_choice_enabled(self.selection):
|
||||||
|
self._set_selection(self.selection)
|
||||||
|
else:
|
||||||
|
self._set_selection(self._next_valid_selection(self.selection))
|
||||||
|
|
||||||
|
def _draw_choice(self, i, offset):
|
||||||
c = self.choices[i]
|
c = self.choices[i]
|
||||||
col = ugfx.WHITE
|
col = ugfx.WHITE
|
||||||
if 'colour' in c:
|
if 'colour' in c:
|
||||||
|
@ -118,19 +131,18 @@ class Menu(State):
|
||||||
else:
|
else:
|
||||||
text = "{} - {} ".format(i + 1, c['name'])
|
text = "{} - {} ".format(i + 1, c['name'])
|
||||||
ugfx.text(18, offset + self.menu_offset, text, col)
|
ugfx.text(18, offset + self.menu_offset, text, col)
|
||||||
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 + self.menu_offset, 18, 18, cost['resource']['col'])
|
if 'cost_or' in c and c['cost_or']:
|
||||||
ugfx.text((42 * j) + 64, offset + self.menu_offset, "x{} ".format(cost['amount']), col)
|
cost_text = "x{} / ".format(cost['amount'])
|
||||||
offset = offset + 20
|
if j == len(c['cost']) - 1:
|
||||||
|
cost_text = "x{} ".format(cost['amount'])
|
||||||
# Set the initial selection
|
ugfx.area((63 * j) + 45, 21 + offset + self.menu_offset, 16, 16, cost['resource']['col'])
|
||||||
if self.is_choice_enabled(self.selection):
|
ugfx.text((63 * j) + 61, 20 + offset + self.menu_offset, cost_text, col)
|
||||||
self._set_selection(self.selection)
|
|
||||||
else:
|
else:
|
||||||
self._set_selection(self._next_valid_selection(self.selection))
|
ugfx.area((42 * j) + 45, 21 + offset + self.menu_offset, 16, 16, cost['resource']['col'])
|
||||||
|
ugfx.text((42 * j) + 61, 20 + offset + self.menu_offset, "x{} ".format(cost['amount']), col)
|
||||||
|
|
||||||
def initialise(self):
|
def initialise(self):
|
||||||
# Register callbacks
|
# Register callbacks
|
||||||
|
@ -196,10 +208,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] and len(self.choices[self.selection]['cost']) > 0 else 1
|
||||||
ugfx.box(0, self._get_offset_for_selection(self.selection) + self.menu_offset, 240, 20 * size, ugfx.BLACK)
|
ugfx.box(0, self._get_offset_for_selection(self.selection) + self.menu_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] and len(self.choices[self.selection]['cost']) > 0 else 1
|
||||||
ugfx.box(0, self._get_offset_for_selection(self.selection) + self.menu_offset, 240, 20 * size, ugfx.WHITE)
|
ugfx.box(0, self._get_offset_for_selection(self.selection) + self.menu_offset, 240, 20 * size, ugfx.WHITE)
|
||||||
|
|
||||||
def _get_offset_for_selection(self, sel):
|
def _get_offset_for_selection(self, sel):
|
||||||
|
@ -245,7 +257,8 @@ class TeamMenu(Menu):
|
||||||
{'name': "Robot Arms",
|
{'name': "Robot Arms",
|
||||||
'colour': ugfx.html_color(0xeaeaea)},
|
'colour': ugfx.html_color(0xeaeaea)},
|
||||||
{'name': "Null Sector",
|
{'name': "Null Sector",
|
||||||
'colour': ugfx.html_color(0x9c27b0)},
|
'colour': ugfx.html_color(0x9c27b0),
|
||||||
|
'cost': []},
|
||||||
{'name': "Start Game"},
|
{'name': "Start Game"},
|
||||||
{'name': "Back"},
|
{'name': "Back"},
|
||||||
]
|
]
|
||||||
|
@ -319,40 +332,32 @@ class BuildMenu(Menu):
|
||||||
|
|
||||||
class TradeMenu(Menu):
|
class TradeMenu(Menu):
|
||||||
|
|
||||||
options = [
|
BACK = len(RESOURCE_KINDS)
|
||||||
{'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):
|
def __init__(self, resources):
|
||||||
# Disable trade options based on whether the player can afford them
|
# Disable trade options based on whether the player can afford them
|
||||||
for option in TradeMenu.options:
|
options = []
|
||||||
if 'cost' not in option:
|
for i in range(len(RESOURCE_KINDS)):
|
||||||
continue
|
option = {'name': "Buy a", 'resource': RESOURCE_KINDS[i], 'cost': [], 'cost_or': True}
|
||||||
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
|
option['disabled'] = True
|
||||||
super().__init__(None, TradeMenu.options, False)
|
for resource_kind in RESOURCE_KINDS:
|
||||||
|
if resource_kind['kind'] != i:
|
||||||
|
for resource in resources:
|
||||||
|
if resource.resource == resource_kind and resource.quantity >= 4:
|
||||||
|
option['cost'].append({'resource': resource_kind, 'amount': 4})
|
||||||
|
option['disabled'] = False
|
||||||
|
options.append(option)
|
||||||
|
options.append({'name': "Back"})
|
||||||
|
super().__init__(None, options, False)
|
||||||
|
|
||||||
|
def _draw_choice(self, i, offset):
|
||||||
|
super()._draw_choice(i, offset)
|
||||||
|
if i < len(RESOURCE_KINDS):
|
||||||
|
ugfx.area(93, 1 + offset + self.menu_offset, 16, 16, RESOURCE_KINDS[i]['col'])
|
||||||
|
|
||||||
|
|
||||||
class NextPlayer(Menu):
|
class NextPlayer(Menu):
|
||||||
|
|
||||||
START_TURN = 0
|
|
||||||
|
|
||||||
def __init__(self, team):
|
def __init__(self, team):
|
||||||
super().__init__('Pass the badge to next team:', [team], False)
|
super().__init__('Pass the badge to next team:', [team], False)
|
||||||
|
|
||||||
|
@ -455,9 +460,6 @@ class Hex:
|
||||||
self.highlight = highlight
|
self.highlight = highlight
|
||||||
self.changed = True
|
self.changed = True
|
||||||
|
|
||||||
def kind(self):
|
|
||||||
return self.resource['kind']
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_neighbouring_hex_coords(coords, direction):
|
def get_neighbouring_hex_coords(coords, direction):
|
||||||
return [a + b for a, b in zip(coords, Hex.directions[direction])]
|
return [a + b for a, b in zip(coords, Hex.directions[direction])]
|
||||||
|
@ -474,7 +476,7 @@ class Hex:
|
||||||
if self.robber:
|
if self.robber:
|
||||||
ugfx.text(round(self.centre[0] - Hex.size * 0.75), round(self.centre[1] - text_offset), "Rob ", text_colour)
|
ugfx.text(round(self.centre[0] - Hex.size * 0.75), round(self.centre[1] - text_offset), "Rob ", text_colour)
|
||||||
else:
|
else:
|
||||||
if self.kind() != 5:
|
if self.resource != DESERT:
|
||||||
ugfx.text(round(self.centre[0] - text_offset), round(self.centre[1] - text_offset), "{} ".format(self.number['roll']), text_colour)
|
ugfx.text(round(self.centre[0] - text_offset), round(self.centre[1] - text_offset), "{} ".format(self.number['roll']), text_colour)
|
||||||
|
|
||||||
|
|
||||||
|
@ -560,12 +562,6 @@ class Resource():
|
||||||
self.resource = resource
|
self.resource = resource
|
||||||
self.quantity = 0
|
self.quantity = 0
|
||||||
|
|
||||||
def kind(self):
|
|
||||||
return self.resource['kind']
|
|
||||||
|
|
||||||
def colour(self):
|
|
||||||
return self.resource['col']
|
|
||||||
|
|
||||||
def increment(self, num=1):
|
def increment(self, num=1):
|
||||||
self.quantity = self.quantity + num
|
self.quantity = self.quantity + num
|
||||||
|
|
||||||
|
@ -588,14 +584,14 @@ class Player:
|
||||||
|
|
||||||
# Player's hand of resources
|
# Player's hand of resources
|
||||||
self.resources = []
|
self.resources = []
|
||||||
for kind in [SHEEP, WHEAT, WOOD, BRICK, ORE]:
|
for kind in RESOURCE_KINDS:
|
||||||
r = Resource(kind)
|
r = Resource(kind)
|
||||||
self.resources.append(r)
|
self.resources.append(r)
|
||||||
|
|
||||||
# Collect starting resources from the hexes adjacent to our starting settlements
|
# Collect starting resources from the hexes adjacent to our starting settlements
|
||||||
for s in [x for x in self.settlements if x.team == self.team]:
|
for s in [x for x in self.settlements if x.team == self.team]:
|
||||||
for h in s.hexes:
|
for h in s.hexes:
|
||||||
if r.kind() == h.kind():
|
if r.resource == h.resource:
|
||||||
r.increment()
|
r.increment()
|
||||||
|
|
||||||
# Turn number
|
# Turn number
|
||||||
|
@ -628,12 +624,19 @@ class Player:
|
||||||
for h in s.hexes:
|
for h in s.hexes:
|
||||||
if h.number['roll'] == num and not h.robber:
|
if h.number['roll'] == num and not h.robber:
|
||||||
for r in self.resources:
|
for r in self.resources:
|
||||||
if r.kind() == h.kind():
|
if r.resource == h.resource:
|
||||||
if s.contents == Settlement.TOWN:
|
if s.contents == Settlement.TOWN:
|
||||||
r.increment()
|
r.increment()
|
||||||
elif s.contents == Settlement.CITY:
|
elif s.contents == Settlement.CITY:
|
||||||
r.increment(2)
|
r.increment(2)
|
||||||
|
|
||||||
|
def trade(self, buy_kind, sell_kind, sell_amount):
|
||||||
|
for r in self.resources:
|
||||||
|
if r.resource == buy_kind:
|
||||||
|
r.increment()
|
||||||
|
if r.resource == sell_kind:
|
||||||
|
r.decrement(sell_amount)
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
# Player's team and score
|
# Player's team and score
|
||||||
ugfx.text(5, 8, "{} ".format(self.team['name']), self.team['colour'])
|
ugfx.text(5, 8, "{} ".format(self.team['name']), self.team['colour'])
|
||||||
|
@ -645,7 +648,7 @@ class Player:
|
||||||
offset = int(ugfx.width() / len(self.resources))
|
offset = int(ugfx.width() / len(self.resources))
|
||||||
square = int(offset / 3)
|
square = int(offset / 3)
|
||||||
for i in range(len(self.resources)):
|
for i in range(len(self.resources)):
|
||||||
ugfx.area((offset * i) + 1, 295, square, 20, self.resources[i].colour())
|
ugfx.area((offset * i) + 1, 295, square, 20, self.resources[i].resource['col'])
|
||||||
ugfx.text((offset * i) + 1 + square, 295, "{} ".format(self.resources[i].quantity), ugfx.WHITE)
|
ugfx.text((offset * i) + 1 + square, 295, "{} ".format(self.resources[i].quantity), ugfx.WHITE)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1062,12 +1065,18 @@ class Settlers:
|
||||||
x = menu.run()
|
x = menu.run()
|
||||||
if x == TradeMenu.BACK:
|
if x == TradeMenu.BACK:
|
||||||
self.enter_state(Settlers.ACTION_MENU)
|
self.enter_state(Settlers.ACTION_MENU)
|
||||||
# TODO initiate trading a thing
|
else:
|
||||||
|
trade_choice = menu.get_selected_choice()
|
||||||
|
# TODO ask user which resource to trade when they have >= 4 of more than one kind of resource
|
||||||
|
# TODO for now, just trade the first one in the cost list
|
||||||
|
cost = trade_choice['cost'][0]
|
||||||
|
self.game.player.trade(trade_choice['resource'], cost['resource'], cost['amount'])
|
||||||
|
self.enter_state(Settlers.GAME)
|
||||||
|
|
||||||
elif self.state == Settlers.ACTION_END_TURN:
|
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()
|
menu.run()
|
||||||
self.enter_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 :-)
|
||||||
|
|
Loading…
Reference in New Issue