Package horizons :: Package util :: Module uhdbaccessor
[hide private]
[frames] | no frames]

Source Code for Module horizons.util.uhdbaccessor

  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 random 
 23   
 24  from horizons.constants import PATHS, TIER 
 25  from horizons.entities import Entities 
 26  from horizons.i18n import gettext as T 
 27  from horizons.util.dbreader import DbReader 
 28  from horizons.util.python import decorators 
29 30 31 ######################################################################## 32 -class UhDbAccessor(DbReader):
33 """UhDbAccessor is the class that contains the sql code. It is meant 34 to keep all the sql code in a central place, to make it reusable and 35 maintainable. 36 37 It should be used as a utility to remove data access code from places where 38 it doesn't belong, such as game logic. 39 40 Due to historic reasons, sql code is spread over the game code; for now, it is left at 41 places, that are data access routines (e.g. unit/building class).""" 42
43 - def __init__(self, dbfile):
44 super().__init__(dbfile=dbfile)
45 46 # ------------------------------------------------------------------ 47 # Db Access Functions start here 48 # ------------------------------------------------------------------ 49 50 # Resource table 51
52 - def get_res_name(self, id):
53 """Returns the translated name for a specific resource id. 54 @param id: int resource's id, of which the name is returned """ 55 name = self.cached_query("SELECT name FROM resource WHERE id = ?", id)[0][0] 56 return T(name)
57
58 - def get_res_inventory_display(self, id):
59 sql = "SELECT shown_in_inventory FROM resource WHERE id = ?" 60 return self.cached_query(sql, id)[0][0]
61
62 - def get_res_value(self, id):
63 """Returns the resource's value 64 @param id: resource id 65 @return: float value""" 66 return self.cached_query("SELECT value FROM resource WHERE id = ?", id)[0][0]
67
68 - def get_res(self, only_tradeable=False, only_inventory=False):
69 """Returns a list of all resources. 70 @param only_tradeable: return only those you can trade. 71 @param only_inventory: return only those displayed in inventories. 72 @return: list of resource ids""" 73 sql = "SELECT id FROM resource WHERE id" 74 if only_tradeable: 75 sql += " AND tradeable = 1" 76 if only_inventory: 77 sql += " AND shown_in_inventory = 1" 78 db_data = self.cached_query(sql) 79 return [x[0] for x in db_data]
80 81 # Sound table 82
83 - def get_sound_file(self, soundname):
84 """ 85 Returns the soundfile to the related sound name. 86 @param sound: string, key in table sounds_special 87 """ 88 sql = 'SELECT file FROM sounds \ 89 INNER JOIN sounds_special ON sounds.id = sounds_special.sound AND \ 90 sounds_special.type = ?' 91 return self.cached_query(sql, soundname)[0][0]
92 93 # Building table 94 95 @decorators.cachedmethod 103 104 @decorators.cachedmethod 113 114 @decorators.cachedmethod 122 123 @decorators.cachedmethod 128 129 # Messages 130
131 - def get_msg_visibility(self, msg_id_string):
132 """ 133 @param msg_id_string: string id of the message 134 @return: int: for how long in seconds the message will stay visible 135 """ 136 sql = "SELECT visible_for FROM message WHERE id_string = ?" 137 return self.cached_query(sql, msg_id_string)[0][0]
138
139 - def get_msg_text(self, msg_id_string):
140 """ 141 @param msg_id_string: string id of the message 142 """ 143 sql = "SELECT text FROM message_text WHERE id_string = ?" 144 return self.cached_query(sql, msg_id_string)[0][0]
145
146 - def get_msg_icon_id(self, msg_id_string):
147 """ 148 @param msg_id_string: string id of the message 149 @return: int: id 150 """ 151 sql = "SELECT icon FROM message where id_string = ?" 152 return self.cached_query(sql, msg_id_string)[0][0]
153
154 - def get_msg_icon_path(self, msg_id_string):
155 """ 156 @param msg_id_string: string id of the message 157 @return: str: path attribute to message icon suitable for ImageButton 158 """ 159 sql = "SELECT path FROM message_icon WHERE icon_id = ?" 160 return self.cached_query(sql, msg_id_string)[0][0]
161 162 # 163 # 164 # Inhabitants 165 # 166 # 167
168 - def get_settler_name(self, level):
169 """Returns the name of inhabitants for a specific tier. 170 @param level: int - which tier 171 @return: string - inhabitant name""" 172 sql = "SELECT name FROM tier WHERE level = ?" 173 return self.cached_query(sql, level)[0][0]
174
175 - def get_settler_house_name(self, level):
176 """Returns name of the residential building for a specific tier 177 @param level: int - which tier 178 @return: string - housing name""" 179 sql = "SELECT residential_name FROM tier WHERE level = ?" 180 return self.cached_query(sql, level)[0][0]
181
182 - def get_settler_tax_income(self, level):
183 sql = "SELECT tax_income FROM tier WHERE level = ?" 184 return self.cached_query(sql, level)[0][0]
185
186 - def get_tier_inhabitants_max(self, level):
187 """Returns the upper limit of inhabitants per house for a specific tier. 188 Inhabitants will try to increase their tier upon exceeding this value. 189 @param level: int - which tier 190 """ 191 sql = "SELECT inhabitants_max FROM tier WHERE level = ?" 192 return self.cached_query(sql, level)[0][0]
193
194 - def get_tier_inhabitants_min(self, level):
195 """Returns the lower limit of inhabitants per house for a specific tier. 196 This limit coincides with the max. amount of the previous tier. 197 Inhabitants will decrease their tier after falling below. 198 @param level: int - which tier 199 """ 200 if level == TIER.LOWEST: 201 return 0 202 else: 203 sql = "SELECT inhabitants_max FROM tier WHERE level = ?" 204 return self.cached_query(sql, level - 1)[0][0]
205
207 sql = "SELECT value FROM balance_values WHERE name='happiness_inhabitants_increase_requirement'" 208 return self.cached_query(sql)[0][0]
209
211 sql = "SELECT value FROM balance_values WHERE name='happiness_inhabitants_decrease_limit'" 212 return self.cached_query(sql)[0][0]
213 214 # Misc 215
216 - def get_player_start_res(self):
217 """Returns resources, that players should get at startup as dict: { res : amount }""" 218 start_res = self.cached_query("SELECT resource, amount FROM player_start_res") 219 return dict(start_res)
220 221 @decorators.cachedmethod
222 - def get_storage_building_capacity(self, storage_type):
223 """Returns the amount that a storage building can store of every resource. 224 @param storage_type: building class id""" 225 sql = "SELECT size FROM storage_building_capacity WHERE type = ?" 226 return self.cached_query(sql, storage_type)[0][0]
227
228 - def get_random_ai_name(self, locale, used_names):
229 """Returns a random name compatible with the given locale. If there are 230 no unused names left, None is returned. 231 """ 232 used_names_placeholder = ', '.join(['?'] * len(used_names)) 233 sql = "SELECT name FROM ainames \ 234 WHERE name NOT IN ({0}) AND \ 235 (locale IS NULL OR locale = ?) \ 236 ORDER BY random() \ 237 LIMIT 1".format(used_names_placeholder) 238 params = used_names 239 params.append(locale) 240 return self(sql, *params)[0][0]
241 242 # Tile sets 243
244 - def get_random_tile_set(self, ground_id):
245 """Returns a tile set for a tile of type ground_id""" 246 sql = "SELECT set_id FROM tile_set WHERE ground_id = ?" 247 db_data = self.cached_query(sql, ground_id) 248 return random.choice(db_data)[0] if db_data else None
249 250 @decorators.cachedmethod
252 """Returns building types that should become translucent on demand""" 253 # use set because of quick contains check 254 return frozenset(id for (id, b) in Entities.buildings.items() if b.translucent)
255 256 # Weapon table 257
258 - def get_weapon_stackable(self, weapon_id):
259 """Returns True if the weapon is stackable, False otherwise.""" 260 return self.cached_query("SELECT stackable FROM weapon WHERE id = ?", weapon_id)[0][0]
261
262 - def get_weapon_attack_radius(self, weapon_id):
263 """Returns weapon's attack radius modifier.""" 264 return self.cached_query("SELECT attack_radius FROM weapon WHERE id = ?", weapon_id)[0][0]
265 266 # Units 267
268 - def get_unit_type_name(self, type_id):
269 """Returns the name of a unit type identified by its type""" 270 return Entities.units[type_id].name
271
272 - def get_unit_tooltip(self, unit_id):
273 """Tries to identify unit properties to display as tooltip. 274 #TODO Should be extended later to also include movement speed, etc.""" 275 helptexts = [] # collects all information we will find 276 unit = Entities.units[unit_id] 277 try: 278 comp = unit.get_component_template('StorageComponent') 279 storage = comp['PositiveTotalNumSlotsStorage'] 280 # Ship storage properties 281 helptext = T('{slotnum} slots, {limit}t') 282 helptext = helptext.format(slotnum=storage['slotnum'], 283 limit=storage['limit']) 284 helptexts.append(helptext) 285 except KeyError: # Component not found, ignore this part 286 pass 287 try: 288 comp = unit.get_component_template('HealthComponent') 289 helptext = T('Health: {health}') 290 helptext = helptext.format(health=comp['maxhealth']) 291 helptexts.append(helptext) 292 except KeyError: # Component not found, ignore this part 293 pass 294 return '\\n'.join(helptexts)
295
296 297 -def read_savegame_template(db):
298 with open(PATHS.SAVEGAME_TEMPLATE, "r") as f: 299 db.execute_script(f.read())
300