Mercurial > rinkhals
changeset 378:71f5897ac5ef
Fences are now buildings, with appropriate (but ugly) UI changes.
author | Jeremy Thurgood <firxen@gmail.com> |
---|---|
date | Sat, 24 Oct 2009 19:08:54 +0000 |
parents | 0dc9d17c689e |
children | a8a7ada27fa2 |
files | data/cursors/repair_cursor.xbm gamelib/animal.py gamelib/buildings.py gamelib/constants.py gamelib/cursors.py gamelib/gameboard.py |
diffstat | 6 files changed, 149 insertions(+), 82 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/cursors/repair_cursor.xbm Sat Oct 24 19:08:54 2009 +0000 @@ -0,0 +1,29 @@ +/* + * img_data = [ + * "................", + * ".....###........", + * "....####........", + * "...#####........", + * "..#####.........", + * ".#######........", + * "######.##.......", + * ".###.#####......", + * "..#...##.##.....", + * ".......#####....", + * "........##.##...", + * ".........#####..", + * "..........##.##.", + * "...........#####", + * "............##.#", + * ".............##.", + * ] + */ + +#define repair_cursor_width 16 +#define repair_cursor_height 16 +#define repair_cursor_hot_x 4 +#define repair_cursor_hot_y 4 +static unsigned char repair_cursor_bits[] = { + 0x00, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0x7c, 0x00, 0xfe, 0x00, + 0xbf, 0x01, 0xee, 0x03, 0xc4, 0x06, 0x80, 0x0f, 0x00, 0x1b, 0x00, 0x3e, + 0x00, 0x6c, 0x00, 0xf8, 0x00, 0xb0, 0x00, 0x60 };
--- a/gamelib/animal.py Tue Oct 13 20:35:05 2009 +0000 +++ b/gamelib/animal.py Sat Oct 24 19:08:54 2009 +0000 @@ -425,7 +425,7 @@ def _make_hole(self, gameboard): """Make a hole in the fence""" - gameboard.tv.set(self.dig_pos.to_tuple(), gameboard.BROKEN_FENCE) + gameboard.get_building(self.dig_pos.to_tuple()).damage(gameboard.tv) self.dig_pos = None def move(self, gameboard): @@ -505,7 +505,9 @@ def _make_hole(self, gameboard): """The Rinkhals eats fences""" - gameboard.tv.set(self.dig_pos.to_tuple(), gameboard.GRASSLAND) + fence = gameboard.get_building(self.dig_pos.to_tuple()) + fence.remove(gameboard.tv) + gameboard.remove_building(fence) self.dig_pos = None def damage(self, gameboard):
--- a/gamelib/buildings.py Tue Oct 13 20:35:05 2009 +0000 +++ b/gamelib/buildings.py Sat Oct 24 19:08:54 2009 +0000 @@ -64,39 +64,59 @@ GRASSLAND = tiles.REVERSE_TILE_MAP['grassland'] MODIFY_KNIFE_RANGE = lambda s, x: 0 MODIFY_GUN_RANGE = lambda s, x: -1 + BREAKABLE = False + ABODE = False def __init__(self, pos): """Initial image, tile vid position, size and tile number for building.""" - self.day_image = imagecache.load_image(self.IMAGE) - self.night_image = imagecache.load_image(self.IMAGE, ('night',)) - self.selected_image = imagecache.load_image(self.SELECTED_IMAGE) + self._set_images() self.pos = pos self.size = self.SIZE self.tile_no = self.TILE_NO self._buy_price = self.BUY_PRICE self._sell_price = self.SELL_PRICE + self._repair_price = getattr(self, 'REPAIR_PRICE', None) self._sun_on = True self._font = pygame.font.SysFont('Vera', 30, bold=True) - self._font_image = pygame.Surface(self.day_image.get_size(), flags=SRCALPHA) + self._font_image = pygame.Surface(self.images['fixed']['day'].get_size(), flags=SRCALPHA) self._font_image.fill((0, 0, 0, 0)) + self._broken = False self._floors = [] - for f in range(self.FLOORS): - places = [] - for j in range(self.size[1]): - row = [] - for i in range(self.size[0]): - row.append(Place(self, (i, j))) - places.append(row) - floor = Floor("Floor %s" % (f+1,), places) - self._floors.append(floor) + if self.FLOORS: + for f in range(self.FLOORS): + places = [] + for j in range(self.size[1]): + row = [] + for i in range(self.size[0]): + row.append(Place(self, (i, j))) + places.append(row) + floor = Floor("Floor %s" % (f+1,), places) + self._floors.append(floor) - # 0: the main iamge + # 0: the main image # 1: above, -1: below - self.draw_stack = {"main": (0, self.day_image)} + self.draw_stack = {"main": (0, self.images['fixed']['day'])} # Create the building somewhere far off screen - Sprite.__init__(self, self.day_image, (-1000, -1000)) + Sprite.__init__(self, self.images['fixed']['day'], (-1000, -1000)) + + def _set_images(self): + self.images = {'fixed': { + 'day': imagecache.load_image(self.IMAGE), + 'night': imagecache.load_image(self.IMAGE, ('night',)), + 'selected': imagecache.load_image(self.SELECTED_IMAGE), + }} + if self.BREAKABLE: + self.images['broken'] = { + 'day': imagecache.load_image(self.IMAGE_BROKEN), + 'night': imagecache.load_image(self.IMAGE_BROKEN, ('night',)), + 'selected': imagecache.load_image(self.SELECTED_IMAGE_BROKEN), + } + + def _set_main_image(self): + image_set = self.images[{True: 'broken',False: 'fixed'}[self._broken]] + self._replace_main(image_set[{True: 'day', False: 'night'}[self._sun_on]]) def _redraw(self): items = self.draw_stack.values() @@ -168,6 +188,27 @@ return (xpos <= tile_pos[0] < xpos + xsize) and \ (ypos <= tile_pos[1] < ypos + ysize) + def broken(self): + return self._broken + + def damage(self, tv): + if not self.BREAKABLE: + return False + self._broken = True + self._sell_price = self.SELL_PRICE_BROKEN + self.tile_no = self.TILE_NO_BROKEN + for tile_pos in self.tile_positions(): + tv.set(tile_pos, self.tile_no) + self._set_main_image() + + def repair(self, tv): + self._broken = False + self._sell_price = self.SELL_PRICE + self.tile_no = self.TILE_NO + for tile_pos in self.tile_positions(): + tv.set(tile_pos, self.tile_no) + self._set_main_image() + def remove(self, tv): """Remove the building from its current position.""" # remove tile @@ -180,18 +221,18 @@ def sell_price(self): return self._sell_price + def repair_price(self): + return self._repair_price + def selected(self, selected): if selected: - self._replace_main(self.selected_image) + self._replace_main(self.images[{True: 'broken',False: 'fixed'}[self._broken]]['selected']) else: - self.sun(self._sun_on) + self._set_main_image() def sun(self, sun_on): self._sun_on = sun_on - if sun_on: - self._replace_main(self.day_image) - else: - self._replace_main(self.night_image) + self._set_main_image() def update_occupant_count(self): count = len(list(self.occupants())) @@ -234,7 +275,10 @@ if place.occupant is not None: yield place.occupant -class HenHouse(Building): +class Abode(Building): + ABODE = True + +class HenHouse(Abode): """A HenHouse.""" TILE_NO = tiles.REVERSE_TILE_MAP['henhouse'] @@ -258,7 +302,7 @@ NAME = 'Hendominium' FLOORS = 2 -class GuardTower(Building): +class GuardTower(Abode): """A GuardTower.""" TILE_NO = tiles.REVERSE_TILE_MAP['guardtower'] @@ -276,6 +320,25 @@ MODIFY_VISION_BONUS = lambda s, x: x+10 MODIFY_VISION_RANGE_PENALTY = lambda s, x: x-2 +class Fence(Building): + """A fence.""" + + TILE_NO = tiles.REVERSE_TILE_MAP['fence'] + TILE_NO_BROKEN = tiles.REVERSE_TILE_MAP['broken fence'] + BREAKABLE = True + BUY_PRICE = 50 + SELL_PRICE = 25 + REPAIR_PRICE = 25 + SELL_PRICE_BROKEN = 5 + SIZE = (1, 1) + IMAGE = 'tiles/fence.png' + SELECTED_IMAGE = 'tiles/fence.png' + IMAGE_BROKEN = 'tiles/broken_fence.png' + SELECTED_IMAGE_BROKEN = 'tiles/broken_fence.png' + NAME = 'Fence' + FLOORS = 0 + + def is_building(obj): """Return true if obj is a build class.""" return getattr(obj, "IS_BUILDING", False) and hasattr(obj, "NAME")
--- a/gamelib/constants.py Tue Oct 13 20:35:05 2009 +0000 +++ b/gamelib/constants.py Sat Oct 24 19:08:54 2009 +0000 @@ -39,7 +39,7 @@ TOOL_SELL_CHICKEN = 1 TOOL_SELL_EGG = 2 TOOL_SELL_BUILDING = 3 -TOOL_BUY_FENCE = 4 +TOOL_REPAIR_BUILDING = 4 TOOL_PLACE_ANIMALS = 5 TOOL_LOGGING = 6 TOOL_SELL_EQUIPMENT = 7
--- a/gamelib/cursors.py Tue Oct 13 20:35:05 2009 +0000 +++ b/gamelib/cursors.py Sat Oct 24 19:08:54 2009 +0000 @@ -14,6 +14,7 @@ for tag, filename in [ ('chicken', 'cursors/chkn.xbm'), ('sell', 'cursors/sell_cursor.xbm'), + ('repair', 'cursors/repair_cursor.xbm'), ]: path = data.filepath(filename) # pygame 1.8 needs the file twice to do the right thing
--- a/gamelib/gameboard.py Tue Oct 13 20:35:05 2009 +0000 +++ b/gamelib/gameboard.py Sat Oct 24 19:08:54 2009 +0000 @@ -77,13 +77,13 @@ self.add_counter(mklabel("Eggs:"), self.egg_counter) self.add_counter(icons.CHKN_ICON, self.chicken_counter) self.add_counter(icons.KILLED_FOX, self.killed_foxes) - self.add_spacer(15) + self.add_spacer(5) self.add_tool_button("Move Hen", constants.TOOL_PLACE_ANIMALS, None, cursors.cursors['select']) self.add_tool_button("Cut Trees", constants.TOOL_LOGGING, constants.LOGGING_PRICE, cursors.cursors['ball']) - self.add_spacer(15) + self.add_spacer(5) self.add_heading("Sell ...") self.add_tool_button("Chicken", constants.TOOL_SELL_CHICKEN, @@ -94,14 +94,10 @@ None, cursors.cursors['sell']) self.add_tool_button("Equipment", constants.TOOL_SELL_EQUIPMENT, None, cursors.cursors['sell']) - self.add_spacer(15) + self.add_spacer(5) self.add_heading("Buy ...") - self.add_tool_button("Fence", constants.TOOL_BUY_FENCE, - "%s/%s" % (constants.BUY_PRICE_FENCE, - constants.REPAIR_PRICE_FENCE)) - for building_cls in buildings.BUILDINGS: self.add_tool_button(building_cls.NAME.title(), building_cls, None, cursors.cursors.get('build', None)) @@ -112,9 +108,12 @@ equipment_cls.BUY_PRICE, cursors.cursors.get('buy', None)) - self.add_spacer(10) + self.add_spacer(5) + self.add_tool_button("Repair", constants.TOOL_REPAIR_BUILDING, None, cursors.cursors['repair']) + + self.add_spacer(5) self.add_tool("Price Reference", self.show_prices) - self.add_spacer(20) + self.add_spacer(10) self.fin_tool = self.add_tool("Finished Day", self.day_done) @@ -163,32 +162,29 @@ tbl = gui.Table() tbl.tr() - doc = gui.Document(width=380) + doc = gui.Document(width=510) space = doc.style.font.size(" ") - for header in ['Item', 'Buy Price', 'Sell Price']: + for header in ['Item', 'Buy Price', 'Sell Price', 'Repair Price']: doc.add(make_box(header)) doc.br(space[1]) for building in buildings.BUILDINGS: doc.add(make_box(building.NAME)) doc.add(make_box('%d' % building.BUY_PRICE)) doc.add(make_box('%d' % building.SELL_PRICE)) + if building.BREAKABLE: + doc.add(make_box('%d' % building.REPAIR_PRICE)) + else: + doc.add(make_box('N/A')) doc.br(space[1]) for equip in equipment.EQUIPMENT: doc.add(make_box(equip.NAME)) doc.add(make_box('%d' % equip.BUY_PRICE)) doc.add(make_box('%d' % equip.SELL_PRICE)) + doc.add(make_box('N/A')) doc.br(space[1]) - doc.add(make_box("Fence")) - doc.add(make_box('%d' % constants.BUY_PRICE_FENCE)) - doc.add(make_box('%d' % constants.SELL_PRICE_FENCE)) - - doc.add(make_box("Repair Fence")) - doc.add(make_box('%d' % constants.REPAIR_PRICE_FENCE)) - doc.add(make_box('')) - fix_widths(doc) - for word in "Damaged equipment or broken fences will be sold for" \ + for word in "Damaged equipment or buildings will be sold for" \ " less than the sell price.".split(): doc.add(gui.Label(word)) doc.space(space) @@ -385,8 +381,6 @@ sprite_curs = sprite_cursor.SpriteCursor(tool.IMAGE, self.tv, tool.BUY_PRICE) elif equipment.is_equipment(tool): sprite_curs = sprite_cursor.SpriteCursor(tool.CHICKEN_IMAGE_FILE, self.tv) - elif tool == constants.TOOL_BUY_FENCE: - sprite_curs = sprite_cursor.SpriteCursor("tiles/fence.png", self.tv) self.set_cursor(cursor, sprite_curs) def set_cursor(self, cursor=None, sprite_curs=None): @@ -441,12 +435,12 @@ self.sell_egg(self.tv.screen_to_tile(e.pos)) elif self.selected_tool == constants.TOOL_PLACE_ANIMALS: self.place_animal(self.tv.screen_to_tile(e.pos)) - elif self.selected_tool == constants.TOOL_BUY_FENCE: - self.buy_fence(self.tv.screen_to_tile(e.pos)) elif self.selected_tool == constants.TOOL_SELL_BUILDING: self.sell_building(self.tv.screen_to_tile(e.pos)) elif self.selected_tool == constants.TOOL_SELL_EQUIPMENT: self.sell_equipment(self.tv.screen_to_tile(e.pos)) + elif self.selected_tool == constants.TOOL_REPAIR_BUILDING: + self.repair_building(self.tv.screen_to_tile(e.pos)) elif self.selected_tool == constants.TOOL_LOGGING: self.logging_forest(self.tv.screen_to_tile(e.pos)) elif buildings.is_building(self.selected_tool): @@ -540,7 +534,7 @@ pygame.mouse.set_cursor(*cursors.cursors['chicken']) return building = self.get_building(tile_pos) - if building: + if building and building.ABODE: if self.animal_to_place: try: place = building.first_empty_place() @@ -686,33 +680,6 @@ self.open_dialog(tbl, close_callback=close_callback) - def buy_fence(self, tile_pos): - this_tile = self.tv.get(tile_pos) - if this_tile not in [self.GRASSLAND, self.BROKEN_FENCE]: - return - if this_tile == self.GRASSLAND: - cost = constants.BUY_PRICE_FENCE - else: - cost = constants.REPAIR_PRICE_FENCE - if any((chicken.pos.x, chicken.pos.y) == tile_pos for chicken in self.chickens): - return - - if self.cash < cost: - print "You can't afford a fence." - return - self.add_cash(-cost) - self.tv.set(tile_pos, self.FENCE) - - def sell_fence(self, tile_pos): - this_tile = self.tv.get(tile_pos) - if this_tile not in [self.FENCE, self.BROKEN_FENCE]: - return - if this_tile == self.FENCE: - self.add_cash(constants.SELL_PRICE_FENCE) - elif this_tile == self.BROKEN_FENCE: - self.add_cash(constants.SELL_PRICE_BROKEN_FENCE) - self.tv.set(tile_pos, self.GRASSLAND) - def logging_forest(self, tile_pos): if self.tv.get(tile_pos) != self.WOODLAND: return @@ -749,7 +716,7 @@ chicken = self.get_outside_chicken(tile_pos) if chicken is None: building = self.get_building(tile_pos) - if building is None: + if not (building and building.ABODE): return # Bounce through open dialog once more self.open_building_dialog(building, do_equip) @@ -757,8 +724,6 @@ do_equip(chicken) def sell_building(self, tile_pos): - if self.tv.get(tile_pos) in [self.FENCE, self.BROKEN_FENCE]: - return self.sell_fence(tile_pos) building = self.get_building(tile_pos) if building is None: return @@ -770,6 +735,13 @@ building.remove(self.tv) self.remove_building(building) + def repair_building(self, tile_pos): + building = self.get_building(tile_pos) + if not (building and building.broken()): + return + self.add_cash(-building.repair_price()) + building.repair(self.tv) + def sell_equipment(self, tile_pos): x, y = 0, 0 def do_sell(chicken, update_button=None):