Introducing: PyScenario - easy-to-use scenario event scripting for RFC

It's usually only a few techs, isn't it? I can't imagine a purpose for knowing the first inventor of every tech.
 
What I mean is, that PyScenario is not a mod-mod - its a scenario event scripting tool. How would I know what Techs the scenario maker needs to check? So I basically need this to work with any Tech, regardless. Building a master index of all Techs and setting a value each time one is acquired is one way to go. Not the preferred way, obviously...
 
I see. Maybe you could get around the giant index by setting up two small ones, where the first tracks which tech index i saves and the other if it has already been discovered?

It's still clunky, but I guess for something with as many possibilities as this, the DLL might be the better address anyway, if you're going for elegance.
 
No index if I can help it, but we'll just have to see about that. And the application is named PyScenario because its done in Python. (And that's because I don't know any C++. :lol:)
 
I'm already curious how you will solve it :)
 
Well, I'm gonna start with trying out CyGame.countKnownTechNumTeams() in the Python console...
 
I'm getting confusing results in the Python console, but this function surely counts the number of teams that has a Tech?
Code:
int CvGame::countKnownTechNumTeams(TechTypes eTech)
{
	int iCount = 0;

	for (int iI = 0; iI < MAX_TEAMS; iI++)
	{
		if (GET_TEAM((TeamTypes)iI).isEverAlive())
		{
			if (GET_TEAM((TeamTypes)iI).isHasTech(eTech))
			{
				iCount++;
			}
		}
	}

	return iCount;
}
So I'll just go with the Python representation of it then and see if it works. :p
 
From my understanding it does.
 
Attached is a custom version of the tech() Condition:

tech( eTech=None, eEra=None, bFirst=None )

The bFirst setting affects other both settings - if set to True then the Civ receiving the Tech must be the first to discover the specified Tech - or to be the first one to enter the specified Era. A False setting will only fire if its not the first time the Tech is discovered or the Era is reached.
 

Attachments

  • Custom_tech.zip
    720 bytes · Views: 68
By the way, I believe I just figured out a way to add signs/landmarks to the map with Python - and to remove them. I actually didn't know that was doable.

This probably means that there will be a sign() Action in the next PyScenario update. :D A Trigger without a Target Players then creates a "landmark" visible to all players. And the default name will be the Trigger label, but you can of course override this with a optional string setting. I'm not sure how the tile labels will be removed however, but what about an augmented erase() Action? Like a bSigns setting. Spawning a city will remove any sign on that plot, of course. But perhaps the city naming could be controlled by whatever the sign says?

Or perhaps the signs can be part of the terrain() Action instead, I dunno yet. But I'm exited none-the-less. (In my own scenario Villages and Towns will spawn dynamically on the map, and now I can add signs to them. :king:)
 
Code:
from PyScenario import *
from Custom import *

Like that? (never remember :p )

[EDIT]: OK, it worked. What happens if I build national wonder in a city if another city already has the wonder? Like palace? Two national wonders or it will disappear from other city?

Or I had [insert national wonder that is not a palace here] built in one of my cities, then I capture an enemy city that also had it?
 
National Wonders are auto razed on acquisition, so normally one player can't get two of them.

But if you use Python (or PyScenario, same difference) to give a city a NW that already exists - who knows? Try it?
 
Some things to start with: modification to tech(), that check if player is the first to invent technology, goldenage() which triggers golden age :p and deflag() which makes fired label look like unfired. Good luck :p
I'm doing the Golden Age thing next but I realized that the method could potentially be useful for more things. What other features could be covered by the same method? I'm thinking stuff like Anarchy, Plague and Great Depression. Anarchy is already covered by the civics() method however, and I'm not so sure I can hack into Plague.py or Stability.py without making changes in the actual modules. And I'd rather not.

edit: Looking the RFC code I can't see why plagues and depressions couldn't be triggered from PyScenario.py without editing the affected modules themselves.

Any ideas before I start testing the Golden Ages?

edit: What about naming a golden age method renaissance()? Its one word and implies that the Civ will be experiencing a rebirth of sorts. What about rebirth()? It might be too similar to respawn() and reset() though... I have no idea what to call something that could be used to set golden age, plague and depression turns however! Perhaps another method then, like calamity()?
 
Attached is the custom Action rebirth():

rebirth( iNum=None, bScaling=True, ePlayer=None )

The method adds/subtracts iNum turns worth of Golden Age for the Target Player. (bScaling adapts this to the current game speed.) A None setting will auto-detect the default number of turns for that player (always scaled for speed). The optional ePlayer setting can be used to override any Target Player for this method only.
Code:
from Custom import *
Trigger.rebirth = rebirth
 

Attachments

  • Custom_rebirth.zip
    579 bytes · Views: 44
... and deflag() which makes fired label look like unfired.
Could you give me an example of use for this?
 
So, in other words, you want Triggers "A" and "B" to only fire once? But once Trigger "C" fires you need to basically reload Trigger "A" so that it doesn't register a fired any more?

Other than that, due to the ad hoc nature of the fired() Condition you wouldn't be able to make a reference to the second Trigger in the first one. Because when the first Trigger is initialized it won't recognize the label of the second one.

Also, the second Trigger is referencing itself - it might fail on the same principle as the first one.

If something like what you propose was to work I might have to rewrite the whole code for Trigger binding, I'm afraid. I'm not sure if I have the time for all the testing and debugging involved. Stuff like move the initialized Trigger objects into a dictionary from the current list setup. That should fix the indexing once-and-for-all - as long as two Triggers don't have the same label.
 
Top Bottom