Package horizons :: Package ai :: Module pirate
[hide private]
[frames] | no frames]

Source Code for Module horizons.ai.pirate

  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.ai.aiplayer.behavior import BehaviorManager 
 25  from horizons.ai.aiplayer.behavior.profile import BehaviorProfileManager 
 26  from horizons.ai.aiplayer.combat.combatmanager import PirateCombatManager 
 27  from horizons.ai.aiplayer.combat.unitmanager import UnitManager 
 28  from horizons.ai.aiplayer.strategy.strategymanager import PirateStrategyManager 
 29  from horizons.ai.generic import GenericAI 
 30  from horizons.command.unit import CreateUnit 
 31  from horizons.component.selectablecomponent import SelectableComponent 
 32  from horizons.constants import UNITS 
 33  from horizons.ext.enum import Enum 
 34  from horizons.scheduler import Scheduler 
 35  from horizons.util.python.callback import Callback 
 36  from horizons.util.shapes import Point 
 37  from horizons.util.worldobject import WorldObject 
 38  from horizons.world.units.pirateship import PirateShip 
 39  from horizons.world.units.ship import TradeShip 
40 41 42 -class Pirate(GenericAI):
43 """A pirate ship moving randomly around. If another ship comes into the reach 44 of it, it will be followed for a short time.""" 45 46 # TODO: Move on_a_mission to GenericAI 47 shipStates = Enum.get_extended(GenericAI.shipStates, 'on_a_mission', 'chasing_ship', 'going_home') 48 49 log = logging.getLogger("ai.pirate") 50 regular_player = False 51 52 caught_ship_radius = 5 53 home_radius = 2 54 55 ship_count = 1 56 57 tick_interval = 32 58 tick_long_interval = 128 59
60 - def __init__(self, session, id, name, color, **kwargs):
61 super().__init__(session, id, name, color, **kwargs) 62 63 # choose a random water tile on the coast and call it home 64 self.home_point = self.session.world.get_random_possible_coastal_ship_position() 65 # random sea tile if costal tile not found. Empty map? 66 if not self.home_point: 67 self.home_point = self.session.world.get_random_possible_ship_position() 68 self.log.debug("Pirate: home at (%d, %d), radius %d", self.home_point.x, self.home_point.y, self.home_radius) 69 self.__init() 70 71 # create a ship and place it randomly (temporary hack) 72 for i in range(self.ship_count): 73 self.create_ship_at_random_position() 74 75 Scheduler().add_new_object(Callback(self.tick), self, 1, -1, self.tick_interval) 76 Scheduler().add_new_object(Callback(self.tick_long), self, 1, -1, self.tick_long_interval)
77
78 - def __init(self):
79 self.world = self.session.world 80 self.unit_manager = UnitManager(self) 81 self.combat_manager = PirateCombatManager(self) 82 self.strategy_manager = PirateStrategyManager(self) 83 self.behavior_manager = BehaviorManager(self)
84 85 @staticmethod
86 - def get_nearest_player_ship(base_ship):
87 lowest_distance = None 88 nearest_ship = None 89 for ship in base_ship.find_nearby_ships(): 90 if isinstance(ship, (PirateShip, TradeShip)) or not ship.has_component(SelectableComponent): 91 continue # don't attack these ships 92 distance = base_ship.position.distance(ship.position) 93 if lowest_distance is None or distance < lowest_distance: 94 lowest_distance = distance 95 nearest_ship = ship 96 return nearest_ship
97
98 - def tick(self):
99 self.combat_manager.tick() 100 101 # Temporary function for pirates respawn 102 self.maintain_ship_count()
103
104 - def tick_long(self):
105 self.strategy_manager.tick()
106
107 - def get_random_profile(self, token):
109
111 point = self.session.world.get_random_possible_ship_position() 112 ship = CreateUnit(self.worldid, UNITS.PIRATE_SHIP, point.x, point.y)(issuer=self.session.world.player) 113 self.ships[ship] = self.shipStates.idle 114 self.combat_manager.add_new_unit(ship)
115
116 - def maintain_ship_count(self):
117 if len(list(self.ships.keys())) < self.ship_count: 118 self.create_ship_at_random_position()
119
120 - def save(self, db):
121 super().save(db) 122 db("UPDATE player SET is_pirate = 1 WHERE rowid = ?", self.worldid) 123 db("INSERT INTO pirate_home_point(x, y) VALUES(?, ?)", self.home_point.x, self.home_point.y) 124 125 current_callback = Callback(self.tick) 126 calls = Scheduler().get_classinst_calls(self, current_callback) 127 assert len(calls) == 1, "got {} calls for saving {}: {}".format( 128 len(calls), current_callback, calls) 129 remaining_ticks = max(list(calls.values())[0], 1) 130 131 current_callback_long = Callback(self.tick_long) 132 calls = Scheduler().get_classinst_calls(self, current_callback_long) 133 assert len(calls) == 1, "got {} calls for saving {}: {}".format( 134 len(calls), current_callback_long, calls) 135 remaining_ticks_long = max(list(calls.values())[0], 1) 136 137 db("INSERT INTO ai_pirate(rowid, remaining_ticks, remaining_ticks_long) VALUES(?, ?, ?)", self.worldid, 138 remaining_ticks, remaining_ticks_long) 139 140 for ship in self.ships: 141 ship_state = self.ships[ship] 142 db("INSERT INTO pirate_ships(rowid, state) VALUES(?, ?)", 143 ship.worldid, ship_state.index) 144 145 # save unit manager 146 self.unit_manager.save(db) 147 148 # save combat manager 149 self.combat_manager.save(db) 150 151 # save strategy manager 152 self.strategy_manager.save(db) 153 154 # save behavior manager 155 self.behavior_manager.save(db)
156
157 - def _load(self, db, worldid):
158 super()._load(db, worldid) 159 self.__init() 160 161 remaining_ticks, = db("SELECT remaining_ticks FROM ai_pirate WHERE rowid = ?", worldid)[0] 162 Scheduler().add_new_object(Callback(self.tick), self, remaining_ticks, -1, self.tick_interval) 163 164 remaining_ticks_long, = db("SELECT remaining_ticks_long FROM ai_pirate WHERE rowid = ?", worldid)[0] 165 Scheduler().add_new_object(Callback(self.tick_long), self, remaining_ticks_long, -1, self.tick_interval) 166 167 home = db("SELECT x, y FROM pirate_home_point")[0] 168 self.home_point = Point(home[0], home[1]) 169 170 self.log.debug("Pirate: home at (%d, %d), radius %d", self.home_point.x, self.home_point.y, self.home_radius)
171
172 - def finish_loading(self, db):
173 # load ships one by one from db (ship instances themselves are loaded already, but 174 # we have to use them here) 175 176 for ship_id, state_id in db("SELECT rowid, state FROM pirate_ships"): 177 state = self.shipStates[state_id] 178 ship = WorldObject.get_object_by_id(ship_id) 179 self.ships[ship] = state 180 181 # load unit manager 182 self.unit_manager = UnitManager.load(db, self) 183 184 # load combat manager 185 self.combat_manager = PirateCombatManager.load(db, self) 186 187 # load strategy manager 188 self.strategy_manager = PirateStrategyManager.load(db, self) 189 190 # load BehaviorManager 191 self.behavior_manager = BehaviorManager.load(db, self)
192
193 - def remove_unit(self, unit):
194 """Called when a ship which is owned by the pirate is removed or killed.""" 195 del self.ships[unit] 196 self.combat_manager.remove_unit(unit) 197 self.unit_manager.remove_unit(unit)
198
199 - def end(self):
200 self.strategy_manager.end() 201 super().end()
202