Looking to ADD a victory condition

jeffrockson

Chieftain
Joined
Feb 8, 2010
Messages
40
Location
USA
Hey everyone,

I've drafted a lengthy document about what I believe to be a very exciting, new victory condition. :king: I've started diving into the forums and modding resources, trying to find some information about the victory conditions. I'm having very little success, so I thought it might be helpful to me and others that'll come looking later to centralize some information about the victory conditions as people discover it.

So, forget graphics and the user interface, I'm just trying to track down how the game actually knows (or could be told to check) whether you've achieved a victory or lost the game. So far, I've come up with the following:

Text and Civilopedia entries:

XML\BasicInfos\CIV5Concepts.xml - contains references to text about the general topic, description, summary, advisor question, which advisor, and the header in the Civilopedia.
XML\EN_US\CIV5_Victory.xml - contains text references and English text for descriptions of victories and defeats.
XML\EN_US\CIV5GameTextInfos_Civilopedia.xml - more text references and English text.
XML\GameInfo\CIV5Victories.xml - contains "Victories" database entries with what appears to be the user-interface information about the types of victories, although the "WinsGame" row suggests it may be more than just user-interface stuff.

Literally, that's all I have after hours :eek: of reading forums and looking through the game directories. I didn't find a single .lua file about this stuff. So, I guess I'm going to be really disappointed if it's hard-coded and I can't mod this. :(

I'll open it up the floor to anyone who has found something that can help me out. It's not important that I add my victory condition the same way Firaxis wrote the default ones. As long as I have an opportunity to make a check against the victory conditions and it works, I'll be thrilled.

Thanks for reading,


JeffRockson
 
It's not hardcoded, but victory conditions, along with the majority of all other advanced modding is tied to the Source code, which is not available.
 
you can have lua check for conditions and set the winner, in a way replacing a victory type. it will use the victory splash screen based on the type of victory it was set.

Game.SetWinner( Teams[ Players[0]:GetTeam() ], 3);

that will trigger the culture win for example

not sure if we can add a new type. we can insert stuff into the GameInfoTypes table, but i think that GameInfo.Victories() will only put out the 5 victory types
 
you can have lua check for conditions and set the winner, in a way replacing a victory type. it will use the victory splash screen based on the type of victory it was set.

Game.SetWinner( Teams[ Players[0]:GetTeam() ], 3);

that will trigger the culture win for example

not sure if we can add a new type. we can insert stuff into the GameInfoTypes table, but i think that GameInfo.Victories() will only put out the 5 victory types

What is the difference between them
Game.SetWinner( Teams[ Players[0]:GetTeam() ], 3);
Events.EndGameShow( EndGameTypes.Domination, Game.GetActiveTeam());
the mongol DLC seems to be using the second method to end game
 
What is the difference between them
Game.SetWinner( Teams[ Players[0]:GetTeam() ], 3);
Events.EndGameShow( EndGameTypes.Domination, Game.GetActiveTeam());
the mongol DLC seems to be using the second method to end game

Good question. I don't have the files in front of me, because I'm at work, but I recall one of those XML file specifying something that seems to match the idea of an "EndGameShow." What I did was copy the Domination victory and create another next to it. So I guess my next question is whether the EndGameTypes data structure is dynamically populated from the XML database or if it's written out in the source code.

Along the same lines, if that SetWinner(team, ?) is specifying a victory type with that number, do we know whether the array or enum that "3" is used with isn't going to work if we give it a "5" or "6" to mean "one more than the ones you're used to seeing, because I added another one"? (I forget which index it should be in this case.)

smellymummy, where did you find that use of Game.SetWinner? I'd like to look around that file a bit more to understand the context in which it's used.

Seraphim8400, same question: where was Events.EndGameShow?

Thanks for reading,


JeffRockson
 
What is the difference between them
Game.SetWinner( Teams[ Players[0]:GetTeam() ], 3);
Events.EndGameShow( EndGameTypes.Domination, Game.GetActiveTeam());
the mongol DLC seems to be using the second method to end game

setwinner only takes victory types (5), while endgameshow takes endgametypes (9). so if anyone wanted more room to change stuff looks like endgameshow would be it. endgametype 5 to 9 are for tutorial1 -tutorial5 according to the table browser

and the arguments for the functions can be found either http://civilization4.net/files/modding/PythonAPI/index.html (just about all the same functions as civ4 work the same). if there isnt anything listed there try here on the forums at http://forums.civfanatics.com/showthread.php?t=385612&page=2

the rest of the time it's trial and error. if you give it bad arguments you'll get a message usually what you have to provide it. this is where the tuner becomes really useful with the lua console and being able to look through the table browser
 
setwinner only takes victory types (5), while endgameshow takes endgametypes (9). so if anyone wanted more room to change stuff looks like endgameshow would be it. endgametype 5 to 9 are for tutorial1 -tutorial5 according to the table browser

and the arguments for the functions can be found either http://civilization4.net/files/modding/PythonAPI/index.html (just about all the same functions as civ4 work the same). if there isnt anything listed there try here on the forums at http://forums.civfanatics.com/showthread.php?t=385612&page=2

the rest of the time it's trial and error. if you give it bad arguments you'll get a message usually what you have to provide it. this is where the tuner becomes really useful with the lua console and being able to look through the table browser

what about Events?
EX:Events.SerialEventCityCaptured
A function add to this event,then it can take(hexPos, playerID, cityID, newPlayerID)
how to understand the arg like (hexPos, playerID, cityID, newPlayerID)?

another question
How can I know which PLOT(s) are contained in a AREA?

jeffrockson:
i saw that function at Assets\DLC\DLC_01\Scenarios\Mongol Scenario\CivsAlive.lua
 
try a print ( hexpos ) to see what it gives you

i dont think a function exists to get the plots from a area. you would need to write your own routine to check neighbor plots and map out the island/continent
 
- -
sorry
my expression is a little bit different from what i think.
I mean how do i know there is 4 parameter in this EVENT rather than 10.
and the more important thing is these 4 parameter represnt 4 different meanings.(hexPos, playerID, cityID, newPlayerID)?
 
Hey guys,

Had a bunch of PhD stuff these past couple of weeks. All done, and I'm back to see what people have figured out around the forums. :)

So, I've read a bunch about people reading through the official game lua Assets to learn about how some of the functions and objects are used. Are there other lua files besides those listed here: http://wiki.2kgames.com/civ5/index.php/Lua_Reference? Because if that's it, then I don't know how anyone does any lua modding besides UI changes.

Incidentally, I was able to successfully call Game.SetWinner(0,0) in the Live Tuner (with InGame scope). It worked for 0 (time), 1 (science), 2 (conquest), 3 (culture), and 4 (diplomacy). The console printed the following after I entered those commands.
EndGameMenu: Play audio: AS2D_VICTORY_SPEECH_SCIENCE_VICTORY
I also saw the victory screen come up with the pretty image, the guy talking, and the two buttons to return to the main menu or play one more turn.

There was a related command, Game.IsVictoryValid(VictoryTypes eVictoryType) that returned true for values 0 through 4, and it returned false for values -1, 5, 6, 7, and 8.

So it looks like the tutorial "victory conditions" were not valid VictoryTypes. However, if they are special and available in the tutorial, then it should be possible to make them valid. So I loaded up the tutorials, but they (at least the Founding Cities one) returned false for all victory indices -1 through 10, which I was kind of surprised to see. But I guess it makes sense. So, how do the tutorials create victories for the player? :undecide:

I looked through the four .lua files in SteamApps\common\sid meier's civilization v\Assets\Tutorial\lua, but found nothing about ending the game or declaring a winner or posting a victory screen for the player. :help:
 
there's more functions available. you have to dig in the table browser to get the class then use that metatable __index thing to list them all

deal for example:
local d = UI.GetScratchDeal(); for k, v in pairs(getmetatable(d).__index) do print(k); end

and in case you missed it, setwinner only takes victory types (by default 5 types), while endgameshow takes endgametypes (by default 9 types), and both do the same: declare a winner and show the win screen (whichever type provided)
 
and in case you missed it, setwinner only takes victory types (by default 5 types), while endgameshow takes endgametypes (by default 9 types), and both do the same: declare a winner and show the win screen (whichever type provided)

Yep, but I was expecting to find how the tutorials ended the game in their .lua files, but I never found anything. Recall the victory screens at the end of each tutorial do not have a "one more turn" button, and they don't have any special artwork. So they must be different than the standard five, I just never found how they were invoked.

So, I found some help from http://forums.civfanatics.com/showthread.php?t=390367:

As far as searching, I use the Find in Files functionality in ModBuddy and have a saved folder set for the Civ 5 standard assets and then *.xml *.lua and *xml, *.lua file type filters. To set up the saved folder set do the following:

1) in ModBuddy go to Edit -> Find and Replace -> Find in Files
2) In the 'Look in:' section, click on the '...' button
3) Under 'Available Folders' browse to your Civ 5 assets folder (select it, don't double click into it) 4) Click the '>' button to add it to the list of 'Selected Folders'
5) In the 'Folder Set' section type in a name (I named mine Civilization 5 Assets) and click Apply
6) Click 'Ok'

From now on you can just select Civilization 5 Assets from the dropdown in the Find in Files dialog.
:goodjob:

So I set that up, and did a Find in Files... for "EndGame," and finally located the Mongols' scenario .lua files. Not sure how I missed them before. Anyway, they use EndGameShow, as mentioned earlier in this thread. Here's a line for causing the player to win (from CivsAlive.lua line 30):

Events.EndGameShow( EndGameTypes.Domination, Game.GetActiveTeam() );

Side note: I actually was just playing around and typed just Events.EndGameShow in the Live Tuner and it showed me a Science victory, so it must have some default values, which is nice to know.

And from DiploCorner.lua, lines 327–332, I found the following values in the EndGameTypes construct:

EndGameTypes.Technology
EndGameTypes.Domination
EndGameTypes.Culture
EndGameTypes.Diplomatic
EndGameTypes.Time


This isn't anything new, but it's good to have some answers. ;)

My next search results took me to Assets/UI/InGame/Popups/EndGameMenu.lua, lines 62–95:

Spoiler :
Code:
if( team == Game.GetActiveTeam() ) then
	Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_VICTORY_BANG" ) );
	local victoryType = nil;
	if( type == EndGameTypes.Tutorial1 ) then
		Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_TUTORIAL_1_COMPLETE" ) );
		bTutorialGame = true;
	elseif( type == EndGameTypes.Tutorial2 ) then
		Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_TUTORIAL_2_COMPLETE" ) );
		bTutorialGame = true;
	elseif( type == EndGameTypes.Tutorial3 ) then
		Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_TUTORIAL_3_COMPLETE" ) );
		bTutorialGame = true;
	elseif( type == EndGameTypes.Tutorial4 ) then
		Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_TUTORIAL_4_COMPLETE" ) );
		bTutorialGame = true;
	elseif( type == EndGameTypes.Tutorial5 ) then
		Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_TUTORIAL_5_COMPLETE" ) );
		bTutorialGame = true;
	elseif( type == EndGameTypes.Technology ) then
		Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_VICTORY_FLAVOR_TECHNOLOGY" ) );
		victoryType = "VICTORY_SPACE_RACE";
	elseif( type == EndGameTypes.Domination ) then
		Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_VICTORY_FLAVOR_DOMINATION" ) );
		victoryType = "VICTORY_DOMINATION";
	elseif( type == EndGameTypes.Culture ) then
		Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_VICTORY_FLAVOR_CULTURE" ) );
		victoryType = "VICTORY_CULTURAL";
	elseif( type == EndGameTypes.Diplomatic ) then
		Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_VICTORY_FLAVOR_DIPLOMACY" ) );
		victoryType = "VICTORY_DIPLOMATIC";
	elseif( type == EndGameTypes.Time ) then
		Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_VICTORY_FLAVOR_TIME" ) );
		victoryType = "VICTORY_TIME";
end
And there we have a few more EndGameTypes:

EndGameTypes.Tutorial1
EndGameTypes.Tutorial2
EndGameTypes.Tutorial3
EndGameTypes.Tutorial4
EndGameTypes.Tutorial5


And there's an alternative at the top which uses a database reference to "TXT_KEY_VICTORY_BANG". It looks like I can use the text references I wrote before I ran into this wall. I'm very glad!

I called Events.EndGameShow(EndGameTypes.Tutorial1) and received a "completed the Movement and Exploration Tutorial" message, even when not in the Movement and Exploration Tutorial! :king:

Not exactly what I want, but the method (OnDisplay added to Events.EndGameShow) goes on! Lines 104–143:

Spoiler :
Code:
if( team == Game.GetActiveTeam() ) then	
	
	...
	
	--print(victoryType);
	if(victoryType)then
		m_strAudio = GetVictoryAudio(victoryType);
		Controls.BackgroundImage:SetTexture(GameInfo.Victories[victoryType].VictoryBackground);    		
	else
		m_strAudio = GetVictoryAudio("VICTORY_TIME");
		Controls.BackgroundImage:SetTexture(GameInfo.Victories["VICTORY_TIME"].VictoryBackground); 		
	end
else
	m_bAllowBack = false;
	Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_DEFEAT_BANG" ) );
	Controls.EndGameText:SetText( Locale.ConvertTextKey( "TXT_KEY_VICTORY_FLAVOR_LOSS" ) );
	Controls.BackgroundImage:UnloadTexture();
	Controls.BackgroundImage:SetTexture( "Victory_Defeat.dds" );
	Controls.BackButton:SetDisabled( true );
	if (not Game:IsNetworkMultiPlayer() and player:IsAlive()) then
		if( type == EndGameTypes.Technology ) then
			Controls.BackButton:SetDisabled( false );
			m_bAllowBack = true;
		elseif( type == EndGameTypes.Domination ) then
			Controls.BackButton:SetDisabled( false );
			m_bAllowBack = true;
		elseif( type == EndGameTypes.Culture ) then
			Controls.BackButton:SetDisabled( false );
			m_bAllowBack = true;
		elseif( type == EndGameTypes.Diplomatic ) then
			Controls.BackButton:SetDisabled( false );
			m_bAllowBack = true;
		elseif( type == EndGameTypes.Time ) then
			Controls.BackButton:SetDisabled( false );
			m_bAllowBack = true;
		end
	end

	m_strAudio = "AS2D_VICTORY_SPEECH_LOSS";
end

Controls.RankingButton:SetHide( bTutorialGame );
Controls.HallOfFameButton:SetHide( bTutorialGame );
Controls.DemographicsButton:SetHide( bTutorialGame );
SO! I think this will do it. Here's my understanding: The audio and background image are loaded based on the victory type. Even if I don't have access to create a new audio file or image, I can roll with no audio and the default background image no problem.:thumbsup:

The else block sets up a defeat screen, which gives me insight into creating my own.

So, I may not need to define my own EndGameType and have the game handle it like all the others, but this method--I think--gives me the power to create one on the fly when I need it. Which is good, because I actually need a defeat condition too! :w00t:

I'll play around and post some progress as I make it. I'll also post a link to my mod when I have made some progress and have something to post!

Thanks for reading,


JeffRockson
 
Back
Top Bottom