GP Tech Lightbulb Idea

ruff_hi

Live 4ever! Or die trying
Joined
Oct 24, 2005
Messages
9,135
Location
an Aussie in Boston
There are lots of discussions in SGs about which tech a GP will lightbulb. I'm thinking of putting in a screen that shows the current tech that each GP will lightbulb as well as the tech the GP will lightbulb if each of the possible researchable techs are known.

To do this, I need to be able to get the lightbulbable tech for each GP - is there such a function in civ python?
 
If you have a unit object you can call the function getDiscoveryTech(). Now this returns the index of the tech, if you need more info gc.getTechInfo(Unit Object.getDiscoveryTech()).getDescription() will give the tech name (Bronze Working), and gc.getTechInfo(Unit Object.getDiscoveryTech()).getType() will return the tyoe tag (TECH_BRONZE_WORKING).:thumbsup:
 
Great - that should get me the current tech, but I am also looking for the next tech (ie assuming I know the current lightbulbed one) as well as possible techs (assuming I know the techs that I could research). Does that mean I will need to add the tech, work out the getdiscoverytech, take the tech away?
 
Yes. You would have to give the required techs then check and the remove the techs.

That's at least from what I know.
 
lightbulbtechix0.jpg


The above is the sort of screen that I mean. Down the left are the various GPs that you can get. The first column of techs is the techs that each GP will lightbulb based on your current known techs. The techs across the top are the techs that you can research. The techs shown in the body of the table are the techs the GPs will lightbulb if you research the tech at the top of the column.

Example 1: Great Artist. This GP will currently lightbulb physics. If you research physics, he will lightbulb fission.

Example 2: Great Tycoon (that is the name of the art file for the merchant!) This GP will currently lightbulb writing. If you research writing, he will lightbulb liberalism. If you research steam power, he will lightbulb monotheism. If you research monotheism, he will lightbulb corporations.

Example 3: What can I do with this table in a real game? Say I just got a Great Prophet. He will currently lightbulb Hinduism. However, if I research Hinduism myself, he will lightbulb radio. That is an obviously great thing to do.

OR - say I want to lightbulb writing and I have a Great Scientist due in 15 rounds. What tech should I not research so that I can still lightbulb writing? Answer: don't research steam power, physics or monotheism.

Note: This is a mock up and the lightbulb techs as well as the research techs are not as per the tree or the actual tech GP preference. Anyone who gives me grief about the techs being all wrong can go stick their head in a pig.
 
The information you seek is available. CvTechInfo has getFlavorValue(int) which will give you the value for each flavor (science, military, gold, culture, production). These map to the XML <flavor> tags. See this post for the XML details. In this post I wrote up briefly what I wanted to do, similar to your idea.

You'll have to experiment to see what int you pass in to getFlavorValue(int). I can't find a FlavorInfo with defines for FLAVOR_GOLD and such, but there aren't that many.

This would be a very helpful mod indeed!
 
The information you seek is available. CvTechInfo has getFlavorValue(int) which will give you the value for each flavor (science, military, gold, culture, production). These map to the XML <flavor> tags. See this post for the XML details. In this post I wrote up briefly what I wanted to do, similar to your idea.
I don't think I need to do this. I can use the code from above (quoted below) to get which tech the GP will lightbulb.

If you have a unit object you can call the function getDiscoveryTech(). Now this returns the index of the tech, if you need more info gc.getTechInfo(Unit Object.getDiscoveryTech()).getDescription() will give the tech name (Bronze Working), and gc.getTechInfo(Unit Object.getDiscoveryTech()).getType() will return the tyoe tag (TECH_BRONZE_WORKING).:thumbsup:

Once I have this, I think I need to do something like this to fill in the grid ...

Code:
for each great person
   display great person icon # first column
   display lightbulb.tech # second column
next great person

for each possible.research.tech
   display possible.research.tech
   add possible.research.tech to current list of known techs
   for each great person
      display lightbulb.tech # next column
   next great person
   remove possible.research.tech from current list of known techs
next possible.research.tech
 
Are there any snags in adding/removing techs like that? What happens when you do that for a tech that the person has already researched 50%? Do they lose their progress? Is it remembered somewhere?

I suppose creating great people and removing them shouldn't have any consequences, so that part should be doable without problems.

Sounds good! :goodjob:
 
Don't know and don't know. I am not sure if you can add a GP. I know that you can kill off a unit. However, do we need to do that? I am thinking that we can say something like ...

zTech = UnitObject(GREAT_SCIENTIST).getDiscoveryTech()

... which will give us the handle to the tech icon, etc.
 
zTech = UnitObject(GREAT_SCIENTIST).getDiscoveryTech()

Right, but

UnitObject(GREAT_SCIENTIST)

is accomplished by creating a unit for the player, right? I don't think you can just create a unit not on the map. But as I said, there shouldn't be any ramifications to putting a great person onto the map temporarily, so long as it doesn't insist on posting a message to that effect.
 
Here is the code I have so far - its not pretty but it works. I have just stuck it in the keyboard event of the autologger just for testing.

Code:
	def onKbdEvent(self, argsList):
			if (theKey == int(InputTypes.KB_T)
			and self.eventMgr.bAlt):

				for i in range(CyMap().numPlots()):
					tPlot = CyMap().plot(CyMap().plotX(i),CyMap().plotY(i))
					if (tPlot.isCity()
					and tPlot.getOwner() == CyGame().getActivePlayer()):
						pPlot = tPlot
						i = CyMap().numPlots()

				iPlayer = CyGame().getActivePlayer()
				pPlayer = gc.getPlayer(iPlayer)

				zNewUnit = pPlayer.initUnit(gc.getInfoTypeForString('UNIT_ARTIST'), pPlot.getX(), pPlot.getY(), UnitAITypes.NO_UNITAI)
				zNewUnit.setName("BUG-TEMP-NAME")

				zNewUnit = pPlayer.initUnit(gc.getInfoTypeForString('UNIT_MERCHANT'), pPlot.getX(), pPlot.getY(), UnitAITypes.NO_UNITAI)
				zNewUnit.setName("BUG-TEMP-NAME")

				zNewUnit = pPlayer.initUnit(gc.getInfoTypeForString('UNIT_SCIENTIST'), pPlot.getX(), pPlot.getY(), UnitAITypes.NO_UNITAI)
				zNewUnit.setName("BUG-TEMP-NAME")

				zNewUnit = pPlayer.initUnit(gc.getInfoTypeForString('UNIT_ENGINEER'), pPlot.getX(), pPlot.getY(), UnitAITypes.NO_UNITAI)
				zNewUnit.setName("BUG-TEMP-NAME")

				zNewUnit = pPlayer.initUnit(gc.getInfoTypeForString('UNIT_PROPHET'), pPlot.getX(), pPlot.getY(), UnitAITypes.NO_UNITAI)
				zNewUnit.setName("BUG-TEMP-NAME")

				i = 0
				for j in range(pPlot.getNumUnits()):
					pLoopUnit = CyInterface().getInterfacePlotUnit(pPlot, j - i)

					tUnitType = pLoopUnit.getUnitType()
					if (tUnitType == gc.getInfoTypeForString('UNIT_ARTIST')
					or tUnitType == gc.getInfoTypeForString('UNIT_MERCHANT')
					or tUnitType == gc.getInfoTypeForString('UNIT_SCIENTIST')
					or tUnitType == gc.getInfoTypeForString('UNIT_ENGINEER')
					or tUnitType == gc.getInfoTypeForString('UNIT_PROPHET')):
						zTech = pLoopUnit.getDiscoveryTech()					
						zMsg = "TECH: %i" % zTech
						CyInterface().addImmediateMessage(zMsg, "")

					if (pLoopUnit.getNameNoDesc() == "BUG-TEMP-NAME"):
						pLoopUnit.kill(False, pLoopUnit.getOwner())
						i = i + 1
This finds a city owned by the player, creates the great people, gets their lightbulb tech preference and then deletes the great people.

All I need now is some code to cycle thru the techs that can be researched, add them 1 at a time, cycle thru the new lightbulb techs, remove the tech and repeat.

Oh - and put together the screen. I've been thinking, this might make a nice second tab to the F6 screen (tech tree).
 
Instead of looping across the map, just use pPlayer.getCity(0) for the first city or pPlayer.getCapitalCity() for the capital. Mr. Micro Optimize at work, so just ignore me. :)

In any case, to address what you actually asked about, the ExoticForeignAdvisor has code that finds all the techs a player can research. That's probably a good place to start.

Ah, I see that there is pPlayer.canResearch(TechType, bTrade). Just pass in False for bTrade. So something like this:

Code:
lTechs = []
for iTech in range(gc.getNumTechInfos()):
    lTechs.append(iTech)

I'm looking through the C++ code to find functions to add/remove techs from a player.
 
Looking further, I notice that player's don't get techs -- teams do. So you need to get the player's team and then use

Code:
CyTeam.setHasTech(TechType eIndex, BOOL bNewValue, PlayerType ePlayer, BOOL bFirst, BOOL bAnnounce)

Probably want bFirst and bAnnounce to be False so the player doesn't get free GPs or see a message.
 
Instead of looping across the map, just use pPlayer.getCity(0) for the first city or pPlayer.getCapitalCity() for the capital. Mr. Micro Optimize at work, so just ignore me. :)
Yeah - well, I would have used the simple code IF I KNEW ABOUT IT!
 
You most deffintaly can NOT go about giving and removing Techs for the purposes of seeing what will be avalible as a result. It will trigger effects like founding religions, spawning Great people and the like, it would be completly unplayable.

i'd recomend you structure the logic around determining what additional techs become avalible based on what techs have the hypotheticaly aquired tech as a pre-requisite. Psudocode would look something like this

Code:
PresentlyKnownTechList = []
ResearchableTechList = []
OpenableTechsList = []
ConfirmedOpenedList = []

for (ResearchableTechList)
     for (AllTechs)
          if (ResearchableTech is prerequsite of any kind)
                OpenableTechs append Tech
     for (OpenableTechsList)
          for (AllPrereqs of OpenbleTech)
                if (Prereq is in PresentlyKnownTech or is ResearchTech)
                     ConfirmedOpenedList append Tech
     for (ResearchableTechList - ResearchTech + ConfirmedOpenedList)
          if (TechFlavor > Highestvalue)
               Highestvalue = TechFlavor
               LightBulb Tech = Tech

return Tech
 
Are you familiar with the online API? It lists all the Python classes and their functions. While it's not ideal and lacks documentation (as it was just generated from C++ code I think), sometimes I can find what I want.
 
Are you familiar with the online API? It lists all the Python classes and their functions. While it's not ideal and lacks documentation (as it was just generated from C++ code I think), sometimes I can find what I want.
I have that bookmarked. It is useful if you know what you are looking for. Sort of like looking up a word in a dictionary to check the spelling but not being able to find it because you cannot spell the word.
 
Impaler[WrG];5778903 said:
You most deffintaly can NOT go about giving and removing Techs for the purposes of seeing what will be avalible as a result. It will trigger effects like founding religions, spawning Great people and the like, it would be completly unplayable.
If this is true (and no reason to doubt it), then we might need to code up the 'tech to lightbulb' stuff from scratch. I don't think Imp's suggestion will be 100% accurate.

If we do need to code it up from scratch - how can I get the list of GP techs to lightbulb into python?
 
Back
Top Bottom