def restartGalaxy(self, tran, obj, galaxyID, imperatorMessage): #client-initiated restart log.debug("Restarting Galaxy", galaxyID) galaxy = tran.db[galaxyID] if galaxy.imperator == 0 or galaxy.imperator != tran.cid: raise GameException('Only galaxy imperator can restart galaxy') imperator = tran.db[tran.cid] if imperator.imperator < 3: raise GameException( 'Only imperator elected three times and more can restart galaxy' ) log.debug("Sending message", imperatorMessage) message = { "sender": imperator.name, "senderID": tran.cid, "forum": "NEWS", "data": (galaxyID, MSG_GNC_GALAXY_RESTARTED, galaxyID, tran.db[OID_UNIVERSE].turn, (imperator.name, galaxy.name, imperatorMessage)), "topic": "EVENT", } self.cmd(obj).sendMsg(tran, obj, message) fh, galaxyFileName = tempfile.mkstemp(text=True) log.debug("Generating new galaxy to temporary file", galaxyFileName) strGalaxyID = 'Circle42P' GenerateGalaxy(strGalaxyID, os.fdopen(fh, "w+b")) oldX = galaxy.x oldY = galaxy.y oldName = galaxy.name log.debug("Deleting galaxy", galaxyID) self.cmd(galaxy).delete(tran, galaxy) log.debug("Creating new galaxy") newGalaxyID = self.createGalaxy(tran, obj) log.debug("Created new galaxy", newGalaxyID) newGalaxy = tran.db[newGalaxyID] log.debug("Loading new ", newGalaxyID) self.cmd(newGalaxy).loadFromXML(tran, newGalaxy, galaxyFileName, strGalaxyID, oldX, oldY, oldName) log.debug("Setup Enviroment", newGalaxyID) self.cmd(newGalaxy).setupEnvironment(tran, newGalaxy) log.debug("Sending Announcement Message", newGalaxyID) #self.cmd(newGalaxy).announceGalaxy(tran,newGalaxy) log.debug("Removing temp file", galaxyFileName) os.remove(galaxyFileName) # TODO: find you what's this code about #message = { # "sender": 'Galaxy %s' % oldName, # "senderID": obj.oid, # "forum": "NEWS", # "data": (obj.oid, MSG_GNC_GALAXY_GENERATOR, obj.oid, tran.db[OID_UNIVERSE].turn, (oldName, newGalaxy.description)), # "topic": "EVENT", #} log.debug("Galaxy Restarting END")
def _checkValidity(ship, tech, installations, equipCounter, raiseExs): if not raiseExs: return # check min hull req elif tech.minHull > ship.combatClass: log.warning("Cannot add tech", tech.id, tech.name) raise GameException("Minimum hull requirement not satisfied.") # check max hull req elif tech.maxHull < ship.combatClass: log.warning("Cannot add tech", tech.id, tech.name) raise GameException("Maximum hull requirement not satisfied.") # check maximum installations elif tech.maxInstallations and installations[ tech.id] > tech.maxInstallations: raise GameException( "Maximum number of equipment installations exceeded.") #check maximum type installations elif tech.subtype == "seq_mod" and tech.equipType in Rules.maxEquipType: try: equipCounter[tech.equipType] += 1 except KeyError: equipCounter[tech.equipType] = 1 if equipCounter[tech.equipType] > Rules.maxEquipType[tech.equipType]: raise GameException( "Maximum number of restricted type equipment installations exceeded: %s." % tech.equipType)
def setActionIndex(self, tran, obj, index): if index >= len(obj.actions) or index < 0: raise GameException('Index out of bounds.') if obj.orbiting == OID_NONE: raise GameException('Move command in progress cannot be changed.') obj.actionIndex = index return obj.actionIndex
def finishGalaxyImperator(self, tran, obj, galaxyID, imperatorMessage): log.debug("Finishing Galaxy", galaxyID) galaxy = tran.db[galaxyID] if galaxy.scenario == Const.SCENARIO_OUTERSPACE: if galaxy.imperator == 0 or galaxy.imperator != tran.cid: raise GameException('Only galaxy imperator can finish galaxy') imperator = tran.db[tran.cid] if imperator.imperator < 3: raise GameException('Only imperator elected three times and more can finish galaxy') log.debug("Sending message", imperatorMessage) message = { "sender": imperator.name, "senderID": tran.cid, "forum": "NEWS", "data": (galaxyID, Const.MSG_GNC_GALAXY_FINISHED, galaxyID, obj.turn, (imperator.name, galaxy.name, imperatorMessage)), "topic": "EVENT", } self.cmd(obj).sendMsg(tran, obj, message) else: raise GameException('Galaxy finish not permitted.') log.debug("Deleting galaxy", galaxyID) self.cmd(galaxy).delete(tran, galaxy)
def _createNewPlayer(self, session, galaxyID): universe = self.db[Const.OID_UNIVERSE] galaxy = self.db[galaxyID] if not galaxy.startingPos: raise GameException('No such starting position.') if galaxyID in self.accountGalaxies(session.login): raise GameException('Account already owns player in this galaxy.') log.debug('Creating new player with CID', session.cid) player = self.cmdPool[Const.T_PLAYER].new(Const.T_PLAYER) player.name = session.nick player.login = session.login player.timeEnabled = galaxy.timeEnabled player.galaxy = galaxy.oid log.debug('Selecting starting point') planetID = IGalaxy.IGalaxy.getFreeStartingPosition(self.db, galaxy) player.planets.append(planetID) log.debug('Creating transaction') tran = Transaction(self, session.cid, session) IPlayer.IPlayer.setStartingTechnologies(player) # register player log.debug('Registering player for login {0}'.format(session.login)) playerID = self.registerPlayer(session.login, player) log.debug('Player ID =', playerID) # singleplayer galaxy needs owner recorded so player can log back there # also provides access rights to control it if galaxy.scenario == Const.SCENARIO_SINGLE: galaxy.owner = playerID planet = self.db[planetID] planet.owner = playerID system = tran.db[planet.compOf] IPlayer.IPlayer.setStartingShipDesigns(player) IPlayer.IPlayer.setStartingPlanet(tran, playerID, planet) IPlayer.IPlayer.setStartingFleet(tran, playerID, system) # add player to universe log.debug('Adding player to universe') universe.players.append(playerID) # initial scan system = self.db[planet.compOf] log.debug('Processing scan phase') self.cmdPool[Const.T_PLANET].processPRODPhase(tran, planet, None) # this only works for one planet starting scenarios, it might be imprecise, as it's # calculated here # TODO: make proper difference between getting stats, and acting on them, and utilize that player.effSciPoints = planet.prodSci * (1 + ( (Rules.baseGovPwr - planet.storPop) / float(Rules.baseGovPwr)) / 2.0) system.scannerPwrs[ playerID] = planet.scannerPwr = Rules.startingScannerPwr self.cmdPool[Const.T_GALAXY].processSCAN2Phase(tran, galaxy, True) # check if galaxy can be "started" (for purpose of single player games) self.cmdPool[Const.T_GALAXY].enableTime(tran, galaxy) # save game info self.generateGameInfo() return playerID, None
def renameFleet(self, tran, obj, name): if not Utils.isCorrectName(name): raise GameException('Invalid name. Only characters, digits, space, dot and dash permitted, max. length is 30 characters.') if re.match("/^Fleet \d+$/",name): raise GameException('Invalid name. You cannot use the format "Fleet ##" for a custom name.') names = {} for fleetID in tran.db[obj.owner].fleets: names[tran.db[fleetID].customname] = None if name in names and name != obj.customname: raise GameException('Name already in use.') obj.customname = name return obj.customname
def _checkValidityWhole(ship, hull, counter, raiseExs): if not raiseExs: return elif counter.get("seq_ctrl", 0) != 1: raise GameException( "Exactly one control module needs to be in the ship.") elif ship.slots > hull.slots: raise GameException( "Hull does not have enough slots to hold specified equipment.") elif ship.weight > hull.maxWeight: raise GameException("Ship is too heavy.") elif len(ship.improvements) > Rules.shipMaxImprovements: raise GameException("Too many improvements.")
def joinFleet(self, tran, obj, fleetID, force=False): if obj.orbiting == OID_NONE: # we are in space return if obj.allowmerge != 1: # owner has turned off auto-joins (join self with other) return if fleetID == OID_NONE: raiseExps = False # find suitable fleet system = tran.db[obj.orbiting] player = tran.db[obj.owner] for tmpID in system.fleets: if tmpID == obj.oid: continue fleet = tran.db[tmpID] if fleet.allowmerge == 0 and not force: # owner has turned off auto-joins (join other with self) continue rel = self.cmd(player).getRelationTo(tran, player, fleet.owner) if rel == REL_UNITY and Utils.isIdleFleet(fleet): fleetID = tmpID break else: raiseExps = True if fleetID == OID_NONE: return # join to selected fleet fleet = tran.db[fleetID] # if the fleet was specified from a client call, validate it: if not fleet.owner == obj.owner: if raiseExps: raise GameException("Fleets do not have the same owner.") return if not fleet.orbiting == obj.orbiting: if raiseExps: raise GameException("Fleets are not in the same system.") return if fleet.allowmerge == 0 and not force: # owner has turned off auto-joins (join other with self) return fleet.ships.extend(obj.ships) # transfer resources fleet.storEn += obj.storEn # update fleet's data self.cmd(fleet).update(tran, fleet) # disband this fleet log.debug('IFleet joinFleet, removing old fleet: source fleet',obj.oid,'; target fleet',fleet.oid) self.cmd(obj).disbandFleet(tran, obj)
def moveAction(self, tran, fleet, index, rel): if index >= len(fleet.actions): raise GameException('No such item in the command list.') if index + rel < 0 or index + rel >= len(fleet.actions): raise GameException('Cannot move.') if index == fleet.actionIndex: raise GameException('Cannot move active command.') if index < fleet.actionIndex: raise GameException('Cannot move processed command.') if index + rel <= fleet.actionIndex: raise GameException('Cannot move before active command.') action = fleet.actions[index] del fleet.actions[index] fleet.actions.insert(index + rel, action) return fleet.actions
def sendAdminMsg(self, tran, obj, message): # check attributes if "forum" not in message: raise GameException("Forum not specified.") if message["forum"] not in self.forums: raise GameException("No such forum.") if "topic" not in message: raise GameException("Topic not specified.") if "data" not in message and "text" not in message: raise GameException("Text or structured data not specified.") # message["recipient"] = obj.name message["recipientID"] = obj.oid # send message return tran.gameMngr.msgMngr.send(tran.gameMngr.gameID, obj.oid, message)
def takeOverPirate(self, sid, playerID, vipPassword): # limit this now only to the qark session = self.clientMngr.getSession(sid) player = self.db[playerID] if vipPassword != self.config.vip.password: raise SecurityException('Wrong VIP password.') if player.galaxy in self.accountGalaxies(session.login): raise GameException('Account already owns player in this galaxy.') if player.galaxy: galaxy = self.db[player.galaxy] if galaxy.scenario == Const.SCENARIO_SINGLE: raise GameException( 'AI in single scenario cannot be taken over.') log.debug('Creating pirate in session {0} with CID {1}'.format( sid, session.cid)) universe = self.db[Const.OID_UNIVERSE] log.debug('Creating transaction') tran = Transaction(self, session.cid, session) # create player #log.debug("Morphing Pirate player", playerID) log.debug("Player type", player.type) if player.type != Const.T_AIPIRPLAYER: raise GameException('No such starting position.') player.type = Const.T_PIRPLAYER self.cmdPool[Const.T_PIRPLAYER].upgrade(tran, player) self.cmdPool[Const.T_PIRPLAYER].update(tran, player) # reregister player self.removePlayer(player.oid) player.fullName = "Pirate %s" % session.nick player.name = session.nick player.login = session.login self.registerPlayer(player.login, player, player.oid) # add player to the universe universe.players.append(playerID) # initial scan scannerPwr = Rules.techs[9002].scannerPwr for planetID in player.planets: planet = self.db[planetID] system = self.db[planet.compOf] system.scannerPwrs[player.oid] = scannerPwr log.debug('Processing scan phase') galaxy = tran.db[player.galaxy] self.cmdPool[Const.T_GALAXY].processSCAN2Phase(tran, galaxy, True) # save game info self.generateGameInfo() return player.oid, None
def deleteAction(self, tran, obj, index): if index >= len(obj.actions) or index < 0: raise GameException('Index out of bounds.') if index == obj.actionIndex and obj.orbiting == OID_NONE: if obj.actions[index][0] == FLACTION_MOVE: raise GameException('Move command in progress cannot be deleted.') else: # convert action to the move command action, targetID, aData = obj.actions[index] obj.actions[index] = (FLACTION_MOVE, targetID, aData) return obj.actions, obj.actionIndex if index == obj.actionIndex and obj.actions[index][0] == FLACTION_WAIT: # reset wait counters obj.actionWaitCounter = 1 del obj.actions[index] if index <= obj.actionIndex and obj.actionIndex > 0: obj.actionIndex -= 1 return obj.actions, obj.actionIndex
def splitFleet(self, tran, obj, ships, mEn): if not len(ships): raise GameException('No ships in the new fleet.') if len(ships) == len(obj.ships): raise GameException('No ships in the original fleet.') # check ships tmpShips = obj.ships[:] for ship in ships: if ship not in tmpShips: raise GameException("No such ship(s) in the original fleet.") tmpShips.remove(ship) # create new fleet fleet = self.new(T_FLEET) tran.db.create(fleet) log.debug(obj.oid, "FLEET -- split fleet, new fleet is", fleet.oid) if obj.orbiting != OID_NONE: refObj = tran.db[obj.orbiting] else: refObj = obj self.cmd(fleet).create(tran, fleet, refObj, obj.owner) # move ships for ship in ships: # use server data idx = obj.ships.index(ship) ship = obj.ships.pop(idx) fleet.ships.append(ship) # update fleet self.cmd(fleet).update(tran, fleet) # move en move = max(min(mEn, fleet.maxEn, obj.storEn), 0) fleet.storEn += move obj.storEn -= move # share speed boost fleet.speedBoost = obj.speedBoost # update fleets self.cmd(obj).update(tran, obj) self.cmd(fleet).update(tran, fleet) # return new fleet, old fleet and player's fleets return fleet, obj, tran.db[obj.owner].fleets
def sendMsg(self, tran, obj, message): if tran.session.cid != Const.OID_ADMIN: message["sender"] = tran.session.nick message["senderID"] = tran.session.cid # check attributes if "forum" not in message: raise GameException("Forum not specified.") if message["forum"] not in self.forums: raise GameException("No such forum.") if "topic" not in message: raise GameException("Topic not specified.") if "data" not in message and "text" not in message: raise GameException("Text or structured data not specified.") # check permissions if tran.session.cid != Const.OID_ADMIN and \ not self.canSendMsg(tran, obj, message["senderID"], message["forum"]): raise SecurityException("You cannot send message to this entity.") # message["recipient"] = obj.name message["recipientID"] = obj.oid # send message return tran.gameMngr.msgMngr.send(tran.gameMngr.gameID, obj.oid, message)
def takeOverAIPlayer(self, sid, playerID): log.debug('Creating new player in session', sid) session = self.clientMngr.getSession(sid) log.debug('Creating new player with CID', session.cid) universe = self.db[OID_UNIVERSE] log.debug('Creating transaction') tran = Transaction(self, session.cid, session) # create player log.debug("Morphing AI player", playerID) player = self.db[playerID] if not (player.type == T_AIPLAYER and player.planets): raise GameException('No such starting position.') player.type = T_PLAYER self.cmdPool[T_PLAYER].upgrade(tran, player) self.cmdPool[T_PLAYER].update(tran, player) # reregister player self.removePlayer(player.oid) player.name = session.nick player.login = session.login self.registerPlayer(player.login, player, player.oid) # reset relations player.diplomacyRels.clear() # add player to the universe universe.players.append(playerID) # make sure, there is something useable on the home planet planet = self.db[player.planets[0]] hasOutpost = False for struct in planet.slots: if struct[STRUCT_IDX_TECHID] == Tech.OUTPOST1: hasOutpost = True if not hasOutpost: # find something to replace finished = False for property in ("prodSci", "prodProd", "prodBio"): for struct in planet.slots: tech = Rules.techs[struct[STRUCT_IDX_TECHID]] if getattr(tech, property) > 0: struct[STRUCT_IDX_TECHID] = Tech.OUTPOST1 struct[STRUCT_IDX_HP] = tech.maxHP finished = True break if finished: break if not finished: # replace last structure struct = planet.slots[-1] struct[STRUCT_IDX_TECHID] = Tech.OUTPOST1 struct[STRUCT_IDX_HP] = tech.maxHP # save game info self.generateGameInfo() return player.oid, None
def processACTIONPhase(self, tran, obj, data): # ACTIONS if Utils.isIdleFleet(obj): #@log.debug('IAsteroid', obj.oid, 'idle') obj.impactDelay += 1 return action, target, actionData = obj.actions[obj.actionIndex] #@log.debug('IAsteroid', obj.oid, 'processing action', action) if action == Const.FLACTION_MOVE: if self.cmd(obj).moveToTarget(tran, obj, target): # we are there obj.actionIndex += 1 else: raise GameException('Unsupported action %d' % action)
def takeOverAIPlayer(self, sid, playerID): log.debug('Creating new player in session', sid) session = self.clientMngr.getSession(sid) log.debug('Creating new player with CID', session.cid) universe = self.db[Const.OID_UNIVERSE] log.debug('Creating transaction') tran = Transaction(self, session.cid, session) player = self.db[playerID] if not (player.type == Const.T_AIPLAYER and player.planets): raise GameException('No such starting position.') if player.galaxy in self.accountGalaxies(session.login): raise GameException('Account already owns player in this galaxy.') galaxy = self.db[player.galaxy] if galaxy.scenario == Const.SCENARIO_SINGLE: raise GameException('AI in single scenario cannot be taken over.') # create player log.debug("Morphing AI player", playerID) player.type = Const.T_PLAYER self.cmdPool[Const.T_PLAYER].upgrade(tran, player) self.cmdPool[Const.T_PLAYER].update(tran, player) # reregister player self.removePlayer(player.oid) player.name = session.nick player.login = session.login self.registerPlayer(player.login, player, player.oid) # reset relations player.diplomacyRels.clear() # add player to the universe universe.players.append(playerID) log.debug('Processing scan phase') galaxy = tran.db[player.galaxy] self.cmdPool[Const.T_GALAXY].processSCAN2Phase(tran, galaxy, True) # save game info self.generateGameInfo() return player.oid, None
def loadDOMAttrs(self, obj, elem): for index in xrange(0, elem.attributes.length): attr = elem.attributes.item(index) if hasattr(obj, attr.nodeName): attrType = type(getattr(obj, attr.nodeName)) if attrType == types.IntType: value = int(attr.nodeValue) elif attrType == types.FloatType: value = float(attr.nodeValue) elif attrType == types.UnicodeType: value = attr.nodeValue elif attrType == types.StringType: value = attr.nodeValue else: raise 'Unsupported attribute type %s' % attrType setattr(obj, attr.nodeName, value) else: raise GameException('Unsupported attribute %s' % attr.nodeName)
def takeOverPirate(self, sid, playerID, vipPassword): # limit this now only to the qark session = self.clientMngr.getSession(sid) if vipPassword != self.config.vip.password: raise SecurityException('You cannot issue this command.') # log.debug('Creating pirate in session', sid) session = self.clientMngr.getSession(sid) log.debug('Creating pirate with CID', session.cid) universe = self.db[OID_UNIVERSE] log.debug('Creating transaction') tran = Transaction(self, session.cid, session) # create player #log.debug("Morphing Pirate player", playerID) player = self.db[playerID] log.debug("Player type", player.type) if player.type != T_AIPIRPLAYER: raise GameException('No such starting position.') player.type = T_PIRPLAYER self.cmdPool[T_PIRPLAYER].upgrade(tran, player) self.cmdPool[T_PIRPLAYER].update(tran, player) # reregister player self.removePlayer(player.oid) player.fullName = "Pirate %s" % session.nick player.name = session.nick player.login = session.login self.registerPlayer(player.login, player, player.oid) # add player to the universe universe.players.append(playerID) # initial scan scannerPwr = Rules.techs[9002].scannerPwr for planetID in player.planets: planet = self.db[planetID] system = self.db[planet.compOf] system.scannerPwrs[player.oid] = scannerPwr log.debug('Processing scan phase') galaxy = tran.db[player.galaxies[0]] self.cmdPool[T_GALAXY].processSCAN2Phase(tran, galaxy, None) # save game info self.generateGameInfo() return player.oid, None
def createNewPlayer(self, sid, galaxyID): log.debug('Creating new player in session', sid) session = self.clientMngr.getSession(sid) log.debug('Creating new player with CID', session.cid) universe = self.db[OID_UNIVERSE] galaxy = self.db[galaxyID] if not galaxy.startingPos: raise GameException('No such starting position.') # create player player = self.cmdPool[T_PLAYER].new(T_PLAYER) player.name = session.nick player.login = session.login player.timeEnabled = galaxy.timeEnabled player.galaxies.append(galaxy.oid) # select starting point randomly log.debug('Selecting starting point') while 1: planetID = random.choice(galaxy.startingPos) galaxy.startingPos.remove(planetID) log.debug('Starting point', planetID) log.debug('Starting point - owner', self.db[planetID].owner) if self.db[planetID].owner == OID_NONE: break if not galaxy.startingPos: raise GameException('No free starting point in the galaxy.') player.planets.append(planetID) # TODO tweak more player's attrs log.debug('Creating transaction') tran = Transaction(self, session.cid, session) # Grant starting technologies (at medium improvement) for techID in Rules.techs.keys(): if Rules.techs[techID].isStarting: player.techs[techID] = (Rules.techBaseImprovement + Rules.techMaxImprovement) / 2 # grant all techs (TODO remove) # player.techs[techID] = Rules.techMaxImprovement # register player log.debug('Registering player') playerID = self.registerPlayer(session.login, player) log.debug('Player ID =', playerID) # TODO tweak more planet's attrs planet = self.db[planetID] planet.slots = [ Utils.newStructure(tran, Tech.PWRPLANTNUK1, playerID, STRUCT_STATUS_ON), Utils.newStructure(tran, Tech.FARM1, playerID, STRUCT_STATUS_ON), Utils.newStructure(tran, Tech.FARM1, playerID, STRUCT_STATUS_ON), Utils.newStructure(tran, Tech.FARM1, playerID, STRUCT_STATUS_ON), Utils.newStructure(tran, Tech.ANCFACTORY, playerID, STRUCT_STATUS_ON), Utils.newStructure(tran, Tech.ANCFACTORY, playerID, STRUCT_STATUS_ON), Utils.newStructure(tran, Tech.ANCRESLAB, playerID, STRUCT_STATUS_ON), Utils.newStructure(tran, Tech.REPAIR1, playerID, STRUCT_STATUS_ON), ] planet.storPop = Rules.startingPopulation planet.storBio = Rules.startingBio planet.storEn = Rules.startingEn planet.scannerPwr = Rules.startingScannerPwr planet.owner = playerID planet.morale = Rules.maxMorale # fleet # add basic ships designs tempTechs = [Tech.FTLENG1, Tech.SCOCKPIT1, Tech.SCANNERMOD1, Tech.CANNON1, Tech.CONBOMB1, Tech.SMALLHULL1, Tech.MEDIUMHULL2, Tech.COLONYMOD2] for techID in tempTechs: player.techs[techID] = 1 dummy, scoutID = self.cmdPool[T_PLAYER].addShipDesign(tran, player, "Scout", Tech.SMALLHULL1, {Tech.FTLENG1:3, Tech.SCOCKPIT1:1, Tech.SCANNERMOD1:1}) dummy, fighterID = self.cmdPool[T_PLAYER].addShipDesign(tran, player, "Fighter", Tech.SMALLHULL1, {Tech.FTLENG1:3, Tech.SCOCKPIT1:1, Tech.CANNON1:1}) self.cmdPool[T_PLAYER].addShipDesign(tran, player, "Bomber", Tech.SMALLHULL1, {Tech.FTLENG1:3, Tech.SCOCKPIT1:1, Tech.CONBOMB1:1}) dummy, colonyID = self.cmdPool[T_PLAYER].addShipDesign(tran, player, "Colony Ship", Tech.MEDIUMHULL2, {Tech.FTLENG1:4, Tech.SCOCKPIT1:1, Tech.COLONYMOD2:1}) for techID in tempTechs: del player.techs[techID] # add small fleet log.debug('Creating fleet') system = self.db[planet.compOf] fleet = self.cmdPool[T_FLEET].new(T_FLEET) self.db.create(fleet) log.debug('Creating fleet - created', fleet.oid) self.cmdPool[T_FLEET].create(tran, fleet, system, playerID) log.debug('Creating fleet - addShips') self.cmdPool[T_FLEET].addNewShip(tran, fleet, scoutID) self.cmdPool[T_FLEET].addNewShip(tran, fleet, scoutID) self.cmdPool[T_FLEET].addNewShip(tran, fleet, fighterID) self.cmdPool[T_FLEET].addNewShip(tran, fleet, fighterID) self.cmdPool[T_FLEET].addNewShip(tran, fleet, colonyID) # add player to universe log.debug('Adding player to universe') universe.players.append(playerID) # initial scan system = self.db[planet.compOf] log.debug('Processing scan phase') system.scannerPwrs[playerID] = Rules.startingScannerPwr self.cmdPool[T_GALAXY].processSCAN2Phase(tran, galaxy, None) # check if galaxy can be "started" self.cmdPool[T_GALAXY].enableTime(tran, galaxy) # save game info self.generateGameInfo() return playerID, None
def processACTIONPhase(self, tran, obj, data): #@log.debug("Fleet", obj.oid, "ACTION") # update fleet data self.cmd(obj).update(tran, obj) # consume support if obj.storEn >= obj.operEn: obj.storEn -= obj.operEn # refuel refuelled = self.cmd(obj).refuelAndRepairAndRecharge(tran, obj) else: # try to refuel fleet refuelled = self.cmd(obj).refuelAndRepairAndRecharge(tran, obj) # there is not enought support -> damage ships log.debug('IFleet', 'No support - damaging ships in fleet', obj.oid) index = 0 player = tran.db[obj.owner] destroyed = [] for designID, hp, shield, exp in obj.ships: spec = player.shipDesigns[designID] operEn = spec.operEn if obj.storEn >= spec.operEn: #@log.debug('IFleet', 'Ship SUPPORT OK', shipTechID) obj.storEn -= spec.operEn elif obj.storEn > 0: # consume remaining fuel obj.storEn = 0 else: # apply damage dmg = max(int(spec.maxHP * Rules.shipDecayRatio), 1) if dmg >= hp: destroyed.append(obj.ships[index]) else: obj.ships[index][SHIP_IDX_HP] -= dmg index += 1 self.cmd(obj).removeShips(tran, obj, destroyed) # if fleet has been destroyed -> abort action processing if not tran.db.has_key(obj.oid): log.debug('IFleet', obj.oid, 'fleet destroyed') return # upgrade ships if obj.orbiting != OID_NONE: # autoRepair is part of serviceShips self.cmd(obj).serviceShips(tran, obj) # record scanner into system scanner overview system = tran.db[obj.orbiting] system.scannerPwrs[obj.owner] = max(obj.scannerPwr, system.scannerPwrs.get(obj.owner, 0)) # ACTIONS if Utils.isIdleFleet(obj): #@log.debug('IFleet', obj.oid, 'fleet idle') # reset retreat counter obj.combatRetreatWait = 0 # reset last position to current position obj.oldX = obj.x obj.oldY = obj.y # there is nothing to do - try to join other fleets self.cmd(obj).joinFleet(tran, obj, OID_NONE) return #@log.debug('IFleet', obj.oid, 'processing action', action) while not Utils.isIdleFleet(obj): action, target, actionData = obj.actions[obj.actionIndex] if action == FLACTION_NONE: obj.actionIndex += 1 elif action == FLACTION_DEPLOY: if self.cmd(obj).actionDeploy(tran, obj): obj.actionIndex += 1 break elif action == FLACTION_WAIT: if obj.actionWaitCounter >= actionData: obj.actionWaitCounter = 1 obj.actionIndex += 1 else: obj.actionWaitCounter += 1 break #wait should wait, not let move; deindented this to act for completed waits also --RC elif action == FLACTION_MOVE: if self.cmd(obj).moveToTarget(tran, obj, target): # we are there obj.actionIndex += 1 break elif action == FLACTION_ENTERWORMHOLE: if self.cmd(obj).moveToWormhole(tran, obj, target): # we are there obj.actionIndex += 1 break elif action == FLACTION_DECLAREWAR: # switch off pact allow military ships player = tran.db[obj.owner] self.cmd(player).changePactCond(tran, player, actionData, PACT_ALLOW_MILITARY_SHIPS, PACT_OFF, [PACT_ALLOW_MILITARY_SHIPS]) # next action obj.actionIndex +=1 elif action == FLACTION_REFUEL: # check current refuel level if self.cmd(obj).moveToTarget(tran, obj, target) and refuelled: # next action obj.actionIndex += 1 else: break elif action == FLACTION_REDIRECT: # ok, let's do some magic if self.cmd(obj).actionRedirect(tran, obj, refuelled): obj.actionIndex += 1 else: break elif action == FLACTION_REPEATFROM: log.debug(obj.oid, "Setting action index to", data) if actionData != None: obj.actionIndex = actionData else: obj.actionIndex += 1 break # TODO fix me else: raise GameException('Unsupported action %d' % action) break # it there is nothing to do -> join other idle fleets # the fleet could joined with another fleet if tran.db.has_key(obj.oid) and Utils.isIdleFleet(obj): # reset retreat counter obj.combatRetreatWait = 0 # try to join some fleet self.cmd(obj).joinFleet(tran, obj, OID_NONE)
def addAction(self, tran, obj, index, action, targetID, aData): # check if target is valid if action == FLACTION_REDIRECT: if targetID != OID_NONE: raise GameException("This command has no target.") elif action == FLACTION_WAIT or action == FLACTION_REPEATFROM: if targetID != OID_NONE: raise GameException("This command has no target.") aData = int(aData) if aData < 0: raise GameException("Number equal or larger than 1 must be specified.") elif action == FLACTION_DECLAREWAR: if targetID != OID_NONE: raise GameException("This command has no target.") if aData == OID_NONE or aData == obj.owner: raise GameException("Invalid commander.") else: target = tran.db[targetID] if target.type not in (T_SYSTEM, T_WORMHOLE, T_PLANET): raise GameException('Can target wormholes, systems or planets only.') if action == FLACTION_ENTERWORMHOLE and target.type != T_WORMHOLE: raise GameException('Can only traverse wormholes.') if action == FLACTION_DEPLOY and target.type != T_PLANET: raise GameException('Can build on/colonize planets only.') if len(obj.actions) + 1 > Rules.maxCmdQueueLen: raise GameException('Too many commands in the queue.') #validate that the target is in the fleet owner's galaxy if target.type == T_PLANET: systemID = target.compOf else: systemID = targetID owner = tran.db[obj.owner] # validate that the player has actually scanned this system if systemID not in owner.validSystems: raise GameException('You cannot find this system (never scanned).') if not owner.galaxies: raise GameException('The fleet owner is not in a galaxy.') galaxy = tran.db[owner.galaxies[0]] if systemID not in galaxy.systems: raise GameException('The target system is not in your galaxy.') obj.actions.insert(index, (action, targetID, aData)) if index <= obj.actionIndex: obj.actionIndex += 1 if obj.actionIndex >= len(obj.actions) or obj.actionIndex < 0: obj.actionIndex = min(index, len(obj.actions) - 1) return obj.actions, obj.actionIndex
def set(self, tran, obj, attr, value): if hasattr(obj, attr): setattr(obj, attr, value) return 1 raise GameException('No such attribute.')
def makeShipFullSpec(player, name, hullID, eqIDs, improvements, raiseExs = True): if not hullID: raise GameException("Ship's hull must be specified.") hull = Rules.techs[hullID] if not hull.isShipHull: raise GameException("Ship's hull must be specified.") ship = IDataHolder() ship.type = T_SHIP # initial values techEff = Rules.techImprEff[player.techs.get(hullID, Rules.techBaseImprovement)] ship.name = name ship.hullID = hullID ship.eqIDs = eqIDs ship.level = hull.level ship.combatClass = hull.combatClass ship.improvements = improvements ship.buildProd = hull.buildProd ship.buildSRes = hull.buildSRes[:] # we need copy ship.operEn = hull.operEn ship.storEn = hull.storEn * techEff ship.weight = hull.weight ship.slots = 0 ship.signature = hull.signature ship.negsignature = 0 ship.minSignature = hull.minSignature ship.signatureCloak = 1.0 #NEW; 100% - this is the default rule ship.signatureDecloak = 1.0 #NEW; 100% - this is the default rule ship.combatAttBase = hull.combatAtt * techEff ship.combatAtt = 0 ship.combatAttMultiplier = 1.0 #NEW; 100% - this is the default rule ship.combatDefBase = hull.combatDef * techEff ship.combatDef = 0 ship.combatDefMultiplier = 1.0 #NEW; 100% - this is the default rule ship.missileDefBase = hull.missileDef * techEff ship.missileDef = 0 ship.missileDefMultiplier = 1.0 #NEW; 100% - this is the default rule ship.scannerPwr = max(hull.scannerPwr * techEff, Rules.scannerMinPwr) ship.autoRepairFix = hull.autoRepairFix ship.autoRepairPerc = hull.autoRepairPerc ship.shieldRechargeFix = hull.shieldRechargeFix ship.shieldRechargePerc = hull.shieldRechargePerc ship.hardShield = 0.0 ship.engPwr = 0 ship.upgradeTo = 0 ship.shieldHP = 0 ship.maxHP = int(hull.maxHP * techEff) ship.weaponIDs = [] ship.deployStructs = [] ship.deployHandlers = [] ship.isMilitary = 0 ship.baseExp = 0 ship.damageAbsorb = 0 combatExtra = 0 shieldPerc = 0.0 unpactStruct = 0 deployHandler = 0 currentNegWeight = 0 currentNegSlots = 0 # add equipment #negslots = {} #negweight = {} counter = {} installations = {} equipCounter = {} for techID in eqIDs: tech = Rules.techs[techID] techEff = Rules.techImprEff[player.techs.get(techID, Rules.techBaseImprovement)] # prevent count < 0; allow count == 0 for placeholders. if eqIDs[techID] < 0 and raiseExs: raise GameException("Invalid equipment count (less than 0).") for i in xrange(0, eqIDs[techID]): counter[tech.subtype] = 1 + counter.get(tech.subtype, 0) installations[techID] = 1 + installations.get(techID, 0) # check min hull req if tech.minHull > ship.combatClass and raiseExs: log.warning("Cannot add tech", techID, tech.name) raise GameException("Minimum hull requirement not satisfied.") # check max hull req #NEW if tech.maxHull < ship.combatClass and raiseExs: log.warning("Cannot add tech", techID, tech.name) raise GameException("Maximum hull requirement not satisfied.") # check maximum installations if tech.maxInstallations and installations[tech.id] > tech.maxInstallations \ and raiseExs: raise GameException("Maximum number of equipment installations exceeded.") #check maximum type installations if tech.subtype == "seq_mod" and tech.equipType in Rules.maxEquipType and raiseExs: if tech.equipType in equipCounter: equipCounter[tech.equipType] += 1 else: equipCounter[tech.equipType] = 1 log.debug(equipCounter[tech.equipType]) if equipCounter[tech.equipType] > Rules.maxEquipType[tech.equipType]: raise GameException("Maximum number of restricted type equipment installations exceeded: %s." % tech.equipType) # add values ship.level = max(ship.level, tech.level) ship.buildProd += tech.buildProd ship.buildSRes.extend(tech.buildSRes) ship.storEn += tech.storEn * techEff if (tech.weight > 0): ship.weight += tech.weight else: currentNegWeight += tech.weight #negweight[techID] = tech.weight + negweight.get(techID, 0) #this is complex for items with max installs... if (tech.slots > 0): ship.slots += tech.slots else: currentNegSlots += tech.slots #negslots[techID] = tech.slots + negslots.get(techID, 0) #this is complex for items with max installs... if tech.signature < 0 and tech.subtype == "seq_mod": ship.negsignature = min(tech.signature,ship.negsignature) else: ship.signature += tech.signature ship.minSignature = max(ship.minSignature, tech.minSignature) ship.signatureCloak = min(ship.signatureCloak, tech.signatureCloak) ship.signatureDecloak = min(ship.signatureDecloak, tech.signatureDecloak) if tech.subtype == "seq_mod": #not cumulative for equipment; pick best ship.combatAtt = max(ship.combatAtt, tech.combatAtt * techEff) ship.combatDef = max(ship.combatDef, tech.combatDef * techEff) ship.missileDef = max(ship.missileDef, tech.missileDef * techEff) else : ship.combatDefBase += tech.combatDef * techEff ship.missileDefBase += tech.missileDef * techEff ship.combatAttBase += tech.combatAtt * techEff #not cumulative; pick best ship.combatAttMultiplier = max(ship.combatAttMultiplier, (tech.combatAttPerc-1.0) * techEff + 1.0) #NEW ship.combatDefMultiplier = max(ship.combatDefMultiplier, (tech.combatDefPerc-1.0) * techEff + 1.0) #NEW ship.missileDefMultiplier = max(ship.missileDefMultiplier, (tech.missileDefPerc-1.0) * techEff + 1.0) #NEW ship.engPwr += tech.engPwr * techEff ship.maxHP += tech.maxHP * techEff shieldPerc = max(shieldPerc, tech.shieldPerc * techEff) ship.scannerPwr = max(ship.scannerPwr, tech.scannerPwr * techEff) ship.operEn += tech.operEn ship.autoRepairFix = max(ship.autoRepairFix, tech.autoRepairFix * techEff) ship.autoRepairPerc = max(ship.autoRepairPerc, tech.autoRepairPerc * techEff) ship.shieldRechargeFix = max(ship.shieldRechargeFix, tech.shieldRechargeFix * techEff) ship.shieldRechargePerc = max(ship.shieldRechargePerc, tech.shieldRechargePerc * techEff) ship.hardShield = max(ship.hardShield,tech.hardShield * techEff) ship.damageAbsorb = min(ship.damageAbsorb + tech.damageAbsorb,Rules.maxDamageAbsorb) #limit this by rule combatExtra += tech.addMP # if weapon - register only if tech.subtype == "seq_wpn": ship.weaponIDs.append(techID) ship.isMilitary = 1 weapon = Rules.techs[techID] ship.baseExp += (weapon.weaponDmgMin + weapon.weaponDmgMax) / 2 * weapon.weaponROF # deployables if tech.unpackStruct != OID_NONE: ship.deployStructs.append(tech.unpackStruct) unpactStruct = 1 if tech.deployHandlerID != OID_NONE: #this calls another tech at execute time, so only need the ID ship.deployHandlers.append(tech.deployHandlerID) deployHandler = 1 #fix limiter based attibs; round when needed #currentNegWeight = 0 #for negtech in negweight: # currentNegWeight = min(currentNegWeight,negweight[negtech]) #currentNegSlots = 0 #for negtech in negslots: # currentNegSlots = min(currentNegSlots,negslots[negtech]) ship.weight = max(ship.weight+currentNegWeight,int(hull.weight/2)) ship.slots = max(ship.slots+currentNegSlots,1) ship.combatAtt += ship.combatAttBase ship.combatDef = int((ship.combatDef + ship.combatDefBase) * ship.combatDefMultiplier) ship.missileDef = int((ship.missileDef + ship.missileDefBase) * ship.missileDefMultiplier) ship.hardShield = min(1.0,ship.hardShield) #don't allow this to be more than 100% blocking!! #add some MP for damage absorb: combatExtra += ship.damageAbsorb * 1500 #calculate final signature ship.signature += ship.negsignature ship.signature *= ship.signatureCloak * ship.signatureDecloak # check various conditions # if unpactStruct and deployHandler and raiseExs: #we don't 'need' this, so I'm leaving it disabled for now; however, we might 'want' it to prevent abuse --RC # raise GameException("Cannot have both a deployable structure and a deployable project on the same ship") if counter.get("seq_ctrl", 0) == 0 and raiseExs: raise GameException("No control module in the ship.") if counter.get("seq_ctrl", 0) > 1 and raiseExs: raise GameException("Only one control module in the ship allowed.") if ship.slots > hull.slots and raiseExs: raise GameException("Hull does not have enough slots to hold specified equipment.") if ship.weight > hull.maxWeight and raiseExs: raise GameException("Ship is too heavy.") # compute secondary paramaters ship.speed = float(ship.engPwr) / ship.weight ship.baseExp = int(ship.baseExp * Rules.shipBaseExpMod) + Rules.shipBaseExp[ship.combatClass] # compute base attack/defence ship.combatAtt += int(ship.speed) ship.combatDef += int(ship.speed) ship.missileDef += int(ship.speed / 2.0) # improvements if len(improvements) > Rules.shipMaxImprovements and raiseExs: raise GameException("Too many improvements.") for i in improvements: if i == SI_SPEED: ship.speed *= Rules.shipImprovementMod elif i == SI_TANKS: ship.storEn *= Rules.shipImprovementMod elif i == SI_ATT: ship.combatAtt *= Rules.shipImprovementMod elif i == SI_DEF: ship.combatDef *= Rules.shipImprovementMod ship.missileDef *= Rules.shipImprovementMod elif i == SI_HP: ship.maxHP *= Rules.shipImprovementMod elif i == SI_SHIELDS: ship.shieldHP *= Rules.shipImprovementMod # round values down ship.storEn = int(ship.storEn) ship.combatAtt = int(ship.combatAtt / (ship.combatClass + 1.0)) ship.combatDef = int(ship.combatDef / (ship.combatClass + 1.0)) ship.missileDef = int(ship.missileDef / (ship.combatClass + 1.0)) ship.maxHP = int(ship.maxHP) ship.shieldHP = int(ship.maxHP * shieldPerc) ship.scannerPwr = int(ship.scannerPwr) ship.engPwr = int(ship.engPwr) ship.signature = int(ship.signature) ship.baseExp = int(ship.baseExp) # compute attack power attackPwr = 0.0 refDefence = 10.0 refAttack = 10.0 refDmg = 10.0 refSpeed = 5.0 #average speed of medium and large hulls for weaponID in ship.weaponIDs: weapon = Rules.techs[weaponID] dmg = (weapon.weaponDmgMin + weapon.weaponDmgMax) / 2 * weapon.weaponROF att = int((ship.combatAtt + weapon.weaponAtt) * ship.combatAttMultiplier) #added combat multiplier # attackPwr += (att / float(att + refDefence) * dmg) attackPwr += (att / float(att + refDefence) * dmg) / (max(1,weapon.weaponClass-1)) #9/11/06 - RC; reduce power of bombs and torps in calculation # defence # ship.combatPwr = int(attackPwr * (ship.maxHP + ship.shieldHP) / (refAttack / (refAttack + ship.combatDef) * refDmg)) ship.combatPwr = int(attackPwr * (ship.maxHP + ship.shieldHP) / (refAttack / (refAttack + ship.combatDef) * refDmg) * min(1.33,max(0.5,(ship.speed / refSpeed))) + combatExtra) #9/11/06 - RC; average speed ships get most weight) # fix signature ship.signature = max(hull.minSignature, ship.signature, ship.minSignature) #removed 1 as min signature; use hulls to control that from now on; change Fleet controls to make min signature for fleet rather than ship so that we can have human stealth craft! :) # return ship
def setMergeState(self, tran, obj, state): if not state in [0,1,2]: raise GameException('Bad join fleet state.') #should we log this? Probably don't need to. obj.allowmerge = state return obj.allowmerge
def makeShipFullSpec(player, name, hullID, eqIDs, improvements, raiseExs=True): if not hullID: raise GameException("Ship's hull must be specified.") hull = Rules.techs[hullID] if not hull.isShipHull: raise GameException("Ship's hull must be specified.") ship = IDataHolder() ship.type = Const.T_SHIP # initial values hullTechEff = Rules.techImprEff[player.techs.get( hullID, Rules.techBaseImprovement)] ship.name = name ship.hullID = hullID ship.eqIDs = eqIDs ship.level = hull.level ship.combatClass = hull.combatClass ship.improvements = improvements ship.buildProd = hull.buildProd ship.buildSRes = copy.copy(hull.buildSRes) # stats grouped as "Base" ship.operEn = hull.operEn ship.storEn = hull.storEn * hullTechEff ship.weight = hull.weight ship.slots = 0 ship.scannerPwr = max(hull.scannerPwr * hullTechEff, Rules.scannerMinPwr) ship.engPwr = 0 ship.engStlPwr = 0 ship.speed = 0.0 ship.battleSpeed = 0.0 # stats grouped as "Signature" ship.signature = hull.signature ship.negsignature = 0 ship.minSignature = hull.minSignature ship.signatureCloak = 1.0 ship.signatureDecloak = 1.0 # stats grouped as "Combat" ship.combatAttBase = hull.combatAtt * hullTechEff ship.combatAtt = 0 ship.combatAttMultiplier = 1.0 ship.combatDefBase = hull.combatDef * hullTechEff ship.combatDef = 0 ship.combatDefMultiplier = 1.0 ship.missileDefBase = hull.missileDef * hullTechEff ship.missileDef = 0 ship.missileDefMultiplier = 1.0 ship.weaponIDs = [] ship.isMilitary = 0 ship.baseExp = 0 combatExtra = 0 # stats grouped as "Sturdiness" ship.autoRepairFix = hull.autoRepairFix ship.autoRepairPerc = hull.autoRepairPerc ship.shieldRechargeFix = hull.shieldRechargeFix ship.shieldRechargePerc = hull.shieldRechargePerc ship.hardShield = 0.0 ship.shieldHP = 0 ship.maxHP = int(hull.maxHP * hullTechEff) ship.damageAbsorb = 0 shieldPerc = 0.0 # stats grouped as "Deployables" ship.deployStructs = [] ship.deployHandlers = [] ship.upgradeTo = 0 counter = {} installations = {} equipCounter = {} for techID in eqIDs: tech = Rules.techs[techID] techEff = Rules.techImprEff[player.techs.get( techID, Rules.techBaseImprovement)] if eqIDs[techID] < 0 and raiseExs: raise GameException("Invalid equipment count (less than 0).") for i in xrange(0, eqIDs[techID]): counter[tech.subtype] = 1 + counter.get(tech.subtype, 0) installations[techID] = 1 + installations.get(techID, 0) _checkValidity(ship, tech, installations, equipCounter, raiseExs) # add values _moduleBase(ship, tech, techEff) _moduleSignature(ship, tech) _moduleCombat(ship, tech, techEff, combatExtra) _moduleSturdiness(ship, tech, techEff, shieldPerc) _moduleDeployables(ship, tech) _checkValidityWhole(ship, hull, counter, raiseExs) _finalizeBase(ship, hull) _finalizeSignature(ship, hull) _finalizeCombat(ship) _finalizeSturdiness(ship, shieldPerc) _setCombatPower(ship, combatExtra) return ship
def moveToTarget(self, tran, obj, targetID): #added action passthrough for wormhole move...needed # DON'T move fleet with speed == 0 if obj.speed <= 0: # they cannot arive (never) # reset retreat counter obj.combatRetreatWait = 0 return 1 if targetID == OID_NONE: # reset retreat counter obj.combatRetreatWait = 0 return 1 # reset/remember old values obj.oldX = obj.x obj.oldY = obj.y obj.eta = 0.0 target = tran.db[targetID] # MOVE to target dx = target.x - obj.x dy = target.y - obj.y #if dx == 0 and dy == 0: # return 1 if obj.orbiting: system = tran.db[obj.orbiting] if system.combatCounter > 0: # well, there is a combat there -> wait a while and reduce ROF obj.combatRetreatWait += 1 if obj.combatRetreatWait <= Rules.combatRetreatWait: return 0 # ok, we suffered enough, move away # reset counter obj.combatRetreatWait = 0 # speed boost? obj.speedBoost = Utils.getSpeedBoost(tran, tran.db[obj.owner], (system, target)) # try: system.fleets.remove(obj.oid) except ValueError: log.warning('IFleet', 'Problem with removing fleet from system.') obj.orbiting = OID_NONE # change close system to target one if obj.closeSystem != OID_NONE: # TODO remove condition in 0.6 system = tran.db[obj.closeSystem] try: system.closeFleets.remove(obj.oid) except ValueError: log.warning("IFleet", "Problem with changing the close system.") if target.type == T_PLANET: system = tran.db[target.compOf] system.closeFleets.append(obj.oid) obj.closeSystem = system.oid elif target.type in (T_SYSTEM, T_WORMHOLE): target.closeFleets.append(obj.oid) obj.closeSystem = target.oid else: raise GameException('Unsupported type of target %d for move command.' % target.type) dist = math.hypot(dx, dy) maxDelta = obj.speed / Rules.turnsPerDay * obj.speedBoost if not maxDelta: obj.combatRetreatWait = 0 return 0 arrived = 0 # 0.01 acceptable error if dist <= maxDelta + 0.01: # we are at destination obj.x = target.x obj.y = target.y if target.type == T_PLANET: obj.orbiting = target.compOf system = tran.db[obj.orbiting] system.fleets.append(obj.oid) arrived = 1 elif target.type == T_SYSTEM or target.type == T_WORMHOLE: #@log.debug('IFleet', obj.oid, 'is aproaching orbit of', targetID) obj.orbiting = target.oid system = tran.db[obj.orbiting] system.fleets.append(obj.oid) #@log.debug('IFleet', system.oid, 'system fleets', system.fleets) arrived = 1 else: raise GameException('Unsupported type of target %d for move command.' % target.type) else: # move obj.x += dx / dist * maxDelta obj.y += dy / dist * maxDelta # (already moved 1 x maxDelta) (0.01 is acceptable error) obj.eta = math.ceil(dist / maxDelta - 1 - 0.01) if arrived: # just make sure that this is reset obj.combatRetreatWait = 0 # turn scanner on obj.scannerOn = True # check the speed boost speedBoost = Utils.getSpeedBoost(tran, tran.db[obj.owner], (system,)) if speedBoost < obj.speedBoost: # damage all ships in the fleet # damage is based on percentual difference percHull = 1.0 - Rules.starGateDamage * (obj.speedBoost / speedBoost - 1.0) log.debug(obj.oid, "fleet speed boost too low - damaging ships", speedBoost, obj.speedBoost, percHull) Utils.sendMessage(tran, obj, MSG_DAMAGE_BY_SG, obj.orbiting, int((1.0 - percHull) * 100)) for ship in obj.ships: ship[SHIP_IDX_HP] = max(1, int(ship[SHIP_IDX_HP] * percHull)) # TODO: send message to player obj.speedBoost = 1.0 # add ship to the scanner pwrs of the system system.scannerPwrs[obj.owner] = max(obj.scannerPwr, system.scannerPwrs.get(obj.owner, 0)) return arrived