예제 #1
0
def findPopCenterPlanets(db, planetsIDs):
    """ It finds "center of mass" of population.

    Returns sorted list    of all planets, beginning with those nearest to the
    found center.

    """
    x = 0
    y = 0
    population = 0
    for planetID in planetsIDs:
        planet = db[planetID]
        x += planet.x * planet.storPop
        y += planet.y * planet.storPop
        population += planet.storPop
    x /= population
    y /= population
    fakeObj = IDataHolder()
    fakeObj.x = x
    fakeObj.y = y
    return findNearest(db,
                       fakeObj,
                       planetsIDs,
                       maxDist=99999,
                       number=len(planetsIDs))
예제 #2
0
 def getPublicInfo(self, tran, obj):
     result = IDataHolder()
     result.oid = obj.oid
     result.type = obj.type
     result.name = obj.name
     result.turn = obj.turn
     return result
예제 #3
0
def getTechInfo(techID):
    player = db[db.playerID]
    tech = Rules.techs[techID]
    # player possess this technology
    if player.techs.has_key(techID):
        return tech

    if tech.fullInfo:
        return tech

    # player can research this technology
    canResearch = 1
    if player.race not in tech.researchRaces:
        canResearch = 0
    for tmpTechID, improvement in tech.researchRequires:
        if not player.techs.has_key(tmpTechID) or player.techs[tmpTechID] < improvement:
            canResearch = 0
            break
    for stratRes in tech.researchReqSRes:
        if player.stratRes.get(stratRes, 0) < 1:
            canResearch = 0
            break
    for tmpTechID in player.techs:
        if techID in Rules.techs[tmpTechID].researchDisables:
            canResearch = 0
            break
    if tech.level > player.techLevel:
        canResearch = 0

    if canResearch:
        result = IDataHolder()
        result.partialData = None
        for attr in [
            "name",
            "isDiscovery",
            "isStructure",
            "isProject",
            "isShipEquip",
            "isShipHull",
            "researchMod",
            "researchTurns",
            "textPreRsrch",
            "researchRequires",
            "subtype",
            "researchReqSRes",
            "researchDisables",
            "level",
            "researchRaces",
        ]:
            setattr(result, attr, getattr(tech, attr))
        return result
    # player should know only basic params about tech
    result = IDataHolder()
    result.partialData = None
    for attr in ["name", "researchRequires", "subtype", "level", "researchRaces"]:
        setattr(result, attr, getattr(tech, attr))
    return result
예제 #4
0
    def forceAllyWithEDEN(self, tran, obj):
        for partyID in obj.diplomacyRels.keys():
            party = tran.db.get(partyID, None)
            if party.type == T_AIEDENPLAYER:
                diplSelf = obj.diplomacyRels.get(party.oid, None)
                log.debug("Allying Pirate with EDEN (forced)", obj.oid,
                          partyID)
                diplEDEN = IDataHolder()
                diplEDEN.type = T_DIPLREL
                diplEDEN.pacts = {
                    PACT_ALLOW_CIVILIAN_SHIPS:
                    [PACT_ACTIVE, PACT_ALLOW_CIVILIAN_SHIPS],
                    PACT_ALLOW_MILITARY_SHIPS:
                    [PACT_ACTIVE, PACT_ALLOW_MILITARY_SHIPS]
                }
                diplEDEN.relation = REL_FRIENDLY
                diplEDEN.relChng = 0
                diplEDEN.lastContact = tran.db[OID_UNIVERSE].turn
                diplEDEN.contactType = CONTACT_STATIC
                diplEDEN.stats = None

                diplSelf.relation = REL_FRIENDLY
                diplSelf.pacts = {
                    PACT_ALLOW_CIVILIAN_SHIPS:
                    [PACT_ACTIVE, PACT_ALLOW_CIVILIAN_SHIPS],
                    PACT_ALLOW_MILITARY_SHIPS:
                    [PACT_ACTIVE, PACT_ALLOW_MILITARY_SHIPS]
                }

                obj.diplomacyRels[party.oid] = diplSelf
                party.diplomacyRels[obj.oid] = diplEDEN
예제 #5
0
	def forceAllyWithEDEN(self,tran,obj):
		for partyID in obj.diplomacyRels.keys():
			party = tran.db.get(partyID, None)
			if party.type == T_AIEDENPLAYER:
				diplSelf = obj.diplomacyRels.get(party.oid, None)
				log.debug("Allying Pirate with EDEN (forced)", obj.oid, partyID)
				diplEDEN = IDataHolder()
				diplEDEN.type = T_DIPLREL
				diplEDEN.pacts = {
						PACT_ALLOW_CIVILIAN_SHIPS: [PACT_ACTIVE, PACT_ALLOW_CIVILIAN_SHIPS],
						PACT_ALLOW_MILITARY_SHIPS: [PACT_ACTIVE, PACT_ALLOW_MILITARY_SHIPS]
				}
				diplEDEN.relation = REL_FRIENDLY
				diplEDEN.relChng = 0
				diplEDEN.lastContact = tran.db[OID_UNIVERSE].turn
				diplEDEN.contactType = CONTACT_STATIC
				diplEDEN.stats = None

				diplSelf.relation = REL_FRIENDLY
				diplSelf.pacts = {
					PACT_ALLOW_CIVILIAN_SHIPS: [PACT_ACTIVE, PACT_ALLOW_CIVILIAN_SHIPS],
					PACT_ALLOW_MILITARY_SHIPS: [PACT_ACTIVE, PACT_ALLOW_MILITARY_SHIPS]
				}
				
				obj.diplomacyRels[party.oid] = diplSelf
				party.diplomacyRels[obj.oid] = diplEDEN
예제 #6
0
 def getDiplomacyWith(self, tran, obj, playerID):
     # this AI battles with overyone
     # make default
     dipl = IDataHolder()
     dipl.type = Const.T_DIPLREL
     dipl.pacts = {}
     if obj.oid == playerID:
         dipl.relation = Const.REL_UNITY
     else:
         dipl.relation = Const.REL_ENEMY
     dipl.relChng = 0
     dipl.lastContact = tran.db[Const.OID_UNIVERSE].turn
     dipl.contactType = Const.CONTACT_NONE
     dipl.stats = None
     return dipl
예제 #7
0
 def init(self, obj):
     IObject.init(self, obj)
     #
     obj.name = ""
     obj.owner = Const.OID_NONE
     obj.x = 0.0
     obj.y = 0.0
     obj.radius = 0.0
     obj.centerWeight = 250.0
     obj.systems = []
     obj.startingPos = []
     obj.numOfStartPos = 0
     obj.timeEnabled = None  # none instead of False, to know when first enablement is happening
     obj.timePaused = False  # this is only used for player-initiated pause, prevents autoenablement
     obj.creationTurn = 0
     obj.imperator = Const.OID_NONE
     obj.description = ""
     obj.scenario = Const.SCENARIO_NONE
     obj.scenarioData = IDataHolder()
     # electromagnetic radiation
     obj.emrLevel = 1.0
     obj.emrTrend = 1.0
     obj.emrTime = 0
     # galaxy keeps track of it's own time as well (because of pauses)
     obj.galaxyTurn = 0
예제 #8
0
 def answer(self, player):
     answer = IDataHolder()
     answer.bookings = len(self.players)
     answer.last_creation = self.last_creation
     answer.is_booked = player in self.players
     answer.owner_nick = self.owner_nick
     answer.gal_type = self.gal_type
     answer.capacity = self.capacity
     return answer
예제 #9
0
 def getIntroInfo(self, tran, obj):
     result = IDataHolder()
     result.cid = tran.cid
     result.turn = obj.turn
     result.serverTime = time.time()
     result.lastClientVersion = ClientVersion.version
     result.lastClientRevision = ClientVersion.revision
     result.rulesetName = Rules.rulesetName
     return result
 def getDiplomacyWith(self, tran, obj, playerID):
     if obj.oid == playerID:
         return REL_UNITY
     # renegade battles with overyone
     # make default
     dipl = IDataHolder()
     dipl.type = T_DIPLREL
     dipl.pacts = {}
     dipl.relation = REL_ENEMY
     dipl.relChng = 0
     dipl.lastContact = tran.db[OID_UNIVERSE].turn
     dipl.contactType = CONTACT_NONE
     dipl.stats = None
     return dipl
예제 #11
0
파일: INature.py 프로젝트: Lukc/ospace-lukc
 def getDiplomacyWith(self, tran, obj, playerID):
     # this AI battles with overyone
     # make default
     dipl = IDataHolder()
     dipl.type = T_DIPLREL
     dipl.pacts = {}
     if obj.oid == playerID:
         dipl.relation = REL_UNITY
     else:
         dipl.relation = REL_ENEMY
     dipl.relChng = 0
     dipl.lastContact = tran.db[OID_UNIVERSE].turn
     dipl.contactType = CONTACT_NONE
     dipl.stats = None
     return dipl
예제 #12
0
	def init(self, obj):
		IObject.init(self, obj)
		#
		obj.login = u''
		obj.fullName = u''
		#
		obj.buoys = {}
		obj.alliedBuoys = {}
		obj.planets = []
		obj.fleets = []
		obj.techs = {} # techs and their sublevel
		obj.rsrchQueue = []
		obj.sciPoints = 0
		obj.effSciPoints = 0
		obj.techLevel = 1
		obj.shipDesigns = {}
		obj.race = "H" # race Bionic, Human, Cyborg
		# bonuses
		obj.prodEff = 1.0
		obj.sciEff = 1.0
		#
		obj.govPwr = 0
		obj.govPwrCtrlRange = 1
		# fleet support
		obj.fleetUpgradePool = 0.0
		obj.fleetUpgradeInProgress = 0
		# production
		obj.prodIncreasePool = 0.0
		# diplomacy
		obj.diplomacyRels = {}
		obj.defaultRelation = Rules.defaultRelation
		obj.voteFor = OID_NONE
		obj.governorOf = OID_NONE
		obj.governors = []
		obj.alliance = OID_NONE
		obj.imperator = 0
		# combat
		# anti-small, anti-medium, anti-large, shield generator
		obj.planetWeapons = [None, None, None, None, None]
		#
		obj.staticMap = {}
		obj.dynamicMap = {}
		obj.galaxies = []
		obj.validSystems = []
		#
		obj.stats = IDataHolder()
		obj.stats.type = T_STATS
		obj.timeEnabled = 0
		obj.stratRes = {}
		obj.lastLogin = 0.0
		#
		obj.shipRedirections = {}
		obj.buoys = {}
		#
		obj.clientStats = {}
예제 #13
0
def newStructure(tran,
                 techID,
                 playerID,
                 status=STRUCT_STATUS_ON | STRUCT_STATUS_NEW):
    tech = Rules.techs[techID]
    s = IDataHolder()
    s = [
        techID,
        int(tech.maxHP * getTechEff(tran, techID, playerID)), status, 0
    ]
    return s
예제 #14
0
def findPopCenterPlanets(db, planetsIDs):
    """ It finds "center of mass" of population.

    Returns sorted list    of all planets, beginning with those nearest to the
    found center.

    """
    x = 0
    y = 0
    population = 0
    for planetID in planetsIDs:
        planet = db[planetID]
        x += planet.x * planet.storPop
        y += planet.y * planet.storPop
        population += planet.storPop
    x /= population
    y /= population
    fakeObj = IDataHolder()
    fakeObj.x = x
    fakeObj.y = y
    return findNearest(db, fakeObj, planetsIDs, maxDist=99999, number=len(planetsIDs))
예제 #15
0
 def getIntroInfo(self, tran, obj):
     result = IDataHolder()
     result.cid = tran.cid
     result.turn = obj.turn
     result.serverTime = time.time()
     result.version = ige.version.version
     return result
예제 #16
0
 def getPublicInfo(self, tran, obj):
     result = IDataHolder()
     result.oid = obj.oid
     result.type = obj.type
     result.name = obj.name
     result.turn = obj.turn
     return result
예제 #17
0
def getDiplomacyWith(contactID):
    obj = getPlayer()
    dipl = obj.diplomacyRels.get(contactID, None)
    if not dipl:
        # make default
        dipl = IDataHolder()
        dipl.type = T_DIPLREL
        dipl.pacts = {
            PACT_ALLOW_CIVILIAN_SHIPS:
            [PACT_ACTIVE, PACT_ALLOW_CIVILIAN_SHIPS]
        }
        dipl.relation = obj.defaultRelation
        dipl.relChng = 0
        dipl.lastContact = 0
        dipl.stats = None
        dipl.contactType = CONTACT_NONE
        obj.diplomacyRels[playerID] = dipl
    return dipl
예제 #18
0
def getDiplomacyWith(contactID):
    obj = getPlayer()
    dipl = obj.diplomacyRels.get(contactID, None)
    if not dipl:
        # make default
        dipl = IDataHolder()
        dipl.type = T_DIPLREL
        dipl.pacts = {PACT_ALLOW_CIVILIAN_SHIPS: [PACT_ACTIVE, PACT_ALLOW_CIVILIAN_SHIPS]}
        dipl.relation = obj.defaultRelation
        dipl.relChng = 0
        dipl.lastContact = 0
        dipl.stats = None
        dipl.contactType = CONTACT_NONE
        obj.diplomacyRels[playerID] = dipl
    return dipl
예제 #19
0
파일: Utils.py 프로젝트: taislin/outerspace
def newStructure(tran,
                 techID,
                 playerID,
                 status=Const.STRUCT_STATUS_ON | Const.STRUCT_STATUS_NEW,
                 hpRatio=None):
    tech = Rules.techs[techID]
    hp = int(tech.maxHP * getTechEff(tran, techID, playerID))
    if hpRatio is None:
        # default is used
        hpRatio = Rules.structDefaultHpRatio
    hp = int(hp * hpRatio)
    s = IDataHolder()
    s = [techID, hp, status, 0]
    return s
예제 #20
0
	def getIntroInfo(self, tran, obj):
		result = IDataHolder()
		result.cid = tran.cid
		result.turn = obj.turn
		result.serverTime = time.time()
		result.version = ige.version.version
		# legacy client side update support
		# TODO: Remove once not needed
		result.lastClientVersion = (
			ige.version.major,
			ige.version.minor,
			ige.version.revision,
			ige.version.status,
		)
		result.lastClientRevision = ige.version.svnRevision
		return result
예제 #21
0
	def getDiplomacyWith(self, tran, obj, playerID):
		if obj.governorOf:
			# player is a governor
			leader = tran.db[obj.governorOf]
			return self.cmd(leader).getDiplomacyWith(tran, leader, objID)
		# player is independent
		dipl = obj.diplomacyRels.get(playerID, None)
		if not dipl:
			# make default
			dipl = IDataHolder()
			dipl.type = T_DIPLREL
			dipl.pacts = {
				PACT_ALLOW_CIVILIAN_SHIPS: [PACT_ACTIVE, PACT_ALLOW_CIVILIAN_SHIPS]
			}
			dipl.relation = obj.defaultRelation
			dipl.relChng = 0
			dipl.lastContact = tran.db[OID_UNIVERSE].turn
			dipl.contactType = CONTACT_NONE
			dipl.stats = None
			if playerID != obj.oid:
				obj.diplomacyRels[playerID] = dipl
			else:
				log.debug("getDiplomacyWith myself", obj.oid)
		return dipl
예제 #22
0
def getTechInfo(techID):
    player = db[db.playerID]
    tech = Rules.techs[techID]
    # player possess this technology
    if player.techs.has_key(techID):
        return tech

    if tech.fullInfo:
        return tech

    # player can research this technology
    canResearch = 1
    if player.race not in tech.researchRaces:
        canResearch = 0
    for tmpTechID, improvement in tech.researchRequires:
        if not player.techs.has_key(
                tmpTechID) or player.techs[tmpTechID] < improvement:
            canResearch = 0
            break
    for stratRes in tech.researchReqSRes:
        if player.stratRes.get(stratRes, 0) < 1:
            canResearch = 0
            break
    for tmpTechID in player.techs:
        if techID in Rules.techs[tmpTechID].researchDisables:
            canResearch = 0
            break
    if tech.level > player.techLevel:
        canResearch = 0

    if canResearch:
        result = IDataHolder()
        result.partialData = None
        for attr in [
                'name', 'isDiscovery', 'isStructure', 'isProject',
                'isShipEquip', 'isShipHull', 'researchMod', 'researchTurns',
                'textPreRsrch', 'researchRequires', 'subtype',
                "researchReqSRes", "researchDisables", "level", "researchRaces"
        ]:
            setattr(result, attr, getattr(tech, attr))
        return result
    # player should know only basic params about tech
    result = IDataHolder()
    result.partialData = None
    for attr in [
            "name", "researchRequires", "subtype", "level", "researchRaces"
    ]:
        setattr(result, attr, getattr(tech, attr))
    return result
예제 #23
0
	def startResearch(self, tran, obj, techID, improveToMax = 0):
		if len(obj.rsrchQueue) > Rules.maxRsrchQueueLen:
			GameException('Queue is full.')
		tech = Rules.techs[techID]
		# player has to be a right race
		if obj.race not in tech.researchRaces:
			raise GameException("Your race cannot research this technology.")
		# item cannot be researched twice
		for tmpTech in obj.rsrchQueue:
			if tmpTech.techID == techID:
				raise GameException('Technology is already sheduled for research.')
		# disabled?
		for tmpTechID in obj.techs:
			if techID in Rules.techs[tmpTechID].researchDisables:
				raise GameException("Previous research has disabled this technology.")
		# check requirements
		for tmpTechID, improvement in tech.researchRequires:
			if not obj.techs.has_key(tmpTechID) or obj.techs[tmpTechID] < improvement:
				raise GameException('You cannot research this technology yet.')
		improvement = obj.techs.get(techID, Rules.techBaseImprovement - 1) + 1
		if improvement > Rules.techMaxImprovement or improvement > tech.maxImprovement:
			raise GameException('You cannot improve this technology further.')
		if tech.level > obj.techLevel:
			raise GameException("Your technological level is insufficient.")
		# check strategic resources
		if improvement == 1:
			for stratRes in tech.researchReqSRes:
				if obj.stratRes.get(stratRes, 0) < 1:
					raise GameException("Required strategy resource missing.")
		item = IDataHolder()
		item.techID = techID
		item.improvement = improvement
		item.currSci = 0
		item.changeSci = 0
		item.improveToMax = improveToMax
		item.type = T_RESTASK
		obj.rsrchQueue.append(item)
		return obj.rsrchQueue
예제 #24
0
	def getDiplomacyWith(self, tran, obj, playerID):
		if obj.governorOf:
			# player is a governor
			leader = tran.db[obj.governorOf]
			return self.cmd(leader).getDiplomacyWith(tran, leader, objID)
		# player is independent
		dipl = obj.diplomacyRels.get(playerID, None)
		if not dipl:
			# make default
			dipl = IDataHolder()
			dipl.type = T_DIPLREL
			dipl.pacts = {
				PACT_ALLOW_CIVILIAN_SHIPS: [PACT_ACTIVE, PACT_ALLOW_CIVILIAN_SHIPS]
			}
			dipl.relation = obj.defaultRelation
			dipl.relChng = 0
			dipl.lastContact = tran.db[OID_UNIVERSE].turn
			dipl.contactType = CONTACT_NONE
			dipl.stats = None
			if playerID != obj.oid:
				obj.diplomacyRels[playerID] = dipl
			else:
				log.debug("getDiplomacyWith myself", obj.oid)
		return dipl
예제 #25
0
파일: IPlayer.py 프로젝트: Lukc/ospace-lukc
	def startGlobalConstruction(self, tran, player, techID, quantity, isShip, reportFinished, queue):
		if len(player.prodQueues) <= queue:
			raise GameException('Invalid queue.')		
		if len(player.prodQueues[queue]) > Rules.maxProdQueueLen:
			raise GameException('Queue is full.')
		if quantity < 1:
			raise GameException("Quantity must be greater than 0")
		if not player.techs.has_key(techID) and isShip == 0:
			raise GameException('You do not own this kind of technology.')
		if not player.shipDesigns.has_key(techID) and isShip == 1:
			raise GameException('You do not own this ship design.')
		if isShip:
			tech = player.shipDesigns[techID]
			if tech.upgradeTo:
				raise GameException("You cannot build obsolete ship design.")
		else:
			tech = Rules.techs[techID]
			if tech.isStructure or not tech.isProject:
				raise GameException('You cannot construct this technology.')
			elif tech.globalDisabled:
				raise GameException('You cannot construct targeted project.')
		neededSR = {}
		for sr in tech.buildSRes:
			if player.stratRes.get(sr, 0) < neededSR.get(sr, 0) + quantity:
				raise GameException("You do not own required strategic resource(s)")
			neededSR[sr] = neededSR.get(sr, 0) + quantity
		# consume strategic resources
		for sr in neededSR:
			player.stratRes[sr] -= neededSR[sr]
		# start construction
		item = IDataHolder()
		item.techID = techID
		item.quantity = int(quantity)
		item.changePerc = 0
		item.isShip = bool(isShip)
		item.reportFin = bool(reportFinished)
		item.type = T_TASK
		player.prodQueues[queue].append(item)
		return player.prodQueues[queue], player.stratRes
예제 #26
0
	def startResearch(self, tran, obj, techID, improveToMax = 0):
		if len(obj.rsrchQueue) > Rules.maxRsrchQueueLen:
			GameException('Queue is full.')
		tech = Rules.techs[techID]
		# player has to be a right race
		if obj.race not in tech.researchRaces:
			raise GameException("Your race cannot research this technology.")
		# item cannot be researched twice
		for tmpTech in obj.rsrchQueue:
			if tmpTech.techID == techID:
				raise GameException('Technology is already sheduled for research.')
		# disabled?
		for tmpTechID in obj.techs:
			if techID in Rules.techs[tmpTechID].researchDisables:
				raise GameException("Previous research has disabled this technology.")
		# check requirements
		for tmpTechID, improvement in tech.researchRequires:
			if not obj.techs.has_key(tmpTechID) or obj.techs[tmpTechID] < improvement:
				raise GameException('You cannot research this technology yet.')
		improvement = obj.techs.get(techID, Rules.techBaseImprovement - 1) + 1
		if improvement > Rules.techMaxImprovement or improvement > tech.maxImprovement:
			raise GameException('You cannot improve this technology further.')
		if tech.level > obj.techLevel:
			raise GameException("Your technological level is insufficient.")
		# check strategic resources
		if improvement == 1:
			for stratRes in tech.researchReqSRes:
				if obj.stratRes.get(stratRes, 0) < 1:
					raise GameException("Required strategy resource missing.")
		item = IDataHolder()
		item.techID = techID
		item.improvement = improvement
		item.currSci = 0
		item.changeSci = 0
		item.improveToMax = improveToMax
		item.type = T_RESTASK
		obj.rsrchQueue.append(item)
		return obj.rsrchQueue
예제 #27
0
	def getScanInfos(self, tran, obj, scanPwr, player):
		if scanPwr >= Rules.level1InfoScanPwr:
			result = IDataHolder()
			result._type = T_SCAN
			result.scanPwr = scanPwr
			result.oid = obj.oid
			result.signature = obj.signature
			result.type = obj.type
			result.orbit = obj.orbit
			result.compOf = obj.compOf
			result.x = obj.x
			result.y = obj.y
			result.plType = obj.plType
		if scanPwr >= Rules.level2InfoScanPwr:
			result.plDiameter = obj.plDiameter
			if getattr(obj, "plType", 'X') != 'G':
				result.plMin = obj.plMin
			result.plBio = obj.plBio
			result.plEn = obj.plEn
			result.plSlots = obj.plSlots
			result.plStratRes = obj.plStratRes
			result.plMaxSlots = obj.plMaxSlots
		if scanPwr >= Rules.level3InfoScanPwr:
			result.name = obj.name
			result.storPop = obj.storPop
			result.owner = obj.owner
		if scanPwr >= Rules.level4InfoScanPwr:
			# TODO provide less information
			result.hasRefuel = (obj.refuelInc > 0) #simple detect if docks exist for problems dialog
			result.slots = obj.slots
			result.shield = obj.shield
			result.prevShield = -1
			result.maxShield = -1
		if scanPwr >= Rules.partnerScanPwr:
			result.maxShield = obj.maxShield
			result.prevShield = obj.prevShield
			result.refuelMax = obj.refuelMax
			result.refuelInc = obj.refuelInc
			result.scannerPwr = obj.scannerPwr
			result.trainShipInc = obj.trainShipInc
			result.trainShipMax = obj.trainShipMax
			result.upgradeShip = obj.upgradeShip
			result.repairShip = obj.repairShip
			result.fleetSpeedBoost = obj.fleetSpeedBoost
		return [result]
예제 #28
0
 def getScanInfos(self, tran, obj, scanPwr, player):
     result = IDataHolder()
     results = [result]
     if scanPwr >= Rules.level1InfoScanPwr:
         result._type = T_SCAN
         result.scanPwr = scanPwr
         result.oid = obj.oid
         result.x = obj.x
         result.y = obj.y
         if hasattr(obj, 'destinationOid'):
             result.destinationOid = obj.destinationOid
         # multiply by 1000 to increase accuracy
         #~ result.dist = obj.dist * 1000
         #~ result.dAngle = obj.dAngle * 1000
         #~ result.sAngle = obj.sAngle * 1000
         result.signature = obj.signature
         result.type = obj.type
         result.compOf = obj.compOf
         result.starClass = obj.starClass
     if scanPwr >= Rules.level2InfoScanPwr:
         result.name = obj.name
         result.combatCounter = obj.combatCounter
     if scanPwr >= Rules.level3InfoScanPwr:
         result.planets = obj.planets
         result.owner = obj.owner
         for planetID in obj.planets:
             planet = tran.db[planetID]
             if planet.owner == player:  ####### This was player.owner, which made no sense. Hope this change doesn't break something
                 continue
             newPwr = scanPwr * planet.signature / obj.signature
             results.extend(
                 self.cmd(planet).getScanInfos(tran, planet, newPwr,
                                               player))
     if scanPwr >= Rules.level4InfoScanPwr:
         result.fleets = obj.fleets
         for fleetID in obj.fleets:
             fleet = tran.db[fleetID]
             if fleet.owner == player:
                 continue
             newPwr = scanPwr * fleet.signature / obj.signature
             results.extend(
                 self.cmd(fleet).getScanInfos(tran, fleet, newPwr, player))
         result.hasmines = 0  #no
         if len(obj.minefield) > 0:
             result.hasmines = 1  #yes
         result.minefield = self.getMines(
             obj, player.oid)  #only shows mines you own
         if len(obj.minefield) > 1 or (len(obj.minefield) == 1
                                       and len(result.minefield) == 0):
             result.hasmines = 2  #yes, and some aren't my mines
     return results
예제 #29
0
    def processBATTLEPhase(self, tran, obj, data):
        system = obj
        #@log.debug('ISystem', 'BATTLE - system', obj.oid)
        # we are processing fleets, planets, ...
        objects = obj.planets[:] + obj.fleets[:]
        # shuffle them to prevent predetermined one-sided battles (temporary hack)
        random.shuffle(objects)
        # store owners of objects
        # find enemies and allies
        attack = {}
        allies = {}
        owners = {}
        ownerIDs = {}
        systemAtt = {}
        systemDef = {}
        hasMine = {}
        isOwnedObject = 0
        for objID in objects:
            attack[objID] = []
            allies[objID] = []
            owner = tran.db[objID].owner
            owners[objID] = owner
            ownerIDs[owner] = owner
            if owner != Const.OID_NONE:
                isOwnedObject = 1
        for owner in ownerIDs:
            tempAtt, tempDef = self.getSystemCombatBonuses(tran, system, owner)
            systemAtt[owner] = tempAtt
            systemDef[owner] = tempDef
            hasMine[owner] = self.getSystemMineSource(tran, system, owner)
        if not isOwnedObject:
            #@log.debug('ISystem', 'No combat')
            # reset combat counters
            system.combatCounter = 0
            return
        # first - direct ones
        index = 1
        for obj1ID in objects:
            obj1 = tran.db[obj1ID]
            if obj1.owner == Const.OID_NONE:
                index += 1
                continue
            commander = tran.db[obj1.owner]
            # relationships
            #for obj2ID in objects[index:]:
            for obj2ID in objects:
                obj2 = tran.db[obj2ID]
                if obj2.owner == Const.OID_NONE or obj1 is obj2:
                    continue
                if obj1.owner == obj2.owner:
                    allies[obj1ID].append(obj2ID)
                    allies[obj2ID].append(obj1ID)
                    continue
                # planet and military object
                elif obj1.type == Const.T_PLANET and obj2.isMilitary and \
                    not self.cmd(commander).isPactActive(tran, commander, obj2.owner, Const.PACT_ALLOW_MILITARY_SHIPS):
                    #@log.debug("ISystem pl - mil", obj1ID, obj2ID)
                    if obj2ID not in attack[obj1ID]:
                        attack[obj1ID].append(obj2ID)
                    if obj1ID not in attack[obj2ID]:
                        attack[obj2ID].append(obj1ID)
                # planet and civilian object
                elif obj1.type == Const.T_PLANET and not obj2.isMilitary and \
                    not self.cmd(commander).isPactActive(tran, commander, obj2.owner, Const.PACT_ALLOW_CIVILIAN_SHIPS):
                    #@log.debug("ISystem pl - civ", obj1ID, obj2ID)
                    if obj2ID not in attack[obj1ID]:
                        attack[obj1ID].append(obj2ID)
                    if obj1ID not in attack[obj2ID]:
                        attack[obj2ID].append(obj1ID)
                # military and military object
                elif obj1.isMilitary and obj2.isMilitary and \
                    not self.cmd(commander).isPactActive(tran, commander, obj2.owner, Const.PACT_ALLOW_MILITARY_SHIPS):
                    #@log.debug("ISystem mil - mil", obj1ID, obj2ID)
                    if obj2ID not in attack[obj1ID]:
                        attack[obj1ID].append(obj2ID)
                    if obj1ID not in attack[obj2ID]:
                        attack[obj2ID].append(obj1ID)
                # military and civilian object
                elif obj1.isMilitary and not obj2.isMilitary and \
                    not self.cmd(commander).isPactActive(tran, commander, obj2.owner, Const.PACT_ALLOW_CIVILIAN_SHIPS):
                    #@log.debug("ISystem mil - civ", obj1ID, obj2ID)
                    if obj2ID not in attack[obj1ID]:
                        attack[obj1ID].append(obj2ID)
                    if obj1ID not in attack[obj2ID]:
                        attack[obj2ID].append(obj1ID)
                # planet and fleet
                #elif obj1.type == Const.T_PLANET and obj2.type == Const.T_FLEET and \
                #    self.cmd(commander).isPactActive(tran, commander, obj2.owner, PACT_MUTUAL_DEFENCE):
                #    allies[obj1ID].append(obj2ID)
                #    allies[obj2ID].append(obj1ID)
                # fleet and fleet
                #elif obj1.type == Const.T_FLEET and obj2.type == Const.T_FLEET and \
                #    self.cmd(commander).isPactActive(tran, commander, obj2.owner, PACT_MUTUAL_OFFENCE):
                #    allies[obj1ID].append(obj2ID)
                #    allies[obj2ID].append(obj1ID)
            index += 1
        #@log.debug('ISystem', 'Targets:', targets)
        #@log.debug('ISystem', 'Allies:', allies)
        # find indirect a/e
        #for objID in objects:
        #    iTargets = []
        #    iAllies = []
        #    # find indirect a/e
        #    todo = allies[objID][:]
        #    while todo:
        #        id = todo.pop(0)
        #        iTargets.extend(targets[id])
        #        for tmpID in allies[id]:
        #            if tmpID not in iAllies:
        #                todo.append(tmpID)
        #                iAllies.append(tmpID)
        #    # remove allies from targets
        #    for id in iAllies:
        #        if id in iTargets:
        #            iTargets.remove(id)
        #    # IMPORTATNT preffer NOT to fire at possible allies
        #    # add my targets
        #    #for id in targets[objID]:
        #    #    if id not in iTargets:
        #    #        iTargets.append(id)
        #    # that's all folks
        #    for id in iTargets:
        #        if objID not in attack[id]:
        #            attack[id].append(objID)
        #        if id not in attack[objID]:
        #            attack[objID].append(id)
        # NOT VALID: objects with action ACTION_ATTACK will attack only their targets
        # check, if there are any targets
        isCombat = 0
        for objID in objects:
            if attack[objID]:
                isCombat = 1
                break  #end loop
        if not isCombat:
            #@log.debug('ISystem', 'No combat')
            # reset combat counters
            system.combatCounter = 0
            for fleetID in system.fleets:
                tran.db[fleetID].combatCounter = 0
            return
        # increase combat counters
        system.combatCounter += 1
        for fleetID in system.fleets:
            tran.db[fleetID].combatCounter += 1
        # debug
        log.debug('ISystem', 'Final attacks in system %d:' % system.oid,
                  attack)
        # mines detonate before battle
        shots = {}
        targets = {}
        firing = {}
        damageCaused = {}
        killsCaused = {}
        damageTaken = {}
        shipsLost = {}
        minesTriggered = {}
        fleetOwners = {}
        isCombat = False
        isMineCombat = False
        for owner in ownerIDs:
            if owner not in hasMine:  # no planets
                continue
            if not hasMine[owner]:  # no planet with control structure
                continue
            controlPlanetID = hasMine[owner][
                0]  # there is list returned, all planets have same effect
            if len(self.getMines(system, owner)) == 0:
                continue  # no mines, something broke
            if len(attack[controlPlanetID]) == 0:
                continue  # no targets
            isMineFired = True
            mineTargets = copy.copy(attack[controlPlanetID])
            while isMineFired:
                while len(mineTargets) > 0:
                    targetID = random.choice(
                        mineTargets)  # select random target
                    targetobj = tran.db.get(targetID, None)
                    try:
                        if targetobj.type == Const.T_FLEET:
                            fleetOwners[targetID] = targetobj.owner
                            break  # target found
                        mineTargets.remove(
                            targetID
                        )  # remove an object type that a mine can't hit from the temporary targets list
                    except:
                        mineTargets.remove(
                            targetID
                        )  # remove a dead fleet from the temporary targets list

                if len(mineTargets) == 0:
                    break  # no fleet targets for mines
                temp, temp, firing[targetID] = self.cmd(
                    targetobj).getPreCombatData(
                        tran,
                        targetobj)  # fix firing for "surrender to" section
                damage, att, ignoreshield, mineID = self.cmd(obj).fireMine(
                    system, owner)
                if not damage:  # no more mines
                    isMineFired = False
                    break
                log.debug('ISystem',
                          'Mine Shooting (damage, att, ignore shield):',
                          damage, att, ignoreshield)
                isMineCombat = True
                minesTriggered[mineID] = minesTriggered.get(mineID, 0) + 1
                # Process Combat
                # for now we assume only one ship can be destroyed by one mine
                dmg, destroyed = self.cmd(targetobj).applyMine(
                    tran, targetobj, att, damage, ignoreshield)
                #log.debug('ISystem-Mines', 'Actual Damage Done:',dmg)
                if dmg > 0:
                    damageTaken[targetID] = damageTaken.get(targetID, 0) + dmg
                    shipsLost[targetID] = shipsLost.get(targetID,
                                                        0) + destroyed
                    killsCaused[mineID] = killsCaused.get(mineID,
                                                          0) + destroyed
                if dmg > 0:
                    damageCaused[mineID] = damageCaused.get(mineID, 0) + dmg
            # send messages about mine effects to the owner of the minefield
            # collect hit players
            players = {}
            for triggerID in firing.keys():
                players[owners[triggerID]] = None
            controllerPlanet = tran.db.get(controlPlanetID, None)
            damageCausedSum = 0
            killsCausedSum = 0
            for mineID in damageCaused.keys():
                damageCausedSum = damageCausedSum + damageCaused.get(mineID, 0)
                killsCausedSum = killsCausedSum + killsCaused.get(mineID, 0)
            Utils.sendMessage(tran, controllerPlanet,
                              Const.MSG_MINES_OWNER_RESULTS, system.oid,
                              (players.keys(),
                               (damageCaused, killsCaused, minesTriggered),
                               damageCausedSum, killsCausedSum))
        # send messages to the players whose fleets got hit by minefields
        for targetID in damageTaken.keys():
            targetFleet = tran.db.get(targetID, None)
            if targetFleet:
                Utils.sendMessage(tran, targetFleet,
                                  Const.MSG_MINES_FLEET_RESULTS, system.oid,
                                  (damageTaken[targetID], shipsLost[targetID]))
            else:
                targetFleet = IDataHolder()
                targetFleet.oid = fleetOwners[targetID]
                Utils.sendMessage(tran, targetFleet,
                                  Const.MSG_MINES_FLEET_RESULTS, system.oid,
                                  (damageTaken[targetID], shipsLost[targetID]))
                Utils.sendMessage(tran, targetFleet, Const.MSG_DESTROYED_FLEET,
                                  system.oid, ())
        damageCaused = {}
        killsCaused = {}
        damageTaken = {}
        shipsLost = {}
        # now to battle
        for objID in objects:
            obj = tran.db.get(objID, None)
            # get shots from object, should be sorted by weaponClass
            # shots = [ shot, ...], shot = (combatAtt, weaponID)
            # get target classes and numbers
            # (class1, class2, class3, class4)
            # cls0 == fighters, cls1 == midships, cls2 == capital ships, cls3 == planet installations
            #@log.debug(objID, obj.name, "getting pre combat data")
            if obj:  # source already destroyed; ignore
                shots[objID], targets[objID], firing[objID] = self.cmd(
                    obj).getPreCombatData(tran, obj)
                if firing[objID]:
                    isCombat = True
        if not isCombat and not isMineCombat:
            # no shots has been fired
            #@log.debug('ISystem', 'No combat')
            # reset combat counters
            system.combatCounter = 0
            for fleetID in system.fleets:
                tran.db[fleetID].combatCounter = 0
            return
        #@log.debug("Shots:", shots)
        #@log.debug("Targets", targets)
        if isCombat:
            for shotIdx in (3, 2, 1, 0):
                for objID in objects:
                    # obj CAN be deleted at this point
                    obj = tran.db.get(objID, None)
                    if obj == None:
                        continue  # source already destroyed; move to next source
                    # if object is fleet, then it's signature is max
                    if obj and obj.type == Const.T_FLEET:
                        obj.signature = Rules.maxSignature
                    # target preselection
                    totalClass = [0, 0, 0, 0]
                    total = 0
                    for targetID in attack[objID]:
                        totalClass[0] += targets[targetID][0]
                        totalClass[1] += targets[targetID][1]
                        totalClass[2] += targets[targetID][2]
                        totalClass[3] += targets[targetID][3]
                    total = totalClass[0] + totalClass[1] + totalClass[
                        2] + totalClass[3]
                    # process shots
                    for combatAtt, weaponID in shots[objID][shotIdx]:
                        weapon = Rules.techs[weaponID]
                        weaponClass = weapon.weaponClass
                        if total == 0:
                            # there are no targets
                            break
                        #@log.debug('ISystem', 'Processing shot', objID, weapon.name, weaponClass)
                        # process from weaponClass up
                        # never shoot on smaller ships than weaponClass
                        applied = 0
                        for tmpWpnClass in xrange(weaponClass, 4):
                            #@log.debug('ISystem', 'Trying target class', tmpWpnClass, totalClass[tmpWpnClass])
                            # select target
                            if totalClass[tmpWpnClass]:
                                target = Utils.rand(0, totalClass[tmpWpnClass])
                                #@log.debug('ISystem', 'Target rnd num', target, totalClass[tmpWpnClass])
                                for targetID in attack[objID]:
                                    if target < targets[targetID][tmpWpnClass]:
                                        #@log.debug(objID, 'attacks', targetID, tmpWpnClass)
                                        # targetID can be deleted at this point
                                        anObj = tran.db.get(targetID, None)
                                        if anObj:
                                            dmg, destroyed, destroyedClass = self.cmd(
                                                anObj).applyShot(
                                                    tran, anObj, systemDef[
                                                        owners[targetID]],
                                                    combatAtt +
                                                    systemAtt[owners[objID]],
                                                    weaponID, tmpWpnClass,
                                                    target)
                                            #@log.debug("ISystem result", dmg, destroyed, destroyedClass, tmpWpnClass)
                                            #@print objID, 'dmg, destroyed', dmg, destroyed
                                            damageTaken[
                                                targetID] = damageTaken.get(
                                                    targetID, 0) + dmg
                                            if destroyed > 0:
                                                shipsLost[
                                                    targetID] = shipsLost.get(
                                                        targetID,
                                                        0) + destroyed
                                                total -= destroyed
                                                totalClass[
                                                    destroyedClass] -= destroyed
                                            if dmg > 0 and obj:
                                                obj.combatExp += dmg
                                                damageCaused[
                                                    objID] = damageCaused.get(
                                                        objID, 0) + dmg
                                            applied = 1
                                        else:
                                            continue  # target already destroyed, move to next target
                                        break
                                    else:
                                        #@log.debug('ISystem', 'Lovering target by', targets[targetID][tmpWpnClass])
                                        target -= targets[targetID][
                                            tmpWpnClass]
                            if applied:
                                break
        # send messages and modify diplomacy relations
        # distribute experience pts
        for objID in objects:
            obj = tran.db.get(objID, None)
            if obj:
                self.cmd(obj).distributeExp(tran, obj)
            if attack[objID]:
                source = obj or tran.db[owners[objID]]
                # collect players
                players = {}
                for attackerID in attack[objID]:
                    players[owners[attackerID]] = None
                d1 = damageTaken.get(objID, 0)
                d2 = damageCaused.get(objID, 0)
                l = shipsLost.get(objID, 0)
                if d1 or d2 or l:
                    # send only if damage is taken/caused
                    Utils.sendMessage(tran, source, Const.MSG_COMBAT_RESULTS,
                                      system.oid, (d1, d2, l, players.keys()))
                if not obj:
                    # report DESTROYED status
                    Utils.sendMessage(tran, source, Const.MSG_DESTROYED_FLEET,
                                      system.oid, ())
                # modify diplomacy relations
                objOwner = tran.db[owners[objID]]
                for attackerID in attack[objID]:
                    attOwner = tran.db.get(owners[attackerID], None)
                    # owner of the fleet
                    rel = self.cmd(objOwner).getDiplomacyWith(
                        tran, objOwner, attOwner.oid)
                    rel.relChng = Rules.relLostWhenAttacked
                    # attacker
                    rel = self.cmd(attOwner).getDiplomacyWith(
                        tran, attOwner, objOwner.oid)
                    rel.rechChng = Rules.relLostWhenAttacked
        # check if object surrenders
        for objID in objects:
            # object surrender IFF it and its allies had target and was not able
            # to fire at it, planet is not counted as ally in this case
            obj = tran.db.get(objID, None)
            if firing[objID] and obj:
                continue
            surrenderTo = []
            for attID in attack[objID]:
                if firing[attID] and tran.db.has_key(attID):
                    surrenderTo.append(tran.db[attID].owner)
            for allyID in allies[objID]:
                if not tran.db.has_key(allyID):
                    continue
                ally = tran.db[allyID]
                if firing[allyID] and ally.type != Const.T_PLANET:
                    surrenderTo = []
                    break
            if surrenderTo:
                index = Utils.rand(0, len(surrenderTo))
                if obj:
                    if self.cmd(obj).surrenderTo(tran, obj,
                                                 surrenderTo[index]):
                        winner = tran.db[surrenderTo[index]]
                        source = tran.db.get(owners[objID], None)
                        log.debug('ISystem', 'BATTLE - surrender', objID,
                                  surrenderTo[index], surrenderTo)
                        if source:
                            Utils.sendMessage(tran, source,
                                              Const.MSG_COMBAT_LOST,
                                              system.oid, winner.oid)
                            Utils.sendMessage(tran, winner,
                                              Const.MSG_COMBAT_WON, system.oid,
                                              source.oid)
                        else:
                            Utils.sendMessage(tran, winner,
                                              Const.MSG_COMBAT_WON, system.oid,
                                              obj.oid)
                else:
                    winner = tran.db[surrenderTo[index]]
                    source = tran.db[owners[objID]]
                    log.debug('ISystem', 'BATTLE - surrender', objID,
                              surrenderTo[index], surrenderTo)
                    Utils.sendMessage(tran, source, Const.MSG_COMBAT_LOST,
                                      system.oid, winner.oid)
                    Utils.sendMessage(tran, winner, Const.MSG_COMBAT_WON,
                                      system.oid, source.oid)
        return
예제 #30
0
	def processRSRCHPhase(self, tran, obj, data):
		if not obj.timeEnabled:
			return
		# sci pts from allies
		pts = obj.sciPoints
		for partnerID in obj.diplomacyRels:
			if self.cmd(obj).isPactActive(tran, obj, partnerID, PACT_MINOR_SCI_COOP):
				partner = tran.db[partnerID]
				pactSpec = Rules.pactDescrs[PACT_MINOR_SCI_COOP]
				pts += min(
					int(partner.sciPoints * pactSpec.effectivity),
					int(obj.sciPoints * pactSpec.effectivity),
				)
			if self.cmd(obj).isPactActive(tran, obj, partnerID, PACT_MAJOR_SCI_COOP):
				partner = tran.db[partnerID]
				pactSpec = Rules.pactDescrs[PACT_MAJOR_SCI_COOP]
				pts += min(
					int(partner.sciPoints * pactSpec.effectivity),
					int(obj.sciPoints * pactSpec.effectivity),
				)
		# compute effective sci pts
		obj.effSciPoints = epts = pts - int(obj.stats.storPop * Rules.sciPtsPerCitizen[obj.techLevel])
		index = 0
		while epts > 0 and obj.rsrchQueue and index < len(obj.rsrchQueue):
			item = obj.rsrchQueue[index]
			tech = Rules.techs[item.techID]
			# check requirements
			canResearch = 1
			# player has to be a right race
			if obj.race not in tech.researchRaces:
				canResearch = 0
			for stratRes in tech.researchReqSRes:
				if obj.stratRes.get(stratRes, 0) < 1 and item.improvement == 1:
					Utils.sendMessage(tran, obj, MSG_MISSING_STRATRES, OID_NONE, stratRes)
					canResearch = 0
					break
			for tmpTechID in obj.techs:
				if item.techID in Rules.techs[tmpTechID].researchDisables:
					canResearch = 0
					Utils.sendMessage(tran, obj, MSG_DELETED_RESEARCH, OID_NONE, item.techID)
					del obj.rsrchQueue[index]
					index -= 1
					break
			if tech.level > obj.techLevel:
				canResearch = 0
				Utils.sendMessage(tran, obj, MSG_DELETED_RESEARCH, OID_NONE, item.techID)
				del obj.rsrchQueue[index]
				index -= 1
			if not canResearch:
				index += 1
				continue
			researchSci = Utils.getTechRCost(obj, item.techID)
			wantSci = min(epts, researchSci - item.currSci,
				researchSci / tech.researchTurns)
			item.currSci += wantSci
			item.changeSci = wantSci
			epts -= wantSci
			if item.currSci >= researchSci:
				del obj.rsrchQueue[index]
				obj.techs[item.techID] = item.improvement
				# call finish handler
				tech = Rules.techs[item.techID]
				tech.finishResearchHandler(tran, obj, tech)
				Utils.sendMessage(tran, obj, MSG_COMPLETED_RESEARCH, OID_NONE, item.techID)
				# update derived attributes of player
				self.cmd(obj).update(tran, obj)
				# repeat research if required by player
				if item.improveToMax == 1 and item.improvement < Rules.techMaxImprovement:
					# reinsert the item on the top of the queue
					self.cmd(obj).startResearch(tran, obj, item.techID, improveToMax = 1)
					idx = len(obj.rsrchQueue) - 1
					self.cmd(obj).moveResearch(tran, obj, idx, - idx)
		if epts > 0 and 0: # TODO: remove me
			Utils.sendMessage(tran, obj, MSG_WASTED_SCIPTS, OID_NONE, epts)
			return
		# oops we have negative epts
		while epts < 0:
			log.debug("Not enought RP", epts, obj.oid)
			if obj.rsrchQueue:
				item = obj.rsrchQueue[0]
				if item.currSci > 0:
					wantSci = min(item.currSci, - epts)
					item.currSci -= wantSci
					item.changeSci = - wantSci
					epts += wantSci
				if item.currSci == 0:
					# remove item from the queue - TODO send message to player
					del obj.rsrchQueue[0]
				# at this point, epts can be zero
				if epts == 0:
					log.debug("RP deficit satisfied", obj.oid)
					break
				# try next project
				if obj.rsrchQueue:
					continue
			# oops we must find technology to degrade
			avail = obj.techs.keys()
			# do not degrade technologies, which enables others
			for techID in obj.techs:
				tech = Rules.techs[techID]
				for tmpTechID, impr in tech.researchRequires:
					if tmpTechID in avail:
						avail.remove(tmpTechID)
			log.debug("Techs avialable for degradation", avail)
			if not avail:
				# no technology...
				break
			# from hight to low IDs
			avail.sort()
			avail.reverse()
			degraded = 0
			for level in range(obj.techLevel, 0, -1):
				for techID in avail:
					tech = Rules.techs[techID]
					# check level
					if tech.level != level:
						continue
					# do not touch starting technologies
					if tech.isStarting and obj.techs[techID] <= 3:
						continue
					# ok we have one to degrade
					item = IDataHolder()
					item.techID = techID
					item.improvement = obj.techs[techID]
					item.currSci = Utils.getTechRCost(obj, techID, obj.techs[techID])
					item.changeSci = 0
					item.improveToMax = 0
					item.type = T_RESTASK
					obj.rsrchQueue.append(item)
					# degrade tech
					if obj.techs[techID] == 1:
						# TODO send message
						del obj.techs[techID]
					else:
						# TODO send message
						obj.techs[techID] -= 1
					if tech.recheckWhenTechLost:
						# reset some attributes
						plLevel = obj.techLevel
						obj.techLevel = 1
						# recheck remaining techs
						for level in range(1, plLevel + 1):
							for techID in obj.techs:
								tech = Rules.techs[techID]
								if tech.level != level:
									continue
								# call finish handler again
								tech.finishResearchHandler(tran, obj, tech)
					degraded = 1
					break
				if degraded: break
		return
예제 #31
0
 def getScanInfo(self, tran, obj, scanPwr):
     result = IDataHolder()
     result._type = T_SCAN
     result.scanPwr = scanPwr
     if scanPwr > Rules.level1InfoScanPwr:
         result.oid = obj.oid
         result.x = obj.x
         result.y = obj.y
         result.oldX = obj.oldX
         result.oldY = obj.oldY
         result.signature = obj.signature
         result.type = obj.type
         result.orbiting = obj.orbiting
         result.speed = obj.speed
         result.eta = obj.eta
     if scanPwr > Rules.level2InfoScanPwr:
         result.name = obj.name
     if scanPwr > Rules.level3InfoScanPwr:
         result.asDiameter = obj.asDiameter
         result.asHP = obj.asHP
     if scanPwr > Rules.level4InfoScanPwr:
         pass
     return result
예제 #32
0
 def _get_system_info(self, system):
     system_info = IDataHolder()
     # my planets in the system
     system_info.system = system
     system_info.breweries = 0
     system_info.shipyards = 0
     system_info.prisons = 0
     system_info.dens = {}
     system_info.bases = {}
     system_info.other_struct_id = {}
     system_info.idle_planets = self.data.myPlanets & set(system.planets)
     for planet_id in copy.copy(system_info.idle_planets):
         planet = self.db[planet_id]
         system_info.bases[planet_id] = 0
         system_info.other_struct_id[planet_id] = None
         system_info.dens[planet_id] = 0
         for struct in planet.slots:
             if struct[0] == Rules.Tech.PIRATEBASE:
                 system_info.bases[planet_id] += 1
             elif struct[0] == Rules.Tech.PIRATEBREWERY:
                 system_info.breweries += 1
             elif struct[0] == Rules.Tech.PIRATEDEN:
                 system_info.dens[planet_id] += 1
             elif struct[0] == Rules.Tech.PIRATESD:
                 system_info.shipyards += 1
             elif struct[0] == Rules.Tech.PIRATEPRISON:
                 system_info.prisons += 1
             else:
                 system_info.other_struct_id[planet_id] = struct[0]
         if getattr(planet, 'prodQueue', None):
             # something is in the production queue, account it and do next
             for task in planet.prodQueue:
                 if task.techID == Rules.Tech.PIRATEBREWERY:
                     system_info.breweries += task.quantity
                 elif task.techID == Rules.Tech.PIRATESD:
                     system_info.shipyards += task.quantity
                 elif task.techID == Rules.Tech.PIRATEPRISON:
                     system_info.prisons += task.quantity
                 elif task.techID in (Rules.Tech.PLCOND5,
                                      Rules.Tech.PLASSEMBL5):
                     self.data.nonhabPlanets.remove(task.targetID)
             system_info.idle_planets.remove(planet_id)
             continue
     return system_info
예제 #33
0
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
예제 #34
0
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
예제 #35
0
def getSystemStructStats(data, client, db, systemID, processQueues=True):
    """ It go through all planets and structures, and creates IDataHolder
    object, with roster of buildings, surplus of bio and en.

    processQueues - if True, it go through all buildQueues and adjust all
                    statistics as it would be all done already.

    Returns IDataHolder with parameters:
        .bio - system surplus of biomass
        .en - system surplus of en
        .planets - dictionary, keys are planetIDs of players or free planets,
                   and values are dictionaries (huh) with keys being techIDs
                   and values being number of those structs.

    """
    systemStats = IDataHolder()
    system = db[systemID]
    player = client.getPlayer()
    myPlanets = set(system.planets) & data.myPlanets
    systemStats.planets = {}
    for planetID in myPlanets:
        systemStats.planets[planetID] = {}
    for planetID in set(system.planets) & data.freePlanets:
        systemStats.planets[planetID] = {}
    # creation of the .planets dictionary
    for planetID in myPlanets:
        planet = db[planetID]
        for techID, hp, something, eff in planet.slots:
            try:
                systemStats.planets[planetID][techID] += 1
            except KeyError:
                systemStats.planets[planetID][techID] = 1
        if not processQueues:
            # do not look into the queue
            continue
        for task in getattr(planet, 'prodQueue', []):
            if not task.isShip:
                techID = task.techID
                tech = client.getFullTechInfo(task.techID)
                if tech.isStructure:
                    if task.targetID not in systemStats.planets.keys():
                        continue
                    try:
                        systemStats.planets[task.targetID][techID] += 1
                    except KeyError:
                        systemStats.planets[task.targetID][techID] = 1
                    if task.demolishStruct:
                        try:
                            systemStats.planets[task.targetID][
                                task.demolishStruct] -= 1
                        except KeyError:
                            systemStats.planets[task.targetID][
                                task.demolishStruct] = -1
    # by parsing .planets object, fill the .bio and .en parameters
    systemStats.bio = 0
    systemStats.en = 0
    for planetID in systemStats.planets:
        planet = db[planetID]
        if planetID not in myPlanets:
            continue
        for techID in systemStats.planets[planetID]:
            quantity = systemStats.planets[planetID][techID]
            deltaBio, deltaEn, deltaProd = getSystemStatsChange(
                client, db, techID, planetID, 0)
            tech = client.getFullTechInfo(techID)
            systemStats.en += quantity * deltaEn
            systemStats.bio += quantity * deltaBio
    return systemStats
예제 #36
0
def tool_parseDB(client, db, enemyTypes):
    """ Parses all data in db for needs of other tools. Other in the name
    means other players.

    """
    data = IDataHolder()
    data.myPlanets = set()
    data.myProdPlanets = set()
    data.mySystems = set()
    data.freePlanets = set()
    data.freeSystems = set()
    data.nonhabPlanets = set()
    data.unknownSystems = set()
    data.otherPlanets = set()
    data.enemyPlanets = set()
    data.otherSystems = set()
    data.enemySystems = set()
    data.systems = set()
    data.myFleets = set()
    data.myMPPerSystem = {}
    data.myTargetedSystems = set()
    data.endangeredSystems = {}
    data.otherFleets = set()
    data.otherInboundFleets = set()
    data.idleFleets = set()
    data.myFleetsWithDesign = {}
    data.myFleetSheets = {}
    data.pirateSystems = set()
    data.relevantSystems = set()
    data.myRelevantSystems = set()
    data.distanceToRelevance = {}
    playerID = client.getPlayerID()
    player = client.getPlayer()
    owners = {}
    for objID in db.keys():
        try:
            obj = db[objID]
        except KeyError:
            # TODO find out why there are these errors
            continue
        objType = getattr(obj, 'type', None)
        if objType == Const.T_PLANET:
            ownerID = getattr(obj, 'owner', None)
            plSlots = getattr(obj, 'plSlots', 0)
            slots = getattr(obj, 'slots', [])
            prodProd = getattr(obj, 'prodProd', 0)
            plType = getattr(obj, 'plType', None)
            if plType == u'G' or plType == u'A':
                data.nonhabPlanets.add(objID)
                continue
            if ownerID == playerID and prodProd:
                data.myProdPlanets.add(objID)
                data.mySystems.add(obj.compOf)
            elif ownerID == playerID and not prodProd:
                # myPlanets are later joined by myProdPlanets
                data.myPlanets.add(objID)
                data.mySystems.add(obj.compOf)
            elif ownerID == Const.OID_NONE and plSlots:
                data.freePlanets.add(objID)
            elif not plSlots:
                data.unknownSystems.add(obj.compOf)
            else:
                # systems with owner other than myself, ignore EDEN planets
                if not ownerID:
                    continue
                elif ownerID not in owners:
                    owners[ownerID] = client.get(ownerID, publicOnly=1)

                if not getattr(owners[ownerID], 'type',
                               Const.OID_NONE) == Const.T_AIEDENPLAYER:
                    data.otherSystems.add(db[objID].compOf)
                    data.otherPlanets.add(objID)
                if getattr(owners[ownerID], 'type',
                           Const.OID_NONE) in enemyTypes:
                    data.enemySystems.add(db[objID].compOf)
                    data.enemyPlanets.add(objID)
                if getattr(owners[ownerID], 'type',
                           Const.OID_NONE) in (Const.T_AIPIRPLAYER,
                                               Const.T_PIRPLAYER):
                    data.pirateSystems.add(db[objID].compOf)
        elif objType == Const.T_SYSTEM:
            if getattr(obj, "starClass", "a")[0] == 'b':
                # black hole -> nothing to see here, let's ignore it completely
                continue
            data.systems.add(objID)
            if not hasattr(db[objID], 'planets'):
                data.unknownSystems.add(objID)
        elif objType == Const.T_FLEET:
            ownerID = getattr(obj, 'owner', None)
            if ownerID == playerID:
                data.myFleets.add(objID)
                data.myFleetSheets[objID] = getFleetSheet(obj)
                if len(obj.actions[obj.actionIndex:]) == 0:
                    data.idleFleets.add(objID)
                for designID in data.myFleetSheets[objID].keys():
                    if not data.myFleetsWithDesign.get(designID, set()):
                        data.myFleetsWithDesign[designID] = set([objID])
                    else:
                        data.myFleetsWithDesign[designID] |= set([objID])
            else:
                data.otherFleets.add(objID)
    # ==================
    # second phase
    # analyzing fleet action queues
    for fleetID in data.myFleets:
        fleet = db[fleetID]
        for orType, orTargID, orData in fleet.actions[fleet.actionIndex:]:
            if orType == Const.FLACTION_WAIT:
                continue
            elif orType == Const.FLACTION_REPEATFROM:
                continue
            elif orType == Const.FLACTION_REDIRECT:
                if orTargID == Const.OID_NONE:
                    continue
            orTarg = db[orTargID]
            if orTarg.type == Const.T_SYSTEM:
                data.unknownSystems -= set([orTargID])
            elif orTarg.type == Const.T_PLANET:
                data.unknownSystems -= set([orTarg.compOf])
            # deploy order removes target from free planets set
            # if deploying to non-free planet, change order TODO [non-systematic]
            if orType == Const.FLACTION_DEPLOY:
                if orTargID in data.freePlanets:
                    data.freePlanets -= set([orTargID])
                else:
                    client.cmdProxy.deleteAction(fleetID, fleet.actionIndex)
        # fill data.myMPPerSystem
        if len(fleet.actions[fleet.actionIndex:]) == 0:
            if fleet.orbiting in data.mySystems:
                try:
                    data.myMPPerSystem[fleet.orbiting] += fleet.combatPwr
                except KeyError:
                    data.myMPPerSystem[fleet.orbiting] = fleet.combatPwr
        else:
            lastOrder = fleet.actions[len(fleet.actions) - 1]
            targetID = lastOrder[1]
            if targetID in data.myPlanets:
                sysID = db[targetID].compOf
                try:
                    data.myMPPerSystem[sysID] += fleet.combatPwr
                except KeyError:
                    data.myMPPerSystem[sysID] = fleet.combatPwr
            elif targetID in data.mySystems:
                try:
                    data.myMPPerSystem[targetID] += fleet.combatPwr
                except KeyError:
                    data.myMPPerSystem[targetID] = fleet.combatPwr

    data.myPlanets |= data.myProdPlanets
    # only systems with free or nonhabitable planets are considered free
    for systemID in data.systems:
        isEmpty = True
        hasEmpty = False
        planets = set(getattr(db[systemID], 'planets', []))
        if planets and not planets - data.freePlanets - data.nonhabPlanets:
            data.freeSystems.add(systemID)
    # find attacking fleets
    for fleetID in data.otherFleets:
        fleet = db[fleetID]
        if getattr(fleet, 'target', None):
            targetID = getattr(fleet, 'target', None)
        elif not getattr(fleet, 'orbiting', Const.OID_NONE) == Const.OID_NONE:
            targetID = getattr(fleet, 'orbiting', Const.OID_NONE)
        if targetID:
            if targetID in data.myPlanets:
                data.myTargetedSystems.add(db[targetID].compOf)
                data.otherInboundFleets.add(fleetID)
            elif targetID in data.mySystems:
                data.myTargetedSystems.add(targetID)
                data.otherInboundFleets.add(fleetID)
    return data
예제 #37
0
 def getPublicInfo(self, tran, obj):
     result = IDataHolder()
     result.oid = obj.oid
     return result
예제 #38
0
 def new(self, type):
     obj = IDataHolder()
     self._cmd[type].init(obj)
     return obj
예제 #39
0
    def getScanInfos(self, tran, obj, scanPwr, player):
        result = IDataHolder()
        results = [result]
        if scanPwr >= Rules.level1InfoScanPwr:
            result._type = Const.T_SCAN
            result.scanPwr = scanPwr
            result.oid = obj.oid
            result.x = obj.x
            result.y = obj.y
            if hasattr(obj, 'destinationOid'):
                result.destinationOid = obj.destinationOid
            result.signature = obj.signature
            result.type = obj.type
            result.compOf = obj.compOf
            result.starClass = obj.starClass
        if scanPwr >= Rules.level2InfoScanPwr:
            result.name = obj.name
            result.combatCounter = obj.combatCounter
        if scanPwr >= Rules.level3InfoScanPwr:
            result.planets = obj.planets
            result.owner = obj.owner
            for planetID in obj.planets:
                planet = tran.db[planetID]
                if planet.owner == player:  ####### This was player.owner, which made no sense. Hope this change doesn't break something
                    continue
                newPwr = scanPwr * planet.signature / obj.signature
                results.extend(
                    self.cmd(planet).getScanInfos(tran, planet, newPwr,
                                                  player))
        if scanPwr >= Rules.level4InfoScanPwr:
            result.fleets = obj.fleets
            for fleetID in obj.fleets:
                fleet = tran.db[fleetID]
                if fleet.owner == player:
                    continue
                newPwr = scanPwr * fleet.signature / obj.signature
                results.extend(
                    self.cmd(fleet).getScanInfos(tran, fleet, newPwr, player))

            result.minefield = self.getMines(obj, player.oid)
            ownsMines = 1 if result.minefield else 0
            result.hasmines = min(2, len(self.getAllMines(obj))) - ownsMines
        return results
예제 #40
0
    def _create_answer(self, gal_type):
        template = self.offerings[gal_type]
        answer = IDataHolder()
        answer.scenario = template.scenario
        answer.minPlanets = template.minPlanets
        answer.maxPlanets = template.maxPlanets
        answer.radius = template.radius
        answer.players = template.players
        answer.resources = template.resources.keys()
        answer.challenges = self._get_challenges(template)

        if not template.startR[0] or not template.startR[1]:
            # that means grouping is used to maximize distance between players
            # most likely brawl scenario
            answer.playerGroup = 1
        else:
            answer.playerGroup = template.playerGroup
        return answer
예제 #41
0
 def getDiplomacyWith(self, tran, obj, playerID):
     if obj.oid == playerID:
         return Const.REL_UNITY
     player = tran.db.get(playerID, None)
     if player.type in (Const.T_AIPIRPLAYER, Const.T_PIRPLAYER):
         dipl = obj.diplomacyRels.get(playerID, None)
         if not dipl:
             # make default
             dipl = IDataHolder()
             dipl.type = Const.T_DIPLREL
             dipl.pacts = {
                     Const.PACT_ALLOW_CIVILIAN_SHIPS: [Const.PACT_ACTIVE, Const.PACT_ALLOW_CIVILIAN_SHIPS],
                     Const.PACT_ALLOW_MILITARY_SHIPS: [Const.PACT_ACTIVE, Const.PACT_ALLOW_MILITARY_SHIPS]
             }
             dipl.relation = Const.REL_FRIENDLY
             dipl.relChng = 0
             dipl.lastContact = tran.db[Const.OID_UNIVERSE].turn
             dipl.contactType = Const.CONTACT_NONE
             dipl.stats = None
             if playerID != obj.oid:
                 obj.diplomacyRels[playerID] = dipl
             else:
                 log.debug("getDiplomacyWith myself", obj.oid)
         return dipl
     # this AI battles with overyone
     # make default
     dipl = IDataHolder()
     dipl.type = Const.T_DIPLREL
     dipl.pacts = {}
     dipl.relation = Const.REL_ENEMY
     dipl.relChng = 0
     dipl.lastContact = tran.db[Const.OID_UNIVERSE].turn
     dipl.contactType = Const.CONTACT_NONE
     dipl.stats = None
     return dipl
예제 #42
0
def makeShipMinSpec(player, name, hullID, eqIDs, improvements,
    raiseExs = True):
    ship = makeShipFullSpec(player, name, hullID, eqIDs, improvements, raiseExs)
    # make 'real' ship spec
    spec = IDataHolder()
    spec.type = T_SHIP
    spec.name = ship.name
    spec.hullID = ship.hullID
    spec.level = ship.level
    spec.eqIDs = ship.eqIDs
    spec.improvements = ship.improvements
    spec.combatClass = ship.combatClass
    spec.signature = ship.signature
    spec.scannerPwr = ship.scannerPwr
    spec.speed = ship.speed
    spec.maxHP = ship.maxHP
    spec.shieldHP = ship.shieldHP
    spec.combatAtt = ship.combatAtt
    spec.combatDef = ship.combatDef
    spec.missileDef = ship.missileDef
    spec.storEn = ship.storEn
    spec.operEn = ship.operEn
    spec.buildProd = ship.buildProd
    spec.buildSRes = ship.buildSRes
    spec.weaponIDs = ship.weaponIDs
    spec.deployStructs = ship.deployStructs
    spec.deployHandlers = ship.deployHandlers
    spec.built = 0
    spec.buildTurns = 1
    spec.upgradeTo = 0
    spec.isMilitary = ship.isMilitary
    spec.baseExp = ship.baseExp
    spec.combatPwr = ship.combatPwr
    spec.autoRepairFix = ship.autoRepairFix
    spec.autoRepairPerc = ship.autoRepairPerc
    spec.shieldRechargeFix = ship.shieldRechargeFix
    spec.shieldRechargePerc = ship.shieldRechargePerc
    spec.hardShield = ship.hardShield
    spec.combatAttMultiplier = ship.combatAttMultiplier
    spec.damageAbsorb = ship.damageAbsorb
    return spec
예제 #43
0
            self.state = 2
        elif self.state == 4 and name == 'preresearch':
            self.tech.textPreRsrch = self.text
            self.state = 3
        elif self.state == 4 and name == 'description':
            self.tech.textDescr = self.text
            self.state = 3
        elif self.state == 4 and name == 'flavor':
            self.tech.textFlavor = self.text
            self.state = 3

    def characters(self, text):
        self.text += text


Tech = IDataHolder()

## init is wrapping all code that needs to be performed before module
# is ready. That is checking if techs changed, if not loading pickled
# data, othervise rebuild database from source data
# We should be able to do server-provided techs in the future (per galaxy
# rulesets)


def init(configDir):
    global Tech, techs

    ## check, if anything has been changed

    def chsumDir(chsum, dirname, names):
        names.sort()
예제 #44
0
def tool_parseDB(client, db, enemyTypes):
    """ Parses all data in db for needs of other tools. Other in the name
    means other players.

    """
    data = IDataHolder()
    data.myPlanets = set()
    data.myProdPlanets = set()
    data.mySystems = set()
    data.freePlanets = set()
    data.freeSystems = set()
    data.nonhabPlanets = set()
    data.unknownSystems = set()
    data.otherPlanets = set()
    data.enemyPlanets = set()
    data.otherSystems = set()
    data.enemySystems = set()
    data.systems = set()
    data.myFleets = set()
    data.myMPPerSystem = {}
    data.myTargetedSystems = set()
    data.endangeredSystems = {}
    data.otherFleets = set()
    data.otherInboundFleets = set()
    data.idleFleets = set()
    data.myFleetsWithDesign = {}
    data.myFleetSheets = {}
    data.pirateSystems = set()
    data.relevantSystems = set()
    data.myRelevantSystems = set()
    data.distanceToRelevance = {}
    playerID = client.getPlayerID()
    player = client.getPlayer()
    owners = {}
    for objID in db.keys():
        try:
            obj = db[objID]
        except KeyError:
            # TODO find out why there are these errors
            continue
        objType = getattr(obj, 'type', None)
        if objType == Const.T_PLANET:
            ownerID = getattr(obj, 'owner', None)
            plSlots = getattr(obj, 'plSlots', 0)
            slots = getattr(obj, 'slots', [])
            prodProd = getattr(obj, 'prodProd', 0)
            plType = getattr(obj, 'plType', None)
            if plType == u'G' or plType == u'A':
                data.nonhabPlanets.add(objID)
                continue
            if ownerID == playerID and prodProd:
                data.myProdPlanets.add(objID)
                data.mySystems.add(obj.compOf)
            elif ownerID == playerID and not prodProd:
                # myPlanets are later joined by myProdPlanets
                data.myPlanets.add(objID)
                data.mySystems.add(obj.compOf)
            elif ownerID == Const.OID_NONE and plSlots:
                data.freePlanets.add(objID)
            elif not plSlots:
                data.unknownSystems.add(obj.compOf)
            else:
                # systems with owner other than myself, ignore EDEN planets
                if not ownerID:
                    continue
                elif ownerID not in owners:
                    owners[ownerID] = client.get(ownerID, publicOnly = 1)

                if not getattr(owners[ownerID], 'type', Const.OID_NONE) == Const.T_AIEDENPLAYER:
                    data.otherSystems.add(db[objID].compOf)
                    data.otherPlanets.add(objID)
                if getattr(owners[ownerID], 'type', Const.OID_NONE) in enemyTypes:
                    data.enemySystems.add(db[objID].compOf)
                    data.enemyPlanets.add(objID)
                if getattr(owners[ownerID], 'type', Const.OID_NONE) in (Const.T_AIPIRPLAYER, Const.T_PIRPLAYER):
                    data.pirateSystems.add(db[objID].compOf)
        elif objType == Const.T_SYSTEM:
            if getattr(obj, "starClass", "a")[0] == 'b':
                # black hole -> nothing to see here, let's ignore it completely
                continue
            data.systems.add(objID)
            if not hasattr(db[objID], 'planets'):
                data.unknownSystems.add(objID)
        elif objType == Const.T_FLEET:
            ownerID = getattr(obj, 'owner', None)
            if ownerID == playerID:
                data.myFleets.add(objID)
                data.myFleetSheets[objID] = getFleetSheet(obj)
                if len(obj.actions[obj.actionIndex:]) == 0:
                    data.idleFleets.add(objID)
                for designID in data.myFleetSheets[objID].keys():
                    if not data.myFleetsWithDesign.get(designID, set()):
                        data.myFleetsWithDesign[designID] = set([objID])
                    else:
                        data.myFleetsWithDesign[designID] |= set([objID])
            else:
                data.otherFleets.add(objID)
    # ==================
    # second phase
    # analyzing fleet action queues
    for fleetID in data.myFleets:
        fleet = db[fleetID]
        for orType, orTargID, orData in fleet.actions[fleet.actionIndex:]:
            if orType == Const.FLACTION_WAIT:
                continue
            elif orType == Const.FLACTION_REPEATFROM:
                continue
            elif orType == Const.FLACTION_REDIRECT:
                if orTargID == Const.OID_NONE:
                    continue
            orTarg = db[orTargID]
            if orTarg.type == Const.T_SYSTEM:
                data.unknownSystems -= set([orTargID])
            elif orTarg.type == Const.T_PLANET:
                data.unknownSystems -= set([orTarg.compOf])
            # deploy order removes target from free planets set
            # if deploying to non-free planet, change order TODO [non-systematic]
            if orType == Const.FLACTION_DEPLOY:
                if orTargID in data.freePlanets:
                    data.freePlanets -= set([orTargID])
                else:
                    client.cmdProxy.deleteAction(fleetID, fleet.actionIndex)
        # fill data.myMPPerSystem
        if len(fleet.actions[fleet.actionIndex:]) == 0:
            if fleet.orbiting in data.mySystems:
                try:
                    data.myMPPerSystem[fleet.orbiting] += fleet.combatPwr
                except KeyError:
                    data.myMPPerSystem[fleet.orbiting] = fleet.combatPwr
        else:
            lastOrder = fleet.actions[len(fleet.actions)-1]
            targetID = lastOrder[1]
            if targetID in data.myPlanets:
                sysID = db[targetID].compOf
                try:
                    data.myMPPerSystem[sysID] += fleet.combatPwr
                except KeyError:
                    data.myMPPerSystem[sysID] = fleet.combatPwr
            elif targetID in data.mySystems:
                try:
                    data.myMPPerSystem[targetID] += fleet.combatPwr
                except KeyError:
                    data.myMPPerSystem[targetID] = fleet.combatPwr

    data.myPlanets |= data.myProdPlanets
    # only systems with free or nonhabitable planets are considered free
    for systemID in data.systems:
        isEmpty = True
        hasEmpty = False
        planets = set(getattr(db[systemID], 'planets', []))
        if planets and not planets - data.freePlanets - data.nonhabPlanets:
            data.freeSystems.add(systemID)
    # find attacking fleets
    for fleetID in data.otherFleets:
        fleet = db[fleetID]
        if getattr(fleet, 'target', None):
            targetID = getattr(fleet, 'target', None)
        elif not getattr(fleet, 'orbiting', Const.OID_NONE) == Const.OID_NONE:
            targetID = getattr(fleet, 'orbiting', Const.OID_NONE)
        if targetID:
            if targetID in data.myPlanets:
                data.myTargetedSystems.add(db[targetID].compOf)
                data.otherInboundFleets.add(fleetID)
            elif targetID in data.mySystems:
                data.myTargetedSystems.add(targetID)
                data.otherInboundFleets.add(fleetID)
    return data
예제 #45
0
 def getScanInfos(self, tran, obj, scanPwr, player):
     result = IDataHolder()
     results = [result]
     if scanPwr >= Rules.level1InfoScanPwr:
         result._type = T_SCAN
         result.scanPwr = scanPwr
         result.oid = obj.oid
         result.x = obj.x
         result.y = obj.y
         if hasattr(obj, 'destinationOid'):
             result.destinationOid = obj.destinationOid
         # multiply by 1000 to increase accuracy
         #~ result.dist = obj.dist * 1000
         #~ result.dAngle = obj.dAngle * 1000
         #~ result.sAngle = obj.sAngle * 1000
         result.signature = obj.signature
         result.type = obj.type
         result.compOf = obj.compOf
         result.starClass = obj.starClass
     if scanPwr >= Rules.level2InfoScanPwr:
         result.name = obj.name
         result.combatCounter = obj.combatCounter
     if scanPwr >= Rules.level3InfoScanPwr:
         result.planets = obj.planets
         result.owner = obj.owner
         for planetID in obj.planets:
             planet = tran.db[planetID]
             if planet.owner == player: ####### This was player.owner, which made no sense. Hope this change doesn't break something
                 continue
             newPwr = scanPwr * planet.signature / obj.signature
             results.extend(self.cmd(planet).getScanInfos(tran, planet, newPwr, player))
     if scanPwr >= Rules.level4InfoScanPwr:
         result.fleets = obj.fleets
         for fleetID in obj.fleets:
             fleet = tran.db[fleetID]
             if fleet.owner == player:
                 continue
             newPwr = scanPwr * fleet.signature / obj.signature
             results.extend(self.cmd(fleet).getScanInfos(tran, fleet, newPwr, player))
         result.hasmines = 0 #no
         if len(obj.minefield) > 0:
             result.hasmines = 1 #yes
         result.minefield = self.getMines(obj,player.oid) #only shows mines you own
         if len(obj.minefield) > 1 or (len(obj.minefield) == 1 and len(result.minefield) == 0):
             result.hasmines = 2 #yes, and some aren't my mines
     return results
예제 #46
0
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
예제 #47
0
	def XXXgetDiplomacyWith(self, tran, obj, playerID):
		if obj.oid == playerID:
			return REL_UNITY
		player = tran.db.get(playerID, None)
		if player.type == T_AIEDENPLAYER:
			dipl = obj.diplomacyRels.get(playerID, None)
			if not dipl:
				# make default
				dipl = IDataHolder()
				dipl.type = T_DIPLREL
				dipl.pacts = {
						PACT_ALLOW_CIVILIAN_SHIPS: [PACT_ACTIVE, PACT_ALLOW_CIVILIAN_SHIPS],
						PACT_ALLOW_MILITARY_SHIPS: [PACT_ACTIVE, PACT_ALLOW_MILITARY_SHIPS]
				}
				dipl.relation = REL_FRIENDLY
				dipl.relChng = 0
				dipl.lastContact = tran.db[OID_UNIVERSE].turn
				dipl.contactType = CONTACT_NONE
				dipl.stats = None
				if playerID != obj.oid:
					obj.diplomacyRels[playerID] = dipl
				else:
					log.debug("getDiplomacyWith myself", obj.oid)
			return dipl
		# this AI battles with overyone
		# make default
		dipl = IDataHolder()
		dipl.type = T_DIPLREL
		dipl.pacts = {}
		dipl.relation = REL_ENEMY
		dipl.relChng = 0
		dipl.lastContact = tran.db[OID_UNIVERSE].turn
		dipl.contactType = CONTACT_NONE
		dipl.stats = None
		return dipl
예제 #48
0
 def getScanInfo(self, tran, obj, scanPwr):
     result = IDataHolder()
     result._type = Const.T_SCAN
     result.scanPwr = scanPwr
     if scanPwr > Rules.level1InfoScanPwr:
         result.oid = obj.oid
         result.x = obj.x
         result.y = obj.y
         result.oldX = obj.oldX
         result.oldY = obj.oldY
         result.signature = obj.signature
         result.type = obj.type
         result.orbiting = obj.orbiting
         result.speed = obj.speed
         result.eta = obj.eta
     if scanPwr > Rules.level2InfoScanPwr:
         result.name = obj.name
     if scanPwr > Rules.level3InfoScanPwr:
         result.asDiameter = obj.asDiameter
         result.asHP = obj.asHP
     if scanPwr > Rules.level4InfoScanPwr:
         pass
     return result
예제 #49
0
    def processBATTLEPhase(self, tran, obj, data):
        system = obj
        #@log.debug('ISystem', 'BATTLE - system', obj.oid)
        # we are processing fleets, planets, ...
        objects = obj.planets[:] + obj.fleets[:]
        # shuffle them to prevent predetermined one-sided battles (temporary hack)
        random.shuffle(objects)
        # store owners of objects
        # find enemies and allies
        attack = {}
        allies = {}
        owners = {}
        ownerIDs = {}
        systemAtt = {}
        systemDef = {}
        hasMine = {}
        isOwnedObject = 0
        for objID in objects:
            attack[objID] = []
            allies[objID] = []
            owner = tran.db[objID].owner
            owners[objID] = owner
            ownerIDs[owner] = owner
            if owner != OID_NONE:
                isOwnedObject = 1
        for owner in ownerIDs:
            tempAtt, tempDef = self.getSystemCombatBonuses(tran,system,owner)
            systemAtt[owner] = tempAtt
            systemDef[owner] = tempDef
            hasMine[owner] = self.getSystemMineSource(tran,system,owner)
        if not isOwnedObject:
            #@log.debug('ISystem', 'No combat')
            # reset combat counters
            system.combatCounter = 0
            return
        # first - direct ones
        index = 1
        for obj1ID in objects:
            obj1 = tran.db[obj1ID]
            if obj1.owner == OID_NONE:
                index += 1
                continue
            commander = tran.db[obj1.owner]
            # relationships
            #for obj2ID in objects[index:]:
            for obj2ID in objects:
                obj2 = tran.db[obj2ID]
                if obj2.owner == OID_NONE or obj1 is obj2:
                    continue
                if obj1.owner == obj2.owner:
                    allies[obj1ID].append(obj2ID)
                    allies[obj2ID].append(obj1ID)
                    continue
                # planet and military object
                elif obj1.type == T_PLANET and obj2.isMilitary and \
                    not self.cmd(commander).isPactActive(tran, commander, obj2.owner, PACT_ALLOW_MILITARY_SHIPS):
                    #@log.debug("ISystem pl - mil", obj1ID, obj2ID)
                    if obj2ID not in attack[obj1ID]:
                        attack[obj1ID].append(obj2ID)
                    if obj1ID not in attack[obj2ID]:
                        attack[obj2ID].append(obj1ID)
                # planet and civilian object
                elif obj1.type == T_PLANET and not obj2.isMilitary and \
                    not self.cmd(commander).isPactActive(tran, commander, obj2.owner, PACT_ALLOW_CIVILIAN_SHIPS):
                    #@log.debug("ISystem pl - civ", obj1ID, obj2ID)
                    if obj2ID not in attack[obj1ID]:
                        attack[obj1ID].append(obj2ID)
                    if obj1ID not in attack[obj2ID]:
                        attack[obj2ID].append(obj1ID)
                # military and military object
                elif obj1.isMilitary and obj2.isMilitary and \
                    not self.cmd(commander).isPactActive(tran, commander, obj2.owner, PACT_ALLOW_MILITARY_SHIPS):
                    #@log.debug("ISystem mil - mil", obj1ID, obj2ID)
                    if obj2ID not in attack[obj1ID]:
                        attack[obj1ID].append(obj2ID)
                    if obj1ID not in attack[obj2ID]:
                        attack[obj2ID].append(obj1ID)
                # military and civilian object
                elif obj1.isMilitary and not obj2.isMilitary and \
                    not self.cmd(commander).isPactActive(tran, commander, obj2.owner, PACT_ALLOW_CIVILIAN_SHIPS):
                    #@log.debug("ISystem mil - civ", obj1ID, obj2ID)
                    if obj2ID not in attack[obj1ID]:
                        attack[obj1ID].append(obj2ID)
                    if obj1ID not in attack[obj2ID]:
                        attack[obj2ID].append(obj1ID)
                # planet and fleet
                #elif obj1.type == T_PLANET and obj2.type == T_FLEET and \
                #    self.cmd(commander).isPactActive(tran, commander, obj2.owner, PACT_MUTUAL_DEFENCE):
                #    allies[obj1ID].append(obj2ID)
                #    allies[obj2ID].append(obj1ID)
                # fleet and fleet
                #elif obj1.type == T_FLEET and obj2.type == T_FLEET and \
                #    self.cmd(commander).isPactActive(tran, commander, obj2.owner, PACT_MUTUAL_OFFENCE):
                #    allies[obj1ID].append(obj2ID)
                #    allies[obj2ID].append(obj1ID)
                # asteroid
                if obj2.type == T_ASTEROID:
                    attack[obj1ID].append(obj2ID)
                    attack[obj2ID].append(obj1ID)
            index += 1
        #@log.debug('ISystem', 'Targets:', targets)
        #@log.debug('ISystem', 'Allies:', allies)
        # find indirect a/e
        #for objID in objects:
        #    iTargets = []
        #    iAllies = []
        #    # find indirect a/e
        #    todo = allies[objID][:]
        #    while todo:
        #        id = todo.pop(0)
        #        iTargets.extend(targets[id])
        #        for tmpID in allies[id]:
        #            if tmpID not in iAllies:
        #                todo.append(tmpID)
        #                iAllies.append(tmpID)
        #    # remove allies from targets
        #    for id in iAllies:
        #        if id in iTargets:
        #            iTargets.remove(id)
        #    # IMPORTATNT preffer NOT to fire at possible allies
        #    # add my targets
        #    #for id in targets[objID]:
        #    #    if id not in iTargets:
        #    #        iTargets.append(id)
        #    # that's all folks
        #    for id in iTargets:
        #        if objID not in attack[id]:
        #            attack[id].append(objID)
        #        if id not in attack[objID]:
        #            attack[objID].append(id)
        # NOT VALID: objects with action ACTION_ATTACK will attack only their targets
        # check, if there are any targets
        isCombat = 0
        for objID in objects:
            if attack[objID]:
                isCombat = 1
                break #end loop
        if not isCombat:
            #@log.debug('ISystem', 'No combat')
            # reset combat counters
            system.combatCounter = 0
            for fleetID in system.fleets:
                tran.db[fleetID].combatCounter = 0
            return
        # increase combat counters
        system.combatCounter += 1
        for fleetID in system.fleets:
            tran.db[fleetID].combatCounter += 1
        # debug
        log.debug('ISystem', 'Final attacks in system %d:' % system.oid, attack)
        # mines detonate before battle
        shots = {}
        targets = {}
        firing = {}
        damageCaused = {}
        killsCaused = {}
        damageTaken = {}
        shipsLost = {}
        minesTriggered = {}
        fleetOwners = {}
        isCombat = False
        isMineCombat = False
        for owner in ownerIDs:
            if not (owner in hasMine): #no planets
                continue
            if hasMine[owner] == 0: #no control structure
                continue
            objID = hasMine[owner]
            if len(self.getMines(system,owner)) == 0:
                continue #no mines, something broke
            #log.debug('ISystem-Mines', 'Mines Found')
            if len(attack[objID]) == 0:
                continue #no targets
            isMineFired = True
            mineTargets = copy.copy(attack[objID])
            while isMineFired:
                while len(mineTargets) > 0:
                    targetID = random.choice(mineTargets) #select random target
                    targetobj = tran.db.get(targetID, None)
                    try:
                        if targetobj.type == T_FLEET:
                            fleetOwners[targetID] = targetobj.owner
                            break #target found
                        mineTargets.remove(targetID) #remove an object type that a mine can't hit from the temporary targets list
                    except:
                        mineTargets.remove(targetID) #remove a dead fleet from the temporary targets list

                if len(mineTargets) == 0:
                    break #no fleet targets for mines
                temp, temp, firing[targetID] = self.cmd(targetobj).getPreCombatData(tran, targetobj) #fix firing for "surrender to" section
                damage,att,ignoreshield, mineID = self.cmd(obj).fireMine(system, owner)
                if not damage: #no more mines
                    isMineFired = False
                    break
                log.debug('ISystem', 'Mine Shooting (damage, att, ignore shield):',damage,att,ignoreshield)
                isMineCombat = True
                minesTriggered[mineID] = minesTriggered.get(mineID, 0) + 1
                #Process Combat
                #for now we assume only one ship can be destroyed by one mine
                dmg, destroyed = self.cmd(targetobj).applyMine(tran, targetobj, att, damage, ignoreshield)
                #log.debug('ISystem-Mines', 'Actual Damage Done:',dmg)
                if dmg > 0:
                    damageTaken[targetID] = damageTaken.get(targetID, 0) + dmg
                    shipsLost[targetID] = shipsLost.get(targetID, 0) + destroyed
                    killsCaused[mineID] = killsCaused.get(mineID, 0) + destroyed
                if dmg > 0:
                    damageCaused[mineID] = damageCaused.get(mineID, 0) + dmg
            # send messages about mine effects to the owner of the minefield
            # collect hit players
            players = {}
            for triggerID in firing.keys():
                players[owners[triggerID]] = None
            controllerPlanet = tran.db.get(objID, None)
            damageCausedSum = 0
            killsCausedSum = 0
            for mineID in damageCaused.keys():
                damageCausedSum = damageCausedSum + damageCaused.get(mineID, 0)
                killsCausedSum = killsCausedSum + killsCaused.get(mineID, 0)
            Utils.sendMessage(tran, controllerPlanet, MSG_MINES_OWNER_RESULTS, system.oid, (players.keys(),(damageCaused, killsCaused, minesTriggered),damageCausedSum,killsCausedSum))
        # send messages to the players whose fleets got hit by minefields
        for targetID in damageTaken.keys():
            targetFleet = tran.db.get(targetID, None)
            if targetFleet:
                Utils.sendMessage(tran, targetFleet, MSG_MINES_FLEET_RESULTS, system.oid, (damageTaken[targetID], shipsLost[targetID]))
            else:
                targetFleet = IDataHolder()
                targetFleet.oid = fleetOwners[targetID]
                Utils.sendMessage(tran, targetFleet, MSG_MINES_FLEET_RESULTS, system.oid, (damageTaken[targetID], shipsLost[targetID]))
                Utils.sendMessage(tran, targetFleet, MSG_DESTROYED_FLEET, system.oid, ())
        damageCaused = {}
        killsCaused = {}
        damageTaken = {}
        shipsLost = {}
        # now to battle
        for objID in objects:
            obj = tran.db.get(objID, None)
            # get shots from object, should be sorted by weaponClass
            # shots = [ shot, ...], shot = (combatAtt, weaponID)
            # get target classes and numbers
            # (class1, class2, class3, class4)
            # cls0 == fighters, cls1 == midships, cls2 == capital ships, cls3 == planet installations
            #@log.debug(objID, obj.name, "getting pre combat data")
            if obj: # source already destroyed; ignore
                shots[objID], targets[objID], firing[objID] = self.cmd(obj).getPreCombatData(tran, obj)
                if firing[objID]:
                    isCombat = True
        if not isCombat and not isMineCombat:
            # no shots has been fired
            #@log.debug('ISystem', 'No combat')
            # reset combat counters
            system.combatCounter = 0
            for fleetID in system.fleets:
                tran.db[fleetID].combatCounter = 0
            return
        #@log.debug("Shots:", shots)
        #@log.debug("Targets", targets)
        if isCombat:
            for shotIdx in (3, 2, 1, 0):
                for objID in objects:
                    # obj CAN be deleted at this point
                    obj = tran.db.get(objID, None)
                    if obj == None:
                        continue # source already destroyed; move to next source
                    # if object is fleet, then it's signature is max
                    if obj and obj.type == T_FLEET:
                        obj.signature = Rules.maxSignature
                    # target preselection
                    totalClass = [0, 0, 0, 0]
                    total = 0
                    for targetID in attack[objID]:
                        totalClass[0] += targets[targetID][0]
                        totalClass[1] += targets[targetID][1]
                        totalClass[2] += targets[targetID][2]
                        totalClass[3] += targets[targetID][3]
                    total = totalClass[0] + totalClass[1] + totalClass[2] + totalClass[3]
                    # process shots
                    for combatAtt, weaponID in shots[objID][shotIdx]:
                        weapon = Rules.techs[weaponID]
                        weaponClass = weapon.weaponClass
                        if total == 0:
                            # there are no targets
                            break
                        #@log.debug('ISystem', 'Processing shot', objID, weapon.name, weaponClass)
                        # process from weaponClass up
                        # never shoot on smaller ships than weaponClass
                        applied = 0
                        for tmpWpnClass in xrange(weaponClass, 4):
                            #@log.debug('ISystem', 'Trying target class', tmpWpnClass, totalClass[tmpWpnClass])
                            # select target
                            if totalClass[tmpWpnClass]:
                                target = Utils.rand(0, totalClass[tmpWpnClass])
                                #@log.debug('ISystem', 'Target rnd num', target, totalClass[tmpWpnClass])
                                for targetID in attack[objID]:
                                    if target < targets[targetID][tmpWpnClass]:
                                        #@log.debug(objID, 'attacks', targetID, tmpWpnClass)
                                        # targetID can be deleted at this point
                                        anObj = tran.db.get(targetID, None)
                                        if anObj:
                                            dmg, destroyed, destroyedClass = self.cmd(anObj).applyShot(tran, anObj, systemDef[owners[targetID]], combatAtt + systemAtt[owners[objID]], weaponID, tmpWpnClass, target)
                                            #@log.debug("ISystem result", dmg, destroyed, destroyedClass, tmpWpnClass)
                                            #@print objID, 'dmg, destroyed', dmg, destroyed
                                            damageTaken[targetID] = damageTaken.get(targetID, 0) + dmg
                                            if destroyed > 0:
                                                shipsLost[targetID] = shipsLost.get(targetID, 0) + destroyed
                                                total -= destroyed
                                                totalClass[destroyedClass] -= destroyed
                                            if dmg > 0 and obj:
                                                obj.combatExp += dmg
                                                damageCaused[objID] = damageCaused.get(objID, 0) + dmg
                                            applied = 1
                                        else:
                                            continue # target already destroyed, move to next target
                                        break
                                    else:
                                        #@log.debug('ISystem', 'Lovering target by', targets[targetID][tmpWpnClass])
                                        target -= targets[targetID][tmpWpnClass]
                            if applied:
                                break
        # send messages and modify diplomacy relations
        # distribute experience pts
        for objID in objects:
            obj = tran.db.get(objID, None)
            if obj:
                self.cmd(obj).distributeExp(tran, obj)
            if attack[objID]:
                source = obj or tran.db[owners[objID]]
                # collect players
                players = {}
                for attackerID in attack[objID]:
                    players[owners[attackerID]] = None
                d1 = damageTaken.get(objID,0)
                d2 = damageCaused.get(objID,0)
                l = shipsLost.get(objID, 0)
                if d1 or d2 or l:
                    # send only if damage is taken/caused
                    Utils.sendMessage(tran, source, MSG_COMBAT_RESULTS, system.oid, (d1, d2, l, players.keys()))
                if not obj:
                    # report DESTROYED status
                    Utils.sendMessage(tran, source, MSG_DESTROYED_FLEET, system.oid, ())
                # modify diplomacy relations
                objOwner = tran.db[owners[objID]]
                for attackerID in attack[objID]:
                    attOwner = tran.db.get(owners[attackerID], None)
                    # owner of the fleet
                    rel = self.cmd(objOwner).getDiplomacyWith(tran, objOwner, attOwner.oid)
                    rel.relChng = Rules.relLostWhenAttacked
                    # attacker
                    rel = self.cmd(attOwner).getDiplomacyWith(tran, attOwner, objOwner.oid)
                    rel.rechChng = Rules.relLostWhenAttacked
        # check if object surrenders
        for objID in objects:
            # object surrender IFF it and its allies had target and was not able
            # to fire at it, planet is not counted as ally in this case
            obj = tran.db.get(objID, None)
            if firing[objID] and obj:
                continue
            surrenderTo = []
            for attID in attack[objID]:
                if firing[attID] and tran.db.has_key(attID):
                    surrenderTo.append(tran.db[attID].owner)
            for allyID in allies[objID]:
                if not tran.db.has_key(allyID):
                    continue
                ally = tran.db[allyID]
                if firing[allyID] and ally.type != T_PLANET:
                    surrenderTo = []
                    break
            if surrenderTo:
                index = Utils.rand(0, len(surrenderTo))
                if obj:
                    if self.cmd(obj).surrenderTo(tran, obj, surrenderTo[index]):
                        winner = tran.db[surrenderTo[index]]
                        source = tran.db.get(owners[objID], None)
                        log.debug('ISystem', 'BATTLE - surrender', objID, surrenderTo[index], surrenderTo)
                        if source:
                            Utils.sendMessage(tran, source, MSG_COMBAT_LOST, system.oid, winner.oid)
                            Utils.sendMessage(tran, winner, MSG_COMBAT_WON, system.oid, source.oid)
                        else:
                            Utils.sendMessage(tran, winner, MSG_COMBAT_WON, system.oid, obj.oid)
                else:
                    winner = tran.db[surrenderTo[index]]
                    source = tran.db[owners[objID]]
                    log.debug('ISystem', 'BATTLE - surrender', objID, surrenderTo[index], surrenderTo)
                    Utils.sendMessage(tran, source, MSG_COMBAT_LOST, system.oid, winner.oid)
                    Utils.sendMessage(tran, winner, MSG_COMBAT_WON, system.oid, source.oid)
        return
예제 #50
0
	def startConstruction(self, tran, obj, techID, quantity, targetID, isShip, reportFinished,
		demolishStruct):
		if len(obj.prodQueue) > Rules.maxProdQueueLen:
			raise GameException('Queue is full.')
		if quantity < 1:
			raise GameException("Quantity must be greater than 0")
		player = tran.db[obj.owner]
		if not player.techs.has_key(techID) and isShip == 0:
			raise GameException('You do not own this kind of technology.')
		if not player.shipDesigns.has_key(techID) and isShip == 1:
			raise GameException('You do not own this ship design.')
		if targetID not in tran.db[obj.compOf].planets:
			raise GameException('You can build only in the same system.')
		if isShip:
			tech = player.shipDesigns[techID]
			if tech.upgradeTo:
				raise GameException("You cannot build obsolete ship design.")
		else:
			tech = Rules.techs[techID]
			if not (tech.isStructure or tech.isProject):
				raise GameException('You cannot construct this technology.')
			if not tech.validateConstrHandler(tran, obj, tran.db[targetID], tech):
				raise GameException('Conditions for construction are not satisfied.')
		neededSR = {}
		for sr in tech.buildSRes:
			if player.stratRes.get(sr, 0) < neededSR.get(sr, 0) + quantity:
				raise GameException("You do not own required strategic resource(s)")
			neededSR[sr] = neededSR.get(sr, 0) + quantity
		# consume strategic resources
		for sr in neededSR:
			player.stratRes[sr] -= neededSR[sr]
		# start construction
		item = IDataHolder()
		item.techID = techID
		item.currProd = 0
		item.currTurn = 0
		item.quantity = int(quantity)
		item.targetID = targetID
		item.changePerc = 0
		item.isShip = bool(isShip)
		item.reportFin = bool(reportFinished)
		item.demolishStruct = demolishStruct
		item.type = T_TASK
		obj.prodQueue.append(item)
		return obj.prodQueue, player.stratRes
예제 #51
0
def makeShipMinSpec(player, name, hullID, eqIDs, improvements, raiseExs=True):
    ship = makeShipFullSpec(player, name, hullID, eqIDs, improvements,
                            raiseExs)
    # make 'real' ship spec
    spec = IDataHolder()
    spec.type = Const.T_SHIP
    spec.name = ship.name
    spec.hullID = ship.hullID
    spec.level = ship.level
    spec.eqIDs = ship.eqIDs
    spec.improvements = ship.improvements
    spec.combatClass = ship.combatClass
    spec.signature = ship.signature
    spec.scannerPwr = ship.scannerPwr
    spec.speed = ship.speed
    spec.battleSpeed = ship.battleSpeed
    spec.maxHP = ship.maxHP
    spec.shieldHP = ship.shieldHP
    spec.combatAtt = ship.combatAtt
    spec.combatDef = ship.combatDef
    spec.missileDef = ship.missileDef
    spec.storEn = ship.storEn
    spec.operEn = ship.operEn
    spec.buildProd = ship.buildProd
    spec.buildSRes = ship.buildSRes
    spec.weaponIDs = ship.weaponIDs
    spec.deployStructs = ship.deployStructs
    spec.deployHandlers = ship.deployHandlers
    spec.built = 0
    spec.buildTurns = 1
    spec.upgradeTo = 0
    spec.isMilitary = ship.isMilitary
    spec.baseExp = ship.baseExp
    spec.combatPwr = ship.combatPwr
    spec.autoRepairFix = ship.autoRepairFix
    spec.autoRepairPerc = ship.autoRepairPerc
    spec.shieldRechargeFix = ship.shieldRechargeFix
    spec.shieldRechargePerc = ship.shieldRechargePerc
    spec.hardShield = ship.hardShield
    spec.combatAttMultiplier = ship.combatAttMultiplier
    spec.damageAbsorb = ship.damageAbsorb
    return spec
예제 #52
0
def getSystemStructStats(data, client, db, systemID, processQueues=True):
    """ It go through all planets and structures, and creates IDataHolder
    object, with roster of buildings, surplus of bio and en.

    processQueues - if True, it go through all buildQueues and adjust all
                    statistics as it would be all done already.

    Returns IDataHolder with parameters:
        .bio - system surplus of biomass
        .en - system surplus of en
        .planets - dictionary, keys are planetIDs of players or free planets,
                   and values are dictionaries (huh) with keys being techIDs
                   and values being number of those structs.

    """
    systemStats = IDataHolder()
    system = db[systemID]
    player = client.getPlayer()
    myPlanets = set(system.planets) & data.myPlanets
    systemStats.planets = {}
    for planetID in myPlanets:
        systemStats.planets[planetID] = {}
    for planetID in set(system.planets) & data.freePlanets:
        systemStats.planets[planetID] = {}
    # creation of the .planets dictionary
    for planetID in myPlanets:
        planet = db[planetID]
        for techID, hp, something, eff in planet.slots:
            try:
                systemStats.planets[planetID][techID] += 1
            except KeyError:
                systemStats.planets[planetID][techID] = 1
        if not processQueues:
            # do not look into the queue
            continue
        for task in getattr(planet, 'prodQueue', []):
            if not task.isShip:
                techID = task.techID
                tech = client.getFullTechInfo(task.techID)
                if tech.isStructure:
                    if task.targetID not in systemStats.planets.keys():
                        continue
                    try:
                        systemStats.planets[task.targetID][techID] += 1
                    except KeyError:
                        systemStats.planets[task.targetID][techID] = 1
                    if task.demolishStruct:
                        try:
                            systemStats.planets[task.targetID][task.demolishStruct] -= 1
                        except KeyError:
                            systemStats.planets[task.targetID][task.demolishStruct] = -1
    # by parsing .planets object, fill the .bio and .en parameters
    systemStats.bio = 0
    systemStats.en = 0
    for planetID in systemStats.planets:
        planet = db[planetID]
        if planetID not in myPlanets:
            continue
        for techID in systemStats.planets[planetID]:
            quantity = systemStats.planets[planetID][techID]
            deltaBio, deltaEn, deltaProd = getSystemStatsChange(client, db, techID, planetID, 0)
            tech = client.getFullTechInfo(techID)
            systemStats.en += quantity * deltaEn
            systemStats.bio += quantity * deltaBio
    return systemStats