Package horizons :: Package world :: Module ground
[hide private]
[frames] | no frames]

Source Code for Module horizons.world.ground

  1  # ################################################### 
  2  # Copyright (C) 2008-2017 The Unknown Horizons Team 
  3  # team@unknown-horizons.org 
  4  # This file is part of Unknown Horizons. 
  5  # 
  6  # Unknown Horizons is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the 
 18  # Free Software Foundation, Inc., 
 19  # 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 20  # ################################################### 
 21   
 22  import logging 
 23   
 24  from fife import fife 
 25   
 26  import horizons.globals 
 27  from horizons.constants import GROUND, LAYERS 
 28  from horizons.util.loaders.tilesetloader import TileSetLoader 
29 30 31 -class SurfaceTile:
32 is_water = False 33 layer = LAYERS.GROUND 34 35 __slots__ = ('x', 'y', 'settlement', 'blocked', 'object', 'session', '_instance', '_tile_set_id') 36
37 - def __init__(self, session, x, y):
38 """ 39 @param session: Session instance 40 @param x: int x position the ground is created. 41 @param y: int y position the ground is created. 42 """ 43 self.x = x 44 self.y = y 45 46 self.settlement = None 47 self.blocked = False 48 self.object = None 49 self.session = session 50 self._tile_set_id = horizons.globals.db.get_random_tile_set(self.id) 51 52 layer = session.view.layers[self.layer] 53 # actualy this should be x + 0.5, y + 0.5, since that's the center of the tile area 54 # however, other code depends on the current alignment. 55 # it this is changed, it should also be changed for buildings and units 56 self._instance = layer.createInstance(self._fife_objects[self._tile_set_id], 57 fife.ExactModelCoordinate(x, y, 0), 58 "") 59 fife.InstanceVisual.create(self._instance)
60
61 - def __str__(self):
62 return ("SurfaceTile(id={}, shape={}, x={}, y={}, water={}, obj={})" 63 .format(self.id, self.shape, self.x, self.y, self.is_water, self.object))
64
65 - def act(self, rotation):
66 self._instance.setRotation(rotation)
67 68 @property
69 - def rotation(self):
70 # workaround for FIFE's inconsistent rotation rounding 71 return int(round(self._instance.getRotation() / 45.0)) * 45
72
73 74 -class Ground(SurfaceTile):
75 """Default land surface""" 76 pass
77
78 79 -class Water(SurfaceTile):
80 """Default water surface""" 81 is_water = True 82 layer = LAYERS.WATER
83
84 85 -class WaterDummy(Water):
86 - def __init__(self, session, x, y):
87 # no super call, we don't have an instance 88 self.x = x 89 self.y = y 90 91 self.settlement = None 92 self.blocked = False 93 self.object = None
94
95 96 -class GroundClass(type):
97 """ 98 @param id: ground id. 99 """ 100 log = logging.getLogger('world') 101
102 - def __init__(self, db, id, shape):
103 """ 104 @param id: id in db for this specific ground class 105 @param db: DbReader instance to get data from 106 """ 107 self.id = id 108 self.shape = shape 109 self._fife_objects = None 110 self.velocity = {} 111 self.classes = ['ground[' + str(id) + ']'] 112 for (name,) in db("SELECT class FROM ground_class WHERE ground = ?", id): 113 self.classes.append(name) 114 if id != -1 : 115 self._loadObject(db)
116
117 - def __new__(self, db, id, shape):
118 """ 119 @param id: ground id. 120 @param shape: ground shape (straight, curve_in, curve_out). 121 """ 122 if id == GROUND.WATER[0]: 123 return type.__new__(self, 'Ground[{:d}-{}]'.format(id, shape), (Water,), {}) 124 elif id == -1: 125 return type.__new__(self, 'Ground[{:d}-{}]'.format(id, shape), (WaterDummy,), {}) 126 else: 127 return type.__new__(self, 'Ground[{:d}-{}]'.format(id, shape), (Ground,), {})
128
129 - def _loadObject(cls, db):
130 """Loads the ground object from the db (animations, etc)""" 131 cls._fife_objects = {} 132 tile_sets = TileSetLoader.get_sets() 133 model = horizons.globals.fife.engine.getModel() 134 load_image = horizons.globals.fife.animationloader.load_image 135 tile_set_data = db("SELECT set_id FROM tile_set WHERE ground_id=?", cls.id) 136 for tile_set_row in tile_set_data: 137 tile_set_id = str(tile_set_row[0]) 138 cls_name = '{:d}-{}'.format(cls.id, cls.shape) 139 cls.log.debug('Loading ground %s', cls_name) 140 fife_object = None 141 try: 142 fife_object = model.createObject(cls_name, 'ground_' + tile_set_id) 143 except fife.NameClash: 144 cls.log.debug('Already loaded ground %d-%s', cls.id, cls.shape) 145 fife_object = model.getObject(cls_name, 'ground_' + tile_set_id) 146 return 147 148 fife.ObjectVisual.create(fife_object) 149 visual = fife_object.get2dGfxVisual() 150 for rotation, data in tile_sets[tile_set_id][cls.shape].items(): 151 if not data: 152 raise KeyError('No data found for tile set `{}` in rotation `{}`. ' 153 'Most likely the shape `{}` is missing.' 154 .format(tile_set_id, rotation, cls.shape)) 155 if len(data) > 1: 156 raise ValueError('Currently only static tiles are supported. ' 157 'Found this data for tile set `{}` in rotation `{}`: ' 158 '{}'.format(tile_set_id, rotation, data)) 159 img = load_image(list(data.keys())[0], tile_set_id, cls.shape, str(rotation)) 160 # make the drawing origin correspond with the center of the groundpart of the image 161 # (instead of the center of the image) 162 img.setYShift(int(img.getWidth() / 4 - img.getHeight() / 2)) 163 visual.addStaticImage(rotation, img.getHandle()) 164 165 # Save the object 166 cls._fife_objects[tile_set_id] = fife_object
167
168 169 -class MapPreviewTile:
170 """This class provides the minimal tile implementation for map preview.""" 171
172 - def __init__(self, x, y, id):
173 super().__init__() # TODO: check if this call is needed 174 self.x = x 175 self.y = y 176 self.id = id 177 self.classes = () 178 self.settlement = None
179