Community Patch for BNW

Hey, when I saw the draft patch notes, I started to (out of procrastination boredom) attempt an icon for the wind plant, though it's not 100% finished (figuring that even if it's not needed for the patch, somebody might find an use for it):

Didn't see your offer at that point, hope I'm not treading on your toes, Wodhann... :undecide:
Gazebo seems to be ignoring my posts, so just go ahead and do them.
 
If I understand correctly, you're asking for the ability to use the same secondary table to produce any yield, correct? Essentially, you'd get rid of the <Happiness>4</Happiness> element of buildings, and make it:

Code:
<BuildingType>x</BuildingType>
<YieldType>YIELD_HAPPINESS</YieldType
<Yield>4</Yield>

Shouldn't be all that hard - all I'd need to do is fill these into the Yield enums and redirect city and player pointers to look at yield changes rather than unique functions.

That's it in a nutshell. I do wish you all the best with that. The little I do know of the C++ backs up whoward69's comments, it is like 2 or 3 completely different teams at Firaxis were asked to do similar things but not given any guidance as to how it all should come together.:eek:

After a while you might see why I would like to see a DLL fix to these things instead of the hobbled together collection of lua functions that CEP uses.

On another area that just came to my mind is the atrocious path-finding of the AI, especially with units that take attrition damage, like missionaries or Carthaginian units over mountains.
Understandably, this one can be place way down the list. You have after all taken on a big task with this 'Community Patch'. Next Friday by 5pm is fine.:mischief:
 
On another area that just came to my mind is the atrocious path-finding of the AI, especially with units that take attrition damage, like missionaries or Carthaginian units over mountains.
Understandably, this one can be place way down the list. You have after all taken on a big task with this 'Community Patch'. Next Friday by 5pm is fine.:mischief:

Oh gawd, that's definitely something I hope can be addressed by this patch.
 
Yeah, the yield stuff is going to be bear. I think it is fixable, but it may be more of a matter of building our own setup on top of what is there. Here's what I've done so far:

1.) YIELD_HAPPINESS, YIELD_HAPPINESS_NATIONAL and YIELD_TOURISM added as enum yields - should validate them to be used in existing secondary tables.

2.) Created an alternative set of secondary tables and processing functions to bypass around 75% of the integers built into xml primary tables for policies and other functions (i.e. <Happiness>4</Happiness>). Once these work for everything, and they are finalized, the existing hodge-podge can be disabled. This will, I believe, have the knock-on effect of speeding up the dll slightly, as fewer disparate functions will need to be called on.

3.) Pushed as many possible functions for buildings, policies and culture to existing secondary yield tables.

Here's a taste of the number of tables I've made so far (very, very rough - about 25% are not enabled yet.):

Spoiler :
Code:
	<Table name="Building_MountainPlotYieldChanges">
		<Column name="BuildingType" type="text" reference="Buildings(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer"/>
	</Table>
	<Table name="Policy_GetYieldFromKills">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldPerWonder">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Belief_PeaceBoost">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetPolicyYieldCost">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldPerCity">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldPerWonder">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldWonderMultiplier">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldPerTechResearched">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldImprovementChange">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldFromKills">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldFromBarbarianKills">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetExtraYield">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetExtraYieldPerCity">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetFreeYield">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetAllFeatureYield">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetSpecialistYieldModifier">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldPerGarrisonedUnit">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldPerTradeRoute">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldPerXPopulation">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetExtraYieldPerLuxury">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetYieldPerUnit">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetCityYieldMod">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetCapitalYieldMod">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetLandTradeRouteYieldChange">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetSeaTradeRouteYieldChange">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetSharedIdeologyTradeYieldChange">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetHappinessToYield">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>
	<Table name="Policy_GetNumCitiesFreeBuilding">
		<Column name="PolicyType" type="text" reference="Policies(Type)"/>
		<Column name="YieldType" type="text" reference="Yields(Type)"/>
		<Column name="Yield" type="integer" notnull="true"/>
	</Table>

Will continue the slog later in the weekend. Thoughts?
G
 
2.) Created an alternative set of secondary tables and processing functions to bypass around 75% of the integers built into xml primary tables for policies and other functions (i.e. <Happiness>4</Happiness>). Once these work for everything, and they are finalized, the existing hodge-podge can be disabled. This will, I believe, have the knock-on effect of speeding up the dll slightly, as fewer disparate functions will need to be called on.

Won't this cause mass incompatibility with mods that add buildings that generate Happiness in this way?

Also, would fixing faith generation from Specialists be within your plans? Currently, specialists yield faith, but it doesn't add to your faith output.
 
Won't this cause mass incompatibility with mods that add buildings that generate Happiness in this way?

Also, would fixing faith generation from Specialists be within your plans? Currently, specialists yield faith, but it doesn't add to your faith output.

If we disabled them entirely, yeah. I guess what I meant to say was we can bypass them, so they'll rarely be called upon.

I'll look into the specialist issue.
G
 
hmm... maybe I'm missing something?

Let's take one example: Policy_GetYieldFromKills

Why would we need that if we can use the vanilla ReportYieldFromKills? Or doesn't that function allow for 'yields from kills' being used in policies?

I was thinking of 'extending' the usefulness of vanilla functions so that there wouldn't be the need to 'bypass'. But then I am not really on top of this.:)

Another example you have is: Building_MountainPlotYieldChanges

I think this may be too specific. Wouldn't it be better to just go with Building_PlotYieldChanges and then make mountains accessible as a plot elsewhere?

I'm just trying to think of your workload, and trying to understand as I go. If I have made an error in assuming such, please let me know and disregard these points.
 
Resolving the yield code such that Gold, Production, Science, Culture, Faith, Tourism, Happiness (both local and global), Great Person points (for any/every GP/Specialist) and a few others I've forgotten, all work the same way will be one of the "holy grails" of a community DLL

The ones I forgot are Food (doh!) and Golden Age points

Won't this cause mass incompatibility with mods that add buildings that generate Happiness in this way?

Which is why any workable solution is a "holy grail" - it must both add new YIELD_HAPPINESS_LOCAL and YIELD_HAPPINESS_GLOBAL yields (which could be added as say yields from a GP improvement on a tile) and still work for the old building specific table columns

Policy_GetYieldFromKills - Why would we need that if we can use the vanilla ReportYieldFromKills? Or doesn't that function allow for 'yields from kills' being used in policies?

It probably doesn't (I've not checked), but the point is that all existing methods need to work for all possible yields and not have replacement functions written - otherwise it's back to breaking hundreds if not thousands of mods

Another example you have is: Building_MountainPlotYieldChanges

I think this may be too specific. Wouldn't it be better to just go with Building_PlotYieldChanges and then make mountains accessible as a plot elsewhere?

Not better IMHO but mandatory

Otherwise you're going to have Building_MountainPlotYieldChanges, Building_HillsPlotYieldChanges, Building_OceanPlotYieldChanges, Building_GrassTerrainYieldChanges, Building_PlainsTerrainYieldChanges, etc, etc, etc instead of the two tables Building_PlotYieldChanges and Building_TerrainYieldChanges

Yields can be generated from Units, Buildings, Improvements, Resources, Features, Terrain, Plots, Policies, Traits, Beliefs, etc - any time you come across or create a table with a specific one or sub-group of these in their name alarm bells should be ringing loudly, eg NaturalWonderYields would be a mistake (as NWs are a sub-group of features)
 
If we disabled them entirely, yeah. I guess what I meant to say was we can bypass them, so they'll rarely be called upon.

I'll look into the specialist issue.
G

Gazebo can you leave us the possibility to change the tourism value from GreatWork ?
Atm it's coded in hard. it would be cool to being able to edit it easily because some mod change the flow of culture and you have to adjust the tourism.


ps : we can change culture but not tourism ...
 
hmm... maybe I'm missing something?

Let's take one example: Policy_GetYieldFromKills

Why would we need that if we can use the vanilla ReportYieldFromKills? Or doesn't that function allow for 'yields from kills' being used in policies?

I was thinking of 'extending' the usefulness of vanilla functions so that there wouldn't be the need to 'bypass'. But then I am not really on top of this.:)

Another example you have is: Building_MountainPlotYieldChanges

I think this may be too specific. Wouldn't it be better to just go with Building_PlotYieldChanges and then make mountains accessible as a plot elsewhere?

I'm just trying to think of your workload, and trying to understand as I go. If I have made an error in assuming such, please let me know and disregard these points.

No worries. I'm not overriding any of the existing secondary tables. I've got two tasks here: make the secondary tables that exist yield-agnostic by telling the dll to read yields from secondary tables rather than the yield-specific tables in primary tables. So for the example we have been using, happiness will now use the same yield table as other yields, and the functions that look for happiness will now call on a secondary table.

Second, I'm making new yield tables to replace yield specific functions such as all the culture functions. That way, as you said, we can change the yield in any secondary table and have it work without issue.

There is, so far as I can see, no easy way to 'open up' the majority of yield specific functions, as they do not call on the entire range of yields from the base function level. In other words, culture functions only fire right now if the yield being considered is culture. To make that function yield-agnostic requires a bit of a re-write from the base level.

For example, last night I tested briefly the yield from kills mechanic. In the new system, I could use any yield (food, production, culture) as the yield reward. My cannibal minutemen were killing barbs and converting the yield into food for the nearest city. This isn't possible without my changes, as the dll excludes food from the list of yield possibilities. The lua is still wonky, but it'll iron out.

I think this may be too specific. Wouldn't it be better to just go with Building_PlotYieldChanges and then make mountains accessible as a plot elsewhere?

Mountains behave oddly, and are the only plot which could not be affected by an existing yield table. Making a table like the Sea_PlotYieldChange for mountains was easy enough, and solves the problem.

In short, all existing yield-agnostic tables are being extended. Yield-specific primary functions are not, and must be bypassed for this to work. I'm going to need more eyes on this, but I simply don't see an easier way to do this while retaining the granularity of the existing functions.
G

Edit: to address the other posts,

I'll look at science overflow, but there isn't much we can do about the multiplayer code.

Tourism changes from great works should be changeable like everything else soon enough.
 
It probably doesn't (I've not checked), but the point is that all existing methods need to work for all possible yields and not have replacement functions written - otherwise it's back to breaking hundreds if not thousands of mods.

I just don't see how that is possible. JonsCulture and its culture function auxiliaries are woven throughout the dll- there is not a point of change where we can just open that up. It has to be bypassed to be made agnostic. :blush:

One saving option is to allow the existing primary table functions to change the new yield agnostic tables in the dll. That would retrofit the old mods/buildings in the game while also opening up the new tables. We would have to put in a hook for the new yield values at every single specific-yield 'change' function, but it would work. At that point we would turn off the function link for the old 'get_functionvalue' and point it to the new one.

Sigh...what have I started...
G
 
Sigh...what have I started...

I kid you not, I've started to look at this, in depth, three times. It is not even "moderately difficult" it is "very, very hard".

Any solution that requires every existing mod to change the way it works and also requires large chunks of the UI to be rewritten is just a waste of time IMHO as it will never be adopted, except possibly by total conversion mods, and those shouldn't be the target of a general purpose community DLL
 
And while I'm doing a mind dump ...

The Second Holy Grail is ... Bonuses

Traits, Policies, Buildings, Beliefs, Techs, et al should all grant (named) bonuses. Bonuses should be the central place to add (new) "advantages". So no more "how do I add bonus X (which appears only for buildings at the moment) to a policy?" ... "oh you have to do it via a hidden building", but "you just assign the bonus used by building B to policy P"
 
I kid you not, I've started to look at this, in depth, three times. It is not even "moderately difficult" it is "very, very hard".

Any solution that requires every existing mod to change the way it works and also requires large chunks of the UI to be rewritten is just a waste of time IMHO as it will never be adopted, except possibly by total conversion mods, and those shouldn't be the target of a general purpose community DLL

Yeah, this is the conclusion I've about come to myself. I think it is a noble dream, perhaps even heroic, but I don't think the cost is worth the benefit. The game was not designed for a unified yield system.

There are things we can do to expand functions for the dll, but to achieve it all we would literally have to re-write the entire base code of the dll from scratch...and the xml...and every mod's xml...and that's not going to happen. :(

I'm going to go ahead with many of the additional tables (not all of the ones I listed above, as a lot of those were just placeholders), as it isn't terribly hard to add additional sources of yields into the dll. The rule of thumb will simply be that if an item has a yield as a primary table yield, don't add it as a secondary table yield (and vice-versa) or it will effectively double that yield. Additional flexibility is never a bad thing, even if it means we're grafting more and more limbs onto the 'monster.'

Honestly, I'm more interested in fixing gameplay issues at present, as they are the least likely to cause mod conflicts, and the most likely to improve game enjoyment. Once I've got the tables working, Whoward, I'll send them your way so you can see if my insanity has panned any gold.
G
 
And now my sadness returns. Ah well, the dream was fine while I slept.

Reality, what a b**ch.
 
Spoiler :
Part 1- Bugs: This phase will focus on fixing major game-breaking issues, specifically those related to the dll. For example, correcting the behavior of natural wonders, or improving the tactical AI.

Part 2- Core Balance: This phase will focus on fixing imbalanced core mechanics, such as faith generated from Desert Folklore, AI competency, and tall v. wide penalties. These are balance changes that will affect all players regardless of choices they make during a game.

Part 3- Strategic Balance: This phase will focus on addressing general imbalances rooted in individual gameplay choices. Examples include problematic policies, National Wonder viability, building changes, and civilization imbalances.

Part 4- Customization: This phase will focus on creating LUA hooks within the DLL that are absent from vanilla BNW. This will enable modders to add new features to the game without having to modify the dll.

I would submit that you can probably skip 2-3 with a few possible obvious exceptions and move mostly into 4. 3 can be already be done by major balance mods designed to use the functions of step 4. It would risk duplication of work to make those kinds of fixes. Adding some functionality in the dll for common lua code fixes would be a bigger use of this project. Balance is kind of a season to taste concern that if it's available in xml/sql, a player with modest modding ability can do on their own and there are mods out there designed to tackle these problems, with years of argument over how that still haven't arrived at "how to fix piety" solutions, and so on. Attempting to do it here too could be a mess.

What would be of note here would be to identify features that are typically identified as broken in default and if there are any missing in major balance mods, then those modders can take the tools available here to go out and make adjustments. If they are missing tools or have to do extensive code work-arounds, that's something that is useful for goal 4 to simplify those tasks. As Expired identified, the yield table is a mess. If that can't be fixed without breaking every mod out there, don't bother. But even adding some easier modding tools and tables to work with it would be a big help if the underlying skeleton is too messy to be repaired at this point.
 
And now my sadness returns. Ah well, the dream was fine while I slept.

The biggest issue with a unified approach to yields is the drive to do it. It is a huge task, and for me, without some obvious benefit in a mod I am writing to play with, it just keeps dropping down the priority list until it falls off the bottom.
 
Part 4- Customization: This phase will focus on creating LUA hooks within the DLL that are absent from vanilla BNW. This will enable modders to add new features to the game without having to modify the dll.

I would submit that you can probably skip 2-3 with a few possible obvious exceptions and move mostly into 4.

There is already a huge amount of work done around 4

Extra events

Spoiler :
Code:
    <!-- Events sent when terraforming occurs (v33) -->
    <!--   GameEvents.TerraformingMap.Add(function(iEvent, iLoad) end) -->
    <!--   GameEvents.TerraformingPlot.Add(function(iEvent, iPlotX, iPlotY, iInfo, iNewValue, iOldValue, iNewExtra, iOldExtra) end) -->
    <!-- See also: "Trait - River Connection" -->
    <Row Class="3" Name="EVENTS_TERRAFORMING" Value="0"/>

    <!-- Events sent when plots change from worker actions (v44) -->
    <!--   GameEvents.TileFeatureChanged.Add(function(iPlotX, iPlotY, iOwner, iOldFeature, iNewFeature) end) -->
    <!--   GameEvents.TileImprovementChanged.Add(function(iPlotX, iPlotY, iOwner, iOldImprovement, iNewImprovement, bPillaged) end) -->
    <!--   GameEvents.TileRouteChanged.Add(function(iPlotX, iPlotY, iOwner, iOldRoute, iNewRoute, bPillaged) end) -->
    <Row Class="3" Name="EVENTS_TILE_IMPROVEMENTS" Value="0"/>

    <!-- Event sent when a team circumnavigates the globe (v19) -->
    <!--   GameEvents.CircumnavigatedGlobe.Add(function(iTeam) end) -->
    <!-- Requires a mod to actually enable the feature in-game -->
    <!-- See also: "Global - Enable Magellan" -->
    <Row Class="3" Name="EVENTS_CIRCUMNAVIGATION" Value="0"/>

    <!-- Event sent when the player enters a new era, see also NewEraPopup.lua and BUTTONPOPUP_NEW_ERA (v19) -->
    <!--   GameEvents.TeamSetEra.Add(function(eTeam, eEra, bFirst) end) -->
    <!-- See also: "Global - Espionage Race" -->
    <Row Class="3" Name="EVENTS_NEW_ERA" Value="0"/>

	<!-- Event sent when the team discovers a new Natural Wonder (v19) -->
	<!--   GameEvents.NaturalWonderDiscovered.Add(function(iTeam, iFeature, iX, iY, bFirst) end) -->
    <!-- See also: "Religion - Natural Wonder Epiphany" -->
    <Row Class="3" Name="EVENTS_NW_DISCOVERY" Value="0"/>

    <!-- Event sent during Game.DoFromUIDiploEvent, see also DiscussionDialog.lua (v19) -->
    <!--   GameEvents.UiDiploEvent.Add(function(eEvent, eAIPlayer, iArg1, iArg2) end) -->
    <!-- See also: "UI - Diary" -->
    <Row Class="3" Name="EVENTS_DIPLO_EVENTS" Value="0"/>

    <!-- Events sent on status change with City States (v19) -->
    <!--   GameEvents.MinorFriendsChanged.Add(function(iMinor, iMajor, bIsFriend, iOldFriendship, iNewFriendship) end) -->
    <!--   GameEvents.MinorAlliesChanged.Add(function(iMinor, iMajor, bIsAlly, iOldFriendship, iNewFriendship) end) -->
    <!-- See also: "Global - City State Airbases" -->
    <Row Class="3" Name="EVENTS_MINORS" Value="0"/>

    <!-- Event sent when a Goody Hut is entered (v33) -->
	<!--   GameEvents.GoodyHutCanNotReceive.Add(function(iPlayer, iUnit, eGoody, bPick) return false end) -->
    <!-- See also: "Goody Huts - No Auto-Mapping" -->
    <Row Class="3" Name="EVENTS_GOODY_CHOICE" Value="0"/>

    <!-- Events sent if a Goody Hut is giving a tech (v30) -->
    <!--   GameEvents.GoodyHutCanResearch.Add(function(iPlayer, eTech) return true end) -->
    <!--   GameEvents.GoodyHutTechResearched.Add(function(iPlayer, eTech) end) -->
    <!-- See also: "Goody Huts - Tech Refund" -->
    <Row Class="3" Name="EVENTS_GOODY_TECH" Value="0"/>

	<!-- Event sent to allow Lua to override the AI's choice of tech (v19) -->
	<!--   GameEvents.AiOverrideChooseNextTech.Add(function(iPlayer, bFreeTech) return iChoosenTech end) -->
    <Row Class="3" Name="EVENTS_AI_OVERRIDE_TECH" Value="0"/>

	<!-- Events sent by Great People actions (v19) -->
	<!--   GameEvents.GreatPersonExpended.Add(function(iPlayer, iUnit, iUnitType, iX, iY) end) -->
    <Row Class="3" Name="EVENTS_GREAT_PEOPLE" Value="0"/>

    <!-- Events sent when a player is about to found a religion (v19) -->
    <!--   GameEvents.PlayerCanFoundPantheon.Add(function(iPlayer) return true end) -->
    <!--   GameEvents.PlayerCanFoundReligion.Add(function(iPlayer, iCity) return true end) -->
    <!--   GameEvents.GetReligionToFound.Add(function(iPlayer, iPreferredReligion, bIsAlreadyFounded) return iPreferredReligion end) -->
    <!--   GameEvents.PantheonFounded.Add(function(iPlayer, iCapitalCity, iReligion, iBelief1) end) -->
    <!--   GameEvents.ReligionFounded.Add(function(iPlayer, iHolyCity, iReligion, iBelief1, iBelief2, iBelief3, iBelief4, iBelief5) end) -->
    <!--   GameEvents.ReligionEnhanced.Add(function(iPlayer, iReligion, iBelief1, iBelief2) end) -->
    <!-- See also: "Religion - Civ Specific Religions" -->
    <Row Class="3" Name="EVENTS_FOUND_RELIGION" Value="0"/>
    <!-- Events sent when choosing beliefs (v19) -->
    <!--   GameEvents.PlayerCanHaveBelief.Add(function(iPlayer, iBelief) return true end) -->
    <!--   GameEvents.ReligionCanHaveBelief.Add(function(iPlayer, iReligion, iBelief) return true end) -->
    <!-- See also: "Religion - Civ Specific Religions" -->
    <Row Class="3" Name="EVENTS_ACQUIRE_BELIEFS" Value="0"/>
	<!-- Events sent to see if religion missions are valid (v46) -->
	<!--   GameEvents.PlayerCanSpreadReligion.Add(function(iPlayer, iUnit, iPlotX, iPlotY) return true end) -->
	<!--   GameEvents.PlayerCanRemoveHeresy.Add(function(iPlayer, iUnit, iPlotX, iPlotY) return true end) -->
    <Row Class="3" Name="EVENTS_RELIGION" Value="0"/>

    <!-- Events sent by plots (v30) -->
	<!--   GameEvents.PlayerCanBuild.Add(function(iPlayer, iUnit, iX, iY, iBuild) return true end) -->
    <!--   GameEvents.PlotCanImprove.Add(function(iX, iY, iImprovement) return true end) -->
    <!--   GameEvents.PlayerBuilding.Add(function(iPlayer, iUnit, iX, iY, iBuild, bStarting) end) (v46) -->
    <!--   GameEvents.PlayerBuilt.Add(function(iPlayer, iUnit, iX, iY, iBuild) end) (v46) -->
    <!-- See also: "Improvement - Pontoon Bridge" -->
    <Row Class="3" Name="EVENTS_PLOT" Value="0"/>

    <!-- Events sent after a city produces/buys/sells something (v19) -->
    <!--   GameEvents.CityTrained.Add(function(iPlayer, iCity, iUnit, bGold, bFaith) end) -->
    <!--   GameEvents.CityConstructed.Add(function(iPlayer, iCity, iBuilding, bGold, bFaith) end) -->
    <!--   GameEvents.CityCreated.Add(function(iPlayer, iCity, iProject, bGold, bFaith) end) -->
    <!--   GameEvents.CityPrepared.Add(function(iPlayer, iCity, iSpecialist, bGold, bFaith) end) (v33) -->
    <!--   GameEvents.CityBoughtPlot.Add(function(iPlayer, iCity, iPlotX, iPlotY, bGold, bCulture) end) -->
    <!--   GameEvents.CitySoldBuilding.Add(function(iPlayer, iCity, iBuilding) end) -->
    <Row Class="3" Name="EVENTS_CITY" Value="0"/>

	<!-- Event sent to ascertain if a city can acquire a plot (v20) -->
	<!--   GameEvents.CityCanAcquirePlot.Add(function(iPlayer, iCity, iPlotX, iPlotY) return true end) -->
    <!-- See also: "Global - Coastal Waters Only" -->
    <Row Class="3" Name="EVENTS_CITY_BORDERS" Value="0"/>
	
	<!-- Event sent to ascertain if a player can over-ride the standard razing rules for the specified city and raze it anyway (v20) -->
	<!--   GameEvents.PlayerCanRaze.Add(function(iPlayer, iCity) return false end) -->
    <!-- See also: "Global - Raze Major Capitals" -->
    <Row Class="3" Name="EVENTS_CITY_RAZING" Value="0"/>

	<!-- Event sent to ascertain the bombard range for a city, and if indirect fire is allowed (v32) -->
	<!-- Return a negative range if indirect fire is permitted -->
	<!--   GameEvents.GetBombardRange.Add(function(iPlayer, iCity) return (-1 * GameDefines.CITY_ATTACK_RANGE) end) -->
    <!-- See also: "Global - City Bombard Range" -->
    <Row Class="3" Name="EVENTS_CITY_BOMBARD" Value="0" DbUpdates="1"/>

	<!-- Events sent to ascertain if one city is connected to another (v33) -->
	<!--   GameEvents.CityConnections.Add(function(iPlayer, bDirect) return false end) -->
	<!--   GameEvents.CityConnected.Add(function(iPlayer, iCityX, iCityY, iToCityX, iToCityY, bDirect) return false end) -->
    <!-- See also: "Trait - River Connection" -->
    <!-- See also: "Global - Air Routes" -->
    <Row Class="3" Name="EVENTS_CITY_CONNECTIONS" Value="0"/>

	<!-- Events sent to ascertain if an area can have civ specific resources and to place those resources (v20) -->
	<!--   GameEvents.AreaCanHaveAnyResource.Add(function(iPlayer, iArea) return true end) -->
	<!--   GameEvents.PlaceResource.Add(function(iPlayer, iResource, iCount, iPlotX, iPlotY) end) -->
    <!-- See also: "Global - Spice Islands" -->
    <Row Class="3" Name="EVENTS_AREA_RESOURCES" Value="0"/>

    <!-- Event sent to ascertain if a unit can rebase to a specific plot (either a city or a carrier) (v19) -->
    <!--   GameEvents.CanLoadAt.Add(function(iPlayer, iUnit, iPlotX, iPlotY) return false end) -->
    <!--   GameEvents.CanRebaseInCity.Add(function(iPlayer, iUnit, iPlotX, iPlotY) return false end) -->
    <!--   GameEvents.CanRebaseTo.Add(function(iPlayer, iUnit, iPlotX, iPlotY, bIsCity) return false end) -->
    <!--   GameEvents.RebaseTo.Add(function(iPlayer, iUnit, iPlotX, iPlotY) end) -->
    <!-- See also: "Improvement - Airbases" -->
    <!-- See also: "Global - City State Airbases" -->
    <Row Class="3" Name="EVENTS_REBASE" Value="0"/>

    <!-- Events sent before and after a paradrop (v19) -->
    <!--   GameEvents.CanParadropFrom.Add(function(iPlayer, iUnit, iPlotX, iPlotY) return false end) -->
    <!--   GameEvents.CannotParadropFrom.Add(function(iPlayer, iUnit, iPlotX, iPlotY) return false end) -->
    <!--   GameEvents.ParadropAt.Add(function(iPlayer, iUnit, iFromX, iFromY, iToX, iToY) end) -->
    <!-- See also: "Units - Paratroop Enhancements" -->
    <Row Class="3" Name="EVENTS_PARADROPS" Value="0"/>

	<!-- Event sent when a unit is created (v46) -->
	<!--   GameEvents.UnitCreated.Add(function(iPlayer, iUnit, iUnitType, iPlotX, iPlotY, bTestVisible) end) -->
    <Row Class="3" Name="EVENTS_UNIT_CREATED" Value="0"/>

	<!-- Event sent just before a unit is killed (via CvUnit::kill()) (v22) -->
	<!--   GameEvents.UnitPrekill.Add(function(iPlayer, iUnit, iUnitType, iX, iY, bDelay, iByPlayer) end) -->
    <!-- See also: "UI - Antiquity Site Tooltips" -->
    <Row Class="3" Name="EVENTS_UNIT_PREKILL" Value="0"/>

	<!-- Event sent as a unit is captured (v46) -->
	<!--   GameEvents.UnitCaptureType.Add(function(iPlayer, iUnit, iUnitType, iByCiv) return iCaptureUnitType; end) -->
    <Row Class="3" Name="EVENTS_UNIT_CAPTURE" Value="0"/>

	<!-- Events sent as units are promoted/upgraded (v19) -->
    <!--   GameEvents.CanHavePromotion.Add(function(iPlayer, iUnit, iPromotionType) return true end) -->
    <!--   GameEvents.UnitPromoted.Add(function(iPlayer, iUnit, iPromotionType) end) -->
    <!--   GameEvents.CanHaveAnyUpgrade.Add(function(iPlayer, iUnit) return true end) -->
    <!--   GameEvents.CanHaveUpgrade.Add(function(iPlayer, iUnit, iUnitClassType, iUnitType) return true end) -->
    <!--   GameEvents.UnitUpgraded.Add(function(iPlayer, iOldUnit, iNewUnit, bGoodyHut) end) -->
    <Row Class="3" Name="EVENTS_UNIT_UPGRADES" Value="0"/>

    <!-- Events sent about war and peace (v19) -->
    <!--   GameEvents.IsAbleToDeclareWar.Add(function(iPlayer, iAgainstTeam) return true end) -->
    <!--   GameEvents.DeclareWar.Add(function(iPlayer, iAgainstTeam) end) -->
    <!--   GameEvents.IsAbleToMakePeace.Add(function(iPlayer, iAgainstTeam) return true end) -->
    <!--   GameEvents.MakePeace.Add(function(iPlayer, iAgainstTeam) end) -->
    <Row Class="3" Name="EVENTS_WAR_AND_PEACE" Value="0"/>

	<!-- Event sent when a nuke is fired (v19) -->
	<!--   GameEvents.NuclearDetonation.Add(function(iPlayer, iX, iY, bWar, bBystanders) end) -->
    <Row Class="3" Name="EVENTS_NUCLEAR_DETONATION" Value="0"/>

	<!-- Event sent to see if a command is valid (v46) -->
	<!--   GameEvents.PlayerCanDoCommand.Add(function(iPlayer, iUnit, iCommand, iData1, iData2, iPlotX, iPlotY, bTestVisible) return true end) -->
    <Row Class="3" Name="EVENTS_COMMAND" Value="0"/>

	<!-- Events sent for custom missions (v46) -->
	<!--   CUSTOM_MISSION_NO_ACTION       = 0 -->
	<!--   CUSTOM_MISSION_ACTION          = 1 -->
	<!--   CUSTOM_MISSION_DONE            = 2 -->
	<!--   CUSTOM_MISSION_ACTION_AND_DONE = 3 -->
	<!--   GameEvents.CustomMissionPossible.Add(function(iPlayer, iUnit, iMission, iData1, iData2, iFlags=0, iTurn=-1, iPlotX, iPlotY, bTestVisible) return false end) -->
	<!--   GameEvents.CustomMissionStart.Add(function(iPlayer, iUnit, iMission, iData1, iData2, iFlags, iTurn) return CUSTOM_MISSION_ACTION end) -->
	<!--   GameEvents.CustomMissionSetActivity.Add(function(iPlayer, iUnit, iMission, iData1, iData2, iFlags, iTurn) return CUSTOM_MISSION_ACTION_AND_DONE end) -->
	<!--   GameEvents.CustomMissionDoStep.Add(function(iPlayer, iUnit, iMission, iData1, iData2, iFlags, iTurn) return CUSTOM_MISSION_ACTION_AND_DONE end) -->
	<!--   GameEvents.CustomMissionCompleted.Add(function(iPlayer, iUnit, iMission, iData1, iData2, iFlags, iTurn) return false end) -->
	<!--   GameEvents.CustomMissionTargetPlot.Add(function(iPlayer, iUnit, iMission, iData1, iData2, iFlags, iTurn) return iPlotIndex end) -->
	<!--   GameEvents.CustomMissionCycleTime.Add(function(iPlayer, iUnit, iMission, iData1, iData2, iFlags, iTurn) return iCameraTime end) - iCameraTime is 0, 1, 5 or 10 -->
	<!--   GameEvents.CustomMissionTimerInc.Add(function(iPlayer, iUnit, iMission, iData1, iData2, iFlags, iTurn) return iTimerInc end) -->
    <Row Class="3" Name="EVENTS_CUSTOM_MISSIONS" Value="0"/>

    <!-- Events generated by the RED (by Gedemon) dll mod code (v19) -->
    <!--   Turn   ==> PlayerEndTurnInitiated, PlayerEndTurnCompleted, TurnComplete -->
    <!--   Combat ==> PushingMissionTo, MustAbortAttack, CombatResult, CombatEnded -->
    <Row Class="3" Name="EVENTS_RED_TURN" Value="0"/>
    <Row Class="3" Name="EVENTS_RED_COMBAT" Value="0"/>
    <Row Class="3" Name="EVENTS_RED_COMBAT_MISSION" Value="0"/>
    <Row Class="3" Name="EVENTS_RED_COMBAT_ABORT" Value="0"/>
    <Row Class="3" Name="EVENTS_RED_COMBAT_RESULT" Value="0"/>
    <Row Class="3" Name="EVENTS_RED_COMBAT_ENDED" Value="0"/>

    <!-- Event sent to ascertain if a unit can move into a given plot (v19) -->
    <!--   GameEvents.CanMoveInto.Add(function(iPlayer, iUnit, iPlotX, iPlotY, bAttack, bDeclareWar) return true end) -->
    <!--   Also requires each unit type to receive the event to be enabled via the new SendCanMoveIntoEvent column in the Units table -->
	<!-- See also: "Units - Railroad Artillery" -->
    <Row Class="3" Name="EVENTS_CAN_MOVE_INTO" Value="0" DbUpdates="1"/>

Additional methods exposed to Lua
Spoiler :
Code:
[B]Game[/B]
bool IsInSomeReligion(eBelief)
[] GetAvailablePantheonBeliefs(ePlayer=NO_PLAYER)
[] GetAvailableFounderBeliefs(ePlayer=NO_PLAYER, eReligion=NO_REPLIGION)
[] GetAvailableFollowerBeliefs(ePlayer=NO_PLAYER, eReligion=NO_REPLIGION)
[] GetAvailableEnhancerBeliefs(ePlayer=NO_PLAYER, eReligion=NO_REPLIGION)
[] GetAvailableBonusBeliefs(ePlayer=NO_PLAYER, eReligion=NO_REPLIGION)
[] GetAvailableReformationBeliefs(ePlayer=NO_PLAYER, eReligion=NO_REPLIGION)
void EnhancePantheon(ePlayer, eBelief)
bool IsAchievementUnlocked(iAchievement)
int GetSteamStat(iSteamStat)
int CreateGreatWork(eGreatWorkType, ePlayer, eEra, sCreator)
[] GetTradeRoute(iRouteIndex) [[see Player:GetTradeRoutes() for details of fields in return structure]]
void ReloadGameDataDefines() [[forces the cached <Defines> values to be reloaded (useful if you've changed them via DB.Query())]]
void ReloadCustomModOptions() [[forces the cached <CustomModOptions> to be reloaded]]

[B]Team[/B]
int GetCityWorkingChange()
bool IsCityWorkingChange()
void ChangeCityWorkingChange(iChange)
bool HasSpyAtTeam(eTeam)

[B]Player[/B]
bool IsCityNameValid(sCityName, bTestDestroyed=false)
int GetSpecificUnitType(sUnitClass)
int GetSpecificBuildingType(sBuildingClass)
bool IsPlotConnectedToPlot(pFromPlot, pToPlot)
int GetMaxStockpile()
void DoSwapGreatWorks(eFocusYield)
BeliefTypes[] GetBeliefsInPantheon()
void SetPersonality(iPersonality)
int GetBuyPlotDistance()
int GetWorkPlotDistance()
int GetCityWorkingChange()
void ChangeCityWorkingChange(iChange)
void DismissNotification(iIndex, bUserInvoked)
bool IsTraitAnyBelief()
int GetPolicyConversionModifier(ePolicyType)
void EspionageCreateSpy()
void EspionagePromoteSpy(iSpyIndex)
void EspionageSetPassive(iSpyIndex, bPassive)
void EspionageSetOutcome(iSpyIndex, iSpyResult, bAffectsDiplomacy)
[] GetEspionageSpies() [[returns additional field; Passive(bool)]]
[] GetPotentialInternationalTradeRouteDestinationsFrom(pUnit, pCity) [[See GetPotentialInternationalTradeRouteDestinations for return details]]
UnitType GetTradeUnitType() [[bug ignoring civ specific units has been fixed]]
[] GetTradeRoutes() [[returns additional fields; UnitID(int), IsRecalled(bool), CircuitsCompleted(int), CircuitsToComplete(int), MovingForward(bool)]]
void AddMessage(sMessage)

[B]City[/B]
int GetProcessProductionTurnsLeft(eProcess)
bool IsAddsFreshWater()
int GetNumBuildingClass(eBuildingClass)
bool IsHasBuildingClass(eBuildingClass)
int GetTourismRateModifier()
void ChangeTourismRateModifier(iChange)
int GetNumGreatWorks(bIgnoreYield=true)
int GetBuyPlotDistance()
int GetWorkPlotDistance()
void GetCityWorkingChange(iChange)
void ChangeCityWorkingChange(iChange)
int GetBaseYieldRateFromGreatWorks(eYield)
int iRange, bool bIndirect GetBombardRange()
void SetNumFreeBuilding(eBuilding)
bool HasDiplomat(ePlayer)
bool HasSpy(ePlayer)
bool HasCounterSpy()
int GetCounterSpy()
int GetBuildingConversionModifier(eBuilding)
int GetBuildingGlobalConversionModifier(eBuilding)
void AddMessage(sMessage)

[B]Unit[/B]
Unit Upgrade(bIsFree=false)
Unit UpgradeTo(iUnitType, bIsFree=false)
void RebaseAt(iPlotX, iPlotY)
bool CanPlunderTradeRoute(pPlot)
bool PlunderTradeRoute()
bool CanCreateGreatWork(pPlot)
bool CreateGreatWork()
bool CanUpgradeTo(iUnitType, iTestVisible=0)
bool CanUpgradeInTerritory(bTestVisible=false)
UnitCombatTypes GetUnitPromotionType()
int GetTradeRouteIndex()
bool IsRecalledTrader()
void RecallTrader(bImmediate)
void EndTrader()
bool IsHoveringUnit()
bool IgnoreTerrainDamage()
bool IgnoreFeatureDamage()
bool ExtraTerrainDamage()
bool ExtraFeatureDamage()
int GetNearbyImprovementCombatBonus()
int GetNearbyImprovementBonusRange()
int GetCombatBonusImprovement()
bool CanCrossMountains()
bool CanCrossOceans()
bool CanCrossIce()
int GetExtraReconRange()
bool IsTerrainHalfMove(eTerrain)
bool IsFeatureHalfMove(eFeature)
void SetActivityType(iActivity, bClearFortify)
void SetReligion(eReligionType)
void SetConversionStrength(iStrength)
int GetConversionStrength(pCity=nil)
void SetSpreadsLeft(iSpreads)
void AddMessage(sMessage)

[B]Plot[/B]
int GetTurnDamage(bIgnoreTerrainDamage, bIgnoreFeatureDamage, bExtraTerrainDamage, bExtraFeatureDamage)
bool IsBlockaded()
bool IsAdjacentToIce()
bool IsNaturalWonder()
bool IsFriendlyCityOrPassableImprovement(pUnit, bCheckImprovement)
int GetUnitLimit()
int GetIndex() [[deprecated, use GetPlotIndex() instead]]
int ePlayer, int iCity GetOwner()
bool IsTerraFirma(pUnit)
int GetPlayerThatBuiltImprovement()
void SetPlayerThatBuiltImprovement(int)
int GetPlayerResponsibleForImprovement()
void SetPlayerResponsibleForImprovement(int)
int GetPlayerResponsibleForRoute()
void SetPlayerResponsibleForRoute(int)
int GetPlayerThatClearedBarbCampHere()
void SetPlayerThatClearedBarbCampHere(int)
void ChangeVisibilityCount(eTeam, iChange, eSeeInvisibleType, bInformExplorationTracking, bAlwaysSeeInvisible) [[bug with iChange has been fixed]]
void AddArchaeologicalRecord(iArtifactClass, iEra, iPlayer1, iPlayer2=-1)
void AddMessage(sMessage, iPlayer=activePlayer)
void AddPopupMessage(sMessage, fDelay=0.0, iPlayer=activePlayer)
 
Top Bottom