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

Source Code for Module horizons.world.production.unitproduction

  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  from horizons.constants import PRODUCTION, RES 
 23  from horizons.scheduler import Scheduler 
 24  from horizons.world.production.production import ChangingProduction 
25 26 27 -class UnitProduction(ChangingProduction):
28 """Production, that produces units.""" 29 uses_gold = True 30 keep_original_prod_line = True 31 32 @property
33 - def progress(self):
34 get_amount = lambda items: sum(amount for res, amount in items.items() if res != RES.GOLD) 35 36 still_needed = get_amount(self._prod_line.consumed_res) 37 all_needed = get_amount(self.original_prod_line.consumed_res) 38 return 1 - float(still_needed) / all_needed
39 40 ## PROTECTED METHODS
41 - def _get_producing_callback(self):
42 return self._produce
43
44 - def _check_available_res(self):
45 # Gold must be available from the beginning 46 if self._prod_line.consumed_res.get(RES.GOLD, 0) > 0: # check if gold is needed 47 amount = self._prod_line.consumed_res[RES.GOLD] 48 for res, amount in self._prod_line.consumed_res.items(): 49 # we change the production, so the amount can become 0 50 # in this case, we must no consider this resource, as it has already been fully provided 51 if amount == 0: 52 continue # nothing to take here 53 if res == RES.GOLD: 54 if self.owner_inventory[RES.GOLD] > 0: 55 return True 56 elif self.inventory[res] > 0: 57 return True 58 return False
59
60 - def _remove_res_to_expend(self, return_without_gold=False):
61 """Takes as many res as there are and returns sum of amount of res taken. 62 @param return_without_gold: return not an integer but a tuple, where the second value is without gold""" 63 taken = 0 64 taken_without_gold = 0 65 for res, amount in self._prod_line.consumed_res.items(): 66 if res == RES.GOLD: 67 inventory = self.owner_inventory 68 else: 69 inventory = self.inventory 70 remnant = inventory.alter(res, amount) # try to get all 71 self._prod_line.change_amount(res, remnant) # set how much we still need to get 72 if return_without_gold and res != RES.GOLD: 73 taken_without_gold += abs(remnant) + amount 74 taken += abs(remnant) + amount 75 if return_without_gold: 76 return (taken, taken_without_gold) 77 else: 78 return taken
79
80 - def _produce(self):
81 # check if we're done 82 still_needed_res = sum(self._prod_line.consumed_res.values()) 83 if still_needed_res == 0: 84 self._finished_producing() 85 return 86 87 removed_res, removed_res_without_gold = self._remove_res_to_expend(return_without_gold=True) 88 # check if there were res 89 if removed_res == 0: 90 # watch inventory for new res 91 self.inventory.add_change_listener(self._check_inventory) 92 if self.__class__.uses_gold: 93 self.owner_inventory.add_change_listener(self._check_inventory) 94 self._state = PRODUCTION.STATES.waiting_for_res 95 self._changed() 96 return 97 98 # calculate how much of the whole production process we can produce now 99 # and set the scheduler waiting time accordingly (e.g. half of res => wait half of prod time) 100 all_needed_res = sum(amount for res, amount in self.original_prod_line.consumed_res.items() 101 if res != RES.GOLD) 102 part_of_whole_production = float(removed_res_without_gold) / all_needed_res 103 prod_time = Scheduler().get_ticks(part_of_whole_production * self._prod_line.time) 104 prod_time = max(prod_time, 1) # wait at least 1 tick 105 # do part of production and call this again when done 106 Scheduler().add_new_object(self._produce, self, prod_time)
107
108 - def _finished_producing(self, **kwargs):
109 super()._finished_producing(continue_producing=False, **kwargs) 110 self._state = PRODUCTION.STATES.done 111 # reset prodline 112 self._prod_line = self._prod_line.get_original_copy()
113