Snippets for mod makers

Machiavelli24

Mod creator
Joined
May 9, 2012
Messages
818
I have a handful of reusable snippets that can be used to implement a wide range off effects. In the past I've provided these haphazardly to other mod makers who have asked but I wanted to present them in a more central location. None of these snippets require a modified DLL.

Workshop location of the whole collection.

Unit Created Event (Vanilla, G&K, BNW)
Workshop
CivFanatics Download
This mod contains code that defines a lua event that fires off when a unit is created. The event does not fire when a unit is upgraded. The lua event provides the information you need to get the owning player object and the unit object.

Building Created Event (Vanilla, G&K, BNW)
Workshop
CivFanatics Download
This mod contains code that defines a lua event that fires off when a building is created. The event does not fire for buildings with 0 or less hammer cost unless they have a faithCost greater than zero and are enabledByBelief. The lua event provides the information you need to get the city object and the buildingclass.

Policies grant buildings (Vanilla, G&K, BNW)
Workshop
CivFanatics Download
This mod contains code that defines three new XML tables. By adding entries to these tables mod makers can have Social Policies grant buildings in cities.

Policy_PGB_FreeBuildingClass: <PolicyType, BuildingClass>
The building will be granted to every city.

Policy_PGB_FreeBuildingClassCapital: <PolicyType, BuildingClass>
The building will be granted to only the capital. If the capital moves (due to conquest) the building automatically moves.

Policy_PGB_FreeBuildingClassCityStates: <PolicyType, BuildingClassType>
The building will be granted to captured city-states.

Religion snippets (G&K, BNW)
Workshop
CivFanatics Download
This mod contains code that defines two lua events and a new XML table:

LuaEvents.CityAdoptsReligionEvent(iOwner, iX, iY, eOldReligion, eNewReligion, bFirstConversion)
A LUA event that fires when a city adopts a religion.

LuaEvents.ReligionFoundedEvent(founderID, iX, iY, eOldReligion, eNewReligion)
A LUA event that fires when a religion is founded.

Belief_FounderFreeBuildingClassCapital: <BeliefType, BuildingClassType>
A table that will grant the building to the player's capital if they have the founder belief. If their capital moves (due to conquest) than the building automatically moves.

Each snippet depend on the snippets above it. Meaning you must use "CityAdoptsReligionEvent" for either of the other snippets to work. And you must be using "ReligionFoundedEvent" for the Belief_FounderFreeBuildingClassCapital table to work.

Religions grant buildings (G&K, BNW)
Workshop
CivFanatics Download
This mod contains code that defines a new XML tables. By adding entries to these tables mod makers can have Religions (not beliefs) grant buildings in cities.

Religion_FreeBuildingClass: <ReligionType, BuildingClass>
When this religion becomes the majority in a city, the city will be granted this building. If the religion stops being the majority the building is removed.

Buildings require empire resources (Vanilla, G&K, BNW)
Workshop
CivFanatics Download
This mod contains code that defines two new XML tables. By adding entries to these tables mod makers can have Buildings that can only be built if the player has access to resources somewhere in their empire. Unlike the "Building_LocalResource" tables the resources do not have to be within the city's limits. Unlike "Building_ResourceQuantityRequirements" the resource is not consumed.
 
I'm getting a lot of "SerialEventUnitCreatedGood.lua:20: attempt to index global 'unit' (a nil value)" at the start of the game, when the units are created.

The code I hooked to it is this:
Spoiler :
Code:
function GreatShreikan(playerID, unitID, unitType)
	local pPlayer = Players[playerID]
	if pPlayer:GetCivilizationType() == GameInfoTypes["CIVILIZATION_CRAB_CLAN"] and unitType == GameInfoTypes["UNIT_SHREIKAN"] then
		local pUnit = pPlayer:GetUnitByID(unitID)
		local i = 2
		while i > 0 do
			local iPromotion = (tablerandom(ShreikanPromo)).ID
			if not pUnit:IsHasPromotion(iPromotion) then
				pUnit:SetHasPromotion(iPromotion, true)
				i = i - 1
			end
		end
		if pUnit:IsHasPromotion(GameInfoTypes["PROMOTION_FIGHTING_GENERAL"]) then
			CCFightingShreikan(pUnit)
			pUnit:SetHasPromotion(GameInfoTypes["PROMOTION_MARKED_FOR_DEATH"], true)
		end
	end
end
LuaEvents.SerialEventUnitCreatedGood.Add(GreatShreikan)

Any idea where it went wrong?
 
What you've got is fine and correct. The problem is that the code I have on the workshop for the Unit Created event is out of date (I thought I had updated it but I had not). Use the following latest and greatest version (taken from the building created event snippet):

Code:
-- Unit_CreatedFunctions.lua
-- Author: Machiavelli
-- DateCreated: 6/1/2012 9:02:22 AM
--------------------------------------------------------------
function CallSerialEventUnitCreatedGood(playerID, unitID, hexVec, unitType, cultureType, civID, primaryColor, secondaryColor, unitFlagIndex, fogState, selected, military, notInvisible)
	if(Players[playerID] == nil or
		Players[playerID]:GetUnitByID(unitID) == nil or
		Players[playerID]:GetUnitByID(unitID):IsDead() or
		Players[playerID]:GetUnitByID(unitID):IsHasPromotion(GameInfoTypes["PROMOTION_CREATED"])) then
        return;
    end

	local unit = Players[playerID]:GetUnitByID(unitID);

	-- Always mark the unit with the created promotion
	unit:SetHasPromotion(GameInfoTypes["PROMOTION_CREATED"], true);

	-- Call the good event
	LuaEvents.SerialEventUnitCreatedGood(playerID, unitID, hexVec, unitType, cultureType, civID, primaryColor, secondaryColor, unitFlagIndex, fogState, selected, military, notInvisible);

	-- Kill the unit if some code hooked into the event has indicated the unit should be deleted
	if(unit:IsHasPromotion(GameInfoTypes["PROMOTION_MARKED_FOR_DEATH"])) then
		unit:Kill();
	end
end

--------------
-- Initialization check.  Ensures this code isn't loaded twice
--------------
local retVal = {};
LuaEvents.SerialEventUnitCreatedGood_IsInitialized(retVal);

-- If retVal isn't changed, no other mod has initialized this code.
if (retVal.isInitialized == nil) then
	LuaEvents.SerialEventUnitCreatedGood_IsInitialized.Add(function (retVal) retVal.isInitialized = true; end);
	-- Initialize the code
	Events.SerialEventUnitCreated.Add(CallSerialEventUnitCreatedGood);
end
 
While the UnitCreated event is very useful, I must admit I find the promotion to be a bit of an eyesore.

Unfortunately, Civ currently hates my computer and crashes constantly so I can't test anything, but in theory if you added a dummy building to each city that gave a free promotion (say, PROMOTION_NEW_UNIT) and removed it when firing the event, it'd work the same but without a (visible) promotion, right?
Basically reverse the way it works right now.
 
While the UnitCreated event is very useful, I must admit I find the promotion to be a bit of an eyesore.

Unfortunately, Civ currently hates my computer and crashes constantly so I can't test anything, but in theory if you added a dummy building to each city that gave a free promotion (say, PROMOTION_NEW_UNIT) and removed it when firing the event, it'd work the same but without a (visible) promotion, right?
Basically reverse the way it works right now.
No. Because units are not always spawned within cities.

(edit)

Actually, looking a little closer at what you actually said as opposed to what I thought you said that could work so long as the building used the <FreePromotion> column. In which case it wouldn't be necessary to add the building to every city, just the capital when it was founded. This could work because the <FreePromotion> column is global to all units within the empire, and is permanent throughout the remainder of the game so long as the building doesn't also have an <Obsolete Tech> column.

But I think the real reason for actively adding the promotion using the Unit Created event is to actively mark the unit as having been 'previously processed' by the unit created event with the least amount of code and game-events possible.
 
I subscriped to the "Policies create buildings" mod on Steam, because I want this script, but the game doesn't download it ... Are the files available somewhere else than on Steam?
 
kaspergm, you'll have to start civ5 and go to the mods menu before it will download the mod. If that doesn't work I can upload a version to civfanatics.
 
That was what I tried ... it would be nice to have it uploaded to CivFanatics if you have time, but I found a workaround by downloading your Reform and Rule on this site and then taking the code from there.
 
If that didn't work, try unsubscribing and re-subscribe while civ is running. The Reform and Rule version is slightly out of date compared to the snippet (I am planning to update Reform and Rule with the snippet version this evening).
 
If that didn't work, try unsubscribing and re-subscribe while civ is running. The Reform and Rule version is slightly out of date compared to the snippet (I am planning to update Reform and Rule with the snippet version this evening).
I did notice the differences, but managed to get it adjusted to work according to the needs I had for now.
 
Thanks for updating your work, and for the pms :D
 
I did a updated each of the snippets today, ensuring all of them had the most up to date code and followed similar conventions. The snippets should all be stable. I don't have any plans to expand or redesign them further. Unless any bugs come out of the woodwork I don't expect to be releasing more updates for them.
 
Is there any known issue between the Unit Created and Condensed Promotions? I can't think of another mod that is doing anything with Promotions. I'm getting a unit with both 'Created' and 'Marked for Death', yet it lives...

Nothing useful in the Lua.log, apparently:
[2312.090] SerialEventUnitCreatedGood: 260
[2312.090] SerialEventUnitCreatedGood: 262
[2312.746] SerialEventUnitCreatedGood: 260
[2312.746] SerialEventUnitCreatedGood: 258
[2313.541] SerialEventUnitCreatedGood: 261
[2313.541] SerialEventUnitCreatedGood: 262
[2314.118] SerialEventUnitCreatedGood: 260
[2314.118] SerialEventUnitCreatedGood: 258
[2314.586] SerialEventUnitCreatedGood: 262
[2314.586] SerialEventUnitCreatedGood: 260
[2315.070] SerialEventUnitCreatedGood: 257
[2315.070] SerialEventUnitCreatedGood: 256

EDIT: Absolutely not Condensed Promotions. I'll test some of the mods, but I use too many at once, it will take a while. :p
 
I'm assuming you've got the latest and greatest version (v 5) and didn't see anything weird in your database.log? You may want to grep through your mod directory for "SerialEventUnitCreatedGood" and "SerialEventUnitCreated" and see what comes up.
 
I need to release an update to policy grant buildings (to bring it in sync with Reform's version) and I was also going to do a small update to the building event (add some robustness features). I can see about throwing up a copy civfanatics when I make those updates sometime this week.
 
Iam not sure if i make something wrong, but when i incorporate the religions grant buildings mod, and i found a religion in my capitol, its grants f.e. the buddism building twice.
Prohably i am just blind or i missed something.....
 
Are you talking about the "blank" (iconless) buildings that are part of "City Adopts Religion" event? There are suppose to be two. One is used to track what religion the city is currently, the other is used to determine if the city is converting to a religion for the first time ever. Technically the two buildings are of different classes but they have the same name because the end user is suppose to ignore them.
 
Top Bottom