def update(self, tran, obj): obj.techLevel = 99 obj.race = "m" # grant technologies obj.techs[Rules.Tech.EMCANNON] = Rules.techMaxImprovement obj.techs[Rules.Tech.SSROCKET] = Rules.techMaxImprovement obj.techs[Rules.Tech.TORPEDO] = Rules.techMaxImprovement obj.techs[Rules.Tech.FTLENG1] = 3 obj.techs[Rules.Tech.SMALLHULL1] = 3 obj.techs[Rules.Tech.SCOCKPIT1] = 3 obj.techs[Rules.Tech.SCANNERMOD1] = 3 obj.techs[Rules.Tech.CONBOMB1] = 3 obj.techs[Rules.Tech.MUTANTBASE] = 3 obj.techs[Rules.Tech.MUTANTBASE2] = 3 obj.techs[Rules.Tech.MUTANTBASE3] = 3 obj.techs[Rules.Tech.MUTANTBASE4] = 3 obj.techs[Rules.Tech.MUTANTPP1] = 3 obj.techs[Rules.Tech.MUTANTPP2] = 3 obj.techs[Rules.Tech.MUTANTFACT1] = 3 obj.techs[Rules.Tech.MUTANTFACT2] = 3 obj.techs[Rules.Tech.MUTANTMINES] = 3 # create two basic designs [they use modules not available to the # player otherwise so it has to be done this way] obj.shipDesigns[1] = ShipUtils.makeShipMinSpec(obj, 'Swarmer', Rules.Tech.SMALLHULL1, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.EMCANNON:2, Rules.Tech.FTLENG1:2}, []) obj.shipDesigns[2] = ShipUtils.makeShipMinSpec(obj, 'Seeder', Rules.Tech.MEDIUMHULL2, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.MUTANTPOD:1, Rules.Tech.FTLENG1:4}, []) obj.shipDesigns[3] = ShipUtils.makeShipMinSpec(obj, 'Seeker', Rules.Tech.SMALLHULL1, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.SCANNERMOD1:1, Rules.Tech.FTLENG1:2}, []) obj.shipDesigns[4] = ShipUtils.makeShipMinSpec(obj, 'Sower', Rules.Tech.SMALLHULL1, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.CONBOMB1:1, Rules.Tech.FTLENG1:2}, []) # call super method IPlayer.update(self, tran, obj)
def setStartingShipDesigns(obj): obj.shipDesigns[1] = ShipUtils.makeShipMinSpec( obj, 'Fighter', Rules.Tech.SMALLHULL1, { Rules.Tech.SCOCKPIT1: 1, Rules.Tech.CANNON1: 1, Rules.Tech.STLENG1: 2 }, []) obj.shipDesigns[2] = ShipUtils.makeShipMinSpec( obj, 'Corvette', Rules.Tech.SMALLHULL1, { Rules.Tech.SCOCKPIT1: 1, Rules.Tech.CANNON1: 2, Rules.Tech.STLENG1: 1, Rules.Tech.STEELARM2: 1 }, []) obj.shipDesigns[3] = ShipUtils.makeShipMinSpec( obj, 'Frigate', Rules.Tech.MEDIUMHULL2, { Rules.Tech.SBRIDGE1: 1, Rules.Tech.CANNON1: 2, Rules.Tech.SSROCKET: 2, Rules.Tech.STLENG1: 2 }, []) obj.shipDesigns[4] = ShipUtils.makeShipMinSpec( obj, 'Destroyer', Rules.Tech.MEDIUMHULL2, { Rules.Tech.SBRIDGE1: 1, Rules.Tech.CANNON1: 4, Rules.Tech.SSROCKET: 2, Rules.Tech.NSTLENG2: 3 }, []) obj.shipDesigns[5] = ShipUtils.makeShipMinSpec( obj, 'Armored Cruiser', Rules.Tech.RENEGADETITANIUMMHULL, { Rules.Tech.SBRIDGE1: 1, Rules.Tech.CANNON1: 5, Rules.Tech.SSROCKET: 3, Rules.Tech.STLENG1: 4 }, [])
def setStartingShipDesigns(obj): obj.shipDesigns[1] = ShipUtils.makeShipMinSpec(obj, 'Swarmer', Rules.Tech.SMALLHULL1, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.EMCANNON:2, Rules.Tech.STLENG1:1, Rules.Tech.FTLENG1:2}, []) obj.shipDesigns[2] = ShipUtils.makeShipMinSpec(obj, 'Seeder', Rules.Tech.MEDIUMHULL2, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.MUTANTPOD:1, Rules.Tech.FTLENG1:4}, []) obj.shipDesigns[3] = ShipUtils.makeShipMinSpec(obj, 'Seeker', Rules.Tech.SMALLHULL1, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.SCANNERMOD1:1, Rules.Tech.FTLENG1:2}, []) obj.shipDesigns[4] = ShipUtils.makeShipMinSpec(obj, 'Sower', Rules.Tech.SMALLHULL1, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.CONBOMB1:1, Rules.Tech.STLENG1:1, Rules.Tech.FTLENG1:2}, [])
def setStartingShipDesigns(obj): obj.shipDesigns[1] = ShipUtils.makeShipMinSpec(obj, 'Fighter', Rules.Tech.SMALLHULL1, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.CANNON1:1, Rules.Tech.STLENG1:2}, []) obj.shipDesigns[2] = ShipUtils.makeShipMinSpec(obj, 'Corvette', Rules.Tech.SMALLHULL1, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.CANNON1:2, Rules.Tech.STLENG1:1, Rules.Tech.STEELARM2:1}, []) obj.shipDesigns[3] = ShipUtils.makeShipMinSpec(obj, 'Frigate', Rules.Tech.MEDIUMHULL2, {Rules.Tech.SBRIDGE1:1, Rules.Tech.CANNON1:2, Rules.Tech.SSROCKET:2, Rules.Tech.STLENG1:2}, []) obj.shipDesigns[4] = ShipUtils.makeShipMinSpec(obj, 'Destroyer', Rules.Tech.MEDIUMHULL2, {Rules.Tech.SBRIDGE1:1, Rules.Tech.CANNON1:4, Rules.Tech.SSROCKET:2, Rules.Tech.NSTLENG2:3}, []) obj.shipDesigns[5] = ShipUtils.makeShipMinSpec(obj, 'Armored Cruiser', Rules.Tech.RENEGADETITANIUMMHULL, {Rules.Tech.SBRIDGE1:1, Rules.Tech.CANNON1:5, Rules.Tech.SSROCKET:3, Rules.Tech.STLENG1:4}, [])
def addShipDesign(self, tran, obj, name, hullID, eqIDs): """Add ship design to the database of designs.""" # normalize design name = name.strip() # check technologies if hullID not in obj.techs: raise GameException("You do not posses this hull type.") for techID in eqIDs: if techID not in obj.techs: raise GameException("You do not posses technology(ies) to construct this ship.") # create spec (throws exception for invad ones) spec = ShipUtils.makeShipMinSpec(obj, name, hullID, eqIDs, []) # check number of designs if len(obj.shipDesigns) > Rules.shipMaxDesigns: raise GameException("No space to store design.") # check name of designs for designID in obj.shipDesigns: if obj.shipDesigns[designID].name == name: raise GameException("Design name is already used.") if re.match("^\s*$",name): raise GameException("Design name must not be entirely whitespace.") # find free design id index = 1 ids = obj.shipDesigns.keys() while 1: if index not in ids: break index += 1 # add design obj.shipDesigns[index] = spec return obj.shipDesigns, index
def update(self, tran, obj): obj.techLevel = 99 obj.race = "r" # grant technologies obj.techs[Rules.Tech.CANNON1] = 3 obj.techs[Rules.Tech.SSROCKET] = 3 obj.techs[Rules.Tech.RENEGADEBASE] = 3 obj.techs[Rules.Tech.RENEGADEBASE2] = 3 obj.techs[Rules.Tech.RENEGADEBASE2MINOR] = 3 obj.techs[Rules.Tech.RENEGADEBASE3] = 3 obj.techs[Rules.Tech.RENEGADEBASE3MINOR] = 3 obj.techs[Rules.Tech.RENEGADECOSMODROME] = 3 if not len(obj.shipDesigns) == 3: # three basic designs [they use modules not available to the player otherwise # so it has to be done this way] obj.shipDesigns[1] = ShipUtils.makeShipMinSpec(obj, 'Fighter', Rules.Tech.SMALLHULL1, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.CANNON1:1}, []) obj.shipDesigns[2] = ShipUtils.makeShipMinSpec(obj, 'Corvette', Rules.Tech.SMALLHULL1, {Rules.Tech.SCOCKPIT1:1, Rules.Tech.CANNON1:2, Rules.Tech.STEELARM2:1}, []) obj.shipDesigns[3] = ShipUtils.makeShipMinSpec(obj, 'Frigate', Rules.Tech.MEDIUMHULL2, {Rules.Tech.SBRIDGE1:1, Rules.Tech.CANNON1:2, Rules.Tech.SSROCKET:2}, []) # call super method IPlayer.update(self, tran, obj)
def getPreCombatData(self, tran, obj): # scan buildings and fire their weapons shots = {0: [], 1: [], 2: [], 3: []} if obj.owner == OID_NONE: return shots, [0, 0, 0, 8], False player = tran.db[obj.owner] system = tran.db[obj.compOf] desCount = {} firing = False systemAtt = 0; systemDef = 0; for struct in obj.slots: structTechID = struct[STRUCT_IDX_TECHID] opStatus = struct[STRUCT_IDX_OPSTATUS] / 100.0 tech = Rules.techs[structTechID] desCount[structTechID] = desCount.get(structTechID, 0) + 1 wpnCount = {} if not tech.structWeapons: continue firing = True for cClass in range(0, 4): weaponID = player.planetWeapons[cClass] if weaponID is None: continue weapon = Rules.techs[weaponID] maxWeaponCount = int(tech.structWeapons[cClass] * opStatus) for weaponIdx in range(0, maxWeaponCount): #@log.debug(obj.oid, "FIRING PLANET WEAPON", weapon.name) wpnCount[weaponID] = wpnCount.get(weaponID, 0) + 1 # weaponEff = Rules.techImprEff[player.techs.get(weaponID, Rules.techBaseImprovement)] # base attack attack = tech.combatAtt + int(weapon.weaponAtt * weaponEff) # because ALL counters starts at 1, subtract 3 count = system.combatCounter + desCount[structTechID] + wpnCount[weaponID] - 2 # add to attacks #@log.debug('IPlanet', obj.oid, structTechID, "Count", count, 'Shots', weapon.name, ShipUtils.getRounds(weapon.weaponROF, count)) for round in xrange(0, ShipUtils.getRounds(weapon.weaponROF, count)): shots[weapon.weaponClass].append((attack, weaponID)) # hit limit obj.maxHits = len(obj.slots) obj.hitCounter = 0 obj.lastHitClass = 3 obj.hitMod = 1.0 log.debug(obj.oid, "Combat settings", obj.maxHits) # +1 means population only hit return shots, [0, 0, 0, 8], firing
def getPreCombatData(self, tran, obj): # compute data shots = {0: [], 1: [], 2: [], 3: []} targets = [0, 0, 0, 0] player = tran.db[obj.owner] desCount = {} firing = False rofMod = 1.0 # limit number of shots per ship obj.maxHits = {0: 0, 1: 0, 2: 0, 3: 0} obj.hitCounters = {0: 0, 1: 0, 2: 0, 3: 0} obj.lastHitClass = 3 obj.hitMods = {0: 1.0, 1: 1.0, 2: 1.0, 3: 1.0} if obj.combatRetreatWait > 0: # ROF penalty #@log.debug(obj.oid, "Fleet inactive", obj.combatRetreatWait) rofMod *= 0.33 if obj.storEn == 0: rofMod *= 0.33 for designID, hp, shield, exp in obj.ships: tech = player.shipDesigns[designID] targets[tech.combatClass] += 1 desCount[designID] = desCount.get(designID, 0) + 1 obj.maxHits[tech.combatClass] += 2 wpnCount = {} for weaponID in tech.weaponIDs: firing = True weapon = Rules.techs[weaponID] wpnCount[weaponID] = wpnCount.get(weaponID, 0) + 1 # weaponEff = Rules.techImprEff[player.techs.get(weaponID, Rules.techBaseImprovement)] # base attack attack = (tech.combatAtt + int(weapon.weaponAtt * weaponEff)) * tech.combatAttMultiplier #added multiplier part # correct using ship's level level = Rules.shipExpToLevel.get(int(exp / tech.baseExp), Rules.shipDefLevel) attack = int(attack * Rules.shipLevelEff[level]) # because ALL counters starts at 1, subtract 3 count = obj.combatCounter + desCount[designID] + wpnCount[weaponID] - 3 # add to attacks #@log.debug('IFleet', obj.oid, designID, "Count", count, 'Shots', weapon.name, ShipUtils.getRounds(weapon.weaponROF, count)) for round in xrange(0, ShipUtils.getRounds(weapon.weaponROF * rofMod, count)): shots[weapon.weaponClass].append((attack, weaponID)) log.debug(obj.oid, "Combat limit settings", obj.maxHits) return shots, targets, firing
def update(self, tran, obj): # update all designs for designID in obj.shipDesigns: old = obj.shipDesigns[designID] new = ShipUtils.makeShipMinSpec(obj, old.name, old.hullID, old.eqIDs, old.improvements, raiseExs = False) new.built = old.built if hasattr(old, "upgradeTo"): new.upgradeTo = old.upgradeTo obj.shipDesigns[designID] = new # check all diplomacyRels for partyID in obj.diplomacyRels.keys(): party = tran.db.get(partyID, None) if not party or party.type not in PLAYER_TYPES: log.debug("Deleting party", obj.oid, partyID) del obj.diplomacyRels[partyID] # delete obj with low scan pwr # check type of the objects in the map for objID in obj.staticMap.keys(): obj.staticMap[objID] = min(obj.staticMap[objID], Rules.maxScanPwr) if obj.staticMap[objID] < Rules.level1InfoScanPwr: del obj.staticMap[objID] if not tran.db.has_key(objID) or tran.db[objID].type not in (T_SYSTEM, T_WORMHOLE): log.debug("Deleting non system %d from static map of player %d" % (objID, obj.oid)) del obj.staticMap[objID] for objID in obj.dynamicMap.keys(): if obj.dynamicMap[objID] < Rules.level1InfoScanPwr: del obj.dynamicMap[objID] if not tran.db.has_key(objID) or tran.db[objID].type not in (T_FLEET, T_ASTEROID): log.debug("Deleting obj %d from dynamic map of player %d" % (objID, objID)) del obj.dynamicMap[objID] # check if all planets are planets for objID in obj.planets[:]: try: if not tran.db.has_key(objID): log.debug("Planet does not exists - removing", obj.oid, objID) obj.planets.remove(objID) if tran.db[objID].type != T_PLANET: log.debug("Planet is not a planet - removing", obj.oid, objID) obj.planets.remove(objID) except: log.warning("There is a problem when processing planet - removing", obj.oid, objID) obj.planets.remove(objID) # check if systems in buoys are systems for objID in obj.buoys.keys(): try: if not tran.db.has_key(objID): log.debug("System for buoy does not exists - removing", obj.oid, objID) del obj.buoys[objID] if tran.db[objID].type not in (T_SYSTEM, T_WORMHOLE): log.debug("System for buoy is not a system - removing", obj.oid, objID) del obj.buoys[objID] except: log.warning("There is a problem when processing system for buoy - removing", obj.oid, objID) del obj.buoys[objID] # check if fleets are fleets for objID in obj.fleets[:]: try: if not tran.db.has_key(objID): log.debug("Fleet does not exists - removing", obj.oid, objID) obj.fleets.remove(objID) if tran.db[objID].type not in (T_FLEET, T_ASTEROID): log.debug("Fleet is not a fleet - removing", obj.oid, objID) obj.fleets.remove(objID) except: log.warning("There is a problem when processing planet - removing", obj.oid, objID) # check accessible technologies wip = 1 while wip: wip = 0 for techID in obj.techs.keys(): if techID not in Rules.techs: wip = 1 log.debug("Deleting nonexistent tech", techID, "player", obj.oid) del obj.techs[techID] continue tech = Rules.techs[techID] # check tech level if tech.level > obj.techLevel: wip = 1 log.debug("Deleting tech", techID, "player", obj.oid) if techID in obj.techs: del obj.techs[techID] # disabled? #for tmpTechID in obj.techs.keys(): # if techID in Rules.techs[tmpTechID].researchDisables: # wip = 1 # log.debug("Deleting tech", techID, "player", obj.oid) # if techID in obj.techs: del obj.techs[techID] # break # check requirements #for tmpTechID, improvement in tech.researchRequires: # if not obj.techs.has_key(tmpTechID) or obj.techs[tmpTechID] < improvement: # wip = 1 # log.debug("Deleting tech", techID, "player", obj.oid) # if techID in obj.techs: del obj.techs[techID] # break for rTask in obj.rsrchQueue[:]: if rTask.techID not in Rules.techs: log.debug("Deleting res task for nonexistent tech", rTask.techID, "player", obj.oid) obj.rsrchQueue.remove(rTask) continue tech = Rules.techs[rTask.techID] if tech.level == 99: log.debug("Deleting res task", rTask.techID, "player", obj.oid) obj.rsrchQueue.remove(rTask) # check if player is in the universe universe = tran.db[OID_UNIVERSE] if obj.oid not in universe.players and obj.oid not in (OID_NATURE, OID_ADMIN): log.debug(obj.oid, "Adding player to the universe") universe.players.append(obj.oid) # check nick (TODO remove in 0.5.33) if not hasattr(obj, "fullName"): obj.fullName = obj.name # check if player is a leader if not obj.galaxies: log.debug(obj.oid, obj.name, "IS NOT IN ANY GALAXY") else: galaxy = tran.db[obj.galaxies[0]] if galaxy.imperator != obj.oid and obj.imperator > 0: log.debug(obj.oid, "Removing imperator/leader bonus") obj.imperator = 0 ## NON VALIDATING CODE (DERIVED ATTRS AND SO ON) # get best technologies for planet weapons bestScores = [0, 0, 0, 0] obj.planetWeapons = [None, None, None, None, None] for techID in obj.techs: tech = Rules.techs[techID] if tech.isShipEquip and tech.weaponDmgMin > 0 and not tech.buildSRes\ and tech.weaponGoodForFlak: # compute score weaponEff = Rules.techImprEff[obj.techs.get(techID, Rules.techBaseImprovement)] score = (tech.weaponDmgMin + tech.weaponDmgMax) / 2.0 * \ tech.weaponROF * (tech.weaponAtt + 10.0)/10 * weaponEff if score > bestScores[tech.weaponClass]: obj.planetWeapons[tech.weaponClass] = techID bestScores[tech.weaponClass] = score #@log.debug(obj.oid, "Planet weapons", obj.planetWeapons) # update all ship designs for designID in obj.shipDesigns: old = obj.shipDesigns[designID] new = ShipUtils.makeShipMinSpec(obj, old.name, old.hullID, old.eqIDs, old.improvements, raiseExs = False) new.built = old.built new.upgradeTo = old.upgradeTo obj.shipDesigns[designID] = new
def applyShot(self, tran, obj, defense, attack, weaponID, cClass, count): #@log.debug('IPlanet', 'Apply shot', weaponID, attack, cClass, count) # compute chance to hit weapon = Rules.techs[weaponID] #system defense bonus is dropped for planets...structures can't move; just calculate defense off structure defense defense = Rules.combatStructDefense destroyed = 0 dmg = 0 # limit number of shots if weapon.weaponClass < obj.lastHitClass: #@log.debug(obj.oid, "Different class", obj.lastHitClass, weapon.weaponClass, obj.maxHits) obj.maxHits = int(Rules.combatHitXferMod * obj.maxHits * (obj.lastHitClass - weapon.weaponClass)) obj.hitCounter = int(Rules.combatHitXferMod * obj.hitCounter * (obj.lastHitClass - weapon.weaponClass)) obj.lastHitClass = weapon.weaponClass if weapon.weaponROF > 1: #@log.debug(obj.oid, "Increasing counter PL", 1.0 / weapon.weaponROF) obj.hitCounter += 1.0 / weapon.weaponROF else: #@log.debug(obj.oid, "Increasing counter PL", 1) obj.hitCounter += 1 if obj.hitCounter > obj.maxHits: obj.hitCounter = 0 obj.hitMod *= Rules.combatStructureHitMod #@log.debug(obj.oid, "Increasing hit penalty", obj.hitMod, obj.maxHits) attackChance = obj.hitMod * attack / (attack + defense) #@log.debug(obj.oid, "Chance to attack", attackChance, obj.hitMod, obj.hitCounter, obj.maxHits, #@ "without penalty:", float(attack) / (attack + defense)) #@log.debug('IPlanet', obj.oid, 'HIT?', attack + defense + 1, defense) absorb = 0 #for when it doesn't hit if random.random() <= attackChance: # hit player = tran.db[obj.owner] weaponEff = Rules.techImprEff[player.techs.get(weaponID, Rules.techBaseImprovement)] dmg = ShipUtils.computeDamage(weapon.weaponClass, 3, weapon.weaponDmgMin, weapon.weaponDmgMax, weaponEff) #@log.debug(obj.oid, 'HIT! att=%d vs def=%d, dmg=%d '% (attack, defense, dmg)) #shield strike if obj.shield > 0: absorb = min(dmg,obj.shield) obj.shield -= absorb dmg -= absorb if dmg == 0: return 0+absorb, 0, 3 # select slot if count == 7 or not obj.slots: #@log.debug('IPlanet', 'Population hit') # population hit if obj.storPop == 0: dmg = 0 else: # free slot hit -> dmg population # OLD dmgPop = int(Rules.popPerSlot * float(dmg) / Rules.popSlotHP * Rules.popKillMod) dmgPop = int(dmg * Rules.popSlotKillMod) obj.storPop = max(obj.storPop - dmgPop, 0) obj.changePop -= dmgPop if obj.storPop > 0: obj.morale -= Rules.moraleModPlHit * float(dmgPop) / float(obj.storPop) #@log.debug('IPlanet', obj.oid, 'Morale penalty', dmg, maxHP, Rules.moraleModPlHit * float(dmg) / float(maxHP)) elif count < 0: # TODO can be count negative? log.warning('IPlanet', 'applyShot: count is negative') else: if count == 6: # random structure hit #@log.debug('IPlanet', 'Random structure hit') struct = obj.slots[Utils.rand(0, len(obj.slots))] else: # most damaged structure hit #@log.debug('IPlanet', 'Most damaged structure hit') struct = obj.slots[-1] for tmpStruct in obj.slots: if tmpStruct[STRUCT_IDX_HP] <= struct[STRUCT_IDX_HP]: struct = tmpStruct # compute sum hp of all buildings sumHP = 0 for tmpStruct in obj.slots: sumHP += tmpStruct[STRUCT_IDX_HP] # damage building struct[STRUCT_IDX_HP] -= dmg # "damage" population tech = Rules.techs[struct[STRUCT_IDX_TECHID]] # compute struct effectivity techEff = Utils.getTechEff(tran, struct[STRUCT_IDX_TECHID], obj.owner) maxHP = int(tech.maxHP * techEff) dmgPop = int(tech.operWorkers * float(dmg) / maxHP * Rules.popKillMod) obj.storPop = max(obj.storPop - dmgPop, 0) obj.changePop -= dmgPop # destroy building if struct[STRUCT_IDX_HP] <= 0: destroyed = 1 dmg += struct[STRUCT_IDX_HP] obj.slots.remove(struct) # compute morale penalty if dmg: obj.morale -= Rules.moraleModPlHit * float(dmg) / float(sumHP) #@log.debug('IPlanet', obj.oid, 'Morale penalty', dmg, sumHP, Rules.moraleModPlHit * float(dmg) / float(sumHP)) #@log.debug('IPlanet', 'Shot applied', dmg, destroyed) # when destroyed, only class 3 (structure) i valid return dmg+absorb, destroyed, 3
def update(self, tran, obj): if not (hasattr(obj,'customname')): #added in 0.5.64 obj.customname = None obj.allowmerge = 1 # if there are no ships -> disband fleet if not len(obj.ships) or obj.owner == OID_NONE: log.warning(obj.oid, "FLEET - no ships in the fleet -- disbanding") self.cmd(obj).disbandFleet(tran, obj) return # check for duplicates (TODO: remove me, bug was fixed) #for ship1 in obj.ships: # duplicates = 0 # for ship2 in obj.ships: # if ship1 is ship2: # duplicates += 1 # if duplicates != 1: # # regenerate ships # newShips = [] # for designID, hp, shield, exp in obj.ships: # newShips.append([designID, hp, shield, exp]) # obj.ships = newShips # raise ServerException("Ship duplicates in %s" % obj) # obj.origScannerPwr = 0 obj.operEn = 0 obj.operProd = 0.0 obj.maxEn = 0 obj.maxSpeed = 999999.9 obj.combatPwr = 0 obj.isMilitary = 0 #ships = {} # find player = tran.db.get(obj.owner, None) if not player or player.type not in PLAYER_TYPES or obj.oid not in player.fleets: # disband fleet when owner is invalid log.warning(obj.oid, "Disbanding fleet - invalid owner", obj) self.cmd(obj).disbandFleet(tran, obj) return obj.signature = 0 remove = [] idx = 0 for designID, hp, shield, exp in obj.ships: if designID in player.shipDesigns: tech = player.shipDesigns[designID] obj.origScannerPwr = max(tech.scannerPwr, obj.origScannerPwr) obj.operEn += tech.operEn obj.operProd += tech.buildProd * Rules.operProdRatio obj.maxEn += tech.storEn obj.maxSpeed = min(obj.maxSpeed, tech.speed) obj.signature += tech.signature obj.combatPwr += int(tech.combatPwr * float(hp + shield) / (tech.maxHP + tech.shieldHP)) obj.isMilitary = obj.isMilitary or tech.isMilitary #ships[tech.signature] = ships.get(tech.signature, 0) + 1 if obj.ships[idx][1] > tech.maxHP: log.debug(obj.oid, "Too high maxHP for ship, player", obj.owner) obj.ships[idx][1] = min(obj.ships[idx][1], tech.maxHP) else: # TODO track this problem log.warning("Player has not this designID", player.oid, designID) remove.append([designID, hp, shield, exp]) idx += 1 # delete ships intended for removal for shipSpec in remove: obj.ships.remove(shipSpec) # misc obj.signature = min(obj.signature, Rules.maxSignature) obj.signature = max(obj.signature,1) #require fleet signature to be at least 1 now that we removed that from a per-ship basis obj.speed = obj.maxSpeed # storage obj.storEn = min(obj.storEn, obj.maxEn) # sort ships only when there is no combat # this prevents resorting fleets in combat if obj.combatCounter == 0: obj.ships = ShipUtils.sortShips(obj.ships) else: log.debug("Skipping ship (re)sorting [fleet in combat]", obj.oid) # closest system if not tran.db.has_key(obj.closeSystem) or tran.db[obj.closeSystem].type not in (T_SYSTEM, T_WORMHOLE): if obj.orbiting == OID_NONE: log.debug("No close system for fleet", obj.oid) # select any system systemID = tran.db[tran.db[OID_UNIVERSE].galaxies[0]].systems[0] obj.closeSystem = systemID log.debug(obj.oid, "Setting NULL close system to", systemID) else: log.debug(obj.oid, "Generating close system from orbiting", obj.orbiting) obj.closeSystem = obj.orbiting system = tran.db[obj.closeSystem] if obj.oid not in system.closeFleets: system.closeFleets.append(obj.oid) # verify close system if tran.db.has_key(obj.closeSystem): system = tran.db[obj.closeSystem] if system.type in (T_SYSTEM, T_WORMHOLE): if obj.oid not in system.closeFleets: log.debug("Adding fleet", obj.oid, "into closeFleets of", system.oid) system.closeFleets.append(obj.oid) else: log.debug(obj.oid, "Close system is not a system") obj.closeSystem = OID_NONE else: log.debug(obj.oid, "Close system does not exists") obj.closeSystem = OID_NONE # compute scanner pwr if obj.closeSystem: system = tran.db[obj.closeSystem] emrLevel = tran.db[system.compOf].emrLevel obj.scannerPwr = int(obj.origScannerPwr * (2.0 - emrLevel)) # replace obsolete commands for actionTuple in obj.actions[:]: try: action, target, actionData = actionTuple except: log.warning(obj.oid, "Removing action", actionTuple) obj.actions.remove(actionTuple) index = 0 for action, target, actionData in obj.actions: if action >= 2 and action <= 100: # this is an old action -> replace it by move command if available if target != OID_NONE: log.debug(obj.oid, "Replacing action", action, "by action MOVE") obj.actions[index][0] = FLACTION_MOVE else: # replace by none action log.debug(obj.oid, "Replacing action", action, "by action NONE") obj.actions[index] = (FLACTION_NONE, None, None) if action == FLACTION_DEPLOY and actionData not in player.shipDesigns: # deployment of scrapped ship log.debug(obj.oid, "invalid ship to deploy") obj.actions[index] = (FLACTION_NONE, None, None) index += 1
def applyShot(self, tran, obj, defense, attack, weaponID, targetClass, target): #@log.debug(obj.oid, 'IFleet', 'Apply shot', attack, weaponID, targetClass, target) player = tran.db[obj.owner] # find correct ship to hit target = -1 targetCiv = 0 while target == -1: index = 0 found = 0 for designID, hp, shield, exp in obj.ships: design = player.shipDesigns[designID] if design.combatClass == targetClass and (design.isMilitary or targetCiv): found = 1 if Utils.rand(1, 101) < Rules.shipTargetPerc[targetClass]: target = index break index += 1 if not targetCiv: targetCiv = 1 continue if not found and targetCiv: # no such target class - try to find another one log.warning("No such target class in the fleet", obj.oid, targetClass) targetClass = targetClass + 1 targetCiv = 0 if targetClass > 3: return 0, 0, 0 designID, hp, shield, exp = obj.ships[target] ship = player.shipDesigns[designID] # compute if ship has been hit weapon = Rules.techs[weaponID] level = Rules.shipExpToLevel.get(int(exp / ship.baseExp), Rules.shipDefLevel) # add system defense bonus to ship inate defense if weapon.weaponIsMissile: defense += int(ship.missileDef * Rules.shipLevelEff[level]) else: defense += int(ship.combatDef * Rules.shipLevelEff[level]) destroyed = 0 destroyedClass = ship.combatClass dmg = 0 blocked = 0 # limit number of shots cClass = weapon.weaponClass if cClass < obj.lastHitClass: #@log.debug(obj.oid, "Different class", obj.lastHitClass, cClass, obj.maxHits) for i in range(obj.lastHitClass - 1, cClass - 1, -1): if obj.hitMods[cClass] >= 0.99: # == 1.0 #@log.debug(obj.oid, "Adding to", i, int(Rules.combatHitXferMod * (obj.maxHits[i + 1] - obj.hitCounters[i + 1])), obj.hitCounters[i + 1]) obj.maxHits[i] += int(Rules.combatHitXferMod * (obj.maxHits[i + 1] - obj.hitCounters[i + 1])) else: #@log.debug(obj.oid, "Not transfering hits") pass obj.maxHits[i + 1] = 0 #@log.debug(obj.oid, "max hits", obj.maxHits) obj.lastHitClass = cClass elif cClass > obj.lastHitClass: log.debug(obj.oid, "INCORRECT ORDER OF SHOTS", obj.lastHitClass, cClass) if weapon.weaponROF > 1: #@log.debug(obj.oid, "Increasing counter", cClass, 1.0 / weapon.weaponROF) obj.hitCounters[cClass] += 1.0 / weapon.weaponROF else: #@log.debug(obj.oid, "Increasing counter", cClass, 1) obj.hitCounters[cClass] += 1 if obj.hitCounters[cClass] > obj.maxHits[cClass]: obj.hitCounters[cClass] = 0 obj.hitMods[cClass] *= Rules.combatShipHitMod #@log.debug(obj.oid, "Increasing hit penalty", obj.hitMods[cClass], obj.maxHits[cClass], "class", cClass) # attackChance = obj.hitMods[cClass] * attack / (attack + defense) #@log.debug(obj.oid, "Chance to attack", attackChance, obj.hitMods[cClass], #@ obj.hitCounters[cClass], obj.maxHits[cClass], "without penalty:", float(attack) / (attack + defense)) if random.random() <= attackChance: player = tran.db[obj.owner] weaponEff = Rules.techImprEff[player.techs.get(weaponID, Rules.techBaseImprovement)] # HIT! -> apply damage dmg = ShipUtils.computeDamage(weapon.weaponClass, ship.combatClass, weapon.weaponDmgMin, weapon.weaponDmgMax, weaponEff) #@log.debug(obj.oid, 'HIT! att=%d vs def=%d, dmg=%d '% (attack, defense, dmg)) # shield if not weapon.weaponIgnoreShield and shield > 0: blocked = min(shield, dmg) obj.ships[target][2] -= blocked dmg -= blocked elif weapon.weaponIgnoreShield and ship.hardShield > 0 and shield > 0: blocked = min(shield, int(dmg*(ship.hardShield))) #hard shields also reduce penetrating weapons obj.ships[target][2] -= blocked dmg -= blocked #damage absorbsion by armor if ship.damageAbsorb > 0 and dmg > 0: dmg = max(0,dmg-ship.damageAbsorb) # armour if dmg >= hp: destroyed = 1 self.cmd(obj).removeShips(tran, obj, [obj.ships[target]]) dmg = hp else: obj.ships[target][1] -= dmg #@log.debug(obj.oid, "Damaged", dmg, blocked, destroyed) return dmg + blocked, destroyed, destroyedClass