1 # ###################################################
2 # Copyright (C) 2008 The OpenAnno Team
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 provider
import Provider
23 from consumer
import Consumer
24 from game
.world
.units
.unit
import Unit
26 from game
.util
import WeakList
27 from game
.gui
.tabwidget
import TabWidget
28 from game
.world
.building
.building
import Building
31 class PrimaryProducer(Provider
):
32 """Class used for production buildings"""
33 def __init__(self
, **kwargs
):
36 super(PrimaryProducer
, self
).__init
__(**kwargs
)
37 self
.active_production_line
= None
44 for (id,) in game
.main
.db("SELECT rowid FROM data.production_line where %(type)s = ?" % {'type' : 'building' if self
.object_type
== 0 else 'unit'}, self
.id):
45 self
.production
[id] = ProductionLine(id)
47 self
.__used
_resources
= {}
48 self
.toggle_active() # start production
49 if isinstance(self
, Building
):
50 self
.toggle_costs() # needed to get toggle to the right position
52 def toggle_active(self
):
54 print "Toggled inactive"
55 self
.active_production_line
= None
56 if self
.hasChangeListener(self
.check_production_startable
):
57 self
.removeChangeListener(self
.check_production_startable
)
58 game
.main
.session
.scheduler
.rem_call(self
, self
.production_step
)
59 if isinstance(self
, Building
):
62 print "Toggled active"
63 if self
.active_production_line
is None and len(self
.production
) > 0:
64 self
.active_production_line
= min(self
.production
.keys())
65 if self
.active_production_line
is not None:
66 self
.addChangeListener(self
.check_production_startable
)
67 self
.check_production_startable()
68 if isinstance(self
, Building
):
70 self
.active
= (not self
.active
)
74 super(PrimaryProducer
, self
).save(db
)
75 # insert active prodline if it isn't in the db
76 if len(db("SELECT active_production_line FROM production WHERE rowid = ?", self
.getId())) == 0:
77 db("INSERT INTO production(rowid, active_production_line) VALUES(?, ?)", self
.getId(), self
.active_production_line
)
79 def load(self
, db
, worldid
):
80 super(PrimaryProducer
, self
).load(db
, worldid
)
81 active_production_line
= db("SELECT active_production_line FROM production WHERE rowid = ?", worldid
)
82 assert(0 <= len(active_production_line
) <= 1)
83 if len(active_production_line
) == 0:
84 self
.active_production_line
= None
86 self
.active_production_line
= active_production_line
[0][0]
89 def check_production_startable(self
):
90 for res
, amount
in self
.production
[self
.active_production_line
].production
.items():
91 if amount
> 0 and self
.inventory
.get_value(res
) + amount
> self
.inventory
.get_size(res
):
94 if min(self
.production
[self
.active_production_line
].production
.values()) < 0:
95 for res
, amount
in self
.production
[self
.active_production_line
].production
.items():
96 #we have something to work with, if the res is needed, we have something in the inv and we dont already have used everything we need from that resource
97 if amount
< 0 and self
.inventory
.get_value(res
) > 0 and self
.__used
_resources
.get(res
, 0) < -amount
:
98 usable_resources
[res
] = -amount
- self
.__used
_resources
.get(res
, 0)
99 if len(usable_resources
) == 0:
101 time
= int(round(self
.production
[self
.active_production_line
].time
* sum(self
.__used
_resources
.values()) / -sum(p
for p
in self
.production
[self
.active_production_line
].production
.values() if p
< 0)))
104 self
.removeChangeListener(self
.check_production_startable
)
105 for res
, amount
in usable_resources
.items():
106 if res
in self
.__used
_resources
:
107 self
.__used
_resources
[res
] += amount
109 self
.__used
_resources
[res
] = amount
110 for res
, amount
in usable_resources
.items():
111 assert(self
.inventory
.alter_inventory(res
, -amount
) == 0)
112 game
.main
.session
.scheduler
.add_new_object(self
.production_step
, self
, 16 *
113 (self
.production
[self
.active_production_line
].time
if min(self
.production
[self
.active_production_line
].production
.values()) >= 0
114 else (int(round(self
.production
[self
.active_production_line
].time
* sum(self
.__used
_resources
.values()) / -sum(p
for p
in self
.production
[self
.active_production_line
].production
.values() if p
< 0))
116 self
._instance
.act("working", self
._instance
.getFacingLocation(), True)
117 #print self.getId(), "begin working"
119 def production_step(self
):
120 #print self.getId(), "production_step"
121 if sum(self
.__used
_resources
.values()) >= -sum(p
for p
in self
.production
[self
.active_production_line
].production
.values() if p
< 0):
122 for res
, amount
in self
.production
[self
.active_production_line
].production
.items():
124 self
.inventory
.alter_inventory(res
, amount
)
125 self
.__used
_resources
= {}
126 self
._instance
.act("default", self
._instance
.getFacingLocation(), True)
127 self
.addChangeListener(self
.check_production_startable
)
128 self
.check_production_startable()
131 super(PrimaryProducer
, self
).save(db
)
132 db("INSERT INTO producer (rowid, active_production_line) VALUES(?,?)", self
.getId(), self
.active_production_line
)
135 class SecondaryProducer(Consumer
, PrimaryProducer
):
136 """Represents a producer, that consumes ressources for production of other ressources (e.g. blacksmith)"""
140 'building_production_overview': {
141 'toggle_active': self
.toggle_active
144 game
.main
.session
.ingame_gui
.show_menu(TabWidget(4, self
, callbacks
))
147 class ProductionLine(object):
148 def __init__(self
, id):
150 self
.time
= game
.main
.db("SELECT time FROM data.production_line WHERE rowid = ?", self
.id)[0][0]
152 for res
, amount
in game
.main
.db("SELECT resource, amount FROM data.production WHERE production_line = ?", self
.id):
153 self
.production
[res
] = amount