Package horizons :: Package world :: Package disaster :: Module disastermanager
[hide private]
[frames] | no frames]

Source Code for Module horizons.world.disaster.disastermanager

  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 logging 
 23   
 24  from horizons.constants import GAME_SPEED 
 25  from horizons.scheduler import Scheduler 
 26  from horizons.util.worldobject import WorldObject 
 27  from horizons.world.disaster.blackdeathdisaster import BlackDeathDisaster 
 28  from horizons.world.disaster.firedisaster import FireDisaster 
 29   
 30   
31 -class DisasterManager:
32 """The disaster manager manages disasters. It seeds them into the 33 game world and makes all requirements for a disaster are met before 34 seeding it.""" 35 log = logging.getLogger("world.disaster") 36 37 # Number of ticks between calls to run() 38 CALL_EVERY = GAME_SPEED.TICKS_PER_SECOND * 60 39 #CALL_EVERY = 1 # to conjure the demons of armageddon 40
41 - def __init__(self, session, disabled=False):
42 """ 43 @param disabled: Don't do anything at all if True (but be responsive to normal calls)""" 44 from horizons.session import Session 45 assert isinstance(session, Session) 46 self.session = session 47 self.disabled = disabled 48 # List of possible disaster classes 49 self.disasters = [FireDisaster, BlackDeathDisaster] 50 51 # Mapping settlement -> active disasters 52 self._active_disaster = {} 53 54 # keep call also when disabled, simplifies save/load 55 Scheduler().add_new_object(self.run, self, run_in=self.CALL_EVERY, loops=-1)
56
57 - def save(self, db):
58 ticks = Scheduler().get_remaining_ticks(self, self.run, True) 59 db("INSERT INTO disaster_manager(remaining_ticks) VALUES(?)", ticks) 60 for disaster in self._active_disaster.values(): 61 disaster.save(db)
62
63 - def load(self, db):
64 db_data = db("SELECT remaining_ticks FROM disaster_manager") 65 if db_data: 66 Scheduler().rem_all_classinst_calls(self) 67 ticks = db_data[0][0] # only one row in table 68 Scheduler().add_new_object(self.run, self, run_in=ticks, 69 loop_interval=self.CALL_EVERY, loops=-1) 70 71 for disaster_id, disaster_type, settlement_id in db("SELECT rowid, type, settlement FROM disaster"): 72 settlement = WorldObject.get_object_by_id(settlement_id) 73 klass = next((i for i in self.disasters if i.TYPE == disaster_type)) 74 cata = klass(settlement, self) 75 self._active_disaster[settlement] = cata 76 cata.load(db, disaster_id)
77
78 - def run(self):
79 if self.disabled: 80 return 81 for settlement in self.session.world.settlements: 82 for disaster in self.disasters: 83 if settlement not in self._active_disaster: 84 if self.session.random.random() <= disaster.SEED_CHANCE: 85 if disaster.can_breakout(settlement): 86 self.log.debug("Seeding disaster: %s", disaster) 87 cata = disaster(settlement, self) 88 cata.breakout() 89 self._active_disaster[settlement] = cata 90 else: 91 self.log.debug("Disaster %s would breakout apply but can't breakout", 92 disaster)
93
94 - def end_disaster(self, settlement):
95 # End the disaster 96 self.log.debug("ending desaster in %s", settlement) 97 self._active_disaster[settlement].end() 98 del self._active_disaster[settlement]
99
100 - def is_affected(self, settlement):
101 """Returns whether there is currently a disaster in a settlement""" 102 return settlement in self._active_disaster
103
104 - def get_disaster(self, settlement):
105 """Returns the currently active disaster for the given settlement. None is 106 returned in case no disaster is currently active.""" 107 if self.is_affected(settlement): 108 return self._active_disaster[settlement] 109 return None
110