def _researchContext(self, tech): player = client.getPlayer() descr = [] improvement = player.techs.get(self.techID, 0) if hasattr(tech, 'researchMod'): prefix = _('Improvement') if improvement else _('Research') descr.append( _('%s costs: %d') % (prefix, Utils.getTechRCost(player, self.techID))) descr.append('') # requires if tech.researchRequires and improvement == 0: descr.append(_('Research requires:')) for tmpTechID, improvement in tech.researchRequires: tmpTech = client.getTechInfo(tmpTechID) descr.append( _(' - %s improvement %d (TL%d)') % (tmpTech.name, improvement, tmpTech.level)) if hasattr(tech, "researchReqSRes"): for stratRes in tech.researchReqSRes: descr.append( _(" - %s (strategic resource)") % (gdata.stratRes[stratRes])) descr.append('') if hasattr(tech, "researchDisables") and tech.researchDisables: descr.append(_("Research disables:")) for tmpTechID in tech.researchDisables: tmpTech = client.getTechInfo(tmpTechID) descr.append(_(" - %s (TL%d)") % (tmpTech.name, tmpTech.level)) descr.append('') return descr
def buildSystem(data, client, db, systemID, prodPlanets, finalSystemPlan): """ Assigns tasks to all idle planets with CP > 0 in one system, according to object finalSystemPlan. There is NO guaranty it will rebuild it correctly as no math model was made for it. It just try to build most effectively, with keeping system in each step self sufficient. For functioning correctly, it is probably necessary to have some reserves [one planets builds slowly big farm, another knowing it builds factory over only outpost, .. :)] finalSystemPlan - dictionary, keys are planetIDs of players or free planets, and values are dictionaries with keys being techIDs and values being number of those structs. """ system = db[systemID] player = client.getPlayer() structStats = getSystemStructStats(data, client, db, systemID) structsToBuild = {} structsToDemolish = {} difference = {} checkBuildQueues(data, client, db, systemID, prodPlanets) # parse final plan to set buildings which need to be build and those that # may be demolished for planetID in finalSystemPlan: difference[planetID] = Utils.dictSubtraction(finalSystemPlan[planetID], structStats.planets[planetID]) for planetID in difference: structsToBuild[planetID] = {} structsToDemolish[planetID] = {} for techID in difference[planetID]: if difference[planetID][techID] > 0: structsToBuild[planetID][techID] = difference[planetID][techID] elif difference[planetID][techID] < 0: structsToDemolish[planetID][techID] = difference[planetID][techID] idlePlanets = copy.copy(prodPlanets) for planetID in prodPlanets: planet = db[planetID] if getattr(planet, 'prodQueue', None): # something in the build queue, skip the planet idlePlanets.remove(planetID) continue # start the most effective project [CP-wise], which is still leaving # sustainable system toBuild = getStructBuildEffectivity(client, db, planetID, structsToBuild.keys(), structsToBuild, structsToDemolish) for techID, targetPlanetID, targetTechID in toBuild: targetPlanet = db[targetPlanetID] if len(targetPlanet.slots) == targetPlanet.plSlots and targetTechID == Const.OID_NONE: continue deltaBio, deltaEn, deltaProd = getSystemStatsChange(client, db, techID, targetPlanetID, targetTechID) if structStats.bio + deltaBio >= 0 and structStats.en + deltaEn >= 0: planet.prodQueue, player.stratRes = client.cmdProxy.startConstruction(planetID, techID, 1, targetPlanetID, techID < 1000, 0, targetTechID) idlePlanets.remove(planetID) # remove this struct from possibility list structsToBuild[targetPlanetID][techID] -= 1 if structsToBuild[targetPlanetID][techID] == 0: del structsToBuild[targetPlanetID][techID] break return idlePlanets
def _processResearchQueueTask(self, task): player = client.getPlayer() tech = client.getTechInfo(task.techID) fulltech = client.getFullTechInfo(task.techID) researchSci = Utils.getTechRCost(player, task.techID, task.improvement) item = ui.Item(tech.name, techID=task.techID) item.tooltipTitle = _("Details") item.tooltip = _("Research points %d/%d, change %d pts/turn.") % ( task.currSci, researchSci, task.changeSci) item.statustip = item.tooltip item.tImpToMax = "*" if task.improveToMax else "" item.tImproveToMax = task.improveToMax item.tProgress = _("%d %%") % int( task.currSci * 100 / researchSci) if task.currSci > 0 else _("-") totalSci = 0 if task.changeSci > 0: etc = float(researchSci - task.currSci) / max( task.changeSci, player.effSciPoints) totalSci += researchSci - task.currSci if player.effSciPoints > 0: item.tETC = res.formatTime(etc) else: item.tETC = res.getNA() elif task.changeSci < 0: etc = -float(task.currSci) / min(task.changeSci, player.effSciPoints) item.tETC = _("[%s]") % res.formatTime(etc) elif player.effSciPoints > 0: etc = float(researchSci) / player.effSciPoints totalSci += researchSci item.tETC = res.formatTime(etc) else: item.tETC = res.getNA() if task.improveToMax: for impr in range(task.improvement + 1, fulltech.maxImprovement + 1): totalSci += Utils.getTechRCost(player, task.techID, impr) item.tLevel = _("%d-%d") % (tech.level, task.improvement) return item, totalSci
def research_manager(self, weighted_techs): """ weighted_techs is dictionary, with weight:list_of_techs pairs """ if len(self.player.rsrchQueue) >= 2: return researchable = self._get_researchable() weights = [] tech_choices = [] for weight, techs in weighted_techs.iteritems(): for tech in researchable.intersection(techs): weights.append(weight) tech_choices.append(tech) if sum(weights): tech = Utils.weightedRandom(tech_choices, weights) self.player.rsrchQueue = self.client.cmdProxy.startResearch(self.player.oid, tech)
def research_manager(self, weighted_techs): """ weighted_techs is dictionary, with weight:list_of_techs pairs """ if len(self.player.rsrchQueue) >= 2: return researchable = self._get_researchable() weights = [] tech_choices = [] for weight, techs in weighted_techs.iteritems(): for tech in researchable.intersection(techs): weights.append(weight) tech_choices.append(tech) if sum(weights): tech = Utils.weightedRandom(tech_choices, weights) self.player.rsrchQueue = self.client.cmdProxy.startResearch( self.player.oid, tech)
def _attack_manager(self): for fleet_id in self._get_attack_fleets(): fleet = self.db[fleet_id] # send the attack fleet, if in range sheet = tool.getFleetSheet(fleet) sowers = sheet[4] swarmers = min(sheet[1], math.ceil(sowers * 1.5)) max_range = 0.8 * tool.subfleetMarange(self.client, self.db, {1:swarmers, 4:sowers}, fleet_id) # four nearest systems are considered, with probability to be chosen based on order nearest = tool.findNearest(self.db, fleet, self.data.enemySystems, max_range, 4) if len(nearest): # range is adjusted to flatten probabilities a bit probability_map = map(lambda x: x ** 2, range(2 + len(nearest), 2, -1)) target = Utils.weightedRandom(nearest, probability_map) fleet, new_fleet, my_fleets = tool.orderPartFleet(self.client, self.db, {1:swarmers, 4:sowers}, True, fleet_id, Const.FLACTION_MOVE, target, None)
def _processImprovableTech(self, tech, scheduledIDs): player = client.getPlayer() item = ui.Item(tech.name, techID=tech.id, tLevel='%d-%d' % (tech.level, player.techs[tech.id]), tStruct=(' ', '*')[tech.isStructure], tShip=(' ', '*')[tech.isShipEquip]) neededSci = Utils.getTechRCost(player, tech.id) item.tETC = res.formatTime( float(neededSci) / player.effSciPoints) if player.effSciPoints > 0 else _("N/A") item.foreground = (0xd0, 0xd0, 0xd0) if tech.id in scheduledIDs else None item.foreground = ( 0x80, 0x40, 0x40) if tech.id in player.obsoleteTechs else item.foreground return item
def _processResearchableTech(self, tech): player = client.getPlayer() item = ui.Item(tech.name, tLevel=tech.level, techID=tech.id) item.tStruct = '*' if getattr(tech, 'isStructure', None) else '' item.tShip = '*' if getattr(tech, 'isShipEquip', None) else '' neededSci = Utils.getTechRCost(player, tech.id) item.tETC = res.formatTime( float(neededSci) / player.effSciPoints) if player.effSciPoints > 0 else _("N/A") item.foreground = None if client.getFullTechInfo( tech.id ).finishResearchHandler == TechHandlers.finishResTLAdvance: item.foreground = gdata.sevColors[gdata.CRI] elif getattr(tech, "researchDisables", None): item.foreground = (0xff, 0xff, 0x00) return item
def _get_attack_fleets(self): attack_fleets = set() for fleet_id in copy.copy(self.data.myFleets): fleet = self.db.get(fleet_id, None) # minimal size of attack fleet is determined by size of originating system - larger # more developed systems will stage stronger attack fleets try: system = self.db[fleet.orbiting] except KeyError: # this fleet is not on orbit, set legacy value minimum = 12 else: minimum = self._system_worthiness(system, [8,5,3,2]) + 10 if getattr(fleet, 'target', Const.OID_NONE) == Const.OID_NONE and getattr(fleet, 'ships', []): # this also covers fleets fighting over enemy systems - in that case, there # is slight chance the fleet will continue to the next system without conquering # the system first if fleet.orbiting in self.data.enemySystems and Utils.weightedRandom([True, False], [9,1]): continue if tool.fleetContains(fleet, {1:minimum, 4:minimum}): attack_fleets.add(fleet_id) return attack_fleets
def show(self): critical = self.win.vCritical.checked major = self.win.vMajor.checked minor = self.win.vMinor.checked info = self.win.vInfo.checked disp = 1 player = client.getPlayer() items = [] # object list (all player's objects + systems) objects = player.fleets[:] objects += player.planets[:] systems = {} for planetID in player.planets: planet = client.get(planetID) if planet.compOf not in systems: systems[planet.compOf] = None objects += systems.keys() # counting construction points value of each global production queue # holder for (number , eff production) of planets set to each queue globalQueueStats=[(0,0), (0,0), (0,0), (0,0), (0,0)] prodQueueProblems = [] # go through all objects for objID in objects: if objID < OID_FREESTART: continue obj = client.get(objID, noUpdate = 1) if not hasattr(obj, "type"): continue if obj.type == T_SYSTEM: if not hasattr(obj, 'planets'): continue bio = 0 totalBio = 0 en = 0 totalEn = 0 buildingQuantity = {} buildingInfo = {} # holds modified planets planetCopies = {} for planetID in obj.planets: planet = client.get(planetID, noUpdate = 1) # copy of planet to change plSlots count if not planetID in planetCopies: cPlanet = copy.deepcopy(planet) planetCopies[planetID] = cPlanet else: cPlanet = planetCopies[planetID] if hasattr(planet, 'owner') and planet.owner == player.oid: queuePlanetNumber, queueEffProd = globalQueueStats[planet.globalQueue] queuePlanetNumber += 1 queueEffProd += planet.effProdProd globalQueueStats[planet.globalQueue] = (queuePlanetNumber, queueEffProd) # compute bio and en for system bio += planet.changeBio totalBio += max(0, planet.storBio - planet.minBio) en += planet.changeEn totalEn += max(0, planet.storEn - planet.minEn) # the planet needs to have global queue 0 - the default one - to have its queue reported if hasattr(planet, 'prodQueue') and self.win.vPlanets.checked and not planet.globalQueue: totalEtc = 0 # compute length of production queue if cPlanet.prodQueue and cPlanet.effProdProd > 0: for task in cPlanet.prodQueue: if task.isShip: tech = client.getPlayer().shipDesigns[task.techID] else: tech = client.getFullTechInfo(task.techID) if tech.isStructure and hasattr(task, "demolishStruct") and task.demolishStruct == 0: # total count of constructing buildings on target if buildingQuantity.has_key(task.targetID): buildingQuantity[task.targetID] += task.quantity else: buildingQuantity[task.targetID] = task.quantity # information about source and target of constructing if buildingInfo.has_key((planetID, task.targetID)): buildingInfo[(planetID, task.targetID)] += task.quantity else: buildingInfo[(planetID, task.targetID)] = task.quantity elif tech.isProject and tech.id == 3802: # we are constructing Habitable Surface Expansion # so after construction we got some new slots on planet if not task.targetID in planetCopies: targetPlanet = client.get(task.targetID, noUpdate = 1) cPlanet = copy.deepcopy(targetPlanet) planetCopies[task.targetID] = cPlanet planetCopies[task.targetID].plSlots += task.quantity if task.targetID != planetID: totalEtc += math.ceil(float(tech.buildProd * Rules.buildOnAnotherPlanetMod - task.currProd) / planet.effProdProd) totalEtc += math.ceil((task.quantity - 1) * float(tech.buildProd * Rules.buildOnAnotherPlanetMod) / planet.effProdProd) else: totalEtc += math.ceil(task.quantity * float(tech.buildProd - task.currProd) / planet.effProdProd) totalEtc += math.ceil((task.quantity - 1) * float(tech.buildProd) / planet.effProdProd) else: totalEtc = 99999 prodQueueProblems.append((planetID, totalEtc, len(planet.prodQueue))) # check for structures status if hasattr(planet, 'slots') and self.win.vPlanets.checked: for struct in planet.slots: status = struct[STRUCT_IDX_STATUS] problem = None tech = client.getFullTechInfo(struct[STRUCT_IDX_TECHID]) if hasattr(player, 'techs'): techEff = Rules.techImprEff[player.techs.get(struct[STRUCT_IDX_TECHID], Rules.techBaseImprovement)] else: techEff = Rules.techImprEff[Rules.techBaseImprovement] HPturn = max(1, int(0.02 * tech.maxHP * techEff)) turnsToDestroy = math.ceil(struct[STRUCT_IDX_HP] / HPturn) if turnsToDestroy < 48: dispDestr = major fgColorDestr = gdata.sevColors[gdata.MAJ] if turnsToDestroy < 24: dispDestr = critical fgColorDestr = gdata.sevColors[gdata.CRI] else: dispDestr = minor fgColorDestr = None if not status & STRUCT_STATUS_ON: # structure is off if dispDestr: items.append(ui.Item(planet.name, tOID = planetID, tType = T_PLANET, foreground = fgColorDestr, vDescription = _('Structure (%s) is off and will be destroyed in %s turns.') % (tech.name, res.formatTime(turnsToDestroy)))) elif status & STRUCT_STATUS_DETER: problem = _('is deteriorating and will be destroyed in %s turns') % res.formatTime(turnsToDestroy) disp = major fgColor = gdata.sevColors[gdata.MAJ] elif status & STRUCT_STATUS_NOBIO: problem = _('has insufficient supply of biomatter') disp = info fgColor = gdata.sevColors[gdata.INFO] elif status & STRUCT_STATUS_NOEN: problem = _('has insufficient supply of energy') disp = info fgColor = gdata.sevColors[gdata.INFO] elif status & STRUCT_STATUS_NOPOP: problem = _('has insufficient supply of workers') disp = info fgColor = gdata.sevColors[gdata.INFO] elif status & STRUCT_STATUS_REPAIRING: problem = _('is repairing') disp = info fgColor = gdata.sevColors[gdata.INFO] if problem and disp: items.append(ui.Item(planet.name, tOID = planetID, tType = T_PLANET, foreground = fgColor, vDescription = _('Structure (%s) %s.') % (tech.name, problem))) for planetID, quantity in buildingQuantity.items(): planet = planetCopies[planetID] # test, if there is total quantity of building as target for this planet if planet.plSlots < len(planet.slots) + quantity and major: # walk infos and search for all planets, that are building # on planet founded above for (sourceID, targetID), quantity in buildingInfo.items(): if planetID == targetID: source = client.get(sourceID, noUpdate = 1) items.append(ui.Item(source.name, tOID = sourceID, tType = T_PLANET, foreground = gdata.sevColors[gdata.MAJ], vDescription = _('There is no space for all constructed buildings on %s.') % (planet.name))) # check bio for system if bio < 0 and self.win.vSystems.checked: disp = minor fgColor = None surplusTurns = totalBio / (-bio) if surplusTurns < 168: disp = major fgColor = gdata.sevColors[gdata.MAJ] if surplusTurns < 48: disp = critical fgColor = gdata.sevColors[gdata.CRI] if disp: if totalBio > 0: items.append(ui.Item(obj.name, tOID = obj.oid, tType = T_SYSTEM, foreground = fgColor, vDescription = _('Bio decreasing - last turn change %d, surplus %d (%s).') % (bio, totalBio,res.formatTime(surplusTurns)))) else: items.append(ui.Item(obj.name, tOID = obj.oid, tType = T_SYSTEM, foreground = fgColor, vDescription = _('Bio decreasing - last turn change %d, surplus %d.') % (bio, totalBio))) #check en for system if en < 0 and self.win.vSystems.checked: disp = minor fgColor = None surplusTurns = totalEn / (-en) if surplusTurns < 168: disp = major fgColor = gdata.sevColors[gdata.MAJ] if surplusTurns < 48: disp = critical fgColor = gdata.sevColors[gdata.CRI] if disp: if totalEn > 0: items.append(ui.Item(obj.name, tOID = obj.oid, tType = T_SYSTEM, foreground = fgColor, vDescription = _('Energy decreasing - last turn change %d, surplus %d (%s).') % (en, totalEn,res.formatTime(surplusTurns)))) else: items.append(ui.Item(obj.name, tOID = obj.oid, tType = T_SYSTEM, foreground = fgColor, vDescription = _('Energy decreasing - last turn change %d, surplus %d.') % (en, totalEn))) # check fleets elif obj.type == T_FLEET and self.win.vFleets.checked: if hasattr(obj, 'owner') and obj.owner == player.oid: energyReserve = obj.storEn * 100 / obj.maxEn system = None disp = major fgColor = gdata.sevColors[gdata.MAJ] note = _(' and IS NOT refueling') maxRefuelMax = 0 if hasattr(obj, 'orbiting') and obj.orbiting: system = client.get(obj.orbiting, noUpdate = 1) if hasattr(system, 'planets'): for planetID in system.planets: planet = client.get(planetID, noUpdate = 1) if hasattr(planet, 'owner') and hasattr(planet, 'refuelMax'): if player.diplomacyRels.has_key(planet.owner): dipl = client.getDiplomacyWith(planet.owner) if dipl.pacts.has_key(PACT_ALLOW_TANKING) and dipl.pacts[PACT_ALLOW_TANKING][0] == PACT_ACTIVE: maxRefuelMax = max(maxRefuelMax, planet.refuelMax) else: if planet.owner == player.oid: maxRefuelMax = max(maxRefuelMax, planet.refuelMax) if maxRefuelMax > 0: disp = info fgColor = gdata.sevColors[gdata.INFO] note = _(' and IS refueling') if maxRefuelMax <= energyReserve: note = _(' and CAN refuel, but reach planet maximum refuel amount') else: continue systemName = res.getUnknownName() if system and hasattr(system, "name"): systemName = system.name # check fleets energy reserve if energyReserve < 50 and maxRefuelMax == 0: disp = major fgColor = gdata.sevColors[gdata.MAJ] if energyReserve < 25 and maxRefuelMax == 0: disp = critical fgColor = gdata.sevColors[gdata.CRI] else: fgColor = gdata.sevColors[gdata.INFO] disp = info # is fleet named? if hasattr(obj,'customname') and obj.customname: name = obj.customname else: name = getattr(obj, "name", None) if energyReserve == 100 and info and disp: items.append(ui.Item(systemName, tOID = obj.oid, tType = T_FLEET,foreground = gdata.sevColors[gdata.INFO], vDescription = _('Fleet "%s" has full fuel tanks.') % (name))) elif disp: items.append(ui.Item(systemName, tOID = obj.oid, tType = T_FLEET,foreground = fgColor, vDescription = _('Fleet "%s" is low on fuel [%d %%]%s.') % (name, energyReserve, note))) queConstValues = [0, 0, 0, 0, 0] queEtc = [0, 0, 0, 0, 0] for queue in xrange(5): quePlanets, queEffProd = globalQueueStats[queue] for task in player.prodQueues[queue]: if task.isShip: tech = client.getPlayer().shipDesigns[task.techID] else: tech = client.getFullTechInfo(task.techID) queConstValues[queue] += task.quantity * tech.buildProd if queEffProd > 0: queEtc[queue] = math.ceil(float(queConstValues[queue])/queEffProd) else: queEtc[queue] = 99999 # creation of items with production queue [default one] problems for planetID, totalEtc, queueLen in prodQueueProblems: planet = client.get(planetID, noUpdate = 1) # check empty production queue if queueLen == 0 and planet.effProdProd > 0 and queConstValues[0] == 0 and critical: items.append(ui.Item(planet.name, tOID = planetID, tType = T_PLANET, foreground = gdata.sevColors[gdata.CRI], vDescription = _('Production queue is empty.'))) # check end of production queue if totalEtc+queEtc[0] < 48: fgColor = None disp = minor if totalEtc+queEtc[0] < 24: disp = major fgColor = gdata.sevColors[gdata.MAJ] if disp: items.append(ui.Item(planet.name, tOID = planetID, tType = T_PLANET, foreground = fgColor, vDescription = _('Production queue may end in {0} turns ({1} directly in planet queue), {2} item(s) on list.'.format(res.formatTime(totalEtc+queEtc[0]), res.formatTime(totalEtc), queueLen)))) # creation of items with global queue problems for queue in xrange(1, 5): queName = res.globalQueueName(queue) quePlanets = globalQueueStats[queue][0] # check empty global production queue with at least one planet [so its relevant] if queConstValues[queue] == 0 and quePlanets > 0 and critical: items.append(ui.Item(_('Global queue ' + queName), tType = T_QUEUE, foreground = gdata.sevColors[gdata.CRI], vDescription = _('Global production queue {0} used by {1} planet(s) is empty.'.format(queName, quePlanets)))) # check end of global production queue elif queEtc[queue] < 48: fgColor = None disp = minor if queEtc[queue] < 24: disp = major fgColor = gdata.sevColors[gdata.MAJ] if disp: items.append(ui.Item(_('Global queue ' + queName), tType = T_QUEUE, foreground = fgColor, vDescription = _('Global production queue {0} used by {1} planet(s) runs out in {2} turns.'.format(queName, quePlanets, res.formatTime(queEtc[queue]))))) # check research queue if self.win.vResearch.checked: totalEtc = 0 # compute length of research queue for task in player.rsrchQueue: tech = client.getTechInfo(task.techID) fulltech = client.getFullTechInfo(task.techID) researchSci = Utils.getTechRCost(player, task.techID, task.improvement) maxImprovement = min(Rules.techMaxImprovement,fulltech.maxImprovement) maxImpTotalSci = 0 if task.improveToMax and task.improvement < maxImprovement: for impr in range(task.improvement+1,maxImprovement+1): maxImpTotalSci += Utils.getTechRCost(player, task.techID, impr) if task.changeSci > 0: value = float(researchSci - task.currSci) / max(task.changeSci, player.effSciPoints) totalEtc += int(value + 1) if player.effSciPoints != 0: totalEtc += float(maxImpTotalSci) / player.effSciPoints elif task.changeSci < 0: totalEtc -= float(task.currSci) / min(task.changeSci, player.effSciPoints) elif player.effSciPoints > 0: value = float(researchSci) / player.effSciPoints totalEtc += int(value + 1) totalEtc += float(maxImpTotalSci) / player.effSciPoints else: totalEtc = 99999 break # check empty research queue if totalEtc == 0 and len(player.rsrchQueue) == 0 and player.effSciPoints > 0 and major: items.append(ui.Item(_('Research'), tType = T_TECHNOLOGY, foreground = gdata.sevColors[gdata.MAJ], vDescription = _('Research queue is empty.'))) # check short reseach queue elif totalEtc < 48: disp = minor fgColor = None if totalEtc < 24: disp = major fgColor = gdata.sevColors[gdata.MAJ] if disp: items.append(ui.Item(_('Research'), tType = T_TECHNOLOGY, foreground = fgColor, vDescription = _('Research queue ends in %s turns, %d item(s) on list.') % (res.formatTime(totalEtc), len(player.rsrchQueue)))) self.win.vProblems.items = items self.win.vProblems.itemsChanged()
def show(self): critical = self.win.vCritical.checked major = self.win.vMajor.checked minor = self.win.vMinor.checked info = self.win.vInfo.checked disp = 1 player = client.getPlayer() items = [] # object list (all player's objects + systems) objects = player.fleets[:] objects += player.planets[:] systems = {} for planetID in player.planets: planet = client.get(planetID) if planet.compOf not in systems: systems[planet.compOf] = None objects += systems.keys() # counting construction points value of each global production queue # holder for (number , eff production) of planets set to each queue globalQueueStats = [(0, 0), (0, 0), (0, 0), (0, 0), (0, 0)] prodQueueProblems = [] # go through all objects for objID in objects: if objID < Const.OID_FREESTART: continue obj = client.get(objID, noUpdate=1) if not hasattr(obj, "type"): continue if obj.type == Const.T_SYSTEM: if not hasattr(obj, 'planets'): continue bio = 0 totalBio = 0 en = 0 totalEn = 0 buildingQuantity = {} buildingInfo = {} # holds modified planets planetCopies = {} for planetID in obj.planets: planet = client.get(planetID, noUpdate=1) # copy of planet to change plSlots count if not planetID in planetCopies: cPlanet = copy.deepcopy(planet) planetCopies[planetID] = cPlanet else: cPlanet = planetCopies[planetID] if hasattr(planet, 'owner') and planet.owner == player.oid: queuePlanetNumber, queueEffProd = globalQueueStats[ planet.globalQueue] queuePlanetNumber += 1 queueEffProd += planet.effProdProd globalQueueStats[planet.globalQueue] = ( queuePlanetNumber, queueEffProd) # compute bio and en for system bio += planet.changeBio totalBio += max(0, planet.storBio - planet.minBio) en += planet.changeEn totalEn += max(0, planet.storEn - planet.minEn) # the planet needs to have global queue 0 - the default one - to have its queue reported if hasattr( planet, 'prodQueue' ) and self.win.vPlanets.checked and not planet.globalQueue: totalEtc = 0 # compute length of production queue if cPlanet.prodQueue and cPlanet.effProdProd > 0: for task in cPlanet.prodQueue: if task.isShip: tech = client.getPlayer().shipDesigns[ task.techID] else: tech = client.getFullTechInfo( task.techID) if tech.isStructure and hasattr( task, "demolishStruct" ) and task.demolishStruct == 0: # total count of constructing buildings on target if buildingQuantity.has_key( task.targetID): buildingQuantity[ task. targetID] += task.quantity else: buildingQuantity[ task. targetID] = task.quantity # information about source and target of constructing if buildingInfo.has_key( (planetID, task.targetID)): buildingInfo[( planetID, task.targetID )] += task.quantity else: buildingInfo[( planetID, task.targetID )] = task.quantity elif tech.isProject and tech.id == 3802: # we are constructing Habitable Surface Expansion # so after construction we got some new slots on planet if not task.targetID in planetCopies: targetPlanet = client.get( task.targetID, noUpdate=1) cPlanet = copy.deepcopy( targetPlanet) planetCopies[ task.targetID] = cPlanet planetCopies[ task. targetID].plSlots += task.quantity if task.targetID != planetID: totalEtc += math.ceil( float(tech.buildProd * Rules.buildOnAnotherPlanetMod - task.currProd) / planet.effProdProd) totalEtc += math.ceil( (task.quantity - 1) * float( tech.buildProd * Rules.buildOnAnotherPlanetMod) / planet.effProdProd) else: totalEtc += math.ceil( task.quantity * float(tech.buildProd - task.currProd) / planet.effProdProd) totalEtc += math.ceil( (task.quantity - 1) * float(tech.buildProd) / planet.effProdProd) else: totalEtc = 99999 prodQueueProblems.append( (planetID, totalEtc, len(planet.prodQueue))) # check for structures status if hasattr(planet, 'slots') and self.win.vPlanets.checked: for struct in planet.slots: status = struct[Const.STRUCT_IDX_STATUS] problem = None tech = client.getFullTechInfo( struct[Const.STRUCT_IDX_TECHID]) if hasattr(player, 'techs'): techEff = Rules.techImprEff[ player.techs.get( struct[Const.STRUCT_IDX_TECHID], Rules.techBaseImprovement)] else: techEff = Rules.techImprEff[ Rules.techBaseImprovement] HPturn = max(1, int(0.02 * tech.maxHP * techEff)) turnsToDestroy = math.ceil( struct[Const.STRUCT_IDX_HP] / HPturn) if turnsToDestroy < 48: dispDestr = major fgColorDestr = gdata.sevColors[gdata.MAJ] if turnsToDestroy < 24: dispDestr = critical fgColorDestr = gdata.sevColors[ gdata.CRI] else: dispDestr = minor fgColorDestr = None if not status & Const.STRUCT_STATUS_ON: # structure is off if dispDestr: items.append( ui.Item( planet.name, tOID=planetID, tType=Const.T_PLANET, foreground=fgColorDestr, vDescription= _('Structure (%s) is off and will be destroyed in %s turns.' ) % (tech.name, res.formatTime(turnsToDestroy) ))) elif status & Const.STRUCT_STATUS_DETER: problem = _('is deteriorating') disp = major fgColor = gdata.sevColors[gdata.MAJ] elif status & Const.STRUCT_STATUS_NOBIO: problem = _( 'has insufficient supply of biomatter') disp = info fgColor = gdata.sevColors[gdata.INFO] elif status & Const.STRUCT_STATUS_NOEN: problem = _( 'has insufficient supply of energy') disp = info fgColor = gdata.sevColors[gdata.INFO] elif status & Const.STRUCT_STATUS_NOPOP: problem = _( 'has insufficient supply of workers') disp = info fgColor = gdata.sevColors[gdata.INFO] elif status & Const.STRUCT_STATUS_REPAIRING: problem = _('is repairing') disp = info fgColor = gdata.sevColors[gdata.INFO] if problem and disp: items.append( ui.Item(planet.name, tOID=planetID, tType=Const.T_PLANET, foreground=fgColor, vDescription=_( 'Structure (%s) %s.') % (tech.name, problem))) for planetID, quantity in buildingQuantity.items(): planet = planetCopies[planetID] # test, if there is total quantity of building as target for this planet if planet.plSlots < len(planet.slots) + quantity and major: # walk infos and search for all planets, that are building # on planet founded above for (sourceID, targetID), quantity in buildingInfo.items(): if planetID == targetID: source = client.get(sourceID, noUpdate=1) items.append( ui.Item( source.name, tOID=sourceID, tType=Const.T_PLANET, foreground=gdata.sevColors[gdata.MAJ], vDescription= _('There is no space for all constructed buildings on %s.' ) % (planet.name))) # check bio for system if bio < 0 and self.win.vSystems.checked: disp = minor fgColor = None surplusTurns = totalBio / (-bio) if surplusTurns < 168: disp = major fgColor = gdata.sevColors[gdata.MAJ] if surplusTurns < 48: disp = critical fgColor = gdata.sevColors[gdata.CRI] if disp: if totalBio > 0: items.append( ui.Item( obj.name, tOID=obj.oid, tType=Const.T_SYSTEM, foreground=fgColor, vDescription= _('Bio decreasing - last turn change %d, surplus %d (%s).' ) % (bio, totalBio, res.formatTime(surplusTurns)))) else: items.append( ui.Item( obj.name, tOID=obj.oid, tType=Const.T_SYSTEM, foreground=fgColor, vDescription= _('Bio decreasing - last turn change %d, surplus %d.' ) % (bio, totalBio))) #check en for system if en < 0 and self.win.vSystems.checked: disp = minor fgColor = None surplusTurns = totalEn / (-en) if surplusTurns < 168: disp = major fgColor = gdata.sevColors[gdata.MAJ] if surplusTurns < 48: disp = critical fgColor = gdata.sevColors[gdata.CRI] if disp: if totalEn > 0: items.append( ui.Item( obj.name, tOID=obj.oid, tType=Const.T_SYSTEM, foreground=fgColor, vDescription= _('Energy decreasing - last turn change %d, surplus %d (%s).' ) % (en, totalEn, res.formatTime(surplusTurns)))) else: items.append( ui.Item( obj.name, tOID=obj.oid, tType=Const.T_SYSTEM, foreground=fgColor, vDescription= _('Energy decreasing - last turn change %d, surplus %d.' ) % (en, totalEn))) # check fleets elif obj.type == Const.T_FLEET and self.win.vFleets.checked: if hasattr(obj, 'owner') and obj.owner == player.oid: energyReserve = obj.storEn * 100 / obj.maxEn system = None disp = major fgColor = gdata.sevColors[gdata.MAJ] note = _(' and IS NOT refueling') maxRefuelMax = 0 if hasattr(obj, 'orbiting') and obj.orbiting: system = client.get(obj.orbiting, noUpdate=1) if hasattr(system, 'planets'): for planetID in system.planets: planet = client.get(planetID, noUpdate=1) if hasattr(planet, 'owner') and hasattr( planet, 'refuelMax'): if player.diplomacyRels.has_key( planet.owner): dipl = client.getDiplomacyWith( planet.owner) if dipl.pacts.has_key( Const.PACT_ALLOW_TANKING ) and dipl.pacts[ Const.PACT_ALLOW_TANKING][ 0] == Const.PACT_ACTIVE: maxRefuelMax = max( maxRefuelMax, planet.refuelMax) else: if planet.owner == player.oid: maxRefuelMax = max( maxRefuelMax, planet.refuelMax) if maxRefuelMax > 0: disp = info fgColor = gdata.sevColors[gdata.INFO] note = _(' and IS refueling') if maxRefuelMax <= energyReserve: note = _( ' and CAN refuel, but reach planet maximum refuel amount' ) else: continue systemName = res.getUnknownName() if system and hasattr(system, "name"): systemName = system.name # check fleets energy reserve if energyReserve < 50 and maxRefuelMax == 0: disp = major fgColor = gdata.sevColors[gdata.MAJ] if energyReserve < 25 and maxRefuelMax == 0: disp = critical fgColor = gdata.sevColors[gdata.CRI] else: fgColor = gdata.sevColors[gdata.INFO] disp = info # is fleet named? if hasattr(obj, 'customname') and obj.customname: name = obj.customname else: name = getattr(obj, "name", None) if energyReserve == 100 and info and disp: items.append( ui.Item(systemName, tOID=obj.oid, tType=Const.T_FLEET, foreground=gdata.sevColors[gdata.INFO], vDescription=_( 'Fleet "%s" has full fuel tanks.') % (name))) elif disp: items.append( ui.Item( systemName, tOID=obj.oid, tType=Const.T_FLEET, foreground=fgColor, vDescription=_( 'Fleet "%s" is low on fuel [%d %%]%s.') % (name, energyReserve, note))) queConstValues = [0, 0, 0, 0, 0] queEtc = [0, 0, 0, 0, 0] for queue in xrange(5): quePlanets, queEffProd = globalQueueStats[queue] for task in player.prodQueues[queue]: if task.isShip: tech = client.getPlayer().shipDesigns[task.techID] else: tech = client.getFullTechInfo(task.techID) queConstValues[queue] += task.quantity * tech.buildProd if queEffProd > 0: queEtc[queue] = math.ceil( float(queConstValues[queue]) / queEffProd) else: queEtc[queue] = 99999 # creation of items with production queue [default one] problems for planetID, totalEtc, queueLen in prodQueueProblems: planet = client.get(planetID, noUpdate=1) # check empty production queue if queueLen == 0 and planet.effProdProd > 0 and queConstValues[ 0] == 0 and critical: items.append( ui.Item(planet.name, tOID=planetID, tType=Const.T_PLANET, foreground=gdata.sevColors[gdata.CRI], vDescription=_('Production queue is empty.'))) # check end of production queue if totalEtc + queEtc[0] < 48: fgColor = None disp = minor if totalEtc + queEtc[0] < 24: disp = major fgColor = gdata.sevColors[gdata.MAJ] if disp: items.append( ui.Item( planet.name, tOID=planetID, tType=Const.T_PLANET, foreground=fgColor, vDescription=_( 'Production queue may end in {0} turns ({1} directly in planet queue), {2} item(s) on list.' .format( res.formatTime(totalEtc + queEtc[0]), res.formatTime(totalEtc), queueLen)))) # creation of items with global queue problems for queue in xrange(1, 5): queName = res.globalQueueName(queue) quePlanets = globalQueueStats[queue][0] # check empty global production queue with at least one planet [so its relevant] if queConstValues[queue] == 0 and quePlanets > 0 and critical: items.append( ui.Item( _('Global queue ' + queName), tType=Const.T_QUEUE, foreground=gdata.sevColors[gdata.CRI], vDescription=_( 'Global production queue {0} used by {1} planet(s) is empty.' .format(queName, quePlanets)))) # check end of global production queue elif queEtc[queue] < 48: fgColor = None disp = minor if queEtc[queue] < 24: disp = major fgColor = gdata.sevColors[gdata.MAJ] if disp: items.append( ui.Item( _('Global queue ' + queName), tType=Const.T_QUEUE, foreground=fgColor, vDescription=_( 'Global production queue {0} used by {1} planet(s) runs out in {2} turns.' .format(queName, quePlanets, res.formatTime(queEtc[queue]))))) # check research queue if self.win.vResearch.checked: totalEtc = 0 # compute length of research queue for task in player.rsrchQueue: tech = client.getTechInfo(task.techID) fulltech = client.getFullTechInfo(task.techID) researchSci = Utils.getTechRCost(player, task.techID, task.improvement) maxImprovement = min(Rules.techMaxImprovement, fulltech.maxImprovement) maxImpTotalSci = 0 if task.improveToMax and task.improvement < maxImprovement: for impr in range(task.improvement + 1, maxImprovement + 1): maxImpTotalSci += Utils.getTechRCost( player, task.techID, impr) if task.changeSci > 0: value = float(researchSci - task.currSci) / max( task.changeSci, player.effSciPoints) totalEtc += int(value + 1) if player.effSciPoints != 0: totalEtc += float(maxImpTotalSci) / player.effSciPoints elif task.changeSci < 0: totalEtc -= float(task.currSci) / min( task.changeSci, player.effSciPoints) elif player.effSciPoints > 0: value = float(researchSci) / player.effSciPoints totalEtc += int(value + 1) totalEtc += float(maxImpTotalSci) / player.effSciPoints else: totalEtc = 99999 break # check empty research queue if totalEtc == 0 and len( player.rsrchQueue ) == 0 and player.effSciPoints > 0 and major: items.append( ui.Item(_('Research'), tType=Const.T_TECHNOLOGY, foreground=gdata.sevColors[gdata.MAJ], vDescription=_('Research queue is empty.'))) # check short reseach queue elif totalEtc < 48: disp = minor fgColor = None if totalEtc < 24: disp = major fgColor = gdata.sevColors[gdata.MAJ] if disp: items.append( ui.Item( _('Research'), tType=Const.T_TECHNOLOGY, foreground=fgColor, vDescription= _('Research queue ends in %s turns, %d item(s) on list.' ) % (res.formatTime(totalEtc), len(player.rsrchQueue)))) self.win.vProblems.items = items self.win.vProblems.itemsChanged()
def show(self): player = client.getPlayer() # title self.win.vRQueueTitle.text = _('Research queue [%d pts/turn]') % ( player.effSciPoints, ) self.win.title = _("Research [TL%d]") % player.techLevel # Known techs items = [] #~researchable = {} disabled = [] taskIDs = {} for task in player.rsrchQueue: taskIDs[task.techID] = None for techID in player.techs.keys(): tech = client.getTechInfo(techID) improvement = player.techs[techID] item = ui.Item(tech.name, techID = techID, tLevel = '%d-%d' % (tech.level, improvement), tStruct = (' ', '*')[tech.isStructure], tShip = (' ', '*')[tech.isShipEquip], ) if improvement < Rules.techMaxImprovement and improvement < tech.maxImprovement: neededSci = Utils.getTechRCost(player, techID) if player.effSciPoints > 0: item.tETC = res.formatTime(float(neededSci) / player.effSciPoints) else: item.tETC = _("N/A") found = 0 if taskIDs.has_key(techID): item.foreground = (0xd0, 0xd0, 0xd0) else: item.foreground = None else: item.tETC = res.getNA() item.foreground = (0x80, 0x80, 0x80) if not self.showCompleted: # skip this item continue items.append(item) disabled.extend(tech.researchDisables) #~for improvement in range(1, improvement + 1): #~ for techID in tech.researchEnables[improvement]: #~ researchable[techID] = 1 self.win.vKTechs.items = items self.win.vKTechs.itemsChanged() # Research queue items = [] index = 0 queueTechs = [] total = 0 for task in player.rsrchQueue: tech = client.getTechInfo(task.techID) fulltech = client.getFullTechInfo(task.techID) queueTechs.append(task.techID) item = ui.Item(tech.name, techID = task.techID, index = index) researchSci = Utils.getTechRCost(player, task.techID, task.improvement) maxImprovement = min(Rules.techMaxImprovement,fulltech.maxImprovement) maxImpTotalSci = 0 if task.improveToMax and task.improvement < maxImprovement: for impr in range(task.improvement+1,maxImprovement+1): maxImpTotalSci += Utils.getTechRCost(player, task.techID, impr) item.tooltip = _("Research points %d/%d, change %d pts/turn.") % (task.currSci, researchSci, task.changeSci) item.statustip = item.tooltip item.tImpToMax = ["", "*"][task.improveToMax] item.tImproveToMax = task.improveToMax if task.currSci > 0: item.tProgress = _("%d %%") % int(task.currSci * 100 / researchSci) else: item.tProgress = _("-") if task.changeSci > 0: value = float(researchSci - task.currSci) / max(task.changeSci, player.effSciPoints) total += int(value + 1) if player.effSciPoints > 0: total += float(maxImpTotalSci) / player.effSciPoints item.tETC = res.formatTime(value) else: total = 0 item.tETC = res.getNA() elif task.changeSci < 0: value = - float(task.currSci) / min(task.changeSci, player.effSciPoints) item.tETC = _("[%s]") % res.formatTime(value) elif player.effSciPoints > 0: value = float(researchSci) / player.effSciPoints total += int(value + 1) total += float(maxImpTotalSci) / player.effSciPoints item.tETC = res.formatTime(value) else: item.tETC = res.getNA() item.tLevel = _("%d-%d") % (tech.level, task.improvement) items.append(item) index += 1 self.win.vRQueue.items = items self.win.vRQueue.itemsChanged() self.win.vRQueueTop.enabled = 0 self.win.vRQueueUp.enabled = 0 self.win.vRQueueDown.enabled = 0 self.win.vRQueueAbort.enabled = 0 self.win.vRQueueRepat.enabled = 0 self.win.vRQueueRepat.pressed = 0 self.win.vRQueueInfo.enabled = 0 if total == 0: self.win.vRTotal.text = _("N/A") else: self.win.vRTotal.text = res.formatTime(total) # Researchable techs items = [] for techID in client.getAllTechIDs(): if player.techs.has_key(techID) or techID in queueTechs \ or techID in disabled: continue # can check requirements tech = client.getTechInfo(techID) if not hasattr(tech, "partialData"): continue item = ui.Item(tech.name, tLevel = tech.level, techID = techID) if hasattr(tech, 'isStructure'): item.tStruct = ('', '*')[tech.isStructure] else: item.tStruct = '' if hasattr(tech, 'isShipEquip'): item.tShip = ('', '*')[tech.isShipEquip] else: item.tShip = '' if hasattr(tech, 'researchMod'): neededSci = Utils.getTechRCost(player, techID) if player.effSciPoints > 0: item.tETC = res.formatTime(float(neededSci) / player.effSciPoints) else: item.tETC = _("N/A") item.foreground = None else: item.tSci = res.getNA() item.foreground = (0xc0, 0xc0, 0xc0) # skip this item continue if hasattr(tech, "researchDisables") and tech.researchDisables: item.foreground = (0xff, 0xff, 0x00) if client.getFullTechInfo(techID).finishResearchHandler == TechHandlers.finishResTLAdvance: item.foreground = gdata.sevColors[gdata.CRI] items.append(item) self.win.vRTechs.items = items self.win.vRTechs.itemsChanged()
def buildSystem(data, client, db, systemID, prodPlanets, finalSystemPlan): """ Assigns tasks to all idle planets with CP > 0 in one system, according to object finalSystemPlan. There is NO guaranty it will rebuild it correctly as no math model was made for it. It just try to build most effectively, with keeping system in each step self sufficient. For functioning correctly, it is probably necessary to have some reserves [one planets builds slowly big farm, another knowing it builds factory over only outpost, .. :)] finalSystemPlan - dictionary, keys are planetIDs of players or free planets, and values are dictionaries with keys being techIDs and values being number of those structs. """ system = db[systemID] player = client.getPlayer() structStats = getSystemStructStats(data, client, db, systemID) structsToBuild = {} structsToDemolish = {} difference = {} checkBuildQueues(data, client, db, systemID, prodPlanets) # parse final plan to set buildings which need to be build and those that # may be demolished for planetID in finalSystemPlan: difference[planetID] = Utils.dictSubtraction( finalSystemPlan[planetID], structStats.planets[planetID]) for planetID in difference: structsToBuild[planetID] = {} structsToDemolish[planetID] = {} for techID in difference[planetID]: if difference[planetID][techID] > 0: structsToBuild[planetID][techID] = difference[planetID][techID] elif difference[planetID][techID] < 0: structsToDemolish[planetID][techID] = difference[planetID][ techID] idlePlanets = copy.copy(prodPlanets) for planetID in prodPlanets: planet = db[planetID] if getattr(planet, 'prodQueue', None): # something in the build queue, skip the planet idlePlanets.remove(planetID) continue # start the most effective project [CP-wise], which is still leaving # sustainable system toBuild = getStructBuildEffectivity(client, db, planetID, structsToBuild.keys(), structsToBuild, structsToDemolish) for techID, targetPlanetID, targetTechID in toBuild: targetPlanet = db[targetPlanetID] if len( targetPlanet.slots ) == targetPlanet.plSlots and targetTechID == Const.OID_NONE: continue deltaBio, deltaEn, deltaProd = getSystemStatsChange( client, db, techID, targetPlanetID, targetTechID) if structStats.bio + deltaBio >= 0 and structStats.en + deltaEn >= 0: planet.prodQueue, player.stratRes = client.cmdProxy.startConstruction( planetID, techID, 1, targetPlanetID, techID < 1000, 0, targetTechID) idlePlanets.remove(planetID) # remove this struct from possibility list structsToBuild[targetPlanetID][techID] -= 1 if structsToBuild[targetPlanetID][techID] == 0: del structsToBuild[targetPlanetID][techID] break return idlePlanets
def show(self): tech = client.getTechInfo(self.techID) player = client.getPlayer() techEff = Rules.techImprEff[player.techs.get( self.techID, Rules.techBaseImprovement)] self.win.title = _('Technology: %s (TL%d)') % (tech.name, tech.level) # fill data # fill description descr = [] improvement = player.techs.get(self.techID, 0) if hasattr(tech, 'researchMod'): if improvement == 0: descr.append( _('Research costs: %d') % Utils.getTechRCost(player, self.techID)) descr.append('') elif improvement < Rules.techMaxImprovement: descr.append( _('Improvement costs: %d') % Utils.getTechRCost(player, self.techID)) descr.append('') # requires if tech.researchRequires and improvement == 0: descr.append(_('Research requires:')) for tmpTechID, improvement in tech.researchRequires: tmpTech = client.getTechInfo(tmpTechID) descr.append( _(' - %s improvement %d (TL%d)') % (tmpTech.name, improvement, tmpTech.level)) if hasattr(tech, "researchReqSRes"): for stratRes in tech.researchReqSRes: descr.append( _(" - %s (strategic resource)") % (gdata.stratRes[stratRes])) descr.append('') if hasattr(tech, "researchDisables") and tech.researchDisables: descr.append(_("Research disables:")) for tmpTechID in tech.researchDisables: tmpTech = client.getTechInfo(tmpTechID) descr.append(_(" - %s (TL%d)") % (tmpTech.name, tmpTech.level)) descr.append('') if hasattr(tech, 'partialData') and hasattr(tech, 'textPreRsrch'): # preresearch info descr.append(_('Estimated use:')) descr.extend(tech.textPreRsrch.split('\n')) descr.append('') elif not hasattr(tech, 'partialData'): tmp = [] for improvement in range(1, 6): for tmpTechID in tech.researchEnables[improvement]: tmpTech = client.getTechInfo(tmpTechID) racesDispl = "" raceChoosen = None if player.techLevel == 1: for techID in player.techs.keys(): if techID in (1990, 1991, 1992): raceChoosen = client.getTechInfo(techID).data else: raceChoosen = player.race if len(tmpTech.researchRaces) > 0 and len( tmpTech.researchRaces) < 3 and not raceChoosen: racesDispl = _(", only for %s") % tmpTech.researchRaces if not raceChoosen or len( tmpTech.researchRaces ) == 0 or raceChoosen in tmpTech.researchRaces: tmp.append( _(' - %s (with improvement %d, on TL%d%s)') % (tmpTech.name, improvement, tmpTech.level, racesDispl)) if tmp: descr.append(_('Research/Improvement enables:')) descr.extend(tmp) descr.append('') # production dependency if tech.prodBioMod != [0, 0, 0, 0 ] and tech.prodBioMod != [0, 0, 0, 1]: descr.append(_("Bio production depends:")) if tech.prodBioMod[0]: descr.append( _(" - %d %% on planet's environment") % (tech.prodBioMod[0] * 100)) if tech.prodBioMod[1]: descr.append( _(" - %d %% on planet's min. abundance") % (tech.prodBioMod[1] * 100)) if tech.prodBioMod[2]: descr.append( _(" - %d %% on planet's en. abundance") % (tech.prodBioMod[2] * 100)) if tech.prodBioMod[3]: descr.append( _(" - %d %% is not dependent on any planet's attribute" ) % (tech.prodBioMod[3] * 100)) descr.append("") if tech.prodEnMod != [0, 0, 0, 0 ] and tech.prodEnMod != [0, 0, 0, 1]: descr.append(_("Energy production depends:")) if tech.prodEnMod[0]: descr.append( _(" - %d %% on planet's environment") % (tech.prodEnMod[0] * 100)) if tech.prodEnMod[1]: descr.append( _(" - %d %% on planet's min. abundance") % (tech.prodEnMod[1] * 100)) if tech.prodEnMod[2]: descr.append( _(" - %d %% on planet's en. abundance") % (tech.prodEnMod[2] * 100)) if tech.prodEnMod[3]: descr.append( _(" - %d %% is not dependent on any planet's attribute" ) % (tech.prodEnMod[3] * 100)) descr.append("") if tech.prodProdMod != [0, 0, 0, 0 ] and tech.prodProdMod != [0, 0, 0, 1]: descr.append(_("Constr. points production depends:")) if tech.prodProdMod[0]: descr.append( _(" - %d %% on planet's environment") % (tech.prodProdMod[0] * 100)) if tech.prodProdMod[1]: descr.append( _(" - %d %% on planet's min. abundance") % (tech.prodProdMod[1] * 100)) if tech.prodProdMod[2]: descr.append( _(" - %d %% on planet's en. abundance") % (tech.prodProdMod[2] * 100)) if tech.prodProdMod[3]: descr.append( _(" - %d %% is not dependent on any planet's attribute" ) % (tech.prodProdMod[3] * 100)) descr.append("") if tech.prodSciMod != [0, 0, 0, 0 ] and tech.prodSciMod != [0, 0, 0, 1]: descr.append(_("Research points production depends:")) if tech.prodSciMod[0]: descr.append( _(" - %d %% on planet's environment") % (tech.prodSciMod[0] * 100)) if tech.prodSciMod[1]: descr.append( _(" - %d %% on planet's min. abundance") % (tech.prodSciMod[1] * 100)) if tech.prodSciMod[2]: descr.append( _(" - %d %% on planet's en. abundance") % (tech.prodSciMod[2] * 100)) if tech.prodSciMod[3]: descr.append( _(" - %d %% is not dependent on any planet's attribute" ) % (tech.prodSciMod[3] * 100)) descr.append("") requiredStrategicResourcesForBuilding = self.getStrategicResourcesText( tech, "buildSRes") requiredStrategicResourcesForResearch = self.getStrategicResourcesText( tech, "researchReqSRes") if len(requiredStrategicResourcesForBuilding) > 0 or len( requiredStrategicResourcesForResearch) > 0: descr.append(_("Required strategic resources:")) if len(requiredStrategicResourcesForBuilding) > 0: descr.append( _(" - for building: %s") % requiredStrategicResourcesForBuilding) if len(requiredStrategicResourcesForResearch) > 0: descr.append( _(" - for research: %s") % requiredStrategicResourcesForResearch) descr.append("") # decription descr.append(_('Description:')) if tech.textDescr != u'Not specified': descr.extend(tech.textDescr.split('\n')) else: descr.extend(tech.textPreRsrch.split('\n')) descr.append('') # flavor descr.append(_('Rumours:')) descr.extend(tech.textFlavor.split('\n')) descr.append('') if not len(descr): descr.append(_('No information available')) # self.win.vDescr.text = descr # re-set techType if neccessary self.techType = self.techType & ( getattr(tech, 'isStructure', 0) * V_STRUCT | getattr(tech, 'isShipHull', 0) * V_HULL | getattr(tech, 'isShipEquip', 0) * V_SEQUIP | getattr(tech, 'isProject', 0) * V_PROJECT) if self.techType == V_NONE: if getattr(tech, 'isStructure', 0): self.techType = V_STRUCT elif getattr(tech, 'isShipHull', 0): self.techType = V_HULL elif getattr(tech, 'isShipEquip', 0): self.techType = V_SEQUIP elif getattr(tech, 'isProject', 0): self.techType = V_PROJECT # set type buttons self.win.vStruct.pressed = self.techType == V_STRUCT self.win.vStruct.enabled = getattr(tech, 'isStructure', 0) self.win.vHull.pressed = self.techType == V_HULL self.win.vHull.enabled = getattr(tech, 'isShipHull', 0) self.win.vSEquip.pressed = self.techType == V_SEQUIP self.win.vSEquip.enabled = getattr(tech, 'isShipEquip', 0) self.win.vProject.pressed = self.techType == V_PROJECT self.win.vProject.enabled = getattr(tech, 'isProject', 0) # fill data items = [] for attr in dir(tech): value = getattr(tech, attr) descr, props, showIfDef, default, convertor = techAttrs.get( attr, defaultAttr) if self.techType & props and (value != default or showIfDef): item = ui.Item(descr, tValue=convertor(value)) if V_EFF & props: item.font = 'normal-bold' item.tValue = convertor(value * techEff) if V_EFF_REV & props: item.font = 'normal-bold' item.tValue = convertor(value / techEff) items.append(item) self.win.vData.items = items self.win.vData.itemsChanged()
def show(self): player = client.getPlayer() # title self.win.vRQueueTitle.text = _('Research queue [%d pts/turn]') % ( player.effSciPoints, ) self.win.title = _("Research [TL%d]") % player.techLevel # Known techs items = [] #~researchable = {} disabled = [] taskIDs = {} for task in player.rsrchQueue: taskIDs[task.techID] = None for techID in player.techs.keys(): if techID in player.obsoleteTechs and not self.showObsolete: continue tech = client.getTechInfo(techID) improvement = player.techs[techID] item = ui.Item(tech.name, techID = techID, tLevel = '%d-%d' % (tech.level, improvement), tStruct = (' ', '*')[tech.isStructure], tShip = (' ', '*')[tech.isShipEquip], ) if improvement < Rules.techMaxImprovement and improvement < tech.maxImprovement: neededSci = Utils.getTechRCost(player, techID) if player.effSciPoints > 0: item.tETC = res.formatTime(float(neededSci) / player.effSciPoints) else: item.tETC = _("N/A") found = 0 if taskIDs.has_key(techID): item.foreground = (0xd0, 0xd0, 0xd0) else: item.foreground = None else: item.tETC = res.getNA() item.foreground = (0x80, 0x80, 0x80) if not self.showCompleted: # skip this item continue if techID in player.obsoleteTechs: item.foreground = (0x80, 0x40, 0x40) items.append(item) disabled.extend(tech.researchDisables) #~for improvement in range(1, improvement + 1): #~ for techID in tech.researchEnables[improvement]: #~ researchable[techID] = 1 self.win.vKTechs.items = items self.win.vKTechs.itemsChanged() # Research queue items = [] index = 0 queueTechs = [] total = 0 for task in player.rsrchQueue: tech = client.getTechInfo(task.techID) fulltech = client.getFullTechInfo(task.techID) queueTechs.append(task.techID) item = ui.Item(tech.name, techID = task.techID, index = index) researchSci = Utils.getTechRCost(player, task.techID, task.improvement) maxImprovement = min(Rules.techMaxImprovement,fulltech.maxImprovement) maxImpTotalSci = 0 if task.improveToMax and task.improvement < maxImprovement: for impr in range(task.improvement+1,maxImprovement+1): maxImpTotalSci += Utils.getTechRCost(player, task.techID, impr) item.tooltipTitle = _("Details") item.tooltip = _("Research points %d/%d, change %d pts/turn.") % (task.currSci, researchSci, task.changeSci) item.statustip = item.tooltip item.tImpToMax = ["", "*"][task.improveToMax] item.tImproveToMax = task.improveToMax if task.currSci > 0: item.tProgress = _("%d %%") % int(task.currSci * 100 / researchSci) else: item.tProgress = _("-") if task.changeSci > 0: value = float(researchSci - task.currSci) / max(task.changeSci, player.effSciPoints) total += int(value + 1) if player.effSciPoints > 0: total += float(maxImpTotalSci) / player.effSciPoints item.tETC = res.formatTime(value) else: total = 0 item.tETC = res.getNA() elif task.changeSci < 0: value = - float(task.currSci) / min(task.changeSci, player.effSciPoints) item.tETC = _("[%s]") % res.formatTime(value) elif player.effSciPoints > 0: value = float(researchSci) / player.effSciPoints total += int(value + 1) total += float(maxImpTotalSci) / player.effSciPoints item.tETC = res.formatTime(value) else: item.tETC = res.getNA() item.tLevel = _("%d-%d") % (tech.level, task.improvement) items.append(item) index += 1 self.win.vRQueue.items = items self.win.vRQueue.itemsChanged() self.win.vRQueueTop.enabled = 0 self.win.vRQueueUp.enabled = 0 self.win.vRQueueDown.enabled = 0 self.win.vRQueueAbort.enabled = 0 self.win.vRQueueRepat.enabled = 0 self.win.vRQueueRepat.pressed = 0 self.win.vRQueueInfo.enabled = 0 if total == 0: self.win.vRTotal.text = _("N/A") else: self.win.vRTotal.text = res.formatTime(total) # Researchable techs items = [] for techID in client.getAllTechIDs(): if player.techs.has_key(techID) or techID in queueTechs \ or techID in disabled: continue # can check requirements tech = client.getTechInfo(techID) if not hasattr(tech, "partialData"): continue item = ui.Item(tech.name, tLevel = tech.level, techID = techID) if hasattr(tech, 'isStructure'): item.tStruct = ('', '*')[tech.isStructure] else: item.tStruct = '' if hasattr(tech, 'isShipEquip'): item.tShip = ('', '*')[tech.isShipEquip] else: item.tShip = '' if hasattr(tech, 'researchMod'): neededSci = Utils.getTechRCost(player, techID) if player.effSciPoints > 0: item.tETC = res.formatTime(float(neededSci) / player.effSciPoints) else: item.tETC = _("N/A") item.foreground = None else: item.tSci = res.getNA() item.foreground = (0xc0, 0xc0, 0xc0) # skip this item continue if hasattr(tech, "researchDisables") and tech.researchDisables: item.foreground = (0xff, 0xff, 0x00) if client.getFullTechInfo(techID).finishResearchHandler == TechHandlers.finishResTLAdvance: item.foreground = gdata.sevColors[gdata.CRI] items.append(item) self.win.vRTechs.items = items self.win.vRTechs.itemsChanged()
def show(self): tech = client.getTechInfo(self.techID) player = client.getPlayer() techEff = Rules.techImprEff[player.techs.get(self.techID, Rules.techBaseImprovement)] self.win.title = _('Technology: %s (TL%d)') % (tech.name, tech.level) # fill data # fill description descr = [] improvement = player.techs.get(self.techID, 0) if hasattr(tech, 'researchMod'): if improvement == 0: descr.append(_('Research costs: %d') % Utils.getTechRCost(player, self.techID)) descr.append('') elif improvement < Rules.techMaxImprovement: descr.append(_('Improvement costs: %d') % Utils.getTechRCost(player, self.techID)) descr.append('') # requires if tech.researchRequires and improvement == 0: descr.append(_('Research requires:')) for tmpTechID, improvement in tech.researchRequires: tmpTech = client.getTechInfo(tmpTechID) descr.append(_(' - %s improvement %d (TL%d)') % (tmpTech.name, improvement, tmpTech.level)) if hasattr(tech, "researchReqSRes"): for stratRes in tech.researchReqSRes: descr.append(_(" - %s (strategic resource)") % (gdata.stratRes[stratRes])) descr.append('') if hasattr(tech, "researchDisables") and tech.researchDisables: descr.append(_("Research disables:")) for tmpTechID in tech.researchDisables: tmpTech = client.getTechInfo(tmpTechID) descr.append(_(" - %s (TL%d)") % (tmpTech.name, tmpTech.level)) descr.append('') if hasattr(tech, 'partialData') and hasattr(tech, 'textPreRsrch'): # preresearch info descr.append(_('Estimated use:')) descr.extend(tech.textPreRsrch.split('\n')) descr.append('') elif not hasattr(tech, 'partialData'): tmp = [] for improvement in range(1, 6): for tmpTechID in tech.researchEnables[improvement]: tmpTech = client.getTechInfo(tmpTechID) racesDispl = "" raceChoosen = None if player.techLevel == 1: for techID in player.techs.keys(): if techID in (1990, 1991, 1992): raceChoosen = client.getTechInfo(techID).data else: raceChoosen = player.race if len(tmpTech.researchRaces) > 0 and len(tmpTech.researchRaces) < 3 and not raceChoosen: racesDispl = _(", only for %s") % tmpTech.researchRaces if not raceChoosen or len(tmpTech.researchRaces) == 0 or raceChoosen in tmpTech.researchRaces: tmp.append(_(' - %s (with improvement %d, on TL%d%s)') % (tmpTech.name, improvement, tmpTech.level, racesDispl)) if tmp: descr.append(_('Research/Improvement enables:')) descr.extend(tmp) descr.append('') # production dependency if tech.prodBioMod != [0, 0, 0, 0] and tech.prodBioMod != [0, 0, 0, 1]: descr.append(_("Bio production depends:")) if tech.prodBioMod[0]: descr.append(_(" - %d %% on planet's environment") % (tech.prodBioMod[0] * 100)) if tech.prodBioMod[1]: descr.append(_(" - %d %% on planet's min. abundance") % (tech.prodBioMod[1] * 100)) if tech.prodBioMod[2]: descr.append(_(" - %d %% on planet's en. abundance") % (tech.prodBioMod[2] * 100)) if tech.prodBioMod[3]: descr.append(_(" - %d %% is not dependent on any planet's attribute") % (tech.prodBioMod[3] * 100)) descr.append("") if tech.prodEnMod != [0, 0, 0, 0] and tech.prodEnMod != [0, 0, 0, 1]: descr.append(_("Energy production depends:")) if tech.prodEnMod[0]: descr.append(_(" - %d %% on planet's environment") % (tech.prodEnMod[0] * 100)) if tech.prodEnMod[1]: descr.append(_(" - %d %% on planet's min. abundance") % (tech.prodEnMod[1] * 100)) if tech.prodEnMod[2]: descr.append(_(" - %d %% on planet's en. abundance") % (tech.prodEnMod[2] * 100)) if tech.prodEnMod[3]: descr.append(_(" - %d %% is not dependent on any planet's attribute") % (tech.prodEnMod[3] * 100)) descr.append("") if tech.prodProdMod != [0, 0, 0, 0] and tech.prodProdMod != [0, 0, 0, 1]: descr.append(_("Constr. points production depends:")) if tech.prodProdMod[0]: descr.append(_(" - %d %% on planet's environment") % (tech.prodProdMod[0] * 100)) if tech.prodProdMod[1]: descr.append(_(" - %d %% on planet's min. abundance") % (tech.prodProdMod[1] * 100)) if tech.prodProdMod[2]: descr.append(_(" - %d %% on planet's en. abundance") % (tech.prodProdMod[2] * 100)) if tech.prodProdMod[3]: descr.append(_(" - %d %% is not dependent on any planet's attribute") % (tech.prodProdMod[3] * 100)) descr.append("") if tech.prodSciMod != [0, 0, 0, 0] and tech.prodSciMod != [0, 0, 0, 1]: descr.append(_("Research points production depends:")) if tech.prodSciMod[0]: descr.append(_(" - %d %% on planet's environment") % (tech.prodSciMod[0] * 100)) if tech.prodSciMod[1]: descr.append(_(" - %d %% on planet's min. abundance") % (tech.prodSciMod[1] * 100)) if tech.prodSciMod[2]: descr.append(_(" - %d %% on planet's en. abundance") % (tech.prodSciMod[2] * 100)) if tech.prodSciMod[3]: descr.append(_(" - %d %% is not dependent on any planet's attribute") % (tech.prodSciMod[3] * 100)) descr.append("") requiredStrategicResourcesForBuilding = self.getStrategicResourcesText(tech, "buildSRes") requiredStrategicResourcesForResearch = self.getStrategicResourcesText(tech, "researchReqSRes") if len(requiredStrategicResourcesForBuilding) > 0 or len(requiredStrategicResourcesForResearch) > 0: descr.append(_("Required strategic resources:")) if len(requiredStrategicResourcesForBuilding) > 0: descr.append(_(" - for building: %s") % requiredStrategicResourcesForBuilding) if len(requiredStrategicResourcesForResearch) > 0: descr.append(_(" - for research: %s") % requiredStrategicResourcesForResearch) descr.append("") # decription descr.append(_('Description:')) if tech.textDescr != u'Not specified': descr.extend(tech.textDescr.split('\n')) else: descr.extend(tech.textPreRsrch.split('\n')) descr.append('') # flavor descr.append(_('Rumours:')) descr.extend(tech.textFlavor.split('\n')) descr.append('') if not len(descr): descr.append(_('No information available')) # self.win.vDescr.text = descr # re-set techType if neccessary self.techType = self.techType & ( getattr(tech ,'isStructure', 0) * V_STRUCT | getattr(tech ,'isShipHull', 0) * V_HULL | getattr(tech ,'isShipEquip', 0) * V_SEQUIP | getattr(tech ,'isProject', 0) * V_PROJECT ) if self.techType == V_NONE: if getattr(tech ,'isStructure', 0): self.techType = V_STRUCT elif getattr(tech ,'isShipHull', 0): self.techType = V_HULL elif getattr(tech ,'isShipEquip', 0): self.techType = V_SEQUIP elif getattr(tech ,'isProject', 0): self.techType = V_PROJECT # set type buttons self.win.vStruct.pressed = self.techType == V_STRUCT self.win.vStruct.enabled = getattr(tech ,'isStructure', 0) self.win.vHull.pressed = self.techType == V_HULL self.win.vHull.enabled = getattr(tech, 'isShipHull', 0) self.win.vSEquip.pressed = self.techType == V_SEQUIP self.win.vSEquip.enabled = getattr(tech, 'isShipEquip', 0) self.win.vProject.pressed = self.techType == V_PROJECT self.win.vProject.enabled = getattr(tech, 'isProject', 0) # fill data items = [] for attr in dir(tech): value = getattr(tech, attr) descr, props, showIfDef, default, convertor = techAttrs.get(attr, defaultAttr) if self.techType & props and (value != default or showIfDef): item = ui.Item(descr, tValue = convertor(value)) if V_EFF & props: item.font = 'normal-bold' item.tValue = convertor(value * techEff) if V_EFF_REV & props: item.font = 'normal-bold' item.tValue = convertor(value / techEff) items.append(item) self.win.vData.items = items self.win.vData.itemsChanged()
def _system_manager(self): for planet_id in self.data.myPlanets: tool.sortStructures(self.client, self.db, planet_id) for system_id in self.data.mySystems: system = self.db[system_id] # creation of final system plans system_blueprint = self._create_system_blueprint(system) idle_planets = tool.buildSystem(self.data, self.client, self.db, system_id, self.data.myProdPlanets & set(system.planets), system_blueprint) # rest of the planets build ships # first get all our ships in the system system_fleet = {} for fleet_id in getattr(system, 'fleets', []): fleet = self.db[fleet_id] if getattr(fleet, 'owner', Const.OID_NONE) == self.player.oid: system_fleet = Utils.dictAddition(system_fleet, tool.getFleetSheet(fleet)) hasSeeders = False hasSeekers = False try: if system_fleet[2] >= 2: hasSeeders = True except KeyError: pass try: if system_fleet[3] >= 2: hasSeekers = True except KeyError: pass # this variable will gather how valuable system is in regards of fighter defense # in general, mutant has quite significant planetary defense, so our target is # to have only about 10 % production spend on support fighters_to_defend = self._system_worthiness(system, [15,8,5,3]) for planet_id in idle_planets: planet = self.db[planet_id] shipDraw = random.randint(1, 10) if (not hasSeeders or not hasSeekers) and shipDraw < 9: # there is 20% chance it won't build civilian ships, but military one if not hasSeeders: planet.prodQueue, self.player.stratRes = self.client.cmdProxy.startConstruction(planet_id, 2, 1, planet_id, True, False, Const.OID_NONE) continue elif not hasSeekers: planet.prodQueue, self.player.stratRes = self.client.cmdProxy.startConstruction(planet_id, 3, 1, planet_id, True, False, Const.OID_NONE) continue # rest is creation of ships based on current state + expected guard fighters try: fighters = system_fleet[1] except KeyError: fighters = 0 try: bombers = system_fleet[4] except KeyError: bombers = 0 expected_fighters = bombers * 1.5 + fighters_to_defend weight_fighter = 3 weight_bomber = 2 if expected_fighters > fighters: # we have to build more fighters weight_fighter += 1 elif expected_fighters < fighters: # we have too many fighters - let's prefer bombers for now weight_bomber += 1 choice = Utils.weightedRandom([1,4], [weight_fighter, weight_bomber]) planet.prodQueue, self.player.stratRes = self.client.cmdProxy.startConstruction(planet_id, choice, 2, planet_id, True, False, Const.OID_NONE)