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 game
.util
.stablelist
import stablelist
23 from game
.util
import WorldObject
26 class Storage(WorldObject
):
27 """Class that represent a storage compartment with fixed resources slots
29 Used e.g. by production buildings (e.g. PrimaryProducer)
31 def __init__(self
, **kwargs
):
32 super(Storage
, self
).__init
__(**kwargs
)
33 # inventory: a dict with this pattern: _inventory[res_id] = [amount, size]
36 def addSlot(self
, res_id
, size
):
37 """ Add the possibility to save size amount of res_id
38 @param res_id: id of the resource
39 @param size: maximum amount of res_id that can be stored here; -1 for infinity
41 self
._inventory
[res_id
] = [0, size
]
44 def hasSlot(self
, res_id
):
45 """ Returns wether slot for res_id exists"""
46 return (res_id
in self
._inventory
.keys())
48 def alter_inventory(self
, res_id
, amount
):
49 """Alters the inventory for the resource res_id with amount.
50 @param res_id: int resource_id
51 @param amount: amount that is to be added.
52 @return: amount that couldn't be stored in this storage"""
55 new_amount
= self
._inventory
[res_id
][0] + amount
58 if new_amount
> self
.get_size(res_id
) and self
.get_size(res_id
) != -1:
59 # stuff doesn't fit in inventory
60 ret
= new_amount
- self
.get_size(res_id
)
61 self
._inventory
[res_id
][0] = self
.get_size(res_id
)
65 # trying to take more stuff than inventory contains
67 self
._inventory
[res_id
][0] = 0
71 # new amount is in boundaries
72 self
._inventory
[res_id
][0] = new_amount
76 def get_value(self
, res_id
):
77 """Returns amount of resource res_id in the storage
78 NOTE: this returns "false" value depending on carriages, that are on their way
79 alter_inventory always returns acctual value of res currently in the building
80 @param res_id: int resource_id
81 @return: int amount of resources for res_id in inventory.
84 value
= self
._inventory
[res_id
][0]
86 # subtract/add carriage stuff
88 for carriage in self.building.pickup_carriages:
89 if len(carriage.target) > 0:
90 if carriage.target[1] == res_id:
91 value -= carriage.target[2]
92 for carriage in self.building.local_carriages:
93 if len(carriage.target) > 0:
94 if carriage.target[1] == res_id:
95 value += carriage.target[2]
102 def get_size(self
, res_id
):
103 """ Returns the capacity of the storage for resource res_id
104 @param res_id: int resource_id
106 return self
._inventory
[res_id
][1]
109 return repr(self
._inventory
)
112 return str(self
._inventory
)
114 def save(self
, db
, ownerid
):
115 super(Storage
, self
).save(db
)
116 for (res
, (value
, size
)) in self
._inventory
.iteritems():
117 db("INSERT INTO storage (object, resource, amount) VALUES (?, ?, ?) ",
120 def load(self
, db
, ownerid
):
121 for (res
, amount
) in db("SELECT resource, amount FROM storage WHERE object = ?", ownerid
):
122 self
.alter_inventory(res
, amount
)
125 class ArbitraryStorage(WorldObject
):
126 """Class that represents a storage compartment for ships
127 Storages have a certain number of slots and a certain maximum number of
128 resources that they can store for a certain slot.
130 def __init__(self
, slots
, size
):
131 self
._inventory
= stablelist()
135 def alter_inventory(self
, res_id
, amount
):
136 # try using existing slots
137 for slot
in self
._inventory
:
138 if slot
[0] == res_id
:
139 new_amount
= slot
[1] + amount
143 elif new_amount
> self
.size
:
145 amount
= new_amount
- self
.size
151 # handle stuff that couldn't be handled with existing slots
153 if len(self
._inventory
) < self
.slots
:
154 if amount
> self
.size
:
155 self
._inventory
.append([res_id
, self
.size
])
157 return self
.alter_inventory(res_id
, amount
- self
.size
)
159 self
._inventory
.append([res_id
, amount
])
162 # return what couldn't be added/taken
166 def get_value(self
, res_id
):
168 for slot
in self
._inventory
:
169 if slot
[0] == res_id
:
173 def get_size(self
, res_id
):
174 """This just ensures compatibility with Storage"""
175 ## TODO: if carriage is on the way, ensure that other slots won't get filled
177 for slot
in self
._inventory
:
178 if slot
[0] == res_id
and slot
[1] < self
.size
:
179 size
+= self
.size
- slot
[1]
181 size
+= (self
.slots
- len(self
._inventory
)) * self
.size
184 def save(self
, db
, ownerid
):
185 super(Storage
, self
).save(db
)
186 for slot
in self
._inventory
:
187 db("INSERT INTO storage (object, resource, amount) VALUES (?, ?, ?) ",
188 ownerid
, slot
[0], slot
[1])
190 def load(self
, db
, ownerid
):
191 #super(Storage, self).load(db)
192 for (res
, amount
) in db("SELECT resource, amount FROM storage WHERE object = ?", ownerid
):
193 self
.alter_inventory(res
, amount
)
196 class GenericStorage(object):
197 def __init__(self
, **kwargs
):
198 super(GenericStorage
, self
).__init
__(**kwargs
)
201 def alter(res
, amount
):
202 if res
in self
._storage
:
203 self
._storage
[res
] += amount
205 self
._storage
[res
] = amount
208 def __getitem__(self
, res
):
209 return self
._storage
[res
] if res
in self
._storage
else 0
211 class SpecializedStorage(GenericStorage
):
212 def alter(res
, amount
):
213 return super(SpecializedStorage
, self
).alter(res
, amount
) if res
in self
._storage
else amount
215 def addResourceSlot(res
):
216 super(SpecializedStorage
, self
).alter(res
, 0)
218 def hasResourceSlot(res
):
219 return res
in self
._storage
221 class SizedSpecializedStorage(SpecializedStorage
):
222 def __init__(self
, **kwargs
):
223 super(SizedSpecializedStorage
, self
).__init
__(**kwargs
)
226 def alter(res
, amount
):
227 return amount
- super(SizedSpecializedStorage
, self
).alter(res
, amount
- max(0, amount
+ self
[res
] - self
.__size
.get(res
,0)))
229 def addResourceSlot(res
, size
, **kwargs
):
230 super(SpecializedStorage
, self
).addResourceSlot(res
= res
, size
= size
, **kwargs
)
231 self
.__size
[res
] = size
233 class TotalStorage(GenericStorage
):
234 def __init__(self
, space
, **kwargs
):
235 super(TotalStorage
, self
).__init
__(space
= space
, **kwargs
)
238 def alter(self
, res
, amount
):
239 return amount
- super(TotalStorage
, self
).alter(res
, amount
- max(0, amount
+ sum(self
._storage
.values()) - self
.__space
))
241 class PositiveStorage(GenericStorage
):
242 def alter(res
, amount
):
243 return amount
- super(PositiveStorage
, self
).alter(res
, amount
- min(0, amount
+ self
[res
]))
245 class PositiveTotalStorage(PositiveStorage
, TotalStorage
):
248 class PositiveSizedSpecializedStorage(PositiveStorage
, SizedSpecializedStorage
):