* Better Patch for Configfile handling
[opeanno-debian-packaging.git] / game / world / building / settler.py
blobef421ab27f2f692fcef29b359a1a3ad8ecbe37b8
1 # ###################################################
2 # Copyright (C) 2008 The OpenAnno Team
3 # team@openanno.org
4 # This file is part of OpenAnno.
6 # OpenAnno 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.
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.
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 # ###################################################
22 from building import Building, Selectable
23 from game.world.consumer import Consumer
24 from game.gui.tabwidget import TabWidget
25 import game.main
26 from buildable import BuildableSingle
27 from game.util import WeakList
28 from random import randint
30 class Settler(Selectable, BuildableSingle, Consumer, Building):
31 """Represents a settlers house, that uses resources and creates inhabitants."""
32 def __init__(self, x, y, owner, instance = None, level=1, **kwargs):
33 self.level = level
34 super(Settler, self).__init__(x=x, y=y, owner=owner, instance=instance, level=level, **kwargs)
35 self.__init()
36 self.run()
38 def create_carriage(self):
39 self.local_carriages.append(game.main.session.entities.units[8](self))
40 ## NOTE: unit 2 requires no roads, which makes testing easier. change to 8 for release.
41 #self.local_carriages.append(game.main.session.entities.units[2](self))
43 def __init(self):
44 print self.id, "Settler debug, inhabitants_max:", self.inhabitants_max
45 self.tax_income = game.main.db("SELECT tax_income FROM settler_level WHERE level=?", self.level)[0][0]
46 print self.id, "Settler debug, tax_income:", self.tax_income
47 self.inventory.limit = 1
48 self.consumation = {}
49 for (res, speed) in game.main.db("SELECT res_id, consume_speed FROM settler_consumation WHERE level = ?", self.level):
50 self.consumation[res] = {'consume_speed': speed, 'consume_state': 0, 'consume_contentment': 0 , 'next_consume': game.main.session.timer.get_ticks(speed)/10}
51 """consume_speed: generel time a consumed good lasts, until a new ton has to be consumed. In seconds.
52 consume_state: 0-10 state, on 10 a new good is consumed or contentment drops, if no new good is in the inventory.
53 consume_contentment: 0-10 state, showing how fullfilled the wish for the specified good is.
54 next_consume: nr. of ticks until the next consume state is set(speed in tps / 10)"""
56 def run(self):
57 game.main.session.scheduler.add_new_object(self.consume, self, loops=-1) # Check consumation every tick
58 game.main.session.scheduler.add_new_object(self.pay_tax, self, runin=game.main.session.timer.get_ticks(30), loops=-1) # pay tax every 30 seconds
59 game.main.session.scheduler.add_new_object(self.inhabitant_check, self, runin=game.main.session.timer.get_ticks(30), loops=-1) # Check if inhabitants in/de-crease
60 self.contentment_max = len(self.consumation)*10 # TODO: different goods have to have different values
62 def consume(self):
63 """Methode that handles the building's consumation. It is called every tick."""
64 for (res, row) in self.consumation.iteritems():
65 if row['next_consume'] > 0: # count down till next consume is scheduled
66 row['next_consume'] -= 1
67 else:
68 if row['consume_state'] < 10:
69 row['consume_state'] += 1 # count to 10 to simulate partly consuming a resource over time
70 if row['consume_state'] == 10: # consume a resource if available
71 if self.inventory[res] > 0:
72 print self.id, 'Settler debug: consuming res:', res
73 row['consume_state'] = 0
74 self.inventory.alter(res, -1) # consume resource
75 row['consume_contentment'] = 10
76 else:
77 if row['consume_contentment'] > 0:
78 row['consume_contentment'] -= 1
79 row['next_consume'] = game.main.session.timer.get_ticks(row["consume_speed"])/10
81 def pay_tax(self):
82 """Pays the tax for this settler"""
83 self.settlement.owner.inventory.alter(1,self.tax_income*self.inhabitants)
84 print self.id, 'Settler debug: payed tax:', self.tax_income*self.inhabitants, 'new player gold:', self.settlement.owner.inventory[1]
86 def inhabitant_check(self):
87 """Checks weather or not the population of this settler should increase or decrease or stay the same."""
88 if sum([self.consumation[i]['consume_contentment'] for i in self.consumation]) == self.contentment_max:
89 content = 1
90 else:
91 content = 0
92 if self.inhabitants < self.inhabitants_max:
93 addition = randint(-1,1) + content
94 addition = min(self.inhabitants_max, max(1, self.inhabitants + addition)) - self.inhabitants
95 self.inhabitants += addition
96 self.settlement.add_inhabitants(addition)
98 def _Consumer__init(self):
99 """Part of initiation that __init__() and load() share
100 NOTE: This function is only for the consumer class, the settler class needs to be a consumer,
101 but without production lines, which is why this has to be overwritten."""
102 self._Consumer__resources = {0: []} #ugly work arround to work with current consumer implementation
103 self.local_carriages = []
105 from game.world.building.building import Building
106 if isinstance(self, Building):
107 self.radius_coords = self.position.get_radius_coordinates(self.radius)
109 self._Consumer__collectors = WeakList()
110 for (res,) in game.main.db("SELECT res_id FROM settler_consumation WHERE level = ?", self.level):
111 print "Settler debug, res:", res
112 self._Consumer__resources[0].append(res)
114 def show_menu(self):
115 game.main.session.ingame_gui.show_menu(TabWidget(2, self))
117 def get_consumed_res(self):
118 """Returns list of resources, that the building uses, without
119 considering, if it currently needs them
121 return self._Consumer__resources[0]
123 def save(self, db):
124 super(Settler, self).save(db)
125 db("INSERT INTO settler(rowid, level) VALUES (?, ?)", self.getId(), self.level)
126 for (res, row) in self.consumation.iteritems():
127 db("INSERT INTO settler_consume(settler_id, res, contentment, next_consume, consume_state) VALUES (?, ?, ?, ?, ?)", self.getId(), res, row['consume_contentment'], row['next_consume'], row['consume_state'])
129 def load(self, db, building_id):
130 self.level = db("SELECT level FROM settler WHERE rowid=?", building_id)[0][0]
131 super(Settler, self).load(db, building_id)
132 self.__init()
133 for (res, contentment, next_consume, consume_state) in db("SELECT res, contentment, next_consume, consume_state FROM settler_consume WHERE settler_id=?", self.getId()):
134 self.consumation[res]['consume_contentment'] = contentment
135 self.consumation[res]['next_consume'] = next_consume
136 self.consumation[res]['consume_state'] = consume_state
137 self.run()