Package horizons :: Package ai :: Package aiplayer :: Package strategy :: Package mission
[hide private]
[frames] | no frames]

Source Code for Package horizons.ai.aiplayer.strategy.mission

  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.mission import Mission 
 25  from horizons.ext.enum import Enum 
 26  from horizons.util.python.callback import Callback 
 27  from horizons.util.worldobject import WorldObject 
28 29 30 -class FleetMission(Mission):
31 32 missionStates = Enum('created', 'fleeing_home') 33 34 # db_table name has to be overwritten by the concrete mission 35 36 log = logging.getLogger("ai.aiplayer.fleetmission") 37
38 - def __init__(self, success_callback, failure_callback, ships):
39 assert ships, "Attempt to create a fleet mission out of 0 ships" 40 super().__init__(success_callback, failure_callback, ships[0].owner) 41 self.__init() 42 self._init_fleet(ships)
43
44 - def __init(self):
45 self.unit_manager = self.owner.unit_manager 46 self.session = self.owner.session 47 self.strategy_manager = self.owner.strategy_manager 48 self.combat_phase = False 49 self.state = self.missionStates.created 50 self._setup_state_callbacks()
51
52 - def _setup_state_callbacks(self):
53 """This function can be overwritten to setup mission specific callbacks""" 54 # combatIntermissions states which function should be called after combat phase was finished (winning or losing). 55 # each combatIntermission entry should provide both, It is the CombatManager that decides which function to call 56 # Dictionary of type: missionState => (won_function, lost_function) 57 self.combatIntermissions = {} 58 59 # _state_fleet_callbacks states which callback is supposed to be called by the fleet when it reaches the target point 60 # based on given mission state. Used when changing mission (initiating new mission phase) states and loading game (restarting mission from given state) 61 # Dictionary of type: missionState => Callback object 62 self._state_fleet_callbacks = {}
63
64 - def _init_fleet(self, ships):
65 self.fleet = self.unit_manager.create_fleet(ships=ships, destroy_callback=Callback(self.cancel, "All ships were destroyed")) 66 for ship in self.fleet.get_ships(): 67 self.owner.ships[ship] = self.owner.shipStates.on_a_mission
68
69 - def save(self, db):
70 super().save(db) 71 db("INSERT INTO ai_fleet_mission (rowid, owner_id, fleet_id, state_id, combat_phase) VALUES(?, ?, ?, ?, ?)", self.worldid, 72 self.owner.worldid, self.fleet.worldid, self.state.index, self.combat_phase)
73 74 @classmethod
75 - def load(cls, worldid, owner, db, success_callback, failure_callback):
76 self = cls.__new__(cls) 77 self._load(worldid, owner, db, success_callback, failure_callback) 78 self._initialize_mission() 79 return self
80
81 - def _load(self, db, worldid, success_callback, failure_callback, owner):
82 super().load(db, worldid, success_callback, failure_callback, owner) 83 self.__init() 84 85 fleet_id, state_id, combat_phase = db("SELECT fleet_id, state_id, combat_phase FROM ai_fleet_mission WHERE rowid = ?", worldid)[0] 86 87 self.fleet = WorldObject.get_object_by_id(fleet_id) 88 self.state = self.missionStates[state_id] 89 self.combat_phase = bool(combat_phase)
90
91 - def _initialize_mission(self):
92 """ 93 Initializes mission after loading is finished. 94 """ 95 96 # Add move callback for fleet, dependent on loaded fleet state 97 if self.state in self._state_fleet_callbacks: 98 self.fleet.callback = self._state_fleet_callbacks[self.state] 99 100 # Add destroy callback, the same for every case of fleet being destroyed 101 self.fleet.destroy_callback = Callback(self.cancel, "All ships were destroyed")
102
103 - def _dismiss_fleet(self):
104 for ship in self.fleet.get_ships(): 105 self.owner.ships[ship] = self.owner.shipStates.idle 106 ship.stop() 107 self.unit_manager.destroy_fleet(self.fleet)
108
109 - def report_success(self, msg):
110 self._dismiss_fleet() 111 self.success_callback(self, msg)
112
113 - def report_failure(self, msg):
114 self._dismiss_fleet() 115 self.failure_callback(self, msg)
116
117 - def lost_ship(self):
118 if self.fleet.size() == 0: 119 self.cancel('Lost all of the ships')
120
121 - def pause_mission(self):
122 self.log.debug("Player %s, Mission %s, pausing mission at state %s", self.owner.name, self.__class__.__name__, self.state) 123 self.combat_phase = True 124 for ship in self.fleet.get_ships(): 125 ship.stop()
126 127 # continue / abort methods are called by CombatManager after it handles combat. 128 # CombatManager decides whether the battle was successful (and if the mission should be continued) or unsuccessful (mission should be aborted)
129 - def continue_mission(self):
130 assert self.combat_phase, "request to continue mission without it being in combat_phase in the first place" 131 assert self.state in self.combatIntermissions, "request to continue mission from not defined state: {}".format(self.state) 132 self.log.debug("Player %s, Mission %s, continuing mission at state %s", self.owner.name, self.__class__.__name__, self.state) 133 self.combat_phase = False 134 self.combatIntermissions[self.state][0]()
135
136 - def abort_mission(self, msg):
137 assert self.combat_phase, "request to abort mission without it being in combat_phase in the first place" 138 assert self.state in self.combatIntermissions, "request to abort mission from not defined state: {}".format(self.state) 139 self.log.debug("Player %s, Mission %s, aborting mission at state %s", self.owner.name, self.__class__.__name__, self.state) 140 self.combat_phase = False 141 self.combatIntermissions[self.state][1]()
142
143 - def cancel(self, msg):
144 self.report_failure(msg)
145
146 - def __str__(self):
147 return super().__str__() + \ 148 (' using {}'.format(self.fleet if hasattr(self, 'fleet') else 'unknown fleet')) + \ 149 ('(mission state:{},'.format(self.state if hasattr(self, 'state') else 'unknown state')) + \ 150 ('combat_phase:{})'.format(self.combat_phase if hasattr(self, 'combat_phase') else 'N/A'))
151